@gajae-code/coding-agent 0.17.2 → 0.17.5
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/CHANGELOG.md +267 -0
- package/dist/types/cli/daemon-cli.d.ts +3 -1
- package/dist/types/cli/github-release.d.ts +17 -0
- package/dist/types/cli/public-command-entry.d.ts +56 -0
- package/dist/types/cli/public-command-errors.d.ts +126 -0
- package/dist/types/cli/public-command-evidence.d.ts +99 -0
- package/dist/types/cli/public-command-help.d.ts +65 -0
- package/dist/types/cli/public-command-registry.d.ts +69 -0
- package/dist/types/cli/session-picker.d.ts +1 -1
- package/dist/types/cli/setup-cli.d.ts +1 -0
- package/dist/types/cli/skills-cli.d.ts +5 -0
- package/dist/types/cli.d.ts +3 -0
- package/dist/types/commands/daemon.d.ts +4 -50
- package/dist/types/commands/sdk.d.ts +20 -37
- package/dist/types/commands/setup.d.ts +3 -0
- package/dist/types/commands/skills.d.ts +9 -0
- package/dist/types/config/autorouting-tier-map.d.ts +1049 -3
- package/dist/types/config/file-lock.d.ts +13 -3
- package/dist/types/config/model-profile-activation.d.ts +45 -1
- package/dist/types/config/model-registry.d.ts +14 -3
- package/dist/types/config/model-resolver.d.ts +1 -1
- package/dist/types/config/settings-schema.d.ts +11 -0
- package/dist/types/coordinator-mcp/question-state.d.ts +6 -1
- package/dist/types/daemon/operator-contract.d.ts +5 -1
- package/dist/types/eval/js/worker-protocol.d.ts +2 -0
- package/dist/types/exec/bash-executor.d.ts +2 -0
- package/dist/types/extensibility/extensions/types.d.ts +12 -0
- package/dist/types/extensibility/gjc-plugins/registry.d.ts +4 -0
- package/dist/types/extensibility/gjc-plugins/runtime-adapters.d.ts +11 -2
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +18 -0
- package/dist/types/extensibility/shared-events.d.ts +3 -1
- package/dist/types/gjc-runtime/session-state-lock.d.ts +61 -0
- package/dist/types/gjc-runtime/state-writer.d.ts +14 -1
- package/dist/types/harness-control-plane/control-endpoint.d.ts +4 -1
- package/dist/types/harness-control-plane/finalize.d.ts +14 -3
- package/dist/types/internal-urls/embedded-protocol.d.ts +9 -0
- package/dist/types/internal-urls/index.d.ts +1 -0
- package/dist/types/internal-urls/parse.d.ts +9 -1
- package/dist/types/main.d.ts +23 -1
- package/dist/types/modes/acp/acp-agent.d.ts +55 -1
- package/dist/types/modes/acp/startup-provenance.d.ts +16 -0
- package/dist/types/modes/components/custom-provider-wizard.d.ts +19 -1
- package/dist/types/modes/components/session-selector.d.ts +5 -2
- package/dist/types/modes/components/user-message-selector.d.ts +5 -2
- package/dist/types/modes/controllers/command-controller.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -1
- package/dist/types/modes/interactive-mode.d.ts +1 -1
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +11 -1
- package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +14 -1
- package/dist/types/modes/types.d.ts +2 -2
- package/dist/types/runtime/process-lifecycle.d.ts +2 -0
- package/dist/types/runtime-mcp/loader.d.ts +2 -0
- package/dist/types/runtime-mcp/manager.d.ts +69 -6
- package/dist/types/runtime-mcp/pool.d.ts +17 -0
- package/dist/types/runtime-mcp/redaction.d.ts +20 -0
- package/dist/types/runtime-mcp/startup-policy.d.ts +6 -0
- package/dist/types/runtime-mcp/tool-bridge.d.ts +9 -0
- package/dist/types/runtime-mcp/transports/http.d.ts +11 -0
- package/dist/types/sdk/broker/broker.d.ts +17 -4
- package/dist/types/sdk/broker/ensure.d.ts +3 -0
- package/dist/types/sdk/broker/identity.d.ts +5 -1
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +23 -3
- package/dist/types/sdk/broker/lifecycle.d.ts +15 -8
- package/dist/types/sdk/broker/managed-task-dag.d.ts +1335 -0
- package/dist/types/sdk/broker/managed-task-verification.d.ts +37 -0
- package/dist/types/sdk/broker/runtime.d.ts +1 -1
- package/dist/types/sdk/broker/session-index.d.ts +22 -3
- package/dist/types/sdk/broker/spawn-authority.d.ts +12 -0
- package/dist/types/sdk/broker/startup-failure.d.ts +4 -0
- package/dist/types/sdk/broker/stderr-drainer.d.ts +13 -0
- package/dist/types/sdk/bus/index.d.ts +19 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +7 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +5 -0
- package/dist/types/sdk/cli/master-cli.d.ts +6 -10
- package/dist/types/sdk/cli/rows.d.ts +19 -1
- package/dist/types/sdk/cli/session-cli.d.ts +22 -5
- package/dist/types/sdk/client/client.d.ts +2 -0
- package/dist/types/sdk/guides/cli.d.ts +3 -4
- package/dist/types/sdk/guides/verify.d.ts +2 -0
- package/dist/types/sdk/host/host.d.ts +9 -0
- package/dist/types/sdk/host/session-runtime.d.ts +31 -0
- package/dist/types/sdk/host/types.d.ts +10 -0
- package/dist/types/sdk/index.d.ts +1 -0
- package/dist/types/sdk/prompt-deadline-flush.d.ts +85 -0
- package/dist/types/sdk/prompt-deadline-manager.d.ts +37 -0
- package/dist/types/sdk/prompt-tool-boundary.d.ts +73 -0
- package/dist/types/sdk/router/session-router.d.ts +2 -0
- package/dist/types/sdk/session.d.ts +3 -3
- package/dist/types/sdk/startup-capability.d.ts +2 -0
- package/dist/types/sdk/transport/relay.d.ts +1 -0
- package/dist/types/sdk/transport/serve-cli.d.ts +48 -4
- package/dist/types/sdk/transport/stdio.d.ts +5 -1
- package/dist/types/session/agent-session.d.ts +175 -23
- package/dist/types/session/fallback-chain-controller.d.ts +6 -6
- package/dist/types/session/fold-coordinator.d.ts +17 -3
- package/dist/types/session/internal/managed-session-storage.d.ts +7 -1
- package/dist/types/session/session-manager.d.ts +64 -1
- package/dist/types/session/session-work-lease.d.ts +14 -0
- package/dist/types/setup/model-onboarding-guidance.d.ts +1 -1
- package/dist/types/setup/provider-onboarding.d.ts +81 -1
- package/dist/types/task/types.d.ts +2 -0
- package/dist/types/tools/bash-interactive.d.ts +1 -0
- package/dist/types/tools/bash.d.ts +37 -11
- package/dist/types/tools/fetch.d.ts +10 -1
- package/dist/types/tools/job.d.ts +1 -1
- package/dist/types/tools/steer-fold.d.ts +31 -0
- package/dist/types/tools/subagent.d.ts +8 -1
- package/dist/types/utils/git.d.ts +28 -2
- package/dist/types/utils/mupdf-embedded.d.ts +2 -0
- package/dist/types/utils/mupdf.d.ts +4 -0
- package/dist/types/utils/session-title-generation.d.ts +6 -0
- package/dist/types/utils/title-generator.d.ts +11 -2
- package/dist/types/web/scrapers/types.d.ts +3 -0
- package/package.json +18 -10
- package/scripts/build-binary.ts +9 -3
- package/scripts/compile-args.ts +0 -9
- package/scripts/embed-mupdf.ts +52 -0
- package/scripts/generate-sdk-operation-inventory.ts +31 -1
- package/scripts/vendor-markit.ts +196 -0
- package/src/async/job-manager.ts +22 -1
- package/src/cli/daemon-cli.ts +53 -18
- package/src/cli/github-release.ts +87 -5
- package/src/cli/mcp-cli.ts +38 -4
- package/src/cli/public-command-entry.ts +450 -0
- package/src/cli/public-command-errors.ts +581 -0
- package/src/cli/public-command-evidence.ts +717 -0
- package/src/cli/public-command-help.ts +360 -0
- package/src/cli/public-command-registry.ts +541 -0
- package/src/cli/session-picker.ts +2 -1
- package/src/cli/setup-cli.ts +10 -1
- package/src/cli/skills-cli.ts +46 -2
- package/src/cli/stats-cli.ts +11 -1
- package/src/cli.ts +61 -1
- package/src/commands/daemon.ts +65 -69
- package/src/commands/sdk.ts +175 -117
- package/src/commands/setup.ts +2 -0
- package/src/commands/skills.ts +11 -0
- package/src/config/autorouting-tier-map.ts +543 -3
- package/src/config/file-lock.ts +206 -65
- package/src/config/model-discovery-manager.ts +4 -4
- package/src/config/model-profile-activation.ts +417 -66
- package/src/config/model-registry.ts +254 -36
- package/src/config/model-resolver.ts +6 -1
- package/src/config/settings-schema.ts +26 -2
- package/src/coordinator-mcp/policy.ts +10 -5
- package/src/coordinator-mcp/question-gate-codec.ts +17 -0
- package/src/coordinator-mcp/question-state.ts +179 -9
- package/src/coordinator-mcp/server.ts +521 -87
- package/src/coordinator-mcp/session-reaper.ts +6 -4
- package/src/crash/record-loader.ts +6 -2
- package/src/daemon/operator-contract.ts +26 -12
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +1 -1
- package/src/eval/js/context-manager.ts +8 -8
- package/src/eval/js/worker-core.ts +9 -4
- package/src/eval/js/worker-protocol.ts +2 -0
- package/src/exec/bash-executor.ts +3 -0
- package/src/extensibility/extensions/runner.ts +52 -4
- package/src/extensibility/extensions/types.ts +10 -0
- package/src/extensibility/gjc-plugins/registry.ts +196 -37
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +46 -8
- package/src/extensibility/runtime-skill-discovery.ts +61 -3
- package/src/extensibility/shared-events.ts +3 -1
- package/src/gjc-runtime/session-state-lock.ts +165 -24
- package/src/gjc-runtime/state-writer.ts +317 -6
- package/src/gjc-runtime/ultragoal-succession.ts +31 -3
- package/src/harness-control-plane/control-endpoint.ts +24 -6
- package/src/harness-control-plane/finalize.ts +312 -25
- package/src/harness-control-plane/owner.ts +323 -89
- package/src/internal-urls/docs-index.generated.ts +23 -20
- package/src/internal-urls/embedded-protocol.ts +83 -0
- package/src/internal-urls/index.ts +1 -0
- package/src/internal-urls/parse.ts +21 -1
- package/src/internal-urls/router.ts +4 -2
- package/src/main.ts +192 -74
- package/src/modes/acp/acp-agent.ts +973 -56
- package/src/modes/acp/startup-provenance.ts +59 -0
- package/src/modes/components/custom-provider-wizard.ts +308 -7
- package/src/modes/components/gjc-bundle-settings.ts +21 -1
- package/src/modes/components/oauth-selector.ts +9 -0
- package/src/modes/components/session-selector.ts +47 -4
- package/src/modes/components/tool-status-header.ts +72 -6
- package/src/modes/components/user-message-selector.ts +57 -15
- package/src/modes/controllers/command-controller.ts +58 -32
- package/src/modes/controllers/extension-ui-controller.ts +33 -7
- package/src/modes/controllers/input-controller.ts +4 -0
- package/src/modes/controllers/runtime-mcp-command-controller.ts +1 -1
- package/src/modes/controllers/selector-controller.ts +161 -15
- package/src/modes/interactive-mode.ts +21 -7
- package/src/modes/runtime-init.ts +1 -0
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +124 -7
- package/src/modes/shared/agent-wire/workflow-gate-types.ts +16 -2
- package/src/modes/types.ts +2 -2
- package/src/prompts/agent-fragments/browser-aside.md +1 -0
- package/src/prompts/system/title-system.md +1 -1
- package/src/prompts/tools/bash.md +1 -1
- package/src/prompts/tools/job.md +1 -1
- package/src/prompts/tools/read.md +2 -0
- package/src/runtime/network-prewarm-service.test.ts +36 -1
- package/src/runtime/network-prewarm-service.ts +28 -3
- package/src/runtime/process-lifecycle.ts +22 -11
- package/src/runtime-mcp/config.ts +16 -1
- package/src/runtime-mcp/loader.ts +6 -3
- package/src/runtime-mcp/manager.ts +845 -109
- package/src/runtime-mcp/pool.test.ts +31 -0
- package/src/runtime-mcp/pool.ts +304 -28
- package/src/runtime-mcp/redaction.ts +42 -0
- package/src/runtime-mcp/startup-policy.ts +7 -0
- package/src/runtime-mcp/tool-bridge.ts +71 -0
- package/src/runtime-mcp/transports/http.ts +108 -25
- package/src/sdk/acp/adapter.ts +27 -8
- package/src/sdk/broker/broker.ts +1431 -198
- package/src/sdk/broker/ensure.ts +21 -3
- package/src/sdk/broker/identity.ts +22 -1
- package/src/sdk/broker/lifecycle-ledger.ts +95 -31
- package/src/sdk/broker/lifecycle.ts +690 -141
- package/src/sdk/broker/managed-task-dag.ts +1927 -0
- package/src/sdk/broker/managed-task-verification.ts +642 -0
- package/src/sdk/broker/runtime.ts +1 -1
- package/src/sdk/broker/session-index.ts +97 -4
- package/src/sdk/broker/spawn-authority.ts +175 -14
- package/src/sdk/broker/startup-failure.ts +80 -1
- package/src/sdk/broker/stderr-drainer.ts +59 -0
- package/src/sdk/broker/transport.ts +1 -0
- package/src/sdk/bus/chat-daemon-control.ts +2 -2
- package/src/sdk/bus/chat-daemon-runtime.ts +1 -0
- package/src/sdk/bus/index.ts +707 -81
- package/src/sdk/bus/telegram-daemon-cli.ts +31 -2
- package/src/sdk/bus/telegram-daemon-contract.ts +7 -1
- package/src/sdk/bus/telegram-daemon.ts +10 -3
- package/src/sdk/cli/master-cli.ts +47 -36
- package/src/sdk/cli/rows.ts +30 -7
- package/src/sdk/cli/session-cli.ts +705 -184
- package/src/sdk/client/client.ts +18 -0
- package/src/sdk/guides/catalog.ts +2 -2
- package/src/sdk/guides/cli.ts +20 -62
- package/src/sdk/guides/verify.ts +14 -0
- package/src/sdk/host/host.ts +49 -5
- package/src/sdk/host/session-runtime.test.ts +184 -2
- package/src/sdk/host/session-runtime.ts +322 -101
- package/src/sdk/host/types.ts +12 -1
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +84 -0
- package/src/sdk/host/websocket-transport.ts +40 -6
- package/src/sdk/index.ts +11 -0
- package/src/sdk/lifecycle/service.ts +2 -0
- package/src/sdk/prompt-deadline-flush.ts +356 -0
- package/src/sdk/prompt-deadline-manager.ts +133 -1
- package/src/sdk/prompt-tool-boundary.ts +121 -0
- package/src/sdk/protocol/operation-inventory.generated.json +106 -0
- package/src/sdk/router/session-router.ts +9 -1
- package/src/sdk/session.ts +763 -116
- package/src/sdk/startup-capability.ts +1 -1
- package/src/sdk/transport/relay.ts +71 -6
- package/src/sdk/transport/serve-cli.ts +397 -42
- package/src/sdk/transport/socket.ts +12 -11
- package/src/sdk/transport/stdio.ts +7 -3
- package/src/session/agent-session.ts +2472 -407
- package/src/session/fallback-chain-controller.ts +6 -7
- package/src/session/fold-coordinator.ts +24 -5
- package/src/session/internal/managed-session-scope.ts +68 -18
- package/src/session/internal/managed-session-storage.ts +334 -12
- package/src/session/session-manager.ts +382 -44
- package/src/session/session-work-lease.ts +34 -0
- package/src/setup/model-onboarding-guidance.ts +1 -1
- package/src/setup/provider-onboarding.ts +397 -24
- package/src/setup/provider-presets.json +2 -1
- package/src/slash-commands/builtin-registry.ts +259 -15
- package/src/task/executor.ts +46 -17
- package/src/task/index.ts +14 -2
- package/src/task/types.ts +2 -0
- package/src/tools/bash-interactive.ts +2 -0
- package/src/tools/bash.ts +118 -78
- package/src/tools/fetch.ts +140 -25
- package/src/tools/job.ts +151 -25
- package/src/tools/output-meta.ts +15 -2
- package/src/tools/path-utils.ts +27 -3
- package/src/tools/read.ts +3 -3
- package/src/tools/steer-fold.ts +107 -0
- package/src/tools/subagent-render.ts +24 -1
- package/src/tools/subagent.ts +27 -1
- package/src/tools/tool-catalog.generated.ts +29 -2
- package/src/tools/tool-errors.ts +4 -0
- package/src/utils/git.ts +53 -3
- package/src/utils/markit.ts +55 -41
- package/src/utils/mupdf-assets.d.ts +4 -0
- package/src/utils/mupdf-embedded.ts +4 -0
- package/src/utils/mupdf.ts +136 -0
- package/src/utils/session-title-generation.ts +29 -0
- package/src/utils/title-generator.ts +46 -2
- package/src/web/scrapers/types.ts +24 -3
- package/vendor/markit-ai/LICENSE +21 -0
- package/vendor/markit-ai/MANIFEST.json +412 -0
- package/vendor/markit-ai/dist/commands/config.d.ts +4 -0
- package/vendor/markit-ai/dist/commands/config.js +139 -0
- package/vendor/markit-ai/dist/commands/convert.d.ts +6 -0
- package/vendor/markit-ai/dist/commands/convert.js +113 -0
- package/vendor/markit-ai/dist/commands/formats.d.ts +2 -0
- package/vendor/markit-ai/dist/commands/formats.js +92 -0
- package/vendor/markit-ai/dist/commands/init.d.ts +2 -0
- package/vendor/markit-ai/dist/commands/init.js +29 -0
- package/vendor/markit-ai/dist/commands/onboard.d.ts +2 -0
- package/vendor/markit-ai/dist/commands/onboard.js +61 -0
- package/vendor/markit-ai/dist/commands/plugin.d.ts +4 -0
- package/vendor/markit-ai/dist/commands/plugin.js +58 -0
- package/vendor/markit-ai/dist/config.d.ts +26 -0
- package/vendor/markit-ai/dist/config.js +42 -0
- package/vendor/markit-ai/dist/converters/audio.d.ts +7 -0
- package/vendor/markit-ai/dist/converters/audio.js +104 -0
- package/vendor/markit-ai/dist/converters/csv.d.ts +7 -0
- package/vendor/markit-ai/dist/converters/csv.js +83 -0
- package/vendor/markit-ai/dist/converters/docx.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/docx.js +57 -0
- package/vendor/markit-ai/dist/converters/epub.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/epub.js +128 -0
- package/vendor/markit-ai/dist/converters/github.d.ts +18 -0
- package/vendor/markit-ai/dist/converters/github.js +148 -0
- package/vendor/markit-ai/dist/converters/html.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/html.js +30 -0
- package/vendor/markit-ai/dist/converters/image.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/image.js +124 -0
- package/vendor/markit-ai/dist/converters/ipynb.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/ipynb.js +75 -0
- package/vendor/markit-ai/dist/converters/iwork.d.ts +20 -0
- package/vendor/markit-ai/dist/converters/iwork.js +391 -0
- package/vendor/markit-ai/dist/converters/json.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/json.js +21 -0
- package/vendor/markit-ai/dist/converters/pdf/columns.d.ts +35 -0
- package/vendor/markit-ai/dist/converters/pdf/columns.js +93 -0
- package/vendor/markit-ai/dist/converters/pdf/extract.d.ts +19 -0
- package/vendor/markit-ai/dist/converters/pdf/extract.js +514 -0
- package/vendor/markit-ai/dist/converters/pdf/grid.d.ts +25 -0
- package/vendor/markit-ai/dist/converters/pdf/grid.js +795 -0
- package/vendor/markit-ai/dist/converters/pdf/headers.d.ts +24 -0
- package/vendor/markit-ai/dist/converters/pdf/headers.js +108 -0
- package/vendor/markit-ai/dist/converters/pdf/index.d.ts +19 -0
- package/vendor/markit-ai/dist/converters/pdf/index.js +136 -0
- package/vendor/markit-ai/dist/converters/pdf/mupdf-loader.js +9 -0
- package/vendor/markit-ai/dist/converters/pdf/render.d.ts +24 -0
- package/vendor/markit-ai/dist/converters/pdf/render.js +513 -0
- package/vendor/markit-ai/dist/converters/pdf/types.d.ts +75 -0
- package/vendor/markit-ai/dist/converters/pdf/types.js +1 -0
- package/vendor/markit-ai/dist/converters/plain-text.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/plain-text.js +87 -0
- package/vendor/markit-ai/dist/converters/pptx.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/pptx.js +289 -0
- package/vendor/markit-ai/dist/converters/rss.d.ts +11 -0
- package/vendor/markit-ai/dist/converters/rss.js +138 -0
- package/vendor/markit-ai/dist/converters/wikipedia.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/wikipedia.js +33 -0
- package/vendor/markit-ai/dist/converters/xlsx.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/xlsx.js +147 -0
- package/vendor/markit-ai/dist/converters/xml.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/xml.js +18 -0
- package/vendor/markit-ai/dist/converters/yaml.d.ts +6 -0
- package/vendor/markit-ai/dist/converters/yaml.js +17 -0
- package/vendor/markit-ai/dist/converters/zip.d.ts +8 -0
- package/vendor/markit-ai/dist/converters/zip.js +57 -0
- package/vendor/markit-ai/dist/index.d.ts +30 -0
- package/vendor/markit-ai/dist/index.js +26 -0
- package/vendor/markit-ai/dist/main.d.ts +2 -0
- package/vendor/markit-ai/dist/main.js +191 -0
- package/vendor/markit-ai/dist/markit.d.ts +45 -0
- package/vendor/markit-ai/dist/markit.js +267 -0
- package/vendor/markit-ai/dist/plugins/api.d.ts +7 -0
- package/vendor/markit-ai/dist/plugins/api.js +42 -0
- package/vendor/markit-ai/dist/plugins/index.d.ts +4 -0
- package/vendor/markit-ai/dist/plugins/index.js +3 -0
- package/vendor/markit-ai/dist/plugins/installer.d.ts +25 -0
- package/vendor/markit-ai/dist/plugins/installer.js +176 -0
- package/vendor/markit-ai/dist/plugins/loader.d.ts +6 -0
- package/vendor/markit-ai/dist/plugins/loader.js +61 -0
- package/vendor/markit-ai/dist/plugins/types.d.ts +25 -0
- package/vendor/markit-ai/dist/plugins/types.js +1 -0
- package/vendor/markit-ai/dist/providers/anthropic.d.ts +2 -0
- package/vendor/markit-ai/dist/providers/anthropic.js +47 -0
- package/vendor/markit-ai/dist/providers/index.d.ts +21 -0
- package/vendor/markit-ai/dist/providers/index.js +56 -0
- package/vendor/markit-ai/dist/providers/openai.d.ts +2 -0
- package/vendor/markit-ai/dist/providers/openai.js +76 -0
- package/vendor/markit-ai/dist/providers/types.d.ts +26 -0
- package/vendor/markit-ai/dist/providers/types.js +1 -0
- package/vendor/markit-ai/dist/types.d.ts +36 -0
- package/vendor/markit-ai/dist/types.js +1 -0
- package/vendor/markit-ai/dist/utils/exit-codes.d.ts +4 -0
- package/vendor/markit-ai/dist/utils/exit-codes.js +4 -0
- package/vendor/markit-ai/dist/utils/output.d.ts +22 -0
- package/vendor/markit-ai/dist/utils/output.js +31 -0
- package/vendor/markit-ai/dist/utils/turndown.d.ts +8 -0
- package/vendor/markit-ai/dist/utils/turndown.js +70 -0
- package/vendor/markit-ai/package.json +74 -0
- package/vendor/markit-ai.patch +49 -0
|
@@ -26,7 +26,12 @@ import {
|
|
|
26
26
|
import { isAuthenticated, kNoAuth } from "../../config/model-registry";
|
|
27
27
|
import { resolveModelChainWithAuth, splitSelectorThinkingSuffix } from "../../config/model-resolver";
|
|
28
28
|
import { type ModelSelectorValue, normalizeModelSelectorValue } from "../../config/model-selector-value";
|
|
29
|
-
import {
|
|
29
|
+
import {
|
|
30
|
+
resolveSdkPromptDeadlineMs,
|
|
31
|
+
resolveSdkPromptMaxRuntimeMs,
|
|
32
|
+
type Settings,
|
|
33
|
+
validateSettingPatch,
|
|
34
|
+
} from "../../config/settings";
|
|
30
35
|
import type { ExtensionAPI, ExtensionCommandContext, ExtensionContext } from "../../extensibility/extensions";
|
|
31
36
|
import type { AgentEndEvent } from "../../extensibility/shared-events";
|
|
32
37
|
import { normalizeGoal } from "../../goals/state";
|
|
@@ -59,6 +64,7 @@ import {
|
|
|
59
64
|
syntheticNamespaceCollision,
|
|
60
65
|
} from "../model-profile-model";
|
|
61
66
|
import { projectQ10Models } from "../models.js";
|
|
67
|
+
import { flushWorktreeOnPromptDeadline } from "../prompt-deadline-flush";
|
|
62
68
|
import { PromptDeadlineManager, type PromptTerminalTransitionEvidence } from "../prompt-deadline-manager";
|
|
63
69
|
import {
|
|
64
70
|
assistantFailureCode,
|
|
@@ -92,7 +98,12 @@ import {
|
|
|
92
98
|
BROKER_RUNTIME_CLOSE_CAPABILITY_FIELD,
|
|
93
99
|
hasBrokerRuntimeAbortCapability,
|
|
94
100
|
} from "./control/runtime-gate";
|
|
95
|
-
import {
|
|
101
|
+
import {
|
|
102
|
+
SESSION_HOST_OBSERVER_CAPABILITY,
|
|
103
|
+
SessionSdkHost,
|
|
104
|
+
type SessionSdkHostOptions,
|
|
105
|
+
TURN_STREAM_CAPABILITY,
|
|
106
|
+
} from "./host";
|
|
96
107
|
import { clearAutoroutingInactive, isAutoroutingInactive, markAutoroutingInactive } from "./internal-autorouting-state";
|
|
97
108
|
import { CursorRegistry, QueryHandlers, RevisionStore, type SessionSurface } from "./query";
|
|
98
109
|
import { createSdkRunCapability } from "./sdk-run-capability";
|
|
@@ -196,6 +207,13 @@ export function verifyMasterCapabilityFrame(input: {
|
|
|
196
207
|
|
|
197
208
|
/** Maximum time a replaced runtime may retain a lifecycle persistence task. */
|
|
198
209
|
const LIFECYCLE_QUIESCENCE_MS = 1_000;
|
|
210
|
+
/**
|
|
211
|
+
* Keep a live session's broker discovery recoverable well inside the session
|
|
212
|
+
* index's two-minute heartbeat freshness window. `ensureBroker` has its own
|
|
213
|
+
* bounded startup/recovery budget; the in-flight guard below prevents those
|
|
214
|
+
* budgets from stacking when one attempt outlives this cadence.
|
|
215
|
+
*/
|
|
216
|
+
export const SESSION_BROKER_RECOVERY_INTERVAL_MS = 30_000;
|
|
199
217
|
|
|
200
218
|
class DiffQueryError extends Error {
|
|
201
219
|
constructor(
|
|
@@ -357,6 +375,17 @@ export interface SdkOnlyTerminalAbortSeams {
|
|
|
357
375
|
terminal?: { scope: "turn" | "owned"; expectedEpoch?: number; steeringSnapshotToken?: number };
|
|
358
376
|
},
|
|
359
377
|
) => Promise<{ status: string; terminalScope?: unknown }>;
|
|
378
|
+
/**
|
|
379
|
+
* Live, SYNCHRONOUS view of the dispatched tool calls the run resource
|
|
380
|
+
* ledger holds for an execution handle (#5637). Strictly read-only: it
|
|
381
|
+
* never claims, reserves, seals or quarantines ledger state. Declared here
|
|
382
|
+
* so both hosts expose ONE seam contract — the bus route consumes it for its
|
|
383
|
+
* deadline tool-boundary wait, and this route threads it so a future boundary
|
|
384
|
+
* wait or deadline abort reads the ledger rather than silently falling back
|
|
385
|
+
* to the event-derived set. Optional so an older host that does not thread it
|
|
386
|
+
* degrades to that fallback instead of failing to construct.
|
|
387
|
+
*/
|
|
388
|
+
pendingToolExecutions?: (handle: string) => readonly string[];
|
|
360
389
|
/** Test override for the maximum durable terminal reservation rows. */
|
|
361
390
|
maxDurableTerminalReservationsForTests?: number;
|
|
362
391
|
}
|
|
@@ -372,6 +401,9 @@ export interface SdkOnlyTerminalAbortSeams {
|
|
|
372
401
|
export class SessionSdkSessionRuntime {
|
|
373
402
|
readonly host: SessionSdkHost;
|
|
374
403
|
readonly transport: SessionSdkTransport;
|
|
404
|
+
readonly #connectionCapabilities = new Map<string, ReadonlySet<string>>();
|
|
405
|
+
readonly #connectionIds = new Set<string>();
|
|
406
|
+
readonly #connectionCapabilitiesProvider: (connectionId: string) => ReadonlySet<string> | undefined;
|
|
375
407
|
readonly #connectionDisposer?: () => void;
|
|
376
408
|
readonly #malformedDisposer?: () => void;
|
|
377
409
|
readonly #capabilitiesDisposer?: () => void;
|
|
@@ -380,10 +412,11 @@ export class SessionSdkSessionRuntime {
|
|
|
380
412
|
|
|
381
413
|
constructor(options: SessionSdkRuntimeOptions) {
|
|
382
414
|
this.transport = options.transport;
|
|
383
|
-
|
|
415
|
+
this.#connectionCapabilitiesProvider =
|
|
416
|
+
options.connectionCapabilities ?? (connectionId => this.#connectionCapabilities.get(connectionId));
|
|
384
417
|
this.host = new SessionSdkHost({
|
|
385
418
|
...options,
|
|
386
|
-
connectionCapabilities:
|
|
419
|
+
connectionCapabilities: this.#connectionCapabilitiesProvider,
|
|
387
420
|
sessionId: options.transport.sessionId,
|
|
388
421
|
stateRoot: options.transport.stateRoot,
|
|
389
422
|
token: options.transport.token,
|
|
@@ -392,14 +425,21 @@ export class SessionSdkSessionRuntime {
|
|
|
392
425
|
if (result instanceof Promise) return result.then(outcome => outcome ?? "written");
|
|
393
426
|
return result ?? "written";
|
|
394
427
|
},
|
|
395
|
-
onFrame:
|
|
428
|
+
onFrame: handler =>
|
|
429
|
+
options.transport.onFrame((connectionId, frame) => {
|
|
430
|
+
this.#connectionIds.add(connectionId);
|
|
431
|
+
handler(connectionId, frame);
|
|
432
|
+
}),
|
|
396
433
|
});
|
|
397
434
|
this.#connectionDisposer = options.transport.onConnectionClose?.(connectionId => {
|
|
398
|
-
|
|
435
|
+
this.#connectionIds.delete(connectionId);
|
|
436
|
+
this.#connectionCapabilities.delete(connectionId);
|
|
399
437
|
this.host.handleDisconnect(connectionId);
|
|
400
438
|
});
|
|
401
439
|
this.#capabilitiesDisposer = options.transport.onNegotiatedCapabilities?.((connectionId, negotiated) => {
|
|
402
|
-
|
|
440
|
+
if (options.connectionCapabilities && this.#connectionCapabilitiesProvider(connectionId) === undefined) return;
|
|
441
|
+
this.#connectionIds.add(connectionId);
|
|
442
|
+
this.#connectionCapabilities.set(connectionId, new Set(negotiated));
|
|
403
443
|
});
|
|
404
444
|
this.#malformedDisposer = options.transport.onMalformedFrame?.((connectionId, message) => {
|
|
405
445
|
this.host.handleMalformedFrame(connectionId, message);
|
|
@@ -418,6 +458,11 @@ export class SessionSdkSessionRuntime {
|
|
|
418
458
|
return this.host.getProviderDefinitions(capability);
|
|
419
459
|
}
|
|
420
460
|
|
|
461
|
+
/** Persist the host's current observable activity for broker/session-list consumers. */
|
|
462
|
+
async reportActivity(state: "active" | "idle", at = Date.now()): Promise<void> {
|
|
463
|
+
await this.host.reportActivity(state, at);
|
|
464
|
+
}
|
|
465
|
+
|
|
421
466
|
emitEvent(frame: SdkFrame): void {
|
|
422
467
|
const eventInput =
|
|
423
468
|
typeof frame.kind === "string"
|
|
@@ -447,6 +492,27 @@ export class SessionSdkSessionRuntime {
|
|
|
447
492
|
}
|
|
448
493
|
}
|
|
449
494
|
|
|
495
|
+
/** Snapshot connections that negotiated every capability in the requirement set. */
|
|
496
|
+
connectionIdsWithCapabilities(required: readonly string[]): string[] {
|
|
497
|
+
return [...this.#connectionIds].flatMap(connectionId => {
|
|
498
|
+
const capabilities = this.#connectionCapabilitiesProvider(connectionId);
|
|
499
|
+
return capabilities !== undefined && required.every(capability => capabilities.has(capability))
|
|
500
|
+
? [connectionId]
|
|
501
|
+
: [];
|
|
502
|
+
});
|
|
503
|
+
}
|
|
504
|
+
/** Deliver a non-replayable frame to connections with an explicit capability intersection. */
|
|
505
|
+
sendFrameToCapabilities(
|
|
506
|
+
required: readonly string[],
|
|
507
|
+
frame: SdkFrame,
|
|
508
|
+
excluding: ReadonlySet<string> = new Set(),
|
|
509
|
+
): void {
|
|
510
|
+
for (const connectionId of this.connectionIdsWithCapabilities(required)) {
|
|
511
|
+
if (excluding.has(connectionId)) continue;
|
|
512
|
+
this.sendFrameTo(connectionId, frame);
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
|
|
450
516
|
publish(frame: SdkFrame): void {
|
|
451
517
|
this.emitEvent(frame);
|
|
452
518
|
}
|
|
@@ -500,7 +566,7 @@ export class SessionSdkSessionRuntime {
|
|
|
500
566
|
}
|
|
501
567
|
}
|
|
502
568
|
|
|
503
|
-
async stop(options: { allowLockContention?: boolean } = {}): Promise<void> {
|
|
569
|
+
async stop(options: { allowLockContention?: boolean; unregisterReason?: "detached_idle" } = {}): Promise<void> {
|
|
504
570
|
this.#connectionDisposer?.();
|
|
505
571
|
this.#capabilitiesDisposer?.();
|
|
506
572
|
this.#malformedDisposer?.();
|
|
@@ -558,6 +624,11 @@ export interface CreateSdkSessionRuntimeOptions {
|
|
|
558
624
|
terminalAbortSeams?: SdkOnlyTerminalAbortSeams;
|
|
559
625
|
/** Callback when a frame is admitted to the runtime (test harness). */
|
|
560
626
|
onFrameAdmitted?: () => void;
|
|
627
|
+
/** Timer seams for deterministic broker-recovery lifecycle tests. */
|
|
628
|
+
setIntervalImpl?: typeof setInterval;
|
|
629
|
+
clearIntervalImpl?: typeof clearInterval;
|
|
630
|
+
/** Test-only broker ensure seam; production always uses the owner-fenced helper. */
|
|
631
|
+
ensureBrokerImpl?: typeof ensureBroker;
|
|
561
632
|
/** Test-only observation of a genuinely timed-out lifecycle drain. */
|
|
562
633
|
onLifecycleDrainTimeoutForTests?: () => void;
|
|
563
634
|
/** Test-only observation of bounded failure-diagnostic deduplication state. */
|
|
@@ -1947,6 +2018,7 @@ function createQuerySurface(
|
|
|
1947
2018
|
...gate,
|
|
1948
2019
|
id: `pending:${gate.gate_id}`,
|
|
1949
2020
|
tag: "pending" as const,
|
|
2021
|
+
answer_recorded: false as const,
|
|
1950
2022
|
})) ??
|
|
1951
2023
|
[]
|
|
1952
2024
|
);
|
|
@@ -4167,6 +4239,7 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
4167
4239
|
sdkRunToken: string;
|
|
4168
4240
|
}>;
|
|
4169
4241
|
registerBroker: () => Promise<void>;
|
|
4242
|
+
stopBrokerRecovery: () => void;
|
|
4170
4243
|
quiesceInput: () => void;
|
|
4171
4244
|
fenceGateResolutions: () => void;
|
|
4172
4245
|
waitForGateResolutionQuiescence: () => Promise<void>;
|
|
@@ -4462,10 +4535,12 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
4462
4535
|
return task;
|
|
4463
4536
|
};
|
|
4464
4537
|
/**
|
|
4465
|
-
* Publish one content frame per owning invocation,
|
|
4466
|
-
*
|
|
4467
|
-
*
|
|
4468
|
-
*
|
|
4538
|
+
* Publish one correlated content frame per owning invocation, plus one
|
|
4539
|
+
* unpositioned copy for connections that explicitly negotiated observer
|
|
4540
|
+
* streaming. A shared run therefore lets every submitter attribute the content
|
|
4541
|
+
* to its own prompt without exposing it to ordinary attached clients.
|
|
4542
|
+
* Content is best-effort and bypasses the lifecycle replay ring; the turn
|
|
4543
|
+
* producing it is authoritative.
|
|
4469
4544
|
*/
|
|
4470
4545
|
const publishContentFrames = (
|
|
4471
4546
|
current: RuntimeState,
|
|
@@ -4474,8 +4549,10 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
4474
4549
|
): void => {
|
|
4475
4550
|
try {
|
|
4476
4551
|
const payload = toAgentWireEventPayload(event);
|
|
4552
|
+
const delivered = new Set<string>();
|
|
4477
4553
|
for (const invocation of invocations) {
|
|
4478
4554
|
if (invocation.connectionId === undefined) continue;
|
|
4555
|
+
delivered.add(invocation.connectionId);
|
|
4479
4556
|
current.runtime.sendFrameTo(invocation.connectionId, {
|
|
4480
4557
|
type: "event",
|
|
4481
4558
|
kind: event.type,
|
|
@@ -4483,6 +4560,14 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
4483
4560
|
...invocation.correlation,
|
|
4484
4561
|
});
|
|
4485
4562
|
}
|
|
4563
|
+
// A relay or dashboard can observe a turn submitted by another client. It
|
|
4564
|
+
// explicitly negotiates both the stream and observer capabilities, so give it
|
|
4565
|
+
// the same live content frames without inventing a submitter correlation.
|
|
4566
|
+
current.runtime.sendFrameToCapabilities(
|
|
4567
|
+
[TURN_STREAM_CAPABILITY, SESSION_HOST_OBSERVER_CAPABILITY],
|
|
4568
|
+
{ type: "event", kind: event.type, payload },
|
|
4569
|
+
delivered,
|
|
4570
|
+
);
|
|
4486
4571
|
} catch {
|
|
4487
4572
|
// Streamed content is best-effort; the turn producing it is authoritative.
|
|
4488
4573
|
}
|
|
@@ -5031,7 +5116,16 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
5031
5116
|
};
|
|
5032
5117
|
api.on("agent_start", (event, ctx) => {
|
|
5033
5118
|
const owner = lifecycleStateForEvent(ctx, "agent_start", event.sdkRunToken);
|
|
5034
|
-
|
|
5119
|
+
// The activity checkpoint is already fire-and-forget and does not depend on
|
|
5120
|
+
// the handler awaiting trackLifecycle, so it composes with #5683 unchanged.
|
|
5121
|
+
void (owner?.runtime ?? lifecycleStateForContext(ctx, "agent_start")?.runtime)
|
|
5122
|
+
?.reportActivity("active")
|
|
5123
|
+
.catch(error => logger.warn(`sdk: active activity checkpoint failed: ${String(error)}`));
|
|
5124
|
+
// Interactive/skill turns must not wait on durable start persist. Keep
|
|
5125
|
+
// trackLifecycle so drain, persist-then-publish, content-hold release, and
|
|
5126
|
+
// shutdown still run; do not return that promise to the extension runner
|
|
5127
|
+
// (EXTENSION_HANDLER_TIMEOUT_MS would otherwise stall the prompt).
|
|
5128
|
+
void trackLifecycle(
|
|
5035
5129
|
async () =>
|
|
5036
5130
|
emitLifecycle(
|
|
5037
5131
|
"agent_start",
|
|
@@ -5047,12 +5141,19 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
5047
5141
|
event.sdkRunTokens,
|
|
5048
5142
|
),
|
|
5049
5143
|
owner,
|
|
5050
|
-
)
|
|
5144
|
+
).catch(error => {
|
|
5145
|
+
logger.error("SDK agent_start lifecycle task failed", {
|
|
5146
|
+
error: sanitizePromptFailure(error),
|
|
5147
|
+
});
|
|
5148
|
+
});
|
|
5051
5149
|
});
|
|
5052
5150
|
api.on("agent_end", (event, ctx) => {
|
|
5053
5151
|
const tokenBinding =
|
|
5054
5152
|
typeof event.sdkRunToken === "string" ? lifecycleRunOwners.get(event.sdkRunToken) : undefined;
|
|
5055
5153
|
const owner = tokenBinding?.state ?? lifecycleStateForEvent(ctx, "agent_end", event.sdkRunToken);
|
|
5154
|
+
void (owner?.runtime ?? lifecycleStateForContext(ctx, "agent_end")?.runtime)
|
|
5155
|
+
?.reportActivity("idle")
|
|
5156
|
+
.catch(error => logger.warn(`sdk: idle activity checkpoint failed: ${String(error)}`));
|
|
5056
5157
|
// Capture the oldest unmatched batch synchronously. A successor may start
|
|
5057
5158
|
// while the failed diagnostic persists; that must not retarget the
|
|
5058
5159
|
// predecessor's reason or terminal boundary to the successor invocation.
|
|
@@ -5218,10 +5319,10 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
5218
5319
|
* the session and see the turn settle but never receive a single word of the
|
|
5219
5320
|
* answer.
|
|
5220
5321
|
*
|
|
5221
|
-
*
|
|
5222
|
-
*
|
|
5223
|
-
*
|
|
5224
|
-
*
|
|
5322
|
+
* Correlated content is scoped to the owning invocations of the batch that is
|
|
5323
|
+
* actually running. Explicit observer connections additionally receive the
|
|
5324
|
+
* uncorrelated copy, including for agent-owned runs with no SDK submitter.
|
|
5325
|
+
* A session with no owner or eligible observer pays one capability-map lookup.
|
|
5225
5326
|
*/
|
|
5226
5327
|
const STREAMED_TURN_EVENT_TYPES: ReadonlySet<string> = new Set([
|
|
5227
5328
|
"message_update",
|
|
@@ -5234,6 +5335,10 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
5234
5335
|
const current = lifecycleStateForContext(ctx, "agent_start");
|
|
5235
5336
|
const activeInvocation = current?.activeInvocation;
|
|
5236
5337
|
if (!current) return;
|
|
5338
|
+
const observerConnections = current.runtime.connectionIdsWithCapabilities([
|
|
5339
|
+
TURN_STREAM_CAPABILITY,
|
|
5340
|
+
SESSION_HOST_OBSERVER_CAPABILITY,
|
|
5341
|
+
]);
|
|
5237
5342
|
const batch = activeInvocation
|
|
5238
5343
|
? current.openLifecycleBatches.find(candidate =>
|
|
5239
5344
|
candidate.invocations.some(
|
|
@@ -5248,7 +5353,7 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
5248
5353
|
: current.lifecycleActive
|
|
5249
5354
|
? (current.attachedInvocations ?? [])
|
|
5250
5355
|
: [];
|
|
5251
|
-
if (invocations.length === 0) return;
|
|
5356
|
+
if (invocations.length === 0 && observerConnections.length === 0) return;
|
|
5252
5357
|
// Content bypasses the lifecycle replay ring and must never interrupt its producer.
|
|
5253
5358
|
if (!event || typeof event.type !== "string" || !STREAMED_TURN_EVENT_TYPES.has(event.type)) return;
|
|
5254
5359
|
// emitLifecycle("agent_start") awaits durable persistence before it
|
|
@@ -5291,6 +5396,10 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
5291
5396
|
typeof (error as { code?: unknown }).code === "string"
|
|
5292
5397
|
? (error as { code: string }).code
|
|
5293
5398
|
: undefined;
|
|
5399
|
+
const brokerDiagnosticCode = (error: unknown): string => {
|
|
5400
|
+
const code = errorCode(error);
|
|
5401
|
+
return code !== undefined && /^[A-Za-z0-9_.-]{1,64}$/u.test(code) ? code : "unavailable";
|
|
5402
|
+
};
|
|
5294
5403
|
const startRuntime = async (ctx: ExtensionContext): Promise<void> => {
|
|
5295
5404
|
if (active) return;
|
|
5296
5405
|
const sessionId = ctx.sessionManager.getSessionId();
|
|
@@ -5315,13 +5424,28 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
5315
5424
|
await steerReconciliation.hydrateFromStore();
|
|
5316
5425
|
const deadlineManager = new PromptDeadlineManager({
|
|
5317
5426
|
reconciliation,
|
|
5318
|
-
getLeaseMs: () =>
|
|
5319
|
-
|
|
5320
|
-
|
|
5321
|
-
|
|
5322
|
-
|
|
5323
|
-
|
|
5324
|
-
|
|
5427
|
+
getLeaseMs: () => resolveSdkPromptDeadlineMs(options.settings?.get("sdk.promptDeadlineMs" as never)),
|
|
5428
|
+
getMaxMs: () => resolveSdkPromptMaxRuntimeMs(options.settings?.get("sdk.promptMaxRuntimeMs" as never)),
|
|
5429
|
+
// Persist the agent's uncommitted work before the retirement below tears
|
|
5430
|
+
// the session down (#5583). Best effort by contract: failures are logged
|
|
5431
|
+
// inside the flush and the deadline outcome is unaffected.
|
|
5432
|
+
onDeadlineExceeded: async (_correlation, signal, isCurrent) => {
|
|
5433
|
+
if (options.settings?.get("sdk.flushWorktreeOnDeadline" as never) === false) return;
|
|
5434
|
+
// `has` is true only for a value the user actually wrote, so this
|
|
5435
|
+
// separates an explicit opt-in from the schema default. The flush only
|
|
5436
|
+
// honours the default inside a linked worktree the session owns.
|
|
5437
|
+
const configured = options.settings?.get("sdk.flushWorktreeOnDeadline" as never);
|
|
5438
|
+
const hasExplicitSetting =
|
|
5439
|
+
typeof options.settings?.has === "function"
|
|
5440
|
+
? options.settings.has("sdk.flushWorktreeOnDeadline" as never)
|
|
5441
|
+
: configured === true;
|
|
5442
|
+
const explicitOptIn = hasExplicitSetting === true && configured === true;
|
|
5443
|
+
await flushWorktreeOnPromptDeadline(ctx.cwd, {
|
|
5444
|
+
agentDir: options.settings?.getAgentDir(),
|
|
5445
|
+
explicitOptIn,
|
|
5446
|
+
isCurrent,
|
|
5447
|
+
signal,
|
|
5448
|
+
});
|
|
5325
5449
|
},
|
|
5326
5450
|
onExpired: (correlation, deadlineOutcome) => {
|
|
5327
5451
|
const owner = lifecycleOwnerHolder.state;
|
|
@@ -6025,83 +6149,168 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
6025
6149
|
};
|
|
6026
6150
|
let publishedEndpointUrl: string | undefined;
|
|
6027
6151
|
let brokerRegistered = false;
|
|
6152
|
+
let brokerRegistrationInFlight: Promise<void> | undefined;
|
|
6153
|
+
let brokerRecoveryStopped = false;
|
|
6028
6154
|
const registerBroker = async (): Promise<void> => {
|
|
6029
6155
|
if (brokerRegistered) return;
|
|
6156
|
+
if (brokerRegistrationInFlight !== undefined) {
|
|
6157
|
+
await brokerRegistrationInFlight;
|
|
6158
|
+
return;
|
|
6159
|
+
}
|
|
6160
|
+
const registration = (async (): Promise<void> => {
|
|
6161
|
+
try {
|
|
6162
|
+
if (options.brokerRegistrationRequired && !options.lifecycleRequestId)
|
|
6163
|
+
throw new Error("Lifecycle broker registration requires a request identity.");
|
|
6164
|
+
await (options.ensureBrokerImpl ?? ensureBroker)({ agentDir: options.agentDir });
|
|
6165
|
+
if (brokerRecoveryStopped) return;
|
|
6166
|
+
const index = await new SessionIndex(options.agentDir).open();
|
|
6167
|
+
if (brokerRecoveryStopped) return;
|
|
6168
|
+
const locator = await resolveSessionLocator(ctx.cwd, stateRoot);
|
|
6169
|
+
const effectiveIncarnation = processIncarnation(process.pid);
|
|
6170
|
+
const direct = await reattestMasterSessionIdentity({
|
|
6171
|
+
index,
|
|
6172
|
+
locator,
|
|
6173
|
+
masterCapability: options.masterCapability,
|
|
6174
|
+
attestationEpoch: options.masterAttestationEpoch,
|
|
6175
|
+
ownerSessionId: options.masterOwnerSessionId,
|
|
6176
|
+
sessionId,
|
|
6177
|
+
pid: process.pid,
|
|
6178
|
+
processIncarnation: effectiveIncarnation,
|
|
6179
|
+
});
|
|
6180
|
+
if (brokerRecoveryStopped) return;
|
|
6181
|
+
let brokerRegistrationEvent: SessionIndexEvent | undefined;
|
|
6182
|
+
await runtime.registerWithBroker({
|
|
6183
|
+
register: async input => {
|
|
6184
|
+
if (publishedEndpointUrl === undefined)
|
|
6185
|
+
throw new Error("SDK transport endpoint was not published before broker registration.");
|
|
6186
|
+
const endpointPath = path.join(input.stateRoot, "sdk", `${input.sessionId}.json`);
|
|
6187
|
+
const file = await readEndpointFile(endpointPath);
|
|
6188
|
+
if (!file) throw new Error("SDK endpoint could not be read as a stable regular file.");
|
|
6189
|
+
const endpoint = JSON.parse(file.source) as Record<string, unknown>;
|
|
6190
|
+
if (
|
|
6191
|
+
endpoint.sessionId !== input.sessionId ||
|
|
6192
|
+
endpoint.pid !== process.pid ||
|
|
6193
|
+
endpoint.url !== publishedEndpointUrl ||
|
|
6194
|
+
endpoint.token !== transport.token
|
|
6195
|
+
)
|
|
6196
|
+
throw new Error("SDK endpoint did not match the published transport authority.");
|
|
6197
|
+
const endpointMtimeMs = file.mtimeMs;
|
|
6198
|
+
const endpointFileId = `${file.dev}:${file.ino}`;
|
|
6199
|
+
const masterRole = masterAttestationForEffectiveHost({
|
|
6200
|
+
masterCapability: options.masterCapability,
|
|
6201
|
+
attestationEpoch: options.masterAttestationEpoch,
|
|
6202
|
+
ownerSessionId: options.masterOwnerSessionId,
|
|
6203
|
+
sessionId: input.sessionId,
|
|
6204
|
+
pid: process.pid,
|
|
6205
|
+
processIncarnation: effectiveIncarnation,
|
|
6206
|
+
direct,
|
|
6207
|
+
});
|
|
6208
|
+
const published = await index.append({
|
|
6209
|
+
type: "host_registered",
|
|
6210
|
+
...input,
|
|
6211
|
+
locator,
|
|
6212
|
+
pid: process.pid,
|
|
6213
|
+
endpointMtimeMs,
|
|
6214
|
+
endpointFileId,
|
|
6215
|
+
...(options.lifecycleRequestId ? { lifecycleRequestId: options.lifecycleRequestId } : {}),
|
|
6216
|
+
...(masterRole ? { masterRole } : {}),
|
|
6217
|
+
});
|
|
6218
|
+
brokerRegistrationEvent = published;
|
|
6219
|
+
if (brokerRecoveryStopped) {
|
|
6220
|
+
// Teardown may have run before append returned its ownership proof.
|
|
6221
|
+
await index.unregisterIfCurrent(published);
|
|
6222
|
+
if (brokerRegistrationEvent === published) brokerRegistrationEvent = undefined;
|
|
6223
|
+
}
|
|
6224
|
+
},
|
|
6225
|
+
heartbeat: async input => {
|
|
6226
|
+
// Heartbeat only ever speaks for the publication this host proved it
|
|
6227
|
+
// owns. A stale or foreign generation must not renew liveness.
|
|
6228
|
+
const expected = brokerRegistrationEvent;
|
|
6229
|
+
if (
|
|
6230
|
+
!expected ||
|
|
6231
|
+
expected.sessionId !== input.sessionId ||
|
|
6232
|
+
expected.endpointGeneration !== input.endpointGeneration ||
|
|
6233
|
+
path.resolve(expected.locator.stateRoot) !== path.resolve(input.stateRoot)
|
|
6234
|
+
)
|
|
6235
|
+
return;
|
|
6236
|
+
await index.append({
|
|
6237
|
+
type: "host_heartbeat",
|
|
6238
|
+
sessionId: expected.sessionId,
|
|
6239
|
+
locator: expected.locator,
|
|
6240
|
+
endpointGeneration: expected.endpointGeneration,
|
|
6241
|
+
pid: expected.pid,
|
|
6242
|
+
...(expected.processIncarnation === undefined
|
|
6243
|
+
? {}
|
|
6244
|
+
: { processIncarnation: expected.processIncarnation }),
|
|
6245
|
+
...(expected.hostIncarnation === undefined
|
|
6246
|
+
? {}
|
|
6247
|
+
: { hostIncarnation: expected.hostIncarnation }),
|
|
6248
|
+
...(expected.masterRole === undefined ? {} : { masterRole: expected.masterRole }),
|
|
6249
|
+
activity: input.activity,
|
|
6250
|
+
ts: input.activity.at,
|
|
6251
|
+
});
|
|
6252
|
+
},
|
|
6253
|
+
unregister: async input => {
|
|
6254
|
+
const expected = brokerRegistrationEvent;
|
|
6255
|
+
if (
|
|
6256
|
+
!expected ||
|
|
6257
|
+
expected.sessionId !== input.sessionId ||
|
|
6258
|
+
expected.endpointGeneration !== input.endpointGeneration ||
|
|
6259
|
+
path.resolve(expected.locator.stateRoot) !== path.resolve(input.stateRoot)
|
|
6260
|
+
)
|
|
6261
|
+
return;
|
|
6262
|
+
// Use the successful publication's proof, never a teardown-time file read.
|
|
6263
|
+
await index.unregisterIfCurrent(expected, input.reason);
|
|
6264
|
+
if (brokerRegistrationEvent === expected) brokerRegistrationEvent = undefined;
|
|
6265
|
+
},
|
|
6266
|
+
});
|
|
6267
|
+
if (brokerRecoveryStopped) return;
|
|
6268
|
+
brokerRegistered = true;
|
|
6269
|
+
} catch (error) {
|
|
6270
|
+
if (options.brokerRegistrationRequired) throw error;
|
|
6271
|
+
logger.warn("sdk broker registration unavailable", { code: brokerDiagnosticCode(error) });
|
|
6272
|
+
}
|
|
6273
|
+
})();
|
|
6274
|
+
brokerRegistrationInFlight = registration;
|
|
6030
6275
|
try {
|
|
6031
|
-
|
|
6032
|
-
|
|
6033
|
-
|
|
6034
|
-
|
|
6035
|
-
|
|
6036
|
-
|
|
6037
|
-
|
|
6038
|
-
|
|
6039
|
-
|
|
6040
|
-
|
|
6041
|
-
|
|
6042
|
-
|
|
6043
|
-
|
|
6044
|
-
|
|
6045
|
-
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
await runtime.registerWithBroker({
|
|
6049
|
-
register: async input => {
|
|
6050
|
-
if (publishedEndpointUrl === undefined)
|
|
6051
|
-
throw new Error("SDK transport endpoint was not published before broker registration.");
|
|
6052
|
-
const endpointPath = path.join(input.stateRoot, "sdk", `${input.sessionId}.json`);
|
|
6053
|
-
const file = await readEndpointFile(endpointPath);
|
|
6054
|
-
if (!file) throw new Error("SDK endpoint could not be read as a stable regular file.");
|
|
6055
|
-
const endpoint = JSON.parse(file.source) as Record<string, unknown>;
|
|
6056
|
-
if (
|
|
6057
|
-
endpoint.sessionId !== input.sessionId ||
|
|
6058
|
-
endpoint.pid !== process.pid ||
|
|
6059
|
-
endpoint.url !== publishedEndpointUrl ||
|
|
6060
|
-
endpoint.token !== transport.token
|
|
6061
|
-
)
|
|
6062
|
-
throw new Error("SDK endpoint did not match the published transport authority.");
|
|
6063
|
-
const endpointMtimeMs = file.mtimeMs;
|
|
6064
|
-
const endpointFileId = `${file.dev}:${file.ino}`;
|
|
6065
|
-
const masterRole = masterAttestationForEffectiveHost({
|
|
6066
|
-
masterCapability: options.masterCapability,
|
|
6067
|
-
attestationEpoch: options.masterAttestationEpoch,
|
|
6068
|
-
ownerSessionId: options.masterOwnerSessionId,
|
|
6069
|
-
sessionId: input.sessionId,
|
|
6070
|
-
pid: process.pid,
|
|
6071
|
-
processIncarnation: effectiveIncarnation,
|
|
6072
|
-
direct,
|
|
6073
|
-
});
|
|
6074
|
-
registration = await index.append({
|
|
6075
|
-
type: "host_registered",
|
|
6076
|
-
...input,
|
|
6077
|
-
locator,
|
|
6078
|
-
pid: process.pid,
|
|
6079
|
-
endpointMtimeMs,
|
|
6080
|
-
endpointFileId,
|
|
6081
|
-
...(options.lifecycleRequestId ? { lifecycleRequestId: options.lifecycleRequestId } : {}),
|
|
6082
|
-
...(masterRole ? { masterRole } : {}),
|
|
6083
|
-
});
|
|
6084
|
-
},
|
|
6085
|
-
unregister: async input => {
|
|
6086
|
-
const expected = registration;
|
|
6087
|
-
if (
|
|
6088
|
-
!expected ||
|
|
6089
|
-
expected.sessionId !== input.sessionId ||
|
|
6090
|
-
expected.endpointGeneration !== input.endpointGeneration ||
|
|
6091
|
-
path.resolve(expected.locator.stateRoot) !== path.resolve(input.stateRoot)
|
|
6092
|
-
)
|
|
6093
|
-
return;
|
|
6094
|
-
// Use the successful publication's proof, never a teardown-time file read.
|
|
6095
|
-
await index.unregisterIfCurrent(expected);
|
|
6096
|
-
if (registration === expected) registration = undefined;
|
|
6097
|
-
},
|
|
6098
|
-
});
|
|
6099
|
-
brokerRegistered = true;
|
|
6276
|
+
await registration;
|
|
6277
|
+
} finally {
|
|
6278
|
+
if (brokerRegistrationInFlight === registration) brokerRegistrationInFlight = undefined;
|
|
6279
|
+
}
|
|
6280
|
+
};
|
|
6281
|
+
let brokerRecoveryTimer: NodeJS.Timeout | undefined;
|
|
6282
|
+
let brokerRecoveryInFlight: Promise<void> | undefined;
|
|
6283
|
+
const runBrokerRecovery = async (): Promise<void> => {
|
|
6284
|
+
if (brokerRecoveryStopped || brokerRecoveryInFlight !== undefined) return;
|
|
6285
|
+
const recovery = (async (): Promise<void> => {
|
|
6286
|
+
if (brokerRecoveryStopped) return;
|
|
6287
|
+
if (brokerRegistered) await (options.ensureBrokerImpl ?? ensureBroker)({ agentDir: options.agentDir });
|
|
6288
|
+
else await registerBroker();
|
|
6289
|
+
})();
|
|
6290
|
+
brokerRecoveryInFlight = recovery;
|
|
6291
|
+
try {
|
|
6292
|
+
await recovery;
|
|
6100
6293
|
} catch (error) {
|
|
6101
|
-
|
|
6102
|
-
|
|
6294
|
+
logger.warn("sdk broker recovery unavailable", { code: brokerDiagnosticCode(error) });
|
|
6295
|
+
} finally {
|
|
6296
|
+
if (brokerRecoveryInFlight === recovery) brokerRecoveryInFlight = undefined;
|
|
6103
6297
|
}
|
|
6104
6298
|
};
|
|
6299
|
+
const startBrokerRecovery = (): void => {
|
|
6300
|
+
if (brokerRecoveryStopped || brokerRecoveryTimer !== undefined) return;
|
|
6301
|
+
const timer = (options.setIntervalImpl ?? setInterval)(
|
|
6302
|
+
() => void runBrokerRecovery(),
|
|
6303
|
+
SESSION_BROKER_RECOVERY_INTERVAL_MS,
|
|
6304
|
+
) as NodeJS.Timeout;
|
|
6305
|
+
brokerRecoveryTimer = timer;
|
|
6306
|
+
timer.unref?.();
|
|
6307
|
+
};
|
|
6308
|
+
const stopBrokerRecovery = (): void => {
|
|
6309
|
+
brokerRecoveryStopped = true;
|
|
6310
|
+
if (brokerRecoveryTimer === undefined) return;
|
|
6311
|
+
(options.clearIntervalImpl ?? clearInterval)(brokerRecoveryTimer);
|
|
6312
|
+
brokerRecoveryTimer = undefined;
|
|
6313
|
+
};
|
|
6105
6314
|
const runtimeOwner: RuntimeState = {
|
|
6106
6315
|
sessionId,
|
|
6107
6316
|
sessionIdentity,
|
|
@@ -6114,6 +6323,7 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
6114
6323
|
pending,
|
|
6115
6324
|
openLifecycleBatches,
|
|
6116
6325
|
registerBroker,
|
|
6326
|
+
stopBrokerRecovery,
|
|
6117
6327
|
quiesceInput: () => {
|
|
6118
6328
|
inputGate.quiescing = true;
|
|
6119
6329
|
lifecycleOwnerHolder.quiescing = true;
|
|
@@ -6129,13 +6339,19 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
6129
6339
|
failureDiagnosticCodes: new Map(),
|
|
6130
6340
|
lifecycleTasks: new Set(),
|
|
6131
6341
|
};
|
|
6342
|
+
// Capture the SDK turn that owns a headless workflow gate before it is
|
|
6343
|
+
// persisted. Q12 can then explain both sides of a stalled turn: the gate
|
|
6344
|
+
// identity and whether an answer was recorded for that originating turn.
|
|
6345
|
+
ctx.workflowGate?.setRuntimeTurnProvider?.(() => active?.activeInvocation?.correlation.turnId);
|
|
6132
6346
|
lifecycleOwnerHolder.state = runtimeOwner;
|
|
6133
6347
|
active = runtimeOwner;
|
|
6134
6348
|
try {
|
|
6135
6349
|
publishedEndpointUrl = (await runtime.start()).url;
|
|
6136
6350
|
await registerBroker();
|
|
6351
|
+
if (!brokerRecoveryStopped) startBrokerRecovery();
|
|
6137
6352
|
} catch (error) {
|
|
6138
6353
|
active = undefined;
|
|
6354
|
+
stopBrokerRecovery();
|
|
6139
6355
|
disposeGate?.();
|
|
6140
6356
|
try {
|
|
6141
6357
|
await runtime.stop();
|
|
@@ -6156,6 +6372,7 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
6156
6372
|
pending,
|
|
6157
6373
|
openLifecycleBatches,
|
|
6158
6374
|
registerBroker,
|
|
6375
|
+
stopBrokerRecovery,
|
|
6159
6376
|
quiesceInput: () => {
|
|
6160
6377
|
inputGate.quiescing = true;
|
|
6161
6378
|
lifecycleOwnerHolder.quiescing = true;
|
|
@@ -6180,7 +6397,7 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
6180
6397
|
throw error;
|
|
6181
6398
|
}
|
|
6182
6399
|
};
|
|
6183
|
-
const stopActive = async (cancelSkillRecovery = false): Promise<void> => {
|
|
6400
|
+
const stopActive = async (cancelSkillRecovery = false, unregisterReason?: "detached_idle"): Promise<void> => {
|
|
6184
6401
|
const current = active;
|
|
6185
6402
|
if (!current) return;
|
|
6186
6403
|
if (cancelSkillRecovery) {
|
|
@@ -6189,6 +6406,7 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
6189
6406
|
}
|
|
6190
6407
|
activePromptOwnerHolder.connectionIds = undefined;
|
|
6191
6408
|
activePromptOwnerHolder.lifecycleEpoch = undefined;
|
|
6409
|
+
current.stopBrokerRecovery();
|
|
6192
6410
|
current.quiesceInput();
|
|
6193
6411
|
current.fenceGateResolutions();
|
|
6194
6412
|
try {
|
|
@@ -6237,7 +6455,10 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
6237
6455
|
retiredLifecycleOwnerTimers.set(current, timer);
|
|
6238
6456
|
} else current.deadlineManager.clearAll();
|
|
6239
6457
|
current.disposeGate?.();
|
|
6240
|
-
await current.runtime.stop({
|
|
6458
|
+
await current.runtime.stop({
|
|
6459
|
+
allowLockContention: cancelSkillRecovery,
|
|
6460
|
+
...(unregisterReason === undefined ? {} : { unregisterReason }),
|
|
6461
|
+
});
|
|
6241
6462
|
} catch (error) {
|
|
6242
6463
|
// Keep the immutable owner available for a retry when transport teardown
|
|
6243
6464
|
// fails after quiescing. Clearing `active` before stop prevents a second
|
|
@@ -6260,7 +6481,7 @@ export function createSdkSessionRuntimeExtension(api: ExtensionAPI, options: Cre
|
|
|
6260
6481
|
await stopActive();
|
|
6261
6482
|
await startRuntime(ctx);
|
|
6262
6483
|
});
|
|
6263
|
-
api.on("session_shutdown", async
|
|
6264
|
-
await stopActive(true);
|
|
6484
|
+
api.on("session_shutdown", async event => {
|
|
6485
|
+
await stopActive(true, event.reason);
|
|
6265
6486
|
});
|
|
6266
6487
|
}
|