Skip to content

Commit e006b67

Browse files
Carry the backend base URL into the module, so proxied Composio can address it
v1.8.0 gave the module a way to obtain a session bearer, which was necessary for proxied Composio and not sufficient: `effective_backend_api_url` still answered an empty string, so the request built against an empty base and failed inside the HTTP client with `builder error` — a message that names neither the cause nor the field. Found by routing OpenHuman's Composio sync onto the driver and watching the run get three provider actions in before dying on the transport. The bearer had reached it; the address had not. ## A field, not a seam The bearer is a seam because it is a credential that expires and gets refreshed, so any snapshot of it goes stale. A base URL is the opposite kind of value: routing configuration that changes when an operator points the host at a different backend, which is a restart rather than a mid-session event. Carrying it in `ModuleConfig` is both simpler and more honest about what it is. ## No default is substituted An empty URL stays empty and fails in the HTTP client. Guessing one here would send a user's memory at whichever backend this crate happened to hard-code — including, for a self-hosted operator, a backend they do not control. A bad error message is a much smaller problem than that, so the field is documented as required for proxied mode rather than defaulted into looking optional. `#[serde(default)]`, so a host that predates the field still loads.
1 parent cd73b56 commit e006b67

5 files changed

Lines changed: 33 additions & 1 deletion

File tree

crates/tinymemory-module/src/config.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,6 +164,22 @@ pub struct ModuleConfig {
164164
/// a no-sync nobody can, this picks the one that can be noticed.
165165
pub memory_sync_interval_secs: Option<u64>,
166166

167+
/// Base URL of the OpenHuman backend, for proxied ("backend") Composio.
168+
///
169+
/// A field rather than a seam member, unlike the session bearer beside it,
170+
/// and the difference is what each thing is. A bearer is a credential that
171+
/// expires and gets refreshed, so a snapshot of it goes stale and has to be
172+
/// asked for per call. A base URL is routing configuration: it changes when
173+
/// an operator points the host at a different backend, which is a restart,
174+
/// not a mid-session event.
175+
///
176+
/// Empty means the host named none. The proxied branch of `composio_config`
177+
/// then builds its request against an empty base and fails inside the HTTP
178+
/// client with a builder error that names no cause — so a host that intends
179+
/// proxied mode must send this.
180+
#[serde(default)]
181+
pub backend_api_url: String,
182+
167183
/// How the host routes Composio calls: `backend` or `direct`.
168184
///
169185
/// Empty means the host stated no mode — an older host, or one with no
@@ -204,6 +220,7 @@ impl Default for ModuleConfig {
204220
local_ai: LocalAiConfig::default(),
205221
embeddings_provider: None,
206222
memory_provider: None,
223+
backend_api_url: String::new(),
207224
default_model: None,
208225
default_temperature: 0.0,
209226
output_language: None,

crates/tinymemory-module/src/provider.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ impl From<&ModuleConfig> for EngineRuntimeConfig {
3333
// mode, and both of those skip work rather than fail it.
3434
memory_sync_interval_secs: config.memory_sync_interval_secs,
3535
composio_mode: config.composio_mode.clone(),
36+
backend_api_url: config.backend_api_url.clone(),
3637
composio_entity_id: config.composio_entity_id.clone(),
3738
}
3839
}

crates/tinymemory-tinycortex/src/engine/mod.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,10 @@ pub struct EngineRuntimeConfig {
118118
/// answer backend mode gets, which is what an unset Composio integration
119119
/// should look like.
120120
pub composio_mode: String,
121+
/// Base URL of the host's backend, for proxied Composio. Empty when the
122+
/// host named none — see `effective_backend_api_url` below for why that is
123+
/// a refusal rather than a default.
124+
pub backend_api_url: String,
121125
/// The Composio entity the host authenticates as.
122126
///
123127
/// An identifier, not a credential: it selects whose connected accounts a
@@ -200,8 +204,15 @@ impl MemoryHostConfig for EngineRuntimeConfig {
200204
fn api_url(&self) -> Option<&str> {
201205
None
202206
}
207+
/// The host's backend base URL, verbatim.
208+
///
209+
/// No default is substituted for an empty one. Guessing a URL here would
210+
/// send a user's memory at whichever backend this crate happened to hard-code
211+
/// — including, for a self-hosted operator, one they do not control. An
212+
/// empty string fails inside the HTTP client instead, which is a bad error
213+
/// message and the right outcome.
203214
fn effective_backend_api_url(&self) -> String {
204-
String::new()
215+
self.backend_api_url.clone()
205216
}
206217
/// Always the named refusal, never `Ok(None)`.
207218
///

crates/tinymemory-tinycortex/src/engine/test.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ fn runtime_config() -> EngineRuntimeConfig {
5555
EngineRuntimeConfig {
5656
workspace_dir: "/workspace".into(),
5757
config_path: "/workspace/config.toml".into(),
58+
backend_api_url: String::new(),
5859
memory: Default::default(),
5960
memory_tree: Default::default(),
6061
scheduler_gate: Default::default(),
@@ -253,6 +254,7 @@ fn the_sync_cadence_is_answered_from_the_host_and_not_from_a_constant() {
253254
fn an_unstated_composio_mode_is_not_direct() {
254255
let config = EngineRuntimeConfig {
255256
composio_mode: String::new(),
257+
backend_api_url: String::new(),
256258
composio_entity_id: String::new(),
257259
..runtime_config()
258260
};

crates/tinymemory-tinycortex/tests/full_provider_conformance.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ fn provider_config(
118118
// sends.
119119
memory_sync_interval_secs: None,
120120
composio_mode: String::new(),
121+
backend_api_url: String::new(),
121122
composio_entity_id: String::new(),
122123
}
123124
}

0 commit comments

Comments
 (0)