@gajae-code/coding-agent 0.12.11 → 0.12.13
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 +68 -0
- package/dist/types/cli/marketplace-hint.d.ts +28 -0
- package/dist/types/cli/notify-cli.d.ts +42 -1
- package/dist/types/cli/update-cli.d.ts +9 -3
- package/dist/types/cli.d.ts +10 -0
- package/dist/types/commands/notify.d.ts +6 -0
- package/dist/types/config/file-lock-gc.d.ts +13 -1
- package/dist/types/config/file-lock.d.ts +3 -0
- package/dist/types/config/model-registry.d.ts +6 -0
- package/dist/types/config/models-config-schema.d.ts +99 -0
- package/dist/types/coordinator/contract.d.ts +1 -1
- package/dist/types/coordinator-mcp/question-state.d.ts +3 -1
- package/dist/types/extensibility/extensions/index.d.ts +1 -0
- package/dist/types/extensibility/extensions/ouroboros-ooo-bridge.d.ts +13 -0
- package/dist/types/extensibility/extensions/prefix-command-bridge.d.ts +0 -1
- package/dist/types/extensibility/extensions/types.d.ts +2 -0
- package/dist/types/gjc-runtime/deep-interview-state.d.ts +14 -0
- package/dist/types/gjc-runtime/gc-runtime.d.ts +11 -0
- package/dist/types/main.d.ts +6 -2
- package/dist/types/modes/acp/acp-agent.d.ts +24 -1
- package/dist/types/modes/components/session-selector.d.ts +1 -1
- package/dist/types/modes/utils/host-status.d.ts +23 -0
- package/dist/types/runtime-mcp/types.d.ts +2 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +12 -0
- package/dist/types/sdk/bus/chat-daemon-cli.d.ts +3 -0
- package/dist/types/sdk/bus/chat-daemon-command-channel.d.ts +244 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +11 -1
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +7 -0
- package/dist/types/sdk/bus/control-plane-frames.d.ts +43 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +18 -0
- package/dist/types/sdk/bus/existing-thread-readiness.d.ts +71 -0
- package/dist/types/sdk/bus/html-format.d.ts +10 -0
- package/dist/types/sdk/bus/notification-service.d.ts +10 -0
- package/dist/types/sdk/bus/slack-daemon.d.ts +27 -0
- package/dist/types/sdk/bus/slack-live-provider.d.ts +11 -0
- package/dist/types/sdk/bus/slack-provider.d.ts +14 -0
- package/dist/types/sdk/bus/slack-thread-binding.d.ts +140 -0
- package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +2 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +28 -7
- package/dist/types/sdk/bus/telegram-daemon.d.ts +119 -17
- package/dist/types/sdk/bus/telegram-reference.d.ts +20 -1
- package/dist/types/sdk/bus/topic-registry.d.ts +130 -85
- package/dist/types/sdk/host/host.d.ts +52 -0
- package/dist/types/sdk/lifecycle-session.d.ts +6 -0
- package/dist/types/sdk/session-activation.d.ts +41 -0
- package/dist/types/sdk/session.d.ts +18 -0
- package/dist/types/sdk/startup-capability.d.ts +8 -1
- package/dist/types/session/agent-session.d.ts +7 -2
- package/dist/types/session/artifacts.d.ts +2 -2
- package/dist/types/session/session-manager.d.ts +40 -6
- package/dist/types/tools/index.d.ts +15 -0
- package/dist/types/utils/npm-registry.d.ts +71 -0
- package/examples/extensions/README.md +38 -4
- package/examples/extensions/ooo-bridge.ts +15 -0
- package/package.json +8 -8
- package/scripts/generate-sdk-operation-inventory.ts +4 -0
- package/src/async/job-manager.ts +9 -2
- package/src/cli/fast-help.ts +1 -0
- package/src/cli/marketplace-hint.ts +39 -0
- package/src/cli/notify-cli.ts +226 -2
- package/src/cli/plugin-cli.ts +10 -0
- package/src/cli/update-cli.ts +90 -23
- package/src/cli.ts +23 -0
- package/src/commands/notify.ts +27 -3
- package/src/commands/sdk.ts +1 -0
- package/src/config/file-lock-gc.ts +65 -26
- package/src/config/file-lock.ts +61 -16
- package/src/config/model-profiles.ts +46 -30
- package/src/config/model-registry.ts +17 -5
- package/src/config/models-config-schema.ts +9 -4
- package/src/coordinator/contract.ts +1 -0
- package/src/coordinator-mcp/question-state.ts +2 -0
- package/src/coordinator-mcp/server.ts +358 -7
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +1 -1
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +2 -0
- package/src/extensibility/extensions/index.ts +1 -0
- package/src/extensibility/extensions/ouroboros-ooo-bridge.ts +235 -0
- package/src/extensibility/extensions/prefix-command-bridge.ts +4 -9
- package/src/extensibility/extensions/runner.ts +15 -2
- package/src/extensibility/extensions/types.ts +2 -0
- package/src/gjc-runtime/deep-interview-recorder.ts +9 -5
- package/src/gjc-runtime/deep-interview-state.ts +27 -3
- package/src/gjc-runtime/gc-render.ts +8 -1
- package/src/gjc-runtime/gc-runtime.ts +15 -1
- package/src/gjc-runtime/launch-tmux.ts +53 -1
- package/src/internal-urls/docs-index.generated.ts +14 -13
- package/src/main.ts +214 -70
- package/src/modes/DESIGN.md +8 -5
- package/src/modes/acp/acp-agent.ts +123 -7
- package/src/modes/components/footer.ts +10 -18
- package/src/modes/components/model-selector.ts +52 -5
- package/src/modes/components/session-selector.ts +26 -3
- package/src/modes/components/status-line/gh.ts +23 -2
- package/src/modes/controllers/event-controller.ts +3 -0
- package/src/modes/controllers/extension-ui-controller.ts +2 -0
- package/src/modes/controllers/input-controller.ts +11 -0
- package/src/modes/controllers/selector-controller.ts +8 -2
- package/src/modes/interactive-mode.ts +7 -1
- package/src/modes/print-mode.ts +10 -0
- package/src/modes/utils/host-status.ts +38 -0
- package/src/prompts/system/project-prompt.md +19 -0
- package/src/runtime-mcp/types.ts +2 -0
- package/src/sdk/broker/lifecycle.ts +60 -3
- package/src/sdk/bus/chat-daemon-cli.ts +42 -0
- package/src/sdk/bus/chat-daemon-command-channel.ts +921 -0
- package/src/sdk/bus/chat-daemon-control.ts +16 -3
- package/src/sdk/bus/chat-daemon-runtime.ts +257 -21
- package/src/sdk/bus/control-plane-frames.ts +51 -0
- package/src/sdk/bus/conversation-store.ts +29 -1
- package/src/sdk/bus/existing-thread-readiness.ts +155 -0
- package/src/sdk/bus/html-format.ts +19 -3
- package/src/sdk/bus/index.ts +91 -12
- package/src/sdk/bus/notification-service.ts +28 -1
- package/src/sdk/bus/rich-render.ts +3 -2
- package/src/sdk/bus/slack-daemon.ts +99 -4
- package/src/sdk/bus/slack-live-provider.ts +32 -2
- package/src/sdk/bus/slack-provider.ts +11 -0
- package/src/sdk/bus/slack-thread-binding.ts +641 -0
- package/src/sdk/bus/telegram-daemon-cli.ts +11 -0
- package/src/sdk/bus/telegram-daemon-contract.ts +28 -7
- package/src/sdk/bus/telegram-daemon.ts +2007 -509
- package/src/sdk/bus/telegram-reference.ts +114 -15
- package/src/sdk/bus/topic-registry.ts +674 -181
- package/src/sdk/host/host.ts +180 -1
- package/src/sdk/lifecycle-session.ts +8 -2
- package/src/sdk/protocol/operation-inventory.generated.json +22 -0
- package/src/sdk/session-activation.ts +127 -0
- package/src/sdk/session.ts +144 -29
- package/src/sdk/startup-capability.ts +10 -1
- package/src/session/agent-session.ts +220 -13
- package/src/session/artifacts.ts +56 -13
- package/src/session/internal/managed-session-storage.ts +228 -7
- package/src/session/session-manager.ts +225 -60
- package/src/setup/provider-presets.json +3 -3
- package/src/task/index.ts +92 -44
- package/src/thinking-metadata.ts +2 -1
- package/src/tools/ask.ts +10 -0
- package/src/tools/index.ts +15 -0
- package/src/tools/todo-write.ts +4 -4
- package/src/utils/npm-registry.ts +660 -0
package/src/sdk/session.ts
CHANGED
|
@@ -408,6 +408,16 @@ export interface CreateAgentSessionOptions {
|
|
|
408
408
|
/** Load MCP tools for a top-level session only from this caller-owned absolute config file path.
|
|
409
409
|
* Mutually exclusive with mcpManager. */
|
|
410
410
|
mcpConfigPath?: string;
|
|
411
|
+
/**
|
|
412
|
+
* Defer connecting an exact MCP config until the interactive UI is ready.
|
|
413
|
+
* @internal CLI-only startup optimization; SDK callers retain synchronous loading by default.
|
|
414
|
+
*/
|
|
415
|
+
deferMcpConfigStartup?: boolean;
|
|
416
|
+
/**
|
|
417
|
+
* Defer memory backend startup until the caller has applied startup model profiles.
|
|
418
|
+
* @internal CLI-only ordering guard; SDK callers retain immediate startup by default.
|
|
419
|
+
*/
|
|
420
|
+
deferMemoryBackendStartup?: boolean;
|
|
411
421
|
|
|
412
422
|
/** Enable LSP integration (tool, formatting, diagnostics, warmup). Default: true */
|
|
413
423
|
enableLsp?: boolean;
|
|
@@ -498,6 +508,10 @@ export interface CreateAgentSessionResult {
|
|
|
498
508
|
setToolUIContext: (uiContext: ExtensionUIContext, hasUI: boolean) => void;
|
|
499
509
|
/** MCP manager for server lifecycle management (undefined if MCP disabled or an exact tools-only config is session-owned) */
|
|
500
510
|
mcpManager?: MCPManager;
|
|
511
|
+
/** Starts a deferred exact-config MCP connection. Present only when deferMcpConfigStartup was requested. */
|
|
512
|
+
startDeferredMcpConfig?: () => Promise<DeferredMcpConfigStartupResult>;
|
|
513
|
+
/** Starts a deferred memory backend. Present only when deferMemoryBackendStartup was requested. */
|
|
514
|
+
startDeferredMemoryBackend?: () => void;
|
|
501
515
|
/** Warning if session was restored with a different model than saved */
|
|
502
516
|
modelFallbackMessage?: string;
|
|
503
517
|
/** LSP servers configured for lazy startup in interactive mode */
|
|
@@ -511,6 +525,11 @@ export interface CreateAgentSessionResult {
|
|
|
511
525
|
gjcRuntimeSnapshot?: GjcRuntimeSnapshotProvider;
|
|
512
526
|
}
|
|
513
527
|
|
|
528
|
+
export interface DeferredMcpConfigStartupResult {
|
|
529
|
+
loadedToolCount: number;
|
|
530
|
+
hasErrors: boolean;
|
|
531
|
+
}
|
|
532
|
+
|
|
514
533
|
// Re-exports
|
|
515
534
|
|
|
516
535
|
export type { PromptTemplate } from "../config/prompt-templates";
|
|
@@ -1007,6 +1026,7 @@ const MCP_CONFIG_PATH_ABSOLUTE_ERROR = "mcpConfigPath requires an absolute path"
|
|
|
1007
1026
|
const MCP_TOOLS_ONLY_MANAGER_SUBSESSION_ERROR = "tools-only MCP managers cannot be reused in sub-sessions";
|
|
1008
1027
|
const MCP_CONFIG_PATH_SUBSESSION_ERROR = "mcpConfigPath cannot be used in sub-sessions";
|
|
1009
1028
|
const MAX_EXACT_MCP_TOOL_COLLISION_NAMES = 10;
|
|
1029
|
+
const DEFERRED_MCP_CONFIG_STARTUP_ERROR = "MCP tools could not be loaded.";
|
|
1010
1030
|
const MAX_EXACT_MCP_TOOL_NAME_LENGTH = 100;
|
|
1011
1031
|
const pluginMcpManagerServers = new WeakMap<MCPManager, ReadonlySet<string>>();
|
|
1012
1032
|
|
|
@@ -1041,6 +1061,20 @@ function findExactMcpToolNameCollisions(
|
|
|
1041
1061
|
return collisions;
|
|
1042
1062
|
}
|
|
1043
1063
|
|
|
1064
|
+
function findDeferredExactMcpToolNameCollisions(
|
|
1065
|
+
exactMcpToolNames: readonly string[],
|
|
1066
|
+
catalogToolNames: Iterable<string>,
|
|
1067
|
+
): string[] {
|
|
1068
|
+
const catalog = new Set(catalogToolNames);
|
|
1069
|
+
const seen = new Set<string>();
|
|
1070
|
+
const collisions = new Set<string>();
|
|
1071
|
+
for (const toolName of exactMcpToolNames) {
|
|
1072
|
+
if (catalog.has(toolName) || seen.has(toolName)) collisions.add(toolName);
|
|
1073
|
+
seen.add(toolName);
|
|
1074
|
+
}
|
|
1075
|
+
return [...collisions];
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1044
1078
|
export async function createAgentSession(options: CreateAgentSessionOptions = {}): Promise<CreateAgentSessionResult> {
|
|
1045
1079
|
const lifecycleStartupCapability = (
|
|
1046
1080
|
options as CreateAgentSessionOptions & { [lifecycleStartupCapabilityOption]?: SdkStartupCapability }
|
|
@@ -1219,7 +1253,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1219
1253
|
return SessionManager.create(cwd, SessionManager.managedDestination(cwd, agentDir));
|
|
1220
1254
|
}));
|
|
1221
1255
|
const logicalSessionId = sessionManager.getSessionId();
|
|
1222
|
-
|
|
1256
|
+
// Fork-context seeds carry conversation content only, never provider identity:
|
|
1257
|
+
// a shared continuity id would make concurrent subagents present the same
|
|
1258
|
+
// session_id upstream, where session-owning transports reject the extra
|
|
1259
|
+
// downstreams (owner_busy) and degrade those turns to uncached HTTP.
|
|
1260
|
+
const providerSessionId = options.providerSessionId ?? logicalSessionId;
|
|
1223
1261
|
const modelApiKeyAvailability = new Map<string, boolean>();
|
|
1224
1262
|
const getModelAvailabilityKey = (candidate: Model): string =>
|
|
1225
1263
|
`${candidate.provider}\u0000${candidate.baseUrl ?? ""}`;
|
|
@@ -1630,7 +1668,11 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1630
1668
|
}
|
|
1631
1669
|
},
|
|
1632
1670
|
getArtifactManager: () => sessionManager.getArtifactManager(),
|
|
1633
|
-
|
|
1671
|
+
isArtifactManagerAuthorized: manager => sessionManager.isArtifactManagerAuthorized(manager),
|
|
1672
|
+
adoptArtifactManager: manager => sessionManager.adoptArtifactManager(manager),
|
|
1673
|
+
releaseArtifactManager: manager => sessionManager.releaseArtifactManager(manager),
|
|
1674
|
+
ensureArtifactManager: () => sessionManager.ensureArtifactManager(),
|
|
1675
|
+
registerSessionCleanup: cleanup => session?.registerToolSessionTransitionCleanup(cleanup) ?? (() => {}),
|
|
1634
1676
|
settings,
|
|
1635
1677
|
authStorage,
|
|
1636
1678
|
modelRegistry,
|
|
@@ -1685,6 +1727,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1685
1727
|
const customTools: CustomTool[] = [];
|
|
1686
1728
|
const exactMcpToolNames: string[] = [];
|
|
1687
1729
|
const pluginMcpToolNames: string[] = [];
|
|
1730
|
+
let deferredExactMcpConfig: { manager: MCPManager; configPath: string } | undefined;
|
|
1688
1731
|
|
|
1689
1732
|
// Add image tools when the active model or configured image providers can generate images.
|
|
1690
1733
|
const imageGenTools = await logger.time("getImageGenTools", () => getImageGenTools(modelRegistry, model));
|
|
@@ -1785,12 +1828,16 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
1785
1828
|
mcpManager = owned;
|
|
1786
1829
|
ownsMcpManager = true;
|
|
1787
1830
|
cleanupOwnedMcpManager = () => owned.disconnectAll();
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1831
|
+
if (options.deferMcpConfigStartup) {
|
|
1832
|
+
deferredExactMcpConfig = { manager: owned, configPath: explicitMcpConfigPath };
|
|
1833
|
+
} else {
|
|
1834
|
+
const result = await owned.discoverAndConnect({ configPath: explicitMcpConfigPath });
|
|
1835
|
+
const resultTools = result.tools as CustomTool[];
|
|
1836
|
+
exactMcpToolNames.push(...resultTools.map(tool => tool.name));
|
|
1837
|
+
customTools.push(...resultTools);
|
|
1838
|
+
if (result.errors.size > 0 || result.tools.length === 0) {
|
|
1839
|
+
logger.warn("MCP tools could not be loaded.");
|
|
1840
|
+
}
|
|
1794
1841
|
}
|
|
1795
1842
|
} else if (!mcpManager && !isCanonicalSubSession) {
|
|
1796
1843
|
// Always-on GJC plugin-bundle MCP servers. Top-level sessions own a manager
|
|
@@ -2198,13 +2245,13 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2198
2245
|
}
|
|
2199
2246
|
// Exact-config MCP tools cannot claim a name already represented by the final candidate catalog.
|
|
2200
2247
|
// Other catalog collisions retain their legacy override behavior.
|
|
2248
|
+
const exactMcpCatalogToolNames = [
|
|
2249
|
+
...builtinCandidateTools.map(tool => tool.name),
|
|
2250
|
+
...preExactCustomToolNames,
|
|
2251
|
+
...wrappedExtensionTools.map(tool => tool.name),
|
|
2252
|
+
];
|
|
2201
2253
|
if (exactMcpToolNames.length > 0) {
|
|
2202
|
-
const
|
|
2203
|
-
...builtinCandidateTools.map(tool => tool.name),
|
|
2204
|
-
...preExactCustomToolNames,
|
|
2205
|
-
...wrappedExtensionTools.map(tool => tool.name),
|
|
2206
|
-
];
|
|
2207
|
-
const collidingToolNames = findExactMcpToolNameCollisions(exactMcpToolNames, catalogToolNames);
|
|
2254
|
+
const collidingToolNames = findExactMcpToolNameCollisions(exactMcpToolNames, exactMcpCatalogToolNames);
|
|
2208
2255
|
if (collidingToolNames.length > 0) {
|
|
2209
2256
|
throw new ExactMcpToolNameCollisionError(collidingToolNames);
|
|
2210
2257
|
}
|
|
@@ -2397,10 +2444,13 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2397
2444
|
);
|
|
2398
2445
|
let initialToolNames = [...initialRequestedActiveToolNames];
|
|
2399
2446
|
if (mcpDiscoveryEnabled) {
|
|
2400
|
-
const restoredSelectedMCPToolNames =
|
|
2401
|
-
|
|
2402
|
-
|
|
2447
|
+
const restoredSelectedMCPToolNames = deferredExactMcpConfig
|
|
2448
|
+
? existingSession.selectedMCPToolNames.filter(name => !mandatoryMCPToolNameSet.has(name))
|
|
2449
|
+
: existingSession.selectedMCPToolNames.filter(
|
|
2450
|
+
name => toolRegistry.has(name) && !mandatoryMCPToolNameSet.has(name),
|
|
2451
|
+
);
|
|
2403
2452
|
if (
|
|
2453
|
+
!deferredExactMcpConfig &&
|
|
2404
2454
|
existingSession.hasPersistedMCPToolSelection &&
|
|
2405
2455
|
restoredSelectedMCPToolNames.length !== existingSession.selectedMCPToolNames.length
|
|
2406
2456
|
) {
|
|
@@ -2751,6 +2801,9 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2751
2801
|
}
|
|
2752
2802
|
}
|
|
2753
2803
|
|
|
2804
|
+
const deferredMcpTurnReady = deferredExactMcpConfig ? Promise.withResolvers<void>() : undefined;
|
|
2805
|
+
if (deferredMcpTurnReady) void deferredMcpTurnReady.promise.catch(() => {});
|
|
2806
|
+
|
|
2754
2807
|
session = new AgentSession({
|
|
2755
2808
|
agent,
|
|
2756
2809
|
thinkingLevel,
|
|
@@ -2767,6 +2820,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2767
2820
|
// subagents and callers that merely observe a manager must not (see
|
|
2768
2821
|
// AgentSession.dispose).
|
|
2769
2822
|
ownedMcpManager: ownsMcpManager ? mcpManager : undefined,
|
|
2823
|
+
startupTurnBarrier: deferredMcpTurnReady?.promise,
|
|
2770
2824
|
scopedModels: options.scopedModels,
|
|
2771
2825
|
promptTemplates,
|
|
2772
2826
|
slashCommands,
|
|
@@ -2793,6 +2847,7 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2793
2847
|
mcpDiscoveryEnabled,
|
|
2794
2848
|
discoveryMode: effectiveDiscoveryMode,
|
|
2795
2849
|
initialSelectedMCPToolNames,
|
|
2850
|
+
preserveUnavailableInitialMCPToolSelection: deferredExactMcpConfig !== undefined,
|
|
2796
2851
|
initialMCPToolSelectionIsExplicit: hasExplicitMCPToolSelection,
|
|
2797
2852
|
initialDiscoveredBuiltinToolSelectionIsExplicit: hasExplicitDiscoveredBuiltinToolSelection,
|
|
2798
2853
|
initialSelectedDiscoveredBuiltinToolNames,
|
|
@@ -2884,18 +2939,24 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2884
2939
|
? discoverStartupLspServers(cwd)
|
|
2885
2940
|
: undefined;
|
|
2886
2941
|
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2891
|
-
|
|
2892
|
-
|
|
2893
|
-
|
|
2894
|
-
|
|
2895
|
-
|
|
2896
|
-
|
|
2897
|
-
|
|
2898
|
-
|
|
2942
|
+
let memoryBackendStarted = false;
|
|
2943
|
+
const startMemoryBackend = () => {
|
|
2944
|
+
if (memoryBackendStarted) return;
|
|
2945
|
+
memoryBackendStarted = true;
|
|
2946
|
+
logger.time("startMemoryStartupTask", () =>
|
|
2947
|
+
Promise.resolve(
|
|
2948
|
+
resolveMemoryBackend(settings).start({
|
|
2949
|
+
session,
|
|
2950
|
+
settings,
|
|
2951
|
+
modelRegistry,
|
|
2952
|
+
agentDir,
|
|
2953
|
+
taskDepth,
|
|
2954
|
+
parentHindsightSessionState: options.parentHindsightSessionState,
|
|
2955
|
+
}),
|
|
2956
|
+
),
|
|
2957
|
+
);
|
|
2958
|
+
};
|
|
2959
|
+
if (!options.deferMemoryBackendStartup) startMemoryBackend();
|
|
2899
2960
|
|
|
2900
2961
|
// Exact-config managers do not receive reactive callbacks; their tools are
|
|
2901
2962
|
// registered once in the session-owned catalog.
|
|
@@ -2949,6 +3010,58 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2949
3010
|
// microtask (the ToolSession closure needs `session` assigned). Await it
|
|
2950
3011
|
// so a resumed canonical workflow session returns with `ask` resident.
|
|
2951
3012
|
await session.workflowGateToolRestoration;
|
|
3013
|
+
let startDeferredMcpConfig: (() => Promise<DeferredMcpConfigStartupResult>) | undefined;
|
|
3014
|
+
if (deferredExactMcpConfig) {
|
|
3015
|
+
const { manager, configPath } = deferredExactMcpConfig;
|
|
3016
|
+
let cancelled = false;
|
|
3017
|
+
let startupPromise: Promise<DeferredMcpConfigStartupResult> | undefined;
|
|
3018
|
+
session.registerToolSessionCleanup(async () => {
|
|
3019
|
+
cancelled = true;
|
|
3020
|
+
deferredMcpTurnReady?.resolve();
|
|
3021
|
+
if (startupPromise) {
|
|
3022
|
+
await manager.disconnectAll().catch(() => {});
|
|
3023
|
+
await startupPromise.catch(() => {});
|
|
3024
|
+
}
|
|
3025
|
+
});
|
|
3026
|
+
startDeferredMcpConfig = () => {
|
|
3027
|
+
if (!startupPromise && session.isDisposed) {
|
|
3028
|
+
return Promise.reject(new Error(DEFERRED_MCP_CONFIG_STARTUP_ERROR));
|
|
3029
|
+
}
|
|
3030
|
+
startupPromise ??= (async () => {
|
|
3031
|
+
try {
|
|
3032
|
+
const result = await manager.discoverAndConnect({ configPath });
|
|
3033
|
+
const resultTools = result.tools as CustomTool[];
|
|
3034
|
+
const toolNames = resultTools.map(tool => tool.name);
|
|
3035
|
+
const collidingToolNames = findDeferredExactMcpToolNameCollisions(
|
|
3036
|
+
toolNames,
|
|
3037
|
+
exactMcpCatalogToolNames,
|
|
3038
|
+
);
|
|
3039
|
+
if (collidingToolNames.length > 0) {
|
|
3040
|
+
throw new ExactMcpToolNameCollisionError(collidingToolNames);
|
|
3041
|
+
}
|
|
3042
|
+
if (!cancelled && !session.isDisposed) {
|
|
3043
|
+
await session.refreshMCPTools(resultTools);
|
|
3044
|
+
if (
|
|
3045
|
+
!session.isDisposed &&
|
|
3046
|
+
(!mcpDiscoveryEnabled || !existingSession.hasPersistedMCPToolSelection)
|
|
3047
|
+
) {
|
|
3048
|
+
await session.activateDiscoveredTools(toolNames);
|
|
3049
|
+
}
|
|
3050
|
+
}
|
|
3051
|
+
deferredMcpTurnReady?.resolve();
|
|
3052
|
+
const hasErrors = result.errors.size > 0 || result.tools.length === 0;
|
|
3053
|
+
if (hasErrors) logger.warn(DEFERRED_MCP_CONFIG_STARTUP_ERROR);
|
|
3054
|
+
return { loadedToolCount: cancelled || session.isDisposed ? 0 : resultTools.length, hasErrors };
|
|
3055
|
+
} catch {
|
|
3056
|
+
const startupError = new Error(DEFERRED_MCP_CONFIG_STARTUP_ERROR);
|
|
3057
|
+
deferredMcpTurnReady?.reject(startupError);
|
|
3058
|
+
await manager.disconnectAll().catch(() => {});
|
|
3059
|
+
throw startupError;
|
|
3060
|
+
}
|
|
3061
|
+
})();
|
|
3062
|
+
return startupPromise;
|
|
3063
|
+
};
|
|
3064
|
+
}
|
|
2952
3065
|
// Expose the published evidence on the session itself so UI surfaces that
|
|
2953
3066
|
// only hold a session (Settings) can consume it without threading the
|
|
2954
3067
|
// creation result through every controller.
|
|
@@ -2959,6 +3072,8 @@ export async function createAgentSession(options: CreateAgentSessionOptions = {}
|
|
|
2959
3072
|
extensionsResult,
|
|
2960
3073
|
setToolUIContext,
|
|
2961
3074
|
mcpManager: ownsMcpManager && mcpManager?.isToolsOnly() ? undefined : mcpManager,
|
|
3075
|
+
startDeferredMcpConfig,
|
|
3076
|
+
startDeferredMemoryBackend: options.deferMemoryBackendStartup ? startMemoryBackend : undefined,
|
|
2962
3077
|
modelFallbackMessage,
|
|
2963
3078
|
lspServers,
|
|
2964
3079
|
eventBus,
|
|
@@ -172,7 +172,16 @@ export class SdkStartupCapability {
|
|
|
172
172
|
this.#cancelled = true;
|
|
173
173
|
}
|
|
174
174
|
|
|
175
|
-
|
|
175
|
+
/**
|
|
176
|
+
* The broker-issued, session-scoped readiness intent this child was launched
|
|
177
|
+
* with. It is carried on the capability rather than read from the ambient
|
|
178
|
+
* environment so bus wiring can never mistake an inherited process-global
|
|
179
|
+
* flag for a broker-managed preparation.
|
|
180
|
+
*/
|
|
181
|
+
constructor(
|
|
182
|
+
readonly rollback?: SdkStartupRollbackTracker,
|
|
183
|
+
readonly readiness: "immediate" | "deferred" = "immediate",
|
|
184
|
+
) {}
|
|
176
185
|
|
|
177
186
|
normalizeFailure(phase: SdkStartupPhase, reason: SdkStartupReason, error?: unknown): SdkStartupFailure {
|
|
178
187
|
return normalizeSdkStartupFailure(phase, reason, error, lifecycleKnownSecrets());
|