better-dsh 0.2.3 → 0.2.4-b
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 +47 -16
- package/docs/10_plans/2026-09-23-remote-execution-framework.md +236 -0
- package/docs/10_plans/2026-09-23-remote-framework-impl.md +2083 -0
- 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/2026-09-17-plugins/351/241/265/345/205/255/347/273/204/344/273/266/346/213/206/345/210/206/345/256/236/346/265/213/346/212/245/345/221/212.md +76 -0
- package/docs/50_test-reports/2026-09-23-remote-framework/345/256/236/346/265/213/346/212/245/345/221/212.md +92 -0
- package/docs/50_test-reports/2026-09-23-remote-framework/347/254/254/344/270/200/344/272/272/347/247/260/345/244/215/346/265/213/346/212/245/345/221/212.md +125 -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/plugins-page-components/spec.md +79 -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 +328 -89
- package/lib/compaction/index.d.ts +47 -0
- package/lib/compaction/index.js +159 -0
- package/lib/failover/index.d.ts +35 -0
- package/lib/failover/index.js +141 -0
- package/lib/fs-aware/sandbox-plugin.d.ts +71 -0
- package/lib/fs-aware/sandbox-plugin.js +249 -0
- package/lib/index.d.ts +10 -41
- package/lib/index.js +226 -8173
- package/lib/lsp-server-registry-946ysdqg.js +972 -0
- package/lib/lsp-server-registry-XU6aHSqZ.js +3 -0
- package/lib/mobile/plugin.d.ts +29 -0
- package/lib/mobile/plugin.js +54 -0
- package/lib/native-capture-x_Hos2e8.js +68 -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/remote/plugin.d.ts +24 -0
- package/lib/remote/plugin.js +1095 -0
- package/lib/url-schemes/index.d.ts +88 -0
- package/lib/url-schemes/index.js +7200 -0
- package/lib/web-trust-BO66y72w.js +361 -0
- package/lib/web-trust-CgpBoFv3.d.ts +106 -0
- package/lib/web-trust.d.ts +2 -0
- package/lib/web-trust.js +3 -0
- package/lib/wrap-Dr8XtIak.js +747 -0
- package/package.json +87 -56
- 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
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
2
|
+
import z from "@deepseek-ai/schemastery";
|
|
3
|
+
|
|
4
|
+
//#region src/compaction/config.ts
|
|
5
|
+
/**
|
|
6
|
+
* The `compaction-tuning` General-row config: the share of the routed context
|
|
7
|
+
* window at which automatic condensation starts.
|
|
8
|
+
*
|
|
9
|
+
* Pure module — no `@deepseek-ai/*` value imports — so the host half and the
|
|
10
|
+
* client half may both import it without dragging either runtime into the
|
|
11
|
+
* browser bundle: the host takes the namespace and the schema defaults, the
|
|
12
|
+
* client takes the namespace literal plus the stepper bounds.
|
|
13
|
+
*
|
|
14
|
+
* @module dashr/compaction/config
|
|
15
|
+
*/
|
|
16
|
+
/** The settings namespace the General row reads and writes. */
|
|
17
|
+
const COMPACTION_SETTINGS_NS = "compaction-tuning";
|
|
18
|
+
/** Upstream `compaction-basic`'s own default: condense at 80% of the window. */
|
|
19
|
+
const DEFAULT_THRESHOLD_RATIO = .8;
|
|
20
|
+
/**
|
|
21
|
+
* Absolute recent-tail budget, in estimated tokens (~50 KB of English text).
|
|
22
|
+
*
|
|
23
|
+
* Composition-only, deliberately: the General row drives `thresholdRatio`
|
|
24
|
+
* alone, so the recency window stays a deployment decision (its base layer is
|
|
25
|
+
* the row config in `cordis.patch.yml`) rather than a second knob on the
|
|
26
|
+
* settings page. The host half still applies it to the engine.
|
|
27
|
+
*/
|
|
28
|
+
const DEFAULT_RETAIN_TOKENS = 5e4;
|
|
29
|
+
/** Ratio bounds the settings schema accepts (a config file may use either end). */
|
|
30
|
+
const THRESHOLD_MIN_RATIO = .05;
|
|
31
|
+
/** @see THRESHOLD_MIN_RATIO */
|
|
32
|
+
const THRESHOLD_MAX_RATIO = 1;
|
|
33
|
+
/** Spec defaults — `Config({})` must equal this. */
|
|
34
|
+
const defaultCompactionTuningConfig = {
|
|
35
|
+
thresholdRatio: DEFAULT_THRESHOLD_RATIO,
|
|
36
|
+
retainTokens: DEFAULT_RETAIN_TOKENS
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
//#endregion
|
|
40
|
+
//#region src/compaction/index.ts
|
|
41
|
+
/** Cordis plugin name. */
|
|
42
|
+
const name = "dashr-compaction-tuning";
|
|
43
|
+
/**
|
|
44
|
+
* No static injects: both `settings` and `compaction` are composed
|
|
45
|
+
* conditionally inside {@link installCompactionTuning}, so the row loads
|
|
46
|
+
* (dormant) in compositions without them.
|
|
47
|
+
*/
|
|
48
|
+
const inject = [];
|
|
49
|
+
/**
|
|
50
|
+
* The `compaction-tuning` settings schema.
|
|
51
|
+
*
|
|
52
|
+
* `thresholdRatio` is the field the General row drives; `retainTokens` is
|
|
53
|
+
* composition-only (see {@link DEFAULT_RETAIN_TOKENS}) but still validated and
|
|
54
|
+
* applied, so the recency window keeps one source of truth.
|
|
55
|
+
*/
|
|
56
|
+
const Config = z.object({
|
|
57
|
+
thresholdRatio: z.number().step(.01).min(THRESHOLD_MIN_RATIO).max(THRESHOLD_MAX_RATIO).default(DEFAULT_THRESHOLD_RATIO),
|
|
58
|
+
retainTokens: z.number().step(1).min(0).default(DEFAULT_RETAIN_TOKENS)
|
|
59
|
+
});
|
|
60
|
+
/**
|
|
61
|
+
* Install the settings namespace and keep the live compaction engine in sync.
|
|
62
|
+
* @param ctx - host context of the row that owns this capability.
|
|
63
|
+
* @param config - composition base layer; schema defaults fill the rest.
|
|
64
|
+
*/
|
|
65
|
+
function installCompactionTuning(ctx, config = defaultCompactionTuningConfig) {
|
|
66
|
+
const logger = ctx.logger("compaction-tuning");
|
|
67
|
+
let source = () => Config(config);
|
|
68
|
+
/** Smallest routed context window seen so far (advisory guard, best effort). */
|
|
69
|
+
let minWindow;
|
|
70
|
+
let probing = false;
|
|
71
|
+
/**
|
|
72
|
+
* Learn the routed context windows so a write can be refused when it would
|
|
73
|
+
* leave `retainTokens >= floor(window x thresholdRatio)` — the condition
|
|
74
|
+
* under which the engine raises `TargetPressureConfigError` per route and
|
|
75
|
+
* automatic condensation quietly stops for that route.
|
|
76
|
+
*/
|
|
77
|
+
const probeWindows = () => {
|
|
78
|
+
if (probing || minWindow !== void 0) return;
|
|
79
|
+
const llm = ctx.get("llm");
|
|
80
|
+
if (llm === void 0) return;
|
|
81
|
+
probing = true;
|
|
82
|
+
(async () => {
|
|
83
|
+
try {
|
|
84
|
+
let smallest;
|
|
85
|
+
for (const provider of llm.listProviders()) for (const model of await llm.listModels(provider.id)) {
|
|
86
|
+
const window = (await llm.resolveModelInfo(provider.id, model.id)).context?.contextWindow;
|
|
87
|
+
if (typeof window !== "number" || window <= 0) continue;
|
|
88
|
+
smallest = smallest === void 0 ? window : Math.min(smallest, window);
|
|
89
|
+
}
|
|
90
|
+
if (smallest !== void 0) {
|
|
91
|
+
minWindow = smallest;
|
|
92
|
+
logger.info(`smallest routed context window: ${smallest} tokens`);
|
|
93
|
+
}
|
|
94
|
+
} catch (error) {
|
|
95
|
+
logger.warn(`context-window probe failed (retention guard disabled): ${error instanceof Error ? error.message : String(error)}`);
|
|
96
|
+
} finally {
|
|
97
|
+
probing = false;
|
|
98
|
+
}
|
|
99
|
+
})();
|
|
100
|
+
};
|
|
101
|
+
/**
|
|
102
|
+
* Overwrite only this module's two fields on the engine's current policy and
|
|
103
|
+
* hand the engine a fresh frozen object.
|
|
104
|
+
* @param reason - short diagnostic tag for the log line.
|
|
105
|
+
*/
|
|
106
|
+
const push = (reason) => {
|
|
107
|
+
const compaction = ctx.get("compaction");
|
|
108
|
+
if (compaction === void 0) return;
|
|
109
|
+
const base = compaction.config;
|
|
110
|
+
if (base === void 0) return;
|
|
111
|
+
const value = source();
|
|
112
|
+
const next = {
|
|
113
|
+
...base,
|
|
114
|
+
thresholdRatio: value.thresholdRatio,
|
|
115
|
+
retainTokens: value.retainTokens
|
|
116
|
+
};
|
|
117
|
+
delete next.retainRatio;
|
|
118
|
+
compaction.config = Object.freeze(next);
|
|
119
|
+
logger.info(`applied (${reason}): thresholdRatio=${value.thresholdRatio} retainTokens=${value.retainTokens}`);
|
|
120
|
+
};
|
|
121
|
+
ctx.inject(["compaction"], () => {
|
|
122
|
+
push("compaction-ready");
|
|
123
|
+
probeWindows();
|
|
124
|
+
});
|
|
125
|
+
ctx.inject(["settings"], (settingsCtx) => {
|
|
126
|
+
if (settingsCtx.settings.get(COMPACTION_SETTINGS_NS) !== void 0) {
|
|
127
|
+
logger.info("settings namespace already served; leaving it to its owner");
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
settingsCtx.settings.installSection(ctx, COMPACTION_SETTINGS_NS, Config, Config(config), {
|
|
131
|
+
setSource: (current) => {
|
|
132
|
+
source = current;
|
|
133
|
+
},
|
|
134
|
+
onChange: () => {
|
|
135
|
+
push("settings-updated");
|
|
136
|
+
},
|
|
137
|
+
validate: (value) => {
|
|
138
|
+
if (minWindow === void 0) return;
|
|
139
|
+
const thresholdTokens = Math.floor(minWindow * value.thresholdRatio);
|
|
140
|
+
if (value.retainTokens >= thresholdTokens) throw new Error(`retainTokens (${value.retainTokens}) must stay below the threshold tokens for every routed model; the smallest window here is ${minWindow}, so ${value.thresholdRatio} leaves only ${thresholdTokens}`);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
push("settings-installed");
|
|
144
|
+
probeWindows();
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
/** Mount the tuning as the row's whole apply (the row config is the settings base). */
|
|
148
|
+
function apply(ctx, config) {
|
|
149
|
+
installCompactionTuning(ctx, config ?? defaultCompactionTuningConfig);
|
|
150
|
+
}
|
|
151
|
+
var compaction_default = {
|
|
152
|
+
name,
|
|
153
|
+
inject,
|
|
154
|
+
Config,
|
|
155
|
+
apply
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
//#endregion
|
|
159
|
+
export { Config, apply, compaction_default as default, inject, installCompactionTuning, name };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
2
|
+
import z from "@deepseek-ai/schemastery";
|
|
3
|
+
|
|
4
|
+
//#region src/failover/config.d.ts
|
|
5
|
+
|
|
6
|
+
/** The fallback chain: two ordered slots. `''` = not set (skip). */
|
|
7
|
+
interface FailoverConfig {
|
|
8
|
+
fallback1: string;
|
|
9
|
+
fallback2: string;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
//#region src/failover/index.d.ts
|
|
13
|
+
|
|
14
|
+
/** Cordis plugin name. */
|
|
15
|
+
declare const name = "dashr-failover";
|
|
16
|
+
/**
|
|
17
|
+
* No static injects: `settings` is composed conditionally inside
|
|
18
|
+
* {@link installFailover} (`ctx.inject(['settings'], …)`), so the row loads
|
|
19
|
+
* (dormant) in compositions without a settings service.
|
|
20
|
+
*/
|
|
21
|
+
declare const inject: string[];
|
|
22
|
+
/** The `failover` settings schema: two optional fallback slots, both default "not set". */
|
|
23
|
+
declare const Config: z<FailoverConfig>;
|
|
24
|
+
/** Install the failover. A no-op composition degrades gracefully (empty chain = pass-through). */
|
|
25
|
+
declare function installFailover(ctx: Context, config?: FailoverConfig): void;
|
|
26
|
+
/** Mount the failover as the row's whole apply (the row config is the chain base). */
|
|
27
|
+
declare function apply(ctx: Context, config: FailoverConfig | undefined): void;
|
|
28
|
+
declare const _default: {
|
|
29
|
+
name: string;
|
|
30
|
+
inject: string[];
|
|
31
|
+
Config: z<FailoverConfig>;
|
|
32
|
+
apply: typeof apply;
|
|
33
|
+
};
|
|
34
|
+
//#endregion
|
|
35
|
+
export { Config, apply, _default as default, inject, installFailover, name };
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
2
|
+
import { randomUUID } from "node:crypto";
|
|
3
|
+
import z from "@deepseek-ai/schemastery";
|
|
4
|
+
import { RetryId } from "@deepseek-ai/dsh-llm-retry";
|
|
5
|
+
|
|
6
|
+
//#region src/failover/config.ts
|
|
7
|
+
/**
|
|
8
|
+
* The `failover` general-fallback config (host-plane, per-turn latch).
|
|
9
|
+
*
|
|
10
|
+
* Pure module — no `@deepseek-ai/*` value imports, so both the host module and
|
|
11
|
+
* the client half may import it (the client type-only) without dragging a host
|
|
12
|
+
* runtime dependency into the browser bundle.
|
|
13
|
+
*
|
|
14
|
+
* A route is a `provider/model` string (e.g. `deepseek/deepseek-v4-flash`).
|
|
15
|
+
* The empty string `''` means "not set" — the slot is skipped.
|
|
16
|
+
*
|
|
17
|
+
* @module dashr/failover/config
|
|
18
|
+
*/
|
|
19
|
+
/** The settings namespace the General row reads and writes. */
|
|
20
|
+
const FAILOVER_SETTINGS_NS = "failover";
|
|
21
|
+
/** Failure codes that activate a fallback switch. */
|
|
22
|
+
const FAILOVER_TRIGGER_CODES = {
|
|
23
|
+
AUTH: true,
|
|
24
|
+
MISSING_CREDENTIAL: true,
|
|
25
|
+
QUOTA: true,
|
|
26
|
+
RATE_LIMIT: true
|
|
27
|
+
};
|
|
28
|
+
/** Spec defaults — `Config({})` must equal this (both slots unset = native behavior). */
|
|
29
|
+
const defaultFailoverConfig = {
|
|
30
|
+
fallback1: "",
|
|
31
|
+
fallback2: ""
|
|
32
|
+
};
|
|
33
|
+
/** The non-empty fallback routes in order (at most 2). */
|
|
34
|
+
function fallbackRoutes(config) {
|
|
35
|
+
return [config.fallback1, config.fallback2].filter((route) => route.length > 0);
|
|
36
|
+
}
|
|
37
|
+
/** Split a `provider/model` route; `undefined` when malformed. */
|
|
38
|
+
function splitRoute(route) {
|
|
39
|
+
const slash = route.indexOf("/");
|
|
40
|
+
if (slash <= 0 || slash === route.length - 1) return void 0;
|
|
41
|
+
return {
|
|
42
|
+
provider: route.slice(0, slash),
|
|
43
|
+
model: route.slice(slash + 1)
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region src/failover/index.ts
|
|
49
|
+
/** Cordis plugin name. */
|
|
50
|
+
const name = "dashr-failover";
|
|
51
|
+
/**
|
|
52
|
+
* No static injects: `settings` is composed conditionally inside
|
|
53
|
+
* {@link installFailover} (`ctx.inject(['settings'], …)`), so the row loads
|
|
54
|
+
* (dormant) in compositions without a settings service.
|
|
55
|
+
*/
|
|
56
|
+
const inject = [];
|
|
57
|
+
/** The `failover` settings schema: two optional fallback slots, both default "not set". */
|
|
58
|
+
const Config = z.object({
|
|
59
|
+
fallback1: z.string().default(""),
|
|
60
|
+
fallback2: z.string().default("")
|
|
61
|
+
});
|
|
62
|
+
/** Replace provider/model on a request config, dropping the inherited reasoning effort. */
|
|
63
|
+
function overrideConfig(seed, to) {
|
|
64
|
+
const { reasoningEffort: _inherited,...rest } = seed;
|
|
65
|
+
return {
|
|
66
|
+
...rest,
|
|
67
|
+
provider: to.provider,
|
|
68
|
+
model: to.model
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/** Install the failover. A no-op composition degrades gracefully (empty chain = pass-through). */
|
|
72
|
+
function installFailover(ctx, config = defaultFailoverConfig) {
|
|
73
|
+
const logger = ctx.logger("llm-failover");
|
|
74
|
+
let source = () => Config(config);
|
|
75
|
+
ctx.inject(["settings"], (sctx) => {
|
|
76
|
+
sctx.settings.installSection(ctx, FAILOVER_SETTINGS_NS, Config, Config(config), {
|
|
77
|
+
setSource: (current) => {
|
|
78
|
+
source = current;
|
|
79
|
+
},
|
|
80
|
+
onChange: () => {}
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
const latches = /* @__PURE__ */ new Map();
|
|
84
|
+
ctx.on("agent/disposed", ({ agent }) => {
|
|
85
|
+
latches.delete(agent.id);
|
|
86
|
+
});
|
|
87
|
+
ctx.on("agent/request-error", async ({ agent, turn, step, provider, failure }, next) => {
|
|
88
|
+
if (FAILOVER_TRIGGER_CODES[failure.code] !== true) return next();
|
|
89
|
+
const routes = fallbackRoutes(source());
|
|
90
|
+
if (routes.length === 0) return next();
|
|
91
|
+
const latch = latches.get(agent.id);
|
|
92
|
+
const fallbackIndex = latch !== void 0 && latch.turn === turn ? latch.fallbackIndex : 0;
|
|
93
|
+
if (fallbackIndex >= routes.length) return next();
|
|
94
|
+
const nextIndex = fallbackIndex + 1;
|
|
95
|
+
const route = routes[nextIndex - 1];
|
|
96
|
+
if (splitRoute(route) === void 0) return next();
|
|
97
|
+
latches.set(agent.id, {
|
|
98
|
+
turn,
|
|
99
|
+
fallbackIndex: nextIndex
|
|
100
|
+
});
|
|
101
|
+
logger.info("llm-failover: agent \"%s\" provider=\"%s\" code=%s -> switch to \"%s\" (per turn)", agent.id, provider, failure.code, route);
|
|
102
|
+
agent.session.append("llm/retry", {
|
|
103
|
+
retryId: RetryId(randomUUID()),
|
|
104
|
+
turn,
|
|
105
|
+
step,
|
|
106
|
+
provider,
|
|
107
|
+
mode: "normal",
|
|
108
|
+
policyKey: "llm-failover",
|
|
109
|
+
retry: nextIndex,
|
|
110
|
+
maxRetries: routes.length,
|
|
111
|
+
delayMs: 0,
|
|
112
|
+
failure: {
|
|
113
|
+
...failure,
|
|
114
|
+
code: "failover",
|
|
115
|
+
message: `[${failure.code}] ${failure.message} → switched to "${route}"`
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
return { kind: "retry" };
|
|
119
|
+
});
|
|
120
|
+
ctx.on("agent/request", async ({ agent, turn }, next) => {
|
|
121
|
+
const seed = await next();
|
|
122
|
+
const latch = latches.get(agent.id);
|
|
123
|
+
if (latch === void 0 || latch.turn !== turn || latch.fallbackIndex <= 0) return seed;
|
|
124
|
+
const route = splitRoute(fallbackRoutes(source())[latch.fallbackIndex - 1] ?? "");
|
|
125
|
+
if (route === void 0) return seed;
|
|
126
|
+
return overrideConfig(seed, route);
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
/** Mount the failover as the row's whole apply (the row config is the chain base). */
|
|
130
|
+
function apply(ctx, config) {
|
|
131
|
+
installFailover(ctx, config ?? defaultFailoverConfig);
|
|
132
|
+
}
|
|
133
|
+
var failover_default = {
|
|
134
|
+
name,
|
|
135
|
+
inject,
|
|
136
|
+
Config,
|
|
137
|
+
apply
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
//#endregion
|
|
141
|
+
export { Config, apply, failover_default as default, inject, installFailover, name };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
2
|
+
import { Config } from "@deepseek-ai/dsh-fs-local";
|
|
3
|
+
|
|
4
|
+
//#region src/fs-aware/sandbox-plugin.d.ts
|
|
5
|
+
|
|
6
|
+
/** Module config: the stock LocalConfig fields plus the scheme gate. */
|
|
7
|
+
interface FsAwareConfig extends Config {
|
|
8
|
+
/** Master gate for scheme interception at the FS layer (default on). */
|
|
9
|
+
urlSchemes?: boolean;
|
|
10
|
+
}
|
|
11
|
+
/** Structural view of the inherited backend (loose, like the spike's Base). */
|
|
12
|
+
interface BaseView {
|
|
13
|
+
resolve(path: string, opts?: {
|
|
14
|
+
cwd?: string;
|
|
15
|
+
signal?: AbortSignal;
|
|
16
|
+
}): Promise<{
|
|
17
|
+
targetKey: string;
|
|
18
|
+
displayPath: string;
|
|
19
|
+
}>;
|
|
20
|
+
stat(target: {
|
|
21
|
+
targetKey: string;
|
|
22
|
+
}, signal?: AbortSignal): Promise<unknown>;
|
|
23
|
+
readText(target: {
|
|
24
|
+
targetKey: string;
|
|
25
|
+
}, signal?: AbortSignal): Promise<string>;
|
|
26
|
+
writeText(target: {
|
|
27
|
+
targetKey: string;
|
|
28
|
+
}, ...rest: unknown[]): Promise<unknown>;
|
|
29
|
+
editText(target: {
|
|
30
|
+
targetKey: string;
|
|
31
|
+
}, ...rest: unknown[]): Promise<unknown>;
|
|
32
|
+
}
|
|
33
|
+
declare const Base: abstract new (ctx: Context, config: FsAwareConfig) => BaseView;
|
|
34
|
+
declare class FsAwareSandboxFileSystem extends Base {
|
|
35
|
+
static inject: string[];
|
|
36
|
+
private readonly resolver;
|
|
37
|
+
private readonly schemeResolution;
|
|
38
|
+
constructor(ctx: Context, config: FsAwareConfig);
|
|
39
|
+
/**
|
|
40
|
+
* FS-layer resolver — the SHARED builder from `wrap.ts` (design D2). One
|
|
41
|
+
* registration source for both FS consumers: this backend and the instance
|
|
42
|
+
* wrap. (A private duplicate here once drifted — a doubled `dsh` register
|
|
43
|
+
* and a literal `'http'` that would silently drop `https` if this backend
|
|
44
|
+
* were ever the outermost layer.) The `ctx`/`agent` handlers it registers
|
|
45
|
+
* are unreachable here: session-layer schemes are guarded before resolve.
|
|
46
|
+
*/
|
|
47
|
+
private buildResolver;
|
|
48
|
+
/** FS-layer resolver env: no live agent — session-layer schemes are excluded upstream. */
|
|
49
|
+
private envFor;
|
|
50
|
+
resolve(path: string, opts?: {
|
|
51
|
+
cwd?: string;
|
|
52
|
+
signal?: AbortSignal;
|
|
53
|
+
}): Promise<{
|
|
54
|
+
targetKey: string;
|
|
55
|
+
displayPath: string;
|
|
56
|
+
}>;
|
|
57
|
+
stat(target: {
|
|
58
|
+
targetKey: string;
|
|
59
|
+
}, signal?: AbortSignal): Promise<unknown>;
|
|
60
|
+
readText(target: {
|
|
61
|
+
targetKey: string;
|
|
62
|
+
}, signal?: AbortSignal): Promise<string>;
|
|
63
|
+
writeText(target: {
|
|
64
|
+
targetKey: string;
|
|
65
|
+
}, ...rest: unknown[]): Promise<unknown>;
|
|
66
|
+
editText(target: {
|
|
67
|
+
targetKey: string;
|
|
68
|
+
}, ...rest: unknown[]): Promise<unknown>;
|
|
69
|
+
}
|
|
70
|
+
//#endregion
|
|
71
|
+
export { FsAwareConfig, FsAwareSandboxFileSystem as default };
|
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
import { f as UrlSchemesError, t as buildFsLayerResolver } from "../wrap-Dr8XtIak.js";
|
|
2
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
3
|
+
import { dirname, sep } from "node:path";
|
|
4
|
+
import { LocalFileSystem } from "@deepseek-ai/dsh-fs-local";
|
|
5
|
+
import { FsError } from "@deepseek-ai/dsh-fs";
|
|
6
|
+
import { writableRoots } from "@deepseek-ai/dsh-sandbox";
|
|
7
|
+
import { stat } from "node:fs/promises";
|
|
8
|
+
|
|
9
|
+
//#region ../../../better-dsh/node_modules/@deepseek-ai/dsh-fs-sandbox/lib/index.js
|
|
10
|
+
/**
|
|
11
|
+
* Path-containment mechanics for the filesystem sandbox. Canonical spellings
|
|
12
|
+
* take the fast lexical path; filesystem identity supplies the conservative
|
|
13
|
+
* fallback for alias-equivalent roots such as Windows 8.3 names and casing.
|
|
14
|
+
* @module @deepseek-ai/dsh-fs-sandbox/containment
|
|
15
|
+
*/
|
|
16
|
+
const MISSING_CODES = new Set(["ENOENT", "ENOTDIR"]);
|
|
17
|
+
function isMissing(error) {
|
|
18
|
+
const code = error.code;
|
|
19
|
+
return MISSING_CODES.has(code);
|
|
20
|
+
}
|
|
21
|
+
function comparablePath(path, caseSensitive) {
|
|
22
|
+
return caseSensitive ? path : path.toLowerCase();
|
|
23
|
+
}
|
|
24
|
+
function isLexicallyUnder(path, root, caseSensitive) {
|
|
25
|
+
const comparableTarget = comparablePath(path, caseSensitive);
|
|
26
|
+
const comparableRoot = comparablePath(root, caseSensitive);
|
|
27
|
+
if (comparableTarget === comparableRoot) return true;
|
|
28
|
+
const prefix = comparableRoot.endsWith(sep) ? comparableRoot : comparableRoot + sep;
|
|
29
|
+
return comparableTarget.startsWith(prefix);
|
|
30
|
+
}
|
|
31
|
+
async function statIfPresent(path) {
|
|
32
|
+
try {
|
|
33
|
+
return await stat(path, { bigint: true });
|
|
34
|
+
} catch (error) {
|
|
35
|
+
/* v8 ignore else -- a non-missing stat failure requires a host permission or I/O fault after resolve reached this ancestor. */
|
|
36
|
+
if (isMissing(error)) return void 0;
|
|
37
|
+
/* v8 ignore next -- requires a host permission or I/O fault after resolve already reached this ancestor. */
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
function sameIdentity(left, right) {
|
|
42
|
+
return left.dev === right.dev && left.ino === right.ino;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Determine whether a canonical target is a writable root or lies beneath it.
|
|
46
|
+
* The lexical fast path handles normal canonical spellings. When spellings
|
|
47
|
+
* differ, walk the target's existing ancestors and compare filesystem identity
|
|
48
|
+
* with the root; this recognizes Windows long-name/8.3 aliases and casing
|
|
49
|
+
* without weakening containment to a textual approximation.
|
|
50
|
+
* @param path - canonical target key, which may end in a missing suffix.
|
|
51
|
+
* @param root - canonical writable root.
|
|
52
|
+
* @param caseSensitive - whether lexical comparison preserves case; defaults
|
|
53
|
+
* to the host filesystem convention used by supported platforms.
|
|
54
|
+
* @returns whether the target is the root or a descendant of it.
|
|
55
|
+
*/
|
|
56
|
+
async function isPathUnder(path, root, caseSensitive = process.platform !== "win32") {
|
|
57
|
+
if (isLexicallyUnder(path, root, caseSensitive)) return true;
|
|
58
|
+
const rootInfo = await statIfPresent(root);
|
|
59
|
+
if (!rootInfo) return false;
|
|
60
|
+
let ancestor = path;
|
|
61
|
+
while (true) {
|
|
62
|
+
const ancestorInfo = await statIfPresent(ancestor);
|
|
63
|
+
if (ancestorInfo && sameIdentity(ancestorInfo, rootInfo)) return true;
|
|
64
|
+
const parent = dirname(ancestor);
|
|
65
|
+
if (parent === ancestor) return false;
|
|
66
|
+
ancestor = parent;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* `SandboxedFileSystem`: the sandbox-enforcing implementation of the
|
|
71
|
+
* `@deepseek-ai/dsh-fs` Service Definition. It extends `LocalFileSystem` so all
|
|
72
|
+
* text-storage mechanics — resolve, stat, read/stream, list, the atomic
|
|
73
|
+
* write and the read-match-write edit critical section — are the local
|
|
74
|
+
* implementation's, verbatim; this package adds only the per-call POLICY fence
|
|
75
|
+
* on the two mutations. Reads pass through untouched: every mode permits
|
|
76
|
+
* reading.
|
|
77
|
+
*
|
|
78
|
+
* The fence is a policy check in TRUSTED code over a MODEL-CONTROLLED path,
|
|
79
|
+
* NOT a kernel boundary — the operations are the seam's own (open, rename),
|
|
80
|
+
* and only the target path is untrusted, so canonicalize-then-contain is the
|
|
81
|
+
* complete answer to this surface. This is containment, not a security
|
|
82
|
+
* boundary; kernel-grade isolation of untrusted CODE stays `ctx.shell`'s job
|
|
83
|
+
* (`@deepseek-ai/dsh-bash-sandbox`). The residual
|
|
84
|
+
* TOCTOU (an ancestor symlink swapped between the containment re-check and the
|
|
85
|
+
* syscall) is narrowed by re-canonicalizing immediately before delegating and
|
|
86
|
+
* is accepted for this threat model.
|
|
87
|
+
*
|
|
88
|
+
* Per-call policy: `read-only` denies every mutation; `workspace-write` allows
|
|
89
|
+
* a mutation only when the target canonicalizes under the policy's workspace
|
|
90
|
+
* root or a platform temp area from the shared `writableRoots` policy;
|
|
91
|
+
* `danger-full-access` delegates unfenced. A denial throws the structured
|
|
92
|
+
* `FS_SANDBOX_DENIED`.
|
|
93
|
+
*
|
|
94
|
+
* @module @deepseek-ai/dsh-fs-sandbox
|
|
95
|
+
*/
|
|
96
|
+
/**
|
|
97
|
+
* Sandbox-enforcing filesystem backend. Registers as `ctx.fs` (loading it
|
|
98
|
+
* INSTEAD OF `dsh-fs-local`, together with a `ctx.sandboxPolicy`, is the whole
|
|
99
|
+
* swap — the model-facing tools are untouched). Its configured default mode is
|
|
100
|
+
* the capability fact exposed by {@link sandboxMode}; `dsh-tool-fs` resolves
|
|
101
|
+
* each session's mode and cwd into a policy for every mutation, while an
|
|
102
|
+
* approved escalation may stamp a strictly wider mode for one call.
|
|
103
|
+
*/
|
|
104
|
+
var SandboxedFileSystem = class extends LocalFileSystem {
|
|
105
|
+
static inject = ["sandboxPolicy"];
|
|
106
|
+
defaultMode;
|
|
107
|
+
constructor(ctx, config) {
|
|
108
|
+
super(ctx, config);
|
|
109
|
+
this.defaultMode = ctx.sandboxPolicy.defaultMode;
|
|
110
|
+
}
|
|
111
|
+
/** The deployment default mode — the capability fact the tool layer reads to advertise escalation. */
|
|
112
|
+
get sandboxMode() {
|
|
113
|
+
return this.defaultMode;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Fence the write by the per-call policy, then delegate to the inherited
|
|
117
|
+
* atomic write. See {@link checkedTarget}.
|
|
118
|
+
* @param target - the resolved target to write.
|
|
119
|
+
* @param content - the full new file content.
|
|
120
|
+
* @param expected - the write intent guarding the write; omit for unconditional.
|
|
121
|
+
* @param signal - aborts before atomic publication takes effect.
|
|
122
|
+
* @param sandboxPolicy - the per-call mode and workspace root; omit to use
|
|
123
|
+
* the deployment fallback.
|
|
124
|
+
* @returns the write outcome from the inherited backend.
|
|
125
|
+
*/
|
|
126
|
+
async writeText(target, content, expected, signal, sandboxPolicy) {
|
|
127
|
+
return super.writeText(await this.checkedTarget(target, sandboxPolicy), content, expected, signal);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Fence the edit by the per-call policy, then delegate to the inherited
|
|
131
|
+
* atomic edit. See {@link checkedTarget}.
|
|
132
|
+
* @param target - the resolved target to edit.
|
|
133
|
+
* @param edit - the literal search/replace request.
|
|
134
|
+
* @param expected - the version guard; omit for an unconditional edit.
|
|
135
|
+
* @param signal - aborts before atomic publication takes effect.
|
|
136
|
+
* @param sandboxPolicy - the per-call mode and workspace root; omit to use
|
|
137
|
+
* the deployment fallback.
|
|
138
|
+
* @returns the edit outcome from the inherited backend.
|
|
139
|
+
*/
|
|
140
|
+
async editText(target, edit, expected, signal, sandboxPolicy) {
|
|
141
|
+
return super.editText(await this.checkedTarget(target, sandboxPolicy), edit, expected, signal);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Enforce the per-call policy against `target` and return the EXACT target the
|
|
145
|
+
* mutation must use, so the checked identity is the mutated one (no
|
|
146
|
+
* check-here-write-there TOCTOU). `read-only` denies; `workspace-write`
|
|
147
|
+
* re-canonicalizes NOW (`resolve` realpaths the deepest existing ancestor,
|
|
148
|
+
* reflecting a concurrently swapped symlink), requires containment under a
|
|
149
|
+
* writable root, and returns THAT fresh target; `danger-full-access` returns
|
|
150
|
+
* the caller's target unfenced. Throws the structured `FS_SANDBOX_DENIED` on
|
|
151
|
+
* refusal — the tool layer maps it to the model-facing `[sandbox: …]` marker
|
|
152
|
+
* and the escalation hint.
|
|
153
|
+
*/
|
|
154
|
+
async checkedTarget(target, sandboxPolicy) {
|
|
155
|
+
const policy = sandboxPolicy ?? this.ctx.sandboxPolicy.resolve();
|
|
156
|
+
const { mode } = policy;
|
|
157
|
+
if (mode === "danger-full-access") return target;
|
|
158
|
+
if (mode === "read-only") throw new FsError(`cannot write "${target.displayPath}": file access denied under read-only mode`, "FS_SANDBOX_DENIED");
|
|
159
|
+
const fresh = await this.resolve(target.displayPath);
|
|
160
|
+
let contained = false;
|
|
161
|
+
for (const root of writableRoots(policy)) if (await isPathUnder(fresh.targetKey, root)) {
|
|
162
|
+
contained = true;
|
|
163
|
+
break;
|
|
164
|
+
}
|
|
165
|
+
if (!contained) throw new FsError(`cannot write "${target.displayPath}": file access denied under workspace-write mode`, "FS_SANDBOX_DENIED");
|
|
166
|
+
return fresh;
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
//#endregion
|
|
171
|
+
//#region src/fs-aware/sandbox-plugin.ts
|
|
172
|
+
/** Scheme prefix test — mirrors the resolver's own grammar. */
|
|
173
|
+
function isSchemePath(path) {
|
|
174
|
+
return /^[a-z][a-z0-9]*:\/\//.test(path);
|
|
175
|
+
}
|
|
176
|
+
/** Session-layer schemes are excluded from FS-layer resolution (design D2). */
|
|
177
|
+
function isSessionLayerScheme(path) {
|
|
178
|
+
return path.startsWith("ctx://") || path.startsWith("agent://") || path.startsWith("skill://");
|
|
179
|
+
}
|
|
180
|
+
function sessionLayerError(url) {
|
|
181
|
+
if (url.startsWith("skill://")) return new UrlSchemesError("CTX_SESSION_LAYER", `${url}: session-layer scheme — skill discovery (which roots load, scan depth, layered scope merge) is the host skill provider's business logic and resolves only against a calling agent, which the filesystem layer does not have. Load skills with the native \`skill\` tool; grep/glob with path=skill://… keep working through the tool layer`);
|
|
182
|
+
return new UrlSchemesError("CTX_SESSION_LAYER", `${url}: session-layer scheme — read it through the read tool (the session-layer resolver environment carries the live agent this filesystem layer does not have)`);
|
|
183
|
+
}
|
|
184
|
+
const Base = SandboxedFileSystem;
|
|
185
|
+
var FsAwareSandboxFileSystem = class extends Base {
|
|
186
|
+
static inject = [
|
|
187
|
+
"sandboxPolicy",
|
|
188
|
+
"settings",
|
|
189
|
+
"agents"
|
|
190
|
+
];
|
|
191
|
+
resolver;
|
|
192
|
+
schemeResolution;
|
|
193
|
+
constructor(ctx, config) {
|
|
194
|
+
super(ctx, config);
|
|
195
|
+
this.schemeResolution = config?.urlSchemes !== false;
|
|
196
|
+
this.resolver = this.buildResolver(ctx);
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* FS-layer resolver — the SHARED builder from `wrap.ts` (design D2). One
|
|
200
|
+
* registration source for both FS consumers: this backend and the instance
|
|
201
|
+
* wrap. (A private duplicate here once drifted — a doubled `dsh` register
|
|
202
|
+
* and a literal `'http'` that would silently drop `https` if this backend
|
|
203
|
+
* were ever the outermost layer.) The `ctx`/`agent` handlers it registers
|
|
204
|
+
* are unreachable here: session-layer schemes are guarded before resolve.
|
|
205
|
+
*/
|
|
206
|
+
buildResolver(ctx) {
|
|
207
|
+
return buildFsLayerResolver({ settings: ctx.settings }, this);
|
|
208
|
+
}
|
|
209
|
+
/** FS-layer resolver env: no live agent — session-layer schemes are excluded upstream. */
|
|
210
|
+
envFor(url) {
|
|
211
|
+
return {
|
|
212
|
+
fs: this,
|
|
213
|
+
rawUrl: url
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
async resolve(path, opts) {
|
|
217
|
+
if (!this.schemeResolution || !isSchemePath(path)) return super.resolve(path, opts);
|
|
218
|
+
if (isSessionLayerScheme(path)) throw sessionLayerError(path);
|
|
219
|
+
await this.resolver.resolve(this.envFor(path), path);
|
|
220
|
+
return {
|
|
221
|
+
targetKey: path,
|
|
222
|
+
displayPath: path
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
async stat(target, signal) {
|
|
226
|
+
if (!this.schemeResolution || !isSchemePath(target.targetKey)) return super.stat(target, signal);
|
|
227
|
+
if (isSessionLayerScheme(target.targetKey)) throw sessionLayerError(target.targetKey);
|
|
228
|
+
return {
|
|
229
|
+
type: "file",
|
|
230
|
+
size: (await this.resolver.resolve(this.envFor(target.targetKey), target.targetKey)).length
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
async readText(target, signal) {
|
|
234
|
+
if (!this.schemeResolution || !isSchemePath(target.targetKey)) return super.readText(target, signal);
|
|
235
|
+
if (isSessionLayerScheme(target.targetKey)) throw sessionLayerError(target.targetKey);
|
|
236
|
+
return this.resolver.resolve(this.envFor(target.targetKey), target.targetKey);
|
|
237
|
+
}
|
|
238
|
+
async writeText(target, ...rest) {
|
|
239
|
+
if (this.schemeResolution && isSchemePath(target.targetKey)) throw new UrlSchemesError("FS_VIRTUAL_READONLY", `cannot write "${target.targetKey}": scheme resources are read-only at the filesystem layer`);
|
|
240
|
+
return super.writeText(target, ...rest);
|
|
241
|
+
}
|
|
242
|
+
async editText(target, ...rest) {
|
|
243
|
+
if (this.schemeResolution && isSchemePath(target.targetKey)) throw new UrlSchemesError("FS_VIRTUAL_READONLY", `cannot edit "${target.targetKey}": scheme resources are read-only at the filesystem layer`);
|
|
244
|
+
return super.editText(target, ...rest);
|
|
245
|
+
}
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
//#endregion
|
|
249
|
+
export { FsAwareSandboxFileSystem as default };
|