mirror of
https://github.com/Darkatse/TauriTavern.git
synced 2026-10-19 07:35:14 +00:00
277 lines
9.8 KiB
Markdown
277 lines
9.8 KiB
Markdown
# TauriTavern Agent Testing Strategy
|
||
|
||
本文档定义 Agent 系统的测试策略。Agent 涉及生成、文件、工具、外部协议、保存与兼容事件,测试必须持续作为开发入口的一部分。
|
||
|
||
## 1. 测试目标
|
||
|
||
测试要守住:
|
||
|
||
- Legacy Generate 兼容。
|
||
- Clean Architecture 边界。
|
||
- Workspace path 安全。
|
||
- Journal 完整性。
|
||
- Windowed payload 保存契约。
|
||
- LLM gateway 不绕过现有 policy/logging。
|
||
- Tool policy 与 approval。
|
||
- MCP 安全边界。
|
||
- 移动端内存与分页读取。
|
||
|
||
## 2. Domain Tests
|
||
|
||
覆盖:
|
||
|
||
```text
|
||
WorkspacePath normalization
|
||
WorkspacePath traversal rejection
|
||
Artifact manifest validation
|
||
Required artifact missing
|
||
AgentRunStatus transitions
|
||
AgentRunEvent serialization
|
||
PlanPolicy strict/free/hybrid
|
||
ToolPolicy allow/deny/approval
|
||
Profile resolution precedence
|
||
Checkpoint metadata
|
||
```
|
||
|
||
Domain tests 不应需要 Tauri、文件系统或 HTTP。
|
||
|
||
## 3. Application Tests
|
||
|
||
使用 mock repositories/gateway/tools。
|
||
|
||
覆盖:
|
||
|
||
```text
|
||
agent loop success
|
||
agent loop model failure
|
||
cancel before model call
|
||
cancel during model call
|
||
workspace write creates checkpoint
|
||
artifact assembly success/failure
|
||
commit service called through expected boundary
|
||
tool loop success
|
||
tool recoverable error
|
||
tool policy denied
|
||
plan locked node violation
|
||
profile switch allowed/denied
|
||
agent.list policy filtering
|
||
agent.delegate creates task and child invocation
|
||
agent.delegate schedules return-mode child task on background scheduler
|
||
agent.await waits for background child task and renders result capsule
|
||
completed child results are injected into the next parent model turn once
|
||
workspace.finish cancels unfinished child tasks without blocking run completion
|
||
task.return records result and terminates child invocation
|
||
child invocation cannot commit, finish, or delegate
|
||
child workspace view maps semantic summaries/scratch paths and hides physical paths
|
||
```
|
||
|
||
关键断言:
|
||
|
||
- 每个副作用都有 journal event。
|
||
- failure 后状态为 `Failed`。
|
||
- cancel 后状态为 `Cancelled`。
|
||
- required artifact 缺失不 commit。
|
||
|
||
## 4. Infrastructure Tests
|
||
|
||
覆盖:
|
||
|
||
```text
|
||
file event journal append/read pagination
|
||
checkpoint snapshot restore
|
||
workspace repository rejects symlink escape
|
||
workspace repository handles unicode relative paths
|
||
file sizes and retention
|
||
MCP config allowlist
|
||
SkillRepository preview/install/read/export/source refs
|
||
Skill archive roundtrip hash
|
||
Skill repository rejects symlink escape
|
||
```
|
||
|
||
文件测试应使用临时目录,并覆盖 macOS/Linux/Windows path 差异。
|
||
|
||
## 5. LLM Gateway Tests
|
||
|
||
覆盖:
|
||
|
||
```text
|
||
gateway calls ChatCompletionService, not HttpChatCompletionRepository
|
||
source denied by iOS policy
|
||
endpoint override denied
|
||
prompt cache hints preserved
|
||
LLM API log wrapper remains in path
|
||
LLM API log readable output separates visible reasoning from assistant text
|
||
stream chunk becomes model_delta event
|
||
cancel propagates
|
||
tool_call_id opaque round-trip
|
||
native metadata round-trip
|
||
canonical AgentModelRequest/AgentModelResponse encode-decode
|
||
recent workspace write/patch tool result hydration
|
||
tool args/results use short hashed local audit file names while preserving opaque provider tool_call_id
|
||
```
|
||
|
||
特别要覆盖 `docs/CurrentState/NativeApiFormats.md` 中的契约:
|
||
|
||
- tool_call_id 不透明。
|
||
- Claude / Gemini / OpenAI Responses / Gemini Interactions native metadata 保真。
|
||
- Custom Claude header 策略不被硬编码覆盖。
|
||
|
||
## 6. Frontend Contract Tests
|
||
|
||
覆盖:
|
||
|
||
```text
|
||
window.__TAURITAVERN__.api.agent exists after ready
|
||
window.__TAURITAVERN__.api.skill exists after ready
|
||
window.__TAURITAVERN__.api.mcp exists after ready when MCP Host ABI lands
|
||
subscribe returns idempotent unsubscribe
|
||
Agent API uses safeInvoke, not raw command dependency in public caller
|
||
types.d.ts includes agent and skill types; mcp types land with MCP Host ABI
|
||
```
|
||
|
||
Legacy 回归:
|
||
|
||
```text
|
||
Agent mode off: Generate signature unchanged
|
||
Agent mode off: GENERATION_STARTED order unchanged
|
||
Agent mode off: GENERATE_AFTER_DATA dryRun still emitted
|
||
Agent mode off: ToolManager legacy behavior unchanged
|
||
Agent event does not emit fake GENERATION_* events
|
||
```
|
||
|
||
当前 Agent Host ABI 与工具循环必须覆盖:
|
||
|
||
```text
|
||
api.agent exposes startRunFromLegacyGenerate and startRunWithPromptSnapshot
|
||
api.agent does not expose ambiguous startRun alias
|
||
Generate(..., dryRun = true) resolves undefined and emits GENERATE_AFTER_DATA
|
||
startRunFromLegacyGenerate captures dryRun payload through event listener
|
||
agentMode disables Legacy ToolManager tools in prompt snapshot
|
||
external tools/tool_choice/tool turns are rejected
|
||
stream true is rejected
|
||
foreground finish before workspace.commit returns recoverable tool error
|
||
workspace.commit append without prior commit creates the run message
|
||
subscribe polling can read events in seq order
|
||
readWorkspaceFile returns UTF-8 text, chars, words, sha256
|
||
readModelTurn returns assistant text, visible reasoning, tool calls, provider summary
|
||
workspace_list_files accepts omitted/empty/dot path as workspace root
|
||
workspace_search_files searches only visible roots and returns snippets
|
||
workspace_read_file full read records read-state
|
||
workspace_read_file character range does not unlock patch state unless it covers the full file
|
||
workspace_apply_patch requires full read-state and checkpoints on success
|
||
chat deletion removes the corresponding Agent chat workspace and run index
|
||
chat deletion fails clearly while the corresponding Agent workspace has an active run
|
||
skill_search respects visible/deny policy and read budget
|
||
skill_read supports line and character ranges
|
||
recoverable tool errors are returned to the model instead of failing the run
|
||
future APIs approveToolCall/listRuns/readDiff/rollback throw explicitly
|
||
```
|
||
|
||
Provider normalizer tests 必须覆盖可见 reasoning 提取:Claude `thinking`、Gemini `thought` 文本、OpenAI Responses reasoning summary 进入 `reasoning_content`;signature / encrypted continuation 仍作为 native/provider state 保留,不能作为可展示文本。
|
||
|
||
## 7. Windowed Payload Integration Tests
|
||
|
||
覆盖:
|
||
|
||
```text
|
||
Agent reads history through windowed/search APIs
|
||
Agent does not expand UI chat window
|
||
Agent commit uses chat save contract
|
||
Agent commit does not trigger cursor mismatch under serialized saves
|
||
cursor mismatch fails clearly
|
||
force does not bypass cursor signature
|
||
rollback committed message uses save contract
|
||
```
|
||
|
||
## 8. Security Tests
|
||
|
||
覆盖:
|
||
|
||
```text
|
||
../ path rejected
|
||
absolute path rejected
|
||
Windows drive path rejected
|
||
symlink escape rejected
|
||
hidden resource not in context
|
||
denied tool not visible
|
||
denied tool call fails
|
||
MCP arbitrary stdio command rejected
|
||
Agent cannot edit MCP config
|
||
extension tool without authorization hidden
|
||
provider source denied by policy
|
||
```
|
||
|
||
## 9. Performance Tests
|
||
|
||
覆盖:
|
||
|
||
```text
|
||
large chat history remains virtual
|
||
journal pagination does not load full file
|
||
workspace tree lazy read
|
||
checkpoint retention cap
|
||
tool result budget truncation/summary
|
||
mobile default budgets
|
||
```
|
||
|
||
指标建议:
|
||
|
||
- Agent run workspace 初始化耗时。
|
||
- Journal append/read latency。
|
||
- Large history Agent start memory growth。
|
||
- Timeline first render event count。
|
||
|
||
## 10. Golden Fixtures
|
||
|
||
建议建立 fixtures:
|
||
|
||
```text
|
||
fixtures/agent/
|
||
prompt_snapshot_openai.json
|
||
prompt_snapshot_claude.json
|
||
run_events_one_step.jsonl
|
||
manifest_main_only.json
|
||
manifest_multi_artifact.json
|
||
tool_result_chat_search.json
|
||
checkpoint_snapshot/
|
||
```
|
||
|
||
Golden fixtures 应尽量脱敏,不包含真实 API key 或私人聊天。
|
||
|
||
## 11. Merge Gates
|
||
|
||
当前落地门禁:
|
||
|
||
- 后端 `cargo check --manifest-path src-tauri/Cargo.toml` 通过。
|
||
- 后端 `cargo test --manifest-path src-tauri/Cargo.toml agent_runtime_service` 通过。
|
||
- 后端 `cargo test --manifest-path src-tauri/Cargo.toml file_agent_repository` 通过。
|
||
- 后端 `cargo test --manifest-path src-tauri/Cargo.toml file_agent_profile_repository` 通过。
|
||
- 涉及前端 ABI 时,前端 `pnpm run check:types`、`pnpm run check:contracts`、`pnpm run check:frontend` 通过。
|
||
- 控制台 smoke 能通过 `startRunFromLegacyGenerate()` 启动 run。
|
||
- 控制台 Agent smoke 能依次调用 `chat_search`、`chat_read_messages`、`worldinfo_read_activated`,写入 `output/main.md` 并进入 `awaiting_commit`。
|
||
- `cargo test agent_model_gateway`、`cargo test openai_responses_payload`、`cargo test claude_native_content_blocks_are_replayed`、`cargo test normalize_` 通过。
|
||
- `provider_state` / gateway 相关测试覆盖 OpenAI Responses `previousResponseId` / `messageCursor`、same-provider native metadata loss fail-fast、cross-provider private metadata 不迁移、LLM API log 剥离 `_tauritavern_provider_state`。
|
||
- 控制台 workspace 读改 smoke 能依次写入 `plan/outline.md`、`scratch/draft.md`,调用 `workspace_list_files`,完整读取 draft,使用 `workspace_apply_patch` 修改 draft,写入 `summaries/revision_notes.md`、`output/main.md` 并进入 `awaiting_commit`。
|
||
- `commit()` 能把 `output/main.md` 写入当前 active chat;`workspace.finish` 成功后才把 durable `persistStateId` 写回该消息,并追加 `run_completed`。
|
||
- Agent Mode off 的 Legacy Generate 行为不变。
|
||
|
||
后续工具/运行时变更不合并,除非:
|
||
|
||
- tool loop 测试通过。
|
||
- tool result 不写 chat message。
|
||
- recoverable tool error 回填模型测试通过。
|
||
- workspace path security 测试通过。
|
||
|
||
Profile / Plan 相关变更不合并,除非:
|
||
|
||
- profile resolution 测试通过。
|
||
- `input/resolved_profile.json` 快照写入测试通过。
|
||
- tool/skill/workspace/output policy 的 runtime 行为测试通过。
|
||
- `agentSystemPrompt` 前端 materialize、PromptManager index/role 保留、runtime marker 泄漏 fail-fast 测试通过。
|
||
- strict/free/hybrid plan 与 profile switch 相关测试在对应功能实现时补齐。
|
||
|
||
MCP 相关变更不合并,除非:
|
||
|
||
- MCP stdio command allowlist 测试通过。
|
||
- dangerous tool approval 测试通过。
|
||
- Agent 不能编辑 MCP config。
|