@agentclientprotocol/codex-acp 0.0.42 → 0.0.44

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.
Files changed (2) hide show
  1. package/dist/index.js +123 -18
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -18958,7 +18958,7 @@ var package_default = {
18958
18958
  publishConfig: {
18959
18959
  access: "public"
18960
18960
  },
18961
- version: "0.0.42",
18961
+ version: "0.0.44",
18962
18962
  description: "",
18963
18963
  main: "dist/index.js",
18964
18964
  bin: {
@@ -19163,11 +19163,11 @@ var CodexAcpClient = class {
19163
19163
  approvalPolicy: null,
19164
19164
  sandbox: null,
19165
19165
  baseInstructions: null,
19166
- config: this.createSessionConfig(request.cwd, request.mcpServers ?? []),
19166
+ config: await this.createSessionConfig(request.cwd, request.mcpServers ?? []),
19167
19167
  cwd: request.cwd,
19168
19168
  developerInstructions: null,
19169
19169
  model: null,
19170
- modelProvider: this.getModelProvider(),
19170
+ modelProvider: this.getResumeModelProvider(),
19171
19171
  personality: null,
19172
19172
  threadId: request.sessionId
19173
19173
  });
@@ -19184,11 +19184,11 @@ var CodexAcpClient = class {
19184
19184
  approvalPolicy: null,
19185
19185
  sandbox: null,
19186
19186
  baseInstructions: null,
19187
- config: this.createSessionConfig(request.cwd, request.mcpServers ?? []),
19187
+ config: await this.createSessionConfig(request.cwd, request.mcpServers ?? []),
19188
19188
  cwd: request.cwd,
19189
19189
  developerInstructions: null,
19190
19190
  model: null,
19191
- modelProvider: this.getModelProvider(),
19191
+ modelProvider: this.getResumeModelProvider(),
19192
19192
  personality: null,
19193
19193
  threadId: request.sessionId
19194
19194
  });
