Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions .cargo/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,5 @@ linker = "arm-linux-gnueabihf-gcc"
ar = "arm-linux-gnueabihf-ar"
# Point to the Linaro toolchain sysroot
# CARGO_CFG_* are set via environment variables

[build]
# Disable cross-compile warnings as errors
rustflags = ["-C", "target-feature=-crt-static"]
153 changes: 153 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ members = [
"peri-resources",
"peri-runtime",
"peri-tui",
"peri-turn-policy",
"langfuse-client",
"peri-lsp",
"peri-js-runtime",
"peri-web-pty",
"peri-workflow",
"peri-wasi",
]
resolver = "2"

Expand Down Expand Up @@ -84,6 +86,7 @@ lru = "0.18"

# --- Build ---
tempfile = "3"
wit-bindgen = { version = "=0.57.1", default-features = false, features = ["macros"] }

# --- Allocator ---
tikv-jemallocator = "0.6"
Expand Down
5 changes: 3 additions & 2 deletions docs/code-index/peri-acp-types.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
# peri-acp-types 代码索引

> 速查表:把「我想做什么」映射到文件。细节以代码为准。更新:2026-08-16
> 速查表:把「我想做什么」映射到文件。细节以代码为准。更新:2026-08-29(MessageContent 判空共享 policy)
> 依据:peri-acp-types/src/lib.rs、docs/standards/architecture-contracts.md、源码(本 crate 无 CLAUDE.md)

## 架构速览

- 定位:契约类型层(type contract layer between layers)——被 peri-agent、peri-acp、peri-middlewares、peri-runtime、peri-tui、peri-workflow、peri-lsp、peri-controller、peri-resources 共同依赖(各 Cargo.toml 均声明 `peri-acp-types`);只定义类型/枚举/trait,不含执行逻辑(cancel 判定函数除外,是纯函数)
- 事实源矩阵(本层定义、他层 re-export 或消费):`identity`(AgentId/EventEnvelope/CancelRequest)、`event_v2`(三层事件 + `*_event_to_executor`)、`compact`(CompactConfig/CompactOutcome)、`tools`(BaseTool)、`session`(TurnId/MessageQueue/AgentRuntime)、`messages`(BaseMessage/MessageContent)
- portable seam:`MessageContent` 类型与投影仍属于本 crate;`is_empty` 的纯判定委托 dependency-free `peri-turn-policy`,供 native 与 `peri-wasi` 共用,不把 WIT 类型带入契约层
- 消费方式:peri-agent 大量 re-export(`src/agent/events_v2.rs:9`、`src/tools/mod.rs:8`、`src/agent/compact_v2/config.rs:8`、`src/session/turn.rs:17`、`src/messages/mod.rs:7`、`src/error.rs:6`);peri-acp 消费事件映射与 cancel(`src/event/mod.rs:31`、`src/host/prompt_handle.rs:20`);controller/runtime 直连 identity(`peri-controller/src/controller.rs:27`、`peri-runtime/src/runtime.rs:17`)
- 稳定不变量:身份三元组 + epoch/attempt 不可复用(防迟到消息命中新实例);`SessionSeq` 单调且**不实现 Default**(缺失必须显式 `Option`);v2 事件强制携带 `turn_id` + `agent_id`;v1 `ExecutorEvent` 仅作协议序列化面载体,发射统一 v2(ARC-EVENT-001)

