From 027582c7922c5cd65583c0331b619e27264e7ad7 Mon Sep 17 00:00:00 2001 From: Darkatse <39111369+Darkatse@users.noreply.github.com> Date: Wed, 22 Jul 2026 20:00:59 -0400 Subject: [PATCH] refactor: remove obsolete phase terminology --- docs/Agent/ProfilesAndPreset.md | 2 +- docs/Agent/PromptAssembly.md | 8 ++--- docs/Agent/README.md | 2 +- docs/AgentContract.md | 2 +- docs/AgentImplementPlan.md | 34 +++++++++---------- docs/CurrentState/AgentFramework.md | 2 +- docs/CurrentState/HostResourceCaching.md | 8 ++--- docs/iOSDevelopment.md | 2 +- .../guardrails/frontend-lines-baseline.json | 2 +- .../src/app/contract_tests/agent_runtime.rs | 2 +- .../tauritavern/src/app/contract_tests/mod.rs | 2 +- .../src/services/agent_model_gateway/tests.rs | 22 ++++++------ .../agent_profile_diagnostic_service.rs | 2 +- .../services/agent_profile_service/tests.rs | 2 +- .../agent_profile_service/validation.rs | 2 +- .../src/services/agent_runtime_service.rs | 2 +- .../agent_runtime_service/lifecycle.rs | 2 +- .../agent_runtime_service/prompt_snapshot.rs | 8 ++--- .../src/services/agent_tools/registry.rs | 10 +++--- src/scripts/backgrounds.js | 2 +- .../managed-iframe-parking-lot.js | 2 +- .../embedded-runtime/managed-iframe-slot.js | 2 +- .../api-connections-subtree-gates.js | 4 +-- .../panel-runtime/extensions-subtree-gates.js | 2 +- .../top-settings-panel-parking.js | 2 +- src/tauri/main/api/agent-prompt-assembly.js | 6 ++-- src/tauri/main/api/agent-prompt-snapshot.js | 8 ++--- src/tauri/main/api/agent-run-options.js | 2 +- src/tauri/main/api/agent.js | 6 ++-- .../main/kernel/invokes/tauri-commands.js | 4 +-- .../embedded-runtime-manager.js | 4 +-- ...resource-cache-authority-contract.test.mjs | 8 ++--- ...ipt-quick-reply-upstream-contract.test.mjs | 2 +- 33 files changed, 85 insertions(+), 85 deletions(-) diff --git a/docs/Agent/ProfilesAndPreset.md b/docs/Agent/ProfilesAndPreset.md index 7dcc4579..e3797ae4 100644 --- a/docs/Agent/ProfilesAndPreset.md +++ b/docs/Agent/ProfilesAndPreset.md @@ -403,7 +403,7 @@ profile_switch_denied ## 12. MVP Profile -当前状态(2026-05-04):Phase 3 Profile 基线已实现 profile resolution,但尚未实现 profile routing、Plan Mode runtime、provider/model switch 或 ContextFrame 预算。`profileId` 会驱动 tools、Skill、workspace roots、output artifact、tool budget、max rounds、model retry 与 model-facing prompt/tool descriptions。`preset.ref` 目前只做校验/记录,不隐式切换 model。 +当前状态(2026-05-04):Profile 基线已实现 profile resolution,但尚未实现 profile routing、Plan Mode runtime、provider/model switch 或 ContextFrame 预算。`profileId` 会驱动 tools、Skill、workspace roots、output artifact、tool budget、max rounds、model retry 与 model-facing prompt/tool descriptions。`preset.ref` 目前只做校验/记录,不隐式切换 model。 当前最小 built-in profile 是 `default-writer`,缺省 `profileId` 时使用它: diff --git a/docs/Agent/PromptAssembly.md b/docs/Agent/PromptAssembly.md index 69149ff7..894823f4 100644 --- a/docs/Agent/PromptAssembly.md +++ b/docs/Agent/PromptAssembly.md @@ -138,22 +138,22 @@ fingerprint { presetSha256, frozenRunInputSnapshotSha256, agentTaskPromptSha256? runtime-time `prompt_assembly_requested` event 不携带完整 request,只包含 `assemblyId`、`scope`、`requestKind`、`requestSchemaVersion` 与 `requestFingerprint`。完整 request 存在 runtime pending map 中,前端 bridge 只能在该 assembly 仍 pending 时读取。这样 event journal 保持轻量,低端移动端轮询不会反复搬运 frozen input、settings 与 prompt 文本。 -## Model 解耦与双阶段覆盖 +## Model 解耦与两次覆盖 -第一阶段发生在 `PromptAssemblyService`: +`PromptAssemblyService` 先处理 preset 与 model binding: 1. 加载 `preset.ref` 的原始 preset settings。 2. 若 `model.mode = connectionRef`,解析 connection 和 `modelId`;若 `model.mode = currentPromptSnapshot`,读取 `FrozenRunInputSnapshot.currentModelConnection`。 3. 删除 preset 中 connection-owned fields:`chat_completion_source`、各 source model key、`custom_url`、`secret_id`、reverse proxy、source-specific endpoint、OpenRouter routing、adapter hints 等。 4. 写入 broker 组装所需的连接字段。`connectionRef` 写入解析出的 source/model;`currentPromptSnapshot` 重放本轮冻结的 current connection,避免 preset 保存的旧 endpoint 或旧 key 污染当前模型。 -第二阶段发生在 Agent runtime,适用于 `model.mode = connectionRef`: +Agent runtime 随后再次覆盖连接字段,仅适用于 `model.mode = connectionRef`: 1. `start_agent_run` 收到 broker 产出的 `promptSnapshot.chatCompletionPayload`。 2. executor 在 tool loop 前调用 `apply_connection_to_payload(connectionRef, modelId, payload)`。 3. 最终 payload 的 source、model、endpoint、secret、reverse proxy、adapter hints 以 LLM Connection 为权威。 -这两个阶段都需要存在于 `connectionRef` 路径:前端组装阶段需要正确 source/model 计算 PromptManager 与 generation parameters;runtime 阶段需要保证真正发送请求时不受 preset 中旧连接信息污染。`currentPromptSnapshot` 没有可重解析的 LLM Connection,因此它在 run 输入冻结阶段捕获 current connection,并通过生成 payload 中的 `secret_id` 避免运行时回退到“当前 active secret”。 +`connectionRef` 路径需要这两次覆盖:前端组装时根据正确的 source/model 计算 PromptManager 与 generation parameters;runtime 发送请求前再排除 preset 中旧连接信息的影响。`currentPromptSnapshot` 没有可重解析的 LLM Connection,因此它在 run 输入冻结时捕获 current connection,并通过生成 payload 中的 `secret_id` 避免运行时回退到“当前 active secret”。 ## 关键文件 diff --git a/docs/Agent/README.md b/docs/Agent/README.md index 9f816ffd..185c19f3 100644 --- a/docs/Agent/README.md +++ b/docs/Agent/README.md @@ -26,4 +26,4 @@ 实时开发进度不写在本目录;请更新 `docs/CurrentState/AgentFramework.md`。 -截至 2026-06-06,canonical model IR、provider native metadata 保真、invocation-scoped provider_state continuation、上下文只读工具、Skill 管理与读取、workspace 读改工具循环、前端 dryRun adapter、Phase 3 Agent Profile 基线、独立 Preset 与 `model.connectionRef + modelId` 组装链路、return-mode SubAgent MVP、run-scoped SubAgent scheduler 基线、`agent.handoff` foreground 接力已落地。当前真实能力边界以 `docs/CurrentState/AgentFramework.md`、`docs/CurrentState/AgentProviderState.md`、`docs/Agent/PromptAssembly.md`、`docs/Agent/SubAgent.md` 与 `docs/Agent/Handoff.md` 为准;MCP、diff/rollback、模型可见 task cancel、Plan Mode runtime 仍是后续设计。 +截至 2026-06-06,canonical model IR、provider native metadata 保真、invocation-scoped provider_state continuation、上下文只读工具、Skill 管理与读取、workspace 读改工具循环、前端 dryRun adapter、Agent Profile 基线、独立 Preset 与 `model.connectionRef + modelId` 组装链路、return-mode SubAgent MVP、run-scoped SubAgent scheduler 基线、`agent.handoff` foreground 接力已落地。当前真实能力边界以 `docs/CurrentState/AgentFramework.md`、`docs/CurrentState/AgentProviderState.md`、`docs/Agent/PromptAssembly.md`、`docs/Agent/SubAgent.md` 与 `docs/Agent/Handoff.md` 为准;MCP、diff/rollback、模型可见 task cancel、Plan Mode runtime 仍是后续设计。 diff --git a/docs/AgentContract.md b/docs/AgentContract.md index ecc10025..f2a064cf 100644 --- a/docs/AgentContract.md +++ b/docs/AgentContract.md @@ -171,7 +171,7 @@ Agent commit 不能直接写 chat JSONL。 ### 1.9 LLM 调用必须复用现有服务边界 -Agent 第一阶段的 LLM 调用必须经过 `ChatCompletionService` 或它的正式 gateway wrapper。 +Agent 的 LLM 调用必须经过 `ChatCompletionService` 或它的正式 gateway wrapper。 禁止: diff --git a/docs/AgentImplementPlan.md b/docs/AgentImplementPlan.md index 6ff59341..6df52d40 100644 --- a/docs/AgentImplementPlan.md +++ b/docs/AgentImplementPlan.md @@ -1,6 +1,6 @@ -# TauriTavern Agent Implementation Plan +# TauriTavern Agent 实施说明 -本文档记录当前可继续开发的实施基线与后续顺序。历史施工计划已经收敛为当前架构、测试与契约;第 8 节只保留 Phase 台账用于追踪,不作为旧行为的事实来源。 +本文档记录 Agent 的当前实现、守护项和待办能力。历史施工计划已经收敛为当前架构、测试与契约;第 8 节按能力域归档,不作为旧行为的事实来源。 当前事实以 `docs/CurrentState/AgentFramework.md` 为准,架构边界以 `docs/AgentArchitecture.md` 与 `docs/AgentContract.md` 为准。 @@ -19,7 +19,7 @@ - Agent runtime 已使用 canonical model IR,不再把 OpenAI-compatible raw JSON 当作运行时事实。 - `provider_state` 已用于 run-scoped continuation。OpenAI Responses 通过它驱动 persistent WebSocket、incremental input 与 `previous_response_id`。 - Agent Skill repository/service、导入导出、embedded skill 导入确认、`api.skill`、`skill.list` / `skill.search` / `skill.read` 已落地。 -- Phase 3 Agent Profile 基线已落地:built-in `default-writer`、file repository、resolver、run snapshot、tool/skill/workspace/output policy、tool budget 与 max rounds。 +- Agent Profile 基线已落地:built-in `default-writer`、file repository、resolver、run snapshot、tool/skill/workspace/output policy、tool budget 与 max rounds。 - Profile `preset.mode = "ref"` 可加载独立 OpenAI/chat-completion preset;`model.mode = "connectionRef"` + `modelId` 可通过 LLM Connection 解耦 preset source/model,并在 runtime 发送前再次权威覆盖 payload。 - Profile `run.modelRetry` 已落地,默认对单次模型调用的 rate limit / transient transport-provider 错误重试 3 次,间隔 3000ms;非瞬时契约错误继续 fail-fast。 - `instructions.agentSystemPrompt` 可完整替换默认 Agent system prompt;缺省时使用 resolved profile 默认 prompt。Preset / PromptManager 控制其位置与 role;前端在该位置 materialize Profile 内容,runtime 只消费最终 messages。`tools.toolDescriptions` 可替换 model-facing tool/property descriptions;缺省时使用默认描述。 @@ -209,11 +209,11 @@ workspace.finish 收尾并提交 persist projection 工具循环轮数来自 `profile.tools.maxRounds`。超过后以 `agent.max_tool_rounds_exceeded` 失败。模型直接输出文本且不调用工具会捕获到 workspace `direct_output.md` 并触发 soft drift recovery;direct output recovery 没有独立的一次性上限,只要仍有下一轮模型调用预算就继续纠偏,直到恢复、取消或在 `maxRounds` 边界以 `model.tool_call_required` 失败 / `run_partial_success` 收口。前台 run 必须在 finish 前至少成功 commit 一次;后台 run 可以无 commit 完成。 -## 8. 后续实施顺序 +## 8. 能力台账 -本节按 Phase 台账追踪,便于提交与回归管理。已完成 Phase 只记录基线和守护项;后续开发从第一个未完成 Phase 继续。 +本节按能力域记录已经实现的边界、持续守护项和后续工作。 -### Phase 0:文档、契约、测试守护(已完成,持续维护) +### 文档、契约与测试守护 已完成: @@ -224,7 +224,7 @@ workspace.finish 收尾并提交 persist projection - Agent 相关实现变更必须同步当前事实、架构边界、Host ABI、工具语义、workspace 语义与测试策略。 -### Phase 1:Workspace + Journal + One-Step Agent(已完成) +### Workspace、Journal 与单步执行 已完成: @@ -232,7 +232,7 @@ workspace.finish 收尾并提交 persist projection - `api.agent.startRunFromLegacyGenerate()` / `startRunWithPromptSnapshot()` / subscribe / cancel / readEvents / commit bridge 已落地。 - Agent Mode off 不改变 Legacy Generate、ToolManager、事件顺序与 chat 保存语义。 -### Phase 2A:Tool Loop Foundation(已完成) +### 工具循环 已完成: @@ -240,7 +240,7 @@ workspace.finish 收尾并提交 persist projection - Tool registry 产 canonical `AgentToolSpec`,provider-facing alias 由 gateway 渲染。 - 工具调用、工具结果、recoverable tool error、fatal runtime error 与 journal 语义已落地。 -### Phase 2B:Workspace 读改工具(已完成) +### Workspace 读写工具 已完成: @@ -248,7 +248,7 @@ workspace.finish 收尾并提交 persist projection - workspace mutation 后创建 checkpoint;完整读取 / 写入 read-state 约束已接入。 - `output/`、`scratch/`、`plan/`、`summaries/`、`persist/` 是当前模型可见 root。 -### Phase 2C:上下文只读工具(已完成) +### 上下文只读工具 已完成: @@ -256,7 +256,7 @@ workspace.finish 收尾并提交 persist projection - `worldinfo.read_activated` 只读取本次 run 捕获的最终激活世界书条目。 - 只读工具结果以 resource ref / snippet / tool result 回填模型,不写入 chat 楼层。 -### Phase 2D:Gateway / Provider Contract 硬化(已完成基线,持续守护) +### Gateway / Provider 契约 结论:`Gateway / Provider Contract 硬化` 不应继续列为未完成主任务。当前基线已经完成;后续只按守护项补测试和防回退。 @@ -274,7 +274,7 @@ workspace.finish 收尾并提交 persist projection - 继续扩展 schema sanitizer edge case、session close、prompt cache 与 provider-native state 共存测试。 - 新 provider adapter 必须保持 native metadata opaque,不得清洗签名、encrypted reasoning 或 tool call id。 -### Phase 2E:Skill 管理与读取(已完成基线) +### Skill 管理与读取 已完成: @@ -282,9 +282,9 @@ workspace.finish 收尾并提交 persist projection - `skill.list` / `skill.search` / `skill.read` 已接入 Agent tool registry。 - Preset / Character embedded source refs 与删除清理语义已落地。 -Phase 3 基线已在 Agent tool 层接入 Skill 可见性、deny policy 与 read budget;Phase 2E 不再扩展 Skill 运行权限。 +Agent tool 层已接入 Skill 可见性、deny policy 与 read budget;Skill 管理与读取本身不再扩展运行权限。 -### Phase 3:Profile / Context / Skill Policy(进行中) +### Profile / Context / Skill Policy 目标:让创作者控制模型、工具、预算和上下文,而不是写死在 runtime。 @@ -306,7 +306,7 @@ Phase 3 基线已在 Agent tool 层接入 Skill 可见性、deny policy 与 read - preset / character author resources 复用 Skill-like 索引与 source ref 语义,不另建平行资源系统。 - Plan node 若锁定 profile,runtime 必须拒绝模型自行切换。 -### Phase 4:Timeline UI 与人工控制 +### Timeline UI 与人工控制 目标:给创作者可理解、可暂停、可提交的 Agent run 体验。 @@ -319,7 +319,7 @@ Phase 3 基线已在 Agent tool 层接入 Skill 可见性、deny policy 与 read - commit preview 与手动提交。 - cancel UI。 -### Phase 5:Diff / Rollback / Resume +### Diff / Rollback / Resume 目标:让多轮创作具备可控回退能力。 @@ -329,7 +329,7 @@ Phase 3 基线已在 Agent tool 层接入 Skill 可见性、deny policy 与 read - `rollback()`:先只恢复 run workspace,不修改已提交聊天消息。 - `resumeRun()`:明确 run continuation 语义,避免复用已 closed run 的状态机。 -### Phase 6:MCP / Extension Tool +### MCP / Extension Tool 目标:引入外部工具生态,但保持 Tauri-native 安全边界。 diff --git a/docs/CurrentState/AgentFramework.md b/docs/CurrentState/AgentFramework.md index 3f44b507..2404b808 100644 --- a/docs/CurrentState/AgentFramework.md +++ b/docs/CurrentState/AgentFramework.md @@ -16,7 +16,7 @@ - `AgentModelGateway` 在 Agent canonical IR 与现有 `ChatCompletionGenerateRequestDto` 之间转换;provider-native metadata 作为 opaque `Native` part 保留。 - `provider_state` 已是 run-owned、invocation-scoped continuation contract;OpenAI Responses 使用它驱动 persistent WebSocket、incremental input 与 `previous_response_id`。 - Agent Skill 管理、导入导出、embedded skill 提示导入、`skill.list` / `skill.search` / `skill.read` 已落地。 -- Phase 3 Agent Profile 基线已落地:`profileId` 会解析为 `ResolvedAgentProfile`,驱动 tools、Skill、workspace roots、output artifact、tool budget、max rounds 与 model-facing prompt/tool descriptions。 +- Agent Profile 基线已落地:`profileId` 会解析为 `ResolvedAgentProfile`,驱动 tools、Skill、workspace roots、output artifact、tool budget、max rounds 与 model-facing prompt/tool descriptions。 - PromptManager 已为 Agent Mode 提供 `agentSystemPrompt` 组装位置与 reserved no-op `agentResults` 位置标记;`agentSystemPrompt` 内容只由 Agent Profile 提供,前端在该 PromptManager index materialize,runtime 只消费最终 messages 并拒绝内部 marker 泄漏;`agentResults` 不再向模型注入历史 commit 内容。 - Profile 已能通过 `preset.mode = "ref"` 使用独立 OpenAI/chat-completion preset,并通过 `model.mode = "connectionRef"` + `modelId` 使用独立 LLM Connection。当前完整 PromptAssemblyBroker 组装覆盖 root run 启动前、return-mode child invocation 与 handoff invocation;运行中 invocation 仍走 host bridge handshake,Rust runtime 不手写替代 PromptManager。 - Return-mode SubAgent MVP 已落地:root/active invocation 可通过 `agent.list`、`agent.delegate`、`agent.await` 创建、查看或等待子任务;child invocation 使用 `task.return` 结束,不能直接 `workspace.commit`、`workspace.finish` 或 `agent.handoff`。SubAgent 硬运行预算来自 target Agent Profile,`agent.delegate` 不接受 `budget` 参数,也不能覆盖或收窄 `maxRounds` / `maxCallsPerRun`。当前 child task 已由 run-scoped scheduler 后台并行执行;`agent.await` 只等待/查询结果,未显式 await 的 terminal results 会在父 Agent 下一次 tool turn 后注入下一轮模型请求。 diff --git a/docs/CurrentState/HostResourceCaching.md b/docs/CurrentState/HostResourceCaching.md index 0ca2210e..421e3489 100644 --- a/docs/CurrentState/HostResourceCaching.md +++ b/docs/CurrentState/HostResourceCaching.md @@ -16,7 +16,7 @@ Host Resource Service 提供: - `/user/images/*` - `/user/files/*` -上游前端和第三方扩展可以继续把这些路径当作普通浏览器子资源 URL 使用。P1 不改变 URL 形态、查询参数意义或角色数据事件语义。 +上游前端和第三方扩展可以继续把这些路径当作普通浏览器子资源 URL 使用。Host Resource Service 不改变 URL 形态、查询参数意义或角色数据事件语义。 ## 2. 架构模型 @@ -29,7 +29,7 @@ Representation 浏览器实际观察到的 bytes + metadata Delivery 当前 Tauri/Wry/IPC 入口能承载的响应形式 ``` -缓存职责也按层分离:filesystem 是资源事实,Rust thumbnail cache 是由 source revision 与 recipe 标识的派生产物,P1 是 WebView 可见表示的唯一 freshness validator,WebView cache 只做机会性存储。mutation 不维护第二套 revision registry,也不依赖 WebView 是否真的保存 synthetic response 才能保证正确性。 +缓存职责也按层分离:filesystem 是资源事实,Rust thumbnail cache 是由 source revision 与 recipe 标识的派生产物,Host Resource Service 是 WebView 可见表示的新鲜度权威,WebView cache 只做机会性存储。mutation 不维护第二套 revision registry,也不依赖 WebView 是否真的保存 synthetic response 才能保证正确性。 `tt-ports::HostResourceAssetStore::open` 一次完成选源和打开文件,返回: @@ -145,7 +145,7 @@ presentation 在路由前精确校验 scheme 和完整 authority;relative URI 开发态 `tt-ext` 是独立注册的 trusted scheme。Production `tauri` protocol 与 dev `tt-ext` 都由 Wry 交付,因此共享同一个 delivery capability。直接 `fetch(tt-ext)` 时保留 `Request.cache` 和 `Range`;所有入口都保留 Host Resource 使用的 `Range`、`If-Range`、`If-None-Match`、`If-Modified-Since` 请求语义。`tt-ext` 对跨源 fetch 显式暴露响应头,避免 ETag、Range metadata 和 trace header 被 CORS 过滤。 -跨源 custom scheme fetch 无法可靠承载会触发 CORS preflight 的条件头,因此 `If-Range`、`If-None-Match`、`If-Modified-Since` 请求直接走 IPC;无条件请求和单一 `Range` 继续走 `tt-ext` Wry。WebKit 的 Service Worker 上下文无法直接 fetch custom scheme 时,client bridge 改由 window 上下文 fetch 同一个 `tt-ext` endpoint,并用 transferable `ArrayBuffer` 回传正文;普通二进制资源不得降级为 serde JSON IPC。条件请求 IPC 通过通用 header wire 调用同一个 Host Resource Service,在非 Android 原样代理调用方显式条件请求的 304,在 Android 按 release 的平台约束返回完整 200;IPC 不启用仅属于 Wry Android 的二次 Range workaround。204/205/304 在 JavaScript `Response` 中统一使用 null body。P1 不引入 Service Worker Cache API,也不声称 IPC 会自行生成浏览器缓存 validator;dev/release 共享的是资源表示与条件请求契约,自动缓存存储仍由各自 transport 负责。 +跨源 custom scheme fetch 无法可靠承载会触发 CORS preflight 的条件头,因此 `If-Range`、`If-None-Match`、`If-Modified-Since` 请求直接走 IPC;无条件请求和单一 `Range` 继续走 `tt-ext` Wry。WebKit 的 Service Worker 上下文无法直接 fetch custom scheme 时,client bridge 改由 window 上下文 fetch 同一个 `tt-ext` endpoint,并用 transferable `ArrayBuffer` 回传正文;普通二进制资源不得降级为 serde JSON IPC。条件请求 IPC 通过通用 header wire 调用同一个 Host Resource Service,在非 Android 原样代理调用方显式条件请求的 304,在 Android 按 release 的平台约束返回完整 200;IPC 不启用仅属于 Wry Android 的二次 Range workaround。204/205/304 在 JavaScript `Response` 中统一使用 null body。当前契约不引入 Service Worker Cache API,也不声称 IPC 会自行生成浏览器缓存 validator;dev/release 共享的是资源表示与条件请求契约,自动缓存存储仍由各自 transport 负责。 ## 8. 持续开发约束 @@ -153,7 +153,7 @@ presentation 在路由前精确校验 scheme 和完整 authority;relative URI - 不在 presentation 或 route handler 手写字符串 status/header DTO; - 新派生表示必须把变换 variant 纳入 ETag,且不能伪造未知 Content-Length; - thumbnail recipe 或单文件缓存格式发生任何可观察变化时必须升级 generator schema;JPEG COM identity 与 generated Host revision 必须继续使用同一身份; -- data-root-backed mutable Host Resource 长期保持稳定 URL + `private, no-cache`;P1 是 WebView 可见表示的唯一 freshness validator,不是 immutable 前的临时 fallback; +- data-root-backed mutable Host Resource 长期保持稳定 URL + `private, no-cache`;Host Resource Service 是 WebView 可见表示的新鲜度权威,这不是采用 immutable 前的临时 fallback; - 不为 mutable Host Resource 建 mutation revision registry 或 `immutable` URL。data root 允许外部/symlink writer;fresh immutable hit 会绕过 Host Resource,令外部变化无法被发现; - 第一方普通 browser resource 不得通过 Tauri asset protocol、base64 read command 或 server-thumbnail Blob cache 绕过本服务; - mutation 只建立文件事实,既不维护/删除 Rust derived cache,也不预热 WebView cache;随后只负责触发稳定 URL 的真实 consumer demand,刷新不是 commit 的组成部分,也不得用随机 query 伪造 revision; diff --git a/docs/iOSDevelopment.md b/docs/iOSDevelopment.md index 4123f1e6..ff05a93b 100644 --- a/docs/iOSDevelopment.md +++ b/docs/iOSDevelopment.md @@ -104,7 +104,7 @@ iOS 上“文件选择 / 文件导出”必须交给系统级能力完成: - `Invalid data: Archive layout is ambiguous` -当前实现会在 **布局扫描** 与 **解压归一化** 两阶段一致忽略 `__MACOSX` 条目,保证这类 zip 可正常导入: +当前实现会在 **布局扫描** 与 **解压归一化** 时忽略 `__MACOSX` 条目,保证这类 zip 可正常导入: - `src-tauri/crates/tt-adapter-archive/src/data_archive/import/layout.rs` - `src-tauri/crates/tt-adapter-archive/src/data_archive/import/extract.rs` diff --git a/scripts/guardrails/frontend-lines-baseline.json b/scripts/guardrails/frontend-lines-baseline.json index d184cbd2..9c80e4b2 100644 --- a/scripts/guardrails/frontend-lines-baseline.json +++ b/scripts/guardrails/frontend-lines-baseline.json @@ -8,7 +8,7 @@ "src/tauri/main/routes/chat-routes.js": 500 }, "notes": [ - "这些文件是宿主层的关键聚合点:Phase 1 起禁止继续增长。", + "这些文件是宿主层的关键聚合点,不再允许继续增长。", "如需新增能力,请优先新增小文件(<= 500 行)并通过组合方式接入;不要继续往这些文件堆逻辑。", "当完成拆分重构后,可更新本基线以反映新的、更小的文件布局。" ] diff --git a/src-tauri/crates/tauritavern/src/app/contract_tests/agent_runtime.rs b/src-tauri/crates/tauritavern/src/app/contract_tests/agent_runtime.rs index 07eca643..8ab794d6 100644 --- a/src-tauri/crates/tauritavern/src/app/contract_tests/agent_runtime.rs +++ b/src-tauri/crates/tauritavern/src/app/contract_tests/agent_runtime.rs @@ -8,7 +8,7 @@ use tt_domain::models::agent::{ async fn agent_runtime_background_run_finish_uses_run_presentation() { let root = temp_root("agent-runtime"); let fixture = agent_runtime_fixture(&root); - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let mut profile = fixture .profile_service .resolve_profile(AgentProfileResolveInput { diff --git a/src-tauri/crates/tauritavern/src/app/contract_tests/mod.rs b/src-tauri/crates/tauritavern/src/app/contract_tests/mod.rs index 40da535f..6b7c91b4 100644 --- a/src-tauri/crates/tauritavern/src/app/contract_tests/mod.rs +++ b/src-tauri/crates/tauritavern/src/app/contract_tests/mod.rs @@ -268,7 +268,7 @@ fn default_agent_responses() -> Vec { async fn resolve_contract_profile( fixture: &AgentRuntimeFixture, ) -> tt_domain::models::agent::profile::ResolvedAgentProfile { - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); fixture .profile_service .resolve_profile(AgentProfileResolveInput { diff --git a/src-tauri/crates/tt-application/src/services/agent_model_gateway/tests.rs b/src-tauri/crates/tt-application/src/services/agent_model_gateway/tests.rs index 1b3fa908..d8314036 100644 --- a/src-tauri/crates/tt-application/src/services/agent_model_gateway/tests.rs +++ b/src-tauri/crates/tt-application/src/services/agent_model_gateway/tests.rs @@ -19,7 +19,7 @@ use tt_ports::repositories::chat_completion_repository::{ #[test] fn decodes_tool_call_to_canonical_name() { - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let response = json!({ "choices": [{ "message": { @@ -49,7 +49,7 @@ fn decodes_tool_call_to_canonical_name() { #[test] fn rejects_tool_call_without_id() { - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let response = json!({ "choices": [{ "message": { @@ -67,7 +67,7 @@ fn rejects_tool_call_without_id() { #[test] fn rejects_normalizer_synthetic_tool_call_id() { - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let response = json!({ "choices": [{ "message": { @@ -175,7 +175,7 @@ fn gemini_schema_sanitizer_projects_nested_objects_to_agent_friendly_schema() { #[test] fn gemini_builtin_tool_schemas_do_not_emit_nested_required() { - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let tools = render_openai_tools(registry.specs(), AgentProviderAdapter::Gemini); for tool in &tools { let name = tool["function"]["name"].as_str().unwrap_or(""); @@ -230,7 +230,7 @@ fn claude_schema_sanitizer_only_removes_transport_metadata() { #[test] fn openai_responses_continuation_sends_only_new_tool_results() { - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let request = AgentModelRequest { payload: json!({ "chat_completion_source": "custom", @@ -281,7 +281,7 @@ fn openai_responses_continuation_sends_only_new_tool_results() { #[test] fn openai_responses_continuation_requires_valid_cursor() { - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let mut request = basic_request( "custom", Some("openai_responses"), @@ -330,7 +330,7 @@ fn same_provider_native_metadata_loss_fails_for_native_formats() { ), ]; - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let raw = response_with_tool_call_without_native(); let response = decode_chat_completion_response(raw, registry.specs()).unwrap(); @@ -352,7 +352,7 @@ fn same_provider_native_metadata_loss_fails_for_native_formats() { #[test] fn provider_state_requires_session_id() { - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let raw = json!({ "id": "msg_1", "model": "test", @@ -375,7 +375,7 @@ fn provider_state_requires_session_id() { #[test] fn claude_provider_state_records_native_continuation() { - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let request = provider_state_test_request("run_claude"); let raw = json!({ "id": "msg_1", @@ -429,7 +429,7 @@ fn claude_provider_state_records_native_continuation() { #[test] fn gemini_provider_state_records_native_continuation() { - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let request = provider_state_test_request("run_gemini"); let raw = json!({ "id": "gemini-chat-completion", @@ -563,7 +563,7 @@ fn assert_gemini_required_shape(schema: &Value, root: bool, context: &str) { fn provider_state_test_request(session_id: &str) -> AgentModelRequest { let mut request = basic_request("claude", None, Vec::new()); - request.tools = BuiltinAgentToolRegistry::phase2c().specs().to_vec(); + request.tools = BuiltinAgentToolRegistry::all().specs().to_vec(); request.provider_state = json!({ "sessionId": session_id }); request } diff --git a/src-tauri/crates/tt-application/src/services/agent_profile_diagnostic_service.rs b/src-tauri/crates/tt-application/src/services/agent_profile_diagnostic_service.rs index 58036960..9c82edb2 100644 --- a/src-tauri/crates/tt-application/src/services/agent_profile_diagnostic_service.rs +++ b/src-tauri/crates/tt-application/src/services/agent_profile_diagnostic_service.rs @@ -585,7 +585,7 @@ mod tests { ( profile_service, diagnostic_service, - BuiltinAgentToolRegistry::phase2c(), + BuiltinAgentToolRegistry::all(), ) } diff --git a/src-tauri/crates/tt-application/src/services/agent_profile_service/tests.rs b/src-tauri/crates/tt-application/src/services/agent_profile_service/tests.rs index 3147d137..e27de056 100644 --- a/src-tauri/crates/tt-application/src/services/agent_profile_service/tests.rs +++ b/src-tauri/crates/tt-application/src/services/agent_profile_service/tests.rs @@ -543,7 +543,7 @@ async fn save_profile_with_preset_ref( profile.preset.mode = AgentPresetBindingMode::Ref; profile.preset.ref_ = Some(preset_ref(api_id, preset_name)); profile.preset.required = true; - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); profile_service .save_profile(profile, registry.specs()) .await diff --git a/src-tauri/crates/tt-application/src/services/agent_profile_service/validation.rs b/src-tauri/crates/tt-application/src/services/agent_profile_service/validation.rs index e2d139a7..4483cd8b 100644 --- a/src-tauri/crates/tt-application/src/services/agent_profile_service/validation.rs +++ b/src-tauri/crates/tt-application/src/services/agent_profile_service/validation.rs @@ -149,7 +149,7 @@ pub(super) fn validate_instructions( pub(super) fn validate_plan_policy(plan: &AgentPlanPolicy) -> Result<(), ApplicationError> { if plan.mode != AgentPlanMode::None { return Err(ApplicationError::ValidationError( - "agent.plan_mode_unsupported: Phase 3 foundation only supports plan.mode = none" + "agent.plan_mode_unsupported: Agent runtime only supports plan.mode = none" .to_string(), )); } diff --git a/src-tauri/crates/tt-application/src/services/agent_runtime_service.rs b/src-tauri/crates/tt-application/src/services/agent_runtime_service.rs index f96a928a..9be7d8a5 100644 --- a/src-tauri/crates/tt-application/src/services/agent_runtime_service.rs +++ b/src-tauri/crates/tt-application/src/services/agent_runtime_service.rs @@ -132,7 +132,7 @@ impl AgentRuntimeService { llm_connection_service: Arc, prompt_assembly_service: Arc, ) -> Self { - let tool_registry = BuiltinAgentToolRegistry::phase2c(); + let tool_registry = BuiltinAgentToolRegistry::all(); let tool_dispatcher = AgentToolDispatcher::new( run_repository.clone(), chat_repository.clone(), diff --git a/src-tauri/crates/tt-application/src/services/agent_runtime_service/lifecycle.rs b/src-tauri/crates/tt-application/src/services/agent_runtime_service/lifecycle.rs index 58949087..cb3311ae 100644 --- a/src-tauri/crates/tt-application/src/services/agent_runtime_service/lifecycle.rs +++ b/src-tauri/crates/tt-application/src/services/agent_runtime_service/lifecycle.rs @@ -36,7 +36,7 @@ impl AgentRuntimeService { ) -> Result { if dto.options.stream { return Err(ApplicationError::ValidationError( - "agent.phase2b_stream_unsupported: Agent Phase 2B only supports non-streaming model calls" + "agent.stream_unsupported: Agent runtime only supports non-streaming model calls" .to_string(), )); } diff --git a/src-tauri/crates/tt-application/src/services/agent_runtime_service/prompt_snapshot.rs b/src-tauri/crates/tt-application/src/services/agent_runtime_service/prompt_snapshot.rs index 04cafefd..d4056c5e 100644 --- a/src-tauri/crates/tt-application/src/services/agent_runtime_service/prompt_snapshot.rs +++ b/src-tauri/crates/tt-application/src/services/agent_runtime_service/prompt_snapshot.rs @@ -108,14 +108,14 @@ pub(super) fn reject_external_tool_request( .is_some_and(|tools| !tools.is_empty()); if has_tools { return Err(ApplicationError::ValidationError( - "agent.external_tools_unsupported_phase2b: Agent Phase 2B owns the tool registry" + "agent.external_tools_unsupported: Agent runtime owns the tool registry" .to_string(), )); } if payload.contains_key("tool_choice") { return Err(ApplicationError::ValidationError( - "agent.external_tool_choice_unsupported_phase2b: Agent Phase 2B owns tool choice" + "agent.external_tool_choice_unsupported: Agent runtime owns tool choice" .to_string(), )); } @@ -137,7 +137,7 @@ pub(super) fn reject_external_tool_request( }) { return Err(ApplicationError::ValidationError( - "agent.external_tool_turns_unsupported_phase2b: prompt snapshot already contains tool turns" + "agent.external_tool_turns_unsupported: prompt snapshot already contains tool turns" .to_string(), )); } @@ -324,7 +324,7 @@ mod tests { assert!( error .to_string() - .contains("agent.external_tool_choice_unsupported_phase2b") + .contains("agent.external_tool_choice_unsupported") ); } diff --git a/src-tauri/crates/tt-application/src/services/agent_tools/registry.rs b/src-tauri/crates/tt-application/src/services/agent_tools/registry.rs index 061f7734..90119a9e 100644 --- a/src-tauri/crates/tt-application/src/services/agent_tools/registry.rs +++ b/src-tauri/crates/tt-application/src/services/agent_tools/registry.rs @@ -22,7 +22,7 @@ pub struct BuiltinAgentToolRegistry { } impl BuiltinAgentToolRegistry { - pub fn phase2c() -> Self { + pub fn all() -> Self { Self { specs: vec![ agent_list_spec(), @@ -368,7 +368,7 @@ mod tests { #[test] fn registry_uses_openai_safe_model_names() { - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let tools = registry.specs(); assert_eq!(tools[0].model_name, "agent_list"); @@ -421,7 +421,7 @@ mod tests { #[test] fn agent_delegate_requires_objective_but_not_title() { - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let delegate = registry .specs() .iter() @@ -451,7 +451,7 @@ mod tests { #[test] fn visible_specs_expose_profile_skill_read_budget() { - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let profile = profile_with_skill_budget(100_000, 100_000); let tools = registry.visible_specs(&profile).expect("visible specs"); let skill_read = tools @@ -487,7 +487,7 @@ mod tests { #[test] fn agent_tool_specs_keep_runtime_terms_out_of_model_descriptions() { - let registry = BuiltinAgentToolRegistry::phase2c(); + let registry = BuiltinAgentToolRegistry::all(); let agent_tools = registry .specs() .iter() diff --git a/src/scripts/backgrounds.js b/src/scripts/backgrounds.js index d5dbf87d..b4bb9846 100644 --- a/src/scripts/backgrounds.js +++ b/src/scripts/backgrounds.js @@ -505,7 +505,7 @@ async function onCopyToSystemBackgroundClick(e) { /** * Gets a frontend-derived preview for a custom background. - * Same-origin Host resources are validated by P1 before a cached preview is reused. + * Same-origin Host resources are validated against their ETag before a cached preview is reused. * @param {string} bg Custom background URL * @returns {Promise} Blob URL of the thumbnail */ diff --git a/src/tauri/main/adapters/embedded-runtime/managed-iframe-parking-lot.js b/src/tauri/main/adapters/embedded-runtime/managed-iframe-parking-lot.js index 1426c3b0..c328373d 100644 --- a/src/tauri/main/adapters/embedded-runtime/managed-iframe-parking-lot.js +++ b/src/tauri/main/adapters/embedded-runtime/managed-iframe-parking-lot.js @@ -5,7 +5,7 @@ * moving them into a hidden DOM container instead of destroying them. * Browsing-context preservation across DOM moves is platform-dependent. * - * This is a Phase-1 mechanism: + * The parking lot: * - Reuses iframe elements when scrolling back. * - Enforces a hard cap (mobile) by evicting oldest parked iframes. * - Uses TTL to avoid leaking parked instances after DOM rebuilds. diff --git a/src/tauri/main/adapters/embedded-runtime/managed-iframe-slot.js b/src/tauri/main/adapters/embedded-runtime/managed-iframe-slot.js index 1d78307c..5548fcbf 100644 --- a/src/tauri/main/adapters/embedded-runtime/managed-iframe-slot.js +++ b/src/tauri/main/adapters/embedded-runtime/managed-iframe-slot.js @@ -11,7 +11,7 @@ const GHOST_PLACEHOLDER_CLASS = 'tt-runtime-ghost'; /** * Marks an iframe mutation as managed by TauriTavern embedded-runtime so that - * chat-level observers can ignore it (ER-3.2 self-heal). + * chat-level self-healing observers can ignore it. * * @param {HTMLIFrameElement} iframe */ diff --git a/src/tauri/main/adapters/panel-runtime/api-connections-subtree-gates.js b/src/tauri/main/adapters/panel-runtime/api-connections-subtree-gates.js index e7bf259f..f690ba07 100644 --- a/src/tauri/main/adapters/panel-runtime/api-connections-subtree-gates.js +++ b/src/tauri/main/adapters/panel-runtime/api-connections-subtree-gates.js @@ -241,7 +241,7 @@ function handleTextgenTypeChange(type) { } /** - * Phase 1 (preinstall): register early `change` listeners so our gate handlers + * Preinstall: register early `change` listeners so our gate handlers * run before SillyTavern's own handlers (including jQuery `.trigger('change')`). */ export function preinstallApiConnectionsSubtreeGates() { @@ -278,7 +278,7 @@ export function preinstallApiConnectionsSubtreeGates() { } /** - * Phase 1 (activate): build gates and immediately park inactive subtrees. + * Activation: build gates and immediately park inactive subtrees. * * @param {{ manager: EmbeddedRuntimeManager }} options */ diff --git a/src/tauri/main/adapters/panel-runtime/extensions-subtree-gates.js b/src/tauri/main/adapters/panel-runtime/extensions-subtree-gates.js index 509f10db..909a8272 100644 --- a/src/tauri/main/adapters/panel-runtime/extensions-subtree-gates.js +++ b/src/tauri/main/adapters/panel-runtime/extensions-subtree-gates.js @@ -53,7 +53,7 @@ function restoreChildren(host, frag) { } /** - * Phase 1: Park extension settings DOM under `#rm_extensions_block` while the + * Park extension settings DOM under `#rm_extensions_block` while the * drawer is closed, keeping the mount containers connected for compatibility. * * @param {{ manager: EmbeddedRuntimeManager }} options diff --git a/src/tauri/main/adapters/panel-runtime/top-settings-panel-parking.js b/src/tauri/main/adapters/panel-runtime/top-settings-panel-parking.js index 41ee4953..6fc26f66 100644 --- a/src/tauri/main/adapters/panel-runtime/top-settings-panel-parking.js +++ b/src/tauri/main/adapters/panel-runtime/top-settings-panel-parking.js @@ -291,7 +291,7 @@ function registerDrawerParking(manager, { panelId, parkedSelector, pinnedSelecto } /** - * Phase 0: Park the heaviest closed drawers under #top-settings-holder by + * Park the heaviest closed drawers under #top-settings-holder by * detaching their heavy subtrees from the main document tree. * * Controlled by `tauritavern-settings.panel_runtime_profile` (default: off). diff --git a/src/tauri/main/api/agent-prompt-assembly.js b/src/tauri/main/api/agent-prompt-assembly.js index 15724bf8..1daf0c59 100644 --- a/src/tauri/main/api/agent-prompt-assembly.js +++ b/src/tauri/main/api/agent-prompt-assembly.js @@ -197,10 +197,10 @@ function hasChatCompletionSource(settings) { function assertNoExternalTools(payload) { const tools = payload?.tools; if (Array.isArray(tools) && tools.length > 0) { - throw new Error('agent.external_tools_unsupported_phase2b: Agent Phase 2B owns the tool registry'); + throw new Error('agent.external_tools_unsupported: Agent runtime owns the tool registry'); } if (Object.prototype.hasOwnProperty.call(payload || {}, 'tool_choice')) { - throw new Error('agent.external_tool_choice_unsupported_phase2b: Agent Phase 2B owns tool choice'); + throw new Error('agent.external_tool_choice_unsupported: Agent runtime owns tool choice'); } } @@ -216,6 +216,6 @@ function assertNoExternalToolTurns(messages) { }); if (hasToolTurn) { - throw new Error('agent.external_tool_turns_unsupported_phase2b: prompt snapshot already contains tool turns'); + throw new Error('agent.external_tool_turns_unsupported: prompt snapshot already contains tool turns'); } } diff --git a/src/tauri/main/api/agent-prompt-snapshot.js b/src/tauri/main/api/agent-prompt-snapshot.js index 1ec7da1d..320008d7 100644 --- a/src/tauri/main/api/agent-prompt-snapshot.js +++ b/src/tauri/main/api/agent-prompt-snapshot.js @@ -31,7 +31,7 @@ export async function buildAgentPromptSnapshotSeed(input = {}) { const script = await import('../../../script.js'); if (script.main_api !== 'openai') { - throw new Error('agent.phase2b_chat_completion_required: Agent Phase 2B requires the OpenAI/chat-completion frontend path'); + throw new Error('agent.chat_completion_required: Agent runtime requires the OpenAI/chat-completion frontend path'); } const { generateData } = await captureAgentDryRun(script, generationType, { @@ -164,10 +164,10 @@ function assertMessagesReady(messages) { function assertNoExternalTools(payload) { const tools = payload?.tools; if (Array.isArray(tools) && tools.length > 0) { - throw new Error('agent.external_tools_unsupported_phase2b: Agent Phase 2B owns the tool registry'); + throw new Error('agent.external_tools_unsupported: Agent runtime owns the tool registry'); } if (Object.prototype.hasOwnProperty.call(payload || {}, 'tool_choice')) { - throw new Error('agent.external_tool_choice_unsupported_phase2b: Agent Phase 2B owns tool choice'); + throw new Error('agent.external_tool_choice_unsupported: Agent runtime owns tool choice'); } } @@ -183,6 +183,6 @@ function assertNoExternalToolTurns(messages) { }); if (hasToolTurn) { - throw new Error('agent.external_tool_turns_unsupported_phase2b: prompt snapshot already contains tool turns'); + throw new Error('agent.external_tool_turns_unsupported: prompt snapshot already contains tool turns'); } } diff --git a/src/tauri/main/api/agent-run-options.js b/src/tauri/main/api/agent-run-options.js index 5b636a54..9453c44f 100644 --- a/src/tauri/main/api/agent-run-options.js +++ b/src/tauri/main/api/agent-run-options.js @@ -7,7 +7,7 @@ export function normalizeAgentRunOptions(value, presentationOverride = undefined const options = value || {}; if (options.stream === true) { - throw new Error('agent.phase2b_stream_unsupported: Agent Phase 2B only supports non-streaming model calls'); + throw new Error('agent.stream_unsupported: Agent runtime only supports non-streaming model calls'); } if (Object.prototype.hasOwnProperty.call(options, 'autoCommit')) { throw new Error('agent.auto_commit_removed: Agent chat commits are driven by workspace.commit'); diff --git a/src/tauri/main/api/agent.js b/src/tauri/main/api/agent.js index 2dac93ce..098d26f6 100644 --- a/src/tauri/main/api/agent.js +++ b/src/tauri/main/api/agent.js @@ -111,14 +111,14 @@ function createAgentApi({ safeInvoke }) { }, promptAssembly, approveToolCall() { - throw new Error('approveToolCall is not implemented in Agent Phase 2B'); + throw new Error('approveToolCall is not implemented'); }, listRuns: runtime.listRuns, readDiff() { - throw new Error('readDiff is not implemented in Agent Phase 2B'); + throw new Error('readDiff is not implemented'); }, rollback() { - throw new Error('rollback is not implemented in Agent Phase 2B'); + throw new Error('rollback is not implemented'); }, }; } diff --git a/src/tauri/main/kernel/invokes/tauri-commands.js b/src/tauri/main/kernel/invokes/tauri-commands.js index bb06637a..ab8dbbb4 100644 --- a/src/tauri/main/kernel/invokes/tauri-commands.js +++ b/src/tauri/main/kernel/invokes/tauri-commands.js @@ -5,8 +5,8 @@ export {}; /** * Host-known backend invoke command names. * - * Phase 3 goal: make the invoke surface searchable and typo-resistant without - * forcing a TS build. Keep this list scoped to commands referenced by the host + * Keep the invoke surface searchable and typo-resistant without forcing a TS + * build. This list stays scoped to commands referenced by the host * kernel (`src/tauri/main/**`). * * @typedef {( diff --git a/src/tauri/main/services/embedded-runtime/embedded-runtime-manager.js b/src/tauri/main/services/embedded-runtime/embedded-runtime-manager.js index c802e518..60477fd3 100644 --- a/src/tauri/main/services/embedded-runtime/embedded-runtime-manager.js +++ b/src/tauri/main/services/embedded-runtime/embedded-runtime-manager.js @@ -283,8 +283,8 @@ export function createEmbeddedRuntimeManager({ profile, now = () => Date.now(), * Marks a slot as "dirty" so the next reconcile can re-assert its desired * state and (re)hydrate it if selected active. * - * This is primarily used for ER-3 self-heal when third-party code removes - * an iframe DOM node without properly unmounting its runtime controller. + * This supports self-healing when third-party code removes an iframe DOM + * node without properly unmounting its runtime controller. * * @param {string} id */ diff --git a/tests/host-resource-cache-authority-contract.test.mjs b/tests/host-resource-cache-authority-contract.test.mjs index d32c879c..e4f6ab02 100644 --- a/tests/host-resource-cache-authority-contract.test.mjs +++ b/tests/host-resource-cache-authority-contract.test.mjs @@ -107,7 +107,7 @@ function createCustomPreviewHarness(source, sourceResponse) { return { getPreview, memory, records, requests, revoked }; } -test('first-party normal reads never override P1 with force-cache', async () => { +test('first-party normal reads never override Host Resource cache policy with force-cache', async () => { const files = await firstPartyJavaScriptFiles(path.join(REPO_ROOT, 'src')); const violations = []; for (const file of files) { @@ -120,7 +120,7 @@ test('first-party normal reads never override P1 with force-cache', async () => assert.deepEqual(violations, []); }); -test('background previews use stable P1 representations without a server Blob cache', async () => { +test('background previews use stable Host Resource representations without a server Blob cache', async () => { const [source, settingsSource] = await Promise.all([ readProjectFile('src/scripts/backgrounds.js'), readProjectFile('src/scripts/tauri/setting/setting-panel/settings-popup.js'), @@ -139,7 +139,7 @@ test('background previews use stable P1 representations without a server Blob ca assert.match(settingsSource, /endsWith\('\.mp4'\)[\s\S]+No-Image-Placeholder\.svg/); }); -test('same-origin custom previews bind candidate reuse to P1 ETag', async () => { +test('same-origin custom previews bind candidate reuse to the Host Resource ETag', async () => { const source = await readProjectFile('src/scripts/backgrounds.js'); let etag = '"source-v1"'; const harness = createCustomPreviewHarness(source, async () => ({ @@ -170,7 +170,7 @@ test('same-origin custom previews bind candidate reuse to P1 ETag', async () => assert.deepEqual(harness.revoked, [cold]); }); -test('same-origin custom preview fails fast when P1 omits ETag', async () => { +test('same-origin custom preview fails fast when the Host Resource omits ETag', async () => { const source = await readProjectFile('src/scripts/backgrounds.js'); const harness = createCustomPreviewHarness(source, async () => ({ ok: true, diff --git a/tests/stscript-quick-reply-upstream-contract.test.mjs b/tests/stscript-quick-reply-upstream-contract.test.mjs index 90f52568..81349034 100644 --- a/tests/stscript-quick-reply-upstream-contract.test.mjs +++ b/tests/stscript-quick-reply-upstream-contract.test.mjs @@ -29,7 +29,7 @@ function extractCommandBlock(source, name) { return source.slice(start, next === -1 ? source.length : next); } -test('root slash commands include SillyTavern 1.18 P8 command surface and local commands', async () => { +test('root slash commands include the SillyTavern 1.18 command surface and local commands', async () => { const source = await readFile(path.join(REPO_ROOT, 'src/scripts/slash-commands.js'), 'utf8'); const names = extractCommandNames(source);