docs/seq-agent-rpc-contract.md
This document defines the required interface between agent runtimes (Flow/AI server) and OS-level automation.
Status: mandatory for new integrations.
If an agent needs macOS UI/app/input actions, it must call seqd via the Rust seq_client library.
request_id, run_id, tool_call_id) across planner + OS executor.seq_client (~/code/seq/api/rust/seq_client) for OS actions.seq_client sends JSON RPC v1 over Unix socket to seqd.seqd executes OS ops and returns typed response envelope.Do not insert shell wrappers in the hot path for OS actions.
Allowed (required):
seq_client::SeqClient + RpcRequest.seqd (/tmp/seqd.sock default).f seq-rpc ... (internally uses native Rust socket RPC, no seq rpc subprocess).Forbidden for production OS-tool execution:
bash -lc "seq ..." inside tool loop.curl/nc direct JSON RPC from tool loop (okay for debugging only).Every request should include:
oprequest_idrun_idtool_call_idThese IDs are required for trace joinability across:
seqd metrics/tracesopen_appopen_app_togglerun_macroclickright_clickdouble_clickmovescrolldragscreenshotping, app_state, perfSee canonical protocol details: ~/code/seq/docs/agent-rpc-v1.md.
SeqClient per worker and reuse it.connect_with_timeout).ok=false as tool failure (surface error field).ping, app_state, perf, maybe screenshot) may retry once.click, drag, open_app, run_macro) must not auto-retry blindly.Hot path target is low latency at the control plane, not guaranteed zero end-to-end UI latency.
Expectations:
Benchmark and regressions should measure:
dur_us returned by seqduse seq_client::{RpcRequest, SeqClient};
use serde_json::json;
use std::time::Duration;
fn call_open_app() -> Result<(), Box<dyn std::error::Error>> {
let client = SeqClient::connect_with_timeout("/tmp/seqd.sock", Duration::from_secs(5))?;
let resp = client.call(
RpcRequest::new("open_app")
.with_request_id("req-42")
.with_run_id("run-abc")
.with_tool_call_id("tool-7")
.with_args_json(json!({ "name": "Safari" })),
)?;
if !resp.ok {
return Err(format!("seq open_app failed: {:?}", resp.error).into());
}
Ok(())
}
f seq-rpc)For Flow-managed agent workloads, use f seq-rpc as the stable operator-facing interface.
It keeps protocol framing in Rust and avoids ad-hoc shell parsing of seq output.
Examples:
# Health
f seq-rpc ping --request-id req-1 --run-id run-1 --tool-call-id tool-1
# Open app
f seq-rpc open-app "Safari" --request-id req-2 --run-id run-1 --tool-call-id tool-2
# Raw op + JSON args
f seq-rpc rpc open_app --args-json '{"name":"Google Chrome"}' --pretty
Default socket resolution order:
--socket <path>SEQ_SOCKET_PATHSEQD_SOCKET/tmp/seqd.sockAI_SERVER_URL=http://127.0.0.1:7331 \
~/code/org/gen/new/ai/scripts/ai-task.sh \
--provider nvidia \
--model moonshotai/kimi-k2.5 \
--project-path ~/code/flow \
--max-steps 6 \
--prompt "Use bash tool once to run: f seq-rpc ping --request-id kimi-smoke --run-id run-smoke --tool-call-id tool-smoke; then summarize ok/op/dur_us."
seq_client.f seq-rpc (native Rust path) instead of seq rpc.request_id, run_id, tool_call_id.seq rpc / nc only for manual debugging and smoke tests.