Expand All @@ -18,7 +19,7 @@
| 改 BaseTool trait / is_direct 默认值 | `src/tools.rs`(trait 事实源;`peri-agent/src/tools/mod.rs:8` re-export;实现方在 peri-middlewares 各工具) | `BaseTool`(:146);`is_direct`(:199,默认 **false** = deferred);`context_retention`(:193,默认 `Preserve`);`timeout`(:170,默认 120s);`definition`(:152 组合 name/desc/params);`derive_title_from_name`(:70) | 默认值即行为契约:新工具不覆写 `is_direct` 即为 deferred(经 SearchExtraTools 发现);`context_retention` 默认 Preserve = 不被压缩;`ToolContext`(:129)只读借用 state,工具不可绕过 dispatch 统一写入 |
| 改 CancelRequest 三元组 | `src/identity.rs`(`CancelRequest` 事实源 :262;`CancelPolicy` 事实源 `src/thread/types.rs:17`) | `CancelRequest::new(identity, policy)`(:273,clear_queue 默认 **false**);`with_clear_queue`(:282);`AttemptIdentity`(:140,四元组) | 定位四元组 (session_id, session_epoch, turn_id, attempt_id),**幂等判定取三元组** (session_id, turn_id, attempt_id);epoch 不可复用(`SessionEpoch::next` :70 只增);cancel ≠ 清除待办;消费方仅传递不解释语义:controller `cancel`(controller.rs:336)、runtime `cancel`(runtime.rs:169)、`RuntimePort::cancel`(`src/runtime.rs:85`)、prompt_handle(peri-acp:20 / peri-agent:23) |
| 改 v2 事件枚举 / `*_event_to_executor` 映射 | `src/event_v2.rs`(三层事件唯一事实源):`RenderEvent` :87、`StateEvent` :204、`ObserveEvent` :278、`Event` :492、`EventBus` :526、`EventHandles` :617 | 发射:`emit_render`(:584,try_send 满时丢弃)、`emit_state`(:592)、`emit_observe`(:601,broadcast 慢消费者 lagging);映射:`render_event_to_executor` :666、`state_event_to_executor` :745、`observe_event_to_executor` :776 | 三层通道契约:render/state = 有界 mpsc critical,observe = 无界 broadcast;映射为**穷尽匹配**返回 `Option<ExecutorEvent>`,无 v1 等价物显式返回 None(如 HitlPending,走独立审批通道);TextChunk/ThinkingChunk 用消息级 `message_id`(:677),ToolStart/ToolEnd 用 turn_id 派生(:698/:712);禁止 wildcard 兜底 |
| 改 MessageContent 判空(is_empty) | `src/messages/content.rs`(`MessageContent` :330;`peri-agent/src/messages/mod.rs:7` re-export) | `is_empty`(:399);`text_content`(:356);`content_blocks`(:378);`has_tool_use`(:408);`strip_system_reminders`(:469) | 判空按变体:`Text(s) => s.is_empty()`(**不 trim**——纯空白字符串不算空)、`Blocks/Raw` 判 vec 空;消费方(如 peri-agent `is_keepgoing`)须用本函数判空,禁止 trim 替代 |
| 改 MessageContent 判空(is_empty) | `src/messages/content.rs`(`MessageContent` 事实源;`peri-agent/src/messages/mod.rs` re-export)+ `peri-turn-policy/src/content.rs`(纯判定) | `MessageContent::is_empty` 投影为 `MessageContentShape` 后调用 `is_message_content_empty`;同文件 `text_content``content_blocks``has_tool_use``strip_system_reminders` | 类型投影按变体传递 text 借用或 blocks/raw 长度;共享判定仍是 `Text(s) => s.is_empty()`(**不 trim**——纯空白字符串不算空)、`Blocks/Raw` 长度为 0。消费方(如 peri-agent `is_keepgoing`)须用本函数,禁止 trim 或在 WASI adapter 复制策略 |
| 改 AgentId/TurnId 身份类型 | `src/identity.rs` + `src/session.rs` | `AgentId`(identity.rs:18,UUID v7:`new` :22、`from_uuid` :27、`TryFrom<String>` :42);`TurnId`(session.rs:58,`new` :61、`as_uuid` :65);`SessionEpoch`(:60,initial=1);`AttemptId`(:90);`SessionSeq`(:173);`EventEnvelope`(:215) | 全部基于 uuid v7(时间有序);身份构造必须经显式构造器(`SessionSeq` 不实现 `Default`,缺失用 `Option`);`EventEnvelope` 身份字段(turn_id/agent_id)由事件源填充、session_id 由 Runtime 聚合补打(:216 注释),mapper 不得临时补齐 |
| 加 v2 事件变体(全链路) | `src/event_v2.rs`(定义 + 映射)→ `peri-agent`(EventBus emit)→ `peri-acp/src/event/`(forwarder :106/118/142 消费)→ TUI | 枚举变体 + 对应 `*_event_to_executor` 分支 + `turn_id()`/`agent_id()` 提取 impl(如 StateEvent :251、ObserveEvent :446) | 新变体必须:强制携带 turn_id+agent_id、显式映射结果或过滤理由(穷尽匹配编译期强制)、覆盖 ACP 转发与客户端消费;终止事件必须使客户端离开 loading(ARC-EVENT-001) |
| 改 cancel 判定 / AgentRuntime 注册表 | `src/session.rs` | `AgentRuntime`(:552,thread_id + cancel_token + policy + status);`cancel_cascade_agents`(:573,仅 Cascade 取消);`cancel_all_agents`(:582,全部取消);`cancel_cascade_in`/`cancel_all_in`(:589/:598,HashMap 注册表版) | 判定是纯函数、无层依赖;Independent(bg)子 agent 不随父取消,仅随 session 根取消;`AgentStatus` 事实源 thread/types.rs:56 |
Expand Down
9 changes: 5 additions & 4 deletions docs/code-index/peri-agent.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
# peri-agent 代码索引

> 速查表:把「我想做什么」映射到文件。细节以代码为准。更新:2026-08-25(完整 frozen snapshot 贯穿 production stage
> 速查表:把「我想做什么」映射到文件。细节以代码为准。更新:2026-08-29(compact selector 共享 policy
> 依据:peri-agent/CLAUDE.md、docs/standards/architecture-contracts.md、源码

## 架构速览

- 数据流:`MessageQueue → Receive → Compact → Reason → Act → MessageQueue`
- 循环入口:`src/agent/stages/mod.rs:612` 的 `run_react_loop(StageContext, max_iterations) -> LoopResult`;Receive 是唯一退出口 + keepgoing 判定点
- 稳定不变量:`FrozenContext` 会话内不可漂移(ARC-FROZEN-001);`BaseTool::is_direct()` 是工具可见性事实源(ARC-TOOLS-001);`CompactConfig` 是 compact 阈值唯一事实源;中间件链序蓝本 `production_blueprint`(ARC-MIDDLEWARE-001)
- 稳定不变量:`FrozenContext` 会话内不可漂移(ARC-FROZEN-001);`BaseTool::is_direct()` 是工具可见性事实源(ARC-TOOLS-001);`CompactConfig` 是 compact 阈值唯一事实源,纯 Skip/Micro/Smart selector 委托 `peri-turn-policy`;中间件链序蓝本 `production_blueprint`(ARC-MIDDLEWARE-001)

## 速查表

| 我想做什么 | 主文件 | 入口/关键函数 | 关键逻辑 |
| --- | --- | --- | --- |
| 改 compact 触发阈值 | `peri-acp-types/src/compact.rs`(`CompactConfig` 事实源,`apply_env_overrides` 实现在 :325;`peri-agent/src/agent/compact_v2/config.rs` 仅 re-export;`peri-acp/src/host/compact_config.rs` 是配置加载调用方) | `CompactConfig` 字段:`auto_compact_threshold`(默认 0.95)、`micro_compact_threshold`(默认 0.75)、`smart_compact_enabled`(废弃恒 false) | budget < 0.75 跳过;≥ 0.75 走 Micro;Micro 收益不足且 budget ≥ auto_compact_threshold 时升级 Full;force=true 直接 Full。注意:调低 Full 阈值时 micro_compact_threshold 必须更低,否则先走 Skip |
| 改 compact 策略选择 | `src/agent/compact_v2/mod.rs` + `src/agent/stages/compact.rs` | `determine_compact_action(budget, config)`(mod.rs:102,Skip/Micro/Smart 选择);`run_compact`(mod.rs:125 编排,Full 升级判定在 :233);阶段入口 `stages/compact.rs::run_compact` | Full 升级判定以代码为准:`budget >= config.auto_compact_threshold` + `llm.is_none()` 守卫 + cache-aware 跳过;`planner.rs::CompactPolicy::force_full_threshold` 无消费点(遗留) |
| 改 compact 策略选择 | `src/agent/compact_v2/mod.rs` + `peri-turn-policy/src/compact.rs` + `src/agent/stages/compact.rs` | native 入口 `determine_compact_action(budget, config)` 委托 `select_compact_action`;`CompactAction` 从 shared crate re-export;`run_compact` 负责编排和 Full 升级;阶段入口 `stages/compact.rs::run_compact` | shared selector 保留原生未校验的浮点比较与 Smart 开关语义;`CompactConfig` 仍是阈值事实源。Full 升级判定仍在 Agent:`budget >= config.auto_compact_threshold` + `llm.is_none()` 守卫 + cache-aware 跳过;WASI 的 `[0,1]` 校验和 Smart 禁用不属于 native 路径 |
| 改 Micro/Full 执行细节 | `src/agent/compact_v2/micro.rs` / `full.rs` | `micro_compact`;`re_inject_v2`、`extract_file_info`、`extract_skill_names` | Micro 按 round 截断(`micro_excluded_tools` 黑名单);Full 走 `peri_model::Model` 摘要 + re-inject |
| 改循环退出 / keepgoing 判定 | `src/session/exec/executor.rs` + `src/agent/stages/mod.rs`(Receive 分支) | `executor.rs:130 is_keepgoing(&MessageContent)`;`run_session_loop`(executor.rs:221);`run_react_loop` 退出判断(stages/mod.rs:647 `consumed_count == 0 && !has_tool_calls`);判空底层 `peri-acp-types/src/messages/content.rs::is_empty`(:399) | 空白 prompt 须用 `MessageContent::is_empty()` 判空(禁止 trim 替代);空历史 + 空白 prompt 时短路 `push_done`;keepgoing 不注入 recall;契约 ARC-KEEPGOING-001 |
| 改 turn fatal failure 分类/传递 | `src/session/exec/executor_helpers/v2_execute.rs` + `executor_helpers.rs` + `executor_helpers/collect.rs`;契约 DTO 在 `peri-acp-types/src/session.rs` | `classify_loop_terminal`;`ExecOutcome.failure` → `PromptResult.failure` | transcript flush 后只采样一次 cancel;单一纯分类器同时决定 Prompt stop reason、`TurnEnded`、fatal failure 与 cascade。Completed 为已提交成功;其他非成功结果中 cancel 优先;契约 ARC-EVENT-001 / ARC-CANCEL-001 |
Expand Down Expand Up @@ -43,7 +43,7 @@

| 功能 | 文件 | 入口/关键点 |
| --- | --- | --- |
| 策略选择 + 触发编排 | compact_v2/mod.rs | `determine_compact_action`(:102);`run_compact`(:125);`CompactResult` |
| 策略选择 + 触发编排 | compact_v2/mod.rs + `peri-turn-policy/src/compact.rs` | `determine_compact_action`(保留 native 入口并委托 shared selector);`CompactAction` re-export;`run_compact`;`CompactResult` |
| 压力计算与计划 | compact_v2/planner.rs | `plan_micro`、`ContextPressure`、`CompactPolicy`(force_full_threshold 无消费点) |
| Micro 执行(按 round 截断) | compact_v2/micro.rs | `micro_compact` |
| Smart 执行(废弃中,恒 false) | compact_v2/smart.rs | `smart_compact` |
Expand Down Expand Up @@ -84,3 +84,4 @@
- ARC-TOOLS-001:`is_direct()` 自声明可见性
- ARC-KEEPGOING-001:空白 prompt = 继续跑 loop
- ARC-MIDDLEWARE-001:中间件链序是行为契约,链序蓝本 `production_blueprint`
- WASI policy seam:native compact 的函数路径、Smart 与未校验浮点比较语义保持不变;`peri-wasi` 只消费 shared selector 的受约束 Skip/Micro 子集,不能反向定义 Agent 行为
Loading
Loading