@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
|
@@ -36,6 +36,7 @@ import {
|
|
|
36
36
|
canContinuePersistedHistory,
|
|
37
37
|
dispatchedToolIdentity,
|
|
38
38
|
getAgentTerminalOwnerContext,
|
|
39
|
+
isContinuingMidRunMaintenanceOutcome,
|
|
39
40
|
isNonDispatchedToolEvent,
|
|
40
41
|
type ManagedAttemptContinuationOwnership,
|
|
41
42
|
type ManagedAttemptDecision,
|
|
@@ -438,6 +439,7 @@ import {
|
|
|
438
439
|
type ConfiguredFallbackChain,
|
|
439
440
|
cappedExponentialWithFullJitter,
|
|
440
441
|
compactionRetryDelay,
|
|
442
|
+
describeCompactionCandidateFailures,
|
|
441
443
|
effectiveFallbackDelay,
|
|
442
444
|
FallbackChainController,
|
|
443
445
|
type FallbackChainRuntimeState,
|
|
@@ -882,6 +884,10 @@ export interface AgentSessionConfig {
|
|
|
882
884
|
skills?: Skill[];
|
|
883
885
|
/** Skill loading warnings (already captured by SDK) */
|
|
884
886
|
skillWarnings?: SkillWarning[];
|
|
887
|
+
/** Re-enumerate filesystem and marketplace skills after plugin lifecycle changes. */
|
|
888
|
+
reloadSkills?: (cwd: string) => Promise<{ skills: Skill[]; warnings: SkillWarning[] }>;
|
|
889
|
+
/** Publish a successfully committed skill catalog to SDK/process snapshots. */
|
|
890
|
+
onSkillsReloaded?: (skills: Skill[], warnings: SkillWarning[]) => void;
|
|
885
891
|
/** Custom commands (TypeScript slash commands) */
|
|
886
892
|
customCommands?: LoadedCustomCommand[];
|
|
887
893
|
skillsSettings?: SkillsSettings;
|
|
@@ -1044,7 +1050,7 @@ type AutoCompactionTerminalStatus =
|
|
|
1044
1050
|
| { kind: "compacted"; continuationScheduled?: boolean }
|
|
1045
1051
|
| { kind: "aborted"; source: "signal" | "hook" }
|
|
1046
1052
|
| { kind: "skipped"; continuationScheduled?: boolean }
|
|
1047
|
-
| { kind: "failed" };
|
|
1053
|
+
| { kind: "failed"; errorMessage: string };
|
|
1048
1054
|
|
|
1049
1055
|
type ToolOutputPruneResult = {
|
|
1050
1056
|
prunedCount: number;
|
|
@@ -2786,7 +2792,7 @@ export class AgentSession {
|
|
|
2786
2792
|
this.#activeAttemptScope = undefined;
|
|
2787
2793
|
this.#activeLogicalRunId = undefined;
|
|
2788
2794
|
}
|
|
2789
|
-
#acceptSdkAttemptRun(handle: AttemptRunHandle, sdkRunToken?: string): void {
|
|
2795
|
+
#acceptSdkAttemptRun(handle: AttemptRunHandle, sdkRunToken?: string, sdkRunTokens?: string[]): void {
|
|
2790
2796
|
const predecessorScope = this.#activeAttemptScope;
|
|
2791
2797
|
const predecessorSdkRunToken =
|
|
2792
2798
|
predecessorScope === undefined ? undefined : this.#sdkRunTokensByAttemptScope.get(predecessorScope);
|
|
@@ -2799,6 +2805,11 @@ export class AgentSession {
|
|
|
2799
2805
|
if (sdkRunToken !== undefined) {
|
|
2800
2806
|
this.#activeSdkRunToken = sdkRunToken;
|
|
2801
2807
|
this.#sdkRunTokensByAttemptScope.set(handle.scope, sdkRunToken);
|
|
2808
|
+
const inheritedCohort =
|
|
2809
|
+
predecessorScope !== undefined && predecessorSdkRunToken === sdkRunToken
|
|
2810
|
+
? this.#sdkRunCohortsByAttemptScope.get(predecessorScope)
|
|
2811
|
+
: undefined;
|
|
2812
|
+
this.#sdkRunCohortsByAttemptScope.set(handle.scope, sdkRunTokens ?? inheritedCohort ?? [sdkRunToken]);
|
|
2802
2813
|
}
|
|
2803
2814
|
if (carryRecoverySkip) this.#skipPostPromptRecoveryWaitByAttemptScope.add(handle.scope);
|
|
2804
2815
|
}
|
|
@@ -3103,6 +3114,7 @@ export class AgentSession {
|
|
|
3103
3114
|
#sdkRunTokensByQueuedMessage = new WeakMap<AgentMessage, string>();
|
|
3104
3115
|
#skipPostPromptRecoveryWaitByAttemptScope = new WeakSet<AttemptScope>();
|
|
3105
3116
|
#sdkRunTokensByAttemptScope = new WeakMap<AttemptScope, string>();
|
|
3117
|
+
#sdkRunCohortsByAttemptScope = new WeakMap<AttemptScope, string[]>();
|
|
3106
3118
|
#activeSdkRunToken: string | undefined;
|
|
3107
3119
|
#activeAttemptScope: AttemptScope | undefined;
|
|
3108
3120
|
#attemptAuthority!: AttemptScopeAuthority;
|
|
@@ -3124,6 +3136,8 @@ export class AgentSession {
|
|
|
3124
3136
|
|
|
3125
3137
|
#skills: Skill[];
|
|
3126
3138
|
#skillWarnings: SkillWarning[];
|
|
3139
|
+
#reloadSkills: AgentSessionConfig["reloadSkills"];
|
|
3140
|
+
#onSkillsReloaded: AgentSessionConfig["onSkillsReloaded"];
|
|
3127
3141
|
|
|
3128
3142
|
// Custom commands (TypeScript slash commands)
|
|
3129
3143
|
#customCommands: LoadedCustomCommand[] = [];
|
|
@@ -4556,6 +4570,8 @@ export class AgentSession {
|
|
|
4556
4570
|
this.agent.setMainAttemptScopeObserver(scope => this.#bindAttemptScope(scope));
|
|
4557
4571
|
this.#skills = config.skills ?? [];
|
|
4558
4572
|
this.#skillWarnings = config.skillWarnings ?? [];
|
|
4573
|
+
this.#reloadSkills = config.reloadSkills;
|
|
4574
|
+
this.#onSkillsReloaded = config.onSkillsReloaded;
|
|
4559
4575
|
this.#customCommands = config.customCommands ?? [];
|
|
4560
4576
|
this.#skillsSettings = config.skillsSettings;
|
|
4561
4577
|
this.#modelRegistry = config.modelRegistry;
|
|
@@ -4569,7 +4585,7 @@ export class AgentSession {
|
|
|
4569
4585
|
this.#transformContext = config.transformContext ?? (messages => messages);
|
|
4570
4586
|
const configuredOnPayload = config.onPayload;
|
|
4571
4587
|
this.#onPayload = configuredOnPayload
|
|
4572
|
-
? (payload, model, scope) => configuredOnPayload(payload, model, scope)
|
|
4588
|
+
? (payload, model, scope, signal) => configuredOnPayload(payload, model, scope, signal)
|
|
4573
4589
|
: undefined;
|
|
4574
4590
|
this.rawSseDebugBuffer = config.rawSseDebugBuffer ?? new RawSseDebugBuffer();
|
|
4575
4591
|
// Avoid wrapping in an `async` closure when no user callback is configured: the
|
|
@@ -4578,9 +4594,9 @@ export class AgentSession {
|
|
|
4578
4594
|
// shows up as ~3.5% self time in streaming profiles.
|
|
4579
4595
|
const configuredOnResponse = config.onResponse;
|
|
4580
4596
|
this.#onResponse = configuredOnResponse
|
|
4581
|
-
? async (response, model, scope) => {
|
|
4597
|
+
? async (response, model, scope, signal) => {
|
|
4582
4598
|
this.rawSseDebugBuffer.recordResponse(response, model);
|
|
4583
|
-
await configuredOnResponse(response, model, scope);
|
|
4599
|
+
await configuredOnResponse(response, model, scope, signal);
|
|
4584
4600
|
}
|
|
4585
4601
|
: (response, model, _scope) => {
|
|
4586
4602
|
this.rawSseDebugBuffer.recordResponse(response, model);
|
|
@@ -5638,6 +5654,27 @@ export class AgentSession {
|
|
|
5638
5654
|
if (failures.length > 0) throw new AggregateError(failures, "Tool session cleanup failed.");
|
|
5639
5655
|
}
|
|
5640
5656
|
|
|
5657
|
+
#claimToolSessionTransitionCleanups(): Promise<void> {
|
|
5658
|
+
const cleanups = Array.from(this.#toolSessionTransitionCleanups);
|
|
5659
|
+
this.#toolSessionTransitionCleanups.clear();
|
|
5660
|
+
return this.#settleClaimedToolSessionCleanups(cleanups, "Tool session transition cleanup failed.");
|
|
5661
|
+
}
|
|
5662
|
+
|
|
5663
|
+
#claimToolSessionCleanups(): Promise<void> {
|
|
5664
|
+
const cleanups = Array.from(this.#toolSessionCleanups);
|
|
5665
|
+
this.#toolSessionCleanups.clear();
|
|
5666
|
+
return this.#settleClaimedToolSessionCleanups(cleanups, "Tool session cleanup failed.");
|
|
5667
|
+
}
|
|
5668
|
+
|
|
5669
|
+
async #settleClaimedToolSessionCleanups(
|
|
5670
|
+
cleanups: readonly (() => Promise<void> | void)[],
|
|
5671
|
+
message: string,
|
|
5672
|
+
): Promise<void> {
|
|
5673
|
+
const results = await Promise.allSettled(cleanups.map(async cleanup => await cleanup()));
|
|
5674
|
+
const failures = results.flatMap(result => (result.status === "rejected" ? [result.reason] : []));
|
|
5675
|
+
if (failures.length > 0) throw new AggregateError(failures, message);
|
|
5676
|
+
}
|
|
5677
|
+
|
|
5641
5678
|
getAsyncJobSnapshot(options?: { recentLimit?: number }): AsyncJobSnapshot | null {
|
|
5642
5679
|
// The session's OWNED manager first: /jobs, the status header, and the
|
|
5643
5680
|
// active-background count must reflect THIS session's jobs — with
|
|
@@ -5918,7 +5955,9 @@ export class AgentSession {
|
|
|
5918
5955
|
const canonicalAdmission = this.#reserveCanonicalMessageAdmission(event);
|
|
5919
5956
|
const terminalOwner = event.type === "agent_end" ? getAgentTerminalOwnerContext(event) : undefined;
|
|
5920
5957
|
const maintenanceCheckpoint =
|
|
5921
|
-
event.type === "agent_end" &&
|
|
5958
|
+
event.type === "agent_end" &&
|
|
5959
|
+
event.stopReason === "maintenance" &&
|
|
5960
|
+
isContinuingMidRunMaintenanceOutcome(event.maintenanceOutcome);
|
|
5922
5961
|
const terminalClaim =
|
|
5923
5962
|
maintenanceCheckpoint || !terminalOwner
|
|
5924
5963
|
? undefined
|
|
@@ -6196,9 +6235,13 @@ export class AgentSession {
|
|
|
6196
6235
|
this.#requestWorkerIntegrationAttempt();
|
|
6197
6236
|
}
|
|
6198
6237
|
// A maintenance agent_end is an internal checkpoint only while another
|
|
6199
|
-
// continuation will follow.
|
|
6200
|
-
//
|
|
6201
|
-
if (
|
|
6238
|
+
// continuation will follow. Failed or aborted maintenance is terminal and
|
|
6239
|
+
// must reach public subscribers.
|
|
6240
|
+
if (
|
|
6241
|
+
event.type === "agent_end" &&
|
|
6242
|
+
event.stopReason === "maintenance" &&
|
|
6243
|
+
isContinuingMidRunMaintenanceOutcome(event.maintenanceOutcome)
|
|
6244
|
+
)
|
|
6202
6245
|
return;
|
|
6203
6246
|
|
|
6204
6247
|
// Hold agent_end until the prompt's finally and all earlier async event work
|
|
@@ -6889,12 +6932,15 @@ export class AgentSession {
|
|
|
6889
6932
|
assistantMsg.stopReason !== "aborted" &&
|
|
6890
6933
|
this.#retryAttempt > 0
|
|
6891
6934
|
) {
|
|
6935
|
+
// Clear ownership before notifying observers: agent_end may run while
|
|
6936
|
+
// the success event is awaiting its subscribers.
|
|
6937
|
+
const attempt = this.#retryAttempt;
|
|
6938
|
+
this.#retryAttempt = 0;
|
|
6892
6939
|
await this.#emitSessionEvent({
|
|
6893
6940
|
type: "auto_retry_end",
|
|
6894
6941
|
success: true,
|
|
6895
|
-
attempt
|
|
6942
|
+
attempt,
|
|
6896
6943
|
});
|
|
6897
|
-
this.#retryAttempt = 0;
|
|
6898
6944
|
// Settle the retry gate here, colocated with the success event, rather
|
|
6899
6945
|
// than relying on the generic #resolveRetry() at the end of the
|
|
6900
6946
|
// agent_end branch. That tail resolver is bypassed by every early
|
|
@@ -6983,7 +7029,7 @@ export class AgentSession {
|
|
|
6983
7029
|
|
|
6984
7030
|
if (
|
|
6985
7031
|
event.type === "agent_end" &&
|
|
6986
|
-
!(event.stopReason === "maintenance" && event.maintenanceOutcome
|
|
7032
|
+
!(event.stopReason === "maintenance" && isContinuingMidRunMaintenanceOutcome(event.maintenanceOutcome))
|
|
6987
7033
|
) {
|
|
6988
7034
|
this.#releaseDeferredSdkFollowUps();
|
|
6989
7035
|
}
|
|
@@ -6996,28 +7042,33 @@ export class AgentSession {
|
|
|
6996
7042
|
// the same run on the rewritten context (no synthetic prompt), skipping
|
|
6997
7043
|
// the goal-runtime / skill-state / retry / compaction finalization a
|
|
6998
7044
|
// normal agent_end runs — none of that applies to an in-progress run.
|
|
6999
|
-
//
|
|
7000
|
-
// continuation if a newer prompt/abort
|
|
7045
|
+
// Failed and aborted outcomes fall through to terminal handling. The
|
|
7046
|
+
// generation guard drops a successful continuation if a newer prompt/abort
|
|
7047
|
+
// has moved the run on.
|
|
7001
7048
|
if (event.stopReason === "maintenance") {
|
|
7002
|
-
|
|
7003
|
-
|
|
7004
|
-
|
|
7005
|
-
|
|
7006
|
-
|
|
7007
|
-
|
|
7008
|
-
|
|
7009
|
-
|
|
7010
|
-
|
|
7011
|
-
|
|
7012
|
-
|
|
7013
|
-
|
|
7014
|
-
|
|
7015
|
-
|
|
7016
|
-
|
|
7017
|
-
|
|
7018
|
-
|
|
7049
|
+
if (isContinuingMidRunMaintenanceOutcome(event.maintenanceOutcome)) {
|
|
7050
|
+
this.#lastAssistantMessage = undefined;
|
|
7051
|
+
if (
|
|
7052
|
+
!maintenanceWasDisposed &&
|
|
7053
|
+
!this.#isDisposed &&
|
|
7054
|
+
maintenanceGeneration !== undefined &&
|
|
7055
|
+
this.#promptGeneration === maintenanceGeneration
|
|
7056
|
+
) {
|
|
7057
|
+
this.#scheduleAgentContinue({
|
|
7058
|
+
generation: maintenanceGeneration,
|
|
7059
|
+
skipCompactionCheck: true,
|
|
7060
|
+
resourceRunId: activePromptHandle,
|
|
7061
|
+
maintenanceContinuation: true,
|
|
7062
|
+
sdkRunToken: attemptScope ? this.#sdkRunTokensByAttemptScope.get(attemptScope) : undefined,
|
|
7063
|
+
});
|
|
7064
|
+
}
|
|
7065
|
+
return;
|
|
7019
7066
|
}
|
|
7020
|
-
|
|
7067
|
+
// Cancellation already owns teardown and terminal publication. Running
|
|
7068
|
+
// normal post-turn finalization here can deadlock abort/dispose while the
|
|
7069
|
+
// maintenance barrier is unwinding. Failed maintenance alone carries the
|
|
7070
|
+
// synthetic assistant error that must flow through terminal handling.
|
|
7071
|
+
if (event.maintenanceOutcome === "aborted") return;
|
|
7021
7072
|
}
|
|
7022
7073
|
const usage = this.getSessionStats().tokens;
|
|
7023
7074
|
await this.#goalRuntime.onAgentEnd({
|
|
@@ -7083,6 +7134,13 @@ export class AgentSession {
|
|
|
7083
7134
|
return;
|
|
7084
7135
|
}
|
|
7085
7136
|
this.#lastSuccessfulYieldToolCallId = undefined;
|
|
7137
|
+
if (event.stopReason === "maintenance" && event.maintenanceOutcome === "failed") {
|
|
7138
|
+
// The maintenance error already terminalized the run. Retrying this
|
|
7139
|
+
// synthetic assistant failure would resubmit the unchanged context that
|
|
7140
|
+
// maintenance failed to rewrite.
|
|
7141
|
+
this.#resolveRetry();
|
|
7142
|
+
return;
|
|
7143
|
+
}
|
|
7086
7144
|
|
|
7087
7145
|
// Check for retryable errors first (overloaded, rate limit, server errors)
|
|
7088
7146
|
if (this.#isRetryableError(msg)) {
|
|
@@ -7482,15 +7540,19 @@ export class AgentSession {
|
|
|
7482
7540
|
const inheritedSdkRunToken = options?.continueQueuedOnly
|
|
7483
7541
|
? undefined
|
|
7484
7542
|
: (options?.sdkRunToken ?? scheduledSdkRunToken);
|
|
7485
|
-
const
|
|
7543
|
+
const consumedSdkRunTokens = acceptance.consumedQueuedMessages
|
|
7486
7544
|
.map(message => this.#sdkRunTokensByQueuedMessage.get(message))
|
|
7487
|
-
.
|
|
7488
|
-
const sdkRunToken =
|
|
7545
|
+
.filter((token): token is string => token !== undefined);
|
|
7546
|
+
const sdkRunToken = consumedSdkRunTokens[0] ?? inheritedSdkRunToken;
|
|
7489
7547
|
this.#fireQueuedPromotionHooks(acceptance.consumedQueuedMessages, {
|
|
7490
7548
|
startsOwnRun: startsOwn,
|
|
7491
7549
|
});
|
|
7492
7550
|
if (startsOwn) this.#activeSdkRunToken = sdkRunToken;
|
|
7493
|
-
this.#acceptSdkAttemptRun(
|
|
7551
|
+
this.#acceptSdkAttemptRun(
|
|
7552
|
+
handle,
|
|
7553
|
+
sdkRunToken,
|
|
7554
|
+
consumedSdkRunTokens.length > 0 ? consumedSdkRunTokens : undefined,
|
|
7555
|
+
);
|
|
7494
7556
|
options?.onRunAccepted?.(handle);
|
|
7495
7557
|
// Keep the queued token available through the acceptance callback;
|
|
7496
7558
|
// SDK follow-up owners bind it to the new attempt scope there.
|
|
@@ -8580,7 +8642,8 @@ export class AgentSession {
|
|
|
8580
8642
|
? this.#sdkRunTokensByAttemptScope.get(deliveryScope as AttemptScope)
|
|
8581
8643
|
: undefined;
|
|
8582
8644
|
const isTerminalAgentEnd =
|
|
8583
|
-
event.type === "agent_end" &&
|
|
8645
|
+
event.type === "agent_end" &&
|
|
8646
|
+
!(event.stopReason === "maintenance" && isContinuingMidRunMaintenanceOutcome(event.maintenanceOutcome));
|
|
8584
8647
|
const finishAttempt = () => {
|
|
8585
8648
|
if (!isTerminalAgentEnd) return;
|
|
8586
8649
|
// A merged wake batch whose flush fired while still streaming cleared its
|
|
@@ -8625,6 +8688,9 @@ export class AgentSession {
|
|
|
8625
8688
|
{
|
|
8626
8689
|
type: "agent_start",
|
|
8627
8690
|
...(sdkRunToken ? { sdkRunToken } : {}),
|
|
8691
|
+
...(deliveryScope
|
|
8692
|
+
? { sdkRunTokens: this.#sdkRunCohortsByAttemptScope.get(deliveryScope as AttemptScope) }
|
|
8693
|
+
: {}),
|
|
8628
8694
|
},
|
|
8629
8695
|
undefined,
|
|
8630
8696
|
deliveryScope,
|
|
@@ -9371,10 +9437,10 @@ export class AgentSession {
|
|
|
9371
9437
|
// one here left signal exit orphaning the subprocess. Each runner clears
|
|
9372
9438
|
// its set, so a graceful dispose running first makes this a no-op rather
|
|
9373
9439
|
// than a double free.
|
|
9374
|
-
this.#
|
|
9440
|
+
this.#claimToolSessionCleanups().catch((error: unknown) =>
|
|
9375
9441
|
logger.warn("signal teardown: tool session cleanups failed", { error }),
|
|
9376
9442
|
),
|
|
9377
|
-
this.#
|
|
9443
|
+
this.#claimToolSessionTransitionCleanups().catch((error: unknown) =>
|
|
9378
9444
|
logger.warn("signal teardown: tool session transition cleanups failed", { error }),
|
|
9379
9445
|
),
|
|
9380
9446
|
]);
|
|
@@ -9500,6 +9566,11 @@ export class AgentSession {
|
|
|
9500
9566
|
});
|
|
9501
9567
|
}
|
|
9502
9568
|
|
|
9569
|
+
/** Test seam: await all currently admitted coordinator sidecar writes. */
|
|
9570
|
+
async awaitCoordinatorRuntimeStatePersistenceForTests(): Promise<void> {
|
|
9571
|
+
await this.#coordinatorPersistQueue;
|
|
9572
|
+
await this.#drainUnbarrieredCoordinatorPersists();
|
|
9573
|
+
}
|
|
9503
9574
|
queueCoordinatorRuntimeStatePersistForTests(event: AgentSessionEvent, gate: Promise<void>): Promise<void> {
|
|
9504
9575
|
this.#agentEventAdmission.set(event, {
|
|
9505
9576
|
persistGeneration: this.#coordinatorPersistGeneration,
|
|
@@ -10226,11 +10297,12 @@ export class AgentSession {
|
|
|
10226
10297
|
let wrappersByVersion = this.#guardedToolWrapperCache.get(tool);
|
|
10227
10298
|
const cached = wrappersByVersion?.get(cacheKey);
|
|
10228
10299
|
if (cached) return cached as T;
|
|
10229
|
-
const
|
|
10300
|
+
const innerTool = tool instanceof ExtensionToolWrapper ? tool.getInnerTool() : tool;
|
|
10301
|
+
const guarded = this.#wrapToolForCwdTransitionFence(
|
|
10230
10302
|
this.#wrapToolForWorkflowMutationGuard(
|
|
10231
10303
|
this.#wrapToolForAcpPermission(
|
|
10232
10304
|
guardToolForUltragoalAsk(
|
|
10233
|
-
|
|
10305
|
+
innerTool,
|
|
10234
10306
|
() => this.sessionManager.getCwd(),
|
|
10235
10307
|
() => ({
|
|
10236
10308
|
activeSkillState: this.getActiveSkillState(),
|
|
@@ -10241,6 +10313,7 @@ export class AgentSession {
|
|
|
10241
10313
|
),
|
|
10242
10314
|
),
|
|
10243
10315
|
);
|
|
10316
|
+
const wrapped = (this.#extensionRunner ? new ExtensionToolWrapper(guarded, this.#extensionRunner) : guarded) as T;
|
|
10244
10317
|
// The object published into `agent.state.tools` — and therefore the object the
|
|
10245
10318
|
// agent loop actually dispatches to — is this guard wrapper, not the registry
|
|
10246
10319
|
// entry. A wrapper built from a proven built-in inherits that proof; one built
|
|
@@ -10921,10 +10994,10 @@ export class AgentSession {
|
|
|
10921
10994
|
preparedOptions.onPayload = sessionOnPayload;
|
|
10922
10995
|
} else {
|
|
10923
10996
|
const requestOnPayload = options.onPayload;
|
|
10924
|
-
preparedOptions.onPayload = async (payload, model, callbackScope) => {
|
|
10925
|
-
const sessionPayload = await sessionOnPayload(payload, model, callbackScope);
|
|
10997
|
+
preparedOptions.onPayload = async (payload, model, callbackScope, signal) => {
|
|
10998
|
+
const sessionPayload = await sessionOnPayload(payload, model, callbackScope, signal);
|
|
10926
10999
|
const sessionResolvedPayload = sessionPayload ?? payload;
|
|
10927
|
-
const requestPayload = await requestOnPayload(sessionResolvedPayload, model, callbackScope);
|
|
11000
|
+
const requestPayload = await requestOnPayload(sessionResolvedPayload, model, callbackScope, signal);
|
|
10928
11001
|
return requestPayload ?? sessionResolvedPayload;
|
|
10929
11002
|
};
|
|
10930
11003
|
}
|
|
@@ -10935,9 +11008,9 @@ export class AgentSession {
|
|
|
10935
11008
|
preparedOptions.onResponse = sessionOnResponse;
|
|
10936
11009
|
} else {
|
|
10937
11010
|
const requestOnResponse = options.onResponse;
|
|
10938
|
-
preparedOptions.onResponse = async (response, model, callbackScope) => {
|
|
10939
|
-
await sessionOnResponse(response, model, callbackScope);
|
|
10940
|
-
await requestOnResponse(response, model, callbackScope);
|
|
11011
|
+
preparedOptions.onResponse = async (response, model, callbackScope, signal) => {
|
|
11012
|
+
await sessionOnResponse(response, model, callbackScope, signal);
|
|
11013
|
+
await requestOnResponse(response, model, callbackScope, signal);
|
|
10941
11014
|
};
|
|
10942
11015
|
}
|
|
10943
11016
|
}
|
|
@@ -11818,6 +11891,11 @@ export class AgentSession {
|
|
|
11818
11891
|
const releaseStartupPromptWaiter = this.#reserveStartupPromptWaiter();
|
|
11819
11892
|
try {
|
|
11820
11893
|
await this.#promptInternal(text, options, releaseStartupPromptWaiter);
|
|
11894
|
+
// Agent-core converts listener failures into an aborted response. Keep a
|
|
11895
|
+
// rejected persistence fence typed at the public prompt boundary instead
|
|
11896
|
+
// of reporting the misleading provider-level "Request was aborted".
|
|
11897
|
+
const appendRejection = this.sessionManager.getAppendIdentityMismatch();
|
|
11898
|
+
if (appendRejection) throw appendRejection;
|
|
11821
11899
|
} finally {
|
|
11822
11900
|
releaseStartupPromptWaiter();
|
|
11823
11901
|
}
|
|
@@ -12409,6 +12487,14 @@ export class AgentSession {
|
|
|
12409
12487
|
hasPendingNextTurnMessages = pendingNextTurnMessageCount > 0;
|
|
12410
12488
|
const promptAttribution: "user" | "agent" | undefined =
|
|
12411
12489
|
"attribution" in message ? message.attribution : undefined;
|
|
12490
|
+
let effectivePrompt = expandedText;
|
|
12491
|
+
const messageImages =
|
|
12492
|
+
"content" in message && Array.isArray(message.content)
|
|
12493
|
+
? message.content.filter((content): content is ImageContent => content.type === "image")
|
|
12494
|
+
: undefined;
|
|
12495
|
+
let effectiveImages =
|
|
12496
|
+
options?.images ?? (messageImages && messageImages.length > 0 ? messageImages : undefined);
|
|
12497
|
+
let promptMessage = message;
|
|
12412
12498
|
let phaseACompleted = false;
|
|
12413
12499
|
let fileMentionMessages: AgentMessage[] = [];
|
|
12414
12500
|
let beforeAgentStartResultMessages: BeforeAgentStartInternalMessage[] = [];
|
|
@@ -12429,7 +12515,49 @@ export class AgentSession {
|
|
|
12429
12515
|
if (!phaseACompleted) {
|
|
12430
12516
|
phaseACompleted = true;
|
|
12431
12517
|
// Phase A (one-time side-effectful products; runs once).
|
|
12432
|
-
const
|
|
12518
|
+
const beforeAgentStartSystemPrompt = await this.#buildSystemPromptForAgentStart(effectivePrompt);
|
|
12519
|
+
hindsightRecall = this.getHindsightSessionState()?.getRecallSnippetForInjection();
|
|
12520
|
+
planReferenceMessage = await this.#buildPlanReferenceMessage();
|
|
12521
|
+
// Emit before_agent_start extension event. Race hook completion with
|
|
12522
|
+
// prompt cancellation so a wedged hook cannot retain SDK prompt authority.
|
|
12523
|
+
if (this.#extensionRunner?.hasHandlers("before_agent_start")) this.#markRetryReplayUnsafe();
|
|
12524
|
+
if (this.#extensionRunner) {
|
|
12525
|
+
const result = await this.#awaitPromptPreflight(
|
|
12526
|
+
generation,
|
|
12527
|
+
preflightSignal,
|
|
12528
|
+
this.#extensionRunner.emitBeforeAgentStart(
|
|
12529
|
+
effectivePrompt,
|
|
12530
|
+
effectiveImages,
|
|
12531
|
+
beforeAgentStartSystemPrompt,
|
|
12532
|
+
preflightSignal,
|
|
12533
|
+
),
|
|
12534
|
+
);
|
|
12535
|
+
if (result?.messages) beforeAgentStartResultMessages = [...result.messages];
|
|
12536
|
+
if (result?.prompt !== undefined) effectivePrompt = result.prompt;
|
|
12537
|
+
if (result && Object.hasOwn(result, "images")) effectiveImages = result.images;
|
|
12538
|
+
if (result?.prompt !== undefined || (result && Object.hasOwn(result, "images"))) {
|
|
12539
|
+
if (
|
|
12540
|
+
promptMessage.role === "user" ||
|
|
12541
|
+
promptMessage.role === "developer" ||
|
|
12542
|
+
promptMessage.role === "custom"
|
|
12543
|
+
) {
|
|
12544
|
+
promptMessage = {
|
|
12545
|
+
...promptMessage,
|
|
12546
|
+
content: [{ type: "text", text: effectivePrompt }, ...(effectiveImages ?? [])],
|
|
12547
|
+
};
|
|
12548
|
+
}
|
|
12549
|
+
}
|
|
12550
|
+
if (result?.systemPrompt !== undefined) {
|
|
12551
|
+
this.agent.setSystemPrompt(result.systemPrompt);
|
|
12552
|
+
} else if (result?.prompt !== undefined) {
|
|
12553
|
+
this.agent.setSystemPrompt(await this.#buildSystemPromptForAgentStart(effectivePrompt));
|
|
12554
|
+
} else {
|
|
12555
|
+
this.agent.setSystemPrompt(beforeAgentStartSystemPrompt);
|
|
12556
|
+
}
|
|
12557
|
+
} else {
|
|
12558
|
+
this.agent.setSystemPrompt(beforeAgentStartSystemPrompt);
|
|
12559
|
+
}
|
|
12560
|
+
const fileMentions = extractFileMentions(effectivePrompt);
|
|
12433
12561
|
if (fileMentions.length > 0) {
|
|
12434
12562
|
const cwd = this.sessionManager.getCwd();
|
|
12435
12563
|
// Collect resolved paths already shown (read or mentioned) in the
|
|
@@ -12457,31 +12585,6 @@ export class AgentSession {
|
|
|
12457
12585
|
recentlyShownPaths,
|
|
12458
12586
|
});
|
|
12459
12587
|
}
|
|
12460
|
-
const beforeAgentStartSystemPrompt = await this.#buildSystemPromptForAgentStart(expandedText);
|
|
12461
|
-
hindsightRecall = this.getHindsightSessionState()?.getRecallSnippetForInjection();
|
|
12462
|
-
planReferenceMessage = await this.#buildPlanReferenceMessage();
|
|
12463
|
-
// Emit before_agent_start extension event. Race hook completion with
|
|
12464
|
-
// prompt cancellation so a wedged hook cannot retain SDK prompt authority.
|
|
12465
|
-
if (this.#extensionRunner?.hasHandlers("before_agent_start")) this.#markRetryReplayUnsafe();
|
|
12466
|
-
if (this.#extensionRunner) {
|
|
12467
|
-
const result = await this.#awaitPromptPreflight(
|
|
12468
|
-
generation,
|
|
12469
|
-
preflightSignal,
|
|
12470
|
-
this.#extensionRunner.emitBeforeAgentStart(
|
|
12471
|
-
expandedText,
|
|
12472
|
-
options?.images,
|
|
12473
|
-
beforeAgentStartSystemPrompt,
|
|
12474
|
-
),
|
|
12475
|
-
);
|
|
12476
|
-
if (result?.messages) beforeAgentStartResultMessages = [...result.messages];
|
|
12477
|
-
if (result?.systemPrompt !== undefined) {
|
|
12478
|
-
this.agent.setSystemPrompt(result.systemPrompt);
|
|
12479
|
-
} else {
|
|
12480
|
-
this.agent.setSystemPrompt(beforeAgentStartSystemPrompt);
|
|
12481
|
-
}
|
|
12482
|
-
} else {
|
|
12483
|
-
this.agent.setSystemPrompt(beforeAgentStartSystemPrompt);
|
|
12484
|
-
}
|
|
12485
12588
|
// Invoke first-party internal before-agent-start contributors. These
|
|
12486
12589
|
// run alongside the extension runner (not via user-loaded hooks) and
|
|
12487
12590
|
// append through the same custom-message attribution path. Errors are nonfatal.
|
|
@@ -12492,8 +12595,8 @@ export class AgentSession {
|
|
|
12492
12595
|
generation,
|
|
12493
12596
|
preflightSignal,
|
|
12494
12597
|
contributor({
|
|
12495
|
-
prompt:
|
|
12496
|
-
images:
|
|
12598
|
+
prompt: effectivePrompt,
|
|
12599
|
+
images: effectiveImages,
|
|
12497
12600
|
sessionId: this.sessionId,
|
|
12498
12601
|
}),
|
|
12499
12602
|
);
|
|
@@ -12551,7 +12654,7 @@ export class AgentSession {
|
|
|
12551
12654
|
}
|
|
12552
12655
|
|
|
12553
12656
|
const promptIndex = messages.length;
|
|
12554
|
-
messages.push(
|
|
12657
|
+
messages.push(promptMessage);
|
|
12555
12658
|
|
|
12556
12659
|
// Re-present captured pending next-turn messages (never drained here).
|
|
12557
12660
|
// Reclassify deferred envelopes before injecting them into the new
|
|
@@ -14200,6 +14303,25 @@ export class AgentSession {
|
|
|
14200
14303
|
await this.refreshBaseSystemPrompt();
|
|
14201
14304
|
}
|
|
14202
14305
|
|
|
14306
|
+
/** Refresh the live registered-skill catalog after install/remove/reload. */
|
|
14307
|
+
async reloadSkills(cwd = this.sessionManager.getCwd()): Promise<void> {
|
|
14308
|
+
if (!this.#reloadSkills) return;
|
|
14309
|
+
const reloaded = await this.#reloadSkills(cwd);
|
|
14310
|
+
const previousSkills = this.#skills;
|
|
14311
|
+
const previousWarnings = this.#skillWarnings;
|
|
14312
|
+
this.#skills = reloaded.skills;
|
|
14313
|
+
this.#skillWarnings = reloaded.warnings;
|
|
14314
|
+
try {
|
|
14315
|
+
await this.refreshBaseSystemPrompt();
|
|
14316
|
+
} catch (error) {
|
|
14317
|
+
this.#skills = previousSkills;
|
|
14318
|
+
this.#skillWarnings = previousWarnings;
|
|
14319
|
+
await this.refreshBaseSystemPrompt().catch(() => {});
|
|
14320
|
+
throw error;
|
|
14321
|
+
}
|
|
14322
|
+
this.#onSkillsReloaded?.(reloaded.skills, reloaded.warnings);
|
|
14323
|
+
}
|
|
14324
|
+
|
|
14203
14325
|
/**
|
|
14204
14326
|
* Retire the cached workspace tree after a rescope so the next turn re-scans
|
|
14205
14327
|
* at the new cwd instead of re-presenting the abandoned launcher root.
|
|
@@ -18407,18 +18529,23 @@ export class AgentSession {
|
|
|
18407
18529
|
* prune → promote → compact machinery and returns an explicit outcome.
|
|
18408
18530
|
*
|
|
18409
18531
|
* A non-"not-needed" outcome ends the current run losslessly
|
|
18410
|
-
* (`agent_end.stopReason === "maintenance"`)
|
|
18411
|
-
*
|
|
18412
|
-
* This method never self-continues, runs goal-runtime
|
|
18413
|
-
* state, or emits a user-facing pause.
|
|
18532
|
+
* (`agent_end.stopReason === "maintenance"`). The `agent_end` handler resumes
|
|
18533
|
+
* committed maintenance with no synthetic prompt and terminalizes failed or
|
|
18534
|
+
* aborted maintenance. This method never self-continues, runs goal-runtime
|
|
18535
|
+
* hooks, clears skill state, or emits a user-facing pause.
|
|
18414
18536
|
*/
|
|
18415
18537
|
async #runMidRunMaintenance(
|
|
18416
18538
|
context: AgentContext,
|
|
18417
18539
|
lifecycle: MidRunMaintenanceLifecycle,
|
|
18418
18540
|
): Promise<ContextMaintenanceResult> {
|
|
18419
|
-
const result = (
|
|
18541
|
+
const result = (
|
|
18542
|
+
outcome: MidRunMaintenanceOutcome,
|
|
18543
|
+
releaseCurrentContext = false,
|
|
18544
|
+
errorMessage?: string,
|
|
18545
|
+
): ContextMaintenanceResult => ({
|
|
18420
18546
|
outcome,
|
|
18421
18547
|
...(releaseCurrentContext ? { releaseCurrentContext: true } : {}),
|
|
18548
|
+
...(errorMessage ? { errorMessage } : {}),
|
|
18422
18549
|
});
|
|
18423
18550
|
if (this.#isDisposed) return { outcome: "aborted" };
|
|
18424
18551
|
const invocationController = new AbortController();
|
|
@@ -18529,7 +18656,13 @@ export class AgentSession {
|
|
|
18529
18656
|
if (compactionStatus.kind === "aborted") {
|
|
18530
18657
|
return compactionStatus.source === "hook" ? result("not-needed") : result("aborted");
|
|
18531
18658
|
}
|
|
18532
|
-
return result(
|
|
18659
|
+
return result(
|
|
18660
|
+
"failed",
|
|
18661
|
+
false,
|
|
18662
|
+
compactionStatus.kind === "failed"
|
|
18663
|
+
? compactionStatus.errorMessage
|
|
18664
|
+
: "Context maintenance could not commit a compaction before the next model request.",
|
|
18665
|
+
);
|
|
18533
18666
|
} finally {
|
|
18534
18667
|
this.#activeMidRunBarrierControllers.delete(invocationController);
|
|
18535
18668
|
}
|
|
@@ -19356,10 +19489,10 @@ export class AgentSession {
|
|
|
19356
19489
|
isError: message.isError,
|
|
19357
19490
|
content: this.#normalizeProviderReplayValue(message.content),
|
|
19358
19491
|
};
|
|
19359
|
-
case "
|
|
19492
|
+
case "pythonExecution":
|
|
19360
19493
|
return {
|
|
19361
19494
|
role: message.role,
|
|
19362
|
-
|
|
19495
|
+
code: message.code,
|
|
19363
19496
|
output: message.output,
|
|
19364
19497
|
exitCode: message.exitCode,
|
|
19365
19498
|
cancelled: message.cancelled,
|
|
@@ -19377,12 +19510,13 @@ export class AgentSession {
|
|
|
19377
19510
|
: undefined,
|
|
19378
19511
|
excludeFromContext: message.excludeFromContext,
|
|
19379
19512
|
};
|
|
19380
|
-
case "
|
|
19513
|
+
case "bashExecution":
|
|
19381
19514
|
return {
|
|
19382
19515
|
role: message.role,
|
|
19383
|
-
|
|
19516
|
+
command: message.command,
|
|
19384
19517
|
output: message.output,
|
|
19385
19518
|
exitCode: message.exitCode,
|
|
19519
|
+
signal: message.signal,
|
|
19386
19520
|
cancelled: message.cancelled,
|
|
19387
19521
|
meta: message.meta
|
|
19388
19522
|
? {
|
|
@@ -19643,12 +19777,15 @@ export class AgentSession {
|
|
|
19643
19777
|
*/
|
|
19644
19778
|
#maintenanceProviderTransport(): {
|
|
19645
19779
|
sessionId: string | undefined;
|
|
19780
|
+
providerSessionId: string | undefined;
|
|
19646
19781
|
providerSessionState: Map<string, ProviderSessionState>;
|
|
19647
19782
|
preferWebsockets: boolean | undefined;
|
|
19648
19783
|
remoteCompactionFallbackHealth: RemoteCompactionFallbackHealthHooks;
|
|
19649
19784
|
} {
|
|
19785
|
+
const providerSessionId = this.agent.providerSessionId ?? this.agent.sessionId;
|
|
19650
19786
|
return {
|
|
19651
|
-
sessionId:
|
|
19787
|
+
sessionId: providerSessionId,
|
|
19788
|
+
providerSessionId,
|
|
19652
19789
|
providerSessionState: this.#providerSessionState,
|
|
19653
19790
|
preferWebsockets: this.agent.preferWebsockets,
|
|
19654
19791
|
remoteCompactionFallbackHealth: this.#remoteCompactionFallbackHealth,
|
|
@@ -20078,6 +20215,10 @@ export class AgentSession {
|
|
|
20078
20215
|
const telemetry = resolveTelemetry(this.agent.telemetry, this.sessionId);
|
|
20079
20216
|
let compactResult: CompactionResult | undefined;
|
|
20080
20217
|
let lastError: unknown;
|
|
20218
|
+
// Every candidate that was tried and failed, in order. Only the last failure
|
|
20219
|
+
// used to reach the user, which named whichever same-provider fallback the
|
|
20220
|
+
// chain ended on and hid that the session model itself had already failed.
|
|
20221
|
+
const candidateFailures: Array<{ model: string; message: string }> = [];
|
|
20081
20222
|
|
|
20082
20223
|
for (const candidate of candidates) {
|
|
20083
20224
|
const apiKey = await this.#modelRegistry.getApiKey(candidate, this.credentialSessionId);
|
|
@@ -20111,6 +20252,7 @@ export class AgentSession {
|
|
|
20111
20252
|
const message = error instanceof Error ? error.message : String(error);
|
|
20112
20253
|
if (this.#isCompactionAuthFailure(error)) {
|
|
20113
20254
|
lastError = this.#buildCompactionAuthError();
|
|
20255
|
+
candidateFailures.push({ model: `${candidate.provider}/${candidate.id}`, message });
|
|
20114
20256
|
break;
|
|
20115
20257
|
}
|
|
20116
20258
|
const retryAfterMs = this.#parseRetryAfterMsFromError(message);
|
|
@@ -20123,6 +20265,7 @@ export class AgentSession {
|
|
|
20123
20265
|
isUsageLimitError(message));
|
|
20124
20266
|
if (!shouldRetry) {
|
|
20125
20267
|
lastError = error;
|
|
20268
|
+
candidateFailures.push({ model: `${candidate.provider}/${candidate.id}`, message });
|
|
20126
20269
|
break;
|
|
20127
20270
|
}
|
|
20128
20271
|
|
|
@@ -20147,6 +20290,7 @@ export class AgentSession {
|
|
|
20147
20290
|
model: `${candidate.provider}/${candidate.id}`,
|
|
20148
20291
|
});
|
|
20149
20292
|
lastError = error;
|
|
20293
|
+
candidateFailures.push({ model: `${candidate.provider}/${candidate.id}`, message });
|
|
20150
20294
|
break; // Exit retry loop, continue to next candidate
|
|
20151
20295
|
}
|
|
20152
20296
|
// No more candidates - we have to wait
|
|
@@ -20172,7 +20316,9 @@ export class AgentSession {
|
|
|
20172
20316
|
|
|
20173
20317
|
if (!compactResult) {
|
|
20174
20318
|
if (lastError) {
|
|
20175
|
-
throw
|
|
20319
|
+
throw candidateFailures.length > 1
|
|
20320
|
+
? describeCompactionCandidateFailures(candidateFailures, lastError)
|
|
20321
|
+
: lastError;
|
|
20176
20322
|
}
|
|
20177
20323
|
throw new Error("Compaction failed: no available model");
|
|
20178
20324
|
}
|
|
@@ -20286,7 +20432,7 @@ export class AgentSession {
|
|
|
20286
20432
|
? `Context overflow recovery failed: ${errorMessage}`
|
|
20287
20433
|
: `Auto-compaction failed: ${errorMessage}`,
|
|
20288
20434
|
});
|
|
20289
|
-
return { kind: "failed" };
|
|
20435
|
+
return { kind: "failed", errorMessage };
|
|
20290
20436
|
} finally {
|
|
20291
20437
|
if (this.#autoCompactionAbortController === autoCompactionAbortController) {
|
|
20292
20438
|
this.#autoCompactionAbortController = undefined;
|
|
@@ -22247,6 +22393,7 @@ export class AgentSession {
|
|
|
22247
22393
|
command,
|
|
22248
22394
|
output: result.output,
|
|
22249
22395
|
exitCode: result.exitCode,
|
|
22396
|
+
signal: result.signal,
|
|
22250
22397
|
cancelled: result.cancelled,
|
|
22251
22398
|
truncated: result.truncated,
|
|
22252
22399
|
meta,
|
|
@@ -22350,7 +22497,10 @@ export class AgentSession {
|
|
|
22350
22497
|
onChunk,
|
|
22351
22498
|
signal: abortController.signal,
|
|
22352
22499
|
});
|
|
22353
|
-
|
|
22500
|
+
// A retained kernel can finish after strict session close has fenced
|
|
22501
|
+
// persistence. The caller still receives its completed result, but it
|
|
22502
|
+
// must not reopen a closing session to append history.
|
|
22503
|
+
if (!this.#evalExecutionDisposing) this.recordPythonResult(code, result, options);
|
|
22354
22504
|
return result;
|
|
22355
22505
|
})();
|
|
22356
22506
|
return await this.trackEvalExecution(execution, abortController);
|