@howaboua/pi-codex-conversion 1.5.8-dev.33.e99b6a4 → 1.5.8-dev.35.57ee19e

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.8-dev.33.e99b6a4",
3
+ "version": "1.5.8-dev.35.57ee19e",
4
4
  "description": "Codex-oriented tool and prompt adapter for pi coding agent",
5
5
  "type": "module",
6
6
  "repository": {
@@ -71,6 +71,19 @@ export type NativeReplayPayloadRewriteResult =
71
71
  | NativeReplayPayloadRewrite
72
72
  | NativeReplayPayloadRewriteFailure;
73
73
 
74
+ type ReplayMessageSet = {
75
+ messages: AgentMessage[];
76
+ input: ResponsesInputItem[];
77
+ };
78
+
79
+ type ReplayMatch = {
80
+ originalPiReplayInput: ResponsesInputItem[];
81
+ preCompactionKept: ReplayMessageSet;
82
+ postCompactionTail: ReplayMessageSet;
83
+ actualPostCompactionTail: ResponsesInputItem[];
84
+ extraPostCompactionTail: ResponsesInputItem[];
85
+ };
86
+
74
87
  function isRecord(value: unknown): value is Record<string, unknown> {
75
88
  return !!value && typeof value === "object" && !Array.isArray(value);
76
89
  }
@@ -359,6 +372,66 @@ function createReplaySlice(
359
372
  };
360
373
  }
361
374
 
