@alas-ide/codex-acp 2.5.0-alas.4 → 2.5.0-alas.5

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 +79 -21
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -34696,6 +34696,32 @@ function goalSessionInfoUpdate(goal, capabilities) {
34696
34696
  };
34697
34697
  }
34698
34698
 
34699
+ // src/SessionFailureExtension.ts
34700
+ var NEUTRAL_SESSION_FAILURE_META_KEY = "sessionFailure";
34701
+ var SESSION_FAILURE_VERSION = 1;
34702
+ function neutralSessionFailureCapability() {
34703
+ return { version: SESSION_FAILURE_VERSION };
34704
+ }
34705
+ function clientRequestsNeutralSessionFailure(capabilities) {
34706
+ const declared = capabilities?._meta?.[NEUTRAL_SESSION_FAILURE_META_KEY];
34707
+ if (declared === null || typeof declared !== "object" || Array.isArray(declared)) return false;
34708
+ const version2 = declared["version"];
34709
+ return typeof version2 === "number" && Number.isInteger(version2) && version2 >= 1;
34710
+ }
34711
+ var NeutralSessionFailureLedger = class {
34712
+ revisions = /* @__PURE__ */ new Map();
34713
+ nextIncident = 1;
34714
+ incidentNumber() {
34715
+ return this.nextIncident++;
34716
+ }
34717
+ /** The lowest revision of `id` that is at least `proposed` and above every revision already sent. */
34718
+ revision(id, proposed) {
34719
+ const revision = Math.max(proposed, (this.revisions.get(id) ?? 0) + 1);
34720
+ this.revisions.set(id, revision);
34721
+ return revision;
34722
+ }
34723
+ };
34724
+
34699
34725
  // src/tool-calls/ClientCapabilities.ts
34700
34726
  var ClientCapabilities = class _ClientCapabilities {
34701
34727
  static DEFAULT = new _ClientCapabilities({
@@ -34708,6 +34734,7 @@ var ClientCapabilities = class _ClientCapabilities {
34708
34734
  planUpdates: false,
34709
34735
  air: { rawInputRendering: false, planContentDelta: false, diffPatch: false },
34710
34736
  diffPatchFormat: "none",
34737
+ sessionFailureFormat: "none",
34711
34738
  permissionPromptFields: false
34712
34739
  });
34713
34740
  /** The client declares `_meta.jetbrains.air`. */
@@ -34726,6 +34753,7 @@ var ClientCapabilities = class _ClientCapabilities {
34726
34753
  planUpdates;
34727
34754
  air;
34728
34755
  diffPatchFormat;
34756
+ sessionFailureFormat;
34729
34757
  /** A permission request has its own `title` and `description` (ACP v2). */
34730
34758
  permissionPromptFields;
34731
34759
  constructor(values) {
@@ -34738,6 +34766,7 @@ var ClientCapabilities = class _ClientCapabilities {
34738
34766
  this.planUpdates = values.planUpdates;
34739
34767
  this.air = values.air;
34740
34768
  this.diffPatchFormat = values.diffPatchFormat;
34769
+ this.sessionFailureFormat = values.sessionFailureFormat;
34741
34770
  this.permissionPromptFields = values.permissionPromptFields;
34742
34771
  }
34743
34772
  static from(capabilities) {
@@ -34759,6 +34788,8 @@ var ClientCapabilities = class _ClientCapabilities {
34759
34788
  },
34760
34789
  // A client that declares both forms gets only the client-neutral one.
34761
34790
  diffPatchFormat: clientRequestsNeutralDiffPatch(capabilities) ? "neutral" : diffPatch ? "air" : "none",
34791
+ // Likewise, and the client-neutral form selects the whole typed failure lane.
34792
+ sessionFailureFormat: clientRequestsNeutralSessionFailure(capabilities) ? "neutral" : clientSupportsAirCapability(capabilities, AIR_SESSION_FAILURE_KEY) ? "air" : "none",
34762
34793
  permissionPromptFields: false
34763
34794
  });
34764
34795
  }
@@ -34781,6 +34812,8 @@ var ClientCapabilities = class _ClientCapabilities {
34781
34812
  planUpdates: true,
34782
34813
  air: { rawInputRendering: false, planContentDelta: false, diffPatch: false },
34783
34814
  diffPatchFormat: "acpV2",
34815
+ // ACP v2 has its own terminal failure state, so it ignores the client-neutral opt-in.
34816
+ sessionFailureFormat: clientSupportsAirCapability(capabilities, AIR_SESSION_FAILURE_KEY) ? "air" : "none",
34784
34817
  permissionPromptFields: true
34785
34818
  });
34786
34819
  }
