import { type ElicitationResponse, type OnElicitation, type ToolInvocationContext, type ToolMetadata, toTool, type ToolMap, type ToolPath,} from "@executor/codemode-core";import { type ScopeId, ExecutionIdSchema, ExecutionInteractionIdSchema, SourceSchema, type Source,} from "#schema";import * as Effect from "effect/Effect";import * as Cause from "effect/Cause";import * as Exit from "effect/Exit";import * as Schema from "effect/Schema";import type { RuntimeLocalScopeState,} from "../scope/runtime-context";import { type LocalStorageServices, type InstallationStoreShape, type SourceArtifactStoreShape, type ScopeConfigStoreShape, type ScopeStateStoreShape, makeLocalStorageLayer,} from "../scope/storage";import { provideOptionalRuntimeLocalScope,} from "../scope/runtime-context";import { runtimeEffectError,} from "../effect-errors"; /** Run an Effect as a Promise, preserving the original error (not FiberFailure). */const runEffect = async <A>( effect: Effect.Effect<A, unknown, LocalStorageServices>, storage: { installationStore: InstallationStoreShape; scopeConfigStore: ScopeConfigStoreShape; scopeStateStore: ScopeStateStoreShape; sourceArtifactStore: SourceArtifactStoreShape; }, runtimeLocalScope: RuntimeLocalScopeState | null = null,): Promise<A> => { const baseLayer = makeLocalStorageLayer(storage); const exit = await Effect.runPromiseExit( provideOptionalRuntimeLocalScope( effect.pipe(Effect.provide(baseLayer)), runtimeLocalScope, ), ); if (Exit.isSuccess(exit)) return exit.value; throw Cause.squash(exit.cause);}; import { type ExecutorAddSourceInput, type ExecutorCredentialManagedSourceInput, type ExecutorHttpSourceAuthInput, type ExecutorMcpSourceInput, type RuntimeSourceAuthService,} from "./source-auth-service";import { deriveSchemaJson, deriveSchemaTypeSignature,} from "../catalog/schema-type-signature";import { ExecutorAddSourceInputSchema, executorAddableSourceAdapters, sourceAdapterRequiresInteractiveConnect,} from "./source-adapters";import { decodeSourceCredentialSelectionContent,} from "./source-credential-interactions"; const ExecutorSourcesAddInputSchema = Schema.standardSchemaV1( ExecutorAddSourceInputSchema,); const ExecutorSourcesAddOutputSchema = Schema.standardSchemaV1(SourceSchema); export const EXECUTOR_SOURCES_ADD_INPUT_HINT = deriveSchemaTypeSignature( ExecutorAddSourceInputSchema, 320,); export const EXECUTOR_SOURCES_ADD_OUTPUT_SIGNATURE = deriveSchemaTypeSignature( SourceSchema, 260,); export const EXECUTOR_SOURCES_ADD_INPUT_SCHEMA = deriveSchemaJson( ExecutorAddSourceInputSchema,) ?? {}; export const EXECUTOR_SOURCES_ADD_OUTPUT_SCHEMA = deriveSchemaJson( SourceSchema,) ?? {}; export const EXECUTOR_SOURCES_ADD_HELP_LINES = [ "Source add input shapes:", ...executorAddableSourceAdapters.flatMap((adapter) => adapter.executorAddInputSchema && adapter.executorAddInputSignatureWidth !== null && adapter.executorAddHelpText ? [ `- ${adapter.displayName}: ${deriveSchemaTypeSignature(adapter.executorAddInputSchema, adapter.executorAddInputSignatureWidth)}`, ...adapter.executorAddHelpText.map((line) => ` ${line}`), ] : [], ), " executor handles the credential setup for you.",] as const; export const buildExecutorSourcesAddDescription = (): string => [ "Add an MCP, OpenAPI, or GraphQL source to the current scope.", ...EXECUTOR_SOURCES_ADD_HELP_LINES, ].join("\n"); const toExecutionId = (value: unknown) => { if (typeof value !== "string" || value.trim().length === 0) { throw new Error("Missing execution run id for executor.sources.add"); } return ExecutionIdSchema.make(value);}; const asToolPath = (value: string): ToolPath => value as ToolPath; const toSerializableValue = <A>(value: A): A => JSON.parse(JSON.stringify(value)) as A; type ExecutorSourcesAddToolArgs = | Omit<ExecutorMcpSourceInput, "scopeId" | "actorScopeId" | "executionId" | "interactionId"> | Omit< ExecutorCredentialManagedSourceInput, "scopeId" | "actorScopeId" | "executionId" | "interactionId" >; type ExecutorGoogleDiscoveryToolArgs = Omit< Extract<ExecutorCredentialManagedSourceInput, { service: string; version: string }>, "scopeId" | "actorScopeId" | "executionId" | "interactionId">; type ExecutorOpenApiToolArgs = Omit< Extract<ExecutorCredentialManagedSourceInput, { specUrl: string }>, "scopeId" | "actorScopeId" | "executionId" | "interactionId">; type ExecutorGraphqlToolArgs = Omit< Extract<ExecutorCredentialManagedSourceInput, { kind: "graphql" }>, "scopeId" | "actorScopeId" | "executionId" | "interactionId">; type ExecutorCredentialPromptArgs = { scopeId: ScopeId; sourceId: Source["id"]; kind: ExecutorCredentialManagedSourceInput["kind"]; endpoint?: string; specUrl?: string; service?: string; version?: string; discoveryUrl?: string | null; name?: string | null; namespace?: string | null;}; const isExecutorMcpToolArgs = ( args: ExecutorSourcesAddToolArgs,): args is Omit<ExecutorMcpSourceInput, "scopeId" | "actorScopeId" | "executionId" | "interactionId"> => args.kind === undefined || sourceAdapterRequiresInteractiveConnect(args.kind); const isExecutorCredentialManagedSourceInput = ( input: ExecutorAddSourceInput,): input is ExecutorCredentialManagedSourceInput => typeof input.kind === "string"; const prepareExecutorAddSourceInput = (input: { args: ExecutorSourcesAddToolArgs; scopeId: ScopeId; actorScopeId: ScopeId; executionId: ReturnType<typeof toExecutionId>; interactionId: ReturnType<typeof ExecutionInteractionIdSchema.make>;}): ExecutorAddSourceInput => { if (isExecutorMcpToolArgs(input.args)) { return { kind: input.args.kind, endpoint: input.args.endpoint, name: input.args.name ?? null, namespace: input.args.namespace ?? null, transport: input.args.transport ?? null, queryParams: input.args.queryParams ?? null, headers: input.args.headers ?? null, command: input.args.command ?? null, args: input.args.args ?? null, env: input.args.env ?? null, cwd: input.args.cwd ?? null, scopeId: input.scopeId, actorScopeId: input.actorScopeId, executionId: input.executionId, interactionId: input.interactionId, } satisfies ExecutorMcpSourceInput; } if ("service" in input.args) { const args = input.args as ExecutorGoogleDiscoveryToolArgs; return { ...args, scopeId: input.scopeId, actorScopeId: input.actorScopeId, executionId: input.executionId, interactionId: input.interactionId, } satisfies Extract<ExecutorCredentialManagedSourceInput, { service: string; version: string }>; } if ("specUrl" in input.args) { const args = input.args as ExecutorOpenApiToolArgs; return { ...args, scopeId: input.scopeId, actorScopeId: input.actorScopeId, executionId: input.executionId, interactionId: input.interactionId, } satisfies Extract<ExecutorCredentialManagedSourceInput, { specUrl: string }>; } const args = input.args as ExecutorGraphqlToolArgs; return { ...args, scopeId: input.scopeId, actorScopeId: input.actorScopeId, executionId: input.executionId, interactionId: input.interactionId, } satisfies Extract<ExecutorCredentialManagedSourceInput, { kind: "graphql" }>;}; const resolveLocalCredentialUrl = (input: { baseUrl: string; scopeId: ScopeId; sourceId: Source["id"]; executionId: string; interactionId: string;}): string => new URL( `/v1/workspaces/${encodeURIComponent(input.scopeId)}/sources/${encodeURIComponent(input.sourceId)}/credentials?interactionId=${encodeURIComponent(`${input.executionId}:${input.interactionId}`)}`, input.baseUrl, ).toString(); const promptForSourceCredentialSelection = (input: { args: ExecutorCredentialPromptArgs; credentialSlot: "runtime" | "import"; source: Source; executionId: string; interactionId: string; path: ToolPath; sourceKey: string; localServerBaseUrl: string | null; metadata?: ToolMetadata; invocation?: ToolInvocationContext; onElicitation?: OnElicitation;}) => Effect.gen(function* () { if (!input.onElicitation) { return yield* runtimeEffectError("sources/executor-tools", "executor.sources.add requires an elicitation-capable host"); } if (input.localServerBaseUrl === null) { return yield* runtimeEffectError("sources/executor-tools", "executor.sources.add requires a local server base URL for credential capture"); } const response: ElicitationResponse = yield* input.onElicitation({ interactionId: input.interactionId, path: input.path, sourceKey: input.sourceKey, args: input.args, metadata: input.metadata, context: input.invocation, elicitation: { mode: "url", message: input.credentialSlot === "import" ? `Open the secure credential page to configure import access for ${input.source.name}` : `Open the secure credential page to connect ${input.source.name}`, url: resolveLocalCredentialUrl({ baseUrl: input.localServerBaseUrl, scopeId: input.args.scopeId, sourceId: input.args.sourceId, executionId: input.executionId, interactionId: input.interactionId, }), elicitationId: input.interactionId, }, }).pipe(Effect.mapError((cause) => cause instanceof Error ? cause : new Error(String(cause)))); if (response.action !== "accept") { return yield* runtimeEffectError("sources/executor-tools", `Source credential setup was not completed for ${input.source.name}`); } const content = yield* Effect.try({ try: () => decodeSourceCredentialSelectionContent(response.content), catch: () => new Error("Credential capture did not return a valid source auth choice for executor.sources.add"), }); if (content.authKind === "none") { return { kind: "none" } satisfies ExecutorHttpSourceAuthInput; } return { kind: "bearer", tokenRef: content.tokenRef, } satisfies ExecutorHttpSourceAuthInput; }); export const createExecutorToolMap = (input: { scopeId: ScopeId; actorScopeId: ScopeId; sourceAuthService: RuntimeSourceAuthService; installationStore: InstallationStoreShape; scopeConfigStore: ScopeConfigStoreShape; scopeStateStore: ScopeStateStoreShape; sourceArtifactStore: SourceArtifactStoreShape; runtimeLocalScope: RuntimeLocalScopeState | null;}): ToolMap => ({ "executor.sources.add": toTool({ tool: { description: buildExecutorSourcesAddDescription(), inputSchema: ExecutorSourcesAddInputSchema, outputSchema: ExecutorSourcesAddOutputSchema, execute: async (args: ExecutorSourcesAddToolArgs, context): Promise<Source> => { const executionId = toExecutionId(context?.invocation?.runId); const interactionId = ExecutionInteractionIdSchema.make( `executor.sources.add:${crypto.randomUUID()}`, ); const preparedArgs = prepareExecutorAddSourceInput({ args, scopeId: input.scopeId, actorScopeId: input.actorScopeId, executionId, interactionId, }); let result = await runEffect( input.sourceAuthService.addExecutorSource( preparedArgs, context?.onElicitation ? { mcpDiscoveryElicitation: { onElicitation: context.onElicitation, path: context.path ?? asToolPath("executor.sources.add"), sourceKey: context.sourceKey, args, metadata: context.metadata, invocation: context.invocation, }, } : undefined, ), { installationStore: input.installationStore, scopeConfigStore: input.scopeConfigStore, scopeStateStore: input.scopeStateStore, sourceArtifactStore: input.sourceArtifactStore, }, input.runtimeLocalScope, ); if (result.kind === "connected") { return toSerializableValue(result.source); } if (result.kind === "credential_required") { let pendingResult = result; if (!isExecutorCredentialManagedSourceInput(preparedArgs)) { throw new Error("Credential-managed source setup expected a named adapter kind"); } let pendingArgs: ExecutorCredentialManagedSourceInput = preparedArgs; while (pendingResult.kind === "credential_required") { const selectedAuth = await runEffect( promptForSourceCredentialSelection({ args: { ...pendingArgs, scopeId: input.scopeId, sourceId: pendingResult.source.id, }, credentialSlot: pendingResult.credentialSlot, source: pendingResult.source, executionId, interactionId, path: context?.path ?? asToolPath("executor.sources.add"), sourceKey: context?.sourceKey ?? "executor", localServerBaseUrl: input.sourceAuthService.getLocalServerBaseUrl(), metadata: context?.metadata, invocation: context?.invocation, onElicitation: context?.onElicitation, }), { installationStore: input.installationStore, scopeConfigStore: input.scopeConfigStore, scopeStateStore: input.scopeStateStore, sourceArtifactStore: input.sourceArtifactStore, }, input.runtimeLocalScope, ); pendingArgs = pendingResult.credentialSlot === "import" && pendingArgs.importAuthPolicy === "separate" ? { ...pendingArgs, importAuth: selectedAuth, } : { ...pendingArgs, auth: selectedAuth, }; const completed = await runEffect( input.sourceAuthService.addExecutorSource( pendingArgs, context?.onElicitation ? { mcpDiscoveryElicitation: { onElicitation: context.onElicitation, path: context.path ?? asToolPath("executor.sources.add"), sourceKey: context.sourceKey, args, metadata: context.metadata, invocation: context.invocation, }, } : undefined, ), { installationStore: input.installationStore, scopeConfigStore: input.scopeConfigStore, scopeStateStore: input.scopeStateStore, sourceArtifactStore: input.sourceArtifactStore, }, input.runtimeLocalScope, ); if (completed.kind === "connected") { return toSerializableValue(completed.source); } if (completed.kind === "credential_required") { pendingResult = completed; continue; } result = completed; break; } if (pendingResult.kind === "credential_required") { result = pendingResult; } } if (!context?.onElicitation) { throw new Error("executor.sources.add requires an elicitation-capable host"); } if (result.kind !== "oauth_required") { throw new Error(`Source add did not reach OAuth continuation for ${result.source.id}`); } const response: ElicitationResponse = await runEffect( context.onElicitation({ interactionId, path: context.path ?? asToolPath("executor.sources.add"), sourceKey: context.sourceKey, args: preparedArgs, metadata: context.metadata, context: context.invocation, elicitation: { mode: "url", message: `Open the provider sign-in page to connect ${result.source.name}`, url: result.authorizationUrl, elicitationId: result.sessionId, }, }), { installationStore: input.installationStore, scopeConfigStore: input.scopeConfigStore, scopeStateStore: input.scopeStateStore, sourceArtifactStore: input.sourceArtifactStore, }, input.runtimeLocalScope, ); if (response.action !== "accept") { throw new Error(`Source add was not completed for ${result.source.id}`); }Lines 1–500 of 530. Load more
import { type ElicitationResponse, type OnElicitation, type ToolInvocationContext, type ToolMetadata, toTool, type ToolMap, type ToolPath, } from "@executor/codemode-core"; import { type ScopeId, ExecutionIdSchema, ExecutionInteractionIdSchema, SourceSchema, type Source, } from "#schema"; import * as Effect from "effect/Effect"; import * as Cause from "effect/Cause"; import * as Exit from "effect/Exit"; import * as Schema from "effect/Schema"; import type { RuntimeLocalScopeState, } from "../scope/runtime-context"; import { type LocalStorageServices, type InstallationStoreShape, type SourceArtifactStoreShape, type ScopeConfigStoreShape, type ScopeStateStoreShape, makeLocalStorageLayer, } from "../scope/storage"; import { provideOptionalRuntimeLocalScope, } from "../scope/runtime-context"; import { runtimeEffectError, } from "../effect-errors"; /** Run an Effect as a Promise, preserving the original error (not FiberFailure). */ const runEffect = async <A>( effect: Effect.Effect<A, unknown, LocalStorageServices>, storage: { installationStore: InstallationStoreShape; scopeConfigStore: ScopeConfigStoreShape; scopeStateStore: ScopeStateStoreShape; sourceArtifactStore: SourceArtifactStoreShape; }, runtimeLocalScope: RuntimeLocalScopeState | null = null, ): Promise<A> => { const baseLayer = makeLocalStorageLayer(storage); const exit = await Effect.runPromiseExit( provideOptionalRuntimeLocalScope( effect.pipe(Effect.provide(baseLayer)), runtimeLocalScope, ), ); if (Exit.isSuccess(exit)) return exit.value; throw Cause.squash(exit.cause); }; import { type ExecutorAddSourceInput, type ExecutorCredentialManagedSourceInput, type ExecutorHttpSourceAuthInput, type ExecutorMcpSourceInput, type RuntimeSourceAuthService, } from "./source-auth-service"; import { deriveSchemaJson, deriveSchemaTypeSignature, } from "../catalog/schema-type-signature"; import { ExecutorAddSourceInputSchema, executorAddableSourceAdapters, sourceAdapterRequiresInteractiveConnect, } from "./source-adapters"; import { decodeSourceCredentialSelectionContent, } from "./source-credential-interactions"; const ExecutorSourcesAddInputSchema = Schema.standardSchemaV1( ExecutorAddSourceInputSchema, ); const ExecutorSourcesAddOutputSchema = Schema.standardSchemaV1(SourceSchema); export const EXECUTOR_SOURCES_ADD_INPUT_HINT = deriveSchemaTypeSignature( ExecutorAddSourceInputSchema, 320, ); export const EXECUTOR_SOURCES_ADD_OUTPUT_SIGNATURE = deriveSchemaTypeSignature( SourceSchema, 260, ); export const EXECUTOR_SOURCES_ADD_INPUT_SCHEMA = deriveSchemaJson( ExecutorAddSourceInputSchema, ) ?? {}; export const EXECUTOR_SOURCES_ADD_OUTPUT_SCHEMA = deriveSchemaJson( SourceSchema, ) ?? {}; export const EXECUTOR_SOURCES_ADD_HELP_LINES = [ "Source add input shapes:", ...executorAddableSourceAdapters.flatMap((adapter) => adapter.executorAddInputSchema && adapter.executorAddInputSignatureWidth !== null && adapter.executorAddHelpText ? [ `- ${adapter.displayName}: ${deriveSchemaTypeSignature(adapter.executorAddInputSchema, adapter.executorAddInputSignatureWidth)}`, ...adapter.executorAddHelpText.map((line) => ` ${line}`), ] : [], ), " executor handles the credential setup for you.", ] as const; export const buildExecutorSourcesAddDescription = (): string => [ "Add an MCP, OpenAPI, or GraphQL source to the current scope.", ...EXECUTOR_SOURCES_ADD_HELP_LINES, ].join("\n"); const toExecutionId = (value: unknown) => { if (typeof value !== "string" || value.trim().length === 0) { throw new Error("Missing execution run id for executor.sources.add"); } return ExecutionIdSchema.make(value); }; const asToolPath = (value: string): ToolPath => value as ToolPath; const toSerializableValue = <A>(value: A): A => JSON.parse(JSON.stringify(value)) as A; type ExecutorSourcesAddToolArgs = | Omit<ExecutorMcpSourceInput, "scopeId" | "actorScopeId" | "executionId" | "interactionId"> | Omit< ExecutorCredentialManagedSourceInput, "scopeId" | "actorScopeId" | "executionId" | "interactionId" >; type ExecutorGoogleDiscoveryToolArgs = Omit< Extract<ExecutorCredentialManagedSourceInput, { service: string; version: string }>, "scopeId" | "actorScopeId" | "executionId" | "interactionId" >; type ExecutorOpenApiToolArgs = Omit< Extract<ExecutorCredentialManagedSourceInput, { specUrl: string }>, "scopeId" | "actorScopeId" | "executionId" | "interactionId" >; type ExecutorGraphqlToolArgs = Omit< Extract<ExecutorCredentialManagedSourceInput, { kind: "graphql" }>, "scopeId" | "actorScopeId" | "executionId" | "interactionId" >; type ExecutorCredentialPromptArgs = { scopeId: ScopeId; sourceId: Source["id"]; kind: ExecutorCredentialManagedSourceInput["kind"]; endpoint?: string; specUrl?: string; service?: string; version?: string; discoveryUrl?: string | null; name?: string | null; namespace?: string | null; }; const isExecutorMcpToolArgs = ( args: ExecutorSourcesAddToolArgs, ): args is Omit<ExecutorMcpSourceInput, "scopeId" | "actorScopeId" | "executionId" | "interactionId"> => args.kind === undefined || sourceAdapterRequiresInteractiveConnect(args.kind); const isExecutorCredentialManagedSourceInput = ( input: ExecutorAddSourceInput, ): input is ExecutorCredentialManagedSourceInput => typeof input.kind === "string"; const prepareExecutorAddSourceInput = (input: { args: ExecutorSourcesAddToolArgs; scopeId: ScopeId; actorScopeId: ScopeId; executionId: ReturnType<typeof toExecutionId>; interactionId: ReturnType<typeof ExecutionInteractionIdSchema.make>; }): ExecutorAddSourceInput => { if (isExecutorMcpToolArgs(input.args)) { return { kind: input.args.kind, endpoint: input.args.endpoint, name: input.args.name ?? null, namespace: input.args.namespace ?? null, transport: input.args.transport ?? null, queryParams: input.args.queryParams ?? null, headers: input.args.headers ?? null, command: input.args.command ?? null, args: input.args.args ?? null, env: input.args.env ?? null, cwd: input.args.cwd ?? null, scopeId: input.scopeId, actorScopeId: input.actorScopeId, executionId: input.executionId, interactionId: input.interactionId, } satisfies ExecutorMcpSourceInput; } if ("service" in input.args) { const args = input.args as ExecutorGoogleDiscoveryToolArgs; return { ...args, scopeId: input.scopeId, actorScopeId: input.actorScopeId, executionId: input.executionId, interactionId: input.interactionId, } satisfies Extract<ExecutorCredentialManagedSourceInput, { service: string; version: string }>; } if ("specUrl" in input.args) { const args = input.args as ExecutorOpenApiToolArgs; return { ...args, scopeId: input.scopeId, actorScopeId: input.actorScopeId, executionId: input.executionId, interactionId: input.interactionId, } satisfies Extract<ExecutorCredentialManagedSourceInput, { specUrl: string }>; } const args = input.args as ExecutorGraphqlToolArgs; return { ...args, scopeId: input.scopeId, actorScopeId: input.actorScopeId, executionId: input.executionId, interactionId: input.interactionId, } satisfies Extract<ExecutorCredentialManagedSourceInput, { kind: "graphql" }>; }; const resolveLocalCredentialUrl = (input: { baseUrl: string; scopeId: ScopeId; sourceId: Source["id"]; executionId: string; interactionId: string; }): string => new URL( `/v1/workspaces/${encodeURIComponent(input.scopeId)}/sources/${encodeURIComponent(input.sourceId)}/credentials?interactionId=${encodeURIComponent(`${input.executionId}:${input.interactionId}`)}`, input.baseUrl, ).toString(); const promptForSourceCredentialSelection = (input: { args: ExecutorCredentialPromptArgs; credentialSlot: "runtime" | "import"; source: Source; executionId: string; interactionId: string; path: ToolPath; sourceKey: string; localServerBaseUrl: string | null; metadata?: ToolMetadata; invocation?: ToolInvocationContext; onElicitation?: OnElicitation; }) => Effect.gen(function* () { if (!input.onElicitation) { return yield* runtimeEffectError("sources/executor-tools", "executor.sources.add requires an elicitation-capable host"); } if (input.localServerBaseUrl === null) { return yield* runtimeEffectError("sources/executor-tools", "executor.sources.add requires a local server base URL for credential capture"); } const response: ElicitationResponse = yield* input.onElicitation({ interactionId: input.interactionId, path: input.path, sourceKey: input.sourceKey, args: input.args, metadata: input.metadata, context: input.invocation, elicitation: { mode: "url", message: input.credentialSlot === "import" ? `Open the secure credential page to configure import access for ${input.source.name}` : `Open the secure credential page to connect ${input.source.name}`, url: resolveLocalCredentialUrl({ baseUrl: input.localServerBaseUrl, scopeId: input.args.scopeId, sourceId: input.args.sourceId, executionId: input.executionId, interactionId: input.interactionId, }), elicitationId: input.interactionId, }, }).pipe(Effect.mapError((cause) => cause instanceof Error ? cause : new Error(String(cause)))); if (response.action !== "accept") { return yield* runtimeEffectError("sources/executor-tools", `Source credential setup was not completed for ${input.source.name}`); } const content = yield* Effect.try({ try: () => decodeSourceCredentialSelectionContent(response.content), catch: () => new Error("Credential capture did not return a valid source auth choice for executor.sources.add"), }); if (content.authKind === "none") { return { kind: "none" } satisfies ExecutorHttpSourceAuthInput; } return { kind: "bearer", tokenRef: content.tokenRef, } satisfies ExecutorHttpSourceAuthInput; }); export const createExecutorToolMap = (input: { scopeId: ScopeId; actorScopeId: ScopeId; sourceAuthService: RuntimeSourceAuthService; installationStore: InstallationStoreShape; scopeConfigStore: ScopeConfigStoreShape; scopeStateStore: ScopeStateStoreShape; sourceArtifactStore: SourceArtifactStoreShape; runtimeLocalScope: RuntimeLocalScopeState | null; }): ToolMap => ({ "executor.sources.add": toTool({ tool: { description: buildExecutorSourcesAddDescription(), inputSchema: ExecutorSourcesAddInputSchema, outputSchema: ExecutorSourcesAddOutputSchema, execute: async (args: ExecutorSourcesAddToolArgs, context): Promise<Source> => { const executionId = toExecutionId(context?.invocation?.runId); const interactionId = ExecutionInteractionIdSchema.make( `executor.sources.add:${crypto.randomUUID()}`, ); const preparedArgs = prepareExecutorAddSourceInput({ args, scopeId: input.scopeId, actorScopeId: input.actorScopeId, executionId, interactionId, }); let result = await runEffect( input.sourceAuthService.addExecutorSource( preparedArgs, context?.onElicitation ? { mcpDiscoveryElicitation: { onElicitation: context.onElicitation, path: context.path ?? asToolPath("executor.sources.add"), sourceKey: context.sourceKey, args, metadata: context.metadata, invocation: context.invocation, }, } : undefined, ), { installationStore: input.installationStore, scopeConfigStore: input.scopeConfigStore, scopeStateStore: input.scopeStateStore, sourceArtifactStore: input.sourceArtifactStore, }, input.runtimeLocalScope, ); if (result.kind === "connected") { return toSerializableValue(result.source); } if (result.kind === "credential_required") { let pendingResult = result; if (!isExecutorCredentialManagedSourceInput(preparedArgs)) { throw new Error("Credential-managed source setup expected a named adapter kind"); } let pendingArgs: ExecutorCredentialManagedSourceInput = preparedArgs; while (pendingResult.kind === "credential_required") { const selectedAuth = await runEffect( promptForSourceCredentialSelection({ args: { ...pendingArgs, scopeId: input.scopeId, sourceId: pendingResult.source.id, }, credentialSlot: pendingResult.credentialSlot, source: pendingResult.source, executionId, interactionId, path: context?.path ?? asToolPath("executor.sources.add"), sourceKey: context?.sourceKey ?? "executor", localServerBaseUrl: input.sourceAuthService.getLocalServerBaseUrl(), metadata: context?.metadata, invocation: context?.invocation, onElicitation: context?.onElicitation, }), { installationStore: input.installationStore, scopeConfigStore: input.scopeConfigStore, scopeStateStore: input.scopeStateStore, sourceArtifactStore: input.sourceArtifactStore, }, input.runtimeLocalScope, ); pendingArgs = pendingResult.credentialSlot === "import" && pendingArgs.importAuthPolicy === "separate" ? { ...pendingArgs, importAuth: selectedAuth, } : { ...pendingArgs, auth: selectedAuth, }; const completed = await runEffect( input.sourceAuthService.addExecutorSource( pendingArgs, context?.onElicitation ? { mcpDiscoveryElicitation: { onElicitation: context.onElicitation, path: context.path ?? asToolPath("executor.sources.add"), sourceKey: context.sourceKey, args, metadata: context.metadata, invocation: context.invocation, }, } : undefined, ), { installationStore: input.installationStore, scopeConfigStore: input.scopeConfigStore, scopeStateStore: input.scopeStateStore, sourceArtifactStore: input.sourceArtifactStore, }, input.runtimeLocalScope, ); if (completed.kind === "connected") { return toSerializableValue(completed.source); } if (completed.kind === "credential_required") { pendingResult = completed; continue; } result = completed; break; } if (pendingResult.kind === "credential_required") { result = pendingResult; } } if (!context?.onElicitation) { throw new Error("executor.sources.add requires an elicitation-capable host"); } if (result.kind !== "oauth_required") { throw new Error(`Source add did not reach OAuth continuation for ${result.source.id}`); } const response: ElicitationResponse = await runEffect( context.onElicitation({ interactionId, path: context.path ?? asToolPath("executor.sources.add"), sourceKey: context.sourceKey, args: preparedArgs, metadata: context.metadata, context: context.invocation, elicitation: { mode: "url", message: `Open the provider sign-in page to connect ${result.source.name}`, url: result.authorizationUrl, elicitationId: result.sessionId, }, }), { installationStore: input.installationStore, scopeConfigStore: input.scopeConfigStore, scopeStateStore: input.scopeStateStore, sourceArtifactStore: input.sourceArtifactStore, }, input.runtimeLocalScope, ); if (response.action !== "accept") { throw new Error(`Source add was not completed for ${result.source.id}`); }