375
+ function createReplayMessageSet<TApi extends Api>(model: Model<TApi>, messages: AgentMessage[]): ReplayMessageSet {
376
+ return {
377
+ messages,
378
+ input: serializeMessagesToResponsesInput(model, messages),
379
+ };
380
+ }
381
+
382
+ function createReplayVariants<TApi extends Api>(args: {
383
+ model: Model<TApi>;
384
+ entries: readonly SessionEntry[];
385
+ }): ReplayMessageSet[] {
386
+ const contextMessages = collectReplayMessages(args.entries);
387
+ const piMessages = collectPiReplayMessages(args.entries);
388
+ const contextSet = createReplayMessageSet(args.model, contextMessages);
389
+ if (areEquivalentValues(contextMessages, piMessages)) return [contextSet];
390
+ return [contextSet, createReplayMessageSet(args.model, piMessages)];
391
+ }
392
+
393
+ function findReplayMatch<TApi extends Api>(args: {
394
+ model: Model<TApi>;
395
+ payloadInput: readonly unknown[];
396
+ freshPreamble: FreshAuthoritativePreamble;
397
+ compactionSummaryMessage: AgentMessage;
398
+ preCompactionEntries: readonly SessionEntry[];
399
+ postCompactionEntries: readonly SessionEntry[];
400
+ }): ReplayMatch | undefined {
401
+ const compactionSummaryInput = serializeMessagesToResponsesInput(args.model, [args.compactionSummaryMessage]);
402
+ const preCompactionVariants = createReplayVariants({ model: args.model, entries: args.preCompactionEntries });
403
+ const postCompactionVariants = createReplayVariants({ model: args.model, entries: args.postCompactionEntries });
404
+
405
+ for (const preCompactionKept of preCompactionVariants) {
406
+ for (const postCompactionTail of postCompactionVariants) {
407
+ const expectedBeforeTrailing: ResponsesInputItem[] = [
408
+ ...args.freshPreamble.leadingInput,
409
+ ...compactionSummaryInput,
410
+ ...preCompactionKept.input,
411
+ ...postCompactionTail.input,
412
+ ];
413
+ const originalPiReplayInput: ResponsesInputItem[] = [...expectedBeforeTrailing, ...args.freshPreamble.trailingInput];
414
+ const tailEndIndex = args.payloadInput.length - args.freshPreamble.trailingInput.length;
415
+ const prefixMatches = areEquivalentValues(args.payloadInput.slice(0, expectedBeforeTrailing.length), expectedBeforeTrailing);
416
+ const trailingMatches = areEquivalentValues(args.payloadInput.slice(tailEndIndex), args.freshPreamble.trailingInput);
417
+
418
+ if (prefixMatches && trailingMatches && tailEndIndex >= expectedBeforeTrailing.length) {
419
+ const actualPostCompactionTail = cloneResponsesInputSlice(
420
+ args.payloadInput.slice(
421
+ args.freshPreamble.leadingInput.length + compactionSummaryInput.length + preCompactionKept.input.length,
422
+ tailEndIndex,
423
+ ),
424
+ );
425
+ const extraPostCompactionTail = cloneResponsesInputSlice(args.payloadInput.slice(expectedBeforeTrailing.length, tailEndIndex));
426
+ if (!actualPostCompactionTail || !extraPostCompactionTail) return undefined;
427
+ return { originalPiReplayInput, preCompactionKept, postCompactionTail, actualPostCompactionTail, extraPostCompactionTail };
428
+ }
429
+ }
430
+ }
431
+
432
+ return undefined;
433
+ }
434
+
362
435
  function findEntryIndexByIdBeforeBoundary(
363
436
  entries: readonly SessionEntry[],
364
437
  entryId: string,
@@ -453,23 +526,27 @@ function buildNativeReplaySegmentsInternal<TApi extends Api>(args: {
453
526
 
454
527
  const preCompactionEntries = args.branchEntries.slice(firstKeptEntryIndex, boundaryIndex);
455
528
  const postCompactionEntries = args.branchEntries.slice(boundaryIndex + 1);
456
- const preCompactionKeptMessages = collectPiReplayMessages(preCompactionEntries);
457
- const postCompactionTailMessages = collectPiReplayMessages(postCompactionEntries);
458
529
  const contextPostCompactionTailMessages = collectReplayMessages(postCompactionEntries);
459
530
  const compactionSummaryMessage = createCompactionSummaryAgentMessage(args.compactionEntry);
460
- const serializedPiHistoryInput = serializeMessagesToResponsesInput(args.model, [
531
+ const replayMatch = findReplayMatch({
532
+ model: args.model,
533
+ payloadInput: args.payload.input,
534
+ freshPreamble,
461
535
  compactionSummaryMessage,
462
- ...preCompactionKeptMessages,
463
- ...postCompactionTailMessages,
464
- ]);
465
- const originalPiReplayInput: ResponsesInputItem[] = [
466
- ...freshPreamble.leadingInput,
467
- ...serializedPiHistoryInput,
468
- ...freshPreamble.trailingInput,
469
- ];
470
-
471
- if (!areEquivalentValues(args.payload.input, originalPiReplayInput)) {
472
- const parity = compareResponsesInputParity(args.payload.input, originalPiReplayInput);
536
+ preCompactionEntries,
537
+ postCompactionEntries,
538
+ });
539
+
540
+ if (!replayMatch) {
541
+ const compactionSummaryInput = serializeMessagesToResponsesInput(args.model, [compactionSummaryMessage]);
542
+ const expectedInput = [
543
+ ...freshPreamble.leadingInput,
544
+ ...compactionSummaryInput,
545
+ ...serializeMessagesToResponsesInput(args.model, collectReplayMessages(preCompactionEntries)),
546
+ ...serializeMessagesToResponsesInput(args.model, collectReplayMessages(postCompactionEntries)),
547
+ ...freshPreamble.trailingInput,
548
+ ];
549
+ const parity = compareResponsesInputParity(args.payload.input, expectedInput);
473
550
  return {
474
551
  ok: false,
475
552
  reason: "expected-pi-replay-mismatch",
@@ -484,7 +561,7 @@ function buildNativeReplaySegmentsInternal<TApi extends Api>(args: {
484
561
  const freshPreambleCount = freshPreamble.leadingInput.length;
485
562
  const trailingPreambleCount = freshPreamble.trailingInput.length;
486
563
  const compactionSummaryCount = serializeMessagesToResponsesInput(args.model, [compactionSummaryMessage]).length;
487
- const preCompactionKeptCount = serializeMessagesToResponsesInput(args.model, preCompactionKeptMessages).length;
564
+ const preCompactionKeptCount = replayMatch.preCompactionKept.input.length;
488
565
  const tailStartIndex = freshPreambleCount + compactionSummaryCount + preCompactionKeptCount;
489
566
  const tailEndIndex = args.payload.input.length - trailingPreambleCount;
490
567
  const actualCompactionSummary = cloneResponsesInputSlice(
@@ -496,8 +573,11 @@ function buildNativeReplaySegmentsInternal<TApi extends Api>(args: {
496
573
  freshPreambleCount + compactionSummaryCount + preCompactionKeptCount,
497
574
  ),
498
575
  );
499
- const actualPostCompactionTail = cloneResponsesInputSlice(args.payload.input.slice(tailStartIndex, tailEndIndex));
500
- const contextPostCompactionTail = serializeMessagesToResponsesInput(args.model, contextPostCompactionTailMessages);
576
+ const actualPostCompactionTail = replayMatch.actualPostCompactionTail;
577
+ const contextPostCompactionTail = [
578
+ ...serializeMessagesToResponsesInput(args.model, contextPostCompactionTailMessages),
579
+ ...replayMatch.extraPostCompactionTail,
580
+ ];
501
581
  if (!actualCompactionSummary || !actualPreCompactionKeptWindow || !actualPostCompactionTail) {
502
582
  return {
503
583
  ok: false,
@@ -507,7 +587,7 @@ function buildNativeReplaySegmentsInternal<TApi extends Api>(args: {
507
587
 
508
588
  const preCompactionKeptWindow = createReplaySlice(
509
589
  preCompactionEntries,
510
- preCompactionKeptMessages,
590
+ replayMatch.preCompactionKept.messages,
511
591
  actualPreCompactionKeptWindow,
512
592
  );
513
593
  const postCompactionTail = createReplaySlice(
@@ -528,7 +608,7 @@ function buildNativeReplaySegmentsInternal<TApi extends Api>(args: {
528
608
  preCompactionKeptWindow,
529
609
  compactedWindow,
530
610
  postCompactionTail,
531
- originalPiReplayInput,
611
+ originalPiReplayInput: replayMatch.originalPiReplayInput,
532
612
  replayInput: [
533
613
  ...freshPreamble.leadingInput,
534
614
  ...compactedWindow,