@@ -19204,7 +19204,7 @@ var CodexAcpClient = class {
19204
19204
  async newSession(request) {
19205
19205
  await this.refreshSkills(request.cwd, request._meta);
19206
19206
  const response = await this.codexClient.threadStart({
19207
- config: this.createSessionConfig(request.cwd, request.mcpServers),
19207
+ config: await this.createSessionConfig(request.cwd, request.mcpServers),
19208
19208
  modelProvider: this.getModelProvider(),
19209
19209
  model: null,
19210
19210
  cwd: request.cwd,
@@ -19232,7 +19232,7 @@ var CodexAcpClient = class {
19232
19232
  getMcpServerStartupVersion() {
19233
19233
  return this.codexClient.getMcpServerStartupVersion();
19234
19234
  }
19235
- createSessionConfig(projectPath, mcpServers) {
19235
+ async createSessionConfig(projectPath, mcpServers) {
19236
19236
  const mergedConfig = {
19237
19237
  ...mergeGatewayConfig(this.config, this.gatewayConfig),
19238
19238
  projects: {
@@ -19244,14 +19244,30 @@ var CodexAcpClient = class {
19244
19244
  if (mcpServers.length === 0) {
19245
19245
  return mergedConfig;
19246
19246
  }
19247
+ const existingNames = await this.getConfigMcpServerNames(projectPath);
19248
+ const uniqueServers = mcpServers.filter((mcp) => !existingNames.has(mcp.name));
19249
+ if (uniqueServers.length === 0) {
19250
+ return mergedConfig;
19251
+ }
19247
19252
  return {
19248
19253
  ...mergedConfig,
19249
- "mcp_servers": Object.fromEntries(mcpServers.map((mcp) => [mcp.name, this.createMcpSeverConfig(mcp)]))
19254
+ "mcp_servers": Object.fromEntries(uniqueServers.map((mcp) => [mcp.name, this.createMcpSeverConfig(mcp)]))
19250
19255
  };
19251
19256
  }
19257
+ async getConfigMcpServerNames(projectPath) {
19258
+ const response = await this.codexClient.configRead({ includeLayers: true, cwd: projectPath });
19259
+ const mcpServers = response?.config?.["mcp_servers"];
19260
+ if (!mcpServers || typeof mcpServers !== "object" || Array.isArray(mcpServers)) {
19261
+ return /* @__PURE__ */ new Set();
19262
+ }
19263
+ return new Set(Object.keys(mcpServers));
19264
+ }
19252
19265
  getModelProvider() {
19253
19266
  return this.gatewayConfig?.modelProvider ?? this.modelProvider;
19254
19267
  }
19268
+ getResumeModelProvider() {
19269
+ return this.getModelProvider() ?? "openai";
19270
+ }
19255
19271
  async refreshSkills(cwd, meta) {
19256
19272
  if (!cwd) {
19257
19273
  return;
@@ -19305,7 +19321,7 @@ var CodexAcpClient = class {
19305
19321
  const input = buildPromptItems(request.prompt);
19306
19322
  const effort = modelId.effort;
19307
19323
  await this.refreshSkills(cwd, request._meta);
19308
- await this.codexClient.turnStart({
19324
+ return await this.codexClient.runTurn({
19309
19325
  outputSchema: null,
19310
19326
  threadId: request.sessionId,
19311
19327
  input,
@@ -19317,7 +19333,6 @@ var CodexAcpClient = class {
19317
19333
  effort,
19318
19334
  model: modelId.model
19319
19335
  });
19320
- return await this.codexClient.awaitTurnCompleted();
19321
19336
  }
19322
19337
  async listSkills(params) {
19323
19338
  return this.codexClient.listSkills(params ?? {});
@@ -19937,7 +19952,7 @@ var CodexAcpServer = class {
19937
19952
  logger.log(`Create new session...`);
19938
19953
  sessionMetadata = await this.runWithProcessCheck(() => this.codexAcpClient.newSession(request));
19939
19954
  }
19940
- const accountResponse = await this.runWithProcessCheck(() => this.codexAcpClient.getAccount());
19955
+ const account = await this.getActiveAccount();
19941
19956
  const { sessionId, currentModelId, models } = sessionMetadata;
19942
19957
  const sessionMcpServers = this.resolveSessionMcpServers(requestedMcpServers, "sessionId" in request);
19943
19958
  const currentModel = this.findCurrentModel(models, currentModelId);
@@ -19952,7 +19967,7 @@ var CodexAcpServer = class {
19952
19967
  totalTokenUsage: null,
19953
19968
  modelContextWindow: null,
19954
19969
  rateLimits: null,
19955
- account: accountResponse.account,
19970
+ account,
19956
19971
  cwd: request.cwd,
19957
19972
  sessionMcpServers
19958
19973
  };
@@ -19969,6 +19984,13 @@ var CodexAcpServer = class {
19969
19984
  const sessionModeState = sessionState.agentMode.toSessionModeState();
19970
19985
  return [sessionId, sessionModelState, sessionModeState];
19971
19986
  }
19987
+ async getActiveAccount() {
19988
+ if (this.codexAcpClient.getModelProvider()) {
19989
+ return null;
19990
+ }
19991
+ const accountResponse = await this.runWithProcessCheck(() => this.codexAcpClient.getAccount());
19992
+ return accountResponse.account;
19993
+ }
19972
19994
  async loadSession(params) {
19973
19995
  logger.log("Loading session...", { sessionId: params.sessionId });
19974
19996
  const {
@@ -20108,7 +20130,7 @@ var CodexAcpServer = class {
20108
20130
  const sessionMetadata = await this.runWithProcessCheck(
20109
20131
  () => this.codexAcpClient.loadSession(request)
20110
20132
  );
20111
- const accountResponse = await this.runWithProcessCheck(() => this.codexAcpClient.getAccount());
20133
+ const account = await this.getActiveAccount();
20112
20134
  const { sessionId, currentModelId, models, thread } = sessionMetadata;
20113
20135
  const sessionMcpServers = this.resolveSessionMcpServers(requestedMcpServers, true);
20114
20136
  const currentModel = this.findCurrentModel(models, currentModelId);
@@ -20123,7 +20145,7 @@ var CodexAcpServer = class {
20123
20145
  totalTokenUsage: null,
20124
20146
  modelContextWindow: null,
20125
20147
  rateLimits: null,
20126
- account: accountResponse.account,
20148
+ account,
20127
20149
  cwd: request.cwd,
20128
20150
  sessionMcpServers
20129
20151
  };
@@ -20551,6 +20573,8 @@ var CodexAppServerClient = class {
20551
20573
  mcpServerStartupVersion = 0;
20552
20574
  mcpServerStartupStates = /* @__PURE__ */ new Map();
20553
20575
  mcpServerStartupResolvers = [];
20576
+ pendingTurnCompletionResolvers = /* @__PURE__ */ new Map();
20577
+ turnCompletionCaptures = /* @__PURE__ */ new Map();
20554
20578
  constructor(connection) {
20555
20579
  this.connection = connection;
20556
20580
  this.connection.onUnhandledNotification((data) => {
@@ -20564,6 +20588,9 @@ var CodexAppServerClient = class {
20564
20588
  });
20565
20589
  this.resolveMcpServerStartupResolvers();
20566
20590
  }
20591
+ if (isTurnCompletedNotification(serverNotification)) {
20592
+ this.recordTurnCompleted(serverNotification.params);
20593
+ }
20567
20594
  this.notify(serverNotification);
20568
20595
  for (const callback of this.codexEventHandlers) {
20569
20596
  callback({ eventType: "notification", ...serverNotification });
@@ -20603,6 +20630,23 @@ var CodexAppServerClient = class {
20603
20630
  async turnStart(params) {
20604
20631
  return await this.sendRequest({ method: "turn/start", params });
20605
20632
  }
20633
+ async runTurn(params) {
20634
+ const capturedCompletions = [];
20635
+ const releaseCapture = this.captureTurnCompletions(params.threadId, (event) => {
20636
+ capturedCompletions.push(event);
20637
+ });
20638
+ try {
20639
+ const turnStarted = await this.turnStart(params);
20640
+ const earlyCompletion = capturedCompletions.find((event) => event.turn.id === turnStarted.turn.id);
20641
+ releaseCapture();
20642
+ if (earlyCompletion) {
20643
+ return earlyCompletion;
20644
+ }
20645
+ return await this.awaitTurnCompleted(params.threadId, turnStarted.turn.id);
20646
+ } finally {
20647
+ releaseCapture();
20648
+ }
20649
+ }
20606
20650
  async turnInterrupt(params) {
20607
20651
  return await this.sendRequest({ method: "turn/interrupt", params });
20608
20652
  }
@@ -20657,11 +20701,10 @@ var CodexAppServerClient = class {
20657
20701
  return await this.sendRequest({ method: "account/read", params });
20658
20702
  }
20659
20703
  //TODO create type-safe helper
20660
- async awaitTurnCompleted() {
20704
+ async awaitTurnCompleted(threadId, turnId) {
20661
20705
  return await new Promise((resolve) => {
20662
- this.connection.onNotification("turn/completed", (event) => {
20663
- resolve(event);
20664
- });
20706
+ const threadResolvers = this.getOrCreatePendingTurnCompletionResolvers(threadId);
20707
+ threadResolvers.set(turnId, resolve);
20665
20708
  });
20666
20709
  }
20667
20710
  async listModels(params = { cursor: null, limit: null }) {
@@ -20683,10 +20726,62 @@ var CodexAppServerClient = class {
20683
20726
  }
20684
20727
  notificationHandlers = /* @__PURE__ */ new Map();
20685
20728
  notify(notification) {
20729
+ const threadId = extractThreadId(notification);
20730
+ if (threadId !== null) {
20731
+ const handler = this.notificationHandlers.get(threadId);
20732
+ if (handler) {
20733
+ handler(notification);
20734
+ }
20735
+ return;
20736
+ }
20686
20737
  for (const notificationHandler of this.notificationHandlers.values()) {
20687
20738
  notificationHandler(notification);
20688
20739
  }
20689
20740
  }
20741
+ recordTurnCompleted(event) {
20742
+ const threadResolvers = this.pendingTurnCompletionResolvers.get(event.threadId);
20743
+ const resolve = threadResolvers?.get(event.turn.id);
20744
+ if (resolve) {
20745
+ threadResolvers.delete(event.turn.id);
20746
+ if (threadResolvers.size === 0) {
20747
+ this.pendingTurnCompletionResolvers.delete(event.threadId);
20748
+ }
20749
+ resolve(event);
20750
+ return;
20751
+ }
20752
+ const captures = this.turnCompletionCaptures.get(event.threadId);
20753
+ if (!captures) {
20754
+ return;
20755
+ }
20756
+ for (const capture of captures) {
20757
+ capture(event);
20758
+ }
20759
+ }
20760
+ getOrCreatePendingTurnCompletionResolvers(threadId) {
20761
+ const existing = this.pendingTurnCompletionResolvers.get(threadId);
20762
+ if (existing) {
20763
+ return existing;
20764
+ }
20765
+ const created = /* @__PURE__ */ new Map();
20766
+ this.pendingTurnCompletionResolvers.set(threadId, created);
20767
+ return created;
20768
+ }
20769
+ captureTurnCompletions(threadId, capture) {
20770
+ const captures = this.turnCompletionCaptures.get(threadId) ?? /* @__PURE__ */ new Set();
20771
+ captures.add(capture);
20772
+ this.turnCompletionCaptures.set(threadId, captures);
20773
+ let released = false;
20774
+ return () => {
20775
+ if (released) {
20776
+ return;
20777
+ }
20778
+ released = true;
20779
+ captures.delete(capture);
20780
+ if (captures.size === 0) {
20781
+ this.turnCompletionCaptures.delete(threadId);
20782
+ }
20783
+ };
20784
+ }
20690
20785
  resolveMcpServerStartupResolvers() {
20691
20786
  const pendingResolvers = [];
20692
20787
  for (const resolver of this.mcpServerStartupResolvers) {
@@ -20746,6 +20841,16 @@ var CodexAppServerClient = class {
20746
20841
  function isMcpServerStatusUpdatedNotification(notification) {
20747
20842
  return notification.method === "mcpServer/startupStatus/updated";
20748
20843
  }
20844
+ function isTurnCompletedNotification(notification) {
20845
+ return notification.method === "turn/completed";
20846
+ }
20847
+ function extractThreadId(notification) {
20848
+ const params = notification.params;
20849
+ if (params && typeof params.threadId === "string") {
20850
+ return params.threadId;
20851
+ }
20852
+ return null;
20853
+ }
20749
20854
 
20750
20855
  // src/login.ts
20751
20856
  function parseArgs(args) {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.0.42",
6
+ "version": "0.0.44",
7
7
  "description": "",
8
8
  "main": "dist/index.js",
9
9
  "bin": {