Skip to content

Commit ae3c35a

Browse files
committed
Add dynamic workflow runtime
1 parent f97ea48 commit ae3c35a

8 files changed

Lines changed: 841 additions & 16 deletions

File tree

Cargo.lock

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

core/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ a3s-common = { version = "0.1.1", path = "../../common" }
1717
a3s-memory = { version = "0.1.2", path = "../../memory" }
1818
a3s-lane = { version = "0.4", path = "../../lane" }
1919
a3s-search = { version = "1.2.3", path = "../../search", default-features = false, features = ["lightpanda"] }
20+
a3s-flow = { version = "0.1.0", path = "../../flow" }
2021

2122
# Async runtime
2223
tokio = { version = "1.35", features = [

core/src/agent_api.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1360,6 +1360,16 @@ impl AgentSession {
13601360
self.tool_executor.register_dynamic_tool(tool);
13611361
}
13621362

1363+
/// Register the A3S Flow-backed dynamic workflow tool for this live session.
1364+
///
1365+
/// The tool is named `dynamic_workflow`. It accepts a sandboxed JavaScript
1366+
/// PTC workflow script and executes it through
1367+
/// [`crate::DynamicWorkflowRuntime`], so A3S Flow owns workflow replay while
1368+
/// the script can still call A3S Code tools.
1369+
pub fn register_dynamic_workflow_runtime(&self) {
1370+
crate::tools::register_dynamic_workflow(self.tool_executor.registry());
1371+
}
1372+
13631373
/// Remove a previously host-registered dynamic tool by name (e.g. on logout).
13641374
/// No-op if no tool of that name is registered.
13651375
pub fn unregister_dynamic_tool(&self, name: &str) {

core/src/agent_api/direct_tools.rs

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,10 @@ impl DirectToolRuntime {
101101
}
102102

103103
pub(super) async fn call(&self, name: &str, args: serde_json::Value) -> Result<ToolCallResult> {
104-
let result = self.tool_executor.execute(name, &args).await?;
104+
let result = self
105+
.tool_executor
106+
.execute_with_context(name, &args, &self.tool_context)
107+
.await?;
105108
Ok(ToolCallResult {
106109
name: name.to_string(),
107110
output: result.output,
@@ -123,6 +126,36 @@ fn parse_glob_output(output: &str) -> Vec<String> {
123126
#[cfg(test)]
124127
mod tests {
125128
use super::*;
129+
use crate::tools::{Tool, ToolOutput};
130+
use anyhow::Result;
131+
use async_trait::async_trait;
132+
133+
struct ContextProbeTool;
134+
135+
#[async_trait]
136+
impl Tool for ContextProbeTool {
137+
fn name(&self) -> &str {
138+
"context_probe"
139+
}
140+
141+
fn description(&self) -> &str {
142+
"Reports direct tool context for tests."
143+
}
144+
145+
fn parameters(&self) -> serde_json::Value {
146+
serde_json::json!({ "type": "object" })
147+
}
148+
149+
async fn execute(
150+
&self,
151+
_args: &serde_json::Value,
152+
ctx: &ToolContext,
153+
) -> Result<ToolOutput> {
154+
Ok(ToolOutput::success(
155+
ctx.session_id.as_deref().unwrap_or("missing-session"),
156+
))
157+
}
158+
}
126159

127160
#[test]
128161
fn parse_glob_output_ignores_empty_lines() {
@@ -131,4 +164,22 @@ mod tests {
131164
vec!["src/lib.rs".to_string(), "src/main.rs".to_string()]
132165
);
133166
}
167+
168+
#[tokio::test]
169+
async fn direct_tool_call_uses_session_tool_context() {
170+
let dir = tempfile::tempdir().unwrap();
171+
let tool_executor = Arc::new(ToolExecutor::new(dir.path().to_string_lossy().to_string()));
172+
tool_executor.register_dynamic_tool(Arc::new(ContextProbeTool));
173+
let runtime = DirectToolRuntime {
174+
tool_executor,
175+
tool_context: ToolContext::new(dir.path().to_path_buf()).with_session_id("session-123"),
176+
};
177+
178+
let output = runtime
179+
.call("context_probe", serde_json::json!({}))
180+
.await
181+
.unwrap();
182+
183+
assert_eq!(output.output, "session-123");
184+
}
134185
}

0 commit comments

Comments
 (0)