lody 0.85.0 → 0.86.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.
@@ -20989,17 +20989,42 @@ var ACPSessionConnection = class {
20989
20989
  });
20990
20990
  }
20991
20991
  };
20992
- var GOAL_EXTENSION_VERSION = 1;
20993
- var GOAL_CONTROL_METHOD = "_session/goal";
20994
- var LEGACY_GOAL_CONTROL_METHOD = "_codex/session/goal_control";
20995
- var GOAL_CONTROL_ACTIONS = ["set", "pause", "resume", "clear"];
20992
+ var LODY_EXTENSION_METHODS = {
20993
+ sessionUsageUpdate: "_lody/session/usage_update",
20994
+ rateLimitsGet: "_lody/rate_limits/get",
20995
+ rateLimitsUpdate: "_lody/rate_limits/update",
20996
+ sessionSteer: "_lody/session/steer",
20997
+ sessionSteerApplied: "_lody/session/steer_applied",
20998
+ sessionGoal: "_lody/session/goal",
20999
+ sessionHistoryRead: "_lody/session/history/read"
21000
+ };
21001
+ var LODY_TOOL_NAMES = {
21002
+ imageGeneration: "ImageGeneration"
21003
+ };
21004
+ var GOAL_CONTROL_METHOD = LODY_EXTENSION_METHODS.sessionGoal;
20996
21005
  var LEGACY_SET_SESSION_MODEL_METHOD = "session/set_model";
