diff --git a/.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.i18n.yaml b/.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.i18n.yaml index 86b4e1deed..bf64ecf4d3 100644 --- a/.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.i18n.yaml +++ b/.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.i18n.yaml @@ -2,5 +2,5 @@ # side as of the last confirmed-consistent state. Both languages carry equal authority; # after editing either side, bring the other along and re-record with: # pnpm run verify-translation-pairing --write -2026-07-24-model-facing-session-query-tools.md: bc9143150d1e17eda9eab7f4864ed3a2f4983157 -2026-07-24-model-facing-session-query-tools.zh.md: c8a0c70789f21e4bbca523b6acc81925fb17b604 +2026-07-24-model-facing-session-query-tools.md: f05f9792619155070ec1c5c721702d7ed94442ce +2026-07-24-model-facing-session-query-tools.zh.md: 2570dda4b3ff22ff26e12e2f9d1418d76f079f5c diff --git a/.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.md b/.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.md index bc9143150d..f05f979261 100644 --- a/.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.md +++ b/.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.md @@ -36,7 +36,7 @@ Session-level results include the latest folded title when available. Each tool ## Host composition -The shipped ACP, TUI, and Web compositions all mount the consumer beside `ctx.sessionQuery`. TUI and Web use their existing timeout and spill policies. ACP mounts the same timeout policy and private local spill backend with the shared 50,000-byte inline threshold, so the five tools have one model-facing contract across hosts. Web also mounts the SQLite query backend at its persistence root; generic tool presentation requires no session-query-specific client plugin. +The consumer is an opt-in plugin. The shipped ACP, TUI, and Web compositions mount `ctx.sessionQuery` for their non-model consumers but do not mount `@deepseek-ai/dsh-tool-session-query`, so their default model requests gain no query prompt or schemas. A composition that opts in also chooses whether to mount the generic timeout and spill policies; the dedicated ACP snapshot fixture mounts both and uses private local spill storage. Generic tool presentation requires no session-query-specific client plugin. ## Alternatives considered @@ -48,7 +48,7 @@ The shipped ACP, TUI, and Web compositions all mount the consumer beside `ctx.se ## Verification -Package tests pin argument validation, filter translation, timestamp normalization, exact-workspace authorization, parent-filter preauthorization and oracle resistance, changed-observation rejection, service-diagnostic redaction for ordinary and adversarial unknown values, best-effort cyclic-cause logging, logger-failure containment, missing-identity behavior, hidden-boundary pruning, current-step exclusion, internal provider paging, exclusive search and parallel exact-read classification, count caps, exact-signal forwarding, abort-reason preservation, persistence cleanup quiescence, one-scan bounded batch title enrichment, projection-before-dequeue ordering, queued-work suppression, started-worker quiescence, per-header validation, title fallbacks, representative search/trace/read rendering, generic presentation, and disposable registration. Integration coverage uses the real SQLite FTS provider over live and persisted sessions. Loader and assembled-host coverage proves that ACP, TUI, and Web register the tools with timeout and spill support, while keyless assembled ACP snapshots pin the prompt guidance and schemas plus path-independent exact event-read spill and retention behavior. +Package tests pin argument validation, filter translation, timestamp normalization, exact-workspace authorization, parent-filter preauthorization and oracle resistance, changed-observation rejection, service-diagnostic redaction for ordinary and adversarial unknown values, best-effort cyclic-cause logging, logger-failure containment, missing-identity behavior, hidden-boundary pruning, current-step exclusion, internal provider paging, exclusive search and parallel exact-read classification, count caps, exact-signal forwarding, abort-reason preservation, persistence cleanup quiescence, one-scan bounded batch title enrichment, projection-before-dequeue ordering, queued-work suppression, started-worker quiescence, per-header validation, title fallbacks, representative search/trace/read rendering, generic presentation, and disposable registration. Integration coverage uses the real SQLite FTS provider over live and persisted sessions. Default-host tests and assembled request-header snapshots prove that the model-facing consumer remains absent while `ctx.sessionQuery` stays available. A package-owned Loader smoke and dedicated keyless ACP snapshot explicitly mount the consumer with timeout and spill support, pinning its prompt guidance, schemas, and path-independent exact event-read retention behavior. ## Consequences diff --git a/.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.zh.md b/.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.zh.md index c8a0c70789..2570dda4b3 100644 --- a/.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.zh.md +++ b/.agents/notes/implemented/feature/2026-07-24-model-facing-session-query-tools.zh.md @@ -36,7 +36,7 @@ Status: implemented ## 宿主组合 -发布的 ACP、TUI 与 Web 组合都在 `ctx.sessionQuery` 旁挂载该消费者。TUI 与 Web 使用已有的超时与 spill 策略。ACP 挂载同一超时策略与私有本地 spill 后端,并采用共享的 50,000 字节行内阈值,因此五个工具在各宿主中具有同一面向模型的契约。Web 还在其持久化根目录挂载 SQLite 查询后端;通用工具表现无需会话查询专用客户端插件。 +该消费方是一个需显式启用的插件。发布的 ACP、TUI 与 Web 组合为其非模型消费方挂载 `ctx.sessionQuery`,但不挂载 `@deepseek-ai/dsh-tool-session-query`,因此其默认模型请求中不包含查询提示词或 schema。选择启用该插件的组合还要决定是否挂载通用的超时与 spill 策略;专用的 ACP 快照 fixture(测试前置数据)同时挂载这两项策略,并使用私有的本地 spill 存储。通用工具表现无需会话查询专用客户端插件。 ## 考虑过的替代方案 @@ -48,7 +48,7 @@ Status: implemented ## 验证 -包级测试固定参数校验、过滤条件转换、时间戳规范化、精确工作区授权、父级过滤预授权与抵御预言机探测、变更观测拒绝、普通值与对抗性未知值的服务诊断脱敏、尽力记录循环 cause、日志失败隔离、身份缺失行为、隐藏边界裁剪、当前步骤排除、内部提供方翻页、搜索独占与精确读取并行分类、数量上限、精确信号传递、中止原因保留、持久化清理静止、单次扫描且并发有界的批量标题扩充、先投影再取出下一个任务的顺序、抑制排队工作、等待已启动 worker 静止、逐会话头校验、标题回退、代表性搜索/追踪/读取渲染、通用表现与可释放注册。集成覆盖使用真实 SQLite FTS 提供方查询实时与持久化会话。Loader 与组装宿主覆盖证明 ACP、TUI 和 Web 会注册带超时及 spill 支持的工具;无密钥组装 ACP 快照则固定提示词指导与 schema,以及与路径无关的精确事件读取 spill 与保留行为。 +包级测试固定参数校验、过滤条件转换、时间戳规范化、精确工作区授权、父级过滤预授权与抵御预言机探测、变更观测拒绝、普通值与对抗性未知值的服务诊断脱敏、尽力记录循环 cause、日志失败隔离、身份缺失行为、隐藏边界裁剪、当前步骤排除、内部提供方翻页、搜索独占与精确读取并行分类、数量上限、精确信号传递、中止原因保留、持久化清理静止、单次扫描且并发有界的批量标题扩充、先投影再取出下一个任务的顺序、抑制排队工作、等待已启动 worker 静止、逐会话头校验、标题回退、代表性搜索/追踪/读取渲染、通用表现与可释放注册。集成覆盖使用真实 SQLite FTS 提供方查询实时与持久化会话。默认宿主测试与组装后的请求头快照证明:面向模型的消费方仍未挂载,而 `ctx.sessionQuery` 保持可用。包自身的 Loader 冒烟测试与专用无密钥 ACP 快照显式挂载该消费方,并配套启用超时与 spill 支持,固定其提示词指引、schema 以及与路径无关的精确事件读取保留行为。 ## 后果 diff --git a/docs/tool-catalog.md b/docs/tool-catalog.md index 06a0ec989c..3cdc822a7a 100644 --- a/docs/tool-catalog.md +++ b/docs/tool-catalog.md @@ -27,7 +27,7 @@ This table connects model-visible tool names to the plugin package and service s | `@deepseek-ai/dsh-tool-lsp` | `lsp` | `ctx.tools`, `ctx.lsp`, `ctx.systemPrompt` | `tool/call`, `tool/result` | - | The lsp tool keeps provider selection and language-server subprocesses behind ctx.lsp, so its model-visible schema stays stable across providers. Requires a registered provider (e.g. `@deepseek-ai/dsh-lsp-local`) at runtime; without one, a query returns the structured `LSP_UNAVAILABLE` error rather than changing the schema. | | `@deepseek-ai/dsh-tool-ralph` | `ralph` | `ctx.tools`, `ctx.workflows`, `ctx.subagents`, `ctx.systemPrompt`, `a calling Agent (exec.agent parents every fresh round)` | `tool/call`, `tool/result`, `workflow and child session events during execution` | - | A fixed foreground workflow starts one fresh structured child per round; the model selects only the immutable objective and an optional round cap. | | `@deepseek-ai/dsh-tool-skill` | `skill` | `ctx.tools`, `ctx.skills` | `tool/call`, `tool/result` | - | - | -| `@deepseek-ai/dsh-tool-session-query` | `session_event_read`, `session_event_search`, `session_event_trace`, `session_search`, `session_trace` | `ctx.tools`, `ctx.systemPrompt`, `ctx.sessionQuery`, `a calling Agent for workspace authority` | `tool/call`, `tool/result` | - | The five read-only tools hide provider cursors and authorize every result from the immutable calling agent session. Default ACP, TUI, and Web compositions enforce the declared search timeout and apply the generic tool-result spill policy. | +| `@deepseek-ai/dsh-tool-session-query` | `session_event_read`, `session_event_search`, `session_event_trace`, `session_search`, `session_trace` | `ctx.tools`, `ctx.systemPrompt`, `ctx.sessionQuery`, `a calling Agent for workspace authority` | `tool/call`, `tool/result` | - | The five read-only tools hide provider cursors and authorize every result from the immutable calling agent session. The package is opt-in; compositions that need enforced deadlines or bounded inline output also mount the generic timeout or spill policies. | | `@deepseek-ai/dsh-tool-subagent` | `subagent` | `ctx.tools`, `ctx.subagents` | `tool/call`, `tool/result`, `child session events through the chosen provider` | `subagent`, `subagent_fork` | The registered tool name is the load-time `toolName` config (default `subagent`); the schema above is that default. The shipped example agents load this package once per subagent backend, so the model additionally sees `subagent_fork` (bound to the fork backend) with an identical schema — see `examples/tui-agent/cordis.yml` and `examples/acp-agent/cordis.yml`. | | `@deepseek-ai/dsh-tool-tasks` | `task_kill`, `task_list`, `task_output` | `ctx.tools`, `ctx.tasks`, `ctx.systemPrompt` | `tool/call`, `tool/result`, `user/message via agent.inject() for background completion notices` | - | The kind-agnostic background-task control surface: background bash commands, PTY sends, and subagents are read, listed, and killed through the same three tools. Loading the plugin attaches the control surface that arms producers' `ctx.tasks.start()`. | | `@deepseek-ai/dsh-tool-todo` | `todo_write` | `ctx.tools`, `owning Agent session` | `tool/call`, `todo/write`, `tool/result` | - | todo_write is session-owned state; UIs render the latest todo/write event as a checklist. | @@ -1010,7 +1010,7 @@ Read the authorized session lineage around one session, including complete visib Source: [`packages/session-query/tool-session-query/src/index.ts`](../packages/session-query/tool-session-query/src/index.ts) -The five read-only tools hide provider cursors and authorize every result from the immutable calling agent session. Default ACP, TUI, and Web compositions enforce the declared search timeout and apply the generic tool-result spill policy. +The five read-only tools hide provider cursors and authorize every result from the immutable calling agent session. The package is opt-in; compositions that need enforced deadlines or bounded inline output also mount the generic timeout or spill policies. ## `@deepseek-ai/dsh-tool-subagent` diff --git a/examples/acp-agent/README.md b/examples/acp-agent/README.md index 52cc51db15..892a32cdc7 100644 --- a/examples/acp-agent/README.md +++ b/examples/acp-agent/README.md @@ -7,7 +7,7 @@ pnpm run demo:acp # needs DEEPSEEK_API_KEY (repo-root .env or env) pnpm run demo:code-mode acp # same protocol with the Code Mode tool transport ``` -The leaf loads the ACP app, DeepSeek adapter, sandboxed bash and filesystem stacks, one-shot approval policy, compaction, subagents, workflows, hooks, a derived session-query index, workspace-authorized session-query tools, generic timeout and local spill policies, and repeat guard. The app creates one fresh agent per `session/new`, persists sessions to JSONL, and keeps stdout protocol-pure. [`fs.cordis.yml`](fs.cordis.yml) redirects spill storage and lowers the inline threshold for dedicated filesystem scenarios; [`code-mode.cordis.yml`](code-mode.cordis.yml) adds `run_code` and its generated TypeScript SDK. +The leaf loads the ACP app, DeepSeek adapter, sandboxed bash and filesystem stacks, one-shot approval policy, compaction, subagents, workflows, hooks, a derived session-query index, and repeat guard. The app creates one fresh agent per `session/new`, persists sessions to JSONL, and keeps stdout protocol-pure. [`session-query.cordis.yml`](session-query.cordis.yml) explicitly opts into the workspace-authorized query tools and generic timeout/spill policies for their dedicated snapshot; [`fs.cordis.yml`](fs.cordis.yml) adds spill storage for filesystem scenarios, while [`code-mode.cordis.yml`](code-mode.cordis.yml) adds `run_code` and its generated TypeScript SDK. ## Protocol channel diff --git a/examples/acp-agent/composition.md b/examples/acp-agent/composition.md index ba9ece13b5..8d112f2910 100644 --- a/examples/acp-agent/composition.md +++ b/examples/acp-agent/composition.md @@ -27,14 +27,6 @@ flowchart LR bundle_agent_core --> spine_sessions["ctx.sessions"] bundle_agent_core --> spine_tools["ctx.tools + tool-bash"] bundle_agent_core --> spine_loop["ctx.agents + ctx.agentLoop"] - plugin_acp_tool_session_query["tool-session-query
@deepseek-ai/dsh-tool-session-query"] - cfg --> plugin_acp_tool_session_query - plugin_acp_timeout_policy["timeout-policy
@deepseek-ai/dsh-timeout-policy"] - cfg --> plugin_acp_timeout_policy - plugin_acp_spill_local["spill-local
@deepseek-ai/dsh-spill-local"] - cfg --> plugin_acp_spill_local - plugin_acp_spill_policy["spill-policy
@deepseek-ai/dsh-spill-policy"] - cfg --> plugin_acp_spill_policy plugin_acp_token_meter["token-meter
@deepseek-ai/dsh-token-meter"] cfg --> plugin_acp_token_meter plugin_acp_compact_basic["compact-basic
@deepseek-ai/dsh-compact-basic"] @@ -79,10 +71,6 @@ flowchart LR | `bash` | `@deepseek-ai/dsh-bash-sandbox` | | `approval` | `@deepseek-ai/dsh-user-approval` | | `acp-agent` | `@deepseek-ai/dsh-acp-demo` | -| `tool-session-query` | `@deepseek-ai/dsh-tool-session-query` | -| `timeout-policy` | `@deepseek-ai/dsh-timeout-policy` | -| `spill-local` | `@deepseek-ai/dsh-spill-local` | -| `spill-policy` | `@deepseek-ai/dsh-spill-policy` | | `token-meter` | `@deepseek-ai/dsh-token-meter` | | `compact-basic` | `@deepseek-ai/dsh-compact-basic` | | `subagent` | `@deepseek-ai/dsh-subagent` | diff --git a/examples/acp-agent/cordis.yml b/examples/acp-agent/cordis.yml index 484809db04..fa7f6ad4ef 100644 --- a/examples/acp-agent/cordis.yml +++ b/examples/acp-agent/cordis.yml @@ -63,26 +63,6 @@ Verify your work by running the code or tests. Keep answers brief and factual. -# The automation app opens ctx.sessionQuery before its ACP transport; this leaf -# owns the workspace-authorized model-facing consumer. -- id: tool-session-query - name: '@deepseek-ai/dsh-tool-session-query' - -# Enforce declared search deadlines and spill oversized plain-text tool output -# without introducing a session-query-specific truncation path. -- id: timeout-policy - name: '@deepseek-ai/dsh-timeout-policy' - -- id: spill-local - name: '@deepseek-ai/dsh-spill-local' - config: - root: !!js process.env.DSH_SNAPSHOT_SPILL_ROOT - -- id: spill-policy - name: '@deepseek-ai/dsh-spill-policy' - config: - maxInlineBytes: 50000 - # Replay-aware request pressure; the routed adapter supplies model capacity. - id: token-meter name: '@deepseek-ai/dsh-token-meter' diff --git a/examples/acp-agent/fs.cordis.snapshot.yml b/examples/acp-agent/fs.cordis.snapshot.yml index 29cef3fe82..0417074edd 100644 --- a/examples/acp-agent/fs.cordis.snapshot.yml +++ b/examples/acp-agent/fs.cordis.snapshot.yml @@ -1,6 +1,7 @@ -# Keyless filesystem snapshots patch the base spill stack and apply the replay -# overlay directly. The sandboxed filesystem stack already lives in the base -# cordis.yml. This file also re-pins the acp-agent model to `deepseek-v4-flash`: `cordis.yml` ships +# Keyless filesystem snapshots apply the spill and replay overlays directly +# because include patches cannot target entries behind a nested include. The +# sandboxed filesystem stack already lives in the base cordis.yml. This file also +# re-pins the acp-agent model to `deepseek-v4-flash`: `cordis.yml` ships # `deepseek-v4-pro`, but the recorded corpus was captured on flash, and a config # patch replaces the whole app config, so the base fields are restated verbatim. - id: base @@ -24,15 +25,15 @@ You are a coding assistant powered by the {{model}} model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug. Verify your work by running the code or tests. Keep answers brief and factual. - - id: spill-local - name: '@deepseek-ai/dsh-spill-local' - config: - root: !!js process.env.DSH_SNAPSHOT_SPILL_ROOT ?? './.spill' - - id: spill-policy - name: '@deepseek-ai/dsh-spill-policy' - config: - maxInlineBytes: 800 - insert: + - id: spill-local + name: '@deepseek-ai/dsh-spill-local' + config: + root: !!js process.env.DSH_SNAPSHOT_SPILL_ROOT ?? './.spill' + - id: spill-policy + name: '@deepseek-ai/dsh-spill-policy' + config: + maxInlineBytes: 800 - id: llm-replay name: '@deepseek-ai/dsh-llm-replay' config: diff --git a/examples/acp-agent/fs.cordis.yml b/examples/acp-agent/fs.cordis.yml index 4528ccf7c0..0d667255c8 100644 --- a/examples/acp-agent/fs.cordis.yml +++ b/examples/acp-agent/fs.cordis.yml @@ -1,16 +1,17 @@ -# Filesystem-scenario overlay: the sandboxed filesystem and generic spill stacks -# already live in the base cordis.yml, so this overlay only redirects spill -# storage and lowers the inline threshold for dedicated scenarios. +# Filesystem-scenario overlay: the sandboxed filesystem stack already lives in +# the base cordis.yml, so this overlay adds only the local tool-result spill +# storage those scenarios exercise. - id: base name: '@cordisjs/plugin-include' config: path: ./cordis.yml patches: - - id: spill-local - name: '@deepseek-ai/dsh-spill-local' - config: - root: !!js process.env.DSH_SNAPSHOT_SPILL_ROOT ?? './.spill' - - id: spill-policy - name: '@deepseek-ai/dsh-spill-policy' - config: - maxInlineBytes: !!js process.env.DSH_SNAPSHOT && 800 || 50000 + - insert: + - id: spill-local + name: '@deepseek-ai/dsh-spill-local' + config: + root: !!js process.env.DSH_SNAPSHOT_SPILL_ROOT ?? './.spill' + - id: spill-policy + name: '@deepseek-ai/dsh-spill-policy' + config: + maxInlineBytes: !!js process.env.DSH_SNAPSHOT && 800 || 50000 diff --git a/examples/acp-agent/session-query.cordis.snapshot.yml b/examples/acp-agent/session-query.cordis.snapshot.yml new file mode 100644 index 0000000000..1edadf8374 --- /dev/null +++ b/examples/acp-agent/session-query.cordis.snapshot.yml @@ -0,0 +1,12 @@ +# Keyless counterpart to session-query.cordis.yml: the nested snapshot overlay +# supplies replay plus deterministic private spill storage and its byte limit. +- id: base + name: '@cordisjs/plugin-include' + config: + path: ./fs.cordis.snapshot.yml + patches: + - insert: + - id: tool-session-query + name: '@deepseek-ai/dsh-tool-session-query' + - id: timeout-policy + name: '@deepseek-ai/dsh-timeout-policy' diff --git a/examples/acp-agent/session-query.cordis.yml b/examples/acp-agent/session-query.cordis.yml new file mode 100644 index 0000000000..e5e45025df --- /dev/null +++ b/examples/acp-agent/session-query.cordis.yml @@ -0,0 +1,12 @@ +# Explicit session-query tool opt-in for the dedicated spill scenario. The +# nested filesystem overlay supplies private spill storage and its byte limit. +- id: base + name: '@cordisjs/plugin-include' + config: + path: ./fs.cordis.yml + patches: + - insert: + - id: tool-session-query + name: '@deepseek-ai/dsh-tool-session-query' + - id: timeout-policy + name: '@deepseek-ai/dsh-timeout-policy' diff --git a/examples/acp-agent/tests/acp.snapshot.ts b/examples/acp-agent/tests/acp.snapshot.ts index f7fa1a2a47..8e74711a57 100644 --- a/examples/acp-agent/tests/acp.snapshot.ts +++ b/examples/acp-agent/tests/acp.snapshot.ts @@ -34,6 +34,7 @@ const BOTH_MODE_CONFIG = fileURLToPath(new URL('../both-mode.cordis.yml', import const WORKSPACE_CONTEXT_CONFIG = fileURLToPath(new URL('../workspace-context.cordis.yml', import.meta.url)) const ADVANCED_CONFIG = fileURLToPath(new URL('../advanced.cordis.yml', import.meta.url)) const FS_CONFIG = fileURLToPath(new URL('../fs.cordis.yml', import.meta.url)) +const SESSION_QUERY_CONFIG = fileURLToPath(new URL('../session-query.cordis.yml', import.meta.url)) const PTY_CONFIG = fileURLToPath(new URL('../pty.cordis.yml', import.meta.url)) const DEPTH_TWO_CONFIG = fileURLToPath(new URL('../depth-two.cordis.yml', import.meta.url)) const PACKED_CHUNKS_CONFIG = fileURLToPath(new URL('../packed-chunks.cordis.yml', import.meta.url)) @@ -92,7 +93,9 @@ const SCENARIOS: Scenario[] = [ name: 'session-query-spill', hasModelTurn: true, recorded: false, - configPath: FS_CONFIG, + pinsHeader: true, + headerClass: 'session-query', + configPath: SESSION_QUERY_CONFIG, posixOnly: true, }, { diff --git a/examples/acp-agent/tests/snapshots/advanced-toolchain/system-prompt.expected.md b/examples/acp-agent/tests/snapshots/advanced-toolchain/system-prompt.expected.md index d45a386c99..fde52770d5 100644 --- a/examples/acp-agent/tests/snapshots/advanced-toolchain/system-prompt.expected.md +++ b/examples/acp-agent/tests/snapshots/advanced-toolchain/system-prompt.expected.md @@ -15,8 +15,6 @@ Check the [exit code: N] marker on every bash result; investigate failures befor Track every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering. -Use session_search to find relevant work from prior sessions, or session_event_search to search earlier events in one session. Search results are cursor-free and workspace-scoped. Follow a useful hit with session_trace, session_event_trace, or session_event_read when you need lineage, relationships, or exact data. - Use goal tools for one long-running completion objective in the current session. create_goal may infer goal intent from a direct human request in any language; do not create a goal for routine single-turn work. Call get_goal before update_goal and copy its exact goal_id and revision. After session resume or fork, an active goal is disarmed: when a human asks to continue or resume in any wording or language, use update_goal action resume to rearm it. Mark complete only when the objective is actually achieved. Mark blocked only after the same blocking condition persists for at least 3 consecutive goal rounds, and report that concrete condition in blocked_reason; difficulty, uncertainty, or useful remaining work is not blocked. Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`). @@ -115,77 +113,6 @@ interface ToolArgsMap { /** Maximum number of lines to return. Defaults to 2000. */ limit?: number; } & Record; - /** Read one full unabridged event and optional neighboring raw-event summaries from an authorized session. */ - session_event_read: { - /** Target session id. Omit for the current session. */ - session_id?: string; - /** Target event sequence number. */ - seq: number; - /** Number of preceding raw events to summarize. Omit for none. */ - before?: number; - /** Number of following raw events to summarize. Omit for none. */ - after?: number; - } & Record; - /** Search prior events in one authorized session; the current session excludes the step performing this call. */ - session_event_search: { - /** Target session id. Omit for the current session. */ - session_id?: string; - /** Literal full-text query over the target session. */ - query: string; - /** Inclusive event sequence lower bound. */ - seq_from?: number; - /** Inclusive event sequence upper bound. */ - seq_to?: number; - /** Inclusive timezone-qualified ISO 8601 event-time lower bound. */ - time_from?: string; - /** Inclusive timezone-qualified ISO 8601 event-time upper bound. */ - time_to?: string; - /** Event types to include. */ - event_types?: string[]; - /** Event surfaces to include. */ - surfaces?: ("current" | "shadowed" | "log-only")[]; - } & Record; - /** Read every direct replacement and provenance relationship for one event in an authorized session. */ - session_event_trace: { - /** Target session id. Omit for the current session. */ - session_id?: string; - /** Target event sequence number. */ - seq: number; - } & Record; - /** Search prior sessions in the caller workspace and return the strongest matching event from each session. */ - session_search: { - /** Literal full-text query over prior session history. */ - query: string; - /** Optional session ids to include. */ - session_ids?: string[]; - /** Inclusive timezone-qualified ISO 8601 creation-time lower bound. */ - created_at_from?: string; - /** Inclusive timezone-qualified ISO 8601 creation-time upper bound. */ - created_at_to?: string; - /** Optional direct parent session ids. */ - parent_session_ids?: string[]; - /** Include sessions with no parent in the parent filter. */ - include_root_sessions?: boolean; - /** Require at least one selected source availability. */ - availability?: ("live" | "persisted")[]; - /** Inclusive event sequence lower bound. */ - event_seq_from?: number; - /** Inclusive event sequence upper bound. */ - event_seq_to?: number; - /** Inclusive timezone-qualified ISO 8601 event-time lower bound. */ - event_time_from?: string; - /** Inclusive timezone-qualified ISO 8601 event-time upper bound. */ - event_time_to?: string; - /** Event types to include. */ - event_types?: string[]; - /** Event surfaces to include. */ - event_surfaces?: ("current" | "shadowed" | "log-only")[]; - } & Record; - /** Read the authorized session lineage around one session, including complete visible ancestor and descendant relationships. */ - session_trace: { - /** Target session id. Omit for the current session. */ - session_id?: string; - } & Record; /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */ skill: { /** The exact skill name from the available skills list. */ @@ -385,11 +312,6 @@ interface ToolOutputMap { }[]; totalLines: number; }; - session_event_read: string; - session_event_search: string; - session_event_trace: string; - session_search: string; - session_trace: string; skill: { name: string; provider: string; diff --git a/examples/acp-agent/tests/snapshots/advanced-toolchain/tool-schemas.expected.json b/examples/acp-agent/tests/snapshots/advanced-toolchain/tool-schemas.expected.json index bb239d8c2d..73b9176478 100644 --- a/examples/acp-agent/tests/snapshots/advanced-toolchain/tool-schemas.expected.json +++ b/examples/acp-agent/tests/snapshots/advanced-toolchain/tool-schemas.expected.json @@ -232,210 +232,6 @@ ] } }, - { - "name": "session_event_read", - "description": "Read one full unabridged event and optional neighboring raw-event summaries from an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - }, - "before": { - "type": "integer", - "description": "Number of preceding raw events to summarize. Omit for none." - }, - "after": { - "type": "integer", - "description": "Number of following raw events to summarize. Omit for none." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_event_search", - "description": "Search prior events in one authorized session; the current session excludes the step performing this call.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "query": { - "type": "string", - "description": "Literal full-text query over the target session." - }, - "seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_event_trace", - "description": "Read every direct replacement and provenance relationship for one event in an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_search", - "description": "Search prior sessions in the caller workspace and return the strongest matching event from each session.", - "parameters": { - "type": "object", - "properties": { - "query": { - "type": "string", - "description": "Literal full-text query over prior session history." - }, - "session_ids": { - "type": "array", - "description": "Optional session ids to include.", - "items": { - "type": "string" - } - }, - "created_at_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time lower bound." - }, - "created_at_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time upper bound." - }, - "parent_session_ids": { - "type": "array", - "description": "Optional direct parent session ids.", - "items": { - "type": "string" - } - }, - "include_root_sessions": { - "type": "boolean", - "description": "Include sessions with no parent in the parent filter." - }, - "availability": { - "type": "array", - "description": "Require at least one selected source availability.", - "items": { - "type": "string", - "enum": [ - "live", - "persisted" - ] - } - }, - "event_seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "event_seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "event_time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "event_time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "event_surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_trace", - "description": "Read the authorized session lineage around one session, including complete visible ancestor and descendant relationships.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - } - } - } - }, { "name": "skill", "description": "Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.", diff --git a/examples/acp-agent/tests/snapshots/both-mode-turn/system-prompt.expected.md b/examples/acp-agent/tests/snapshots/both-mode-turn/system-prompt.expected.md index b66bb0de0c..3817b0bc8a 100644 --- a/examples/acp-agent/tests/snapshots/both-mode-turn/system-prompt.expected.md +++ b/examples/acp-agent/tests/snapshots/both-mode-turn/system-prompt.expected.md @@ -15,8 +15,6 @@ Check the [exit code: N] marker on every bash result; investigate failures befor Track every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering. -Use session_search to find relevant work from prior sessions, or session_event_search to search earlier events in one session. Search results are cursor-free and workspace-scoped. Follow a useful hit with session_trace, session_event_trace, or session_event_read when you need lineage, relationships, or exact data. - Use goal tools for one long-running completion objective in the current session. create_goal may infer goal intent from a direct human request in any language; do not create a goal for routine single-turn work. Call get_goal before update_goal and copy its exact goal_id and revision. After session resume or fork, an active goal is disarmed: when a human asks to continue or resume in any wording or language, use update_goal action resume to rearm it. Mark complete only when the objective is actually achieved. Mark blocked only after the same blocking condition persists for at least 3 consecutive goal rounds, and report that concrete condition in blocked_reason; difficulty, uncertainty, or useful remaining work is not blocked. Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`). @@ -98,77 +96,6 @@ interface ToolArgsMap { /** Maximum number of lines to return. Defaults to 2000. */ limit?: number; } & Record; - /** Read one full unabridged event and optional neighboring raw-event summaries from an authorized session. */ - session_event_read: { - /** Target session id. Omit for the current session. */ - session_id?: string; - /** Target event sequence number. */ - seq: number; - /** Number of preceding raw events to summarize. Omit for none. */ - before?: number; - /** Number of following raw events to summarize. Omit for none. */ - after?: number; - } & Record; - /** Search prior events in one authorized session; the current session excludes the step performing this call. */ - session_event_search: { - /** Target session id. Omit for the current session. */ - session_id?: string; - /** Literal full-text query over the target session. */ - query: string; - /** Inclusive event sequence lower bound. */ - seq_from?: number; - /** Inclusive event sequence upper bound. */ - seq_to?: number; - /** Inclusive timezone-qualified ISO 8601 event-time lower bound. */ - time_from?: string; - /** Inclusive timezone-qualified ISO 8601 event-time upper bound. */ - time_to?: string; - /** Event types to include. */ - event_types?: string[]; - /** Event surfaces to include. */ - surfaces?: ("current" | "shadowed" | "log-only")[]; - } & Record; - /** Read every direct replacement and provenance relationship for one event in an authorized session. */ - session_event_trace: { - /** Target session id. Omit for the current session. */ - session_id?: string; - /** Target event sequence number. */ - seq: number; - } & Record; - /** Search prior sessions in the caller workspace and return the strongest matching event from each session. */ - session_search: { - /** Literal full-text query over prior session history. */ - query: string; - /** Optional session ids to include. */ - session_ids?: string[]; - /** Inclusive timezone-qualified ISO 8601 creation-time lower bound. */ - created_at_from?: string; - /** Inclusive timezone-qualified ISO 8601 creation-time upper bound. */ - created_at_to?: string; - /** Optional direct parent session ids. */ - parent_session_ids?: string[]; - /** Include sessions with no parent in the parent filter. */ - include_root_sessions?: boolean; - /** Require at least one selected source availability. */ - availability?: ("live" | "persisted")[]; - /** Inclusive event sequence lower bound. */ - event_seq_from?: number; - /** Inclusive event sequence upper bound. */ - event_seq_to?: number; - /** Inclusive timezone-qualified ISO 8601 event-time lower bound. */ - event_time_from?: string; - /** Inclusive timezone-qualified ISO 8601 event-time upper bound. */ - event_time_to?: string; - /** Event types to include. */ - event_types?: string[]; - /** Event surfaces to include. */ - event_surfaces?: ("current" | "shadowed" | "log-only")[]; - } & Record; - /** Read the authorized session lineage around one session, including complete visible ancestor and descendant relationships. */ - session_trace: { - /** Target session id. Omit for the current session. */ - session_id?: string; - } & Record; /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */ skill: { /** The exact skill name from the available skills list. */ @@ -356,11 +283,6 @@ interface ToolOutputMap { }[]; totalLines: number; }; - session_event_read: string; - session_event_search: string; - session_event_trace: string; - session_search: string; - session_trace: string; skill: { name: string; provider: string; diff --git a/examples/acp-agent/tests/snapshots/both-mode-turn/tool-schemas.expected.json b/examples/acp-agent/tests/snapshots/both-mode-turn/tool-schemas.expected.json index ac3323d626..0fc8107917 100644 --- a/examples/acp-agent/tests/snapshots/both-mode-turn/tool-schemas.expected.json +++ b/examples/acp-agent/tests/snapshots/both-mode-turn/tool-schemas.expected.json @@ -175,210 +175,6 @@ ] } }, - { - "name": "session_event_read", - "description": "Read one full unabridged event and optional neighboring raw-event summaries from an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - }, - "before": { - "type": "integer", - "description": "Number of preceding raw events to summarize. Omit for none." - }, - "after": { - "type": "integer", - "description": "Number of following raw events to summarize. Omit for none." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_event_search", - "description": "Search prior events in one authorized session; the current session excludes the step performing this call.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "query": { - "type": "string", - "description": "Literal full-text query over the target session." - }, - "seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_event_trace", - "description": "Read every direct replacement and provenance relationship for one event in an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_search", - "description": "Search prior sessions in the caller workspace and return the strongest matching event from each session.", - "parameters": { - "type": "object", - "properties": { - "query": { - "type": "string", - "description": "Literal full-text query over prior session history." - }, - "session_ids": { - "type": "array", - "description": "Optional session ids to include.", - "items": { - "type": "string" - } - }, - "created_at_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time lower bound." - }, - "created_at_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time upper bound." - }, - "parent_session_ids": { - "type": "array", - "description": "Optional direct parent session ids.", - "items": { - "type": "string" - } - }, - "include_root_sessions": { - "type": "boolean", - "description": "Include sessions with no parent in the parent filter." - }, - "availability": { - "type": "array", - "description": "Require at least one selected source availability.", - "items": { - "type": "string", - "enum": [ - "live", - "persisted" - ] - } - }, - "event_seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "event_seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "event_time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "event_time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "event_surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_trace", - "description": "Read the authorized session lineage around one session, including complete visible ancestor and descendant relationships.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - } - } - } - }, { "name": "skill", "description": "Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.", diff --git a/examples/acp-agent/tests/snapshots/code-mode-turn/system-prompt.expected.md b/examples/acp-agent/tests/snapshots/code-mode-turn/system-prompt.expected.md index b66bb0de0c..3817b0bc8a 100644 --- a/examples/acp-agent/tests/snapshots/code-mode-turn/system-prompt.expected.md +++ b/examples/acp-agent/tests/snapshots/code-mode-turn/system-prompt.expected.md @@ -15,8 +15,6 @@ Check the [exit code: N] marker on every bash result; investigate failures befor Track every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering. -Use session_search to find relevant work from prior sessions, or session_event_search to search earlier events in one session. Search results are cursor-free and workspace-scoped. Follow a useful hit with session_trace, session_event_trace, or session_event_read when you need lineage, relationships, or exact data. - Use goal tools for one long-running completion objective in the current session. create_goal may infer goal intent from a direct human request in any language; do not create a goal for routine single-turn work. Call get_goal before update_goal and copy its exact goal_id and revision. After session resume or fork, an active goal is disarmed: when a human asks to continue or resume in any wording or language, use update_goal action resume to rearm it. Mark complete only when the objective is actually achieved. Mark blocked only after the same blocking condition persists for at least 3 consecutive goal rounds, and report that concrete condition in blocked_reason; difficulty, uncertainty, or useful remaining work is not blocked. Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`). @@ -98,77 +96,6 @@ interface ToolArgsMap { /** Maximum number of lines to return. Defaults to 2000. */ limit?: number; } & Record; - /** Read one full unabridged event and optional neighboring raw-event summaries from an authorized session. */ - session_event_read: { - /** Target session id. Omit for the current session. */ - session_id?: string; - /** Target event sequence number. */ - seq: number; - /** Number of preceding raw events to summarize. Omit for none. */ - before?: number; - /** Number of following raw events to summarize. Omit for none. */ - after?: number; - } & Record; - /** Search prior events in one authorized session; the current session excludes the step performing this call. */ - session_event_search: { - /** Target session id. Omit for the current session. */ - session_id?: string; - /** Literal full-text query over the target session. */ - query: string; - /** Inclusive event sequence lower bound. */ - seq_from?: number; - /** Inclusive event sequence upper bound. */ - seq_to?: number; - /** Inclusive timezone-qualified ISO 8601 event-time lower bound. */ - time_from?: string; - /** Inclusive timezone-qualified ISO 8601 event-time upper bound. */ - time_to?: string; - /** Event types to include. */ - event_types?: string[]; - /** Event surfaces to include. */ - surfaces?: ("current" | "shadowed" | "log-only")[]; - } & Record; - /** Read every direct replacement and provenance relationship for one event in an authorized session. */ - session_event_trace: { - /** Target session id. Omit for the current session. */ - session_id?: string; - /** Target event sequence number. */ - seq: number; - } & Record; - /** Search prior sessions in the caller workspace and return the strongest matching event from each session. */ - session_search: { - /** Literal full-text query over prior session history. */ - query: string; - /** Optional session ids to include. */ - session_ids?: string[]; - /** Inclusive timezone-qualified ISO 8601 creation-time lower bound. */ - created_at_from?: string; - /** Inclusive timezone-qualified ISO 8601 creation-time upper bound. */ - created_at_to?: string; - /** Optional direct parent session ids. */ - parent_session_ids?: string[]; - /** Include sessions with no parent in the parent filter. */ - include_root_sessions?: boolean; - /** Require at least one selected source availability. */ - availability?: ("live" | "persisted")[]; - /** Inclusive event sequence lower bound. */ - event_seq_from?: number; - /** Inclusive event sequence upper bound. */ - event_seq_to?: number; - /** Inclusive timezone-qualified ISO 8601 event-time lower bound. */ - event_time_from?: string; - /** Inclusive timezone-qualified ISO 8601 event-time upper bound. */ - event_time_to?: string; - /** Event types to include. */ - event_types?: string[]; - /** Event surfaces to include. */ - event_surfaces?: ("current" | "shadowed" | "log-only")[]; - } & Record; - /** Read the authorized session lineage around one session, including complete visible ancestor and descendant relationships. */ - session_trace: { - /** Target session id. Omit for the current session. */ - session_id?: string; - } & Record; /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */ skill: { /** The exact skill name from the available skills list. */ @@ -356,11 +283,6 @@ interface ToolOutputMap { }[]; totalLines: number; }; - session_event_read: string; - session_event_search: string; - session_event_trace: string; - session_search: string; - session_trace: string; skill: { name: string; provider: string; diff --git a/examples/acp-agent/tests/snapshots/code-mode-workspace-context/system-prompt.expected.md b/examples/acp-agent/tests/snapshots/code-mode-workspace-context/system-prompt.expected.md index b66bb0de0c..3817b0bc8a 100644 --- a/examples/acp-agent/tests/snapshots/code-mode-workspace-context/system-prompt.expected.md +++ b/examples/acp-agent/tests/snapshots/code-mode-workspace-context/system-prompt.expected.md @@ -15,8 +15,6 @@ Check the [exit code: N] marker on every bash result; investigate failures befor Track every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering. -Use session_search to find relevant work from prior sessions, or session_event_search to search earlier events in one session. Search results are cursor-free and workspace-scoped. Follow a useful hit with session_trace, session_event_trace, or session_event_read when you need lineage, relationships, or exact data. - Use goal tools for one long-running completion objective in the current session. create_goal may infer goal intent from a direct human request in any language; do not create a goal for routine single-turn work. Call get_goal before update_goal and copy its exact goal_id and revision. After session resume or fork, an active goal is disarmed: when a human asks to continue or resume in any wording or language, use update_goal action resume to rearm it. Mark complete only when the objective is actually achieved. Mark blocked only after the same blocking condition persists for at least 3 consecutive goal rounds, and report that concrete condition in blocked_reason; difficulty, uncertainty, or useful remaining work is not blocked. Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`). @@ -98,77 +96,6 @@ interface ToolArgsMap { /** Maximum number of lines to return. Defaults to 2000. */ limit?: number; } & Record; - /** Read one full unabridged event and optional neighboring raw-event summaries from an authorized session. */ - session_event_read: { - /** Target session id. Omit for the current session. */ - session_id?: string; - /** Target event sequence number. */ - seq: number; - /** Number of preceding raw events to summarize. Omit for none. */ - before?: number; - /** Number of following raw events to summarize. Omit for none. */ - after?: number; - } & Record; - /** Search prior events in one authorized session; the current session excludes the step performing this call. */ - session_event_search: { - /** Target session id. Omit for the current session. */ - session_id?: string; - /** Literal full-text query over the target session. */ - query: string; - /** Inclusive event sequence lower bound. */ - seq_from?: number; - /** Inclusive event sequence upper bound. */ - seq_to?: number; - /** Inclusive timezone-qualified ISO 8601 event-time lower bound. */ - time_from?: string; - /** Inclusive timezone-qualified ISO 8601 event-time upper bound. */ - time_to?: string; - /** Event types to include. */ - event_types?: string[]; - /** Event surfaces to include. */ - surfaces?: ("current" | "shadowed" | "log-only")[]; - } & Record; - /** Read every direct replacement and provenance relationship for one event in an authorized session. */ - session_event_trace: { - /** Target session id. Omit for the current session. */ - session_id?: string; - /** Target event sequence number. */ - seq: number; - } & Record; - /** Search prior sessions in the caller workspace and return the strongest matching event from each session. */ - session_search: { - /** Literal full-text query over prior session history. */ - query: string; - /** Optional session ids to include. */ - session_ids?: string[]; - /** Inclusive timezone-qualified ISO 8601 creation-time lower bound. */ - created_at_from?: string; - /** Inclusive timezone-qualified ISO 8601 creation-time upper bound. */ - created_at_to?: string; - /** Optional direct parent session ids. */ - parent_session_ids?: string[]; - /** Include sessions with no parent in the parent filter. */ - include_root_sessions?: boolean; - /** Require at least one selected source availability. */ - availability?: ("live" | "persisted")[]; - /** Inclusive event sequence lower bound. */ - event_seq_from?: number; - /** Inclusive event sequence upper bound. */ - event_seq_to?: number; - /** Inclusive timezone-qualified ISO 8601 event-time lower bound. */ - event_time_from?: string; - /** Inclusive timezone-qualified ISO 8601 event-time upper bound. */ - event_time_to?: string; - /** Event types to include. */ - event_types?: string[]; - /** Event surfaces to include. */ - event_surfaces?: ("current" | "shadowed" | "log-only")[]; - } & Record; - /** Read the authorized session lineage around one session, including complete visible ancestor and descendant relationships. */ - session_trace: { - /** Target session id. Omit for the current session. */ - session_id?: string; - } & Record; /** Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill. */ skill: { /** The exact skill name from the available skills list. */ @@ -356,11 +283,6 @@ interface ToolOutputMap { }[]; totalLines: number; }; - session_event_read: string; - session_event_search: string; - session_event_trace: string; - session_search: string; - session_trace: string; skill: { name: string; provider: string; diff --git a/examples/acp-agent/tests/snapshots/escalation-approved/system-prompt.expected.md b/examples/acp-agent/tests/snapshots/escalation-approved/system-prompt.expected.md index 362d0a6355..e3437ad61a 100644 --- a/examples/acp-agent/tests/snapshots/escalation-approved/system-prompt.expected.md +++ b/examples/acp-agent/tests/snapshots/escalation-approved/system-prompt.expected.md @@ -15,8 +15,6 @@ Check the [exit code: N] marker on every bash result; investigate failures befor Track every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering. -Use session_search to find relevant work from prior sessions, or session_event_search to search earlier events in one session. Search results are cursor-free and workspace-scoped. Follow a useful hit with session_trace, session_event_trace, or session_event_read when you need lineage, relationships, or exact data. - Use goal tools for one long-running completion objective in the current session. create_goal may infer goal intent from a direct human request in any language; do not create a goal for routine single-turn work. Call get_goal before update_goal and copy its exact goal_id and revision. After session resume or fork, an active goal is disarmed: when a human asks to continue or resume in any wording or language, use update_goal action resume to rearm it. Mark complete only when the objective is actually achieved. Mark blocked only after the same blocking condition persists for at least 3 consecutive goal rounds, and report that concrete condition in blocked_reason; difficulty, uncertainty, or useful remaining work is not blocked. diff --git a/examples/acp-agent/tests/snapshots/escalation-approved/tool-schemas.expected.json b/examples/acp-agent/tests/snapshots/escalation-approved/tool-schemas.expected.json index dde0ba0d7a..d4973bfea4 100644 --- a/examples/acp-agent/tests/snapshots/escalation-approved/tool-schemas.expected.json +++ b/examples/acp-agent/tests/snapshots/escalation-approved/tool-schemas.expected.json @@ -159,210 +159,6 @@ ] } }, - { - "name": "session_event_read", - "description": "Read one full unabridged event and optional neighboring raw-event summaries from an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - }, - "before": { - "type": "integer", - "description": "Number of preceding raw events to summarize. Omit for none." - }, - "after": { - "type": "integer", - "description": "Number of following raw events to summarize. Omit for none." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_event_search", - "description": "Search prior events in one authorized session; the current session excludes the step performing this call.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "query": { - "type": "string", - "description": "Literal full-text query over the target session." - }, - "seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_event_trace", - "description": "Read every direct replacement and provenance relationship for one event in an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_search", - "description": "Search prior sessions in the caller workspace and return the strongest matching event from each session.", - "parameters": { - "type": "object", - "properties": { - "query": { - "type": "string", - "description": "Literal full-text query over prior session history." - }, - "session_ids": { - "type": "array", - "description": "Optional session ids to include.", - "items": { - "type": "string" - } - }, - "created_at_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time lower bound." - }, - "created_at_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time upper bound." - }, - "parent_session_ids": { - "type": "array", - "description": "Optional direct parent session ids.", - "items": { - "type": "string" - } - }, - "include_root_sessions": { - "type": "boolean", - "description": "Include sessions with no parent in the parent filter." - }, - "availability": { - "type": "array", - "description": "Require at least one selected source availability.", - "items": { - "type": "string", - "enum": [ - "live", - "persisted" - ] - } - }, - "event_seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "event_seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "event_time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "event_time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "event_surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_trace", - "description": "Read the authorized session lineage around one session, including complete visible ancestor and descendant relationships.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - } - } - } - }, { "name": "skill", "description": "Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.", diff --git a/examples/acp-agent/tests/snapshots/lsp-definition/system-prompt.expected.md b/examples/acp-agent/tests/snapshots/lsp-definition/system-prompt.expected.md index cb50752e91..7bde8fe289 100644 --- a/examples/acp-agent/tests/snapshots/lsp-definition/system-prompt.expected.md +++ b/examples/acp-agent/tests/snapshots/lsp-definition/system-prompt.expected.md @@ -17,8 +17,6 @@ Track every background task id you start. You are notified in-session when a tas Use search/read for ordinary navigation. Use lsp when textual matches are ambiguous or before a change requires precise definitions, implementations, or references. Positions are one-based line and character (UTF-16) at the cursor; an off-symbol position may return no results. findReferences always includes the declaration. -Use session_search to find relevant work from prior sessions, or session_event_search to search earlier events in one session. Search results are cursor-free and workspace-scoped. Follow a useful hit with session_trace, session_event_trace, or session_event_read when you need lineage, relationships, or exact data. - Use goal tools for one long-running completion objective in the current session. create_goal may infer goal intent from a direct human request in any language; do not create a goal for routine single-turn work. Call get_goal before update_goal and copy its exact goal_id and revision. After session resume or fork, an active goal is disarmed: when a human asks to continue or resume in any wording or language, use update_goal action resume to rearm it. Mark complete only when the objective is actually achieved. Mark blocked only after the same blocking condition persists for at least 3 consecutive goal rounds, and report that concrete condition in blocked_reason; difficulty, uncertainty, or useful remaining work is not blocked. Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`). diff --git a/examples/acp-agent/tests/snapshots/lsp-definition/tool-schemas.expected.json b/examples/acp-agent/tests/snapshots/lsp-definition/tool-schemas.expected.json index 3d28b1dfb8..5d27e93da3 100644 --- a/examples/acp-agent/tests/snapshots/lsp-definition/tool-schemas.expected.json +++ b/examples/acp-agent/tests/snapshots/lsp-definition/tool-schemas.expected.json @@ -196,210 +196,6 @@ ] } }, - { - "name": "session_event_read", - "description": "Read one full unabridged event and optional neighboring raw-event summaries from an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - }, - "before": { - "type": "integer", - "description": "Number of preceding raw events to summarize. Omit for none." - }, - "after": { - "type": "integer", - "description": "Number of following raw events to summarize. Omit for none." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_event_search", - "description": "Search prior events in one authorized session; the current session excludes the step performing this call.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "query": { - "type": "string", - "description": "Literal full-text query over the target session." - }, - "seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_event_trace", - "description": "Read every direct replacement and provenance relationship for one event in an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_search", - "description": "Search prior sessions in the caller workspace and return the strongest matching event from each session.", - "parameters": { - "type": "object", - "properties": { - "query": { - "type": "string", - "description": "Literal full-text query over prior session history." - }, - "session_ids": { - "type": "array", - "description": "Optional session ids to include.", - "items": { - "type": "string" - } - }, - "created_at_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time lower bound." - }, - "created_at_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time upper bound." - }, - "parent_session_ids": { - "type": "array", - "description": "Optional direct parent session ids.", - "items": { - "type": "string" - } - }, - "include_root_sessions": { - "type": "boolean", - "description": "Include sessions with no parent in the parent filter." - }, - "availability": { - "type": "array", - "description": "Require at least one selected source availability.", - "items": { - "type": "string", - "enum": [ - "live", - "persisted" - ] - } - }, - "event_seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "event_seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "event_time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "event_time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "event_surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_trace", - "description": "Read the authorized session lineage around one session, including complete visible ancestor and descendant relationships.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - } - } - } - }, { "name": "skill", "description": "Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.", diff --git a/examples/acp-agent/tests/snapshots/pty-tools/system-prompt.expected.md b/examples/acp-agent/tests/snapshots/pty-tools/system-prompt.expected.md index ccce83d9b7..df065a83cb 100644 --- a/examples/acp-agent/tests/snapshots/pty-tools/system-prompt.expected.md +++ b/examples/acp-agent/tests/snapshots/pty-tools/system-prompt.expected.md @@ -17,8 +17,6 @@ Use a terminal session only when work needs persistent terminal state or interac Track every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering. -Use session_search to find relevant work from prior sessions, or session_event_search to search earlier events in one session. Search results are cursor-free and workspace-scoped. Follow a useful hit with session_trace, session_event_trace, or session_event_read when you need lineage, relationships, or exact data. - Use goal tools for one long-running completion objective in the current session. create_goal may infer goal intent from a direct human request in any language; do not create a goal for routine single-turn work. Call get_goal before update_goal and copy its exact goal_id and revision. After session resume or fork, an active goal is disarmed: when a human asks to continue or resume in any wording or language, use update_goal action resume to rearm it. Mark complete only when the objective is actually achieved. Mark blocked only after the same blocking condition persists for at least 3 consecutive goal rounds, and report that concrete condition in blocked_reason; difficulty, uncertainty, or useful remaining work is not blocked. Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`). diff --git a/examples/acp-agent/tests/snapshots/pty-tools/tool-schemas.expected.json b/examples/acp-agent/tests/snapshots/pty-tools/tool-schemas.expected.json index d29602b97d..e9f7a2ea63 100644 --- a/examples/acp-agent/tests/snapshots/pty-tools/tool-schemas.expected.json +++ b/examples/acp-agent/tests/snapshots/pty-tools/tool-schemas.expected.json @@ -159,210 +159,6 @@ ] } }, - { - "name": "session_event_read", - "description": "Read one full unabridged event and optional neighboring raw-event summaries from an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - }, - "before": { - "type": "integer", - "description": "Number of preceding raw events to summarize. Omit for none." - }, - "after": { - "type": "integer", - "description": "Number of following raw events to summarize. Omit for none." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_event_search", - "description": "Search prior events in one authorized session; the current session excludes the step performing this call.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "query": { - "type": "string", - "description": "Literal full-text query over the target session." - }, - "seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_event_trace", - "description": "Read every direct replacement and provenance relationship for one event in an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_search", - "description": "Search prior sessions in the caller workspace and return the strongest matching event from each session.", - "parameters": { - "type": "object", - "properties": { - "query": { - "type": "string", - "description": "Literal full-text query over prior session history." - }, - "session_ids": { - "type": "array", - "description": "Optional session ids to include.", - "items": { - "type": "string" - } - }, - "created_at_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time lower bound." - }, - "created_at_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time upper bound." - }, - "parent_session_ids": { - "type": "array", - "description": "Optional direct parent session ids.", - "items": { - "type": "string" - } - }, - "include_root_sessions": { - "type": "boolean", - "description": "Include sessions with no parent in the parent filter." - }, - "availability": { - "type": "array", - "description": "Require at least one selected source availability.", - "items": { - "type": "string", - "enum": [ - "live", - "persisted" - ] - } - }, - "event_seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "event_seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "event_time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "event_time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "event_surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_trace", - "description": "Read the authorized session lineage around one session, including complete visible ancestor and descendant relationships.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - } - } - } - }, { "name": "skill", "description": "Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.", diff --git a/examples/acp-agent/tests/snapshots/session-query-spill/session.jsonl b/examples/acp-agent/tests/snapshots/session-query-spill/session.jsonl index 6d8a294c1e..26fd2bf5c1 100644 --- a/examples/acp-agent/tests/snapshots/session-query-spill/session.jsonl +++ b/examples/acp-agent/tests/snapshots/session-query-spill/session.jsonl @@ -11,7 +11,7 @@ {"type":"assistant/chunk","seq":9,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}} {"type":"assistant/message","seq":10,"time":0,"data":{"turn":1,"step":1,"content":[{"type":"tool-call","id":"call_session_query_spill","name":"session_event_read","arguments":"{\"seq\":4}"}],"provenance":{"provider":"deepseek","model":"deepseek-v4-flash"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[5,6,7,8,9],"surfaceOp":"append"} {"type":"tool/call","seq":11,"time":0,"data":{"turn":1,"step":1,"callId":"call_session_query_spill","name":"session_event_read","arguments":"{\"seq\":4}"}} -{"type":"tool/result","seq":12,"time":0,"data":{"turn":1,"step":1,"callId":"call_session_query_spill","content":[{"type":"text","text":"Session {{sessionId}} — Read request event 4 with\nTarget event seq 4:\n```json\n{\n \"type\": \"request/header\",\n \"seq\": 4,\n \"time\": 1784876318672,\n \"data\": {\n \"header\": {\n \"config\": {\n \"provider\": \"deepseek\",\n \"model\": \"deepseek-v4-flash\"\n },\n rmissions: one sentence for the user explaining why this exact file operation needs the wider access.\"\n }\n },\n \"required\": [\n \"file_path\",\n \"content\"\n ]\n }\n }\n ]\n },\n \"reason\": \"initial\"\n }\n}\n```\n\n(Omitted 39431 bytes. Full formatted result stored at: /tmp/dsh-acp-snap-035d1d054/session-ac29d2afe494/505bce11df84-session_event_read.txt. Use read with offset/limit, or grep this path to search within it.)"}],"isError":false},"sourceEventSeqs":[11],"surfaceOp":"append"} +{"type":"tool/result","seq":12,"time":0,"data":{"turn":1,"step":1,"callId":"call_session_query_spill","content":[{"type":"text","text":"Session {{sessionId}} — Read request event 4 with\nTarget event seq 4:\n```json\n{\n \"type\": \"request/header\",\n \"seq\": 4,\n \"time\": 1784876318672,\n \"data\": {\n \"header\": {\n \"config\": {\n \"provider\": \"deepseek\",\n \"model\": \"deepseek-v4-flash\"\n },\n rmissions: one sentence for the user explaining why this exact file operation needs the wider access.\"\n }\n },\n \"required\": [\n \"file_path\",\n \"content\"\n ]\n }\n }\n ]\n },\n \"reason\": \"initial\"\n }\n}\n```\n\n(Omitted 36006 bytes. Full formatted result stored at: /tmp/dsh-acp-snap-035d1d054/session-ac29d2afe494/505bce11df84-session_event_read.txt. Use read with offset/limit, or grep this path to search within it.)"}],"isError":false},"sourceEventSeqs":[11],"surfaceOp":"append"} {"type":"step/end","seq":13,"time":0,"data":{"turn":1,"step":1}} {"type":"step/start","seq":14,"time":0,"data":{"turn":1,"step":2}} {"type":"assistant/chunk","seq":15,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}} diff --git a/examples/acp-agent/tests/snapshots/session-query-spill/system-prompt.expected.md b/examples/acp-agent/tests/snapshots/session-query-spill/system-prompt.expected.md new file mode 100644 index 0000000000..68bdd841c7 --- /dev/null +++ b/examples/acp-agent/tests/snapshots/session-query-spill/system-prompt.expected.md @@ -0,0 +1,27 @@ +You are an AI agent powered by the DeepSeek Harness SDK. + +You are a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}. Your bash tool runs under a file sandbox — a `[sandbox: file access denied …]` result is policy, not a command bug. + +Verify your work by running the code or tests. Keep answers brief and factual. + + +Use the read tool — not shell commands like cat — to inspect text files. Results include line numbers. Use offset and limit to continue reading large files. + +Use the write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-policy requires it) and prefer edit for targeted changes. + +Use the edit tool for targeted changes to existing UTF-8 text files. It replaces literal old_string with new_string; by default old_string must appear exactly once. If old_string appears multiple times, provide a more specific old_string or set replace_all to true. Read the file first (the default fs-policy requires it), unless you just created or edited it in this session. + +Check the [exit code: N] marker on every bash result; investigate failures before moving on. + +Track every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering. + +Use session_search to find relevant work from prior sessions, or session_event_search to search earlier events in one session. Search results are cursor-free and workspace-scoped. Follow a useful hit with session_trace, session_event_trace, or session_event_read when you need lineage, relationships, or exact data. + +Use goal tools for one long-running completion objective in the current session. create_goal may infer goal intent from a direct human request in any language; do not create a goal for routine single-turn work. Call get_goal before update_goal and copy its exact goal_id and revision. After session resume or fork, an active goal is disarmed: when a human asks to continue or resume in any wording or language, use update_goal action resume to rearm it. Mark complete only when the objective is actually achieved. Mark blocked only after the same blocking condition persists for at least 3 consecutive goal rounds, and report that concrete condition in blocked_reason; difficulty, uncertainty, or useful remaining work is not blocked. + +Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`). + + +Use the workflow tool ONLY when the user explicitly asks for a workflow or for large multi-agent orchestration: you write a JavaScript script (the tool description documents the exact format) that fans work out across many subagents with phases and structured results. For one or two delegations, prefer plain subagent calls. + +Use the ralph tool ONLY when the direct human explicitly asks for a Ralph loop or fresh-agent iterative execution. Each Ralph round starts a fresh child with no conversation seed and uses the shared workspace as durable memory. Completion and blockers are worker reports, not independent evaluation. Use same-session goal tools for ordinary long-running objectives, and plain subagents or workflows for bounded delegation and fan-out. diff --git a/examples/acp-agent/tests/snapshots/session-query-spill/tool-schemas.expected.json b/examples/acp-agent/tests/snapshots/session-query-spill/tool-schemas.expected.json new file mode 100644 index 0000000000..dde0ba0d7a --- /dev/null +++ b/examples/acp-agent/tests/snapshots/session-query-spill/tool-schemas.expected.json @@ -0,0 +1,677 @@ +{ + "initial": [ + { + "name": "bash", + "description": "Execute a bash command (`bash -c`) and return its stdout/stderr. Each call runs in a fresh shell: no state (cwd, variables, functions) persists between calls — pass `workdir` instead of using `cd`. Non-zero exits are reported as `[exit code: N]`. Current harness environment facts are exposed through managed `$DSH_*` variables; inspect them when needed. Commands may run under a file sandbox; a blocked file operation is reported as `[sandbox: file access denied under mode]` — a policy denial, not a bug in the command; do not retry another way. Long output is truncated to its tail; the full output is saved to a file whose path is reported when available. Set `run_in_background: true` for long-running commands: the call returns a task id immediately; read its output with `task_output` and stop it with `task_kill`. Attempting a command the sandbox may deny is safe and expected: run it and read the marker rather than assuming the denial. When a command is denied and a wider mode would let it succeed, escalate immediately in the same turn — the one sanctioned exception to a denial: retry the exact same command once with `sandbox_permissions` (the narrowest wider mode that suffices) plus a one-sentence `justification`. Do not detour through chat to ask permission first — the approval prompt raised by that retry is how the user consents. If the session states approval prompts are disabled, there is no exception: a denial is final — do not set `sandbox_permissions`. Never escalate speculatively: ground the request in a real denial — normally the one this command just hit; escalating up front is fine only when this session already denied the same access. A rejected escalation is final for that command — stop and explain, never work around it — but it does not forbid attempting or escalating other commands later.", + "parameters": { + "type": "object", + "properties": { + "command": { + "type": "string", + "description": "The bash command to execute." + }, + "description": { + "type": "string", + "description": "Clear, concise description of what this command does in active voice, 5-10 words (shown in the UI). Examples: \"ls\" → \"List files in current directory\"; \"git status\" → \"Show working tree status\"; \"npm install\" → \"Install package dependencies\"." + }, + "timeoutMs": { + "type": "number", + "description": "Timeout in milliseconds. The executor applies its configured default and cap, and kills the command on expiry." + }, + "workdir": { + "type": "string", + "description": "Working directory for this command. Defaults to the session workspace; a relative path is resolved against it." + }, + "run_in_background": { + "type": "boolean", + "description": "Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies." + }, + "sandbox_permissions": { + "type": "string", + "description": "The wider sandbox mode this command needs. Only valid as a one-shot retry of a command the sandbox just denied; requires justification and user approval.", + "enum": [ + "workspace-write", + "danger-full-access" + ] + }, + "justification": { + "type": "string", + "description": "Required with sandbox_permissions: one sentence for the user explaining why this exact command needs the wider access." + } + }, + "required": [ + "command", + "description" + ] + } + }, + { + "name": "create_goal", + "description": "Create one persisted same-session completion goal when the current direct human request is a long-running objective that should continue across autonomous goal rounds. You may infer that intent without requiring the user to say \"create a goal\". Do not use this for trivial single-turn work. Execution rejects non-human and subagent authority.", + "parameters": { + "type": "object", + "properties": { + "objective": { + "type": "string", + "description": "The concrete completion objective inferred from the direct human request." + }, + "max_goal_rounds": { + "type": "number", + "description": "Optional positive safe-integer limit on automatic continuation rounds." + } + }, + "required": [ + "objective" + ] + } + }, + { + "name": "edit", + "description": "Edit an existing UTF-8 text file by replacing literal text.", + "parameters": { + "type": "object", + "properties": { + "file_path": { + "type": "string", + "description": "Path to edit, resolved by the filesystem backend." + }, + "old_string": { + "type": "string", + "description": "Literal text to replace. Must match exactly." + }, + "new_string": { + "type": "string", + "description": "Literal replacement text. Use an empty string to delete the match." + }, + "replace_all": { + "type": "boolean", + "description": "Replace all matches. Defaults to false; when false, old_string must appear exactly once." + }, + "sandbox_permissions": { + "type": "string", + "description": "The wider sandbox mode this file operation needs. Only valid as a one-shot retry of an operation the sandbox just denied; requires justification and user approval.", + "enum": [ + "workspace-write", + "danger-full-access" + ] + }, + "justification": { + "type": "string", + "description": "Required with sandbox_permissions: one sentence for the user explaining why this exact file operation needs the wider access." + } + }, + "required": [ + "file_path", + "old_string", + "new_string" + ] + } + }, + { + "name": "get_goal", + "description": "Read the current same-session goal, including its exact id/revision, objective, phase, completed continuation rounds, round limit, blocker reason when present, and whether another continuation is armed. Call this before updating a goal.", + "parameters": { + "type": "object", + "properties": {} + } + }, + { + "name": "ralph", + "description": "Run a foreground fresh-agent Ralph loop toward one immutable objective. Use only when the direct human explicitly asks for Ralph or fresh-agent iteration. Each round opens a new child with no parent conversation or prior child session; the shared workspace is long-term memory, and only a bounded structured report crosses rounds. The call returns when a worker reports completion or a concrete blocker, or at the round limit. Ordinary long-running same-session work belongs to goal tools.", + "parameters": { + "type": "object", + "properties": { + "objective": { + "type": "string", + "description": "The immutable completion objective for every fresh Ralph round." + }, + "maxRounds": { + "type": "number", + "description": "Optional positive safe-integer round cap, bounded by the deployment ceiling." + } + }, + "required": [ + "objective" + ] + } + }, + { + "name": "read", + "description": "Read a UTF-8 text file and return line-numbered content.", + "parameters": { + "type": "object", + "properties": { + "file_path": { + "type": "string", + "description": "Path to read, resolved by the filesystem backend." + }, + "offset": { + "type": "number", + "description": "1-based first line to return. Defaults to 1." + }, + "limit": { + "type": "number", + "description": "Maximum number of lines to return. Defaults to 2000." + } + }, + "required": [ + "file_path" + ] + } + }, + { + "name": "session_event_read", + "description": "Read one full unabridged event and optional neighboring raw-event summaries from an authorized session.", + "parameters": { + "type": "object", + "properties": { + "session_id": { + "type": "string", + "description": "Target session id. Omit for the current session." + }, + "seq": { + "type": "integer", + "description": "Target event sequence number." + }, + "before": { + "type": "integer", + "description": "Number of preceding raw events to summarize. Omit for none." + }, + "after": { + "type": "integer", + "description": "Number of following raw events to summarize. Omit for none." + } + }, + "required": [ + "seq" + ] + } + }, + { + "name": "session_event_search", + "description": "Search prior events in one authorized session; the current session excludes the step performing this call.", + "parameters": { + "type": "object", + "properties": { + "session_id": { + "type": "string", + "description": "Target session id. Omit for the current session." + }, + "query": { + "type": "string", + "description": "Literal full-text query over the target session." + }, + "seq_from": { + "type": "integer", + "description": "Inclusive event sequence lower bound." + }, + "seq_to": { + "type": "integer", + "description": "Inclusive event sequence upper bound." + }, + "time_from": { + "type": "string", + "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." + }, + "time_to": { + "type": "string", + "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." + }, + "event_types": { + "type": "array", + "description": "Event types to include.", + "items": { + "type": "string" + } + }, + "surfaces": { + "type": "array", + "description": "Event surfaces to include.", + "items": { + "type": "string", + "enum": [ + "current", + "shadowed", + "log-only" + ] + } + } + }, + "required": [ + "query" + ] + } + }, + { + "name": "session_event_trace", + "description": "Read every direct replacement and provenance relationship for one event in an authorized session.", + "parameters": { + "type": "object", + "properties": { + "session_id": { + "type": "string", + "description": "Target session id. Omit for the current session." + }, + "seq": { + "type": "integer", + "description": "Target event sequence number." + } + }, + "required": [ + "seq" + ] + } + }, + { + "name": "session_search", + "description": "Search prior sessions in the caller workspace and return the strongest matching event from each session.", + "parameters": { + "type": "object", + "properties": { + "query": { + "type": "string", + "description": "Literal full-text query over prior session history." + }, + "session_ids": { + "type": "array", + "description": "Optional session ids to include.", + "items": { + "type": "string" + } + }, + "created_at_from": { + "type": "string", + "description": "Inclusive timezone-qualified ISO 8601 creation-time lower bound." + }, + "created_at_to": { + "type": "string", + "description": "Inclusive timezone-qualified ISO 8601 creation-time upper bound." + }, + "parent_session_ids": { + "type": "array", + "description": "Optional direct parent session ids.", + "items": { + "type": "string" + } + }, + "include_root_sessions": { + "type": "boolean", + "description": "Include sessions with no parent in the parent filter." + }, + "availability": { + "type": "array", + "description": "Require at least one selected source availability.", + "items": { + "type": "string", + "enum": [ + "live", + "persisted" + ] + } + }, + "event_seq_from": { + "type": "integer", + "description": "Inclusive event sequence lower bound." + }, + "event_seq_to": { + "type": "integer", + "description": "Inclusive event sequence upper bound." + }, + "event_time_from": { + "type": "string", + "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." + }, + "event_time_to": { + "type": "string", + "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." + }, + "event_types": { + "type": "array", + "description": "Event types to include.", + "items": { + "type": "string" + } + }, + "event_surfaces": { + "type": "array", + "description": "Event surfaces to include.", + "items": { + "type": "string", + "enum": [ + "current", + "shadowed", + "log-only" + ] + } + } + }, + "required": [ + "query" + ] + } + }, + { + "name": "session_trace", + "description": "Read the authorized session lineage around one session, including complete visible ancestor and descendant relationships.", + "parameters": { + "type": "object", + "properties": { + "session_id": { + "type": "string", + "description": "Target session id. Omit for the current session." + } + } + } + }, + { + "name": "skill", + "description": "Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.", + "parameters": { + "type": "object", + "properties": { + "name": { + "type": "string", + "description": "The exact skill name from the available skills list." + } + }, + "required": [ + "name" + ] + } + }, + { + "name": "subagent", + "description": "Delegate a self-contained task to a subagent (a separate agent that works in its own context) and return its final result. Use this to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent runs to completion and you receive only its final answer, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. Set `run_in_background: true` to return a task id; collect with `task_output` and stop with `task_kill`.", + "parameters": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "A short (3-5 word) description of the delegated task, for display." + }, + "prompt": { + "type": "string", + "description": "The complete, self-contained task for the subagent. It does not share this conversation's context, so include everything it needs." + }, + "run_in_background": { + "type": "boolean", + "description": "Run as a background task and return its id; collect with task_output or stop with task_kill." + } + }, + "required": [ + "description", + "prompt" + ] + } + }, + { + "name": "subagent_fork", + "description": "Delegate a task to a subagent that inherits this conversation: a child agent seeded with all completed turns so far (it does not see the current in-flight turn), returning only its final result. Use this when the subtask builds on this conversation's context — a follow-up analysis, a review, a continuation — without consuming this conversation's context for the work itself. You receive only its final answer, not its intermediate steps. Set `run_in_background: true` to return a task id; collect with `task_output` and stop with `task_kill`.", + "parameters": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "A short (3-5 word) description of the delegated task, for display." + }, + "prompt": { + "type": "string", + "description": "The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new." + }, + "run_in_background": { + "type": "boolean", + "description": "Run as a background task and return its id; collect with task_output or stop with task_kill." + } + }, + "required": [ + "description", + "prompt" + ] + } + }, + { + "name": "task_kill", + "description": "Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops.", + "parameters": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "description": "Task id returned by the tool that started the background work." + }, + "reason": { + "type": "string", + "description": "Optional short reason, recorded in the log and forwarded to the task." + } + }, + "required": [ + "task_id" + ] + } + }, + { + "name": "task_list", + "description": "List your background tasks (running and finished) with their ids, kinds, and statuses.", + "parameters": { + "type": "object", + "properties": {} + } + }, + { + "name": "task_output", + "description": "Read a background task. Stream tasks return only output since the previous read; final-output tasks return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap.", + "parameters": { + "type": "object", + "properties": { + "task_id": { + "type": "string", + "description": "Task id returned by the tool that started the background work." + }, + "wait": { + "type": "boolean", + "description": "Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive." + }, + "timeout_ms": { + "type": "number", + "description": "Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum." + } + }, + "required": [ + "task_id" + ] + } + }, + { + "name": "todo_write", + "description": "Record and update a structured task list for the current work. Send the ENTIRE list every call — it REPLACES the previous list (there are no partial updates, no per-item edits). Use it to plan multi-step work and show progress: add one todo per concrete step before you start. Keep AT MOST ONE todo `in_progress` at a time; while work remains, exactly one active task should be `in_progress`. Mark a todo `completed` the moment it is done (do not batch completions), and allow no `in_progress` item only once all work is complete. Skip the list for trivial single-step tasks. Statuses: `pending` (not started), `in_progress` (being worked on now), `completed` (finished).", + "parameters": { + "type": "object", + "properties": { + "todos": { + "type": "array", + "description": "The COMPLETE task list, replacing any previous list.", + "items": { + "type": "object", + "additionalProperties": true, + "properties": { + "content": { + "type": "string", + "description": "What the task is — a short imperative line." + }, + "status": { + "type": "string", + "description": "pending (not started) | in_progress (now) | completed (done).", + "enum": [ + "pending", + "in_progress", + "completed" + ] + } + }, + "required": [ + "content", + "status" + ] + } + } + }, + "required": [ + "todos" + ] + } + }, + { + "name": "update_goal", + "description": "Update the exact current goal revision. edit, pause, and resume require a direct top-level human request. During an automatic continuation of the current goal, complete and blocked are also allowed. blocked is rejected before the configured minimum round count; the model remains responsible for judging that the same condition persisted across those rounds and must explain it in blocked_reason.", + "parameters": { + "type": "object", + "properties": { + "goal_id": { + "type": "string", + "description": "Exact id returned by get_goal." + }, + "revision": { + "type": "number", + "description": "Exact positive revision returned by get_goal." + }, + "action": { + "type": "string", + "description": "edit | pause | resume | complete | blocked", + "enum": [ + "edit", + "pause", + "resume", + "complete", + "blocked" + ] + }, + "objective": { + "type": "string", + "description": "Replacement objective; valid only with action edit." + }, + "max_goal_rounds": { + "type": "number", + "description": "Replacement cap; valid only with action edit." + }, + "blocked_reason": { + "type": "string", + "description": "Concrete blocking condition; required only with action blocked." + } + }, + "required": [ + "goal_id", + "revision", + "action" + ] + } + }, + { + "name": "workflow", + "description": "Run a JavaScript workflow script that orchestrates subagents at scale. Use this for work that fans out across many independent pieces — an audit over many files, a migration, multi-angle research, adversarial verification of findings — where you write the orchestration as a script instead of delegating turn by turn.\n\nThe workflow's identity rides the `meta` parameter as JSON: required `name` (short kebab-case) and `description` strings, optional `whenToUse` string and `phases` array (`{title, detail?, provider?, model?}`). The `script` parameter is the plain JavaScript body ONLY (NOT TypeScript, and NO `export const meta` statement — meta is a parameter, not code), running with top-level await; end with `return ` — the value must be JSON-serializable and is this tool's result.\n\nScript-body hooks:\n- `agent(prompt, opts?): Promise` — run one subagent to completion. Without `opts.schema` it resolves to the child's final text; with `opts.schema` (an object-rooted JSON Schema using ONLY type/properties/required/additionalProperties/items/enum/const/oneOf — no pattern/format/numeric bounds) it resolves to the validated object. Resolves `null` when the child fails (filter with `.filter(Boolean)`). Other opts: `label` (display), `phase` (progress group), and independent `provider`/`model` LLM target overrides (either may be provided alone). Anything else (`effort`/`isolation`/`agentType`) is rejected loudly.\n- `pipeline(items, ...stages): Promise` — run each item through the stages independently with NO barrier between stages (prefer this for multi-stage work). Each stage receives `(prev, item, index)`. An ordinary stage throw drops that ITEM to `null` and skips its remaining stages.\n- `parallel(thunks): Promise` — run zero-argument functions concurrently and await ALL of them (a barrier; use only when a stage genuinely needs every prior result together). A throwing thunk resolves to `null`.\n- `phase(title)` — start a progress phase; `log(message)` — narrate progress; `args` — the tool call's `args` input, verbatim.\n\nMisused hooks (bad arguments, unknown options, unsupported schemas, tripped caps) throw errors that ALWAYS kill the script — they never dissolve into a per-item `null`.\n\nConstraints: concurrency and total-agent caps apply; no filesystem, network, timers, or Node.js APIs are provided — the agents do the work, the script only coordinates them. The run executes in the foreground: this call returns when the whole script finishes.", + "parameters": { + "type": "object", + "properties": { + "script": { + "type": "string", + "description": "The plain-JS workflow script body (top-level await allowed; NO `export const meta` statement; end with `return `)." + }, + "meta": { + "type": "object", + "description": "The workflow identity block (plain JSON — never code).", + "additionalProperties": true, + "properties": { + "name": { + "type": "string", + "description": "Short kebab-case workflow name." + }, + "description": { + "type": "string", + "description": "One-line description of what the workflow does." + }, + "whenToUse": { + "type": "string", + "description": "Optional guidance on when this workflow applies." + }, + "phases": { + "type": "array", + "description": "Optional phase declarations matched by phase() calls.", + "items": { + "type": "object", + "additionalProperties": true, + "properties": { + "title": { + "type": "string", + "description": "The phase title phase() calls match by exact string." + }, + "detail": { + "type": "string", + "description": "Optional one-line description of the phase." + }, + "provider": { + "type": "string", + "description": "Optional provider override this phase is expected to use." + }, + "model": { + "type": "string", + "description": "Optional model override this phase is expected to use." + } + }, + "required": [ + "title" + ] + } + } + }, + "required": [ + "name", + "description" + ] + }, + "args": { + "type": "object", + "description": "Optional JSON input exposed to the script as the `args` global (wrap a bare list as a field, e.g. {\"files\": [...]}).", + "additionalProperties": true + } + }, + "required": [ + "script", + "meta" + ] + } + }, + { + "name": "write", + "description": "Create or fully replace a UTF-8 text file.", + "parameters": { + "type": "object", + "properties": { + "file_path": { + "type": "string", + "description": "Path to write, resolved by the filesystem backend." + }, + "content": { + "type": "string", + "description": "Full UTF-8 text content to write." + }, + "sandbox_permissions": { + "type": "string", + "description": "The wider sandbox mode this file operation needs. Only valid as a one-shot retry of an operation the sandbox just denied; requires justification and user approval.", + "enum": [ + "workspace-write", + "danger-full-access" + ] + }, + "justification": { + "type": "string", + "description": "Required with sandbox_permissions: one sentence for the user explaining why this exact file operation needs the wider access." + } + }, + "required": [ + "file_path", + "content" + ] + } + } + ], + "changes": [] +} diff --git a/examples/acp-agent/tests/snapshots/skill-load/system-prompt.expected.md b/examples/acp-agent/tests/snapshots/skill-load/system-prompt.expected.md index 68bdd841c7..17e6773a03 100644 --- a/examples/acp-agent/tests/snapshots/skill-load/system-prompt.expected.md +++ b/examples/acp-agent/tests/snapshots/skill-load/system-prompt.expected.md @@ -15,8 +15,6 @@ Check the [exit code: N] marker on every bash result; investigate failures befor Track every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering. -Use session_search to find relevant work from prior sessions, or session_event_search to search earlier events in one session. Search results are cursor-free and workspace-scoped. Follow a useful hit with session_trace, session_event_trace, or session_event_read when you need lineage, relationships, or exact data. - Use goal tools for one long-running completion objective in the current session. create_goal may infer goal intent from a direct human request in any language; do not create a goal for routine single-turn work. Call get_goal before update_goal and copy its exact goal_id and revision. After session resume or fork, an active goal is disarmed: when a human asks to continue or resume in any wording or language, use update_goal action resume to rearm it. Mark complete only when the objective is actually achieved. Mark blocked only after the same blocking condition persists for at least 3 consecutive goal rounds, and report that concrete condition in blocked_reason; difficulty, uncertainty, or useful remaining work is not blocked. Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`). diff --git a/examples/acp-agent/tests/snapshots/skill-load/tool-schemas.expected.json b/examples/acp-agent/tests/snapshots/skill-load/tool-schemas.expected.json index dde0ba0d7a..d4973bfea4 100644 --- a/examples/acp-agent/tests/snapshots/skill-load/tool-schemas.expected.json +++ b/examples/acp-agent/tests/snapshots/skill-load/tool-schemas.expected.json @@ -159,210 +159,6 @@ ] } }, - { - "name": "session_event_read", - "description": "Read one full unabridged event and optional neighboring raw-event summaries from an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - }, - "before": { - "type": "integer", - "description": "Number of preceding raw events to summarize. Omit for none." - }, - "after": { - "type": "integer", - "description": "Number of following raw events to summarize. Omit for none." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_event_search", - "description": "Search prior events in one authorized session; the current session excludes the step performing this call.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "query": { - "type": "string", - "description": "Literal full-text query over the target session." - }, - "seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_event_trace", - "description": "Read every direct replacement and provenance relationship for one event in an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_search", - "description": "Search prior sessions in the caller workspace and return the strongest matching event from each session.", - "parameters": { - "type": "object", - "properties": { - "query": { - "type": "string", - "description": "Literal full-text query over prior session history." - }, - "session_ids": { - "type": "array", - "description": "Optional session ids to include.", - "items": { - "type": "string" - } - }, - "created_at_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time lower bound." - }, - "created_at_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time upper bound." - }, - "parent_session_ids": { - "type": "array", - "description": "Optional direct parent session ids.", - "items": { - "type": "string" - } - }, - "include_root_sessions": { - "type": "boolean", - "description": "Include sessions with no parent in the parent filter." - }, - "availability": { - "type": "array", - "description": "Require at least one selected source availability.", - "items": { - "type": "string", - "enum": [ - "live", - "persisted" - ] - } - }, - "event_seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "event_seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "event_time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "event_time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "event_surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_trace", - "description": "Read the authorized session lineage around one session, including complete visible ancestor and descendant relationships.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - } - } - } - }, { "name": "skill", "description": "Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.", diff --git a/examples/acp-agent/tests/snapshots/text-turn/system-prompt.expected.md b/examples/acp-agent/tests/snapshots/text-turn/system-prompt.expected.md index 68bdd841c7..17e6773a03 100644 --- a/examples/acp-agent/tests/snapshots/text-turn/system-prompt.expected.md +++ b/examples/acp-agent/tests/snapshots/text-turn/system-prompt.expected.md @@ -15,8 +15,6 @@ Check the [exit code: N] marker on every bash result; investigate failures befor Track every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering. -Use session_search to find relevant work from prior sessions, or session_event_search to search earlier events in one session. Search results are cursor-free and workspace-scoped. Follow a useful hit with session_trace, session_event_trace, or session_event_read when you need lineage, relationships, or exact data. - Use goal tools for one long-running completion objective in the current session. create_goal may infer goal intent from a direct human request in any language; do not create a goal for routine single-turn work. Call get_goal before update_goal and copy its exact goal_id and revision. After session resume or fork, an active goal is disarmed: when a human asks to continue or resume in any wording or language, use update_goal action resume to rearm it. Mark complete only when the objective is actually achieved. Mark blocked only after the same blocking condition persists for at least 3 consecutive goal rounds, and report that concrete condition in blocked_reason; difficulty, uncertainty, or useful remaining work is not blocked. Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`). diff --git a/examples/acp-agent/tests/snapshots/text-turn/tool-schemas.expected.json b/examples/acp-agent/tests/snapshots/text-turn/tool-schemas.expected.json index dde0ba0d7a..d4973bfea4 100644 --- a/examples/acp-agent/tests/snapshots/text-turn/tool-schemas.expected.json +++ b/examples/acp-agent/tests/snapshots/text-turn/tool-schemas.expected.json @@ -159,210 +159,6 @@ ] } }, - { - "name": "session_event_read", - "description": "Read one full unabridged event and optional neighboring raw-event summaries from an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - }, - "before": { - "type": "integer", - "description": "Number of preceding raw events to summarize. Omit for none." - }, - "after": { - "type": "integer", - "description": "Number of following raw events to summarize. Omit for none." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_event_search", - "description": "Search prior events in one authorized session; the current session excludes the step performing this call.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "query": { - "type": "string", - "description": "Literal full-text query over the target session." - }, - "seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_event_trace", - "description": "Read every direct replacement and provenance relationship for one event in an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_search", - "description": "Search prior sessions in the caller workspace and return the strongest matching event from each session.", - "parameters": { - "type": "object", - "properties": { - "query": { - "type": "string", - "description": "Literal full-text query over prior session history." - }, - "session_ids": { - "type": "array", - "description": "Optional session ids to include.", - "items": { - "type": "string" - } - }, - "created_at_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time lower bound." - }, - "created_at_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time upper bound." - }, - "parent_session_ids": { - "type": "array", - "description": "Optional direct parent session ids.", - "items": { - "type": "string" - } - }, - "include_root_sessions": { - "type": "boolean", - "description": "Include sessions with no parent in the parent filter." - }, - "availability": { - "type": "array", - "description": "Require at least one selected source availability.", - "items": { - "type": "string", - "enum": [ - "live", - "persisted" - ] - } - }, - "event_seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "event_seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "event_time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "event_time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "event_surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_trace", - "description": "Read the authorized session lineage around one session, including complete visible ancestor and descendant relationships.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - } - } - } - }, { "name": "skill", "description": "Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.", diff --git a/examples/acp-agent/tests/snapshots/workspace-context/system-prompt.expected.md b/examples/acp-agent/tests/snapshots/workspace-context/system-prompt.expected.md index 45c9e0970c..6cd8d5725f 100644 --- a/examples/acp-agent/tests/snapshots/workspace-context/system-prompt.expected.md +++ b/examples/acp-agent/tests/snapshots/workspace-context/system-prompt.expected.md @@ -15,8 +15,6 @@ Check the [exit code: N] marker on every bash result; investigate failures befor Track every background task id you start. You are notified in-session when a task finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running task's work. Before giving a final answer, collect every still-relevant task with task_output (set wait: true only when you are genuinely blocked on it), and task_kill tasks that stopped mattering. -Use session_search to find relevant work from prior sessions, or session_event_search to search earlier events in one session. Search results are cursor-free and workspace-scoped. Follow a useful hit with session_trace, session_event_trace, or session_event_read when you need lineage, relationships, or exact data. - Use goal tools for one long-running completion objective in the current session. create_goal may infer goal intent from a direct human request in any language; do not create a goal for routine single-turn work. Call get_goal before update_goal and copy its exact goal_id and revision. After session resume or fork, an active goal is disarmed: when a human asks to continue or resume in any wording or language, use update_goal action resume to rearm it. Mark complete only when the objective is actually achieved. Mark blocked only after the same blocking condition persists for at least 3 consecutive goal rounds, and report that concrete condition in blocked_reason; difficulty, uncertainty, or useful remaining work is not blocked. Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`). diff --git a/examples/acp-agent/tests/snapshots/workspace-context/tool-schemas.expected.json b/examples/acp-agent/tests/snapshots/workspace-context/tool-schemas.expected.json index dde0ba0d7a..d4973bfea4 100644 --- a/examples/acp-agent/tests/snapshots/workspace-context/tool-schemas.expected.json +++ b/examples/acp-agent/tests/snapshots/workspace-context/tool-schemas.expected.json @@ -159,210 +159,6 @@ ] } }, - { - "name": "session_event_read", - "description": "Read one full unabridged event and optional neighboring raw-event summaries from an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - }, - "before": { - "type": "integer", - "description": "Number of preceding raw events to summarize. Omit for none." - }, - "after": { - "type": "integer", - "description": "Number of following raw events to summarize. Omit for none." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_event_search", - "description": "Search prior events in one authorized session; the current session excludes the step performing this call.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "query": { - "type": "string", - "description": "Literal full-text query over the target session." - }, - "seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_event_trace", - "description": "Read every direct replacement and provenance relationship for one event in an authorized session.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - }, - "seq": { - "type": "integer", - "description": "Target event sequence number." - } - }, - "required": [ - "seq" - ] - } - }, - { - "name": "session_search", - "description": "Search prior sessions in the caller workspace and return the strongest matching event from each session.", - "parameters": { - "type": "object", - "properties": { - "query": { - "type": "string", - "description": "Literal full-text query over prior session history." - }, - "session_ids": { - "type": "array", - "description": "Optional session ids to include.", - "items": { - "type": "string" - } - }, - "created_at_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time lower bound." - }, - "created_at_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 creation-time upper bound." - }, - "parent_session_ids": { - "type": "array", - "description": "Optional direct parent session ids.", - "items": { - "type": "string" - } - }, - "include_root_sessions": { - "type": "boolean", - "description": "Include sessions with no parent in the parent filter." - }, - "availability": { - "type": "array", - "description": "Require at least one selected source availability.", - "items": { - "type": "string", - "enum": [ - "live", - "persisted" - ] - } - }, - "event_seq_from": { - "type": "integer", - "description": "Inclusive event sequence lower bound." - }, - "event_seq_to": { - "type": "integer", - "description": "Inclusive event sequence upper bound." - }, - "event_time_from": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time lower bound." - }, - "event_time_to": { - "type": "string", - "description": "Inclusive timezone-qualified ISO 8601 event-time upper bound." - }, - "event_types": { - "type": "array", - "description": "Event types to include.", - "items": { - "type": "string" - } - }, - "event_surfaces": { - "type": "array", - "description": "Event surfaces to include.", - "items": { - "type": "string", - "enum": [ - "current", - "shadowed", - "log-only" - ] - } - } - }, - "required": [ - "query" - ] - } - }, - { - "name": "session_trace", - "description": "Read the authorized session lineage around one session, including complete visible ancestor and descendant relationships.", - "parameters": { - "type": "object", - "properties": { - "session_id": { - "type": "string", - "description": "Target session id. Omit for the current session." - } - } - } - }, { "name": "skill", "description": "Load the full instructions for an available skill. Call this with the exact skill name from the session skill catalog before acting on a task that names or clearly matches that skill.", diff --git a/examples/tui-agent/composition.md b/examples/tui-agent/composition.md index 557923b733..fd6d163952 100644 --- a/examples/tui-agent/composition.md +++ b/examples/tui-agent/composition.md @@ -23,8 +23,6 @@ flowchart LR bundle_agent_core --> spine_sessions["ctx.sessions"] bundle_agent_core --> spine_tools["ctx.tools + tool-bash"] bundle_agent_core --> spine_loop["ctx.agents + ctx.agentLoop"] - plugin_tui_tool_session_query["tool-session-query
@deepseek-ai/dsh-tool-session-query"] - cfg --> plugin_tui_tool_session_query plugin_tui_session_title_llm["session-title-llm
@deepseek-ai/dsh-session-title-first-message-llm"] cfg --> plugin_tui_session_title_llm plugin_tui_token_meter["token-meter
@deepseek-ai/dsh-token-meter"] @@ -73,7 +71,6 @@ flowchart LR | `llm-deepseek` | `@deepseek-ai/dsh-llm-deepseek` | | `bash` | `@deepseek-ai/dsh-bash-local` | | `tui-agent` | `@deepseek-ai/dsh-tui-demo` | -| `tool-session-query` | `@deepseek-ai/dsh-tool-session-query` | | `session-title-llm` | `@deepseek-ai/dsh-session-title-first-message-llm` | | `token-meter` | `@deepseek-ai/dsh-token-meter` | | `tool-result-prune` | `@deepseek-ai/dsh-compact-tool-result-prune` | diff --git a/examples/tui-agent/cordis.yml b/examples/tui-agent/cordis.yml index 4fccfff1c7..3070fcdc01 100644 --- a/examples/tui-agent/cordis.yml +++ b/examples/tui-agent/cordis.yml @@ -52,11 +52,6 @@ Verify your work by running the code or tests. Keep answers brief and factual. -# The app above owns ctx.sessionQuery; expose its workspace-authorized -# prior-session search and exact trace/read operations to the model. -- id: tool-session-query - name: '@deepseek-ai/dsh-tool-session-query' - # Model-made session titles on the first-message cadence: replaces the spine's # deterministic fallback title with a short model summary. The TUI renders the # logged `session/title` as the banner subtitle and the terminal window title. diff --git a/packages/examples/acp-demo/README.md b/packages/examples/acp-demo/README.md index e215a80939..9666e4444f 100644 --- a/packages/examples/acp-demo/README.md +++ b/packages/examples/acp-demo/README.md @@ -36,7 +36,7 @@ The app does not install commands, user interaction, session navigation, configu | `goals` | owner defaults | Persisted same-session goal domain and model tools, or `false`. | | `llmRetry` | owner defaults | Bounded transient model-request retry policy. | -The shipped [`examples/acp-agent/cordis.yml`](../../../examples/acp-agent/cordis.yml) adds the DeepSeek adapter, sandboxed bash and filesystem providers, one-shot approval policy, compaction, subagents, workflows, hooks, a derived session-query index, generic timeout and spill policies, and model-facing tools. Snapshot overlays replace only nondeterministic providers or policy values. +The shipped [`examples/acp-agent/cordis.yml`](../../../examples/acp-agent/cordis.yml) adds the DeepSeek adapter, sandboxed bash and filesystem providers, one-shot approval policy, compaction, subagents, workflows, hooks, and model-facing tools. The app supplies the derived session-query index, while the model-facing query consumer remains an explicit leaf opt-in. Snapshot overlays replace only nondeterministic providers or policy values. ## Bin diff --git a/packages/examples/acp-demo/tests/load-path.e2e.ts b/packages/examples/acp-demo/tests/load-path.e2e.ts index 9f61e28314..2c507a0bad 100644 --- a/packages/examples/acp-demo/tests/load-path.e2e.ts +++ b/packages/examples/acp-demo/tests/load-path.e2e.ts @@ -28,9 +28,8 @@ const tsxLoader = fileURLToPath(import.meta.resolve('tsx')) // Repo root is four levels up from packages/examples/acp-demo/tests. const repoTsconfig = fileURLToPath(new URL('../../../../tsconfig.json', import.meta.url)) -// A minimal leaf that loads this app + the two backends and the shipped -// session-query consumer/policies — the same shape as examples/acp-agent/cordis.yml, -// inlined so the package test owns its fixture. +// A minimal opt-in leaf that loads this app + the two backends and the optional +// session-query consumer/policies, inlined so the package test owns its fixture. const CORDIS_YML = ` - id: llm-deepseek name: '@deepseek-ai/dsh-llm-deepseek' diff --git a/packages/examples/tui-demo/README.md b/packages/examples/tui-demo/README.md index 9e2a50f1b5..e3321bd97f 100644 --- a/packages/examples/tui-demo/README.md +++ b/packages/examples/tui-demo/README.md @@ -13,7 +13,7 @@ Use [`@deepseek-ai/dsh-cli-demo`](../cli-demo/README.md) for pipes, scripts, and | `@deepseek-ai/dsh-command-goal` | Direct `/goal` status and mutation over the spine's persisted-goal stack | | `@deepseek-ai/dsh-session-persistence-jsonl` | Durable session log under `persistenceRoot` | | `@deepseek-ai/dsh-session-checkpoint-policy` | Semantic durability barriers before model requests and top-level tool effects, plus completed-step checkpoints | -| `@deepseek-ai/dsh-session-query-sqlite` + `@deepseek-ai/dsh-session-reference` | Combined exact/FTS session queries and bounded `@session` snapshots consumed by the TUI; the default leaf adds the model-facing query tools | +| `@deepseek-ai/dsh-session-query-sqlite` + `@deepseek-ai/dsh-session-reference` | Combined exact/FTS session queries and bounded `@session` snapshots consumed by the TUI; model-facing query tools remain a leaf opt-in | | `@deepseek-ai/dsh-user-interaction` | Provider-neutral human question service | | `@deepseek-ai/dsh-tui` | Full-screen transcript, editor, tool cards, plan, and question overlays | | `@deepseek-ai/dsh-tool-ask-user` | Model-facing `ask_user_question` tool | diff --git a/packages/host/runtime/README.md b/packages/host/runtime/README.md index 221f0f46c0..14ce60e1c2 100644 --- a/packages/host/runtime/README.md +++ b/packages/host/runtime/README.md @@ -1,6 +1,6 @@ # @deepseek-ai/dsh-host-runtime -Host runtime assembly for `dsh`: `bootHost` composes the core plugin spine (LLM service + DeepSeek adapter, sessions with JSONL persistence, a derived SQLite FTS session-query index, immediate fallback titles, optional first-message model summaries, system prompt, tool and agent registries, agent loop, five workspace-authorized model-facing session-query tools, workspace instructions, local bash, the generic tool-timeout and 50,000-byte spill policies, and the provider-neutral user-interaction service), and `startHost` is the one-step shell seam returning `{ api, handler, defaults, ctx, dispose }` (its `api` comes from [`dsh-host-apiproxy`](../apiproxy/README.md)'s `createApiProxy` over that composition). +Host runtime assembly for `dsh`: `bootHost` composes the core plugin spine (LLM service + DeepSeek adapter, sessions with JSONL persistence, a derived SQLite FTS session-query index, immediate fallback titles, optional first-message model summaries, system prompt, tool and agent registries, agent loop, workspace instructions, local bash, the generic tool-timeout and 50,000-byte spill policies, and the provider-neutral user-interaction service), and `startHost` is the one-step shell seam returning `{ api, handler, defaults, ctx, dispose }` (its `api` comes from [`dsh-host-apiproxy`](../apiproxy/README.md)'s `createApiProxy` over that composition). Which plugins mount and with what defaults is decided only here — shells must not `ctx.plugin` to alter the assembly. `RunningHost.ctx` is a formal seam with exactly two sanctioned uses: mounting protocol front-door plugins (e.g. a future `dsh acp`) and headless session-event subscription; consuming clients must not bypass `api` through it. @@ -22,53 +22,19 @@ Unary methods take the narrow `RpcRequest

` and echo `request.rpcId`; a prompt ## Model Experience -### Prior-history system prompt +### Optional session-query consumer #### What the model sees -Every main host agent receives the fixed prior-history guidance below because `bootHost` always mounts the session-query tool plugin. - -##### Prior-history guidance - -```markdown -Use session_search to find relevant work from prior sessions, or session_event_search to search earlier events in one session. Search results are cursor-free and workspace-scoped. Follow a useful hit with session_trace, session_event_trace, or session_event_read when you need lineage, relationships, or exact data. -``` +The derived `ctx.sessionQuery` index is not model-facing. `bootHost` intentionally leaves the optional [`dsh-tool-session-query`](../../session-query/tool-session-query/README.md) consumer unmounted, so main host agents receive neither its prior-history prompt section nor its five schemas by default. #### Token effect -One fixed concise section is present on every request; `workspaceContext: false` does not remove it. +The index adds no prompt or schema tokens. A custom composition that mounts the consumer owns its added prompt, schemas, calls, and results. #### KV Cache effect -The repeated prefix is stable while the fixed host assembly and guidance text are unchanged. Provider cache availability and eviction remain outside the host contract. - -### Session-query tool schemas - -#### What the model sees - -The fixed assembly mounts the generated [`session_search`, `session_event_search`, `session_trace`, `session_event_trace`, and `session_event_read` schemas](../../../docs/tool-catalog.md#deepseek-aidsh-tool-session-query). The schemas expose no workspace path, provider cursor, output page, model-controlled result limit, or timeout argument. - -#### Token effect - -Five fixed read-only schemas are present on every main-agent request; their cost changes only if the host assembly or an agent-scoped visibility policy changes. - -#### KV Cache effect - -The schema prefix is stable while visibility, definitions, and order are unchanged. The host makes no claim that a provider will cache or retain that prefix. - -### Session-query execution and results - -#### What the model sees - -Cross-session results require exact equality with the calling session's workspace, while a caller without a workspace can target only itself. `session_search` excludes the calling session, and `session_event_search` on the current session excludes the step performing the call. Both searches are cursor-free, collect at most 100 authorized results, and carry a cooperative 30-second deadline; the three trace/read tools carry caller cancellation but declare no host deadline. Results are plain text. When a final result exceeds 50,000 UTF-8 bytes, the generic spill policy attempts to retain the complete formatted text in a private session-scoped file and replace it with a bounded preview, locator, and retrieval hint; a spill failure leaves the original result visible. - -#### Token effect - -Call arguments and data-dependent results remain in history until compaction. Search result count is bounded; after a successful spill, only the bounded preview and retrieval notice are resent, while the complete text remains outside model context. - -#### KV Cache effect - -Calls and results append after the reusable request prefix. Compaction may replace earlier history; timeout or spill outcomes change only the appended result text. +The index alone does not change the reusable model-request prefix; mounting the optional consumer would add its stable prompt and schema prefix. ### Workspace instructions diff --git a/packages/host/runtime/package.json b/packages/host/runtime/package.json index cb31e87fe9..b43cb9c468 100644 --- a/packages/host/runtime/package.json +++ b/packages/host/runtime/package.json @@ -58,7 +58,6 @@ "@deepseek-ai/dsh-tool-fs": "workspace:^", "@deepseek-ai/dsh-tool-fs-search": "workspace:^", "@deepseek-ai/dsh-tool-skill": "workspace:^", - "@deepseek-ai/dsh-tool-session-query": "workspace:^", "@deepseek-ai/dsh-tool-subagent": "workspace:^", "@deepseek-ai/dsh-tool-tasks": "workspace:^", "@deepseek-ai/dsh-tool-todo": "workspace:^", diff --git a/packages/host/runtime/src/boot.ts b/packages/host/runtime/src/boot.ts index 353f74d0b6..4e2976ccc4 100644 --- a/packages/host/runtime/src/boot.ts +++ b/packages/host/runtime/src/boot.ts @@ -20,7 +20,6 @@ import AgentLoop from '@deepseek-ai/dsh-agent-loop' import * as LlmDeepSeek from '@deepseek-ai/dsh-llm-deepseek' import SessionPersistenceJsonl from '@deepseek-ai/dsh-session-persistence-jsonl' import SessionQuerySqlite from '@deepseek-ai/dsh-session-query-sqlite' -import * as toolSessionQuery from '@deepseek-ai/dsh-tool-session-query' import LocalBashExecutor from '@deepseek-ai/dsh-bash-local' import * as toolBash from '@deepseek-ai/dsh-tool-bash' import * as toolTodo from '@deepseek-ai/dsh-tool-todo' @@ -135,7 +134,6 @@ export async function bootHost(options: BootHostOptions): Promise { await ctx.plugin(LlmDeepSeek, {}) await ctx.plugin(SessionPersistenceJsonl, { root: options.persistenceRoot }) await ctx.plugin(SessionQuerySqlite, { path: join(options.persistenceRoot, 'session-query.db') }) - await ctx.plugin(toolSessionQuery, {}) await ctx.plugin(LocalBashExecutor, {}) // Tool suite mirroring the demo:repl composition (repl-agent/cordis.yml + // the agent-spine bundle) so web sessions get the same coding-agent tool diff --git a/packages/host/runtime/tests/host-runtime.spec.ts b/packages/host/runtime/tests/host-runtime.spec.ts index 9912ec0785..22f64fb198 100644 --- a/packages/host/runtime/tests/host-runtime.spec.ts +++ b/packages/host/runtime/tests/host-runtime.spec.ts @@ -141,21 +141,20 @@ describe('bootHost / startHost', () => { await handle.dispose() }) - it('assembles workspace-authorized session query tools over the derived SQLite index', async () => { + it('assembles the derived SQLite query index without model-facing query tools', async () => { const persistenceRoot = mkdtempSync(join(tmpdir(), 'dsh-boot-session-query-')) const handle = await bootHost({ persistenceRoot, workspaceContext: false, }) expect(handle.ctx.get('sessionQuery')).toBeDefined() - expect(handle.ctx.tools.schemas().map(schema => schema.name)).toEqual(expect.arrayContaining([ + expect(handle.ctx.tools.schemas().map(schema => schema.name)).toEqual(expect.not.arrayContaining([ 'session_search', 'session_event_search', 'session_trace', 'session_event_trace', 'session_event_read', ])) - expect(handle.ctx.tools.get('session_search')?.timeoutMs).toBe(30_000) await handle.dispose() }) diff --git a/packages/host/runtime/tsconfig.json b/packages/host/runtime/tsconfig.json index b0cef9eb16..55f517f778 100644 --- a/packages/host/runtime/tsconfig.json +++ b/packages/host/runtime/tsconfig.json @@ -50,9 +50,6 @@ { "path": "../../session-query/session-query-sqlite" }, - { - "path": "../../session-query/tool-session-query" - }, { "path": "../../bash/bash-local" }, diff --git a/packages/session-query/tool-session-query/README.md b/packages/session-query/tool-session-query/README.md index 504405d698..ef957765c4 100644 --- a/packages/session-query/tool-session-query/README.md +++ b/packages/session-query/tool-session-query/README.md @@ -1,6 +1,6 @@ # @deepseek-ai/dsh-tool-session-query -Workspace-authorized model tools over `ctx.sessionQuery`. The package depends only on the unified interface and registers `session_search`, `session_event_search`, `session_trace`, `session_event_trace`, and `session_event_read`. +Workspace-authorized model tools over `ctx.sessionQuery`. The opt-in package depends only on the unified interface and registers `session_search`, `session_event_search`, `session_trace`, `session_event_trace`, and `session_event_read`; shipped host compositions do not mount it by default. ## Configuration diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 400ae6df7e..de8e114782 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -2346,9 +2346,6 @@ importers: '@deepseek-ai/dsh-tool-fs-search': specifier: workspace:^ version: link:../../fs/tool-fs-search - '@deepseek-ai/dsh-tool-session-query': - specifier: workspace:^ - version: link:../../session-query/tool-session-query '@deepseek-ai/dsh-tool-skill': specifier: workspace:^ version: link:../../skill/tool-skill diff --git a/scripts/gen-tool-catalog.ts b/scripts/gen-tool-catalog.ts index 6c81aee2c6..3bbfd5b1ea 100644 --- a/scripts/gen-tool-catalog.ts +++ b/scripts/gen-tool-catalog.ts @@ -331,7 +331,7 @@ const TOOL_PACKAGES: ToolPackage[] = [ await ctx.plugin(ToolSessionQuery) }, note: - 'The five read-only tools hide provider cursors and authorize every result from the immutable calling agent session. Default ACP, TUI, and Web compositions enforce the declared search timeout and apply the generic tool-result spill policy.', + 'The five read-only tools hide provider cursors and authorize every result from the immutable calling agent session. The package is opt-in; compositions that need enforced deadlines or bounded inline output also mount the generic timeout or spill policies.', }, { pkg: '@deepseek-ai/dsh-tool-subagent',