@@ -37059,6 +37092,7 @@ var SessionIndexTitles = class {
37059
37092
 
37060
37093
  // src/CodexEventHandler.ts
37061
37094
  var MAX_SESSION_FAILURE_TITLE_LENGTH = 240;
37095
+ var SESSION_NOTICE_KIND = "notice";
37062
37096
  var SESSION_FAILURE_POLICY = {
37063
37097
  transport_lost: {
37064
37098
  category: "connection",
@@ -37141,12 +37175,14 @@ function failureWasShownAsMessage(error62) {
37141
37175
  return error62 instanceof RequestError && failuresShownAsMessages.has(error62);
37142
37176
  }
37143
37177
  var CodexEventHandler = class {
37144
- constructor(connection, sessionState, supportsTypedSessionFailures, sessionFailureEpoch, subagents, onAccountUpdated, collectTurnDiffs, supportsCompaction, supportsNotices) {
37178
+ constructor(connection, sessionState, sessionFailureFormat, sessionFailureEpoch, subagents, onAccountUpdated, collectTurnDiffs, supportsCompaction, supportsNotices, neutralFailures) {
37179
+ this.sessionFailureFormat = sessionFailureFormat;
37145
37180
  this.supportsCompaction = supportsCompaction;
37146
37181
  this.supportsNotices = supportsNotices;
37182
+ this.neutralFailures = neutralFailures;
37147
37183
  this.onAccountUpdated = onAccountUpdated;
37148
37184
  this.sessionState = sessionState;
37149
- this.supportsTypedSessionFailures = supportsTypedSessionFailures;
37185
+ this.supportsTypedSessionFailures = sessionFailureFormat !== "none";
37150
37186
  this.sessionFailureEpoch = sessionFailureEpoch;
37151
37187
  this.session = new ACPSessionConnection(connection, sessionState.sessionId);
37152
37188
  this.renderer = new AcpToolCallRenderer(sessionState.clientCapabilities);
@@ -37157,9 +37193,12 @@ var CodexEventHandler = class {
37157
37193
  this.failuresById.set(sessionState.sessionFailure.id, sessionState.sessionFailure);
37158
37194
  }
37159
37195
  }
37196
+ sessionFailureFormat;
37160
37197
  supportsCompaction;
37161
37198
  supportsNotices;
37199
+ neutralFailures;
37162
37200
  sessionState;
37201
+ /** The typed failure lane, in either form. Only {@link createSessionFailureMeta} reads the form itself. */
37163
37202
  supportsTypedSessionFailures;
37164
37203
  sessionFailureEpoch;
37165
37204
  pendingErrors = [];
@@ -37991,11 +38030,12 @@ ${event.details}` : event.summary;
37991
38030
  const previous = this.failuresById.get(id);
37992
38031
  const failure3 = {
37993
38032
  id,
37994
- revision: nextSessionFailureRevision(previous, id),
38033
+ revision: this.sessionFailureRevision(previous, id),
37995
38034
  category: policy.category,
37996
38035
  severity,
37997
38036
  title: readableServiceErrorMessage(title),
37998
- actions: actionsOverride ?? policy.actions
38037
+ actions: actionsOverride ?? policy.actions,
38038
+ kind
37999
38039
  };
38000
38040
  this.failuresById.set(id, failure3);
38001
38041
  this.failureTurnIdById.set(id, attributeToTurn ? turnId : void 0);
@@ -38010,7 +38050,14 @@ ${event.details}` : event.summary;
38010
38050
  return `${turnId}:error`;
38011
38051
  }
38012
38052
  this.allocatedFailureScopes.add(scope);
38013
- return `${scope}:error:${this.sessionFailureEpoch}:${this.nextNoticeId++}`;
38053
+ return `${scope}:error:${this.sessionFailureEpoch}:${this.nextIncidentNumber()}`;
38054
+ }
38055
+ nextIncidentNumber() {
38056
+ return this.sessionFailureFormat === "neutral" ? this.neutralFailures.incidentNumber() : this.nextNoticeId++;
38057
+ }
38058
+ sessionFailureRevision(previous, id) {
38059
+ const revision = nextSessionFailureRevision(previous, id);
38060
+ return this.sessionFailureFormat === "neutral" ? this.neutralFailures.revision(id, revision) : revision;
38014
38061
  }
38015
38062
  /**
38016
38063
  * A retry warning remains the active incident until Codex produces turn content again. That content is
@@ -38043,15 +38090,16 @@ ${event.details}` : event.summary;
38043
38090
  recordSessionNotice(title, details) {
38044
38091
  const key = `${title}\0${details ?? ""}`;
38045
38092
  const previous = this.lastSessionNotice?.key === key ? this.lastSessionNotice.failure : void 0;
38046
- const id = previous?.id ?? `${this.sessionState.sessionId}:notice:${this.sessionFailureEpoch}:${this.nextNoticeId++}`;
38093
+ const id = previous?.id ?? `${this.sessionState.sessionId}:notice:${this.sessionFailureEpoch}:${this.nextIncidentNumber()}`;
38047
38094
  const notice = {
38048
38095
  id,
38049
- revision: nextSessionFailureRevision(previous, id),
38096
+ revision: this.sessionFailureRevision(previous, id),
38050
38097
  category: "unknown",
38051
38098
  severity: "warning",
38052
38099
  title,
38053
38100
  ...details === void 0 ? {} : { details },
38054
- actions: []
38101
+ actions: [],
38102
+ kind: SESSION_NOTICE_KIND
38055
38103
  };
38056
38104
  this.lastSessionNotice = { key, failure: notice };
38057
38105
  return notice;
@@ -38062,11 +38110,15 @@ ${event.details}` : event.summary;
38062
38110
  return combinedTitle.length <= MAX_SESSION_FAILURE_TITLE_LENGTH ? [combinedTitle] : [summary, details];
38063
38111
  }
38064
38112
  createSessionFailureMeta(failure3) {
38113
+ if (this.sessionFailureFormat === "neutral") {
38114
+ return { [NEUTRAL_SESSION_FAILURE_META_KEY]: { version: SESSION_FAILURE_VERSION, ...failure3 } };
38115
+ }
38116
+ const { kind: _kind, ...airFailure } = failure3;
38065
38117
  return {
38066
38118
  [JETBRAINS_META_KEY]: {
38067
38119
  [AIR_META_KEY]: {
38068
38120
  [AIR_EXTENSION_VERSION_KEY]: AIR_EXTENSION_VERSION,
38069
- [AIR_SESSION_FAILURE_KEY]: failure3
38121
+ [AIR_SESSION_FAILURE_KEY]: airFailure
38070
38122
  }
38071
38123
  }
38072
38124
  };
@@ -40623,7 +40675,7 @@ var package_default = {
40623
40675
  publishConfig: {
40624
40676
  access: "public"
40625
40677
  },
40626
- version: "2.5.0-alas.4",
40678
+ version: "2.5.0-alas.5",
40627
40679
  description: "",
40628
40680
  main: "dist/index.js",
40629
40681
  bin: {
@@ -40701,7 +40753,7 @@ var package_default = {
40701
40753
  alasDownstream: {
40702
40754
  upstreamVersion: "2.5.0",
40703
40755
  upstreamCommit: "34e08970aa324a2be985f5080674d5aa91d7666f",
40704
- sourceCommit: "8af13bd4134b9a24acfd06b85418642f3c2742b6"
40756
+ sourceCommit: "d1c53266b4d5d1f308323259b81d01ea687104ef"
40705
40757
  }
40706
40758
  };
40707
40759
 
@@ -52124,9 +52176,6 @@ var DENY_ALL_ELICITATIONS = {
52124
52176
  handleElicitation: async () => ({ action: "cancel", content: null, _meta: null }),
52125
52177
  handleUserInput: async () => ({ answers: {} })
52126
52178
  };
52127
- function clientSupportsTypedSessionFailures(capabilities) {
52128
- return clientSupportsAirCapability(capabilities, AIR_SESSION_FAILURE_KEY);
52129
- }
52130
52179
  function clientSupportsAgentFileChangeReports(capabilities) {
52131
52180
  return clientSupportsAirCapability(capabilities, AIR_AGENT_FILE_CHANGE_REPORT_KEY);
52132
52181
  }
@@ -52146,6 +52195,7 @@ var CodexAcpServer = class {
52146
52195
  getExitCode;
52147
52196
  getRecentStderr;
52148
52197
  sessionFailureEpoch;
52198
+ neutralSessionFailures = new NeutralSessionFailureLedger();
52149
52199
  availableCommands;
52150
52200
  clientInfo;
52151
52201
  clientCapabilities;
@@ -52570,6 +52620,11 @@ var CodexAcpServer = class {
52570
52620
  ...protocolVersion === 1 && this.capabilities.diffPatchFormat === "neutral" ? {
52571
52621
  [NEUTRAL_DIFF_PATCH_META_KEY]: neutralDiffPatchCapability()
52572
52622
  } : {},
52623
+ // The client-neutral session failure, see `docs/air-extensions.md`. ACP v2 has its own terminal
52624
+ // failure state, so `ClientCapabilities.fromV2` never selects it.
52625
+ ...protocolVersion === 1 && this.capabilities.sessionFailureFormat === "neutral" ? {
52626
+ [NEUTRAL_SESSION_FAILURE_META_KEY]: neutralSessionFailureCapability()
52627
+ } : {},
52573
52628
  // The session index for a client that opted in without AIR, see `docs/air-extensions.md`.
52574
52629
  ...neutralSessionIndex ? {
52575
52630
  [NEUTRAL_SESSION_INDEX_META_KEY]: neutralSessionIndex
@@ -53192,13 +53247,14 @@ You have been logged out. Please try again.`);
53192
53247
  baselineEventHandler = new CodexEventHandler(
53193
53248
  this.connection,
53194
53249
  sessionState,
53195
- clientSupportsTypedSessionFailures(this.clientCapabilities),
53250
+ this.capabilities.sessionFailureFormat,
53196
53251
  this.sessionFailureEpoch,
53197
53252
  sessionState.subagents,
53198
53253
  (accountUpdated) => this.handleAccountUpdated(accountUpdated),
53199
53254
  false,
53200
53255
  clientSupportsCompaction(this.clientCapabilities),
53201
- clientSupportsNotices(this.clientCapabilities)
53256
+ clientSupportsNotices(this.clientCapabilities),
53257
+ this.neutralSessionFailures
53202
53258
  );
53203
53259
  }
53204
53260
  await this.trackCodexForegroundWork(sessionState, event);
@@ -54475,13 +54531,14 @@ You have been logged out. Please try again.`);
54475
54531
  const eventHandler = new CodexEventHandler(
54476
54532
  this.connection,
54477
54533
  sessionState,
54478
- clientSupportsTypedSessionFailures(this.clientCapabilities),
54534
+ this.capabilities.sessionFailureFormat,
54479
54535
  this.sessionFailureEpoch,
54480
54536
  sessionState.subagents,
54481
54537
  (accountUpdated) => this.handleAccountUpdated(accountUpdated),
54482
54538
  false,
54483
54539
  clientSupportsCompaction(this.clientCapabilities),
54484
- clientSupportsNotices(this.clientCapabilities)
54540
+ clientSupportsNotices(this.clientCapabilities),
54541
+ this.neutralSessionFailures
54485
54542
  );
54486
54543
  const permissionContext = this.permissionLifecycleContext(sessionState).beginPrompt();
54487
54544
  const toolCallRenderer = new AcpToolCallRenderer(this.capabilities);
@@ -56038,13 +56095,14 @@ You have been logged out. Please try again.`);
56038
56095
  const promptEventHandler = new CodexEventHandler(
56039
56096
  this.connection,
56040
56097
  sessionState,
56041
- clientSupportsTypedSessionFailures(this.clientCapabilities),
56098
+ this.capabilities.sessionFailureFormat,
56042
56099
  this.sessionFailureEpoch,
56043
56100
  sessionState.subagents,
56044
56101
  (accountUpdated) => this.handleAccountUpdated(accountUpdated),
56045
56102
  agentFileChangeReportRequest !== null,
56046
56103
  clientSupportsCompaction(this.clientCapabilities),
56047
- clientSupportsNotices(this.clientCapabilities)
56104
+ clientSupportsNotices(this.clientCapabilities),
56105
+ this.neutralSessionFailures
56048
56106
  );
56049
56107
  eventHandler = promptEventHandler;
56050
56108
  const permissionLifecycle = this.permissionLifecycleContext(sessionState);
@@ -56463,7 +56521,7 @@ You have been logged out. Please try again.`);
56463
56521
  }
56464
56522
  insertion?.onFailure?.(toV2Failure(err));
56465
56523
  const isUnexpectedFailure = !(err instanceof RequestError);
56466
- if (eventHandler !== null && clientSupportsTypedSessionFailures(this.clientCapabilities) && (isProcessExit || isUnexpectedFailure)) {
56524
+ if (eventHandler !== null && this.capabilities.sessionFailureFormat !== "none" && (isProcessExit || isUnexpectedFailure)) {
56467
56525
  eventHandler.recordSyntheticTerminalFailure(
56468
56526
  isProcessExit ? "transport_lost" : "internal_error",
56469
56527
  sessionState.currentTurnId
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "2.5.0-alas.4",
6
+ "version": "2.5.0-alas.5",
7
7
  "description": "",
8
8
  "main": "dist/index.js",
9
9
  "bin": {
@@ -81,6 +81,6 @@
81
81
  "alasDownstream": {
82
82
  "upstreamVersion": "2.5.0",
83
83
  "upstreamCommit": "34e08970aa324a2be985f5080674d5aa91d7666f",
84
- "sourceCommit": "8af13bd4134b9a24acfd06b85418642f3c2742b6"
84
+ "sourceCommit": "d1c53266b4d5d1f308323259b81d01ea687104ef"
85
85
  }
86
86
  }