20997
- var ACP_EXT_SESSION_USAGE_UPDATE_METHOD = "_acp_ext:session_usage_update";
20998
- var ACP_EXT_SESSION_RATE_LIMITS_METHOD = "_acp_ext:session_rate_limits";
20999
- var ACP_EXT_CODEX_PROPOSED_PLAN_METHOD = "_acp_ext:codex_proposed_plan";
21000
- var CODEX_STEER_APPLIED_METHOD = "_codex/steerApplied";
21001
- var SESSION_STEERING_METHOD = "_session/steering";
21002
- var LODY_READ_SESSION_HISTORY_METHOD = "_lody/session/history/read";
21006
+ var ACP_EXT_SESSION_USAGE_UPDATE_METHOD = LODY_EXTENSION_METHODS.sessionUsageUpdate;
21007
+ var ACP_EXT_SESSION_RATE_LIMITS_METHOD = LODY_EXTENSION_METHODS.rateLimitsUpdate;
21008
+ var CODEX_STEER_APPLIED_METHOD = LODY_EXTENSION_METHODS.sessionSteerApplied;
21009
+ var SESSION_STEERING_METHOD = LODY_EXTENSION_METHODS.sessionSteer;
21010
+ var LODY_READ_SESSION_HISTORY_METHOD = LODY_EXTENSION_METHODS.sessionHistoryRead;
21011
+ var LODY_RATE_LIMITS_GET_METHOD = LODY_EXTENSION_METHODS.rateLimitsGet;
21012
+ var CODEX_LODY_CAPABILITIES = {
21013
+ usage: { version: 1 },
21014
+ rateLimits: { version: 1, query: true },
21015
+ forkAtTurn: { version: 1 },
21016
+ steering: {
21017
+ version: 1,
21018
+ transport: "request",
21019
+ upstreamTurn: "same",
21020
+ configPolicy: "active"
21021
+ },
21022
+ tasks: { version: 1, background: true },
21023
+ subagents: { version: 1, lifecycle: true },
21024
+ goal: { version: 1, actions: ["set", "pause", "resume", "clear"] },
21025
+ compaction: { version: 1 },
21026
+ sessionHistory: { version: 1 }
21027
+ };
21003
21028
  function getLodyForkTurnId(meta3) {
21004
21029
  if (typeof meta3 !== "object" || meta3 === null) return null;
21005
21030
  const lody = meta3["lody"];
@@ -21010,19 +21035,8 @@ function getLodyForkTurnId(meta3) {
21010
21035
  const turnId = forkAtTurn["turnId"];
21011
21036
  return version2 === 1 && typeof turnId === "string" && turnId.length > 0 ? turnId : null;
21012
21037
  }
21013
- var CODEX_STEER_CAPABILITY = {
21014
- version: 1,
21015
- method: SESSION_STEERING_METHOD,
21016
- appliedNotification: CODEX_STEER_APPLIED_METHOD,
21017
- upstreamTurn: "same",
21018
- configPolicy: "active"
21019
- };
21020
- var LODY_READ_SESSION_HISTORY_CAPABILITY = {
21021
- version: 1,
21022
- method: LODY_READ_SESSION_HISTORY_METHOD
21023
- };
21024
21038
  function isExtMethodRequest(request) {
21025
- 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;
21039
+ return request.method === "authentication/status" || request.method === "authentication/logout" || request.method === LEGACY_SET_SESSION_MODEL_METHOD || request.method === GOAL_CONTROL_METHOD || request.method === SESSION_STEERING_METHOD;
21026
21040
  }
21027
21041
  function toTokenCount(usage) {
21028
21042
  return {
@@ -21662,16 +21676,22 @@ function createTerminalOutputMeta(mode, terminalId, data) {
21662
21676
  };
21663
21677
  }
21664
21678
  }
21665
- var CONTEXT_COMPACTION_META_KEY = "contextCompaction";
21666
- var CONTEXT_COMPACTION_META_VERSION = 1;
21667
21679
  function createContextCompactionMeta(metadata = {}) {
21668
21680
  return {
21669
- [CONTEXT_COMPACTION_META_KEY]: {
21670
- version: CONTEXT_COMPACTION_META_VERSION,
21671
- ...metadata
21681
+ lody: {
21682
+ activity: {
21683
+ version: 1,
21684
+ kind: "context_compaction",
21685
+ ...metadata.trigger === void 0 ? {} : { automatic: metadata.trigger === "automatic" },
21686
+ ...metadata.preTokens === void 0 ? {} : { usedTokensBefore: metadata.preTokens },
21687
+ ...metadata.postTokens === void 0 ? {} : { usedTokensAfter: metadata.postTokens },
21688
+ ...metadata.durationMs === void 0 ? {} : { durationMs: metadata.durationMs },
21689
+ ...metadata.error === void 0 ? {} : { failureReason: metadata.error }
21690
+ }
21672
21691
  }
21673
21692
  };
21674
21693
  }
21694
+ var imageGenerationMeta = { lody: { toolName: LODY_TOOL_NAMES.imageGeneration } };
21675
21695
  var CONTEXT_COMPACTION_META = createContextCompactionMeta();
21676
21696
  function toAcpStatus(status) {
21677
21697
  switch (status) {
@@ -21790,6 +21810,7 @@ function createImageGenerationStartUpdate(item) {
21790
21810
  kind: "other",
21791
21811
  title: "Image generation",
21792
21812
  status: "in_progress",
21813
+ _meta: imageGenerationMeta,
21793
21814
  rawInput: {
21794
21815
  id: item.id
21795
21816
  }
@@ -21800,6 +21821,7 @@ function createImageGenerationCompleteUpdate(item) {
21800
21821
  sessionUpdate: "tool_call_update",
21801
21822
  toolCallId: item.id,
21802
21823
  status: imageGenerationTerminalStatus(item.status),
21824
+ _meta: imageGenerationMeta,
21803
21825
  content: imageGenerationContent(item),
21804
21826
  rawOutput: imageGenerationRawOutput(item)
21805
21827
  };
@@ -21810,6 +21832,7 @@ function createImageGenerationUpdate(item, options) {
21810
21832
  toolCallId: item.id,
21811
21833
  kind: "other",
21812
21834
  title: "Image generation",
21835
+ _meta: imageGenerationMeta,
21813
21836
  status: options?.terminalStatus ? imageGenerationTerminalStatus(item.status) : imageGenerationToolStatus(item.status),
21814
21837
  content: imageGenerationContent(item),
21815
21838
  rawOutput: imageGenerationRawOutput(item)
@@ -21994,6 +22017,17 @@ function createCollabAgentToolCallRawInput(item) {
21994
22017
  }
21995
22018
  function createCollabAgentToolCallMeta(item) {
21996
22019
  return {
22020
+ lody: {
22021
+ task: {
22022
+ version: 1,
22023
+ taskId: item.id,
22024
+ kind: "subagent",
22025
+ status: toAcpStatus(item.status),
22026
+ description: item.prompt,
22027
+ actor: item.tool,
22028
+ ...typeof item.model === "string" ? { modelId: item.model } : {}
22029
+ }
22030
+ },
21997
22031
  codex: {
21998
22032
  collaboration: {
21999
22033
  tool: item.tool,
@@ -22015,6 +22049,16 @@ function createSubAgentActivityUpdate(item, status, sessionUpdate) {
22015
22049
  activityKind: item.kind
22016
22050
  },
22017
22051
  _meta: {
22052
+ lody: {
22053
+ task: {
22054
+ version: 1,
22055
+ taskId: item.id,
22056
+ kind: "subagent",
22057
+ status,
22058
+ description: title,
22059
+ actor: name
22060
+ }
22061
+ },
22018
22062
  codex: {
22019
22063
  subagent: {
22020
22064
  threadId: item.agentThreadId,
@@ -22459,12 +22503,11 @@ function createCodexMessagePhaseMeta(phase) {
22459
22503
  if (!phase) {
22460
22504
  return void 0;
22461
22505
  }
22462
- return { codex: { phase } };
22506
+ return { lody: { messagePhase: phase } };
22463
22507
  }
22464
22508
  function createCodexAgentMessageMeta(phase, turnId) {
22465
22509
  return {
22466
- ...phase ? { codex: { phase } } : {},
22467
- lody: { turnId }
22510
+ lody: { turnId, ...phase ? { messagePhase: phase } : {} }
22468
22511
  };
22469
22512
  }
22470
22513
  function createUserMessageChunk(content, messageId, meta3) {
@@ -22530,9 +22573,6 @@ function toGoalStatus(status) {
22530
22573
  return "limited";
22531
22574
  }
22532
22575
  }
22533
- function toUnixMilliseconds(timestampSeconds) {
22534
- return timestampSeconds * 1e3;
22535
- }
22536
22576
  function toThreadGoalSnapshot(goal) {
22537
22577
  return {
22538
22578
  objective: goal.objective.trim(),
@@ -22540,15 +22580,36 @@ function toThreadGoalSnapshot(goal) {
22540
22580
  tokenBudget: goal.tokenBudget,
22541
22581
  tokensUsed: goal.tokensUsed,
22542
22582
  timeUsedSeconds: goal.timeUsedSeconds,
22543
- createdAt: toUnixMilliseconds(goal.createdAt),
22544
- updatedAt: toUnixMilliseconds(goal.updatedAt),
22545
- controlMethod: GOAL_CONTROL_METHOD
22583
+ createdAtEpochSeconds: goal.createdAt,
22584
+ updatedAtEpochSeconds: goal.updatedAt
22546
22585
  };
22547
22586
  }
22548
22587
  function sameThreadGoalSnapshot(left, right) {
22549
22588
  if (left === void 0) return false;
22550
22589
  if (left === null || right === null) return left === right;
22551
- return left.objective === right.objective && left.status === right.status && left.tokenBudget === right.tokenBudget && left.createdAt === right.createdAt;
22590
+ return left.objective === right.objective && left.status === right.status && left.tokenBudget === right.tokenBudget && left.createdAtEpochSeconds === right.createdAtEpochSeconds;
22591
+ }
22592
+ function toLodyRateLimit(snapshot) {
22593
+ const limitId = snapshot.limitId ?? snapshot.limitName ?? "codex";
22594
+ return {
22595
+ limitId,
22596
+ scope: { providerId: "codex" },
22597
+ limitName: snapshot.limitName,
22598
+ planName: snapshot.planType,
22599
+ windows: [snapshot.primary, snapshot.secondary].filter((window) => window !== null).map((window) => ({
22600
+ usedPercent: window.usedPercent,
22601
+ windowDurationSeconds: window.windowDurationMins === null ? null : window.windowDurationMins * 60,
22602
+ resetsAtEpochSeconds: window.resetsAt
22603
+ }))
22604
+ };
22605
+ }
22606
+ function toLodyRateLimitsResponse(response) {
22607
+ const buckets = Object.values(response.rateLimitsByLimitId ?? {}).filter((snapshot) => snapshot !== void 0);
22608
+ const snapshots = buckets.length > 0 ? buckets : [response.rateLimits];
22609
+ return {
22610
+ rateLimits: snapshots.map(toLodyRateLimit),
22611
+ fetchedAtEpochSeconds: Math.floor(Date.now() / 1e3)
22612
+ };
22552
22613
  }
22553
22614
  var JETBRAINS_META_KEY = "jetbrains";
22554
22615
  var AIR_META_KEY = "air";
@@ -22679,8 +22740,6 @@ var CodexEventHandler = class _CodexEventHandler {
22679
22740
  reasoningSummaryFilters = /* @__PURE__ */ new Map();
22680
22741
  terminalCommandIds = /* @__PURE__ */ new Set();
22681
22742
  terminalCommandOutputIds = /* @__PURE__ */ new Set();
22682
- proposedPlanMarkdown = "";
22683
- proposedPlanTurnId = null;
22684
22743
  agentMessagePhases = /* @__PURE__ */ new Map();
22685
22744
  activeSubAgentActivities = /* @__PURE__ */ new Set();
22686
22745
  constructor(connection, sessionState, supportsPlanUpdates = false, supportsTypedSessionFailures = false, sessionFailureEpoch = randomUUID()) {
@@ -22871,7 +22930,7 @@ var CodexEventHandler = class _CodexEventHandler {
22871
22930
  sessionUpdate: "session_info_update",
22872
22931
  title: notification.params.threadName ?? null,
22873
22932
  _meta: {
22874
- codex: {
22933
+ lody: {
22875
22934
  titleSource: this.sessionState.sessionTitleSource
22876
22935
  }
22877
22936
  }
@@ -22988,16 +23047,6 @@ var CodexEventHandler = class _CodexEventHandler {
22988
23047
  this.createSessionUsageExtNotification(notification.params)
22989
23048
  );
22990
23049
  return;
22991
- case "item/plan/delta":
22992
- if (!this.supportsPlanUpdates) {
22993
- await this.emitCodexProposedPlanDelta(notification.params);
22994
- }
22995
- return;
22996
- case "turn/completed":
22997
- if (!this.supportsPlanUpdates) {
22998
- await this.emitCodexProposedPlanCompleted(notification.params);
22999
- }
23000
- return;
23001
23050
  default:
23002
23051
  return;
23003
23052
  }
@@ -23009,70 +23058,20 @@ var CodexEventHandler = class _CodexEventHandler {
23009
23058
  createSessionUsageExtNotification(params) {
23010
23059
  const totalUsage = params.tokenUsage.total;
23011
23060
  return {
23061
+ sessionId: this.sessionState.sessionId,
23012
23062
  usage: {
23013
23063
  inputTokens: totalUsage.inputTokens,
23014
23064
  outputTokens: totalUsage.outputTokens,
23015
23065
  cacheReadInputTokens: totalUsage.cachedInputTokens,
23016
23066
  reasoningOutputTokens: totalUsage.reasoningOutputTokens,
23017
- contextWindow: params.tokenUsage.modelContextWindow
23067
+ ...params.tokenUsage.modelContextWindow === null ? {} : { contextWindow: params.tokenUsage.modelContextWindow }
23018
23068
  }
23019
23069
  };
23020
23070
  }
23021
- async emitCodexProposedPlanDelta(params) {
23022
- this.proposedPlanMarkdown += params.delta;
23023
- this.proposedPlanTurnId = params.turnId;
23024
- await this.notifyExt(
23025
- ACP_EXT_CODEX_PROPOSED_PLAN_METHOD,
23026
- this.createCodexProposedPlanExtNotification(
23027
- params.turnId,
23028
- this.proposedPlanMarkdown,
23029
- "delta"
23030
- )
23031
- );
23032
- }
23033
- async emitCodexProposedPlanCompleted(params) {
23034
- if (this.proposedPlanMarkdown.trim().length === 0) {
23035
- return;
23036
- }
23037
- await this.notifyExt(
23038
- ACP_EXT_CODEX_PROPOSED_PLAN_METHOD,
23039
- this.createCodexProposedPlanExtNotification(
23040
- this.proposedPlanTurnId ?? params.turn.id,
23041
- this.proposedPlanMarkdown,
23042
- "completed"
23043
- )
23044
- );
23045
- }
23046
- createCodexProposedPlanExtNotification(turnId, markdown, status) {
23047
- return {
23048
- schemaVersion: 1,
23049
- sessionId: this.sessionState.sessionId,
23050
- turnId,
23051
- markdown,
23052
- status,
23053
- isLatest: true
23054
- };
23055
- }
23056
23071
  createSessionRateLimitsExtNotification(rateLimits) {
23057
- const windows = [rateLimits.primary, rateLimits.secondary].filter(
23058
- (window) => window !== null
23059
- );
23060
- const fiveHour = windows.find((window) => window.windowDurationMins === 5 * 60) ?? null;
23061
- const sevenDay = windows.find((window) => window.windowDurationMins === 7 * 24 * 60) ?? null;
23062
23072
  return {
23063
- schemaVersion: 2,
23064
- planName: rateLimits.planType,
23065
- limitName: rateLimits.limitName,
23066
- limitId: rateLimits.limitId,
23067
- windows: windows.map((window) => ({
23068
- usedPercent: window.usedPercent,
23069
- windowDurationMins: window.windowDurationMins,
23070
- resetsAt: window.resetsAt
23071
- })),
23072
- fiveHour: fiveHour?.usedPercent ?? null,
23073
- sevenDay: sevenDay?.usedPercent ?? null,
23074
- fiveHourResetAt: fiveHour?.resetsAt ?? null,
23075
- sevenDayResetAt: sevenDay?.resetsAt ?? null
23073
+ rateLimits: [toLodyRateLimit(rateLimits)],
23074
+ fetchedAtEpochSeconds: Math.floor(Date.now() / 1e3)
23076
23075
  };
23077
23076
  }
23078
23077
  createCodexSessionInfoUpdate(codexMetadata) {
@@ -23095,20 +23094,24 @@ var CodexEventHandler = class _CodexEventHandler {
23095
23094
  const detailsText = event.details ? `
23096
23095
 
23097
23096
  ${event.details}` : "";
23098
- return this.createCodexSessionInfoUpdate({
23099
- warning: {
23097
+ return {
23098
+ sessionUpdate: "session_info_update",
23099
+ _meta: { lody: { notice: {
23100
+ level: "warning",
23100
23101
  message: `${event.summary}${detailsText}`,
23101
23102
  source: "configWarning"
23102
- }
23103
- });
23103
+ } } }
23104
+ };
23104
23105
  }
23105
23106
  createWarningEvent(event) {
23106
- return this.createCodexSessionInfoUpdate({
23107
- warning: {
23107
+ return {
23108
+ sessionUpdate: "session_info_update",
23109
+ _meta: { lody: { notice: {
23110
+ level: "warning",
23108
23111
  message: event.message,
23109
23112
  source: "warning"
23110
- }
23111
- });
23113
+ } } }
23114
+ };
23112
23115
  }
23113
23116
  /**
23114
23117
  * Unlike `warning` and `configWarning`, this notification was dropped outright, so there is no
@@ -23146,7 +23149,7 @@ ${event.details}` : "";
23146
23149
  createGoalSessionInfoUpdate(goal) {
23147
23150
  return {
23148
23151
  sessionUpdate: "session_info_update",
23149
- _meta: { goal }
23152
+ _meta: { lody: { goal } }
23150
23153
  };
23151
23154
  }
23152
23155
  createReasoningSummaryDeltaEvent(event) {
@@ -24242,6 +24245,9 @@ var ELICITATION_OPTIONS = [
24242
24245
  { optionId: "decline", name: "Decline", kind: "reject_once" }
24243
24246
  ];
24244
24247
  var USER_INPUT_OTHER_FIELD_SUFFIX = "__other";
24248
+ var lodyElicitationMeta = (meta3) => ({
24249
+ lody: { elicitation: { version: 1, ...meta3 } }
24250
+ });
24245
24251
  function parsePersistOptions(meta3) {
24246
24252
  const result = /* @__PURE__ */ new Set();
24247
24253
  if (!meta3 || typeof meta3 !== "object") return result;
@@ -24612,12 +24618,7 @@ var CodexElicitationHandler = class {
24612
24618
  const base = {
24613
24619
  title: question.header || question.id,
24614
24620
  description: question.question,
24615
- _meta: {
24616
- codex: {
24617
- isOther: question.isOther,
24618
- isSecret: question.isSecret
24619
- }
24620
- }
24621
+ _meta: lodyElicitationMeta({ secret: question.isSecret })
24621
24622
  };
24622
24623
  if (!hasOtherAnswer) {
24623
24624
  required2.push(question.id);
@@ -24639,13 +24640,10 @@ var CodexElicitationHandler = class {
24639
24640
  type: "string",
24640
24641
  title: "Other",
24641
24642
  description: "Type your own answer instead of choosing an option above.",
24642
- _meta: {
24643
- codex: {
24644
- questionId: question.id,
24645
- isOtherAnswer: true,
24646
- isSecret: question.isSecret
24647
- }
24648
- }
24643
+ _meta: lodyElicitationMeta({
24644
+ customAnswerFor: question.id,
24645
+ secret: question.isSecret
24646
+ })
24649
24647
  };
24650
24648
  }
24651
24649
  }
@@ -24660,11 +24658,9 @@ var CodexElicitationHandler = class {
24660
24658
  properties,
24661
24659
  required: required2
24662
24660
  },
24663
- _meta: {
24664
- codex: {
24665
- autoResolutionMs: params.autoResolutionMs
24666
- }
24667
- }
24661
+ _meta: lodyElicitationMeta({
24662
+ autoResolveAfterSeconds: params.autoResolutionMs === null ? null : params.autoResolutionMs / 1e3
24663
+ })
24668
24664
  };
24669
24665
  }
24670
24666
  buildPermissionRequest(params, context) {
@@ -25662,6 +25658,7 @@ var package_default = {
25662
25658
  dependencies: {
25663
25659
  "@agentclientprotocol/sdk": "^1.3.0",
25664
25660
  "@openai/codex": "^0.148.0",
25661
+ "acp-extension-core": "0.1.0",
25665
25662
  diff: "^9.0.0",
25666
25663
  open: "^11.0.0",
25667
25664
  "vscode-jsonrpc": "^9.0.1",
@@ -26921,7 +26918,7 @@ var CodexAcpClient = class {
26921
26918
  threadId: params.threadId,
26922
26919
  expectedTurnId: params.turnId,
26923
26920
  input: buildPromptItems(params.prompt),
26924
- ...params.steerId ? { clientUserMessageId: params.steerId } : {}
26921
+ clientUserMessageId: params.steerId
26925
26922
  });
26926
26923
  }
26927
26924
  async fetchAvailableModels() {
@@ -29666,26 +29663,10 @@ var CodexAcpServer = class _CodexAcpServer {
29666
29663
  http: true,
29667
29664
  sse: false
29668
29665
  },
29669
- _meta: {
29670
- codex: {
29671
- steer: CODEX_STEER_CAPABILITY
29672
- },
29673
- lody: {
29674
- forkAtTurn: { version: 1 },
29675
- readSessionHistory: LODY_READ_SESSION_HISTORY_CAPABILITY
29676
- }
29677
- }
29666
+ _meta: { lody: CODEX_LODY_CAPABILITIES }
29678
29667
  },
29679
29668
  authMethods: getCodexAuthMethods(_params.clientCapabilities),
29680
29669
  _meta: {
29681
- steering: {
29682
- supported: true
29683
- },
29684
- goal: {
29685
- version: GOAL_EXTENSION_VERSION,
29686
- controlMethod: GOAL_CONTROL_METHOD,
29687
- actions: [...GOAL_CONTROL_ACTIONS]
29688
- },
29689
29670
  [JETBRAINS_META_KEY]: {
29690
29671
  [AIR_META_KEY]: {
29691
29672
  [AIR_EXTENSION_VERSION_KEY]: AIR_EXTENSION_VERSION,
@@ -29714,8 +29695,7 @@ var CodexAcpServer = class _CodexAcpServer {
29714
29695
  return await this.unstable_setSessionModel(this.parseLegacySetSessionModelParams(methodRequest.params));
29715
29696
  case SESSION_STEERING_METHOD:
29716
29697
  return await this.executeOrQueueSteeringRequest(this.parseSessionSteerParams(methodRequest.params));
29717
- case GOAL_CONTROL_METHOD:
29718
- case LEGACY_GOAL_CONTROL_METHOD: {
29698
+ case GOAL_CONTROL_METHOD: {
29719
29699
  const sessionState = this.sessions.get(methodRequest.params.sessionId);
29720
29700
  if (!sessionState) {
29721
29701
  throw RequestError.invalidParams(void 0, `Unknown session: ${methodRequest.params.sessionId}`);
@@ -29792,6 +29772,11 @@ var CodexAcpServer = class _CodexAcpServer {
29792
29772
  }
29793
29773
  }
29794
29774
  }
29775
+ async readRateLimits() {
29776
+ return toLodyRateLimitsResponse(
29777
+ await this.runWithProcessCheck(() => this.codexAcpClient.getRateLimits())
29778
+ );
29779
+ }
29795
29780
  async getOrCreateSession(request) {
29796
29781
  try {
29797
29782
  return await this.tryCreateSession(request);
@@ -30536,16 +30521,14 @@ Check ${configPath} and project .codex directories, especially their config.toml
30536
30521
  *
30537
30522
  * Every session gets its own {@link SteeringQueue}: the request is enqueued
30538
30523
  * and awaited, so concurrent steers for one session run strictly one at a
30539
- * time, in arrival order, and can never race to inject into or start —
30540
- * rival turns. Steers for different sessions use different queues and run
30524
+ * time, in arrival order, and can never race to inject into rival turns.
30525
+ * Steers for different sessions use different queues and run
30541
30526
  * concurrently. Once the queue drains to idle it is removed from the map,
30542
30527
  * so no per-session entry leaks after the session goes quiet (the identity
30543
30528
  * check guards against deleting a queue a later request has since reused).
30544
30529
  *
30545
30530
  * @param params The target session id and the prompt to steer with.
30546
- * @returns Whether the prompt joined the active turn ("injected"), started a
30547
- * new one ("startedNewTurn"), or could not be applied ("failed"); see
30548
- * {@link performSteeringRequest}.
30531
+ * @returns Whether the prompt joined the active turn or could not be applied.
30549
30532
  */
30550
30533
  async executeOrQueueSteeringRequest(params) {
30551
30534
  const queue = this.getSteeringQueue(params.sessionId);
@@ -30579,12 +30562,10 @@ Check ${configPath} and project .codex directories, especially their config.toml
30579
30562
  return queue;
30580
30563
  }
30581
30564
  /**
30582
- * Delivers a steering prompt to the session: injects it into the live turn
30583
- * when there is one, otherwise starts a new turn.
30565
+ * Delivers a steering prompt to the currently active turn.
30584
30566
  *
30585
30567
  * @param params The target session id and the prompt to steer with.
30586
- * @returns "injected" when the prompt joined an existing turn, otherwise the
30587
- * outcome of starting a new turn.
30568
+ * @returns "injected" when the prompt joined the active turn.
30588
30569
  */
30589
30570
  async performSteeringRequest(params) {
30590
30571
  logger.log("Steering session requested", {
@@ -30601,10 +30582,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
30601
30582
  return { outcome: "injected" };
30602
30583
  }
30603
30584
  }
30604
- if (params.steerId) {
30605
- throw RequestError.invalidRequest("No active Codex turn to steer");
30606
- }
30607
- return await this.startNewTurnFromSteering(params);
30585
+ return { outcome: "failed" };
30608
30586
  }
30609
30587
  /**
30610
30588
  * Rejects a steering prompt whose content the active model cannot accept
@@ -30621,38 +30599,34 @@ Check ${configPath} and project .codex directories, especially their config.toml
30621
30599
  *
30622
30600
  * A failed injection is fatal only when the turn is still the session's
30623
30601
  * current turn and Codex reported something other than "no active turn to
30624
- * steer". Otherwise the turn has already ended underneath us and the caller
30625
- * should start a new turn instead.
30602
+ * steer". Otherwise the turn has already ended underneath us and steering
30603
+ * reports a failed delivery.
30626
30604
  *
30627
- * @returns true when the prompt was injected; false when the caller should
30628
- * fall back to starting a new turn.
30605
+ * @returns true when the prompt was injected; false when the target turn
30606
+ * already ended.
30629
30607
  */
30630
30608
  async injectSteerIntoActiveTurn(params, turnId, sessionState) {
30631
30609
  const activePrompt = this.activePrompts.get(params.sessionId);
30632
30610
  const activeTurn = activePrompt?.currentTurn;
30633
- if (params.steerId) {
30634
- const firstText = params.prompt[0]?.type === "text" ? params.prompt[0].text : "";
30635
- if (firstText.startsWith("/")) {
30636
- throw RequestError.invalidRequest("Slash commands cannot steer an active Codex turn");
30637
- }
30638
- if (!activePrompt || !activeTurn || activeTurn.turnId !== turnId || activePrompt.signal.aborted) {
30639
- return false;
30640
- }
30611
+ const firstText = params.prompt[0]?.type === "text" ? params.prompt[0].text : "";
30612
+ if (firstText.startsWith("/")) {
30613
+ throw RequestError.invalidRequest("Slash commands cannot steer an active Codex turn");
30641
30614
  }
30642
- const pending = params.steerId ? this.pendingSteers.get(params.sessionId) ?? /* @__PURE__ */ new Map() : null;
30643
- if (params.steerId && activePrompt && pending) {
30644
- if (pending.has(params.steerId)) {
30645
- throw RequestError.invalidRequest(`Duplicate Codex steer id: ${params.steerId}`);
30646
- }
30647
- pending.set(params.steerId, { activePrompt, turnId });
30648
- this.pendingSteers.set(params.sessionId, pending);
30615
+ if (!activePrompt || !activeTurn || activeTurn.turnId !== turnId || activePrompt.signal.aborted) {
30616
+ return false;
30617
+ }
30618
+ const pending = this.pendingSteers.get(params.sessionId) ?? /* @__PURE__ */ new Map();
30619
+ if (pending.has(params.steerId)) {
30620
+ throw RequestError.invalidRequest(`Duplicate Codex steer id: ${params.steerId}`);
30649
30621
  }
30622
+ pending.set(params.steerId, { activePrompt, turnId });
30623
+ this.pendingSteers.set(params.sessionId, pending);
30650
30624
  try {
30651
30625
  const response = await this.runWithProcessCheck(() => this.codexAcpClient.steerTurn({
30652
- threadId: params.steerId && activeTurn ? activeTurn.threadId : params.sessionId,
30626
+ threadId: activeTurn.threadId,
30653
30627
  turnId,
30654
30628
  prompt: params.prompt,
30655
- ...params.steerId ? { steerId: params.steerId } : {}
30629
+ steerId: params.steerId
30656
30630
  }));
30657
30631
  if (response.turnId !== turnId) {
30658
30632
  throw RequestError.internalError(
@@ -30662,7 +30636,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
30662
30636
  }
30663
30637
  return true;
30664
30638
  } catch (err) {
30665
- if (params.steerId && activePrompt && pending?.get(params.steerId)?.activePrompt === activePrompt) {
30639
+ if (pending.get(params.steerId)?.activePrompt === activePrompt) {
30666
30640
  pending.delete(params.steerId);
30667
30641
  if (pending.size === 0) this.pendingSteers.delete(params.sessionId);
30668
30642
  }
@@ -30674,22 +30648,6 @@ Check ${configPath} and project .codex directories, especially their config.toml
30674
30648
  return false;
30675
30649
  }
30676
30650
  }
30677
- /**
30678
- * Starts a new turn from a steering prompt when there is no live turn to
30679
- * inject into, and returns as soon as that turn is running.
30680
- *
30681
- * Waits for any previous prompt to drain first, then re-checks that the
30682
- * session is not closing — the await above is a window during which a close
30683
- * request can arrive.
30684
- *
30685
- * @param params The target session id and the prompt to steer with.
30686
- * @returns "startedNewTurn" once the turn is running; throws if the prompt
30687
- * fails or is cancelled before the turn starts.
30688
- */
30689
- async startNewTurnFromSteering(params) {
30690
- await this.startNewTurnFromExternalPrompt(params, "Steering");
30691
- return { outcome: "startedNewTurn" };
30692
- }
30693
30651
  async startGoalContinuationIfCurrent(sessionState, sessionGeneration, goalControlGeneration, expectedGoal) {
30694
30652
  await this.startNewTurnFromExternalPrompt({
30695
30653
  sessionId: sessionState.sessionId,
@@ -30768,13 +30726,13 @@ Check ${configPath} and project .codex directories, especially their config.toml
30768
30726
  const sessionId = params["sessionId"];
30769
30727
  const prompt = params["prompt"];
30770
30728
  const steerId = params["steerId"];
30771
- if (typeof sessionId !== "string" || !Array.isArray(prompt) || steerId !== void 0 && (typeof steerId !== "string" || steerId.length === 0)) {
30729
+ if (typeof sessionId !== "string" || !Array.isArray(prompt) || typeof steerId !== "string" || steerId.length === 0) {
30772
30730
  throw RequestError.invalidParams();
30773
30731
  }
30774
30732
  return {
30775
30733
  sessionId,
30776
30734
  prompt,
30777
- ...typeof steerId === "string" ? { steerId } : {}
30735
+ steerId
30778
30736
  };
30779
30737
  }
30780
30738
  createSessionConfigOptions(sessionState) {
@@ -30842,7 +30800,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
30842
30800
  await session.update({
30843
30801
  sessionUpdate: "session_info_update",
30844
30802
  _meta: {
30845
- goal: snapshot
30803
+ lody: { goal: snapshot }
30846
30804
  }
30847
30805
  });
30848
30806
  }
@@ -30981,7 +30939,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
30981
30939
  sessionUpdate: "session_info_update",
30982
30940
  title: explicitTitle,
30983
30941
  _meta: {
30984
- codex: {
30942
+ lody: {
30985
30943
  titleSource: "explicit"
30986
30944
  }
30987
30945
  }
@@ -31010,7 +30968,7 @@ Check ${configPath} and project .codex directories, especially their config.toml
31010
30968
  sessionUpdate: "session_info_update",
31011
30969
  title,
31012
30970
  _meta: {
31013
- codex: {
30971
+ lody: {
31014
30972
  titleSource: "fallback"
31015
30973
  }
31016
30974
  }
@@ -32151,7 +32109,7 @@ var goalControlParamsParser = external_exports.discriminatedUnion("action", [
32151
32109
  }).passthrough()
32152
32110
  ]);
32153
32111
  function registerGoalControlRequests(app, getAgent) {
32154
- return app.onRequest(GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(GOAL_CONTROL_METHOD, ctx.params)).onRequest(LEGACY_GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(LEGACY_GOAL_CONTROL_METHOD, ctx.params));
32112
+ return app.onRequest(GOAL_CONTROL_METHOD, goalControlParamsParser, (ctx) => getAgent().extMethod(GOAL_CONTROL_METHOD, ctx.params));
32155
32113
  }
32156
32114
  var emptyExtensionParamsParser = external_exports.preprocess(
32157
32115
  (params) => params ?? {},
@@ -32164,11 +32122,16 @@ var legacySetSessionModelParamsParser = external_exports.object({
32164
32122
  var sessionSteerParamsParser = external_exports.object({
32165
32123
  sessionId: external_exports.string(),
32166
32124
  prompt: external_exports.array(external_exports.any()),
32167
- steerId: external_exports.string().min(1).optional()
32125
+ steerId: external_exports.string().min(1)
32168
32126
  }).passthrough();
32169
32127
  var lodyReadSessionHistoryParamsParser = external_exports.object({
32170
32128
  sessionId: external_exports.string().min(1)
32171
32129
  }).passthrough();
32130
+ var lodyRateLimitsGetParamsParser = external_exports.object({
32131
+ sessionId: external_exports.string().optional(),
32132
+ accountId: external_exports.string().optional(),
32133
+ modelId: external_exports.string().optional()
32134
+ }).passthrough();
32172
32135
  function createCodexAcpApp(options) {
32173
32136
  let codexAcpServer = null;
32174
32137
  const getAgent = () => {
@@ -32185,7 +32148,7 @@ function createCodexAcpApp(options) {
32185
32148
  codexAcpServer = null;
32186
32149
  }
32187
32150
  });
32188
- }).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().unstable_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(LODY_READ_SESSION_HISTORY_METHOD, lodyReadSessionHistoryParamsParser, (ctx) => getAgent().readSessionHistory(ctx.params)).onRequest(SESSION_STEERING_METHOD, sessionSteerParamsParser, (ctx) => getAgent().extMethod(SESSION_STEERING_METHOD, ctx.params));
32151
+ }).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().unstable_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(LODY_RATE_LIMITS_GET_METHOD, lodyRateLimitsGetParamsParser, () => getAgent().readRateLimits()).onRequest(LODY_READ_SESSION_HISTORY_METHOD, lodyReadSessionHistoryParamsParser, (ctx) => getAgent().readSessionHistory(ctx.params)).onRequest(SESSION_STEERING_METHOD, sessionSteerParamsParser, (ctx) => getAgent().extMethod(SESSION_STEERING_METHOD, ctx.params));
32189
32152
  return registerGoalControlRequests(agentApp, getAgent);
32190
32153
  }
32191
32154
  if (process.argv.includes("--version")) {