@narumitw/pi-codex-compact 0.51.0 → 0.51.1

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.
package/README.md CHANGED
@@ -74,7 +74,7 @@ Escape or Ctrl+C closes without compacting, and an obsolete menu cannot trigger
74
74
  **Settings** opens the bounded settings editor.
75
75
  In non-TUI modes, the command reports the manual settings path instead of opening custom UI or compacting.
76
76
 
77
- Pi's built-in `/compact` remains available and follows the same extension hook when the active model is compatible.
77
+ Pi's built-in `/compact` remains available and follows the same extension hook when the active model uses `openai-codex-responses`.
78
78
 
79
79
  ## ⚙️ Settings
80
80
 
@@ -99,7 +99,7 @@ There is no environment-variable or project-level override.
99
99
 
100
100
  | Setting | Default | Accepted values | Behavior | Recommendation |
101
101
  | --- | ---: | --- | --- | --- |
102
- | `enabled` | `true` | Boolean | Attempt Remote V2 for a compatible model. | Keep enabled unless diagnosing provider behavior. |
102
+ | `enabled` | `true` | Boolean | Attempt Remote V2 when the active model uses `openai-codex-responses`. | Keep enabled unless diagnosing provider behavior. |
103
103
  | `requestTimeoutMs` | `300000` | Integer from 30,000 to 600,000 ms | Bound one extension-owned remote request. | Keep five minutes; increase only for a consistently slow connection. |
104
104
  | `maxRetries` | `2` | Integer from 0 to 2 | Retry transient provider transport failures before Pi fallback. | Keep two; use zero when diagnosing the first failure. |
105
105
  | `replacementTokenBudget` | `64000` | Integer from 8,000 to 128,000 tokens | Bound approximate retained user-message text beside the opaque item. | Keep 64K; lower it to reduce session size or raise it only when recent user context is being lost. |
@@ -191,7 +191,7 @@ src/codex-compact.ts Pi lifecycle, command, provider projection, and fallback
191
191
  src/remote.ts Provider stream invocation, auth payload, timeout, and retry controls
192
192
  src/protocol.ts Bounded SSE parsing and Remote V2 payload/output validation
193
193
  src/checkpoint.ts Replacement history, fingerprints, persistence, and replay projection
194
- src/model-compatibility.ts API-based Remote V2 model eligibility
194
+ src/model-api.ts Codex Responses API detection for Remote V2 eligibility
195
195
  src/settings.ts Global settings validation and atomic persistence
196
196
  src/settings-menu.ts First-use manual compaction and settings TUI
197
197
 
@@ -1,13 +1,13 @@
1
1
  // @generated by scripts/build-runtime.mjs; do not edit.
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
3
 
4
- // src/model-compatibility.ts
4
+ // src/model-api.ts
5
5
  import { hasApi } from "@earendil-works/pi-ai";
6
- function isCodexRemoteCompactionModel(model) {
6
+ function usesCodexResponsesApi(model) {
7
7
  return model !== void 0 && hasApi(model, "openai-codex-responses");
8
8
  }
9
9
 
10
10
  export {
11
- isCodexRemoteCompactionModel
11
+ usesCodexResponsesApi
12
12
  };
13
- //# sourceMappingURL=chunk-3WRPJHG2.ts.map
13
+ //# sourceMappingURL=chunk-I3JF4V7C.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/model-api.ts"],
4
+ "sourcesContent": ["import type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { hasApi } from \"@earendil-works/pi-ai\";\n\nexport function usesCodexResponsesApi(\n\tmodel: Model<Api> | undefined,\n): model is Model<\"openai-codex-responses\"> {\n\treturn model !== undefined && hasApi(model, \"openai-codex-responses\");\n}\n"],
5
+ "mappings": ";;;;AACA,SAAS,cAAc;AAEhB,SAAS,sBACf,OAC2C;AAC3C,SAAO,UAAU,UAAa,OAAO,OAAO,wBAAwB;AACrE;",
6
+ "names": []
7
+ }
@@ -1,8 +1,8 @@
1
1
  // @generated by scripts/build-runtime.mjs; do not edit.
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
3
  import {
4
- isCodexRemoteCompactionModel
5
- } from "./chunk-3WRPJHG2.js";
4
+ usesCodexResponsesApi
5
+ } from "./chunk-I3JF4V7C.js";
6
6
 
7
7
  // src/settings-menu.ts
