Skip to content

Commit 5f9052e

Browse files
Merge pull request #41 from YellowSnnowmann/feat/18-b3-sync-on-a-foreign-driver
Run Composio normalisation and storage on a driver that is not TinyCortex (#18 §B3)
2 parents a8dfab2 + f1d1645 commit 5f9052e

31 files changed

Lines changed: 2950 additions & 18 deletions

Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
[workspace]
2-
members = [".", "api", "core", "adapters/tinycortex", "adapters/remote", "conformance"]
3-
default-members = [".", "api", "core", "adapters/tinycortex", "adapters/remote", "conformance"]
2+
# `sync` is the engine-neutral Composio normalisers (issue #18 §B3).
3+
members = [".", "api", "core", "sync", "adapters/tinycortex", "adapters/remote", "conformance"]
4+
default-members = [".", "api", "core", "sync", "adapters/tinycortex", "adapters/remote", "conformance"]
45
# `vendor/` holds engine submodules (tinycortex, tinybus, tinyagents), each of
56
# which is its own workspace with its own lockfile. Same exclusion
67
# `vendor/tinycortex` uses for its own nested vendor directory.
@@ -79,6 +80,9 @@ tinymemory-api = { path = "api", features = ["test-support"] }
7980
# integration tests. A dev-dependency only: the facade must not carry a test
8081
# harness into a consumer's dependency graph.
8182
tinymemory-conformance = { path = "conformance" }
83+
# The extracted Composio normalisers, for the integration test that runs them
84+
# against a driver that is not TinyCortex (issue #18 §B3).
85+
tinymemory-sync = { path = "sync" }
8286

8387
[features]
8488
default = []

conformance/src/suite/mod.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,7 @@ pub async fn assert_awkward_content_round_trips(provider: &dyn MemoryProvider) {
601601
("large", "x".repeat(64 * 1024)),
602602
("newlines", "a\nb\r\nc\0d".to_string()),
603603
];
604-
let mut accepted = 0usize;
604+
let mut accepted: Vec<&str> = Vec::new();
605605
for (key, content) in &cases {
606606
// A driver may refuse a shape outright — `MemoryCore::store` documents
607607
// `Invalid` "for caller input the driver rejects", and the TinyCortex
@@ -629,7 +629,7 @@ pub async fn assert_awkward_content_round_trips(provider: &dyn MemoryProvider) {
629629
{
630630
continue;
631631
}
632-
accepted += 1;
632+
accepted.push(key);
633633
if let Some(got) = provider
634634
.get(&ns, key)
635635
.await
@@ -638,12 +638,17 @@ pub async fn assert_awkward_content_round_trips(provider: &dyn MemoryProvider) {
638638
assert_eq!(&got.content, content, "{who}: `{key}` content was mangled");
639639
}
640640
}
641-
// Without this a driver that refused every shape would pass having stored
642-
// nothing, which is the vacuous reading of "may refuse".
641+
// "May refuse" needs a floor, or a driver that refused everything would pass
642+
// having stored nothing. The floor is `unicode` specifically rather than a
643+
// count: refusing `empty` is documented validation, and refusing `large` is
644+
// a defensible size limit, but refusing ordinary UTF-8 text is a broken
645+
// driver — and unicode is the case where mangling actually shows, since
646+
// truncation and re-encoding are invisible on ASCII.
643647
assert!(
644-
accepted > 0,
645-
"{who}: refused every content shape — unicode, empty, large and \
646-
newlines were all rejected, so this assertion proved nothing"
648+
accepted.contains(&"unicode"),
649+
"{who}: refused ordinary UTF-8 content — accepted {accepted:?}. A driver \
650+
may refuse a shape, but not this one; every assertion about content \
651+
surviving a round trip rests on it."
647652
);
648653
let keys: Vec<&str> = cases.iter().map(|(k, _)| *k).collect();
649654
cleanup(provider, &ns, &keys).await;

core/Cargo.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ readme = "../README.md"
1616
# The contract. `tinymemory-core` implements and consumes it; the host seam
1717
# traits (config, event sink, embeddings, chat) live in `tinymemory_api::host`.
1818
tinymemory-api = { path = "../api" }
19+
# Composio payload normalisers, extracted out of the engine (issue #18 §B3).
20+
# They were reached through `tinycortex` until now, which meant a host binding a
21+
# different engine could not have Composio sync despite none of this code
22+
# caring which engine is bound.
23+
tinymemory-sync = { path = "../sync" }
1924
tinymemory = { path = ".." }
2025

2126
# The default embedded engine. `store/`, `tree/` and `sync/` drive it directly;

core/src/sync/composio/providers/clickup/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
// The payload normalisers moved to tinycortex (they are pure Value
1818
// transforms, i.e. driver-side). Aliased under the old module name so
1919
// every `normalization::extract_*` call site below stays unchanged.
20-
use crate::engine::backend::sync::composio::providers::normalize::clickup as normalization;
20+
use tinymemory_sync::clickup as normalization;
2121
mod provider;
2222
#[cfg(test)]
2323
mod tests;

core/src/sync/composio/providers/github/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
// The payload normalisers moved to tinycortex (they are pure Value
1717
// transforms, i.e. driver-side). Aliased under the old module name so
1818
// every `normalization::extract_*` call site below stays unchanged.
19-
use crate::engine::backend::sync::composio::providers::normalize::github as normalization;
19+
use tinymemory_sync::github as normalization;
2020
mod provider;
2121
#[cfg(test)]
2222
mod tests;

core/src/sync/composio/providers/gmail/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// The Gmail post-processor moved to tinycortex (a pure Value transform, i.e.
22
// driver-side). Aliased under the old module name so the single call site in
33
// `provider.rs` stays unchanged.
4-
use crate::engine::backend::sync::composio::providers::normalize::gmail_post_process as post_process;
4+
use tinymemory_sync::gmail_post_process as post_process;
55
mod provider;
66
#[cfg(test)]
77
mod tests;

core/src/sync/composio/providers/helpers.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
//! Shared helpers for Composio provider implementations.
22
//!
33
//! `pick_str` used to live here. It is a provider payload normaliser, so it
4-
//! moved to `crate::engine::backend::sync::composio::providers::normalize::helpers`
4+
//! moved to `tinymemory_sync::helpers`
55
//! and is re-exported from this module's parent. The helpers that remain are
66
//! request-building rather than normalisation, and stay host-side.
77
8-
use crate::engine::backend::sync::composio::providers::normalize::helpers::pick_str;
8+
use tinymemory_sync::helpers::pick_str;
99

1010
/// Shallow-merge an `extra` JSON object into a (mutable) action-args
1111
/// object. Only object-typed extras are merged; non-object `extra`

core/src/sync/composio/providers/linear/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
// The payload normalisers moved to tinycortex (they are pure Value
77
// transforms, i.e. driver-side). Aliased under the old module name so
88
// every `normalization::extract_*` call site below stays unchanged.
9-
use crate::engine::backend::sync::composio::providers::normalize::linear as normalization;
9+
use tinymemory_sync::linear as normalization;
1010
mod provider;
1111
#[cfg(test)]
1212
mod tests;

core/src/sync/composio/providers/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,11 @@ pub(crate) use helpers::{first_array_str, merge_extra};
281281
// re-exported here so the ~40 in-tree call sites keep resolving unchanged.
282282
// Note this is deliberately NOT `providers::common::pick_str`, which coerces
283283
// numbers to strings — see the doc comments on both definitions.
284-
pub(crate) use crate::engine::backend::sync::composio::providers::normalize::helpers::pick_str;
285284
pub use registry::{
286285
all_providers, get_provider, init_default_providers, register_provider, ProviderArc,
287286
};
288287
pub use scope_lookup::{curated_scope_for, toolkit_has_scope};
288+
pub(crate) use tinymemory_sync::helpers::pick_str;
289289
pub use tool_scope::{classify_unknown, find_curated, toolkit_from_slug, CuratedTool, ToolScope};
290290
pub use traits::{resolve_sync_interval_secs, sync_interval_env_var, ComposioProvider};
291291
pub use types::{

0 commit comments

Comments
 (0)