diff --git a/dist/client-CxNllqui.d.ts b/dist/client-CxNllqui.d.ts index 5e2113a..b7b5151 100644 --- a/dist/client-CxNllqui.d.ts +++ b/dist/client-CxNllqui.d.ts @@ -135,6 +135,7 @@ declare class AcpClient { private throwPromptPermissionFailureIfPresent; setSessionMode(sessionId: string, modeId: string): Promise; setSessionConfigOption(sessionId: string, configId: string, value: string): Promise; + requestExtension(method: string, params: Record): Promise>; setSessionModel(sessionId: string, modelId: string, controlOverride?: ModelControlOverride): Promise; private setSessionModelThroughConfig; private setSessionModelThroughLegacyMethod; diff --git a/dist/live-checkpoint-BSIrfgVo.js b/dist/live-checkpoint-BSIrfgVo.js index d454fd7..991d21d 100644 --- a/dist/live-checkpoint-BSIrfgVo.js +++ b/dist/live-checkpoint-BSIrfgVo.js @@ -1068,6 +1068,7 @@ function serializeSessionRecordForDisk(record) { last_agent_disconnect_reason: canonical.lastAgentDisconnectReason, protocol_version: canonical.protocolVersion, agent_capabilities: canonical.agentCapabilities, + agent_goal_capability: canonical.agentGoalCapability, title: canonical.title, messages: canonical.messages, updated_at: canonical.updated_at, @@ -1541,6 +1542,7 @@ function parseSessionRecord(raw) { lastAgentDisconnectReason: optionals.lastAgentDisconnectReason, protocolVersion: typeof record.protocol_version === "number" ? record.protocol_version : void 0, agentCapabilities: asRecord$4(record.agent_capabilities), + agentGoalCapability: asRecord$4(record.agent_goal_capability), title: conversation.title, messages: conversation.messages, updated_at: conversation.updated_at, @@ -1661,7 +1663,7 @@ const ZED_TAG_KEYS = /* @__PURE__ */ new Set([ "RedactedThinking", "ToolUse" ]); -const MAP_OBJECT_PATHS = /* @__PURE__ */ new Set(["request_token_usage", "messages.Agent.tool_results"]); +const MAP_OBJECT_PATHS = /* @__PURE__ */ new Set(["request_token_usage", "messages.Agent.tool_results", "acpx.session_options.env"]); const OPAQUE_VALUE_PATHS = /* @__PURE__ */ new Set([ "agent_capabilities", "messages.Agent.content.ToolUse.input", @@ -3104,10 +3106,10 @@ function authEnvKey(methodId) { authEnvKeyCache.set(methodId, key); return key; } -function readEnvCredential(methodId) { +function readEnvCredential(methodId, environment = process.env) { const key = authEnvKey(methodId); if (!key) return; - const value = process.env[key]; + const value = environment[key]; if (typeof value === "string" && value.trim().length > 0) return value; } function protectedEnvKey(key) { @@ -3135,8 +3137,21 @@ function promotePrefixedAuthEnvironment(env) { } return protectedKeys; } -function buildAgentEnvironment(authCredentials, sessionEnv) { - const env = { ...process.env }; +function isPlainStringEnvironment(value) { + if (value === null || typeof value !== "object" || Array.isArray(value)) return false; + const prototype = Object.getPrototypeOf(value); + return (prototype === Object.prototype || prototype === null) && Object.values(value).every((entry) => typeof entry === "string"); +} +function resolveAgentEnvironment(spawnEnvironment) { + let sourceEnvironment = process.env; + if (spawnEnvironment !== void 0) { + sourceEnvironment = spawnEnvironment(); + if (!isPlainStringEnvironment(sourceEnvironment)) throw new TypeError("ACPX spawn environment must be a plain record of string values"); + } + return sourceEnvironment; +} +function buildAgentEnvironment(authCredentials, sessionEnv, spawnEnvironment) { + const env = { ...resolveAgentEnvironment(spawnEnvironment) }; const protectedAuthEnvKeys = promotePrefixedAuthEnvironment(env); if (authCredentials) for (const [methodId, credential] of Object.entries(authCredentials)) { addAuthCredentialEnvKeys(protectedAuthEnvKeys, methodId, credential); @@ -3178,10 +3193,10 @@ function resolveConfiguredAuthCredential(methodId, authCredentials) { const configCredentials = authCredentials ?? {}; return configCredentials[methodId] ?? configCredentials[toEnvToken(methodId)]; } -function buildAgentSpawnOptions(cwd, authCredentials, sessionEnv) { +function buildAgentSpawnOptions(cwd, authCredentials, sessionEnv, spawnEnvironment) { return { cwd, - env: buildAgentEnvironment(authCredentials, sessionEnv), + env: buildAgentEnvironment(authCredentials, sessionEnv, spawnEnvironment), stdio: [ "pipe", "pipe", @@ -3961,10 +3976,13 @@ function resolveClientCapabilities(params) { ...params.elicitationModes.includes("url") ? { url: {} } : {} } } : {} }; - if (!params.devinAcp) return baseCapabilities; + const typedSessionFailureMeta = { + jetbrains: { air: { version: 1, capabilities: ["sessionFailure"] } } + }; + if (!params.devinAcp) return { ...baseCapabilities, _meta: typedSessionFailureMeta }; return { ...baseCapabilities, - _meta: DEVIN_COMPATIBILITY_CLIENT_CAPABILITIES_META + _meta: { ...typedSessionFailureMeta, ...DEVIN_COMPATIBILITY_CLIENT_CAPABILITIES_META } }; } function hasResponseField(response, field) { @@ -4216,9 +4234,21 @@ var AcpClient = class { this.lastAgentExit = void 0; this.lastKnownPid = child.pid ?? void 0; this.attachAgentLifecycleObservers(child); + if (this.options.onAgentSpawn) { + try { + if (!child.pid) throw new Error("ACPX agent spawn did not expose a valid process id."); + await this.options.onAgentSpawn({ pid: child.pid, startedAt: this.agentStartedAt }); + } catch (error) { + try { + child.kill("SIGKILL"); + } catch {} + throw error; + } + } const startupStderr = []; child.stderr.on("data", (chunk) => { this.captureStartupStderr(startupStderr, chunk); + this.options.onAgentStderr?.(String(chunk)); if (!this.options.verbose) return; process.stderr.write(chunk); }); @@ -4253,7 +4283,12 @@ var AcpClient = class { geminiAcp: isGeminiAcpCommand(spawnCommand, args), copilotAcp: isCopilotAcpCommand(spawnCommand, args), claudeAcp: isClaudeAcpCommand(spawnCommand, args), - spawnOptions: buildAgentSpawnOptions(this.options.cwd, this.options.authCredentials, this.options.sessionOptions?.env) + spawnOptions: buildAgentSpawnOptions( + this.options.spawnCwd ?? this.options.cwd, + this.options.authCredentials, + this.options.sessionOptions?.env, + this.options.spawnEnvironment + ) }; } logAgentLaunch(plan) { @@ -4279,10 +4314,17 @@ var AcpClient = class { } async spawnAgentProcess(plan) { const spawnCommand = buildAgentSpawnCommand(plan.spawnCommand, plan.args, process.platform, plan.spawnOptions.env); - const spawnedChild = spawn(spawnCommand.command, spawnCommand.args, { + const options = { ...plan.spawnOptions, windowsVerbatimArguments: spawnCommand.windowsVerbatimArguments - }); + }; + const spawnedChild = this.options.spawnAgent + ? this.options.spawnAgent({ + command: spawnCommand.command, + args: spawnCommand.args, + options + }) + : spawn(spawnCommand.command, spawnCommand.args, options); try { await waitForSpawn$1(spawnedChild); } catch (error) { @@ -4422,7 +4464,10 @@ var AcpClient = class { const createPromise = this.runConnectionRequest(() => connection.newSession({ cwd: sessionCwd, mcpServers: this.options.mcpServers ?? [], - _meta: buildClaudeCodeOptionsMeta(this.options.sessionOptions, claudeAcp) + _meta: this.isGrokBuildAcpCommand() + ? { rules: typeof this.options.sessionOptions?.systemPrompt === "string" + ? this.options.sessionOptions.systemPrompt : this.options.sessionOptions?.systemPrompt?.append ?? "" } + : buildClaudeCodeOptionsMeta(this.options.sessionOptions, claudeAcp) })); result = claudeAcp ? await withTimeout(createPromise, resolveClaudeAcpSessionCreateTimeoutMs()) : await createPromise; } catch (error) { @@ -4864,7 +4909,7 @@ var AcpClient = class { } selectAuthMethod(methods) { for (const method of methods) { - const envCredential = readEnvCredential(method.id); + const envCredential = readEnvCredential(method.id, resolveAgentEnvironment(this.options.spawnEnvironment)); if (envCredential) return { methodId: method.id, credential: envCredential, @@ -4890,7 +4935,7 @@ var AcpClient = class { } readAgentSpecificEnvCredential(methodId) { if (!this.isGrokBuildAcpCommand() || methodId !== "xai.api_key") return; - const value = process.env.XAI_API_KEY; + const value = (resolveAgentEnvironment(this.options.spawnEnvironment)).XAI_API_KEY; return typeof value === "string" && value.trim().length > 0 ? value : void 0; } selectAgentManagedAuthMethod(methodId) { @@ -5028,6 +5073,12 @@ var AcpClient = class { attachAgentLifecycleObservers(child) { child.once("exit", (exitCode, signal) => { this.recordAgentExit("process_exit", exitCode, signal); + this.options.onAgentExit?.({ + pid: child.pid ?? this.lastKnownPid, + exitCode, + signal, + exitedAt: isoNow$1() + }); }); child.once("close", (exitCode, signal) => { this.recordAgentExit("process_close", exitCode, signal); @@ -6435,6 +6486,27 @@ async function withConnectedSession(options) { //#region src/runtime/engine/prompt-turn.ts const SESSION_REPLY_IDLE_MS = 1e3; const SESSION_REPLY_DRAIN_TIMEOUT_MS = 5e3; +const TYPED_SESSION_FAILURE_CATEGORIES = /* @__PURE__ */ new Set([ + "connection", + "access", + "limit", + "service", + "request", + "unknown" +]); +function typedTerminalSessionFailureCategory(response) { + if (response === null || typeof response !== "object" || Array.isArray(response)) return null; + const meta = response._meta; + if (meta === null || typeof meta !== "object" || Array.isArray(meta)) return null; + const jetbrains = meta.jetbrains; + if (jetbrains === null || typeof jetbrains !== "object" || Array.isArray(jetbrains)) return null; + const air = jetbrains.air; + if (air === null || typeof air !== "object" || Array.isArray(air)) return null; + if (!Number.isInteger(air.version) || air.version < 1) return null; + const failure = air.sessionFailure; + if (failure === null || typeof failure !== "object" || Array.isArray(failure) || failure.severity !== "error") return null; + return typeof failure.category === "string" && TYPED_SESSION_FAILURE_CATEGORIES.has(failure.category) ? failure.category : "unknown"; +} async function runPromptTurn(params) { try { const promptPromise = params.client.prompt(params.sessionId, params.prompt, params.onPromptRequestStarted, params.onElicitation); @@ -6444,6 +6516,19 @@ async function runPromptTurn(params) { idleMs: SESSION_REPLY_IDLE_MS, timeoutMs: SESSION_REPLY_DRAIN_TIMEOUT_MS }).catch(() => {}); + const terminalFailureCategory = typedTerminalSessionFailureCategory(response); + if (terminalFailureCategory !== null) { + // Inspect provider text only in memory, before emitting the safe category. + const failure = response._meta.jetbrains.air.sessionFailure; + try { + params.onTerminalSessionFailure?.({ + category: terminalFailureCategory, + ...(typeof failure.title === "string" ? { title: failure.title.slice(0, 4096) } : {}), + ...(typeof failure.details === "string" ? { details: failure.details.slice(0, 4096) } : {}) + }); + } catch {} + throw new Error(`ACP agent reported a terminal ${terminalFailureCategory} failure.`); + } recordPromptResponseUsage(params.conversation, response.usage, params.promptMessageId); return { stopReason: response.stopReason, diff --git a/dist/runtime.d.ts b/dist/runtime.d.ts index e8102ac..2277321 100644 --- a/dist/runtime.d.ts +++ b/dist/runtime.d.ts @@ -1,7 +1,8 @@ import { _ as SessionRecord, a as AcpElicitationHandler, c as AcpElicitationResponse, f as McpServer$1, h as PermissionPolicy, i as AcpElicitationContext, l as AcpPermissionDecision, m as PermissionMode, n as SystemPromptOption, o as AcpElicitationMode, p as NonInteractivePermissionPolicy, s as AcpElicitationRequest, t as SessionAgentOptions, u as AcpPermissionRequest } from "./session-options-DwRDODlr.js"; import { a as RequestedModelUnsupportedErrorCode, i as RequestedModelUnsupportedError, n as REQUESTED_MODEL_UNSUPPORTED_ERROR_CODE, o as RequestedModelUnsupportedReason, r as REQUESTED_MODEL_UNSUPPORTED_REASONS, s as isRequestedModelUnsupportedError, t as AcpClient } from "./client-CxNllqui.js"; +import { ChildProcess, SpawnOptionsWithoutStdio } from "node:child_process"; import fs from "node:fs"; -import { ToolCallContent, ToolCallLocation, ToolKind } from "@agentclientprotocol/sdk"; +import { SessionNotification, ToolCallContent, ToolCallLocation, ToolKind } from "@agentclientprotocol/sdk"; //#region src/agent-registry.d.ts declare const DEFAULT_AGENT_NAME = "codex"; //#endregion @@ -44,6 +45,7 @@ type AcpRuntimeTurnAttachment = { data: string; }; type AcpRuntimeTurnInput = { + onTerminalSessionFailure?: (failure: { category: string; title?: string; details?: string }) => void; handle: AcpRuntimeHandle; text: string; attachments?: AcpRuntimeTurnAttachment[]; @@ -141,6 +143,11 @@ type AcpTextDeltaOriginMeta = { kind?: string; source?: string; }; +type AcpRuntimePlanEntry = { + content: string; + priority?: string; + status: "pending" | "in_progress" | "completed"; +}; type AcpRuntimeEvent = { type: "text_delta"; text: string; @@ -186,6 +193,10 @@ type AcpRuntimeEvent = { * non-null `input` schema. */ availableCommands?: AcpRuntimeAvailableCommand[]; +} | { + type: "plan"; + tag: "plan"; + entries: AcpRuntimePlanEntry[]; } | { type: "tool_call"; text: string; @@ -313,6 +324,35 @@ type AcpRuntimeOptions = { onPermissionRequest?: (req: AcpPermissionRequest, ctx: { signal: AbortSignal; }) => Promise; + /** Ephemeral allowlisted environment evaluated immediately before child spawn. */ + spawnEnvironment?: () => Record; + /** Host-only spawn cwd; does not change the cwd advertised in session/new. */ + spawnCwd?: string; + /** Host-owned verified executable launch. */ + spawnAgent?: (input: { + command: string; + args: readonly string[]; + options: SpawnOptionsWithoutStdio; + }) => ChildProcess; + onAgentSpawn?: (meta: { pid: number; startedAt: string }) => Promise | void; + onAgentStderr?: (chunk: string) => void; + onAgentExit?: (meta: { + pid?: number; + exitCode: number | null; + signal: NodeJS.Signals | null; + exitedAt: string; + }) => void; + onAcpMessage?: (direction: "inbound" | "outbound", message: unknown) => void; + /** Ephemeral full ACP notification callback; never written to session records. */ + onSessionNotification?: (notification: SessionNotification) => void; + /** Ephemeral normalized ACP client filesystem/terminal operation callback. */ + onClientOperation?: (operation: { + method: string; + status: string; + summary: string; + details?: string; + timestamp: string; + }) => void; }; type AcpFileSessionStoreOptions = { stateDir: string; @@ -369,6 +409,7 @@ declare class AcpRuntimeManager { private createAndSaveRuntimeRecord; private retainInitializedSessionOwner; startTurn(input: { + onTerminalSessionFailure?: (failure: { category: string; title?: string; details?: string }) => void; handle: AcpRuntimeHandle; text: string; attachments?: AcpRuntimeTurnAttachment[]; @@ -414,6 +455,7 @@ declare class AcpRuntimeManager { private cleanupRuntimeTurn; private finalizeRuntimeTurnRecord; runTurn(input: { + onTerminalSessionFailure?: (failure: { category: string; title?: string; details?: string }) => void; handle: AcpRuntimeHandle; text: string; attachments?: AcpRuntimeTurnAttachment[]; diff --git a/dist/runtime.js b/dist/runtime.js index a1f4a70..57117c9 100644 --- a/dist/runtime.js +++ b/dist/runtime.js @@ -371,7 +371,7 @@ const PROMPT_EVENT_PARSERS = { current_mode_update: (payload) => statusUpdateEvent("current_mode_update", payload), config_option_update: (payload) => statusUpdateEvent("config_option_update", payload), session_info_update: (payload) => statusUpdateEvent("session_info_update", payload), - plan: (payload) => statusUpdateEvent("plan", payload), + plan: planUpdateEvent, client_operation: clientOperationEvent, update: updateStatusEvent, done: () => null, @@ -424,6 +424,34 @@ function availableCommandsUpdateEvent(payload) { availableCommands }; } +function persistedGoalCapability(goal) { + if (!isRecord(goal) || goal.version !== 1 || goal.controlMethod !== "_session/goal" || !Array.isArray(goal.actions)) return; + const actions = goal.actions.filter((action) => ["set", "pause", "resume", "clear"].includes(action)); + if (!actions.includes("set") || !actions.includes("clear")) return; + return { version: 1, control_method: goal.controlMethod, actions }; +} +function restoredGoalCapability(goal) { + if (!isRecord(goal)) return; + const canonical = persistedGoalCapability({ ...goal, controlMethod: goal.control_method ?? goal.controlMethod }); + if (!canonical) return; + return { version: canonical.version, controlMethod: canonical.control_method, actions: canonical.actions }; +} + + +function planUpdateEvent(payload) { + const raw = Array.isArray(payload.entries) ? payload.entries : []; + const entries = []; + for (const entry of raw) { + if (!isRecord(entry)) continue; + const content = asTrimmedString(entry.content); + if (!content) continue; + const status = asTrimmedString(entry.status); + if (status !== "pending" && status !== "in_progress" && status !== "completed") continue; + const priority = asTrimmedString(entry.priority); + entries.push({ content, status, ...priority ? { priority } : {} }); + } + return { type: "plan", tag: "plan", entries }; +} function normalizeUsageCost(value) { if (!isRecord(value)) return; const amount = asOptionalFiniteNumber(value.amount); @@ -812,7 +840,17 @@ var AcpRuntimeManager = class { this.deps = deps; } createClient(options) { - return this.deps.clientFactory?.(options) ?? new AcpClient(options); + const patchedOptions = { + ...options, + spawnCwd: this.options.spawnCwd, + spawnEnvironment: this.options.spawnEnvironment, + spawnAgent: this.options.spawnAgent, + onAgentSpawn: this.options.onAgentSpawn, + onAgentStderr: this.options.onAgentStderr, + onAgentExit: this.options.onAgentExit, + onAcpMessage: this.options.onAcpMessage + }; + return this.deps.clientFactory?.(patchedOptions) ?? new AcpClient(patchedOptions); } createSessionOwner(input) { const owner = { @@ -821,12 +859,16 @@ var AcpRuntimeManager = class { pendingSessionUpdates: [] }; input.client.setEventHandlers({ + onAcpMessage: this.options.onAcpMessage, onSessionUpdate: (notification) => this.routeOwnedSessionUpdate(owner, notification), onClientOperation: (operation) => this.routeOwnedClientOperation(owner, operation) }); return owner; } routeOwnedSessionUpdate(owner, notification) { + try { + this.options.onSessionNotification?.(notification); + } catch {} const active = owner.activeTurn; if (active) { const { task, turn } = active; @@ -863,6 +905,9 @@ var AcpRuntimeManager = class { projection.checkpoint.request(); } routeOwnedClientOperation(owner, operation) { + try { + this.options.onClientOperation?.(operation); + } catch {} const active = owner.activeTurn; if (!active) return; const { task, turn } = active; @@ -1008,6 +1053,8 @@ var AcpRuntimeManager = class { record.closedAt = void 0; record.protocolVersion = owner.client.initializeResult?.protocolVersion; record.agentCapabilities = owner.client.initializeResult?.agentCapabilities; + record.agentGoalCapability = persistedGoalCapability(owner.client.initializeResult?._meta?.goal); + this.options.onAgentInitialize?.(owner.client.initializeResult); applyLifecycleSnapshotToRecord(record, owner.client.getAgentLifecycleSnapshot()); } async finishBufferedOwnerControl(owner, record) { @@ -1086,6 +1133,11 @@ var AcpRuntimeManager = class { record.closed = false; record.closedAt = void 0; this.closingActiveRecords.delete(record.acpxRecordId); + this.options.onAgentInitialize?.({ + protocolVersion: record.protocolVersion, + agentCapabilities: record.agentCapabilities, + _meta: record.agentGoalCapability ? { goal: restoredGoalCapability(record.agentGoalCapability) } : void 0 + }); await this.options.sessionStore.save(record); return record; } @@ -1149,6 +1201,8 @@ var AcpRuntimeManager = class { this.closingActiveRecords.delete(record.acpxRecordId); record.protocolVersion = client.initializeResult?.protocolVersion; record.agentCapabilities = client.initializeResult?.agentCapabilities; + record.agentGoalCapability = persistedGoalCapability(client.initializeResult?._meta?.goal); + this.options.onAgentInitialize?.(client.initializeResult); applyConfigOptionsToRecord(record, session.sessionResult); const modelApplication = await applyRequestedModelIfAdvertised({ client, @@ -1301,6 +1355,7 @@ var AcpRuntimeManager = class { client: turn.client, sessionId, prompt: task.promptInput, + onTerminalSessionFailure: task.input.onTerminalSessionFailure, timeoutMs: task.input.timeoutMs ?? this.options.timeoutMs, conversation: turn.conversation, promptMessageId: turn.promptMessageId, @@ -1469,6 +1524,10 @@ var AcpRuntimeManager = class { setSessionConfigOption: async (configId, value) => { return (await task.state.activeController.setResolvedSessionConfigOption(configId, value)).response; }, + requestExtension: async (method, params) => { + await this.waitForRuntimeControlSession(task, turn); + return await turn.client.requestExtension(method, params); + }, setResolvedSessionConfigOption: async (configId, value) => await this.setRuntimeResolvedSessionConfigOption(task, turn, configId, value) }; } @@ -1575,6 +1634,8 @@ var AcpRuntimeManager = class { reconcileAgentSessionId(turn.record, turn.record.agentSessionId); turn.record.protocolVersion = turn.client.initializeResult?.protocolVersion; turn.record.agentCapabilities = turn.client.initializeResult?.agentCapabilities; + turn.record.agentGoalCapability = persistedGoalCapability(turn.client.initializeResult?._meta?.goal); + this.options.onAgentInitialize?.(turn.client.initializeResult); turn.record.acpx = turn.acpxState; applyConversation(turn.record, turn.conversation); applyLifecycleSnapshotToRecord(turn.record, turn.client.getAgentLifecycleSnapshot()); @@ -1707,6 +1768,17 @@ var AcpRuntimeManager = class { }); await this.options.sessionStore.save(result.record); } + async requestExtension(input) { + const recordId = input.handle.acpxRecordId ?? input.handle.sessionKey; + return await this.withManagerLock(this.runtimeOperationLocks, recordId, async () => { + const record = await this.requireRecord(recordId); + const controller = this.activeControllers.get(record.acpxRecordId); + if (controller) return await controller.requestExtension(input.method, input.params); + return (await this.withRuntimeControlSession(record, input.sessionMode ?? "persistent", async ({ client }) => { + return await client.requestExtension(input.method, input.params); + })).value; + }); + } async cancel(handle) { await this.activeControllers.get(handle.acpxRecordId ?? handle.sessionKey)?.requestCancelActivePrompt(); } @@ -2055,6 +2127,7 @@ var AcpxRuntime = class { const turnPromise = this.getManager().then((manager) => manager.startTurn({ handle, text: input.text, + onTerminalSessionFailure: input.onTerminalSessionFailure, attachments: input.attachments, mode: input.mode, sessionMode: state.mode, @@ -2087,6 +2160,7 @@ var AcpxRuntime = class { yield* (await this.getManager()).runTurn({ handle, text: input.text, + onTerminalSessionFailure: input.onTerminalSessionFailure, attachments: input.attachments, mode: input.mode, sessionMode: state.mode, @@ -2119,6 +2193,14 @@ var AcpxRuntime = class { const { handle, state } = this.resolveManagerHandle(input.handle); await (await this.getManager()).setConfigOption(handle, input.key, input.value, state.mode); } + async requestExtension(input) { + const { handle, state } = this.resolveManagerHandle(input.handle); + return await (await this.getManager()).requestExtension({ + ...input, + handle, + sessionMode: input.sessionMode ?? state.mode + }); + } async cancel(input) { const { handle } = this.resolveManagerHandle(input.handle); await (await this.getManager()).cancel(handle); diff --git a/dist/session-options-DwRDODlr.d.ts b/dist/session-options-DwRDODlr.d.ts index c3da164..ab6c1bf 100644 --- a/dist/session-options-DwRDODlr.d.ts +++ b/dist/session-options-DwRDODlr.d.ts @@ -1,4 +1,5 @@ import { AgentCapabilities, AnyMessage, ContentBlock, CreateElicitationRequest, ElicitationContentValue, JsonRpcId, McpServer, McpServer as McpServer$1, RequestPermissionRequest, SessionConfigOption, SessionNotification, SetSessionConfigOptionResponse, ToolKind } from "@agentclientprotocol/sdk"; +import { ChildProcess, SpawnOptionsWithoutStdio } from "node:child_process"; //#region src/prompt-content.d.ts type PromptInput = ContentBlock[]; //#endregion @@ -116,6 +117,24 @@ type AcpClientOptions = { }; env?: Record; }; + /** Ephemeral child environment factory; its return value is never persisted. */ + spawnEnvironment?: () => Record; + /** Host-only child cwd, separate from the cwd advertised to ACP. */ + spawnCwd?: string; + /** Host-owned verified executable launch. */ + spawnAgent?: (input: { + command: string; + args: readonly string[]; + options: SpawnOptionsWithoutStdio; + }) => ChildProcess; + onAgentSpawn?: (meta: { pid: number; startedAt: string }) => Promise | void; + onAgentStderr?: (chunk: string) => void; + onAgentExit?: (meta: { + pid?: number; + exitCode: number | null; + signal: NodeJS.Signals | null; + exitedAt: string; + }) => void; onAcpMessage?: (direction: AcpMessageDirection, message: AcpJsonRpcMessage) => void; onAcpOutputMessage?: (direction: AcpMessageDirection, message: AcpJsonRpcMessage) => void; onSessionUpdate?: (notification: SessionNotification) => void; @@ -263,6 +282,7 @@ type SessionRecord = { lastAgentDisconnectReason?: string; protocolVersion?: number; agentCapabilities?: AgentCapabilities; + agentGoalCapability?: Record; title?: string | null; messages: SessionMessage[]; updated_at: string; @@ -295,4 +315,4 @@ type SessionAgentOptions = { }; //#endregion export { SessionRecord as _, AcpElicitationHandler as a, AcpElicitationResponse as c, AuthPolicy as d, McpServer$1 as f, PermissionStats as g, PermissionPolicy as h, AcpElicitationContext as i, AcpPermissionDecision as l, PermissionMode as m, SystemPromptOption as n, AcpElicitationMode as o, NonInteractivePermissionPolicy as p, AcpClientOptions as r, AcpElicitationRequest as s, SessionAgentOptions as t, AcpPermissionRequest as u, PromptInput as v }; -//# sourceMappingURL=session-options-DwRDODlr.d.ts.map \ No newline at end of file +//# sourceMappingURL=session-options-DwRDODlr.d.ts.map