8
8
  function safeText(value) {
@@ -68,7 +68,7 @@ function createCodexCompactMenu(runtime, options = {}) {
68
68
  {
69
69
  id: "enabled",
70
70
  label: "Remote compaction",
71
- description: "Use Codex Remote V2 when the active model is compatible.",
71
+ description: "Use Codex Remote V2 when the model uses openai-codex-responses.",
72
72
  currentValue: state.settings.enabled ? "On" : "Off",
73
73
  values: ["On", "Off"],
74
74
  action: "set-enabled"
@@ -176,16 +176,16 @@ function compactMenuStatus(ctx) {
176
176
  const model = ctx.model;
177
177
  return {
178
178
  model: model ? `${model.provider}/${model.id}` : "none",
179
- remoteCompatible: isCodexRemoteCompactionModel(model)
179
+ remoteEligible: usesCodexResponsesApi(model)
180
180
  };
181
181
  }
182
182
  function compactRoute(state, status) {
183
183
  if (!state.settings.enabled) return "Pi native (Remote V2 off)";
184
- return status?.remoteCompatible ? "Codex Remote V2" : "Pi native (model not compatible)";
184
+ return status?.remoteEligible ? "Codex Remote V2" : "Pi native (requires openai-codex-responses)";
185
185
  }
186
186
  export {
187
187
  compactMenuStatus,
188
188
  createCodexCompactMenu,
189
189
  showCodexCompactMenu
190
190
  };
191
- //# sourceMappingURL=settings-menu-4YW2GOKW.ts.map
191
+ //# sourceMappingURL=settings-menu-H6GC3TNJ.ts.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/settings-menu.ts"],
4
+ "sourcesContent": ["import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport type { MenuDefinition } from \"@narumitw/pi-tui-kit\";\nimport { usesCodexResponsesApi } from \"./model-api.js\";\nimport type {\n\tCodexCompactSettings,\n\tCodexCompactSettingsRuntime,\n\tCodexCompactSettingsState,\n} from \"./settings.js\";\n\ntype Screen = \"main\" | \"settings\" | \"invalid\";\ntype Action =\n\t| \"compact-now\"\n\t| \"set-enabled\"\n\t| \"set-timeout\"\n\t| \"set-retries\"\n\t| \"set-retention\"\n\t| \"set-notify\";\n\nexport interface SettingsMenuOwner {\n\tsignal: AbortSignal;\n\tisCurrent(): boolean;\n}\n\ninterface CompactMenuStatus {\n\tmodel: string;\n\tremoteEligible: boolean;\n}\n\nfunction safeText(value: string): string {\n\treturn Array.from(value, (character) => {\n\t\tconst codePoint = character.codePointAt(0) ?? 0;\n\t\treturn codePoint < 32 || (codePoint >= 127 && codePoint <= 159) ? \" \" : character;\n\t}).join(\"\");\n}\n\nfunction timeoutLabel(milliseconds: number): string {\n\treturn `${milliseconds / 60_000} min`;\n}\n\nfunction retentionLabel(tokens: number): string {\n\treturn `${tokens / 1000}K tokens`;\n}\n\nasync function update(\n\truntime: CodexCompactSettingsRuntime,\n\tctx: ExtensionCommandContext,\n\tpatch: Partial<CodexCompactSettings>,\n\tsignal: AbortSignal,\n) {\n\ttry {\n\t\tawait runtime.update(patch, signal);\n\t\tctx.ui.notify(\"Codex compaction settings saved.\", \"info\");\n\t\treturn { kind: \"stay\" as const };\n\t} catch (error) {\n\t\tif (signal.aborted) return { kind: \"rejected\" as const };\n\t\tctx.ui.notify(\n\t\t\t`Could not save pi-codex-compact.json: ${safeText(error instanceof Error ? error.message : String(error))}`,\n\t\t\t\"error\",\n\t\t);\n\t\treturn { kind: \"rejected\" as const };\n\t}\n}\n\nexport function createCodexCompactMenu(\n\truntime: CodexCompactSettingsRuntime,\n\toptions: { onCompactRequested?: () => void; status?: CompactMenuStatus } = {},\n): MenuDefinition<CodexCompactSettingsState, Screen, Action, ExtensionCommandContext> {\n\treturn {\n\t\tstart: \"main\",\n\t\tscreens: {\n\t\t\tmain: ({ state }) => ({\n\t\t\t\tkind: \"actions\",\n\t\t\t\ttitle: \"Codex Remote Compaction\",\n\t\t\t\tlines: [\n\t\t\t\t\t`Remote V2: ${state.settings.enabled ? \"On\" : \"Off\"}`,\n\t\t\t\t\t`Active model: ${safeText(options.status?.model ?? \"none\")}`,\n\t\t\t\t\t`Compact route: ${safeText(compactRoute(state, options.status))}`,\n\t\t\t\t],\n\t\t\t\titems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"compact-now\",\n\t\t\t\t\t\tlabel: \"Compact now\",\n\t\t\t\t\t\tdescription: \"Close this menu and compact the active session immediately.\",\n\t\t\t\t\t\taction: \"compact-now\",\n\t\t\t\t\t},\n\t\t\t\t\tstate.kind === \"invalid\"\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tid: \"settings\",\n\t\t\t\t\t\t\t\tlabel: \"Settings\",\n\t\t\t\t\t\t\t\tdescription: \"Read-only until the invalid settings file is repaired.\",\n\t\t\t\t\t\t\t\tto: \"invalid\" as const,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: { id: \"settings\", label: \"Settings\", to: \"settings\" as const },\n\t\t\t\t\t{ id: \"close\", label: \"Close\", close: true },\n\t\t\t\t],\n\t\t\t\thint: \"close\",\n\t\t\t}),\n\t\t\tsettings: ({ state }) => ({\n\t\t\t\tkind: \"settings\",\n\t\t\t\ttitle: \"Codex Remote Compaction Settings\",\n\t\t\t\tlines: [`User settings \u00B7 ${safeText(state.path)}`],\n\t\t\t\titems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"enabled\",\n\t\t\t\t\t\tlabel: \"Remote compaction\",\n\t\t\t\t\t\tdescription: \"Use Codex Remote V2 when the model uses openai-codex-responses.\",\n\t\t\t\t\t\tcurrentValue: state.settings.enabled ? \"On\" : \"Off\",\n\t\t\t\t\t\tvalues: [\"On\", \"Off\"],\n\t\t\t\t\t\taction: \"set-enabled\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"requestTimeoutMs\",\n\t\t\t\t\t\tlabel: \"Request timeout\",\n\t\t\t\t\t\tdescription: \"Maximum time for the extension-owned remote compaction request.\",\n\t\t\t\t\t\tcurrentValue: timeoutLabel(state.settings.requestTimeoutMs),\n\t\t\t\t\t\tvalues: [\"2 min\", \"5 min\", \"10 min\"],\n\t\t\t\t\t\taction: \"set-timeout\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"maxRetries\",\n\t\t\t\t\t\tlabel: \"Transport retries\",\n\t\t\t\t\t\tdescription: \"Retry transient provider failures before falling back to Pi.\",\n\t\t\t\t\t\tcurrentValue: String(state.settings.maxRetries),\n\t\t\t\t\t\tvalues: [\"0\", \"1\", \"2\"],\n\t\t\t\t\t\taction: \"set-retries\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"replacementTokenBudget\",\n\t\t\t\t\t\tlabel: \"Retained user history\",\n\t\t\t\t\t\tdescription: \"Approximate user-message budget kept beside the opaque checkpoint.\",\n\t\t\t\t\t\tcurrentValue: retentionLabel(state.settings.replacementTokenBudget),\n\t\t\t\t\t\tvalues: [\"32K tokens\", \"64K tokens\", \"96K tokens\", \"128K tokens\"],\n\t\t\t\t\t\taction: \"set-retention\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"notifyOnFallback\",\n\t\t\t\t\t\tlabel: \"Fallback notifications\",\n\t\t\t\t\t\tdescription: \"Warn when Remote V2 fails and native Pi compaction takes over.\",\n\t\t\t\t\t\tcurrentValue: state.settings.notifyOnFallback ? \"On\" : \"Off\",\n\t\t\t\t\t\tvalues: [\"On\", \"Off\"],\n\t\t\t\t\t\taction: \"set-notify\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t}),\n\t\t\tinvalid: ({ state }) => ({\n\t\t\t\tkind: \"detail\",\n\t\t\t\ttitle: \"Codex Compact Settings \u00B7 Read only\",\n\t\t\t\tlines: [\n\t\t\t\t\t`Invalid settings file: ${safeText(state.path)}`,\n\t\t\t\t\t`Issue: ${safeText(state.issue ?? \"unknown validation error\")}`,\n\t\t\t\t\t\"Built-in defaults are active. Repair the file and run /reload; it will not be overwritten.\",\n\t\t\t\t],\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\t\"compact-now\": async () => {\n\t\t\t\toptions.onCompactRequested?.();\n\t\t\t\treturn { kind: \"close\" };\n\t\t\t},\n\t\t\t\"set-enabled\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(runtime, ctx, { enabled: value === \"On\" }, signal),\n\t\t\t\"set-timeout\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(\n\t\t\t\t\truntime,\n\t\t\t\t\tctx,\n\t\t\t\t\t{ requestTimeoutMs: Number.parseInt(value ?? \"5\", 10) * 60_000 },\n\t\t\t\t\tsignal,\n\t\t\t\t),\n\t\t\t\"set-retries\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(runtime, ctx, { maxRetries: Number.parseInt(value ?? \"2\", 10) }, signal),\n\t\t\t\"set-retention\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(\n\t\t\t\t\truntime,\n\t\t\t\t\tctx,\n\t\t\t\t\t{ replacementTokenBudget: Number.parseInt(value ?? \"64\", 10) * 1000 },\n\t\t\t\t\tsignal,\n\t\t\t\t),\n\t\t\t\"set-notify\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(runtime, ctx, { notifyOnFallback: value === \"On\" }, signal),\n\t\t},\n\t};\n}\n\nexport async function showCodexCompactMenu(\n\truntime: CodexCompactSettingsRuntime,\n\tctx: ExtensionCommandContext,\n\towner: SettingsMenuOwner,\n): Promise<void> {\n\tif (ctx.mode !== \"tui\") {\n\t\tctx.ui.notify(`Edit Codex compaction settings at ${safeText(runtime.get().path)}.`, \"info\");\n\t\treturn;\n\t}\n\tconst { runMenu } = await import(\"@narumitw/pi-tui-kit\");\n\tif (owner.signal.aborted || !owner.isCurrent()) return;\n\tlet compactRequested = false;\n\tawait runMenu(\n\t\tctx,\n\t\tcreateCodexCompactMenu(runtime, {\n\t\t\tonCompactRequested: () => {\n\t\t\t\tcompactRequested = true;\n\t\t\t},\n\t\t\tstatus: compactMenuStatus(ctx),\n\t\t}),\n\t\t{\n\t\t\tgetState: () => runtime.get(),\n\t\t\tsignal: owner.signal,\n\t\t\tisCurrent: owner.isCurrent,\n\t\t},\n\t);\n\tif (!compactRequested || owner.signal.aborted || !owner.isCurrent()) return;\n\tctx.compact({\n\t\tonError: (error) => {\n\t\t\tif (!owner.signal.aborted && owner.isCurrent()) {\n\t\t\t\tctx.ui.notify(`Compaction failed: ${safeText(error.message)}`, \"error\");\n\t\t\t}\n\t\t},\n\t});\n}\n\nexport function compactMenuStatus(ctx: ExtensionCommandContext): CompactMenuStatus {\n\tconst model = ctx.model;\n\treturn {\n\t\tmodel: model ? `${model.provider}/${model.id}` : \"none\",\n\t\tremoteEligible: usesCodexResponsesApi(model),\n\t};\n}\n\nfunction compactRoute(\n\tstate: Readonly<CodexCompactSettingsState>,\n\tstatus: CompactMenuStatus | undefined,\n): string {\n\tif (!state.settings.enabled) return \"Pi native (Remote V2 off)\";\n\treturn status?.remoteEligible ? \"Codex Remote V2\" : \"Pi native (requires openai-codex-responses)\";\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
package/dist/index.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  // @generated by scripts/build-runtime.mjs; do not edit.
2
2
  // @ts-nocheck -- generated JavaScript uses a .ts extension for Pi's Jiti loader.
3
3
  import {
4
- isCodexRemoteCompactionModel
5
- } from "./chunks/chunk-3WRPJHG2.js";
4
+ usesCodexResponsesApi
5
+ } from "./chunks/chunk-I3JF4V7C.js";
6
6
 
7
7
  // src/codex-compact.ts
8
8
  import {
@@ -608,7 +608,7 @@ function activeCheckpoint(ctx) {
608
608
  return latestCheckpoint(ctx.sessionManager.getBranch());
609
609
  }
610
610
  function isCheckpointCompatible(details, model) {
611
- return isCodexRemoteCompactionModel(model) && model.id === details.modelId;
611
+ return usesCodexResponsesApi(model) && model.id === details.modelId;
612
612
  }
613
613
  function keptMessages(event) {
614
614
  const leafId = event.branchEntries.at(-1)?.id ?? null;
@@ -653,7 +653,7 @@ function sessionStillOwned(ctx, sessionId, signal) {
653
653
  }
654
654
  async function compactRemotely(pi, event, ctx, settings, fetch) {
655
655
  const model = ctx.model;
656
- if (!settings.enabled || !isCodexRemoteCompactionModel(model)) return void 0;
656
+ if (!settings.enabled || !usesCodexResponsesApi(model)) return void 0;
657
657
  const sessionId = ctx.sessionManager.getSessionId();
658
658
  ctx.ui.setStatus(STATUS_KEY, "Codex remote compaction\u2026");
659
659
  try {
@@ -724,7 +724,7 @@ function createCodexCompactExtension(options = {}) {
724
724
  handler: async (_args, ctx) => {
725
725
  const ownerGeneration = generation;
726
726
  const controller = sessionController;
727
- const { showCodexCompactMenu } = await import("./chunks/settings-menu-4YW2GOKW.js");
727
+ const { showCodexCompactMenu } = await import("./chunks/settings-menu-H6GC3TNJ.js");
728
728
  if (ownerGeneration !== generation || controller.signal.aborted) return;
729
729
  await showCodexCompactMenu(settingsRuntime, ctx, {
730
730
  signal: controller.signal,
package/dist/index.ts.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../src/codex-compact.ts", "../src/checkpoint.ts", "../src/protocol.ts", "../src/remote.ts", "../src/settings.ts"],
4
- "sourcesContent": ["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { Api, Context, Model, Tool } from \"@earendil-works/pi-ai\";\nimport {\n\tbuildContextEntries,\n\tbuildSessionContext,\n\tconvertToLlm,\n\ttype ExtensionAPI,\n\ttype ExtensionContext,\n\ttype SessionBeforeCompactEvent,\n\tsessionEntryToContextMessages,\n} from \"@earendil-works/pi-coding-agent\";\nimport {\n\tbuildReplacementHistory,\n\ttype CodexCheckpointDetails,\n\tcheckpointMarker,\n\tcreateCheckpointDetails,\n\tfallbackSummary,\n\tlatestCheckpoint,\n\tprojectCheckpointContext,\n} from \"./checkpoint.js\";\nimport { isCodexRemoteCompactionModel } from \"./model-compatibility.js\";\nimport { hasCheckpointMarker, rewriteCheckpointMarker } from \"./protocol.js\";\nimport { requestRemoteCompaction } from \"./remote.js\";\nimport {\n\ttype CodexCompactSettings,\n\ttype CodexCompactSettingsRuntime,\n\ttype CodexCompactSettingsState,\n\tcreateCodexCompactSettingsRuntime,\n} from \"./settings.js\";\n\nconst STATUS_KEY = \"codex-compact\";\n\nfunction activeCheckpoint(ctx: ExtensionContext) {\n\treturn latestCheckpoint(ctx.sessionManager.getBranch());\n}\n\nfunction isCheckpointCompatible(\n\tdetails: CodexCheckpointDetails,\n\tmodel: Model<Api> | undefined,\n): model is Model<\"openai-codex-responses\"> {\n\treturn isCodexRemoteCompactionModel(model) && model.id === details.modelId;\n}\n\nfunction keptMessages(event: SessionBeforeCompactEvent): AgentMessage[] {\n\tconst leafId = event.branchEntries.at(-1)?.id ?? null;\n\tconst contextEntries = buildContextEntries(event.branchEntries, leafId);\n\tconst keptIndex = contextEntries.findIndex(\n\t\t(entry) => entry.id === event.preparation.firstKeptEntryId,\n\t);\n\tif (keptIndex < 0) {\n\t\tthrow new Error(\"Pi compaction cut point is not present in the active context\");\n\t}\n\treturn contextEntries.slice(keptIndex).flatMap(sessionEntryToContextMessages);\n}\n\nfunction activeTools(pi: ExtensionAPI): Tool[] {\n\tconst enabled = new Set(pi.getActiveTools());\n\treturn pi\n\t\t.getAllTools()\n\t\t.filter((tool) => enabled.has(tool.name))\n\t\t.map((tool) => ({\n\t\t\tname: tool.name,\n\t\t\tdescription: tool.description,\n\t\t\tparameters: tool.parameters,\n\t\t}));\n}\n\nfunction projectedCurrentMessages(\n\tevent: SessionBeforeCompactEvent,\n\tmodel: Model<\"openai-codex-responses\">,\n): { messages: AgentMessage[]; prior?: CodexCheckpointDetails } {\n\tconst leafId = event.branchEntries.at(-1)?.id ?? null;\n\tconst session = buildSessionContext(event.branchEntries, leafId);\n\tconst prior = latestCheckpoint(event.branchEntries);\n\tif (!prior) return { messages: session.messages };\n\tif (prior.details.modelId !== model.id) {\n\t\tthrow new Error(\"The active opaque checkpoint belongs to a different Codex model\");\n\t}\n\tconst projected = projectCheckpointContext(session.messages, prior.details, prior.entry.summary);\n\tif (!projected) {\n\t\tthrow new Error(\"The previous opaque checkpoint could not be projected safely\");\n\t}\n\treturn { messages: projected, prior: prior.details };\n}\n\nfunction notifyFailure(\n\tctx: ExtensionContext,\n\terror: unknown,\n\tsettings: CodexCompactSettings,\n): void {\n\tif (!ctx.hasUI || !settings.notifyOnFallback) return;\n\tconst message = error instanceof Error ? error.message : String(error);\n\tctx.ui.notify(`Codex remote compaction failed; using Pi compaction. ${message}`, \"warning\");\n}\n\nfunction sessionStillOwned(ctx: ExtensionContext, sessionId: string, signal: AbortSignal): boolean {\n\treturn !signal.aborted && ctx.sessionManager.getSessionId() === sessionId;\n}\n\nasync function compactRemotely(\n\tpi: ExtensionAPI,\n\tevent: SessionBeforeCompactEvent,\n\tctx: ExtensionContext,\n\tsettings: CodexCompactSettings,\n\tfetch?: typeof globalThis.fetch,\n) {\n\tconst model = ctx.model;\n\tif (!settings.enabled || !isCodexRemoteCompactionModel(model)) return undefined;\n\tconst sessionId = ctx.sessionManager.getSessionId();\n\tctx.ui.setStatus(STATUS_KEY, \"Codex remote compaction\u2026\");\n\ttry {\n\t\tconst auth = await ctx.modelRegistry.getApiKeyAndHeaders(model);\n\t\tif (!sessionStillOwned(ctx, sessionId, event.signal)) return { cancel: true };\n\t\tif (!auth.ok) throw new Error(auth.error);\n\t\tconst provider = ctx.modelRegistry.getProvider(model.provider);\n\t\tif (!provider) throw new Error(\"The active Codex Responses provider is unavailable\");\n\t\tconst current = projectedCurrentMessages(event, model);\n\t\tconst context: Context = {\n\t\t\tsystemPrompt: ctx.getSystemPrompt(),\n\t\t\tmessages: convertToLlm(current.messages),\n\t\t\ttools: activeTools(pi),\n\t\t};\n\t\tconst response = await requestRemoteCompaction({\n\t\t\tprovider,\n\t\t\tmodel,\n\t\t\tcontext,\n\t\t\tapiKey: auth.apiKey,\n\t\t\theaders: auth.headers,\n\t\t\tenv: auth.env,\n\t\t\tsignal: event.signal,\n\t\t\tpriorCheckpoint: current.prior\n\t\t\t\t? {\n\t\t\t\t\t\tmarker: checkpointMarker(current.prior.checkpointId),\n\t\t\t\t\t\treplacementHistory: current.prior.replacementHistory,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\trequestTimeoutMs: settings.requestTimeoutMs,\n\t\t\tmaxRetries: settings.maxRetries,\n\t\t\tfetch,\n\t\t});\n\t\tif (!sessionStillOwned(ctx, sessionId, event.signal)) return { cancel: true };\n\t\tconst replacementHistory = buildReplacementHistory(response.promptInput, response.item, {\n\t\t\ttokenBudget: settings.replacementTokenBudget,\n\t\t});\n\t\tconst details = createCheckpointDetails({\n\t\t\tprovider: model.provider,\n\t\t\tmodelId: model.id,\n\t\t\treplacementHistory,\n\t\t\tkeptMessages: keptMessages(event),\n\t\t});\n\t\treturn {\n\t\t\tcompaction: {\n\t\t\t\tsummary: fallbackSummary(details.checkpointId),\n\t\t\t\tfirstKeptEntryId: event.preparation.firstKeptEntryId,\n\t\t\t\ttokensBefore: event.preparation.tokensBefore,\n\t\t\t\tusage: response.usage,\n\t\t\t\tdetails,\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tif (event.signal.aborted || ctx.sessionManager.getSessionId() !== sessionId) {\n\t\t\treturn { cancel: true };\n\t\t}\n\t\tnotifyFailure(ctx, error, settings);\n\t\treturn undefined;\n\t} finally {\n\t\tif (ctx.sessionManager.getSessionId() === sessionId) ctx.ui.setStatus(STATUS_KEY, undefined);\n\t}\n}\n\nexport function createCodexCompactExtension(\n\toptions: { fetch?: typeof globalThis.fetch; settingsRuntime?: CodexCompactSettingsRuntime } = {},\n): (pi: ExtensionAPI) => void {\n\treturn (pi) => {\n\t\tconst providerWarnings = new Set<string>();\n\t\tconst settingsRuntime = options.settingsRuntime ?? createCodexCompactSettingsRuntime();\n\t\tlet sessionController = new AbortController();\n\t\tlet generation = 0;\n\n\t\tpi.registerCommand(\"codex-compact\", {\n\t\t\tdescription: \"Compact now or configure Codex Remote Compaction V2\",\n\t\t\thandler: async (_args, ctx) => {\n\t\t\t\tconst ownerGeneration = generation;\n\t\t\t\tconst controller = sessionController;\n\t\t\t\tconst { showCodexCompactMenu } = await import(\"./settings-menu.js\");\n\t\t\t\tif (ownerGeneration !== generation || controller.signal.aborted) return;\n\t\t\t\tawait showCodexCompactMenu(settingsRuntime, ctx, {\n\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t\tisCurrent: () => ownerGeneration === generation && !controller.signal.aborted,\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\n\t\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\t\tsessionController.abort();\n\t\t\tsessionController = new AbortController();\n\t\t\tgeneration += 1;\n\t\t\tconst ownerGeneration = generation;\n\t\t\tconst sessionId = ctx.sessionManager.getSessionId();\n\t\t\tproviderWarnings.clear();\n\t\t\tlet state: Readonly<CodexCompactSettingsState>;\n\t\t\ttry {\n\t\t\t\tstate = await settingsRuntime.reload(sessionController.signal);\n\t\t\t} catch (error) {\n\t\t\t\tif (sessionController.signal.aborted || ownerGeneration !== generation) return;\n\t\t\t\tif (ctx.hasUI) {\n\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t`Could not load pi-codex-compact.json; using defaults. ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\t\"warning\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tsessionController.signal.aborted ||\n\t\t\t\townerGeneration !== generation ||\n\t\t\t\tctx.sessionManager.getSessionId() !== sessionId\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (ctx.hasUI && state.kind === \"invalid\") {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Invalid pi-codex-compact.json; using defaults without overwriting it. ${state.issue}`,\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"session_before_compact\", (event, ctx) =>\n\t\t\tcompactRemotely(pi, event, ctx, settingsRuntime.get().settings, options.fetch),\n\t\t);\n\n\t\tpi.on(\"context\", (event, ctx) => {\n\t\t\tif (!settingsRuntime.get().settings.enabled) return undefined;\n\t\t\tconst checkpoint = activeCheckpoint(ctx);\n\t\t\tif (!checkpoint || !isCheckpointCompatible(checkpoint.details, ctx.model)) return undefined;\n\t\t\tconst messages = projectCheckpointContext(\n\t\t\t\tevent.messages,\n\t\t\t\tcheckpoint.details,\n\t\t\t\tcheckpoint.entry.summary,\n\t\t\t);\n\t\t\treturn messages ? { messages } : undefined;\n\t\t});\n\n\t\tpi.on(\"before_provider_request\", (event, ctx) => {\n\t\t\tif (!settingsRuntime.get().settings.enabled) return undefined;\n\t\t\tconst checkpoint = activeCheckpoint(ctx);\n\t\t\tif (!checkpoint || !isCheckpointCompatible(checkpoint.details, ctx.model)) return undefined;\n\t\t\tconst marker = checkpointMarker(checkpoint.details.checkpointId);\n\t\t\tif (!hasCheckpointMarker(event.payload, marker)) return undefined;\n\t\t\treturn rewriteCheckpointMarker(event.payload, marker, checkpoint.details.replacementHistory);\n\t\t});\n\n\t\tpi.on(\"model_select\", (event, ctx) => {\n\t\t\tif (!settingsRuntime.get().settings.enabled) return;\n\t\t\tconst checkpoint = activeCheckpoint(ctx);\n\t\t\tif (!checkpoint || isCheckpointCompatible(checkpoint.details, event.model)) return;\n\t\t\tconst key = `${ctx.sessionManager.getSessionId()}:${event.model.provider}:${event.model.id}`;\n\t\t\tif (providerWarnings.has(key)) return;\n\t\t\tproviderWarnings.add(key);\n\t\t\tif (ctx.hasUI) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\"The active Codex checkpoint cannot replay on this model; Pi will expose only its fallback marker and retained recent messages.\",\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n\t\t\tgeneration += 1;\n\t\t\tsessionController.abort();\n\t\t\tproviderWarnings.clear();\n\t\t\tctx.ui.setStatus(STATUS_KEY, undefined);\n\t\t\tawait settingsRuntime.flush();\n\t\t});\n\t};\n}\n\nexport default createCodexCompactExtension();\n", "import { createHash, randomUUID } from \"node:crypto\";\nimport type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { CompactionEntry, SessionEntry } from \"@earendil-works/pi-coding-agent\";\nimport { type JsonObject, validateCompactionItem } from \"./protocol.js\";\n\nexport const CHECKPOINT_KIND = \"pi-codex-remote-compaction\";\nexport const CHECKPOINT_VERSION = 1;\nexport const REPLACEMENT_TOKEN_BUDGET = 64_000;\nexport const REPLACEMENT_BYTE_BUDGET = 8 * 1024 * 1024;\nconst MAX_MEDIA_ITEM_BYTES = 2 * 1024 * 1024;\nconst MAX_PROVIDER_ID_LENGTH = 256;\n\nexport interface CodexCheckpointDetails {\n\tkind: typeof CHECKPOINT_KIND;\n\tversion: typeof CHECKPOINT_VERSION;\n\tcheckpointId: string;\n\tprovider: string;\n\tapi: \"openai-codex-responses\";\n\tmodelId: string;\n\tprotocol: \"remote-compaction-v2\";\n\treplacementHistory: JsonObject[];\n\tkeptMessageFingerprints: string[];\n\tcreatedAt: string;\n}\n\nfunction isObject(value: unknown): value is JsonObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction stableValue(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(stableValue);\n\tif (!isObject(value)) return value;\n\treturn Object.fromEntries(\n\t\tObject.entries(value)\n\t\t\t.sort(([left], [right]) => left.localeCompare(right))\n\t\t\t.map(([key, child]) => [key, stableValue(child)]),\n\t);\n}\n\nfunction serializedBytes(value: unknown): number {\n\treturn Buffer.byteLength(JSON.stringify(value), \"utf8\");\n}\n\nexport function fingerprintMessage(message: AgentMessage): string {\n\treturn createHash(\"sha256\")\n\t\t.update(JSON.stringify(stableValue(message)))\n\t\t.digest(\"hex\");\n}\n\nexport function checkpointMarker(checkpointId: string): string {\n\treturn [\n\t\t`[PI_CODEX_REMOTE_CHECKPOINT:${checkpointId}]`,\n\t\t\"Opaque checkpoint injection failed. Do not infer missing history; tell the user to re-enable\",\n\t\t\"@narumitw/pi-codex-compact with a model using the openai-codex-responses API.\",\n\t].join(\" \");\n}\n\nexport function fallbackSummary(checkpointId: string): string {\n\treturn [\n\t\t`OpenAI Codex Remote Compaction V2 checkpoint ${checkpointId} stores the older history opaquely.`,\n\t\t\"Full replay requires @narumitw/pi-codex-compact and the same model through a compatible Codex Responses provider.\",\n\t\t\"Without them, only Pi's retained recent messages remain available.\",\n\t].join(\" \");\n}\n\nfunction markerMessage(checkpointId: string, timestamp: number): AgentMessage {\n\treturn {\n\t\trole: \"user\",\n\t\tcontent: [{ type: \"text\", text: checkpointMarker(checkpointId) }],\n\t\ttimestamp,\n\t};\n}\n\nexport function parseCheckpointDetails(value: unknown): CodexCheckpointDetails | undefined {\n\tif (!isObject(value)) return undefined;\n\tif (\n\t\tvalue.kind !== CHECKPOINT_KIND ||\n\t\tvalue.version !== CHECKPOINT_VERSION ||\n\t\ttypeof value.checkpointId !== \"string\" ||\n\t\tvalue.checkpointId.length < 8 ||\n\t\ttypeof value.provider !== \"string\" ||\n\t\tvalue.provider.length === 0 ||\n\t\tvalue.provider.length > MAX_PROVIDER_ID_LENGTH ||\n\t\tvalue.api !== \"openai-codex-responses\" ||\n\t\ttypeof value.modelId !== \"string\" ||\n\t\tvalue.protocol !== \"remote-compaction-v2\" ||\n\t\t!Array.isArray(value.replacementHistory) ||\n\t\t!Array.isArray(value.keptMessageFingerprints) ||\n\t\ttypeof value.createdAt !== \"string\"\n\t) {\n\t\treturn undefined;\n\t}\n\tif (\n\t\tvalue.replacementHistory.length === 0 ||\n\t\t!value.replacementHistory.every(isObject) ||\n\t\t!value.keptMessageFingerprints.every(\n\t\t\t(fingerprint) => typeof fingerprint === \"string\" && /^[a-f0-9]{64}$/.test(fingerprint),\n\t\t) ||\n\t\tserializedBytes(value.replacementHistory) > REPLACEMENT_BYTE_BUDGET\n\t) {\n\t\treturn undefined;\n\t}\n\tconst last = value.replacementHistory.at(-1);\n\ttry {\n\t\tvalidateCompactionItem(last);\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn structuredClone(value) as unknown as CodexCheckpointDetails;\n}\n\nexport function latestCheckpoint(entries: readonly SessionEntry[]):\n\t| {\n\t\t\tentry: CompactionEntry<CodexCheckpointDetails>;\n\t\t\tdetails: CodexCheckpointDetails;\n\t }\n\t| undefined {\n\tfor (let index = entries.length - 1; index >= 0; index--) {\n\t\tconst entry = entries[index];\n\t\tif (entry.type !== \"compaction\") continue;\n\t\tconst details = parseCheckpointDetails(entry.details);\n\t\treturn details\n\t\t\t? { entry: entry as CompactionEntry<CodexCheckpointDetails>, details }\n\t\t\t: undefined;\n\t}\n\treturn undefined;\n}\n\nfunction isOlderCompactionSummary(message: AgentMessage, timestamp: number): boolean {\n\treturn (\n\t\tmessage.role === \"compactionSummary\" &&\n\t\tNumber.isFinite(message.timestamp) &&\n\t\tNumber.isFinite(timestamp) &&\n\t\tmessage.timestamp < timestamp\n\t);\n}\n\nexport function projectCheckpointContext(\n\tmessages: readonly AgentMessage[],\n\tdetails: CodexCheckpointDetails,\n\tcheckpointSummary: string,\n): AgentMessage[] | undefined {\n\tconst summaryIndex = messages.findIndex(\n\t\t(message) => message.role === \"compactionSummary\" && message.summary === checkpointSummary,\n\t);\n\tif (summaryIndex < 0) return undefined;\n\tconst timestamp = messages[summaryIndex].timestamp;\n\tlet messageIndex = summaryIndex + 1;\n\tlet fingerprintIndex = 0;\n\twhile (fingerprintIndex < details.keptMessageFingerprints.length) {\n\t\tif (messageIndex >= messages.length) return undefined;\n\t\tconst message = messages[messageIndex];\n\t\tif (fingerprintMessage(message) === details.keptMessageFingerprints[fingerprintIndex]) {\n\t\t\tmessageIndex += 1;\n\t\t\tfingerprintIndex += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (isOlderCompactionSummary(message, timestamp)) {\n\t\t\tmessageIndex += 1;\n\t\t\tcontinue;\n\t\t}\n\t\treturn undefined;\n\t}\n\twhile (\n\t\tmessageIndex < messages.length &&\n\t\tisOlderCompactionSummary(messages[messageIndex], timestamp)\n\t) {\n\t\tmessageIndex += 1;\n\t}\n\treturn [\n\t\t...messages.slice(0, summaryIndex),\n\t\tmarkerMessage(details.checkpointId, timestamp),\n\t\t...messages.slice(messageIndex),\n\t];\n}\n\nfunction rawText(item: JsonObject): string {\n\tif (!Array.isArray(item.content)) return \"\";\n\treturn item.content\n\t\t.flatMap((part) =>\n\t\t\tisObject(part) && typeof part.text === \"string\" && part.type === \"input_text\"\n\t\t\t\t? [part.text]\n\t\t\t\t: [],\n\t\t)\n\t\t.join(\"\\n\");\n}\n\nfunction hasMedia(item: JsonObject): boolean {\n\treturn (\n\t\tArray.isArray(item.content) &&\n\t\titem.content.some((part) => isObject(part) && part.type === \"input_image\")\n\t);\n}\n\nfunction truncateTextItem(item: JsonObject, maxChars: number): JsonObject | undefined {\n\tif (!Array.isArray(item.content) || maxChars <= 32) return undefined;\n\tlet remaining = maxChars - 16;\n\tconst content = [...item.content].reverse().flatMap((part) => {\n\t\tif (\n\t\t\t!isObject(part) ||\n\t\t\tpart.type !== \"input_text\" ||\n\t\t\ttypeof part.text !== \"string\" ||\n\t\t\tremaining <= 0\n\t\t) {\n\t\t\treturn [];\n\t\t}\n\t\tconst text = part.text.slice(-remaining);\n\t\tremaining -= text.length;\n\t\treturn [{ ...part, text: `[truncated]\\n${text}` }];\n\t});\n\tif (content.length === 0) return undefined;\n\treturn { ...item, content: content.reverse() };\n}\n\nexport function buildReplacementHistory(\n\tinput: readonly unknown[],\n\tcompactionItem: JsonObject,\n\toptions: { tokenBudget?: number; byteBudget?: number } = {},\n): JsonObject[] {\n\tconst tokenBudget = options.tokenBudget ?? REPLACEMENT_TOKEN_BUDGET;\n\tconst byteBudget = options.byteBudget ?? REPLACEMENT_BYTE_BUDGET;\n\tconst opaque = validateCompactionItem(compactionItem);\n\tlet remainingBytes = byteBudget - serializedBytes(opaque);\n\tlet remainingChars = tokenBudget * 4;\n\tif (remainingBytes <= 0)\n\t\tthrow new Error(\"Opaque compaction item exceeds replacement history budget\");\n\tconst retainedNewestFirst: JsonObject[] = [];\n\tconst candidates = input.filter(\n\t\t(item): item is JsonObject =>\n\t\t\tisObject(item) && item.role === \"user\" && item.type !== \"compaction_trigger\",\n\t);\n\tfor (let index = candidates.length - 1; index >= 0; index--) {\n\t\tconst candidate = candidates[index];\n\t\tconst bytes = serializedBytes(candidate);\n\t\tif (hasMedia(candidate) && bytes > MAX_MEDIA_ITEM_BYTES) continue;\n\t\tconst text = rawText(candidate);\n\t\tlet retained = candidate;\n\t\tif (text.length > remainingChars) {\n\t\t\tif (hasMedia(candidate)) continue;\n\t\t\tconst truncated = truncateTextItem(candidate, remainingChars);\n\t\t\tif (!truncated) continue;\n\t\t\tretained = truncated;\n\t\t}\n\t\tif (serializedBytes(retained) > remainingBytes) {\n\t\t\tif (hasMedia(retained)) continue;\n\t\t\tconst maxCharsByBytes = Math.max(0, remainingBytes - 128);\n\t\t\tconst truncated = truncateTextItem(retained, Math.min(remainingChars, maxCharsByBytes));\n\t\t\tif (!truncated || serializedBytes(truncated) > remainingBytes) continue;\n\t\t\tretained = truncated;\n\t\t}\n\t\tretainedNewestFirst.push(structuredClone(retained));\n\t\tremainingBytes -= serializedBytes(retained);\n\t\tremainingChars -= Math.min(remainingChars, rawText(retained).length);\n\t\tif (remainingBytes <= 128 || remainingChars <= 32) break;\n\t}\n\treturn [...retainedNewestFirst.reverse(), opaque];\n}\n\nexport function createCheckpointDetails(input: {\n\tprovider: string;\n\tmodelId: string;\n\treplacementHistory: JsonObject[];\n\tkeptMessages: readonly AgentMessage[];\n\tcheckpointId?: string;\n\tcreatedAt?: string;\n}): CodexCheckpointDetails {\n\tconst details: CodexCheckpointDetails = {\n\t\tkind: CHECKPOINT_KIND,\n\t\tversion: CHECKPOINT_VERSION,\n\t\tcheckpointId: input.checkpointId ?? randomUUID(),\n\t\tprovider: input.provider,\n\t\tapi: \"openai-codex-responses\",\n\t\tmodelId: input.modelId,\n\t\tprotocol: \"remote-compaction-v2\",\n\t\treplacementHistory: structuredClone(input.replacementHistory),\n\t\tkeptMessageFingerprints: input.keptMessages.map(fingerprintMessage),\n\t\tcreatedAt: input.createdAt ?? new Date().toISOString(),\n\t};\n\tconst parsed = parseCheckpointDetails(details);\n\tif (!parsed) throw new Error(\"Created an invalid Codex checkpoint\");\n\treturn parsed;\n}\n", "export const MAX_SSE_BYTES = 8 * 1024 * 1024;\nexport const MAX_COMPACTION_ITEM_BYTES = 2 * 1024 * 1024;\n\nexport type JsonObject = Record<string, unknown>;\n\nexport class CodexCompactionProtocolError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"CodexCompactionProtocolError\";\n\t}\n}\n\nfunction isObject(value: unknown): value is JsonObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction byteLength(value: unknown): number {\n\treturn Buffer.byteLength(JSON.stringify(value), \"utf8\");\n}\n\nexport function isCompactionItem(value: unknown): value is JsonObject {\n\treturn (\n\t\tisObject(value) &&\n\t\tvalue.type === \"compaction\" &&\n\t\ttypeof value.encrypted_content === \"string\" &&\n\t\tvalue.encrypted_content.length > 0\n\t);\n}\n\nexport function validateCompactionItem(\n\tvalue: unknown,\n\tmaxBytes = MAX_COMPACTION_ITEM_BYTES,\n): JsonObject {\n\tif (!isCompactionItem(value)) {\n\t\tthrow new CodexCompactionProtocolError(\n\t\t\t\"Remote response did not contain a valid compaction item\",\n\t\t);\n\t}\n\tif (byteLength(value) > maxBytes) {\n\t\tthrow new CodexCompactionProtocolError(\"Remote compaction item exceeded the size limit\");\n\t}\n\treturn structuredClone(value);\n}\n\nexport interface CollectedCompaction {\n\titem: JsonObject;\n\tcompletedResponse?: JsonObject;\n}\n\nfunction compactionItemsFromEvent(event: JsonObject): unknown[] {\n\tconst items: unknown[] = [];\n\tif (event.type === \"response.output_item.done\" && isObject(event.item)) {\n\t\titems.push(event.item);\n\t}\n\tif (event.type === \"response.completed\" && isObject(event.response)) {\n\t\tconst output = event.response.output;\n\t\tif (Array.isArray(output)) items.push(...output);\n\t}\n\treturn items.filter((item) => isObject(item) && item.type === \"compaction\");\n}\n\nexport async function collectCompactionSse(\n\tstream: ReadableStream<Uint8Array>,\n\toptions: {\n\t\tsignal?: AbortSignal;\n\t\tmaxBytes?: number;\n\t\tmaxItemBytes?: number;\n\t} = {},\n): Promise<CollectedCompaction> {\n\tconst maxBytes = options.maxBytes ?? MAX_SSE_BYTES;\n\tconst reader = stream.getReader();\n\tconst onAbort = () => {\n\t\tvoid reader.cancel(new DOMException(\"Compaction aborted\", \"AbortError\")).catch(() => undefined);\n\t};\n\toptions.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\tconst decoder = new TextDecoder();\n\tlet bytes = 0;\n\tlet pending = \"\";\n\tlet dataLines: string[] = [];\n\tlet completedResponse: JsonObject | undefined;\n\tconst items = new Map<string, JsonObject>();\n\n\tconst checkAbort = () => {\n\t\tif (options.signal?.aborted) throw new DOMException(\"Compaction aborted\", \"AbortError\");\n\t};\n\tconst dispatch = () => {\n\t\tif (dataLines.length === 0) return;\n\t\tconst data = dataLines.join(\"\\n\");\n\t\tdataLines = [];\n\t\tif (data === \"[DONE]\") return;\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(data);\n\t\t} catch {\n\t\t\tthrow new CodexCompactionProtocolError(\"Remote compaction returned malformed SSE JSON\");\n\t\t}\n\t\tif (!isObject(parsed)) return;\n\t\tif (parsed.type === \"response.completed\") {\n\t\t\tcompletedResponse = isObject(parsed.response) ? parsed.response : {};\n\t\t}\n\t\tfor (const candidate of compactionItemsFromEvent(parsed)) {\n\t\t\tconst item = validateCompactionItem(candidate, options.maxItemBytes);\n\t\t\titems.set(JSON.stringify(item), item);\n\t\t}\n\t};\n\tconst processLine = (line: string) => {\n\t\tif (line === \"\") {\n\t\t\tdispatch();\n\t\t\treturn;\n\t\t}\n\t\tif (line.startsWith(\":\")) return;\n\t\tif (line === \"data\") dataLines.push(\"\");\n\t\telse if (line.startsWith(\"data:\")) dataLines.push(line.slice(5).replace(/^ /, \"\"));\n\t};\n\n\ttry {\n\t\twhile (true) {\n\t\t\tcheckAbort();\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tbytes += value.byteLength;\n\t\t\tif (bytes > maxBytes) {\n\t\t\t\tthrow new CodexCompactionProtocolError(\"Remote compaction stream exceeded the size limit\");\n\t\t\t}\n\t\t\tpending += decoder.decode(value, { stream: true });\n\t\t\tlet newline = pending.indexOf(\"\\n\");\n\t\t\twhile (newline !== -1) {\n\t\t\t\tconst rawLine = pending.slice(0, newline);\n\t\t\t\tpending = pending.slice(newline + 1);\n\t\t\t\tprocessLine(rawLine.endsWith(\"\\r\") ? rawLine.slice(0, -1) : rawLine);\n\t\t\t\tnewline = pending.indexOf(\"\\n\");\n\t\t\t}\n\t\t}\n\t\tpending += decoder.decode();\n\t\tif (pending.length > 0) processLine(pending.endsWith(\"\\r\") ? pending.slice(0, -1) : pending);\n\t\tdispatch();\n\t\tcheckAbort();\n\t} catch (error) {\n\t\tawait reader.cancel(error).catch(() => undefined);\n\t\tthrow error;\n\t} finally {\n\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\treader.releaseLock();\n\t}\n\n\tif (!completedResponse) {\n\t\tthrow new CodexCompactionProtocolError(\n\t\t\t\"Remote compaction stream ended without response.completed\",\n\t\t);\n\t}\n\tif (items.size !== 1) {\n\t\tthrow new CodexCompactionProtocolError(\n\t\t\t`Remote compaction returned ${items.size} distinct compaction items; expected exactly one`,\n\t\t);\n\t}\n\treturn { item: [...items.values()][0], completedResponse };\n}\n\nfunction markerTextFromItem(item: unknown): string | undefined {\n\tif (!isObject(item) || item.role !== \"user\" || !Array.isArray(item.content)) return undefined;\n\tif (item.content.length !== 1) return undefined;\n\tconst content = item.content[0];\n\tif (!isObject(content) || content.type !== \"input_text\" || typeof content.text !== \"string\") {\n\t\treturn undefined;\n\t}\n\treturn content.text;\n}\n\nexport function rewriteCheckpointMarker(\n\tpayload: unknown,\n\tmarker: string,\n\treplacementHistory: readonly unknown[],\n): JsonObject {\n\tif (!isObject(payload) || !Array.isArray(payload.input)) {\n\t\tthrow new CodexCompactionProtocolError(\"Codex Responses payload is missing an input array\");\n\t}\n\tconst matches = payload.input\n\t\t.map((item, index) => (markerTextFromItem(item) === marker ? index : -1))\n\t\t.filter((index) => index >= 0);\n\tif (matches.length !== 1) {\n\t\tthrow new CodexCompactionProtocolError(\n\t\t\t`Provider payload contained ${matches.length} checkpoint markers; expected exactly one`,\n\t\t);\n\t}\n\tconst index = matches[0];\n\treturn {\n\t\t...payload,\n\t\tinput: [\n\t\t\t...payload.input.slice(0, index),\n\t\t\t...structuredClone(replacementHistory),\n\t\t\t...payload.input.slice(index + 1),\n\t\t],\n\t};\n}\n\nexport function appendCompactionTrigger(payload: unknown): JsonObject {\n\tif (!isObject(payload) || !Array.isArray(payload.input)) {\n\t\tthrow new CodexCompactionProtocolError(\"Codex Responses payload is missing an input array\");\n\t}\n\tif (payload.input.some((item) => isObject(item) && item.type === \"compaction_trigger\")) {\n\t\tthrow new CodexCompactionProtocolError(\n\t\t\t\"Provider payload already contains a compaction trigger\",\n\t\t);\n\t}\n\treturn { ...payload, input: [...payload.input, { type: \"compaction_trigger\" }] };\n}\n\nexport function prepareRemoteCompactionPayload(\n\tpayload: unknown,\n\tcheckpoint?: { marker: string; replacementHistory: readonly unknown[] },\n): JsonObject {\n\tconst expanded = checkpoint\n\t\t? rewriteCheckpointMarker(payload, checkpoint.marker, checkpoint.replacementHistory)\n\t\t: payload;\n\treturn appendCompactionTrigger(expanded);\n}\n\nexport function hasCheckpointMarker(payload: unknown, marker: string): boolean {\n\treturn (\n\t\tisObject(payload) &&\n\t\tArray.isArray(payload.input) &&\n\t\tpayload.input.some((item) => markerTextFromItem(item) === marker)\n\t);\n}\n", "import type { Context, Model, Provider, ProviderHeaders, Usage } from \"@earendil-works/pi-ai\";\nimport {\n\tCodexCompactionProtocolError,\n\ttype CollectedCompaction,\n\tcollectCompactionSse,\n\ttype JsonObject,\n\tprepareRemoteCompactionPayload,\n} from \"./protocol.js\";\n\ninterface PriorCheckpointPayload {\n\tmarker: string;\n\treplacementHistory: readonly unknown[];\n}\n\nexport interface RemoteCompactionRequest {\n\tprovider: Provider;\n\tmodel: Model<\"openai-codex-responses\">;\n\tcontext: Context;\n\tapiKey?: string;\n\theaders?: ProviderHeaders;\n\tenv?: Record<string, string>;\n\tsignal: AbortSignal;\n\tpriorCheckpoint?: PriorCheckpointPayload;\n\trequestTimeoutMs?: number;\n\tmaxRetries?: number;\n\tfetch?: typeof globalThis.fetch;\n}\n\nexport interface RemoteCompactionResponse {\n\titem: JsonObject;\n\tpromptInput: JsonObject[];\n\tusage: Usage;\n}\n\nconst EMPTY_USAGE: Usage = {\n\tinput: 0,\n\toutput: 0,\n\tcacheRead: 0,\n\tcacheWrite: 0,\n\ttotalTokens: 0,\n\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n};\n\nfunction isObject(value: unknown): value is JsonObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction abortError(): DOMException {\n\treturn new DOMException(\"Compaction aborted\", \"AbortError\");\n}\n\nexport async function requestRemoteCompaction(\n\trequest: RemoteCompactionRequest,\n): Promise<RemoteCompactionResponse> {\n\tif (request.signal.aborted) throw abortError();\n\tlet sentInput: JsonObject[] | undefined;\n\tconst inspections: Promise<\n\t\t{ ok: true; value: CollectedCompaction } | { ok: false; error: unknown }\n\t>[] = [];\n\tconst baseFetch = request.fetch ?? globalThis.fetch;\n\tconst inspectedFetch: typeof globalThis.fetch = async (input, init) => {\n\t\tconst response = await baseFetch(input, init);\n\t\tif (!response.ok || !response.body) return response;\n\t\tconst [providerBody, inspectionBody] = response.body.tee();\n\t\tconst inspection = collectCompactionSse(inspectionBody, { signal: request.signal }).then(\n\t\t\t(value) => ({ ok: true as const, value }),\n\t\t\t(error: unknown) => ({ ok: false as const, error }),\n\t\t);\n\t\tinspections.push(inspection);\n\t\treturn new Response(providerBody, {\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\theaders: response.headers,\n\t\t});\n\t};\n\n\tconst stream = request.provider.stream(request.model, request.context, {\n\t\tapiKey: request.apiKey,\n\t\theaders: request.headers,\n\t\tenv: request.env,\n\t\tsignal: request.signal,\n\t\ttransport: \"sse\",\n\t\tcacheRetention: \"none\",\n\t\ttimeoutMs: request.requestTimeoutMs ?? 5 * 60 * 1000,\n\t\tmaxRetries: request.maxRetries ?? 2,\n\t\tfetch: inspectedFetch,\n\t\tonPayload: (payload) => {\n\t\t\tconst prepared = prepareRemoteCompactionPayload(payload, request.priorCheckpoint);\n\t\t\tif (!Array.isArray(prepared.input) || !prepared.input.every(isObject)) {\n\t\t\t\tthrow new CodexCompactionProtocolError(\n\t\t\t\t\t\"Prepared compaction payload has invalid input items\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tsentInput = structuredClone(prepared.input.slice(0, -1)) as JsonObject[];\n\t\t\treturn prepared;\n\t\t},\n\t});\n\n\tlet usage = EMPTY_USAGE;\n\tfor await (const event of stream) {\n\t\tif (request.signal.aborted) throw abortError();\n\t\tif (event.type === \"error\") {\n\t\t\tthrow new Error(event.error.errorMessage ?? \"Codex remote compaction request failed\");\n\t\t}\n\t\tif (event.type === \"done\") usage = event.message.usage;\n\t}\n\tif (request.signal.aborted) throw abortError();\n\tif (!sentInput)\n\t\tthrow new CodexCompactionProtocolError(\"Provider did not expose a request payload\");\n\tif (inspections.length === 0) {\n\t\tthrow new CodexCompactionProtocolError(\"Provider response did not expose an SSE body\");\n\t}\n\tconst inspection = await inspections.at(-1);\n\tif (request.signal.aborted) throw abortError();\n\tif (!inspection?.ok) throw inspection?.error ?? new Error(\"Remote compaction inspection failed\");\n\treturn { item: inspection.value.item, promptInput: sentInput, usage };\n}\n", "import { randomUUID } from \"node:crypto\";\nimport { constants } from \"node:fs\";\nimport { mkdir, open, rename, rm, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\nimport { getAgentDir } from \"@earendil-works/pi-coding-agent\";\n\nexport const CODEX_COMPACT_SETTINGS_FILE = \"pi-codex-compact.json\";\nexport const MAX_SETTINGS_BYTES = 64 * 1024;\n\nexport interface CodexCompactSettings {\n\tenabled: boolean;\n\trequestTimeoutMs: number;\n\tmaxRetries: number;\n\treplacementTokenBudget: number;\n\tnotifyOnFallback: boolean;\n}\n\nexport const DEFAULT_CODEX_COMPACT_SETTINGS: Readonly<CodexCompactSettings> = Object.freeze({\n\tenabled: true,\n\trequestTimeoutMs: 300_000,\n\tmaxRetries: 2,\n\treplacementTokenBudget: 64_000,\n\tnotifyOnFallback: true,\n});\n\nconst LIMITS = Object.freeze({\n\trequestTimeoutMs: { minimum: 30_000, maximum: 600_000 },\n\tmaxRetries: { minimum: 0, maximum: 2 },\n\treplacementTokenBudget: { minimum: 8_000, maximum: 128_000 },\n});\n\nexport interface CodexCompactSettingsState {\n\tkind: \"missing\" | \"loaded\" | \"invalid\";\n\tpath: string;\n\tsettings: CodexCompactSettings;\n\tdocument?: Record<string, unknown>;\n\tissue?: string;\n}\n\nexport interface CodexCompactSettingsRuntime {\n\tget(): Readonly<CodexCompactSettingsState>;\n\treload(signal?: AbortSignal): Promise<Readonly<CodexCompactSettingsState>>;\n\tupdate(\n\t\tpatch: Partial<CodexCompactSettings>,\n\t\tsignal?: AbortSignal,\n\t): Promise<Readonly<CodexCompactSettingsState>>;\n\tflush(): Promise<void>;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction validInteger(value: unknown, minimum: number, maximum: number): value is number {\n\treturn (\n\t\ttypeof value === \"number\" && Number.isSafeInteger(value) && value >= minimum && value <= maximum\n\t);\n}\n\nexport function normalizeCodexCompactSettings(value: unknown): CodexCompactSettings | undefined {\n\tif (!isRecord(value)) return undefined;\n\tif (Object.hasOwn(value, \"enabled\") && typeof value.enabled !== \"boolean\") return undefined;\n\tif (Object.hasOwn(value, \"notifyOnFallback\") && typeof value.notifyOnFallback !== \"boolean\") {\n\t\treturn undefined;\n\t}\n\tfor (const [field, limits] of Object.entries(LIMITS) as Array<\n\t\t[keyof typeof LIMITS, { minimum: number; maximum: number }]\n\t>) {\n\t\tif (\n\t\t\tObject.hasOwn(value, field) &&\n\t\t\t!validInteger(value[field], limits.minimum, limits.maximum)\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\treturn {\n\t\tenabled:\n\t\t\ttypeof value.enabled === \"boolean\" ? value.enabled : DEFAULT_CODEX_COMPACT_SETTINGS.enabled,\n\t\trequestTimeoutMs:\n\t\t\ttypeof value.requestTimeoutMs === \"number\"\n\t\t\t\t? value.requestTimeoutMs\n\t\t\t\t: DEFAULT_CODEX_COMPACT_SETTINGS.requestTimeoutMs,\n\t\tmaxRetries:\n\t\t\ttypeof value.maxRetries === \"number\"\n\t\t\t\t? value.maxRetries\n\t\t\t\t: DEFAULT_CODEX_COMPACT_SETTINGS.maxRetries,\n\t\treplacementTokenBudget:\n\t\t\ttypeof value.replacementTokenBudget === \"number\"\n\t\t\t\t? value.replacementTokenBudget\n\t\t\t\t: DEFAULT_CODEX_COMPACT_SETTINGS.replacementTokenBudget,\n\t\tnotifyOnFallback:\n\t\t\ttypeof value.notifyOnFallback === \"boolean\"\n\t\t\t\t? value.notifyOnFallback\n\t\t\t\t: DEFAULT_CODEX_COMPACT_SETTINGS.notifyOnFallback,\n\t};\n}\n\nexport function codexCompactSettingsPath(): string {\n\treturn join(getAgentDir(), CODEX_COMPACT_SETTINGS_FILE);\n}\n\nfunction aborted(signal?: AbortSignal): void {\n\tif (signal?.aborted) throw new DOMException(\"Settings operation aborted\", \"AbortError\");\n}\n\nexport async function loadCodexCompactSettings(\n\tpath = codexCompactSettingsPath(),\n\tsignal?: AbortSignal,\n): Promise<CodexCompactSettingsState> {\n\taborted(signal);\n\ttry {\n\t\tconst handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);\n\t\tlet text: string;\n\t\ttry {\n\t\t\tconst stats = await handle.stat();\n\t\t\taborted(signal);\n\t\t\tif (!stats.isFile()) throw new Error(\"settings path is not a regular file\");\n\t\t\tif (stats.size > MAX_SETTINGS_BYTES) throw new Error(\"settings file exceeds 64 KiB\");\n\t\t\ttext = await handle.readFile(\"utf8\");\n\t\t} finally {\n\t\t\tawait handle.close();\n\t\t}\n\t\taborted(signal);\n\t\tconst document = JSON.parse(text) as unknown;\n\t\tconst settings = normalizeCodexCompactSettings(document);\n\t\tif (!settings || !isRecord(document)) throw new Error(\"invalid settings shape or bounds\");\n\t\treturn { kind: \"loaded\", path, settings, document };\n\t} catch (error) {\n\t\tif (signal?.aborted) throw error;\n\t\tif (isNodeError(error) && error.code === \"ENOENT\") {\n\t\t\treturn {\n\t\t\t\tkind: \"missing\",\n\t\t\t\tpath,\n\t\t\t\tsettings: { ...DEFAULT_CODEX_COMPACT_SETTINGS },\n\t\t\t\tdocument: {},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tkind: \"invalid\",\n\t\t\tpath,\n\t\t\tsettings: { ...DEFAULT_CODEX_COMPACT_SETTINGS },\n\t\t\tissue:\n\t\t\t\tisNodeError(error) && error.code === \"ELOOP\"\n\t\t\t\t\t? \"symbolic links are not accepted\"\n\t\t\t\t\t: error instanceof Error\n\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t: String(error),\n\t\t};\n\t}\n}\n\nasync function savePatch(\n\tpath: string,\n\tpatch: Partial<CodexCompactSettings>,\n\tsignal?: AbortSignal,\n): Promise<CodexCompactSettingsState> {\n\tconst latest = await loadCodexCompactSettings(path, signal);\n\tif (latest.kind === \"invalid\") {\n\t\tthrow new Error(\n\t\t\t\"Cannot overwrite an invalid pi-codex-compact.json; repair it and reload first\",\n\t\t);\n\t}\n\tconst document = { ...latest.document, ...patch };\n\tconst settings = normalizeCodexCompactSettings(document);\n\tif (!settings) throw new Error(\"Refusing to save invalid Codex compaction settings\");\n\tconst temporaryPath = join(dirname(path), `.${basename(path)}.${randomUUID()}.tmp`);\n\tawait mkdir(dirname(path), { recursive: true });\n\taborted(signal);\n\ttry {\n\t\tawait writeFile(temporaryPath, `${JSON.stringify(document, null, 2)}\\n`, {\n\t\t\tencoding: \"utf8\",\n\t\t\tflag: \"wx\",\n\t\t\tmode: 0o600,\n\t\t});\n\t\taborted(signal);\n\t\tconst current = await loadCodexCompactSettings(path, signal);\n\t\tif (\n\t\t\tcurrent.kind === \"invalid\" ||\n\t\t\tcurrent.kind !== latest.kind ||\n\t\t\tJSON.stringify(current.document) !== JSON.stringify(latest.document)\n\t\t) {\n\t\t\tthrow new Error(\"pi-codex-compact.json changed while saving; reopen settings and retry\");\n\t\t}\n\t\tawait rename(temporaryPath, path);\n\t} finally {\n\t\tawait rm(temporaryPath, { force: true }).catch(() => undefined);\n\t}\n\treturn { kind: \"loaded\", path, settings, document };\n}\n\nexport function createCodexCompactSettingsRuntime(\n\tpath = codexCompactSettingsPath(),\n): CodexCompactSettingsRuntime {\n\tlet state: CodexCompactSettingsState = {\n\t\tkind: \"missing\",\n\t\tpath,\n\t\tsettings: { ...DEFAULT_CODEX_COMPACT_SETTINGS },\n\t\tdocument: {},\n\t};\n\tlet queue = Promise.resolve();\n\tconst enqueue = <T>(operation: () => Promise<T>): Promise<T> => {\n\t\tconst result = queue.then(operation, operation);\n\t\tqueue = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t};\n\treturn {\n\t\tget: () => structuredClone(state),\n\t\treload: (signal) =>\n\t\t\tenqueue(async () => {\n\t\t\t\tstate = await loadCodexCompactSettings(path, signal);\n\t\t\t\treturn structuredClone(state);\n\t\t\t}),\n\t\tupdate: (patch, signal) =>\n\t\t\tenqueue(async () => {\n\t\t\t\tstate = await savePatch(path, patch, signal);\n\t\t\t\treturn structuredClone(state);\n\t\t\t}),\n\t\tflush: () => queue,\n\t};\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n"],
5
- "mappings": ";;;;;;;AAEA;AAAA,EACC;AAAA,EACA;AAAA,EACA;AAAA,EAIA;AAAA,OACM;;;ACVP,SAAS,YAAY,kBAAkB;;;ACAhC,IAAM,gBAAgB,IAAI,OAAO;AACjC,IAAM,4BAA4B,IAAI,OAAO;AAI7C,IAAM,+BAAN,cAA2C,MAAM;AAAA,EACvD,YAAY,SAAiB;AAC5B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACb;AACD;AAEA,SAAS,SAAS,OAAqC;AACtD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC3E;AAEA,SAAS,WAAW,OAAwB;AAC3C,SAAO,OAAO,WAAW,KAAK,UAAU,KAAK,GAAG,MAAM;AACvD;AAEO,SAAS,iBAAiB,OAAqC;AACrE,SACC,SAAS,KAAK,KACd,MAAM,SAAS,gBACf,OAAO,MAAM,sBAAsB,YACnC,MAAM,kBAAkB,SAAS;AAEnC;AAEO,SAAS,uBACf,OACA,WAAW,2BACE;AACb,MAAI,CAAC,iBAAiB,KAAK,GAAG;AAC7B,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAAA,EACD;AACA,MAAI,WAAW,KAAK,IAAI,UAAU;AACjC,UAAM,IAAI,6BAA6B,gDAAgD;AAAA,EACxF;AACA,SAAO,gBAAgB,KAAK;AAC7B;AAOA,SAAS,yBAAyB,OAA8B;AAC/D,QAAM,QAAmB,CAAC;AAC1B,MAAI,MAAM,SAAS,+BAA+B,SAAS,MAAM,IAAI,GAAG;AACvE,UAAM,KAAK,MAAM,IAAI;AAAA,EACtB;AACA,MAAI,MAAM,SAAS,wBAAwB,SAAS,MAAM,QAAQ,GAAG;AACpE,UAAM,SAAS,MAAM,SAAS;AAC9B,QAAI,MAAM,QAAQ,MAAM,EAAG,OAAM,KAAK,GAAG,MAAM;AAAA,EAChD;AACA,SAAO,MAAM,OAAO,CAAC,SAAS,SAAS,IAAI,KAAK,KAAK,SAAS,YAAY;AAC3E;AAEA,eAAsB,qBACrB,QACA,UAII,CAAC,GAC0B;AAC/B,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,SAAS,OAAO,UAAU;AAChC,QAAM,UAAU,MAAM;AACrB,SAAK,OAAO,OAAO,IAAI,aAAa,sBAAsB,YAAY,CAAC,EAAE,MAAM,MAAM,MAAS;AAAA,EAC/F;AACA,UAAQ,QAAQ,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;AACjE,QAAM,UAAU,IAAI,YAAY;AAChC,MAAI,QAAQ;AACZ,MAAI,UAAU;AACd,MAAI,YAAsB,CAAC;AAC3B,MAAI;AACJ,QAAM,QAAQ,oBAAI,IAAwB;AAE1C,QAAM,aAAa,MAAM;AACxB,QAAI,QAAQ,QAAQ,QAAS,OAAM,IAAI,aAAa,sBAAsB,YAAY;AAAA,EACvF;AACA,QAAM,WAAW,MAAM;AACtB,QAAI,UAAU,WAAW,EAAG;AAC5B,UAAM,OAAO,UAAU,KAAK,IAAI;AAChC,gBAAY,CAAC;AACb,QAAI,SAAS,SAAU;AACvB,QAAI;AACJ,QAAI;AACH,eAAS,KAAK,MAAM,IAAI;AAAA,IACzB,QAAQ;AACP,YAAM,IAAI,6BAA6B,+CAA+C;AAAA,IACvF;AACA,QAAI,CAAC,SAAS,MAAM,EAAG;AACvB,QAAI,OAAO,SAAS,sBAAsB;AACzC,0BAAoB,SAAS,OAAO,QAAQ,IAAI,OAAO,WAAW,CAAC;AAAA,IACpE;AACA,eAAW,aAAa,yBAAyB,MAAM,GAAG;AACzD,YAAM,OAAO,uBAAuB,WAAW,QAAQ,YAAY;AACnE,YAAM,IAAI,KAAK,UAAU,IAAI,GAAG,IAAI;AAAA,IACrC;AAAA,EACD;AACA,QAAM,cAAc,CAAC,SAAiB;AACrC,QAAI,SAAS,IAAI;AAChB,eAAS;AACT;AAAA,IACD;AACA,QAAI,KAAK,WAAW,GAAG,EAAG;AAC1B,QAAI,SAAS,OAAQ,WAAU,KAAK,EAAE;AAAA,aAC7B,KAAK,WAAW,OAAO,EAAG,WAAU,KAAK,KAAK,MAAM,CAAC,EAAE,QAAQ,MAAM,EAAE,CAAC;AAAA,EAClF;AAEA,MAAI;AACH,WAAO,MAAM;AACZ,iBAAW;AACX,YAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,UAAI,KAAM;AACV,eAAS,MAAM;AACf,UAAI,QAAQ,UAAU;AACrB,cAAM,IAAI,6BAA6B,kDAAkD;AAAA,MAC1F;AACA,iBAAW,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;AACjD,UAAI,UAAU,QAAQ,QAAQ,IAAI;AAClC,aAAO,YAAY,IAAI;AACtB,cAAM,UAAU,QAAQ,MAAM,GAAG,OAAO;AACxC,kBAAU,QAAQ,MAAM,UAAU,CAAC;AACnC,oBAAY,QAAQ,SAAS,IAAI,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,OAAO;AACnE,kBAAU,QAAQ,QAAQ,IAAI;AAAA,MAC/B;AAAA,IACD;AACA,eAAW,QAAQ,OAAO;AAC1B,QAAI,QAAQ,SAAS,EAAG,aAAY,QAAQ,SAAS,IAAI,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,OAAO;AAC3F,aAAS;AACT,eAAW;AAAA,EACZ,SAAS,OAAO;AACf,UAAM,OAAO,OAAO,KAAK,EAAE,MAAM,MAAM,MAAS;AAChD,UAAM;AAAA,EACP,UAAE;AACD,YAAQ,QAAQ,oBAAoB,SAAS,OAAO;AACpD,WAAO,YAAY;AAAA,EACpB;AAEA,MAAI,CAAC,mBAAmB;AACvB,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAAA,EACD;AACA,MAAI,MAAM,SAAS,GAAG;AACrB,UAAM,IAAI;AAAA,MACT,8BAA8B,MAAM,IAAI;AAAA,IACzC;AAAA,EACD;AACA,SAAO,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,EAAE,CAAC,GAAG,kBAAkB;AAC1D;AAEA,SAAS,mBAAmB,MAAmC;AAC9D,MAAI,CAAC,SAAS,IAAI,KAAK,KAAK,SAAS,UAAU,CAAC,MAAM,QAAQ,KAAK,OAAO,EAAG,QAAO;AACpF,MAAI,KAAK,QAAQ,WAAW,EAAG,QAAO;AACtC,QAAM,UAAU,KAAK,QAAQ,CAAC;AAC9B,MAAI,CAAC,SAAS,OAAO,KAAK,QAAQ,SAAS,gBAAgB,OAAO,QAAQ,SAAS,UAAU;AAC5F,WAAO;AAAA,EACR;AACA,SAAO,QAAQ;AAChB;AAEO,SAAS,wBACf,SACA,QACA,oBACa;AACb,MAAI,CAAC,SAAS,OAAO,KAAK,CAAC,MAAM,QAAQ,QAAQ,KAAK,GAAG;AACxD,UAAM,IAAI,6BAA6B,mDAAmD;AAAA,EAC3F;AACA,QAAM,UAAU,QAAQ,MACtB,IAAI,CAAC,MAAMA,WAAW,mBAAmB,IAAI,MAAM,SAASA,SAAQ,EAAG,EACvE,OAAO,CAACA,WAAUA,UAAS,CAAC;AAC9B,MAAI,QAAQ,WAAW,GAAG;AACzB,UAAM,IAAI;AAAA,MACT,8BAA8B,QAAQ,MAAM;AAAA,IAC7C;AAAA,EACD;AACA,QAAM,QAAQ,QAAQ,CAAC;AACvB,SAAO;AAAA,IACN,GAAG;AAAA,IACH,OAAO;AAAA,MACN,GAAG,QAAQ,MAAM,MAAM,GAAG,KAAK;AAAA,MAC/B,GAAG,gBAAgB,kBAAkB;AAAA,MACrC,GAAG,QAAQ,MAAM,MAAM,QAAQ,CAAC;AAAA,IACjC;AAAA,EACD;AACD;AAEO,SAAS,wBAAwB,SAA8B;AACrE,MAAI,CAAC,SAAS,OAAO,KAAK,CAAC,MAAM,QAAQ,QAAQ,KAAK,GAAG;AACxD,UAAM,IAAI,6BAA6B,mDAAmD;AAAA,EAC3F;AACA,MAAI,QAAQ,MAAM,KAAK,CAAC,SAAS,SAAS,IAAI,KAAK,KAAK,SAAS,oBAAoB,GAAG;AACvF,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAAA,EACD;AACA,SAAO,EAAE,GAAG,SAAS,OAAO,CAAC,GAAG,QAAQ,OAAO,EAAE,MAAM,qBAAqB,CAAC,EAAE;AAChF;AAEO,SAAS,+BACf,SACA,YACa;AACb,QAAM,WAAW,aACd,wBAAwB,SAAS,WAAW,QAAQ,WAAW,kBAAkB,IACjF;AACH,SAAO,wBAAwB,QAAQ;AACxC;AAEO,SAAS,oBAAoB,SAAkB,QAAyB;AAC9E,SACC,SAAS,OAAO,KAChB,MAAM,QAAQ,QAAQ,KAAK,KAC3B,QAAQ,MAAM,KAAK,CAAC,SAAS,mBAAmB,IAAI,MAAM,MAAM;AAElE;;;AD1NO,IAAM,kBAAkB;AACxB,IAAM,qBAAqB;AAC3B,IAAM,2BAA2B;AACjC,IAAM,0BAA0B,IAAI,OAAO;AAClD,IAAM,uBAAuB,IAAI,OAAO;AACxC,IAAM,yBAAyB;AAe/B,SAASC,UAAS,OAAqC;AACtD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC3E;AAEA,SAAS,YAAY,OAAyB;AAC7C,MAAI,MAAM,QAAQ,KAAK,EAAG,QAAO,MAAM,IAAI,WAAW;AACtD,MAAI,CAACA,UAAS,KAAK,EAAG,QAAO;AAC7B,SAAO,OAAO;AAAA,IACb,OAAO,QAAQ,KAAK,EAClB,KAAK,CAAC,CAAC,IAAI,GAAG,CAAC,KAAK,MAAM,KAAK,cAAc,KAAK,CAAC,EACnD,IAAI,CAAC,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC;AAAA,EAClD;AACD;AAEA,SAAS,gBAAgB,OAAwB;AAChD,SAAO,OAAO,WAAW,KAAK,UAAU,KAAK,GAAG,MAAM;AACvD;AAEO,SAAS,mBAAmB,SAA+B;AACjE,SAAO,WAAW,QAAQ,EACxB,OAAO,KAAK,UAAU,YAAY,OAAO,CAAC,CAAC,EAC3C,OAAO,KAAK;AACf;AAEO,SAAS,iBAAiB,cAA8B;AAC9D,SAAO;AAAA,IACN,+BAA+B,YAAY;AAAA,IAC3C;AAAA,IACA;AAAA,EACD,EAAE,KAAK,GAAG;AACX;AAEO,SAAS,gBAAgB,cAA8B;AAC7D,SAAO;AAAA,IACN,gDAAgD,YAAY;AAAA,IAC5D;AAAA,IACA;AAAA,EACD,EAAE,KAAK,GAAG;AACX;AAEA,SAAS,cAAc,cAAsB,WAAiC;AAC7E,SAAO;AAAA,IACN,MAAM;AAAA,IACN,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,iBAAiB,YAAY,EAAE,CAAC;AAAA,IAChE;AAAA,EACD;AACD;AAEO,SAAS,uBAAuB,OAAoD;AAC1F,MAAI,CAACA,UAAS,KAAK,EAAG,QAAO;AAC7B,MACC,MAAM,SAAS,mBACf,MAAM,YAAY,sBAClB,OAAO,MAAM,iBAAiB,YAC9B,MAAM,aAAa,SAAS,KAC5B,OAAO,MAAM,aAAa,YAC1B,MAAM,SAAS,WAAW,KAC1B,MAAM,SAAS,SAAS,0BACxB,MAAM,QAAQ,4BACd,OAAO,MAAM,YAAY,YACzB,MAAM,aAAa,0BACnB,CAAC,MAAM,QAAQ,MAAM,kBAAkB,KACvC,CAAC,MAAM,QAAQ,MAAM,uBAAuB,KAC5C,OAAO,MAAM,cAAc,UAC1B;AACD,WAAO;AAAA,EACR;AACA,MACC,MAAM,mBAAmB,WAAW,KACpC,CAAC,MAAM,mBAAmB,MAAMA,SAAQ,KACxC,CAAC,MAAM,wBAAwB;AAAA,IAC9B,CAAC,gBAAgB,OAAO,gBAAgB,YAAY,iBAAiB,KAAK,WAAW;AAAA,EACtF,KACA,gBAAgB,MAAM,kBAAkB,IAAI,yBAC3C;AACD,WAAO;AAAA,EACR;AACA,QAAM,OAAO,MAAM,mBAAmB,GAAG,EAAE;AAC3C,MAAI;AACH,2BAAuB,IAAI;AAAA,EAC5B,QAAQ;AACP,WAAO;AAAA,EACR;AACA,SAAO,gBAAgB,KAAK;AAC7B;AAEO,SAAS,iBAAiB,SAKpB;AACZ,WAAS,QAAQ,QAAQ,SAAS,GAAG,SAAS,GAAG,SAAS;AACzD,UAAM,QAAQ,QAAQ,KAAK;AAC3B,QAAI,MAAM,SAAS,aAAc;AACjC,UAAM,UAAU,uBAAuB,MAAM,OAAO;AACpD,WAAO,UACJ,EAAE,OAAyD,QAAQ,IACnE;AAAA,EACJ;AACA,SAAO;AACR;AAEA,SAAS,yBAAyB,SAAuB,WAA4B;AACpF,SACC,QAAQ,SAAS,uBACjB,OAAO,SAAS,QAAQ,SAAS,KACjC,OAAO,SAAS,SAAS,KACzB,QAAQ,YAAY;AAEtB;AAEO,SAAS,yBACf,UACA,SACA,mBAC6B;AAC7B,QAAM,eAAe,SAAS;AAAA,IAC7B,CAAC,YAAY,QAAQ,SAAS,uBAAuB,QAAQ,YAAY;AAAA,EAC1E;AACA,MAAI,eAAe,EAAG,QAAO;AAC7B,QAAM,YAAY,SAAS,YAAY,EAAE;AACzC,MAAI,eAAe,eAAe;AAClC,MAAI,mBAAmB;AACvB,SAAO,mBAAmB,QAAQ,wBAAwB,QAAQ;AACjE,QAAI,gBAAgB,SAAS,OAAQ,QAAO;AAC5C,UAAM,UAAU,SAAS,YAAY;AACrC,QAAI,mBAAmB,OAAO,MAAM,QAAQ,wBAAwB,gBAAgB,GAAG;AACtF,sBAAgB;AAChB,0BAAoB;AACpB;AAAA,IACD;AACA,QAAI,yBAAyB,SAAS,SAAS,GAAG;AACjD,sBAAgB;AAChB;AAAA,IACD;AACA,WAAO;AAAA,EACR;AACA,SACC,eAAe,SAAS,UACxB,yBAAyB,SAAS,YAAY,GAAG,SAAS,GACzD;AACD,oBAAgB;AAAA,EACjB;AACA,SAAO;AAAA,IACN,GAAG,SAAS,MAAM,GAAG,YAAY;AAAA,IACjC,cAAc,QAAQ,cAAc,SAAS;AAAA,IAC7C,GAAG,SAAS,MAAM,YAAY;AAAA,EAC/B;AACD;AAEA,SAAS,QAAQ,MAA0B;AAC1C,MAAI,CAAC,MAAM,QAAQ,KAAK,OAAO,EAAG,QAAO;AACzC,SAAO,KAAK,QACV;AAAA,IAAQ,CAAC,SACTA,UAAS,IAAI,KAAK,OAAO,KAAK,SAAS,YAAY,KAAK,SAAS,eAC9D,CAAC,KAAK,IAAI,IACV,CAAC;AAAA,EACL,EACC,KAAK,IAAI;AACZ;AAEA,SAAS,SAAS,MAA2B;AAC5C,SACC,MAAM,QAAQ,KAAK,OAAO,KAC1B,KAAK,QAAQ,KAAK,CAAC,SAASA,UAAS,IAAI,KAAK,KAAK,SAAS,aAAa;AAE3E;AAEA,SAAS,iBAAiB,MAAkB,UAA0C;AACrF,MAAI,CAAC,MAAM,QAAQ,KAAK,OAAO,KAAK,YAAY,GAAI,QAAO;AAC3D,MAAI,YAAY,WAAW;AAC3B,QAAM,UAAU,CAAC,GAAG,KAAK,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC,SAAS;AAC7D,QACC,CAACA,UAAS,IAAI,KACd,KAAK,SAAS,gBACd,OAAO,KAAK,SAAS,YACrB,aAAa,GACZ;AACD,aAAO,CAAC;AAAA,IACT;AACA,UAAM,OAAO,KAAK,KAAK,MAAM,CAAC,SAAS;AACvC,iBAAa,KAAK;AAClB,WAAO,CAAC,EAAE,GAAG,MAAM,MAAM;AAAA,EAAgB,IAAI,GAAG,CAAC;AAAA,EAClD,CAAC;AACD,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SAAO,EAAE,GAAG,MAAM,SAAS,QAAQ,QAAQ,EAAE;AAC9C;AAEO,SAAS,wBACf,OACA,gBACA,UAAyD,CAAC,GAC3C;AACf,QAAM,cAAc,QAAQ,eAAe;AAC3C,QAAM,aAAa,QAAQ,cAAc;AACzC,QAAM,SAAS,uBAAuB,cAAc;AACpD,MAAI,iBAAiB,aAAa,gBAAgB,MAAM;AACxD,MAAI,iBAAiB,cAAc;AACnC,MAAI,kBAAkB;AACrB,UAAM,IAAI,MAAM,2DAA2D;AAC5E,QAAM,sBAAoC,CAAC;AAC3C,QAAM,aAAa,MAAM;AAAA,IACxB,CAAC,SACAA,UAAS,IAAI,KAAK,KAAK,SAAS,UAAU,KAAK,SAAS;AAAA,EAC1D;AACA,WAAS,QAAQ,WAAW,SAAS,GAAG,SAAS,GAAG,SAAS;AAC5D,UAAM,YAAY,WAAW,KAAK;AAClC,UAAM,QAAQ,gBAAgB,SAAS;AACvC,QAAI,SAAS,SAAS,KAAK,QAAQ,qBAAsB;AACzD,UAAM,OAAO,QAAQ,SAAS;AAC9B,QAAI,WAAW;AACf,QAAI,KAAK,SAAS,gBAAgB;AACjC,UAAI,SAAS,SAAS,EAAG;AACzB,YAAM,YAAY,iBAAiB,WAAW,cAAc;AAC5D,UAAI,CAAC,UAAW;AAChB,iBAAW;AAAA,IACZ;AACA,QAAI,gBAAgB,QAAQ,IAAI,gBAAgB;AAC/C,UAAI,SAAS,QAAQ,EAAG;AACxB,YAAM,kBAAkB,KAAK,IAAI,GAAG,iBAAiB,GAAG;AACxD,YAAM,YAAY,iBAAiB,UAAU,KAAK,IAAI,gBAAgB,eAAe,CAAC;AACtF,UAAI,CAAC,aAAa,gBAAgB,SAAS,IAAI,eAAgB;AAC/D,iBAAW;AAAA,IACZ;AACA,wBAAoB,KAAK,gBAAgB,QAAQ,CAAC;AAClD,sBAAkB,gBAAgB,QAAQ;AAC1C,sBAAkB,KAAK,IAAI,gBAAgB,QAAQ,QAAQ,EAAE,MAAM;AACnE,QAAI,kBAAkB,OAAO,kBAAkB,GAAI;AAAA,EACpD;AACA,SAAO,CAAC,GAAG,oBAAoB,QAAQ,GAAG,MAAM;AACjD;AAEO,SAAS,wBAAwB,OAOb;AAC1B,QAAM,UAAkC;AAAA,IACvC,MAAM;AAAA,IACN,SAAS;AAAA,IACT,cAAc,MAAM,gBAAgB,WAAW;AAAA,IAC/C,UAAU,MAAM;AAAA,IAChB,KAAK;AAAA,IACL,SAAS,MAAM;AAAA,IACf,UAAU;AAAA,IACV,oBAAoB,gBAAgB,MAAM,kBAAkB;AAAA,IAC5D,yBAAyB,MAAM,aAAa,IAAI,kBAAkB;AAAA,IAClE,WAAW,MAAM,cAAa,oBAAI,KAAK,GAAE,YAAY;AAAA,EACtD;AACA,QAAM,SAAS,uBAAuB,OAAO;AAC7C,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,qCAAqC;AAClE,SAAO;AACR;;;AEvPA,IAAM,cAAqB;AAAA,EAC1B,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,YAAY;AAAA,EACZ,aAAa;AAAA,EACb,MAAM,EAAE,OAAO,GAAG,QAAQ,GAAG,WAAW,GAAG,YAAY,GAAG,OAAO,EAAE;AACpE;AAEA,SAASC,UAAS,OAAqC;AACtD,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC3E;AAEA,SAAS,aAA2B;AACnC,SAAO,IAAI,aAAa,sBAAsB,YAAY;AAC3D;AAEA,eAAsB,wBACrB,SACoC;AACpC,MAAI,QAAQ,OAAO,QAAS,OAAM,WAAW;AAC7C,MAAI;AACJ,QAAM,cAEA,CAAC;AACP,QAAM,YAAY,QAAQ,SAAS,WAAW;AAC9C,QAAM,iBAA0C,OAAO,OAAO,SAAS;AACtE,UAAM,WAAW,MAAM,UAAU,OAAO,IAAI;AAC5C,QAAI,CAAC,SAAS,MAAM,CAAC,SAAS,KAAM,QAAO;AAC3C,UAAM,CAAC,cAAc,cAAc,IAAI,SAAS,KAAK,IAAI;AACzD,UAAMC,cAAa,qBAAqB,gBAAgB,EAAE,QAAQ,QAAQ,OAAO,CAAC,EAAE;AAAA,MACnF,CAAC,WAAW,EAAE,IAAI,MAAe,MAAM;AAAA,MACvC,CAAC,WAAoB,EAAE,IAAI,OAAgB,MAAM;AAAA,IAClD;AACA,gBAAY,KAAKA,WAAU;AAC3B,WAAO,IAAI,SAAS,cAAc;AAAA,MACjC,QAAQ,SAAS;AAAA,MACjB,YAAY,SAAS;AAAA,MACrB,SAAS,SAAS;AAAA,IACnB,CAAC;AAAA,EACF;AAEA,QAAM,SAAS,QAAQ,SAAS,OAAO,QAAQ,OAAO,QAAQ,SAAS;AAAA,IACtE,QAAQ,QAAQ;AAAA,IAChB,SAAS,QAAQ;AAAA,IACjB,KAAK,QAAQ;AAAA,IACb,QAAQ,QAAQ;AAAA,IAChB,WAAW;AAAA,IACX,gBAAgB;AAAA,IAChB,WAAW,QAAQ,oBAAoB,IAAI,KAAK;AAAA,IAChD,YAAY,QAAQ,cAAc;AAAA,IAClC,OAAO;AAAA,IACP,WAAW,CAAC,YAAY;AACvB,YAAM,WAAW,+BAA+B,SAAS,QAAQ,eAAe;AAChF,UAAI,CAAC,MAAM,QAAQ,SAAS,KAAK,KAAK,CAAC,SAAS,MAAM,MAAMD,SAAQ,GAAG;AACtE,cAAM,IAAI;AAAA,UACT;AAAA,QACD;AAAA,MACD;AACA,kBAAY,gBAAgB,SAAS,MAAM,MAAM,GAAG,EAAE,CAAC;AACvD,aAAO;AAAA,IACR;AAAA,EACD,CAAC;AAED,MAAI,QAAQ;AACZ,mBAAiB,SAAS,QAAQ;AACjC,QAAI,QAAQ,OAAO,QAAS,OAAM,WAAW;AAC7C,QAAI,MAAM,SAAS,SAAS;AAC3B,YAAM,IAAI,MAAM,MAAM,MAAM,gBAAgB,wCAAwC;AAAA,IACrF;AACA,QAAI,MAAM,SAAS,OAAQ,SAAQ,MAAM,QAAQ;AAAA,EAClD;AACA,MAAI,QAAQ,OAAO,QAAS,OAAM,WAAW;AAC7C,MAAI,CAAC;AACJ,UAAM,IAAI,6BAA6B,2CAA2C;AACnF,MAAI,YAAY,WAAW,GAAG;AAC7B,UAAM,IAAI,6BAA6B,8CAA8C;AAAA,EACtF;AACA,QAAM,aAAa,MAAM,YAAY,GAAG,EAAE;AAC1C,MAAI,QAAQ,OAAO,QAAS,OAAM,WAAW;AAC7C,MAAI,CAAC,YAAY,GAAI,OAAM,YAAY,SAAS,IAAI,MAAM,qCAAqC;AAC/F,SAAO,EAAE,MAAM,WAAW,MAAM,MAAM,aAAa,WAAW,MAAM;AACrE;;;ACpHA,SAAS,cAAAE,mBAAkB;AAC3B,SAAS,iBAAiB;AAC1B,SAAS,OAAO,MAAM,QAAQ,IAAI,iBAAiB;AACnD,SAAS,UAAU,SAAS,YAAY;AACxC,SAAS,mBAAmB;AAErB,IAAM,8BAA8B;AACpC,IAAM,qBAAqB,KAAK;AAUhC,IAAM,iCAAiE,OAAO,OAAO;AAAA,EAC3F,SAAS;AAAA,EACT,kBAAkB;AAAA,EAClB,YAAY;AAAA,EACZ,wBAAwB;AAAA,EACxB,kBAAkB;AACnB,CAAC;AAED,IAAM,SAAS,OAAO,OAAO;AAAA,EAC5B,kBAAkB,EAAE,SAAS,KAAQ,SAAS,IAAQ;AAAA,EACtD,YAAY,EAAE,SAAS,GAAG,SAAS,EAAE;AAAA,EACrC,wBAAwB,EAAE,SAAS,KAAO,SAAS,MAAQ;AAC5D,CAAC;AAoBD,SAAS,SAAS,OAAkD;AACnE,SAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAC3E;AAEA,SAAS,aAAa,OAAgB,SAAiB,SAAkC;AACxF,SACC,OAAO,UAAU,YAAY,OAAO,cAAc,KAAK,KAAK,SAAS,WAAW,SAAS;AAE3F;AAEO,SAAS,8BAA8B,OAAkD;AAC/F,MAAI,CAAC,SAAS,KAAK,EAAG,QAAO;AAC7B,MAAI,OAAO,OAAO,OAAO,SAAS,KAAK,OAAO,MAAM,YAAY,UAAW,QAAO;AAClF,MAAI,OAAO,OAAO,OAAO,kBAAkB,KAAK,OAAO,MAAM,qBAAqB,WAAW;AAC5F,WAAO;AAAA,EACR;AACA,aAAW,CAAC,OAAO,MAAM,KAAK,OAAO,QAAQ,MAAM,GAEhD;AACF,QACC,OAAO,OAAO,OAAO,KAAK,KAC1B,CAAC,aAAa,MAAM,KAAK,GAAG,OAAO,SAAS,OAAO,OAAO,GACzD;AACD,aAAO;AAAA,IACR;AAAA,EACD;AACA,SAAO;AAAA,IACN,SACC,OAAO,MAAM,YAAY,YAAY,MAAM,UAAU,+BAA+B;AAAA,IACrF,kBACC,OAAO,MAAM,qBAAqB,WAC/B,MAAM,mBACN,+BAA+B;AAAA,IACnC,YACC,OAAO,MAAM,eAAe,WACzB,MAAM,aACN,+BAA+B;AAAA,IACnC,wBACC,OAAO,MAAM,2BAA2B,WACrC,MAAM,yBACN,+BAA+B;AAAA,IACnC,kBACC,OAAO,MAAM,qBAAqB,YAC/B,MAAM,mBACN,+BAA+B;AAAA,EACpC;AACD;AAEO,SAAS,2BAAmC;AAClD,SAAO,KAAK,YAAY,GAAG,2BAA2B;AACvD;AAEA,SAAS,QAAQ,QAA4B;AAC5C,MAAI,QAAQ,QAAS,OAAM,IAAI,aAAa,8BAA8B,YAAY;AACvF;AAEA,eAAsB,yBACrB,OAAO,yBAAyB,GAChC,QACqC;AACrC,UAAQ,MAAM;AACd,MAAI;AACH,UAAM,SAAS,MAAM,KAAK,MAAM,UAAU,WAAW,UAAU,UAAU;AACzE,QAAI;AACJ,QAAI;AACH,YAAM,QAAQ,MAAM,OAAO,KAAK;AAChC,cAAQ,MAAM;AACd,UAAI,CAAC,MAAM,OAAO,EAAG,OAAM,IAAI,MAAM,qCAAqC;AAC1E,UAAI,MAAM,OAAO,mBAAoB,OAAM,IAAI,MAAM,8BAA8B;AACnF,aAAO,MAAM,OAAO,SAAS,MAAM;AAAA,IACpC,UAAE;AACD,YAAM,OAAO,MAAM;AAAA,IACpB;AACA,YAAQ,MAAM;AACd,UAAM,WAAW,KAAK,MAAM,IAAI;AAChC,UAAM,WAAW,8BAA8B,QAAQ;AACvD,QAAI,CAAC,YAAY,CAAC,SAAS,QAAQ,EAAG,OAAM,IAAI,MAAM,kCAAkC;AACxF,WAAO,EAAE,MAAM,UAAU,MAAM,UAAU,SAAS;AAAA,EACnD,SAAS,OAAO;AACf,QAAI,QAAQ,QAAS,OAAM;AAC3B,QAAI,YAAY,KAAK,KAAK,MAAM,SAAS,UAAU;AAClD,aAAO;AAAA,QACN,MAAM;AAAA,QACN;AAAA,QACA,UAAU,EAAE,GAAG,+BAA+B;AAAA,QAC9C,UAAU,CAAC;AAAA,MACZ;AAAA,IACD;AACA,WAAO;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA,UAAU,EAAE,GAAG,+BAA+B;AAAA,MAC9C,OACC,YAAY,KAAK,KAAK,MAAM,SAAS,UAClC,oCACA,iBAAiB,QAChB,MAAM,UACN,OAAO,KAAK;AAAA,IAClB;AAAA,EACD;AACD;AAEA,eAAe,UACd,MACA,OACA,QACqC;AACrC,QAAM,SAAS,MAAM,yBAAyB,MAAM,MAAM;AAC1D,MAAI,OAAO,SAAS,WAAW;AAC9B,UAAM,IAAI;AAAA,MACT;AAAA,IACD;AAAA,EACD;AACA,QAAM,WAAW,EAAE,GAAG,OAAO,UAAU,GAAG,MAAM;AAChD,QAAM,WAAW,8BAA8B,QAAQ;AACvD,MAAI,CAAC,SAAU,OAAM,IAAI,MAAM,oDAAoD;AACnF,QAAM,gBAAgB,KAAK,QAAQ,IAAI,GAAG,IAAI,SAAS,IAAI,CAAC,IAAIA,YAAW,CAAC,MAAM;AAClF,QAAM,MAAM,QAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC9C,UAAQ,MAAM;AACd,MAAI;AACH,UAAM,UAAU,eAAe,GAAG,KAAK,UAAU,UAAU,MAAM,CAAC,CAAC;AAAA,GAAM;AAAA,MACxE,UAAU;AAAA,MACV,MAAM;AAAA,MACN,MAAM;AAAA,IACP,CAAC;AACD,YAAQ,MAAM;AACd,UAAM,UAAU,MAAM,yBAAyB,MAAM,MAAM;AAC3D,QACC,QAAQ,SAAS,aACjB,QAAQ,SAAS,OAAO,QACxB,KAAK,UAAU,QAAQ,QAAQ,MAAM,KAAK,UAAU,OAAO,QAAQ,GAClE;AACD,YAAM,IAAI,MAAM,uEAAuE;AAAA,IACxF;AACA,UAAM,OAAO,eAAe,IAAI;AAAA,EACjC,UAAE;AACD,UAAM,GAAG,eAAe,EAAE,OAAO,KAAK,CAAC,EAAE,MAAM,MAAM,MAAS;AAAA,EAC/D;AACA,SAAO,EAAE,MAAM,UAAU,MAAM,UAAU,SAAS;AACnD;AAEO,SAAS,kCACf,OAAO,yBAAyB,GACF;AAC9B,MAAI,QAAmC;AAAA,IACtC,MAAM;AAAA,IACN;AAAA,IACA,UAAU,EAAE,GAAG,+BAA+B;AAAA,IAC9C,UAAU,CAAC;AAAA,EACZ;AACA,MAAI,QAAQ,QAAQ,QAAQ;AAC5B,QAAM,UAAU,CAAI,cAA4C;AAC/D,UAAM,SAAS,MAAM,KAAK,WAAW,SAAS;AAC9C,YAAQ,OAAO;AAAA,MACd,MAAM;AAAA,MACN,MAAM;AAAA,IACP;AACA,WAAO;AAAA,EACR;AACA,SAAO;AAAA,IACN,KAAK,MAAM,gBAAgB,KAAK;AAAA,IAChC,QAAQ,CAAC,WACR,QAAQ,YAAY;AACnB,cAAQ,MAAM,yBAAyB,MAAM,MAAM;AACnD,aAAO,gBAAgB,KAAK;AAAA,IAC7B,CAAC;AAAA,IACF,QAAQ,CAAC,OAAO,WACf,QAAQ,YAAY;AACnB,cAAQ,MAAM,UAAU,MAAM,OAAO,MAAM;AAC3C,aAAO,gBAAgB,KAAK;AAAA,IAC7B,CAAC;AAAA,IACF,OAAO,MAAM;AAAA,EACd;AACD;AAEA,SAAS,YAAY,OAAgD;AACpE,SAAO,iBAAiB,SAAS,UAAU;AAC5C;;;AJpMA,IAAM,aAAa;AAEnB,SAAS,iBAAiB,KAAuB;AAChD,SAAO,iBAAiB,IAAI,eAAe,UAAU,CAAC;AACvD;AAEA,SAAS,uBACR,SACA,OAC2C;AAC3C,SAAO,6BAA6B,KAAK,KAAK,MAAM,OAAO,QAAQ;AACpE;AAEA,SAAS,aAAa,OAAkD;AACvE,QAAM,SAAS,MAAM,cAAc,GAAG,EAAE,GAAG,MAAM;AACjD,QAAM,iBAAiB,oBAAoB,MAAM,eAAe,MAAM;AACtE,QAAM,YAAY,eAAe;AAAA,IAChC,CAAC,UAAU,MAAM,OAAO,MAAM,YAAY;AAAA,EAC3C;AACA,MAAI,YAAY,GAAG;AAClB,UAAM,IAAI,MAAM,8DAA8D;AAAA,EAC/E;AACA,SAAO,eAAe,MAAM,SAAS,EAAE,QAAQ,6BAA6B;AAC7E;AAEA,SAAS,YAAY,IAA0B;AAC9C,QAAM,UAAU,IAAI,IAAI,GAAG,eAAe,CAAC;AAC3C,SAAO,GACL,YAAY,EACZ,OAAO,CAAC,SAAS,QAAQ,IAAI,KAAK,IAAI,CAAC,EACvC,IAAI,CAAC,UAAU;AAAA,IACf,MAAM,KAAK;AAAA,IACX,aAAa,KAAK;AAAA,IAClB,YAAY,KAAK;AAAA,EAClB,EAAE;AACJ;AAEA,SAAS,yBACR,OACA,OAC+D;AAC/D,QAAM,SAAS,MAAM,cAAc,GAAG,EAAE,GAAG,MAAM;AACjD,QAAM,UAAU,oBAAoB,MAAM,eAAe,MAAM;AAC/D,QAAM,QAAQ,iBAAiB,MAAM,aAAa;AAClD,MAAI,CAAC,MAAO,QAAO,EAAE,UAAU,QAAQ,SAAS;AAChD,MAAI,MAAM,QAAQ,YAAY,MAAM,IAAI;AACvC,UAAM,IAAI,MAAM,iEAAiE;AAAA,EAClF;AACA,QAAM,YAAY,yBAAyB,QAAQ,UAAU,MAAM,SAAS,MAAM,MAAM,OAAO;AAC/F,MAAI,CAAC,WAAW;AACf,UAAM,IAAI,MAAM,8DAA8D;AAAA,EAC/E;AACA,SAAO,EAAE,UAAU,WAAW,OAAO,MAAM,QAAQ;AACpD;AAEA,SAAS,cACR,KACA,OACA,UACO;AACP,MAAI,CAAC,IAAI,SAAS,CAAC,SAAS,iBAAkB;AAC9C,QAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AACrE,MAAI,GAAG,OAAO,wDAAwD,OAAO,IAAI,SAAS;AAC3F;AAEA,SAAS,kBAAkB,KAAuB,WAAmB,QAA8B;AAClG,SAAO,CAAC,OAAO,WAAW,IAAI,eAAe,aAAa,MAAM;AACjE;AAEA,eAAe,gBACd,IACA,OACA,KACA,UACA,OACC;AACD,QAAM,QAAQ,IAAI;AAClB,MAAI,CAAC,SAAS,WAAW,CAAC,6BAA6B,KAAK,EAAG,QAAO;AACtE,QAAM,YAAY,IAAI,eAAe,aAAa;AAClD,MAAI,GAAG,UAAU,YAAY,+BAA0B;AACvD,MAAI;AACH,UAAM,OAAO,MAAM,IAAI,cAAc,oBAAoB,KAAK;AAC9D,QAAI,CAAC,kBAAkB,KAAK,WAAW,MAAM,MAAM,EAAG,QAAO,EAAE,QAAQ,KAAK;AAC5E,QAAI,CAAC,KAAK,GAAI,OAAM,IAAI,MAAM,KAAK,KAAK;AACxC,UAAM,WAAW,IAAI,cAAc,YAAY,MAAM,QAAQ;AAC7D,QAAI,CAAC,SAAU,OAAM,IAAI,MAAM,oDAAoD;AACnF,UAAM,UAAU,yBAAyB,OAAO,KAAK;AACrD,UAAM,UAAmB;AAAA,MACxB,cAAc,IAAI,gBAAgB;AAAA,MAClC,UAAU,aAAa,QAAQ,QAAQ;AAAA,MACvC,OAAO,YAAY,EAAE;AAAA,IACtB;AACA,UAAM,WAAW,MAAM,wBAAwB;AAAA,MAC9C;AAAA,MACA;AAAA,MACA;AAAA,MACA,QAAQ,KAAK;AAAA,MACb,SAAS,KAAK;AAAA,MACd,KAAK,KAAK;AAAA,MACV,QAAQ,MAAM;AAAA,MACd,iBAAiB,QAAQ,QACtB;AAAA,QACA,QAAQ,iBAAiB,QAAQ,MAAM,YAAY;AAAA,QACnD,oBAAoB,QAAQ,MAAM;AAAA,MACnC,IACC;AAAA,MACH,kBAAkB,SAAS;AAAA,MAC3B,YAAY,SAAS;AAAA,MACrB;AAAA,IACD,CAAC;AACD,QAAI,CAAC,kBAAkB,KAAK,WAAW,MAAM,MAAM,EAAG,QAAO,EAAE,QAAQ,KAAK;AAC5E,UAAM,qBAAqB,wBAAwB,SAAS,aAAa,SAAS,MAAM;AAAA,MACvF,aAAa,SAAS;AAAA,IACvB,CAAC;AACD,UAAM,UAAU,wBAAwB;AAAA,MACvC,UAAU,MAAM;AAAA,MAChB,SAAS,MAAM;AAAA,MACf;AAAA,MACA,cAAc,aAAa,KAAK;AAAA,IACjC,CAAC;AACD,WAAO;AAAA,MACN,YAAY;AAAA,QACX,SAAS,gBAAgB,QAAQ,YAAY;AAAA,QAC7C,kBAAkB,MAAM,YAAY;AAAA,QACpC,cAAc,MAAM,YAAY;AAAA,QAChC,OAAO,SAAS;AAAA,QAChB;AAAA,MACD;AAAA,IACD;AAAA,EACD,SAAS,OAAO;AACf,QAAI,MAAM,OAAO,WAAW,IAAI,eAAe,aAAa,MAAM,WAAW;AAC5E,aAAO,EAAE,QAAQ,KAAK;AAAA,IACvB;AACA,kBAAc,KAAK,OAAO,QAAQ;AAClC,WAAO;AAAA,EACR,UAAE;AACD,QAAI,IAAI,eAAe,aAAa,MAAM,UAAW,KAAI,GAAG,UAAU,YAAY,MAAS;AAAA,EAC5F;AACD;AAEO,SAAS,4BACf,UAA8F,CAAC,GAClE;AAC7B,SAAO,CAAC,OAAO;AACd,UAAM,mBAAmB,oBAAI,IAAY;AACzC,UAAM,kBAAkB,QAAQ,mBAAmB,kCAAkC;AACrF,QAAI,oBAAoB,IAAI,gBAAgB;AAC5C,QAAI,aAAa;AAEjB,OAAG,gBAAgB,iBAAiB;AAAA,MACnC,aAAa;AAAA,MACb,SAAS,OAAO,OAAO,QAAQ;AAC9B,cAAM,kBAAkB;AACxB,cAAM,aAAa;AACnB,cAAM,EAAE,qBAAqB,IAAI,MAAM,OAAO,oCAAoB;AAClE,YAAI,oBAAoB,cAAc,WAAW,OAAO,QAAS;AACjE,cAAM,qBAAqB,iBAAiB,KAAK;AAAA,UAChD,QAAQ,WAAW;AAAA,UACnB,WAAW,MAAM,oBAAoB,cAAc,CAAC,WAAW,OAAO;AAAA,QACvE,CAAC;AAAA,MACF;AAAA,IACD,CAAC;AAED,OAAG,GAAG,iBAAiB,OAAO,QAAQ,QAAQ;AAC7C,wBAAkB,MAAM;AACxB,0BAAoB,IAAI,gBAAgB;AACxC,oBAAc;AACd,YAAM,kBAAkB;AACxB,YAAM,YAAY,IAAI,eAAe,aAAa;AAClD,uBAAiB,MAAM;AACvB,UAAI;AACJ,UAAI;AACH,gBAAQ,MAAM,gBAAgB,OAAO,kBAAkB,MAAM;AAAA,MAC9D,SAAS,OAAO;AACf,YAAI,kBAAkB,OAAO,WAAW,oBAAoB,WAAY;AACxE,YAAI,IAAI,OAAO;AACd,cAAI,GAAG;AAAA,YACN,yDAAyD,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA,YAC/G;AAAA,UACD;AAAA,QACD;AACA;AAAA,MACD;AACA,UACC,kBAAkB,OAAO,WACzB,oBAAoB,cACpB,IAAI,eAAe,aAAa,MAAM,WACrC;AACD;AAAA,MACD;AACA,UAAI,IAAI,SAAS,MAAM,SAAS,WAAW;AAC1C,YAAI,GAAG;AAAA,UACN,yEAAyE,MAAM,KAAK;AAAA,UACpF;AAAA,QACD;AAAA,MACD;AAAA,IACD,CAAC;AAED,OAAG;AAAA,MAAG;AAAA,MAA0B,CAAC,OAAO,QACvC,gBAAgB,IAAI,OAAO,KAAK,gBAAgB,IAAI,EAAE,UAAU,QAAQ,KAAK;AAAA,IAC9E;AAEA,OAAG,GAAG,WAAW,CAAC,OAAO,QAAQ;AAChC,UAAI,CAAC,gBAAgB,IAAI,EAAE,SAAS,QAAS,QAAO;AACpD,YAAM,aAAa,iBAAiB,GAAG;AACvC,UAAI,CAAC,cAAc,CAAC,uBAAuB,WAAW,SAAS,IAAI,KAAK,EAAG,QAAO;AAClF,YAAM,WAAW;AAAA,QAChB,MAAM;AAAA,QACN,WAAW;AAAA,QACX,WAAW,MAAM;AAAA,MAClB;AACA,aAAO,WAAW,EAAE,SAAS,IAAI;AAAA,IAClC,CAAC;AAED,OAAG,GAAG,2BAA2B,CAAC,OAAO,QAAQ;AAChD,UAAI,CAAC,gBAAgB,IAAI,EAAE,SAAS,QAAS,QAAO;AACpD,YAAM,aAAa,iBAAiB,GAAG;AACvC,UAAI,CAAC,cAAc,CAAC,uBAAuB,WAAW,SAAS,IAAI,KAAK,EAAG,QAAO;AAClF,YAAM,SAAS,iBAAiB,WAAW,QAAQ,YAAY;AAC/D,UAAI,CAAC,oBAAoB,MAAM,SAAS,MAAM,EAAG,QAAO;AACxD,aAAO,wBAAwB,MAAM,SAAS,QAAQ,WAAW,QAAQ,kBAAkB;AAAA,IAC5F,CAAC;AAED,OAAG,GAAG,gBAAgB,CAAC,OAAO,QAAQ;AACrC,UAAI,CAAC,gBAAgB,IAAI,EAAE,SAAS,QAAS;AAC7C,YAAM,aAAa,iBAAiB,GAAG;AACvC,UAAI,CAAC,cAAc,uBAAuB,WAAW,SAAS,MAAM,KAAK,EAAG;AAC5E,YAAM,MAAM,GAAG,IAAI,eAAe,aAAa,CAAC,IAAI,MAAM,MAAM,QAAQ,IAAI,MAAM,MAAM,EAAE;AAC1F,UAAI,iBAAiB,IAAI,GAAG,EAAG;AAC/B,uBAAiB,IAAI,GAAG;AACxB,UAAI,IAAI,OAAO;AACd,YAAI,GAAG;AAAA,UACN;AAAA,UACA;AAAA,QACD;AAAA,MACD;AAAA,IACD,CAAC;AAED,OAAG,GAAG,oBAAoB,OAAO,QAAQ,QAAQ;AAChD,oBAAc;AACd,wBAAkB,MAAM;AACxB,uBAAiB,MAAM;AACvB,UAAI,GAAG,UAAU,YAAY,MAAS;AACtC,YAAM,gBAAgB,MAAM;AAAA,IAC7B,CAAC;AAAA,EACF;AACD;AAEA,IAAO,wBAAQ,4BAA4B;",
4
+ "sourcesContent": ["import type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { Api, Context, Model, Tool } from \"@earendil-works/pi-ai\";\nimport {\n\tbuildContextEntries,\n\tbuildSessionContext,\n\tconvertToLlm,\n\ttype ExtensionAPI,\n\ttype ExtensionContext,\n\ttype SessionBeforeCompactEvent,\n\tsessionEntryToContextMessages,\n} from \"@earendil-works/pi-coding-agent\";\nimport {\n\tbuildReplacementHistory,\n\ttype CodexCheckpointDetails,\n\tcheckpointMarker,\n\tcreateCheckpointDetails,\n\tfallbackSummary,\n\tlatestCheckpoint,\n\tprojectCheckpointContext,\n} from \"./checkpoint.js\";\nimport { usesCodexResponsesApi } from \"./model-api.js\";\nimport { hasCheckpointMarker, rewriteCheckpointMarker } from \"./protocol.js\";\nimport { requestRemoteCompaction } from \"./remote.js\";\nimport {\n\ttype CodexCompactSettings,\n\ttype CodexCompactSettingsRuntime,\n\ttype CodexCompactSettingsState,\n\tcreateCodexCompactSettingsRuntime,\n} from \"./settings.js\";\n\nconst STATUS_KEY = \"codex-compact\";\n\nfunction activeCheckpoint(ctx: ExtensionContext) {\n\treturn latestCheckpoint(ctx.sessionManager.getBranch());\n}\n\nfunction isCheckpointCompatible(\n\tdetails: CodexCheckpointDetails,\n\tmodel: Model<Api> | undefined,\n): model is Model<\"openai-codex-responses\"> {\n\treturn usesCodexResponsesApi(model) && model.id === details.modelId;\n}\n\nfunction keptMessages(event: SessionBeforeCompactEvent): AgentMessage[] {\n\tconst leafId = event.branchEntries.at(-1)?.id ?? null;\n\tconst contextEntries = buildContextEntries(event.branchEntries, leafId);\n\tconst keptIndex = contextEntries.findIndex(\n\t\t(entry) => entry.id === event.preparation.firstKeptEntryId,\n\t);\n\tif (keptIndex < 0) {\n\t\tthrow new Error(\"Pi compaction cut point is not present in the active context\");\n\t}\n\treturn contextEntries.slice(keptIndex).flatMap(sessionEntryToContextMessages);\n}\n\nfunction activeTools(pi: ExtensionAPI): Tool[] {\n\tconst enabled = new Set(pi.getActiveTools());\n\treturn pi\n\t\t.getAllTools()\n\t\t.filter((tool) => enabled.has(tool.name))\n\t\t.map((tool) => ({\n\t\t\tname: tool.name,\n\t\t\tdescription: tool.description,\n\t\t\tparameters: tool.parameters,\n\t\t}));\n}\n\nfunction projectedCurrentMessages(\n\tevent: SessionBeforeCompactEvent,\n\tmodel: Model<\"openai-codex-responses\">,\n): { messages: AgentMessage[]; prior?: CodexCheckpointDetails } {\n\tconst leafId = event.branchEntries.at(-1)?.id ?? null;\n\tconst session = buildSessionContext(event.branchEntries, leafId);\n\tconst prior = latestCheckpoint(event.branchEntries);\n\tif (!prior) return { messages: session.messages };\n\tif (prior.details.modelId !== model.id) {\n\t\tthrow new Error(\"The active opaque checkpoint belongs to a different Codex model\");\n\t}\n\tconst projected = projectCheckpointContext(session.messages, prior.details, prior.entry.summary);\n\tif (!projected) {\n\t\tthrow new Error(\"The previous opaque checkpoint could not be projected safely\");\n\t}\n\treturn { messages: projected, prior: prior.details };\n}\n\nfunction notifyFailure(\n\tctx: ExtensionContext,\n\terror: unknown,\n\tsettings: CodexCompactSettings,\n): void {\n\tif (!ctx.hasUI || !settings.notifyOnFallback) return;\n\tconst message = error instanceof Error ? error.message : String(error);\n\tctx.ui.notify(`Codex remote compaction failed; using Pi compaction. ${message}`, \"warning\");\n}\n\nfunction sessionStillOwned(ctx: ExtensionContext, sessionId: string, signal: AbortSignal): boolean {\n\treturn !signal.aborted && ctx.sessionManager.getSessionId() === sessionId;\n}\n\nasync function compactRemotely(\n\tpi: ExtensionAPI,\n\tevent: SessionBeforeCompactEvent,\n\tctx: ExtensionContext,\n\tsettings: CodexCompactSettings,\n\tfetch?: typeof globalThis.fetch,\n) {\n\tconst model = ctx.model;\n\tif (!settings.enabled || !usesCodexResponsesApi(model)) return undefined;\n\tconst sessionId = ctx.sessionManager.getSessionId();\n\tctx.ui.setStatus(STATUS_KEY, \"Codex remote compaction\u2026\");\n\ttry {\n\t\tconst auth = await ctx.modelRegistry.getApiKeyAndHeaders(model);\n\t\tif (!sessionStillOwned(ctx, sessionId, event.signal)) return { cancel: true };\n\t\tif (!auth.ok) throw new Error(auth.error);\n\t\tconst provider = ctx.modelRegistry.getProvider(model.provider);\n\t\tif (!provider) throw new Error(\"The active Codex Responses provider is unavailable\");\n\t\tconst current = projectedCurrentMessages(event, model);\n\t\tconst context: Context = {\n\t\t\tsystemPrompt: ctx.getSystemPrompt(),\n\t\t\tmessages: convertToLlm(current.messages),\n\t\t\ttools: activeTools(pi),\n\t\t};\n\t\tconst response = await requestRemoteCompaction({\n\t\t\tprovider,\n\t\t\tmodel,\n\t\t\tcontext,\n\t\t\tapiKey: auth.apiKey,\n\t\t\theaders: auth.headers,\n\t\t\tenv: auth.env,\n\t\t\tsignal: event.signal,\n\t\t\tpriorCheckpoint: current.prior\n\t\t\t\t? {\n\t\t\t\t\t\tmarker: checkpointMarker(current.prior.checkpointId),\n\t\t\t\t\t\treplacementHistory: current.prior.replacementHistory,\n\t\t\t\t\t}\n\t\t\t\t: undefined,\n\t\t\trequestTimeoutMs: settings.requestTimeoutMs,\n\t\t\tmaxRetries: settings.maxRetries,\n\t\t\tfetch,\n\t\t});\n\t\tif (!sessionStillOwned(ctx, sessionId, event.signal)) return { cancel: true };\n\t\tconst replacementHistory = buildReplacementHistory(response.promptInput, response.item, {\n\t\t\ttokenBudget: settings.replacementTokenBudget,\n\t\t});\n\t\tconst details = createCheckpointDetails({\n\t\t\tprovider: model.provider,\n\t\t\tmodelId: model.id,\n\t\t\treplacementHistory,\n\t\t\tkeptMessages: keptMessages(event),\n\t\t});\n\t\treturn {\n\t\t\tcompaction: {\n\t\t\t\tsummary: fallbackSummary(details.checkpointId),\n\t\t\t\tfirstKeptEntryId: event.preparation.firstKeptEntryId,\n\t\t\t\ttokensBefore: event.preparation.tokensBefore,\n\t\t\t\tusage: response.usage,\n\t\t\t\tdetails,\n\t\t\t},\n\t\t};\n\t} catch (error) {\n\t\tif (event.signal.aborted || ctx.sessionManager.getSessionId() !== sessionId) {\n\t\t\treturn { cancel: true };\n\t\t}\n\t\tnotifyFailure(ctx, error, settings);\n\t\treturn undefined;\n\t} finally {\n\t\tif (ctx.sessionManager.getSessionId() === sessionId) ctx.ui.setStatus(STATUS_KEY, undefined);\n\t}\n}\n\nexport function createCodexCompactExtension(\n\toptions: { fetch?: typeof globalThis.fetch; settingsRuntime?: CodexCompactSettingsRuntime } = {},\n): (pi: ExtensionAPI) => void {\n\treturn (pi) => {\n\t\tconst providerWarnings = new Set<string>();\n\t\tconst settingsRuntime = options.settingsRuntime ?? createCodexCompactSettingsRuntime();\n\t\tlet sessionController = new AbortController();\n\t\tlet generation = 0;\n\n\t\tpi.registerCommand(\"codex-compact\", {\n\t\t\tdescription: \"Compact now or configure Codex Remote Compaction V2\",\n\t\t\thandler: async (_args, ctx) => {\n\t\t\t\tconst ownerGeneration = generation;\n\t\t\t\tconst controller = sessionController;\n\t\t\t\tconst { showCodexCompactMenu } = await import(\"./settings-menu.js\");\n\t\t\t\tif (ownerGeneration !== generation || controller.signal.aborted) return;\n\t\t\t\tawait showCodexCompactMenu(settingsRuntime, ctx, {\n\t\t\t\t\tsignal: controller.signal,\n\t\t\t\t\tisCurrent: () => ownerGeneration === generation && !controller.signal.aborted,\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\n\t\tpi.on(\"session_start\", async (_event, ctx) => {\n\t\t\tsessionController.abort();\n\t\t\tsessionController = new AbortController();\n\t\t\tgeneration += 1;\n\t\t\tconst ownerGeneration = generation;\n\t\t\tconst sessionId = ctx.sessionManager.getSessionId();\n\t\t\tproviderWarnings.clear();\n\t\t\tlet state: Readonly<CodexCompactSettingsState>;\n\t\t\ttry {\n\t\t\t\tstate = await settingsRuntime.reload(sessionController.signal);\n\t\t\t} catch (error) {\n\t\t\t\tif (sessionController.signal.aborted || ownerGeneration !== generation) return;\n\t\t\t\tif (ctx.hasUI) {\n\t\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\t`Could not load pi-codex-compact.json; using defaults. ${error instanceof Error ? error.message : String(error)}`,\n\t\t\t\t\t\t\"warning\",\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (\n\t\t\t\tsessionController.signal.aborted ||\n\t\t\t\townerGeneration !== generation ||\n\t\t\t\tctx.sessionManager.getSessionId() !== sessionId\n\t\t\t) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (ctx.hasUI && state.kind === \"invalid\") {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t`Invalid pi-codex-compact.json; using defaults without overwriting it. ${state.issue}`,\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"session_before_compact\", (event, ctx) =>\n\t\t\tcompactRemotely(pi, event, ctx, settingsRuntime.get().settings, options.fetch),\n\t\t);\n\n\t\tpi.on(\"context\", (event, ctx) => {\n\t\t\tif (!settingsRuntime.get().settings.enabled) return undefined;\n\t\t\tconst checkpoint = activeCheckpoint(ctx);\n\t\t\tif (!checkpoint || !isCheckpointCompatible(checkpoint.details, ctx.model)) return undefined;\n\t\t\tconst messages = projectCheckpointContext(\n\t\t\t\tevent.messages,\n\t\t\t\tcheckpoint.details,\n\t\t\t\tcheckpoint.entry.summary,\n\t\t\t);\n\t\t\treturn messages ? { messages } : undefined;\n\t\t});\n\n\t\tpi.on(\"before_provider_request\", (event, ctx) => {\n\t\t\tif (!settingsRuntime.get().settings.enabled) return undefined;\n\t\t\tconst checkpoint = activeCheckpoint(ctx);\n\t\t\tif (!checkpoint || !isCheckpointCompatible(checkpoint.details, ctx.model)) return undefined;\n\t\t\tconst marker = checkpointMarker(checkpoint.details.checkpointId);\n\t\t\tif (!hasCheckpointMarker(event.payload, marker)) return undefined;\n\t\t\treturn rewriteCheckpointMarker(event.payload, marker, checkpoint.details.replacementHistory);\n\t\t});\n\n\t\tpi.on(\"model_select\", (event, ctx) => {\n\t\t\tif (!settingsRuntime.get().settings.enabled) return;\n\t\t\tconst checkpoint = activeCheckpoint(ctx);\n\t\t\tif (!checkpoint || isCheckpointCompatible(checkpoint.details, event.model)) return;\n\t\t\tconst key = `${ctx.sessionManager.getSessionId()}:${event.model.provider}:${event.model.id}`;\n\t\t\tif (providerWarnings.has(key)) return;\n\t\t\tproviderWarnings.add(key);\n\t\t\tif (ctx.hasUI) {\n\t\t\t\tctx.ui.notify(\n\t\t\t\t\t\"The active Codex checkpoint cannot replay on this model; Pi will expose only its fallback marker and retained recent messages.\",\n\t\t\t\t\t\"warning\",\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\tpi.on(\"session_shutdown\", async (_event, ctx) => {\n\t\t\tgeneration += 1;\n\t\t\tsessionController.abort();\n\t\t\tproviderWarnings.clear();\n\t\t\tctx.ui.setStatus(STATUS_KEY, undefined);\n\t\t\tawait settingsRuntime.flush();\n\t\t});\n\t};\n}\n\nexport default createCodexCompactExtension();\n", "import { createHash, randomUUID } from \"node:crypto\";\nimport type { AgentMessage } from \"@earendil-works/pi-agent-core\";\nimport type { CompactionEntry, SessionEntry } from \"@earendil-works/pi-coding-agent\";\nimport { type JsonObject, validateCompactionItem } from \"./protocol.js\";\n\nexport const CHECKPOINT_KIND = \"pi-codex-remote-compaction\";\nexport const CHECKPOINT_VERSION = 1;\nexport const REPLACEMENT_TOKEN_BUDGET = 64_000;\nexport const REPLACEMENT_BYTE_BUDGET = 8 * 1024 * 1024;\nconst MAX_MEDIA_ITEM_BYTES = 2 * 1024 * 1024;\nconst MAX_PROVIDER_ID_LENGTH = 256;\n\nexport interface CodexCheckpointDetails {\n\tkind: typeof CHECKPOINT_KIND;\n\tversion: typeof CHECKPOINT_VERSION;\n\tcheckpointId: string;\n\tprovider: string;\n\tapi: \"openai-codex-responses\";\n\tmodelId: string;\n\tprotocol: \"remote-compaction-v2\";\n\treplacementHistory: JsonObject[];\n\tkeptMessageFingerprints: string[];\n\tcreatedAt: string;\n}\n\nfunction isObject(value: unknown): value is JsonObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction stableValue(value: unknown): unknown {\n\tif (Array.isArray(value)) return value.map(stableValue);\n\tif (!isObject(value)) return value;\n\treturn Object.fromEntries(\n\t\tObject.entries(value)\n\t\t\t.sort(([left], [right]) => left.localeCompare(right))\n\t\t\t.map(([key, child]) => [key, stableValue(child)]),\n\t);\n}\n\nfunction serializedBytes(value: unknown): number {\n\treturn Buffer.byteLength(JSON.stringify(value), \"utf8\");\n}\n\nexport function fingerprintMessage(message: AgentMessage): string {\n\treturn createHash(\"sha256\")\n\t\t.update(JSON.stringify(stableValue(message)))\n\t\t.digest(\"hex\");\n}\n\nexport function checkpointMarker(checkpointId: string): string {\n\treturn [\n\t\t`[PI_CODEX_REMOTE_CHECKPOINT:${checkpointId}]`,\n\t\t\"Opaque checkpoint injection failed. Do not infer missing history; tell the user to re-enable\",\n\t\t\"@narumitw/pi-codex-compact with a model using the openai-codex-responses API.\",\n\t].join(\" \");\n}\n\nexport function fallbackSummary(checkpointId: string): string {\n\treturn [\n\t\t`OpenAI Codex Remote Compaction V2 checkpoint ${checkpointId} stores the older history opaquely.`,\n\t\t\"Full replay requires @narumitw/pi-codex-compact and the same model through a compatible Codex Responses provider.\",\n\t\t\"Without them, only Pi's retained recent messages remain available.\",\n\t].join(\" \");\n}\n\nfunction markerMessage(checkpointId: string, timestamp: number): AgentMessage {\n\treturn {\n\t\trole: \"user\",\n\t\tcontent: [{ type: \"text\", text: checkpointMarker(checkpointId) }],\n\t\ttimestamp,\n\t};\n}\n\nexport function parseCheckpointDetails(value: unknown): CodexCheckpointDetails | undefined {\n\tif (!isObject(value)) return undefined;\n\tif (\n\t\tvalue.kind !== CHECKPOINT_KIND ||\n\t\tvalue.version !== CHECKPOINT_VERSION ||\n\t\ttypeof value.checkpointId !== \"string\" ||\n\t\tvalue.checkpointId.length < 8 ||\n\t\ttypeof value.provider !== \"string\" ||\n\t\tvalue.provider.length === 0 ||\n\t\tvalue.provider.length > MAX_PROVIDER_ID_LENGTH ||\n\t\tvalue.api !== \"openai-codex-responses\" ||\n\t\ttypeof value.modelId !== \"string\" ||\n\t\tvalue.protocol !== \"remote-compaction-v2\" ||\n\t\t!Array.isArray(value.replacementHistory) ||\n\t\t!Array.isArray(value.keptMessageFingerprints) ||\n\t\ttypeof value.createdAt !== \"string\"\n\t) {\n\t\treturn undefined;\n\t}\n\tif (\n\t\tvalue.replacementHistory.length === 0 ||\n\t\t!value.replacementHistory.every(isObject) ||\n\t\t!value.keptMessageFingerprints.every(\n\t\t\t(fingerprint) => typeof fingerprint === \"string\" && /^[a-f0-9]{64}$/.test(fingerprint),\n\t\t) ||\n\t\tserializedBytes(value.replacementHistory) > REPLACEMENT_BYTE_BUDGET\n\t) {\n\t\treturn undefined;\n\t}\n\tconst last = value.replacementHistory.at(-1);\n\ttry {\n\t\tvalidateCompactionItem(last);\n\t} catch {\n\t\treturn undefined;\n\t}\n\treturn structuredClone(value) as unknown as CodexCheckpointDetails;\n}\n\nexport function latestCheckpoint(entries: readonly SessionEntry[]):\n\t| {\n\t\t\tentry: CompactionEntry<CodexCheckpointDetails>;\n\t\t\tdetails: CodexCheckpointDetails;\n\t }\n\t| undefined {\n\tfor (let index = entries.length - 1; index >= 0; index--) {\n\t\tconst entry = entries[index];\n\t\tif (entry.type !== \"compaction\") continue;\n\t\tconst details = parseCheckpointDetails(entry.details);\n\t\treturn details\n\t\t\t? { entry: entry as CompactionEntry<CodexCheckpointDetails>, details }\n\t\t\t: undefined;\n\t}\n\treturn undefined;\n}\n\nfunction isOlderCompactionSummary(message: AgentMessage, timestamp: number): boolean {\n\treturn (\n\t\tmessage.role === \"compactionSummary\" &&\n\t\tNumber.isFinite(message.timestamp) &&\n\t\tNumber.isFinite(timestamp) &&\n\t\tmessage.timestamp < timestamp\n\t);\n}\n\nexport function projectCheckpointContext(\n\tmessages: readonly AgentMessage[],\n\tdetails: CodexCheckpointDetails,\n\tcheckpointSummary: string,\n): AgentMessage[] | undefined {\n\tconst summaryIndex = messages.findIndex(\n\t\t(message) => message.role === \"compactionSummary\" && message.summary === checkpointSummary,\n\t);\n\tif (summaryIndex < 0) return undefined;\n\tconst timestamp = messages[summaryIndex].timestamp;\n\tlet messageIndex = summaryIndex + 1;\n\tlet fingerprintIndex = 0;\n\twhile (fingerprintIndex < details.keptMessageFingerprints.length) {\n\t\tif (messageIndex >= messages.length) return undefined;\n\t\tconst message = messages[messageIndex];\n\t\tif (fingerprintMessage(message) === details.keptMessageFingerprints[fingerprintIndex]) {\n\t\t\tmessageIndex += 1;\n\t\t\tfingerprintIndex += 1;\n\t\t\tcontinue;\n\t\t}\n\t\tif (isOlderCompactionSummary(message, timestamp)) {\n\t\t\tmessageIndex += 1;\n\t\t\tcontinue;\n\t\t}\n\t\treturn undefined;\n\t}\n\twhile (\n\t\tmessageIndex < messages.length &&\n\t\tisOlderCompactionSummary(messages[messageIndex], timestamp)\n\t) {\n\t\tmessageIndex += 1;\n\t}\n\treturn [\n\t\t...messages.slice(0, summaryIndex),\n\t\tmarkerMessage(details.checkpointId, timestamp),\n\t\t...messages.slice(messageIndex),\n\t];\n}\n\nfunction rawText(item: JsonObject): string {\n\tif (!Array.isArray(item.content)) return \"\";\n\treturn item.content\n\t\t.flatMap((part) =>\n\t\t\tisObject(part) && typeof part.text === \"string\" && part.type === \"input_text\"\n\t\t\t\t? [part.text]\n\t\t\t\t: [],\n\t\t)\n\t\t.join(\"\\n\");\n}\n\nfunction hasMedia(item: JsonObject): boolean {\n\treturn (\n\t\tArray.isArray(item.content) &&\n\t\titem.content.some((part) => isObject(part) && part.type === \"input_image\")\n\t);\n}\n\nfunction truncateTextItem(item: JsonObject, maxChars: number): JsonObject | undefined {\n\tif (!Array.isArray(item.content) || maxChars <= 32) return undefined;\n\tlet remaining = maxChars - 16;\n\tconst content = [...item.content].reverse().flatMap((part) => {\n\t\tif (\n\t\t\t!isObject(part) ||\n\t\t\tpart.type !== \"input_text\" ||\n\t\t\ttypeof part.text !== \"string\" ||\n\t\t\tremaining <= 0\n\t\t) {\n\t\t\treturn [];\n\t\t}\n\t\tconst text = part.text.slice(-remaining);\n\t\tremaining -= text.length;\n\t\treturn [{ ...part, text: `[truncated]\\n${text}` }];\n\t});\n\tif (content.length === 0) return undefined;\n\treturn { ...item, content: content.reverse() };\n}\n\nexport function buildReplacementHistory(\n\tinput: readonly unknown[],\n\tcompactionItem: JsonObject,\n\toptions: { tokenBudget?: number; byteBudget?: number } = {},\n): JsonObject[] {\n\tconst tokenBudget = options.tokenBudget ?? REPLACEMENT_TOKEN_BUDGET;\n\tconst byteBudget = options.byteBudget ?? REPLACEMENT_BYTE_BUDGET;\n\tconst opaque = validateCompactionItem(compactionItem);\n\tlet remainingBytes = byteBudget - serializedBytes(opaque);\n\tlet remainingChars = tokenBudget * 4;\n\tif (remainingBytes <= 0)\n\t\tthrow new Error(\"Opaque compaction item exceeds replacement history budget\");\n\tconst retainedNewestFirst: JsonObject[] = [];\n\tconst candidates = input.filter(\n\t\t(item): item is JsonObject =>\n\t\t\tisObject(item) && item.role === \"user\" && item.type !== \"compaction_trigger\",\n\t);\n\tfor (let index = candidates.length - 1; index >= 0; index--) {\n\t\tconst candidate = candidates[index];\n\t\tconst bytes = serializedBytes(candidate);\n\t\tif (hasMedia(candidate) && bytes > MAX_MEDIA_ITEM_BYTES) continue;\n\t\tconst text = rawText(candidate);\n\t\tlet retained = candidate;\n\t\tif (text.length > remainingChars) {\n\t\t\tif (hasMedia(candidate)) continue;\n\t\t\tconst truncated = truncateTextItem(candidate, remainingChars);\n\t\t\tif (!truncated) continue;\n\t\t\tretained = truncated;\n\t\t}\n\t\tif (serializedBytes(retained) > remainingBytes) {\n\t\t\tif (hasMedia(retained)) continue;\n\t\t\tconst maxCharsByBytes = Math.max(0, remainingBytes - 128);\n\t\t\tconst truncated = truncateTextItem(retained, Math.min(remainingChars, maxCharsByBytes));\n\t\t\tif (!truncated || serializedBytes(truncated) > remainingBytes) continue;\n\t\t\tretained = truncated;\n\t\t}\n\t\tretainedNewestFirst.push(structuredClone(retained));\n\t\tremainingBytes -= serializedBytes(retained);\n\t\tremainingChars -= Math.min(remainingChars, rawText(retained).length);\n\t\tif (remainingBytes <= 128 || remainingChars <= 32) break;\n\t}\n\treturn [...retainedNewestFirst.reverse(), opaque];\n}\n\nexport function createCheckpointDetails(input: {\n\tprovider: string;\n\tmodelId: string;\n\treplacementHistory: JsonObject[];\n\tkeptMessages: readonly AgentMessage[];\n\tcheckpointId?: string;\n\tcreatedAt?: string;\n}): CodexCheckpointDetails {\n\tconst details: CodexCheckpointDetails = {\n\t\tkind: CHECKPOINT_KIND,\n\t\tversion: CHECKPOINT_VERSION,\n\t\tcheckpointId: input.checkpointId ?? randomUUID(),\n\t\tprovider: input.provider,\n\t\tapi: \"openai-codex-responses\",\n\t\tmodelId: input.modelId,\n\t\tprotocol: \"remote-compaction-v2\",\n\t\treplacementHistory: structuredClone(input.replacementHistory),\n\t\tkeptMessageFingerprints: input.keptMessages.map(fingerprintMessage),\n\t\tcreatedAt: input.createdAt ?? new Date().toISOString(),\n\t};\n\tconst parsed = parseCheckpointDetails(details);\n\tif (!parsed) throw new Error(\"Created an invalid Codex checkpoint\");\n\treturn parsed;\n}\n", "export const MAX_SSE_BYTES = 8 * 1024 * 1024;\nexport const MAX_COMPACTION_ITEM_BYTES = 2 * 1024 * 1024;\n\nexport type JsonObject = Record<string, unknown>;\n\nexport class CodexCompactionProtocolError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"CodexCompactionProtocolError\";\n\t}\n}\n\nfunction isObject(value: unknown): value is JsonObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction byteLength(value: unknown): number {\n\treturn Buffer.byteLength(JSON.stringify(value), \"utf8\");\n}\n\nexport function isCompactionItem(value: unknown): value is JsonObject {\n\treturn (\n\t\tisObject(value) &&\n\t\tvalue.type === \"compaction\" &&\n\t\ttypeof value.encrypted_content === \"string\" &&\n\t\tvalue.encrypted_content.length > 0\n\t);\n}\n\nexport function validateCompactionItem(\n\tvalue: unknown,\n\tmaxBytes = MAX_COMPACTION_ITEM_BYTES,\n): JsonObject {\n\tif (!isCompactionItem(value)) {\n\t\tthrow new CodexCompactionProtocolError(\n\t\t\t\"Remote response did not contain a valid compaction item\",\n\t\t);\n\t}\n\tif (byteLength(value) > maxBytes) {\n\t\tthrow new CodexCompactionProtocolError(\"Remote compaction item exceeded the size limit\");\n\t}\n\treturn structuredClone(value);\n}\n\nexport interface CollectedCompaction {\n\titem: JsonObject;\n\tcompletedResponse?: JsonObject;\n}\n\nfunction compactionItemsFromEvent(event: JsonObject): unknown[] {\n\tconst items: unknown[] = [];\n\tif (event.type === \"response.output_item.done\" && isObject(event.item)) {\n\t\titems.push(event.item);\n\t}\n\tif (event.type === \"response.completed\" && isObject(event.response)) {\n\t\tconst output = event.response.output;\n\t\tif (Array.isArray(output)) items.push(...output);\n\t}\n\treturn items.filter((item) => isObject(item) && item.type === \"compaction\");\n}\n\nexport async function collectCompactionSse(\n\tstream: ReadableStream<Uint8Array>,\n\toptions: {\n\t\tsignal?: AbortSignal;\n\t\tmaxBytes?: number;\n\t\tmaxItemBytes?: number;\n\t} = {},\n): Promise<CollectedCompaction> {\n\tconst maxBytes = options.maxBytes ?? MAX_SSE_BYTES;\n\tconst reader = stream.getReader();\n\tconst onAbort = () => {\n\t\tvoid reader.cancel(new DOMException(\"Compaction aborted\", \"AbortError\")).catch(() => undefined);\n\t};\n\toptions.signal?.addEventListener(\"abort\", onAbort, { once: true });\n\tconst decoder = new TextDecoder();\n\tlet bytes = 0;\n\tlet pending = \"\";\n\tlet dataLines: string[] = [];\n\tlet completedResponse: JsonObject | undefined;\n\tconst items = new Map<string, JsonObject>();\n\n\tconst checkAbort = () => {\n\t\tif (options.signal?.aborted) throw new DOMException(\"Compaction aborted\", \"AbortError\");\n\t};\n\tconst dispatch = () => {\n\t\tif (dataLines.length === 0) return;\n\t\tconst data = dataLines.join(\"\\n\");\n\t\tdataLines = [];\n\t\tif (data === \"[DONE]\") return;\n\t\tlet parsed: unknown;\n\t\ttry {\n\t\t\tparsed = JSON.parse(data);\n\t\t} catch {\n\t\t\tthrow new CodexCompactionProtocolError(\"Remote compaction returned malformed SSE JSON\");\n\t\t}\n\t\tif (!isObject(parsed)) return;\n\t\tif (parsed.type === \"response.completed\") {\n\t\t\tcompletedResponse = isObject(parsed.response) ? parsed.response : {};\n\t\t}\n\t\tfor (const candidate of compactionItemsFromEvent(parsed)) {\n\t\t\tconst item = validateCompactionItem(candidate, options.maxItemBytes);\n\t\t\titems.set(JSON.stringify(item), item);\n\t\t}\n\t};\n\tconst processLine = (line: string) => {\n\t\tif (line === \"\") {\n\t\t\tdispatch();\n\t\t\treturn;\n\t\t}\n\t\tif (line.startsWith(\":\")) return;\n\t\tif (line === \"data\") dataLines.push(\"\");\n\t\telse if (line.startsWith(\"data:\")) dataLines.push(line.slice(5).replace(/^ /, \"\"));\n\t};\n\n\ttry {\n\t\twhile (true) {\n\t\t\tcheckAbort();\n\t\t\tconst { done, value } = await reader.read();\n\t\t\tif (done) break;\n\t\t\tbytes += value.byteLength;\n\t\t\tif (bytes > maxBytes) {\n\t\t\t\tthrow new CodexCompactionProtocolError(\"Remote compaction stream exceeded the size limit\");\n\t\t\t}\n\t\t\tpending += decoder.decode(value, { stream: true });\n\t\t\tlet newline = pending.indexOf(\"\\n\");\n\t\t\twhile (newline !== -1) {\n\t\t\t\tconst rawLine = pending.slice(0, newline);\n\t\t\t\tpending = pending.slice(newline + 1);\n\t\t\t\tprocessLine(rawLine.endsWith(\"\\r\") ? rawLine.slice(0, -1) : rawLine);\n\t\t\t\tnewline = pending.indexOf(\"\\n\");\n\t\t\t}\n\t\t}\n\t\tpending += decoder.decode();\n\t\tif (pending.length > 0) processLine(pending.endsWith(\"\\r\") ? pending.slice(0, -1) : pending);\n\t\tdispatch();\n\t\tcheckAbort();\n\t} catch (error) {\n\t\tawait reader.cancel(error).catch(() => undefined);\n\t\tthrow error;\n\t} finally {\n\t\toptions.signal?.removeEventListener(\"abort\", onAbort);\n\t\treader.releaseLock();\n\t}\n\n\tif (!completedResponse) {\n\t\tthrow new CodexCompactionProtocolError(\n\t\t\t\"Remote compaction stream ended without response.completed\",\n\t\t);\n\t}\n\tif (items.size !== 1) {\n\t\tthrow new CodexCompactionProtocolError(\n\t\t\t`Remote compaction returned ${items.size} distinct compaction items; expected exactly one`,\n\t\t);\n\t}\n\treturn { item: [...items.values()][0], completedResponse };\n}\n\nfunction markerTextFromItem(item: unknown): string | undefined {\n\tif (!isObject(item) || item.role !== \"user\" || !Array.isArray(item.content)) return undefined;\n\tif (item.content.length !== 1) return undefined;\n\tconst content = item.content[0];\n\tif (!isObject(content) || content.type !== \"input_text\" || typeof content.text !== \"string\") {\n\t\treturn undefined;\n\t}\n\treturn content.text;\n}\n\nexport function rewriteCheckpointMarker(\n\tpayload: unknown,\n\tmarker: string,\n\treplacementHistory: readonly unknown[],\n): JsonObject {\n\tif (!isObject(payload) || !Array.isArray(payload.input)) {\n\t\tthrow new CodexCompactionProtocolError(\"Codex Responses payload is missing an input array\");\n\t}\n\tconst matches = payload.input\n\t\t.map((item, index) => (markerTextFromItem(item) === marker ? index : -1))\n\t\t.filter((index) => index >= 0);\n\tif (matches.length !== 1) {\n\t\tthrow new CodexCompactionProtocolError(\n\t\t\t`Provider payload contained ${matches.length} checkpoint markers; expected exactly one`,\n\t\t);\n\t}\n\tconst index = matches[0];\n\treturn {\n\t\t...payload,\n\t\tinput: [\n\t\t\t...payload.input.slice(0, index),\n\t\t\t...structuredClone(replacementHistory),\n\t\t\t...payload.input.slice(index + 1),\n\t\t],\n\t};\n}\n\nexport function appendCompactionTrigger(payload: unknown): JsonObject {\n\tif (!isObject(payload) || !Array.isArray(payload.input)) {\n\t\tthrow new CodexCompactionProtocolError(\"Codex Responses payload is missing an input array\");\n\t}\n\tif (payload.input.some((item) => isObject(item) && item.type === \"compaction_trigger\")) {\n\t\tthrow new CodexCompactionProtocolError(\n\t\t\t\"Provider payload already contains a compaction trigger\",\n\t\t);\n\t}\n\treturn { ...payload, input: [...payload.input, { type: \"compaction_trigger\" }] };\n}\n\nexport function prepareRemoteCompactionPayload(\n\tpayload: unknown,\n\tcheckpoint?: { marker: string; replacementHistory: readonly unknown[] },\n): JsonObject {\n\tconst expanded = checkpoint\n\t\t? rewriteCheckpointMarker(payload, checkpoint.marker, checkpoint.replacementHistory)\n\t\t: payload;\n\treturn appendCompactionTrigger(expanded);\n}\n\nexport function hasCheckpointMarker(payload: unknown, marker: string): boolean {\n\treturn (\n\t\tisObject(payload) &&\n\t\tArray.isArray(payload.input) &&\n\t\tpayload.input.some((item) => markerTextFromItem(item) === marker)\n\t);\n}\n", "import type { Context, Model, Provider, ProviderHeaders, Usage } from \"@earendil-works/pi-ai\";\nimport {\n\tCodexCompactionProtocolError,\n\ttype CollectedCompaction,\n\tcollectCompactionSse,\n\ttype JsonObject,\n\tprepareRemoteCompactionPayload,\n} from \"./protocol.js\";\n\ninterface PriorCheckpointPayload {\n\tmarker: string;\n\treplacementHistory: readonly unknown[];\n}\n\nexport interface RemoteCompactionRequest {\n\tprovider: Provider;\n\tmodel: Model<\"openai-codex-responses\">;\n\tcontext: Context;\n\tapiKey?: string;\n\theaders?: ProviderHeaders;\n\tenv?: Record<string, string>;\n\tsignal: AbortSignal;\n\tpriorCheckpoint?: PriorCheckpointPayload;\n\trequestTimeoutMs?: number;\n\tmaxRetries?: number;\n\tfetch?: typeof globalThis.fetch;\n}\n\nexport interface RemoteCompactionResponse {\n\titem: JsonObject;\n\tpromptInput: JsonObject[];\n\tusage: Usage;\n}\n\nconst EMPTY_USAGE: Usage = {\n\tinput: 0,\n\toutput: 0,\n\tcacheRead: 0,\n\tcacheWrite: 0,\n\ttotalTokens: 0,\n\tcost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0, total: 0 },\n};\n\nfunction isObject(value: unknown): value is JsonObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction abortError(): DOMException {\n\treturn new DOMException(\"Compaction aborted\", \"AbortError\");\n}\n\nexport async function requestRemoteCompaction(\n\trequest: RemoteCompactionRequest,\n): Promise<RemoteCompactionResponse> {\n\tif (request.signal.aborted) throw abortError();\n\tlet sentInput: JsonObject[] | undefined;\n\tconst inspections: Promise<\n\t\t{ ok: true; value: CollectedCompaction } | { ok: false; error: unknown }\n\t>[] = [];\n\tconst baseFetch = request.fetch ?? globalThis.fetch;\n\tconst inspectedFetch: typeof globalThis.fetch = async (input, init) => {\n\t\tconst response = await baseFetch(input, init);\n\t\tif (!response.ok || !response.body) return response;\n\t\tconst [providerBody, inspectionBody] = response.body.tee();\n\t\tconst inspection = collectCompactionSse(inspectionBody, { signal: request.signal }).then(\n\t\t\t(value) => ({ ok: true as const, value }),\n\t\t\t(error: unknown) => ({ ok: false as const, error }),\n\t\t);\n\t\tinspections.push(inspection);\n\t\treturn new Response(providerBody, {\n\t\t\tstatus: response.status,\n\t\t\tstatusText: response.statusText,\n\t\t\theaders: response.headers,\n\t\t});\n\t};\n\n\tconst stream = request.provider.stream(request.model, request.context, {\n\t\tapiKey: request.apiKey,\n\t\theaders: request.headers,\n\t\tenv: request.env,\n\t\tsignal: request.signal,\n\t\ttransport: \"sse\",\n\t\tcacheRetention: \"none\",\n\t\ttimeoutMs: request.requestTimeoutMs ?? 5 * 60 * 1000,\n\t\tmaxRetries: request.maxRetries ?? 2,\n\t\tfetch: inspectedFetch,\n\t\tonPayload: (payload) => {\n\t\t\tconst prepared = prepareRemoteCompactionPayload(payload, request.priorCheckpoint);\n\t\t\tif (!Array.isArray(prepared.input) || !prepared.input.every(isObject)) {\n\t\t\t\tthrow new CodexCompactionProtocolError(\n\t\t\t\t\t\"Prepared compaction payload has invalid input items\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tsentInput = structuredClone(prepared.input.slice(0, -1)) as JsonObject[];\n\t\t\treturn prepared;\n\t\t},\n\t});\n\n\tlet usage = EMPTY_USAGE;\n\tfor await (const event of stream) {\n\t\tif (request.signal.aborted) throw abortError();\n\t\tif (event.type === \"error\") {\n\t\t\tthrow new Error(event.error.errorMessage ?? \"Codex remote compaction request failed\");\n\t\t}\n\t\tif (event.type === \"done\") usage = event.message.usage;\n\t}\n\tif (request.signal.aborted) throw abortError();\n\tif (!sentInput)\n\t\tthrow new CodexCompactionProtocolError(\"Provider did not expose a request payload\");\n\tif (inspections.length === 0) {\n\t\tthrow new CodexCompactionProtocolError(\"Provider response did not expose an SSE body\");\n\t}\n\tconst inspection = await inspections.at(-1);\n\tif (request.signal.aborted) throw abortError();\n\tif (!inspection?.ok) throw inspection?.error ?? new Error(\"Remote compaction inspection failed\");\n\treturn { item: inspection.value.item, promptInput: sentInput, usage };\n}\n", "import { randomUUID } from \"node:crypto\";\nimport { constants } from \"node:fs\";\nimport { mkdir, open, rename, rm, writeFile } from \"node:fs/promises\";\nimport { basename, dirname, join } from \"node:path\";\nimport { getAgentDir } from \"@earendil-works/pi-coding-agent\";\n\nexport const CODEX_COMPACT_SETTINGS_FILE = \"pi-codex-compact.json\";\nexport const MAX_SETTINGS_BYTES = 64 * 1024;\n\nexport interface CodexCompactSettings {\n\tenabled: boolean;\n\trequestTimeoutMs: number;\n\tmaxRetries: number;\n\treplacementTokenBudget: number;\n\tnotifyOnFallback: boolean;\n}\n\nexport const DEFAULT_CODEX_COMPACT_SETTINGS: Readonly<CodexCompactSettings> = Object.freeze({\n\tenabled: true,\n\trequestTimeoutMs: 300_000,\n\tmaxRetries: 2,\n\treplacementTokenBudget: 64_000,\n\tnotifyOnFallback: true,\n});\n\nconst LIMITS = Object.freeze({\n\trequestTimeoutMs: { minimum: 30_000, maximum: 600_000 },\n\tmaxRetries: { minimum: 0, maximum: 2 },\n\treplacementTokenBudget: { minimum: 8_000, maximum: 128_000 },\n});\n\nexport interface CodexCompactSettingsState {\n\tkind: \"missing\" | \"loaded\" | \"invalid\";\n\tpath: string;\n\tsettings: CodexCompactSettings;\n\tdocument?: Record<string, unknown>;\n\tissue?: string;\n}\n\nexport interface CodexCompactSettingsRuntime {\n\tget(): Readonly<CodexCompactSettingsState>;\n\treload(signal?: AbortSignal): Promise<Readonly<CodexCompactSettingsState>>;\n\tupdate(\n\t\tpatch: Partial<CodexCompactSettings>,\n\t\tsignal?: AbortSignal,\n\t): Promise<Readonly<CodexCompactSettingsState>>;\n\tflush(): Promise<void>;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction validInteger(value: unknown, minimum: number, maximum: number): value is number {\n\treturn (\n\t\ttypeof value === \"number\" && Number.isSafeInteger(value) && value >= minimum && value <= maximum\n\t);\n}\n\nexport function normalizeCodexCompactSettings(value: unknown): CodexCompactSettings | undefined {\n\tif (!isRecord(value)) return undefined;\n\tif (Object.hasOwn(value, \"enabled\") && typeof value.enabled !== \"boolean\") return undefined;\n\tif (Object.hasOwn(value, \"notifyOnFallback\") && typeof value.notifyOnFallback !== \"boolean\") {\n\t\treturn undefined;\n\t}\n\tfor (const [field, limits] of Object.entries(LIMITS) as Array<\n\t\t[keyof typeof LIMITS, { minimum: number; maximum: number }]\n\t>) {\n\t\tif (\n\t\t\tObject.hasOwn(value, field) &&\n\t\t\t!validInteger(value[field], limits.minimum, limits.maximum)\n\t\t) {\n\t\t\treturn undefined;\n\t\t}\n\t}\n\treturn {\n\t\tenabled:\n\t\t\ttypeof value.enabled === \"boolean\" ? value.enabled : DEFAULT_CODEX_COMPACT_SETTINGS.enabled,\n\t\trequestTimeoutMs:\n\t\t\ttypeof value.requestTimeoutMs === \"number\"\n\t\t\t\t? value.requestTimeoutMs\n\t\t\t\t: DEFAULT_CODEX_COMPACT_SETTINGS.requestTimeoutMs,\n\t\tmaxRetries:\n\t\t\ttypeof value.maxRetries === \"number\"\n\t\t\t\t? value.maxRetries\n\t\t\t\t: DEFAULT_CODEX_COMPACT_SETTINGS.maxRetries,\n\t\treplacementTokenBudget:\n\t\t\ttypeof value.replacementTokenBudget === \"number\"\n\t\t\t\t? value.replacementTokenBudget\n\t\t\t\t: DEFAULT_CODEX_COMPACT_SETTINGS.replacementTokenBudget,\n\t\tnotifyOnFallback:\n\t\t\ttypeof value.notifyOnFallback === \"boolean\"\n\t\t\t\t? value.notifyOnFallback\n\t\t\t\t: DEFAULT_CODEX_COMPACT_SETTINGS.notifyOnFallback,\n\t};\n}\n\nexport function codexCompactSettingsPath(): string {\n\treturn join(getAgentDir(), CODEX_COMPACT_SETTINGS_FILE);\n}\n\nfunction aborted(signal?: AbortSignal): void {\n\tif (signal?.aborted) throw new DOMException(\"Settings operation aborted\", \"AbortError\");\n}\n\nexport async function loadCodexCompactSettings(\n\tpath = codexCompactSettingsPath(),\n\tsignal?: AbortSignal,\n): Promise<CodexCompactSettingsState> {\n\taborted(signal);\n\ttry {\n\t\tconst handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);\n\t\tlet text: string;\n\t\ttry {\n\t\t\tconst stats = await handle.stat();\n\t\t\taborted(signal);\n\t\t\tif (!stats.isFile()) throw new Error(\"settings path is not a regular file\");\n\t\t\tif (stats.size > MAX_SETTINGS_BYTES) throw new Error(\"settings file exceeds 64 KiB\");\n\t\t\ttext = await handle.readFile(\"utf8\");\n\t\t} finally {\n\t\t\tawait handle.close();\n\t\t}\n\t\taborted(signal);\n\t\tconst document = JSON.parse(text) as unknown;\n\t\tconst settings = normalizeCodexCompactSettings(document);\n\t\tif (!settings || !isRecord(document)) throw new Error(\"invalid settings shape or bounds\");\n\t\treturn { kind: \"loaded\", path, settings, document };\n\t} catch (error) {\n\t\tif (signal?.aborted) throw error;\n\t\tif (isNodeError(error) && error.code === \"ENOENT\") {\n\t\t\treturn {\n\t\t\t\tkind: \"missing\",\n\t\t\t\tpath,\n\t\t\t\tsettings: { ...DEFAULT_CODEX_COMPACT_SETTINGS },\n\t\t\t\tdocument: {},\n\t\t\t};\n\t\t}\n\t\treturn {\n\t\t\tkind: \"invalid\",\n\t\t\tpath,\n\t\t\tsettings: { ...DEFAULT_CODEX_COMPACT_SETTINGS },\n\t\t\tissue:\n\t\t\t\tisNodeError(error) && error.code === \"ELOOP\"\n\t\t\t\t\t? \"symbolic links are not accepted\"\n\t\t\t\t\t: error instanceof Error\n\t\t\t\t\t\t? error.message\n\t\t\t\t\t\t: String(error),\n\t\t};\n\t}\n}\n\nasync function savePatch(\n\tpath: string,\n\tpatch: Partial<CodexCompactSettings>,\n\tsignal?: AbortSignal,\n): Promise<CodexCompactSettingsState> {\n\tconst latest = await loadCodexCompactSettings(path, signal);\n\tif (latest.kind === \"invalid\") {\n\t\tthrow new Error(\n\t\t\t\"Cannot overwrite an invalid pi-codex-compact.json; repair it and reload first\",\n\t\t);\n\t}\n\tconst document = { ...latest.document, ...patch };\n\tconst settings = normalizeCodexCompactSettings(document);\n\tif (!settings) throw new Error(\"Refusing to save invalid Codex compaction settings\");\n\tconst temporaryPath = join(dirname(path), `.${basename(path)}.${randomUUID()}.tmp`);\n\tawait mkdir(dirname(path), { recursive: true });\n\taborted(signal);\n\ttry {\n\t\tawait writeFile(temporaryPath, `${JSON.stringify(document, null, 2)}\\n`, {\n\t\t\tencoding: \"utf8\",\n\t\t\tflag: \"wx\",\n\t\t\tmode: 0o600,\n\t\t});\n\t\taborted(signal);\n\t\tconst current = await loadCodexCompactSettings(path, signal);\n\t\tif (\n\t\t\tcurrent.kind === \"invalid\" ||\n\t\t\tcurrent.kind !== latest.kind ||\n\t\t\tJSON.stringify(current.document) !== JSON.stringify(latest.document)\n\t\t) {\n\t\t\tthrow new Error(\"pi-codex-compact.json changed while saving; reopen settings and retry\");\n\t\t}\n\t\tawait rename(temporaryPath, path);\n\t} finally {\n\t\tawait rm(temporaryPath, { force: true }).catch(() => undefined);\n\t}\n\treturn { kind: \"loaded\", path, settings, document };\n}\n\nexport function createCodexCompactSettingsRuntime(\n\tpath = codexCompactSettingsPath(),\n): CodexCompactSettingsRuntime {\n\tlet state: CodexCompactSettingsState = {\n\t\tkind: \"missing\",\n\t\tpath,\n\t\tsettings: { ...DEFAULT_CODEX_COMPACT_SETTINGS },\n\t\tdocument: {},\n\t};\n\tlet queue = Promise.resolve();\n\tconst enqueue = <T>(operation: () => Promise<T>): Promise<T> => {\n\t\tconst result = queue.then(operation, operation);\n\t\tqueue = result.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t\treturn result;\n\t};\n\treturn {\n\t\tget: () => structuredClone(state),\n\t\treload: (signal) =>\n\t\t\tenqueue(async () => {\n\t\t\t\tstate = await loadCodexCompactSettings(path, signal);\n\t\t\t\treturn structuredClone(state);\n\t\t\t}),\n\t\tupdate: (patch, signal) =>\n\t\t\tenqueue(async () => {\n\t\t\t\tstate = await savePatch(path, patch, signal);\n\t\t\t\treturn structuredClone(state);\n\t\t\t}),\n\t\tflush: () => queue,\n\t};\n}\n\nfunction isNodeError(error: unknown): error is NodeJS.ErrnoException {\n\treturn error instanceof Error && \"code\" in error;\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["index", "isObject", "isObject", "inspection", "randomUUID"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@narumitw/pi-codex-compact",
3
- "version": "0.51.0",
3
+ "version": "0.51.1",
4
4
  "description": "Codex Remote Compaction V2 for compatible Pi providers.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -18,7 +18,7 @@ import {
18
18
  latestCheckpoint,
19
19
  projectCheckpointContext,
20
20
  } from "./checkpoint.js";
21
- import { isCodexRemoteCompactionModel } from "./model-compatibility.js";
21
+ import { usesCodexResponsesApi } from "./model-api.js";
22
22
  import { hasCheckpointMarker, rewriteCheckpointMarker } from "./protocol.js";
23
23
  import { requestRemoteCompaction } from "./remote.js";
24
24
  import {
@@ -38,7 +38,7 @@ function isCheckpointCompatible(
38
38
  details: CodexCheckpointDetails,
39
39
  model: Model<Api> | undefined,
40
40
  ): model is Model<"openai-codex-responses"> {
41
- return isCodexRemoteCompactionModel(model) && model.id === details.modelId;
41
+ return usesCodexResponsesApi(model) && model.id === details.modelId;
42
42
  }
43
43
 
44
44
  function keptMessages(event: SessionBeforeCompactEvent): AgentMessage[] {
@@ -105,7 +105,7 @@ async function compactRemotely(
105
105
  fetch?: typeof globalThis.fetch,
106
106
  ) {
107
107
  const model = ctx.model;
108
- if (!settings.enabled || !isCodexRemoteCompactionModel(model)) return undefined;
108
+ if (!settings.enabled || !usesCodexResponsesApi(model)) return undefined;
109
109
  const sessionId = ctx.sessionManager.getSessionId();
110
110
  ctx.ui.setStatus(STATUS_KEY, "Codex remote compaction…");
111
111
  try {
@@ -1,7 +1,7 @@
1
1
  import type { Api, Model } from "@earendil-works/pi-ai";
2
2
  import { hasApi } from "@earendil-works/pi-ai";
3
3
 
4
- export function isCodexRemoteCompactionModel(
4
+ export function usesCodexResponsesApi(
5
5
  model: Model<Api> | undefined,
6
6
  ): model is Model<"openai-codex-responses"> {
7
7
  return model !== undefined && hasApi(model, "openai-codex-responses");
@@ -1,6 +1,6 @@
1
1
  import type { ExtensionCommandContext } from "@earendil-works/pi-coding-agent";
2
2
  import type { MenuDefinition } from "@narumitw/pi-tui-kit";
3
- import { isCodexRemoteCompactionModel } from "./model-compatibility.js";
3
+ import { usesCodexResponsesApi } from "./model-api.js";
4
4
  import type {
5
5
  CodexCompactSettings,
6
6
  CodexCompactSettingsRuntime,
@@ -23,7 +23,7 @@ export interface SettingsMenuOwner {
23
23
 
24
24
  interface CompactMenuStatus {
25
25
  model: string;
26
- remoteCompatible: boolean;
26
+ remoteEligible: boolean;
27
27
  }
28
28
 
29
29
  function safeText(value: string): string {
@@ -103,7 +103,7 @@ export function createCodexCompactMenu(
103
103
  {
104
104
  id: "enabled",
105
105
  label: "Remote compaction",
106
- description: "Use Codex Remote V2 when the active model is compatible.",
106
+ description: "Use Codex Remote V2 when the model uses openai-codex-responses.",
107
107
  currentValue: state.settings.enabled ? "On" : "Off",
108
108
  values: ["On", "Off"],
109
109
  action: "set-enabled",
@@ -222,7 +222,7 @@ export function compactMenuStatus(ctx: ExtensionCommandContext): CompactMenuStat
222
222
  const model = ctx.model;
223
223
  return {
224
224
  model: model ? `${model.provider}/${model.id}` : "none",
225
- remoteCompatible: isCodexRemoteCompactionModel(model),
225
+ remoteEligible: usesCodexResponsesApi(model),
226
226
  };
227
227
  }
228
228
 
@@ -231,5 +231,5 @@ function compactRoute(
231
231
  status: CompactMenuStatus | undefined,
232
232
  ): string {
233
233
  if (!state.settings.enabled) return "Pi native (Remote V2 off)";
234
- return status?.remoteCompatible ? "Codex Remote V2" : "Pi native (model not compatible)";
234
+ return status?.remoteEligible ? "Codex Remote V2" : "Pi native (requires openai-codex-responses)";
235
235
  }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/model-compatibility.ts"],
4
- "sourcesContent": ["import type { Api, Model } from \"@earendil-works/pi-ai\";\nimport { hasApi } from \"@earendil-works/pi-ai\";\n\nexport function isCodexRemoteCompactionModel(\n\tmodel: Model<Api> | undefined,\n): model is Model<\"openai-codex-responses\"> {\n\treturn model !== undefined && hasApi(model, \"openai-codex-responses\");\n}\n"],
5
- "mappings": ";;;;AACA,SAAS,cAAc;AAEhB,SAAS,6BACf,OAC2C;AAC3C,SAAO,UAAU,UAAa,OAAO,OAAO,wBAAwB;AACrE;",
6
- "names": []
7
- }
@@ -1,7 +0,0 @@
1
- {
2
- "version": 3,
3
- "sources": ["../../src/settings-menu.ts"],
4
- "sourcesContent": ["import type { ExtensionCommandContext } from \"@earendil-works/pi-coding-agent\";\nimport type { MenuDefinition } from \"@narumitw/pi-tui-kit\";\nimport { isCodexRemoteCompactionModel } from \"./model-compatibility.js\";\nimport type {\n\tCodexCompactSettings,\n\tCodexCompactSettingsRuntime,\n\tCodexCompactSettingsState,\n} from \"./settings.js\";\n\ntype Screen = \"main\" | \"settings\" | \"invalid\";\ntype Action =\n\t| \"compact-now\"\n\t| \"set-enabled\"\n\t| \"set-timeout\"\n\t| \"set-retries\"\n\t| \"set-retention\"\n\t| \"set-notify\";\n\nexport interface SettingsMenuOwner {\n\tsignal: AbortSignal;\n\tisCurrent(): boolean;\n}\n\ninterface CompactMenuStatus {\n\tmodel: string;\n\tremoteCompatible: boolean;\n}\n\nfunction safeText(value: string): string {\n\treturn Array.from(value, (character) => {\n\t\tconst codePoint = character.codePointAt(0) ?? 0;\n\t\treturn codePoint < 32 || (codePoint >= 127 && codePoint <= 159) ? \" \" : character;\n\t}).join(\"\");\n}\n\nfunction timeoutLabel(milliseconds: number): string {\n\treturn `${milliseconds / 60_000} min`;\n}\n\nfunction retentionLabel(tokens: number): string {\n\treturn `${tokens / 1000}K tokens`;\n}\n\nasync function update(\n\truntime: CodexCompactSettingsRuntime,\n\tctx: ExtensionCommandContext,\n\tpatch: Partial<CodexCompactSettings>,\n\tsignal: AbortSignal,\n) {\n\ttry {\n\t\tawait runtime.update(patch, signal);\n\t\tctx.ui.notify(\"Codex compaction settings saved.\", \"info\");\n\t\treturn { kind: \"stay\" as const };\n\t} catch (error) {\n\t\tif (signal.aborted) return { kind: \"rejected\" as const };\n\t\tctx.ui.notify(\n\t\t\t`Could not save pi-codex-compact.json: ${safeText(error instanceof Error ? error.message : String(error))}`,\n\t\t\t\"error\",\n\t\t);\n\t\treturn { kind: \"rejected\" as const };\n\t}\n}\n\nexport function createCodexCompactMenu(\n\truntime: CodexCompactSettingsRuntime,\n\toptions: { onCompactRequested?: () => void; status?: CompactMenuStatus } = {},\n): MenuDefinition<CodexCompactSettingsState, Screen, Action, ExtensionCommandContext> {\n\treturn {\n\t\tstart: \"main\",\n\t\tscreens: {\n\t\t\tmain: ({ state }) => ({\n\t\t\t\tkind: \"actions\",\n\t\t\t\ttitle: \"Codex Remote Compaction\",\n\t\t\t\tlines: [\n\t\t\t\t\t`Remote V2: ${state.settings.enabled ? \"On\" : \"Off\"}`,\n\t\t\t\t\t`Active model: ${safeText(options.status?.model ?? \"none\")}`,\n\t\t\t\t\t`Compact route: ${safeText(compactRoute(state, options.status))}`,\n\t\t\t\t],\n\t\t\t\titems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"compact-now\",\n\t\t\t\t\t\tlabel: \"Compact now\",\n\t\t\t\t\t\tdescription: \"Close this menu and compact the active session immediately.\",\n\t\t\t\t\t\taction: \"compact-now\",\n\t\t\t\t\t},\n\t\t\t\t\tstate.kind === \"invalid\"\n\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\tid: \"settings\",\n\t\t\t\t\t\t\t\tlabel: \"Settings\",\n\t\t\t\t\t\t\t\tdescription: \"Read-only until the invalid settings file is repaired.\",\n\t\t\t\t\t\t\t\tto: \"invalid\" as const,\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t: { id: \"settings\", label: \"Settings\", to: \"settings\" as const },\n\t\t\t\t\t{ id: \"close\", label: \"Close\", close: true },\n\t\t\t\t],\n\t\t\t\thint: \"close\",\n\t\t\t}),\n\t\t\tsettings: ({ state }) => ({\n\t\t\t\tkind: \"settings\",\n\t\t\t\ttitle: \"Codex Remote Compaction Settings\",\n\t\t\t\tlines: [`User settings \u00B7 ${safeText(state.path)}`],\n\t\t\t\titems: [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"enabled\",\n\t\t\t\t\t\tlabel: \"Remote compaction\",\n\t\t\t\t\t\tdescription: \"Use Codex Remote V2 when the active model is compatible.\",\n\t\t\t\t\t\tcurrentValue: state.settings.enabled ? \"On\" : \"Off\",\n\t\t\t\t\t\tvalues: [\"On\", \"Off\"],\n\t\t\t\t\t\taction: \"set-enabled\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"requestTimeoutMs\",\n\t\t\t\t\t\tlabel: \"Request timeout\",\n\t\t\t\t\t\tdescription: \"Maximum time for the extension-owned remote compaction request.\",\n\t\t\t\t\t\tcurrentValue: timeoutLabel(state.settings.requestTimeoutMs),\n\t\t\t\t\t\tvalues: [\"2 min\", \"5 min\", \"10 min\"],\n\t\t\t\t\t\taction: \"set-timeout\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"maxRetries\",\n\t\t\t\t\t\tlabel: \"Transport retries\",\n\t\t\t\t\t\tdescription: \"Retry transient provider failures before falling back to Pi.\",\n\t\t\t\t\t\tcurrentValue: String(state.settings.maxRetries),\n\t\t\t\t\t\tvalues: [\"0\", \"1\", \"2\"],\n\t\t\t\t\t\taction: \"set-retries\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"replacementTokenBudget\",\n\t\t\t\t\t\tlabel: \"Retained user history\",\n\t\t\t\t\t\tdescription: \"Approximate user-message budget kept beside the opaque checkpoint.\",\n\t\t\t\t\t\tcurrentValue: retentionLabel(state.settings.replacementTokenBudget),\n\t\t\t\t\t\tvalues: [\"32K tokens\", \"64K tokens\", \"96K tokens\", \"128K tokens\"],\n\t\t\t\t\t\taction: \"set-retention\",\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tid: \"notifyOnFallback\",\n\t\t\t\t\t\tlabel: \"Fallback notifications\",\n\t\t\t\t\t\tdescription: \"Warn when Remote V2 fails and native Pi compaction takes over.\",\n\t\t\t\t\t\tcurrentValue: state.settings.notifyOnFallback ? \"On\" : \"Off\",\n\t\t\t\t\t\tvalues: [\"On\", \"Off\"],\n\t\t\t\t\t\taction: \"set-notify\",\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t}),\n\t\t\tinvalid: ({ state }) => ({\n\t\t\t\tkind: \"detail\",\n\t\t\t\ttitle: \"Codex Compact Settings \u00B7 Read only\",\n\t\t\t\tlines: [\n\t\t\t\t\t`Invalid settings file: ${safeText(state.path)}`,\n\t\t\t\t\t`Issue: ${safeText(state.issue ?? \"unknown validation error\")}`,\n\t\t\t\t\t\"Built-in defaults are active. Repair the file and run /reload; it will not be overwritten.\",\n\t\t\t\t],\n\t\t\t\thint: \"back\",\n\t\t\t}),\n\t\t},\n\t\tactions: {\n\t\t\t\"compact-now\": async () => {\n\t\t\t\toptions.onCompactRequested?.();\n\t\t\t\treturn { kind: \"close\" };\n\t\t\t},\n\t\t\t\"set-enabled\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(runtime, ctx, { enabled: value === \"On\" }, signal),\n\t\t\t\"set-timeout\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(\n\t\t\t\t\truntime,\n\t\t\t\t\tctx,\n\t\t\t\t\t{ requestTimeoutMs: Number.parseInt(value ?? \"5\", 10) * 60_000 },\n\t\t\t\t\tsignal,\n\t\t\t\t),\n\t\t\t\"set-retries\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(runtime, ctx, { maxRetries: Number.parseInt(value ?? \"2\", 10) }, signal),\n\t\t\t\"set-retention\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(\n\t\t\t\t\truntime,\n\t\t\t\t\tctx,\n\t\t\t\t\t{ replacementTokenBudget: Number.parseInt(value ?? \"64\", 10) * 1000 },\n\t\t\t\t\tsignal,\n\t\t\t\t),\n\t\t\t\"set-notify\": ({ ctx, value, signal }) =>\n\t\t\t\tupdate(runtime, ctx, { notifyOnFallback: value === \"On\" }, signal),\n\t\t},\n\t};\n}\n\nexport async function showCodexCompactMenu(\n\truntime: CodexCompactSettingsRuntime,\n\tctx: ExtensionCommandContext,\n\towner: SettingsMenuOwner,\n): Promise<void> {\n\tif (ctx.mode !== \"tui\") {\n\t\tctx.ui.notify(`Edit Codex compaction settings at ${safeText(runtime.get().path)}.`, \"info\");\n\t\treturn;\n\t}\n\tconst { runMenu } = await import(\"@narumitw/pi-tui-kit\");\n\tif (owner.signal.aborted || !owner.isCurrent()) return;\n\tlet compactRequested = false;\n\tawait runMenu(\n\t\tctx,\n\t\tcreateCodexCompactMenu(runtime, {\n\t\t\tonCompactRequested: () => {\n\t\t\t\tcompactRequested = true;\n\t\t\t},\n\t\t\tstatus: compactMenuStatus(ctx),\n\t\t}),\n\t\t{\n\t\t\tgetState: () => runtime.get(),\n\t\t\tsignal: owner.signal,\n\t\t\tisCurrent: owner.isCurrent,\n\t\t},\n\t);\n\tif (!compactRequested || owner.signal.aborted || !owner.isCurrent()) return;\n\tctx.compact({\n\t\tonError: (error) => {\n\t\t\tif (!owner.signal.aborted && owner.isCurrent()) {\n\t\t\t\tctx.ui.notify(`Compaction failed: ${safeText(error.message)}`, \"error\");\n\t\t\t}\n\t\t},\n\t});\n}\n\nexport function compactMenuStatus(ctx: ExtensionCommandContext): CompactMenuStatus {\n\tconst model = ctx.model;\n\treturn {\n\t\tmodel: model ? `${model.provider}/${model.id}` : \"none\",\n\t\tremoteCompatible: isCodexRemoteCompactionModel(model),\n\t};\n}\n\nfunction compactRoute(\n\tstate: Readonly<CodexCompactSettingsState>,\n\tstatus: CompactMenuStatus | undefined,\n): string {\n\tif (!state.settings.enabled) return \"Pi native (Remote V2 off)\";\n\treturn status?.remoteCompatible ? \"Codex Remote V2\" : \"Pi native (model not compatible)\";\n}\n"],
5
- "mappings": ";;;;;;;AA4BA,SAAS,SAAS,OAAuB;AACxC,SAAO,MAAM,KAAK,OAAO,CAAC,cAAc;AACvC,UAAM,YAAY,UAAU,YAAY,CAAC,KAAK;AAC9C,WAAO,YAAY,MAAO,aAAa,OAAO,aAAa,MAAO,MAAM;AAAA,EACzE,CAAC,EAAE,KAAK,EAAE;AACX;AAEA,SAAS,aAAa,cAA8B;AACnD,SAAO,GAAG,eAAe,GAAM;AAChC;AAEA,SAAS,eAAe,QAAwB;AAC/C,SAAO,GAAG,SAAS,GAAI;AACxB;AAEA,eAAe,OACd,SACA,KACA,OACA,QACC;AACD,MAAI;AACH,UAAM,QAAQ,OAAO,OAAO,MAAM;AAClC,QAAI,GAAG,OAAO,oCAAoC,MAAM;AACxD,WAAO,EAAE,MAAM,OAAgB;AAAA,EAChC,SAAS,OAAO;AACf,QAAI,OAAO,QAAS,QAAO,EAAE,MAAM,WAAoB;AACvD,QAAI,GAAG;AAAA,MACN,yCAAyC,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC,CAAC;AAAA,MACzG;AAAA,IACD;AACA,WAAO,EAAE,MAAM,WAAoB;AAAA,EACpC;AACD;AAEO,SAAS,uBACf,SACA,UAA2E,CAAC,GACS;AACrF,SAAO;AAAA,IACN,OAAO;AAAA,IACP,SAAS;AAAA,MACR,MAAM,CAAC,EAAE,MAAM,OAAO;AAAA,QACrB,MAAM;AAAA,QACN,OAAO;AAAA,QACP,OAAO;AAAA,UACN,cAAc,MAAM,SAAS,UAAU,OAAO,KAAK;AAAA,UACnD,iBAAiB,SAAS,QAAQ,QAAQ,SAAS,MAAM,CAAC;AAAA,UAC1D,kBAAkB,SAAS,aAAa,OAAO,QAAQ,MAAM,CAAC,CAAC;AAAA,QAChE;AAAA,QACA,OAAO;AAAA,UACN;AAAA,YACC,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,aAAa;AAAA,YACb,QAAQ;AAAA,UACT;AAAA,UACA,MAAM,SAAS,YACZ;AAAA,YACA,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,aAAa;AAAA,YACb,IAAI;AAAA,UACL,IACC,EAAE,IAAI,YAAY,OAAO,YAAY,IAAI,WAAoB;AAAA,UAChE,EAAE,IAAI,SAAS,OAAO,SAAS,OAAO,KAAK;AAAA,QAC5C;AAAA,QACA,MAAM;AAAA,MACP;AAAA,MACA,UAAU,CAAC,EAAE,MAAM,OAAO;AAAA,QACzB,MAAM;AAAA,QACN,OAAO;AAAA,QACP,OAAO,CAAC,sBAAmB,SAAS,MAAM,IAAI,CAAC,EAAE;AAAA,QACjD,OAAO;AAAA,UACN;AAAA,YACC,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,aAAa;AAAA,YACb,cAAc,MAAM,SAAS,UAAU,OAAO;AAAA,YAC9C,QAAQ,CAAC,MAAM,KAAK;AAAA,YACpB,QAAQ;AAAA,UACT;AAAA,UACA;AAAA,YACC,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,aAAa;AAAA,YACb,cAAc,aAAa,MAAM,SAAS,gBAAgB;AAAA,YAC1D,QAAQ,CAAC,SAAS,SAAS,QAAQ;AAAA,YACnC,QAAQ;AAAA,UACT;AAAA,UACA;AAAA,YACC,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,aAAa;AAAA,YACb,cAAc,OAAO,MAAM,SAAS,UAAU;AAAA,YAC9C,QAAQ,CAAC,KAAK,KAAK,GAAG;AAAA,YACtB,QAAQ;AAAA,UACT;AAAA,UACA;AAAA,YACC,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,aAAa;AAAA,YACb,cAAc,eAAe,MAAM,SAAS,sBAAsB;AAAA,YAClE,QAAQ,CAAC,cAAc,cAAc,cAAc,aAAa;AAAA,YAChE,QAAQ;AAAA,UACT;AAAA,UACA;AAAA,YACC,IAAI;AAAA,YACJ,OAAO;AAAA,YACP,aAAa;AAAA,YACb,cAAc,MAAM,SAAS,mBAAmB,OAAO;AAAA,YACvD,QAAQ,CAAC,MAAM,KAAK;AAAA,YACpB,QAAQ;AAAA,UACT;AAAA,QACD;AAAA,MACD;AAAA,MACA,SAAS,CAAC,EAAE,MAAM,OAAO;AAAA,QACxB,MAAM;AAAA,QACN,OAAO;AAAA,QACP,OAAO;AAAA,UACN,0BAA0B,SAAS,MAAM,IAAI,CAAC;AAAA,UAC9C,UAAU,SAAS,MAAM,SAAS,0BAA0B,CAAC;AAAA,UAC7D;AAAA,QACD;AAAA,QACA,MAAM;AAAA,MACP;AAAA,IACD;AAAA,IACA,SAAS;AAAA,MACR,eAAe,YAAY;AAC1B,gBAAQ,qBAAqB;AAC7B,eAAO,EAAE,MAAM,QAAQ;AAAA,MACxB;AAAA,MACA,eAAe,CAAC,EAAE,KAAK,OAAO,OAAO,MACpC,OAAO,SAAS,KAAK,EAAE,SAAS,UAAU,KAAK,GAAG,MAAM;AAAA,MACzD,eAAe,CAAC,EAAE,KAAK,OAAO,OAAO,MACpC;AAAA,QACC;AAAA,QACA;AAAA,QACA,EAAE,kBAAkB,OAAO,SAAS,SAAS,KAAK,EAAE,IAAI,IAAO;AAAA,QAC/D;AAAA,MACD;AAAA,MACD,eAAe,CAAC,EAAE,KAAK,OAAO,OAAO,MACpC,OAAO,SAAS,KAAK,EAAE,YAAY,OAAO,SAAS,SAAS,KAAK,EAAE,EAAE,GAAG,MAAM;AAAA,MAC/E,iBAAiB,CAAC,EAAE,KAAK,OAAO,OAAO,MACtC;AAAA,QACC;AAAA,QACA;AAAA,QACA,EAAE,wBAAwB,OAAO,SAAS,SAAS,MAAM,EAAE,IAAI,IAAK;AAAA,QACpE;AAAA,MACD;AAAA,MACD,cAAc,CAAC,EAAE,KAAK,OAAO,OAAO,MACnC,OAAO,SAAS,KAAK,EAAE,kBAAkB,UAAU,KAAK,GAAG,MAAM;AAAA,IACnE;AAAA,EACD;AACD;AAEA,eAAsB,qBACrB,SACA,KACA,OACgB;AAChB,MAAI,IAAI,SAAS,OAAO;AACvB,QAAI,GAAG,OAAO,qCAAqC,SAAS,QAAQ,IAAI,EAAE,IAAI,CAAC,KAAK,MAAM;AAC1F;AAAA,EACD;AACA,QAAM,EAAE,QAAQ,IAAI,MAAM,OAAO,sBAAsB;AACvD,MAAI,MAAM,OAAO,WAAW,CAAC,MAAM,UAAU,EAAG;AAChD,MAAI,mBAAmB;AACvB,QAAM;AAAA,IACL;AAAA,IACA,uBAAuB,SAAS;AAAA,MAC/B,oBAAoB,MAAM;AACzB,2BAAmB;AAAA,MACpB;AAAA,MACA,QAAQ,kBAAkB,GAAG;AAAA,IAC9B,CAAC;AAAA,IACD;AAAA,MACC,UAAU,MAAM,QAAQ,IAAI;AAAA,MAC5B,QAAQ,MAAM;AAAA,MACd,WAAW,MAAM;AAAA,IAClB;AAAA,EACD;AACA,MAAI,CAAC,oBAAoB,MAAM,OAAO,WAAW,CAAC,MAAM,UAAU,EAAG;AACrE,MAAI,QAAQ;AAAA,IACX,SAAS,CAAC,UAAU;AACnB,UAAI,CAAC,MAAM,OAAO,WAAW,MAAM,UAAU,GAAG;AAC/C,YAAI,GAAG,OAAO,sBAAsB,SAAS,MAAM,OAAO,CAAC,IAAI,OAAO;AAAA,MACvE;AAAA,IACD;AAAA,EACD,CAAC;AACF;AAEO,SAAS,kBAAkB,KAAiD;AAClF,QAAM,QAAQ,IAAI;AAClB,SAAO;AAAA,IACN,OAAO,QAAQ,GAAG,MAAM,QAAQ,IAAI,MAAM,EAAE,KAAK;AAAA,IACjD,kBAAkB,6BAA6B,KAAK;AAAA,EACrD;AACD;AAEA,SAAS,aACR,OACA,QACS;AACT,MAAI,CAAC,MAAM,SAAS,QAAS,QAAO;AACpC,SAAO,QAAQ,mBAAmB,oBAAoB;AACvD;",
6
- "names": []
7
- }