feat(aop): unify agent transport end to end#62
Conversation
Introduce core/tool (shared tool contracts) and core/node (shared web connectivity) to break cross-package dependencies: - core/tool: ToolDefinition, Result, Executor, Tool interfaces with zero project dependencies. Renamed from core/toolapi with simplified names (tool.Definition, tool.Result, tool.Executor, tool.Tool). - core/node: shared WebSocket connectivity extracted from pkg/webagent (1400→612 lines). Defines ConnectConfig + ChatHandler interface so both runner and agent connect to web via the same node.Connect(). - pkg/agent no longer imports pkg/commands (Config.Tools is now tool.Executor interface; LoopCommand accepts injected io.Writer). - pkg/commands no longer imports pkg/agent/provider (types come from core/tool via aliases; pkg/tools/* need zero changes). - cmd/runner no longer imports pkg/webagent (uses core/node directly). - core/config no longer imports pkg/webproto (FetchRemoteConfig moved to pkg/webagent where the web dependency belongs). - pkg/agent/probe no longer imports pkg/webproto (uses own ProbeConfig; pkg/web converts DistributeConfig at the boundary). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Agent Output Protocol (AOP): - New pkg/aop/ package: Go types, agent.Event→AOP conversion, JSONL writer - All event serialization paths switched to AOP v1 format - Delete pkg/agent/event_json.go (old MarshalJSON no longer needed) - Web hub forwardAgentEvent consumes AOP events directly - Harness/timeline adapted to parse AOP JSONL Chat unification: - Local viewer component forks deleted (6 files) - src/viewer/index.ts now re-exports from @cyber/viewer - All chat rendering uses upstream viewer ChatPanel with variant/slot system - aiscan-specific features (scan cards, eval badge, agent_joined) via extension registry Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Drop the webproto envelope from the stdio transport: stdin takes a single StdioRequest and stdout is raw AOP JSONL, matching the unified transport direction. Removes the now-unused aop writer and webagent pipeline, and updates web/frontend panels accordingly. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The bespoke pkg/cairnrunner protocol was a functional subset of the existing webagent/webproto protocol. cmd/runner now connects as a tool-only node through webagent.RunToolNode (no LLM provider, agent loop, or IOA dependency); cairn's server absorbs the remaining envelope differences. webproto gains ExecResult (structured exec completion) and an optional stream field on exec output messages, both additive for existing consumers. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Runs RunToolNode against a mock hub speaking the register/connected + exec + file.read dialect the cairn bridge now implements, asserting the handshake identity, streamed exec output/result envelope, base64 file reads, and tool.data call-ID correlation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Lets the agent bound long-running commands explicitly instead of relying solely on the 300s default. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The agent core now emits AOP natively (message/message.delta parts, status+ext for eval/compact/token-budget/llm-request), replacing the private agent.Event model and every boundary converter. stdio becomes a persistent multi-session AOP host; the web hub dispatches user messages as AOP, persists complete message events only, and replays history over SSE; TUI, webagent, scan, and harness consume the raw stream. The frontend reduces AOP directly — legacy chat timeline fallbacks, ChatPayload, ResponseFormat, and the text event type are gone. Also fixes compact/eval events previously emitted without a session id, and stamps per-session seq numbers for replay dedup. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mid-run inbox steering was a TUI-only side channel inconsistent with the one-message-one-Run FIFO semantics of the stdio and web surfaces. Busy input now queues as pendingRun and drains after the current run finishes; Stop cancels the current run and discards the queue. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Chat tasks now close when the run's root session.end arrives instead of the legacy complete/error control frames: the hub learns child sessions from session.start parent_session_id so sub-agent ends are not terminal, AOP error events stay display-only, and a canceled stop carrying the ctx error closes cleanly. The webagent no longer sends a complete frame after Run; eval mode keeps its control frames and suppresses its per-round session brackets so N-round evals are not converged early. Closure is idempotent against mixed-version agents that still send complete. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…mantics Cover message_id/part_index stability across streaming retries, input image validation (path/base64/size cap/MIME sniffing), same-session FIFO ordering with cross-session concurrency on the stdio host, and that SSE replay is a pure read with no frames to agents, no task convergence, and no new persisted events. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The hub tsconfig compiles cyber-ui package sources directly; excluding *.test.ts(x) keeps viewer vitest files out of its compilation. The cyber-ui bump brings in the legacy-APG annotations and the AOP reducer test suite. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
阶段总结:架构向 AOP 单一语义载体演进思路aiscan agent 的一切活动(文本流、思考、工具、usage、生命周期、subagent 委派)只由 AOP envelope 承载;stdio / WebSocket / SSE 退化为纯粹的 envelope 搬运工。各层只保留一种做法,演进中产生的并行机制逐一收敛。 架构演进的四个动作1. 协议:AOP 成为唯一事件格式 2. 执行:入口与路径统一 3. 传输:运行时单点化 4. 通知与持久化:事件总线唯一通道 现状事件格式 1 种(AOP)、执行入口 1 个、通知通道 1 条、REPL 1 条路径—— |
Summary
Depends on chainreactors/cyber-ui#4.
Validation
pm run build in web/frontend
Generated web/static assets and unrelated local worktree changes are intentionally excluded.