@ycodium-ai/agent-acp 0.2.3024 → 0.2.3034

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 +91 -39
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -25259,6 +25259,62 @@ function acpModelChoicesFromSessionModels(models) {
25259
25259
  return out;
25260
25260
  }
25261
25261
 
25262
+ // ../../packages/ycodium-acp-executor/src/apply-effort.ts
25263
+ var applyRequestedEffort = async (input2) => {
25264
+ const requested = input2.requestedEffort?.trim();
25265
+ if (!requested) return;
25266
+ const effort = findAcpEffortConfig(input2.configOptions);
25267
+ if (effort === void 0) return;
25268
+ const matched = effort.choices.find((choice) => choice.value === requested);
25269
+ if (matched === void 0) {
25270
+ input2.log?.info("requested effort is not in the agent catalog; keeping its own", {
25271
+ requestedEffort: requested,
25272
+ advertised: effort.choices.map((choice) => choice.value)
25273
+ });
25274
+ return;
25275
+ }
25276
+ if (matched.isDefault === true) return;
25277
+ if (!input2.isLive(input2.expectedGeneration)) return;
25278
+ try {
25279
+ await input2.connection.request("session/set_config_option", {
25280
+ sessionId: input2.acpSessionId,
25281
+ configId: effort.configId,
25282
+ value: requested
25283
+ });
25284
+ } catch (error62) {
25285
+ input2.log?.info("setting the effort level failed; the session keeps its own", {
25286
+ requestedEffort: requested,
25287
+ configId: effort.configId,
25288
+ error: error62 instanceof Error ? error62.message : String(error62)
25289
+ });
25290
+ }
25291
+ };
25292
+
25293
+ // ../../packages/ycodium-acp-executor/src/failureCategory.ts
25294
+ var ACP_FAILURE_CATEGORIES = [
25295
+ "quota",
25296
+ "rate-limit",
25297
+ "context-limit",
25298
+ "auth",
25299
+ "model-unavailable",
25300
+ "transport",
25301
+ "unknown"
25302
+ ];
25303
+ var isAcpFailureCategory = (value) => ACP_FAILURE_CATEGORIES.some((category) => category === value);
25304
+ var readAcpFailureCategory = (error62) => {
25305
+ if (typeof error62 !== "object" || error62 === null) return void 0;
25306
+ const value = error62.failureCategory;
25307
+ return isAcpFailureCategory(value) ? value : void 0;
25308
+ };
25309
+ var withFailureCategory = (error62, category) => category === void 0 ? error62 : Object.assign(error62, { failureCategory: category });
25310
+ var failureCategoryField = (category) => category === void 0 ? {} : { failureCategory: category };
25311
+ var acpTransportIfEstablished = (sessionEstablished, disposed) => sessionEstablished && !disposed ? "transport" : void 0;
25312
+ var acpPromptFailureCategory = (error62, input2) => {
25313
+ const signaled = readAcpFailureCategory(error62);
25314
+ if (signaled !== void 0) return signaled;
25315
+ return error62 instanceof AcpConnectionClosedError ? acpTransportIfEstablished(input2.sessionEstablished, input2.disposed) : void 0;
25316
+ };
25317
+
25262
25318
  // ../../packages/ycodium-acp-executor/src/runtime-mode.ts
25263
25319
  function isRecord5(value) {
25264
25320
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -25361,7 +25417,7 @@ var ACP_CONFIG_CATEGORY_HANDLING = {
25361
25417
  },
25362
25418
  thought_level: {
25363
25419
  consumed: true,
25364
- via: "config-options.ts:findAcpEffortConfig \u2192 executor.ts:applyRequestedEffort"
25420
+ via: "config-options.ts:findAcpEffortConfig \u2192 apply-effort.ts:applyRequestedEffort"
25365
25421
  },
25366
25422
  model_option: {
25367
25423
  consumed: true,
@@ -25849,11 +25905,16 @@ function createAcpExecutor(options) {
25849
25905
  payload: { answers }
25850
25906
  });
25851
25907
  };
