Skip to main content

2. Verified findings that shape the design

2.1 Protocol, agent libraries and frontend​

#Finding (Nov 2026)Design consequence
1ag-ui-core 0.1.0 was last published in August 2025 and has no AG-UI 1.0 types such as outcomes and interrupts (noted in everruns PR #3964). A new community ag-ui Rust SDK targeting 1.0 is in review in ag-ui PR #2778 and is not yet publishedHand-write the AG-UI 1.0 wire types and SSE encoder in a crate called agui. Move to the official crate once it ships
2AG-UI 1.0 models approval as RUN_FINISHED with an interrupt outcome. The client resumes with resume[] on the same thread, must address every open interrupt, and the resume must be idempotent. State is sent in snapshot events before the interruptApproval is a graph pause, then snapshot events, then the interrupt outcome. Resume sets the decision in the session and runs the graph again
3Pydantic AI's AG-UI docs note that older clients, including the @ag-ui/core version CopilotKit used at the time, reject the outcome and interrupt fields. CopilotKit issue #8080 (v1.83.0) reports that useInterrupt sends a synthetic tool message for tool-bound interruptsRead protocolVersion on each request. Version 1.0 clients get the interrupt outcome with reason: "confirmation". Older clients get a legacy custom event
4rig 0.43–0.46 changed heavily; a downstream migration issue (kaibo #226) describes it as close to a rewrite. In 0.46.0 (31 Oct 2026) transport moved to rig-reqwest, the agent runtime to rig-agent, and models are DynModel<Completion>All rig types stay inside the llm crate behind the LlmProvider trait
5graph-flow 0.8.1's rig feature depends on rig-core ^0.42 (source-verified)Keep that feature off. Tasks call LlmProvider
6graph-flow 0.8.1 is MIT, a small single-maintainer project. Its API: GraphBuilder, Task, FlowRunner::new(graph, storage), SessionStorage (save, get, delete), a synchronous Context::set/get, and NextAction::{Continue, ContinueAndExecute, GoTo, End, WaitForInput} (source-verified)Confine graph-flow to two folders of the app so it can be replaced
7CopilotKit v2 runtime uses createCopilotRuntimeHandler with CopilotRuntime({ agents }) and HttpAgent from @ag-ui/client (seen in CopilotKit issue #8192 on runtime 1.83.0 and @ag-ui/client 1.0.2)The Next.js route registers one HttpAgent per workflow, built from the backend's agent list

2.2 Loco.rs​

#FindingDesign consequence
8loco-rs latest is 1.3.1, Apache-2.0, requires Rust 1.94. It builds on axum ^0.8.1, sea-orm ^2.0, sqlx ^0.9, tera ^2.1 (source-verified)Loco owns HTTP, config, the DB pool, queue, auth and CLI
9graph-flow's postgres feature depends on sqlx ^0.8.6, while Loco uses sqlx 0.9 (source-verified)Disable graph-flow's default features and implement SessionStorage on Loco's SeaORM connection (§7.6)
10Loco has a Postgres-backed job queue (queue.kind: Postgres), three worker modes, a cron scheduler, typed settings: access through ctx.config.settings::<T>(), a SharedStore on AppContext, and opt-in multi-tenancy helpers (source-verified)No Redis or Valkey in the core. No hand-written job queue or config loader
11Loco loads config/{env}.yaml and deep-merges an optional config/{env}.local.yaml. YAML is rendered through Tera first, with get_env(name=..., default=...) available (source-verified)Secrets stay in environment variables and are referenced from YAML
12Loco contains no OpenTelemetry code (source-verified by search)Keep a small telemetry crate and install it from Loco's init_logger hook
13Loco parses YAML with serde_yaml_ng 0.10 (MIT). The original serde_yaml is marked deprecated (source-verified)Use serde_yaml_ng for the definition files, so there is one YAML parser
14The pgvector Rust crate has no SeaORM feature (source-verified)Vector queries use SeaORM raw statements with a ::vector cast (§7.8)