@alas-ide/codex-acp 2.5.0-alas.6 → 2.5.0-alas.8

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 +88 -28
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -32121,6 +32121,18 @@ var CODEX_NETWORK_PERMISSION_TITLE = "Allow network access?";
32121
32121
  var CODEX_FILE_CHANGE_PERMISSION_TITLE = "Make edits?";
32122
32122
  var CODEX_ADDITIONAL_PERMISSIONS_TITLE = "Grant permissions?";
32123
32123
  var PERMISSION_PROMPT_META_KEY = "permission_prompt";
32124
+ var NEUTRAL_PERMISSION_PRESENTATION_META_KEY = "permissionPresentation";
32125
+ var NEUTRAL_QUESTION_CUSTOM_ANSWER_META_KEY = "questionCustomAnswer";
32126
+ var NEUTRAL_RECOMMENDED_CONFIG_VALUE_META_KEY = "recommendedConfigValue";
32127
+ function neutralPresentationCapability() {
32128
+ return { version: 1 };
32129
+ }
32130
+ function clientRequestsNeutralPresentation(capabilities, key) {
32131
+ const declared = capabilities?._meta?.[key];
32132
+ if (declared === null || typeof declared !== "object" || Array.isArray(declared)) return false;
32133
+ const version2 = declared["version"];
32134
+ return typeof version2 === "number" && Number.isInteger(version2) && version2 >= 1;
32135
+ }
32124
32136
  function requestPermissionMeta(capabilities, title, reason) {
32125
32137
  const description = nonBlank(reason);
32126
32138
  const permission = {
@@ -32130,6 +32142,7 @@ function requestPermissionMeta(capabilities, title, reason) {
32130
32142
  };
32131
32143
  const meta3 = {
32132
32144
  ...airOnlyMeta(capabilities.airClient, AIR_PERMISSION_KEY, permission),
32145
+ ...capabilities.neutralPermissionPresentation ? { [NEUTRAL_PERMISSION_PRESENTATION_META_KEY]: permission } : {},
32133
32146
  ...capabilities.permissionPromptFields ? { [PERMISSION_PROMPT_META_KEY]: permission } : {}
32134
32147
  };
32135
32148
  return Object.keys(meta3).length > 0 ? { _meta: meta3 } : {};
@@ -32141,11 +32154,15 @@ function readPermissionMeta(meta3) {
32141
32154
  if (typeof title !== "string") return void 0;
32142
32155
  return { version: 1, title, ...typeof description === "string" ? { description } : {} };
32143
32156
  }
32144
- function optionPermissionMeta(airClient, description) {
32157
+ function optionPermissionMeta(capabilities, description) {
32145
32158
  const normalized = nonBlank(description);
32146
32159
  if (!normalized) return void 0;
32147
32160
  const permission = { version: 1, description: normalized };
32148
- return airOnlyMeta(airClient, AIR_PERMISSION_KEY, permission);
32161
+ const meta3 = {
32162
+ ...airOnlyMeta(capabilities.airClient, AIR_PERMISSION_KEY, permission),
32163
+ ...capabilities.neutralPermissionPresentation ? { [NEUTRAL_PERMISSION_PRESENTATION_META_KEY]: permission } : {}
32164
+ };
32165
+ return Object.keys(meta3).length > 0 ? meta3 : void 0;
32149
32166
  }
32150
32167
  function nonBlank(value) {
32151
32168
  const normalized = value?.trim();
@@ -35074,7 +35091,10 @@ var ClientCapabilities = class _ClientCapabilities {
35074
35091
  diffPatchFormat: "none",
35075
35092
  sessionFailureFormat: "none",
35076
35093
  agentFileChangeReportFormat: "none",
35077
- permissionPromptFields: false
35094
+ permissionPromptFields: false,
35095
+ neutralPermissionPresentation: false,
35096
+ neutralQuestionCustomAnswer: false,
35097
+ neutralRecommendedConfigValue: false
35078
35098
  });
35079
35099
  /** The client declares `_meta.jetbrains.air`. */
35080
35100
  airClient;
@@ -35096,6 +35116,12 @@ var ClientCapabilities = class _ClientCapabilities {
35096
35116
  agentFileChangeReportFormat;
35097
35117
  /** A permission request has its own `title` and `description` (ACP v2). */
35098
35118
  permissionPromptFields;
35119
+ /** The client gets the permission presentation in `_meta.permissionPresentation`. Only ACP v1 reads the opt-in. */
35120
+ neutralPermissionPresentation;
35121
+ /** A question's note field carries `_meta.questionCustomAnswer`. Only ACP v1 reads the opt-in. */
35122
+ neutralQuestionCustomAnswer;
35123
+ /** Model and effort selectors carry `_meta.recommendedConfigValue`. Only ACP v1 reads the opt-in. */
35124
+ neutralRecommendedConfigValue;
35099
35125
  constructor(values) {
35100
35126
  this.airClient = values.airClient;
35101
35127
  this.airToolCallContract = values.airToolCallContract;
@@ -35109,6 +35135,9 @@ var ClientCapabilities = class _ClientCapabilities {
35109
35135
  this.sessionFailureFormat = values.sessionFailureFormat;
35110
35136
  this.agentFileChangeReportFormat = values.agentFileChangeReportFormat;
35111
35137
  this.permissionPromptFields = values.permissionPromptFields;
35138
+ this.neutralPermissionPresentation = values.neutralPermissionPresentation;
35139
+ this.neutralQuestionCustomAnswer = values.neutralQuestionCustomAnswer;
35140
+ this.neutralRecommendedConfigValue = values.neutralRecommendedConfigValue;
35112
35141
  }
35113
35142
  static from(capabilities) {
35114
35143
  const airClient = isAirClient(capabilities);
@@ -35133,7 +35162,10 @@ var ClientCapabilities = class _ClientCapabilities {
35133
35162
  sessionFailureFormat: clientRequestsNeutralSessionFailure(capabilities) ? "neutral" : clientSupportsAirCapability(capabilities, AIR_SESSION_FAILURE_KEY) ? "air" : "none",
35134
35163
  // Likewise. The request and the report use the selected form.
35135
35164
  agentFileChangeReportFormat: clientRequestsNeutralAgentFileChangeReport(capabilities) ? "neutral" : clientSupportsAirCapability(capabilities, AIR_AGENT_FILE_CHANGE_REPORT_KEY) ? "air" : "none",
35136
- permissionPromptFields: false
35165
+ permissionPromptFields: false,
35166
+ neutralPermissionPresentation: clientRequestsNeutralPresentation(capabilities, NEUTRAL_PERMISSION_PRESENTATION_META_KEY),
35167
+ neutralQuestionCustomAnswer: clientRequestsNeutralPresentation(capabilities, NEUTRAL_QUESTION_CUSTOM_ANSWER_META_KEY),
35168
+ neutralRecommendedConfigValue: clientRequestsNeutralPresentation(capabilities, NEUTRAL_RECOMMENDED_CONFIG_VALUE_META_KEY)
35137
35169
  });
35138
35170
  }
35139
35171
  /**
@@ -35159,7 +35191,11 @@ var ClientCapabilities = class _ClientCapabilities {
35159
35191
  sessionFailureFormat: clientSupportsAirCapability(capabilities, AIR_SESSION_FAILURE_KEY) ? "air" : "none",
35160
35192
  // The client-neutral report is an ACP v1 extension, so v2 ignores its opt-in.
35161
35193
  agentFileChangeReportFormat: clientSupportsAirCapability(capabilities, AIR_AGENT_FILE_CHANGE_REPORT_KEY) ? "air" : "none",
35162
- permissionPromptFields: true
35194
+ permissionPromptFields: true,
35195
+ // A v2 request has its own title and description, so v2 ignores both client-neutral opt-ins.
35196
+ neutralPermissionPresentation: false,
35197
+ neutralQuestionCustomAnswer: false,
35198
+ neutralRecommendedConfigValue: false
35163
35199
  });
35164
35200
  }
35165
35201
  /**
@@ -35447,7 +35483,13 @@ function modelOptions(availableModels, currentBaseModelId) {
35447
35483
  }
35448
35484
  return options;
35449
35485
  }
35450
- function createModelConfigOption(availableModels, currentBaseModelId, recommendedModelId) {
35486
+ function recommendationMeta(value, records) {
35487
+ return {
35488
+ ...records.air ? withAirMeta(void 0, AIR_RECOMMENDED_CONFIG_VALUE_KEY, value) : {},
35489
+ ...records.neutral ? { [NEUTRAL_RECOMMENDED_CONFIG_VALUE_META_KEY]: { version: 1, value } } : {}
35490
+ };
35491
+ }
35492
+ function createModelConfigOption(availableModels, currentBaseModelId, recommendedModelId, records = { air: true, neutral: false }) {
35451
35493
  const options = modelOptions(availableModels, currentBaseModelId);
35452
35494
  const recommendation = recommendedModelId && options.some((option) => option.value === recommendedModelId) ? recommendedModelId : void 0;
35453
35495
  return {
@@ -35458,10 +35500,10 @@ function createModelConfigOption(availableModels, currentBaseModelId, recommende
35458
35500
  type: "select",
35459
35501
  currentValue: currentBaseModelId,
35460
35502
  options,
35461
- ...recommendation ? { _meta: withAirMeta(void 0, AIR_RECOMMENDED_CONFIG_VALUE_KEY, recommendation) } : {}
35503
+ ...recommendation ? { _meta: recommendationMeta(recommendation, records) } : {}
35462
35504
  };
35463
35505
  }
35464
- function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEffort, recommendedEffort) {
35506
+ function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEffort, recommendedEffort, records = { air: true, neutral: false }) {
35465
35507
  const recommendation = findSupportedEffort(supportedReasoningEfforts, recommendedEffort);
35466
35508
  return {
35467
35509
  id: REASONING_EFFORT_CONFIG_ID,
@@ -35475,7 +35517,7 @@ function createReasoningEffortConfigOption(supportedReasoningEfforts, currentEff
35475
35517
  name: capitalize(option.reasoningEffort),
35476
35518
  description: option.description
35477
35519
  })),
35478
- ...recommendation ? { _meta: withAirMeta(void 0, AIR_RECOMMENDED_CONFIG_VALUE_KEY, recommendation) } : {}
35520
+ ...recommendation ? { _meta: recommendationMeta(recommendation, records) } : {}
35479
35521
  };
35480
35522
  }
35481
35523
  function createSubagentModelConfigOption(availableModels, parentBaseModelId, model) {
@@ -38937,9 +38979,9 @@ function parsePersistOptions(meta3) {
38937
38979
  function isMcpToolCallApproval(meta3) {
38938
38980
  return isRecord2(meta3) && meta3["codex_approval_kind"] === "mcp_tool_call";
38939
38981
  }
38940
- function buildMcpPermissionOptions(isToolApproval, persistOptions, airClient) {
38982
+ function buildMcpPermissionOptions(isToolApproval, persistOptions, capabilities) {
38941
38983
  const permissionOption2 = (optionId, name, kind, description) => {
38942
- const meta3 = optionPermissionMeta(airClient, description);
38984
+ const meta3 = optionPermissionMeta(capabilities, description);
38943
38985
  return { optionId, name, kind, ...meta3 ? { _meta: meta3 } : {} };
38944
38986
  };
38945
38987
  const options = [permissionOption2(
@@ -39001,7 +39043,7 @@ function buildMcpPermissionRequest(sessionId, params, context, nextStandaloneToo
39001
39043
  options: buildMcpPermissionOptions(
39002
39044
  context.isToolApproval,
39003
39045
  context.persistOptions,
39004
- renderer.capabilities.airClient
39046
+ renderer.capabilities
39005
39047
  )
39006
39048
  },
39007
39049
  correlatedCallId
@@ -39114,7 +39156,7 @@ function userInputResponseValue(content, fieldId) {
39114
39156
  }
39115
39157
  return value;
39116
39158
  }
39117
- function buildUserInputSchema(questions, clientCapabilities, answersRequired) {
39159
+ function buildUserInputSchema(questions, clientCapabilities, answersRequired, neutralCustomAnswer = false) {
39118
39160
  const properties = {};
39119
39161
  const required2 = [];
39120
39162
  const questionIds = new Set(questions.map((question) => question.id));
@@ -39166,7 +39208,10 @@ function buildUserInputSchema(questions, clientCapabilities, answersRequired) {
39166
39208
  properties[userInputNoteFieldId(question.id, questionIds)] = {
39167
39209
  type: "string",
39168
39210
  title: "Additional answer or note",
39169
- _meta: airClient ? withAirMeta({ ...noteMeta, [LEGACY_AIR_CUSTOM_ANSWER_KEY]: true }, AIR_CUSTOM_ANSWER_KEY, true) : noteMeta
39211
+ _meta: {
39212
+ ...airClient ? withAirMeta({ ...noteMeta, [LEGACY_AIR_CUSTOM_ANSWER_KEY]: true }, AIR_CUSTOM_ANSWER_KEY, true) : noteMeta,
39213
+ ...neutralCustomAnswer ? { [NEUTRAL_QUESTION_CUSTOM_ANSWER_META_KEY]: { version: 1, questionId: question.id } } : {}
39214
+ }
39170
39215
  };
39171
39216
  }
39172
39217
  }
@@ -39176,13 +39221,13 @@ function buildUserInputSchema(questions, clientCapabilities, answersRequired) {
39176
39221
  ...answersRequired ? { required: required2 } : {}
39177
39222
  };
39178
39223
  }
39179
- function buildUserInputRequest(params, clientCapabilities) {
39224
+ function buildUserInputRequest(params, clientCapabilities, neutralCustomAnswer) {
39180
39225
  return {
39181
39226
  sessionId: params.threadId,
39182
39227
  toolCallId: params.itemId,
39183
39228
  mode: "form",
39184
39229
  message: "Codex needs your input to continue.",
39185
- requestedSchema: buildUserInputSchema(params.questions, clientCapabilities, true),
39230
+ requestedSchema: buildUserInputSchema(params.questions, clientCapabilities, true, neutralCustomAnswer),
39186
39231
  _meta: {
39187
39232
  codex: {
39188
39233
  autoResolutionMs: params.autoResolutionMs
@@ -39345,7 +39390,7 @@ var CodexElicitationHandler = class {
39345
39390
  return cancellationSignal ? { cancellationSignal } : void 0;
39346
39391
  }
39347
39392
  async requestUserInputElicitation(params) {
39348
- const request = buildUserInputRequest(params, this.clientCapabilities);
39393
+ const request = buildUserInputRequest(params, this.clientCapabilities, this.renderer.capabilities.neutralQuestionCustomAnswer);
39349
39394
  const signal = subagentInteractionSignal(params.threadId, this.cancellationSignal);
39350
39395
  if (params.autoResolutionMs === null) {
39351
39396
  return await withSubagentUserAction(params.threadId, () => this.connection.request(
@@ -40721,7 +40766,7 @@ var package_default = {
40721
40766
  publishConfig: {
40722
40767
  access: "public"
40723
40768
  },
40724
- version: "2.5.0-alas.6",
40769
+ version: "2.5.0-alas.8",
40725
40770
  description: "",
40726
40771
  main: "dist/index.js",
40727
40772
  bin: {
@@ -40799,7 +40844,7 @@ var package_default = {
40799
40844
  alasDownstream: {
40800
40845
  upstreamVersion: "2.5.0",
40801
40846
  upstreamCommit: "34e08970aa324a2be985f5080674d5aa91d7666f",
40802
- sourceCommit: "7c99c083270255f2960fa4cd2da93f72bdf402ad"
40847
+ sourceCommit: "bd5ff04afa9b20774e3a7ff1559172fbf50fe9f4"
40803
40848
  }
40804
40849
  };
40805
40850
 
@@ -49257,14 +49302,16 @@ var AsyncQuestionClient = class {
49257
49302
  }
49258
49303
  };
49259
49304
  var AsyncQuestionElicitations = class {
49260
- constructor(sessionId, clientCapabilities, client) {
49305
+ constructor(sessionId, clientCapabilities, client, neutralCustomAnswer = false) {
49261
49306
  this.sessionId = sessionId;
49262
49307
  this.clientCapabilities = clientCapabilities;
49263
49308
  this.client = client;
49309
+ this.neutralCustomAnswer = neutralCustomAnswer;
49264
49310
  }
49265
49311
  sessionId;
49266
49312
  clientCapabilities;
49267
49313
  client;
49314
+ neutralCustomAnswer;
49268
49315
  // The running turns that asked a question, each with the signal that cancels its questions.
49269
49316
  turns = /* @__PURE__ */ new Map();
49270
49317
  /** Asks the questions of a completed async message and cancels them when their turn ends; never waits. */
@@ -49309,7 +49356,7 @@ var AsyncQuestionElicitations = class {
49309
49356
  mode: "form",
49310
49357
  message: "Codex keeps working while you answer. An answer sent after it finishes is not delivered.",
49311
49358
  // Questions are answered independently, as in Codex.
49312
- requestedSchema: buildUserInputSchema(questions, this.clientCapabilities, false),
49359
+ requestedSchema: buildUserInputSchema(questions, this.clientCapabilities, false, this.neutralCustomAnswer),
49313
49360
  _meta: { codex: { delivery: "async" } }
49314
49361
  };
49315
49362
  void this.client.createElicitation(request, turn.signal).then(
@@ -52673,6 +52720,17 @@ var CodexAcpServer = class {
52673
52720
  ...protocolVersion === 1 && this.capabilities.agentFileChangeReportFormat === "neutral" ? {
52674
52721
  [NEUTRAL_AGENT_FILE_CHANGE_REPORT_META_KEY]: neutralAgentFileChangeReportCapability()
52675
52722
  } : {},
52723
+ // The client-neutral presentation contracts, see `docs/air-extensions.md`. `ClientCapabilities.fromV2`
52724
+ // never selects them.
52725
+ ...this.capabilities.neutralPermissionPresentation ? {
52726
+ [NEUTRAL_PERMISSION_PRESENTATION_META_KEY]: neutralPresentationCapability()
52727
+ } : {},
52728
+ ...this.capabilities.neutralQuestionCustomAnswer ? {
52729
+ [NEUTRAL_QUESTION_CUSTOM_ANSWER_META_KEY]: neutralPresentationCapability()
52730
+ } : {},
52731
+ ...this.capabilities.neutralRecommendedConfigValue ? {
52732
+ [NEUTRAL_RECOMMENDED_CONFIG_VALUE_META_KEY]: neutralPresentationCapability()
52733
+ } : {},
52676
52734
  // The session index for a client that opted in without AIR, see `docs/air-extensions.md`.
52677
52735
  ...neutralSessionIndex ? {
52678
52736
  [NEUTRAL_SESSION_INDEX_META_KEY]: neutralSessionIndex
@@ -54721,10 +54779,11 @@ You have been logged out. Please try again.`);
54721
54779
  }
54722
54780
  createSessionConfigOptions(sessionState) {
54723
54781
  const currentModelId = ModelId.fromString(sessionState.currentModelId);
54724
- const useRecommendedValue = clientSupportsAirCapability(
54725
- this.clientCapabilities,
54726
- AIR_RECOMMENDED_CONFIG_VALUE_KEY
54727
- );
54782
+ const records = {
54783
+ air: clientSupportsAirCapability(this.clientCapabilities, AIR_RECOMMENDED_CONFIG_VALUE_KEY),
54784
+ neutral: this.capabilities.neutralRecommendedConfigValue
54785
+ };
54786
+ const useRecommendedValue = records.air || records.neutral;
54728
54787
  const currentModel = this.findCurrentModel(sessionState.availableModels, sessionState.currentModelId);
54729
54788
  const recommendedModelId = useRecommendedValue ? sessionState.availableModels.find((model) => model.isDefault)?.id : void 0;
54730
54789
  const configOptions = [
@@ -54732,14 +54791,15 @@ You have been logged out. Please try again.`);
54732
54791
  createCollaborationModeConfigOption(sessionState.collaborationMode)
54733
54792
  ];
54734
54793
  if (sessionState.availableModels.length > 0) {
54735
- configOptions.push(createModelConfigOption(sessionState.availableModels, currentModelId.model, recommendedModelId));
54794
+ configOptions.push(createModelConfigOption(sessionState.availableModels, currentModelId.model, recommendedModelId, records));
54736
54795
  }
54737
54796
  if (sessionState.supportedReasoningEfforts.length > 0) {
54738
54797
  configOptions.push(
54739
54798
  createReasoningEffortConfigOption(
54740
54799
  sessionState.supportedReasoningEfforts,
54741
54800
  currentModelId.effort,
54742
- useRecommendedValue ? currentModel?.defaultReasoningEffort : void 0
54801
+ useRecommendedValue ? currentModel?.defaultReasoningEffort : void 0,
54802
+ records
54743
54803
  )
54744
54804
  );
54745
54805
  }
@@ -56659,7 +56719,7 @@ You have been logged out. Please try again.`);
56659
56719
  this.connection,
56660
56720
  this.clientCapabilities,
56661
56721
  () => this.codexAcpClient
56662
- ));
56722
+ ), this.capabilities.neutralQuestionCustomAnswer);
56663
56723
  this.asyncQuestions.set(sessionId, questions);
56664
56724
  }
56665
56725
  return questions;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "2.5.0-alas.6",
6
+ "version": "2.5.0-alas.8",
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": "7c99c083270255f2960fa4cd2da93f72bdf402ad"
84
+ "sourceCommit": "bd5ff04afa9b20774e3a7ff1559172fbf50fe9f4"
85
85
  }
86
86
  }