better-dsh 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cordis.patch.yml +1 -1
- package/docs/50_test-reports/2026-09-06-write/345/267/245/345/205/267sandbox/345/215/207/347/272/247/351/200/217/344/274/240bug/345/244/215/345/217/221/345/217/212/346/214/202/350/265/267-/344/272/213/344/273/266/346/212/245/345/221/212.md +176 -0
- package/docs/50_test-reports/2026-09-08-hashline-edit-E_RANGE_UNVERIFIED/350/267/250/350/275/256/344/274/232/350/257/235/351/224/256/345/244/261/346/225/210-/350/257/212/346/226/255/346/212/245/345/221/212.md +226 -0
- package/docs/50_test-reports/2026-09-11-control-prompt-into-eval-description/345/256/236/346/265/213/346/212/245/345/221/212.md +222 -0
- package/docs/50_test-reports/2026-09-12-fs-scheme-resolution-/345/256/236/346/265/213/346/212/245/345/221/212.md +81 -0
- package/docs/50_test-reports/2026-09-12-url-schemes-grammar-matrix/344/270/216catalog-centralize-/345/256/236/346/265/213/346/212/245/345/221/212.md +234 -0
- package/docs/50_test-reports/2026-09-12-url-schemes-recallable-context-design/351/252/214/350/257/201/346/212/245/345/221/212.md +160 -0
- package/docs/50_test-reports/2026-09-12-url-schemes-recallable-context-/345/256/236/346/265/213/345/211/247/346/234/254.md +44 -0
- package/docs/50_test-reports/2026-09-12-url-schemes-recallable-context-/345/256/236/346/265/213/346/212/245/345/221/212.md +89 -0
- package/docs/50_test-reports/2026-09-12-url-schemes-/345/205/255scheme/345/206/222/347/203/237/344/270/216/350/276/271/347/225/214/345/256/236/346/265/213/346/212/245/345/221/212.md +198 -0
- package/docs/50_test-reports/2026-09-13-hashline-off/344/270/213scheme/345/217/257/350/276/276/346/200/247/345/267/245/345/205/267/351/235/242/344/270/215/345/257/271/347/247/260-/345/256/236/346/265/213/346/212/245/345/221/212.md +246 -0
- package/docs/50_test-reports/2026-09-13-preact-ui-shell/345/256/236/346/265/213/346/212/245/345/221/212.md +50 -0
- package/docs/50_test-reports/2026-09-14-4999-skill/346/270/205/345/215/225/344/270/216lsp-gate/345/256/236/346/265/213/346/212/245/345/221/212.md +63 -0
- package/docs/50_test-reports/upstream-dsh-0.1.3-alpha.2-local-test-report.md +44 -0
- package/docs/50_test-reports/upstream-dsh-0.1.3-alpha.2-report.md +110 -0
- package/docs/50_test-reports/upstream-dsh-0.1.5-rc.2-local-test-report.md +79 -0
- package/docs/50_test-reports/v0.2.3b-hashline-content-locator/345/256/236/346/265/213/346/212/245/345/221/212.md +73 -0
- package/docs/50_test-reports/v0.2.3c-mobile-wave/345/256/236/346/265/213/346/212/245/345/221/212.md +47 -0
- package/docs/50_test-reports/v0.2.4-ios-focus-zoom-suppression/345/256/236/346/265/213/346/212/245/345/221/212.md +158 -0
- package/docs/specs/agent/spec.md +54 -0
- package/docs/specs/ast/spec.md +34 -0
- package/docs/specs/compaction-recall/spec.md +46 -0
- package/docs/specs/ctx/spec.md +107 -0
- package/docs/specs/dsh/spec.md +47 -0
- package/docs/specs/dvc/spec.md +87 -0
- package/docs/specs/escalation-guidance/spec.md +44 -0
- package/docs/specs/fs-scheme-resolution/spec.md +37 -0
- package/docs/specs/hash-edit/spec.md +41 -0
- package/docs/specs/http-read/spec.md +73 -0
- package/docs/specs/kernel-provisioning/spec.md +53 -0
- package/docs/specs/lsp/spec.md +121 -0
- package/docs/specs/mobile-layout/spec.md +108 -0
- package/docs/specs/model-failover/spec.md +20 -0
- package/docs/specs/preact-ui-shell/spec.md +22 -0
- package/docs/specs/repl-dispatch-resilience/spec.md +21 -0
- package/docs/specs/skill/spec.md +58 -0
- package/docs/specs/tool-surface/spec.md +222 -0
- package/docs/specs/url-schema/spec.md +148 -0
- package/docs/specs/web-trust-fence/spec.md +43 -0
- package/docs/upstream-dsh-0.1.5-rc.2-report.md +156 -0
- package/dsh-docs/AGENTS.md +75 -0
- package/dsh-docs/agent-lifecycle.md +84 -0
- package/dsh-docs/agent-lifecycle.zh.md +86 -0
- package/dsh-docs/api-gateway.md +164 -0
- package/dsh-docs/api-gateway.zh.md +164 -0
- package/dsh-docs/architecture.md +150 -0
- package/dsh-docs/architecture.zh.md +154 -0
- package/dsh-docs/capability-seams.md +543 -0
- package/dsh-docs/capability-seams.zh.md +545 -0
- package/dsh-docs/config-catalog.md +3473 -0
- package/dsh-docs/config-catalog.zh.md +3474 -0
- package/dsh-docs/cookbook/adding-a-package.md +117 -0
- package/dsh-docs/cookbook/adding-a-package.zh.md +119 -0
- package/dsh-docs/cookbook/adding-a-remote-api.md +197 -0
- package/dsh-docs/cookbook/adding-a-remote-api.zh.md +197 -0
- package/dsh-docs/cookbook/adding-a-session-format-version.md +109 -0
- package/dsh-docs/cookbook/adding-a-session-format-version.zh.md +109 -0
- package/dsh-docs/cookbook/adding-a-settings-card.md +102 -0
- package/dsh-docs/cookbook/adding-a-settings-card.zh.md +102 -0
- package/dsh-docs/cookbook/adding-a-tool.md +101 -0
- package/dsh-docs/cookbook/adding-a-tool.zh.md +103 -0
- package/dsh-docs/cookbook/adding-a-vendored-package.md +59 -0
- package/dsh-docs/cookbook/adding-a-vendored-package.zh.md +59 -0
- package/dsh-docs/cookbook/adding-an-llm-adapter.md +43 -0
- package/dsh-docs/cookbook/adding-an-llm-adapter.zh.md +43 -0
- package/dsh-docs/cookbook/extension-cookbook.md +132 -0
- package/dsh-docs/cookbook/extension-cookbook.zh.md +136 -0
- package/dsh-docs/cookbook/maintaining-dsh-code-review.md +64 -0
- package/dsh-docs/cookbook/maintaining-dsh-code-review.zh.md +64 -0
- package/dsh-docs/cookbook/responding-to-pr-review-on-a-stack.md +32 -0
- package/dsh-docs/cookbook/responding-to-pr-review-on-a-stack.zh.md +32 -0
- package/dsh-docs/cordis-api/context.md +364 -0
- package/dsh-docs/cordis-api/context.zh.md +366 -0
- package/dsh-docs/cordis-api/events.md +207 -0
- package/dsh-docs/cordis-api/events.zh.md +209 -0
- package/dsh-docs/cordis-api/fiber.md +375 -0
- package/dsh-docs/cordis-api/fiber.zh.md +377 -0
- package/dsh-docs/cordis-api/inherited.md +39 -0
- package/dsh-docs/cordis-api/registry.md +152 -0
- package/dsh-docs/cordis-api/registry.zh.md +154 -0
- package/dsh-docs/cordis-api/service.md +102 -0
- package/dsh-docs/cordis-api/service.zh.md +104 -0
- package/dsh-docs/cordis-primer.md +45 -0
- package/dsh-docs/cordis-primer.zh.md +51 -0
- package/dsh-docs/cordis-tutorial/01-first-plugin.md +95 -0
- package/dsh-docs/cordis-tutorial/01-first-plugin.zh.md +95 -0
- package/dsh-docs/cordis-tutorial/02-lifecycle-and-effects.md +98 -0
- package/dsh-docs/cordis-tutorial/02-lifecycle-and-effects.zh.md +98 -0
- package/dsh-docs/cordis-tutorial/03-services.md +98 -0
- package/dsh-docs/cordis-tutorial/03-services.zh.md +98 -0
- package/dsh-docs/cordis-tutorial/04-events.md +144 -0
- package/dsh-docs/cordis-tutorial/04-events.zh.md +144 -0
- package/dsh-docs/cordis-tutorial/05-config.md +84 -0
- package/dsh-docs/cordis-tutorial/05-config.zh.md +84 -0
- package/dsh-docs/cordis-tutorial/06-composition-and-hmr.md +113 -0
- package/dsh-docs/cordis-tutorial/06-composition-and-hmr.zh.md +113 -0
- package/dsh-docs/cordis-tutorial/07-into-the-harness.md +108 -0
- package/dsh-docs/cordis-tutorial/07-into-the-harness.zh.md +108 -0
- package/dsh-docs/cordis-tutorial/index.md +60 -0
- package/dsh-docs/cordis-tutorial/index.zh.md +62 -0
- package/dsh-docs/deepseek-llm-api-wire-extensions.md +163 -0
- package/dsh-docs/deepseek-llm-api-wire-extensions.zh.md +163 -0
- package/dsh-docs/defensive-patterns.md +33 -0
- package/dsh-docs/defensive-patterns.zh.md +35 -0
- package/dsh-docs/development.md +167 -0
- package/dsh-docs/development.zh.md +173 -0
- package/dsh-docs/event-producer-consumer.md +86 -0
- package/dsh-docs/event-producer-consumer.zh.md +88 -0
- package/dsh-docs/glossary.md +45 -0
- package/dsh-docs/glossary.zh.md +45 -0
- package/dsh-docs/graph-atlas.md +22 -0
- package/dsh-docs/graph-atlas.zh.md +24 -0
- package/dsh-docs/i18n/README.md +60 -0
- package/dsh-docs/i18n/README.zh.md +62 -0
- package/dsh-docs/i18n/style-samples.md +87 -0
- package/dsh-docs/i18n/terminology.md +214 -0
- package/dsh-docs/i18n/translation-prompt.md +263 -0
- package/dsh-docs/i18n/translation-rules.md +69 -0
- package/dsh-docs/i18n/translation-rules.zh.md +69 -0
- package/dsh-docs/module-graph.md +1411 -0
- package/dsh-docs/module-graph.zh.md +1413 -0
- package/dsh-docs/persistence-catalog.md +1075 -0
- package/dsh-docs/persistence-catalog.zh.md +1077 -0
- package/dsh-docs/postmortem/0001-acp-default-export-drops-inject.md +113 -0
- package/dsh-docs/postmortem/0001-acp-default-export-drops-inject.zh.md +113 -0
- package/dsh-docs/postmortem/0002-js-expression-disabled-filesystem-tools.md +47 -0
- package/dsh-docs/postmortem/0002-js-expression-disabled-filesystem-tools.zh.md +47 -0
- package/dsh-docs/postmortem/0003-web-agent-gui-feedback-loop.md +53 -0
- package/dsh-docs/postmortem/0003-web-agent-gui-feedback-loop.zh.md +53 -0
- package/dsh-docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.md +55 -0
- package/dsh-docs/postmortem/0004-landlock-partial-notice-misclassified-child-failures.zh.md +55 -0
- package/dsh-docs/postmortem/README.md +18 -0
- package/dsh-docs/postmortem/README.zh.md +18 -0
- package/dsh-docs/rescope.md +53 -0
- package/dsh-docs/rescope.zh.md +53 -0
- package/dsh-docs/session-format-status.md +47 -0
- package/dsh-docs/session-format-status.zh.md +47 -0
- package/dsh-docs/subsystems/README.md +61 -0
- package/dsh-docs/subsystems/README.zh.md +61 -0
- package/dsh-docs/subsystems/agent-team.md +207 -0
- package/dsh-docs/subsystems/agent-team.zh.md +207 -0
- package/dsh-docs/subsystems/approval.md +170 -0
- package/dsh-docs/subsystems/approval.zh.md +170 -0
- package/dsh-docs/subsystems/attachment.md +351 -0
- package/dsh-docs/subsystems/attachment.zh.md +351 -0
- package/dsh-docs/subsystems/client-modules.md +168 -0
- package/dsh-docs/subsystems/client-modules.zh.md +168 -0
- package/dsh-docs/subsystems/client-resources.md +91 -0
- package/dsh-docs/subsystems/client-resources.zh.md +91 -0
- package/dsh-docs/subsystems/code-runtime.md +195 -0
- package/dsh-docs/subsystems/code-runtime.zh.md +195 -0
- package/dsh-docs/subsystems/commands.md +219 -0
- package/dsh-docs/subsystems/commands.zh.md +219 -0
- package/dsh-docs/subsystems/compaction.md +238 -0
- package/dsh-docs/subsystems/compaction.zh.md +238 -0
- package/dsh-docs/subsystems/conversation.md +258 -0
- package/dsh-docs/subsystems/conversation.zh.md +258 -0
- package/dsh-docs/subsystems/core.md +1209 -0
- package/dsh-docs/subsystems/core.zh.md +1219 -0
- package/dsh-docs/subsystems/credentials.md +329 -0
- package/dsh-docs/subsystems/credentials.zh.md +329 -0
- package/dsh-docs/subsystems/extensions.md +382 -0
- package/dsh-docs/subsystems/extensions.zh.md +382 -0
- package/dsh-docs/subsystems/feedback.md +266 -0
- package/dsh-docs/subsystems/feedback.zh.md +266 -0
- package/dsh-docs/subsystems/filesystem.md +505 -0
- package/dsh-docs/subsystems/filesystem.zh.md +505 -0
- package/dsh-docs/subsystems/goal.md +277 -0
- package/dsh-docs/subsystems/goal.zh.md +277 -0
- package/dsh-docs/subsystems/invariants.md +88 -0
- package/dsh-docs/subsystems/invariants.zh.md +88 -0
- package/dsh-docs/subsystems/jobs.md +290 -0
- package/dsh-docs/subsystems/jobs.zh.md +290 -0
- package/dsh-docs/subsystems/llm-streaming.md +1080 -0
- package/dsh-docs/subsystems/llm-streaming.zh.md +1086 -0
- package/dsh-docs/subsystems/lsp.md +202 -0
- package/dsh-docs/subsystems/lsp.zh.md +202 -0
- package/dsh-docs/subsystems/permission-presets.md +131 -0
- package/dsh-docs/subsystems/permission-presets.zh.md +131 -0
- package/dsh-docs/subsystems/persistence.md +395 -0
- package/dsh-docs/subsystems/persistence.zh.md +395 -0
- package/dsh-docs/subsystems/plan.md +87 -0
- package/dsh-docs/subsystems/plan.zh.md +87 -0
- package/dsh-docs/subsystems/sandbox.md +220 -0
- package/dsh-docs/subsystems/sandbox.zh.md +220 -0
- package/dsh-docs/subsystems/schedule.md +192 -0
- package/dsh-docs/subsystems/schedule.zh.md +192 -0
- package/dsh-docs/subsystems/scope.md +59 -0
- package/dsh-docs/subsystems/scope.zh.md +59 -0
- package/dsh-docs/subsystems/session-projection.md +354 -0
- package/dsh-docs/subsystems/session-projection.zh.md +354 -0
- package/dsh-docs/subsystems/session-query.md +509 -0
- package/dsh-docs/subsystems/session-query.zh.md +509 -0
- package/dsh-docs/subsystems/session-reference.md +219 -0
- package/dsh-docs/subsystems/session-reference.zh.md +219 -0
- package/dsh-docs/subsystems/session-telemetry.md +194 -0
- package/dsh-docs/subsystems/session-telemetry.zh.md +194 -0
- package/dsh-docs/subsystems/session-title.md +204 -0
- package/dsh-docs/subsystems/session-title.zh.md +204 -0
- package/dsh-docs/subsystems/session.md +1155 -0
- package/dsh-docs/subsystems/session.zh.md +1159 -0
- package/dsh-docs/subsystems/settings.md +405 -0
- package/dsh-docs/subsystems/settings.zh.md +405 -0
- package/dsh-docs/subsystems/shell.md +303 -0
- package/dsh-docs/subsystems/shell.zh.md +303 -0
- package/dsh-docs/subsystems/sidebar-right.md +148 -0
- package/dsh-docs/subsystems/sidebar-right.zh.md +148 -0
- package/dsh-docs/subsystems/skills.md +354 -0
- package/dsh-docs/subsystems/skills.zh.md +354 -0
- package/dsh-docs/subsystems/slots.md +175 -0
- package/dsh-docs/subsystems/slots.zh.md +175 -0
- package/dsh-docs/subsystems/spill.md +117 -0
- package/dsh-docs/subsystems/spill.zh.md +117 -0
- package/dsh-docs/subsystems/storage.md +260 -0
- package/dsh-docs/subsystems/storage.zh.md +260 -0
- package/dsh-docs/subsystems/subagent.md +766 -0
- package/dsh-docs/subsystems/subagent.zh.md +770 -0
- package/dsh-docs/subsystems/subprocess.md +324 -0
- package/dsh-docs/subsystems/subprocess.zh.md +324 -0
- package/dsh-docs/subsystems/system-prompt.md +220 -0
- package/dsh-docs/subsystems/system-prompt.zh.md +220 -0
- package/dsh-docs/subsystems/terminal.md +184 -0
- package/dsh-docs/subsystems/terminal.zh.md +184 -0
- package/dsh-docs/subsystems/todo.md +32 -0
- package/dsh-docs/subsystems/todo.zh.md +32 -0
- package/dsh-docs/subsystems/token-meter.md +105 -0
- package/dsh-docs/subsystems/token-meter.zh.md +105 -0
- package/dsh-docs/subsystems/tools.md +720 -0
- package/dsh-docs/subsystems/tools.zh.md +720 -0
- package/dsh-docs/subsystems/typert.md +343 -0
- package/dsh-docs/subsystems/typert.zh.md +343 -0
- package/dsh-docs/subsystems/user-questions.md +178 -0
- package/dsh-docs/subsystems/user-questions.zh.md +178 -0
- package/dsh-docs/subsystems/web-client.md +95 -0
- package/dsh-docs/subsystems/web-client.zh.md +95 -0
- package/dsh-docs/subsystems/web-server.md +154 -0
- package/dsh-docs/subsystems/web-server.zh.md +154 -0
- package/dsh-docs/subsystems/web.md +206 -0
- package/dsh-docs/subsystems/web.zh.md +206 -0
- package/dsh-docs/subsystems/webhook.md +70 -0
- package/dsh-docs/subsystems/webhook.zh.md +70 -0
- package/dsh-docs/subsystems/workflow.md +278 -0
- package/dsh-docs/subsystems/workflow.zh.md +278 -0
- package/dsh-docs/subsystems/workspace.md +321 -0
- package/dsh-docs/subsystems/workspace.zh.md +321 -0
- package/dsh-docs/testing.md +54 -0
- package/dsh-docs/testing.zh.md +54 -0
- package/dsh-docs/tool-catalog.md +2225 -0
- package/dsh-docs/tool-catalog.zh.md +2233 -0
- package/dsh-docs/tool-execution-pipeline.md +62 -0
- package/dsh-docs/tool-execution-pipeline.zh.md +64 -0
- package/dsh-docs/user/develop/basic/config.md +106 -0
- package/dsh-docs/user/develop/basic/config.zh.md +106 -0
- package/dsh-docs/user/develop/basic/index.md +144 -0
- package/dsh-docs/user/develop/basic/index.zh.md +144 -0
- package/dsh-docs/user/develop/basic/publish.md +183 -0
- package/dsh-docs/user/develop/basic/publish.zh.md +183 -0
- package/dsh-docs/user/develop/basic/tool.md +52 -0
- package/dsh-docs/user/develop/basic/tool.zh.md +52 -0
- package/dsh-docs/user/develop/framework/events.md +143 -0
- package/dsh-docs/user/develop/framework/events.zh.md +143 -0
- package/dsh-docs/user/develop/framework/index.md +137 -0
- package/dsh-docs/user/develop/framework/index.zh.md +137 -0
- package/dsh-docs/user/develop/framework/service.md +148 -0
- package/dsh-docs/user/develop/framework/service.zh.md +150 -0
- package/dsh-docs/user/develop/practice/dynamic-cordis.md +15 -0
- package/dsh-docs/user/develop/practice/dynamic-cordis.zh.md +15 -0
- package/dsh-docs/user/develop/practice/index.md +155 -0
- package/dsh-docs/user/develop/practice/index.zh.md +155 -0
- package/dsh-docs/user/develop/practice/llm-adapter.md +189 -0
- package/dsh-docs/user/develop/practice/llm-adapter.zh.md +189 -0
- package/dsh-docs/user/guide/github-review.md +102 -0
- package/dsh-docs/user/guide/github-review.zh.md +102 -0
- package/dsh-docs/user/guide/index.md +30 -0
- package/dsh-docs/user/guide/index.zh.md +30 -0
- package/dsh-docs/user/guide/mcp-memory.md +101 -0
- package/dsh-docs/user/guide/mcp-memory.zh.md +101 -0
- package/dsh-docs/user/guide/network-proxy.md +85 -0
- package/dsh-docs/user/guide/network-proxy.zh.md +85 -0
- package/dsh-docs/user/guide/providers.md +190 -0
- package/dsh-docs/user/guide/providers.zh.md +190 -0
- package/dsh-docs/user/guide/python-sdk.md +150 -0
- package/dsh-docs/user/guide/python-sdk.zh.md +150 -0
- package/dsh-docs/user/guide/schedule.md +21 -0
- package/dsh-docs/user/guide/schedule.zh.md +21 -0
- package/dsh-docs/user/index.md +11 -0
- package/dsh-docs/user/index.zh.md +11 -0
- package/dsh-docs/web-styling.md +29 -0
- package/dsh-docs/web-styling.zh.md +29 -0
- package/eval-description.md +33 -0
- package/lib/client/index.js +327 -88
- package/lib/fs-aware/sandbox-plugin.d.ts +71 -0
- package/lib/fs-aware/sandbox-plugin.js +249 -0
- package/lib/index.d.ts +22 -22
- package/lib/index.js +3095 -3204
- package/lib/lsp-server-registry-DkaYmTwt.js +972 -0
- package/lib/lsp-server-registry-_hk-Wcia.js +3 -0
- package/lib/py-sdk-Chvy92MB.js +178 -0
- package/lib/py-sdk.d.ts +19 -2
- package/lib/py-sdk.js +2 -2
- package/lib/wrap-JFjcWwZf.js +747 -0
- package/package.json +9 -3
- package/url-schemes-instruction.md +22 -0
- package/control-prompt.md +0 -37
- package/docs/50_test-reports/v0.1.8d_artifacts/README.md +0 -138
- package/docs/50_test-reports/v0.1.8d_artifacts/code-mode-repl-only.observation.md +0 -74
- package/docs/50_test-reports/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.jsonl +0 -3890
- package/docs/50_test-reports/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.w-sample-0435.jsonl +0 -544
- package/docs/50_test-reports/v0.1.8d_artifacts/functions.json +0 -592
- package/docs/50_test-reports/v0.1.8d_artifacts/skills-catalog.snapshot.md +0 -30
- package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.output-schemas.json +0 -1236
- package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.python.txt +0 -592
- package/docs/50_test-reports/v0.1.8d_artifacts/tools-sdk.typescript.txt +0 -516
- package/docs/50_test-reports/v0.1.8d_artifacts/wire-vs-transcription.diff.md +0 -54
- package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/Cargo.lock +0 -7
- package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/Cargo.toml +0 -6
- package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/src/bin/messy.rs +0 -8
- package/docs/50_test-reports/v0.2.0b_artifacts/f2probe/src/main.rs +0 -4
- package/docs/50_test-reports/v0.2.0b_artifacts/hashline-probe.md +0 -5
- package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/Cargo.lock +0 -7
- package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/Cargo.toml +0 -7
- package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/build.rs +0 -4
- package/docs/50_test-reports/v0.2.0b_artifacts/slowprobe/src/main.rs +0 -13
- package/docs/60_exploration-and-research/cordis-research.md +0 -350
- package/docs/60_exploration-and-research/dsh-web-profile-package-map.md +0 -186
- package/docs/60_exploration-and-research/dsh-web-ui-slot-system-research.md +0 -310
- package/docs/60_exploration-and-research/dsh-webui-strip-boundary-research.md +0 -300
- package/docs/60_exploration-and-research/ios-chat-app-bridge-research.md +0 -324
- package/docs/60_exploration-and-research/web-frontend-composability-research.md +0 -191
- package/docs/REPL-/345/267/245/345/205/267/350/260/203/347/224/250-/346/210/252/346/226/255/350/257/212/346/226/255.md +0 -110
- package/docs/adr/0001-bridge-tool-layer-not-service-layer.md +0 -14
- package/docs/adr/0002-masking-is-presentation-only.md +0 -15
- package/docs/plans/A2A-messaging-channel-test-archive.md +0 -256
- package/docs/plans/code-mode-vs-rlm-ipython-comparison.md +0 -137
- package/docs/plans/dashr-blueprint-review.md +0 -201
- package/docs/plans/dashr-blueprint.md +0 -561
- package/docs/plans/dashr-compaction-window-and-archive.md +0 -307
- package/docs/plans/dashr-profile-layer-feasibility.md +0 -367
- package/docs/plans/dashr-sandbox-escalation-semantics-gap.md +0 -171
- package/docs/plans/dashr-security-sandbox-analysis.md +0 -187
- package/docs/plans/dashr-surface-invariant-and-omp-imports.md +0 -97
- package/docs/plans/ipython-kernel-interactive-interface-test-report.md +0 -152
- package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft.md +0 -146
- package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v3.md +0 -50
- package/docs/plans/kernel-refactoring/Dash-IPython-Control-Prompt-draft_v4.md +0 -79
- package/docs/plans/kernel-refactoring/Dash-vs-PrimeAgent-systemprompt-toolcatalog-comparison.md +0 -138
- package/docs/plans/kernel-refactoring/RLM-system-prompt-injection-gap-report.md +0 -161
- package/docs/plans/kernel-refactoring/V0.1.5-development-plan.md +0 -109
- package/docs/plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_dsh.md +0 -50
- package/docs/plans/kernel-refactoring/actinoable-surface-to-llm-in-agent-runtime_prime.md +0 -113
- package/docs/plans/recallable-compaction.md +0 -147
- package/docs/plans/spike-tag-repro.mjs +0 -102
- package/docs/plans/upstream-analysis.md +0 -128
- package/docs/v0.1.8-improved-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -142
- package/docs/v0.1.8-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -193
- package/docs/v0.1.8b-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -96
- package/docs/v0.1.8c-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -127
- package/docs/v0.1.8d-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -150
- package/docs/v0.1.8d_artifacts/README.md +0 -138
- package/docs/v0.1.8d_artifacts/code-mode-repl-only.observation.md +0 -74
- package/docs/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.jsonl +0 -3890
- package/docs/v0.1.8d_artifacts/dsh-session-session-4a293388-9ae1-474b-87a0-9e17bb556d94.w-sample-0435.jsonl +0 -544
- package/docs/v0.1.8d_artifacts/functions.json +0 -592
- package/docs/v0.1.8d_artifacts/skills-catalog.snapshot.md +0 -30
- package/docs/v0.1.8d_artifacts/tools-sdk.output-schemas.json +0 -1236
- package/docs/v0.1.8d_artifacts/tools-sdk.python.txt +0 -592
- package/docs/v0.1.8d_artifacts/tools-sdk.typescript.txt +0 -516
- package/docs/v0.1.8d_artifacts/wire-vs-transcription.diff.md +0 -54
- package/docs/v0.1.8e-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -224
- package/docs/v0.1.9a-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -168
- package/docs/v0.2.0b-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -123
- package/docs/v0.2.0b_artifacts/f2probe/Cargo.lock +0 -7
- package/docs/v0.2.0b_artifacts/f2probe/Cargo.toml +0 -6
- package/docs/v0.2.0b_artifacts/f2probe/src/bin/messy.rs +0 -8
- package/docs/v0.2.0b_artifacts/f2probe/src/main.rs +0 -4
- package/docs/v0.2.0b_artifacts/hashline-probe.md +0 -5
- package/docs/v0.2.0b_artifacts/slowprobe/Cargo.lock +0 -7
- package/docs/v0.2.0b_artifacts/slowprobe/Cargo.toml +0 -7
- package/docs/v0.2.0b_artifacts/slowprobe/build.rs +0 -4
- package/docs/v0.2.0b_artifacts/slowprobe/src/main.rs +0 -13
- package/docs/v0.2.1-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -110
- package/docs/v0.2.1b-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -86
- package/docs/v0.2.1c-/345/256/236/346/265/213/346/212/245/345/221/212.md +0 -66
- package/lib/py-sdk-BCaOGYz7.d.ts +0 -125
- package/lib/py-sdk-CbgYiX8O.js +0 -691
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
# REPL 工具调用截断诊断(v0.2.1b 实测中发现,2026-09-01)
|
|
2
|
-
|
|
3
|
-
## 结论先行
|
|
4
|
-
|
|
5
|
-
**任何从 REPL(`eval` cell)内部发起的工具调用(`tool.<name>(...)`)都会让 dsh web daemon 进程崩溃并自动重启;会话日志在 `tool/code-dispatch-start` 处撕裂,恢复时 repair 机制合成「interrupted-tool-result」,模型看到的即「工具调用被截断、结果未知」。** 4 次探针 4 次复现,与 journald 守护进程崩溃记录逐条对应。
|
|
6
|
-
|
|
7
|
-
这不是 REPL 同步/异步的问题,也不是 subagent 特有问题——是 dashr 子分派桥接层的结构性缺陷 + 部署运行态注册表视图缺 symbol 的直接原因叠加。
|
|
8
|
-
|
|
9
|
-
## 一、复现矩阵(第一人称)
|
|
10
|
-
|
|
11
|
-
| # | cell 内容 | 结果 |
|
|
12
|
-
|---|---|---|
|
|
13
|
-
| 1 | `await tool.subagent({… run_in_background: false })` | 截断(daemon 崩溃 17:39:17) |
|
|
14
|
-
| 2 | `await tool.subagent({… run_in_background: true })` | 截断(daemon 崩溃 17:41:15) |
|
|
15
|
-
| 3 | `await tool.bash({… run_in_background: true })` | 截断(daemon 崩溃 17:57:05) |
|
|
16
|
-
| 4 | `await tool.read({path: "dashr/package.json"})` | 截断(daemon 崩溃 18:02:27) |
|
|
17
|
-
|
|
18
|
-
对照:纯 Python cell(`dir(tool)`、顶层 `return` 判错、`await asyncio.sleep(0)`)全部正常。**凡含 `tool.*` RPC 的 cell 必崩,与工具、与 background 与否无关。**
|
|
19
|
-
|
|
20
|
-
## 二、截断面定位(三层证据)
|
|
21
|
-
|
|
22
|
-
### 1. 会话日志(`~/.dsh/sessions/…/session.jsonl.zstd`)
|
|
23
|
-
4 次截断的共同指纹:`tool/call (eval)` → `tool/code-dispatch-start`(**已持久化**)→ 日志撕裂(无 `tool/code-dispatch`、无 `step/end`/`turn/end`)→ 重载时 `packages/core/session/src/repair.ts` 的 `interruptedTurnClosers` 合成 `interrupted-tool-result-<callId>-<seq>`(`TOOL_OUTCOME_UNKNOWN`)。会话内 **0 条 error 事件**——错误根本没走到会话层。
|
|
24
|
-
|
|
25
|
-
### 2. 守护进程日志(`journalctl --user -u dsh.service`)——铁证
|
|
26
|
-
```
|
|
27
|
-
Sep 01 17:39:17 pnpm[414449]: dsh: fatal load failure: TypeError: Cannot read properties of undefined (reading 'prepare')
|
|
28
|
-
at Object.start (…/better-dsh/lib/index.js:11281:41)
|
|
29
|
-
at <anonymous> (…/lib/index.js:11191:21)
|
|
30
|
-
at drive (…/lib/index.js:11207:7)
|
|
31
|
-
at outcome (…/lib/index.js:11310:6)
|
|
32
|
-
at new Promise (<anonymous>)
|
|
33
|
-
at toolFunctions.<computed> (…/lib/index.js:11320:72)
|
|
34
|
-
at Proxy.dispatchHostRequest (…/lib/index.js:2180:21)
|
|
35
|
-
Sep 01 17:39:19 systemd: dsh.service: Main process exited, code=exited, status=1/FAILURE
|
|
36
|
-
Sep 01 17:39:23 systemd: dsh.service: Scheduled restart job, restart counter is at 1.
|
|
37
|
-
```
|
|
38
|
-
17:39:17 / 17:41:15 / 17:57:05 / 18:02:27 四次崩溃,栈完全一致。`scheduler.prepare` 中 `scheduler` 为 `undefined`——即 `registry[TOOL_RUNTIME_SCHEDULER]` 在部署运行态取不到值。
|
|
39
|
-
|
|
40
|
-
### 3. 源码链(`dashr/src/index.ts`)
|
|
41
|
-
- kernel 侧:`tool.<name>(...)` → `binding.call` RPC(`src/bootstrap.ts` `_dashr_callable`)。
|
|
42
|
-
- host 侧:`dispatchHostRequest`(`src/runtime.ts:545`)→ `await fn(args)`(`src/index.ts` `binding()`)。
|
|
43
|
-
- `binding()` 内部(`src/index.ts:666`):`const scheduler = registry[TOOL_RUNTIME_SCHEDULER]` → 单驱动道 `drive()`(`src/index.ts:591-621`)→ `start()` 内 `await scheduler.prepare(input)`(`src/index.ts:712`)。
|
|
44
|
-
- **结构性缺陷**:`drive()` 的 async IIFE 是 `try { … } finally { … }`,**没有 catch**;调用处是 `void drive()`。任何 `start()`/`commit()` 抛错(如 `scheduler.prepare` TypeError)都会变成 **unhandled rejection**——binding promise 既不 resolve 也不 reject,cell 永久挂起,错误外泄给进程。
|
|
45
|
-
**完整链条**:cell 工具调用 → dispatch 启动(`code-dispatch-start` 已入日志)→ `registry[TOOL_RUNTIME_SCHEDULER]` 为 undefined → `scheduler.prepare` TypeError → driver 无 catch → unhandled rejection → `installFailLoud` 判定 fatal → daemon exit(1) → systemd 重启 → 会话重载 repair 合成「interrupted-tool-result」→ 模型收到截断消息。**截断面:binding 桥 → registry symbol 查询 → driver 的未处理拒绝。**
|
|
46
|
-
|
|
47
|
-
## 三、命名澄清:REPL dispatch log 与 code-dispatch 是两个不同层(重要)
|
|
48
|
-
|
|
49
|
-
容易混淆,先分清:
|
|
50
|
-
|
|
51
|
-
| 名字 | 层级 | 是谁 | 本次 change 是否改名 |
|
|
52
|
-
|---|---|---|---|
|
|
53
|
-
| `tool/code-dispatch-start` / `tool/code-dispatch` | **会话持久日志事件**(durable log,`agent.session.append`) | dashr `src/index.ts:689,712`;harness `known-event-types.ts:63-64` 注册 | **否**——v0.1.x 就有,历史遗留名 |
|
|
54
|
-
| `dashr/repl-dispatch-log` | **waterfall 扩展点**(内容整形监听事件) | dashr 自注册(`src/index.ts:458`) | **是**——v0.2.1 从上游 `tools/code-dispatch-log`/`tools/ptc-dispatch-log` 改名为「自己的 REPL dispatch log」 |
|
|
55
|
-
| `tools/ptc-dispatch-log` | waterfall(上游 PTC 用) | harness `src/ptc.ts:282` + spill policy 监听(`spill-policy/src/index.ts:217`) | dashr 已不再 emit(仅注释提及) |
|
|
56
|
-
|
|
57
|
-
**结论**:
|
|
58
|
-
- 「自己的 REPL dispatch log」`dashr/repl-dispatch-log` **在代码里存在且自注册**——目标形态已就位。它之所以「没被触发」,是因为崩溃发生在它之前的 `scheduler.prepare`(它在 settle 之后才跑)——**是崩溃的结果,不是原因**。
|
|
59
|
-
- 会话日志里我用作定位证据的 `tool/code-dispatch-start` 是**持久日志事件名**,与 waterfall 改名无关,只是「撕裂点之前最后一条已写入事件」的定位标记。
|
|
60
|
-
- 改名引入了一个**真实但非崩溃的副作用**:harness 的 spill policy 仍监听上游 `tools/ptc-dispatch-log`,dashr 不再 emit → 溢出限幅(oversized 结果的 preview+locator 替换)对 eval 子调用日志**静默失效**。**已补(2026-09-01 晚,见六)**:dashr `shapeDispatchLog` 跑完 `dashr/repl-dispatch-log` 后,再把同一 dispatch(载荷结构与上游 `PtcDispatchLog` 完全一致)喂进 `tools/ptc-dispatch-log` 载体,spill 臂恢复生效。改动在 `dashr/src/index.ts`,lib 已重建(`f0febba7…`),**部署位同步 + daemon 重启待用户执行**。
|
|
61
|
-
|
|
62
|
-
## 四、为什么 `registry[TOOL_RUNTIME_SCHEDULER]` 是 undefined(直接原因)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
- 已排除:dsh-tools 双副本 symbol 不一致(实测插件与 daemon 均解析到同一 realpath `/home/u1/workspaces/dsh-alpha/packages/core/tools`,symbol 严格相等);dashr 分派代码改动(266d232/06e516a/HEAD 逐字节一致);dsh-tools alpha.1 vs alpha.3 差异(仅 import 整理/ToolCallId brand 等外观差异)。
|
|
66
|
-
- 关键观察:`classify()` 调用的 `registry.executionMode(input)` **正常**(`code-dispatch-start` 已写入日志,证明 `start()` 之前的分派逻辑跑通),而 `registry[TOOL_RUNTIME_SCHEDULER]` **取不到**。`executionMode` 是 ToolRuntime 类方法、`TOOL_RUNTIME_SCHEDULER` 是类实例 symbol 字段——即部署运行态 `runtimeCtx.tools` 返回的**不是原生 ToolRuntime 实例**,而是一个有方法、缺实例 symbol 字段的服务视图(cordis 作用域服务解析 / plugin tree 挂载路径差异)。
|
|
67
|
-
- 测试为什么全绿:dashr 测试组合(`test/helpers.ts`)把 `ctx.tools` 解析到**根作用域的原生 ToolRuntime 实例**,symbol 在位;生产组合经 harness plugin tree / scope 层解析,拿到的是视图。
|
|
68
|
-
- **何时坏的(重要修正)**:v0.1.8 实测报告(2026-08-24)实证 DASHR 自己的 `eval` 桥当时**正常工作**——同 cell 并发 `tool.read` + `tool.bash` 完成。2026-08-28 会话用的是 harness 自带 PTC `run_cell`(`tools.bash`,复数命名空间 = PTC SDK 形态;该 PTC 核心经 `@deepseek-ai/dsh-code-runtime-python` 执行 **Python**,非 TS),不能代表 dashr 桥状态。**崩溃由 2026-09-01 的 harness alpha(0.1.2-alpha.1)升级引入**——升级后 plugin tree 里 `runtimeCtx.tools` 变成缺实例 symbol 字段的服务视图;dashr v0.2.1 的 dispatch-log 改名不是崩溃原因。
|
|
69
|
-
|
|
70
|
-
## 五、REPL 同步/异步问题的回答(顺带闭环)
|
|
71
|
-
|
|
72
|
-
- 模型层:`eval` 是同步工具调用,模型等 cell 结果——这是设计使然,与缺陷无关。
|
|
73
|
-
- cell 内:`tool.<name>(...)` 是 kernel→host 的 `binding.call` RPC,被 cell `await`;host 经与原生调用同一 registry 分派器执行。`run_in_background: true` 的工具实现**快速返回 id**(subagent `{kind:'continuable', subagentId}`、bash 返回 job id),background 语义本应保留、子任务与 cell 结束无关。
|
|
74
|
-
- 但**当前运行时该路径整体坏掉**:任何子分派在 `scheduler.prepare` 即 TypeError,与 background 无关——所以「在 REPL 里 background 是否异步」目前是伪问题,路径不通;修好后 background 语义会按上述设计成立。
|
|
75
|
-
|
|
76
|
-
## 六、修复方向(分层)
|
|
77
|
-
|
|
78
|
-
1. **dashr 立即修(阻断 daemon 崩溃)**:`drive()` 加 catch / `start()`、`commit()` 失败必须 settle binding promise 为错误结果——cell 内工具调用失败应变成可见的 `ToolCallError`,**绝不允许以 unhandled rejection 外泄杀 daemon**。这是把「任何分派错误」放大成「整个运行时崩溃」的放大器,无论直接原因是什么都必须先修。
|
|
79
|
-
2. **dashr 防御**:`registry[TOOL_RUNTIME_SCHEDULER]` 为 undefined 时抛带上下文的 loud 错误(cell 可见),而不是裸 `undefined.prepare` TypeError。
|
|
80
|
-
3. **根因定位(harness 接线)**:在活体 daemon 上探针确认 plugin tree 中 `runtimeCtx.tools` 的实际对象(cordis 作用域服务视图 / 第二个 tools 实例),修正挂载使插件拿到原生 ToolRuntime(symbol 在位)。这一步需要 daemon 侧可写环境(本会话 bwrap 沙箱只读宿主,无法直接探查活体)。
|
|
81
|
-
4. **测试补强(部分完成)**:已加「`tools/ptc-dispatch-log` 载体回喂」回归用例(`test/bridge.spec.ts`,全量 396 绿)。仍缺「生产形态」挂载测试——按 harness 的 plugin-tree/scope 方式挂载插件,断言 `ctx.tools[TOOL_RUNTIME_SCHEDULER]` 已定义 + 一个真实工具 RPC 从 cell 完成;防止此环境差异回归。
|
|
82
|
-
5. **回归核验基线**:修复后重跑本文档第一节的 4 探针矩阵(4/4 应全部返回结果而非截断),并观察 `journalctl --user -u dsh.service` 无新崩溃。
|
|
83
|
-
|
|
84
|
-
## 附:证据文件
|
|
85
|
-
- 会话日志:`~/.dsh/sessions/--home-u1-workspaces-dashr--/session-ad9ac311-3400-4304-b501-e7303da850df/session.jsonl.zstd`
|
|
86
|
-
- 守护进程日志:`journalctl --user -u dsh.service`(17:39:17 / 17:41:15 / 17:57:05 / 18:02:27 四条 fatal load failure)
|
|
87
|
-
- 对照工作会话:`06ac8b2c-fb2e-458f-80d6-a0d28e50f193`(2026-08-28,9 对完整 code-dispatch,PTC run_cell 路径)
|
|
88
|
-
|
|
89
|
-
---
|
|
90
|
-
|
|
91
|
-
## 七、v0.2.1c 修复执行记录(2026-09-01,change v0-2-1c-repl-tool-crash-fix)
|
|
92
|
-
|
|
93
|
-
### 六.1 + 六.2 已实现(dashr 侧)
|
|
94
|
-
|
|
95
|
-
- `drive()` async IIFE 补 `catch`:lane 级 backstop——任何逃逸 start()/commit() 自身包裹的错误(或 classify() 抛错)settle 所有 queued-but-unsettled 分派为可见错误、清空队列、复位 exclusive、记 warn,**绝不外泄 unhandled rejection**。
|
|
96
|
-
- `PendingDispatch` 新增 `fail(error)`:把 binding promise settle 为 `{ isError: true, message }`(经 `settleError` → `settle`,kernel 转 `ToolCallError`)。
|
|
97
|
-
- `start()` / `commit()` 各自 try/catch:prepare 失败、dispatch body rejection、finalize/finish 失败都 settle 自己的 binding,不再向 lane 抛。
|
|
98
|
-
- `binding()` 内 `registry[TOOL_RUNTIME_SCHEDULER]` 判空:undefined 时抛带上下文的 loud 错误(点名 symbol、指向 harness 挂载接线),替代裸 `undefined.prepare` TypeError。
|
|
99
|
-
- 回归测试 3 个(`test/bridge.spec.ts`,全量 399 绿含 3 新):view 缺 symbol → cell 收到含 `TOOL_RUNTIME_SCHEDULER` 的 loud 错误;`scheduler.prepare` 抛错 → binding settle 为可见错误;classify 抛错 → lane backstop settle 且进程存活。
|
|
100
|
-
|
|
101
|
-
### 六.3 根因探针(本轮结论,待活体 daemon 复核)
|
|
102
|
-
|
|
103
|
-
- **根因已锁定并更正(2026-09-02 活体探针 + 受控实验;推翻本节 2026-09-01 的 shadow 分支推断)**:真实根因是**部署拓扑 dual-copy**——崩溃期(2026-09-01 17:39–18:02)部署位插件嵌套 `node_modules/@deepseek-ai/*` 的 17 条 symlink(已退役 dev 接线)指向 dsh-alpha 源码树,插件 import 的 `TOOL_RUNTIME_SCHEDULER` 来自 alpha 副本的 dsh-tools 模块实例;daemon 的 `ToolRuntime` 实例由 host vendored 副本构建,其 symbol 字段以 host 副本 symbol 为键。两 symbol 为不同 `Symbol()` 实例:跨副本读实例字段 → `undefined`(`executionMode` 等字符串键方法不受影响、照常工作——症状逐字吻合)。
|
|
104
|
-
- 证据链(2026-09-02):① 活体 4 探针(`tool.bash` fg/bg、`tool.read`、`tool.subagent` bg:false/bg:true)经 `eval` cell 路径 4/4 真实结果——现行生产形态 symbol 在位;② 部署位 `require.resolve('@deepseek-ai/dsh-tools')` = `/home/u1/.local/lib/node_modules/@deepseek-ai/dsh/node_modules/@deepseek-ai/dsh-tools/lib/index.js`(host vendored,③→④ 层);③ 受控实验:host 与 z_dsh-alpha 两副本 `TOOL_RUNTIME_SCHEDULER` 严格不等,host 键实例经 alpha symbol 读 → `undefined`、经 host symbol 读 → object;④ 时间线闭环:改名 `dsh-alpha → z_dsh-alpha`(2026-09-01 22:29)→ symlink 悬空 → 2026-09-02 清理删除 → daemon 重启 → 自愈。
|
|
105
|
-
- shadow 分支理论为何被否:它与症状吻合但从未被活体证实,且无法解释「拓扑清理 + 重启后自愈」;dual-copy 机制同时解释故障与恢复。v0.2.1c 报告引「symbol 严格相等」的排除测量与崩溃期拓扑矛盾(疑测同一副本两次或取于改名后),以直接证据为准。
|
|
106
|
-
- cordis traceable proxy 本身无嫌疑(symbol 转发分支在位;现行活体 plain read 即返回带 symbol 原生实例)。
|
|
107
|
-
- dashr 侧交付边界:六.1+六.2(不崩溃 + loud 错误)继续有效;dual-copy 已由部署拓扑收敛消除(部署纪律:插件 `node_modules/@deepseek-ai/` 只留 `schemastery`+`cosmokit`);v0.2.1d 给 guard 错误附 dsh-tools 解析路径实现事件自诊断。
|
|
108
|
-
### 六.4 生产形态挂载测试(说明)
|
|
109
|
-
|
|
110
|
-
- 三个回归用例以「缺 symbol 视图」「prepare 抛错」「classify 抛错」三种形态驱动 `createRunCellTool`,覆盖六.1+六.2 全部防御面;测试组合(根作用域原生实例)本就 symbol 在位,断言 `runtimeCtx.tools[TOOL_RUNTIME_SCHEDULER]` 定义的用例属于测试组合自身形态(根挂载原生实例),无法复现生产 realm 差异——该差异须在活体 daemon 上复核(六.5)。
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# Bridge the tool layer, not the service layer
|
|
2
|
-
|
|
3
|
-
DASHR's `rlm()` family dispatches upstream delegation tools through the tool registry (nested sub-dispatch), not `ctx.subagents` service methods. The tool layer carries the deployment's enforcement surface — approval pipeline, sandbox policy, per-instance config (maxDepth, backgroundMode, persona) — that a direct service call would silently bypass. The cost: per-call model selection is impossible, because the tool schema exposes no `model` parameter; `rlm(model=...)` from 0.1.4 is dropped, and `subagentModel` degrades to a static `agentOptions.model` in the preset patch.
|
|
4
|
-
|
|
5
|
-
## Considered Options
|
|
6
|
-
|
|
7
|
-
- **Service layer direct** (0.1.4's approach): `ctx.subagents.start()` with a hand-built request. Full control over request fields (including `agentOptions.model` and `maxDepth`), but every policy the tool instance would have applied must be re-implemented or lost.
|
|
8
|
-
- **Tool layer nested dispatch** (chosen): `rlm("spawn")` executes the registry's `subagent` tool with a parent token. Upstream policy is inherited wholesale; the schema boundary is the tool's own contract.
|
|
9
|
-
|
|
10
|
-
## Consequences
|
|
11
|
-
|
|
12
|
-
- `rlm(mode, prompt, *, label, run_in_background)` — no `model` kwarg. Parent-model inheritance is the default; a different child model requires a preset patch, not a call argument.
|
|
13
|
-
- Depth enforcement comes from the tool instance's `maxDepth` config, patched to 10 in the preset (see `dev/kernel-refactoring/V0.1.5-development-plan.md` Q22/Q23).
|
|
14
|
-
- The upstream delegation tools (`subagent`, `subagent_fork`, `interrupt_agent`) must stay registered and executable even though the model never sees their names — which is why masking is presentation-only (ADR-0002).
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# Masking is presentation-only
|
|
2
|
-
|
|
3
|
-
Hiding exactly two upstream A2A tool names (`send_message` — the parent→child downlink — and `report` — the child→parent uplink) from the model is done by excluding them from the generated Tool Catalog text and from the kernel binding names — nothing else. The two tools stay registered, executable, and dispatchable; the single `send_message` bridge dispatches them internally. Every OTHER upstream delegation tool (`subagent`, `subagent_fork`, `list_agents`, `interrupt_agent`, `workflow`, `ralph`) is exposed directly as a native `tool.*` member — no re-wrapping (v0.1.9).
|
|
4
|
-
|
|
5
|
-
## Considered Options
|
|
6
|
-
|
|
7
|
-
- **`restrict()` at runtime**: hides names in the registry's model-facing view, but validates against the live view at call time — ordering hazards against late tool registration can fail the whole preset mount.
|
|
8
|
-
- **`disabled: true` include patches**: physically unregisters the tool, which also removes the bridge's dispatch target. Masking must not break the bridge.
|
|
9
|
-
- **Presentation-only exclusion** (chosen): the registry is never touched. The model's surface (wire schema collapse to `eval`, Tool Catalog text, kernel bindings) is entirely DASHR-generated, so exclusion happens at the two points DASHR owns.
|
|
10
|
-
|
|
11
|
-
## Consequences
|
|
12
|
-
|
|
13
|
-
- The masked tools remain in the registry and are reachable via nested sub-dispatch with a parent token, which passes the model-direct guard.
|
|
14
|
-
- **Field-verified (v0.1.8d, `both` presentation mode)**: reachable by MODEL-DIRECT native call too — no parent token needed. A probe calling the masked `skill({"name":…})` through the API function-call surface executed in full. Cause: the mask registers no visibility filter, so the name stays in `view(scope).visible`, and `resolveExecution` collapses model-direct calls only under `code` mode. The mask is an ADVERTISING cut, not an enforcement point; the hard gate is the REPL binding allowlist (`unknown binding`). If a deployment ever needs true model-direct rejection, the mechanisms are a visibility-layer `restrict()` (rejected here for ordering hazards) or a `code`-mode collapse — both are deployment-level decisions, not mask-level ones.
|
|
15
|
-
- Zero upstream mutation means zero interference with host-plane modules that enumerate or interact with the delegation tools.
|
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
# Dash 运行时 A2A Messaging Channel 实测存档
|
|
2
|
-
|
|
3
|
-
> 实测日期(UTC):2026-08-17T17:57:57Z
|
|
4
|
-
> 实测主体:Dash Agent 运行时自身(root session,`deepseek-v4-pro`)
|
|
5
|
-
> 工作区:`/home/u1/workspaces/dashr`
|
|
6
|
-
> 方式:全程通过 `run_cell` 调用 `tools.*` 实际执行,所有结论均来自真实工具返回,非文档推断。
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## 1. 测试目标与范围
|
|
11
|
-
|
|
12
|
-
验证 Dash 运行时的 **A2A(Agent-to-Agent)messaging channel** 是否实现及其边界。
|
|
13
|
-
|
|
14
|
-
Dash 运行时按 **session 树** 划分 agent,因此 A2A 关系可归为三类:
|
|
15
|
-
|
|
16
|
-
1. **Parent ↔ Child**(双向)
|
|
17
|
-
2. **Siblings**(同父、同层)
|
|
18
|
-
3. ~~Out of family tree~~(跨 family tree)
|
|
19
|
-
|
|
20
|
-
第 3 类**天然不在范围**:运行时没有全局 session 总线,消息路由完全基于 session 树的 `parentSession` 指针。本存档只实测第 1、2 类,并以一个 grandchild 场景做旁证。
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## 2. 实测拓扑(真实 session 树)
|
|
25
|
-
|
|
26
|
-
从 root 视角 `list_agents(scope=descendants)` 及各 session 头部记录还原:
|
|
27
|
-
|
|
28
|
-
```text
|
|
29
|
-
ROOT(me) session-d11e193f-a813-4200-96b1-0465ae8e8063 depth=0 parentSession=null preset=standard
|
|
30
|
-
├── A f743dca9-3953-4382-ac45-487a27df9db1 depth=1 parentSession=ROOT preset=rlm-mode
|
|
31
|
-
│ └── G 057bd298-d186-4eb4-bb5c-4a6ee2c158cd depth=2 parentSession=A preset=rlm-mode
|
|
32
|
-
└── B 06ac8b2c-fb2e-458f-80d6-a0d28e50f193 depth=1 parentSession=ROOT preset=rlm-mode
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
各 session 头部记录(`session.jsonl.zstd` 首行,`type=session`)实测摘录:
|
|
36
|
-
|
|
37
|
-
| agent | id | parentSession | origin | delegationDepth | agentPreset |
|
|
38
|
-
|---|---|---|---|---|---|
|
|
39
|
-
| root | `session-d11e193f-a813-4200-96b1-0465ae8e8063` | `null` | `null` | 0 | `standard` |
|
|
40
|
-
| A | `f743dca9-3953-4382-ac45-487a27df9db1` | `session-d11e193f-...` | `subagent` | 1 | `rlm-mode` |
|
|
41
|
-
| B | `06ac8b2c-fb2e-458f-80d6-a0d28e50f193` | `session-d11e193f-...` | `subagent` | 1 | `rlm-mode` |
|
|
42
|
-
| G | `057bd298-d186-4eb4-bb5c-4a6ee2c158cd` | `f743dca9-3953-...` | `subagent` | 2 | `rlm-mode` |
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## 3. 关键机制发现
|
|
47
|
-
|
|
48
|
-
### 3.1 身份:subagent id == 子 session id == `DSH_SESSION_ID`
|
|
49
|
-
|
|
50
|
-
`subagent(..., run_in_background=true)` 返回的 `subagentId` 就是子 session 的 id,也等于子 agent 进程内的 `DSH_SESSION_ID`。
|
|
51
|
-
|
|
52
|
-
- spawn A 返回:`{"kind":"continuable","subagentId":"f743dca9-3953-4382-ac45-487a27df9db1"}`
|
|
53
|
-
- A 自报:`DSH_SESSION_ID=f743dca9-3953-4382-ac45-487a27df9db1`(一致)
|
|
54
|
-
|
|
55
|
-
### 3.2 父身份:不暴露在 env / list_agents,只写在子 session 日志头部
|
|
56
|
-
|
|
57
|
-
子 agent **无法**通过环境变量(无 `DSH_PARENT_*`)或 `list_agents`(只显示自己的 children/descendants)得知父身份。
|
|
58
|
-
|
|
59
|
-
但父身份写在子 agent **自己的** `session.jsonl` 头部 `parentSession` 字段里。B 实测是读自己 session 日志首条记录发现的:
|
|
60
|
-
|
|
61
|
-
```json
|
|
62
|
-
{"type":"session","id":"06ac8b2c-...","parentSession":"session-d11e193f-a813-4200-96b1-0465ae8e8063","origin":"subagent","delegationDepth":1,"agentPreset":"rlm-mode"}
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
### 3.3 路由规则(核心)
|
|
66
|
-
|
|
67
|
-
`send_message(caller, target)` 仅当 **`target.parentSession == caller.sessionId`** 时放行,即 **只能给自己的“直接子”发消息**。
|
|
68
|
-
|
|
69
|
-
越界时统一抛 `ToolCallError`:
|
|
70
|
-
> `subagent "<id>" belongs to another parent session`
|
|
71
|
-
|
|
72
|
-
---
|
|
73
|
-
|
|
74
|
-
## 4. 测试矩阵与结果
|
|
75
|
-
|
|
76
|
-
### 4.1 Parent ↔ Child ✅(可用,但**不对称**)
|
|
77
|
-
|
|
78
|
-
| 方向 | 通道 | 结果 | 证据 |
|
|
79
|
-
|---|---|---|---|
|
|
80
|
-
| Parent→Child | `send_message`(显式下行) | ✅ 可用,可递归 | 见下 |
|
|
81
|
-
| Child→Parent | completion notice(完成回传) | ✅ 可用 | A/B/G 每次 final message 都回到 root |
|
|
82
|
-
| Child→Parent | `send_message`(显式上行 push) | ❌ 不可用 | `belongs to another parent session` |
|
|
83
|
-
|
|
84
|
-
**下行实测(都回传了 token):**
|
|
85
|
-
- root→A:`DOWN_PING_8841` → A 回 `DOWN_OK` ✅
|
|
86
|
-
- root→B:`RELAY_OK` → B 回 `RELAY_OK` ✅
|
|
87
|
-
- A→G:`G_ECHO_PING` → G 回 `G_ECHO_OK` ✅(证明子 agent 可递归当父节点)
|
|
88
|
-
|
|
89
|
-
**上行实测:**
|
|
90
|
-
- A 调 `send_message(subagent_id="session-d11e193f-...", ...)` → 抛错 `subagent "session-d11e193f-..." belongs to another parent session` ❌
|
|
91
|
-
|
|
92
|
-
> 结论:下行是显式消息通道;上行只有“交结果”的完成回传,**不是对等双向**。
|
|
93
|
-
|
|
94
|
-
### 4.2 Siblings ❌(无直接通道)
|
|
95
|
-
|
|
96
|
-
- **A→B 直接发消息**:抛错 `subagent "06ac8b2c-fb2e-458f-80d6-a0d28e50f193" belongs to another parent session` ❌
|
|
97
|
-
- **不可见**:A 视角 `list_agents(scope=children)` 与 `scope=descendants` 均返回 `[]`,看不到 sibling B;sibling 关系只有共同父节点(root)能通过 `list_agents` 看到。
|
|
98
|
-
- **唯一通路**:经共同 parent 中转(A 交回 root → root 转发给 B)。实测 root→B 中转腿可行。
|
|
99
|
-
|
|
100
|
-
### 4.3 Grandchild(旁证:规则不特判、只认“直接子”)
|
|
101
|
-
|
|
102
|
-
- root→G(depth 2)直接发消息:抛错 `subagent "057bd298-..." belongs to another parent session` ❌
|
|
103
|
-
- 说明 sibling / 向上 / 跨层 全被同一条规则挡下,**不是针对 sibling 的特判**。
|
|
104
|
-
|
|
105
|
-
---
|
|
106
|
-
|
|
107
|
-
## 5. 原始证据汇总
|
|
108
|
-
|
|
109
|
-
**关键消息 ID(`send_message` 返回):**
|
|
110
|
-
- root→A(DOWN 测试):`400063ce-b604-48db-b853-5bc2811df8e2`
|
|
111
|
-
- root→B(RELAY 测试):`946106a9-59e3-4527-8eba-211999289db4`
|
|
112
|
-
- A→G(follow-up):`590760b1-443d-4124-a0f9-8bbfc26f0eef`
|
|
113
|
-
- A 交叉测试指令:`ace2038e-ca4a-499b-8754-77b1d5c4cacb`
|
|
114
|
-
|
|
115
|
-
**统一拒绝错误(3 处实测一致):**
|
|
116
|
-
```
|
|
117
|
-
ToolCallError(send_message): subagent "<id>" belongs to another parent session
|
|
118
|
-
```
|
|
119
|
-
分别出现在:A→B(sibling)、A→root(上行)、root→G(跨层)。
|
|
120
|
-
|
|
121
|
-
---
|
|
122
|
-
|
|
123
|
-
## 6. 结论
|
|
124
|
-
|
|
125
|
-
1. **A2A messaging channel 已实现,但形态是“树上的定向消息 + 完成回传”,不是全局对等消息总线。**
|
|
126
|
-
2. 边界严格由 `parentSession` 指针决定:`send_message` 只到**自己的直接子**。
|
|
127
|
-
3. **Parent↔Child**:下行可用且可递归;上行仅有完成回传,无显式 push。
|
|
128
|
-
4. **Siblings**:无直接通道、不可见,只能经共同父节点中转。
|
|
129
|
-
5. **Out of family tree / 跨层**:被同一条路由规则拒绝,符合“无全局总线”的预判。
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## 7. 遗留
|
|
134
|
-
|
|
135
|
-
测试产生的子 agent A、B、G 当前均处于 `ready`(空闲可续),不会再执行任务,除非继续 `send_message`。
|
|
136
|
-
- A = `f743dca9-3953-4382-ac45-487a27df9db1`
|
|
137
|
-
- B = `06ac8b2c-fb2e-458f-80d6-a0d28e50f193`
|
|
138
|
-
- G = `057bd298-d186-4eb4-bb5c-4a6ee2c158cd`
|
|
139
|
-
|
|
140
|
-
---
|
|
141
|
-
|
|
142
|
-
# 附录(2026-08-17 追加):Prime Agent 参照调查 — Finisher 事件实录与通道对比
|
|
143
|
-
|
|
144
|
-
> 追加背景:用户对本文 §4.2 的"sibling 之间不能直接通讯"提出疑问——Dash 的机制参考自 Prime Agent(当前 conversation 的运行时),而 Prime Agent 在真实工作中发生过一次 sibling 间"感知"事件(Doer 被用户 Escape 中断后 continue,主 Agent 误判其死亡并派了 Finisher,Finisher 却自己发现了 Doer 还在工作)。本附录从 Prime Agent 的会话日志与源码取证,回答四个问题,并给出两个实现的通道对比表。
|
|
145
|
-
>
|
|
146
|
-
> 术语口径:本附录按"设施(facility)= 运行时/界面直接提供给模型、cell 内可直接调用的能力"计;"读源码找端点 curl"类旁证不算工具。
|
|
147
|
-
> 取证来源:主会话日志 `/home/u1/.prime/agent/sessions/01a00967-75d6-755c-827c-562a446786a1.jsonl`(entry 2352/2357/2358 等)、Finisher 自身 session transcript(`sub-ff62e2e1/*.jsonl`)、Prime Agent 源码 `dist/core/agent-messages.js` + `dist/modes/daemon/daemon-mode.js`。
|
|
148
|
-
|
|
149
|
-
## 8. Finisher 事件实录(Q1–Q4)
|
|
150
|
-
|
|
151
|
-
### 8.1 Q1:Finisher 是怎么知道 Doer 还活着的?
|
|
152
|
-
|
|
153
|
-
**不是消息,是观察通道(`agent_observe`)。** Finisher 自身 transcript 的调用统计:
|
|
154
|
-
|
|
155
|
-
```
|
|
156
|
-
agent_observe.get_agent ×5 (读 sibling 的实时 status)
|
|
157
|
-
agent_observe.recent_messages ×7 (读 sibling 的 transcript 尾部)
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
它读到的事实:`m4b-doer-glm52 status=running、isStreaming=true`,transcript 末尾是"刚修完 tsc 类型错误、刚跑完孤儿检查"。辅助旁证是文件系统(mtime 4 秒前刚变、debug 文件被删、新文件出现)——但**主通道是直接读 sibling 的 transcript**。在 Prime Agent 里这不是猜测,是读取。
|
|
161
|
-
|
|
162
|
-
**术语澄清(用户追问,2026-08-17)**:`agent_observe` 不是"读源码 + 找端点 + curl"式的 API 调用。它和 `agent_message`、`websearch`、`edit` 一样,是运行时**预注入 kernel 命名空间的 Python 模块**——模型在 run_cell 里直接 `await agent_observe.get_agent('m4b-doer-glm52')`,与调用任何其他工具无异;daemon 通信、身份、权限对模型完全透明。按用户的设施定义("界面和运行时直接提供给模型、可直接 interact 的东西"),这是**设施(facility)**,不是外部 API。本文 §9 表格中的"观察 API"字样应按"观察设施"理解——措辞已在下文统一修正。
|
|
163
|
-
|
|
164
|
-
### 8.2 Q2:Prime Agent 的 channel 能看到 sibling 吗?
|
|
165
|
-
|
|
166
|
-
**能,且是设计内的一等公民。** 源码(`dist/core/agent-messages.js`):
|
|
167
|
-
|
|
168
|
-
```js
|
|
169
|
-
agentFamilyRelationship(current, target) {
|
|
170
|
-
if (isAgentFamilyParent(target, current)) return "parent";
|
|
171
|
-
if (isAgentFamilyParent(current, target)) return "child";
|
|
172
|
-
if (current.depth === target.depth && sameAgentFamilyParent(current, target, ...))
|
|
173
|
-
return "sibling"; // 同 depth + 同 parentSessionId/Path = sibling
|
|
174
|
-
return undefined; // 核家庭之外 → 拒绝
|
|
175
|
-
}
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
`buildAgentFamilyRoster()` 把 **parent + siblings + children(含各自 status)** 全部列给当前 agent——sibling 的存在、名字、状态对每个 agent 可见。daemon 侧(`daemon-mode.js`)的 target 解析对消息与观察统一走同一守卫:`assertAgentFamilyReach`(parent/siblings/children 之外一律拒绝,错误文案 `"Agent reach is limited to parent, siblings, and children"`)。
|
|
179
|
-
|
|
180
|
-
### 8.3 Q3:sibling 之间究竟能不能通讯?
|
|
181
|
-
|
|
182
|
-
- **Prime Agent:能。** `agent_message.send(..., receiver_role='sibling')` 合法,`send("all")` 家庭广播也覆盖 sibling。
|
|
183
|
-
- **但那次冲突的 resolve 走的是父,不是 sibling 直连。** 实录消息流(主会话 entry 2352/2357/2358):
|
|
184
|
-
1. Finisher → 父:报告"Doer 未死" + 自己的计划,并明说"需要你先停掉/删除 m4b-doer-glm52,避免对写。**请指示**";
|
|
185
|
-
2. 父 → Finisher:`receiver_role='child'` 角色变更指令"**它在写,你只看**",`deliveryStatus: queued`(steering 投递——busy 中的目标在运行中也能收到);
|
|
186
|
-
3. Finisher 此后持续 `agent_observe` 盯 Doer,Doer idle 后做只读验收;Doer 全程未被直接打扰。
|
|
187
|
-
- 原因:Finisher 正确判断了**生命周期归属**——停/删 Doer 是父的权限(`delete_subagent` 是 parent-owned),冲突裁决权在父。**能力存在,编排走父**。这是权限模型(谁有权裁决)与能力模型(谁可以直达)的区别。
|
|
188
|
-
|
|
189
|
-
### 8.4 Q4:冲突 resolve 时消息是怎么传的?
|
|
190
|
-
|
|
191
|
-
三步,全部经父中转(见 8.3);Finisher 与 Doer 之间没有直接消息,只有 Finisher → Doer 的**单向只读观察**(status + transcript 预览)。这与 Dash 实测的"唯一通路:经共同 parent 中转"表面相同,但 Dash 的中转是**因为没有其他通道**,Prime Agent 的中转是**编排选择**(存在 sibling 直连与观察通道)。
|
|
192
|
-
|
|
193
|
-
## 9. Prime Agent vs Dash:A2A Messaging Channel 对比表
|
|
194
|
-
|
|
195
|
-
| 维度 | Prime Agent | Dash(本文 §3–§5 实测 + 上游 continuation.ts) |
|
|
196
|
-
|---|---|---|
|
|
197
|
-
| 拓扑模型 | **核家庭(nuclear family)**:parent + siblings + direct children 双向;根互为 sibling | **严格树**:只认 `parentSession` 指针 |
|
|
198
|
-
| 可达性判定 | `agentFamilyRelationship`(同 parent 边即 sibling) | `target.parentSession == caller.sessionId`(**只能是直接子**) |
|
|
199
|
-
| Sibling 可见性 | ✅ 家庭名单显式列出 siblings + status | ❌ 不可见(`list_agents` 只有自己的 descendants) |
|
|
200
|
-
| Sibling 消息 | ✅ `receiver_role='sibling'` | ❌ `subagent "<id>" belongs to another parent session` |
|
|
201
|
-
| Sibling 观察(设施) | ✅ 预注入 kernel 模块 `agent_observe`:cell 内直接调用 `get_agent` / `recent_messages` / `list_agents`——status + 有界 transcript 预览,只读 | ❌ 无观察设施:cell 内没有任何可调用的观察函数;只能靠非设施旁证(读文件 mtime、自己翻 session 日志文件——按用户定义"不算工具") |
|
|
202
|
-
| 上行 | ✅ 显式消息(双向对等) | ❌ 显式 push 被拒,只有完成回传 |
|
|
203
|
-
| 下行 | ✅ 可递归 | ✅ 可递归(实测 A→G) |
|
|
204
|
-
| 群发 | ✅ `send("all")` 家庭广播(逐条 receipt) | ❌ |
|
|
205
|
-
| 投递语义 | steering delivery:busy 目标运行中可收(`deliveryStatus: queued`);idle 目标直接进上下文 | 完成回传 + 显式下行(busy 中的投递语义未实测) |
|
|
206
|
-
| 身份 | daemon 推导 sender,不可伪造;无 `from` 参数 | 父身份不暴露在 env / list_agents,只在子 session 日志头部 |
|
|
207
|
-
| 生命周期 | 父拥有 `delete_subagent`;child 仅在父会话存续期可用 | 父拥有(continuation 同源规则) |
|
|
208
|
-
| 观察/消息分权 | 观察只读(无 mutate 命令),与消息分离 | 无观察层 |
|
|
209
|
-
|
|
210
|
-
**一句话总结**:Dash 实现的是"树上的一条下行边 + 完成回传"的最小树消息;Prime Agent 把可达域从"父子边"扩展成**核家庭**——多出的是 sibling 可达(消息)、sibling 观察(status/transcript 只读)、家庭名单可见性、显式上行与群发。8.1 的 Finisher 事件恰好命中了 Dash 缺失的那一块:在 Dash 运行时上重演同一场景,Finisher 会完全失明——看不到 Doer 的 status、读不到 transcript,冲突的发现大概率迟到到"两个 agent 开始对写同一批文件"之后。
|
|
211
|
-
|
|
212
|
-
## 10. 对 Dash 的启示(遗留待办候选)
|
|
213
|
-
|
|
214
|
-
1. **补 sibling 观察(设施口径)**:只读的 status + 最近消息预览(有界),是上面场景的充分条件——即使不开放 sibling 直接消息,观察通道也能让冲突在写入前被发现。实现形态应与 Prime Agent 同级:**预注入 kernel 的 Python 模块**(Dash 侧即 tools.* binding 或 `_dashr_*` 注入 helper),模型 cell 内直接调用;而不是"自己去读 session 日志文件"——后者按用户定义不算工具,只能算碰巧存在的旁证。
|
|
215
|
-
2. **补家庭名单可见性**:`list_agents` 至少向每个 agent 暴露同父 sibling 的存在与状态(当前只显示 descendants,父身份还要读自己日志)。
|
|
216
|
-
3. **sibling 消息是否开放**是设计取舍:Prime Agent 有直连但编排惯例走父(生命周期在父)。Dash 若只补观察,可保持"消息走父、观察可横"的分权。
|
|
217
|
-
4. **上行显式 push**:Prime Agent 双向对等;Dash 只有完成回传,子 agent 无法主动给父发"我需要裁决"类消息(Finisher 事件里那条"请指示"在 Dash 上发不出去)。
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
## 11. Delegation 三层模型:通道与"返回结果"的关系(2026-08-17 追加)
|
|
222
|
-
|
|
223
|
-
> 用户追问:"PA 的 A2A Messaging Channel 是不是独立于 delegation 返回 result 的东西?"——答案:方向对了一半,有一个关键修正:**结果本身恰恰就是骑在这个通道上传的**。
|
|
224
|
-
|
|
225
|
-
### 11.1 Prime Agent 的三层结构
|
|
226
|
-
|
|
227
|
-
```
|
|
228
|
-
① 委派准入(spawn/admission)
|
|
229
|
-
rlm('task', name=...) → 立即返回 handle(rlm_child_id / session_dir / model)
|
|
230
|
-
← 独立于通道,纯簿记。rlm() 永远不返回子 agent 的答案
|
|
231
|
-
|
|
232
|
-
② 结果传输
|
|
233
|
-
子 agent 的最终答复 = await agent_message.send(message, receiver_role='parent')
|
|
234
|
-
← 结果就是一条父向消息,骑在 messaging channel 上("写文件给父读"是旁路)
|
|
235
|
-
|
|
236
|
-
③ 存活/完成状态面
|
|
237
|
-
status(idle/running)、repliedSinceTask、"completed without sending a reply" 通知、
|
|
238
|
-
agent_observe 的 status + transcript 预览
|
|
239
|
-
← 独立于通道,是监测机制,不是结果传输
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
- 说"通道独立于 delegation 的返回"**对一半**:`rlm()` 的准入返回与通道无关(只给 handle、立刻返回、绝不等结果)。
|
|
243
|
-
- 但 delegation 的 **result 没有独立管道**:子 agent 的最终答案就是一条父向消息。Finisher 事件里那条 "[from child:m4b-finisher-glm52] …请指示" 与它的正式交付报告形态完全相同——**结果交付只是通道的一种用途,不是另一套机制**。
|
|
244
|
-
|
|
245
|
-
### 11.2 两实现的对照(DSH 实测 §4.1 的"不对称"之根源)
|
|
246
|
-
|
|
247
|
-
| | 结果传输 | 显式消息 |
|
|
248
|
-
|---|---|---|
|
|
249
|
-
| **Dash** | 完成回传:内置 delegation 机制,final message 自动回根 | `send_message` 显式下行——**两套东西** |
|
|
250
|
-
| **Prime Agent** | 子 agent 显式 `agent_message.send(receiver_role='parent')`——**结果也是一条消息** | 同一通道,双向 + sibling + 群发——**一套东西** |
|
|
251
|
-
|
|
252
|
-
Dash 把"交结果"做成了 delegation 的内置特权路径(上行 push 被拒无妨,结果有专线);Prime Agent 把"交结果"统一成了消息(上行 push 天然存在,因为结果本身就是上行消息的一种)。
|
|
253
|
-
|
|
254
|
-
### 11.3 一个由此产生的行为差异
|
|
255
|
-
|
|
256
|
-
Finisher 事件里,父 agent 被 "completed without sending a reply" 误导——因为 Prime Agent 里**"完成"与"回传结果"是解耦的**:③ 层的完成状态通知先到(子 agent 因 interrupt 被误报 completed),② 层的结果消息还没发。Dash 里这两件事绑在一起(完成回传 = 结果到达),反而没有这个坑。**两解耦各有代价**:解耦 = 结果通道可复用(sibling 消息、steering、角色变更都走同一设施),但完成≠有结果;绑定 = 语义简单,但通道只剩"显式下行"这一条窄边。
|
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
# 上游 DSH Code Mode 与 Dash RLM(ipython)对比调研
|
|
2
|
-
|
|
3
|
-
> 调研日期(UTC):2026-08-19
|
|
4
|
-
> 上游源码:`upstream/deepseek-harness`(已从 rc.5 更新到 `dsh-v0.1.0-rc.7`,commit `99f6f02fec`)
|
|
5
|
-
> 对比对象:DSH 原生 Code Mode(`run_code`)vs Dash RLM 插件(`ipython`)
|
|
6
|
-
> 方式:读上游源码 + 设计 Agent Note + 本会话实测 dashr 运行时,全部结论均有文件/行号/引文支撑。
|
|
7
|
-
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## 1. 结论速览(TL;DR)
|
|
11
|
-
|
|
12
|
-
| 问题 | 结论 |
|
|
13
|
-
|---|---|
|
|
14
|
-
| ① DSH Code Mode 是否也是「单一顶层工具 + 代码块」? | ✅ 是。`run_code` 就是唯一顶层工具,形状与 `ipython` 完全同构 |
|
|
15
|
-
| ② 沙箱逃逸是否等价? | ✅ 是。上游自己也写明「containment, not a security boundary」,信任姿态 = bash;任何图灵完备模式都会逃逸,只是快慢/直接间接之别 |
|
|
16
|
-
| ③ 最关键差异 | 🔴 **DSH 明确「拒绝」了持久化 kernel(REPL 式),而 Dash RLM 恰恰是持久化 IPython kernel**。这是二者最根本的分歧,根因是「可重建性」(reconstructability) |
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## 2. 上游版本与源码定位
|
|
21
|
-
|
|
22
|
-
- 远程:`https://github.com/deepseek-ai/deepseek-harness.git`
|
|
23
|
-
- 更新:本地 rc.5 → `dsh-v0.1.0-rc.7`(tag 即 `origin/master`,`git merge --ff-only` 完成)
|
|
24
|
-
- 核心文件:
|
|
25
|
-
- `packages/core/tools/src/code-mode.ts` —— `run_code` 工具定义 + dispatch bridge
|
|
26
|
-
- `packages/core/tools/src/py-types.ts` / `ts-types.ts` —— SDK 生成(Python/TS 两套)
|
|
27
|
-
- `packages/code-runtime/code-runtime/` —— 执行能力 seam(`ctx.codeRuntime`)
|
|
28
|
-
- `packages/code-runtime/code-runtime-worker-thread/` —— 唯一 shipped 后端
|
|
29
|
-
- `.agents/notes/implemented/feature/2026-06-15-code-mode.md` —— 权威设计文档
|
|
30
|
-
- `.agents/notes/implemented/feature/2026-07-31-code-mode-language-dispatch.md` —— Python 呈现层
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## 3. 表面形状对比:是不是「单一顶层工具」
|
|
35
|
-
|
|
36
|
-
**是。** 两者都把「工具调用界面」归一化成一个顶层工具:
|
|
37
|
-
|
|
38
|
-
| | DSH Code Mode | Dash RLM |
|
|
39
|
-
|---|---|---|
|
|
40
|
-
| 顶层工具名 | `run_code`(`RUN_CODE_NAME`) | `ipython` |
|
|
41
|
-
| 必填参数 | `code` + `description` 两个 | `cell` + `description` 两个 |
|
|
42
|
-
| 代码块语义 | 「async 函数的 body」,顶层 `await`/`return` 可用 | 一个 IPython cell,顶层 `await`/`return` 可用 |
|
|
43
|
-
| 输出契约 | 只 `print`/`return` 的才进模型上下文 | 只 `print`/`return` 的才回来 |
|
|
44
|
-
| 模式开关 | `tools: { mode: 'native'|'code'|'both' }` | `agent-preset: rlm-mode` |
|
|
45
|
-
|
|
46
|
-
在 `mode: 'code'` 下,wire 上只挂 `run_code` 一个工具 + 一段生成的 SDK `.d.ts`。这与 dashr 的「只有 `ipython` 可直连」是同一形态。
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## 4. 执行基底对比(最根本差异)
|
|
51
|
-
|
|
52
|
-
| 维度 | DSH Code Mode | Dash RLM |
|
|
53
|
-
|---|---|---|
|
|
54
|
-
| 执行载体 | 每次 run 起一个**全新** `worker_threads.Worker` | **持久化** IPython/Jupyter kernel 进程 |
|
|
55
|
-
| 状态 | **无状态**(每次 fresh,进程世界随 worker 销毁) | **有状态**(变量/import 跨 cell 存活,实测确认) |
|
|
56
|
-
| 语言 | TypeScript(唯一 shipped 后端) | Python(真实 IPython) |
|
|
57
|
-
| 隔离 | worker 线程:空 env、heap 上限、可硬终止 | 真实 kernel 进程(无 worker 级 containment) |
|
|
58
|
-
|
|
59
|
-
DSH 把 TS 程序 host-side 做 `stripTypeScriptTypes`(去类型),再包成 `AsyncFunction` 在 worker 里执行;绑定经 message port 桥接。**每次都是纯函数调用,无跨 run 状态。**
|
|
60
|
-
|
|
61
|
-
Dash RLM 则是在一个长期存活的内核里逐 cell `exec`,变量天然累积——这就是我在本会话里直接验证过的「上一轮变量下一轮还在」。
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## 5. 语言对比
|
|
66
|
-
|
|
67
|
-
| | DSH | Dash RLM |
|
|
68
|
-
|---|---|---|
|
|
69
|
-
| 实际可运行语言 | **TypeScript**(`language = 'typescript'`,`isolation = 'worker-thread'`) | **Python**(IPython) |
|
|
70
|
-
| Python 支持 | **仅呈现层**:`py-types.ts` + `renderToolsSdkPy` + `PYTHON_FLAVOR` 都在,但**没有 published Python 后端**——设计文档原话:「The Python branch of both tables is unreachable in the shipped tree」 | 原生 Python,真跑 |
|
|
71
|
-
|
|
72
|
-
即:DSH 把 Python 的「schema/SDK/描述」都准备好了,但还没有能执行 Python 的后端;dashr 则是反过来的——直接实现了 Python 执行(IPython),走的是 DSH 预留的「future Python backend」那条路。
|
|
73
|
-
|
|
74
|
-
---
|
|
75
|
-
|
|
76
|
-
## 6. 工具绑定形式对比
|
|
77
|
-
|
|
78
|
-
| | DSH | Dash RLM |
|
|
79
|
-
|---|---|---|
|
|
80
|
-
| 调用形式 | `await tools.name(args)`(命名空间对象 `tools`) | `await name(args)`(扁平顶层函数) |
|
|
81
|
-
| 错误类 | `ToolCallError`,带 `toolName` | `ToolCallError`,带 `toolName` |
|
|
82
|
-
| 参数契约 | 单个 args 对象,必须 lossless JSON | 单个位置 args 对象,拒绝 kwargs |
|
|
83
|
-
| 命名防护 | null-prototype + `defineProperty` 防 `__proto__`/`constructor` 撞名 | 扁平 `user_ns[global_name]` 绑定 |
|
|
84
|
-
|
|
85
|
-
`ToolCallError` + `toolName` 这个契约是 dashr 从上游「搬」过来的(上游 `code-mode.ts` 里 `errorClass: { name: 'ToolCallError', memberNameProperty: 'toolName' }` 与 dashr bootstrap 完全一致)。差异在命名空间:DSH 用 `tools.` 前缀统一收敛,dashr 用扁平全局名(这是我在实测里注意到的「工具目录像原生函数」摩擦的根源之一)。
|
|
86
|
-
|
|
87
|
-
---
|
|
88
|
-
|
|
89
|
-
## 7. 并发模型对比
|
|
90
|
-
|
|
91
|
-
- **DSH**:每个 run 一个调度队列,严格按提交顺序启动,逐调用走 `registry.executionMode`(`isConcurrencySafe`)分类 parallel/exclusive;连续的 parallel 调用最多重叠 `maxParallelSubCalls`(默认 10,1 即串行);exclusive 调用排空池后单独跑。承诺「只读调用可用 `Promise.all`/`asyncio.gather` 重叠,写调用按提交顺序单独跑」。
|
|
92
|
-
- **Dash RLM**:cell 内用 `asyncio.gather` 扇出,同样有重叠上限;底层同样走「并发安全分类 + 顺序提交」的契约。
|
|
93
|
-
|
|
94
|
-
二者并发语义高度同构——dashr 的「submission-order + overlap cap」直接继承自上游这套设计。
|
|
95
|
-
|
|
96
|
-
---
|
|
97
|
-
|
|
98
|
-
## 8. 隔离与沙箱逃逸(安全性)
|
|
99
|
-
|
|
100
|
-
**上游自己就把话说透了。** `code-runtime-worker-thread` README 第一段:
|
|
101
|
-
|
|
102
|
-
> **Containment, not a security boundary**: trust posture is bash-equivalent by design ... model code can reach Node APIs and has authority comparable to the bash tool.
|
|
103
|
-
|
|
104
|
-
设计文档 §Trust posture(第 84 行):
|
|
105
|
-
|
|
106
|
-
> The worker runtime provides containment, not a security boundary ... `worker.terminate()` stops the thread but not OS processes it spawned. Code Mode uses the same `tools/pre-execute` policy gate as bash ...
|
|
107
|
-
|
|
108
|
-
**结论**:DSH Code Mode 的 worker 只是「资源隔离」(isolate、空 env、heap 上限、硬终止),**不是安全边界**;信任姿态等价于 bash(bash 本就能执行任意 shell 命令)。所以:
|
|
109
|
-
|
|
110
|
-
- **Code Mode 逃逸**:模型代码能直接 reach Node API,等价于 bash。
|
|
111
|
-
- **RLM/ipython 逃逸**:kernel 进程原生 `open()` 可写任意路径(本会话已实测复现)。
|
|
112
|
-
- **普通 native 模式逃逸**:bash + write 组合先写脚本再执行,同样图灵完备。
|
|
113
|
-
|
|
114
|
-
三者本质等价——都是「图灵完备的代码执行能力」,差别只在**实现步骤的快慢/直接间接**,不在是否可能。这与你(用户)的判断完全一致。
|
|
115
|
-
|
|
116
|
-
---
|
|
117
|
-
|
|
118
|
-
## 9. 关键分歧:DSH 明确拒绝了「持久化 kernel」
|
|
119
|
-
|
|
120
|
-
设计文档「Alternatives considered」第 119 行,一字不差:
|
|
121
|
-
|
|
122
|
-
> **A REPL-style persistent kernel** (state survives across `run_code` calls). **Rejected for the MVP**: cross-call state would be invisible to the session log, breaking the **reconstructability guarantee that every request is a pure function of the log**; fresh-per-run keeps it. A kernel-style backend remains expressible behind the seam later, with its own logging story.
|
|
123
|
-
|
|
124
|
-
**这正是 dashr 现在的做法。** 上游为了「每个请求是日志的纯函数、会话可完整重建」这个保证,主动放弃了持久化 kernel;dashr 反其道而行,选了持久化 IPython kernel,因此:
|
|
125
|
-
|
|
126
|
-
- **得到**:对偏好编程/强化编程训练的模型更直接、状态可累积(不需要每次重新声明变量/import)、真正的交互式内核体验。
|
|
127
|
-
- **失去**:跨 cell 状态对 session log 不可见 → 破坏了「纯函数 of log」的可重建性;任何一次会话回放都无法仅凭日志重建出与当时一致的 kernel 内存态。
|
|
128
|
-
|
|
129
|
-
这不是对错问题,而是 **capability(能力)与 reproducibility/security(可重建性/安全)的取舍**——dashr 站在了「能力/直接性」这一侧,上游站在了「可重建/可审计」这一侧。
|
|
130
|
-
|
|
131
|
-
---
|
|
132
|
-
|
|
133
|
-
## 10. 对 dashr 的启示(可选下一步)
|
|
134
|
-
|
|
135
|
-
1. **接口命名**:上游用 `tools.name()` 命名空间,dashr 用扁平 `name()`。命名空间能显著缓解「工具目录像原生函数、被模型直接调用」的心智摩擦(本会话实测两次直接调 `grep`/`read` 被拒)。
|
|
136
|
-
2. **无状态 vs 有状态**:dashr 的持久化 kernel 需要补「状态可见化」——至少把关键状态(如写入过的变量、已安装的包)显式记录进 log,否则回放/审计会失真。上游的 fresh-per-run 是零成本的这一面。
|
|
137
|
-
3. **沙箱叙事**:上游已经把「containment ≠ security boundary」写进 README 和设计文档;dashr 的文档可以对齐这个表述,把「kernel 原生 I/O 可写工作区外」从「隐患」重新定性为「bash 等价信任姿态」。
|