@oh-my-pi/pi-coding-agent 17.0.9 → 17.1.1
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 +78 -0
- package/README.md +1 -1
- package/dist/cli.js +4685 -4614
- package/dist/types/async/job-manager.d.ts +37 -1
- package/dist/types/cli/args.d.ts +2 -0
- package/dist/types/cli/bench-cli.d.ts +41 -0
- package/dist/types/commands/bench.d.ts +15 -3
- package/dist/types/commands/launch.d.ts +4 -0
- package/dist/types/config/model-registry.d.ts +3 -1
- package/dist/types/config/models-config-schema.d.ts +18 -6
- package/dist/types/config/models-config.d.ts +14 -5
- package/dist/types/config/provider-globals.d.ts +2 -2
- package/dist/types/config/service-tier.d.ts +5 -1
- package/dist/types/config/settings-schema.d.ts +374 -47
- package/dist/types/config/settings.d.ts +7 -0
- package/dist/types/dap/client.d.ts +20 -0
- package/dist/types/exec/bash-executor.d.ts +38 -0
- package/dist/types/exec/direnv.d.ts +33 -0
- package/dist/types/export/html/args.d.ts +15 -0
- package/dist/types/export/html/index.d.ts +11 -26
- package/dist/types/export/html/web-palette.d.ts +55 -116
- package/dist/types/extensibility/extensions/loader.d.ts +3 -0
- package/dist/types/extensibility/extensions/types.d.ts +17 -2
- package/dist/types/extensibility/legacy-pi-coding-agent-shim.d.ts +3 -0
- package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +13 -0
- package/dist/types/live/attestation.d.ts +2 -0
- package/dist/types/live/controller.d.ts +48 -0
- package/dist/types/live/protocol.d.ts +85 -0
- package/dist/types/live/protocol.test.d.ts +1 -0
- package/dist/types/live/transport.d.ts +35 -0
- package/dist/types/live/visualizer.d.ts +30 -0
- package/dist/types/lsp/client.d.ts +16 -1
- package/dist/types/mcp/config-writer.test.d.ts +1 -0
- package/dist/types/mcp/oauth-discovery.d.ts +2 -0
- package/dist/types/mcp/smithery-auth.d.ts +1 -1
- package/dist/types/mcp/smithery-auth.test.d.ts +1 -0
- package/dist/types/memory-backend/tool-names.d.ts +2 -0
- package/dist/types/modes/components/assistant-message.d.ts +1 -0
- package/dist/types/modes/components/custom-message.d.ts +1 -1
- package/dist/types/modes/components/login-dialog.d.ts +2 -2
- package/dist/types/modes/components/message-frame.d.ts +8 -4
- package/dist/types/modes/components/plan-review-overlay.d.ts +26 -0
- package/dist/types/modes/components/session-account-selector.d.ts +11 -0
- package/dist/types/modes/components/settings-defs.d.ts +7 -1
- package/dist/types/modes/components/status-line/component.jj-cache.test.d.ts +1 -0
- package/dist/types/modes/components/tool-execution.d.ts +9 -1
- package/dist/types/modes/controllers/command-controller.d.ts +1 -1
- package/dist/types/modes/controllers/event-controller.d.ts +6 -1
- package/dist/types/modes/controllers/live-command-controller.d.ts +14 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +6 -0
- package/dist/types/modes/theme/theme.d.ts +1 -1
- package/dist/types/modes/types.d.ts +4 -1
- package/dist/types/modes/utils/context-usage.d.ts +12 -2
- package/dist/types/plan-mode/plan-files.d.ts +10 -0
- package/dist/types/registry/agent-lifecycle.d.ts +21 -9
- package/dist/types/registry/agent-registry.d.ts +11 -4
- package/dist/types/sdk.d.ts +15 -1
- package/dist/types/secrets/index.d.ts +15 -2
- package/dist/types/secrets/obfuscator.d.ts +113 -15
- package/dist/types/session/acp-permission-gate.d.ts +19 -0
- package/dist/types/session/agent-session-events.d.ts +84 -0
- package/dist/types/session/agent-session-types.d.ts +321 -0
- package/dist/types/session/agent-session.d.ts +135 -753
- package/dist/types/session/async-job-delivery.d.ts +28 -0
- package/dist/types/session/auth-storage.d.ts +1 -1
- package/dist/types/session/bash-runner.d.ts +75 -0
- package/dist/types/session/blob-store.d.ts +11 -1
- package/dist/types/session/blob-store.test.d.ts +1 -0
- package/dist/types/session/checkpoint-entries.d.ts +28 -0
- package/dist/types/session/eval-runner.d.ts +51 -0
- package/dist/types/session/irc-bridge.d.ts +46 -0
- package/dist/types/session/messages.d.ts +24 -0
- package/dist/types/session/model-controls.d.ts +180 -0
- package/dist/types/session/prewalk.d.ts +46 -0
- package/dist/types/session/queued-messages.d.ts +22 -0
- package/dist/types/session/redis-session-storage.d.ts +1 -0
- package/dist/types/session/retry-fallback-chains.d.ts +74 -0
- package/dist/types/session/role-models.d.ts +15 -0
- package/dist/types/session/session-advisors.d.ts +228 -0
- package/dist/types/session/session-entries.d.ts +8 -0
- package/dist/types/session/session-handoff.d.ts +70 -0
- package/dist/types/session/session-history-format.d.ts +6 -1
- package/dist/types/session/session-maintenance.d.ts +246 -0
- package/dist/types/session/session-manager.d.ts +41 -0
- package/dist/types/session/session-memory.d.ts +56 -0
- package/dist/types/session/session-provider-boundary.d.ts +62 -0
- package/dist/types/session/session-stats.d.ts +48 -0
- package/dist/types/session/session-tools.d.ts +158 -0
- package/dist/types/session/session-workspace.d.ts +32 -0
- package/dist/types/session/stream-guards.d.ts +44 -0
- package/dist/types/session/streaming-output.d.ts +8 -0
- package/dist/types/session/todo-tracker.d.ts +56 -0
- package/dist/types/session/ttsr-coordinator.d.ts +51 -0
- package/dist/types/session/turn-recovery.d.ts +225 -0
- package/dist/types/slash-commands/helpers/session-pin.d.ts +9 -0
- package/dist/types/stt/index.d.ts +0 -2
- package/dist/types/stt/stt-controller.d.ts +7 -0
- package/dist/types/system-prompt.d.ts +2 -0
- package/dist/types/task/executor.d.ts +4 -1
- package/dist/types/task/output-manager.d.ts +3 -1
- package/dist/types/tiny/title-client.d.ts +10 -0
- package/dist/types/tools/approval.d.ts +1 -0
- package/dist/types/tools/browser/launch.d.ts +5 -0
- package/dist/types/tools/builtin-names.d.ts +1 -1
- package/dist/types/tools/computer/protocol.d.ts +43 -0
- package/dist/types/tools/computer/supervisor.d.ts +32 -0
- package/dist/types/tools/computer/worker-entry.d.ts +1 -0
- package/dist/types/tools/computer/worker.d.ts +15 -0
- package/dist/types/tools/computer-renderer.d.ts +22 -0
- package/dist/types/tools/computer.d.ts +71 -0
- package/dist/types/tools/context.d.ts +2 -0
- package/dist/types/tools/default-renderer.d.ts +21 -0
- package/dist/types/tools/image-gen.d.ts +4 -4
- package/dist/types/tools/image-providers.d.ts +38 -0
- package/dist/types/tools/index.d.ts +7 -0
- package/dist/types/tools/path-utils.d.ts +8 -0
- package/dist/types/tools/todo.d.ts +10 -4
- package/dist/types/tools/xdev.d.ts +5 -1
- package/dist/types/tts/streaming-player.d.ts +10 -29
- package/dist/types/tts/vocalizer.d.ts +5 -0
- package/dist/types/utils/jj.d.ts +29 -0
- package/dist/types/utils/lang-from-path.d.ts +1 -0
- package/dist/types/utils/title-generator.d.ts +30 -0
- package/dist/types/utils/tools-manager.d.ts +1 -2
- package/dist/types/vibe/runtime.d.ts +36 -8
- package/dist/types/web/search/index.d.ts +1 -1
- package/dist/types/web/search/provider.d.ts +15 -5
- package/dist/types/web/search/types.d.ts +94 -0
- package/package.json +12 -12
- package/scripts/generate-share-viewer.ts +4 -6
- package/src/advisor/__tests__/advisor.test.ts +643 -0
- package/src/advisor/runtime.ts +144 -43
- package/src/async/job-manager.ts +90 -2
- package/src/cli/args.ts +3 -0
- package/src/cli/auth-gateway-cli.ts +18 -3
- package/src/cli/bench-cli.ts +395 -29
- package/src/cli/flag-tables.ts +3 -0
- package/src/cli/gc-cli.ts +2 -2
- package/src/cli/setup-cli.ts +2 -14
- package/src/cli/usage-cli.ts +10 -1
- package/src/cli.ts +8 -0
- package/src/collab/host.ts +3 -2
- package/src/commands/bench.ts +18 -4
- package/src/commands/launch.ts +4 -0
- package/src/config/model-registry.ts +16 -2
- package/src/config/models-config-schema.ts +15 -4
- package/src/config/provider-globals.ts +9 -9
- package/src/config/service-tier.ts +26 -1
- package/src/config/settings-schema.ts +270 -51
- package/src/config/settings.ts +81 -2
- package/src/dap/client.ts +37 -4
- package/src/edit/index.ts +49 -12
- package/src/eval/executor-base.ts +1 -0
- package/src/eval/js/executor.ts +2 -0
- package/src/eval/py/executor.ts +103 -33
- package/src/exec/bash-executor.ts +90 -6
- package/src/exec/direnv.ts +145 -0
- package/src/export/html/args.ts +20 -0
- package/src/export/html/index.ts +45 -47
- package/src/export/html/template.css +19 -1
- package/src/export/html/template.html +6 -0
- package/src/export/html/template.js +21 -0
- package/src/export/html/tool-views.generated.js +31 -31
- package/src/export/html/web-palette.ts +116 -132
- package/src/export/share.ts +249 -49
- package/src/extensibility/extensions/loader.ts +29 -1
- package/src/extensibility/extensions/runner.ts +6 -0
- package/src/extensibility/extensions/types.ts +33 -2
- package/src/extensibility/extensions/wrapper.ts +68 -12
- package/src/extensibility/legacy-pi-coding-agent-shim.ts +7 -1
- package/src/extensibility/plugins/legacy-pi-compat.ts +19 -1
- package/src/hindsight/state.ts +64 -6
- package/src/internal-urls/local-protocol.ts +2 -1
- package/src/internal-urls/memory-protocol.ts +2 -2
- package/src/internal-urls/skill-protocol.ts +2 -2
- package/src/internal-urls/ssh-protocol.ts +2 -1
- package/src/internal-urls/vault-protocol.ts +2 -1
- package/src/live/attestation.ts +91 -0
- package/src/live/controller.ts +517 -0
- package/src/live/prompts/agent-final-message.md +3 -0
- package/src/live/prompts/live-instructions.md +23 -0
- package/src/live/protocol.test.ts +140 -0
- package/src/live/protocol.ts +233 -0
- package/src/live/transport.ts +422 -0
- package/src/live/visualizer.ts +214 -0
- package/src/lsp/client.ts +29 -9
- package/src/lsp/index.ts +19 -4
- package/src/main.ts +8 -1
- package/src/mcp/config-writer.test.ts +43 -0
- package/src/mcp/config-writer.ts +109 -82
- package/src/mcp/oauth-discovery.ts +10 -2
- package/src/mcp/smithery-auth.test.ts +29 -0
- package/src/mcp/smithery-auth.ts +3 -2
- package/src/memories/index.ts +40 -20
- package/src/memory-backend/tool-names.ts +2 -0
- package/src/mnemopi/backend.ts +24 -7
- package/src/modes/acp/acp-agent.ts +56 -10
- package/src/modes/acp/acp-event-mapper.ts +8 -1
- package/src/modes/components/agent-hub.ts +1 -1
- package/src/modes/components/assistant-message.ts +7 -2
- package/src/modes/components/custom-message.ts +4 -1
- package/src/modes/components/login-dialog.ts +14 -4
- package/src/modes/components/message-frame.ts +14 -8
- package/src/modes/components/plan-review-overlay.ts +350 -35
- package/src/modes/components/session-account-selector.ts +62 -0
- package/src/modes/components/settings-defs.ts +23 -1
- package/src/modes/components/settings-selector.ts +169 -1
- package/src/modes/components/status-line/component.jj-cache.test.ts +229 -0
- package/src/modes/components/status-line/component.ts +123 -2
- package/src/modes/components/tool-execution.ts +28 -112
- package/src/modes/controllers/command-controller.ts +56 -15
- package/src/modes/controllers/event-controller.ts +111 -16
- package/src/modes/controllers/extension-ui-controller.test.ts +1 -0
- package/src/modes/controllers/extension-ui-controller.ts +20 -4
- package/src/modes/controllers/input-controller.ts +47 -39
- package/src/modes/controllers/live-command-controller.ts +255 -0
- package/src/modes/controllers/mcp-command-controller.ts +10 -1
- package/src/modes/controllers/omfg-controller.ts +44 -40
- package/src/modes/controllers/selector-controller.ts +80 -10
- package/src/modes/controllers/session-focus-controller.ts +6 -1
- package/src/modes/interactive-mode.ts +176 -38
- package/src/modes/runtime-init.ts +2 -0
- package/src/modes/setup-wizard/scenes/web-search.ts +17 -9
- package/src/modes/theme/theme.ts +1 -1
- package/src/modes/types.ts +4 -1
- package/src/modes/utils/context-usage.ts +23 -7
- package/src/modes/utils/ui-helpers.ts +10 -5
- package/src/plan-mode/plan-files.ts +40 -0
- package/src/prompts/bench/cache-prefix-chunk.md +1 -0
- package/src/prompts/bench/cache-prefix.md +3 -0
- package/src/prompts/bench/cache-suffix.md +1 -0
- package/src/prompts/system/computer-safety.md +14 -0
- package/src/prompts/system/custom-system-prompt.md +1 -1
- package/src/prompts/system/project-prompt.md +8 -1
- package/src/prompts/system/subagent-async-pending.md +6 -0
- package/src/prompts/system/system-prompt.md +1 -1
- package/src/prompts/system/workflow-notice.md +48 -40
- package/src/prompts/system/xdev-mount-notice.md +4 -0
- package/src/prompts/tools/computer.md +26 -0
- package/src/prompts/tools/todo.md +3 -1
- package/src/registry/agent-lifecycle.ts +116 -46
- package/src/registry/agent-registry.ts +35 -8
- package/src/registry/persisted-agents.ts +26 -2
- package/src/sdk.ts +215 -136
- package/src/secrets/index.ts +127 -4
- package/src/secrets/obfuscator.ts +2328 -105
- package/src/session/acp-permission-gate.ts +165 -0
- package/src/session/agent-session-error-log.test.ts +1 -1
- package/src/session/agent-session-events.ts +66 -0
- package/src/session/agent-session-types.ts +343 -0
- package/src/session/agent-session.ts +1940 -12218
- package/src/session/artifacts.ts +6 -5
- package/src/session/async-job-delivery.ts +74 -0
- package/src/session/auth-storage.ts +1 -0
- package/src/session/bash-runner.ts +326 -0
- package/src/session/blob-store.test.ts +56 -0
- package/src/session/blob-store.ts +18 -2
- package/src/session/checkpoint-entries.ts +81 -0
- package/src/session/eval-runner.ts +217 -0
- package/src/session/indexed-session-storage.ts +9 -2
- package/src/session/irc-bridge.ts +203 -0
- package/src/session/messages.ts +266 -1
- package/src/session/model-controls.ts +714 -0
- package/src/session/prewalk.ts +252 -0
- package/src/session/queued-messages.ts +93 -0
- package/src/session/redis-session-storage.ts +51 -11
- package/src/session/retry-fallback-chains.ts +455 -0
- package/src/session/role-models.ts +85 -0
- package/src/session/session-advisors.ts +1679 -0
- package/src/session/session-context.ts +6 -3
- package/src/session/session-entries.ts +8 -0
- package/src/session/session-handoff.ts +308 -0
- package/src/session/session-history-format.ts +20 -9
- package/src/session/session-loader.ts +0 -46
- package/src/session/session-maintenance.ts +2983 -0
- package/src/session/session-manager.ts +390 -30
- package/src/session/session-memory.ts +222 -0
- package/src/session/session-provider-boundary.ts +307 -0
- package/src/session/session-stats.ts +293 -0
- package/src/session/session-tools.ts +980 -0
- package/src/session/session-workspace.ts +53 -0
- package/src/session/stream-guards.ts +417 -0
- package/src/session/streaming-output.ts +52 -5
- package/src/session/todo-tracker.ts +380 -0
- package/src/session/ttsr-coordinator.ts +496 -0
- package/src/session/turn-recovery.ts +1629 -0
- package/src/slash-commands/builtin-registry.ts +257 -20
- package/src/slash-commands/helpers/session-pin.ts +44 -0
- package/src/slash-commands/helpers/usage-report.ts +22 -3
- package/src/stt/downloader.ts +0 -2
- package/src/stt/index.ts +0 -2
- package/src/stt/stt-controller.ts +57 -146
- package/src/system-prompt.ts +45 -17
- package/src/task/executor.ts +285 -70
- package/src/task/index.ts +98 -105
- package/src/task/output-manager.ts +25 -3
- package/src/task/persisted-revive.ts +4 -3
- package/src/task/structured-subagent.ts +1 -0
- package/src/tiny/title-client.ts +22 -0
- package/src/tools/approval.ts +55 -10
- package/src/tools/bash-interactive.ts +116 -86
- package/src/tools/bash-skill-urls.ts +28 -2
- package/src/tools/bash.ts +339 -123
- package/src/tools/browser/launch.ts +9 -1
- package/src/tools/browser/tab-supervisor.ts +8 -5
- package/src/tools/browser.ts +94 -47
- package/src/tools/builtin-names.ts +1 -0
- package/src/tools/computer/protocol.ts +28 -0
- package/src/tools/computer/supervisor.ts +258 -0
- package/src/tools/computer/worker-entry.ts +25 -0
- package/src/tools/computer/worker.ts +135 -0
- package/src/tools/computer-renderer.ts +108 -0
- package/src/tools/computer.ts +433 -0
- package/src/tools/context.ts +2 -0
- package/src/tools/default-renderer.ts +139 -0
- package/src/tools/essential-tools.ts +1 -0
- package/src/tools/image-gen.ts +20 -28
- package/src/tools/image-providers.ts +50 -0
- package/src/tools/index.ts +14 -0
- package/src/tools/path-utils.ts +49 -2
- package/src/tools/read.ts +156 -88
- package/src/tools/renderers.ts +9 -1
- package/src/tools/todo.ts +101 -11
- package/src/tools/vibe.ts +1 -2
- package/src/tools/write.ts +51 -1
- package/src/tools/xdev.ts +121 -29
- package/src/tts/streaming-player.ts +82 -283
- package/src/tts/vocalizer.ts +18 -1
- package/src/utils/clipboard.ts +1 -30
- package/src/utils/jj.ts +125 -4
- package/src/utils/lang-from-path.ts +7 -0
- package/src/utils/mac-file-urls.applescript +37 -0
- package/src/utils/title-generator.ts +137 -1
- package/src/utils/tool-choice.ts +14 -0
- package/src/utils/tools-manager.ts +1 -19
- package/src/vibe/runtime.ts +852 -72
- package/src/web/search/index.ts +3 -6
- package/src/web/search/provider.ts +31 -16
- package/src/web/search/providers/xai.ts +7 -1
- package/src/web/search/types.ts +3 -0
- package/dist/types/stt/recorder.d.ts +0 -30
- package/dist/types/stt/transcriber.d.ts +0 -14
- package/dist/types/stt/wav.d.ts +0 -29
- package/dist/types/tts/player.d.ts +0 -32
- package/src/stt/recorder.ts +0 -551
- package/src/stt/transcriber.ts +0 -60
- package/src/stt/wav.ts +0 -173
- package/src/tts/player.ts +0 -137
package/src/sdk.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type {
|
|
|
14
14
|
CredentialDisabledEvent,
|
|
15
15
|
Message,
|
|
16
16
|
Model,
|
|
17
|
+
ModelUsageHealth,
|
|
17
18
|
ProviderSessionState,
|
|
18
19
|
SimpleStreamOptions,
|
|
19
20
|
} from "@oh-my-pi/pi-ai";
|
|
@@ -32,7 +33,7 @@ import {
|
|
|
32
33
|
formatActiveRepoWatchdogPrompt,
|
|
33
34
|
formatAdvisorContextPrompt,
|
|
34
35
|
} from "./advisor";
|
|
35
|
-
import {
|
|
36
|
+
import { AsyncJobManager } from "./async";
|
|
36
37
|
import { AutoLearnController, buildAutoLearnInstructions } from "./autolearn/controller";
|
|
37
38
|
import { createAutoresearchExtension } from "./autoresearch";
|
|
38
39
|
import { loadCapability } from "./capability";
|
|
@@ -55,6 +56,7 @@ import {
|
|
|
55
56
|
resolveModelRoleValue,
|
|
56
57
|
} from "./config/model-resolver";
|
|
57
58
|
import { loadPromptTemplates as loadPromptTemplatesInternal, type PromptTemplate } from "./config/prompt-templates";
|
|
59
|
+
import { applyProviderGlobalsFromSettings } from "./config/provider-globals";
|
|
58
60
|
import { buildServiceTierByFamily } from "./config/service-tier";
|
|
59
61
|
import { Settings, type SkillsSettings } from "./config/settings";
|
|
60
62
|
import { CursorExecHandlers } from "./cursor";
|
|
@@ -105,19 +107,22 @@ import {
|
|
|
105
107
|
} from "./mcp";
|
|
106
108
|
import { MCP_CONNECTION_STATUS_EVENT_CHANNEL, type McpConnectionStatusEvent } from "./mcp/startup-events";
|
|
107
109
|
import { createSessionMemoryRuntimeContext, resolveMemoryBackend } from "./memory-backend";
|
|
110
|
+
import { MEMORY_BACKEND_TOOL_NAMES } from "./memory-backend/tool-names";
|
|
108
111
|
import type { MnemopiSessionState } from "./mnemopi/state";
|
|
109
|
-
import asyncResultTemplate from "./prompts/tools/async-result.md" with { type: "text" };
|
|
110
112
|
import lateDiagnosticTemplate from "./prompts/tools/lsp-late-diagnostic.md" with { type: "text" };
|
|
111
113
|
import { AgentLifecycleManager } from "./registry/agent-lifecycle";
|
|
112
|
-
import { AgentRegistry, MAIN_AGENT_ID } from "./registry/agent-registry";
|
|
114
|
+
import { type AgentRef, AgentRegistry, MAIN_AGENT_ID } from "./registry/agent-registry";
|
|
113
115
|
import {
|
|
114
116
|
collectEnvSecrets,
|
|
115
117
|
deobfuscateSessionContext,
|
|
116
118
|
deobfuscateToolArguments,
|
|
119
|
+
getExistingSecretPlaceholderKey,
|
|
120
|
+
getSecretPlaceholderKey,
|
|
117
121
|
loadSecrets,
|
|
118
122
|
obfuscateMessages,
|
|
119
123
|
obfuscateProviderContext,
|
|
120
124
|
SecretObfuscator,
|
|
125
|
+
secretEntriesNeedPlaceholderKey,
|
|
121
126
|
} from "./secrets";
|
|
122
127
|
import { AgentSession, type InitialRetryFallbackState, type PlanYolo, type Prewalk } from "./session/agent-session";
|
|
123
128
|
import { discoverAuthStorage as discoverAuthStorageFromConfig } from "./session/auth-broker-config";
|
|
@@ -132,6 +137,12 @@ import {
|
|
|
132
137
|
wrapSteeringForModel,
|
|
133
138
|
} from "./session/messages";
|
|
134
139
|
import { clampProviderContextImages } from "./session/provider-image-budget";
|
|
140
|
+
import {
|
|
141
|
+
expandDefaultRetryFallbackChains,
|
|
142
|
+
findRetryFallbackCandidates,
|
|
143
|
+
type RetryFallbackResolutionContext,
|
|
144
|
+
resolveRetryFallbackChainKey,
|
|
145
|
+
} from "./session/retry-fallback-chains";
|
|
135
146
|
import { getRestorableSessionModels } from "./session/session-context";
|
|
136
147
|
import { SessionManager } from "./session/session-manager";
|
|
137
148
|
import { createSettingsAwareStreamFn } from "./session/settings-stream-fn";
|
|
@@ -173,15 +184,10 @@ import {
|
|
|
173
184
|
GrepTool,
|
|
174
185
|
getSearchTools,
|
|
175
186
|
HIDDEN_TOOLS,
|
|
176
|
-
isImageProviderPreference,
|
|
177
187
|
isMountableUnderXdev,
|
|
178
|
-
isSearchProviderId,
|
|
179
|
-
isSearchProviderPreference,
|
|
180
188
|
type LspStartupServerInfo,
|
|
181
189
|
ReadTool,
|
|
182
|
-
|
|
183
|
-
setPreferredImageProvider,
|
|
184
|
-
setPreferredSearchProvider,
|
|
190
|
+
releaseComputerSessionsForOwner,
|
|
185
191
|
type Tool,
|
|
186
192
|
type ToolSession,
|
|
187
193
|
WebSearchTool,
|
|
@@ -199,62 +205,14 @@ import { ttsTool } from "./tools/tts";
|
|
|
199
205
|
import { resolveActiveRepoContext } from "./utils/active-repo-context";
|
|
200
206
|
import { EventBus } from "./utils/event-bus";
|
|
201
207
|
import { buildNamedToolChoice } from "./utils/tool-choice";
|
|
208
|
+
import { VibeSessionRegistry } from "./vibe/runtime";
|
|
202
209
|
import { buildWorkspaceTree, type WorkspaceTree } from "./workspace-tree";
|
|
203
210
|
|
|
204
|
-
type AsyncResultEntry = {
|
|
205
|
-
jobId: string;
|
|
206
|
-
result: string;
|
|
207
|
-
job: AsyncJob | undefined;
|
|
208
|
-
durationMs: number | undefined;
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
type AsyncResultJobDetails = {
|
|
212
|
-
jobId: string;
|
|
213
|
-
type?: "bash" | "task";
|
|
214
|
-
label?: string;
|
|
215
|
-
durationMs?: number;
|
|
216
|
-
};
|
|
217
|
-
|
|
218
|
-
type AsyncResultDetails = {
|
|
219
|
-
jobs: AsyncResultJobDetails[];
|
|
220
|
-
};
|
|
221
|
-
|
|
222
211
|
type McpNotificationEntry = {
|
|
223
212
|
serverName: string;
|
|
224
213
|
uri: string;
|
|
225
214
|
};
|
|
226
215
|
|
|
227
|
-
function buildAsyncResultBatchMessage(entries: AsyncResultEntry[]): CustomMessage<AsyncResultDetails> | null {
|
|
228
|
-
if (entries.length === 0) return null;
|
|
229
|
-
const jobs = entries.map(entry => ({
|
|
230
|
-
jobId: entry.jobId,
|
|
231
|
-
result: entry.result,
|
|
232
|
-
type: entry.job?.type,
|
|
233
|
-
label: entry.job?.label,
|
|
234
|
-
durationMs: entry.durationMs,
|
|
235
|
-
}));
|
|
236
|
-
const details: AsyncResultDetails = {
|
|
237
|
-
jobs: jobs.map(job => ({
|
|
238
|
-
jobId: job.jobId,
|
|
239
|
-
type: job.type,
|
|
240
|
-
label: job.label,
|
|
241
|
-
durationMs: job.durationMs,
|
|
242
|
-
})),
|
|
243
|
-
};
|
|
244
|
-
return {
|
|
245
|
-
role: "custom",
|
|
246
|
-
customType: "async-result",
|
|
247
|
-
content: prompt.render(asyncResultTemplate, {
|
|
248
|
-
multiple: jobs.length > 1,
|
|
249
|
-
jobs,
|
|
250
|
-
}),
|
|
251
|
-
display: true,
|
|
252
|
-
attribution: "agent",
|
|
253
|
-
details,
|
|
254
|
-
timestamp: Date.now(),
|
|
255
|
-
};
|
|
256
|
-
}
|
|
257
|
-
|
|
258
216
|
type LateDiagnosticsDetails = {
|
|
259
217
|
files: Array<{ path: string; summary: string; errored: boolean; messages: string[] }>;
|
|
260
218
|
};
|
|
@@ -371,6 +329,8 @@ function applyMCPEnvironment(result: { exaApiKeys: string[] }): void {
|
|
|
371
329
|
export interface CreateAgentSessionOptions {
|
|
372
330
|
/** Working directory for project-local discovery. Default: getProjectDir() */
|
|
373
331
|
cwd?: string;
|
|
332
|
+
/** Additional workspace directories beyond cwd (multi-root), absolute or cwd-relative. */
|
|
333
|
+
additionalDirectories?: string[];
|
|
374
334
|
/** Global config directory. Default: ~/.omp/agent */
|
|
375
335
|
agentDir?: string;
|
|
376
336
|
/** Spawns to allow. Default: "*" */
|
|
@@ -525,6 +485,13 @@ export interface CreateAgentSessionOptions {
|
|
|
525
485
|
agentDisplayName?: string;
|
|
526
486
|
/** Optional shared agent registry for IRC routing. Default: AgentRegistry.global(). */
|
|
527
487
|
agentRegistry?: AgentRegistry;
|
|
488
|
+
/**
|
|
489
|
+
* Registry generation authorized for this creation. `null` requires the id
|
|
490
|
+
* to be absent; an AgentRef allows a parked revival to reuse only that ref.
|
|
491
|
+
* Undefined preserves legacy unconditional registration for external SDK callers.
|
|
492
|
+
* @internal
|
|
493
|
+
*/
|
|
494
|
+
expectedAgentRef?: AgentRef | null;
|
|
528
495
|
/** Parent task ID prefix for nested artifact naming (e.g., "Extensions") */
|
|
529
496
|
parentTaskPrefix?: string;
|
|
530
497
|
/**
|
|
@@ -554,6 +521,11 @@ export interface CreateAgentSessionOptions {
|
|
|
554
521
|
|
|
555
522
|
/** Whether UI is available (enables interactive tools like ask). Default: false */
|
|
556
523
|
hasUI?: boolean;
|
|
524
|
+
/**
|
|
525
|
+
* Defer `confirm` reserve-policy fallback until AgentSession prompt-time UI is configured.
|
|
526
|
+
* ACP uses this while capabilities are negotiated without enabling UI-only tools.
|
|
527
|
+
*/
|
|
528
|
+
deferUsageReserveConfirmation?: boolean;
|
|
557
529
|
|
|
558
530
|
/**
|
|
559
531
|
* Opt-in OpenTelemetry instrumentation forwarded to the underlying Agent.
|
|
@@ -1292,26 +1264,22 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1292
1264
|
discoveredSkillsPromise?.catch(() => {});
|
|
1293
1265
|
|
|
1294
1266
|
// Initialize provider preferences from settings
|
|
1295
|
-
|
|
1296
|
-
if (Array.isArray(excludedWebSearchProviders)) {
|
|
1297
|
-
setExcludedSearchProviders(excludedWebSearchProviders.filter(isSearchProviderId));
|
|
1298
|
-
}
|
|
1299
|
-
|
|
1300
|
-
const webSearchProvider = settings.get("providers.webSearch");
|
|
1301
|
-
if (typeof webSearchProvider === "string" && isSearchProviderPreference(webSearchProvider)) {
|
|
1302
|
-
setPreferredSearchProvider(webSearchProvider);
|
|
1303
|
-
}
|
|
1304
|
-
|
|
1305
|
-
const imageProvider = settings.get("providers.image");
|
|
1306
|
-
if (isImageProviderPreference(imageProvider)) {
|
|
1307
|
-
setPreferredImageProvider(imageProvider);
|
|
1308
|
-
}
|
|
1267
|
+
applyProviderGlobalsFromSettings(settings);
|
|
1309
1268
|
|
|
1310
1269
|
const sessionManager =
|
|
1311
1270
|
options.sessionManager ??
|
|
1312
1271
|
logger.time("sessionManager", () =>
|
|
1313
1272
|
SessionManager.create(cwd, SessionManager.getDefaultSessionDir(cwd, agentDir)),
|
|
1314
1273
|
);
|
|
1274
|
+
const configuredDirs = options.additionalDirectories
|
|
1275
|
+
? options.additionalDirectories
|
|
1276
|
+
: settings.get("workspace.additionalDirectories");
|
|
1277
|
+
if (configuredDirs.length > 0) {
|
|
1278
|
+
// Merge with any roots restored from the session header (resume/fork), not replace.
|
|
1279
|
+
const existing = sessionManager.getAdditionalDirectories();
|
|
1280
|
+
const merged = [...new Set([...existing, ...configuredDirs])];
|
|
1281
|
+
await sessionManager.setAdditionalDirectories(merged);
|
|
1282
|
+
}
|
|
1315
1283
|
const providerSessionId = options.providerSessionId ?? sessionManager.getSessionId();
|
|
1316
1284
|
const forkCacheShapeChanged =
|
|
1317
1285
|
options.model !== undefined ||
|
|
@@ -1349,8 +1317,30 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1349
1317
|
const fileEntries = await logger.time("loadSecrets", loadSecrets, cwd, agentDir);
|
|
1350
1318
|
const envEntries = collectEnvSecrets();
|
|
1351
1319
|
const allEntries = [...envEntries, ...fileEntries];
|
|
1320
|
+
const needsPlaceholderKey = secretEntriesNeedPlaceholderKey(allEntries);
|
|
1321
|
+
const placeholderKey = needsPlaceholderKey
|
|
1322
|
+
? await getSecretPlaceholderKey(agentDir)
|
|
1323
|
+
: await getExistingSecretPlaceholderKey(agentDir);
|
|
1352
1324
|
if (allEntries.length > 0) {
|
|
1353
|
-
|
|
1325
|
+
// The persisted placeholder key — and creating its key file under the
|
|
1326
|
+
// configured agentDir — is only needed for reversible obfuscate-mode
|
|
1327
|
+
// placeholders, or for a default (no custom `replacement`) replace-mode
|
|
1328
|
+
// regex whose key-derived idempotent fallback marker needs a stable key
|
|
1329
|
+
// across restarts (see `secretEntryNeedsPlaceholderKey`). A replace-only
|
|
1330
|
+
// secrets set with no such regex must not require the key; otherwise a
|
|
1331
|
+
// headless run with an unwritable default config root fails startup for a
|
|
1332
|
+
// feature it does not use.
|
|
1333
|
+
obfuscator = new SecretObfuscator(allEntries, placeholderKey);
|
|
1334
|
+
}
|
|
1335
|
+
if (obfuscator?.hasSecrets() !== true && placeholderKey !== undefined) {
|
|
1336
|
+
// No configured entry produced an active secret (e.g. only ignored short
|
|
1337
|
+
// plain entries, or no entries at all), but a persisted key exists. Build a
|
|
1338
|
+
// redaction-only obfuscator so a tool read of the key file does not ship the
|
|
1339
|
+
// reusable HMAC key to the provider.
|
|
1340
|
+
obfuscator = new SecretObfuscator(
|
|
1341
|
+
[{ type: "plain", mode: "replace", content: placeholderKey }],
|
|
1342
|
+
placeholderKey,
|
|
1343
|
+
);
|
|
1354
1344
|
}
|
|
1355
1345
|
}
|
|
1356
1346
|
const secretsEnabled = obfuscator?.hasSecrets() === true;
|
|
@@ -1566,28 +1556,6 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1566
1556
|
const restrictToolNames = options.restrictToolNames === true;
|
|
1567
1557
|
const enableLsp = !restrictToolNames && (options.enableLsp ?? true);
|
|
1568
1558
|
const asyncMaxJobs = Math.min(100, Math.max(1, settings.get("async.maxJobs") ?? 100));
|
|
1569
|
-
const ASYNC_INLINE_RESULT_MAX_CHARS = 12_000;
|
|
1570
|
-
const ASYNC_PREVIEW_MAX_CHARS = 4_000;
|
|
1571
|
-
const formatAsyncResultForFollowUp = async (result: string): Promise<string> => {
|
|
1572
|
-
if (result.length <= ASYNC_INLINE_RESULT_MAX_CHARS) {
|
|
1573
|
-
return result;
|
|
1574
|
-
}
|
|
1575
|
-
|
|
1576
|
-
const preview = `${result.slice(0, ASYNC_PREVIEW_MAX_CHARS)}\n\n[Output truncated. Showing first ${ASYNC_PREVIEW_MAX_CHARS.toLocaleString()} characters.]`;
|
|
1577
|
-
try {
|
|
1578
|
-
const { path: artifactPath, id: artifactId } = await sessionManager.allocateArtifactPath("async");
|
|
1579
|
-
if (artifactPath && artifactId) {
|
|
1580
|
-
await Bun.write(artifactPath, result);
|
|
1581
|
-
return `${preview}\nFull output: artifact://${artifactId}`;
|
|
1582
|
-
}
|
|
1583
|
-
} catch (error) {
|
|
1584
|
-
logger.warn("Failed to persist async follow-up artifact", {
|
|
1585
|
-
error: error instanceof Error ? error.message : String(error),
|
|
1586
|
-
});
|
|
1587
|
-
}
|
|
1588
|
-
|
|
1589
|
-
return preview;
|
|
1590
|
-
};
|
|
1591
1559
|
// Only the first top-level session in a process owns an AsyncJobManager.
|
|
1592
1560
|
// Subagents inherit the parent's manager via `AsyncJobManager.instance()`
|
|
1593
1561
|
// (set below), and any additional top-level session spun up in-process
|
|
@@ -1596,24 +1564,12 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1596
1564
|
// owning session's manager and break the `task`/`bash` async paths
|
|
1597
1565
|
// (issue #1923). The `instance()` guard means later sessions also skip
|
|
1598
1566
|
// constructing an orphaned manager that nothing would ever route to.
|
|
1567
|
+
// Delivery is owner-routed: every AgentSession registers its own sink
|
|
1568
|
+
// (see session/async-job-delivery.ts), so the manager takes no default
|
|
1569
|
+
// onJobComplete here.
|
|
1599
1570
|
const asyncJobManager =
|
|
1600
1571
|
!options.parentTaskPrefix && !AsyncJobManager.instance()
|
|
1601
|
-
? new AsyncJobManager({
|
|
1602
|
-
maxRunningJobs: asyncMaxJobs,
|
|
1603
|
-
onJobComplete: async (jobId, result, job) => {
|
|
1604
|
-
if (!session || asyncJobManager!.isDeliverySuppressed(jobId)) return;
|
|
1605
|
-
const formattedResult = await formatAsyncResultForFollowUp(result);
|
|
1606
|
-
if (asyncJobManager!.isDeliverySuppressed(jobId)) return;
|
|
1607
|
-
|
|
1608
|
-
const durationMs = job ? Math.max(0, Date.now() - job.startTime) : undefined;
|
|
1609
|
-
session.yieldQueue.enqueue<AsyncResultEntry>("async-result", {
|
|
1610
|
-
jobId,
|
|
1611
|
-
result: formattedResult,
|
|
1612
|
-
job,
|
|
1613
|
-
durationMs,
|
|
1614
|
-
});
|
|
1615
|
-
},
|
|
1616
|
-
})
|
|
1572
|
+
? new AsyncJobManager({ maxRunningJobs: asyncMaxJobs })
|
|
1617
1573
|
: undefined;
|
|
1618
1574
|
|
|
1619
1575
|
const scopedAsyncJobManager = asyncJobManager ?? (options.parentTaskPrefix ? AsyncJobManager.instance() : undefined);
|
|
@@ -1623,15 +1579,18 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1623
1579
|
const resolvedAgentDisplayName =
|
|
1624
1580
|
options.agentDisplayName ?? ((options.taskDepth ?? 0) > 0 || options.parentTaskPrefix ? "sub" : "main");
|
|
1625
1581
|
const agentKind = (options.taskDepth ?? 0) > 0 || options.parentTaskPrefix ? ("sub" as const) : ("main" as const);
|
|
1582
|
+
let registeredAgentRef: AgentRef | undefined;
|
|
1626
1583
|
/**
|
|
1627
1584
|
* Forget the agent ref on teardown — unless the agent is being parked (or is
|
|
1628
1585
|
* already parked). Parking disposes the session but keeps the ref addressable
|
|
1629
1586
|
* (history://, revive); only process teardown / explicit kill unregisters.
|
|
1630
1587
|
*/
|
|
1631
1588
|
const unregisterUnlessParked = (): void => {
|
|
1632
|
-
|
|
1633
|
-
if (
|
|
1634
|
-
|
|
1589
|
+
const ref = registeredAgentRef;
|
|
1590
|
+
if (!ref || agentRegistry.get(resolvedAgentId) !== ref) return;
|
|
1591
|
+
if (ref.status === "parked") return;
|
|
1592
|
+
if (AgentLifecycleManager.global().isParking(resolvedAgentId, ref)) return;
|
|
1593
|
+
agentRegistry.unregister(resolvedAgentId, ref);
|
|
1635
1594
|
};
|
|
1636
1595
|
const evalKernelOwnerId = `agent-session:${Snowflake.next()}`;
|
|
1637
1596
|
|
|
@@ -1660,6 +1619,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1660
1619
|
isToolActive: name => activeToolNames.has(name),
|
|
1661
1620
|
setActiveToolNames,
|
|
1662
1621
|
hasUI: options.hasUI ?? false,
|
|
1622
|
+
get additionalDirectories() {
|
|
1623
|
+
return sessionManager.getAdditionalDirectories();
|
|
1624
|
+
},
|
|
1663
1625
|
enableLsp,
|
|
1664
1626
|
enableIrc: restrictToolNames ? false : options.enableIrc,
|
|
1665
1627
|
restrictToolNames,
|
|
@@ -1684,6 +1646,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1684
1646
|
prewalkArmed: options.prewalk !== undefined,
|
|
1685
1647
|
taskDepth: options.taskDepth ?? 0,
|
|
1686
1648
|
getSessionFile: () => sessionManager.getSessionFile() ?? null,
|
|
1649
|
+
sessionManager,
|
|
1687
1650
|
getEvalKernelOwnerId: () => evalKernelOwnerId,
|
|
1688
1651
|
getEvalSessionId: () =>
|
|
1689
1652
|
session?.getEvalSessionId() ?? options.parentEvalSessionId ?? defaultEvalSessionId(toolSession),
|
|
@@ -2141,27 +2104,38 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2141
2104
|
if (!resolved.configuredRole || !settings.get("retry.modelFallback")) {
|
|
2142
2105
|
return primaryPatterns;
|
|
2143
2106
|
}
|
|
2144
|
-
const
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2107
|
+
const fallbackContext: RetryFallbackResolutionContext = {
|
|
2108
|
+
chains: expandDefaultRetryFallbackChains(settings.get("retry.fallbackChains"), [
|
|
2109
|
+
...Object.keys(settings.getModelRoles()),
|
|
2110
|
+
resolved.configuredRole,
|
|
2111
|
+
]),
|
|
2112
|
+
getModelRole: role => settings.getModelRole(role),
|
|
2113
|
+
modelLookup: modelRegistry,
|
|
2114
|
+
};
|
|
2149
2115
|
const originalSelector = resolved.configuredPatterns[0];
|
|
2116
|
+
const originalModel = parseModelPattern(originalSelector, availableModels, matchPreferences).model;
|
|
2117
|
+
const chainKey = resolveRetryFallbackChainKey(
|
|
2118
|
+
fallbackContext,
|
|
2119
|
+
originalSelector,
|
|
2120
|
+
originalModel,
|
|
2121
|
+
resolved.configuredRole,
|
|
2122
|
+
);
|
|
2123
|
+
if (!chainKey) return primaryPatterns;
|
|
2150
2124
|
const parsedOriginal = parseModelString(originalSelector, {
|
|
2151
2125
|
allowMaxSuffix: true,
|
|
2152
2126
|
allowAutoAlias: true,
|
|
2153
2127
|
isLiteralModelId: (provider, id) => modelRegistry.find(provider, id) !== undefined,
|
|
2154
2128
|
});
|
|
2155
2129
|
const retryFallback: InitialRetryFallbackState = {
|
|
2156
|
-
role:
|
|
2130
|
+
role: chainKey,
|
|
2157
2131
|
originalSelector,
|
|
2158
2132
|
originalThinkingLevel: parsedOriginal?.thinkingLevel,
|
|
2159
2133
|
};
|
|
2160
2134
|
return [
|
|
2161
2135
|
...primaryPatterns,
|
|
2162
|
-
...
|
|
2163
|
-
|
|
2164
|
-
|
|
2136
|
+
...findRetryFallbackCandidates(fallbackContext, chainKey, originalSelector, originalModel, {
|
|
2137
|
+
allowMissingPrimary: true,
|
|
2138
|
+
}).map(candidate => ({ pattern: candidate.raw, retryFallback })),
|
|
2165
2139
|
];
|
|
2166
2140
|
}
|
|
2167
2141
|
if (resolved.model) {
|
|
@@ -2181,10 +2155,68 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2181
2155
|
}));
|
|
2182
2156
|
}),
|
|
2183
2157
|
);
|
|
2158
|
+
let usageFallbackTriggered = false;
|
|
2184
2159
|
for (let patternIndex = 0; patternIndex < expandedModelPatterns.length; patternIndex += 1) {
|
|
2185
2160
|
const { pattern, retryFallback } = expandedModelPatterns[patternIndex];
|
|
2186
2161
|
const primary = parseModelPattern(pattern, availableModels, matchPreferences);
|
|
2187
2162
|
if (!primary.model || (retryFallback && !hasModelAuth(primary.model))) continue;
|
|
2163
|
+
let hasUsageFallbackCandidate = false;
|
|
2164
|
+
for (
|
|
2165
|
+
let candidateIndex = patternIndex + 1;
|
|
2166
|
+
candidateIndex < expandedModelPatterns.length;
|
|
2167
|
+
candidateIndex += 1
|
|
2168
|
+
) {
|
|
2169
|
+
const candidate = parseModelPattern(
|
|
2170
|
+
expandedModelPatterns[candidateIndex].pattern,
|
|
2171
|
+
availableModels,
|
|
2172
|
+
matchPreferences,
|
|
2173
|
+
);
|
|
2174
|
+
if (candidate.model && hasModelAuth(candidate.model)) {
|
|
2175
|
+
hasUsageFallbackCandidate = true;
|
|
2176
|
+
break;
|
|
2177
|
+
}
|
|
2178
|
+
}
|
|
2179
|
+
const usageReservePolicy = settings.get("retry.usageReservePolicy");
|
|
2180
|
+
if (
|
|
2181
|
+
(hasUsageFallbackCandidate || usageReservePolicy === "fail-closed") &&
|
|
2182
|
+
settings.get("retry.modelFallback") &&
|
|
2183
|
+
settings.get("retry.usageAwareFallback")
|
|
2184
|
+
) {
|
|
2185
|
+
let usageHealth: ModelUsageHealth | undefined;
|
|
2186
|
+
try {
|
|
2187
|
+
usageHealth = await modelRegistry.authStorage.getModelUsageHealth(primary.model.provider, {
|
|
2188
|
+
modelId: primary.model.id,
|
|
2189
|
+
baseUrl: primary.model.baseUrl,
|
|
2190
|
+
reserveFraction: settings.get("retry.usageReservePct") / 100,
|
|
2191
|
+
});
|
|
2192
|
+
} catch (error) {
|
|
2193
|
+
logger.debug("Usage-aware model preflight failed open", {
|
|
2194
|
+
provider: primary.model.provider,
|
|
2195
|
+
model: primary.model.id,
|
|
2196
|
+
error: String(error),
|
|
2197
|
+
});
|
|
2198
|
+
}
|
|
2199
|
+
if (usageHealth?.state === "depleted") {
|
|
2200
|
+
if (usageReservePolicy === "fail-closed") {
|
|
2201
|
+
throw new Error(
|
|
2202
|
+
`Usage depleted for ${primary.model.provider}/${primary.model.id}; reserve policy is fail-closed.`,
|
|
2203
|
+
);
|
|
2204
|
+
}
|
|
2205
|
+
usageFallbackTriggered = true;
|
|
2206
|
+
continue;
|
|
2207
|
+
}
|
|
2208
|
+
if (usageHealth?.state === "reserve") {
|
|
2209
|
+
if (usageReservePolicy === "fail-closed") {
|
|
2210
|
+
throw new Error(
|
|
2211
|
+
`Usage reserve reached for ${primary.model.provider}/${primary.model.id}; reserve policy is fail-closed.`,
|
|
2212
|
+
);
|
|
2213
|
+
}
|
|
2214
|
+
if (usageReservePolicy === "auto" || (!options.hasUI && !options.deferUsageReserveConfirmation)) {
|
|
2215
|
+
usageFallbackTriggered = true;
|
|
2216
|
+
continue;
|
|
2217
|
+
}
|
|
2218
|
+
}
|
|
2219
|
+
}
|
|
2188
2220
|
let selectedModel = primary.model;
|
|
2189
2221
|
let selectedThinkingLevel = primary.thinkingLevel;
|
|
2190
2222
|
let selectedExplicitThinkingLevel = primary.explicitThinkingLevel;
|
|
@@ -2264,7 +2296,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2264
2296
|
}
|
|
2265
2297
|
}
|
|
2266
2298
|
model = selectedModel;
|
|
2267
|
-
initialRetryFallback =
|
|
2299
|
+
initialRetryFallback =
|
|
2300
|
+
retryFallback && usageFallbackTriggered ? { ...retryFallback, pinned: true } : retryFallback;
|
|
2268
2301
|
modelFallbackMessage = undefined;
|
|
2269
2302
|
if (selectedExplicitThinkingLevel) {
|
|
2270
2303
|
restoredSessionThinkingLevel = selectedThinkingLevel;
|
|
@@ -2644,8 +2677,13 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2644
2677
|
}
|
|
2645
2678
|
const defaultPrompt = await buildSystemPromptInternal({
|
|
2646
2679
|
cwd,
|
|
2680
|
+
additionalWorkspaceRoots: sessionManager.getAdditionalDirectories(),
|
|
2647
2681
|
xdevTools: toolSession.xdevRegistry?.entries() ?? [],
|
|
2648
|
-
xdevDocs:
|
|
2682
|
+
xdevDocs:
|
|
2683
|
+
toolSession.xdevRegistry?.docsAll(
|
|
2684
|
+
settings.get("tools.xdevDocs"),
|
|
2685
|
+
settings.get("tools.xdevInlineDevices"),
|
|
2686
|
+
) ?? "",
|
|
2649
2687
|
autoQaEnabled: !restrictToolNames && isAutoQaEnabled(settings),
|
|
2650
2688
|
resolvedCustomPrompt: options.customSystemPrompt,
|
|
2651
2689
|
skills: session?.skills ?? skills,
|
|
@@ -2750,16 +2788,25 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2750
2788
|
// so that subagents launched in the same parallel batch can see each other in
|
|
2751
2789
|
// their initial `# IRC Peers` block (rendered inside `rebuildSystemPrompt`).
|
|
2752
2790
|
// The session reference is attached after construction below.
|
|
2753
|
-
|
|
2791
|
+
const registrationInput = {
|
|
2754
2792
|
id: resolvedAgentId,
|
|
2755
2793
|
displayName: resolvedAgentDisplayName,
|
|
2756
2794
|
kind: agentKind,
|
|
2757
2795
|
parentId: options.parentAgentId,
|
|
2758
2796
|
session: null,
|
|
2759
2797
|
sessionFile: sessionManager.getSessionFile() ?? null,
|
|
2760
|
-
status: "running",
|
|
2761
|
-
}
|
|
2762
|
-
|
|
2798
|
+
status: "running" as const,
|
|
2799
|
+
};
|
|
2800
|
+
registeredAgentRef =
|
|
2801
|
+
options.expectedAgentRef === undefined
|
|
2802
|
+
? agentRegistry.register(registrationInput)
|
|
2803
|
+
: agentRegistry.registerIfAvailable(registrationInput, options.expectedAgentRef);
|
|
2804
|
+
if (!registeredAgentRef) {
|
|
2805
|
+
throw new Error(`Agent "${resolvedAgentId}" is already owned by another session generation.`);
|
|
2806
|
+
}
|
|
2807
|
+
// A reused parked ref remains parked until the new AgentSession is fully
|
|
2808
|
+
// constructed and attached. Startup failure therefore leaves it revivable.
|
|
2809
|
+
hasRegistered = options.expectedAgentRef === undefined || options.expectedAgentRef === null;
|
|
2763
2810
|
|
|
2764
2811
|
// Partition the initial enabled set for the xd:// transport: ambient
|
|
2765
2812
|
// discoverable tools become mounted devices, while explicitly requested
|
|
@@ -3070,6 +3117,19 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
3070
3117
|
skillsSettings: settings.getGroup("skills"),
|
|
3071
3118
|
modelRegistry,
|
|
3072
3119
|
toolRegistry,
|
|
3120
|
+
memoryAgentDir: agentDir,
|
|
3121
|
+
memoryTaskDepth: taskDepth,
|
|
3122
|
+
createMemoryTools: restrictToolNames
|
|
3123
|
+
? undefined
|
|
3124
|
+
: async () => {
|
|
3125
|
+
const tools = await Promise.all(
|
|
3126
|
+
MEMORY_BACKEND_TOOL_NAMES.map(name => BUILTIN_TOOLS[name](toolSession)),
|
|
3127
|
+
);
|
|
3128
|
+
return tools.filter((tool): tool is AgentTool => tool !== null);
|
|
3129
|
+
},
|
|
3130
|
+
createComputerTool: restrictToolNames
|
|
3131
|
+
? undefined
|
|
3132
|
+
: async () => (await BUILTIN_TOOLS.computer(toolSession)) ?? null,
|
|
3073
3133
|
createVibeTools:
|
|
3074
3134
|
(options.taskDepth ?? 0) === 0 && !options.parentTaskPrefix
|
|
3075
3135
|
? () => createVibeTools(toolSession)
|
|
@@ -3116,12 +3176,6 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
3116
3176
|
titleSystemPrompt: options.titleSystemPrompt,
|
|
3117
3177
|
});
|
|
3118
3178
|
hasSession = true;
|
|
3119
|
-
if (asyncJobManager) {
|
|
3120
|
-
session.yieldQueue.register<AsyncResultEntry>("async-result", {
|
|
3121
|
-
isStale: entry => asyncJobManager.isDeliverySuppressed(entry.jobId),
|
|
3122
|
-
build: buildAsyncResultBatchMessage,
|
|
3123
|
-
});
|
|
3124
|
-
}
|
|
3125
3179
|
session.yieldQueue.register<McpNotificationEntry>("mcp-notification", {
|
|
3126
3180
|
build: buildMcpNotificationBatchMessage,
|
|
3127
3181
|
});
|
|
@@ -3133,7 +3187,19 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
3133
3187
|
// Attach the live session to the pre-registered ref so peers can route IRC
|
|
3134
3188
|
// messages here. Refresh sessionFile in case it was unavailable at pre-register
|
|
3135
3189
|
// time. The dispose wrapper below unregisters on teardown (unless parked).
|
|
3136
|
-
|
|
3190
|
+
if (
|
|
3191
|
+
!registeredAgentRef ||
|
|
3192
|
+
!agentRegistry.attachSession(
|
|
3193
|
+
resolvedAgentId,
|
|
3194
|
+
session,
|
|
3195
|
+
sessionManager.getSessionFile() ?? null,
|
|
3196
|
+
registeredAgentRef,
|
|
3197
|
+
) ||
|
|
3198
|
+
!agentRegistry.setStatus(resolvedAgentId, "running", registeredAgentRef)
|
|
3199
|
+
) {
|
|
3200
|
+
throw new Error(`Agent "${resolvedAgentId}" was replaced during session initialization.`);
|
|
3201
|
+
}
|
|
3202
|
+
hasRegistered = true;
|
|
3137
3203
|
{
|
|
3138
3204
|
const originalDispose = session.dispose.bind(session);
|
|
3139
3205
|
session.dispose = async () => {
|
|
@@ -3147,6 +3213,17 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
3147
3213
|
// adopted subagent sessions, revivers. Tear it down while shared
|
|
3148
3214
|
// resources (kernels, MCP, LSP) are still live. Subagent disposal
|
|
3149
3215
|
// must NOT touch the global lifecycle.
|
|
3216
|
+
const vibeRegistry = VibeSessionRegistry.global();
|
|
3217
|
+
const vibeParentSession = {
|
|
3218
|
+
getAgentId: () => resolvedAgentId,
|
|
3219
|
+
getSessionId: () => sessionManager.getSessionId(),
|
|
3220
|
+
getSessionFile: () => sessionManager.getSessionFile() ?? null,
|
|
3221
|
+
sessionManager,
|
|
3222
|
+
asyncJobManager: scopedAsyncJobManager,
|
|
3223
|
+
settings,
|
|
3224
|
+
getActiveModelString,
|
|
3225
|
+
};
|
|
3226
|
+
await vibeRegistry.suspendScope(vibeRegistry.ownerScope(vibeParentSession), scopedAsyncJobManager);
|
|
3150
3227
|
await AgentLifecycleManager.global().dispose();
|
|
3151
3228
|
}
|
|
3152
3229
|
await originalDispose();
|
|
@@ -3388,6 +3465,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
3388
3465
|
try {
|
|
3389
3466
|
if (hasSession) {
|
|
3390
3467
|
await session.dispose();
|
|
3468
|
+
if (hasRegistered) unregisterUnlessParked();
|
|
3391
3469
|
} else {
|
|
3392
3470
|
if (hasRegistered) unregisterUnlessParked();
|
|
3393
3471
|
if (asyncJobManager) {
|
|
@@ -3396,6 +3474,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
3396
3474
|
}
|
|
3397
3475
|
await asyncJobManager.dispose({ timeoutMs: 3_000 });
|
|
3398
3476
|
}
|
|
3477
|
+
await releaseComputerSessionsForOwner(evalKernelOwnerId);
|
|
3399
3478
|
await disposeKernelSessionsByOwner(evalKernelOwnerId);
|
|
3400
3479
|
await disposeRubyKernelSessionsByOwner(evalKernelOwnerId);
|
|
3401
3480
|
await disposeJuliaKernelSessionsByOwner(evalKernelOwnerId);
|