Merge commit '70396085b141370ce32de1be4e225b4384eaf46d' into HEAD

# Conflicts:
#	.agents/notes/implemented/feature/2026-07-07-mcp-client-plugin.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-20-code-mode-typed-tool-returns.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-22-web-multimodal-image-input-and-durable-attachments.i18n.yaml
#	.agents/notes/implemented/feature/2026-07-22-web-multimodal-image-input-and-durable-attachments.md
#	.agents/notes/implemented/feature/2026-07-22-web-multimodal-image-input-and-durable-attachments.zh.md
#	.agents/notes/implemented/simplification/2026-07-23-acp-automation-only-protocol.i18n.yaml
#	docs/config-catalog.i18n.yaml
#	docs/module-graph.i18n.yaml
#	docs/module-graph.md
#	docs/module-graph.zh.md
#	docs/tool-catalog.i18n.yaml
#	docs/tool-catalog.md
#	docs/tool-catalog.zh.md
#	examples/acp-agent/tests/snapshots/advanced-toolchain/tool-schemas.expected.json
#	examples/acp-agent/tests/snapshots/both-mode-turn/tool-schemas.expected.json
#	examples/acp-agent/tests/snapshots/code-mode-turn/tool-schemas.expected.json
#	packages/core/tools/README.i18n.yaml
#	packages/core/tools/README.zh.md
#	packages/core/tools/src/code-mode.ts
#	packages/host/apiproxy/tests/api-proxy-models.spec.ts
#	packages/host/plugin-inventory/tests/inventory.spec.ts
#	packages/mcp/mcp-client/tests/mcp-client.e2e.ts
#	packages/mcp/mcp-client/tests/mcp-client.spec.ts
#	packages/self-modification/tool-cordis/src/api-catalog.ts
#	packages/test-support/acp-snapshot/README.i18n.yaml
#	pnpm-lock.yaml
This commit is contained in:
Tianyi Cui
2026-08-17 11:31:59 +08:00
3845 changed files with 62208 additions and 100402 deletions

View File

@@ -24,7 +24,9 @@
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker'
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: cordis-host-runner
name: '@deepseek-ai/dsh-cordis-host-runner'
- id: tool-cordis
name: '@deepseek-ai/dsh-tool-cordis'
- id: llm-replay

View File

@@ -22,6 +22,8 @@
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker'
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: cordis-host-runner
name: '@deepseek-ai/dsh-cordis-host-runner'
- id: tool-cordis
name: '@deepseek-ai/dsh-tool-cordis'

View File

@@ -1,4 +1,4 @@
# Keyless replay counterpart of workspace-context.cordis.yml. Patches do not
# Keyless replay counterpart of agent-instructions.cordis.yml. Patches do not
# compose across includes, so this applies the scenario config and model swap
# directly to the live tree.
- id: base

View File

@@ -1,4 +1,4 @@
# Keyless counterpart to background-task-admission.cordis.yml: replace the
# Keyless counterpart to background-job-admission.cordis.yml: replace the
# DeepSeek adapter with replay while preserving the app's one-task admission
# config and the recorded flash route.
- id: base
@@ -19,7 +19,7 @@
workspaceContext:
maxBytes: 65536
tasks:
maxConcurrentTasksPerOwner: 1
maxConcurrentJobsPerOwner: 1
persona: |
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.

View File

@@ -17,7 +17,7 @@
workspaceContext:
maxBytes: 65536
tasks:
maxConcurrentTasksPerOwner: 1
maxConcurrentJobsPerOwner: 1
persona: |
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.

View File

@@ -26,7 +26,7 @@
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker'
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:

View File

@@ -24,4 +24,4 @@
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker'
name: '@deepseek-ai/dsh-code-runtime-worker-thread'

View File

@@ -42,8 +42,8 @@
models:
- id: deepseek-v4-flash
- id: deepseek-v4-pro
- id: user-interaction
name: '@deepseek-ai/dsh-user-interaction'
- id: user-questions
name: '@deepseek-ai/dsh-user-questions'
- id: tool-ask-user
name: '@deepseek-ai/dsh-tool-ask-user'
- id: child-question-tripwire

View File

@@ -6,8 +6,8 @@
path: ./cordis.yml
patches:
- insert:
- id: user-interaction
name: '@deepseek-ai/dsh-user-interaction'
- id: user-questions
name: '@deepseek-ai/dsh-user-questions'
- id: tool-ask-user
name: '@deepseek-ai/dsh-tool-ask-user'
- id: child-question-tripwire

View File

@@ -28,7 +28,7 @@
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker'
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:

View File

@@ -26,4 +26,4 @@
- id: attachment-local
name: '@deepseek-ai/dsh-attachment-local'
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker'
name: '@deepseek-ai/dsh-code-runtime-worker-thread'

View File

@@ -25,6 +25,6 @@
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker'
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'

View File

@@ -1,4 +1,4 @@
# Code Mode workspace-context snapshot recording overlay. The default filesystem
# Code Mode agent-instructions snapshot recording overlay. The default filesystem
# tools trigger nested instruction discovery after a read.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
@@ -22,4 +22,4 @@
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker'
name: '@deepseek-ai/dsh-code-runtime-worker-thread'

View File

@@ -26,7 +26,7 @@
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker'
name: '@deepseek-ai/dsh-code-runtime-worker-thread'
- id: llm-replay
name: '@deepseek-ai/dsh-llm-replay'
config:

View File

@@ -25,4 +25,4 @@
Verify your work by running the code or tests. Keep answers brief and factual.
- insert:
- id: code-runtime
name: '@deepseek-ai/dsh-code-runtime-worker'
name: '@deepseek-ai/dsh-code-runtime-worker-thread'

View File

