@gajae-code/coding-agent 0.16.3 → 0.16.6
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 +113 -0
- package/dist/types/capability/types.d.ts +4 -0
- package/dist/types/cli/args.d.ts +2 -2
- package/dist/types/cli/customize-doctor.d.ts +22 -0
- package/dist/types/cli/root-flags.d.ts +4 -2
- package/dist/types/cli.d.ts +1 -1
- package/dist/types/commands/launch.d.ts +1 -1
- package/dist/types/config/autorouting-tier-map.d.ts +3 -0
- package/dist/types/config/file-lock.d.ts +31 -3
- package/dist/types/config/model-registry.d.ts +4 -0
- package/dist/types/config/model-resolver.d.ts +9 -0
- package/dist/types/config/settings-schema.d.ts +29 -1
- package/dist/types/coordinator-mcp/question-state.d.ts +7 -0
- package/dist/types/coordinator-mcp/server.d.ts +7 -0
- package/dist/types/discovery/claude-plugins.d.ts +3 -1
- package/dist/types/discovery/helpers.d.ts +35 -0
- package/dist/types/exec/bash-executor.d.ts +17 -1
- package/dist/types/exec/bash-shell-guardian.d.ts +15 -0
- package/dist/types/exec/bash-shell-runtime-entry.d.ts +2 -0
- package/dist/types/exec/bash-shell-signals.d.ts +2 -0
- package/dist/types/exec/bash-shell-supervisor-entry.d.ts +1 -0
- package/dist/types/exec/bash-shell-supervisor.d.ts +10 -0
- package/dist/types/exec/bash-shell-worker-entry.d.ts +2 -0
- package/dist/types/exec/bash-shell-worker-protocol.d.ts +63 -0
- package/dist/types/exec/bash-shell-worker.d.ts +1 -0
- package/dist/types/exec/isolated-shell.d.ts +19 -0
- package/dist/types/extensibility/extensions/function-hooks-internal.d.ts +9 -0
- package/dist/types/extensibility/extensions/function-hooks.d.ts +169 -0
- package/dist/types/extensibility/extensions/index.d.ts +1 -0
- package/dist/types/extensibility/extensions/runner.d.ts +46 -6
- package/dist/types/extensibility/extensions/types.d.ts +16 -0
- package/dist/types/extensibility/extensions/wrapper.d.ts +3 -1
- package/dist/types/extensibility/gjc-plugins/constrained-hooks.d.ts +35 -2
- package/dist/types/extensibility/gjc-plugins/mcp-policy.d.ts +16 -0
- package/dist/types/extensibility/gjc-plugins/paths.d.ts +2 -0
- package/dist/types/extensibility/gjc-plugins/types.d.ts +25 -0
- package/dist/types/extensibility/hooks/types.d.ts +4 -0
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +5 -2
- package/dist/types/extensibility/shared-events.d.ts +1 -1
- package/dist/types/extensibility/skill-management.d.ts +9 -4
- package/dist/types/extensibility/skills.d.ts +2 -0
- package/dist/types/gjc-runtime/empty-delete-gc.d.ts +4 -1
- package/dist/types/gjc-runtime/linux-proc.d.ts +2 -0
- package/dist/types/gjc-runtime/session-state-lock.d.ts +14 -0
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +41 -3
- package/dist/types/gjc-runtime/ultragoal-succession.d.ts +251 -0
- package/dist/types/modes/components/assistant-message.d.ts +1 -2
- package/dist/types/modes/components/bash-execution.d.ts +1 -0
- package/dist/types/modes/components/execution-shared.d.ts +1 -0
- package/dist/types/modes/components/settings-selector.d.ts +6 -1
- package/dist/types/modes/components/status-line/command.d.ts +35 -0
- package/dist/types/modes/components/status-line/index.d.ts +1 -0
- package/dist/types/modes/components/status-line/types.d.ts +5 -0
- package/dist/types/modes/components/tool-status-header.d.ts +14 -0
- package/dist/types/modes/controllers/event-controller.d.ts +6 -0
- package/dist/types/modes/interactive-mode.d.ts +3 -0
- package/dist/types/modes/types.d.ts +7 -0
- package/dist/types/runtime-mcp/client.d.ts +9 -1
- package/dist/types/runtime-mcp/manager.d.ts +7 -1
- package/dist/types/runtime-mcp/pool.d.ts +22 -3
- package/dist/types/runtime-mcp/transports/stdio.d.ts +0 -4
- package/dist/types/runtime-mcp/types.d.ts +22 -0
- package/dist/types/sdk/broker/ensure.d.ts +32 -0
- package/dist/types/sdk/broker/lifecycle-ledger.d.ts +0 -1
- package/dist/types/sdk/broker/lifecycle.d.ts +6 -0
- package/dist/types/sdk/broker/startup-failure.d.ts +4 -1
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +2 -0
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +12 -0
- package/dist/types/sdk/bus/chat-effect-journal.d.ts +17 -2
- package/dist/types/sdk/bus/conversation-store.d.ts +11 -0
- package/dist/types/sdk/bus/lifecycle-commands.d.ts +8 -8
- package/dist/types/sdk/bus/slack-daemon.d.ts +1 -1
- package/dist/types/sdk/bus/slack-live-provider.d.ts +6 -0
- package/dist/types/sdk/bus/slack-provider.d.ts +12 -0
- package/dist/types/sdk/bus/topic-registry.d.ts +8 -0
- package/dist/types/sdk/client/client.d.ts +6 -0
- package/dist/types/sdk/host/host.d.ts +3 -1
- package/dist/types/sdk/host/session-runtime.d.ts +26 -1
- package/dist/types/sdk/lifecycle/service.d.ts +1 -0
- package/dist/types/sdk/router/session-router.d.ts +10 -2
- package/dist/types/sdk/session-api-key.d.ts +26 -0
- package/dist/types/sdk/session.d.ts +5 -1
- package/dist/types/sdk/transport/serve-cli.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +11 -0
- package/dist/types/session/fallback-chain-controller.d.ts +15 -0
- package/dist/types/session/internal/managed-session-storage.d.ts +7 -0
- package/dist/types/session/messages.d.ts +1 -0
- package/dist/types/session/session-manager.d.ts +3 -1
- package/dist/types/setup/paseo/announce.d.ts +112 -0
- package/dist/types/setup/paseo/setup-deps.d.ts +2 -1
- package/dist/types/skill-state/canonical-skills.d.ts +4 -0
- package/dist/types/system-prompt.d.ts +10 -0
- package/dist/types/task/executor.d.ts +5 -1
- package/dist/types/tools/bash.d.ts +1 -0
- package/dist/types/tools/fetch.d.ts +7 -0
- package/dist/types/tools/github-cache.d.ts +2 -1
- package/dist/types/tools/index.d.ts +10 -0
- package/dist/types/tools/path-utils.d.ts +2 -0
- package/dist/types/tools/search.d.ts +6 -0
- package/package.json +9 -7
- package/scripts/capture-status-line-custom-editor-showcase.ts +151 -0
- package/scripts/generate-sdk-operation-inventory.ts +11 -0
- package/scripts/verify-status-line-custom-editor-showcase.ts +309 -0
- package/src/capability/index.ts +14 -2
- package/src/capability/types.ts +4 -0
- package/src/cli/args.ts +20 -9
- package/src/cli/customize-doctor.ts +155 -12
- package/src/cli/root-flags.ts +5 -3
- package/src/cli.ts +22 -0
- package/src/commands/sdk.ts +74 -31
- package/src/config/autorouting-tier-map.ts +1 -0
- package/src/config/file-lock-gc.ts +40 -2
- package/src/config/file-lock.ts +379 -31
- package/src/config/model-preset-registry.ts +120 -19
- package/src/config/model-profiles.ts +40 -0
- package/src/config/model-registry.ts +73 -23
- package/src/config/model-resolver.ts +48 -0
- package/src/config/settings-schema.ts +33 -1
- package/src/config/settings.ts +1 -0
- package/src/coordinator-mcp/question-state.ts +33 -2
- package/src/coordinator-mcp/server.ts +477 -101
- package/src/crash/sanitize.ts +1 -1
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/models/catalog.ts +11 -11
- package/src/defaults/gjc/extensions/grok-cli-vendor/src/provider/register.ts +13 -2
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +22 -0
- package/src/discovery/builtin.ts +52 -55
- package/src/discovery/claude-plugins.ts +12 -4
- package/src/discovery/helpers.ts +307 -34
- package/src/exec/bash-executor.ts +330 -50
- package/src/exec/bash-shell-guardian.ts +388 -0
- package/src/exec/bash-shell-runtime-entry.ts +5 -0
- package/src/exec/bash-shell-signals.ts +29 -0
- package/src/exec/bash-shell-supervisor-entry.ts +3 -0
- package/src/exec/bash-shell-supervisor.ts +359 -0
- package/src/exec/bash-shell-worker-entry.ts +5 -0
- package/src/exec/bash-shell-worker-protocol.ts +36 -0
- package/src/exec/bash-shell-worker.ts +116 -0
- package/src/exec/isolated-shell.ts +393 -0
- package/src/extensibility/extensions/function-hooks-internal.ts +73 -0
- package/src/extensibility/extensions/function-hooks.ts +959 -0
- package/src/extensibility/extensions/index.ts +22 -0
- package/src/extensibility/extensions/loader.ts +53 -2
- package/src/extensibility/extensions/runner.ts +895 -264
- package/src/extensibility/extensions/types.ts +42 -0
- package/src/extensibility/extensions/wrapper.ts +56 -15
- package/src/extensibility/gjc-plugins/compiler.ts +228 -60
- package/src/extensibility/gjc-plugins/constrained-hooks.ts +321 -23
- package/src/extensibility/gjc-plugins/installer.ts +13 -12
- package/src/extensibility/gjc-plugins/mcp-policy.ts +81 -52
- package/src/extensibility/gjc-plugins/paths.ts +13 -0
- package/src/extensibility/gjc-plugins/registry.ts +113 -1
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +758 -16
- package/src/extensibility/gjc-plugins/runtime-quarantine.ts +20 -2
- package/src/extensibility/gjc-plugins/schema.ts +121 -4
- package/src/extensibility/gjc-plugins/types.ts +25 -0
- package/src/extensibility/hooks/loader.ts +133 -16
- package/src/extensibility/hooks/types.ts +28 -0
- package/src/extensibility/runtime-skill-discovery.ts +149 -190
- package/src/extensibility/shared-events.ts +1 -1
- package/src/extensibility/skill-management.ts +200 -52
- package/src/extensibility/skills.ts +73 -25
- package/src/gjc-runtime/empty-delete-gc.ts +94 -4
- package/src/gjc-runtime/gc-runtime.ts +29 -0
- package/src/gjc-runtime/linux-proc.ts +14 -0
- package/src/gjc-runtime/repository-binding.ts +1 -1
- package/src/gjc-runtime/session-state-lock.ts +143 -10
- package/src/gjc-runtime/session-state-sidecar.ts +27 -11
- package/src/gjc-runtime/state-writer.ts +30 -29
- package/src/gjc-runtime/ultragoal-runtime.ts +189 -47
- package/src/gjc-runtime/ultragoal-succession.ts +1667 -0
- package/src/gjc-runtime/workflow-manifest.generated.json +52 -1
- package/src/gjc-runtime/workflow-manifest.ts +16 -0
- package/src/harness-control-plane/session-lease.ts +2 -2
- package/src/internal-urls/docs-index.generated.ts +12 -12
- package/src/lsp/config.ts +10 -3
- package/src/lsp/index.ts +1 -1
- package/src/lsp/path-trust.ts +69 -14
- package/src/main.ts +78 -35
- package/src/modes/DESIGN.md +54 -0
- package/src/modes/acp/acp-agent.ts +16 -3
- package/src/modes/components/assistant-message.ts +22 -9
- package/src/modes/components/bash-execution.ts +4 -1
- package/src/modes/components/execution-shared.ts +4 -1
- package/src/modes/components/model-selector.ts +166 -33
- package/src/modes/components/session-observer-overlay.ts +1 -1
- package/src/modes/components/settings-selector.ts +1075 -235
- package/src/modes/components/status-line/command.ts +190 -0
- package/src/modes/components/status-line/index.ts +1 -0
- package/src/modes/components/status-line/segments.ts +32 -5
- package/src/modes/components/status-line/types.ts +5 -0
- package/src/modes/components/tool-status-header.ts +396 -22
- package/src/modes/controllers/command-controller.ts +3 -0
- package/src/modes/controllers/event-controller.ts +151 -7
- package/src/modes/controllers/extension-ui-controller.ts +1 -0
- package/src/modes/controllers/input-controller.ts +6 -3
- package/src/modes/controllers/selector-controller.ts +21 -0
- package/src/modes/interactive-mode.ts +53 -6
- package/src/modes/print-mode.ts +5 -1
- package/src/modes/prompt-action-autocomplete.ts +54 -27
- package/src/modes/runtime-init.ts +2 -0
- package/src/modes/types.ts +17 -3
- package/src/modes/utils/ui-helpers.ts +2 -0
- package/src/prompts/system/system-prompt.md +8 -0
- package/src/prompts/tools/search.md +2 -0
- package/src/prompts/tools/subagent.md +1 -0
- package/src/runtime-mcp/client.ts +60 -17
- package/src/runtime-mcp/manager.ts +189 -14
- package/src/runtime-mcp/pool.test.ts +218 -0
- package/src/runtime-mcp/pool.ts +224 -23
- package/src/runtime-mcp/transports/stdio.ts +158 -24
- package/src/runtime-mcp/types.ts +24 -0
- package/src/sdk/broker/broker.ts +124 -32
- package/src/sdk/broker/ensure.ts +248 -41
- package/src/sdk/broker/lifecycle-ledger.ts +7 -17
- package/src/sdk/broker/lifecycle.ts +56 -6
- package/src/sdk/broker/startup-failure.ts +15 -6
- package/src/sdk/bus/chat-daemon-control.ts +3 -1
- package/src/sdk/bus/chat-daemon-runtime.ts +72 -6
- package/src/sdk/bus/chat-effect-journal.ts +132 -7
- package/src/sdk/bus/conversation-store.ts +29 -0
- package/src/sdk/bus/lifecycle-commands.ts +17 -11
- package/src/sdk/bus/slack-conversation.ts +1 -0
- package/src/sdk/bus/slack-daemon.ts +478 -49
- package/src/sdk/bus/slack-live-provider.ts +12 -0
- package/src/sdk/bus/slack-provider.ts +5 -0
- package/src/sdk/bus/telegram-daemon.ts +16 -2
- package/src/sdk/bus/topic-registry.ts +19 -0
- package/src/sdk/cli/master-cli.ts +1 -1
- package/src/sdk/cli/session-cli.ts +11 -8
- package/src/sdk/client/client.ts +66 -17
- package/src/sdk/host/host.ts +29 -9
- package/src/sdk/host/query/revision-store.ts +19 -13
- package/src/sdk/host/reverse-leases.ts +7 -4
- package/src/sdk/host/session-runtime.test.ts +52 -10
- package/src/sdk/host/session-runtime.ts +383 -44
- package/src/sdk/lifecycle/service.ts +4 -0
- package/src/sdk/protocol/operation-inventory.generated.json +77 -0
- package/src/sdk/router/session-router.ts +89 -38
- package/src/sdk/session-api-key.ts +94 -0
- package/src/sdk/session.ts +228 -55
- package/src/sdk/transport/relay.ts +35 -13
- package/src/sdk/transport/serve-cli.ts +3 -3
- package/src/session/agent-session.ts +240 -90
- package/src/session/contribution-prep.ts +214 -21
- package/src/session/fallback-chain-controller.ts +38 -0
- package/src/session/internal/managed-session-storage.ts +19 -5
- package/src/session/messages.ts +5 -0
- package/src/session/session-manager.ts +29 -5
- package/src/session-import/redact.ts +5 -1
- package/src/setup/paseo/announce.ts +456 -0
- package/src/setup/paseo/setup-deps.ts +15 -3
- package/src/skill-state/canonical-skills.ts +12 -0
- package/src/skills/skills.test.ts +41 -21
- package/src/slash-commands/builtin-registry.ts +1 -0
- package/src/system-prompt.ts +29 -3
- package/src/task/executor.ts +7 -1
- package/src/task/index.ts +21 -4
- package/src/tools/bash.ts +63 -19
- package/src/tools/cron.ts +1 -1
- package/src/tools/fetch.ts +29 -1
- package/src/tools/gh.ts +26 -3
- package/src/tools/github-cache.ts +68 -16
- package/src/tools/index.ts +10 -0
- package/src/tools/job.ts +21 -4
- package/src/tools/monitor.ts +8 -2
- package/src/tools/path-utils.ts +7 -0
- package/src/tools/read.ts +14 -2
- package/src/tools/render-utils.ts +1 -3
- package/src/tools/resource-gc.ts +28 -8
- package/src/tools/search.ts +116 -58
- package/src/tools/skill-discovery.ts +5 -0
- package/src/tools/skill.ts +37 -2
- package/src/tools/subagent.ts +6 -3
- package/src/tools/tool-catalog.generated.ts +10 -3
- package/src/tools/ultragoal-ask-guard.ts +2 -2
- package/src/web/insane/bridge.ts +113 -23
- package/src/web/search/providers/perplexity.ts +102 -41
|
@@ -2841,6 +2841,50 @@
|
|
|
2841
2841
|
"testIds": "not_applicable"
|
|
2842
2842
|
}
|
|
2843
2843
|
},
|
|
2844
|
+
{
|
|
2845
|
+
"sourceId": "agent_session:awaitDisposeCompletion",
|
|
2846
|
+
"sourceFile": "packages/coding-agent/src/session/agent-session.ts",
|
|
2847
|
+
"sourceKind": "agent_session",
|
|
2848
|
+
"decision": "exclude",
|
|
2849
|
+
"rationale": "test-only disposal completion seam, not a user-facing SDK control seam",
|
|
2850
|
+
"exclusionMetadata": {
|
|
2851
|
+
"adapterMappings": "not_applicable",
|
|
2852
|
+
"testIds": "not_applicable"
|
|
2853
|
+
}
|
|
2854
|
+
},
|
|
2855
|
+
{
|
|
2856
|
+
"sourceId": "agent_session:setDisposeTimeoutForTests",
|
|
2857
|
+
"sourceFile": "packages/coding-agent/src/session/agent-session.ts",
|
|
2858
|
+
"sourceKind": "agent_session",
|
|
2859
|
+
"decision": "exclude",
|
|
2860
|
+
"rationale": "test-only disposal timeout seam, not a user-facing SDK control seam",
|
|
2861
|
+
"exclusionMetadata": {
|
|
2862
|
+
"adapterMappings": "not_applicable",
|
|
2863
|
+
"testIds": "not_applicable"
|
|
2864
|
+
}
|
|
2865
|
+
},
|
|
2866
|
+
{
|
|
2867
|
+
"sourceId": "agent_session:trackPostPromptTaskForTests",
|
|
2868
|
+
"sourceFile": "packages/coding-agent/src/session/agent-session.ts",
|
|
2869
|
+
"sourceKind": "agent_session",
|
|
2870
|
+
"decision": "exclude",
|
|
2871
|
+
"rationale": "test-only post-prompt task seam, not a user-facing SDK control seam",
|
|
2872
|
+
"exclusionMetadata": {
|
|
2873
|
+
"adapterMappings": "not_applicable",
|
|
2874
|
+
"testIds": "not_applicable"
|
|
2875
|
+
}
|
|
2876
|
+
},
|
|
2877
|
+
{
|
|
2878
|
+
"sourceId": "agent_session:requestWorkerIntegrationForTests",
|
|
2879
|
+
"sourceFile": "packages/coding-agent/src/session/agent-session.ts",
|
|
2880
|
+
"sourceKind": "agent_session",
|
|
2881
|
+
"decision": "exclude",
|
|
2882
|
+
"rationale": "test-only worker integration seam, not a user-facing SDK control seam",
|
|
2883
|
+
"exclusionMetadata": {
|
|
2884
|
+
"adapterMappings": "not_applicable",
|
|
2885
|
+
"testIds": "not_applicable"
|
|
2886
|
+
}
|
|
2887
|
+
},
|
|
2844
2888
|
{
|
|
2845
2889
|
"sourceId": "agent_session:closeWriterStrict",
|
|
2846
2890
|
"sourceFile": "packages/coding-agent/src/session/agent-session.ts",
|
|
@@ -2885,6 +2929,28 @@
|
|
|
2885
2929
|
"testIds": "not_applicable"
|
|
2886
2930
|
}
|
|
2887
2931
|
},
|
|
2932
|
+
{
|
|
2933
|
+
"sourceId": "agent_session:runWithPromptAdmissionForTests",
|
|
2934
|
+
"sourceFile": "packages/coding-agent/src/session/agent-session.ts",
|
|
2935
|
+
"sourceKind": "agent_session",
|
|
2936
|
+
"decision": "exclude",
|
|
2937
|
+
"rationale": "test-only prompt admission seam, not a user-facing SDK control seam",
|
|
2938
|
+
"exclusionMetadata": {
|
|
2939
|
+
"adapterMappings": "not_applicable",
|
|
2940
|
+
"testIds": "not_applicable"
|
|
2941
|
+
}
|
|
2942
|
+
},
|
|
2943
|
+
{
|
|
2944
|
+
"sourceId": "agent_session:awaitCoordinatorRuntimeStatePersistenceForTests",
|
|
2945
|
+
"sourceFile": "packages/coding-agent/src/session/agent-session.ts",
|
|
2946
|
+
"sourceKind": "agent_session",
|
|
2947
|
+
"decision": "exclude",
|
|
2948
|
+
"rationale": "test-only coordinator persistence drain barrier, not a user-facing SDK control seam",
|
|
2949
|
+
"exclusionMetadata": {
|
|
2950
|
+
"adapterMappings": "not_applicable",
|
|
2951
|
+
"testIds": "not_applicable"
|
|
2952
|
+
}
|
|
2953
|
+
},
|
|
2888
2954
|
{
|
|
2889
2955
|
"sourceId": "agent_session:queueCoordinatorRuntimeStatePersistForTests",
|
|
2890
2956
|
"sourceFile": "packages/coding-agent/src/session/agent-session.ts",
|
|
@@ -3912,6 +3978,17 @@
|
|
|
3912
3978
|
"testIds": "not_applicable"
|
|
3913
3979
|
}
|
|
3914
3980
|
},
|
|
3981
|
+
{
|
|
3982
|
+
"sourceId": "agent_session:reloadSkills",
|
|
3983
|
+
"sourceFile": "packages/coding-agent/src/session/agent-session.ts",
|
|
3984
|
+
"sourceKind": "agent_session",
|
|
3985
|
+
"decision": "exclude",
|
|
3986
|
+
"rationale": "internal marketplace lifecycle refresh for the session skill catalog; not an independent SDK ingress operation",
|
|
3987
|
+
"exclusionMetadata": {
|
|
3988
|
+
"adapterMappings": "not_applicable",
|
|
3989
|
+
"testIds": "not_applicable"
|
|
3990
|
+
}
|
|
3991
|
+
},
|
|
3915
3992
|
{
|
|
3916
3993
|
"sourceId": "agent_session:retireWorkspaceTreeForRescope",
|
|
3917
3994
|
"sourceFile": "packages/coding-agent/src/session/agent-session.ts",
|
|
@@ -2,6 +2,7 @@ import * as crypto from "node:crypto";
|
|
|
2
2
|
import * as fs from "node:fs/promises";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import { logger, resolveEquivalentPath } from "@gajae-code/utils";
|
|
5
|
+
import { matchesIndexedEndpointFile } from "../broker/endpoint-authority";
|
|
5
6
|
import {
|
|
6
7
|
canonicalSessionCwd,
|
|
7
8
|
SessionIndex as DefaultSessionIndex,
|
|
@@ -11,7 +12,13 @@ import {
|
|
|
11
12
|
type SessionIndex,
|
|
12
13
|
} from "../broker/session-index";
|
|
13
14
|
import { cancellableSleep, lifecycleRequestTimeoutMs } from "../broker/startup-budget";
|
|
14
|
-
import {
|
|
15
|
+
import {
|
|
16
|
+
SdkClient,
|
|
17
|
+
SdkClientError,
|
|
18
|
+
type SdkDispatchContext,
|
|
19
|
+
type SdkDispatchHandler,
|
|
20
|
+
SdkPreparedDispatchError,
|
|
21
|
+
} from "../client/client";
|
|
15
22
|
import {
|
|
16
23
|
endpointDirectory,
|
|
17
24
|
readSdkBrokerDiscovery,
|
|
@@ -27,6 +34,7 @@ import {
|
|
|
27
34
|
import { ACP_SESSION_RECONNECT, SESSION_REQUEST_TIMEOUT_MS } from "../session-reconnect";
|
|
28
35
|
|
|
29
36
|
export interface SessionEndpointIdentity {
|
|
37
|
+
readonly dev: bigint;
|
|
30
38
|
readonly mtimeMs: number;
|
|
31
39
|
readonly mtimeNs: bigint;
|
|
32
40
|
readonly ctimeNs: bigint;
|
|
@@ -56,6 +64,7 @@ export function sessionAttachmentAuthorityId(input: {
|
|
|
56
64
|
.digest("hex");
|
|
57
65
|
const endpointIdentity = input.endpointIdentity
|
|
58
66
|
? {
|
|
67
|
+
dev: input.endpointIdentity.dev.toString(),
|
|
59
68
|
mtimeMs: input.endpointIdentity.mtimeMs,
|
|
60
69
|
mtimeNs: input.endpointIdentity.mtimeNs.toString(),
|
|
61
70
|
ctimeNs: input.endpointIdentity.ctimeNs.toString(),
|
|
@@ -86,7 +95,13 @@ export interface SessionAttachment {
|
|
|
86
95
|
readonly connectionId?: string;
|
|
87
96
|
readonly generation: number;
|
|
88
97
|
isCurrent(): boolean;
|
|
89
|
-
send(
|
|
98
|
+
send(
|
|
99
|
+
frame: Record<string, unknown>,
|
|
100
|
+
options?: {
|
|
101
|
+
beforeDispatch?: () => void;
|
|
102
|
+
dispatchFence?: (dispatch: () => Promise<void>) => Promise<void>;
|
|
103
|
+
},
|
|
104
|
+
): unknown;
|
|
90
105
|
/**
|
|
91
106
|
* Idempotent provider-lease heartbeat send that skips the pre-send authority
|
|
92
107
|
* reconcile (#4689).
|
|
@@ -179,6 +194,7 @@ export interface SessionRouterClient {
|
|
|
179
194
|
frame: Record<string, unknown>,
|
|
180
195
|
options?: {
|
|
181
196
|
timeoutMs?: number;
|
|
197
|
+
connectedOnly?: boolean;
|
|
182
198
|
/** Synchronous pre-send observer; a throw aborts the dispatch before the wire. */
|
|
183
199
|
beforeDispatch?: (context: SdkDispatchContext) => void;
|
|
184
200
|
/** Synchronous post-send boundary observer for transport-close-aware consumers. */
|
|
@@ -456,6 +472,7 @@ async function lstatEndpoint(file: string): Promise<SessionEndpointIdentity | un
|
|
|
456
472
|
)
|
|
457
473
|
return undefined;
|
|
458
474
|
return {
|
|
475
|
+
dev: identity.dev,
|
|
459
476
|
mtimeMs: stat.mtimeMs,
|
|
460
477
|
mtimeNs: identity.mtimeNs,
|
|
461
478
|
ctimeNs: identity.ctimeNs,
|
|
@@ -470,6 +487,7 @@ function warningAffectsSession(warning: string, sessionId: string): boolean {
|
|
|
470
487
|
|
|
471
488
|
function sameEndpointIdentity(expected: SessionEndpointIdentity, current: SessionEndpointIdentity): boolean {
|
|
472
489
|
return (
|
|
490
|
+
expected.dev === current.dev &&
|
|
473
491
|
expected.mtimeMs === current.mtimeMs &&
|
|
474
492
|
expected.mtimeNs === current.mtimeNs &&
|
|
475
493
|
expected.ctimeNs === current.ctimeNs &&
|
|
@@ -909,6 +927,7 @@ export class SessionRouter {
|
|
|
909
927
|
timeoutMs?: number;
|
|
910
928
|
beforeDispatch?: (context: SdkDispatchContext) => void;
|
|
911
929
|
onDispatch?: SdkDispatchHandler;
|
|
930
|
+
dispatchFence?: (dispatch: () => Promise<Record<string, unknown>>) => Promise<Record<string, unknown>>;
|
|
912
931
|
},
|
|
913
932
|
): Promise<Record<string, unknown>> {
|
|
914
933
|
const matchesExpectedAuthority = (attachment: SessionAttachment): boolean =>
|
|
@@ -946,31 +965,34 @@ export class SessionRouter {
|
|
|
946
965
|
// token: the wire frame alone carries credentials, and the observer
|
|
947
966
|
// context is a deep-frozen, token-redacted copy (#4640 review).
|
|
948
967
|
const wireFrame = this.#prepareFrame(attached, frame);
|
|
949
|
-
const { beforeDispatch, onDispatch, ...requestOptions } = options ?? {};
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
:
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
968
|
+
const { beforeDispatch, onDispatch, dispatchFence, ...requestOptions } = options ?? {};
|
|
969
|
+
try {
|
|
970
|
+
await attached.client.connect?.();
|
|
971
|
+
} catch (error) {
|
|
972
|
+
if (error instanceof SdkClientError) throw new SdkPreparedDispatchError(error);
|
|
973
|
+
throw error;
|
|
974
|
+
}
|
|
975
|
+
if (!this.#attachmentPublished(attached))
|
|
976
|
+
throw new SessionRouterError("pre_send", "SDK session attachment changed during transport preparation.");
|
|
977
|
+
const dispatch = () =>
|
|
978
|
+
attached.client.request(wireFrame, {
|
|
979
|
+
...requestOptions,
|
|
980
|
+
connectedOnly: true,
|
|
981
|
+
timeoutMs: requestOptions.timeoutMs ?? SESSION_REQUEST_TIMEOUT_MS,
|
|
982
|
+
...(beforeDispatch
|
|
983
|
+
? {
|
|
984
|
+
beforeDispatch: (context: SdkDispatchContext) =>
|
|
985
|
+
beforeDispatch({ ...context, frame: redactDispatchFrame(context.frame) }),
|
|
986
|
+
}
|
|
987
|
+
: {}),
|
|
988
|
+
...(onDispatch
|
|
989
|
+
? {
|
|
990
|
+
onDispatch: (context: SdkDispatchContext) =>
|
|
991
|
+
onDispatch({ ...context, frame: redactDispatchFrame(context.frame) }),
|
|
992
|
+
}
|
|
993
|
+
: {}),
|
|
994
|
+
});
|
|
995
|
+
const response = await (dispatchFence ? dispatchFence(dispatch) : dispatch());
|
|
974
996
|
const settled = this.#sessions.get(sessionId);
|
|
975
997
|
if (
|
|
976
998
|
!settled ||
|
|
@@ -1141,7 +1163,12 @@ export class SessionRouter {
|
|
|
1141
1163
|
}
|
|
1142
1164
|
|
|
1143
1165
|
/** Lists saved sessions through Router-owned Broker discovery without exposing credentials or mutation authority. */
|
|
1144
|
-
async listBrokerSessions(
|
|
1166
|
+
async listBrokerSessions(
|
|
1167
|
+
input: Record<string, unknown>,
|
|
1168
|
+
idempotencyKey: string,
|
|
1169
|
+
options?: { beforeDispatch?: (context: SdkDispatchContext) => void },
|
|
1170
|
+
dispatchFence?: (dispatch: () => Promise<Record<string, unknown>>) => Promise<Record<string, unknown>>,
|
|
1171
|
+
): Promise<Record<string, unknown>> {
|
|
1145
1172
|
const operation = "session.list";
|
|
1146
1173
|
const discovery = await readSdkBrokerDiscovery(this.#agentDir);
|
|
1147
1174
|
if (!discovery) throw new SessionRouterError("pre_send", "SDK broker discovery is unavailable.");
|
|
@@ -1155,10 +1182,18 @@ export class SessionRouter {
|
|
|
1155
1182
|
}
|
|
1156
1183
|
try {
|
|
1157
1184
|
const timeoutMs = lifecycleRequestTimeoutMs(operation, input);
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1185
|
+
try {
|
|
1186
|
+
await client.connect?.();
|
|
1187
|
+
} catch (error) {
|
|
1188
|
+
if (error instanceof SdkClientError) throw new SdkPreparedDispatchError(error);
|
|
1189
|
+
throw error;
|
|
1190
|
+
}
|
|
1191
|
+
const dispatch = () =>
|
|
1192
|
+
client.request(
|
|
1193
|
+
{ type: "broker_request", operation, input, idempotencyKey },
|
|
1194
|
+
{ ...(timeoutMs === undefined ? {} : { timeoutMs }), ...options, connectedOnly: true },
|
|
1195
|
+
);
|
|
1196
|
+
return await (dispatchFence ? dispatchFence(dispatch) : dispatch());
|
|
1162
1197
|
} finally {
|
|
1163
1198
|
await client.close().catch(error => {
|
|
1164
1199
|
logger.warn(`SDK Broker session.list transport cleanup failed (${String(error)}).`);
|
|
@@ -1360,7 +1395,7 @@ export class SessionRouter {
|
|
|
1360
1395
|
// cannot keep the old attachment authorized.
|
|
1361
1396
|
const identityBefore = await lstatEndpoint(attached.endpoint.path);
|
|
1362
1397
|
if (!identityBefore || !sameEndpointIdentity(attached.endpointIdentity, identityBefore)) return false;
|
|
1363
|
-
if (identityBefore
|
|
1398
|
+
if (!matchesIndexedEndpointFile(identityBefore, indexed)) return false;
|
|
1364
1399
|
let raw: Record<string, unknown>;
|
|
1365
1400
|
try {
|
|
1366
1401
|
const parsed = JSON.parse(await Bun.file(attached.endpoint.path).text());
|
|
@@ -1384,7 +1419,7 @@ export class SessionRouter {
|
|
|
1384
1419
|
const identityAfter = await lstatEndpoint(attached.endpoint.path);
|
|
1385
1420
|
return (
|
|
1386
1421
|
identityAfter !== undefined &&
|
|
1387
|
-
identityAfter
|
|
1422
|
+
matchesIndexedEndpointFile(identityAfter, indexed) &&
|
|
1388
1423
|
sameEndpointIdentity(attached.endpointIdentity, identityAfter)
|
|
1389
1424
|
);
|
|
1390
1425
|
}
|
|
@@ -1416,7 +1451,7 @@ export class SessionRouter {
|
|
|
1416
1451
|
const endpointIdentity = await lstatEndpoint(endpointPath);
|
|
1417
1452
|
const endpoint = await readSdkSessionEndpoint(cwd, indexed.sessionId, scope);
|
|
1418
1453
|
if (!endpoint || endpoint.stale || endpoint.pid !== indexed.pid) return null;
|
|
1419
|
-
if (!endpointIdentity || endpointIdentity
|
|
1454
|
+
if (!endpointIdentity || !matchesIndexedEndpointFile(endpointIdentity, indexed)) return null;
|
|
1420
1455
|
// Identity is proven INSIDE this authority read (#4730 review): sampling it
|
|
1421
1456
|
// afterwards would let an identical rename between the read and the sample
|
|
1422
1457
|
// install the replacement's inode as the trusted baseline.
|
|
@@ -1441,7 +1476,7 @@ export class SessionRouter {
|
|
|
1441
1476
|
const endpointIdentityAfterRead = await lstatEndpoint(endpoint.path);
|
|
1442
1477
|
if (
|
|
1443
1478
|
!endpointIdentityAfterRead ||
|
|
1444
|
-
endpointIdentityAfterRead
|
|
1479
|
+
!matchesIndexedEndpointFile(endpointIdentityAfterRead, indexed) ||
|
|
1445
1480
|
!sameEndpointIdentity(endpointIdentity, endpointIdentityAfterRead)
|
|
1446
1481
|
)
|
|
1447
1482
|
return null;
|
|
@@ -1641,7 +1676,13 @@ export class SessionRouter {
|
|
|
1641
1676
|
return attached?.client.connectionId;
|
|
1642
1677
|
},
|
|
1643
1678
|
isCurrent: () => attached !== undefined && this.#attachmentPublished(attached),
|
|
1644
|
-
send: async (
|
|
1679
|
+
send: async (
|
|
1680
|
+
frame: Record<string, unknown>,
|
|
1681
|
+
options?: {
|
|
1682
|
+
beforeDispatch?: () => void;
|
|
1683
|
+
dispatchFence?: (dispatch: () => Promise<void>) => Promise<void>;
|
|
1684
|
+
},
|
|
1685
|
+
) => {
|
|
1645
1686
|
if (!attached || !this.#attachmentPublished(attached))
|
|
1646
1687
|
throw new SessionRouterError("pre_send", "SDK session attachment is stale.");
|
|
1647
1688
|
if (attached.initializingPublication) {
|
|
@@ -1659,7 +1700,17 @@ export class SessionRouter {
|
|
|
1659
1700
|
} else await this.#serialReconcile(runEpoch, true, true);
|
|
1660
1701
|
if (!attached || !this.#attachmentPublished(attached))
|
|
1661
1702
|
throw new SessionRouterError("pre_send", "SDK session attachment is stale.");
|
|
1662
|
-
attached
|
|
1703
|
+
const dispatchAttachment = attached;
|
|
1704
|
+
const dispatch = async () => {
|
|
1705
|
+
options?.beforeDispatch?.();
|
|
1706
|
+
try {
|
|
1707
|
+
dispatchAttachment.client.send(this.#prepareFrame(dispatchAttachment, frame));
|
|
1708
|
+
} catch (error) {
|
|
1709
|
+
if (error instanceof SdkClientError) throw new SdkPreparedDispatchError(error);
|
|
1710
|
+
throw error;
|
|
1711
|
+
}
|
|
1712
|
+
};
|
|
1713
|
+
await (options?.dispatchFence ? options.dispatchFence(dispatch) : dispatch());
|
|
1663
1714
|
},
|
|
1664
1715
|
/**
|
|
1665
1716
|
* Provider-lease heartbeats skip the pre-send authority reconcile
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AgentLoop calls `getApiKey(provider)` before `streamFn`.
|
|
3
|
+
* Resolve/stream already use `getApiKey(model)`. If those two lookups diverge,
|
|
4
|
+
* the child dies locally (~8ms, 0 tokens, sanitized "Agent run failed.")
|
|
5
|
+
* and never reaches the working model-scoped path (#5081).
|
|
6
|
+
*/
|
|
7
|
+
export type SessionApiKeyModel = {
|
|
8
|
+
provider: string;
|
|
9
|
+
baseUrl?: string;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export type SessionApiKeyRegistry = {
|
|
13
|
+
getApiKey(
|
|
14
|
+
model: SessionApiKeyModel,
|
|
15
|
+
sessionId?: string,
|
|
16
|
+
options?: { signal?: AbortSignal },
|
|
17
|
+
): Promise<string | undefined>;
|
|
18
|
+
getApiKeyForProvider(
|
|
19
|
+
provider: string,
|
|
20
|
+
sessionId?: string,
|
|
21
|
+
baseUrl?: string,
|
|
22
|
+
options?: { signal?: AbortSignal },
|
|
23
|
+
): Promise<string | undefined>;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type SessionApiKeyResolution = {
|
|
27
|
+
apiKey: string;
|
|
28
|
+
credentialSessionId: string | undefined;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export type SessionApiKeyCredentialType = "api_key" | "oauth" | undefined;
|
|
32
|
+
|
|
33
|
+
export function isStableSessionApiKeyCredentialType(
|
|
34
|
+
previous: SessionApiKeyCredentialType,
|
|
35
|
+
replacement: SessionApiKeyCredentialType,
|
|
36
|
+
): boolean {
|
|
37
|
+
return previous === replacement;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function resolveLiveSessionApiKeyModel(
|
|
41
|
+
live: SessionApiKeyModel | undefined,
|
|
42
|
+
captured: SessionApiKeyModel | undefined,
|
|
43
|
+
provider: string,
|
|
44
|
+
): SessionApiKeyModel | undefined {
|
|
45
|
+
if (live?.provider === provider) return live;
|
|
46
|
+
if (captured?.provider === provider) return captured;
|
|
47
|
+
return undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
async function lookupOnce(
|
|
51
|
+
registry: SessionApiKeyRegistry,
|
|
52
|
+
provider: string,
|
|
53
|
+
sessionId: string | undefined,
|
|
54
|
+
model: SessionApiKeyModel | undefined,
|
|
55
|
+
signal: AbortSignal | undefined,
|
|
56
|
+
): Promise<string | undefined> {
|
|
57
|
+
signal?.throwIfAborted();
|
|
58
|
+
const matchingModel = model?.provider === provider ? model : undefined;
|
|
59
|
+
const options = signal ? { signal } : undefined;
|
|
60
|
+
let key: string | undefined;
|
|
61
|
+
if (matchingModel) {
|
|
62
|
+
key = await registry.getApiKey(matchingModel, sessionId, options);
|
|
63
|
+
signal?.throwIfAborted();
|
|
64
|
+
}
|
|
65
|
+
if (!key) {
|
|
66
|
+
key = await registry.getApiKeyForProvider(provider, sessionId, matchingModel?.baseUrl, options);
|
|
67
|
+
signal?.throwIfAborted();
|
|
68
|
+
}
|
|
69
|
+
return key;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export async function lookupSessionApiKey(
|
|
73
|
+
registry: SessionApiKeyRegistry,
|
|
74
|
+
provider: string,
|
|
75
|
+
sessionId: string | undefined,
|
|
76
|
+
model: SessionApiKeyModel | undefined,
|
|
77
|
+
allowUnscopedRetry = true,
|
|
78
|
+
signal?: AbortSignal,
|
|
79
|
+
): Promise<SessionApiKeyResolution> {
|
|
80
|
+
let key = await lookupOnce(registry, provider, sessionId, model, signal);
|
|
81
|
+
// Architect children inherit the parent SID. Direct `-p --no-session` does
|
|
82
|
+
// not. Scoped miss then global/broker hit is the remaining 0-token death
|
|
83
|
+
// after #5105 (jsonl: Agent run failed / output 0).
|
|
84
|
+
if (!key && sessionId && allowUnscopedRetry) {
|
|
85
|
+
key = await lookupOnce(registry, provider, undefined, model, signal);
|
|
86
|
+
if (key) return { apiKey: key, credentialSessionId: undefined };
|
|
87
|
+
}
|
|
88
|
+
if (!key) {
|
|
89
|
+
throw Object.assign(new Error(`No API key found for provider "${provider}"`), {
|
|
90
|
+
code: "provider_unavailable",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return { apiKey: key, credentialSessionId: sessionId };
|
|
94
|
+
}
|