Merge master at 35eeb4a112
This commit is contained in:
@@ -8,7 +8,7 @@ Extract reusable logic into `packages/`, where per-file coverage and README gate
|
||||
|
||||
Each example has both:
|
||||
|
||||
- **Keyless:** boot the real `cordis.yml` through the Loader, drive it, and assert output and clean exit. Catches Loader/export-shape failures hand-mounted tests miss ([postmortem](../docs/postmortem/0001-acp-default-export-drops-inject.md)).
|
||||
- **Keyless:** boot the real `cordis.yml` through the Loader, drive it, and assert output and clean exit. Catches invalid Loader exports that hand-mounted tests miss ([postmortem](../docs/postmortem/0001-acp-default-export-drops-inject.md)).
|
||||
- **With-key:** send a live-model prompt and verify external state, not the model's claim. Self-skip without `DEEPSEEK_API_KEY`; see [testing.md](../docs/testing.md).
|
||||
|
||||
Keyless process smokes use `@deepseek-ai/dsh-loader-smoke` for Loader launch resolution; terminal tests wrap that launch in a pseudo-terminal. Tests supply paths, environment, input, and assertions. Every checked-in test Cordis config lives under its corresponding `examples/<agent>/` leaf. Map a package-owned config to `examples/<agent>/tests/fixtures/<group>/<package>/cordis.yml`, keep its driver and assertions package-local, and declare every package it names in both root `tsconfig.json` references and `examples/package.json`.
|
||||
|
||||
@@ -54,6 +54,7 @@ const PARTIAL_LANDLOCK_CONFIG = fileURLToPath(new URL('../partial-landlock.cordi
|
||||
const PWSH_CONFIG = fileURLToPath(new URL('./pwsh.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))
|
||||
const FS_DIFF_BOUND_CONFIG = fileURLToPath(new URL('./fs-diff-bound.cordis.yml', import.meta.url))
|
||||
const SNAPSHOTS_DIR = join(dirname(fileURLToPath(import.meta.url)), 'snapshots')
|
||||
const PACKED_CHUNKS_SOURCE = 'hook-cc-pretool-deny'
|
||||
|
||||
@@ -259,7 +260,7 @@ const SCENARIOS: Scenario[] = [
|
||||
// and then `migrate:packed-session-fixtures`, which canonicalizes the live
|
||||
// log's eager-drain-packed rows into the maximal-run layout replay produces.
|
||||
// The recorded fixture's `request/header` config and `request/context` are
|
||||
// normalized to the replay-produced minimal shape (the live adapter logs
|
||||
// normalized to the minimal fields produced during replay (the live adapter logs
|
||||
// model capabilities like maxTokens/reasoningEffort that llm-replay has no
|
||||
// data for), and its tool-result paths are canonicalized to `/` separators.
|
||||
{
|
||||
@@ -276,6 +277,21 @@ const SCENARIOS: Scenario[] = [
|
||||
{ name: 'fs-write', hasModelTurn: true, recorded: true },
|
||||
{ name: 'fs-edit', hasModelTurn: true, recorded: true },
|
||||
{ name: 'fs-write-overwrite', hasModelTurn: true, recorded: true },
|
||||
// An overwrite whose replacement is at/above the configured diff-basis bound:
|
||||
// the persisted result meta carries no contextual hunks and presentation
|
||||
// falls back to the whole-file diff. The overlay leaves the prompt and tool
|
||||
// sequence identical to text-turn, but the freshly recorded header carries
|
||||
// the current adapter capability fields, so the scenario pins its own class.
|
||||
{
|
||||
name: 'fs-write-overwrite-bounded',
|
||||
hasModelTurn: true,
|
||||
recorded: true,
|
||||
pinsHeader: true,
|
||||
headerClass: 'fs-diff-bound',
|
||||
systemPromptSource: 'text-turn',
|
||||
toolSchemasSource: 'text-turn',
|
||||
configPath: FS_DIFF_BOUND_CONFIG,
|
||||
},
|
||||
{ name: 'fs-read-window', hasModelTurn: true, recorded: true },
|
||||
{ name: 'fs-policy-reject', hasModelTurn: true, recorded: true },
|
||||
{ name: 'fs-delete-recreate', hasModelTurn: true, recorded: true },
|
||||
|
||||
@@ -20,7 +20,7 @@ import { cleanupAcpExampleTest } from './cleanup.ts'
|
||||
*
|
||||
* Keyless smoke: boot the REAL `cordis.yml` through the `dsh-acp-agent` bin as
|
||||
* an ACP subprocess and drive initialize + session/new — the real-Loader-path
|
||||
* guard (postmortem 0001) for THIS tree's export shapes, including the
|
||||
* guard (postmortem 0001) for THIS tree's exports, including the
|
||||
* sandbox executor AND the approval service. No prompt is sent, so neither the
|
||||
* model nor a sandbox runner is ever exercised.
|
||||
*
|
||||
@@ -74,8 +74,8 @@ function launchExampleAcpAgent(
|
||||
requestPermission(params) {
|
||||
permissionRequests.push(params)
|
||||
const option = params.options.find(o => o.optionId === answer)
|
||||
// The scripted machine policy selects the requested option; an
|
||||
// unexpected request shape cancels (fail closed, never grants).
|
||||
// The scripted machine policy selects the requested option. If that
|
||||
// option is absent, the policy cancels (fail closed, never grant).
|
||||
if (option === undefined) return Promise.resolve({ outcome: { outcome: 'cancelled' } })
|
||||
return Promise.resolve({ outcome: { outcome: 'selected', optionId: option.optionId } })
|
||||
},
|
||||
@@ -107,7 +107,7 @@ describe('default sandbox composition keyless smoke (real cordis.yml via the Loa
|
||||
const { client } = spawned
|
||||
// A dummy key boots the adapter; no prompt is ever sent, so no model call
|
||||
// and no sandbox runner probe happen. This drives the fiber tree the same
|
||||
// way an ACP caller would, which catches a broken export/inject shape.
|
||||
// way an ACP caller would, which catches broken exports or injection.
|
||||
const init = await client.initialize({ protocolVersion: PROTOCOL_VERSION, clientCapabilities: {} })
|
||||
expect(init.protocolVersion).toBe(PROTOCOL_VERSION)
|
||||
expect(init.agentCapabilities).toEqual({
|
||||
|
||||
46
examples/acp-agent/tests/fs-diff-bound.cordis.snapshot.yml
Normal file
46
examples/acp-agent/tests/fs-diff-bound.cordis.snapshot.yml
Normal file
@@ -0,0 +1,46 @@
|
||||
# Keyless replay counterpart to fs-diff-bound.cordis.yml. Replay patches apply
|
||||
# directly against the live cordis.yml because include patches cannot target
|
||||
# entries behind a nested include; the acp-agent restatement keeps the recorded
|
||||
# deepseek-v4-flash model and raw JSONL persistence for the harness's harvest.
|
||||
- id: base
|
||||
name: '@cordisjs/plugin-include'
|
||||
config:
|
||||
path: ../cordis.yml
|
||||
patches:
|
||||
- id: llm-deepseek
|
||||
name: '@deepseek-ai/dsh-llm-deepseek'
|
||||
disabled: true
|
||||
- id: acp-agent
|
||||
name: '@deepseek-ai/dsh-acp-demo'
|
||||
config:
|
||||
provider: deepseek-official
|
||||
model: deepseek-v4-flash
|
||||
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
|
||||
persistenceCompression: none
|
||||
workspaceContext:
|
||||
maxBytes: 65536
|
||||
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.
|
||||
|
||||
Verify your work by running the code or tests. Keep answers brief and factual.
|
||||
- id: fs-sandbox
|
||||
name: '@deepseek-ai/dsh-fs-sandbox'
|
||||
config:
|
||||
cwd: !!js process.cwd()
|
||||
diffBasisMaxBytes: 64
|
||||
- insert:
|
||||
- id: llm-replay
|
||||
name: '@deepseek-ai/dsh-llm-replay'
|
||||
config:
|
||||
providers:
|
||||
- id: deepseek-official
|
||||
name: DeepSeek
|
||||
models:
|
||||
# Capability parity with the live adapter so replay
|
||||
# reconstructs the freshly recorded request header.
|
||||
- id: deepseek-v4-flash
|
||||
contextWindow: 1000000
|
||||
defaultMaxTokens: 256000
|
||||
reasoningEfforts: ['off', 'high', 'max']
|
||||
defaultReasoningEffort: max
|
||||
- id: deepseek-v4-pro
|
||||
29
examples/acp-agent/tests/fs-diff-bound.cordis.yml
Normal file
29
examples/acp-agent/tests/fs-diff-bound.cordis.yml
Normal file
@@ -0,0 +1,29 @@
|
||||
# Live counterpart for the bounded-overwrite-diff snapshot: the base stack with
|
||||
# the fs backend's overwrite diff-basis limit shrunk so a modest replacement
|
||||
# crosses the exclusive bound and the write result falls back to a whole-file
|
||||
# diff. A config patch replaces the row's whole config, so `cwd` is restated
|
||||
# verbatim, and the acp-agent restatement re-pins `deepseek-v4-flash` to match
|
||||
# the recorded corpus and its pinned request headers.
|
||||
- id: base
|
||||
name: '@cordisjs/plugin-include'
|
||||
config:
|
||||
path: ../cordis.yml
|
||||
patches:
|
||||
- id: acp-agent
|
||||
name: '@deepseek-ai/dsh-acp-demo'
|
||||
config:
|
||||
provider: deepseek-official
|
||||
model: deepseek-v4-flash
|
||||
persistenceRoot: !!js process.env.DSH_SNAPSHOT_SESSIONS_ROOT ?? './.sessions'
|
||||
persistenceCompression: !!js "process.env.DSH_SNAPSHOT === undefined ? 'zstd' : 'none'"
|
||||
workspaceContext:
|
||||
maxBytes: 65536
|
||||
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.
|
||||
|
||||
Verify your work by running the code or tests. Keep answers brief and factual.
|
||||
- id: fs-sandbox
|
||||
name: '@deepseek-ai/dsh-fs-sandbox'
|
||||
config:
|
||||
cwd: !!js process.cwd()
|
||||
diffBasisMaxBytes: 64
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"steps": [
|
||||
{ "op": "initialize" },
|
||||
{ "op": "newSession" },
|
||||
{ "op": "prompt", "text": "First use the read tool to read data.txt in the current directory. Then use the write tool (NOT bash) to replace its entire contents with exactly this single line: The replacement line is deliberately longer than the configured sixty-four byte diff-basis bound. Then reply with exactly the single word DONE." }
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
{"type":"session","version":0,"id":"14b14f51-2428-43a0-bcc5-5f392d4faa19","createdAt":1786204699215,"cwd":"{{cwd}}","delegationDepth":0}
|
||||
{"type":"agent/inbox/spliced","seq":0,"time":1786204699218,"data":{"target":"next-turn","start":0,"inserted":[{"content":[{"type":"text","text":"First use the read tool to read data.txt in the current directory. Then use the write tool (NOT bash) to replace its entire contents with exactly this single line: The replacement line is deliberately longer than the configured sixty-four byte diff-basis bound. Then reply with exactly the single word DONE."}],"source":{"kind":"user"},"role":"user","id":"41d72cfe-0e37-474f-83dc-2b15bacf9c0d"}]}}
|
||||
{"type":"turn/start","seq":1,"time":1786204699219,"data":{"turn":1}}
|
||||
{"type":"agent/inbox/spliced","seq":2,"time":1786204699220,"data":{"target":"next-turn","start":0,"removedCount":1,"inserted":[]}}
|
||||
{"type":"step/start","seq":3,"time":1786204699259,"data":{"turn":1,"step":1}}
|
||||
{"type":"user/message","seq":4,"time":1786204699259,"data":{"content":[{"type":"text","text":"First use the read tool to read data.txt in the current directory. Then use the write tool (NOT bash) to replace its entire contents with exactly this single line: The replacement line is deliberately longer than the configured sixty-four byte diff-basis bound. Then reply with exactly the single word DONE."}],"source":{"kind":"user"},"role":"user","id":"41d72cfe-0e37-474f-83dc-2b15bacf9c0d"},"surfaceOp":"append"}
|
||||
{"type":"user/message","seq":5,"time":1786204699260,"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":"e374fb32-1cad-4e2d-9cd3-66ac8fcf9588"},"surfaceOp":"append"}
|
||||
{"type":"session/title","seq":6,"time":1786204699261,"data":{"title":"First use the read tool","messageSeqs":[4],"source":{"kind":"fallback"}}}
|
||||
{"type":"request/header","seq":7,"time":1786204699262,"data":{"header":{"config":{"provider":"deepseek-official","model":"deepseek-v4-flash","maxTokens":256000,"reasoningEffort":"max"},"adapterDefaults":{"reasoningEffort":true,"maxTokens":true},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
|
||||
{"type":"request/context","seq":8,"time":1786204699262,"data":{"provider":"deepseek-official","model":"deepseek-v4-flash","contextWindow":1000000}}
|
||||
{"type":"assistant/chunk","seq":9,"time":1786204701601,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":0,"blockType":"reasoning"}}}
|
||||
{"type":"reasoning-chunks","seq0":10,"time0":1786204701602,"data":{"turn":1,"step":1,"index":0,"dt":[60,22,2,1,0,1,0,19,2,1,1,17,21,2,0,20,2,1,21,0,0,0,1,21,2],"texts":["The"," user"," wants"," me"," to"," read"," data",".txt"," first",","," then"," write"," to"," replace"," its"," contents"," with"," the"," exact"," line",","," then"," reply"," D","ONE","."]}}
|
||||
{"type":"assistant/chunk","seq":36,"time":1786204701863,"data":{"turn":1,"step":1,"chunk":{"type":"block-start","index":1,"blockType":"tool-call"}}}
|
||||
{"type":"tool-call-chunks","seq0":37,"time0":1786204701864,"data":{"turn":1,"step":1,"index":1,"dt":[21,2,0,21,2,1,0,26,1,0,17],"id":"call_00_Jxz49JNt6i4oaDnzes2I0794","name":"read","args":["","{","\"","file","_path","\"",": ","\"","data",".txt","\"","}"]}}
|
||||
{"type":"assistant/chunk","seq":49,"time":1786204701981,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":0,"block":{"type":"reasoning","text":"The user wants me to read data.txt first, then write to replace its contents with the exact line, then reply DONE."}}}}
|
||||
{"type":"assistant/chunk","seq":50,"time":1786204701982,"data":{"turn":1,"step":1,"chunk":{"type":"block-end","index":1,"block":{"type":"tool-call","id":"call_00_Jxz49JNt6i4oaDnzes2I0794","name":"read","arguments":"{\"file_path\": \"data.txt\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":51,"time":1786204701982,"data":{"turn":1,"step":1,"chunk":{"type":"usage","usage":{"inputTokens":5803,"outputTokens":71,"cacheReadTokens":0,"reasoningTokens":26}}}}
|
||||
{"type":"assistant/chunk","seq":52,"time":1786204701982,"data":{"turn":1,"step":1,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":53,"time":1786204701988,"data":{"turn":1,"step":1,"message":{"role":"assistant","content":[{"type":"reasoning","text":"The user wants me to read data.txt first, then write to replace its contents with the exact line, then reply DONE."},{"type":"tool-call","id":"call_00_Jxz49JNt6i4oaDnzes2I0794","name":"read","arguments":"{\"file_path\": \"data.txt\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"9060e190-9971-4838-81bf-48c3e3888609"},"usage":{"inputTokens":5803,"outputTokens":71,"cacheReadTokens":0,"reasoningTokens":26}},"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],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":54,"time":1786204701990,"data":{"turn":1,"step":1,"callId":"call_00_Jxz49JNt6i4oaDnzes2I0794","name":"read","arguments":"{\"file_path\": \"data.txt\"}"}}
|
||||
{"type":"tool/result","seq":55,"time":1786204702006,"data":{"turn":1,"step":1,"message":{"source":{"kind":"tool","callId":"call_00_Jxz49JNt6i4oaDnzes2I0794"},"content":[{"type":"tool-result","toolCallId":"call_00_Jxz49JNt6i4oaDnzes2I0794","content":[{"type":"text","text":"<path>{{cwd}}/data.txt</path>\n<type>file</type>\n<content>\n1: original contents\n\n(End of file - total 1 lines)\n</content>"}],"isError":false}],"role":"user","id":"1406fd7d-f181-41d0-b0db-ef196010f620"},"meta":{"path":"{{cwd}}/data.txt","offset":1,"lines":[{"number":1,"text":"original contents"}],"totalLines":1}},"sourceEventSeqs":[54],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":56,"time":1786204702006,"data":{"turn":1,"step":1}}
|
||||
{"type":"step/start","seq":57,"time":1786204702016,"data":{"turn":1,"step":2}}
|
||||
{"type":"assistant/chunk","seq":58,"time":1786204703539,"data":{"turn":1,"step":2,"chunk":{"type":"block-start","index":0,"blockType":"tool-call"}}}
|
||||
{"type":"tool-call-chunks","seq0":59,"time0":1786204703539,"data":{"turn":1,"step":2,"index":0,"dt":[0,1,0,0,0,1,0,0,1,0,12,2,0,0,0,22,35,1,0,0,0,0,0,1,0,8,2,0,0,71,1,0,0,1,0],"id":"call_00_ET_7mLiYX652hJA9GW6d1bl4653","name":"write","args":["","{","\"","file","_path","\"",": ","\"","data",".txt","\"",", ","\"","content","\"",": ","\"","The"," replacement"," line"," is"," deliberately"," longer"," than"," the"," configured"," sixty","-four"," byte"," diff","-b","asis"," bound",".","\"","}"]}}
|
||||
{"type":"assistant/chunk","seq":95,"time":1786204703720,"data":{"turn":1,"step":2,"chunk":{"type":"block-end","index":0,"block":{"type":"tool-call","id":"call_00_ET_7mLiYX652hJA9GW6d1bl4653","name":"write","arguments":"{\"file_path\": \"data.txt\", \"content\": \"The replacement line is deliberately longer than the configured sixty-four byte diff-basis bound.\"}"}}}}
|
||||
{"type":"assistant/chunk","seq":96,"time":1786204703720,"data":{"turn":1,"step":2,"chunk":{"type":"usage","usage":{"inputTokens":202,"outputTokens":76,"cacheReadTokens":5760,"reasoningTokens":0}}}}
|
||||
{"type":"assistant/chunk","seq":97,"time":1786204703720,"data":{"turn":1,"step":2,"chunk":{"type":"finish","reason":{"kind":"tool-calls"}}}}
|
||||
{"type":"assistant/message","seq":98,"time":1786204703722,"data":{"turn":1,"step":2,"message":{"role":"assistant","content":[{"type":"tool-call","id":"call_00_ET_7mLiYX652hJA9GW6d1bl4653","name":"write","arguments":"{\"file_path\": \"data.txt\", \"content\": \"The replacement line is deliberately longer than the configured sixty-four byte diff-basis bound.\"}"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"46d3792a-eded-45e7-8151-00ca0584f10b"},"usage":{"inputTokens":202,"outputTokens":76,"cacheReadTokens":5760,"reasoningTokens":0}},"sourceEventSeqs":[58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97],"surfaceOp":"append"}
|
||||
{"type":"tool/call","seq":99,"time":1786204703722,"data":{"turn":1,"step":2,"callId":"call_00_ET_7mLiYX652hJA9GW6d1bl4653","name":"write","arguments":"{\"file_path\": \"data.txt\", \"content\": \"The replacement line is deliberately longer than the configured sixty-four byte diff-basis bound.\"}"}}
|
||||
{"type":"tool/result","seq":100,"time":1786204703740,"data":{"turn":1,"step":2,"message":{"source":{"kind":"tool","callId":"call_00_ET_7mLiYX652hJA9GW6d1bl4653"},"content":[{"type":"tool-result","toolCallId":"call_00_ET_7mLiYX652hJA9GW6d1bl4653","content":[{"type":"text","text":"<path>{{cwd}}/data.txt</path>\n<type>file</type>\n<content>\nUpdated file\n</content>"}],"isError":false}],"role":"user","id":"98c41fc1-6ce6-445f-94f7-32aa7e1c6ea7"},"meta":{"diffs":[]}},"sourceEventSeqs":[99],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":101,"time":1786204703740,"data":{"turn":1,"step":2}}
|
||||
{"type":"step/start","seq":102,"time":1786204703749,"data":{"turn":1,"step":3}}
|
||||
{"type":"assistant/chunk","seq":103,"time":1786204705029,"data":{"turn":1,"step":3,"chunk":{"type":"block-start","index":0,"blockType":"text"}}}
|
||||
{"type":"assistant/chunk","seq":104,"time":1786204705029,"data":{"turn":1,"step":3,"chunk":{"type":"text-delta","index":0,"text":"D"}}}
|
||||
{"type":"assistant/chunk","seq":105,"time":1786204705053,"data":{"turn":1,"step":3,"chunk":{"type":"text-delta","index":0,"text":"ONE"}}}
|
||||
{"type":"assistant/chunk","seq":106,"time":1786204705055,"data":{"turn":1,"step":3,"chunk":{"type":"block-end","index":0,"block":{"type":"text","text":"DONE"}}}}
|
||||
{"type":"assistant/chunk","seq":107,"time":1786204705055,"data":{"turn":1,"step":3,"chunk":{"type":"usage","usage":{"inputTokens":100,"outputTokens":3,"cacheReadTokens":6016,"reasoningTokens":0}}}}
|
||||
{"type":"assistant/chunk","seq":108,"time":1786204705056,"data":{"turn":1,"step":3,"chunk":{"type":"finish","reason":{"kind":"stop"}}}}
|
||||
{"type":"assistant/message","seq":109,"time":1786204705057,"data":{"turn":1,"step":3,"message":{"role":"assistant","content":[{"type":"text","text":"DONE"}],"source":{"kind":"model","provider":"deepseek-official","model":"deepseek-v4-flash"},"id":"ddf50859-b0b9-404d-a71c-a1f11ff53341"},"usage":{"inputTokens":100,"outputTokens":3,"cacheReadTokens":6016,"reasoningTokens":0}},"sourceEventSeqs":[103,104,105,106,107,108],"surfaceOp":"append"}
|
||||
{"type":"step/end","seq":110,"time":1786204705057,"data":{"turn":1,"step":3}}
|
||||
{"type":"turn/end","seq":111,"time":1786204705058,"data":{"turn":1,"reason":{"kind":"completed"}}}
|
||||
@@ -0,0 +1,4 @@
|
||||
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentInfo":{"name":"deepseek-harness-acp","version":"0.0.1"},"agentCapabilities":{"promptCapabilities":{"image":false,"audio":false,"embeddedContext":false}},"authMethods":[]}}
|
||||
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}"}}
|
||||
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_message_chunk","content":{"type":"text","text":"DONE"}}}}
|
||||
{"jsonrpc":"2.0","id":3,"result":{"stopReason":"end_turn"}}
|
||||
@@ -0,0 +1 @@
|
||||
original contents
|
||||
@@ -67,7 +67,7 @@ describe('headless-agent keyless smoke', () => {
|
||||
it('keeps the checked-in prepared wrapper identical to the generator output for its manifest', async () => {
|
||||
// The fixture claims "Generated by dsh-plugin-prepare"; this pin makes the
|
||||
// claim true — a wrapper-template change fails here until the fixture is
|
||||
// regenerated, so the assembled smoke can never exercise a stale shape.
|
||||
// regenerated, so the assembled smoke can never exercise stale generated fields.
|
||||
const fixture = fileURLToPath(new URL('./fixtures/repository-plugin/', import.meta.url))
|
||||
const root = await mkdtemp(join(tmpdir(), 'dsh-fixture-drift-'))
|
||||
try {
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write examples/mcp-memory/README.md
|
||||
README.md: 792bb31b668b427c8734286878a9ec98071190d8
|
||||
README.zh.md: 51020f5288c4fbd245914280b8e7e4772e8cad69
|
||||
README.md: 58da672030eaf2ddf70ee92d506de300efcd9650
|
||||
README.zh.md: 0a2f109f9458ec7e1aba50e7fc9b6fd0fca15dbd
|
||||
|
||||
@@ -10,7 +10,7 @@ These third-party configurations are provided as interoperability examples only.
|
||||
|
||||
DSH parses the selected Cordis overlay, starts a configured stdio command or connects to a configured Streamable HTTP URL, discovers MCP tools, and exposes them as `mcp__<serverName>__<tool>`. DSH does **not** download the server, initialize its database, choose its model or embedding provider, create a cloud account, migrate vendor data, or supervise a separate HTTP service. For stdio, the generic client launches and stops the child with the DSH plugin lifecycle; for HTTP, the upstream service must already be running.
|
||||
|
||||
The stdio bridge deliberately removes ambient credential-shaped and `DSH_*` variables before launching a child; other ambient variables remain inherited. Each example adds only the baseline override it needs. If an optional upstream feature needs another secret, add that variable to the row's `config.env` instead of putting the secret directly in YAML.
|
||||
The stdio bridge deliberately removes ambient variables whose names usually identify credentials and all `DSH_*` variables before launching a child; other ambient variables remain inherited. Each example adds only the baseline override it needs. If an optional upstream feature needs another secret, add that variable to the row's `config.env` instead of putting the secret directly in YAML.
|
||||
|
||||
## Choose one
|
||||
|
||||
@@ -95,7 +95,7 @@ A new DSH session is required; a Host restart is not. Restart or HMR is needed o
|
||||
|
||||
## Bring another MCP server
|
||||
|
||||
Copy the same generic shape and use a unique `id` and `serverName`:
|
||||
Copy the same entry fields and use a unique `id` and `serverName`:
|
||||
|
||||
```yaml
|
||||
- insert:
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
DSH 解析选中的 Cordis overlay,启动已配置的 stdio 命令或连接已配置的 Streamable HTTP URL,发现 MCP 工具,并以 `mcp__<serverName>__<tool>` 的形式公开这些工具。DSH **不负责** 下载服务器、初始化其数据库、选择模型或 embedding 提供方、创建云端账户、迁移提供方数据,也不监管独立的 HTTP 服务。对于 stdio,通用客户端会随 DSH 插件生命周期启动和停止子进程;对于 HTTP,上游服务必须已经运行。
|
||||
|
||||
stdio 桥接器在启动子进程前会主动移除环境中名称类似凭据的变量和 `DSH_*` 变量;其余环境变量仍会继承。每份示例仅添加其基线所需的覆盖项。如果某个可选的上游功能还需要其他密钥,请将该变量添加到配置项的 `config.env`,不要把密钥直接写进 YAML。
|
||||
stdio 桥接器在启动子进程前会主动移除环境中名称通常表示凭据的变量和所有 `DSH_*` 变量;其余环境变量仍会继承。每份示例仅添加其基线所需的覆盖项。如果某个可选的上游功能还需要其他密钥,请将该变量添加到配置项的 `config.env`,不要把密钥直接写进 YAML。
|
||||
|
||||
## 选择一个
|
||||
|
||||
@@ -95,7 +95,7 @@ Engram 负责存储和项目选择:它默认使用 `~/.engram`,从 DSH 工
|
||||
|
||||
## 接入其他 MCP 服务器
|
||||
|
||||
复制相同的通用结构,并使用唯一的 `id` 和 `serverName`:
|
||||
复制相同的条目字段,并使用唯一的 `id` 和 `serverName`:
|
||||
|
||||
```yaml
|
||||
- insert:
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write examples/web-cordis/README.md
|
||||
README.md: 21fe0a210b2e591a96dc254014a0f91ed9afa2ba
|
||||
README.zh.md: b3fecb4312dbcbaeff460a21f1d2db6b5288f9ad
|
||||
README.md: 5d46db7e9d4416f0e6327f7e119bc863ffbdc8a6
|
||||
README.zh.md: 9074d8a2dc19b851d85e4fe037f588f70d8da4c7
|
||||
|
||||
@@ -18,4 +18,4 @@ Start the ACP automation server instead:
|
||||
pnpm run demo:cordis acp
|
||||
```
|
||||
|
||||
Both commands require `DEEPSEEK_API_KEY`. The [Cordis tool reference](../../packages/self-modification/tool-cordis/README.md) owns the tool, lifecycle, and safety contracts.
|
||||
Both commands require `DEEPSEEK_API_KEY`. The [Cordis tool reference](../../packages/self-modification/tool-cordis/README.md) defines the tool arguments, lifetime, cleanup, and safety contracts.
|
||||
|
||||
@@ -18,4 +18,4 @@ pnpm run demo:cordis
|
||||
pnpm run demo:cordis acp
|
||||
```
|
||||
|
||||
这两条命令都需要 `DEEPSEEK_API_KEY`。工具、生命周期和安全约定由 [Cordis 工具参考](../../packages/self-modification/tool-cordis/README.md)定义。
|
||||
这两条命令都需要 `DEEPSEEK_API_KEY`。[Cordis 工具参考](../../packages/self-modification/tool-cordis/README.md)定义了四类约定:工具参数、存续时间、清理行为和安全性。
|
||||
|
||||
Reference in New Issue
Block a user