Let a host ask whether a toolkit has a sync pipeline - #106
Conversation
`is_composio_toolkit_syncable` is the gate that decides whether a Composio connection can become a memory source, and it is engine-internal. A host that cannot ask it has three bad options: keep its own copy of the list and drift, infer the answer from a failed sync — by which point it has already registered the source it should not have — or reach past the contract into the engine crate. OpenHuman does the third today, and it is the last thing keeping the engine's provider re-export alive there (openhuman#5560). `IsToolkitSyncable(toolkit) -> bool` closes it. A predicate rather than the list, because the answer depends on a normalisation the driver owns: it trims and lower-cases before matching. A caller handed the list would have to reimplement that rule, and would be right until the day the rule changed and silently wrong after. The question keeps the rule on the side that owns it, and the cost is one round-trip per connection authorisation rather than per sync. `Unsupported` rather than `Ok(false)` from a driver that cannot enumerate its pipelines: "I have no pipeline for this" and "I cannot tell you" are different answers, and a caller that conflated them would quietly stop registering every memory source while still looking healthy. Defaulted on the trait, so this is additive for any other implementor; the null driver takes the default and answers `Unsupported`. 985 + 113 + 62 + 163 + 134 + 24 tests pass in the root workspace and the module's own; both build clean with --all-targets.
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: Warning Your free Security trial is over. An organization admin can activate billing to continue. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
How this change flows2 changed behaviours across 11 relationships. 6 surrounding behaviours are shown (60 graph nodes walked). 27 further behaviours left out to keep the diagram readable. flowchart LR
n0["...hod_fails_with_its_advertised_family_name<br/>changed"]:::changed
n1["TinycortexProvider<br/>changed"]:::changed
n2["block_on"]:::impacted
n3["assert"]:::impacted
n4["EngineRuntimeConfig"]:::impacted
n5["assert_unsupported"]:::impacted
n6["...eturn_unsupported_naming_their_capability"]:::impacted
n7["Result"]:::impacted
n0 -->|calls| n2
n0 -->|tests| n2
n0 -->|calls| n3
n0 -->|calls| n5
n0 -->|tests| n5
n1 -->|uses| n4
n5 -->|uses| n7
n6 -->|calls| n2
n6 -->|tests| n2
n6 -->|calls| n5
n6 -->|tests| n5
classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Green: changed behaviour. Grey: surrounding behaviour. Arrows name the call, use, implementation, or test relationship. Orange: has findings. Red: has a finding that blocks the merge. |
What
One member:
IsToolkitSyncable(toolkit) -> bool, onMemorySourceSync.Why
is_composio_toolkit_syncabledecides whether a Composio connection can become a memory source, and it is engine-internal. A host that cannot ask it has three options, all bad:OpenHuman does the third. It is now the last thing keeping the engine's provider re-export alive there (tinyhumansai/openhuman#5560), and that re-export is one of the shims holding
tinymemory-corein the shipped dependency graph.The gate matters because of what getting it wrong looks like. From the host's own comment on the code this replaces:
Design notes
A predicate, not the list. The answer depends on a normalisation the driver owns — it trims and lower-cases before matching. A caller handed
["clickup", "github", "gmail", "linear", "notion", "slack"]would have to reimplement that rule, and would be correct right up until the rule changed, then silently wrong. Asking the question keeps the rule on the side that owns it. The cost is one round-trip per connection authorisation, not per sync.Unsupported, notOk(false), from a driver that cannot enumerate its pipelines. "I have no pipeline for this" and "I cannot tell you" are different facts. A caller that conflated them would quietly stop registering every memory source while still looking healthy — the same failure mode the member exists to prevent, one level up.Defaulted on the trait, so this is additive for any other implementor; the null driver takes the default and answers
Unsupported.The doc also states what
falsemeans, since that is where the original bug came from: not "refuse the connection". A toolkit with no pipeline is still a perfectly good agent-tool integration. What it cannot be is a memory source.Tests
Null-driver
Unsupportedcoverage, and the member joins the manifest,METHODSand the loader E2E's expected list, so the four registration sites stay in agreement.Root workspace and the module's own workspace both build clean with
--all-targets; 985 + 113 + 62 + 163 + 134 + 24 tests pass.After this
Releases, then OpenHuman re-pins and
memory/sync/composio/bus.rsloses its last engine call — which lets theprovidersre-export shim be deleted along with it.Stacked conceptually on #105 (
BootstrapConnection), already merged and released in v1.11.0: that one moved the connection-created hook behind the bus, this one moves the gate that decides whether to run it.