25852
- const abortPendingSettlement = (reason) => {
25908
+ const abortPendingSettlement = (reason, failureCategory) => {
25853
25909
  const waiting = pendingSettlement;
25854
25910
  if (waiting === void 0) return;
25855
25911
  pendingSettlement = void 0;
25856
- waiting.settle({ error: new AcpExecutorRequestError("session/prompt", reason) });
25912
+ waiting.settle({
25913
+ error: withFailureCategory(
25914
+ new AcpExecutorRequestError("session/prompt", reason),
25915
+ failureCategory
25916
+ )
25917
+ });
25857
25918
  };
25858
25919
  const settleAllUserInputs = () => {
25859
25920
  for (const pending of pendingUserInputs.values()) {
@@ -25877,9 +25938,12 @@ function createAcpExecutor(options) {
25877
25938
  rememberSettledPromptKey(waiting.promptKey);
25878
25939
  if (signal.outcome === "error") {
25879
25940
  waiting.settle({
25880
- error: new AcpExecutorRequestError(
25881
- "session/prompt",
25882
- signal.detail ?? "prompt failed without an error detail"
25941
+ error: withFailureCategory(
25942
+ new AcpExecutorRequestError(
25943
+ "session/prompt",
25944
+ signal.detail ?? "prompt failed without an error detail"
25945
+ ),
25946
+ signal.failureCategory
25883
25947
  )
25884
25948
  });
25885
25949
  } else {
@@ -26034,7 +26098,10 @@ function createAcpExecutor(options) {
26034
26098
  }
26035
26099
  settleAllApprovals("cancel");
26036
26100
  settleAllUserInputs();
26037
- abortPendingSettlement("connection closed");
26101
+ abortPendingSettlement(
26102
+ "connection closed",
26103
+ acpTransportIfEstablished(startResult !== void 0, disposed)
26104
+ );
26038
26105
  promptWaiters.splice(0).forEach((wake) => wake());
26039
26106
  },
26040
26107
  () => {
@@ -26089,35 +26156,6 @@ function createAcpExecutor(options) {
26089
26156
  }
26090
26157
  return { ...input2.state, currentModelId: value, configOptions };
26091
26158
  };
26092
- const applyRequestedEffort = async (input2) => {
26093
- const requested = input2.requestedEffort?.trim();
26094
- if (!requested) return;
26095
- const effort = findAcpEffortConfig(input2.configOptions);
26096
- if (effort === void 0) return;
26097
- const matched = effort.choices.find((choice) => choice.value === requested);
26098
- if (matched === void 0) {
26099
- options.log?.info("requested effort is not in the agent catalog; keeping its own", {
26100
- requestedEffort: requested,
26101
- advertised: effort.choices.map((choice) => choice.value)
26102
- });
26103
- return;
26104
- }
26105
- if (matched.isDefault === true) return;
26106
- if (!isLive(input2.expectedGeneration)) return;
26107
- try {
26108
- await connection.request("session/set_config_option", {
26109
- sessionId: input2.acpSessionId,
26110
- configId: effort.configId,
26111
- value: requested
26112
- });
26113
- } catch (error62) {
26114
- options.log?.info("setting the effort level failed; the session keeps its own", {
26115
- requestedEffort: requested,
26116
- configId: effort.configId,
26117
- error: error62 instanceof Error ? error62.message : String(error62)
26118
- });
26119
- }
26120
- };
26121
26159
  const startOnce = async (expectedGeneration) => {
26122
26160
  const initializePayload = acpInitializePayload(options.clientInfo, options.clientCapabilities);
26123
26161
  const initialized = await connection.request(
@@ -26192,6 +26230,9 @@ function createAcpExecutor(options) {
26192
26230
  expectedGeneration
26193
26231
  });
26194
26232
  await applyRequestedEffort({
26233
+ connection,
26234
+ log: options.log,
26235
+ isLive,
26195
26236
  configOptions: nextModelSelectionState.configOptions,
26196
26237
  acpSessionId: nextSessionId,
26197
26238
  requestedEffort: options.requestedEffort,
@@ -26314,7 +26355,8 @@ function createAcpExecutor(options) {
26314
26355
  payload: {
26315
26356
  state: input2.state,
26316
26357
  stopReason: input2.stopReason,
26317
- ...input2.errorMessage === void 0 ? {} : { errorMessage: input2.errorMessage }
26358
+ ...input2.errorMessage === void 0 ? {} : { errorMessage: input2.errorMessage },
26359
+ ...input2.state === "failed" ? failureCategoryField(input2.failureCategory) : {}
26318
26360
  }
26319
26361
  });
26320
26362
  interruptedTurnIds.delete(input2.turnId);
@@ -26411,15 +26453,25 @@ function createAcpExecutor(options) {
26411
26453
  if (disposed) {
26412
26454
  throw new AcpExecutorDisposedError();
26413
26455
  }
26456
+ const failureCategory = acpPromptFailureCategory(error62, {
26457
+ sessionEstablished: startResult !== void 0,
26458
+ disposed
26459
+ });
26414
26460
  if (written && input2.onDispatched !== void 0 && !interruptedTurnIds.has(turnId)) {
26415
26461
  const errorMessage = error62 instanceof Error && error62.message.trim() || "ACP prompt failed";
26416
- if (settle2({ turnId, stopReason: "error", state: "failed", errorMessage }))
26462
+ if (settle2({
26463
+ turnId,
26464
+ stopReason: "error",
26465
+ state: "failed",
26466
+ errorMessage,
26467
+ ...failureCategory === void 0 ? {} : { failureCategory }
26468
+ }))
26417
26469
  options.log?.warn?.("turn failed after dispatch", {
26418
26470
  threadId: options.threadId,
26419
26471
  failure: errorMessage
26420
26472
  });
26421
26473
  }
26422
- throw error62;
26474
+ throw error62 instanceof Error ? withFailureCategory(error62, failureCategory) : error62;
26423
26475
  }
26424
26476
  await connection.awaitInboundIdle();
26425
26477
  if (options.beforeApplyResult) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ycodium-ai/agent-acp",
3
- "version": "0.2.3024",
3
+ "version": "0.2.3034",
4
4
  "description": "Generic ACP executor: user-supplied CLI over Agent Client Protocol stdio.",
5
5
  "keywords": [
6
6
  "ycodium",
@@ -21,9 +21,9 @@
21
21
  "@types/node": "24.12.4",
22
22
  "esbuild": "0.28.1",
23
23
  "vite-plus": "0.2.2",
24
- "ycodium-acp-executor": "0.2.0",
25
- "ycodium-executor-testing": "0.0.0",
26
- "@ycodium-ai/plugin-api": "0.2.3024"
24
+ "@ycodium-ai/plugin-api": "0.2.3034",
25
+ "ycodium-acp-executor": "0.2.3034",
26
+ "ycodium-executor-testing": "0.0.0"
27
27
  },
28
28
  "ycodium": {
29
29
  "plugin": "./dist/index.js",