@agentclientprotocol/codex-acp 1.8.0 → 1.10.0
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/README.md +7 -0
- package/dist/index.js +925 -62
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -22131,32 +22131,7 @@ function attachLogs(proc) {
|
|
|
22131
22131
|
});
|
|
22132
22132
|
}
|
|
22133
22133
|
|
|
22134
|
-
// src/
|
|
22135
|
-
var JETBRAINS_META_KEY = "jetbrains";
|
|
22136
|
-
var AIR_META_KEY = "air";
|
|
22137
|
-
var AIR_EXTENSION_VERSION_KEY = "version";
|
|
22138
|
-
var AIR_EXTENSION_CAPABILITIES_KEY = "capabilities";
|
|
22139
|
-
var AIR_SESSION_FAILURE_KEY = "sessionFailure";
|
|
22140
|
-
var AIR_AGENT_FILE_CHANGE_REPORT_KEY = "agentFileChangeReport";
|
|
22141
|
-
var AIR_NATIVE_SUBAGENT_SESSIONS_KEY = "nativeSubagentSessions";
|
|
22142
|
-
var AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY = "agentFileChangeReportRequest";
|
|
22143
|
-
var AIR_EXTENSION_VERSION = 1;
|
|
22144
|
-
function clientSupportsAirCapability(capabilities, capability) {
|
|
22145
|
-
const jetbrains = capabilities?._meta?.[JETBRAINS_META_KEY];
|
|
22146
|
-
const air = jetbrains?.[AIR_META_KEY];
|
|
22147
|
-
const version2 = air?.[AIR_EXTENSION_VERSION_KEY];
|
|
22148
|
-
const supported = air?.[AIR_EXTENSION_CAPABILITIES_KEY];
|
|
22149
|
-
return typeof version2 === "number" && Number.isInteger(version2) && version2 >= AIR_EXTENSION_VERSION && Array.isArray(supported) && supported.includes(capability);
|
|
22150
|
-
}
|
|
22151
|
-
|
|
22152
|
-
// src/subagents/AcpSubagents.ts
|
|
22153
|
-
function clientSupportsSubagents(capabilities) {
|
|
22154
|
-
const subagents = capabilities?.subagents;
|
|
22155
|
-
if (typeof subagents === "object" && subagents !== null && !Array.isArray(subagents)) {
|
|
22156
|
-
return true;
|
|
22157
|
-
}
|
|
22158
|
-
return clientSupportsAirCapability(capabilities, AIR_NATIVE_SUBAGENT_SESSIONS_KEY);
|
|
22159
|
-
}
|
|
22134
|
+
// src/AcpSessionExtensions.ts
|
|
22160
22135
|
function asSdkSessionNotification(notification) {
|
|
22161
22136
|
return notification;
|
|
22162
22137
|
}
|
|
@@ -23676,6 +23651,26 @@ function sameThreadGoalSnapshot(left, right) {
|
|
|
23676
23651
|
// src/CodexEventHandler.ts
|
|
23677
23652
|
import { randomUUID } from "node:crypto";
|
|
23678
23653
|
|
|
23654
|
+
// src/AirExtension.ts
|
|
23655
|
+
var JETBRAINS_META_KEY = "jetbrains";
|
|
23656
|
+
var AIR_META_KEY = "air";
|
|
23657
|
+
var AIR_EXTENSION_VERSION_KEY = "version";
|
|
23658
|
+
var AIR_EXTENSION_CAPABILITIES_KEY = "capabilities";
|
|
23659
|
+
var AIR_SESSION_FAILURE_KEY = "sessionFailure";
|
|
23660
|
+
var AIR_AGENT_FILE_CHANGE_REPORT_KEY = "agentFileChangeReport";
|
|
23661
|
+
var AIR_NATIVE_SUBAGENT_SESSIONS_KEY = "nativeSubagentSessions";
|
|
23662
|
+
var AIR_ASYNC_TASKS_KEY = "asyncTasks";
|
|
23663
|
+
var AIR_ASYNC_TASKS_BACKGROUNDED_KEY = "backgrounded";
|
|
23664
|
+
var AIR_AGENT_FILE_CHANGE_REPORT_REQUEST_KEY = "agentFileChangeReportRequest";
|
|
23665
|
+
var AIR_EXTENSION_VERSION = 1;
|
|
23666
|
+
function clientSupportsAirCapability(capabilities, capability) {
|
|
23667
|
+
const jetbrains = capabilities?._meta?.[JETBRAINS_META_KEY];
|
|
23668
|
+
const air = jetbrains?.[AIR_META_KEY];
|
|
23669
|
+
const version2 = air?.[AIR_EXTENSION_VERSION_KEY];
|
|
23670
|
+
const supported = air?.[AIR_EXTENSION_CAPABILITIES_KEY];
|
|
23671
|
+
return typeof version2 === "number" && Number.isInteger(version2) && version2 >= AIR_EXTENSION_VERSION && Array.isArray(supported) && supported.includes(capability);
|
|
23672
|
+
}
|
|
23673
|
+
|
|
23679
23674
|
// src/subagents/CodexAgentPath.ts
|
|
23680
23675
|
function normalizeAgentPath(path9) {
|
|
23681
23676
|
const normalized = path9.trim().replace(/\/+$/, "");
|
|
@@ -23731,14 +23726,14 @@ var CodexSubagentEventRouter = class _CodexSubagentEventRouter {
|
|
|
23731
23726
|
}
|
|
23732
23727
|
return childTurn;
|
|
23733
23728
|
}
|
|
23734
|
-
const
|
|
23735
|
-
if (typeof
|
|
23736
|
-
const pending = this.pendingSpawns.get(
|
|
23729
|
+
const notificationThreadId2 = notification.params.threadId;
|
|
23730
|
+
if (typeof notificationThreadId2 === "string" && this.pendingSpawns.has(notificationThreadId2)) {
|
|
23731
|
+
const pending = this.pendingSpawns.get(notificationThreadId2);
|
|
23737
23732
|
if (pending.buffered.length === _CodexSubagentEventRouter.MAX_PENDING_NOTIFICATIONS) {
|
|
23738
23733
|
pending.buffered.shift();
|
|
23739
23734
|
pending.droppedBufferedNotifications += 1;
|
|
23740
23735
|
if (pending.droppedBufferedNotifications === 1) {
|
|
23741
|
-
logger.log(`Pending subagent ${
|
|
23736
|
+
logger.log(`Pending subagent ${notificationThreadId2} exceeded the notification buffer; dropping oldest updates`);
|
|
23742
23737
|
}
|
|
23743
23738
|
}
|
|
23744
23739
|
pending.buffered.push(notification);
|
|
@@ -23823,6 +23818,25 @@ var CodexSubagentEventRouter = class _CodexSubagentEventRouter {
|
|
|
23823
23818
|
const threadId = notification.params.threadId;
|
|
23824
23819
|
return typeof threadId === "string" && this.children.has(threadId) ? this.children.get(threadId).sessionId : this.rootSessionId;
|
|
23825
23820
|
}
|
|
23821
|
+
closingChildSessions(notification) {
|
|
23822
|
+
if (!this.supported) return [];
|
|
23823
|
+
if (notification.method === "turn/completed") {
|
|
23824
|
+
if (terminalStateFromTurn(notification.params.turn.status) === void 0) return [];
|
|
23825
|
+
return this.closingChildSession(notification.params.threadId);
|
|
23826
|
+
}
|
|
23827
|
+
if (notification.method !== "item/started" && notification.method !== "item/completed") return [];
|
|
23828
|
+
const item = notification.params.item;
|
|
23829
|
+
if (item.type === "subAgentActivity") {
|
|
23830
|
+
return item.kind === "interrupted" ? this.closingChildSession(item.agentThreadId) : [];
|
|
23831
|
+
}
|
|
23832
|
+
if (item.type !== "collabAgentToolCall") return [];
|
|
23833
|
+
const closing = /* @__PURE__ */ new Map();
|
|
23834
|
+
for (const [threadId, state] of Object.entries(item.agentsStates)) {
|
|
23835
|
+
if (!state || terminalStateOf(state.status) === void 0) continue;
|
|
23836
|
+
for (const child of this.closingChildSession(threadId)) closing.set(threadId, child);
|
|
23837
|
+
}
|
|
23838
|
+
return [...closing.values()];
|
|
23839
|
+
}
|
|
23826
23840
|
takeBufferedNotifications() {
|
|
23827
23841
|
return this.replayQueue.splice(0);
|
|
23828
23842
|
}
|
|
@@ -23898,6 +23912,10 @@ var CodexSubagentEventRouter = class _CodexSubagentEventRouter {
|
|
|
23898
23912
|
isKnownChild(threadId) {
|
|
23899
23913
|
return threadId !== this.rootSessionId && (this.children.has(threadId) || this.pendingSpawns.has(threadId) || this.terminalPendingSpawns.has(threadId));
|
|
23900
23914
|
}
|
|
23915
|
+
closingChildSession(threadId) {
|
|
23916
|
+
const child = this.children.get(threadId);
|
|
23917
|
+
return child && child.terminalState === void 0 ? [{ threadId, sessionId: child.sessionId }] : [];
|
|
23918
|
+
}
|
|
23901
23919
|
async materialize(childSessionId, path9) {
|
|
23902
23920
|
if (this.children.has(childSessionId)) return;
|
|
23903
23921
|
const pending = this.pendingSpawns.get(childSessionId);
|
|
@@ -24051,6 +24069,37 @@ function fallbackName(sessionId) {
|
|
|
24051
24069
|
return `Agent ${suffix}`;
|
|
24052
24070
|
}
|
|
24053
24071
|
|
|
24072
|
+
// src/RateLimitsMap.ts
|
|
24073
|
+
function rateLimitId(snapshot, fallback = "codex") {
|
|
24074
|
+
return snapshot.limitId ?? fallback;
|
|
24075
|
+
}
|
|
24076
|
+
function createRateLimitsMap(response) {
|
|
24077
|
+
const result = /* @__PURE__ */ new Map();
|
|
24078
|
+
const snapshots = Object.entries(response.rateLimitsByLimitId ?? {}).filter((entry) => entry[1] !== void 0);
|
|
24079
|
+
if (snapshots.length === 0) {
|
|
24080
|
+
snapshots.push([rateLimitId(response.rateLimits), response.rateLimits]);
|
|
24081
|
+
}
|
|
24082
|
+
for (const [fallbackId, snapshot] of snapshots) {
|
|
24083
|
+
const limitId = rateLimitId(snapshot, fallbackId);
|
|
24084
|
+
result.set(limitId, {
|
|
24085
|
+
limitId,
|
|
24086
|
+
limitName: snapshot.limitName ?? limitId,
|
|
24087
|
+
snapshot
|
|
24088
|
+
});
|
|
24089
|
+
}
|
|
24090
|
+
return result;
|
|
24091
|
+
}
|
|
24092
|
+
function mergeRateLimitSnapshot(previous, update) {
|
|
24093
|
+
return {
|
|
24094
|
+
...update,
|
|
24095
|
+
limitId: update.limitId ?? "codex",
|
|
24096
|
+
credits: update.credits ?? previous.credits,
|
|
24097
|
+
individualLimit: update.individualLimit ?? previous.individualLimit,
|
|
24098
|
+
spendControlReached: update.spendControlReached ?? previous.spendControlReached,
|
|
24099
|
+
planType: update.planType ?? previous.planType
|
|
24100
|
+
};
|
|
24101
|
+
}
|
|
24102
|
+
|
|
24054
24103
|
// src/CodexEventHandler.ts
|
|
24055
24104
|
var MAX_SESSION_FAILURE_TITLE_LENGTH = 240;
|
|
24056
24105
|
var SESSION_FAILURE_POLICY = {
|
|
@@ -24159,11 +24208,14 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24159
24208
|
terminalCommandOutputIds = /* @__PURE__ */ new Set();
|
|
24160
24209
|
agentMessagePhases = /* @__PURE__ */ new Map();
|
|
24161
24210
|
subagents;
|
|
24211
|
+
/** Connection-level `authStatus` sink; the app-server account push feeds it. */
|
|
24212
|
+
onAccountUpdated;
|
|
24162
24213
|
constructor(connection, sessionState, supportsPlanUpdates = false, supportsTypedSessionFailures = false, sessionFailureEpoch = randomUUID(), subagents = new CodexSubagentEventRouter(
|
|
24163
24214
|
sessionState.sessionId,
|
|
24164
24215
|
false,
|
|
24165
24216
|
new ACPSessionConnection(connection, sessionState.sessionId)
|
|
24166
|
-
)) {
|
|
24217
|
+
), onAccountUpdated) {
|
|
24218
|
+
this.onAccountUpdated = onAccountUpdated;
|
|
24167
24219
|
this.sessionState = sessionState;
|
|
24168
24220
|
this.supportsPlanUpdates = supportsPlanUpdates;
|
|
24169
24221
|
this.supportsTypedSessionFailures = supportsTypedSessionFailures;
|
|
@@ -24272,17 +24324,29 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24272
24324
|
}
|
|
24273
24325
|
async handleNotification(notification) {
|
|
24274
24326
|
await this.flushPendingErrors();
|
|
24327
|
+
const closingChildren = this.subagents.closingChildSessions(notification);
|
|
24328
|
+
for (const child of closingChildren) {
|
|
24329
|
+
await this.sessionState.asyncTasks.reconcile(child.threadId, child.sessionId);
|
|
24330
|
+
}
|
|
24275
24331
|
const handledBySubagents = await this.subagents.handle(notification);
|
|
24276
24332
|
for (const buffered of this.subagents.takeBufferedNotifications()) {
|
|
24277
24333
|
await this.handleNotification(buffered);
|
|
24278
24334
|
}
|
|
24279
|
-
|
|
24280
|
-
|
|
24335
|
+
const ignoredBySubagents = !handledBySubagents && this.subagents.shouldIgnore(notification);
|
|
24336
|
+
let updateEvent;
|
|
24337
|
+
if (!handledBySubagents && !ignoredBySubagents && notification.method === "item/started" && notification.params.item.type === "commandExecution") {
|
|
24338
|
+
updateEvent = await this.createUpdateEvent(notification);
|
|
24281
24339
|
}
|
|
24282
|
-
if (
|
|
24283
|
-
|
|
24340
|
+
if (!handledBySubagents) {
|
|
24341
|
+
await this.sessionState.asyncTasks.handleNotification(
|
|
24342
|
+
notification,
|
|
24343
|
+
this.subagents.notificationSessionId(notification),
|
|
24344
|
+
toolCallTitle(updateEvent)
|
|
24345
|
+
);
|
|
24284
24346
|
}
|
|
24285
|
-
|
|
24347
|
+
if (handledBySubagents) return;
|
|
24348
|
+
if (ignoredBySubagents) return;
|
|
24349
|
+
if (updateEvent === void 0) updateEvent = await this.createUpdateEvent(notification);
|
|
24286
24350
|
if (updateEvent) {
|
|
24287
24351
|
await this.session.update(updateEvent, this.subagents.notificationSessionId(notification));
|
|
24288
24352
|
}
|
|
@@ -24387,6 +24451,9 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24387
24451
|
case "account/rateLimits/updated":
|
|
24388
24452
|
this.handleRateLimitsUpdated(notification.params);
|
|
24389
24453
|
return null;
|
|
24454
|
+
case "account/updated":
|
|
24455
|
+
this.onAccountUpdated?.(notification.params);
|
|
24456
|
+
return null;
|
|
24390
24457
|
case "configWarning":
|
|
24391
24458
|
return await this.createConfigWarningEvent(notification.params);
|
|
24392
24459
|
case "warning":
|
|
@@ -24437,7 +24504,6 @@ var CodexEventHandler = class _CodexEventHandler {
|
|
|
24437
24504
|
case "turn/moderationMetadata":
|
|
24438
24505
|
case "item/fileChange/outputDelta":
|
|
24439
24506
|
case "item/fileChange/patchUpdated":
|
|
24440
|
-
case "account/updated":
|
|
24441
24507
|
case "fs/changed":
|
|
24442
24508
|
case "mcpServer/startupStatus/updated":
|
|
24443
24509
|
case "mcpServer/event/stream/notification":
|
|
@@ -25083,11 +25149,13 @@ ${event.stdin}
|
|
|
25083
25149
|
if (!this.sessionState.rateLimits) {
|
|
25084
25150
|
this.sessionState.rateLimits = /* @__PURE__ */ new Map();
|
|
25085
25151
|
}
|
|
25086
|
-
const limitId = params.rateLimits.limitId ??
|
|
25152
|
+
const limitId = params.rateLimits.limitId ?? "codex";
|
|
25153
|
+
const existingEntry = this.sessionState.rateLimits.get(limitId);
|
|
25154
|
+
const snapshot = existingEntry ? mergeRateLimitSnapshot(existingEntry.snapshot, params.rateLimits) : { ...params.rateLimits, limitId };
|
|
25087
25155
|
this.sessionState.rateLimits.set(limitId, {
|
|
25088
25156
|
limitId,
|
|
25089
|
-
limitName:
|
|
25090
|
-
snapshot
|
|
25157
|
+
limitName: snapshot.limitName ?? existingEntry?.limitName ?? limitId,
|
|
25158
|
+
snapshot
|
|
25091
25159
|
});
|
|
25092
25160
|
}
|
|
25093
25161
|
handleFuzzyFileSearchSessionUpdated(params) {
|
|
@@ -25115,6 +25183,10 @@ ${event.stdin}
|
|
|
25115
25183
|
return createGuardianApprovalReviewToolCall(params);
|
|
25116
25184
|
}
|
|
25117
25185
|
};
|
|
25186
|
+
function toolCallTitle(update) {
|
|
25187
|
+
if (update?.sessionUpdate !== "tool_call") return void 0;
|
|
25188
|
+
return update.title;
|
|
25189
|
+
}
|
|
25118
25190
|
|
|
25119
25191
|
// src/permissions/option-ids.ts
|
|
25120
25192
|
var ApprovalOptionId = {
|
|
@@ -27247,7 +27319,7 @@ var package_default = {
|
|
|
27247
27319
|
publishConfig: {
|
|
27248
27320
|
access: "public"
|
|
27249
27321
|
},
|
|
27250
|
-
version: "1.
|
|
27322
|
+
version: "1.10.0",
|
|
27251
27323
|
description: "",
|
|
27252
27324
|
main: "dist/index.js",
|
|
27253
27325
|
bin: {
|
|
@@ -27310,7 +27382,7 @@ var package_default = {
|
|
|
27310
27382
|
},
|
|
27311
27383
|
dependencies: {
|
|
27312
27384
|
"@agentclientprotocol/sdk": "^1.4.0",
|
|
27313
|
-
"@openai/codex": "^0.
|
|
27385
|
+
"@openai/codex": "^0.153.3",
|
|
27314
27386
|
diff: "^9.0.0",
|
|
27315
27387
|
open: "^11.0.1",
|
|
27316
27388
|
"vscode-jsonrpc": "^9.0.1",
|
|
@@ -27908,6 +27980,12 @@ var CodexAcpClient = class {
|
|
|
27908
27980
|
config;
|
|
27909
27981
|
modelProvider;
|
|
27910
27982
|
gatewayConfig;
|
|
27983
|
+
/**
|
|
27984
|
+
* Where the stored gateway routing came from: the `gateway` auth method
|
|
27985
|
+
* (agent-owned authentication) or the ACP `providers/*` API (client-driven
|
|
27986
|
+
* routing). `authStatus` reports only the agent-owned one.
|
|
27987
|
+
*/
|
|
27988
|
+
gatewayConfigSource;
|
|
27911
27989
|
pendingLoginCompleted = null;
|
|
27912
27990
|
pendingAccountUpdated = null;
|
|
27913
27991
|
sessionNotificationQueues = /* @__PURE__ */ new Map();
|
|
@@ -27919,6 +27997,7 @@ var CodexAcpClient = class {
|
|
|
27919
27997
|
this.config = codexConfig ?? {};
|
|
27920
27998
|
this.modelProvider = modelProvider ?? null;
|
|
27921
27999
|
this.gatewayConfig = null;
|
|
28000
|
+
this.gatewayConfigSource = null;
|
|
27922
28001
|
this.subagents = new CodexSubagentSubscriptions(codexClient);
|
|
27923
28002
|
}
|
|
27924
28003
|
get appServerClient() {
|
|
@@ -27951,6 +28030,7 @@ var CodexAcpClient = class {
|
|
|
27951
28030
|
throw RequestError.invalidRequest();
|
|
27952
28031
|
}
|
|
27953
28032
|
this.gatewayConfig = null;
|
|
28033
|
+
this.gatewayConfigSource = null;
|
|
27954
28034
|
switch (authRequest.methodId) {
|
|
27955
28035
|
case "api-key":
|
|
27956
28036
|
return await this.authenticateWithApiKey(authRequest);
|
|
@@ -28034,7 +28114,7 @@ var CodexAcpClient = class {
|
|
|
28034
28114
|
apiType: GatewayAuthMethod._meta.gateway.protocol,
|
|
28035
28115
|
headers: gatewaySettings.headers,
|
|
28036
28116
|
providerName: gatewaySettings.providerName
|
|
28037
|
-
});
|
|
28117
|
+
}, "authentication");
|
|
28038
28118
|
return true;
|
|
28039
28119
|
}
|
|
28040
28120
|
readApiKeyFromEnv() {
|
|
@@ -28080,6 +28160,11 @@ var CodexAcpClient = class {
|
|
|
28080
28160
|
};
|
|
28081
28161
|
}
|
|
28082
28162
|
}
|
|
28163
|
+
/**
|
|
28164
|
+
* The provider that actually serves requests, ACP-configured gateway
|
|
28165
|
+
* routing included. Use {@link getAgentConfiguredModelProvider} instead
|
|
28166
|
+
* when asking what the agent itself is configured with (`authStatus`).
|
|
28167
|
+
*/
|
|
28083
28168
|
async getCurrentModelProvider() {
|
|
28084
28169
|
const sessionModelProvider = this.getModelProvider();
|
|
28085
28170
|
if (sessionModelProvider !== null) {
|
|
@@ -28105,7 +28190,7 @@ var CodexAcpClient = class {
|
|
|
28105
28190
|
* method and the ACP `providers/set` method. Throws `invalid_params` for an
|
|
28106
28191
|
* unsupported protocol or a malformed base URL.
|
|
28107
28192
|
*/
|
|
28108
|
-
applyGatewayConfig(params) {
|
|
28193
|
+
applyGatewayConfig(params, source) {
|
|
28109
28194
|
const apiType = params.apiType;
|
|
28110
28195
|
const wireApi = SUPPORTED_GATEWAY_PROTOCOLS[apiType];
|
|
28111
28196
|
if (!wireApi) {
|
|
@@ -28122,6 +28207,7 @@ var CodexAcpClient = class {
|
|
|
28122
28207
|
"X-Client-Feature-ID": "codex",
|
|
28123
28208
|
...params.headers
|
|
28124
28209
|
};
|
|
28210
|
+
this.gatewayConfigSource = source;
|
|
28125
28211
|
this.gatewayConfig = {
|
|
28126
28212
|
modelProvider: CUSTOM_GATEWAY_PROVIDER_ID,
|
|
28127
28213
|
config: {
|
|
@@ -28186,7 +28272,7 @@ var CodexAcpClient = class {
|
|
|
28186
28272
|
apiType: request.apiType,
|
|
28187
28273
|
baseUrl: request.baseUrl,
|
|
28188
28274
|
headers: request.headers
|
|
28189
|
-
});
|
|
28275
|
+
}, "acpProviders");
|
|
28190
28276
|
logger.log("providers/set applied", {
|
|
28191
28277
|
providerId: request.providerId,
|
|
28192
28278
|
apiType: request.apiType,
|
|
@@ -28202,6 +28288,7 @@ var CodexAcpClient = class {
|
|
|
28202
28288
|
const overrideWasActive = this.gatewayConfig !== null;
|
|
28203
28289
|
if (request.providerId === OPENAI_PROVIDER_ID) {
|
|
28204
28290
|
this.gatewayConfig = null;
|
|
28291
|
+
this.gatewayConfigSource = null;
|
|
28205
28292
|
}
|
|
28206
28293
|
const current = this.gatewayConfig ? {
|
|
28207
28294
|
apiType: gatewayApiTypeFromConfig(this.gatewayConfig),
|
|
@@ -28219,6 +28306,36 @@ var CodexAcpClient = class {
|
|
|
28219
28306
|
async getAccount() {
|
|
28220
28307
|
return this.codexClient.accountRead({ refreshToken: false });
|
|
28221
28308
|
}
|
|
28309
|
+
async getRateLimits() {
|
|
28310
|
+
return this.codexClient.accountRateLimitsRead();
|
|
28311
|
+
}
|
|
28312
|
+
/**
|
|
28313
|
+
* Presentable name of the gateway the agent itself authenticated against
|
|
28314
|
+
* (the `gateway` auth method), or `null`. Routing that the client
|
|
28315
|
+
* configured through `providers/set` is deliberately not reported here:
|
|
28316
|
+
* `authStatus` describes the agent-owned login only.
|
|
28317
|
+
*/
|
|
28318
|
+
getAuthGatewayProviderName() {
|
|
28319
|
+
return this.gatewayConfigSource === "authentication" ? this.gatewayConfig?.config.name ?? null : null;
|
|
28320
|
+
}
|
|
28321
|
+
/** Whether this provider id is client-driven routing set through `providers/set`. */
|
|
28322
|
+
isClientConfiguredProvider(providerId) {
|
|
28323
|
+
return providerId === CUSTOM_GATEWAY_PROVIDER_ID && this.gatewayConfigSource === "acpProviders";
|
|
28324
|
+
}
|
|
28325
|
+
/**
|
|
28326
|
+
* The model provider the agent itself is configured with (launch option or
|
|
28327
|
+
* Codex config), ignoring any ACP-configured gateway routing. The
|
|
28328
|
+
* routing-aware counterpart is {@link getCurrentModelProvider}.
|
|
28329
|
+
*/
|
|
28330
|
+
async getAgentConfiguredModelProvider() {
|
|
28331
|
+
const provider = this.getModelProvider();
|
|
28332
|
+
const agentProvider = this.isClientConfiguredProvider(provider) ? this.modelProvider : provider;
|
|
28333
|
+
if (agentProvider !== null) {
|
|
28334
|
+
return agentProvider;
|
|
28335
|
+
}
|
|
28336
|
+
const settingsModelProvider = await this.codexClient.configRead({ includeLayers: false });
|
|
28337
|
+
return settingsModelProvider?.config?.model_provider ?? null;
|
|
28338
|
+
}
|
|
28222
28339
|
async resumeSession(request, onSubscribed) {
|
|
28223
28340
|
const additionalDirectories = readAdditionalDirectories(request.cwd, request.additionalDirectories, request._meta);
|
|
28224
28341
|
await this.refreshSkills(request.cwd, additionalDirectories);
|
|
@@ -29408,6 +29525,12 @@ var CodexAppServerClient = class {
|
|
|
29408
29525
|
async threadCompactStart(params) {
|
|
29409
29526
|
return await this.sendRequest({ method: "thread/compact/start", params });
|
|
29410
29527
|
}
|
|
29528
|
+
async threadBackgroundTerminalsList(params) {
|
|
29529
|
+
return await this.sendRequest({ method: "thread/backgroundTerminals/list", params });
|
|
29530
|
+
}
|
|
29531
|
+
async threadBackgroundTerminalsTerminate(params) {
|
|
29532
|
+
return await this.sendRequest({ method: "thread/backgroundTerminals/terminate", params });
|
|
29533
|
+
}
|
|
29411
29534
|
async threadGoalSet(params) {
|
|
29412
29535
|
return await this.sendRequest({ method: "thread/goal/set", params });
|
|
29413
29536
|
}
|
|
@@ -29473,6 +29596,9 @@ var CodexAppServerClient = class {
|
|
|
29473
29596
|
async accountRead(params) {
|
|
29474
29597
|
return await this.sendRequest({ method: "account/read", params });
|
|
29475
29598
|
}
|
|
29599
|
+
async accountRateLimitsRead() {
|
|
29600
|
+
return await this.sendRequest({ method: "account/rateLimits/read", params: void 0 });
|
|
29601
|
+
}
|
|
29476
29602
|
//TODO create type-safe helper
|
|
29477
29603
|
async awaitTurnCompleted(threadId, turnId) {
|
|
29478
29604
|
return await new Promise((resolve) => {
|
|
@@ -30079,6 +30205,7 @@ var CodexCommands = class {
|
|
|
30079
30205
|
return { handled: true, turnCompleted };
|
|
30080
30206
|
}
|
|
30081
30207
|
case "status": {
|
|
30208
|
+
await this.refreshRateLimits(sessionState);
|
|
30082
30209
|
const session = new ACPSessionConnection(this.connection, sessionId);
|
|
30083
30210
|
const message = this.buildStatusMessage(sessionState);
|
|
30084
30211
|
await session.update(createAgentTextMessageChunk(message));
|
|
@@ -30227,6 +30354,16 @@ var CodexCommands = class {
|
|
|
30227
30354
|
];
|
|
30228
30355
|
return lines.join(" \n");
|
|
30229
30356
|
}
|
|
30357
|
+
async refreshRateLimits(sessionState) {
|
|
30358
|
+
try {
|
|
30359
|
+
const response = await this.runWithProcessCheck(() => this.codexAcpClient.getRateLimits());
|
|
30360
|
+
if (response) {
|
|
30361
|
+
sessionState.rateLimits = createRateLimitsMap(response);
|
|
30362
|
+
}
|
|
30363
|
+
} catch (err) {
|
|
30364
|
+
logger.error(`Failed to refresh rate limits for session ${sessionState.sessionId}`, err);
|
|
30365
|
+
}
|
|
30366
|
+
}
|
|
30230
30367
|
formatAccountInfo(account) {
|
|
30231
30368
|
if (!account) {
|
|
30232
30369
|
return "not logged in";
|
|
@@ -30257,10 +30394,10 @@ var CodexCommands = class {
|
|
|
30257
30394
|
return "data not available yet";
|
|
30258
30395
|
}
|
|
30259
30396
|
const used = usage.totalTokens;
|
|
30260
|
-
const
|
|
30397
|
+
const percentUsed = Math.round(used / contextWindow * 100);
|
|
30261
30398
|
const usedFormatted = this.formatTokenCount(used);
|
|
30262
30399
|
const totalFormatted = this.formatTokenCount(contextWindow);
|
|
30263
|
-
return `${
|
|
30400
|
+
return `${percentUsed}% used (${usedFormatted} used / ${totalFormatted})`;
|
|
30264
30401
|
}
|
|
30265
30402
|
formatRateLimitLines(rateLimits) {
|
|
30266
30403
|
if (!rateLimits || rateLimits.size === 0) {
|
|
@@ -30294,8 +30431,31 @@ var CodexCommands = class {
|
|
|
30294
30431
|
lines.push(`**${prefix}Credits:** ${rateLimits.credits.balance}`);
|
|
30295
30432
|
}
|
|
30296
30433
|
}
|
|
30434
|
+
if (rateLimits.individualLimit) {
|
|
30435
|
+
const limit = rateLimits.individualLimit;
|
|
30436
|
+
const used = this.formatCreditAmount(limit.used);
|
|
30437
|
+
const total = this.formatCreditAmount(limit.limit);
|
|
30438
|
+
if (used !== null && total !== null) {
|
|
30439
|
+
const percentLeft = Math.round(Math.min(100, Math.max(0, limit.remainingPercent)));
|
|
30440
|
+
const resetDate = new Date(limit.resetsAt * 1e3).toLocaleDateString("en-US", { month: "short", day: "numeric" });
|
|
30441
|
+
lines.push(
|
|
30442
|
+
`**${prefix}individual spend limit:** ${percentLeft}% left (${used} of ${total} credits used; resets ${resetDate})`
|
|
30443
|
+
);
|
|
30444
|
+
}
|
|
30445
|
+
}
|
|
30297
30446
|
return lines;
|
|
30298
30447
|
}
|
|
30448
|
+
formatCreditAmount(raw) {
|
|
30449
|
+
const trimmed = raw.trim();
|
|
30450
|
+
if (trimmed.length === 0) {
|
|
30451
|
+
return null;
|
|
30452
|
+
}
|
|
30453
|
+
const value = Number(trimmed);
|
|
30454
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
30455
|
+
return null;
|
|
30456
|
+
}
|
|
30457
|
+
return Math.round(value).toLocaleString("en-US");
|
|
30458
|
+
}
|
|
30299
30459
|
formatWindowLabel(windowDurationMins) {
|
|
30300
30460
|
if (windowDurationMins === null) {
|
|
30301
30461
|
return "Limit";
|
|
@@ -31342,11 +31502,147 @@ function numberValue(value) {
|
|
|
31342
31502
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
31343
31503
|
}
|
|
31344
31504
|
|
|
31505
|
+
// src/async-tasks/AsyncTaskExtension.ts
|
|
31506
|
+
var ASYNC_TASK_STOP_METHOD = "_session/async_task/stop";
|
|
31507
|
+
|
|
31508
|
+
// src/AuthStatusMeta.ts
|
|
31509
|
+
var AUTH_STATUS_UPDATE_METHOD = "_auth/status_update";
|
|
31510
|
+
var AUTH_STATUS_META_KEY = "authStatus";
|
|
31511
|
+
function authStatusCapability() {
|
|
31512
|
+
return {};
|
|
31513
|
+
}
|
|
31514
|
+
var NOT_LOGGED_IN_LABEL = "Not logged in";
|
|
31515
|
+
var DEFAULT_GATEWAY_LABEL = "Custom model gateway";
|
|
31516
|
+
var PLAN_DISPLAY_NAMES = {
|
|
31517
|
+
free: "Free",
|
|
31518
|
+
go: "Go",
|
|
31519
|
+
plus: "Plus",
|
|
31520
|
+
pro: "Pro",
|
|
31521
|
+
team: "Team",
|
|
31522
|
+
business: "Business",
|
|
31523
|
+
enterprise: "Enterprise",
|
|
31524
|
+
edu: "Edu"
|
|
31525
|
+
};
|
|
31526
|
+
function planTypePresentable(planType) {
|
|
31527
|
+
if (!planType || planType === "unknown") {
|
|
31528
|
+
return null;
|
|
31529
|
+
}
|
|
31530
|
+
return PLAN_DISPLAY_NAMES[planType] ?? capitalize2(planType);
|
|
31531
|
+
}
|
|
31532
|
+
function capitalize2(value) {
|
|
31533
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
31534
|
+
}
|
|
31535
|
+
function chatGptLabel(planType) {
|
|
31536
|
+
const plan = planTypePresentable(planType);
|
|
31537
|
+
return plan === null ? "ChatGPT" : `ChatGPT ${plan}`;
|
|
31538
|
+
}
|
|
31539
|
+
function gatewayStatus(providerName) {
|
|
31540
|
+
const detail = typeof providerName === "string" && providerName.trim().length > 0 ? providerName.trim() : void 0;
|
|
31541
|
+
return {
|
|
31542
|
+
kind: "gateway",
|
|
31543
|
+
label: DEFAULT_GATEWAY_LABEL,
|
|
31544
|
+
...detail === void 0 ? {} : { detail }
|
|
31545
|
+
};
|
|
31546
|
+
}
|
|
31547
|
+
function unauthenticatedStatus() {
|
|
31548
|
+
return {
|
|
31549
|
+
kind: "none",
|
|
31550
|
+
label: NOT_LOGGED_IN_LABEL
|
|
31551
|
+
};
|
|
31552
|
+
}
|
|
31553
|
+
function fromAccount(account) {
|
|
31554
|
+
if (account === null) {
|
|
31555
|
+
return unauthenticatedStatus();
|
|
31556
|
+
}
|
|
31557
|
+
switch (account.type) {
|
|
31558
|
+
case "chatgpt": {
|
|
31559
|
+
const accountInfo = {};
|
|
31560
|
+
if (account.email) {
|
|
31561
|
+
accountInfo.email = account.email;
|
|
31562
|
+
}
|
|
31563
|
+
if (account.planType) {
|
|
31564
|
+
accountInfo.plan = account.planType;
|
|
31565
|
+
}
|
|
31566
|
+
return {
|
|
31567
|
+
kind: "account",
|
|
31568
|
+
label: chatGptLabel(account.planType),
|
|
31569
|
+
...Object.keys(accountInfo).length > 0 ? { account: accountInfo } : {}
|
|
31570
|
+
};
|
|
31571
|
+
}
|
|
31572
|
+
case "apiKey":
|
|
31573
|
+
return {
|
|
31574
|
+
kind: "api_key",
|
|
31575
|
+
label: "OpenAI API key"
|
|
31576
|
+
};
|
|
31577
|
+
case "amazonBedrock":
|
|
31578
|
+
return {
|
|
31579
|
+
kind: "external",
|
|
31580
|
+
label: "AWS Bedrock"
|
|
31581
|
+
};
|
|
31582
|
+
}
|
|
31583
|
+
}
|
|
31584
|
+
function fromAccountUpdated(notification, previous) {
|
|
31585
|
+
const authMode = notification.authMode;
|
|
31586
|
+
if (authMode === null) {
|
|
31587
|
+
return unauthenticatedStatus();
|
|
31588
|
+
}
|
|
31589
|
+
switch (authMode) {
|
|
31590
|
+
case "chatgpt":
|
|
31591
|
+
case "chatgptAuthTokens": {
|
|
31592
|
+
const status = {
|
|
31593
|
+
kind: "account",
|
|
31594
|
+
label: chatGptLabel(notification.planType)
|
|
31595
|
+
};
|
|
31596
|
+
const accountInfo = {};
|
|
31597
|
+
const previousEmail = previous?.kind === "account" ? previous.account?.email : void 0;
|
|
31598
|
+
if (previousEmail) {
|
|
31599
|
+
accountInfo.email = previousEmail;
|
|
31600
|
+
}
|
|
31601
|
+
if (notification.planType) {
|
|
31602
|
+
accountInfo.plan = notification.planType;
|
|
31603
|
+
}
|
|
31604
|
+
if (Object.keys(accountInfo).length > 0) {
|
|
31605
|
+
status.account = accountInfo;
|
|
31606
|
+
}
|
|
31607
|
+
return status;
|
|
31608
|
+
}
|
|
31609
|
+
case "apikey":
|
|
31610
|
+
return {
|
|
31611
|
+
kind: "api_key",
|
|
31612
|
+
label: "OpenAI API key"
|
|
31613
|
+
};
|
|
31614
|
+
case "personalAccessToken":
|
|
31615
|
+
return {
|
|
31616
|
+
kind: "api_key",
|
|
31617
|
+
label: "OpenAI personal access token"
|
|
31618
|
+
};
|
|
31619
|
+
case "bedrockApiKey":
|
|
31620
|
+
case "bedrockAccessKeys":
|
|
31621
|
+
return {
|
|
31622
|
+
kind: "external",
|
|
31623
|
+
label: "AWS Bedrock"
|
|
31624
|
+
};
|
|
31625
|
+
case "agentIdentity":
|
|
31626
|
+
return {
|
|
31627
|
+
kind: "external",
|
|
31628
|
+
label: "Agent identity"
|
|
31629
|
+
};
|
|
31630
|
+
case "headers":
|
|
31631
|
+
return gatewayStatus();
|
|
31632
|
+
}
|
|
31633
|
+
}
|
|
31634
|
+
function sameAuthStatus(previous, next) {
|
|
31635
|
+
if (!previous) {
|
|
31636
|
+
return false;
|
|
31637
|
+
}
|
|
31638
|
+
return previous.kind === next.kind && previous.label === next.label && previous.detail === next.detail && previous.account?.email === next.account?.email && previous.account?.organization === next.account?.organization && previous.account?.plan === next.account?.plan && JSON.stringify(previous.vendor) === JSON.stringify(next.vendor);
|
|
31639
|
+
}
|
|
31640
|
+
|
|
31345
31641
|
// src/AcpExtensions.ts
|
|
31346
31642
|
var LEGACY_SET_SESSION_MODEL_METHOD = "session/set_model";
|
|
31347
31643
|
var SESSION_STEERING_METHOD = "_session/steering";
|
|
31348
31644
|
function isExtMethodRequest(request) {
|
|
31349
|
-
return request.method === "authentication/status" || request.method === "authentication/logout" || request.method === LEGACY_SET_SESSION_MODEL_METHOD || request.method === GOAL_CONTROL_METHOD || request.method === LEGACY_GOAL_CONTROL_METHOD || request.method === SESSION_STEERING_METHOD;
|
|
31645
|
+
return request.method === "authentication/status" || request.method === "authentication/logout" || request.method === LEGACY_SET_SESSION_MODEL_METHOD || request.method === GOAL_CONTROL_METHOD || request.method === LEGACY_GOAL_CONTROL_METHOD || request.method === SESSION_STEERING_METHOD || request.method === ASYNC_TASK_STOP_METHOD;
|
|
31350
31646
|
}
|
|
31351
31647
|
|
|
31352
31648
|
// src/FastModeConfig.ts
|
|
@@ -31413,6 +31709,15 @@ function clientSupportsPlanUpdates(clientCapabilities) {
|
|
|
31413
31709
|
return clientCapabilities?.plan != null;
|
|
31414
31710
|
}
|
|
31415
31711
|
|
|
31712
|
+
// src/subagents/AcpSubagents.ts
|
|
31713
|
+
function clientSupportsSubagents(capabilities) {
|
|
31714
|
+
const subagents = capabilities?.subagents;
|
|
31715
|
+
if (typeof subagents === "object" && subagents !== null && !Array.isArray(subagents)) {
|
|
31716
|
+
return true;
|
|
31717
|
+
}
|
|
31718
|
+
return clientSupportsAirCapability(capabilities, AIR_NATIVE_SUBAGENT_SESSIONS_KEY);
|
|
31719
|
+
}
|
|
31720
|
+
|
|
31416
31721
|
// src/CodexAcpServer.ts
|
|
31417
31722
|
import { randomUUID as randomUUID2 } from "node:crypto";
|
|
31418
31723
|
|
|
@@ -31501,6 +31806,332 @@ function extractTitle(turn) {
|
|
|
31501
31806
|
|
|
31502
31807
|
// src/CodexAcpServer.ts
|
|
31503
31808
|
import { once } from "node:events";
|
|
31809
|
+
|
|
31810
|
+
// src/async-tasks/CodexBackgroundTerminalTasks.ts
|
|
31811
|
+
var CodexBackgroundTerminalTasks = class {
|
|
31812
|
+
constructor(enabled, rootSessionId, appServer, session) {
|
|
31813
|
+
this.enabled = enabled;
|
|
31814
|
+
this.rootSessionId = rootSessionId;
|
|
31815
|
+
this.appServer = appServer;
|
|
31816
|
+
this.session = session;
|
|
31817
|
+
}
|
|
31818
|
+
enabled;
|
|
31819
|
+
rootSessionId;
|
|
31820
|
+
appServer;
|
|
31821
|
+
session;
|
|
31822
|
+
tasks = /* @__PURE__ */ new Map();
|
|
31823
|
+
syncs = /* @__PURE__ */ new Map();
|
|
31824
|
+
appServerGeneration = 0;
|
|
31825
|
+
appServerQueriesEnabled = true;
|
|
31826
|
+
disposed = false;
|
|
31827
|
+
async handleNotification(notification, sessionId, commandTitle2) {
|
|
31828
|
+
if (!this.isActive()) return;
|
|
31829
|
+
const threadId = notificationThreadId(notification);
|
|
31830
|
+
if (threadId === null) return;
|
|
31831
|
+
if (notification.method === "item/started" && notification.params.item.type === "commandExecution") {
|
|
31832
|
+
this.observeCommandStarted(notification.params.item, threadId, sessionId, commandTitle2);
|
|
31833
|
+
return;
|
|
31834
|
+
}
|
|
31835
|
+
if (notification.method === "item/completed" && notification.params.item.type === "commandExecution") {
|
|
31836
|
+
await this.observeCommandCompleted(notification.params.item, threadId);
|
|
31837
|
+
return;
|
|
31838
|
+
}
|
|
31839
|
+
if (notification.method === "turn/completed") {
|
|
31840
|
+
await this.reconcile(threadId, sessionId);
|
|
31841
|
+
return;
|
|
31842
|
+
}
|
|
31843
|
+
if (notification.method === "item/started") {
|
|
31844
|
+
this.refresh(threadId, sessionId);
|
|
31845
|
+
}
|
|
31846
|
+
}
|
|
31847
|
+
observeCommandStarted(item, threadId, sessionId, commandTitle2) {
|
|
31848
|
+
if (!this.isActive() || item.processId === null) return;
|
|
31849
|
+
this.remember(threadId, sessionId, {
|
|
31850
|
+
itemId: item.id,
|
|
31851
|
+
processId: item.processId,
|
|
31852
|
+
command: item.command
|
|
31853
|
+
}, commandTitle2);
|
|
31854
|
+
}
|
|
31855
|
+
async observeCommandCompleted(item, threadId) {
|
|
31856
|
+
if (!this.isActive()) return;
|
|
31857
|
+
const task = this.tasks.get(wireTaskId(this.rootSessionId, threadId, item.id));
|
|
31858
|
+
if (task) await this.finish(task, item.status === "completed" ? "completed" : "failed");
|
|
31859
|
+
}
|
|
31860
|
+
refresh(threadId = this.rootSessionId, sessionId = this.rootSessionId) {
|
|
31861
|
+
void this.reconcile(threadId, sessionId);
|
|
31862
|
+
}
|
|
31863
|
+
async reconcile(threadId = this.rootSessionId, sessionId = this.rootSessionId) {
|
|
31864
|
+
try {
|
|
31865
|
+
await this.sync(threadId, sessionId);
|
|
31866
|
+
} catch (error51) {
|
|
31867
|
+
if (this.isActive()) logger.error(`Failed to list background terminals for ${threadId}`, error51);
|
|
31868
|
+
}
|
|
31869
|
+
}
|
|
31870
|
+
setAppServer(appServer) {
|
|
31871
|
+
this.appServer = appServer;
|
|
31872
|
+
this.appServerGeneration += 1;
|
|
31873
|
+
this.appServerQueriesEnabled = true;
|
|
31874
|
+
}
|
|
31875
|
+
prepareForAppServerReplacement() {
|
|
31876
|
+
this.appServerGeneration += 1;
|
|
31877
|
+
this.appServerQueriesEnabled = false;
|
|
31878
|
+
}
|
|
31879
|
+
async recover(threadId, sessionId, itemIds) {
|
|
31880
|
+
if (!this.canQueryAppServer() || itemIds.size === 0) return;
|
|
31881
|
+
const snapshot = await this.listAll(threadId);
|
|
31882
|
+
if (snapshot === null) return;
|
|
31883
|
+
for (const terminal of snapshot.terminals) {
|
|
31884
|
+
if (!this.queryIsCurrent(snapshot.generation)) return;
|
|
31885
|
+
if (!itemIds.has(terminal.itemId)) continue;
|
|
31886
|
+
const task = this.remember(threadId, sessionId, terminal);
|
|
31887
|
+
if (task.publication === "unpublished" && task.state === "running") await this.announce(task);
|
|
31888
|
+
}
|
|
31889
|
+
}
|
|
31890
|
+
async finishAll(state) {
|
|
31891
|
+
if (!this.isActive()) return;
|
|
31892
|
+
const errors = [];
|
|
31893
|
+
for (const task of this.tasks.values()) {
|
|
31894
|
+
try {
|
|
31895
|
+
await this.finish(task, state);
|
|
31896
|
+
} catch (error51) {
|
|
31897
|
+
errors.push(error51);
|
|
31898
|
+
}
|
|
31899
|
+
}
|
|
31900
|
+
if (errors.length > 0) {
|
|
31901
|
+
throw new AggregateError(errors, `Failed to finish ${errors.length} background terminal task(s)`);
|
|
31902
|
+
}
|
|
31903
|
+
}
|
|
31904
|
+
async sync(threadId = this.rootSessionId, sessionId = this.rootSessionId) {
|
|
31905
|
+
if (!this.canQueryAppServer()) return;
|
|
31906
|
+
const current = this.syncs.get(threadId);
|
|
31907
|
+
if (current) {
|
|
31908
|
+
current.requested = true;
|
|
31909
|
+
current.sessionId = sessionId;
|
|
31910
|
+
return await current.promise;
|
|
31911
|
+
}
|
|
31912
|
+
const pending = {
|
|
31913
|
+
requested: false,
|
|
31914
|
+
sessionId,
|
|
31915
|
+
promise: Promise.resolve()
|
|
31916
|
+
};
|
|
31917
|
+
pending.promise = this.syncUntilCurrent(threadId, pending).finally(() => {
|
|
31918
|
+
if (this.syncs.get(threadId) === pending) this.syncs.delete(threadId);
|
|
31919
|
+
});
|
|
31920
|
+
this.syncs.set(threadId, pending);
|
|
31921
|
+
await pending.promise;
|
|
31922
|
+
}
|
|
31923
|
+
async stop(taskId) {
|
|
31924
|
+
if (!this.isActive()) return false;
|
|
31925
|
+
const task = this.tasks.get(taskId);
|
|
31926
|
+
if (!task || task.publication !== "published") return false;
|
|
31927
|
+
if (task.state === "stopped" && !task.terminalPublished) {
|
|
31928
|
+
await this.publishTerminalState(task);
|
|
31929
|
+
return true;
|
|
31930
|
+
}
|
|
31931
|
+
if (task.state !== "running") return false;
|
|
31932
|
+
task.state = "stopping";
|
|
31933
|
+
try {
|
|
31934
|
+
const response = await this.appServer.threadBackgroundTerminalsTerminate({
|
|
31935
|
+
threadId: task.threadId,
|
|
31936
|
+
processId: task.processId
|
|
31937
|
+
});
|
|
31938
|
+
if (!response.terminated) {
|
|
31939
|
+
if (task.state === "stopping") task.state = "running";
|
|
31940
|
+
return false;
|
|
31941
|
+
}
|
|
31942
|
+
await this.finish(task, "stopped");
|
|
31943
|
+
return true;
|
|
31944
|
+
} catch (error51) {
|
|
31945
|
+
if (task.state === "stopping") task.state = "running";
|
|
31946
|
+
throw error51;
|
|
31947
|
+
}
|
|
31948
|
+
}
|
|
31949
|
+
clear() {
|
|
31950
|
+
this.disposed = true;
|
|
31951
|
+
this.appServerGeneration += 1;
|
|
31952
|
+
this.appServerQueriesEnabled = false;
|
|
31953
|
+
this.tasks.clear();
|
|
31954
|
+
this.syncs.clear();
|
|
31955
|
+
}
|
|
31956
|
+
async syncThread(threadId, sessionId) {
|
|
31957
|
+
const snapshot = await this.listAll(threadId);
|
|
31958
|
+
if (snapshot === null || !this.queryIsCurrent(snapshot.generation)) return;
|
|
31959
|
+
const liveTaskIds = /* @__PURE__ */ new Set();
|
|
31960
|
+
for (const terminal of snapshot.terminals) {
|
|
31961
|
+
if (!this.queryIsCurrent(snapshot.generation)) return;
|
|
31962
|
+
liveTaskIds.add(terminal.itemId);
|
|
31963
|
+
const task = this.remember(threadId, sessionId, terminal);
|
|
31964
|
+
if (task.publication === "unpublished" && task.state === "running") await this.announce(task);
|
|
31965
|
+
}
|
|
31966
|
+
for (const task of this.tasks.values()) {
|
|
31967
|
+
if (!this.queryIsCurrent(snapshot.generation)) return;
|
|
31968
|
+
if (task.threadId === threadId && task.publication === "published" && (task.state === "running" || task.state === "stopping") && !liveTaskIds.has(task.itemId)) {
|
|
31969
|
+
await this.finish(task, "stopped");
|
|
31970
|
+
}
|
|
31971
|
+
}
|
|
31972
|
+
}
|
|
31973
|
+
async syncUntilCurrent(threadId, pending) {
|
|
31974
|
+
let hasFailure = false;
|
|
31975
|
+
let failure;
|
|
31976
|
+
do {
|
|
31977
|
+
pending.requested = false;
|
|
31978
|
+
try {
|
|
31979
|
+
await this.syncThread(threadId, pending.sessionId);
|
|
31980
|
+
hasFailure = false;
|
|
31981
|
+
} catch (error51) {
|
|
31982
|
+
hasFailure = true;
|
|
31983
|
+
failure = error51;
|
|
31984
|
+
}
|
|
31985
|
+
} while (pending.requested && this.canQueryAppServer());
|
|
31986
|
+
if (hasFailure) throw failure;
|
|
31987
|
+
}
|
|
31988
|
+
async announce(task) {
|
|
31989
|
+
if (task.publication === "published") return;
|
|
31990
|
+
if (task.announcement !== null) {
|
|
31991
|
+
await task.announcement;
|
|
31992
|
+
return;
|
|
31993
|
+
}
|
|
31994
|
+
task.publication = "publishing";
|
|
31995
|
+
const announcement = this.publishAnnouncement(task);
|
|
31996
|
+
task.announcement = announcement;
|
|
31997
|
+
try {
|
|
31998
|
+
await announcement;
|
|
31999
|
+
} finally {
|
|
32000
|
+
if (task.announcement === announcement) task.announcement = null;
|
|
32001
|
+
}
|
|
32002
|
+
if (isTerminalState(task.state)) await this.publishTerminalState(task);
|
|
32003
|
+
}
|
|
32004
|
+
async publishAnnouncement(task) {
|
|
32005
|
+
try {
|
|
32006
|
+
await this.publishSpawn(task);
|
|
32007
|
+
task.publication = "published";
|
|
32008
|
+
} catch (error51) {
|
|
32009
|
+
task.publication = "unpublished";
|
|
32010
|
+
throw error51;
|
|
32011
|
+
}
|
|
32012
|
+
}
|
|
32013
|
+
async publishSpawn(task) {
|
|
32014
|
+
await this.session.update({
|
|
32015
|
+
sessionUpdate: "tool_call_update",
|
|
32016
|
+
toolCallId: task.itemId,
|
|
32017
|
+
_meta: {
|
|
32018
|
+
[JETBRAINS_META_KEY]: {
|
|
32019
|
+
[AIR_META_KEY]: {
|
|
32020
|
+
[AIR_ASYNC_TASKS_KEY]: {
|
|
32021
|
+
[AIR_ASYNC_TASKS_BACKGROUNDED_KEY]: true
|
|
32022
|
+
}
|
|
32023
|
+
}
|
|
32024
|
+
}
|
|
32025
|
+
}
|
|
32026
|
+
}, task.sessionId);
|
|
32027
|
+
await this.session.update({
|
|
32028
|
+
sessionUpdate: "async_task_spawned",
|
|
32029
|
+
asyncTaskId: task.asyncTaskId,
|
|
32030
|
+
name: task.name,
|
|
32031
|
+
taskType: "shell",
|
|
32032
|
+
showInTranscript: false,
|
|
32033
|
+
canStop: true,
|
|
32034
|
+
toolCallId: task.itemId
|
|
32035
|
+
}, task.sessionId);
|
|
32036
|
+
}
|
|
32037
|
+
remember(threadId, sessionId, terminal, commandTitle2) {
|
|
32038
|
+
const asyncTaskId = wireTaskId(this.rootSessionId, threadId, terminal.itemId);
|
|
32039
|
+
const existing = this.tasks.get(asyncTaskId);
|
|
32040
|
+
if (existing) {
|
|
32041
|
+
existing.processId = terminal.processId;
|
|
32042
|
+
if (commandTitle2 !== void 0) existing.name = commandTitle2;
|
|
32043
|
+
return existing;
|
|
32044
|
+
}
|
|
32045
|
+
const task = {
|
|
32046
|
+
threadId,
|
|
32047
|
+
sessionId,
|
|
32048
|
+
asyncTaskId,
|
|
32049
|
+
processId: terminal.processId,
|
|
32050
|
+
itemId: terminal.itemId,
|
|
32051
|
+
name: commandTitle2 ?? terminal.command,
|
|
32052
|
+
publication: "unpublished",
|
|
32053
|
+
announcement: null,
|
|
32054
|
+
terminalUpdate: null,
|
|
32055
|
+
terminalPublished: false,
|
|
32056
|
+
state: "running"
|
|
32057
|
+
};
|
|
32058
|
+
this.tasks.set(asyncTaskId, task);
|
|
32059
|
+
return task;
|
|
32060
|
+
}
|
|
32061
|
+
async finish(task, state) {
|
|
32062
|
+
if (task.state === "running" || task.state === "stopping") {
|
|
32063
|
+
task.state = state;
|
|
32064
|
+
} else if (task.state !== state) {
|
|
32065
|
+
return;
|
|
32066
|
+
}
|
|
32067
|
+
if (task.announcement !== null) await task.announcement;
|
|
32068
|
+
if (task.publication === "published") await this.publishTerminalState(task);
|
|
32069
|
+
}
|
|
32070
|
+
async publishTerminalState(task) {
|
|
32071
|
+
if (!isTerminalState(task.state) || task.terminalPublished) return;
|
|
32072
|
+
if (task.terminalUpdate !== null) {
|
|
32073
|
+
await task.terminalUpdate;
|
|
32074
|
+
return;
|
|
32075
|
+
}
|
|
32076
|
+
const terminalUpdate = this.session.update({
|
|
32077
|
+
sessionUpdate: "async_task_state_update",
|
|
32078
|
+
asyncTaskId: task.asyncTaskId,
|
|
32079
|
+
state: task.state,
|
|
32080
|
+
toolCallId: task.itemId
|
|
32081
|
+
}, task.sessionId);
|
|
32082
|
+
task.terminalUpdate = terminalUpdate;
|
|
32083
|
+
try {
|
|
32084
|
+
await terminalUpdate;
|
|
32085
|
+
task.terminalPublished = true;
|
|
32086
|
+
} finally {
|
|
32087
|
+
if (task.terminalUpdate === terminalUpdate) task.terminalUpdate = null;
|
|
32088
|
+
}
|
|
32089
|
+
}
|
|
32090
|
+
async listAll(threadId) {
|
|
32091
|
+
const appServer = this.appServer;
|
|
32092
|
+
const generation = this.appServerGeneration;
|
|
32093
|
+
const terminals = [];
|
|
32094
|
+
const seenCursors = /* @__PURE__ */ new Set();
|
|
32095
|
+
let cursor = null;
|
|
32096
|
+
do {
|
|
32097
|
+
const response = await appServer.threadBackgroundTerminalsList({
|
|
32098
|
+
threadId,
|
|
32099
|
+
cursor
|
|
32100
|
+
});
|
|
32101
|
+
if (!this.queryIsCurrent(generation)) return null;
|
|
32102
|
+
terminals.push(...response.data);
|
|
32103
|
+
cursor = response.nextCursor;
|
|
32104
|
+
if (cursor !== null) {
|
|
32105
|
+
if (seenCursors.has(cursor)) {
|
|
32106
|
+
throw new Error("Codex returned a repeated background terminal cursor");
|
|
32107
|
+
}
|
|
32108
|
+
seenCursors.add(cursor);
|
|
32109
|
+
}
|
|
32110
|
+
} while (cursor !== null);
|
|
32111
|
+
return { generation, terminals };
|
|
32112
|
+
}
|
|
32113
|
+
isActive() {
|
|
32114
|
+
return this.enabled && !this.disposed;
|
|
32115
|
+
}
|
|
32116
|
+
canQueryAppServer() {
|
|
32117
|
+
return this.isActive() && this.appServerQueriesEnabled;
|
|
32118
|
+
}
|
|
32119
|
+
queryIsCurrent(generation) {
|
|
32120
|
+
return this.canQueryAppServer() && generation === this.appServerGeneration;
|
|
32121
|
+
}
|
|
32122
|
+
};
|
|
32123
|
+
function isTerminalState(state) {
|
|
32124
|
+
return state === "completed" || state === "failed" || state === "stopped";
|
|
32125
|
+
}
|
|
32126
|
+
function wireTaskId(rootSessionId, threadId, itemId) {
|
|
32127
|
+
return threadId === rootSessionId ? itemId : `${threadId}:${itemId}`;
|
|
32128
|
+
}
|
|
32129
|
+
function notificationThreadId(notification) {
|
|
32130
|
+
const threadId = notification.params.threadId;
|
|
32131
|
+
return typeof threadId === "string" ? threadId : null;
|
|
32132
|
+
}
|
|
32133
|
+
|
|
32134
|
+
// src/CodexAcpServer.ts
|
|
31504
32135
|
var CODEX_PROCESS_EXITED_ERROR_CODE = 1001;
|
|
31505
32136
|
function clientSupportsTypedSessionFailures(capabilities) {
|
|
31506
32137
|
return clientSupportsAirCapability(capabilities, AIR_SESSION_FAILURE_KEY);
|
|
@@ -31525,6 +32156,8 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
31525
32156
|
clientCapabilities;
|
|
31526
32157
|
terminalOutputMode;
|
|
31527
32158
|
booleanConfigOptionsSupported;
|
|
32159
|
+
/** Last `authStatus` pushed to the client; used to suppress duplicates. */
|
|
32160
|
+
currentAuthStatus;
|
|
31528
32161
|
sessions;
|
|
31529
32162
|
pendingMcpStartupSessions;
|
|
31530
32163
|
pendingTurnStarts;
|
|
@@ -31536,6 +32169,7 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
31536
32169
|
goalControlGenerations;
|
|
31537
32170
|
permissionLifecycleContexts;
|
|
31538
32171
|
codexProcessState;
|
|
32172
|
+
codexProcessGeneration = 0;
|
|
31539
32173
|
initializeRequest = null;
|
|
31540
32174
|
providerUpdate = null;
|
|
31541
32175
|
constructor(connection, codexAcpClient, defaultAuthRequest, getExitCode, getRecentStderr, codexProcessState) {
|
|
@@ -31561,14 +32195,16 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
31561
32195
|
this.clientCapabilities = null;
|
|
31562
32196
|
this.terminalOutputMode = "terminal_output_delta";
|
|
31563
32197
|
this.booleanConfigOptionsSupported = false;
|
|
32198
|
+
this.currentAuthStatus = null;
|
|
31564
32199
|
this.availableCommands = this.createAvailableCommands(codexAcpClient);
|
|
32200
|
+
this.observeCodexProcess();
|
|
31565
32201
|
}
|
|
31566
32202
|
createAvailableCommands(client) {
|
|
31567
32203
|
return new CodexCommands(
|
|
31568
32204
|
this.connection,
|
|
31569
32205
|
client,
|
|
31570
32206
|
(operation) => this.runWithProcessCheck(operation),
|
|
31571
|
-
() => this.
|
|
32207
|
+
() => this.refreshAuthState(null)
|
|
31572
32208
|
);
|
|
31573
32209
|
}
|
|
31574
32210
|
async initialize(_params) {
|
|
@@ -31579,6 +32215,7 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
31579
32215
|
this.terminalOutputMode = resolveTerminalOutputMode(_params.clientCapabilities);
|
|
31580
32216
|
this.booleanConfigOptionsSupported = clientSupportsBooleanConfigOptions(_params.clientCapabilities);
|
|
31581
32217
|
await this.runWithProcessCheck(() => this.codexAcpClient.initialize(_params));
|
|
32218
|
+
this.publishFirstAuthStatusAfterResponse();
|
|
31582
32219
|
const sessionCapabilities = {
|
|
31583
32220
|
resume: {},
|
|
31584
32221
|
list: {},
|
|
@@ -31610,6 +32247,11 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
31610
32247
|
acp: false,
|
|
31611
32248
|
http: true,
|
|
31612
32249
|
sse: false
|
|
32250
|
+
},
|
|
32251
|
+
_meta: {
|
|
32252
|
+
// Presence means "this agent pushes `_auth/status_update`". It
|
|
32253
|
+
// never carries a payload, and the client never asks for one.
|
|
32254
|
+
[AUTH_STATUS_META_KEY]: authStatusCapability()
|
|
31613
32255
|
}
|
|
31614
32256
|
},
|
|
31615
32257
|
authMethods: getCodexAuthMethods(_params.clientCapabilities),
|
|
@@ -31628,7 +32270,8 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
31628
32270
|
[AIR_EXTENSION_CAPABILITIES_KEY]: [
|
|
31629
32271
|
AIR_SESSION_FAILURE_KEY,
|
|
31630
32272
|
AIR_AGENT_FILE_CHANGE_REPORT_KEY,
|
|
31631
|
-
AIR_NATIVE_SUBAGENT_SESSIONS_KEY
|
|
32273
|
+
AIR_NATIVE_SUBAGENT_SESSIONS_KEY,
|
|
32274
|
+
AIR_ASYNC_TASKS_KEY
|
|
31632
32275
|
]
|
|
31633
32276
|
}
|
|
31634
32277
|
}
|
|
@@ -31651,6 +32294,18 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
31651
32294
|
return await this.unstable_setSessionModel(this.parseLegacySetSessionModelParams(methodRequest.params));
|
|
31652
32295
|
case SESSION_STEERING_METHOD:
|
|
31653
32296
|
return await this.executeOrQueueSteeringRequest(this.parseSessionSteerParams(methodRequest.params));
|
|
32297
|
+
case ASYNC_TASK_STOP_METHOD: {
|
|
32298
|
+
if (this.providerUpdate !== null) {
|
|
32299
|
+
await this.providerUpdate;
|
|
32300
|
+
}
|
|
32301
|
+
const sessionState = this.sessions.get(methodRequest.params.sessionId);
|
|
32302
|
+
if (!sessionState) return { stopped: false };
|
|
32303
|
+
return {
|
|
32304
|
+
stopped: await this.runWithProcessCheck(
|
|
32305
|
+
() => sessionState.asyncTasks.stop(methodRequest.params.asyncTaskId)
|
|
32306
|
+
)
|
|
32307
|
+
};
|
|
32308
|
+
}
|
|
31654
32309
|
case GOAL_CONTROL_METHOD:
|
|
31655
32310
|
case LEGACY_GOAL_CONTROL_METHOD: {
|
|
31656
32311
|
const sessionState = this.sessions.get(methodRequest.params.sessionId);
|
|
@@ -31741,7 +32396,7 @@ var CodexAcpServer = class _CodexAcpServer {
|
|
|
31741
32396
|
async handleError(e) {
|
|
31742
32397
|
if (e.message.includes("log out") || e.message.includes("cloud requirements")) {
|
|
31743
32398
|
await this.runWithProcessCheck(() => this.codexAcpClient.logout());
|
|
31744
|
-
await this.
|
|
32399
|
+
await this.refreshAuthState(null);
|
|
31745
32400
|
throw RequestError.internalError(`${e.message}
|
|
31746
32401
|
|
|
31747
32402
|
You have been logged out. Please try again.`);
|
|
@@ -31892,7 +32547,8 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
31892
32547
|
sessionId,
|
|
31893
32548
|
clientSupportsSubagents(this.clientCapabilities),
|
|
31894
32549
|
new ACPSessionConnection(this.connection, sessionId)
|
|
31895
|
-
)
|
|
32550
|
+
),
|
|
32551
|
+
asyncTasks: this.createAsyncTasks(sessionId)
|
|
31896
32552
|
};
|
|
31897
32553
|
sessionState.titleGen = new TitleGenerator(
|
|
31898
32554
|
this.codexAcpClient.appServerClient,
|
|
@@ -31900,7 +32556,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
31900
32556
|
sessionState.cwd,
|
|
31901
32557
|
() => sessionState.sessionTitleSource
|
|
31902
32558
|
);
|
|
31903
|
-
this.
|
|
32559
|
+
this.installSessionState(sessionState);
|
|
31904
32560
|
resumeSubscribed = false;
|
|
31905
32561
|
const canPublishSessionUpdates = operation !== "fork";
|
|
31906
32562
|
if (canPublishSessionUpdates && requestedMcpServers.length > 0 && mcpServerStartupVersion !== null) {
|
|
@@ -31915,6 +32571,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
31915
32571
|
}
|
|
31916
32572
|
if (operation === "resume") {
|
|
31917
32573
|
this.publishCurrentGoalAsync(sessionState, sessionGeneration);
|
|
32574
|
+
this.publishAsyncTasksAsync(sessionState, sessionGeneration);
|
|
31918
32575
|
}
|
|
31919
32576
|
const sessionModelState = this.createModelState(models, currentModelId);
|
|
31920
32577
|
const sessionModeState = sessionState.agentMode.toSessionModeState();
|
|
@@ -31922,12 +32579,14 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
31922
32579
|
}
|
|
31923
32580
|
async getAuthStateForProvider(authProvider) {
|
|
31924
32581
|
if (!this.authProviderUsesOpenAiAccount(authProvider)) {
|
|
32582
|
+
await this.publishAuthStatus(authProvider, null);
|
|
31925
32583
|
return {
|
|
31926
32584
|
account: null,
|
|
31927
32585
|
authConfigured: true
|
|
31928
32586
|
};
|
|
31929
32587
|
}
|
|
31930
32588
|
const accountResponse = await this.runWithProcessCheck(() => this.codexAcpClient.getAccount());
|
|
32589
|
+
await this.publishAuthStatus(authProvider, accountResponse.account);
|
|
31931
32590
|
return {
|
|
31932
32591
|
account: accountResponse.account,
|
|
31933
32592
|
authConfigured: accountResponse.account !== null || !accountResponse.requiresOpenaiAuth
|
|
@@ -31942,6 +32601,18 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
31942
32601
|
}
|
|
31943
32602
|
return a === b;
|
|
31944
32603
|
}
|
|
32604
|
+
createAsyncTasks(sessionId) {
|
|
32605
|
+
return new CodexBackgroundTerminalTasks(
|
|
32606
|
+
clientSupportsAirCapability(this.clientCapabilities, AIR_ASYNC_TASKS_KEY),
|
|
32607
|
+
sessionId,
|
|
32608
|
+
this.codexAcpClient.appServerClient,
|
|
32609
|
+
new ACPSessionConnection(this.connection, sessionId)
|
|
32610
|
+
);
|
|
32611
|
+
}
|
|
32612
|
+
installSessionState(sessionState) {
|
|
32613
|
+
this.sessions.get(sessionState.sessionId)?.asyncTasks.clear();
|
|
32614
|
+
this.sessions.set(sessionState.sessionId, sessionState);
|
|
32615
|
+
}
|
|
31945
32616
|
getAuthProviderForAuthenticateRequest(request) {
|
|
31946
32617
|
if (isCodexAuthRequest(request) && request.methodId === "gateway") {
|
|
31947
32618
|
return "custom-gateway";
|
|
@@ -31960,6 +32631,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
31960
32631
|
thread
|
|
31961
32632
|
} = await this.getOrCreateSessionWithHistory(params);
|
|
31962
32633
|
await this.streamThreadHistory(sessionId, thread);
|
|
32634
|
+
await this.getSessionState(sessionId).asyncTasks.reconcile();
|
|
31963
32635
|
logger.log("Session loaded", {
|
|
31964
32636
|
sessionId,
|
|
31965
32637
|
modelId: modelState.currentModelId,
|
|
@@ -32033,6 +32705,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
32033
32705
|
try {
|
|
32034
32706
|
if (sessionState) {
|
|
32035
32707
|
await this.interruptSessionTurn(sessionState, "Close", true);
|
|
32708
|
+
sessionState.asyncTasks.clear();
|
|
32036
32709
|
} else {
|
|
32037
32710
|
logger.log("Close request received for unknown local session", { sessionId: params.sessionId });
|
|
32038
32711
|
}
|
|
@@ -32106,7 +32779,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
32106
32779
|
logger.log("Authenticate request failed");
|
|
32107
32780
|
throw RequestError.invalidParams();
|
|
32108
32781
|
}
|
|
32109
|
-
await this.
|
|
32782
|
+
await this.refreshAuthState(this.getAuthProviderForAuthenticateRequest(_params));
|
|
32110
32783
|
logger.log("Authenticate request completed");
|
|
32111
32784
|
return {};
|
|
32112
32785
|
}
|
|
@@ -32137,7 +32810,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
32137
32810
|
async logout(_params) {
|
|
32138
32811
|
logger.log("Logout request received");
|
|
32139
32812
|
await this.runWithProcessCheck(() => this.codexAcpClient.logout());
|
|
32140
|
-
await this.
|
|
32813
|
+
await this.refreshAuthState(null);
|
|
32141
32814
|
logger.log("Logout request completed");
|
|
32142
32815
|
}
|
|
32143
32816
|
listProviders(_params) {
|
|
@@ -32168,6 +32841,10 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
32168
32841
|
await Promise.all(activePrompts);
|
|
32169
32842
|
}
|
|
32170
32843
|
logger.log("Restarting Codex app-server for provider update", { sessionCount: this.sessions.size });
|
|
32844
|
+
for (const session of this.sessions.values()) {
|
|
32845
|
+
session.asyncTasks.prepareForAppServerReplacement();
|
|
32846
|
+
}
|
|
32847
|
+
await this.finishAllAsyncTasks("stopped", "before the provider restart");
|
|
32171
32848
|
const replacement = await this.restartCodexClient();
|
|
32172
32849
|
apply(replacement);
|
|
32173
32850
|
if (this.initializeRequest === null) {
|
|
@@ -32178,6 +32855,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
32178
32855
|
this.availableCommands = this.createAvailableCommands(replacement);
|
|
32179
32856
|
const resumeErrors = [];
|
|
32180
32857
|
for (const session of this.sessions.values()) {
|
|
32858
|
+
session.asyncTasks.setAppServer(replacement.appServerClient);
|
|
32181
32859
|
try {
|
|
32182
32860
|
await replacement.resumeSession({
|
|
32183
32861
|
sessionId: session.sessionId,
|
|
@@ -32186,6 +32864,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
32186
32864
|
mcpServers: session.mcpServers ?? []
|
|
32187
32865
|
});
|
|
32188
32866
|
session.authProvider = replacement.getModelProvider();
|
|
32867
|
+
session.asyncTasks.refresh();
|
|
32189
32868
|
logger.log("Resumed session after provider restart", { sessionId: session.sessionId });
|
|
32190
32869
|
} catch (error51) {
|
|
32191
32870
|
resumeErrors.push(error51);
|
|
@@ -32215,12 +32894,22 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
32215
32894
|
state.stderr = (state.stderr + data.toString()).slice(-2 * 1024);
|
|
32216
32895
|
});
|
|
32217
32896
|
}
|
|
32897
|
+
observeCodexProcess() {
|
|
32898
|
+
const process12 = this.codexProcessState?.connection.process;
|
|
32899
|
+
if (!process12) return;
|
|
32900
|
+
const generation = ++this.codexProcessGeneration;
|
|
32901
|
+
process12.once("exit", () => {
|
|
32902
|
+
if (generation !== this.codexProcessGeneration) return;
|
|
32903
|
+
void this.finishAllAsyncTasks("failed", "after the Codex process exited");
|
|
32904
|
+
});
|
|
32905
|
+
}
|
|
32218
32906
|
async restartCodexClient() {
|
|
32219
32907
|
const state = this.codexProcessState;
|
|
32220
32908
|
if (state === null) {
|
|
32221
32909
|
throw new Error("Codex process state is unavailable");
|
|
32222
32910
|
}
|
|
32223
32911
|
const previous = state.connection;
|
|
32912
|
+
this.codexProcessGeneration += 1;
|
|
32224
32913
|
const exited = previous.process.exitCode === null ? once(previous.process, "exit") : Promise.resolve();
|
|
32225
32914
|
previous.process.stdin.end();
|
|
32226
32915
|
const forceKill = setTimeout(() => {
|
|
@@ -32234,21 +32923,162 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
32234
32923
|
state.stderr = "";
|
|
32235
32924
|
state.connection = startCodexConnection(state.codexPath);
|
|
32236
32925
|
this.captureStderr();
|
|
32926
|
+
this.observeCodexProcess();
|
|
32237
32927
|
return new CodexAcpClient(
|
|
32238
32928
|
new CodexAppServerClient(state.connection.connection),
|
|
32239
32929
|
state.config,
|
|
32240
32930
|
state.modelProvider
|
|
32241
32931
|
);
|
|
32242
32932
|
}
|
|
32933
|
+
/** Returns whether the auth state was read (and thus the auth status pushed). */
|
|
32243
32934
|
async refreshSessionsAuthState(authProvider) {
|
|
32244
|
-
if (this.sessions.size === 0) return;
|
|
32935
|
+
if (this.sessions.size === 0) return false;
|
|
32245
32936
|
const sessionsToRefresh = [...this.sessions.values()].filter((sessionState) => this.authProvidersMatch(sessionState.authProvider, authProvider));
|
|
32246
|
-
if (sessionsToRefresh.length === 0) return;
|
|
32937
|
+
if (sessionsToRefresh.length === 0) return false;
|
|
32247
32938
|
const authState = await this.getAuthStateForProvider(authProvider);
|
|
32248
32939
|
for (const sessionState of sessionsToRefresh) {
|
|
32249
32940
|
sessionState.account = authState.account;
|
|
32250
32941
|
sessionState.authConfigured = authState.authConfigured;
|
|
32251
32942
|
}
|
|
32943
|
+
return true;
|
|
32944
|
+
}
|
|
32945
|
+
/**
|
|
32946
|
+
* Refreshes the sessions of a provider and makes sure the connection-level
|
|
32947
|
+
* `authStatus` is pushed even when no session matched (the empty-screen
|
|
32948
|
+
* login case). Reuses the session refresh read; never adds a second one.
|
|
32949
|
+
*/
|
|
32950
|
+
async refreshAuthState(authProvider) {
|
|
32951
|
+
const refreshed = await this.refreshSessionsAuthState(authProvider);
|
|
32952
|
+
if (refreshed) return;
|
|
32953
|
+
try {
|
|
32954
|
+
await this.getAuthStateForProvider(authProvider ?? this.codexAcpClient.getModelProvider());
|
|
32955
|
+
} catch (error51) {
|
|
32956
|
+
logger.log("Failed to refresh auth status", { error: String(error51) });
|
|
32957
|
+
}
|
|
32958
|
+
}
|
|
32959
|
+
/**
|
|
32960
|
+
* Schedules the connection's first `_auth/status_update`: one account read,
|
|
32961
|
+
* pushed whatever it says, including `none`.
|
|
32962
|
+
*
|
|
32963
|
+
* The push must not overtake the `initialize` response. The JSON-RPC layer
|
|
32964
|
+
* writes that response in the microtask that resolves {@link initialize}, so
|
|
32965
|
+
* the read starts from a check-phase callback, which always runs after it.
|
|
32966
|
+
* `initialize` itself never waits for the read.
|
|
32967
|
+
*
|
|
32968
|
+
* "Unconditional" costs nothing extra here: nothing has been pushed yet on
|
|
32969
|
+
* this connection, so {@link setAuthStatus} cannot suppress this one.
|
|
32970
|
+
*/
|
|
32971
|
+
publishFirstAuthStatusAfterResponse() {
|
|
32972
|
+
setImmediate(() => void this.publishAuthStatusRead());
|
|
32973
|
+
}
|
|
32974
|
+
/**
|
|
32975
|
+
* Reads the agent-owned identity and pushes it.
|
|
32976
|
+
*
|
|
32977
|
+
* Never rejects: an unreadable source means "nothing to report", not an
|
|
32978
|
+
* error. The client then keeps showing the last pushed value, or "not
|
|
32979
|
+
* reported" when there was none.
|
|
32980
|
+
*/
|
|
32981
|
+
async publishAuthStatusRead() {
|
|
32982
|
+
let authStatus;
|
|
32983
|
+
try {
|
|
32984
|
+
authStatus = await this.readAgentAuthIdentity();
|
|
32985
|
+
} catch (error51) {
|
|
32986
|
+
logger.log("Cannot determine auth status", { error: String(error51) });
|
|
32987
|
+
return;
|
|
32988
|
+
}
|
|
32989
|
+
await this.setAuthStatus(authStatus);
|
|
32990
|
+
}
|
|
32991
|
+
/**
|
|
32992
|
+
* Builds the agent-owned auth identity. Routing the client configured
|
|
32993
|
+
* through the ACP `providers/*` API is invisible here: the reported state
|
|
32994
|
+
* is what the agent itself is logged in with. `gateway` stays reserved for
|
|
32995
|
+
* agent-owned gateway state — the `gateway` auth method, or a provider the
|
|
32996
|
+
* user configured in Codex's own config.
|
|
32997
|
+
*/
|
|
32998
|
+
async readAgentAuthIdentity() {
|
|
32999
|
+
const authGatewayName = this.codexAcpClient.getAuthGatewayProviderName();
|
|
33000
|
+
if (authGatewayName !== null) {
|
|
33001
|
+
return gatewayStatus(authGatewayName);
|
|
33002
|
+
}
|
|
33003
|
+
const modelProvider = await this.runWithProcessCheck(() => this.codexAcpClient.getAgentConfiguredModelProvider());
|
|
33004
|
+
if (!this.authProviderUsesOpenAiAccount(modelProvider)) {
|
|
33005
|
+
return gatewayStatus(modelProvider);
|
|
33006
|
+
}
|
|
33007
|
+
const accountResponse = await this.runWithProcessCheck(() => this.codexAcpClient.getAccount());
|
|
33008
|
+
return fromAccount(accountResponse.account);
|
|
33009
|
+
}
|
|
33010
|
+
/**
|
|
33011
|
+
* Pushes `_auth/status_update` for the freshly read account of a provider.
|
|
33012
|
+
* Agent-owned gateway authentication wins; a client-driven provider
|
|
33013
|
+
* override is ignored and the agent-owned login is reported instead.
|
|
33014
|
+
*/
|
|
33015
|
+
async publishAuthStatus(authProvider, account) {
|
|
33016
|
+
const authGatewayName = this.codexAcpClient.getAuthGatewayProviderName();
|
|
33017
|
+
if (authGatewayName !== null) {
|
|
33018
|
+
await this.setAuthStatus(gatewayStatus(authGatewayName));
|
|
33019
|
+
return;
|
|
33020
|
+
}
|
|
33021
|
+
if (this.authProviderUsesOpenAiAccount(authProvider)) {
|
|
33022
|
+
await this.setAuthStatus(fromAccount(account));
|
|
33023
|
+
return;
|
|
33024
|
+
}
|
|
33025
|
+
if (this.codexAcpClient.isClientConfiguredProvider(authProvider)) {
|
|
33026
|
+
await this.publishAuthStatusRead();
|
|
33027
|
+
return;
|
|
33028
|
+
}
|
|
33029
|
+
await this.setAuthStatus(gatewayStatus(authProvider));
|
|
33030
|
+
}
|
|
33031
|
+
/**
|
|
33032
|
+
* Handles the app-server `account/updated` push: the free freshness channel
|
|
33033
|
+
* for logins and logouts happening outside this connection.
|
|
33034
|
+
*/
|
|
33035
|
+
handleAccountUpdated(notification) {
|
|
33036
|
+
void this.applyAccountUpdated(notification);
|
|
33037
|
+
}
|
|
33038
|
+
/**
|
|
33039
|
+
* `account/updated` describes the Codex account only. It must never
|
|
33040
|
+
* overwrite an agent-owned gateway status, which no account event can
|
|
33041
|
+
* invalidate; only a gateway logout or a provider change does.
|
|
33042
|
+
*/
|
|
33043
|
+
async applyAccountUpdated(notification) {
|
|
33044
|
+
try {
|
|
33045
|
+
if (this.codexAcpClient.getAuthGatewayProviderName() !== null) {
|
|
33046
|
+
return;
|
|
33047
|
+
}
|
|
33048
|
+
if (this.currentAuthStatus === null) {
|
|
33049
|
+
await this.publishAuthStatusRead();
|
|
33050
|
+
return;
|
|
33051
|
+
}
|
|
33052
|
+
if (this.currentAuthStatus.kind === "gateway") {
|
|
33053
|
+
return;
|
|
33054
|
+
}
|
|
33055
|
+
await this.setAuthStatus(fromAccountUpdated(notification, this.currentAuthStatus));
|
|
33056
|
+
} catch (error51) {
|
|
33057
|
+
logger.log("Failed to apply account update to auth status", { error: String(error51) });
|
|
33058
|
+
}
|
|
33059
|
+
}
|
|
33060
|
+
/**
|
|
33061
|
+
* Stores `next` and pushes `_auth/status_update`.
|
|
33062
|
+
*
|
|
33063
|
+
* A push goes out only when the payload changed. The identity is read on
|
|
33064
|
+
* many occasions — `initialize`, each session create, each `account/updated`
|
|
33065
|
+
* — and almost all of them see the login already reported.
|
|
33066
|
+
* Clients replace their whole state on each update and tolerate duplicates,
|
|
33067
|
+
* so a repeat is harmless, but it is pure noise all the same.
|
|
33068
|
+
*
|
|
33069
|
+
* The first push of a connection always goes out: nothing was reported yet,
|
|
33070
|
+
* so no payload can equal it.
|
|
33071
|
+
*/
|
|
33072
|
+
async setAuthStatus(next) {
|
|
33073
|
+
if (sameAuthStatus(this.currentAuthStatus, next)) {
|
|
33074
|
+
return;
|
|
33075
|
+
}
|
|
33076
|
+
this.currentAuthStatus = next;
|
|
33077
|
+
try {
|
|
33078
|
+
await this.connection.notify(AUTH_STATUS_UPDATE_METHOD, { authStatus: next });
|
|
33079
|
+
} catch (error51) {
|
|
33080
|
+
logger.log("Failed to send auth status update", { error: String(error51) });
|
|
33081
|
+
}
|
|
32252
33082
|
}
|
|
32253
33083
|
async setSessionMode(_params) {
|
|
32254
33084
|
logger.log("Set session mode requested", {
|
|
@@ -32643,6 +33473,10 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
32643
33473
|
publishCurrentGoalAsync(sessionState, sessionGeneration) {
|
|
32644
33474
|
void this.publishCurrentGoalBestEffort(sessionState, sessionGeneration, true);
|
|
32645
33475
|
}
|
|
33476
|
+
publishAsyncTasksAsync(sessionState, sessionGeneration) {
|
|
33477
|
+
if (!this.sessionPublishIsCurrent(sessionState, sessionGeneration)) return;
|
|
33478
|
+
sessionState.asyncTasks.refresh();
|
|
33479
|
+
}
|
|
32646
33480
|
async publishCurrentGoalBestEffort(sessionState, sessionGeneration, force) {
|
|
32647
33481
|
try {
|
|
32648
33482
|
await this.publishCurrentGoal(sessionState, sessionGeneration, force);
|
|
@@ -32766,7 +33600,8 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
32766
33600
|
sessionId,
|
|
32767
33601
|
clientSupportsSubagents(this.clientCapabilities),
|
|
32768
33602
|
new ACPSessionConnection(this.connection, sessionId)
|
|
32769
|
-
)
|
|
33603
|
+
),
|
|
33604
|
+
asyncTasks: this.createAsyncTasks(sessionId)
|
|
32770
33605
|
};
|
|
32771
33606
|
sessionState.titleGen = new TitleGenerator(
|
|
32772
33607
|
this.codexAcpClient.appServerClient,
|
|
@@ -32774,7 +33609,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
32774
33609
|
sessionState.cwd,
|
|
32775
33610
|
() => sessionState.sessionTitleSource
|
|
32776
33611
|
);
|
|
32777
|
-
this.
|
|
33612
|
+
this.installSessionState(sessionState);
|
|
32778
33613
|
subscribed = false;
|
|
32779
33614
|
if (requestedMcpServers.length > 0 && mcpServerStartupVersion !== null) {
|
|
32780
33615
|
this.pendingMcpStartupSessions.set(sessionId, {
|
|
@@ -32866,6 +33701,15 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
32866
33701
|
/* @__PURE__ */ new Set([...ancestry, item.agentThreadId]),
|
|
32867
33702
|
threadCache
|
|
32868
33703
|
);
|
|
33704
|
+
try {
|
|
33705
|
+
await sessionState.asyncTasks.recover(
|
|
33706
|
+
item.agentThreadId,
|
|
33707
|
+
childSessionId,
|
|
33708
|
+
commandItemIds(childTurn.items)
|
|
33709
|
+
);
|
|
33710
|
+
} catch (error51) {
|
|
33711
|
+
logger.error(`Failed to restore background terminals for ${item.agentThreadId}`, error51);
|
|
33712
|
+
}
|
|
32869
33713
|
}
|
|
32870
33714
|
}
|
|
32871
33715
|
} else if (activityKind === "completed" || activityKind === "interrupted") {
|
|
@@ -33438,7 +34282,6 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
33438
34282
|
let promptWasCancelled = false;
|
|
33439
34283
|
let recoverableSessionFailure = sessionState.sessionFailure;
|
|
33440
34284
|
sessionState.currentTurnId = null;
|
|
33441
|
-
sessionState.lastTokenUsage = null;
|
|
33442
34285
|
const activePrompt = this.trackActivePrompt(params.sessionId);
|
|
33443
34286
|
let pendingTurnStart = null;
|
|
33444
34287
|
const ensurePendingTurnStart = () => {
|
|
@@ -33471,7 +34314,8 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
33471
34314
|
clientSupportsPlanUpdates(this.clientCapabilities),
|
|
33472
34315
|
clientSupportsTypedSessionFailures(this.clientCapabilities),
|
|
33473
34316
|
this.sessionFailureEpoch,
|
|
33474
|
-
sessionState.subagents
|
|
34317
|
+
sessionState.subagents,
|
|
34318
|
+
(accountUpdated) => this.handleAccountUpdated(accountUpdated)
|
|
33475
34319
|
);
|
|
33476
34320
|
eventHandler = promptEventHandler;
|
|
33477
34321
|
const permissionLifecycle = this.permissionLifecycleContext(sessionState);
|
|
@@ -33516,6 +34360,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
33516
34360
|
}
|
|
33517
34361
|
const commandPromise = this.availableCommands.tryHandleCommand(params.prompt, sessionState, {
|
|
33518
34362
|
onTurnStartPending: () => {
|
|
34363
|
+
sessionState.lastTokenUsage = null;
|
|
33519
34364
|
ensurePendingTurnStart();
|
|
33520
34365
|
},
|
|
33521
34366
|
onTurnStarted: (turnId, threadId) => {
|
|
@@ -33612,6 +34457,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
33612
34457
|
sessionState.fastModeEnabled,
|
|
33613
34458
|
sessionState.currentModelSupportsFast
|
|
33614
34459
|
);
|
|
34460
|
+
sessionState.lastTokenUsage = null;
|
|
33615
34461
|
ensurePendingTurnStart();
|
|
33616
34462
|
const sendPromptPromise = this.runWithProcessCheck(
|
|
33617
34463
|
() => this.codexAcpClient.sendPrompt(
|
|
@@ -33914,6 +34760,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
|
|
|
33914
34760
|
throw new RequestError(requestErrorCode, `VC++ redistributable should be installed`);
|
|
33915
34761
|
}
|
|
33916
34762
|
if (exitCode !== null) {
|
|
34763
|
+
await this.finishAllAsyncTasks("failed", "after the Codex process exited");
|
|
33917
34764
|
const stderr = this.getRecentStderr().trim();
|
|
33918
34765
|
const detail = stderr ? `:
|
|
33919
34766
|
${stderr}` : "";
|
|
@@ -33922,6 +34769,15 @@ ${stderr}` : "";
|
|
|
33922
34769
|
throw err;
|
|
33923
34770
|
}
|
|
33924
34771
|
}
|
|
34772
|
+
async finishAllAsyncTasks(state, reason) {
|
|
34773
|
+
for (const session of this.sessions.values()) {
|
|
34774
|
+
try {
|
|
34775
|
+
await session.asyncTasks.finishAll(state);
|
|
34776
|
+
} catch (error51) {
|
|
34777
|
+
logger.error(`Failed to finish background terminal tasks ${reason}`, error51);
|
|
34778
|
+
}
|
|
34779
|
+
}
|
|
34780
|
+
}
|
|
33925
34781
|
async cancel(params) {
|
|
33926
34782
|
const sessionState = this.sessions.get(params.sessionId);
|
|
33927
34783
|
if (!sessionState) {
|
|
@@ -33971,6 +34827,9 @@ function mergeHistoryUpdates(responseItemFallbackUpdates, threadUpdates) {
|
|
|
33971
34827
|
}
|
|
33972
34828
|
return merged;
|
|
33973
34829
|
}
|
|
34830
|
+
function commandItemIds(items) {
|
|
34831
|
+
return new Set(items.filter((item) => item.type === "commandExecution").map((item) => item.id));
|
|
34832
|
+
}
|
|
33974
34833
|
function historyUpdateKey(update) {
|
|
33975
34834
|
switch (update.sessionUpdate) {
|
|
33976
34835
|
case "user_message_chunk":
|
|
@@ -34154,6 +35013,10 @@ var goalControlParamsParser = external_exports.discriminatedUnion("action", [
|
|
|
34154
35013
|
action: external_exports.enum(["pause", "resume", "clear"])
|
|
34155
35014
|
}).passthrough()
|
|
34156
35015
|
]);
|
|
35016
|
+
var asyncTaskStopParamsParser = external_exports.object({
|
|
35017
|
+
sessionId: external_exports.string().trim().min(1),
|
|
35018
|
+
asyncTaskId: external_exports.string().trim().min(1)
|
|
35019
|
+
}).passthrough();
|
|
34157
35020
|
if (process.argv.includes("--version")) {
|
|
34158
35021
|
console.log(`${package_default.name} ${package_default.version}`);
|
|
34159
35022
|
process.exit(0);
|
|
@@ -34234,5 +35097,5 @@ function startAcpServer() {
|
|
|
34234
35097
|
codexAcpServer = null;
|
|
34235
35098
|
}
|
|
34236
35099
|
});
|
|
34237
|
-
}).onRequest(methods.agent.initialize, (ctx) => getAgent().initialize(ctx.params)).onRequest(methods.agent.session.new, (ctx) => getAgent().newSession(ctx.params)).onRequest(methods.agent.session.load, (ctx) => getAgent().loadSession(ctx.params)).onRequest(methods.agent.session.fork, (ctx) => getAgent().forkSession(ctx.params)).onRequest(methods.agent.session.list, (ctx) => getAgent().listSessions(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => getAgent().deleteSession(ctx.params)).onRequest(methods.agent.session.resume, (ctx) => getAgent().resumeSession(ctx.params)).onRequest(methods.agent.session.close, (ctx) => getAgent().closeSession(ctx.params)).onRequest(methods.agent.session.setMode, (ctx) => getAgent().setSessionMode(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => getAgent().setSessionConfigOption(ctx.params)).onRequest(methods.agent.authenticate, (ctx) => getAgent().authenticate(ctx.params, ctx.requestId)).onRequest(methods.agent.logout, (ctx) => getAgent().logout(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => getAgent().listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => getAgent().setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => getAgent().disableProvider(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => getAgent().prompt(ctx.params, ctx.signal)).onNotification(methods.agent.session.cancel, (ctx) => getAgent().cancel(ctx.params)).onRequest("authentication/status", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/status", ctx.params)).onRequest("authentication/logout", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/logout", ctx.params)).onRequest(LEGACY_SET_SESSION_MODEL_METHOD, legacySetSessionModelParamsParser, (ctx) => getAgent().extMethod(LEGACY_SET_SESSION_MODEL_METHOD, ctx.params)).onRequest(SESSION_STEERING_METHOD, sessionSteerParamsParser, (ctx) => getAgent().extMethod(SESSION_STEERING_METHOD, ctx.params)).onRequest(GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(GOAL_CONTROL_METHOD, ctx.params)).connect(acpJsonStream);
|
|
35100
|
+
}).onRequest(methods.agent.initialize, (ctx) => getAgent().initialize(ctx.params)).onRequest(methods.agent.session.new, (ctx) => getAgent().newSession(ctx.params)).onRequest(methods.agent.session.load, (ctx) => getAgent().loadSession(ctx.params)).onRequest(methods.agent.session.fork, (ctx) => getAgent().forkSession(ctx.params)).onRequest(methods.agent.session.list, (ctx) => getAgent().listSessions(ctx.params)).onRequest(methods.agent.session.delete, (ctx) => getAgent().deleteSession(ctx.params)).onRequest(methods.agent.session.resume, (ctx) => getAgent().resumeSession(ctx.params)).onRequest(methods.agent.session.close, (ctx) => getAgent().closeSession(ctx.params)).onRequest(methods.agent.session.setMode, (ctx) => getAgent().setSessionMode(ctx.params)).onRequest(methods.agent.session.setConfigOption, (ctx) => getAgent().setSessionConfigOption(ctx.params)).onRequest(methods.agent.authenticate, (ctx) => getAgent().authenticate(ctx.params, ctx.requestId)).onRequest(methods.agent.logout, (ctx) => getAgent().logout(ctx.params)).onRequest(methods.agent.providers.list, (ctx) => getAgent().listProviders(ctx.params)).onRequest(methods.agent.providers.set, (ctx) => getAgent().setProvider(ctx.params)).onRequest(methods.agent.providers.disable, (ctx) => getAgent().disableProvider(ctx.params)).onRequest(methods.agent.session.prompt, (ctx) => getAgent().prompt(ctx.params, ctx.signal)).onNotification(methods.agent.session.cancel, (ctx) => getAgent().cancel(ctx.params)).onRequest("authentication/status", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/status", ctx.params)).onRequest("authentication/logout", emptyExtensionParamsParser, (ctx) => getAgent().extMethod("authentication/logout", ctx.params)).onRequest(LEGACY_SET_SESSION_MODEL_METHOD, legacySetSessionModelParamsParser, (ctx) => getAgent().extMethod(LEGACY_SET_SESSION_MODEL_METHOD, ctx.params)).onRequest(SESSION_STEERING_METHOD, sessionSteerParamsParser, (ctx) => getAgent().extMethod(SESSION_STEERING_METHOD, ctx.params)).onRequest(ASYNC_TASK_STOP_METHOD, asyncTaskStopParamsParser, (ctx) => getAgent().extMethod(ASYNC_TASK_STOP_METHOD, ctx.params)).onRequest(GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(GOAL_CONTROL_METHOD, ctx.params)).connect(acpJsonStream);
|
|
34238
35101
|
}
|