@@ -31,16 +31,16 @@ flowchart LR
bundle_agent_core --> spine_loop["ctx.agents + ctx.agentLoop"]
plugin_acp_token_meter["token-meter<br/>@deepseek-ai/dsh-token-meter"]
cfg --> plugin_acp_token_meter
plugin_acp_compact_basic["compact-basic<br/>@deepseek-ai/dsh-compact-basic"]
cfg --> plugin_acp_compact_basic
plugin_acp_compaction_basic["compaction-basic<br/>@deepseek-ai/dsh-compaction-basic"]
cfg --> plugin_acp_compaction_basic
plugin_acp_session_projection["session-projection<br/>@deepseek-ai/dsh-session-projection"]
cfg --> plugin_acp_session_projection
plugin_acp_subagent["subagent<br/>@deepseek-ai/dsh-subagent"]
cfg --> plugin_acp_subagent
plugin_acp_subagent_spawn["subagent-spawn<br/>@deepseek-ai/dsh-subagent-spawn"]
cfg --> plugin_acp_subagent_spawn
plugin_acp_subagent_fork["subagent-fork<br/>@deepseek-ai/dsh-subagent-fork"]
cfg --> plugin_acp_subagent_fork
plugin_acp_subagent_spawn_in_process["subagent-spawn-in-process<br/>@deepseek-ai/dsh-subagent-spawn-in-process"]
cfg --> plugin_acp_subagent_spawn_in_process
plugin_acp_subagent_fork_in_process["subagent-fork-in-process<br/>@deepseek-ai/dsh-subagent-fork-in-process"]
cfg --> plugin_acp_subagent_fork_in_process
plugin_acp_tool_subagent_control["tool-subagent-control<br/>@deepseek-ai/dsh-tool-subagent-control"]
cfg --> plugin_acp_tool_subagent_control
plugin_acp_tool_subagent_list_agents["tool-subagent-list-agents<br/>@deepseek-ai/dsh-tool-subagent-control/list-agents"]
@@ -51,24 +51,24 @@ flowchart LR
cfg --> plugin_acp_tool_subagent
plugin_acp_tool_subagent_fork["tool-subagent-fork<br/>@deepseek-ai/dsh-tool-subagent"]
cfg --> plugin_acp_tool_subagent_fork
plugin_acp_workflow_workerthread["workflow-workerthread<br/>@deepseek-ai/dsh-workflow-workerthread"]
cfg --> plugin_acp_workflow_workerthread
plugin_acp_workflow_worker_thread["workflow-worker-thread<br/>@deepseek-ai/dsh-workflow-worker-thread"]
cfg --> plugin_acp_workflow_worker_thread
plugin_acp_tool_workflow["tool-workflow<br/>@deepseek-ai/dsh-tool-workflow"]
cfg --> plugin_acp_tool_workflow
plugin_acp_tool_ralph["tool-ralph<br/>@deepseek-ai/dsh-tool-ralph"]
cfg --> plugin_acp_tool_ralph
plugin_acp_tool_todo["tool-todo<br/>@deepseek-ai/dsh-tool-todo"]
cfg --> plugin_acp_tool_todo
plugin_acp_repeat_tool_guard["repeat-tool-guard<br/>@deepseek-ai/dsh-repeat-tool-guard"]
cfg --> plugin_acp_repeat_tool_guard
plugin_acp_repeat_tool_reminder["repeat-tool-reminder<br/>@deepseek-ai/dsh-repeat-tool-reminder"]
cfg --> plugin_acp_repeat_tool_reminder
plugin_acp_fs_sandbox["fs-sandbox<br/>@deepseek-ai/dsh-fs-sandbox"]
cfg --> plugin_acp_fs_sandbox
plugin_acp_fs_policy["fs-policy<br/>@deepseek-ai/dsh-fs-policy"]
cfg --> plugin_acp_fs_policy
plugin_acp_fs_observation_policy["fs-observation-policy<br/>@deepseek-ai/dsh-fs-observation-policy"]
cfg --> plugin_acp_fs_observation_policy
plugin_acp_tool_fs["tool-fs<br/>@deepseek-ai/dsh-tool-fs"]
cfg --> plugin_acp_tool_fs
plugin_acp_hooks_claude["hooks-claude<br/>@deepseek-ai/dsh-hooks-claude"]
cfg --> plugin_acp_hooks_claude
plugin_acp_hooks_claude_code["hooks-claude-code<br/>@deepseek-ai/dsh-hooks-claude-code"]
cfg --> plugin_acp_hooks_claude_code
plugin_acp_hooks_codex["hooks-codex<br/>@deepseek-ai/dsh-hooks-codex"]
cfg --> plugin_acp_hooks_codex
```
@@ -83,25 +83,25 @@ flowchart LR
| `approval` | `@deepseek-ai/dsh-user-approval` |
| `acp-agent` | `@deepseek-ai/dsh-acp-demo` |
| `token-meter` | `@deepseek-ai/dsh-token-meter` |
| `compact-basic` | `@deepseek-ai/dsh-compact-basic` |
| `compaction-basic` | `@deepseek-ai/dsh-compaction-basic` |
| `session-projection` | `@deepseek-ai/dsh-session-projection` |
| `subagent` | `@deepseek-ai/dsh-subagent` |
| `subagent-spawn` | `@deepseek-ai/dsh-subagent-spawn` |
| `subagent-fork` | `@deepseek-ai/dsh-subagent-fork` |
| `subagent-spawn-in-process` | `@deepseek-ai/dsh-subagent-spawn-in-process` |
| `subagent-fork-in-process` | `@deepseek-ai/dsh-subagent-fork-in-process` |
| `tool-subagent-control` | `@deepseek-ai/dsh-tool-subagent-control` |
| `tool-subagent-list-agents` | `@deepseek-ai/dsh-tool-subagent-control/list-agents` |
| `tool-subagent-report` | `@deepseek-ai/dsh-tool-subagent-report` |
| `tool-subagent` | `@deepseek-ai/dsh-tool-subagent` |
| `tool-subagent-fork` | `@deepseek-ai/dsh-tool-subagent` |
| `workflow-workerthread` | `@deepseek-ai/dsh-workflow-workerthread` |
| `workflow-worker-thread` | `@deepseek-ai/dsh-workflow-worker-thread` |
| `tool-workflow` | `@deepseek-ai/dsh-tool-workflow` |
| `tool-ralph` | `@deepseek-ai/dsh-tool-ralph` |
| `tool-todo` | `@deepseek-ai/dsh-tool-todo` |
| `repeat-tool-guard` | `@deepseek-ai/dsh-repeat-tool-guard` |
| `repeat-tool-reminder` | `@deepseek-ai/dsh-repeat-tool-reminder` |
| `fs-sandbox` | `@deepseek-ai/dsh-fs-sandbox` |
| `fs-policy` | `@deepseek-ai/dsh-fs-policy` |
| `fs-observation-policy` | `@deepseek-ai/dsh-fs-observation-policy` |
| `tool-fs` | `@deepseek-ai/dsh-tool-fs` |
| `hooks-claude` | `@deepseek-ai/dsh-hooks-claude` |
| `hooks-claude-code` | `@deepseek-ai/dsh-hooks-claude-code` |
| `hooks-codex` | `@deepseek-ai/dsh-hooks-codex` |
Source config: [`examples/acp-agent/cordis.yml`](cordis.yml).

View File

@@ -6,5 +6,7 @@
path: ./cordis.yml
patches:
- insert:
- id: cordis-host-runner
name: '@deepseek-ai/dsh-cordis-host-runner'
- id: tool-cordis
name: '@deepseek-ai/dsh-tool-cordis'

View File

@@ -70,8 +70,8 @@
# Summarize an older range after measured pressure or a canonical provider overflow.
# Ratios scale against the routed model's context window.
- id: compact-basic
name: '@deepseek-ai/dsh-compact-basic'
- id: compaction-basic
name: '@deepseek-ai/dsh-compaction-basic'
config:
thresholdRatio: 0.8
retainRatio: 0.08
@@ -90,13 +90,13 @@
- id: subagent
name: '@deepseek-ai/dsh-subagent'
- id: subagent-spawn
name: '@deepseek-ai/dsh-subagent-spawn'
- id: subagent-spawn-in-process
name: '@deepseek-ai/dsh-subagent-spawn-in-process'
config:
providerName: spawn
- id: subagent-fork
name: '@deepseek-ai/dsh-subagent-fork'
- id: subagent-fork-in-process
name: '@deepseek-ai/dsh-subagent-fork-in-process'
config:
providerName: fork
@@ -123,7 +123,8 @@
# Fork stays one-shot because a continuable child's `report` tool and prompt
# section precede the inherited history a fork reuses; `run_in_background` is off
# because this example mounts no task service. See .agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.md.
# as an explicit foreground-only choice even though agent-spine-demo mounts the
# generic Job runtime. See .agents/notes/implemented/architecture/2026-08-10-fork-children-stay-one-shot.md.
- id: tool-subagent-fork
name: '@deepseek-ai/dsh-tool-subagent'
config:
@@ -136,8 +137,8 @@
# The worker-thread workflow engine fans a model-written JavaScript script's
# `agent()` calls out through the spawn backend; the adjacent tool exposes it to the model.
- id: workflow-workerthread
name: '@deepseek-ai/dsh-workflow-workerthread'
- id: workflow-worker-thread
name: '@deepseek-ai/dsh-workflow-worker-thread'
config:
provider: spawn
@@ -153,22 +154,22 @@
allowParallelInProgress: true
# Identical repeat calls trigger advisory context, never a block, at the default
# thresholds [3, 5, 8]. Only the repeat-tool-guard snapshot scenario reaches them.
- id: repeat-tool-guard
name: '@deepseek-ai/dsh-repeat-tool-guard'
# thresholds [3, 5, 8]. Only the repeat-tool-reminder snapshot scenario reaches them.
- id: repeat-tool-reminder
name: '@deepseek-ai/dsh-repeat-tool-reminder'
# The filesystem stack rides the SAME sandbox policy as bash: dsh-fs-sandbox
# replaces dsh-fs-local behind ctx.fs and fences write/edit by the effective
# mode (read-only denies, workspace-write contains to the workspace + temp
# roots, danger-full-access passes through), so read/write/edit are available
# under every mode. fs-policy (read-before-edit) composes orthogonally on top.
# under every mode. fs-observation-policy (read-before-edit) composes orthogonally on top.
- id: fs-sandbox
name: '@deepseek-ai/dsh-fs-sandbox'
config:
cwd: !!js process.cwd()
- id: fs-policy
name: '@deepseek-ai/dsh-fs-policy'
- id: fs-observation-policy
name: '@deepseek-ai/dsh-fs-observation-policy'
- id: tool-fs
name: '@deepseek-ai/dsh-tool-fs'
@@ -177,9 +178,9 @@
# `session/new.cwd`; one `hooks.json` therefore applies to every session and a
# project-local file is not discovered. Missing config registers nothing. Hook
# commands still run in the session cwd. Warnings use `ctx.logger`, never stdout;
# see packages/hooks/hooks-claude/README.md for the deferred per-session design.
- id: hooks-claude
name: '@deepseek-ai/dsh-hooks-claude'
# see packages/hooks/hooks-claude-code/README.md for the deferred per-session design.
- id: hooks-claude-code
name: '@deepseek-ai/dsh-hooks-claude-code'
config:
configPath: ./hooks.json

View File

@@ -27,12 +27,12 @@
config:
provider: codex
toolName: subagent_codex
enableRunInBackground: false
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-claude-code
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: claude-code
toolName: subagent_claude_code
enableRunInBackground: false
backgroundMode: one-shot
maxDepth: provider-managed

View File

@@ -1,5 +1,5 @@
# Add both native product providers and the same independent foreground tool
# rows an Agent Preset may contribute. Loading the composition starts neither
# Add both native product providers and the same independent one-shot tool rows
# an Agent Preset may contribute. Loading the composition starts neither
# product; the scenario pins both model-visible schemas.
- id: base
name: '@deepseek-ai/cordis-plugin-include'
@@ -16,12 +16,12 @@
config:
provider: codex
toolName: subagent_codex
enableRunInBackground: false
backgroundMode: one-shot
maxDepth: provider-managed
- id: tool-subagent-claude-code
name: '@deepseek-ai/dsh-tool-subagent'
config:
provider: claude-code
toolName: subagent_claude_code
enableRunInBackground: false
backgroundMode: one-shot
maxDepth: provider-managed

View File

@@ -25,5 +25,5 @@
config:
provider: codex
toolName: subagent_codex
enableRunInBackground: false
backgroundMode: one-shot
maxDepth: provider-managed

View File

@@ -1,4 +1,4 @@
# Add the native Codex product provider and its preset-shaped foreground tool to
# Add the native Codex product provider and its preset-shaped one-shot tool to
# the real ACP composition. The model is told not to call it; the scenario pins
# the assembled request schema without starting Codex.
- id: base
@@ -14,5 +14,5 @@
config:
provider: codex
toolName: subagent_codex
enableRunInBackground: false
backgroundMode: one-shot
maxDepth: provider-managed

View File

@@ -53,11 +53,11 @@ class SnapshotSession {
/** Cordis plugin name. */
export const name = 'pty-snapshot-backend'
/** Required PTY service. */
export const inject = ['pty']
export const inject = ['terminals']
/** Register the deterministic snapshot backend. */
export function apply(ctx) {
ctx.pty.registerBackend({
ctx.terminals.registerBackend({
type: 'shell',
spawn: () => Promise.resolve(new SnapshotSession()),
})

View File

@@ -9,11 +9,11 @@
disabled: true
- insert:
- id: pty
name: '@deepseek-ai/dsh-pty'
name: '@deepseek-ai/dsh-terminal'
- id: pty-snapshot-backend
name: './pty-snapshot-backend.mjs'
- id: tool-pty
name: '@deepseek-ai/dsh-tool-pty'
- id: tool-terminal
name: '@deepseek-ai/dsh-tool-terminal'
config:
maxResultBytes: 64
- id: llm-replay

View File

@@ -7,9 +7,9 @@
patches:
- insert:
- id: pty
name: '@deepseek-ai/dsh-pty'
- id: pty-local
name: '@deepseek-ai/dsh-pty-local'
name: '@deepseek-ai/dsh-terminal'
- id: terminal-bash
name: '@deepseek-ai/dsh-terminal-bash'
config:
pollIntervalMs: 10
exactProbeAfterMs: 20
@@ -17,5 +17,5 @@
handoffGraceMs: 250
timeoutMs: 2000
disposeGraceMs: 500
- id: tool-pty
name: '@deepseek-ai/dsh-tool-pty'
- id: tool-terminal
name: '@deepseek-ai/dsh-tool-terminal'

View File

@@ -9,4 +9,4 @@
- id: tool-session-query
name: '@deepseek-ai/dsh-tool-session-query'
- id: timeout-policy
name: '@deepseek-ai/dsh-timeout-policy'
name: '@deepseek-ai/dsh-tool-call-timeout-policy'

View File

@@ -9,4 +9,4 @@
- id: tool-session-query
name: '@deepseek-ai/dsh-tool-session-query'
- id: timeout-policy
name: '@deepseek-ai/dsh-timeout-policy'
name: '@deepseek-ai/dsh-tool-call-timeout-policy'

View File

@@ -42,7 +42,7 @@
models:
- id: title-model
- id: session-title-provider
name: '@deepseek-ai/dsh-session-title-first-message-llm'
name: '@deepseek-ai/dsh-session-title-first-prompt-llm'
config:
targetWords: 5
targetCjkCharacters: 10

View File

@@ -1,4 +1,4 @@
# Session-title snapshot composition: the optional first-message provider uses
# Session-title snapshot composition: the optional first-prompt provider uses
# the ordinary DeepSeek route while the ACP app and every other capability stay
# identical to the base example.
- id: base
@@ -8,7 +8,7 @@
patches:
- insert:
- id: session-title-provider
name: '@deepseek-ai/dsh-session-title-first-message-llm'
name: '@deepseek-ai/dsh-session-title-first-prompt-llm'
config:
targetWords: 5
targetCjkCharacters: 10

View File

@@ -16,7 +16,7 @@ import { decodeStorageRecord } from '@deepseek-ai/dsh-session'
* uniformity guard, the fixture guards). Fixtures live under `snapshots/<name>/`;
* `pnpm run test:snapshot:record` re-records model transcripts against the real
* API; `pnpm run test:snapshot:refresh` rewrites current replay expected outputs keyless.
* See the package README (packages/support/acp-snapshot) and the snapshot Agent Note,
* See the package README (packages/test-support/acp-snapshot) and the snapshot Agent Note,
* .agents/notes/implemented/testing/2026-06-19-acp-snapshot-tests.md.
*/
@@ -35,7 +35,7 @@ const CODE_MODE_CONFIG = fileURLToPath(new URL('../code-mode.cordis.yml', import
const CODE_MODE_IMAGE_CONFIG = fileURLToPath(new URL('../code-mode-image.cordis.yml', import.meta.url))
const CODE_MODE_WORKSPACE_CONTEXT_CONFIG = fileURLToPath(new URL('../code-mode-workspace-context.cordis.yml', import.meta.url))
const BOTH_MODE_CONFIG = fileURLToPath(new URL('../both-mode.cordis.yml', import.meta.url))
const WORKSPACE_CONTEXT_CONFIG = fileURLToPath(new URL('../workspace-context.cordis.yml', import.meta.url))
const WORKSPACE_CONTEXT_CONFIG = fileURLToPath(new URL('../agent-instructions.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))
@@ -62,7 +62,7 @@ const FS_SEARCH_CONFIG = fileURLToPath(new URL('./fs-search.cordis.yml', import.
const PARTIAL_LANDLOCK_CONFIG = fileURLToPath(new URL('../partial-landlock.cordis.yml', import.meta.url))
const PWSH_CONFIG = fileURLToPath(new URL('./pwsh.cordis.yml', import.meta.url))
const BACKGROUND_TASK_ADMISSION_CONFIG = fileURLToPath(
new URL('../background-task-admission.cordis.yml', import.meta.url),
new URL('../background-job-admission.cordis.yml', import.meta.url),
)
const PRODUCT_SUBAGENT_CODEX_CONFIG = fileURLToPath(new URL('../product-subagent-codex.cordis.yml', import.meta.url))
const PRODUCT_SUBAGENT_BOTH_CONFIG = fileURLToPath(new URL('../product-subagent-both.cordis.yml', import.meta.url))
@@ -230,7 +230,7 @@ const SCENARIOS: Scenario[] = [
},
{ name: 'bash-tool-turn', hasModelTurn: true, recorded: true },
{
name: 'background-task-admission',
name: 'background-job-admission',
hasModelTurn: true,
recorded: false,
overridden: true,
@@ -266,7 +266,7 @@ const SCENARIOS: Scenario[] = [
posixOnly: true,
},
// A valid cwd plus a missing provider executable exercises the assembled
// foreground error and background task marker without a platform runner.
// foreground error and background job marker without a platform runner.
{
name: 'missing-sandbox-runner',
hasModelTurn: true,
@@ -360,7 +360,7 @@ const SCENARIOS: Scenario[] = [
// LIVE model to repeat one call three times is not a stable recording, so
// the fixture scripts five identical todo_write calls and pins BOTH reminder
// tiers (gentle at 3, detailed at 5) as injected user/message in transcript and log.
{ name: 'repeat-tool-guard', hasModelTurn: true, recorded: false },
{ name: 'repeat-tool-reminder', hasModelTurn: true, recorded: false },
// Authored replay: a root AGENTS.md pins the session prefix, then a read in
// nested/ discovers its narrower AGENTS.md as a raw, metadata-bearing
// injected user/message. Both portable AGENTS.md fixtures are symlinks to a sibling
@@ -373,12 +373,12 @@ const SCENARIOS: Scenario[] = [
// The scenario-specific config keeps home/root discovery hermetic, and the
// resulting prefix needs its own pinned header class.
{
name: 'workspace-context',
name: 'agent-instructions',
hasModelTurn: true,
recorded: false,
overridden: true,
pinsHeader: true,
headerClass: 'workspace-context',
headerClass: 'agent-instructions',
toolSchemasSource: 'text-turn',
configPath: WORKSPACE_CONTEXT_CONFIG,
prepareWorkspace: prepareDelimiterPathWorkspace,
@@ -388,7 +388,7 @@ const SCENARIOS: Scenario[] = [
// Cancelling a live bash call relies on POSIX process-group termination;
// Windows bash process-tree kill is deferred with the Bash execution domain.
{ name: 'cancel-tool-calls', hasModelTurn: true, recorded: false, overridden: true, posixOnly: true },
{ name: 'subagent-spawn', hasModelTurn: true, recorded: true },
{ name: 'subagent-spawn-in-process', hasModelTurn: true, recorded: true },
// Keyless authored scenario: the child ends at max-tokens with an empty
// usage-only assistant/message after earlier text and a tool call. The
// parent's tool result must retain that assistant output and stop reason.
@@ -400,7 +400,7 @@ const SCENARIOS: Scenario[] = [
// scripts and harvest order nondeterministically across concurrent children
// (XXX(concurrent-subagents) in dsh-llm-replay).
{ name: 'subagent-parallel', hasModelTurn: true, recorded: false },
{ name: 'subagent-fork', hasModelTurn: true, recorded: true },
{ name: 'subagent-fork-in-process', hasModelTurn: true, recorded: true },
{ name: 'subagent-mixed', hasModelTurn: true, recorded: true },
// Authored continuable-subagent transcript: a background delegation returns
// only the durable subagent id, two send_message calls queue as later FIFO
@@ -499,8 +499,9 @@ const SCENARIOS: Scenario[] = [
// child runs as a spawn subagent under the worker-thread engine (its session is the
// child fixture), and the tool result carries the script's return value.
{ name: 'workflow-run', hasModelTurn: true, recorded: true },
// Authored counterpart to the packaged Python SDK snapshot: mount a live marker, inspect it
// through Code Mode, run direct and workflow children, then unmount it. The extra Code Mode and
// Authored counterpart to the packaged Python SDK snapshot: define a host-half marker package and
// run it, inspect this session's dynamic packages through Code Mode, run direct and workflow
// children, then undefine it. The extra Code Mode and
// Cordis plugins require their own request-header pin; the fixture tests deterministic composition.
{
name: 'advanced-toolchain',

View File

@@ -1,15 +1,15 @@
import type { Context } from '@deepseek-ai/cordis'
import '@deepseek-ai/dsh-user-interaction'
import '@deepseek-ai/dsh-user-questions'
/** Snapshot-only provider whose invocation means the child guard failed. */
export const name = 'child-question-tripwire'
/** User-interaction service required by the tripwire provider. */
export const inject = ['userInteraction']
export const inject = ['userQuestions']
/** Register a provider that must remain unreachable for the delegated call. */
export function apply(ctx: Context): void {
ctx.userInteraction.registerProvider({
ctx.userQuestions.registerProvider({
async ask() {
throw new Error('snapshot tripwire: delegated question reached the UI provider')
},

View File

@@ -14,14 +14,14 @@
config:
graceMs: 200
- id: bash-env
name: '@deepseek-ai/dsh-bash-env'
- id: shell-env
name: '@deepseek-ai/dsh-shell-env'
- id: tasks
name: '@deepseek-ai/dsh-tasks-local'
name: '@deepseek-ai/dsh-jobs-local'
- id: tool-tasks
name: '@deepseek-ai/dsh-tool-tasks'
- id: tool-jobs
name: '@deepseek-ai/dsh-tool-jobs'
- id: tool-pwsh
name: '@deepseek-ai/dsh-tool-pwsh'

View File

@@ -37,7 +37,7 @@ try {
run_in_background: true,
},
})
const taskId = (background.value as { taskId: string }).taskId
const jobId = (background.value as { jobId: string }).jobId
// The output delta and the terminal status can land in separate reads
// (Windows flushes the child pipe at exit), so accumulate both.
@@ -47,8 +47,8 @@ try {
const read = await ctx.tools.execute({
signal: new AbortController().signal,
callId: CallId('loader-bg-read'),
name: 'task_output',
arguments: { task_id: taskId },
name: 'job_output',
arguments: { job_id: jobId },
})
backgroundText += read.content.filter(block => block.type === 'text').map(block => block.text).join('')
if (backgroundText.includes('loader-bg-ok') && backgroundText.includes('[status: completed')) break

View File

@@ -1,4 +1,4 @@
# Test-only composition of both public opt-in providers and foreground tools.
# Test-only composition of both public opt-in providers and one-shot task tools.
# The owning e2e boots this tree but never invokes a model or product process.
- id: fixture
name: './fixture.ts'
@@ -20,7 +20,7 @@
config:
provider: codex
toolName: subagent_codex
enableRunInBackground: false
backgroundMode: one-shot
maxDepth: 'provider-managed'
- id: tool-subagent-claude-code
@@ -28,7 +28,7 @@
config:
provider: claude-code
toolName: subagent_claude_code
enableRunInBackground: false
backgroundMode: one-shot
maxDepth: 'provider-managed'
- id: agent-spine

View File

@@ -53,11 +53,16 @@ try {
required: tool.parameters.required,
}
})
const jobTools = ctx.tools.schemas()
.map(schema => schema.name)
.filter(name => name === 'job_kill' || name === 'job_list' || name === 'job_output')
.sort()
process.stdout.write(`${JSON.stringify({
registeredProviders: ctx.subagents.list(),
providers,
tools,
jobTools,
starts,
})}\n`)
} finally {

View File

@@ -1,4 +1,4 @@
# Test-only composition of the public opt-in provider and foreground tool.
# Test-only composition of the public opt-in provider and one-shot task tool.
# The owning e2e boots this tree but never invokes the model or Codex.
- id: fixture
name: './fixture.ts'
@@ -17,7 +17,7 @@
config:
provider: codex
toolName: subagent_codex
enableRunInBackground: false
backgroundMode: one-shot
maxDepth: 'provider-managed'
- id: agent-spine

View File

@@ -31,6 +31,10 @@ try {
if (typeof properties !== 'object' || properties === null || Array.isArray(properties)) {
throw new Error('subagent_codex tool has invalid parameter properties')
}
const jobTools = ctx.tools.schemas()
.map(schema => schema.name)
.filter(name => name === 'job_kill' || name === 'job_list' || name === 'job_output')
.sort()
process.stdout.write(`${JSON.stringify({
providers: ctx.subagents.list(),
@@ -44,6 +48,7 @@ try {
parameterNames: Object.keys(properties).sort(),
required: tool.parameters.required,
},
jobTools,
starts,
})}\n`)
} finally {

View File

@@ -1,6 +1,6 @@
import type { Context } from '@deepseek-ai/cordis'
import type {} from '@deepseek-ai/dsh-agent'
import { CompactionId, compactCheckpointSource } from '@deepseek-ai/dsh-compact'
import { CompactionId, compactCheckpointSource } from '@deepseek-ai/dsh-compaction'
import { createUserMessage } from '@deepseek-ai/dsh-llm'
import type {} from '@deepseek-ai/dsh-tools'
@@ -21,7 +21,7 @@ export function apply(ctx: Context): void {
const baseline = agent.session.surface.nodes
.map(seq => agent.session.events[seq])
.find(event => event?.type === 'user/message'
&& event.data.source.kind === 'workspace-instructions'
&& event.data.source.kind === 'agent-instructions'
&& event.data.source.baseline === true)
if (baseline === undefined) throw new Error('workspace baseline missing before snapshot compaction')
agent.session.append('user/message', createUserMessage({

View File

@@ -41,6 +41,6 @@
- id: deepseek-v4-flash
contextWindow: 1000000
defaultMaxTokens: 256000
reasoningEfforts: ['off', 'high', 'max']
reasoningEfforts: ['off', 'low', 'high', 'max']
defaultReasoningEffort: max
- id: deepseek-v4-pro

View File

@@ -24,7 +24,7 @@
workspaceContext: false
skills:
enabled: false
toolTasks: false
toolJobs: false
goals: false
persona: You are a concise snapshot agent working in {{cwd}}.

View File

@@ -21,7 +21,7 @@
workspaceContext: false
skills:
enabled: false
toolTasks: false
toolJobs: false
goals: false
persona: You are a concise snapshot agent working in {{cwd}}.

View File

@@ -3,8 +3,8 @@
"kind": "chunks",
"chunks": [
{ "type": "block-start", "index": 0, "blockType": "tool-call" },
{ "type": "tool-call-delta", "index": 0, "id": "call_goal_create", "name": "create_goal", "argumentsDelta": "{\"objective\":\"Finish the ACP goal-session snapshot proof\",\"max_goal_rounds\":2}" },
{ "type": "block-end", "index": 0, "block": { "type": "tool-call", "id": "call_goal_create", "name": "create_goal", "arguments": "{\"objective\":\"Finish the ACP goal-session snapshot proof\",\"max_goal_rounds\":2}" } },
{ "type": "tool-call-delta", "index": 0, "id": "call_goal_create", "name": "create_goal", "argumentsDelta": "{\"objective\":\"Finish the ACP goal-round-driver snapshot proof\",\"max_goal_rounds\":2}" },
{ "type": "block-end", "index": 0, "block": { "type": "tool-call", "id": "call_goal_create", "name": "create_goal", "arguments": "{\"objective\":\"Finish the ACP goal-round-driver snapshot proof\",\"max_goal_rounds\":2}" } },
{ "type": "usage", "usage": { "inputTokens": 20, "outputTokens": 8 } },
{ "type": "finish", "reason": { "kind": "tool-calls" } }
]

View File

@@ -9,14 +9,14 @@
{"type":"request/header","seq":7,"time":0,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","seq":8,"time":0,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
{"type":"assistant/chunk","seq":9,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
{"type":"assistant/chunk","seq":10,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"call_goal_create","name":"create_goal","argumentsDelta":"{\"objective\":\"Finish the ACP goal-session snapshot proof\",\"max_goal_rounds\":2}"}}}
{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_goal_create","name":"create_goal","arguments":"{\"objective\":\"Finish the ACP goal-session snapshot proof\",\"max_goal_rounds\":2}"}}}}
{"type":"assistant/chunk","seq":10,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"call_goal_create","name":"create_goal","argumentsDelta":"{\"objective\":\"Finish the ACP goal-round-driver snapshot proof\",\"max_goal_rounds\":2}"}}}
{"type":"assistant/chunk","seq":11,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_goal_create","name":"create_goal","arguments":"{\"objective\":\"Finish the ACP goal-round-driver snapshot proof\",\"max_goal_rounds\":2}"}}}}
{"type":"assistant/chunk","seq":12,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":20,"outputTokens":8}}}}
{"type":"assistant/chunk","seq":13,"time":0,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":14,"time":0,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_goal_create","name":"create_goal","arguments":"{\"objective\":\"Finish the ACP goal-session snapshot proof\",\"max_goal_rounds\":2}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":20,"outputTokens":8}},"sourceEventSeqs":[9,10,11,12,13],"surfaceOp":"append"}
{"type":"tool/call","seq":15,"time":0,"data":{"turn":1,"step":1,"callId":"call_goal_create","name":"create_goal","arguments":"{\"objective\":\"Finish the ACP goal-session snapshot proof\",\"max_goal_rounds\":2}"}}
{"type":"goal/change","seq":16,"time":0,"data":{"kind":"goal/change","version":1,"operation":"create","goal":{"id":"goal-{{sessionId}}","revision":1,"objective":"Finish the ACP goal-session snapshot proof","phase":"active","maxGoalRounds":2},"roundsStarted":0,"createdAt":0,"updatedAt":0}}
{"type":"tool/result","seq":17,"time":0,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_goal_create"},"content":[{"type":"tool-result","toolCallId":"call_goal_create","content":[{"type":"text","text":"{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":1,\"objective\":\"Finish the ACP goal-session snapshot proof\",\"phase\":\"active\",\"roundsStarted\":0,\"maxGoalRounds\":2},\"activation\":\"armed\"}"}],"isError":false}],"role":"user","id":"{{sessionId}}"}},"sourceEventSeqs":[15],"surfaceOp":"append"}
{"type":"assistant/message","seq":14,"time":0,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_goal_create","name":"create_goal","arguments":"{\"objective\":\"Finish the ACP goal-round-driver snapshot proof\",\"max_goal_rounds\":2}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":20,"outputTokens":8}},"sourceEventSeqs":[9,10,11,12,13],"surfaceOp":"append"}
{"type":"tool/call","seq":15,"time":0,"data":{"turn":1,"step":1,"callId":"call_goal_create","name":"create_goal","arguments":"{\"objective\":\"Finish the ACP goal-round-driver snapshot proof\",\"max_goal_rounds\":2}"}}
{"type":"goal/change","seq":16,"time":0,"data":{"kind":"goal/change","version":1,"operation":"create","goal":{"id":"goal-{{sessionId}}","revision":1,"objective":"Finish the ACP goal-round-driver snapshot proof","phase":"active","maxGoalRounds":2},"roundsStarted":0,"createdAt":0,"updatedAt":0}}
{"type":"tool/result","seq":17,"time":0,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_goal_create"},"content":[{"type":"tool-result","toolCallId":"call_goal_create","content":[{"type":"text","text":"{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":1,\"objective\":\"Finish the ACP goal-round-driver snapshot proof\",\"phase\":\"active\",\"roundsStarted\":0,\"maxGoalRounds\":2},\"activation\":\"armed\"}"}],"isError":false}],"role":"user","id":"{{sessionId}}"}},"sourceEventSeqs":[15],"surfaceOp":"append"}
{"type":"step/end","seq":18,"time":0,"data":{"turn":1,"step":1}}
{"type":"step/start","seq":19,"time":0,"data":{"turn":1,"step":2}}
{"type":"assistant/chunk","seq":20,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
@@ -26,7 +26,7 @@
{"type":"assistant/chunk","seq":24,"time":0,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":25,"time":0,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_goal_get","name":"get_goal","arguments":"{}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":30,"outputTokens":4}},"sourceEventSeqs":[20,21,22,23,24],"surfaceOp":"append"}
{"type":"tool/call","seq":26,"time":0,"data":{"turn":1,"step":2,"callId":"call_goal_get","name":"get_goal","arguments":"{}"}}
{"type":"tool/result","seq":27,"time":0,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"call_goal_get"},"content":[{"type":"tool-result","toolCallId":"call_goal_get","content":[{"type":"text","text":"{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":1,\"objective\":\"Finish the ACP goal-session snapshot proof\",\"phase\":\"active\",\"roundsStarted\":0,\"maxGoalRounds\":2},\"activation\":\"armed\"}"}],"isError":false}],"role":"user","id":"{{sessionId}}"}},"sourceEventSeqs":[26],"surfaceOp":"append"}
{"type":"tool/result","seq":27,"time":0,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"call_goal_get"},"content":[{"type":"tool-result","toolCallId":"call_goal_get","content":[{"type":"text","text":"{\"goal\":{\"id\":\"goal-{{sessionId}}\",\"revision\":1,\"objective\":\"Finish the ACP goal-round-driver snapshot proof\",\"phase\":\"active\",\"roundsStarted\":0,\"maxGoalRounds\":2},\"activation\":\"armed\"}"}],"isError":false}],"role":"user","id":"{{sessionId}}"}},"sourceEventSeqs":[26],"surfaceOp":"append"}
{"type":"step/end","seq":28,"time":0,"data":{"turn":1,"step":2}}
{"type":"step/start","seq":29,"time":0,"data":{"turn":1,"step":3}}
{"type":"assistant/chunk","seq":30,"time":0,"data":{"turn":1,"step":3,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
@@ -37,11 +37,11 @@
{"type":"assistant/message","seq":35,"time":0,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"text","text":"GOAL READY"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":35,"outputTokens":2}},"sourceEventSeqs":[30,31,32,33,34],"surfaceOp":"append"}
{"type":"step/end","seq":36,"time":0,"data":{"turn":1,"step":3}}
{"type":"turn/end","seq":37,"time":0,"data":{"turn":1,"reason":{"kind":"completed"}}}
{"type":"agent/inbox/spliced","seq":38,"time":0,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"<goal_round>\nObjective: \"Finish the ACP goal-session snapshot proof\"\nRound: 1/2\n\nContinue working toward the objective in this same session. Treat the current workspace, tool results, and durable session state as authoritative; inspect them instead of assuming earlier narration is still current. Make concrete progress and verify the result. Before claiming completion, gather evidence that the whole objective is achieved, read the current goal, and mark it complete. If work remains, leave the goal active for the next round. Follow the configured goal-tool policy before reporting a blocker.\n</goal_round>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":1,"round":1},"role":"user","id":"{{sessionId}}"}]}}
{"type":"agent/inbox/spliced","seq":38,"time":0,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"<goal_round>\nObjective: \"Finish the ACP goal-round-driver snapshot proof\"\nRound: 1/2\n\nContinue working toward the objective in this same session. Treat the current workspace, tool results, and durable session state as authoritative; inspect them instead of assuming earlier narration is still current. Make concrete progress and verify the result. Before claiming completion, gather evidence that the whole objective is achieved, read the current goal, and mark it complete. If work remains, leave the goal active for the next round. Follow the configured goal-tool policy before reporting a blocker.\n</goal_round>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":1,"round":1},"role":"user","id":"{{sessionId}}"}]}}
{"type":"turn/start","seq":39,"time":0,"data":{"turn":2}}
{"type":"agent/inbox/spliced","seq":40,"time":0,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","seq":41,"time":0,"data":{"turn":2,"step":1}}
{"type":"user/message","seq":42,"time":0,"data":{"content":[{"type":"text","text":"<goal_round>\nObjective: \"Finish the ACP goal-session snapshot proof\"\nRound: 1/2\n\nContinue working toward the objective in this same session. Treat the current workspace, tool results, and durable session state as authoritative; inspect them instead of assuming earlier narration is still current. Make concrete progress and verify the result. Before claiming completion, gather evidence that the whole objective is achieved, read the current goal, and mark it complete. If work remains, leave the goal active for the next round. Follow the configured goal-tool policy before reporting a blocker.\n</goal_round>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":1,"round":1},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}
{"type":"user/message","seq":42,"time":0,"data":{"content":[{"type":"text","text":"<goal_round>\nObjective: \"Finish the ACP goal-round-driver snapshot proof\"\nRound: 1/2\n\nContinue working toward the objective in this same session. Treat the current workspace, tool results, and durable session state as authoritative; inspect them instead of assuming earlier narration is still current. Make concrete progress and verify the result. Before claiming completion, gather evidence that the whole objective is achieved, read the current goal, and mark it complete. If work remains, leave the goal active for the next round. Follow the configured goal-tool policy before reporting a blocker.\n</goal_round>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":1,"round":1},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}
{"type":"assistant/chunk","seq":43,"time":0,"data":{"turn":2,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
{"type":"assistant/chunk","seq":44,"time":0,"data":{"turn":2,"step":1,"chunk":{"type":"text-delta","index":0,"text":"GOAL ROUND ONE"}}}
{"type":"assistant/chunk","seq":45,"time":0,"data":{"turn":2,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"GOAL ROUND ONE"}}}}
@@ -50,13 +50,13 @@
{"type":"assistant/message","seq":48,"time":0,"data":{"turn":2,"step":1,"message":{"role":"assistant","content":[{"type":"text","text":"GOAL ROUND ONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"{{sessionId}}"},"usage":{"inputTokens":40,"outputTokens":3}},"sourceEventSeqs":[43,44,45,46,47],"surfaceOp":"append"}
{"type":"step/end","seq":49,"time":0,"data":{"turn":2,"step":1}}
{"type":"turn/end","seq":50,"time":0,"data":{"turn":2,"reason":{"kind":"completed"}}}
{"type":"agent/inbox/spliced","seq":51,"time":0,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"<goal_round>\nObjective: \"Finish the ACP goal-session snapshot proof\"\nRound: 2/2\n\nContinue working toward the objective in this same session. Treat the current workspace, tool results, and durable session state as authoritative; inspect them instead of assuming earlier narration is still current. Make concrete progress and verify the result. Before claiming completion, gather evidence that the whole objective is achieved, read the current goal, and mark it complete. If work remains, leave the goal active for the next round. Follow the configured goal-tool policy before reporting a blocker.\n</goal_round>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":1,"round":2},"role":"user","id":"{{sessionId}}"}]}}
{"type":"agent/inbox/spliced","seq":51,"time":0,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"<goal_round>\nObjective: \"Finish the ACP goal-round-driver snapshot proof\"\nRound: 2/2\n\nContinue working toward the objective in this same session. Treat the current workspace, tool results, and durable session state as authoritative; inspect them instead of assuming earlier narration is still current. Make concrete progress and verify the result. Before claiming completion, gather evidence that the whole objective is achieved, read the current goal, and mark it complete. If work remains, leave the goal active for the next round. Follow the configured goal-tool policy before reporting a blocker.\n</goal_round>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":1,"round":2},"role":"user","id":"{{sessionId}}"}]}}
{"type":"turn/start","seq":52,"time":0,"data":{"turn":3}}
{"type":"agent/inbox/spliced","seq":53,"time":0,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","seq":54,"time":0,"data":{"turn":3,"step":1}}
{"type":"user/message","seq":55,"time":0,"data":{"content":[{"type":"text","text":"<goal_round>\nObjective: \"Finish the ACP goal-session snapshot proof\"\nRound: 2/2\n\nContinue working toward the objective in this same session. Treat the current workspace, tool results, and durable session state as authoritative; inspect them instead of assuming earlier narration is still current. Make concrete progress and verify the result. Before claiming completion, gather evidence that the whole objective is achieved, read the current goal, and mark it complete. If work remains, leave the goal active for the next round. Follow the configured goal-tool policy before reporting a blocker.\n</goal_round>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":1,"round":2},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}
{"type":"user/message","seq":55,"time":0,"data":{"content":[{"type":"text","text":"<goal_round>\nObjective: \"Finish the ACP goal-round-driver snapshot proof\"\nRound: 2/2\n\nContinue working toward the objective in this same session. Treat the current workspace, tool results, and durable session state as authoritative; inspect them instead of assuming earlier narration is still current. Make concrete progress and verify the result. Before claiming completion, gather evidence that the whole objective is achieved, read the current goal, and mark it complete. If work remains, leave the goal active for the next round. Follow the configured goal-tool policy before reporting a blocker.\n</goal_round>"}],"source":{"kind":"goal","goalId":"goal-{{sessionId}}","revision":1,"round":2},"role":"user","id":"{{sessionId}}"},"surfaceOp":"append"}
{"type":"assistant/chunk","seq":56,"time":0,"data":{"turn":3,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
{"type":"assistant/chunk","seq":57,"time":0,"data":{"turn":3,"step":1,"chunk":{"type":"text-delta","index":0,"text":"partial"}}}
{"type":"step/end","seq":58,"time":0,"data":{"turn":3,"step":1}}
{"type":"turn/end","seq":59,"time":0,"data":{"turn":3,"reason":{"kind":"aborted","reason":{"kind":"user"}}}}
{"type":"goal/change","seq":60,"time":0,"data":{"kind":"goal/change","version":1,"operation":"pause","goal":{"id":"goal-{{sessionId}}","revision":2,"objective":"Finish the ACP goal-session snapshot proof","phase":"paused","maxGoalRounds":2},"roundsStarted":2,"createdAt":0,"updatedAt":0}}
{"type":"goal/change","seq":60,"time":0,"data":{"kind":"goal/change","version":1,"operation":"pause","goal":{"id":"goal-{{sessionId}}","revision":2,"objective":"Finish the ACP goal-round-driver snapshot proof","phase":"paused","maxGoalRounds":2},"roundsStarted":2,"createdAt":0,"updatedAt":0}}

View File

@@ -16,7 +16,7 @@ import { describe, expect, it } from 'vitest'
// This lifecycle proof has goal-specific timestamp normalization and semantic
// assertions, so it owns a separate snapshot root from the generic suite.
const scenarioDir = join(dirname(fileURLToPath(import.meta.url)), 'goal-snapshots/goal-session')
const scenarioDir = join(dirname(fileURLToPath(import.meta.url)), 'goal-snapshots/goal-round-driver')
const fixtureFile = join(scenarioDir, 'session.jsonl')
const overrideFile = join(scenarioDir, 'replay.override.json')
const stdoutExpected = join(scenarioDir, 'stdout.expected.jsonl')
@@ -90,7 +90,7 @@ describe('same-session goal snapshot through the ACP automation driver', () => {
expect(rounds).toEqual([1, 2])
expect(foldGoal(events)).toMatchObject({
goal: {
objective: 'Finish the ACP goal-session snapshot proof',
objective: 'Finish the ACP goal-round-driver snapshot proof',
phase: 'paused',
revision: 2,
maxGoalRounds: 2,

View File

@@ -10,8 +10,8 @@
- insert:
- id: lsp
name: '@deepseek-ai/dsh-lsp'
- id: lsp-local
name: '@deepseek-ai/dsh-lsp-local'
- id: lsp-stdio
name: '@deepseek-ai/dsh-lsp-stdio'
config:
servers:
fixture:
@@ -20,7 +20,7 @@
extensionToLanguage:
'.ts': typescript
- id: timeout-policy
name: '@deepseek-ai/dsh-timeout-policy'
name: '@deepseek-ai/dsh-tool-call-timeout-policy'
- id: tool-lsp
name: '@deepseek-ai/dsh-tool-lsp'
config:

View File

@@ -8,8 +8,8 @@
- insert:
- id: lsp
name: '@deepseek-ai/dsh-lsp'
- id: lsp-local
name: '@deepseek-ai/dsh-lsp-local'
- id: lsp-stdio
name: '@deepseek-ai/dsh-lsp-stdio'
config:
servers:
fixture:
@@ -18,7 +18,7 @@
extensionToLanguage:
'.ts': typescript
- id: timeout-policy
name: '@deepseek-ai/dsh-timeout-policy'
name: '@deepseek-ai/dsh-tool-call-timeout-policy'
- id: tool-lsp
name: '@deepseek-ai/dsh-tool-lsp'
config:

View File

@@ -14,8 +14,8 @@
- id: bash
name: '@deepseek-ai/dsh-pwsh-local'
- id: bash-env
name: '@deepseek-ai/dsh-bash-env'
- id: shell-env
name: '@deepseek-ai/dsh-shell-env'
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
@@ -27,7 +27,7 @@
workspaceContext: false
skills:
enabled: false
# task_output/task_kill stay mounted (the bundle's toolTasks default) so
# job_output/job_kill stay mounted (the bundle's toolJobs default) so
# background pwsh runs are readable and killable.
goals: false
# The pwsh tool replaces the bundle's bash tool in this composition.

View File

@@ -11,8 +11,8 @@
- id: bash
name: '@deepseek-ai/dsh-pwsh-local'
- id: bash-env
name: '@deepseek-ai/dsh-bash-env'
- id: shell-env
name: '@deepseek-ai/dsh-shell-env'
- id: acp-agent
name: '@deepseek-ai/dsh-acp-demo'
@@ -24,7 +24,7 @@
workspaceContext: false
skills:
enabled: false
# task_output/task_kill stay mounted (the bundle's toolTasks default) so
# job_output/job_kill stay mounted (the bundle's toolJobs default) so
# background pwsh runs are readable and killable.
goals: false
# The pwsh tool replaces the bundle's bash tool in this composition.

View File

@@ -1,7 +1,14 @@
{
"steps": [
{ "op": "initialize" },
{ "op": "newSession" },
{ "op": "prompt", "text": "Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_ACP_OK." }
{
"op": "initialize"
},
{
"op": "newSession"
},
{
"op": "prompt",
"text": "Run this advanced flow exactly once: define a host-only dynamic Cordis Package named Snapshot Marker; run and inspect snap-1/pkg-1 through run_code; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; remove snap-1; then reply with exactly ADVANCED_ACP_OK."
}
]
}

View File

@@ -6,7 +6,7 @@
{"type":"subagent/descriptor","seq":4,"time":1786357538308,"data":{"version":2,"mode":"one-shot","provider":"spawn","label":"Check direct child"}}
{"type":"step/start","seq":5,"time":1786357538310,"data":{"turn":1,"step":1}}
{"type":"user/message","seq":6,"time":1785730458555,"data":{"content":[{"type":"text","text":"Reply with exactly DIRECT_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"ebe0cfa0-a909-47e0-8294-28ad84a8fe77"},"surfaceOp":"append"}
{"type":"user/message","seq":7,"time":1786357538310,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"10c6c81d-85a2-4c50-a8c2-2f58f309f070"},"surfaceOp":"append"}
{"type":"user/message","seq":7,"time":1786357538310,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"21c656d1-bb34-4dcd-8d27-9eac72ffcd72"},"surfaceOp":"append"}
{"type":"session/title","seq":8,"time":1786357538310,"data":{"title":"Reply with exactly DIRECT_CHILD_OK and","messageSeqs":[6],"source":{"kind":"fallback"}}}
{"type":"request/header","seq":9,"time":1785730458555,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","seq":10,"time":1785730458555,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}

View File

@@ -6,7 +6,7 @@
{"type":"subagent/descriptor","seq":4,"time":1786357538469,"data":{"version":2,"mode":"one-shot","provider":"spawn"}}
{"type":"step/start","seq":5,"time":1786357538470,"data":{"turn":1,"step":1}}
{"type":"user/message","seq":6,"time":1785730458703,"data":{"content":[{"type":"text","text":"Reply with exactly WORKFLOW_CHILD_OK and nothing else."}],"source":{"kind":"user"},"role":"user","id":"2ac2cc54-9bce-4cfa-a569-a64f51bc30a7"},"surfaceOp":"append"}
{"type":"user/message","seq":7,"time":1786357538471,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"5a8c5ad7-352c-475a-9356-87510cc6b1a8"},"surfaceOp":"append"}
{"type":"user/message","seq":7,"time":1786357538471,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`).\n\nYou are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."},{"name":"subagent:delegation","text":"You are a delegated subagent: your permission scope was fixed when you were started and cannot be widened from inside this session — operations that require approval are rejected automatically. When the task needs access beyond that scope, do not retry the denied operation; state the limitation in your reply so the delegating agent can handle it."}]},"role":"user","id":"1843b045-94c6-4f30-b1f0-21a3adc04fe9"},"surfaceOp":"append"}
{"type":"session/title","seq":8,"time":1786357538471,"data":{"title":"Reply with exactly WORKFLOW_CHILD_OK and","messageSeqs":[6],"source":{"kind":"fallback"}}}
{"type":"request/header","seq":9,"time":1785730458703,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","seq":10,"time":1785730458703,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}

View File

@@ -1,74 +1,76 @@
{"type":"session","version":0,"id":"11111111-1111-4111-8111-111111111111","createdAt":1783950000000,"cwd":"{{cwd}}","delegationDepth":0}
{"type":"agent/inbox/spliced","seq":0,"time":1785498801734,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_ACP_OK."}],"source":{"kind":"user"},"role":"user","id":"6e45782a-31be-4ba7-8c4a-7411a2027e36"}]}}
{"type":"agent/inbox/spliced","seq":0,"time":1785498801734,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Run this advanced flow exactly once: define a host-only dynamic Cordis Package named Snapshot Marker; run and inspect snap-1/pkg-1 through run_code; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; remove snap-1; then reply with exactly ADVANCED_ACP_OK."}],"source":{"kind":"user"},"role":"user","id":"6a989c18-ce01-46ce-8105-43789f710fb5"}]}}
{"type":"turn/start","seq":1,"time":1785821417918,"data":{"turn":1}}
{"type":"agent/inbox/spliced","seq":2,"time":1785821417919,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","seq":3,"time":1783957884486,"data":{"turn":1,"step":1}}
{"type":"user/message","seq":4,"time":1785498801761,"data":{"content":[{"type":"text","text":"Run this advanced flow exactly once: try a no-op temporary Cordis Plugin named snapshot-marker; use run_code to inspect the live temporary Plugins through tools.cordis_inspect; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; stop dyn-1; then reply with exactly ADVANCED_ACP_OK."}],"source":{"kind":"user"},"role":"user","id":"6e45782a-31be-4ba7-8c4a-7411a2027e36"},"surfaceOp":"append"}
{"type":"user/message","seq":4,"time":1785498801761,"data":{"content":[{"type":"text","text":"Run this advanced flow exactly once: define a host-only dynamic Cordis Package named Snapshot Marker; run and inspect snap-1/pkg-1 through run_code; delegate once to a direct spawn child; run one workflow that delegates to another spawn child; remove snap-1; then reply with exactly ADVANCED_ACP_OK."}],"source":{"kind":"user"},"role":"user","id":"6a989c18-ce01-46ce-8105-43789f710fb5"},"surfaceOp":"append"}
{"type":"user/message","seq":5,"time":1785730458430,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"f66cc92b-b90c-4aeb-9568-7463d5eeede9"},"surfaceOp":"append"}
{"type":"session/title","seq":6,"time":1785730458430,"data":{"title":"Run this advanced flow exactly","messageSeqs":[4],"source":{"kind":"fallback"}}}
{"type":"request/header","seq":7,"time":1785498801765,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","seq":8,"time":1785730458431,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
{"type":"assistant/chunk","seq":9,"time":1783950000007,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
{"type":"assistant/chunk","seq":10,"time":1783950000008,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-mount","name":"cordis_mount","argumentsDelta":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}}}
{"type":"assistant/chunk","seq":11,"time":1783950000009,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}}}}
{"type":"assistant/chunk","seq":10,"time":1783950000008,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-define","name":"cordis_define","argumentsDelta":"{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"}}}
{"type":"assistant/chunk","seq":11,"time":1783950000009,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-define","name":"cordis_define","arguments":"{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"}}}}
{"type":"assistant/chunk","seq":12,"time":1785498801774,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
{"type":"assistant/chunk","seq":13,"time":1785730458439,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":14,"time":1785730458440,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"0713b7ec-0182-4820-8ec1-39d0371b533b"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[9,10,11,12,13],"surfaceOp":"append"}
{"type":"tool/call","seq":15,"time":1785730458440,"data":{"turn":1,"step":1,"callId":"advanced-mount","name":"cordis_mount","arguments":"{\"code\":\"return { name: 'snapshot-marker', apply() {} }\"}"}}
{"type":"tool/result","seq":16,"time":1785730458450,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"advanced-mount"},"content":[{"type":"tool-result","toolCallId":"advanced-mount","content":[{"type":"text","text":"Temporary Plugin dyn-1 is running (plugin \"snapshot-marker\"; available until unmounted or DSH restarts)."}],"isError":false}],"role":"user","id":"b10e76f0-e1a5-4c2c-b6a2-6cbdcf259cca"}},"sourceEventSeqs":[15],"surfaceOp":"append"}
{"type":"assistant/message","seq":14,"time":1785730458440,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-define","name":"cordis_define","arguments":"{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"0713b7ec-0182-4820-8ec1-39d0371b533b"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[9,10,11,12,13],"surfaceOp":"append"}
{"type":"tool/call","seq":15,"time":1785730458440,"data":{"turn":1,"step":1,"callId":"advanced-define","name":"cordis_define","arguments":"{\"plugin\":{\"kind\":\"new\",\"idPrefix\":\"snap\"},\"name\":\"Snapshot Marker\",\"purpose\":\"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\"code\":{\"host\":\"return { apply() {} }\"}}"}}
{"type":"tool/result","seq":16,"time":1785730458450,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"advanced-define"},"content":[{"type":"tool-result","toolCallId":"advanced-define","content":[{"type":"text","text":"Defined snap-1/pkg-1 (Snapshot Marker); it is not running yet. Use cordis_run to activate this Package."}],"isError":false}],"role":"user","id":"e583400c-a37d-4f0a-ba44-f57a1ab063bd"},"meta":{"pluginId":"snap-1","packageId":"pkg-1"}},"sourceEventSeqs":[15],"surfaceOp":"append"}
{"type":"step/end","seq":17,"time":1785730458450,"data":{"turn":1,"step":1}}
{"type":"step/start","seq":18,"time":1785730458460,"data":{"turn":1,"step":2}}
{"type":"assistant/chunk","seq":19,"time":1783950000017,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
{"type":"assistant/chunk","seq":20,"time":1783950000018,"data":{"turn":1,"step":2,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-code","name":"run_code","argumentsDelta":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}}}
{"type":"assistant/chunk","seq":21,"time":1783950000019,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}}}}
{"type":"assistant/chunk","seq":20,"time":1783950000018,"data":{"turn":1,"step":2,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-code","name":"run_code","argumentsDelta":"{\"code\":\"const run = await tools.cordis_run({ pluginId: 'snap-1', packageId: 'pkg-1', mode: 'run' });\\nconst inspected = await tools.cordis_inspect_self({ pluginId: 'snap-1' });\\nreturn { run, inspected };\",\"description\":\"Run and inspect the dynamic Cordis Package\"}"}}}
{"type":"assistant/chunk","seq":21,"time":1783950000019,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\":\"const run = await tools.cordis_run({ pluginId: 'snap-1', packageId: 'pkg-1', mode: 'run' });\\nconst inspected = await tools.cordis_inspect_self({ pluginId: 'snap-1' });\\nreturn { run, inspected };\",\"description\":\"Run and inspect the dynamic Cordis Package\"}"}}}}
{"type":"assistant/chunk","seq":22,"time":1785498801800,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
{"type":"assistant/chunk","seq":23,"time":1785730458465,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":24,"time":1785730458465,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"e3061430-3f2d-4dd8-a3ee-c0fde800547d"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[19,20,21,22,23],"surfaceOp":"append"}
{"type":"tool/call","seq":25,"time":1785730458465,"data":{"turn":1,"step":2,"callId":"advanced-code","name":"run_code","arguments":"{\"code\": \"return await tools.cordis_inspect({ what: 'temporary' })\", \"description\": \"Run the scripted inspection program\"}"}}
{"type":"tool/code-dispatch-start","seq":26,"time":1785730458517,"data":{"rootCallId":"advanced-code","parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"temporary"}}}
{"type":"tool/code-dispatch","seq":27,"time":1785730458518,"data":{"rootCallId":"advanced-code","parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_inspect","arguments":{"what":"temporary"},"isError":false,"content":[{"type":"text","text":"## Temporary Plugins\n- Temporary Plugin dyn-1: snapshot-marker [running] — provides: none; waiting for: none; lifetime: until unmounted or DSH restarts"}]}}
{"type":"tool/result","seq":28,"time":1785730458520,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"advanced-code"},"content":[{"type":"tool-result","toolCallId":"advanced-code","content":[{"type":"text","text":"## Temporary Plugins\n- Temporary Plugin dyn-1: snapshot-marker [running] — provides: none; waiting for: none; lifetime: until unmounted or DSH restarts"}],"isError":false}],"role":"user","id":"4dce223d-0097-4ac2-a717-d1c430240cef"}},"sourceEventSeqs":[25],"surfaceOp":"append"}
{"type":"step/end","seq":29,"time":1785730458520,"data":{"turn":1,"step":2}}
{"type":"step/start","seq":30,"time":1785730458527,"data":{"turn":1,"step":3}}
{"type":"assistant/chunk","seq":31,"time":1783950000029,"data":{"turn":1,"step":3,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
{"type":"assistant/chunk","seq":32,"time":1783950000030,"data":{"turn":1,"step":3,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-direct-child","name":"subagent","argumentsDelta":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}}}
{"type":"assistant/chunk","seq":33,"time":1785036891179,"data":{"turn":1,"step":3,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}}}}
{"type":"assistant/chunk","seq":34,"time":1785498801872,"data":{"turn":1,"step":3,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
{"type":"assistant/chunk","seq":35,"time":1785730458531,"data":{"turn":1,"step":3,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":36,"time":1785730458531,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"51fe1d59-eebc-457b-a072-fe217546ff04"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[31,32,33,34,35],"surfaceOp":"append"}
{"type":"tool/call","seq":37,"time":1785730458531,"data":{"turn":1,"step":3,"callId":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}}
{"type":"tool/result","seq":38,"time":1785730458562,"data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"advanced-direct-child"},"content":[{"type":"tool-result","toolCallId":"advanced-direct-child","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"isError":false}],"role":"user","id":"09028579-5ae5-4d57-955e-02504f4dfc2a"}},"sourceEventSeqs":[37],"surfaceOp":"append"}
{"type":"step/end","seq":39,"time":1785730458563,"data":{"turn":1,"step":3}}
{"type":"step/start","seq":40,"time":1785730458572,"data":{"turn":1,"step":4}}
{"type":"assistant/chunk","seq":41,"time":1783957884594,"data":{"turn":1,"step":4,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
{"type":"assistant/chunk","seq":42,"time":1783957884594,"data":{"turn":1,"step":4,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-workflow","name":"workflow","argumentsDelta":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"}}}
{"type":"assistant/chunk","seq":43,"time":1785036891211,"data":{"turn":1,"step":4,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"}}}}
{"type":"assistant/chunk","seq":44,"time":1785498801920,"data":{"turn":1,"step":4,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
{"type":"assistant/chunk","seq":45,"time":1785730458577,"data":{"turn":1,"step":4,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":46,"time":1785730458577,"data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"ebeca5c6-68ae-43b3-87c3-c48fdfe416c8"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[41,42,43,44,45],"surfaceOp":"append"}
{"type":"tool/call","seq":47,"time":1785730458577,"data":{"turn":1,"step":4,"callId":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"}}
{"type":"tool-workflow/run-start","seq":48,"time":1786359248404,"data":{"runId":"2f6d6a6e-6d76-4a8a-8677-6671366645dc","name":"advanced-acp-snapshot"}}
{"type":"tool-workflow/agent-start","seq":49,"time":1786359248518,"data":{"runId":"2f6d6a6e-6d76-4a8a-8677-6671366645dc","seq":1,"label":"workflow-child","phase":"Delegate","childId":"33333333-3333-4333-8333-333333333333"}}
{"type":"tool-workflow/agent-end","seq":50,"time":1786359248542,"data":{"runId":"2f6d6a6e-6d76-4a8a-8677-6671366645dc","seq":1,"outcome":"completed"}}
{"type":"tool-workflow/run-end","seq":51,"time":1786359248543,"data":{"runId":"2f6d6a6e-6d76-4a8a-8677-6671366645dc","stopReason":"completed"}}
{"type":"tool/result","seq":52,"time":1786359248543,"data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"advanced-workflow"},"content":[{"type":"tool-result","toolCallId":"advanced-workflow","content":[{"type":"text","text":"workflow \"advanced-acp-snapshot\" completed (1 agent).\nReturn value:\n{\n \"reply\": \"WORKFLOW_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"f892f17e-1e93-4f4b-9e9e-15116593b6fc"}},"sourceEventSeqs":[47],"surfaceOp":"append"}
{"type":"step/end","seq":53,"time":1786359248543,"data":{"turn":1,"step":4}}
{"type":"step/start","seq":54,"time":1786359248550,"data":{"turn":1,"step":5}}
{"type":"assistant/chunk","seq":55,"time":1785730458728,"data":{"turn":1,"step":5,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
{"type":"assistant/chunk","seq":56,"time":1786359248554,"data":{"turn":1,"step":5,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-unmount","name":"cordis_unmount","argumentsDelta":"{\"id\":\"dyn-1\"}"}}}
{"type":"assistant/chunk","seq":57,"time":1786359248554,"data":{"turn":1,"step":5,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}}}}
{"type":"assistant/chunk","seq":58,"time":1786359248554,"data":{"turn":1,"step":5,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
{"type":"assistant/chunk","seq":59,"time":1786359248554,"data":{"turn":1,"step":5,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":60,"time":1786359248554,"data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"1291ce3c-e568-4f0d-a95a-5157b8b2cc75"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[55,56,57,58,59],"surfaceOp":"append"}
{"type":"tool/call","seq":61,"time":1786359248554,"data":{"turn":1,"step":5,"callId":"advanced-unmount","name":"cordis_unmount","arguments":"{\"id\":\"dyn-1\"}"}}
{"type":"tool/result","seq":62,"time":1786359248558,"data":{"turn":1,"step":5,"message":{"source":{"kind":"tool","callId":"advanced-unmount"},"content":[{"type":"tool-result","toolCallId":"advanced-unmount","content":[{"type":"text","text":"Temporary Plugin dyn-1 was unmounted and removed."}],"isError":false}],"role":"user","id":"b3634221-2358-4e82-aac5-e37f0a115023"}},"sourceEventSeqs":[61],"surfaceOp":"append"}
{"type":"step/end","seq":63,"time":1786359248558,"data":{"turn":1,"step":5}}
{"type":"step/start","seq":64,"time":1786359248564,"data":{"turn":1,"step":6}}
{"type":"assistant/chunk","seq":65,"time":1785730458751,"data":{"turn":1,"step":6,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
{"type":"assistant/chunk","seq":66,"time":1786359248568,"data":{"turn":1,"step":6,"chunk":{"type":"text-delta","index":0,"text":"ADVANCED_ACP_OK"}}}
{"type":"assistant/chunk","seq":67,"time":1786359248568,"data":{"turn":1,"step":6,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"ADVANCED_ACP_OK"}}}}
{"type":"assistant/chunk","seq":68,"time":1786359248568,"data":{"turn":1,"step":6,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
{"type":"assistant/chunk","seq":69,"time":1786359248568,"data":{"turn":1,"step":6,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
{"type":"assistant/message","seq":70,"time":1786359248568,"data":{"turn":1,"step":6,"message":{"role":"assistant","content":[{"type":"text","text":"ADVANCED_ACP_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"a32b89ce-13ed-48ba-a7f9-24144b94ec56"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[65,66,67,68,69],"surfaceOp":"append"}
{"type":"step/end","seq":71,"time":1786359248568,"data":{"turn":1,"step":6}}
{"type":"turn/end","seq":72,"time":1786359248568,"data":{"turn":1,"reason":{"kind":"completed"}}}
{"type":"assistant/message","seq":24,"time":1785730458465,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-code","name":"run_code","arguments":"{\"code\":\"const run = await tools.cordis_run({ pluginId: 'snap-1', packageId: 'pkg-1', mode: 'run' });\\nconst inspected = await tools.cordis_inspect_self({ pluginId: 'snap-1' });\\nreturn { run, inspected };\",\"description\":\"Run and inspect the dynamic Cordis Package\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"e3061430-3f2d-4dd8-a3ee-c0fde800547d"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[19,20,21,22,23],"surfaceOp":"append"}
{"type":"tool/call","seq":25,"time":1785730458465,"data":{"turn":1,"step":2,"callId":"advanced-code","name":"run_code","arguments":"{\"code\":\"const run = await tools.cordis_run({ pluginId: 'snap-1', packageId: 'pkg-1', mode: 'run' });\\nconst inspected = await tools.cordis_inspect_self({ pluginId: 'snap-1' });\\nreturn { run, inspected };\",\"description\":\"Run and inspect the dynamic Cordis Package\"}"}}
{"type":"tool/code-dispatch-start","seq":26,"time":1785730458517,"data":{"rootCallId":"advanced-code","parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_run","arguments":{"pluginId":"snap-1","packageId":"pkg-1","mode":"run"}}}
{"type":"tool/code-dispatch","seq":27,"time":1785730458518,"data":{"rootCallId":"advanced-code","parentCallId":"advanced-code","subCallId":"advanced-code:code:1","name":"cordis_run","arguments":{"pluginId":"snap-1","packageId":"pkg-1","mode":"run"},"isError":false,"content":[{"type":"text","text":"snap-1/pkg-1 is running (run-1)."}]}}
{"type":"tool/code-dispatch-start","seq":28,"time":1786553843104,"data":{"rootCallId":"advanced-code","parentCallId":"advanced-code","subCallId":"advanced-code:code:2","name":"cordis_inspect_self","arguments":{"pluginId":"snap-1"}}}
{"type":"tool/code-dispatch","seq":29,"time":1786553843104,"data":{"rootCallId":"advanced-code","parentCallId":"advanced-code","subCallId":"advanced-code:code:2","name":"cordis_inspect_self","arguments":{"pluginId":"snap-1"},"isError":false,"content":[{"type":"text","text":"{\n \"mode\": \"plugin\",\n \"pluginId\": \"snap-1\",\n \"name\": \"Snapshot Marker\",\n \"packageCount\": 1,\n \"state\": \"running\",\n \"currentPackageId\": \"pkg-1\",\n \"activeRun\": {\n \"pluginRunId\": \"run-1\",\n \"packageId\": \"pkg-1\"\n },\n \"packages\": [\n {\n \"packageId\": \"pkg-1\",\n \"name\": \"Snapshot Marker\",\n \"purpose\": \"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\n \"hasHostHalf\": true,\n \"hasClientHalf\": false,\n \"isCurrent\": true,\n \"isNext\": false\n }\n ]\n}"}]}}
{"type":"tool/result","seq":30,"time":1786553843106,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"advanced-code"},"content":[{"type":"tool-result","toolCallId":"advanced-code","content":[{"type":"text","text":"{\n \"run\": {\n \"status\": \"running\",\n \"pluginId\": \"snap-1\",\n \"packageId\": \"pkg-1\",\n \"pluginRunId\": \"run-1\",\n \"currentPackageId\": \"pkg-1\",\n \"host\": {\n \"status\": \"running\",\n \"provides\": [],\n \"waitingFor\": []\n },\n \"client\": {\n \"status\": \"absent\",\n \"waitingFor\": []\n }\n },\n \"inspected\": {\n \"mode\": \"plugin\",\n \"pluginId\": \"snap-1\",\n \"name\": \"Snapshot Marker\",\n \"packageCount\": 1,\n \"state\": \"running\",\n \"currentPackageId\": \"pkg-1\",\n \"activeRun\": {\n \"pluginRunId\": \"run-1\",\n \"packageId\": \"pkg-1\"\n },\n \"packages\": [\n {\n \"packageId\": \"pkg-1\",\n \"name\": \"Snapshot Marker\",\n \"purpose\": \"Exercise the dynamic Cordis Package lifecycle in the snapshot.\",\n \"hasHostHalf\": true,\n \"hasClientHalf\": false,\n \"isCurrent\": true,\n \"isNext\": false\n }\n ]\n }\n}"}],"isError":false}],"role":"user","id":"fe7613ff-5837-4493-af89-0c06f1ef1010"}},"sourceEventSeqs":[25],"surfaceOp":"append"}
{"type":"step/end","seq":31,"time":1786553843106,"data":{"turn":1,"step":2}}
{"type":"step/start","seq":32,"time":1786553843113,"data":{"turn":1,"step":3}}
{"type":"assistant/chunk","seq":33,"time":1785036891179,"data":{"turn":1,"step":3,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
{"type":"assistant/chunk","seq":34,"time":1785498801872,"data":{"turn":1,"step":3,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-direct-child","name":"subagent","argumentsDelta":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}}}
{"type":"assistant/chunk","seq":35,"time":1785730458531,"data":{"turn":1,"step":3,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}}}}
{"type":"assistant/chunk","seq":36,"time":1786553843117,"data":{"turn":1,"step":3,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
{"type":"assistant/chunk","seq":37,"time":1786553843117,"data":{"turn":1,"step":3,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":38,"time":1786553843117,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"51fe1d59-eebc-457b-a072-fe217546ff04"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[33,34,35,36,37],"surfaceOp":"append"}
{"type":"tool/call","seq":39,"time":1786553843118,"data":{"turn":1,"step":3,"callId":"advanced-direct-child","name":"subagent","arguments":"{\"description\":\"Check direct child\",\"prompt\":\"Reply with exactly DIRECT_CHILD_OK and nothing else.\",\"run_in_background\":false}"}}
{"type":"tool/result","seq":40,"time":1786553843151,"data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"advanced-direct-child"},"content":[{"type":"tool-result","toolCallId":"advanced-direct-child","content":[{"type":"text","text":"DIRECT_CHILD_OK"}],"isError":false}],"role":"user","id":"09028579-5ae5-4d57-955e-02504f4dfc2a"}},"sourceEventSeqs":[39],"surfaceOp":"append"}
{"type":"step/end","seq":41,"time":1786553843151,"data":{"turn":1,"step":3}}
{"type":"step/start","seq":42,"time":1786553843157,"data":{"turn":1,"step":4}}
{"type":"assistant/chunk","seq":43,"time":1785036891211,"data":{"turn":1,"step":4,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
{"type":"assistant/chunk","seq":44,"time":1785498801920,"data":{"turn":1,"step":4,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-workflow","name":"workflow","argumentsDelta":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"}}}
{"type":"assistant/chunk","seq":45,"time":1785730458577,"data":{"turn":1,"step":4,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"}}}}
{"type":"assistant/chunk","seq":46,"time":1786553843162,"data":{"turn":1,"step":4,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
{"type":"assistant/chunk","seq":47,"time":1786553843162,"data":{"turn":1,"step":4,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":48,"time":1786553843162,"data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"ebeca5c6-68ae-43b3-87c3-c48fdfe416c8"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[43,44,45,46,47],"surfaceOp":"append"}
{"type":"tool/call","seq":49,"time":1786553843163,"data":{"turn":1,"step":4,"callId":"advanced-workflow","name":"workflow","arguments":"{\"script\":\"phase('Delegate')\\nconst reply = await agent('Reply with exactly WORKFLOW_CHILD_OK and nothing else.', { label: 'workflow-child' })\\nreturn { reply }\",\"meta\":{\"name\":\"advanced-acp-snapshot\",\"description\":\"exercise one workflow child through ACP\"}}"}}
{"type":"tool-workflow/run-start","seq":50,"time":1786553843167,"data":{"runId":"8ae2383b-3e28-438d-b9fd-1823db77fdaa","name":"advanced-acp-snapshot"}}
{"type":"tool-workflow/agent-start","seq":51,"time":1786553843285,"data":{"runId":"8ae2383b-3e28-438d-b9fd-1823db77fdaa","seq":1,"label":"workflow-child","phase":"Delegate","childId":"33333333-3333-4333-8333-333333333333"}}
{"type":"tool-workflow/agent-end","seq":52,"time":1786553843313,"data":{"runId":"8ae2383b-3e28-438d-b9fd-1823db77fdaa","seq":1,"outcome":"completed"}}
{"type":"tool-workflow/run-end","seq":53,"time":1786553843314,"data":{"runId":"8ae2383b-3e28-438d-b9fd-1823db77fdaa","stopReason":"completed"}}
{"type":"tool/result","seq":54,"time":1786553843314,"data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"advanced-workflow"},"content":[{"type":"tool-result","toolCallId":"advanced-workflow","content":[{"type":"text","text":"workflow \"advanced-acp-snapshot\" completed (1 agent).\nReturn value:\n{\n \"reply\": \"WORKFLOW_CHILD_OK\"\n}"}],"isError":false}],"role":"user","id":"f892f17e-1e93-4f4b-9e9e-15116593b6fc"}},"sourceEventSeqs":[49],"surfaceOp":"append"}
{"type":"step/end","seq":55,"time":1786553843314,"data":{"turn":1,"step":4}}
{"type":"step/start","seq":56,"time":1786553843321,"data":{"turn":1,"step":5}}
{"type":"assistant/chunk","seq":57,"time":1786359248554,"data":{"turn":1,"step":5,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
{"type":"assistant/chunk","seq":58,"time":1786359248554,"data":{"turn":1,"step":5,"chunk":{"type":"tool-call-delta","index":0,"id":"advanced-undefine","name":"cordis_undefine","argumentsDelta":"{\"pluginId\":\"snap-1\"}"}}}
{"type":"assistant/chunk","seq":59,"time":1786359248554,"data":{"turn":1,"step":5,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\":\"snap-1\"}"}}}}
{"type":"assistant/chunk","seq":60,"time":1786553843325,"data":{"turn":1,"step":5,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
{"type":"assistant/chunk","seq":61,"time":1786553843325,"data":{"turn":1,"step":5,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":62,"time":1786553843325,"data":{"turn":1,"step":5,"message":{"role":"assistant","content":[{"type":"tool-call","id":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\":\"snap-1\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"1291ce3c-e568-4f0d-a95a-5157b8b2cc75"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[57,58,59,60,61],"surfaceOp":"append"}
{"type":"tool/call","seq":63,"time":1786553843325,"data":{"turn":1,"step":5,"callId":"advanced-undefine","name":"cordis_undefine","arguments":"{\"pluginId\":\"snap-1\"}"}}
{"type":"tool/result","seq":64,"time":1786553843329,"data":{"turn":1,"step":5,"message":{"source":{"kind":"tool","callId":"advanced-undefine"},"content":[{"type":"tool-result","toolCallId":"advanced-undefine","content":[{"type":"text","text":"Removed dynamic Plugin snap-1 and all of its Packages."}],"isError":false}],"role":"user","id":"dd45db06-baa0-4e48-ad52-681b511c8f80"}},"sourceEventSeqs":[63],"surfaceOp":"append"}
{"type":"step/end","seq":65,"time":1786553843330,"data":{"turn":1,"step":5}}
{"type":"step/start","seq":66,"time":1786553843337,"data":{"turn":1,"step":6}}
{"type":"assistant/chunk","seq":67,"time":1786359248568,"data":{"turn":1,"step":6,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
{"type":"assistant/chunk","seq":68,"time":1786359248568,"data":{"turn":1,"step":6,"chunk":{"type":"text-delta","index":0,"text":"ADVANCED_ACP_OK"}}}
{"type":"assistant/chunk","seq":69,"time":1786359248568,"data":{"turn":1,"step":6,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"ADVANCED_ACP_OK"}}}}
{"type":"assistant/chunk","seq":70,"time":1786553843341,"data":{"turn":1,"step":6,"chunk":{"type":"usage","usage":{"inputTokens":3,"outputTokens":3}}}}
{"type":"assistant/chunk","seq":71,"time":1786553843341,"data":{"turn":1,"step":6,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
{"type":"assistant/message","seq":72,"time":1786553843341,"data":{"turn":1,"step":6,"message":{"role":"assistant","content":[{"type":"text","text":"ADVANCED_ACP_OK"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"a32b89ce-13ed-48ba-a7f9-24144b94ec56"},"usage":{"inputTokens":3,"outputTokens":3}},"sourceEventSeqs":[67,68,69,70,71],"surfaceOp":"append"}
{"type":"step/end","seq":73,"time":1786553843342,"data":{"turn":1,"step":6}}
{"type":"turn/end","seq":74,"time":1786553843342,"data":{"turn":1,"reason":{"kind":"completed"}}}

View File

@@ -1,4 +1,4 @@
You are an AI agent powered by the DeepSeek Harness SDK.
You are an AI agent powered by DeepSeek Harness.
You are a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.
@@ -7,25 +7,131 @@ 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 write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-observation-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.
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-observation-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.
Track every background job id you start. You are notified in-session when a job finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running job's work. Before giving a final answer, collect every still-relevant job with job_output (set wait: true only when you are genuinely blocked on it), and job_kill jobs that stopped mattering.
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.
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.
# Dynamic Cordis Plugins
Dynamic Cordis plugins temporarily extend the current DSH process. A Plugin uses apply(ctx) to consume Services, listen to Events, provide Services, register model Tools, or register browser UI in Slots.
- Plugin and Package definitions exist only in the current process. define itself does not modify repository source, configuration, or disk, and definitions do not survive a process restart.
- The restricted execution environment prevents accidental misuse; it is not a security boundary for malicious code. Services obtained by dynamic code connect to the real runtime.
## Make the user-facing plan clear first
- Dynamic Cordis Plugins are one available implementation mechanism, not the default for every request. Consider whether one could help only when the user intends to design or create something, or when a temporary interface could materially aid the current work. The presence of these instructions or Tools, and discussion of Cordis itself, do not make a request a dynamic-Plugin task.
- When Cordis is a plausible fit, infer the intended work target and lifetime from the request and conversation. Use it only when the outcome belongs to the current running harness and should be delivered as a temporary runtime extension. If that distinction is materially ambiguous, ask at most one concise question about the intended result or lifetime. Otherwise proceed with the matching workflow; do not require the user to know or choose Cordis as an implementation mechanism.
- Once a dynamic Plugin is appropriate, decide whether the task creates a new Plugin or modifies the Plugin named by the user with @pluginId. Proceed directly when the goal is clear; do not ask for repeated confirmation.
- Choose Host, Client, or both from the requested outcome. Do not propose a Client/browser UI when the task does not need visible page behavior, and do not avoid Client when the requested outcome is visual, interactive, or depends on page state. Host versus Client is an implementation choice; do not make the user choose it.
- When a design direction or a potentially useful interface would materially affect the result, ask at most one concise outcome or creative-preference question and offer a few candidate directions. Otherwise proceed directly; do not conduct a multi-round interview or a complex questionnaire.
- cordis_define only defines and presents code; it does not run it. After definition, explain the pluginId and packageId returned by the Host and whether the next step is a run or update.
- cordis_run may require user approval. When it returns awaiting-approval, explain that the user must allow or reject it in the UI. Do not wait, retry, or claim that it is running.
- When it returns starting, explain that the request has entered the asynchronous flow and the Client is still activating. starting does not mean success. Wait for the system to report the final result through steering context.
- Do not request approval again after the user rejects it. After a technical failure, fix the same Plugin from its diagnostics; do not silently create a replacement Plugin.
## Recommended workflow and Tools
Before creating, modifying, or repairing a Plugin, load the cordis-plugin-development Skill. The Skill provides requirement navigation, capability composition, complete examples, and troubleshooting. Treat Inspect Provider results as the source of truth for exact APIs.
1. cordis_inspect_list: discover the current Host and Client Providers and their read-only query methods.
2. cordis_inspect_query: use the returned platform, provider, method, and schema to query exact Service, Event, Builtin, Slot, Theme token, or Tool information.
3. cordis_inspect_self: inspect the current Session's Plugins, Packages, version pointers, source, and diagnostics. Source is returned only when both pluginId and packageId are specified.
4. cordis_define: create the first Package for a new Plugin or append an immutable Package to an existing Plugin. It defines code but does not run it.
5. cordis_run: activate an exact Package. Use run for the first activation, restarting current, or rollback; use update to switch versions.
6. cordis_stop: remove the current Run and pending approval request while retaining definitions, grants, and version pointers.
7. cordis_undefine: permanently stop and delete a Plugin and all of its Packages. Use it only after confirming that the user no longer needs them.
- Inspect and Catalog data only confirm capabilities, names, signatures, types, and registration protocols before code is written; they do not replace business APIs.
- Query Service.listService and Event.listEvents without input to choose from their compact signature directories, then query the exact service or event before using it. Exact queries return the structured contract and only its referenced types.
- At runtime, a Plugin must call real Services or listen to real Events. Do not cache, display, or depend on Inspect results as business data.
## Identity, versions, and approval
- pluginId identifies a Plugin that can be modified over time. For a new Plugin, submit only a semantic idPrefix of 36 lowercase English letters; the Host allocates the final ID.
- packageId identifies one immutable Host/Client source version under a Plugin. To change code, define a new Package; never overwrite an old version.
- pluginRunId identifies one activation attempt and connects its approval, Host/Client loading, private RPC, Run card, and errors.
- currentPackageId is the most recent fully successful Package. Stopping, starting an update, or failing an update does not clear it.
- nextPackageId is the target awaiting approval, being attempted, awaiting Client activation, or most recently failed.
- A single check mark authorizes only the current Package; double check marks authorize future versions of the same Plugin. A grant remains in effect after a technical failure.
- An update stops the old Run before starting the target Package. Failure does not automatically restart the old version; retry next with update or roll back to current with run.
When the user enters @pluginId, the system injects identity, the default base Package, version pointers, and runtime status, but not source code:
1. Call cordis_inspect_self(pluginId, packageId) to read the target source.
2. Use cordis_define in existing mode to append a Package to the same Plugin.
3. Call cordis_run in run or update mode according to the version relationship.
Never silently create another Plugin for @pluginId. If the reference is unavailable because it was removed, belongs to another Session, or was lost on process restart, tell the user directly.
## High-frequency errors that must be avoided
### Services: ctx.get and inject
- Read an optional Service with ctx.get('serviceName') by default and handle undefined.
- Declare inject: ['serviceName'] on the returned Plugin object only when the Service is a hard dependency and the Plugin must enter waiting until Cordis reactivates it after the Service appears.
- Read ctx.serviceName only after declaring that Service in inject. Never access an undeclared Service as a ctx property.
```js
return {
inject: ['requiredService'],
apply(ctx) {
ctx.requiredService.someMethod()
const optionalService = ctx.get('optionalService')
if (optionalService !== undefined) optionalService.someMethod()
},
}
```
### Code: use plain JavaScript only
- Host and Client code is not transformed by TypeScript, JSX, or a bundler.
- Do not use TypeScript types, as, decorators, import, require, or JSX.
- Client React code must use React.createElement(...); never write <Component />.
- Do not assume that process, Buffer, window, document, fetch, native timers, or any other global is available. Query the corresponding platform's Builtins and Services first.
### Data: do not serialize live data
- Services, Events, Slots, Sessions, and their derived Cordis/DSH objects are internal live data, not ordinary JSON that can be dumped.
- Do not apply JSON.stringify, structuredClone, recursive enumeration, full copying, or whole-object display to live data.
- Read only the leaf fields required by the task, then construct the smallest owned data object without Host references.
### Lifecycle: every side effect must be reversible
- Services, Events, Tools, handlers, timers, Slots, styles, and theme overrides must all belong to the current Fiber.
- Use ctx.effect(), ctx.on(), or official APIs that return a disposer so stop, update, or undefine removes every side effect.
- The cordis-plugin-development Skill contains complete timer, Waterfall, Slot, theme, Tool, RPC, and React examples and troubleshooting guidance.
## Host and Client
- Host runs in the DSH Node.js process and is appropriate for files, networking, commands, Agent/Session access, Host Events, Services, model Tools, and JSON methods callable by the Client.
- Client runs in the browser page and is appropriate for themes, layout, current page state, Tool cards, and Slot UI.
- Host and Client communicate through Package-private JSON methods: Host uses harness.handle(method, handler), and Client uses host.call(method, args). The direction is Client→Host, and only lossless JSON may cross it.
- Client UI must be registered in a queried Slot; apply() cannot directly return a React Element. Query Slots.listSubTree without root to choose from the compact purpose/topology tree, then query the exact root for its full registration contract and props before writing code.
- See the Skill and Inspect Providers for Run-specific panels and exact Slot registration patterns.
## Asynchronous results and recovery
- Do not wait inside a Tool for approval or browser work that can happen only after the current turn ends.
- Asynchronous success, rejection, and runtime errors update Run state and notify you through steering context.
- After a technical failure, use cordis_inspect_self to read the exact Package source and its message/stack. Define a corrected Package under the same Plugin and retry autonomously.
- Use the cordis-plugin-development Skill for other failure causes, repair procedures, and complete extension patterns.
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.
Use subagent in the background by default. Start independent delegations together in one assistant message and continue useful work while they run. Set `run_in_background: false` only when your next action depends on that subagent's result. When a background run settles, the runtime sends you a notice containing its outcome and any final assistant message.
## Writing code for run_code
Pass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:
`run_code` takes two required arguments: `code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped) — and `description`, a short summary of what the program does. Inside the program:
- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools["my-tool"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.
- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.
@@ -38,7 +144,7 @@ The available tools:
type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }
interface ToolArgsMap {
/** 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> 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. */
/** 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> 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 job id immediately; read its output with `job_output` and stop it with `job_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. */
bash: {
/** The bash command to execute. */
command: string;
@@ -48,29 +154,73 @@ interface ToolArgsMap {
timeoutMs?: number;
/** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */
workdir?: string;
/** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */
/** Run in the background and return a job id immediately (collect with job_output, stop with job_kill). No timeout applies. */
run_in_background?: boolean;
/** 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. */
sandbox_permissions?: "workspace-write" | "danger-full-access";
/** Required with sandbox_permissions: one sentence for the user explaining why this exact command needs the wider access. */
justification?: string;
} & Record<string, JsonValue>;
/** Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:"api"` or `what:"events"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc. */
cordis_inspect: {
/** Limit the report to one section. Omit for all sections. */
what?: "services" | "plugins" | "tools" | "temporary" | "api" | "events";
/** Exact service key or event name whose original JSDoc to include; valid only with what:"api" or what:"events". */
name?: string;
/** Define an immutable Cordis Package. For a new Plugin, use kind:"new" and provide only a semantic prefix of 36 lowercase English letters; the Host returns the final pluginId and packageId. To modify an existing Plugin, use kind:"existing" with its exact pluginId to append a Package without overwriting older versions. Provide at least one of code.host and code.client. Each value is a plain JavaScript function body that returns a Cordis Plugin; no TypeScript, JSX, or import transformation occurs. Query Inspect before depending on a Service, Event, Builtin, Slot, or token. Define only validates parameters and syntax and records source: it does not request approval, execute apply, or change currentPackageId. On success, call cordis_run with the returned IDs. */
cordis_define: {
plugin: {
kind: "new";
/** Suggested semantic prefix of 36 lowercase English letters; the Host adds a unique numeric suffix. */
idPrefix: string;
} | {
kind: "existing";
/** Exact ID of an existing Plugin; the new Package is appended to that instance. */
pluginId: string;
};
/** Short, readable Package name. */
name: string;
/** One-sentence, user-facing description of the Package purpose. */
purpose: string;
code: {
/** Plain JavaScript function body that returns the Host-half Cordis Plugin. */
host?: string;
/** Plain JavaScript function body that returns the browser Client-half Cordis Plugin. */
client?: string;
};
} & Record<string, JsonValue>;
/** Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement an SDK Plugin or installable profile bundle through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:"api" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:"events"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:<id>]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:"api" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime. */
cordis_mount: {
/** JavaScript body returning a temporary Plugin; evaluated now and saved nowhere. */
code: string;
/** List every Cordis Inspect Provider currently known to the Host, including local Host Providers and the latest manifests synchronized from the Client. Each entry includes its platform, purpose, read-only methods, and input/output schemas. Call this Tool before creating or modifying a Package, then select the provider and method for cordis_inspect_query from its result. Do not guess names or treat an Inspect method as a business Service that Plugin code can call. */
cordis_inspect_list: Record<string, JsonValue>;
/** Run a read-only query explicitly declared by an Inspect Provider. platform, provider, and method must come from cordis_inspect_list, and input must satisfy that method's schema. Use this Tool before cordis_define to read exact Service methods, Event modes, Builtin signatures, Tool schemas, theme tokens, or live Slot trees and props. Host queries run locally. A Client query waits for the first valid page response and remains pending until a page answers or the Tool is cancelled. This Tool cannot invoke business Service methods or modify the runtime. For Service.listService and Event.listEvents, query without input to navigate the compact signature directory, then query the exact service or event for its structured contract and referenced types. For Slots.listSubTree, query without root to navigate the compact tree, then query the exact root for its complete registration contract and props. */
cordis_inspect_query: {
/** Runtime platform that owns the Provider. */
platform: "host" | "client";
/** Exact Provider ID returned by cordis_inspect_list. */
provider: string;
/** Exact method name declared by the Provider manifest. */
method: string;
/** Optional query input; it must satisfy the method input schema. */
input?: JsonValue;
} & Record<string, JsonValue>;
/** Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins. */
cordis_unmount: {
/** The temporary Plugin id returned by cordis_mount (for example "dyn-1"); valid only in this process and invalid after unmount or restart. */
id: string;
/** Inspect dynamic Cordis objects owned by the current Session at increasing levels of detail. With no IDs, list only Plugin summaries. With pluginId alone, return version pointers, the latest Run, and every Package summary. Only pluginId plus packageId returns that immutable Package's Host/Client source and runtime diagnostics. packageId cannot be supplied alone. Query an exact Package before handling @pluginId, repairing an asynchronous failure, or defining an updated version. This Tool is read-only: it neither executes code nor changes version pointers. */
cordis_inspect_self: {
/** Stable Plugin ID returned by cordis_define or injected by @pluginId; omit it to list every current Plugin. */
pluginId?: string;
/** Exact immutable Package ID owned by pluginId; when specified, source and diagnostics are returned. */
packageId?: string;
} & Record<string, JsonValue>;
/** Activate one exact Package of a dynamic Plugin. Use mode:"run" for the first activation, restarting currentPackageId, or rollback. When current exists, use mode:"update" to switch to a different Package, even if the Plugin is currently stopped. An unauthorized Client Package creates an approval request and returns awaiting-approval; an authorized Package returns starting and continues asynchronously in the browser. Neither result waits for the final outcome inside the Tool. currentPackageId changes only after complete success; on failure, the old current and target next remain. Asynchronous success, rejection, or technical failure is reported through state and steering. After a technical failure, read diagnostics with cordis_inspect_self, correct the same Plugin, and retry autonomously. Do not request approval again after the user rejects it. */
cordis_run: {
/** Stable Plugin ID returned by cordis_define. */
pluginId: string;
/** Exact immutable Package ID to activate under that Plugin. */
packageId: string;
/** Use run for the first activation, restarting current, or rollback; use update to switch from current to a different Package. */
mode: "run" | "update";
} & Record<string, JsonValue>;
/** Stop the current Run of a dynamic Plugin and cancel unfinished approval or activation requests. Retain the Plugin, every immutable Package, grants, currentPackageId, and nextPackageId so it can later run or update directly. Stopping an already stopped Plugin succeeds idempotently. Use this Tool to disable effects temporarily; use cordis_undefine for permanent removal. */
cordis_stop: {
/** Stable dynamic Plugin ID to stop. */
pluginId: string;
} & Record<string, JsonValue>;
/** Permanently remove a dynamic Plugin owned by the current Session. If it is running or awaiting approval, first stop it and cancel the request, then delete every Package, grant, and version pointer. After this returns, its pluginId, packageIds, @ reference, and Package business views are invalid; historical cards retain only a "Plugin removed" record. Do not call this Tool when versions must remain available for restart or rollback; use cordis_stop instead. */
cordis_undefine: {
/** Stable dynamic Plugin ID to remove permanently. */
pluginId: string;
} & Record<string, JsonValue>;
/** 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. */
create_goal: {
@@ -101,6 +251,24 @@ interface ToolArgsMap {
/** The agent id of the running agent to interrupt. */
agent_id: string;
} & Record<string, JsonValue>;
/** Request cancellation of a running background job by job id. Returns immediately; the job settles as killed once its work actually stops. */
job_kill: {
/** Job id returned by the tool that started the background work. */
job_id: string;
/** Optional short reason, recorded in the log and forwarded to the job. */
reason?: string;
} & Record<string, JsonValue>;
/** List your background jobs (running and finished) with their ids, kinds, and statuses. */
job_list: Record<string, JsonValue>;
/** Read a background job. Stream jobs return only output since the previous read; final-output jobs return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */
job_output: {
/** Job id returned by the tool that started the background work. */
job_id: string;
/** Block until the job reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the job alive. */
wait?: boolean;
/** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */
timeout_ms?: number;
} & Record<string, JsonValue>;
/** List your continuable background subagents by durable id and label. Use it to recall which ones you started, not to poll for completion — you are told when one finishes. Status comes from the live registry: running means the agent is working right now, idle means it is loaded but between turns (it may be waiting on agents it started), and ready means it exists only in storage — resumable, not terminal, and not a result waiting to be collected; a `send_message` starts a new turn on the same conversation, and a direct child remains a `send_message` candidate in every status. The snapshot is not a delivery promise — `send_message` performs the authoritative check and may still fail. Children that could not be read are reported as diagnostics instead of being silently dropped. Scope `descendants` walks the whole tree below you in stable pre-order, annotating each entry with its durable direct-parent session id and depth. You may use `send_message` only for depth-1 entries; deeper entries are candidates for `interrupt_agent` only. */
list_agents: {
/** children (default) lists direct children only; descendants walks the complete tree below you. */
@@ -150,24 +318,6 @@ interface ToolArgsMap {
/** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */
prompt: string;
} & Record<string, JsonValue>;
/** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */
task_kill: {
/** Task id returned by the tool that started the background work. */
task_id: string;
/** Optional short reason, recorded in the log and forwarded to the task. */
reason?: string;
} & Record<string, JsonValue>;
/** List your background tasks (running and finished) with their ids, kinds, and statuses. */
task_list: Record<string, JsonValue>;
/** 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. */
task_output: {
/** Task id returned by the tool that started the background work. */
task_id: string;
/** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */
wait?: boolean;
/** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */
timeout_ms?: number;
} & Record<string, JsonValue>;
/** 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. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one 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). */
todo_write: {
/** The COMPLETE task list, replacing any previous list. */
@@ -236,7 +386,7 @@ interface ToolArgsMap {
interface ToolOutputMap {
bash: {
kind: "background";
taskId: string;
jobId: string;
} | {
kind: "foreground";
exitCode: number | null;
@@ -261,17 +411,24 @@ interface ToolOutputMap {
runnerFailed?: boolean;
};
};
cordis_inspect: string;
cordis_mount: {
id: string;
pluginName: string;
state: "pending" | "loading" | "active" | "failed" | "disposed" | "unloading";
provides: string[];
waitingFor: string[];
cordis_define: {
pluginId: string;
packageId: string;
name: string;
purpose: string;
hasHostHalf: boolean;
hasClientHalf: boolean;
};
cordis_unmount: {
id: string;
pluginName: string;
cordis_inspect_list: JsonValue;
cordis_inspect_query: JsonValue;
cordis_inspect_self: JsonValue;
cordis_run: JsonValue;
cordis_stop: {
pluginId: string;
};
cordis_undefine: {
pluginId: string;
wasRunning: boolean;
};
create_goal: {
goal: null;
@@ -315,6 +472,39 @@ interface ToolOutputMap {
interrupt_agent: {
accepted: boolean;
};
job_kill: {
outcome: "cancellation-requested" | "already-finished";
job: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
job_list: ({
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
})[];
job_output: {
text: string;
job: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
list_agents: ({
kind: "child";
id: string;
@@ -363,7 +553,7 @@ interface ToolOutputMap {
};
subagent: {
kind: "background";
taskId: string;
jobId: string;
} | {
kind: "continuable";
subagentId: string;
@@ -374,7 +564,7 @@ interface ToolOutputMap {
};
subagent_fork: {
kind: "background";
taskId: string;
jobId: string;
} | {
kind: "continuable";
subagentId: string;
@@ -383,39 +573,6 @@ interface ToolOutputMap {
runId: string;
output: JsonValue[];
};
task_kill: {
outcome: "cancellation-requested" | "already-finished";
task: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
task_list: ({
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
})[];
task_output: {
text: string;
task: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
todo_write: {
todos: ({
content: string;

View File

@@ -2,7 +2,7 @@
"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> 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.",
"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> 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 job id immediately; read its output with `job_output` and stop it with `job_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": {
@@ -24,7 +24,7 @@
},
"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."
"description": "Run in the background and return a job id immediately (collect with job_output, stop with job_kill). No timeout applies."
},
"sandbox_permissions": {
"type": "string",
@@ -46,59 +46,199 @@
}
},
{
"name": "cordis_inspect",
"description": "Inspect the live Cordis runtime in the current DSH process. Read-only. Sections: `services` (every provided ctx service and the plugin fiber that owns it), `plugins` (all live plugin fibers with their lifecycle states), `tools` (the model-facing tools currently registered, i.e. what you can call), `temporary` (only temporary Plugins created by cordis_mount: id, name, state, provided services, awaited services, and lifetime), `api` (method signatures AND argument/return type shapes for every LIVE service — read this before writing plugin code that calls a service), `events` (every harness event with its dispatch mode and exact signature — pick listener targets here). Temporary Plugins exist only in memory, remain active across later turns, and disappear after cordis_unmount, toolset unload, or DSH restart; they are not restored automatically. The `temporary` section is a subset of `plugins`. Omit `what` to get all six sections. With `what:\"api\"` or `what:\"events\"`, pass an exact `name` to narrow to one service/event and include its original source JSDoc.",
"name": "cordis_define",
"description": "Define an immutable Cordis Package. For a new Plugin, use kind:\"new\" and provide only a semantic prefix of 36 lowercase English letters; the Host returns the final pluginId and packageId. To modify an existing Plugin, use kind:\"existing\" with its exact pluginId to append a Package without overwriting older versions. Provide at least one of code.host and code.client. Each value is a plain JavaScript function body that returns a Cordis Plugin; no TypeScript, JSX, or import transformation occurs. Query Inspect before depending on a Service, Event, Builtin, Slot, or token. Define only validates parameters and syntax and records source: it does not request approval, execute apply, or change currentPackageId. On success, call cordis_run with the returned IDs.",
"parameters": {
"type": "object",
"properties": {
"what": {
"type": "string",
"description": "Limit the report to one section. Omit for all sections.",
"enum": [
"services",
"plugins",
"tools",
"temporary",
"api",
"events"
"plugin": {
"oneOf": [
{
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"type": "string",
"const": "new"
},
"idPrefix": {
"type": "string",
"description": "Suggested semantic prefix of 36 lowercase English letters; the Host adds a unique numeric suffix."
}
},
"required": [
"kind",
"idPrefix"
]
},
{
"type": "object",
"additionalProperties": false,
"properties": {
"kind": {
"type": "string",
"const": "existing"
},
"pluginId": {
"type": "string",
"description": "Exact ID of an existing Plugin; the new Package is appended to that instance."
}
},
"required": [
"kind",
"pluginId"
]
}
]
},
"name": {
"type": "string",
"description": "Exact service key or event name whose original JSDoc to include; valid only with what:\"api\" or what:\"events\"."
}
}
}
},
{
"name": "cordis_mount",
"description": "Mount a temporary Cordis Plugin in the current DSH process. This creates an in-memory runtime Plugin, not an installed or configured Plugin. It remains active across later turns until cordis_unmount, toolset unload, or DSH restart. It does not create files, install a package, change cordis.yml or personal/project config, survive restart, or automatically become permanent. To keep it, ask the Agent to implement an SDK Plugin or installable profile bundle through the regular development workflow. It may affect other sessions in the same process; the sandbox is not a security boundary, and injected services reach the real runtime. `code` runs now as the body of an async JavaScript function in an isolated sandbox and MUST `return` a plugin. Two forms: FUNCTION form `return (ctx) => { … }` — declares no inject, so it can register tools, listen to events, and provide services, but reaching ANY service (e.g. ctx.bash) throws; use it only when you need no services. OBJECT form `return { name?, inject: ['bash', 'llm', …], apply(ctx) { … } }` — declares dependencies, and cordis activates the plugin only after the services exist; PREFER this form. You may reach ONLY the services you list in inject: an undeclared service throws even if it exists, because an undeclared dependency would not be cleaned up if its provider is unmounted. BEFORE calling a service from your code, read cordis_inspect what:\"api\" — it lists method signatures AND the type shapes of their arguments/returns (do not guess a field's type; e.g. a bash run's stdout is an object, not a string). Inside `apply`, use the standard cordis API: `ctx.on(event, listener)` to observe events (see cordis_inspect what:\"events\"), or call `harness.registerTool(ctx, harness.defineTool({ name, description, parameters: { text: { type: 'string', required: true } }, output: { schema: { type: 'string' }, render(_args, value) { return [{ type: 'text', text: value }] } }, async execute(args) { return args.text } }))` to give yourself a new tool — it becomes callable on your NEXT step. Tool parameters: each key IS a property — { type: 'string'|'number'|'integer'|'boolean'|'null'|'object'|'array'|'json', required?: true, description?, enum?, const?, items?, properties? }; every direct DSL object declares additionalProperties: true|false, and oneOf: [schema, schema, ...] replaces type for an exact-one union. A raw JSON-Schema { type: 'object', properties, required?: […] } wrapper is also accepted with open-by-default objects. A tool's `execute` MUST return the lossless JSON value declared by `output.schema`; `output.render(args, value)` separately returns Native/model content blocks. Temporary Plugins can COMPOSE: one Plugin may `ctx.provide('name', value)` a service and another may declare `inject: ['name']` to consume it — the consumer stays pending until the provider exists and returns to pending when the provider is unmounted. Everything registered inside `apply` is cleaned up automatically by cordis_unmount. Sandbox globals: `console` (tagged `[cordis:<id>]`, writes through to the harness terminal), `harness.defineTool`, `harness.registerTool`, `btoa`, `atob`, `TextEncoder`, `TextDecoder`. Node APIs are DISABLED — do filesystem/network/timer work through the cordis services, never Node built-ins: `require`, `setTimeout`/`setInterval`, and `fetch` throw redirect errors; `process` and `Buffer` are undefined. Instead use inject: ['fs'] + ctx.fs for files, inject: ['web'] + ctx.web for HTTP, inject: ['bash'] + ctx.bash for processes, and inject: ['timer'] + ctx.setTimeout/ctx.setInterval for timing (fiber effects, auto-cleaned when unmounted) — cordis_inspect what:\"api\" shows what THIS runtime provides. Write PLAIN JavaScript, not TypeScript (no `as`, no type annotations). Cautions: (1) waterfall events (e.g. tools/pre-execute) hand the listener a trailing `next` callback which MUST be called — returning without `next()` SHORT-CIRCUITS the call; prefer plain notification events unless you intend to intercept. (2) Never await something that only resolves after the current turn (your code runs INSIDE a tool call of that turn — it would deadlock). (3) Your `ctx` is a restricted façade: you can register tools, observe events, provide/consume services, and use timers, but framework internals (ctx.root, ctx.fiber, ctx.extend, ctx.plugin, …) are withheld. It is not a security boundary though — the services you inject (e.g. ctx.bash) reach the real runtime.",
"parameters": {
"type": "object",
"properties": {
"code": {
"description": "Short, readable Package name."
},
"purpose": {
"type": "string",
"description": "JavaScript body returning a temporary Plugin; evaluated now and saved nowhere."
"description": "One-sentence, user-facing description of the Package purpose."
},
"code": {
"type": "object",
"additionalProperties": false,
"properties": {
"host": {
"type": "string",
"description": "Plain JavaScript function body that returns the Host-half Cordis Plugin."
},
"client": {
"type": "string",
"description": "Plain JavaScript function body that returns the browser Client-half Cordis Plugin."
}
}
}
},
"required": [
"plugin",
"name",
"purpose",
"code"
]
}
},
{
"name": "cordis_unmount",
"description": "Unmount a current-process temporary Plugin created by cordis_mount. Waits for its tools, listeners, services, timers, and other owned effects to clean up completely. Only dyn-N temporary ids are accepted; this cannot remove Loader, configured, or installed Plugins.",
"name": "cordis_inspect_list",
"description": "List every Cordis Inspect Provider currently known to the Host, including local Host Providers and the latest manifests synchronized from the Client. Each entry includes its platform, purpose, read-only methods, and input/output schemas. Call this Tool before creating or modifying a Package, then select the provider and method for cordis_inspect_query from its result. Do not guess names or treat an Inspect method as a business Service that Plugin code can call.",
"parameters": {
"type": "object",
"properties": {}
}
},
{
"name": "cordis_inspect_query",
"description": "Run a read-only query explicitly declared by an Inspect Provider. platform, provider, and method must come from cordis_inspect_list, and input must satisfy that method's schema. Use this Tool before cordis_define to read exact Service methods, Event modes, Builtin signatures, Tool schemas, theme tokens, or live Slot trees and props. Host queries run locally. A Client query waits for the first valid page response and remains pending until a page answers or the Tool is cancelled. This Tool cannot invoke business Service methods or modify the runtime. For Service.listService and Event.listEvents, query without input to navigate the compact signature directory, then query the exact service or event for its structured contract and referenced types. For Slots.listSubTree, query without root to navigate the compact tree, then query the exact root for its complete registration contract and props.",
"parameters": {
"type": "object",
"properties": {
"id": {
"platform": {
"type": "string",
"description": "The temporary Plugin id returned by cordis_mount (for example \"dyn-1\"); valid only in this process and invalid after unmount or restart."
"description": "Runtime platform that owns the Provider.",
"enum": [
"host",
"client"
]
},
"provider": {
"type": "string",
"description": "Exact Provider ID returned by cordis_inspect_list."
},
"method": {
"type": "string",
"description": "Exact method name declared by the Provider manifest."
},
"input": {
"description": "Optional query input; it must satisfy the method input schema."
}
},
"required": [
"id"
"platform",
"provider",
"method"
]
}
},
{
"name": "cordis_inspect_self",
"description": "Inspect dynamic Cordis objects owned by the current Session at increasing levels of detail. With no IDs, list only Plugin summaries. With pluginId alone, return version pointers, the latest Run, and every Package summary. Only pluginId plus packageId returns that immutable Package's Host/Client source and runtime diagnostics. packageId cannot be supplied alone. Query an exact Package before handling @pluginId, repairing an asynchronous failure, or defining an updated version. This Tool is read-only: it neither executes code nor changes version pointers.",
"parameters": {
"type": "object",
"properties": {
"pluginId": {
"type": "string",
"description": "Stable Plugin ID returned by cordis_define or injected by @pluginId; omit it to list every current Plugin."
},
"packageId": {
"type": "string",
"description": "Exact immutable Package ID owned by pluginId; when specified, source and diagnostics are returned."
}
}
}
},
{
"name": "cordis_run",
"description": "Activate one exact Package of a dynamic Plugin. Use mode:\"run\" for the first activation, restarting currentPackageId, or rollback. When current exists, use mode:\"update\" to switch to a different Package, even if the Plugin is currently stopped. An unauthorized Client Package creates an approval request and returns awaiting-approval; an authorized Package returns starting and continues asynchronously in the browser. Neither result waits for the final outcome inside the Tool. currentPackageId changes only after complete success; on failure, the old current and target next remain. Asynchronous success, rejection, or technical failure is reported through state and steering. After a technical failure, read diagnostics with cordis_inspect_self, correct the same Plugin, and retry autonomously. Do not request approval again after the user rejects it.",
"parameters": {
"type": "object",
"properties": {
"pluginId": {
"type": "string",
"description": "Stable Plugin ID returned by cordis_define."
},
"packageId": {
"type": "string",
"description": "Exact immutable Package ID to activate under that Plugin."
},
"mode": {
"type": "string",
"description": "Use run for the first activation, restarting current, or rollback; use update to switch from current to a different Package.",
"enum": [
"run",
"update"
]
}
},
"required": [
"pluginId",
"packageId",
"mode"
]
}
},
{
"name": "cordis_stop",
"description": "Stop the current Run of a dynamic Plugin and cancel unfinished approval or activation requests. Retain the Plugin, every immutable Package, grants, currentPackageId, and nextPackageId so it can later run or update directly. Stopping an already stopped Plugin succeeds idempotently. Use this Tool to disable effects temporarily; use cordis_undefine for permanent removal.",
"parameters": {
"type": "object",
"properties": {
"pluginId": {
"type": "string",
"description": "Stable dynamic Plugin ID to stop."
}
},
"required": [
"pluginId"
]
}
},
{
"name": "cordis_undefine",
"description": "Permanently remove a dynamic Plugin owned by the current Session. If it is running or awaiting approval, first stop it and cancel the request, then delete every Package, grant, and version pointer. After this returns, its pluginId, packageIds, @ reference, and Package business views are invalid; historical cards retain only a \"Plugin removed\" record. Do not call this Tool when versions must remain available for restart or rollback; use cordis_stop instead.",
"parameters": {
"type": "object",
"properties": {
"pluginId": {
"type": "string",
"description": "Stable dynamic Plugin ID to remove permanently."
}
},
"required": [
"pluginId"
]
}
},
@@ -188,6 +328,58 @@
]
}
},
{
"name": "job_kill",
"description": "Request cancellation of a running background job by job id. Returns immediately; the job settles as killed once its work actually stops.",
"parameters": {
"type": "object",
"properties": {
"job_id": {
"type": "string",
"description": "Job 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 job."
}
},
"required": [
"job_id"
]
}
},
{
"name": "job_list",
"description": "List your background jobs (running and finished) with their ids, kinds, and statuses.",
"parameters": {
"type": "object",
"properties": {}
}
},
{
"name": "job_output",
"description": "Read a background job. Stream jobs return only output since the previous read; final-output jobs 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": {
"job_id": {
"type": "string",
"description": "Job id returned by the tool that started the background work."
},
"wait": {
"type": "boolean",
"description": "Block until the job reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the job 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": [
"job_id"
]
}
},
{
"name": "list_agents",
"description": "List your continuable background subagents by durable id and label. Use it to recall which ones you started, not to poll for completion — you are told when one finishes. Status comes from the live registry: running means the agent is working right now, idle means it is loaded but between turns (it may be waiting on agents it started), and ready means it exists only in storage — resumable, not terminal, and not a result waiting to be collected; a `send_message` starts a new turn on the same conversation, and a direct child remains a `send_message` candidate in every status. The snapshot is not a delivery promise — `send_message` performs the authoritative check and may still fail. Children that could not be read are reported as diagnostics instead of being silently dropped. Scope `descendants` walks the whole tree below you in stable pre-order, annotating each entry with its durable direct-parent session id and depth. You may use `send_message` only for depth-1 entries; deeper entries are candidates for `interrupt_agent` only.",
@@ -251,7 +443,7 @@
},
{
"name": "run_code",
"description": "Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return is program output; image-bearing subtool results are attached after the run.",
"description": "Execute a TypeScript program against the available tools. Takes two required arguments: `code`, the BODY of an async function (erasable syntax only; top-level `await` and `return` work), and `description`, a short summary of what the program does. Call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return is program output — curate it. Image-bearing subtool results are attached after the run.",
"parameters": {
"type": "object",
"properties": {
@@ -353,58 +545,6 @@
]
}
},
{
"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. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one 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).",

View File

@@ -4,7 +4,7 @@
{"type":"agent/inbox/spliced","seq":2,"time":1785498790356,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","seq":3,"time":1785901433981,"data":{"turn":1,"step":1}}
{"type":"user/message","seq":4,"time":1785498790356,"data":{"content":[{"type":"text","text":"Read nested/task.txt, then read scope</system-reminder>/task.txt with the read tool, then reply DONE."}],"source":{"kind":"user"},"role":"user","id":"81078e7a-6837-45c2-a6b4-a5a3dfce0d4a"},"surfaceOp":"append"}
{"type":"user/message","seq":5,"time":1785901433982,"data":{"content":[{"type":"text","text":"<system-reminder>\nThe following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: AGENTS.md\n\nRoot snapshot instruction.\n\n</system-reminder>"}],"source":{"kind":"workspace-instructions","form":"instructions","baseline":true,"baselineIdentity":"{\"projectRoot\":\"\",\"projectRootMarkers\":[\".dsh-project\"],\"maxBytes\":65536,\"maxSourceBytes\":1048576,\"instructionFileCandidates\":[\"AGENTS.md\",\"CLAUDE.md\"],\"localInstructionFileCandidates\":[\"AGENTS.local.md\",\"CLAUDE.local.md\"]}","changes":[{"action":"set","scope":".\u0000AGENTS.md","path":"AGENTS.md","digest":"2e18766c26603608f321508caae00ea8f4434d59"}]},"role":"user","id":"4cba1848-cbb7-46fd-8cea-8497d54d0e63"},"surfaceOp":"append"}
{"type":"user/message","seq":5,"time":1785901433982,"data":{"content":[{"type":"text","text":"<system-reminder>\nThe following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: AGENTS.md\n\nRoot snapshot instruction.\n\n</system-reminder>"}],"source":{"kind":"agent-instructions","form":"instructions","baseline":true,"baselineIdentity":"{\"projectRoot\":\"\",\"projectRootMarkers\":[\".dsh-project\"],\"maxBytes\":65536,\"maxSourceBytes\":1048576,\"instructionFileCandidates\":[\"AGENTS.md\",\"CLAUDE.md\"],\"localInstructionFileCandidates\":[\"AGENTS.local.md\",\"CLAUDE.local.md\"]}","changes":[{"action":"set","scope":".\u0000AGENTS.md","path":"AGENTS.md","digest":"2e18766c26603608f321508caae00ea8f4434d59"}]},"role":"user","id":"4cba1848-cbb7-46fd-8cea-8497d54d0e63"},"surfaceOp":"append"}
{"type":"user/message","seq":6,"time":1785730689193,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"e4406554-e400-49c6-b8a3-0fe36841160b"},"surfaceOp":"append"}
{"type":"session/title","seq":7,"time":1785730689193,"data":{"title":"Read nested/task.txt, then read scope</s","messageSeqs":[4],"source":{"kind":"fallback"}}}
{"type":"request/header","seq":8,"time":1785498790358,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
@@ -19,10 +19,10 @@
{"type":"user/message","seq":17,"time":1785982371865,"data":{"content":[{"type":"text","text":"Earlier context was compacted for this snapshot."}],"source":{"kind":"plugin","plugin":"compact","compactionId":"workspace-context-fixture"},"role":"user","id":"162c764f-f01d-484d-ad81-1481dc29792a"},"sourceEventSeqs":[5],"surfaceOp":{"op":"replace","start":5,"end":5}}
{"type":"tool/result","seq":18,"time":1785982371865,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_workspace_read"},"content":[{"type":"tool-result","toolCallId":"call_workspace_read","content":[{"type":"text","text":"<path>{{cwd}}/nested/task.txt</path>\n<type>file</type>\n<content>\n1: snapshot task\n\n(End of file - total 1 lines)\n</content>"}],"isError":false}],"role":"user","id":"a46fded2-333a-4fb2-b01e-28520bffbc21"},"meta":{"path":"{{cwd}}/nested/task.txt","offset":1,"lines":[{"number":1,"text":"snapshot task"}],"totalLines":1}},"sourceEventSeqs":[16],"surfaceOp":"append"}
{"type":"step/end","seq":19,"time":1785982371865,"data":{"turn":1,"step":1}}
{"type":"agent/inbox/spliced","seq":20,"time":1785730689207,"data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"<system-reminder>\nThe following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: AGENTS.md\n\nRoot snapshot instruction.\n\n</system-reminder>"},{"type":"text","text":"<system-reminder>\nAdditional instructions from: nested/AGENTS.md\n\nThese instructions apply to work under `nested`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nNested snapshot instruction.\n\n</system-reminder>"}],"source":{"kind":"workspace-instructions","form":"instructions","baseline":true,"baselineIdentity":"{\"projectRoot\":\"\",\"projectRootMarkers\":[\".dsh-project\"],\"maxBytes\":65536,\"maxSourceBytes\":1048576,\"instructionFileCandidates\":[\"AGENTS.md\",\"CLAUDE.md\"],\"localInstructionFileCandidates\":[\"AGENTS.local.md\",\"CLAUDE.local.md\"]}","changes":[{"action":"set","scope":".\u0000AGENTS.md","path":"AGENTS.md","digest":"2e18766c26603608f321508caae00ea8f4434d59"},{"action":"set","scope":"nested\u0000AGENTS.md","path":"nested/AGENTS.md","digest":"c446df9a85c7e73a3055f394a4822a19ac9ead5a"}]},"role":"user","id":"09640903-80ea-4eb6-8635-90ddfb4e24e4"}]}}
{"type":"agent/inbox/spliced","seq":20,"time":1785730689207,"data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"<system-reminder>\nThe following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: AGENTS.md\n\nRoot snapshot instruction.\n\n</system-reminder>"},{"type":"text","text":"<system-reminder>\nAdditional instructions from: nested/AGENTS.md\n\nThese instructions apply to work under `nested`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nNested snapshot instruction.\n\n</system-reminder>"}],"source":{"kind":"agent-instructions","form":"instructions","baseline":true,"baselineIdentity":"{\"projectRoot\":\"\",\"projectRootMarkers\":[\".dsh-project\"],\"maxBytes\":65536,\"maxSourceBytes\":1048576,\"instructionFileCandidates\":[\"AGENTS.md\",\"CLAUDE.md\"],\"localInstructionFileCandidates\":[\"AGENTS.local.md\",\"CLAUDE.local.md\"]}","changes":[{"action":"set","scope":".\u0000AGENTS.md","path":"AGENTS.md","digest":"2e18766c26603608f321508caae00ea8f4434d59"},{"action":"set","scope":"nested\u0000AGENTS.md","path":"nested/AGENTS.md","digest":"c446df9a85c7e73a3055f394a4822a19ac9ead5a"}]},"role":"user","id":"09640903-80ea-4eb6-8635-90ddfb4e24e4"}]}}
{"type":"agent/inbox/spliced","seq":21,"time":1785982371873,"data":{"target":"next-step","start":0,"removedCount":1,"inserted":[],"outcome":"canceled"}}
{"type":"step/start","seq":22,"time":1785982371873,"data":{"turn":1,"step":2}}
{"type":"user/message","seq":23,"time":1785982371873,"data":{"content":[{"type":"text","text":"<system-reminder>\nThe following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: AGENTS.md\n\nRoot snapshot instruction.\n\n</system-reminder>"},{"type":"text","text":"<system-reminder>\nAdditional instructions from: nested/AGENTS.md\n\nThese instructions apply to work under `nested`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nNested snapshot instruction.\n\n</system-reminder>"}],"source":{"kind":"workspace-instructions","form":"instructions","baseline":true,"baselineIdentity":"{\"projectRoot\":\"\",\"projectRootMarkers\":[\".dsh-project\"],\"maxBytes\":65536,\"maxSourceBytes\":1048576,\"instructionFileCandidates\":[\"AGENTS.md\",\"CLAUDE.md\"],\"localInstructionFileCandidates\":[\"AGENTS.local.md\",\"CLAUDE.local.md\"]}","changes":[{"action":"set","scope":".\u0000AGENTS.md","path":"AGENTS.md","digest":"2e18766c26603608f321508caae00ea8f4434d59"},{"action":"set","scope":"nested\u0000AGENTS.md","path":"nested/AGENTS.md","digest":"c446df9a85c7e73a3055f394a4822a19ac9ead5a"}]},"role":"user","id":"09640903-80ea-4eb6-8635-90ddfb4e24e4"},"surfaceOp":"append"}
{"type":"user/message","seq":23,"time":1785982371873,"data":{"content":[{"type":"text","text":"<system-reminder>\nThe following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: AGENTS.md\n\nRoot snapshot instruction.\n\n</system-reminder>"},{"type":"text","text":"<system-reminder>\nAdditional instructions from: nested/AGENTS.md\n\nThese instructions apply to work under `nested`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nNested snapshot instruction.\n\n</system-reminder>"}],"source":{"kind":"agent-instructions","form":"instructions","baseline":true,"baselineIdentity":"{\"projectRoot\":\"\",\"projectRootMarkers\":[\".dsh-project\"],\"maxBytes\":65536,\"maxSourceBytes\":1048576,\"instructionFileCandidates\":[\"AGENTS.md\",\"CLAUDE.md\"],\"localInstructionFileCandidates\":[\"AGENTS.local.md\",\"CLAUDE.local.md\"]}","changes":[{"action":"set","scope":".\u0000AGENTS.md","path":"AGENTS.md","digest":"2e18766c26603608f321508caae00ea8f4434d59"},{"action":"set","scope":"nested\u0000AGENTS.md","path":"nested/AGENTS.md","digest":"c446df9a85c7e73a3055f394a4822a19ac9ead5a"}]},"role":"user","id":"09640903-80ea-4eb6-8635-90ddfb4e24e4"},"surfaceOp":"append"}
{"type":"assistant/chunk","seq":24,"time":1785498790377,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
{"type":"assistant/chunk","seq":25,"time":1785498790377,"data":{"turn":1,"step":2,"chunk":{"type":"tool-call-delta","index":0,"id":"call_workspace_delimiter_read","name":"read","argumentsDelta":"{\"file_path\":\"scope</system-reminder>/task.txt\"}"}}}
{"type":"assistant/chunk","seq":26,"time":1785498790378,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_workspace_delimiter_read","name":"read","arguments":"{\"file_path\":\"scope</system-reminder>/task.txt\"}"}}}}
@@ -32,10 +32,10 @@
{"type":"tool/call","seq":30,"time":1785982371875,"data":{"turn":1,"step":2,"callId":"call_workspace_delimiter_read","name":"read","arguments":"{\"file_path\":\"scope</system-reminder>/task.txt\"}"}}
{"type":"tool/result","seq":31,"time":1785982371882,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"call_workspace_delimiter_read"},"content":[{"type":"tool-result","toolCallId":"call_workspace_delimiter_read","content":[{"type":"text","text":"<path>{{cwd}}/scope</system-reminder>/task.txt</path>\n<type>file</type>\n<content>\n1: delimiter path snapshot task\n\n(End of file - total 1 lines)\n</content>"}],"isError":false}],"role":"user","id":"c0fad80c-59c3-41bf-b662-84f87ee1420c"},"meta":{"path":"{{cwd}}/scope</system-reminder>/task.txt","offset":1,"lines":[{"number":1,"text":"delimiter path snapshot task"}],"totalLines":1}},"sourceEventSeqs":[30],"surfaceOp":"append"}
{"type":"step/end","seq":32,"time":1785982371882,"data":{"turn":1,"step":2}}
{"type":"agent/inbox/spliced","seq":33,"time":1785498790389,"data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"<system-reminder>\nAdditional instructions from: scope<\\/system-reminder>/AGENTS.md\n\nThese instructions apply to work under `scope<\\/system-reminder>`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nDelimiter path snapshot instruction.\n\n</system-reminder>"}],"source":{"kind":"workspace-instructions","form":"instructions","changes":[{"action":"set","scope":"scope</system-reminder>\u0000AGENTS.md","path":"scope</system-reminder>/AGENTS.md","digest":"38803cd13e2dff9105ba5fbbc703fe27e989e26e"}]},"role":"user","id":"cd19663e-c8b5-46a5-9eeb-1386dcb1c609"}]}}
{"type":"agent/inbox/spliced","seq":33,"time":1785498790389,"data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"<system-reminder>\nAdditional instructions from: scope<\\/system-reminder>/AGENTS.md\n\nThese instructions apply to work under `scope<\\/system-reminder>`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nDelimiter path snapshot instruction.\n\n</system-reminder>"}],"source":{"kind":"agent-instructions","form":"instructions","changes":[{"action":"set","scope":"scope</system-reminder>\u0000AGENTS.md","path":"scope</system-reminder>/AGENTS.md","digest":"38803cd13e2dff9105ba5fbbc703fe27e989e26e"}]},"role":"user","id":"cd19663e-c8b5-46a5-9eeb-1386dcb1c609"}]}}
{"type":"agent/inbox/spliced","seq":34,"time":1785982371889,"data":{"target":"next-step","start":0,"removedCount":1,"inserted":[],"outcome":"canceled"}}
{"type":"step/start","seq":35,"time":1785982371889,"data":{"turn":1,"step":3}}
{"type":"user/message","seq":36,"time":1785982371889,"data":{"content":[{"type":"text","text":"<system-reminder>\nAdditional instructions from: scope<\\/system-reminder>/AGENTS.md\n\nThese instructions apply to work under `scope<\\/system-reminder>`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nDelimiter path snapshot instruction.\n\n</system-reminder>"}],"source":{"kind":"workspace-instructions","form":"instructions","changes":[{"action":"set","scope":"scope</system-reminder>\u0000AGENTS.md","path":"scope</system-reminder>/AGENTS.md","digest":"38803cd13e2dff9105ba5fbbc703fe27e989e26e"}]},"role":"user","id":"cd19663e-c8b5-46a5-9eeb-1386dcb1c609"},"surfaceOp":"append"}
{"type":"user/message","seq":36,"time":1785982371889,"data":{"content":[{"type":"text","text":"<system-reminder>\nAdditional instructions from: scope<\\/system-reminder>/AGENTS.md\n\nThese instructions apply to work under `scope<\\/system-reminder>`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nDelimiter path snapshot instruction.\n\n</system-reminder>"}],"source":{"kind":"agent-instructions","form":"instructions","changes":[{"action":"set","scope":"scope</system-reminder>\u0000AGENTS.md","path":"scope</system-reminder>/AGENTS.md","digest":"38803cd13e2dff9105ba5fbbc703fe27e989e26e"}]},"role":"user","id":"cd19663e-c8b5-46a5-9eeb-1386dcb1c609"},"surfaceOp":"append"}
{"type":"assistant/chunk","seq":37,"time":1785498790396,"data":{"turn":1,"step":3,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
{"type":"assistant/chunk","seq":38,"time":1785498790396,"data":{"turn":1,"step":3,"chunk":{"type":"text-delta","index":0,"text":"DONE"}}}
{"type":"assistant/chunk","seq":39,"time":1785498790396,"data":{"turn":1,"step":3,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DONE"}}}}

View File

@@ -1,4 +1,4 @@
You are an AI agent powered by the DeepSeek Harness SDK.
You are an AI agent powered by DeepSeek Harness.
You are a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.
@@ -7,13 +7,13 @@ 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 write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-observation-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.
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-observation-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.
Track every background job id you start. You are notified in-session when a job finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running job's work. Before giving a final answer, collect every still-relevant job with job_output (set wait: true only when you are genuinely blocked on it), and job_kill jobs that stopped mattering.
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.

View File

@@ -4,7 +4,7 @@
{ "op": "newSession" },
{
"op": "prompt",
"text": "Start one background Bash task that stays alive. Immediately try to start a second background Bash task, observe the limit error, stop the first task by its returned task id, verify that second-task-ran.txt does not exist, then reply with exactly BOUNDED_BACKGROUND_TASKS and stop."
"text": "Start one background Bash task that stays alive. Immediately try to start a second background Bash task, observe the limit error, stop the first task by its returned job id, verify that second-task-ran.txt does not exist, then reply with exactly BOUNDED_BACKGROUND_TASKS and stop."
}
]
}

View File

@@ -3,8 +3,8 @@
"kind": "chunks",
"chunks": [
{ "type": "block-start", "index": 0, "blockType": "tool-call" },
{ "type": "tool-call-delta", "index": 0, "id": "bounded-task-first", "name": "bash", "argumentsDelta": "{\"command\":\"while :; do sleep 60; done\",\"description\":\"Hold the only background task slot\",\"run_in_background\":true}" },
{ "type": "block-end", "index": 0, "block": { "type": "tool-call", "id": "bounded-task-first", "name": "bash", "arguments": "{\"command\":\"while :; do sleep 60; done\",\"description\":\"Hold the only background task slot\",\"run_in_background\":true}" } },
{ "type": "tool-call-delta", "index": 0, "id": "bounded-task-first", "name": "bash", "argumentsDelta": "{\"command\":\"while :; do sleep 60; done\",\"description\":\"Hold the only background job slot\",\"run_in_background\":true}" },
{ "type": "block-end", "index": 0, "block": { "type": "tool-call", "id": "bounded-task-first", "name": "bash", "arguments": "{\"command\":\"while :; do sleep 60; done\",\"description\":\"Hold the only background job slot\",\"run_in_background\":true}" } },
{ "type": "usage", "usage": { "inputTokens": 10, "outputTokens": 5 } },
{ "type": "finish", "reason": { "kind": "tool-calls" } }
]
@@ -13,8 +13,8 @@
"kind": "chunks",
"chunks": [
{ "type": "block-start", "index": 0, "blockType": "tool-call" },
{ "type": "tool-call-delta", "index": 0, "id": "bounded-task-second", "name": "bash", "argumentsDelta": "{\"command\":\"printf SHOULD_NOT_RUN > second-task-ran.txt; while :; do sleep 60; done\",\"description\":\"Attempt a second background task\",\"run_in_background\":true}" },
{ "type": "block-end", "index": 0, "block": { "type": "tool-call", "id": "bounded-task-second", "name": "bash", "arguments": "{\"command\":\"printf SHOULD_NOT_RUN > second-task-ran.txt; while :; do sleep 60; done\",\"description\":\"Attempt a second background task\",\"run_in_background\":true}" } },
{ "type": "tool-call-delta", "index": 0, "id": "bounded-task-second", "name": "bash", "argumentsDelta": "{\"command\":\"printf SHOULD_NOT_RUN > second-task-ran.txt; while :; do sleep 60; done\",\"description\":\"Attempt a second background job\",\"run_in_background\":true}" },
{ "type": "block-end", "index": 0, "block": { "type": "tool-call", "id": "bounded-task-second", "name": "bash", "arguments": "{\"command\":\"printf SHOULD_NOT_RUN > second-task-ran.txt; while :; do sleep 60; done\",\"description\":\"Attempt a second background job\",\"run_in_background\":true}" } },
{ "type": "usage", "usage": { "inputTokens": 10, "outputTokens": 5 } },
{ "type": "finish", "reason": { "kind": "tool-calls" } }
]
@@ -23,8 +23,8 @@
"kind": "chunks",
"chunks": [
{ "type": "block-start", "index": 0, "blockType": "tool-call" },
{ "type": "tool-call-delta", "index": 0, "id": "bounded-task-kill", "name": "task_kill", "argumentsDelta": "{\"task_id\":\"bash-1\",\"reason\":\"free the bounded task slot\"}" },
{ "type": "block-end", "index": 0, "block": { "type": "tool-call", "id": "bounded-task-kill", "name": "task_kill", "arguments": "{\"task_id\":\"bash-1\",\"reason\":\"free the bounded task slot\"}" } },
{ "type": "tool-call-delta", "index": 0, "id": "bounded-task-kill", "name": "job_kill", "argumentsDelta": "{\"job_id\":\"bash-1\",\"reason\":\"free the bounded task slot\"}" },
{ "type": "block-end", "index": 0, "block": { "type": "tool-call", "id": "bounded-task-kill", "name": "job_kill", "arguments": "{\"job_id\":\"bash-1\",\"reason\":\"free the bounded task slot\"}" } },
{ "type": "usage", "usage": { "inputTokens": 10, "outputTokens": 5 } },
{ "type": "finish", "reason": { "kind": "tool-calls" } }
]

View File

@@ -1,41 +1,41 @@
{"type":"session","version":0,"id":"77777777-7777-4777-8777-777777777777","createdAt":0,"cwd":"{{cwd}}","delegationDepth":0}
{"type":"agent/inbox/spliced","seq":0,"time":1786434813544,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Start one background Bash task that stays alive. Immediately try to start a second background Bash task, observe the limit error, stop the first task by its returned task id, verify that second-task-ran.txt does not exist, then reply with exactly BOUNDED_BACKGROUND_TASKS and stop."}],"source":{"kind":"user"},"role":"user","id":"fca9abcd-66a9-4c79-ab34-7e25e65e01af"}]}}
{"type":"agent/inbox/spliced","seq":0,"time":1786434813544,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Start one background Bash task that stays alive. Immediately try to start a second background Bash task, observe the limit error, stop the first task by its returned job id, verify that second-task-ran.txt does not exist, then reply with exactly BOUNDED_BACKGROUND_TASKS and stop."}],"source":{"kind":"user"},"role":"user","id":"fca9abcd-66a9-4c79-ab34-7e25e65e01af"}]}}
{"type":"turn/start","seq":1,"time":1786434813545,"data":{"turn":1}}
{"type":"agent/inbox/spliced","seq":2,"time":1786434813546,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","seq":3,"time":1786434813574,"data":{"turn":1,"step":1}}
{"type":"user/message","seq":4,"time":1786434813574,"data":{"content":[{"type":"text","text":"Start one background Bash task that stays alive. Immediately try to start a second background Bash task, observe the limit error, stop the first task by its returned task id, verify that second-task-ran.txt does not exist, then reply with exactly BOUNDED_BACKGROUND_TASKS and stop."}],"source":{"kind":"user"},"role":"user","id":"fca9abcd-66a9-4c79-ab34-7e25e65e01af"},"surfaceOp":"append"}
{"type":"user/message","seq":4,"time":1786434813574,"data":{"content":[{"type":"text","text":"Start one background Bash task that stays alive. Immediately try to start a second background Bash task, observe the limit error, stop the first task by its returned job id, verify that second-task-ran.txt does not exist, then reply with exactly BOUNDED_BACKGROUND_TASKS and stop."}],"source":{"kind":"user"},"role":"user","id":"fca9abcd-66a9-4c79-ab34-7e25e65e01af"},"surfaceOp":"append"}
{"type":"user/message","seq":5,"time":1786434813575,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"f7801581-b729-4cbc-b205-1eabd5b96de7"},"surfaceOp":"append"}
{"type":"session/title","seq":6,"time":1786434813575,"data":{"title":"Start one background Bash task","messageSeqs":[4],"source":{"kind":"fallback"}}}
{"type":"request/header","seq":7,"time":1786434813576,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","seq":8,"time":1786434813576,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}
{"type":"assistant/chunk","seq":9,"time":1786434813581,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
{"type":"assistant/chunk","seq":10,"time":1786434813581,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"bounded-task-first","name":"bash","argumentsDelta":"{\"command\":\"while :; do sleep 60; done\",\"description\":\"Hold the only background task slot\",\"run_in_background\":true}"}}}
{"type":"assistant/chunk","seq":11,"time":1786434813581,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"bounded-task-first","name":"bash","arguments":"{\"command\":\"while :; do sleep 60; done\",\"description\":\"Hold the only background task slot\",\"run_in_background\":true}"}}}}
{"type":"assistant/chunk","seq":10,"time":1786434813581,"data":{"turn":1,"step":1,"chunk":{"type":"tool-call-delta","index":0,"id":"bounded-task-first","name":"bash","argumentsDelta":"{\"command\":\"while :; do sleep 60; done\",\"description\":\"Hold the only background job slot\",\"run_in_background\":true}"}}}
{"type":"assistant/chunk","seq":11,"time":1786434813581,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"bounded-task-first","name":"bash","arguments":"{\"command\":\"while :; do sleep 60; done\",\"description\":\"Hold the only background job slot\",\"run_in_background\":true}"}}}}
{"type":"assistant/chunk","seq":12,"time":1786434813581,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}}
{"type":"assistant/chunk","seq":13,"time":1786434813581,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":14,"time":1786434813582,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"bounded-task-first","name":"bash","arguments":"{\"command\":\"while :; do sleep 60; done\",\"description\":\"Hold the only background task slot\",\"run_in_background\":true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"f25e0e7c-76a4-45a6-a825-64d1bd42fe59"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[9,10,11,12,13],"surfaceOp":"append"}
{"type":"tool/call","seq":15,"time":1786434813582,"data":{"turn":1,"step":1,"callId":"bounded-task-first","name":"bash","arguments":"{\"command\":\"while :; do sleep 60; done\",\"description\":\"Hold the only background task slot\",\"run_in_background\":true}"}}
{"type":"tool/result","seq":16,"time":1786434813594,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"bounded-task-first"},"content":[{"type":"tool-result","toolCallId":"bounded-task-first","content":[{"type":"text","text":"started background task bash-1"}],"isError":false}],"role":"user","id":"0e19086f-2a9a-4e78-b5eb-5a117cad9416"}},"sourceEventSeqs":[15],"surfaceOp":"append"}
{"type":"assistant/message","seq":14,"time":1786434813582,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"tool-call","id":"bounded-task-first","name":"bash","arguments":"{\"command\":\"while :; do sleep 60; done\",\"description\":\"Hold the only background job slot\",\"run_in_background\":true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"f25e0e7c-76a4-45a6-a825-64d1bd42fe59"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[9,10,11,12,13],"surfaceOp":"append"}
{"type":"tool/call","seq":15,"time":1786434813582,"data":{"turn":1,"step":1,"callId":"bounded-task-first","name":"bash","arguments":"{\"command\":\"while :; do sleep 60; done\",\"description\":\"Hold the only background job slot\",\"run_in_background\":true}"}}
{"type":"tool/result","seq":16,"time":1786434813594,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"bounded-task-first"},"content":[{"type":"tool-result","toolCallId":"bounded-task-first","content":[{"type":"text","text":"started background job bash-1"}],"isError":false}],"role":"user","id":"0e19086f-2a9a-4e78-b5eb-5a117cad9416"}},"sourceEventSeqs":[15],"surfaceOp":"append"}
{"type":"step/end","seq":17,"time":1786434813594,"data":{"turn":1,"step":1}}
{"type":"step/start","seq":18,"time":1786434813600,"data":{"turn":1,"step":2}}
{"type":"assistant/chunk","seq":19,"time":1786434813605,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
{"type":"assistant/chunk","seq":20,"time":1786434813605,"data":{"turn":1,"step":2,"chunk":{"type":"tool-call-delta","index":0,"id":"bounded-task-second","name":"bash","argumentsDelta":"{\"command\":\"printf SHOULD_NOT_RUN > second-task-ran.txt; while :; do sleep 60; done\",\"description\":\"Attempt a second background task\",\"run_in_background\":true}"}}}
{"type":"assistant/chunk","seq":21,"time":1786434813605,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"bounded-task-second","name":"bash","arguments":"{\"command\":\"printf SHOULD_NOT_RUN > second-task-ran.txt; while :; do sleep 60; done\",\"description\":\"Attempt a second background task\",\"run_in_background\":true}"}}}}
{"type":"assistant/chunk","seq":20,"time":1786434813605,"data":{"turn":1,"step":2,"chunk":{"type":"tool-call-delta","index":0,"id":"bounded-task-second","name":"bash","argumentsDelta":"{\"command\":\"printf SHOULD_NOT_RUN > second-task-ran.txt; while :; do sleep 60; done\",\"description\":\"Attempt a second background job\",\"run_in_background\":true}"}}}
{"type":"assistant/chunk","seq":21,"time":1786434813605,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"bounded-task-second","name":"bash","arguments":"{\"command\":\"printf SHOULD_NOT_RUN > second-task-ran.txt; while :; do sleep 60; done\",\"description\":\"Attempt a second background job\",\"run_in_background\":true}"}}}}
{"type":"assistant/chunk","seq":22,"time":1786434813605,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}}
{"type":"assistant/chunk","seq":23,"time":1786434813605,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":24,"time":1786434813605,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"bounded-task-second","name":"bash","arguments":"{\"command\":\"printf SHOULD_NOT_RUN > second-task-ran.txt; while :; do sleep 60; done\",\"description\":\"Attempt a second background task\",\"run_in_background\":true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"48c909b3-5651-462f-b0d3-09198d119a2f"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[19,20,21,22,23],"surfaceOp":"append"}
{"type":"tool/call","seq":25,"time":1786434813606,"data":{"turn":1,"step":2,"callId":"bounded-task-second","name":"bash","arguments":"{\"command\":\"printf SHOULD_NOT_RUN > second-task-ran.txt; while :; do sleep 60; done\",\"description\":\"Attempt a second background task\",\"run_in_background\":true}"}}
{"type":"tool/result","seq":26,"time":1786434813609,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"bounded-task-second"},"content":[{"type":"tool-result","toolCallId":"bounded-task-second","content":[{"type":"text","text":"Error: background task limit reached for this owner (limit: 1); use task_kill to stop an unneeded task, wait for it to finish, then retry"}],"isError":true}],"role":"user","id":"c0386bdf-df3c-4d2b-af8e-04ee28682214"}},"sourceEventSeqs":[25],"surfaceOp":"append"}
{"type":"assistant/message","seq":24,"time":1786434813605,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"bounded-task-second","name":"bash","arguments":"{\"command\":\"printf SHOULD_NOT_RUN > second-task-ran.txt; while :; do sleep 60; done\",\"description\":\"Attempt a second background job\",\"run_in_background\":true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"48c909b3-5651-462f-b0d3-09198d119a2f"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[19,20,21,22,23],"surfaceOp":"append"}
{"type":"tool/call","seq":25,"time":1786434813606,"data":{"turn":1,"step":2,"callId":"bounded-task-second","name":"bash","arguments":"{\"command\":\"printf SHOULD_NOT_RUN > second-task-ran.txt; while :; do sleep 60; done\",\"description\":\"Attempt a second background job\",\"run_in_background\":true}"}}
{"type":"tool/result","seq":26,"time":1786434813609,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"bounded-task-second"},"content":[{"type":"tool-result","toolCallId":"bounded-task-second","content":[{"type":"text","text":"started background job bash-2"}],"isError":false}],"role":"user","id":"eff27c8c-b60d-4bf4-af9d-45d040974d32"}},"sourceEventSeqs":[25],"surfaceOp":"append"}
{"type":"step/end","seq":27,"time":1786434813609,"data":{"turn":1,"step":2}}
{"type":"step/start","seq":28,"time":1786434813614,"data":{"turn":1,"step":3}}
{"type":"assistant/chunk","seq":29,"time":1786434813618,"data":{"turn":1,"step":3,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
{"type":"assistant/chunk","seq":30,"time":1786434813618,"data":{"turn":1,"step":3,"chunk":{"type":"tool-call-delta","index":0,"id":"bounded-task-kill","name":"task_kill","argumentsDelta":"{\"task_id\":\"bash-1\",\"reason\":\"free the bounded task slot\"}"}}}
{"type":"assistant/chunk","seq":31,"time":1786434813618,"data":{"turn":1,"step":3,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"bounded-task-kill","name":"task_kill","arguments":"{\"task_id\":\"bash-1\",\"reason\":\"free the bounded task slot\"}"}}}}
{"type":"assistant/chunk","seq":30,"time":1786434813618,"data":{"turn":1,"step":3,"chunk":{"type":"tool-call-delta","index":0,"id":"bounded-task-kill","name":"job_kill","argumentsDelta":"{\"job_id\":\"bash-1\",\"reason\":\"free the bounded task slot\"}"}}}
{"type":"assistant/chunk","seq":31,"time":1786434813618,"data":{"turn":1,"step":3,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"bounded-task-kill","name":"job_kill","arguments":"{\"job_id\":\"bash-1\",\"reason\":\"free the bounded task slot\"}"}}}}
{"type":"assistant/chunk","seq":32,"time":1786434813618,"data":{"turn":1,"step":3,"chunk":{"type":"usage","usage":{"inputTokens":10,"outputTokens":5}}}}
{"type":"assistant/chunk","seq":33,"time":1786434813618,"data":{"turn":1,"step":3,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":34,"time":1786434813618,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"bounded-task-kill","name":"task_kill","arguments":"{\"task_id\":\"bash-1\",\"reason\":\"free the bounded task slot\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"6dc2d854-59f7-4c70-8a0f-64416b324055"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[29,30,31,32,33],"surfaceOp":"append"}
{"type":"tool/call","seq":35,"time":1786434813618,"data":{"turn":1,"step":3,"callId":"bounded-task-kill","name":"task_kill","arguments":"{\"task_id\":\"bash-1\",\"reason\":\"free the bounded task slot\"}"}}
{"type":"tool/result","seq":36,"time":1786434813623,"data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"bounded-task-kill"},"content":[{"type":"tool-result","toolCallId":"bounded-task-kill","content":[{"type":"text","text":"requested cancellation of task bash-1"}],"isError":false}],"role":"user","id":"5abf87b2-3e10-448f-a529-dfc40dce2f08"}},"sourceEventSeqs":[35],"surfaceOp":"append"}
{"type":"assistant/message","seq":34,"time":1786434813618,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"bounded-task-kill","name":"job_kill","arguments":"{\"job_id\":\"bash-1\",\"reason\":\"free the bounded task slot\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"6dc2d854-59f7-4c70-8a0f-64416b324055"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[29,30,31,32,33],"surfaceOp":"append"}
{"type":"tool/call","seq":35,"time":1786434813618,"data":{"turn":1,"step":3,"callId":"bounded-task-kill","name":"job_kill","arguments":"{\"job_id\":\"bash-1\",\"reason\":\"free the bounded task slot\"}"}}
{"type":"tool/result","seq":36,"time":1786434813623,"data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"bounded-task-kill"},"content":[{"type":"tool-result","toolCallId":"bounded-task-kill","content":[{"type":"text","text":"requested cancellation of job bash-1"}],"isError":false}],"role":"user","id":"b0154d3a-c8c6-4469-98bf-7ea625e8d319"}},"sourceEventSeqs":[35],"surfaceOp":"append"}
{"type":"step/end","seq":37,"time":1786434813623,"data":{"turn":1,"step":3}}
{"type":"step/start","seq":38,"time":1786434813628,"data":{"turn":1,"step":4}}
{"type":"assistant/chunk","seq":39,"time":1786434813632,"data":{"turn":1,"step":4,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
@@ -45,7 +45,7 @@
{"type":"assistant/chunk","seq":43,"time":1786434813632,"data":{"turn":1,"step":4,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":44,"time":1786434813632,"data":{"turn":1,"step":4,"message":{"role":"assistant","content":[{"type":"tool-call","id":"bounded-task-side-effect-check","name":"bash","arguments":"{\"command\":\"test ! -e second-task-ran.txt\",\"description\":\"Verify the rejected producer did not run\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"85ebd1ec-c3b2-4bd2-87cb-135089efc440"},"usage":{"inputTokens":10,"outputTokens":5}},"sourceEventSeqs":[39,40,41,42,43],"surfaceOp":"append"}
{"type":"tool/call","seq":45,"time":1786436340879,"data":{"turn":1,"step":4,"callId":"bounded-task-side-effect-check","name":"bash","arguments":"{\"command\":\"test ! -e second-task-ran.txt\",\"description\":\"Verify the rejected producer did not run\"}"}}
{"type":"tool/result","seq":46,"time":1786436340886,"data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"bounded-task-side-effect-check"},"content":[{"type":"tool-result","toolCallId":"bounded-task-side-effect-check","content":[{"type":"text","text":"(no output)"}],"isError":false}],"role":"user","id":"49f76b57-92a2-4ae2-9711-11ad7cbd4e4c"}},"sourceEventSeqs":[45],"surfaceOp":"append"}
{"type":"tool/result","seq":46,"time":1786436340886,"data":{"turn":1,"step":4,"message":{"source":{"kind":"tool","callId":"bounded-task-side-effect-check"},"content":[{"type":"tool-result","toolCallId":"bounded-task-side-effect-check","content":[{"type":"text","text":"(no output)\n[exit code: 1]"}],"isError":false}],"role":"user","id":"2a68ce69-ad00-47dd-8bdd-ff70a8c0fd8d"}},"sourceEventSeqs":[45],"surfaceOp":"append"}
{"type":"step/end","seq":47,"time":1786436340886,"data":{"turn":1,"step":4}}
{"type":"step/start","seq":48,"time":1786436340891,"data":{"turn":1,"step":5}}
{"type":"assistant/chunk","seq":49,"time":1786436340897,"data":{"turn":1,"step":5,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}

View File

@@ -1,4 +1,4 @@
You are an AI agent powered by the DeepSeek Harness SDK.
You are an AI agent powered by DeepSeek Harness.
You are a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.
@@ -7,13 +7,13 @@ 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 write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-observation-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.
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-observation-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.
Track every background job id you start. You are notified in-session when a job finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running job's work. Before giving a final answer, collect every still-relevant job with job_output (set wait: true only when you are genuinely blocked on it), and job_kill jobs that stopped mattering.
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.
@@ -25,7 +25,7 @@ Use subagent in the background by default. Start independent delegations togethe
## Writing code for run_code
Pass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:
`run_code` takes two required arguments: `code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped) — and `description`, a short summary of what the program does. Inside the program:
- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools["my-tool"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.
- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.
@@ -38,7 +38,7 @@ The available tools:
type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }
interface ToolArgsMap {
/** 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> 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. */
/** 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> 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 job id immediately; read its output with `job_output` and stop it with `job_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. */
bash: {
/** The bash command to execute. */
command: string;
@@ -48,7 +48,7 @@ interface ToolArgsMap {
timeoutMs?: number;
/** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */
workdir?: string;
/** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */
/** Run in the background and return a job id immediately (collect with job_output, stop with job_kill). No timeout applies. */
run_in_background?: boolean;
/** 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. */
sandbox_permissions?: "workspace-write" | "danger-full-access";
@@ -84,6 +84,24 @@ interface ToolArgsMap {
/** The agent id of the running agent to interrupt. */
agent_id: string;
} & Record<string, JsonValue>;
/** Request cancellation of a running background job by job id. Returns immediately; the job settles as killed once its work actually stops. */
job_kill: {
/** Job id returned by the tool that started the background work. */
job_id: string;
/** Optional short reason, recorded in the log and forwarded to the job. */
reason?: string;
} & Record<string, JsonValue>;
/** List your background jobs (running and finished) with their ids, kinds, and statuses. */
job_list: Record<string, JsonValue>;
/** Read a background job. Stream jobs return only output since the previous read; final-output jobs return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */
job_output: {
/** Job id returned by the tool that started the background work. */
job_id: string;
/** Block until the job reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the job alive. */
wait?: boolean;
/** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */
timeout_ms?: number;
} & Record<string, JsonValue>;
/** List your continuable background subagents by durable id and label. Use it to recall which ones you started, not to poll for completion — you are told when one finishes. Status comes from the live registry: running means the agent is working right now, idle means it is loaded but between turns (it may be waiting on agents it started), and ready means it exists only in storage — resumable, not terminal, and not a result waiting to be collected; a `send_message` starts a new turn on the same conversation, and a direct child remains a `send_message` candidate in every status. The snapshot is not a delivery promise — `send_message` performs the authoritative check and may still fail. Children that could not be read are reported as diagnostics instead of being silently dropped. Scope `descendants` walks the whole tree below you in stable pre-order, annotating each entry with its durable direct-parent session id and depth. You may use `send_message` only for depth-1 entries; deeper entries are candidates for `interrupt_agent` only. */
list_agents: {
/** children (default) lists direct children only; descendants walks the complete tree below you. */
@@ -133,24 +151,6 @@ interface ToolArgsMap {
/** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */
prompt: string;
} & Record<string, JsonValue>;
/** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */
task_kill: {
/** Task id returned by the tool that started the background work. */
task_id: string;
/** Optional short reason, recorded in the log and forwarded to the task. */
reason?: string;
} & Record<string, JsonValue>;
/** List your background tasks (running and finished) with their ids, kinds, and statuses. */
task_list: Record<string, JsonValue>;
/** 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. */
task_output: {
/** Task id returned by the tool that started the background work. */
task_id: string;
/** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */
wait?: boolean;
/** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */
timeout_ms?: number;
} & Record<string, JsonValue>;
/** 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. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one 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). */
todo_write: {
/** The COMPLETE task list, replacing any previous list. */
@@ -219,7 +219,7 @@ interface ToolArgsMap {
interface ToolOutputMap {
bash: {
kind: "background";
taskId: string;
jobId: string;
} | {
kind: "foreground";
exitCode: number | null;
@@ -286,6 +286,39 @@ interface ToolOutputMap {
interrupt_agent: {
accepted: boolean;
};
job_kill: {
outcome: "cancellation-requested" | "already-finished";
job: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
job_list: ({
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
})[];
job_output: {
text: string;
job: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
list_agents: ({
kind: "child";
id: string;
@@ -334,7 +367,7 @@ interface ToolOutputMap {
};
subagent: {
kind: "background";
taskId: string;
jobId: string;
} | {
kind: "continuable";
subagentId: string;
@@ -345,7 +378,7 @@ interface ToolOutputMap {
};
subagent_fork: {
kind: "background";
taskId: string;
jobId: string;
} | {
kind: "continuable";
subagentId: string;
@@ -354,39 +387,6 @@ interface ToolOutputMap {
runId: string;
output: JsonValue[];
};
task_kill: {
outcome: "cancellation-requested" | "already-finished";
task: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
task_list: ({
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
})[];
task_output: {
text: string;
task: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
todo_write: {
todos: ({
content: string;

View File

@@ -2,7 +2,7 @@
"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> 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.",
"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> 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 job id immediately; read its output with `job_output` and stop it with `job_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": {
@@ -24,7 +24,7 @@
},
"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."
"description": "Run in the background and return a job id immediately (collect with job_output, stop with job_kill). No timeout applies."
},
"sandbox_permissions": {
"type": "string",
@@ -131,6 +131,58 @@
]
}
},
{
"name": "job_kill",
"description": "Request cancellation of a running background job by job id. Returns immediately; the job settles as killed once its work actually stops.",
"parameters": {
"type": "object",
"properties": {
"job_id": {
"type": "string",
"description": "Job 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 job."
}
},
"required": [
"job_id"
]
}
},
{
"name": "job_list",
"description": "List your background jobs (running and finished) with their ids, kinds, and statuses.",
"parameters": {
"type": "object",
"properties": {}
}
},
{
"name": "job_output",
"description": "Read a background job. Stream jobs return only output since the previous read; final-output jobs 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": {
"job_id": {
"type": "string",
"description": "Job id returned by the tool that started the background work."
},
"wait": {
"type": "boolean",
"description": "Block until the job reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the job 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": [
"job_id"
]
}
},
{
"name": "list_agents",
"description": "List your continuable background subagents by durable id and label. Use it to recall which ones you started, not to poll for completion — you are told when one finishes. Status comes from the live registry: running means the agent is working right now, idle means it is loaded but between turns (it may be waiting on agents it started), and ready means it exists only in storage — resumable, not terminal, and not a result waiting to be collected; a `send_message` starts a new turn on the same conversation, and a direct child remains a `send_message` candidate in every status. The snapshot is not a delivery promise — `send_message` performs the authoritative check and may still fail. Children that could not be read are reported as diagnostics instead of being silently dropped. Scope `descendants` walks the whole tree below you in stable pre-order, annotating each entry with its durable direct-parent session id and depth. You may use `send_message` only for depth-1 entries; deeper entries are candidates for `interrupt_agent` only.",
@@ -194,7 +246,7 @@
},
{
"name": "run_code",
"description": "Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return is program output; image-bearing subtool results are attached after the run.",
"description": "Execute a TypeScript program against the available tools. Takes two required arguments: `code`, the BODY of an async function (erasable syntax only; top-level `await` and `return` work), and `description`, a short summary of what the program does. Call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return is program output — curate it. Image-bearing subtool results are attached after the run.",
"parameters": {
"type": "object",
"properties": {
@@ -296,58 +348,6 @@
]
}
},
{
"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. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one 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).",

View File

@@ -1,4 +1,4 @@
You are an AI agent powered by the DeepSeek Harness SDK.
You are an AI agent powered by DeepSeek Harness.
You are a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.
@@ -9,13 +9,13 @@ 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 write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-observation-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.
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-observation-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.
Track every background job id you start. You are notified in-session when a job finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running job's work. Before giving a final answer, collect every still-relevant job with job_output (set wait: true only when you are genuinely blocked on it), and job_kill jobs that stopped mattering.
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.
@@ -27,7 +27,7 @@ Use subagent in the background by default. Start independent delegations togethe
## Writing code for run_code
Pass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:
`run_code` takes two required arguments: `code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped) — and `description`, a short summary of what the program does. Inside the program:
- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools["my-tool"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.
- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.
@@ -40,7 +40,7 @@ The available tools:
type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }
interface ToolArgsMap {
/** 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> 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. */
/** 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> 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 job id immediately; read its output with `job_output` and stop it with `job_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. */
bash: {
/** The bash command to execute. */
command: string;
@@ -50,7 +50,7 @@ interface ToolArgsMap {
timeoutMs?: number;
/** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */
workdir?: string;
/** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */
/** Run in the background and return a job id immediately (collect with job_output, stop with job_kill). No timeout applies. */
run_in_background?: boolean;
/** 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. */
sandbox_permissions?: "workspace-write" | "danger-full-access";
@@ -86,6 +86,24 @@ interface ToolArgsMap {
/** The agent id of the running agent to interrupt. */
agent_id: string;
} & Record<string, JsonValue>;
/** Request cancellation of a running background job by job id. Returns immediately; the job settles as killed once its work actually stops. */
job_kill: {
/** Job id returned by the tool that started the background work. */
job_id: string;
/** Optional short reason, recorded in the log and forwarded to the job. */
reason?: string;
} & Record<string, JsonValue>;
/** List your background jobs (running and finished) with their ids, kinds, and statuses. */
job_list: Record<string, JsonValue>;
/** Read a background job. Stream jobs return only output since the previous read; final-output jobs return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */
job_output: {
/** Job id returned by the tool that started the background work. */
job_id: string;
/** Block until the job reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the job alive. */
wait?: boolean;
/** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */
timeout_ms?: number;
} & Record<string, JsonValue>;
/** List your continuable background subagents by durable id and label. Use it to recall which ones you started, not to poll for completion — you are told when one finishes. Status comes from the live registry: running means the agent is working right now, idle means it is loaded but between turns (it may be waiting on agents it started), and ready means it exists only in storage — resumable, not terminal, and not a result waiting to be collected; a `send_message` starts a new turn on the same conversation, and a direct child remains a `send_message` candidate in every status. The snapshot is not a delivery promise — `send_message` performs the authoritative check and may still fail. Children that could not be read are reported as diagnostics instead of being silently dropped. Scope `descendants` walks the whole tree below you in stable pre-order, annotating each entry with its durable direct-parent session id and depth. You may use `send_message` only for depth-1 entries; deeper entries are candidates for `interrupt_agent` only. */
list_agents: {
/** children (default) lists direct children only; descendants walks the complete tree below you. */
@@ -140,24 +158,6 @@ interface ToolArgsMap {
/** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */
prompt: string;
} & Record<string, JsonValue>;
/** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */
task_kill: {
/** Task id returned by the tool that started the background work. */
task_id: string;
/** Optional short reason, recorded in the log and forwarded to the task. */
reason?: string;
} & Record<string, JsonValue>;
/** List your background tasks (running and finished) with their ids, kinds, and statuses. */
task_list: Record<string, JsonValue>;
/** 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. */
task_output: {
/** Task id returned by the tool that started the background work. */
task_id: string;
/** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */
wait?: boolean;
/** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */
timeout_ms?: number;
} & Record<string, JsonValue>;
/** 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. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one 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). */
todo_write: {
/** The COMPLETE task list, replacing any previous list. */
@@ -226,7 +226,7 @@ interface ToolArgsMap {
interface ToolOutputMap {
bash: {
kind: "background";
taskId: string;
jobId: string;
} | {
kind: "foreground";
exitCode: number | null;
@@ -293,6 +293,39 @@ interface ToolOutputMap {
interrupt_agent: {
accepted: boolean;
};
job_kill: {
outcome: "cancellation-requested" | "already-finished";
job: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
job_list: ({
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
})[];
job_output: {
text: string;
job: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
list_agents: ({
kind: "child";
id: string;
@@ -352,7 +385,7 @@ interface ToolOutputMap {
};
subagent: {
kind: "background";
taskId: string;
jobId: string;
} | {
kind: "continuable";
subagentId: string;
@@ -363,7 +396,7 @@ interface ToolOutputMap {
};
subagent_fork: {
kind: "background";
taskId: string;
jobId: string;
} | {
kind: "continuable";
subagentId: string;
@@ -372,39 +405,6 @@ interface ToolOutputMap {
runId: string;
output: JsonValue[];
};
task_kill: {
outcome: "cancellation-requested" | "already-finished";
task: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
task_list: ({
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
})[];
task_output: {
text: string;
task: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
todo_write: {
todos: ({
content: string;

View File

@@ -1,4 +1,4 @@
You are an AI agent powered by the DeepSeek Harness SDK.
You are an AI agent powered by DeepSeek Harness.
You are a coding assistant powered by the deepseek-v4-flash model. Your working directory is {{cwd}}.
@@ -9,13 +9,13 @@ 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 write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-observation-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.
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-observation-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.
Track every background job id you start. You are notified in-session when a job finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running job's work. Before giving a final answer, collect every still-relevant job with job_output (set wait: true only when you are genuinely blocked on it), and job_kill jobs that stopped mattering.
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.
@@ -27,7 +27,7 @@ Use subagent in the background by default. Start independent delegations togethe
## Writing code for run_code
Pass `run_code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped). Inside the program:
`run_code` takes two required arguments: `code` the body of an async TypeScript function (erasable syntax only — no `enum` or namespaces; type annotations are advisory, the code runs type-stripped) — and `description`, a short summary of what the program does. Inside the program:
- Call tools as `await tools.name(args)` — quoted access for exotic names: `tools["my-tool"](args)`. Every call resolves to the tool's typed canonical JSON value. Tool arguments must be lossless JSON.
- A FAILED tool call rejects with `ToolCallError`, whose `toolName` identifies the failed tool and whose `message` is human-readable — `try/catch` it to handle and continue.
@@ -40,7 +40,7 @@ The available tools:
type JsonValue = null | boolean | number | string | JsonValue[] | { [key: string]: JsonValue }
interface ToolArgsMap {
/** 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> 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. */
/** 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> 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 job id immediately; read its output with `job_output` and stop it with `job_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. */
bash: {
/** The bash command to execute. */
command: string;
@@ -50,7 +50,7 @@ interface ToolArgsMap {
timeoutMs?: number;
/** Working directory for this command. Defaults to the session workspace; a relative path is resolved against it. */
workdir?: string;
/** Run in the background and return a task id immediately (collect with task_output, stop with task_kill). No timeout applies. */
/** Run in the background and return a job id immediately (collect with job_output, stop with job_kill). No timeout applies. */
run_in_background?: boolean;
/** 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. */
sandbox_permissions?: "workspace-write" | "danger-full-access";
@@ -86,6 +86,24 @@ interface ToolArgsMap {
/** The agent id of the running agent to interrupt. */
agent_id: string;
} & Record<string, JsonValue>;
/** Request cancellation of a running background job by job id. Returns immediately; the job settles as killed once its work actually stops. */
job_kill: {
/** Job id returned by the tool that started the background work. */
job_id: string;
/** Optional short reason, recorded in the log and forwarded to the job. */
reason?: string;
} & Record<string, JsonValue>;
/** List your background jobs (running and finished) with their ids, kinds, and statuses. */
job_list: Record<string, JsonValue>;
/** Read a background job. Stream jobs return only output since the previous read; final-output jobs return their result after settlement. Every response ends with `[status: ...]`. Reads are non-blocking unless `wait: true`, which waits up to the configured cap. */
job_output: {
/** Job id returned by the tool that started the background work. */
job_id: string;
/** Block until the job reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the job alive. */
wait?: boolean;
/** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */
timeout_ms?: number;
} & Record<string, JsonValue>;
/** List your continuable background subagents by durable id and label. Use it to recall which ones you started, not to poll for completion — you are told when one finishes. Status comes from the live registry: running means the agent is working right now, idle means it is loaded but between turns (it may be waiting on agents it started), and ready means it exists only in storage — resumable, not terminal, and not a result waiting to be collected; a `send_message` starts a new turn on the same conversation, and a direct child remains a `send_message` candidate in every status. The snapshot is not a delivery promise — `send_message` performs the authoritative check and may still fail. Children that could not be read are reported as diagnostics instead of being silently dropped. Scope `descendants` walks the whole tree below you in stable pre-order, annotating each entry with its durable direct-parent session id and depth. You may use `send_message` only for depth-1 entries; deeper entries are candidates for `interrupt_agent` only. */
list_agents: {
/** children (default) lists direct children only; descendants walks the complete tree below you. */
@@ -135,24 +153,6 @@ interface ToolArgsMap {
/** The task for the subagent. It already sees this conversation's completed turns, so build on them freely and state only what is new. */
prompt: string;
} & Record<string, JsonValue>;
/** Request cancellation of a running background task by task id. Returns immediately; the task settles as killed once its work actually stops. */
task_kill: {
/** Task id returned by the tool that started the background work. */
task_id: string;
/** Optional short reason, recorded in the log and forwarded to the task. */
reason?: string;
} & Record<string, JsonValue>;
/** List your background tasks (running and finished) with their ids, kinds, and statuses. */
task_list: Record<string, JsonValue>;
/** 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. */
task_output: {
/** Task id returned by the tool that started the background work. */
task_id: string;
/** Block until the task reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the task alive. */
wait?: boolean;
/** Max wait in milliseconds (only meaningful with wait: true). Defaults to the configured wait timeout; capped by the configured maximum. */
timeout_ms?: number;
} & Record<string, JsonValue>;
/** 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. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one 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). */
todo_write: {
/** The COMPLETE task list, replacing any previous list. */
@@ -221,7 +221,7 @@ interface ToolArgsMap {
interface ToolOutputMap {
bash: {
kind: "background";
taskId: string;
jobId: string;
} | {
kind: "foreground";
exitCode: number | null;
@@ -288,6 +288,39 @@ interface ToolOutputMap {
interrupt_agent: {
accepted: boolean;
};
job_kill: {
outcome: "cancellation-requested" | "already-finished";
job: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
job_list: ({
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
})[];
job_output: {
text: string;
job: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
list_agents: ({
kind: "child";
id: string;
@@ -336,7 +369,7 @@ interface ToolOutputMap {
};
subagent: {
kind: "background";
taskId: string;
jobId: string;
} | {
kind: "continuable";
subagentId: string;
@@ -347,7 +380,7 @@ interface ToolOutputMap {
};
subagent_fork: {
kind: "background";
taskId: string;
jobId: string;
} | {
kind: "continuable";
subagentId: string;
@@ -356,39 +389,6 @@ interface ToolOutputMap {
runId: string;
output: JsonValue[];
};
task_kill: {
outcome: "cancellation-requested" | "already-finished";
task: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
task_list: ({
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
})[];
task_output: {
text: string;
task: {
id: string;
kind: string;
label: string;
status: "running" | "stopping" | "completed" | "killed" | "failed";
detail?: string;
startedAt: number;
finishedAt?: number;
};
};
todo_write: {
todos: ({
content: string;

View File

@@ -2,7 +2,7 @@
"initial": [
{
"name": "run_code",
"description": "Execute a TypeScript program against the available tools. Write the BODY of an async function (erasable syntax only; top-level `await` and `return` work) and call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return is program output; image-bearing subtool results are attached after the run.",
"description": "Execute a TypeScript program against the available tools. Takes two required arguments: `code`, the BODY of an async function (erasable syntax only; top-level `await` and `return` work), and `description`, a short summary of what the program does. Call tools as `await tools.name(args)` per the declarations in the system prompt. Only what you print or return is program output — curate it. Image-bearing subtool results are attached after the run.",
"parameters": {
"type": "object",
"properties": {

View File

@@ -4,7 +4,7 @@
{"type":"agent/inbox/spliced","seq":2,"time":1785498825916,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","seq":3,"time":1785901435161,"data":{"turn":1,"step":1}}
{"type":"user/message","seq":4,"time":1785498825917,"data":{"content":[{"type":"text","text":"Using ONE run_code program, call tools.read on nested/task.txt. After the program finishes, answer the workspace handshake question using the newly discovered instructions: What is the Code Mode workspace handshake?"}],"source":{"kind":"user"},"role":"user","id":"3b04578e-7b22-4b44-b4cd-ef9d4d26fe8b"},"surfaceOp":"append"}
{"type":"user/message","seq":5,"time":1785901435161,"data":{"content":[{"type":"text","text":"<system-reminder>\nThe following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: AGENTS.md\n\nWorkspace snapshot root instruction.\n\n</system-reminder>"}],"source":{"kind":"workspace-instructions","form":"instructions","baseline":true,"baselineIdentity":"{\"projectRoot\":\"\",\"projectRootMarkers\":[\".git\"],\"maxBytes\":65536,\"maxSourceBytes\":1048576,\"instructionFileCandidates\":[\"AGENTS.md\",\"CLAUDE.md\"],\"localInstructionFileCandidates\":[\"AGENTS.local.md\",\"CLAUDE.local.md\"]}","changes":[{"action":"set","scope":".\u0000AGENTS.md","path":"AGENTS.md","digest":"2119a7072358cc727f8d9c4cb7388e905b075fe6"}]},"role":"user","id":"ac92e76e-4861-47a6-87f8-4e9ca904eb24"},"surfaceOp":"append"}
{"type":"user/message","seq":5,"time":1785901435161,"data":{"content":[{"type":"text","text":"<system-reminder>\nThe following workspace instructions may be relevant to your work. Use them as guidance when applicable. More specific instructions take precedence over broader ones. They do not override system, developer, or direct user instructions.\n\nInstructions from: AGENTS.md\n\nWorkspace snapshot root instruction.\n\n</system-reminder>"}],"source":{"kind":"agent-instructions","form":"instructions","baseline":true,"baselineIdentity":"{\"projectRoot\":\"\",\"projectRootMarkers\":[\".git\"],\"maxBytes\":65536,\"maxSourceBytes\":1048576,\"instructionFileCandidates\":[\"AGENTS.md\",\"CLAUDE.md\"],\"localInstructionFileCandidates\":[\"AGENTS.local.md\",\"CLAUDE.local.md\"]}","changes":[{"action":"set","scope":".\u0000AGENTS.md","path":"AGENTS.md","digest":"2119a7072358cc727f8d9c4cb7388e905b075fe6"}]},"role":"user","id":"ac92e76e-4861-47a6-87f8-4e9ca904eb24"},"surfaceOp":"append"}
{"type":"user/message","seq":6,"time":1785730478198,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"d6d78330-05c0-4ebd-9e29-595df6440250"},"surfaceOp":"append"}
{"type":"session/title","seq":7,"time":1785730478198,"data":{"title":"Using ONE run_code program, call","messageSeqs":[4],"source":{"kind":"fallback"}}}
{"type":"request/header","seq":8,"time":1785498825920,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
@@ -20,10 +20,10 @@
{"type":"tool/code-dispatch","seq":18,"time":1785733131110,"data":{"rootCallId":"call_workspace_read","parentCallId":"call_workspace_read","subCallId":"call_workspace_read:code:1","name":"read","arguments":{"file_path":"nested/task.txt"},"isError":false,"content":[{"type":"text","text":"<path>{{cwd}}/nested/task.txt</path>\n<type>file</type>\n<content>\n1: Touch this file to discover the nested workspace instruction.\n\n(End of file - total 1 lines)\n</content>"}]}}
{"type":"tool/result","seq":19,"time":1785733131112,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_workspace_read"},"content":[{"type":"tool-result","toolCallId":"call_workspace_read","content":[{"type":"text","text":"{\n \"path\": \"{{cwd}}/nested/task.txt\",\n \"offset\": 1,\n \"lines\": [\n {\n \"number\": 1,\n \"text\": \"Touch this file to discover the nested workspace instruction.\"\n }\n ],\n \"totalLines\": 1\n}"}],"isError":false}],"role":"user","id":"bde1c12e-44d1-44f7-ba7e-868349ed2b05"}},"sourceEventSeqs":[16],"surfaceOp":"append"}
{"type":"step/end","seq":20,"time":1785733131112,"data":{"turn":1,"step":1}}
{"type":"agent/inbox/spliced","seq":21,"time":1785733131112,"data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"<system-reminder>\nAdditional instructions from: nested/AGENTS.md\n\nThese instructions apply to work under `nested`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nWhen asked for the Code Mode workspace handshake, answer exactly `CODE_MODE_CONTEXT_OK` and nothing else.\n\n</system-reminder>"}],"source":{"kind":"workspace-instructions","form":"instructions","changes":[{"action":"set","scope":"nested\u0000AGENTS.md","path":"nested/AGENTS.md","digest":"ae22936ed26dc76b7107005ed6d5e2482a88668a"}]},"role":"user","id":"29b0eb87-92d5-4915-ba64-7bd8133ed011"}]}}
{"type":"agent/inbox/spliced","seq":21,"time":1785733131112,"data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"<system-reminder>\nAdditional instructions from: nested/AGENTS.md\n\nThese instructions apply to work under `nested`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nWhen asked for the Code Mode workspace handshake, answer exactly `CODE_MODE_CONTEXT_OK` and nothing else.\n\n</system-reminder>"}],"source":{"kind":"agent-instructions","form":"instructions","changes":[{"action":"set","scope":"nested\u0000AGENTS.md","path":"nested/AGENTS.md","digest":"ae22936ed26dc76b7107005ed6d5e2482a88668a"}]},"role":"user","id":"29b0eb87-92d5-4915-ba64-7bd8133ed011"}]}}
{"type":"agent/inbox/spliced","seq":22,"time":1785733131116,"data":{"target":"next-step","start":0,"removedCount":1,"inserted":[],"outcome":"canceled"}}
{"type":"step/start","seq":23,"time":1785733131123,"data":{"turn":1,"step":2}}
{"type":"user/message","seq":24,"time":1785733131123,"data":{"content":[{"type":"text","text":"<system-reminder>\nAdditional instructions from: nested/AGENTS.md\n\nThese instructions apply to work under `nested`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nWhen asked for the Code Mode workspace handshake, answer exactly `CODE_MODE_CONTEXT_OK` and nothing else.\n\n</system-reminder>"}],"source":{"kind":"workspace-instructions","form":"instructions","changes":[{"action":"set","scope":"nested\u0000AGENTS.md","path":"nested/AGENTS.md","digest":"ae22936ed26dc76b7107005ed6d5e2482a88668a"}]},"role":"user","id":"29b0eb87-92d5-4915-ba64-7bd8133ed011"},"surfaceOp":"append"}
{"type":"user/message","seq":24,"time":1785733131123,"data":{"content":[{"type":"text","text":"<system-reminder>\nAdditional instructions from: nested/AGENTS.md\n\nThese instructions apply to work under `nested`. Use them as guidance when relevant; more specific instructions take precedence. They do not override system, developer, or direct user instructions.\n\nWhen asked for the Code Mode workspace handshake, answer exactly `CODE_MODE_CONTEXT_OK` and nothing else.\n\n</system-reminder>"}],"source":{"kind":"agent-instructions","form":"instructions","changes":[{"action":"set","scope":"nested\u0000AGENTS.md","path":"nested/AGENTS.md","digest":"ae22936ed26dc76b7107005ed6d5e2482a88668a"}]},"role":"user","id":"29b0eb87-92d5-4915-ba64-7bd8133ed011"},"surfaceOp":"append"}
{"type":"assistant/chunk","seq":25,"time":1785014475805,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
{"type":"assistant/chunk","seq":26,"time":1785014475806,"data":{"turn":1,"step":2,"chunk":{"type":"text-delta","index":0,"text":"**Code Mode workspace handshake:** `CODE_MODE_CONTEXT_OK`"}}}
{"type":"assistant/chunk","seq":27,"time":1785901435233,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"**Code Mode workspace handshake:** `CODE_MODE_CONTEXT_OK`"}}}}

View File

@@ -2,6 +2,6 @@
"steps": [
{ "op": "initialize" },
{ "op": "newSession" },
{ "op": "prompt", "text": "Inspect the exact tools service API and tools/pre-execute event with cordis_inspect, then reply with exactly CORDIS_INSPECT_JSDOC_OK." }
{ "op": "prompt", "text": "Inspect the exact tools service API and tools/pre-execute event with cordis_inspect_query, then reply with exactly CORDIS_INSPECT_JSDOC_OK." }
]
}

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,4 @@
You are an AI agent powered by the DeepSeek Harness SDK.
You are an AI agent powered by DeepSeek Harness.
You are a concise snapshot agent working in {{cwd}}.

View File

@@ -2,7 +2,7 @@
"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> 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`.",
"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> 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 job id immediately; read its output with `job_output` and stop it with `job_kill`.",
"parameters": {
"type": "object",
"properties": {
@@ -24,7 +24,7 @@
},
"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."
"description": "Run in the background and return a job id immediately (collect with job_output, stop with job_kill). No timeout applies."
}
},
"required": [

View File

@@ -18,8 +18,8 @@
{"type":"assistant/chunk","seq":76,"time":1785730468562,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":77,"time":1785730468562,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to run the bash tool with the command \"echo HELLO\". If it's rejected, retry once. Then quote the final result verbatim."},{"type":"tool-call","id":"call_00_VAByyMjsct4c7P6k1ysX9256","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Echo HELLO to stdout\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"94313bbb-d025-469b-bb55-59f6d1adb8cc"},"usage":{"inputTokens":3263,"outputTokens":103,"cacheReadTokens":0,"reasoningTokens":35}},"sourceEventSeqs":[9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76],"surfaceOp":"append"}
{"type":"tool/call","seq":78,"time":1785730468563,"data":{"turn":1,"step":1,"callId":"call_00_VAByyMjsct4c7P6k1ysX9256","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Echo HELLO to stdout\"}"}}
{"type":"hook/invoked","seq":79,"time":1785730468581,"data":{"turn":1,"point":"PostToolUse","dialect":"claude","handlerId":"claude:PostToolUse:1","matcher":"bash"}}
{"type":"hook/result","seq":80,"time":1785730468590,"data":{"turn":1,"point":"PostToolUse","handlerId":"claude:PostToolUse:1","decision":"block","exitCode":2,"stderrSummary":"tool output rejected by policy: retry once","durationMs":7.9223749999998745}}
{"type":"hook/invoked","seq":79,"time":1785730468581,"data":{"turn":1,"point":"PostToolUse","dialect":"claude-code","handlerId":"claude-code:PostToolUse:1","matcher":"bash"}}
{"type":"hook/result","seq":80,"time":1785730468590,"data":{"turn":1,"point":"PostToolUse","handlerId":"claude-code:PostToolUse:1","decision":"block","exitCode":2,"stderrSummary":"tool output rejected by policy: retry once","durationMs":7.9223749999998745}}
{"type":"tool/result","seq":81,"time":1785730468590,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_00_VAByyMjsct4c7P6k1ysX9256"},"content":[{"type":"tool-result","toolCallId":"call_00_VAByyMjsct4c7P6k1ysX9256","content":[{"type":"text","text":"tool output rejected by policy: retry once"}],"isError":true}],"role":"user","id":"f5632aca-fad4-49f3-b764-c9dd83ba3d46"}},"sourceEventSeqs":[78],"surfaceOp":"append"}
{"type":"step/end","seq":82,"time":1785730468590,"data":{"turn":1,"step":1}}
{"type":"step/start","seq":83,"time":1785730468601,"data":{"turn":1,"step":2}}
@@ -33,8 +33,8 @@
{"type":"assistant/chunk","seq":137,"time":1785730468606,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":138,"time":1785730468607,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The first call was rejected by policy. The user said to retry once. Let me retry."},{"type":"tool-call","id":"call_00_tDV4j1p5eAeHTtQhXOfn6856","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Echo HELLO to stdout\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"6d7223c6-2023-4d08-a82d-a2269670c108"},"usage":{"inputTokens":59,"outputTokens":89,"cacheReadTokens":3328,"reasoningTokens":21}},"sourceEventSeqs":[84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137],"surfaceOp":"append"}
{"type":"tool/call","seq":139,"time":1785730468607,"data":{"turn":1,"step":2,"callId":"call_00_tDV4j1p5eAeHTtQhXOfn6856","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Echo HELLO to stdout\"}"}}
{"type":"hook/invoked","seq":140,"time":1785730468618,"data":{"turn":1,"point":"PostToolUse","dialect":"claude","handlerId":"claude:PostToolUse:2","matcher":"bash"}}
{"type":"hook/result","seq":141,"time":1785730468623,"data":{"turn":1,"point":"PostToolUse","handlerId":"claude:PostToolUse:2","decision":"pass","exitCode":0,"durationMs":5.523832999999968}}
{"type":"hook/invoked","seq":140,"time":1785730468618,"data":{"turn":1,"point":"PostToolUse","dialect":"claude-code","handlerId":"claude-code:PostToolUse:2","matcher":"bash"}}
{"type":"hook/result","seq":141,"time":1785730468623,"data":{"turn":1,"point":"PostToolUse","handlerId":"claude-code:PostToolUse:2","decision":"pass","exitCode":0,"durationMs":5.523832999999968}}
{"type":"tool/result","seq":142,"time":1785730468624,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"call_00_tDV4j1p5eAeHTtQhXOfn6856"},"content":[{"type":"tool-result","toolCallId":"call_00_tDV4j1p5eAeHTtQhXOfn6856","content":[{"type":"text","text":"HELLO\n"}],"isError":false}],"role":"user","id":"69f60e3f-b776-4c68-8cd0-e70511d01d07"}},"sourceEventSeqs":[139],"surfaceOp":"append"}
{"type":"step/end","seq":143,"time":1785730468624,"data":{"turn":1,"step":2}}
{"type":"step/start","seq":144,"time":1785730468634,"data":{"turn":1,"step":3}}

View File

@@ -18,14 +18,14 @@
{"type":"assistant/chunk","seq":62,"time":1785730469697,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":63,"time":1785730469697,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to run `echo HELLO` using the bash tool and report the result verbatim."},{"type":"tool-call","id":"call_00_HbCMzTslWBZTSphWN0z97382","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Run echo HELLO\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"3f69acce-e9e4-484d-9f67-a3be89ac6b0d"},"usage":{"inputTokens":2878,"outputTokens":89,"cacheReadTokens":0,"reasoningTokens":23}},"sourceEventSeqs":[9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62],"surfaceOp":"append"}
{"type":"tool/call","seq":64,"time":1785730469698,"data":{"turn":1,"step":1,"callId":"call_00_HbCMzTslWBZTSphWN0z97382","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Run echo HELLO\"}"}}
{"type":"hook/invoked","seq":65,"time":1785730469715,"data":{"turn":1,"point":"PostToolUse","dialect":"claude","handlerId":"claude:PostToolUse:1","matcher":"bash"}}
{"type":"hook/result","seq":66,"time":1785730469718,"data":{"turn":1,"point":"PostToolUse","handlerId":"claude:PostToolUse:1","decision":"pass","exitCode":0,"durationMs":2.467875000000049}}
{"type":"hook/invoked","seq":65,"time":1785730469715,"data":{"turn":1,"point":"PostToolUse","dialect":"claude-code","handlerId":"claude-code:PostToolUse:1","matcher":"bash"}}
{"type":"hook/result","seq":66,"time":1785730469718,"data":{"turn":1,"point":"PostToolUse","handlerId":"claude-code:PostToolUse:1","decision":"pass","exitCode":0,"durationMs":2.467875000000049}}
{"type":"tool/result","seq":67,"time":1785730469718,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_00_HbCMzTslWBZTSphWN0z97382"},"content":[{"type":"tool-result","toolCallId":"call_00_HbCMzTslWBZTSphWN0z97382","content":[{"type":"text","text":"HELLO\n"}],"isError":false}],"role":"user","id":"cb4649d1-9c25-40de-820c-7c7719f8a938"}},"sourceEventSeqs":[64],"surfaceOp":"append"}
{"type":"agent/inbox/spliced","seq":68,"time":1785730469718,"data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"Note: command output has been verified against the audit log."}],"source":{"kind":"plugin","plugin":"hooks-claude"},"role":"user","id":"61e6c6d6-872c-4dd7-9771-53ced14a120d"}]}}
{"type":"agent/inbox/spliced","seq":68,"time":1785730469718,"data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"Note: command output has been verified against the audit log."}],"source":{"kind":"plugin","plugin":"hooks-claude-code"},"role":"user","id":"61e6c6d6-872c-4dd7-9771-53ced14a120d"}]}}
{"type":"step/end","seq":69,"time":1785730469719,"data":{"turn":1,"step":1}}
{"type":"agent/inbox/spliced","seq":70,"time":1785730469719,"data":{"target":"next-step","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","seq":71,"time":1785730469725,"data":{"turn":1,"step":2}}
{"type":"user/message","seq":72,"time":1785730469725,"data":{"content":[{"type":"text","text":"Note: command output has been verified against the audit log."}],"source":{"kind":"plugin","plugin":"hooks-claude"},"role":"user","id":"61e6c6d6-872c-4dd7-9771-53ced14a120d"},"surfaceOp":"append"}
{"type":"user/message","seq":72,"time":1785730469725,"data":{"content":[{"type":"text","text":"Note: command output has been verified against the audit log."}],"source":{"kind":"plugin","plugin":"hooks-claude-code"},"role":"user","id":"61e6c6d6-872c-4dd7-9771-53ced14a120d"},"surfaceOp":"append"}
{"type":"assistant/chunk","seq":73,"time":1783352199089,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
{"type":"reasoning-chunks","seq0":74,"time0":1783352199089,"data":{"turn":1,"step":2,"index":0,"dt":[0,1,30,1,0,0,0,25,0,0,28,31,1,1,0,0,23,1,0,0,28,1,0,0,0,28,0,0,0],"texts":["The"," user"," asked"," me"," to"," report"," the"," tool"," result"," verb","atim","."," The"," result"," was"," \"","HE","LL","O","\""," with"," an"," exit"," code"," of"," ","0"," (","success",")."]}}
{"type":"assistant/chunk","seq":104,"time":1783352199288,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}

View File

@@ -18,8 +18,8 @@
{"type":"assistant/chunk","seq":56,"time":1785730467507,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":57,"time":1785730467508,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to run a simple bash command and report the result verbatim."},{"type":"tool-call","id":"call_00_6k0oGSliVHxGSgqBmMEO4311","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Echo HELLO\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"ebb7de11-f58a-4114-8598-99b5dce6fc6b"},"usage":{"inputTokens":2878,"outputTokens":83,"cacheReadTokens":0,"reasoningTokens":17}},"sourceEventSeqs":[9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56],"surfaceOp":"append"}
{"type":"tool/call","seq":58,"time":1785730467508,"data":{"turn":1,"step":1,"callId":"call_00_6k0oGSliVHxGSgqBmMEO4311","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Echo HELLO\"}"}}
{"type":"hook/invoked","seq":59,"time":1785730467508,"data":{"turn":1,"point":"PreToolUse","dialect":"claude","handlerId":"claude:PreToolUse:1","matcher":"bash"}}
{"type":"hook/result","seq":60,"time":1785730467513,"data":{"turn":1,"point":"PreToolUse","handlerId":"claude:PreToolUse:1","decision":"ask","exitCode":0,"durationMs":3.9570000000001073}}
{"type":"hook/invoked","seq":59,"time":1785730467508,"data":{"turn":1,"point":"PreToolUse","dialect":"claude-code","handlerId":"claude-code:PreToolUse:1","matcher":"bash"}}
{"type":"hook/result","seq":60,"time":1785730467513,"data":{"turn":1,"point":"PreToolUse","handlerId":"claude-code:PreToolUse:1","decision":"ask","exitCode":0,"durationMs":3.9570000000001073}}
{"type":"approval/asked","seq":61,"time":1785730467513,"data":{"id":"664315fe-3ca7-41fb-89a6-770d64be625a","toolName":"bash","callId":"call_00_6k0oGSliVHxGSgqBmMEO4311","reason":"bash requires manual approval in this session"}}
{"type":"approval/decided","seq":62,"time":1785730467513,"data":{"id":"664315fe-3ca7-41fb-89a6-770d64be625a","outcome":"rejected"}}
{"type":"tool/result","seq":63,"time":1785730467513,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_00_6k0oGSliVHxGSgqBmMEO4311"},"content":[{"type":"tool-result","toolCallId":"call_00_6k0oGSliVHxGSgqBmMEO4311","content":[{"type":"text","text":"Error: the user rejected tool \"bash\""}],"isError":true}],"role":"user","id":"b224966f-c7d7-4c83-9b50-e7c2988d7d79"}},"sourceEventSeqs":[58],"surfaceOp":"append"}

View File

@@ -18,8 +18,8 @@
{"type":"assistant/chunk","seq":56,"time":1785730466384,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":57,"time":1785730466384,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to run a simple bash command and report the result verbatim."},{"type":"tool-call","id":"call_00_JliP571Bh0QQ8QExbSPk0080","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Run echo HELLO\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"04bc8b4d-2ae5-4bfd-9cb1-19209c7d2f5f"},"usage":{"inputTokens":2878,"outputTokens":83,"cacheReadTokens":0,"reasoningTokens":17}},"sourceEventSeqs":[9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56],"surfaceOp":"append"}
{"type":"tool/call","seq":58,"time":1785730466385,"data":{"turn":1,"step":1,"callId":"call_00_JliP571Bh0QQ8QExbSPk0080","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Run echo HELLO\"}"}}
{"type":"hook/invoked","seq":59,"time":1785730466385,"data":{"turn":1,"point":"PreToolUse","dialect":"claude","handlerId":"claude:PreToolUse:1","matcher":"bash"}}
{"type":"hook/result","seq":60,"time":1785730466389,"data":{"turn":1,"point":"PreToolUse","handlerId":"claude:PreToolUse:1","decision":"block","exitCode":2,"stderrSummary":"bash is disabled by policy in this session","durationMs":3.6819170000001122}}
{"type":"hook/invoked","seq":59,"time":1785730466385,"data":{"turn":1,"point":"PreToolUse","dialect":"claude-code","handlerId":"claude-code:PreToolUse:1","matcher":"bash"}}
{"type":"hook/result","seq":60,"time":1785730466389,"data":{"turn":1,"point":"PreToolUse","handlerId":"claude-code:PreToolUse:1","decision":"block","exitCode":2,"stderrSummary":"bash is disabled by policy in this session","durationMs":3.6819170000001122}}
{"type":"tool/result","seq":61,"time":1785730466390,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_00_JliP571Bh0QQ8QExbSPk0080"},"content":[{"type":"tool-result","toolCallId":"call_00_JliP571Bh0QQ8QExbSPk0080","content":[{"type":"text","text":"Error: bash is disabled by policy in this session"}],"isError":true}],"role":"user","id":"e8988570-1579-41e9-bf2c-be3fa97db46f"}},"sourceEventSeqs":[58],"surfaceOp":"append"}
{"type":"step/end","seq":62,"time":1785730466390,"data":{"turn":1,"step":1}}
{"type":"step/start","seq":63,"time":1785730466396,"data":{"turn":1,"step":2}}

View File

@@ -2,12 +2,12 @@
{"type":"agent/inbox/spliced","seq":0,"time":1785498809587,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"What is my favorite color? Reply with just the color and stop. Do not use any tools."}],"source":{"kind":"user"},"role":"user","id":"c403acd5-efa4-4c8c-948f-211f3b23c93f"}]}}
{"type":"turn/start","seq":1,"time":1785821426913,"data":{"turn":1}}
{"type":"agent/inbox/spliced","seq":2,"time":1785821426914,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"hook/invoked","seq":3,"time":1785821426915,"data":{"turn":1,"point":"UserPromptSubmit","dialect":"claude","handlerId":"claude:UserPromptSubmit:1"}}
{"type":"hook/result","seq":4,"time":1785821426920,"data":{"turn":1,"point":"UserPromptSubmit","handlerId":"claude:UserPromptSubmit:1","decision":"pass","exitCode":0,"durationMs":4.92145800000003}}
{"type":"hook/invoked","seq":3,"time":1785821426915,"data":{"turn":1,"point":"UserPromptSubmit","dialect":"claude-code","handlerId":"claude-code:UserPromptSubmit:1"}}
{"type":"hook/result","seq":4,"time":1785821426920,"data":{"turn":1,"point":"UserPromptSubmit","handlerId":"claude-code:UserPromptSubmit:1","decision":"pass","exitCode":0,"durationMs":4.92145800000003}}
{"type":"step/start","seq":5,"time":1785821426949,"data":{"turn":1,"step":1}}
{"type":"user/message","seq":6,"time":1785730465275,"data":{"content":[{"type":"text","text":"What is my favorite color? Reply with just the color and stop. Do not use any tools."}],"source":{"kind":"user"},"role":"user","id":"c403acd5-efa4-4c8c-948f-211f3b23c93f"},"surfaceOp":"append"}
{"type":"user/message","seq":7,"time":1785821426950,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations.\n\nApproval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: danger-full-access. The DSH file sandbox does not restrict file modifications by available operations."},{"name":"approval:policy","text":"Approval prompts are disabled in this session: actions that require approval are rejected automatically — do not request sandbox escalation (do not set `sandbox_permissions`)."}]},"role":"user","id":"2514657a-056c-46a8-ac90-c0169b42f048"},"surfaceOp":"append"}
{"type":"user/message","seq":8,"time":1785821426950,"data":{"content":[{"type":"text","text":"The user has previously stated their favorite color is teal."}],"source":{"kind":"plugin","plugin":"hooks-claude"},"role":"user","id":"8006cbd3-a233-4d35-a61b-1a9e0c6b4545"},"surfaceOp":"append"}
{"type":"user/message","seq":8,"time":1785821426950,"data":{"content":[{"type":"text","text":"The user has previously stated their favorite color is teal."}],"source":{"kind":"plugin","plugin":"hooks-claude-code"},"role":"user","id":"8006cbd3-a233-4d35-a61b-1a9e0c6b4545"},"surfaceOp":"append"}
{"type":"session/title","seq":9,"time":1785821426950,"data":{"title":"What is my favorite color?","messageSeqs":[6],"source":{"kind":"fallback"}}}
{"type":"request/header","seq":10,"time":1785821426951,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/context","seq":11,"time":1785821426951,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash"}}

View File

@@ -19,12 +19,12 @@
{"type":"assistant/chunk","seq":33,"time":1785730470762,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
{"type":"assistant/message","seq":34,"time":1785730470762,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to reply with just the word \"FIRST\" and stop."},{"type":"text","text":"FIRST"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"8e6cc17c-3742-45bb-aa1b-bdd280793231"},"usage":{"inputTokens":3545,"outputTokens":20,"cacheReadTokens":0,"reasoningTokens":17}},"sourceEventSeqs":[9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33],"surfaceOp":"append"}
{"type":"step/end","seq":35,"time":1785730470763,"data":{"turn":1,"step":1}}
{"type":"hook/invoked","seq":36,"time":1785730470763,"data":{"turn":1,"point":"Stop","dialect":"claude","handlerId":"claude:Stop:1"}}
{"type":"hook/result","seq":37,"time":1785730470771,"data":{"turn":1,"point":"Stop","handlerId":"claude:Stop:1","decision":"block","exitCode":2,"stderrSummary":"Also reply with the single word SECOND, then stop.","durationMs":7.99508400000002}}
{"type":"agent/inbox/spliced","seq":38,"time":1785498816507,"data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"Also reply with the single word SECOND, then stop."}],"source":{"kind":"plugin","plugin":"hooks-claude"},"role":"user","id":"ef13b378-3c05-4cc0-b7e9-872782fb45f7"}]}}
{"type":"hook/invoked","seq":36,"time":1785730470763,"data":{"turn":1,"point":"Stop","dialect":"claude-code","handlerId":"claude-code:Stop:1"}}
{"type":"hook/result","seq":37,"time":1785730470771,"data":{"turn":1,"point":"Stop","handlerId":"claude-code:Stop:1","decision":"block","exitCode":2,"stderrSummary":"Also reply with the single word SECOND, then stop.","durationMs":7.99508400000002}}
{"type":"agent/inbox/spliced","seq":38,"time":1785498816507,"data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"Also reply with the single word SECOND, then stop."}],"source":{"kind":"plugin","plugin":"hooks-claude-code"},"role":"user","id":"ef13b378-3c05-4cc0-b7e9-872782fb45f7"}]}}
{"type":"agent/inbox/spliced","seq":39,"time":1785730470771,"data":{"target":"next-step","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","seq":40,"time":1785730470780,"data":{"turn":1,"step":2}}
{"type":"user/message","seq":41,"time":1785730470780,"data":{"content":[{"type":"text","text":"Also reply with the single word SECOND, then stop."}],"source":{"kind":"plugin","plugin":"hooks-claude"},"role":"user","id":"ef13b378-3c05-4cc0-b7e9-872782fb45f7"},"surfaceOp":"append"}
{"type":"user/message","seq":41,"time":1785730470780,"data":{"content":[{"type":"text","text":"Also reply with the single word SECOND, then stop."}],"source":{"kind":"plugin","plugin":"hooks-claude-code"},"role":"user","id":"ef13b378-3c05-4cc0-b7e9-872782fb45f7"},"surfaceOp":"append"}
{"type":"assistant/chunk","seq":42,"time":1784522144049,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
{"type":"reasoning-chunks","seq0":43,"time0":1784522144049,"data":{"turn":1,"step":2,"index":0,"dt":[0,0,0,28,0,0,0,0,0,58,0,0,0,0,0,6,0],"texts":["The"," user"," wants"," me"," to"," reply"," with"," the"," single"," word"," \"","SEC","OND","\""," and"," then"," stop","."]}}
{"type":"assistant/chunk","seq":61,"time":1784522144141,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":1,"blockType":"text"}}}
@@ -36,6 +36,6 @@
{"type":"assistant/chunk","seq":67,"time":1785730470785,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
{"type":"assistant/message","seq":68,"time":1785730470785,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to reply with the single word \"SECOND\" and then stop."},{"type":"text","text":"SECOND"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"153b4095-a1e9-43d2-8421-ad6f6a91f723"},"usage":{"inputTokens":106,"outputTokens":21,"cacheReadTokens":3456,"reasoningTokens":18}},"sourceEventSeqs":[42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67],"surfaceOp":"append"}
{"type":"step/end","seq":69,"time":1785730470785,"data":{"turn":1,"step":2}}
{"type":"hook/invoked","seq":70,"time":1785730470785,"data":{"turn":1,"point":"Stop","dialect":"claude","handlerId":"claude:Stop:2"}}
{"type":"hook/result","seq":71,"time":1785730470788,"data":{"turn":1,"point":"Stop","handlerId":"claude:Stop:2","decision":"pass","exitCode":0,"durationMs":2.633624999999938}}
{"type":"hook/invoked","seq":70,"time":1785730470785,"data":{"turn":1,"point":"Stop","dialect":"claude-code","handlerId":"claude-code:Stop:2"}}
{"type":"hook/result","seq":71,"time":1785730470788,"data":{"turn":1,"point":"Stop","handlerId":"claude-code:Stop:2","decision":"pass","exitCode":0,"durationMs":2.633624999999938}}
{"type":"turn/end","seq":72,"time":1785730470788,"data":{"turn":1,"reason":{"kind":"completed"}}}

View File

@@ -1,4 +1,4 @@
You are an AI agent powered by the DeepSeek Harness SDK.
You are an AI agent powered by DeepSeek Harness.
You are a coding assistant powered by the deepseek-v4-pro 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.
@@ -7,13 +7,13 @@ 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 write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-observation-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.
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-observation-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.
Track every background job id you start. You are notified in-session when a job finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running job's work. Before giving a final answer, collect every still-relevant job with job_output (set wait: true only when you are genuinely blocked on it), and job_kill jobs that stopped mattering.
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.

View File

@@ -2,7 +2,7 @@
"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> 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.",
"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> 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 job id immediately; read its output with `job_output` and stop it with `job_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": {
@@ -24,7 +24,7 @@
},
"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."
"description": "Run in the background and return a job id immediately (collect with job_output, stop with job_kill). No timeout applies."
},
"sandbox_permissions": {
"type": "string",
@@ -131,6 +131,58 @@
]
}
},
{
"name": "job_kill",
"description": "Request cancellation of a running background job by job id. Returns immediately; the job settles as killed once its work actually stops.",
"parameters": {
"type": "object",
"properties": {
"job_id": {
"type": "string",
"description": "Job 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 job."
}
},
"required": [
"job_id"
]
}
},
{
"name": "job_list",
"description": "List your background jobs (running and finished) with their ids, kinds, and statuses.",
"parameters": {
"type": "object",
"properties": {}
}
},
{
"name": "job_output",
"description": "Read a background job. Stream jobs return only output since the previous read; final-output jobs 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": {
"job_id": {
"type": "string",
"description": "Job id returned by the tool that started the background work."
},
"wait": {
"type": "boolean",
"description": "Block until the job reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the job 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": [
"job_id"
]
}
},
{
"name": "list_agents",
"description": "List your continuable background subagents by durable id and label. Use it to recall which ones you started, not to poll for completion — you are told when one finishes. Status comes from the live registry: running means the agent is working right now, idle means it is loaded but between turns (it may be waiting on agents it started), and ready means it exists only in storage — resumable, not terminal, and not a result waiting to be collected; a `send_message` starts a new turn on the same conversation, and a direct child remains a `send_message` candidate in every status. The snapshot is not a delivery promise — `send_message` performs the authoritative check and may still fail. Children that could not be read are reported as diagnostics instead of being silently dropped. Scope `descendants` walks the whole tree below you in stable pre-order, annotating each entry with its durable direct-parent session id and depth. You may use `send_message` only for depth-1 entries; deeper entries are candidates for `interrupt_agent` only.",
@@ -312,58 +364,6 @@
]
}
},
{
"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. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one 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).",

View File

@@ -4,7 +4,7 @@
{ "op": "newSession" },
{
"op": "prompt",
"text": "Run true once with bash in the foreground. After that fails, run true with bash in the background, read task bash-1 with task_output and wait=true, then reply with exactly RUNNER_FAILURES_SURFACED and stop."
"text": "Run true once with bash in the foreground. After that fails, run true with bash in the background, read task bash-1 with job_output and wait=true, then reply with exactly RUNNER_FAILURES_SURFACED and stop."
}
]
}

View File

@@ -1,9 +1,9 @@
{"type":"session","version":0,"id":"55555555-5555-4555-8555-555555555555","createdAt":1785304900000,"cwd":"{{cwd}}","delegationDepth":0}
{"type":"agent/inbox/spliced","seq":0,"time":1785916902430,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Run true once with bash in the foreground. After that fails, run true with bash in the background, read task bash-1 with task_output and wait=true, then reply with exactly RUNNER_FAILURES_SURFACED and stop."}],"source":{"kind":"user"},"role":"user","id":"2d2f8e7a-f08a-464d-8e94-048d1d95717e"}]}}
{"type":"agent/inbox/spliced","seq":0,"time":1785916902430,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"Run true once with bash in the foreground. After that fails, run true with bash in the background, read task bash-1 with job_output and wait=true, then reply with exactly RUNNER_FAILURES_SURFACED and stop."}],"source":{"kind":"user"},"role":"user","id":"2d2f8e7a-f08a-464d-8e94-048d1d95717e"}]}}
{"type":"turn/start","seq":1,"time":1785916902430,"data":{"turn":1}}
{"type":"agent/inbox/spliced","seq":2,"time":1785916902430,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","seq":3,"time":1785916902458,"data":{"turn":1,"step":1}}
{"type":"user/message","seq":4,"time":1785916902458,"data":{"content":[{"type":"text","text":"Run true once with bash in the foreground. After that fails, run true with bash in the background, read task bash-1 with task_output and wait=true, then reply with exactly RUNNER_FAILURES_SURFACED and stop."}],"source":{"kind":"user"},"role":"user","id":"2d2f8e7a-f08a-464d-8e94-048d1d95717e"},"surfaceOp":"append"}
{"type":"user/message","seq":4,"time":1785916902458,"data":{"content":[{"type":"text","text":"Run true once with bash in the foreground. After that fails, run true with bash in the background, read task bash-1 with job_output and wait=true, then reply with exactly RUNNER_FAILURES_SURFACED and stop."}],"source":{"kind":"user"},"role":"user","id":"2d2f8e7a-f08a-464d-8e94-048d1d95717e"},"surfaceOp":"append"}
{"type":"user/message","seq":5,"time":1785916902459,"data":{"content":[{"type":"text","text":"Current runtime context. This snapshot supersedes earlier runtime-context snapshots.\n\nCurrent DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns.\n\nApproval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}],"source":{"kind":"plugin","plugin":"@deepseek-ai/dsh-system-prompt","form":"snapshot","sections":[{"name":"sandbox:policy","text":"Current DSH file policy: read-only. Any available operation enforced by the DSH file sandbox cannot modify files in the standing mode. Do not refuse a required modification from this policy alone: try an available tool normally and follow any denial and escalation guidance it returns."},{"name":"approval:policy","text":"Approval policy: ask. Operations that require approval may ask through the configured answerers; without an available answerer, the request fails closed."}]},"role":"user","id":"de3778e7-e47a-4d34-a004-ecf43da3c9db"},"surfaceOp":"append"}
{"type":"session/title","seq":6,"time":1785916902459,"data":{"title":"Run true once with bash","messageSeqs":[4],"source":{"kind":"fallback"}}}
{"type":"request/header","seq":7,"time":1785916902460,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
@@ -25,22 +25,22 @@
{"type":"assistant/chunk","seq":23,"time":1785916902500,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":24,"time":1785916902500,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"missing-runner-background","name":"bash","arguments":"{\"command\":\"true\",\"description\":\"Exercise missing sandbox runner in background\",\"run_in_background\":true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"b8ff9c32-71e9-46e3-a30d-60c9c0a99eb9"},"usage":{"inputTokens":1,"outputTokens":1}},"sourceEventSeqs":[19,20,21,22,23],"surfaceOp":"append"}
{"type":"tool/call","seq":25,"time":1785916902500,"data":{"turn":1,"step":2,"callId":"missing-runner-background","name":"bash","arguments":"{\"command\":\"true\",\"description\":\"Exercise missing sandbox runner in background\",\"run_in_background\":true}"}}
{"type":"tool/result","seq":26,"time":1785916902508,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"missing-runner-background"},"content":[{"type":"tool-result","toolCallId":"missing-runner-background","content":[{"type":"text","text":"started background task bash-1"}],"isError":false}],"role":"user","id":"a40cf397-5842-4c09-a6b8-f831eb84827c"}},"sourceEventSeqs":[25],"surfaceOp":"append"}
{"type":"tool/result","seq":26,"time":1785916902508,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"missing-runner-background"},"content":[{"type":"tool-result","toolCallId":"missing-runner-background","content":[{"type":"text","text":"started background job bash-1"}],"isError":false}],"role":"user","id":"a40cf397-5842-4c09-a6b8-f831eb84827c"}},"sourceEventSeqs":[25],"surfaceOp":"append"}
{"type":"step/end","seq":27,"time":1785916902508,"data":{"turn":1,"step":2}}
{"type":"agent/inbox/spliced","seq":28,"time":1785916902508,"data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"background task bash-1 (bash: true) finished [status: killed, killed before exit]. Read its output with task_output."}],"source":{"kind":"plugin","plugin":"tool-tasks","form":"notice","summary":"bash true [status: killed, killed before exit]"},"role":"user","id":"989e3c2b-5b21-4694-83d5-6cddac55ce0e"}]}}
{"type":"agent/inbox/spliced","seq":28,"time":1785916902508,"data":{"target":"next-step","start":0,"inserted":[{"content":[{"type":"text","text":"background job bash-1 (bash: true) finished [status: killed, killed before exit]. Read its output with job_output."}],"source":{"kind":"plugin","plugin":"tool-jobs","form":"notice","summary":"bash true [status: killed, killed before exit]"},"role":"user","id":"989e3c2b-5b21-4694-83d5-6cddac55ce0e"}]}}
{"type":"step/start","seq":29,"time":1785916902519,"data":{"turn":1,"step":3}}
{"type":"assistant/chunk","seq":30,"time":1785825343607,"data":{"turn":1,"step":3,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
{"type":"assistant/chunk","seq":31,"time":1785825343607,"data":{"turn":1,"step":3,"chunk":{"type":"tool-call-delta","index":0,"id":"missing-runner-output","name":"task_output","argumentsDelta":"{\"task_id\":\"bash-1\",\"wait\":true}"}}}
{"type":"assistant/chunk","seq":32,"time":1785825343607,"data":{"turn":1,"step":3,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"missing-runner-output","name":"task_output","arguments":"{\"task_id\":\"bash-1\",\"wait\":true}"}}}}
{"type":"assistant/chunk","seq":31,"time":1785825343607,"data":{"turn":1,"step":3,"chunk":{"type":"tool-call-delta","index":0,"id":"missing-runner-output","name":"job_output","argumentsDelta":"{\"job_id\":\"bash-1\",\"wait\":true}"}}}
{"type":"assistant/chunk","seq":32,"time":1785825343607,"data":{"turn":1,"step":3,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"missing-runner-output","name":"job_output","arguments":"{\"job_id\":\"bash-1\",\"wait\":true}"}}}}
{"type":"assistant/chunk","seq":33,"time":1785825343607,"data":{"turn":1,"step":3,"chunk":{"type":"usage","usage":{"inputTokens":1,"outputTokens":1}}}}
{"type":"assistant/chunk","seq":34,"time":1785916902524,"data":{"turn":1,"step":3,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":35,"time":1785916902524,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"missing-runner-output","name":"task_output","arguments":"{\"task_id\":\"bash-1\",\"wait\":true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"b5e176c7-fe2f-4b73-855d-416a48326392"},"usage":{"inputTokens":1,"outputTokens":1}},"sourceEventSeqs":[30,31,32,33,34],"surfaceOp":"append"}
{"type":"tool/call","seq":36,"time":1785916902524,"data":{"turn":1,"step":3,"callId":"missing-runner-output","name":"task_output","arguments":"{\"task_id\":\"bash-1\",\"wait\":true}"}}
{"type":"assistant/message","seq":35,"time":1785916902524,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"tool-call","id":"missing-runner-output","name":"job_output","arguments":"{\"job_id\":\"bash-1\",\"wait\":true}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"b5e176c7-fe2f-4b73-855d-416a48326392"},"usage":{"inputTokens":1,"outputTokens":1}},"sourceEventSeqs":[30,31,32,33,34],"surfaceOp":"append"}
{"type":"tool/call","seq":36,"time":1785916902524,"data":{"turn":1,"step":3,"callId":"missing-runner-output","name":"job_output","arguments":"{\"job_id\":\"bash-1\",\"wait\":true}"}}
{"type":"tool/result","seq":37,"time":1785916902532,"data":{"turn":1,"step":3,"message":{"source":{"kind":"tool","callId":"missing-runner-output"},"content":[{"type":"tool-result","toolCallId":"missing-runner-output","content":[{"type":"text","text":"[stderr]\nspawn failed: Error: spawn {{cwd}}/.dsh-missing-sandbox-runner ENOENT\n[sandbox: the sandbox runner itself failed under read-only mode — the command did not run; this is a sandbox problem, not a command failure]\n[status: killed, killed before exit]"}],"isError":false}],"role":"user","id":"ac65952f-f6e9-459e-a653-87022fe03d60"}},"sourceEventSeqs":[36],"surfaceOp":"append"}
{"type":"step/end","seq":38,"time":1785916902532,"data":{"turn":1,"step":3}}
{"type":"agent/inbox/spliced","seq":39,"time":1785916902532,"data":{"target":"next-step","start":0,"removedCount":1,"inserted":[]}}
{"type":"step/start","seq":40,"time":1785916902542,"data":{"turn":1,"step":4}}
{"type":"user/message","seq":41,"time":1785916902542,"data":{"content":[{"type":"text","text":"background task bash-1 (bash: true) finished [status: killed, killed before exit]. Read its output with task_output."}],"source":{"kind":"plugin","plugin":"tool-tasks","form":"notice","summary":"bash true [status: killed, killed before exit]"},"role":"user","id":"989e3c2b-5b21-4694-83d5-6cddac55ce0e"},"surfaceOp":"append"}
{"type":"user/message","seq":41,"time":1785916902542,"data":{"content":[{"type":"text","text":"background job bash-1 (bash: true) finished [status: killed, killed before exit]. Read its output with job_output."}],"source":{"kind":"plugin","plugin":"tool-jobs","form":"notice","summary":"bash true [status: killed, killed before exit]"},"role":"user","id":"989e3c2b-5b21-4694-83d5-6cddac55ce0e"},"surfaceOp":"append"}
{"type":"assistant/chunk","seq":42,"time":1785825343627,"data":{"turn":1,"step":4,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
{"type":"assistant/chunk","seq":43,"time":1785825343628,"data":{"turn":1,"step":4,"chunk":{"type":"text-delta","index":0,"text":"RUNNER_FAILURES_SURFACED"}}}
{"type":"assistant/chunk","seq":44,"time":1785916902550,"data":{"turn":1,"step":4,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"RUNNER_FAILURES_SURFACED"}}}}

View File

@@ -18,8 +18,8 @@
{"type":"assistant/chunk","seq":56,"time":1785730418696,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
{"type":"assistant/message","seq":57,"time":1785730418696,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to run a simple bash command and report the result verbatim."},{"type":"tool-call","id":"call_00_JliP571Bh0QQ8QExbSPk0080","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Run echo HELLO\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"658eb4a4-7462-43d8-91eb-13d09363db20"},"usage":{"inputTokens":2878,"outputTokens":83,"cacheReadTokens":0,"reasoningTokens":17}},"sourceEventSeqs":[9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56],"surfaceOp":"append"}
{"type":"tool/call","seq":58,"time":1785730418696,"data":{"turn":1,"step":1,"callId":"call_00_JliP571Bh0QQ8QExbSPk0080","name":"bash","arguments":"{\"command\": \"echo HELLO\", \"description\": \"Run echo HELLO\"}"}}
{"type":"hook/invoked","seq":59,"time":1785730418697,"data":{"turn":1,"point":"PreToolUse","dialect":"claude","handlerId":"claude:PreToolUse:1","matcher":"bash"}}
{"type":"hook/result","seq":60,"time":1785730418702,"data":{"turn":1,"point":"PreToolUse","handlerId":"claude:PreToolUse:1","decision":"block","exitCode":2,"stderrSummary":"bash is disabled by policy in this session","durationMs":4.435375000000022}}
{"type":"hook/invoked","seq":59,"time":1785730418697,"data":{"turn":1,"point":"PreToolUse","dialect":"claude-code","handlerId":"claude-code:PreToolUse:1","matcher":"bash"}}
{"type":"hook/result","seq":60,"time":1785730418702,"data":{"turn":1,"point":"PreToolUse","handlerId":"claude-code:PreToolUse:1","decision":"block","exitCode":2,"stderrSummary":"bash is disabled by policy in this session","durationMs":4.435375000000022}}
{"type":"tool/result","seq":61,"time":1785730418702,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_00_JliP571Bh0QQ8QExbSPk0080"},"content":[{"type":"tool-result","toolCallId":"call_00_JliP571Bh0QQ8QExbSPk0080","content":[{"type":"text","text":"Error: bash is disabled by policy in this session"}],"isError":true}],"role":"user","id":"85f289f4-cb3c-468e-bbad-e66fefe2346f"}},"sourceEventSeqs":[58],"surfaceOp":"append"}
{"type":"step/end","seq":62,"time":1785730418702,"data":{"turn":1,"step":1}}
{"type":"step/start","seq":63,"time":1785730418710,"data":{"turn":1,"step":2}}

View File

@@ -2,7 +2,7 @@
"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> 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.",
"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> 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 job id immediately; read its output with `job_output` and stop it with `job_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": {
@@ -24,7 +24,7 @@
},
"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."
"description": "Run in the background and return a job id immediately (collect with job_output, stop with job_kill). No timeout applies."
},
"sandbox_permissions": {
"type": "string",
@@ -131,6 +131,58 @@
]
}
},
{
"name": "job_kill",
"description": "Request cancellation of a running background job by job id. Returns immediately; the job settles as killed once its work actually stops.",
"parameters": {
"type": "object",
"properties": {
"job_id": {
"type": "string",
"description": "Job 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 job."
}
},
"required": [
"job_id"
]
}
},
{
"name": "job_list",
"description": "List your background jobs (running and finished) with their ids, kinds, and statuses.",
"parameters": {
"type": "object",
"properties": {}
}
},
{
"name": "job_output",
"description": "Read a background job. Stream jobs return only output since the previous read; final-output jobs 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": {
"job_id": {
"type": "string",
"description": "Job id returned by the tool that started the background work."
},
"wait": {
"type": "boolean",
"description": "Block until the job reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the job 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": [
"job_id"
]
}
},
{
"name": "list_agents",
"description": "List your continuable background subagents by durable id and label. Use it to recall which ones you started, not to poll for completion — you are told when one finishes. Status comes from the live registry: running means the agent is working right now, idle means it is loaded but between turns (it may be waiting on agents it started), and ready means it exists only in storage — resumable, not terminal, and not a result waiting to be collected; a `send_message` starts a new turn on the same conversation, and a direct child remains a `send_message` candidate in every status. The snapshot is not a delivery promise — `send_message` performs the authoritative check and may still fail. Children that could not be read are reported as diagnostics instead of being silently dropped. Scope `descendants` walks the whole tree below you in stable pre-order, annotating each entry with its durable direct-parent session id and depth. You may use `send_message` only for depth-1 entries; deeper entries are candidates for `interrupt_agent` only.",
@@ -256,7 +308,7 @@
},
{
"name": "subagent_claude_code",
"description": "Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. This call waits for the subagent and returns its result.",
"description": "Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. This call waits for the result by default. Set `run_in_background: true` to return a job id; collect with `job_output` and stop with `job_kill`.",
"parameters": {
"type": "object",
"properties": {
@@ -267,6 +319,10 @@
"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": "Whether to run as a background job and return its id. Defaults to false; collect with job_output or stop with job_kill."
}
},
"required": [
@@ -277,7 +333,7 @@
},
{
"name": "subagent_codex",
"description": "Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. This call waits for the subagent and returns its result.",
"description": "Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. This call waits for the result by default. Set `run_in_background: true` to return a job id; collect with `job_output` and stop with `job_kill`.",
"parameters": {
"type": "object",
"properties": {
@@ -288,6 +344,10 @@
"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": "Whether to run as a background job and return its id. Defaults to false; collect with job_output or stop with job_kill."
}
},
"required": [
@@ -317,58 +377,6 @@
]
}
},
{
"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. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one 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).",

View File

@@ -1,4 +1,4 @@
You are an AI agent powered by the DeepSeek Harness SDK.
You are an AI agent powered by DeepSeek Harness.
You are a coding assistant powered by the deepseek-v4-pro 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.
@@ -7,13 +7,13 @@ 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 write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-observation-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.
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-observation-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.
Track every background job id you start. You are notified in-session when a job finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running job's work. Before giving a final answer, collect every still-relevant job with job_output (set wait: true only when you are genuinely blocked on it), and job_kill jobs that stopped mattering.
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.

View File

@@ -2,7 +2,7 @@
"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> 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.",
"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> 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 job id immediately; read its output with `job_output` and stop it with `job_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": {
@@ -24,7 +24,7 @@
},
"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."
"description": "Run in the background and return a job id immediately (collect with job_output, stop with job_kill). No timeout applies."
},
"sandbox_permissions": {
"type": "string",
@@ -131,6 +131,58 @@
]
}
},
{
"name": "job_kill",
"description": "Request cancellation of a running background job by job id. Returns immediately; the job settles as killed once its work actually stops.",
"parameters": {
"type": "object",
"properties": {
"job_id": {
"type": "string",
"description": "Job 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 job."
}
},
"required": [
"job_id"
]
}
},
{
"name": "job_list",
"description": "List your background jobs (running and finished) with their ids, kinds, and statuses.",
"parameters": {
"type": "object",
"properties": {}
}
},
{
"name": "job_output",
"description": "Read a background job. Stream jobs return only output since the previous read; final-output jobs 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": {
"job_id": {
"type": "string",
"description": "Job id returned by the tool that started the background work."
},
"wait": {
"type": "boolean",
"description": "Block until the job reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the job 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": [
"job_id"
]
}
},
{
"name": "list_agents",
"description": "List your continuable background subagents by durable id and label. Use it to recall which ones you started, not to poll for completion — you are told when one finishes. Status comes from the live registry: running means the agent is working right now, idle means it is loaded but between turns (it may be waiting on agents it started), and ready means it exists only in storage — resumable, not terminal, and not a result waiting to be collected; a `send_message` starts a new turn on the same conversation, and a direct child remains a `send_message` candidate in every status. The snapshot is not a delivery promise — `send_message` performs the authoritative check and may still fail. Children that could not be read are reported as diagnostics instead of being silently dropped. Scope `descendants` walks the whole tree below you in stable pre-order, annotating each entry with its durable direct-parent session id and depth. You may use `send_message` only for depth-1 entries; deeper entries are candidates for `interrupt_agent` only.",
@@ -256,7 +308,7 @@
},
{
"name": "subagent_codex",
"description": "Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. This call waits for the subagent and returns its result.",
"description": "Delegate a self-contained task to a subagent (a separate agent that works in its own context) to offload focused, independent work — research, a scoped implementation, an analysis — so it does not consume this conversation's context. The subagent returns its result, not its intermediate steps. Give it a complete, standalone prompt: it does not see this conversation. This call waits for the result by default. Set `run_in_background: true` to return a job id; collect with `job_output` and stop with `job_kill`.",
"parameters": {
"type": "object",
"properties": {
@@ -267,6 +319,10 @@
"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": "Whether to run as a background job and return its id. Defaults to false; collect with job_output or stop with job_kill."
}
},
"required": [
@@ -296,58 +352,6 @@
]
}
},
{
"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. Mark every todo being actively worked on `in_progress` — several at once when work genuinely runs in parallel (e.g. concurrent subagents or background commands), one for sequential work; while work remains, at least one 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).",

View File

@@ -1,4 +1,4 @@
You are an AI agent powered by the DeepSeek Harness SDK.
You are an AI agent powered by DeepSeek Harness.
You are a coding assistant powered by the deepseek-v4-pro 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.
@@ -7,15 +7,15 @@ 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 write tool to create files or completely replace file contents. Existing files are overwritten, so read an existing file first (the default fs-observation-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.
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-observation-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.
Use a terminal session only when work needs persistent terminal state or interactive stdin; prefer bash/read/write/edit for bounded one-shot operations. Track every terminal session id and close sessions that no longer matter. An inferred_idle or timeout result does not prove the foreground command exited.
Use a terminal session only when work needs persistent terminal state or interactive stdin; prefer shell/read/write/edit for bounded one-shot operations. Track every terminal session id and close sessions that no longer matter. An inferred_idle or timeout result does not prove the foreground command exited.
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.
Track every background job id you start. You are notified in-session when a job finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running job's work. Before giving a final answer, collect every still-relevant job with job_output (set wait: true only when you are genuinely blocked on it), and job_kill jobs that stopped mattering.
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.

View File

@@ -2,7 +2,7 @@
"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> 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.",
"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> 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 job id immediately; read its output with `job_output` and stop it with `job_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": {
@@ -24,7 +24,7 @@
},
"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."
"description": "Run in the background and return a job id immediately (collect with job_output, stop with job_kill). No timeout applies."
},
"sandbox_permissions": {
"type": "string",
@@ -131,6 +131,58 @@
]
}
},
{
"name": "job_kill",
"description": "Request cancellation of a running background job by job id. Returns immediately; the job settles as killed once its work actually stops.",
"parameters": {
"type": "object",
"properties": {
"job_id": {
"type": "string",
"description": "Job 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 job."
}
},
"required": [
"job_id"
]
}
},
{
"name": "job_list",
"description": "List your background jobs (running and finished) with their ids, kinds, and statuses.",
"parameters": {
"type": "object",
"properties": {}
}
},
{
"name": "job_output",
"description": "Read a background job. Stream jobs return only output since the previous read; final-output jobs 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": {
"job_id": {
"type": "string",
"description": "Job id returned by the tool that started the background work."
},
"wait": {
"type": "boolean",
"description": "Block until the job reaches a terminal status or the timeout expires. A timed-out wait returns [status: running] and leaves the job 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": [
"job_id"
]
}
},
{
"name": "list_agents",
"description": "List your continuable background subagents by durable id and label. Use it to recall which ones you started, not to poll for completion — you are told when one finishes. Status comes from the live registry: running means the agent is working right now, idle means it is loaded but between turns (it may be waiting on agents it started), and ready means it exists only in storage — resumable, not terminal, and not a result waiting to be collected; a `send_message` starts a new turn on the same conversation, and a direct child remains a `send_message` candidate in every status. The snapshot is not a delivery promise — `send_message` performs the authoritative check and may still fail. Children that could not be read are reported as diagnostics instead of being silently dropped. Scope `descendants` walks the whole tree below you in stable pre-order, annotating each entry with its durable direct-parent session id and depth. You may use `send_message` only for depth-1 entries; deeper entries are candidates for `interrupt_agent` only.",
@@ -275,58 +327,6 @@
]
}
},
{
"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": "terminal_close",
"description": "Close one persistent terminal and wait until its captured owned process tree is gone.",
@@ -401,7 +401,7 @@
},
{
"name": "terminal_send",
"description": "Send text to a persistent terminal. By default Enter is submitted and the call waits for a prompt, stdin wait, output silence, timeout, or session exit. Background mode returns a task id for task_output/task_kill.",
"description": "Send text to a persistent terminal. By default Enter is submitted and the call waits for a prompt, stdin wait, output silence, timeout, or session exit. Background mode returns a job id for job_output/job_kill.",
"parameters": {
"type": "object",
"properties": {
@@ -419,7 +419,7 @@
},
"run_in_background": {
"type": "boolean",
"description": "Return a task id immediately; collect with task_output or stop with task_kill."
"description": "Return a job id immediately; collect with job_output or stop with job_kill."
}
},
"required": [

View File

@@ -1,7 +1,7 @@
You are an AI agent powered by the DeepSeek Harness SDK.
You are an AI agent powered by DeepSeek Harness.
You are a concise snapshot agent working in {{cwd}}.
Non-zero exits are reported as `[exit code: N]` markers; investigate failures before moving on. On Windows a killed process settles as `[exit code: 1]` without a signal marker; treat a bare exit 1 after an interruption as a termination, not a command failure.
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.
Track every background job id you start. You are notified in-session when a job finishes — do not busy-poll or sleep on one; keep working on independent steps and do not duplicate a running job's work. Before giving a final answer, collect every still-relevant job with job_output (set wait: true only when you are genuinely blocked on it), and job_kill jobs that stopped mattering.

Some files were not shown because too many files have changed in this diff Show More