mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-27 08:00:17 +00:00
Fix owner-scoped message routing fallbacks (#1574)
* Fix owner-scoped message routing fallbacks * Address PR feedback on routing regressions * Address review notes on routing fallbacks
This commit is contained in:
@@ -1438,6 +1438,9 @@ impl From<TaskOutput> for Result<String, Error> {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::sync::Arc;
|
||||
|
||||
use crate::channels::ChannelManager;
|
||||
use crate::llm::ToolSelection;
|
||||
|
||||
use super::*;
|
||||
@@ -1448,6 +1451,8 @@ mod tests {
|
||||
ToolCompletionResponse,
|
||||
};
|
||||
use crate::safety::SafetyLayer;
|
||||
use crate::testing::{BroadcastCapture, RecordingBroadcastChannel};
|
||||
use crate::tools::builtin::MessageTool;
|
||||
use crate::tools::{Tool, ToolError as ToolExecError, ToolOutput};
|
||||
|
||||
/// A test tool that sleeps for a configurable duration before returning.
|
||||
@@ -1539,6 +1544,20 @@ mod tests {
|
||||
Worker::new(job_id, deps)
|
||||
}
|
||||
|
||||
async fn make_worker_with_message_tool()
|
||||
-> (Worker, Arc<MessageTool>, BroadcastCapture, BroadcastCapture) {
|
||||
let channel_manager = ChannelManager::new();
|
||||
let (gateway, gateway_captures) = RecordingBroadcastChannel::new("gateway");
|
||||
let (telegram, telegram_captures) = RecordingBroadcastChannel::new("telegram");
|
||||
channel_manager.add(Box::new(gateway)).await;
|
||||
channel_manager.add(Box::new(telegram)).await;
|
||||
|
||||
let message_tool = Arc::new(MessageTool::new(Arc::new(channel_manager)));
|
||||
let worker = make_worker(vec![message_tool.clone()]).await;
|
||||
|
||||
(worker, message_tool, gateway_captures, telegram_captures)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_tool_selection_preserves_call_id() {
|
||||
let selection = ToolSelection {
|
||||
@@ -2147,4 +2166,50 @@ mod tests {
|
||||
|
||||
assert_eq!(ctx.metadata, original); // safety: test
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn autonomous_message_tool_ignores_stale_gateway_context_when_routine_metadata_targets_telegram()
|
||||
{
|
||||
let (worker, message_tool, gateway_captures, telegram_captures) =
|
||||
make_worker_with_message_tool().await;
|
||||
|
||||
message_tool
|
||||
.set_context(
|
||||
Some("gateway".to_string()),
|
||||
Some("stale-gateway-target".to_string()),
|
||||
)
|
||||
.await;
|
||||
|
||||
worker
|
||||
.context_manager()
|
||||
.update_context(worker.job_id, |ctx| {
|
||||
ctx.user_id = "telegram".to_string();
|
||||
ctx.metadata = serde_json::json!({
|
||||
"notify_channel": "telegram",
|
||||
"owner_id": "owner-scope",
|
||||
});
|
||||
Ok::<(), String>(())
|
||||
})
|
||||
.await
|
||||
.unwrap() // safety: test
|
||||
.unwrap(); // safety: test
|
||||
|
||||
let result = worker
|
||||
.execute_tool(
|
||||
"message",
|
||||
&serde_json::json!({"content": "hello from routine"}),
|
||||
)
|
||||
.await
|
||||
.unwrap(); // safety: test
|
||||
assert!(
|
||||
result.contains("telegram:owner-scope"),
|
||||
"expected telegram owner-scope routing, got: {result}"
|
||||
);
|
||||
|
||||
assert!(gateway_captures.lock().await.is_empty());
|
||||
let telegram = telegram_captures.lock().await.clone();
|
||||
assert_eq!(telegram.len(), 1);
|
||||
assert_eq!(telegram[0].0, "owner-scope");
|
||||
assert_eq!(telegram[0].1.content, "hello from routine");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user