@howaboua/pi-codex-conversion 1.5.11-dev.45.7d9b450 → 1.5.11

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@howaboua/pi-codex-conversion",
3
- "version": "1.5.11-dev.45.7d9b450",
3
+ "version": "1.5.11",
4
4
  "description": "Codex-oriented tool and prompt adapter for pi coding agent",
5
5
  "type": "module",
6
6
  "repository": {
@@ -142,6 +142,28 @@ function notifyNativeCompactionFallback(ctx: ExtensionContext, state: AdapterSta
142
142
  ctx.ui.notify(`${message}; Pi compaction will run.${stashed ? " Previous native compacted window will be included in Pi compaction fallback." : ""}`, "error");
143
143
  }
144
144
 
145
+ function textFromResponsesContent(content: unknown): string {
146
+ if (typeof content === "string") return content;
147
+ if (!Array.isArray(content)) return "";
148
+ return content
149
+ .map((item) => isRecord(item) && item.type === "input_text" && typeof item.text === "string" ? item.text : "")
150
+ .join("\n");
151
+ }
152
+
153
+ function isPiCompactionSummarizationPayload(payload: ResponsesCompatibleRequestPayload): boolean {
154
+ const instructions = typeof payload.instructions === "string" ? payload.instructions : "";
155
+ if (/compact|summar/i.test(instructions)) return true;
156
+
157
+ return payload.input.some((item) => {
158
+ if (!isRecord(item)) return false;
159
+ const role = item.role;
160
+ const text = textFromResponsesContent(item.content);
161
+ if ((role === "system" || role === "developer") && /compact|summar/i.test(text)) return true;
162
+ if (role === "user" && /<conversation>|previous compaction summary|summary/i.test(text)) return true;
163
+ return false;
164
+ });
165
+ }
166
+
145
167
  export async function handleCodexSessionBeforeCompact(event: SessionBeforeCompactEvent, ctx: ExtensionContext, state: AdapterState, pi: ExtensionAPI) {
146
168
  if (!state.config.responsesCompaction || !shouldUseCodexAdapter(ctx, state.config)) {
147
169
  return undefined;
@@ -165,6 +187,9 @@ async function handleCodexSessionBeforeCompactInner(event: SessionBeforeCompactE
165
187
 
166
188
  const resolution = await resolveNativeCompactionEnvironment(ctx, { enabled: true });
167
189
  if (!resolution.ok) {
190
+ if (resolution.reason === "unsupported-provider" || resolution.reason === "unsupported-api") {
191
+ return undefined;
192
+ }
168
193
  ctx.ui.notify(`OpenAI native compaction is enabled but unavailable (${resolution.reason}); Pi compaction was not run.`, "error");
169
194
  return { cancel: true };
170
195
  }
@@ -306,11 +331,15 @@ export async function injectPendingNativeWindowIntoPiCompactionRequest(payload:
306
331
  state.pendingPiCompactionNativeWindow = undefined;
307
332
  return undefined;
308
333
  }
334
+ if (!isPiCompactionSummarizationPayload(payload)) return undefined;
309
335
 
310
336
  const resolution = await resolveNativeCompactionEnvironment(ctx, { enabled: true }, payload);
311
337
  if (!resolution.ok) return undefined;
312
338
  const runtime = resolution.runtime;
313
- if (pending.provider !== runtime.provider || pending.api !== runtime.api || pending.baseUrl !== runtime.baseUrl) return undefined;
339
+ if (pending.provider !== runtime.provider || pending.api !== runtime.api || pending.baseUrl !== runtime.baseUrl) {
340
+ state.pendingPiCompactionNativeWindow = undefined;
341
+ return undefined;
342
+ }
314
343
 
315
344
  const input = [...payload.input];
316
345
  let insertAt = 0;
@@ -320,6 +349,7 @@ export async function injectPendingNativeWindowIntoPiCompactionRequest(payload:
320
349
  insertAt++;
321
350
  }
322
351
 
352
+ state.pendingPiCompactionNativeWindow = undefined;
323
353
  return {
324
354
  ...payload,
325
355
  input: [
@@ -390,6 +390,15 @@ function createReplayVariants<TApi extends Api>(args: {
390
390
  return [contextSet, createReplayMessageSet(args.model, piMessages)];
391
391
  }
392
392
 
393
+ function clonePayloadConversationInput(args: {
394
+ payloadInput: readonly unknown[];
395
+ freshPreamble: FreshAuthoritativePreamble;
396
+ }): ResponsesInputItem[] | undefined {
397
+ const tailEndIndex = args.payloadInput.length - args.freshPreamble.trailingInput.length;
398
+ if (tailEndIndex < args.freshPreamble.leadingInput.length) return undefined;
399
+ return cloneResponsesInputSlice(args.payloadInput.slice(args.freshPreamble.leadingInput.length, tailEndIndex));
400
+ }
401
+
393
402
  function findReplayMatch<TApi extends Api>(args: {
394
403
  model: Model<TApi>;
395
404
  payloadInput: readonly unknown[];
@@ -506,21 +515,57 @@ function buildNativeReplaySegmentsInternal<TApi extends Api>(args: {
506
515
  };
507
516
  }
508
517
 
509
- const newerCompactionEntry = args.branchEntries
510
- .slice(boundaryIndex + 1)
511
- .some((entry) => entry.type === "compaction");
512
- if (newerCompactionEntry) {
518
+ const compactedWindow = cloneOpaqueCompactedWindow(args.compactionEntry.details?.compactedWindow ?? []);
519
+ if (!compactedWindow) {
513
520
  return {
514
521
  ok: false,
515
- reason: "unexpected-compaction-after-boundary",
522
+ reason: "invalid-compacted-window",
516
523
  };
517
524
  }
518
525
 
519
- const compactedWindow = cloneOpaqueCompactedWindow(args.compactionEntry.details?.compactedWindow ?? []);
520
- if (!compactedWindow) {
526
+ const newerCompactionEntry = args.branchEntries
527
+ .slice(boundaryIndex + 1)
528
+ .some((entry) => entry.type === "compaction");
529
+ if (newerCompactionEntry) {
530
+ const conversationInput = clonePayloadConversationInput({ payloadInput: args.payload.input, freshPreamble });
531
+ const originalPiReplayInput = cloneResponsesInputSlice(args.payload.input);
532
+ if (!conversationInput || !originalPiReplayInput) {
533
+ return {
534
+ ok: false,
535
+ reason: "unexpected-compaction-after-boundary",
536
+ };
537
+ }
538
+
521
539
  return {
522
- ok: false,
523
- reason: "invalid-compacted-window",
540
+ ok: true,
541
+ segments: {
542
+ boundaryIndex,
543
+ firstKeptEntryIndex,
544
+ instructions: freshPreamble.instructions,
545
+ freshPreamble: freshPreamble.leadingInput,
546
+ trailingPreamble: freshPreamble.trailingInput,
547
+ compactionSummary: [],
548
+ preCompactionKeptWindow: createReplaySlice([], [], []),
549
+ compactedWindow,
550
+ postCompactionTail: createReplaySlice(args.branchEntries.slice(boundaryIndex + 1), [], conversationInput),
551
+ originalPiReplayInput,
552
+ replayInput: [
553
+ ...freshPreamble.leadingInput,
554
+ ...compactedWindow,
555
+ ...conversationInput,
556
+ ...freshPreamble.trailingInput,
557
+ ],
558
+ },
559
+ rewrittenPayload: {
560
+ ...args.payload,
561
+ ...(freshPreamble.instructions !== undefined ? { instructions: freshPreamble.instructions } : {}),
562
+ input: [
563
+ ...freshPreamble.leadingInput,
564
+ ...compactedWindow,
565
+ ...conversationInput,
566
+ ...freshPreamble.trailingInput,
567
+ ],
568
+ },
524
569
  };
525
570
  }
526
571
 
@@ -9,7 +9,7 @@ export const NATIVE_COMPACTION_DISPLAY_TEXT = [
9
9
  "",
10
10
  "The compaction result is encrypted by OpenAI and is not human-readable in Pi.",
11
11
  "",
12
- "Warning: do not turn Responses compaction off mid-session; old context may be much less reliable.",
12
+ "Warning: do not turn Responses compaction off or switch providers mid-session; old context may be much less reliable.",
13
13
  ].join("\n");
14
14
 
15
15
  export type NativeCompactionStrategy = typeof NATIVE_COMPACTION_STRATEGY;
@@ -92,7 +92,8 @@ export async function openCodexSettingsScreen(ctx: ExtensionContext, options: Co
92
92
  function formatCompactionNotes(theme: Theme): string[] {
93
93
  return [
94
94
  theme.fg("dim", " Beta: native OpenAI Responses compaction is experimental. Please report any issues."),
95
- theme.fg("error", " Warning: do not turn this off mid-session; old context may be much less reliable."),
95
+ theme.fg("error", " Warning: do not turn this off or switch providers mid-session; old context may be much less reliable."),
96
+ theme.fg("warning", " If native compaction recovery fails, go back below 90% context and compact from there."),
96
97
  ];
97
98
  }
98
99