Skip to content

feat(aop): unify agent transport end to end#62

Open
M09Ic wants to merge 40 commits into
masterfrom
feat/aop-single-transport
Open

feat(aop): unify agent transport end to end#62
M09Ic wants to merge 40 commits into
masterfrom
feat/aop-single-transport

Conversation

@M09Ic

@M09Ic M09Ic commented Jul 19, 2026

Copy link
Copy Markdown
Contributor

Summary

  • make AOP the only aiscan agent activity transport; remove ChatEvent text/thinking/tool mappings and legacy SSE event types
  • remove protocol version fields and negotiation from the AOP envelope
  • persist raw AOP envelopes and replay them as named �vent: aop SSE frames
  • render text streaming, thinking, tool calls/results, usage, errors, and lifecycle directly through cyber-ui
  • retain only product-domain events such as scan/eval/compact outside AOP

Depends on chainreactors/cyber-ui#4.

Validation

  • go test ./pkg/aop ./pkg/web

pm run build in web/frontend

Generated web/static assets and unrelated local worktree changes are intentionally excluded.

M09Ic and others added 30 commits July 18, 2026 08:37
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>
M09Ic and others added 10 commits July 22, 2026 00:24
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>
@M09Ic

M09Ic commented Jul 22, 2026

Copy link
Copy Markdown
Contributor Author

阶段总结:架构向 AOP 单一语义载体演进

思路

aiscan agent 的一切活动(文本流、思考、工具、usage、生命周期、subagent 委派)只由 AOP envelope 承载;stdio / WebSocket / SSE 退化为纯粹的 envelope 搬运工。各层只保留一种做法,演进中产生的并行机制逐一收敛。

架构演进的四个动作

1. 协议:AOP 成为唯一事件格式
移除 ChatEvent 的 text/thinking/tool 映射、legacy SSE 类型与版本协商。cyber-ui agent-protocol schema 拆分为 events/ext/types,Go 与 TS 双端 codegen——schema 是协议的唯一事实源,扩展经 x/<ns> 强类型包访问。

2. 执行:入口与路径统一
agent.ExecuteInbound 成为 LLM 执行的唯一入口,stdio host、webagent chat、runtime session 全部走它;stdio 接受 plain request、流式输出 raw AOP,harness 直接复用这条生产路径做测试。

3. 传输:运行时单点化
core/transport 单点选择 transport;runner 从独立 cairnrunner 变为 webagent tool-only 节点;PTY 统一 canonical frames。AgentRuntime 成为唯一的运行时所有者:per-session FIFO 会话、常驻 main REPL(本地/远端同一路由器)、断线重连。

4. 通知与持久化:事件总线唯一通道
subagent handoff 从专用 hook 改为 AOP 总线订阅器(delegation ext / session.end 驱动),输出 IOA native 消息并以 Refs 串线程;会话历史持久化 raw envelope、SSE 原样回放,chat task 收敛由根 session.end 驱动。

现状

事件格式 1 种(AOP)、执行入口 1 个、通知通道 1 条、REPL 1 条路径——go build/vet 干净,go test ./... 与前端 tsc && vite build 全绿。依赖 cyber-ui 93b348d(对应 chainreactors/cyber-ui#4)。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant