♻️ refactor: plugin-first 架构重构与工具表面精简#26
Merged
whatevertogo merged 10 commits intomasterfrom Apr 24, 2026
Merged
Conversation
…nel/sdk crate,建立 host-session / agent-runtime / plugin-host 三层 删除 kernel、sdk、application 三个 crate,将编排逻辑下沉至 server 组合根, 核心状态管理抽入新 host-session crate,turn loop 重构为独立 agent-runtime, 插件系统由 plugin-host 全部重写,替换旧 plugin crate。 core - 抽走 session_catalog / session_plan / workflow / projection / composer 到 host-session - 抽走 plugin/manifest、plugin/registry、projection 到对应新 crate - 新增 max_output_continuation_attempts 配置项(修复 max_consecutive_failures 误用为 continuation 限制的 bug) - 新增 prompt.rs 承接 system prompt 类型 session-runtime → agent-runtime - 重命名 crate,turn loop 由单一 TurnLoop struct 驱动 - 新增 TurnExecutionResources / TurnExecutionContext 分离无状态资源与可变状态 - 新增 hook_dispatch / tool_dispatch 抽象层 - output continuation 现由独立配置控制(默认 3 次,下限 1) application → server - 会话路由、terminal projection、conversation read model 全部迁入 server - HTTP 路由直接对接 session_catalog / agent_control_registry,不再经过 application 中间层 - 新增 AgentControlRegistry 管理代理树深度与并发限制 - 新增 session_runtime_port_adapter 适配 agent-runtime 接口 - 各 bootstrap 模块(capabilities、governance、plugins、providers)重写为直接组装 plugin → plugin-host - 全新插件生命周期:descriptor → backend plan → process spawn → negotiate → runtime catalog - 支持 builtin / external-process / http 三种 backend - 新增 descriptor / registry / snapshot / transport / host_dispatch 完整子系统 删除 - kernel crate(agent_tree、registry、gateway、surface 全部移入 server) - sdk crate(context、stream、hook、tool 迁入 plugin-host 或删除) - application crate(lib、session_use_cases、terminal、workflow 迁入 server) - plugin crate(loader、invoker、peer、supervisor 由 plugin-host 替代) - examples/example-plugin、examples/plugins/repo-inspector - session-runtime 大部分模块(actor、turn、state、query 由 agent-runtime + host-session 替代) docs / infra - PROJECT_ARCHITECTURE.md、AGENTS.md、CLAUDE.md 同步更新 - check-crate-boundaries.mjs 适配新 crate 图 - openspec 新增 plugin-first-runtime-rearchitecture change,归档旧 changes tests - agent-runtime loop:16 tests(含 continuation limit 回归测试) - adapter-llm dto:3 tests(OpenAI 消息序列化边界) - server mode compiler:3 tests(含 child fork mode 降级) - plugin-host:新增 host_tests.rs(3498 行覆盖 backend / registry / transport)
…被重试的问题 crates/adapter-llm/src/openai.rs - 将 SSE 流解码错误(is_decode)纳入可重试错误条件,避免 decode 失败直接终止流 crates/server/src/mode_catalog_service.rs - 新增 bound_tool_contract_snapshot 方法,按 mode_id 查询绑定工具合约快照 crates/server/src/session_runtime_port_adapter.rs - 将 RouterToolDispatcher 中 mode/contract 快照从不可变字段改为 Mutex 保护的 RuntimeModeToolState, 使 mode 切换时 tool dispatcher 能实时获取最新 contract - RuntimeToolEventSink 在 ModeChanged 事件时校验 from 与当前 runtime mode 一致性, 并自动刷新 bound_tool_contract_snapshot - 新增 enterPlanMode → upsertSessionPlan → exitPlanMode 全链路集成测试
…刷新选择逻辑 crates/server/src/mcp/mod.rs - 删除未使用的 McpServerStatusView/McpServerStatusSummary/McpActionSummary/McpPort/McpService(消除 7 个 dead_code warning) crates/server/src/session_runtime_port_adapter.rs - 新增从 plan 模式 exit→code→reenter plan 的完整集成测试,覆盖 review-pending 两步退出和二次进入 frontend/src/hooks/app/useSessionCoordinator.ts - 将 session 刷新的目标选择逻辑提取为独立函数 resolveRefreshTargetSelection - 新增 pendingPreferredSessionIdRef 跟踪跨刷新周期待激活的 session,避免因异步竞态丢失用户选择 - 清理 activateSession/reset 时的 pending 状态 frontend/src/hooks/app/useSessionCoordinator.test.ts - 新增 resolveRefreshTargetSelection 单元测试(pending preferred 优先、保留 active subRun path) frontend/src/hooks/useAgent.ts - 为 JSON.parse 结果添加 unknown 类型注解(类型安全) frontend/src/lib/api/conversation.ts - 格式化长行(isApprovalLikeTurnText、buildTurnProjectionFlags 签名) frontend/src/components/Chat/*.test.tsx, frontend/src/lib/subRunView.test.ts - 清理尾部空行、格式化 path 字符串
将运行时和治理链路中与死代码、仅测试入口相关的 `allow(dead_code)` 与未使用辅助实现下调为测试范围或移除, 同步删除 `composer_skill` 端口定义文件并清理不再需要的治理面诊断/校验方法,保持主行为接口更小更清晰。 Constraint: 仅进行行为等价前提下的清理,不引入新依赖或 API 改造 Rejected: 保留陈旧未用项 | 会持续放大误报与后续维护负担 Confidence: high Scope-risk: narrow Tested: cargo check -p astrcode-server --all-features Not-tested: 未做完整端到端回归和 UI 手工回归
从 core 中拆出 5 个窄领域契约 crate(prompt-contract、governance-contract、 tool-contract、llm-contract、runtime-contract),从 agent-runtime 中拆出 context-window crate。core 只保留稳定值对象和事件模型,不再承载工具/LLM/ 治理/运行时边界 trait。所有 adapter、owner、server 调用点已迁移至新 crate 导入路径,core 旧 re-export 标记为 #[doc(hidden)] 以引导新代码使用契约层。 同时新增 HTTP 插件 backend 支持,更新 crate 边界检查规则与架构文档。
移除 listDir 工具(由 shell ls/dir 替代),简化 editFile(移除批量 edits 数组), 简化 shell(移除 shell override 参数),增强 grep(新增 literal 模式、参数别名归一化、 默认输出改为 files_with_matches),增强 readFile(charOffset 分页支持持久化结果)。 capability_prompt 不再为 plan 工具生成详细指南块,仅保留摘要行, enterPlanMode 摘要引导 LLM 在复杂任务时主动使用。 tool-summary 块增加工具选择导航,移除逐工具 caveat 拼接。 OpenAI provider 新增 builtin_tool_rank 确定序排列工具 schema, 避免跨 turn 工具顺序抖动导致 KV 缓存失效。
regressions.mjs 引用了重构后已删除的 astrcode-session-runtime 和 astrcode-plugin crate,改为锚定 agent-runtime 和 adapter-prompt 中 的等价测试。重新生成 crates-dependency-graph.md。
deny.toml 的 tokio wrappers 列表包含已删除的 crate(application、 kernel、plugin、session-runtime),缺少新 crate(tool-contract、 agent-runtime、host-session、governance-contract 等)。 eval runner 测试超时从 3s 调整为 10s 以适应 CI 慢环境。
core_end_to_end 测试的 mock server 在 fixture 文件不存在时 panic, CI 环境下偶发失败。改为返回占位文本让测试继续执行,由最终 report 断言统一判定通过/失败。
Contributor
There was a problem hiding this comment.
Pull request overview
Note
Copilot was unable to run its full agentic suite in this review.
This PR migrates Astrcode to a plugin-first architecture (host-session / agent-runtime / plugin-host), while slimming the exposed tool surface and improving prompt/KV-cache stability.
Changes:
- Removed the legacy
applicationcrate (workflows, terminal queries, MCP/watch services, and ports) as part of the new layering. - Introduced
astrcode-agent-runtimeplus new contract crates, and updated adapters to depend on the new contracts/host-session types. - Updated tool/prompt surfaces: removed
listDir, simplifiedshell/prompt guides, and adjusted built-in agent/tool lists + docs.
Reviewed changes
Copilot reviewed 120 out of 506 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| crates/application/src/workflow/orchestrator.rs | Removed legacy workflow orchestration entrypoint |
| crates/application/src/workflow/mod.rs | Removed workflow module exports |
| crates/application/src/workflow/definition.rs | Removed builtin workflow definitions |
| crates/application/src/workflow/compiler.rs | Removed workflow definition compiler/validator |
| crates/application/src/workflow/bridge.rs | Removed plan→execute typed bridge |
| crates/application/src/watch/mod.rs | Removed file watching use-case service |
| crates/application/src/terminal_queries/summary.rs | Removed terminal summary query logic |
| crates/application/src/terminal_queries/snapshot.rs | Removed terminal snapshot query logic |
| crates/application/src/terminal_queries/resume.rs | Removed resume/slash-candidate queries |
| crates/application/src/terminal_queries/mod.rs | Removed terminal query subdomain module |
| crates/application/src/terminal_queries/cursor.rs | Removed cursor validation utilities |
| crates/application/src/terminal/stream_projection.rs | Removed terminal stream projector wrapper |
| crates/application/src/terminal/mod.rs | Removed terminal facts/contracts and summarizers |
| crates/application/src/terminal/contracts.rs | Removed terminal contract DTOs |
| crates/application/src/session_identity.rs | Removed application session-id normalization shim |
| crates/application/src/ports/session_submission.rs | Removed app→session submission DTO bridge |
| crates/application/src/ports/session_contracts.rs | Removed app-owned session orchestration contracts |
| crates/application/src/ports/composer_skill.rs | Removed composer skill port trait |
| crates/application/src/ports/app_session.rs | Removed app session-runtime port facade |
| crates/application/src/ports/app_kernel.rs | Removed app kernel port facade |
| crates/application/src/ports/agent_session.rs | Removed agent-session port facade |
| crates/application/src/ports/agent_kernel.rs | Removed agent-kernel port facade |
| crates/application/src/mcp/mod.rs | Removed application MCP management use-cases |
| crates/application/src/execution/root.rs | Removed legacy root agent execution entrypoint |
| crates/application/src/composer/mod.rs | Removed legacy composer options service |
| crates/application/src/agent_use_cases.rs | Removed legacy agent control use-cases |
| crates/application/Cargo.toml | Removed astrcode-application crate manifest |
| crates/agent-runtime/src/types.rs | Added runtime turn input/output + execution surface DTOs |
| crates/agent-runtime/src/tool_dispatch.rs | Added runtime→plugin-host tool dispatch trait & request |
| crates/agent-runtime/src/stream.rs | Added provider streaming skeleton |
| crates/agent-runtime/src/runtime.rs | Added minimal runtime entrypoint driving TurnLoop |
| crates/agent-runtime/src/provider.rs | Added provider abstraction types (usage/events/limits) |
| crates/agent-runtime/src/lib.rs | Added agent-runtime crate module surface + re-exports |
| crates/agent-runtime/src/hook_dispatch.rs | Added runtime→plugin-host hook dispatch trait & types |
| crates/agent-runtime/src/context_window/tool_results.rs | Minor comment/doc cleanup in tool result name mapping |
| crates/agent-runtime/src/context_window/token_usage.rs | Added request token estimation + compaction thresholds |
| crates/agent-runtime/src/context_window/settings.rs | Added runtime context-window settings adapter |
| crates/agent-runtime/src/context_window/request.rs | Added request assembly + compaction/tool-budget pipeline |
| crates/agent-runtime/src/context_window/prune_pass.rs | Added prune pass (truncate/clear old tool results) |
| crates/agent-runtime/src/context_window/mod.rs | Added context-window module wiring/re-exports |
| crates/agent-runtime/src/context_window/micro_compact.rs | Added idle-gap micro-compaction for tool results |
| crates/agent-runtime/src/context_window/file_access.rs | Adjusted file-access tracker helper formatting; removed tests |
| crates/agent-runtime/src/context_window/compaction/sanitize.rs | Fixed whitespace collapse call to use module-qualified helper |
| crates/agent-runtime/src/context_window/compaction/protocol.rs | Refactored helpers and moved persisted-output helpers to core |
| crates/agent-runtime/src/context_window/compaction.rs | Refactored compaction to depend on llm-contract provider surface |
| crates/agent-runtime/src/cancel.rs | Added cancellation skeleton (placeholder) |
| crates/agent-runtime/Cargo.toml | Added new astrcode-agent-runtime crate manifest |
| crates/adapter-tools/src/test_support.rs | Switched ToolContext import to tool-contract |
| crates/adapter-tools/src/lib.rs | Updated docs for tool-contract + removed listDir mention |
| crates/adapter-tools/src/builtin_tools/write_file.rs | Switched to tool-contract types; prompt text tightened |
| crates/adapter-tools/src/builtin_tools/upsert_session_plan.rs | Moved plan/session types to host-session/governance/tool-contract |
| crates/adapter-tools/src/builtin_tools/tool_search.rs | Switched to tool-contract types |
| crates/adapter-tools/src/builtin_tools/task_write.rs | Switched Tool* types to tool-contract |
| crates/adapter-tools/src/builtin_tools/skill_tool.rs | Switched Tool* types to tool-contract |
| crates/adapter-tools/src/builtin_tools/shell.rs | Removed shell override input; updated prompts/tests accordingly |
| crates/adapter-tools/src/builtin_tools/session_plan.rs | Moved plan/workflow types to host-session; ToolContext to tool-contract |
| crates/adapter-tools/src/builtin_tools/mode_transition.rs | ModeId moved to governance-contract; emitted event uses stored ModeId |
| crates/adapter-tools/src/builtin_tools/mod.rs | Removed listDir module; docs reference tool-contract |
| crates/adapter-tools/src/builtin_tools/fs_common.rs | Switched ToolContext import to tool-contract |
| crates/adapter-tools/src/builtin_tools/find_files.rs | Updated defaults/docs and switched to tool-contract types |
| crates/adapter-tools/src/builtin_tools/exit_plan_mode.rs | Mode/tool contracts moved; prompt surface updated |
| crates/adapter-tools/src/builtin_tools/enter_plan_mode.rs | Mode/tool contracts moved; prompt surface updated |
| crates/adapter-tools/src/builtin_tools/apply_patch.rs | Switched to tool-contract types; prompt text trimmed |
| crates/adapter-tools/src/agent_tools/tests.rs | SubAgentExecutor moved to host-session; Tool* imports to tool-contract |
| crates/adapter-tools/src/agent_tools/spawn_tool.rs | SubAgentExecutor moved to host-session; Tool* imports to tool-contract |
| crates/adapter-tools/src/agent_tools/send_tool.rs | Tool* imports to tool-contract |
| crates/adapter-tools/src/agent_tools/result_mapping.rs | ToolExecutionResult moved to tool-contract |
| crates/adapter-tools/src/agent_tools/observe_tool.rs | Tool* imports to tool-contract |
| crates/adapter-tools/src/agent_tools/collaboration_executor.rs | CollaborationExecutor moved from core to host-session |
| crates/adapter-tools/src/agent_tools/collab_result_mapping.rs | ToolExecutionResult moved to tool-contract |
| crates/adapter-tools/src/agent_tools/close_tool.rs | Tool* imports to tool-contract |
| crates/adapter-tools/Cargo.toml | Added dependencies on host-session/governance/tool-contract |
| crates/adapter-storage/src/session/repository.rs | Moved EventStore/recovery types to host-session |
| crates/adapter-storage/src/session/checkpoint.rs | Moved recovery types to host-session |
| crates/adapter-storage/src/session/batch_appender.rs | Moved SessionRecoveryCheckpoint to host-session |
| crates/adapter-storage/Cargo.toml | Added dependency on host-session |
| crates/adapter-skills/src/builtin_skills/mod.rs | Removed listDir from allowed tools (breaking tool-surface change) |
| crates/adapter-prompt/src/prompt_declaration.rs | Moved PromptDeclaration types to prompt-contract |
| crates/adapter-prompt/src/plan.rs | ToolDefinition moved to tool-contract |
| crates/adapter-prompt/src/layered_builder.rs | Prompt cache types moved to prompt-contract |
| crates/adapter-prompt/src/core_port.rs | Prompt provider port types moved to host-session + contracts |
| crates/adapter-prompt/src/contributors/workflow_examples.rs | Updated guidance to mention shell for directory inspection |
| crates/adapter-prompt/src/contributors/capability_prompt.rs | Switched default tool guides to summary-only (except discovery/collab) |
| crates/adapter-prompt/src/contribution.rs | ToolDefinition moved to tool-contract |
| crates/adapter-prompt/src/composer.rs | PromptCacheHints moved to prompt-contract |
| crates/adapter-prompt/src/block.rs | SystemPromptLayer moved to prompt-contract |
| crates/adapter-prompt/Cargo.toml | Added dependencies on host-session/governance/prompt/tool contracts |
| crates/adapter-mcp/src/manager/surface.rs | PromptDeclaration moved to prompt-contract |
| crates/adapter-mcp/src/manager/reconnect.rs | Tightened test-only helpers with #[cfg(test)] |
| crates/adapter-mcp/src/manager/mod.rs | PromptDeclaration moved to prompt-contract; ManagedRuntimeComponent to runtime-contract |
| crates/adapter-mcp/src/core_port.rs | ResourceProvider moved to plugin-host |
| crates/adapter-mcp/src/bridge/prompt_bridge.rs | Prompt layer/types moved to prompt-contract |
| crates/adapter-mcp/Cargo.toml | Replaced adapter-prompt dep with prompt/runtime/plugin-host contracts |
| crates/adapter-llm/src/openai/responses.rs | SystemPromptBlock moved to governance-contract |
| crates/adapter-llm/src/openai/dto.rs | LlmUsage moved to llm-contract; added serialization tests |
| crates/adapter-llm/src/lib.rs | LlmEvent + PromptCache* types moved to llm-contract |
| crates/adapter-llm/src/cache_tracker.rs | Prompt cache diagnostics types moved to llm-contract |
| crates/adapter-llm/Cargo.toml | Added dependencies on governance/llm/prompt contracts |
| crates/adapter-agents/src/builtin_agents/explore.md | Updated tool list to replace listDir with shell |
| README.md | Updated tool list + config docs (added continuation attempts) |
| Cargo.toml | Workspace membership rewritten for plugin-first crates/contracts |
| CLAUDE.md | Updated Rust naming/design guidelines |
| AGENTS.md | Updated Rust naming/design guidelines |
Comments suppressed due to low confidence (1)
crates/agent-runtime/src/context_window/compaction.rs:554
instructions_presentis always recorded asfalse, which makesCompactAppliedMetainaccurate whenCompactConfig.custom_instructionsis provided (and can affect telemetry/debugging and any downstream behavior keyed on this meta). Use theCompactConfigargument to computeinstructions_present(e.g.,custom_instructions.is_some_and(|v| !v.trim().is_empty())) instead of ignoring it.
meta: CompactAppliedMeta {
mode: prepared_input
.prompt_mode
.compact_mode(retry_state.salvage_attempts),
instructions_present: false,
fallback_used: parsed_output.used_fallback || retry_state.salvage_attempts > 0,
retry_count: retry_state.salvage_attempts.min(u32::MAX as usize) as u32,
input_units: prepared_input.input_units.min(u32::MAX as usize) as u32,
output_summary_chars,
},
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+1
to
+5
| pub(crate) use astrcode_context_window::{ | ||
| ContextWindowSettings, compaction, file_access, micro_compact, token_usage, tool_result_budget, | ||
| }; | ||
|
|
||
| pub(crate) mod request; |
Comment on lines
+94
to
+99
| if user_turn_indices.is_empty() { | ||
| return messages.len(); | ||
| } | ||
|
|
||
| let keep_turns = requested_recent_turns.min(user_turn_indices.len()).max(1); | ||
| user_turn_indices[user_turn_indices.len() - keep_turns] |
| killed; only output produced so far is returned. If quoting issues, set \ | ||
| `shell` explicitly to pwsh/cmd/wsl/sh.", | ||
| "Single shot only: no stdin and no interactive prompts. Use `cwd` instead of \ | ||
| `cd &&`; set `shell` explicitly only for quoting or shell-family issues.", |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
一、PR 概述
将 Astrcode 从 application/kernel/sdk 三层架构重构为 host-session / agent-runtime / plugin-host 三层 plugin-first 架构,同时精简工具表面、优化 KV 缓存稳定性和提示词效率。
二、背景 / 动机
三、改动内容
架构重构
工具表面精简
提示词优化
always_include死代码KV 缓存优化
其他
#[doc(hidden)]标注改动类型:
四、实现说明
node scripts/check-crate-boundaries.mjs --strict通过五、行为变化(对外影响)
六、测试与验证
自测结果:
测试命令:
cargo test --workspace --exclude astrcode --lib cargo clippy --all-targets --all-features -- -D warnings node scripts/check-crate-boundaries.mjs --strict七、文件变更统计
主要涉及 crate:adapter-tools, adapter-prompt, adapter-llm, adapter-agents, agent-runtime, host-session, plugin-host, governance-contract, server, context-window