@cortexkit/pi-magic-context 0.49.14 → 0.49.15

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/dist/index.js CHANGED
@@ -27,6 +27,7 @@ import {
27
27
  claimConfigParseFailuresOnce,
28
28
  parseJsoncRecovering,
29
29
  detectConfigFile,
30
+ OPENCODE_OUTPUT_CAP,
30
31
  MIN_PLAUSIBLE_CONTEXT_LIMIT,
31
32
  catalogOutputReserve,
32
33
  deriveWindowGeometry,
@@ -247,7 +248,7 @@ import {
247
248
  registerTodoStateLifecycle,
248
249
  syncCtxMemoryToolEnabled,
249
250
  registerMagicContextTools
250
- } from "./index-65kty5te.js";
251
+ } from "./index-hshd96pt.js";
251
252
  import {
252
253
  canonicalModelIdentity,
253
254
  piModelRefToCanonical,
@@ -772,10 +773,12 @@ import {
772
773
  DREAMER_PRIMER_INVESTIGATOR_ALLOWED_TOOLS,
773
774
  buildHiddenAgentRegistrations,
774
775
  logTemperatureDecision,
776
+ readHostSystemPrompt,
775
777
  subagentStepCap,
776
778
  SubagentTelemetry,
777
- readHostSystemPrompt
778
- } from "./index-y29y2j2w.js";
779
+ HISTORIAN_MAX_OUTPUT_TOKENS_ENV2,
780
+ SUBAGENT_OUTPUT_CEILING_ENV2
781
+ } from "./index-ajfpyk0x.js";
779
782
  import {
780
783
  PiTagHydrationError,
781
784
  getPiTagSnapshotView,
@@ -3506,7 +3509,7 @@ function startHostStallProfilerSwitch() {
3506
3509
  // package.json
3507
3510
  var package_default = {
3508
3511
  name: "@cortexkit/pi-magic-context",
3509
- version: "0.49.14",
3512
+ version: "0.49.15",
3510
3513
  type: "module",
3511
3514
  description: "Pi and OMP coding agent extension for Magic Context — cross-session memory and context management",
3512
3515
  main: "dist/index.js",
@@ -3570,10 +3573,12 @@ var package_default = {
3570
3573
  "@types/better-sqlite3": "^7.6.13",
3571
3574
  "@types/bun": "^1.3.10",
3572
3575
  "@types/node": "^22.20.0",
3576
+ "omp-coding-agent-1812": "npm:@oh-my-pi/pi-coding-agent@18.12.3",
3573
3577
  "pi-agent-core-087": "npm:@earendil-works/pi-agent-core@0.87.1",
3574
3578
  "pi-ai-086": "npm:@earendil-works/pi-ai@0.86.0",
3575
3579
  "pi-coding-agent-086": "npm:@earendil-works/pi-coding-agent@0.86.0",
3576
3580
  "pi-coding-agent-087": "npm:@earendil-works/pi-coding-agent@0.87.1",
3581
+ "pi-coding-agent-130": "npm:@earendil-works/pi-coding-agent@1.3.0",
3577
3582
  typebox: "^1.3.1",
3578
3583
  typescript: "^5.8.0"
3579
3584
  },
@@ -4690,6 +4695,7 @@ var AGENT_STEPS = {
4690
4695
  [DREAMER_PRIMER_INVESTIGATOR_AGENT]: 40,
4691
4696
  [DREAMER_RETROSPECTIVE_AGENT]: 40
4692
4697
  };
4698
+ var DISPOSED_CHILDREN_KEY = Symbol.for("@cortexkit/magic-context/v2/disposed-hidden-children");
4693
4699
  class HiddenAgentStepLimit extends Error {
4694
4700
  agent;
4695
4701
  cap;
@@ -5915,6 +5921,7 @@ Examples:
5915
5921
  - Every displayed raw message ordinal MUST appear in exactly one compartment. Gaps between compartments are invalid. When a displayed block is pure tool-only noise with no narrative text, do NOT skip it — extend the preceding compartment's \`end\` to absorb the range, or fold it into the current compartment if it's part of an ongoing work unit. Never create a dedicated compartment just to cover a tool-only run.
5916
5922
  - If a chunk is entirely tool-only with no narrative text (a long autonomous coding stretch), produce a single compartment whose narrative is derived from what the tools collectively accomplished.
5917
5923
  - If the chunk ends mid-topic, leave the unfinished portion out and report its first message index in \`<unprocessed_from>\`.
5924
+ - If every message in the chunk is covered by a compartment, nothing is unprocessed: set \`<unprocessed_from>\` to the chunk's last message index + 1. Never write \`0\` or the last covered index in that case.
5918
5925
 
5919
5926
  ---
5920
5927
 
@@ -6920,16 +6927,19 @@ function validateParsedCompartments(compartments, chunkStart, chunkEnd, unproces
6920
6927
  expectedStart = compartment.endMessage + 1;
6921
6928
  }
6922
6929
  if (unprocessedFrom !== null) {
6930
+ if (expectedStart <= chunkEnd) {
6931
+ if (unprocessedFrom !== expectedStart) {
6932
+ return `<unprocessed_from> ${unprocessedFrom} does not match next uncovered message ${expectedStart}`;
6933
+ }
6934
+ return null;
6935
+ }
6923
6936
  if (unprocessedFrom === chunkEnd + 1) {
6924
6937
  return null;
6925
6938
  }
6926
6939
  if (unprocessedFrom < chunkStart || unprocessedFrom > chunkEnd) {
6927
6940
  return `<unprocessed_from> ${unprocessedFrom} is outside chunk ${chunkStart}-${chunkEnd}`;
6928
6941
  }
6929
- if (unprocessedFrom !== expectedStart) {
6930
- return `<unprocessed_from> ${unprocessedFrom} does not match next uncovered message ${expectedStart}`;
6931
- }
6932
- return null;
6942
+ return `<unprocessed_from> ${unprocessedFrom} does not match completed chunk boundary ${chunkEnd + 1}`;
6933
6943
  }
6934
6944
  if (expectedStart <= chunkEnd) {
6935
6945
  return `output left uncovered messages ${expectedStart}-${chunkEnd} without <unprocessed_from>`;
@@ -16463,6 +16473,7 @@ var VERIFY_BATCH_SIZE = 5;
16463
16473
  var VERIFY_TOKENS_PER_MEMORY = 1e5;
16464
16474
  var VERIFY_RUN_TOKEN_BUDGET = 2500000;
16465
16475
  var VERIFY_RUN_SLICE_MS = 240000;
16476
+ var VERIFY_IN_FLIGHT_GRACE_MS = 120000;
16466
16477
  function verifyBatchTokenBudget(size, configured) {
16467
16478
  return Math.min(configured ?? Number.MAX_SAFE_INTEGER, size * VERIFY_TOKENS_PER_MEMORY);
16468
16479
  }
@@ -16549,7 +16560,15 @@ async function runVerifyWithCooldown(args) {
16549
16560
  const runTokenBudget = Math.min(args.tokenBudget ?? VERIFY_RUN_TOKEN_BUDGET, VERIFY_RUN_TOKEN_BUDGET);
16550
16561
  try {
16551
16562
  for (let i = 0;i < batches.length; i += 1) {
16552
- const remainingMs = Math.max(0, Math.min(args.deadline, sliceDeadline) - Date.now());
16563
+ const now = Date.now();
16564
+ const startCutoff = Math.min(args.deadline, sliceDeadline);
16565
+ const hardStop = Math.min(args.deadline, sliceDeadline + VERIFY_IN_FLIGHT_GRACE_MS);
16566
+ const remainingMs = Math.max(0, hardStop - now);
16567
+ if (now >= startCutoff) {
16568
+ result.stopReason = "deadline";
16569
+ log2(`[dreamer] ${args.forceBroad ? "verify-broad" : "verify"}: stopping before batch ${i + 1}/${batches.length} — the run deadline passed ${now - startCutoff}ms ago`);
16570
+ break;
16571
+ }
16553
16572
  if (remainingMs < VERIFY_BATCH_FLOOR_MS) {
16554
16573
  result.stopReason = "deadline";
16555
16574
  log2(`[dreamer] ${args.forceBroad ? "verify-broad" : "verify"}: stopping before batch ${i + 1}/${batches.length} — remaining budget ${remainingMs}ms is below the ${VERIFY_BATCH_FLOOR_MS}ms batch floor`);
@@ -19894,6 +19913,7 @@ import { createInterface } from "node:readline";
19894
19913
  import { StringDecoder } from "node:string_decoder";
19895
19914
  import { fileURLToPath } from "node:url";
19896
19915
  var PI_CODING_AGENT_MODULE = "@earendil-works/pi-coding-agent";
19916
+ var HIDDEN_CHILD_OUTPUT_CEILING = OPENCODE_OUTPUT_CAP;
19897
19917
  var PI_CODING_AGENT_PACKAGE_NAMES = new Set([
19898
19918
  PI_CODING_AGENT_MODULE,
19899
19919
  "@oh-my-pi/pi-coding-agent"
@@ -20631,6 +20651,8 @@ class PiSubagentRunner {
20631
20651
  let child;
20632
20652
  const parentEnv = { ...process.env };
20633
20653
  delete parentEnv.MAGIC_CONTEXT_HISTORIAN_TEMPERATURE;
20654
+ delete parentEnv[HISTORIAN_MAX_OUTPUT_TOKENS_ENV2];
20655
+ delete parentEnv[SUBAGENT_OUTPUT_CEILING_ENV2];
20634
20656
  try {
20635
20657
  child = inRootAsyncContext2(() => this.spawnImpl(this.invocation.command, [...this.invocation.prefixArgs, ...this.extraArgs, ...args], {
20636
20658
  windowsHide: true,
@@ -20645,8 +20667,10 @@ class PiSubagentRunner {
20645
20667
  MAGIC_CONTEXT_HISTORIAN_TEMPERATURE: String(options.temperature)
20646
20668
  } : {},
20647
20669
  ...options.maxOutputTokens !== undefined ? {
20648
- MAGIC_CONTEXT_HISTORIAN_MAX_OUTPUT_TOKENS: String(options.maxOutputTokens)
20649
- } : {}
20670
+ [HISTORIAN_MAX_OUTPUT_TOKENS_ENV2]: String(options.maxOutputTokens)
20671
+ } : {
20672
+ [SUBAGENT_OUTPUT_CEILING_ENV2]: String(HIDDEN_CHILD_OUTPUT_CEILING)
20673
+ }
20650
20674
  },
20651
20675
  stdio: [
20652
20676
  deliverViaStdin || rpcBudget ? "pipe" : "ignore",
@@ -34325,6 +34349,255 @@ function isOmpUnmanagedCaptureRequest(payload) {
34325
34349
  return last?.role === "user" && firstText(last.content, request.textType)?.startsWith(CAPTURE_PREFIX) === true;
34326
34350
  }
34327
34351
 
34352
+ // src/pi-dispatch-chain.ts
34353
+ import { isDeepStrictEqual } from "node:util";
34354
+
34355
+ // src/pi-dispatch-tool-ids.ts
34356
+ function record4(value) {
34357
+ return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
34358
+ }
34359
+ var sanitize = (id) => id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
34360
+ function hash2(id) {
34361
+ return typeof Bun === "undefined" ? undefined : Bun.hash(id).toString(36);
34362
+ }
34363
+ function responsesComponent(id) {
34364
+ const sep = id.search(/[\n|]/);
34365
+ return sep > 0 ? id.slice(0, sep) : id;
34366
+ }
34367
+ function codexCallId(id) {
34368
+ if (!id) {
34369
+ const suffix = hash2("empty");
34370
+ return suffix === undefined ? undefined : `call_${suffix}`;
34371
+ }
34372
+ const sep = id.search(/[\n|]/);
34373
+ const base = sep > 0 ? id.slice(0, sep) : sep === 0 ? id.slice(1) : id;
34374
+ const normalized = base.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+$/, "");
34375
+ if (normalized && normalized.length <= 64 && normalized === base)
34376
+ return normalized;
34377
+ const suffix = hash2(base || id);
34378
+ if (suffix === undefined)
34379
+ return;
34380
+ return `${(normalized || "call").slice(0, Math.max(0, 63 - suffix.length))}_${suffix}`.slice(0, 64);
34381
+ }
34382
+ function piToolCallWireId(id, model, source) {
34383
+ const origin = record4(source);
34384
+ const same = origin !== undefined && origin.provider === model.provider && origin.api === model.api && origin.model === model.id;
34385
+ const compat = record4(model.compat);
34386
+ switch (model.api) {
34387
+ case "openai-completions": {
34388
+ if (compat?.requiresMistralToolIds === true) {
34389
+ const normalized = id.replace(/[^a-zA-Z0-9]/g, "");
34390
+ return (normalized + "ABCDEFGHI".slice(0, Math.max(0, 9 - normalized.length))).slice(0, 9);
34391
+ }
34392
+ if (!same && id.includes("|"))
34393
+ return id.split("|", 1)[0].replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 40);
34394
+ return compat?.usesOpenAIToolCallIdLimit === true ? id.slice(0, 40) : id;
34395
+ }
34396
+ case "anthropic-messages": {
34397
+ if (same && compat?.officialEndpoint !== true)
34398
+ return id;
34399
+ const normalized = sanitize(id);
34400
+ if (normalized)
34401
+ return normalized;
34402
+ const suffix = hash2(id);
34403
+ return suffix === undefined ? undefined : `toolu_${suffix}`;
34404
+ }
34405
+ case "bedrock-converse-stream":
34406
+ return sanitize(id);
34407
+ case "google-generative-ai":
34408
+ case "google-gemini-cli":
34409
+ case "google-vertex":
34410
+ return same ? id : sanitize(id);
34411
+ case "openai-responses":
34412
+ case "azure-openai-responses": {
34413
+ const sep = id.search(/[\n|]/);
34414
+ const simple = sep < 0 && id.length <= 64 && /^[a-zA-Z0-9_-]+$/.test(id);
34415
+ const foreign = origin && (origin.provider !== model.provider || origin.api !== model.api);
34416
+ return !same && !simple && (foreign || sep >= 0 || id.length > 64) ? codexCallId(responsesComponent(id)) : responsesComponent(id);
34417
+ }
34418
+ case "openai-codex-responses":
34419
+ return codexCallId(responsesComponent(id));
34420
+ default:
34421
+ return id;
34422
+ }
34423
+ }
34424
+
34425
+ // src/pi-dispatch-chain-tail.ts
34426
+ function object(value) {
34427
+ return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
34428
+ }
34429
+ var OMITTED_IMAGE = "[image omitted: model does not support vision]";
34430
+ function piEncodeChainTail(messages, assistant, responseItems, model) {
34431
+ const harmony = object(model.identity)?.class === "gpt-oss";
34432
+ const text = (value) => {
34433
+ const wellFormed = value.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "�");
34434
+ return harmony ? wellFormed.replace(/<\|(start|end|message|channel|constrain|return|call)\|>/g, "<\\|$1\\|>") : wellFormed;
34435
+ };
34436
+ const supportsImages = model.input?.includes("image") === true;
34437
+ const image = (block) => {
34438
+ const detail = block.detail === "original" && object(model.compat)?.supportsImageDetailOriginal !== true ? "auto" : block.detail ?? "auto";
34439
+ const file = object(block.providerFile);
34440
+ if (file?.provider === "openai" && typeof file.id === "string" && file.id)
34441
+ return { type: "input_image", detail, file_id: file.id };
34442
+ if (typeof block.url !== "string" && (typeof block.mimeType !== "string" || typeof block.data !== "string"))
34443
+ return;
34444
+ return {
34445
+ type: "input_image",
34446
+ detail,
34447
+ image_url: block.url ?? `data:${block.mimeType};base64,${block.data}`
34448
+ };
34449
+ };
34450
+ const items = [];
34451
+ for (const value of messages) {
34452
+ const message = object(value);
34453
+ if (!message || message.providerPayload !== undefined)
34454
+ return;
34455
+ const user = message.role === "user" || message.role === "developer";
34456
+ if (!user && message.role !== "toolResult")
34457
+ return;
34458
+ const content = typeof message.content === "string" && user ? [{ type: "text", text: message.content }] : message.content;
34459
+ if (!Array.isArray(content))
34460
+ return;
34461
+ const texts = [];
34462
+ const images = [];
34463
+ const ordered = [];
34464
+ for (const value of content) {
34465
+ const block = object(value);
34466
+ if (block?.type === "text" && typeof block.text === "string") {
34467
+ texts.push(block.text);
34468
+ if (!user || block.text.trim())
34469
+ ordered.push({ type: "input_text", text: text(block.text) });
34470
+ } else if (block?.type === "image") {
34471
+ const encoded = image(block);
34472
+ if (!encoded)
34473
+ return;
34474
+ images.push(encoded);
34475
+ if (supportsImages)
34476
+ ordered.push(encoded);
34477
+ } else
34478
+ return;
34479
+ }
34480
+ if (user) {
34481
+ const input = texts.filter((value) => value.trim()).map((value) => ({ type: "input_text", text: text(value) }));
34482
+ if (supportsImages)
34483
+ input.push(...images);
34484
+ else if (images.length)
34485
+ input.push({ type: "input_text", text: OMITTED_IMAGE });
34486
+ if (input.length)
34487
+ items.push({ role: message.role, content: input });
34488
+ continue;
34489
+ }
34490
+ if (typeof message.toolCallId !== "string" || message.providerMetadata !== undefined)
34491
+ return;
34492
+ const id = piToolCallWireId(message.toolCallId, model, assistant);
34493
+ const call = responseItems.map(object).find((item) => item?.call_id === id);
34494
+ if (!id || call?.type !== "function_call" && call?.type !== "custom_tool_call")
34495
+ return;
34496
+ const joined = texts.join(`
34497
+ `);
34498
+ const output = images.length && supportsImages ? ordered : text(images.length && !supportsImages ? joined ? `${joined}
34499
+ ${OMITTED_IMAGE}` : OMITTED_IMAGE : joined);
34500
+ items.push({
34501
+ type: call.type === "custom_tool_call" ? "custom_tool_call_output" : "function_call_output",
34502
+ call_id: id,
34503
+ output
34504
+ });
34505
+ }
34506
+ return items;
34507
+ }
34508
+
34509
+ // src/pi-dispatch-chain.ts
34510
+ function object2(value) {
34511
+ return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
34512
+ }
34513
+ function piChainCapableApi(api) {
34514
+ return api === "openai-codex-responses" || api === "openai-responses" || api === "azure-openai-responses";
34515
+ }
34516
+ function piPreparedHistory(messages, model) {
34517
+ const snapshots = [];
34518
+ const responseIds = [];
34519
+ for (const message of messages) {
34520
+ const fields = lkgContentFields(message);
34521
+ if (!fields)
34522
+ return;
34523
+ snapshots.push({ id: "", fields });
34524
+ const source = object2(message);
34525
+ responseIds.push(source?.role === "assistant" && typeof source.responseId === "string" && source.responseId.length > 0 ? source.responseId : undefined);
34526
+ }
34527
+ const prepared = { snapshots, responseIds };
34528
+ let index = responseIds.length - 1;
34529
+ while (index >= 0 && responseIds[index] === undefined)
34530
+ index--;
34531
+ const assistant = object2(messages[index]);
34532
+ const response = piChainResponse(assistant);
34533
+ if (model && assistant && response) {
34534
+ const delta = piEncodeChainTail(messages.slice(index + 1), assistant, response.responseItems, model);
34535
+ if (delta)
34536
+ prepared.continuation = { index, ...response, delta };
34537
+ }
34538
+ return prepared;
34539
+ }
34540
+ function piChainedRequest(payload) {
34541
+ const body = object2(payload);
34542
+ if (!body || body.previous_response_id === undefined)
34543
+ return;
34544
+ const id = body.previous_response_id;
34545
+ if (body.messages !== undefined || !Array.isArray(body.input) || typeof id !== "string" || !id)
34546
+ throw new Error("invalid chained continuation frame");
34547
+ return { previousResponseId: id, delta: body.input };
34548
+ }
34549
+ function piChainResponse(message) {
34550
+ const source = object2(message);
34551
+ if (source?.role !== "assistant")
34552
+ return;
34553
+ if (source.stopReason !== "stop" && source.stopReason !== "toolUse")
34554
+ return;
34555
+ if (typeof source.responseId !== "string" || !source.responseId)
34556
+ return;
34557
+ const payload = object2(source.providerPayload);
34558
+ if (payload?.type !== "openaiResponsesHistory" || payload.dt !== true || !Array.isArray(payload.items))
34559
+ return;
34560
+ return {
34561
+ responseId: source.responseId,
34562
+ responseItems: structuredClone(payload.items)
34563
+ };
34564
+ }
34565
+ function piExpandChainedRequest(payload, chained, anchor, prepared, pass) {
34566
+ if (!anchor)
34567
+ return {
34568
+ refusal: "no completed managed response is recorded for this continuation"
34569
+ };
34570
+ if (anchor.supersededBy !== undefined && (anchor.supersededBy !== pass.current || !pass.resend))
34571
+ return {
34572
+ refusal: "the last managed request has no completed response"
34573
+ };
34574
+ if (chained.previousResponseId !== anchor.responseId)
34575
+ return {
34576
+ refusal: "continuation does not follow the last managed request's response"
34577
+ };
34578
+ if (!prepared)
34579
+ return { refusal: "this pass's prepared history was not recorded" };
34580
+ const carried = anchor.prepared.snapshots.length;
34581
+ if (exactReusablePrefix(prepared.snapshots, anchor.prepared.snapshots) !== carried)
34582
+ return {
34583
+ refusal: "prepared history does not extend the previous managed request"
34584
+ };
34585
+ if (prepared.responseIds[carried] !== anchor.responseId)
34586
+ return {
34587
+ refusal: "prepared history does not continue from the previous managed response"
34588
+ };
34589
+ const continuation = prepared.continuation;
34590
+ if (!continuation || continuation.index !== carried || !isDeepStrictEqual(continuation.responseItems, anchor.responseItems))
34591
+ return {
34592
+ refusal: "prepared response or tail encoding cannot continue the recorded response"
34593
+ };
34594
+ if (!isDeepStrictEqual(continuation.delta, chained.delta))
34595
+ return { refusal: "delta differs from the prepared provider input tail" };
34596
+ const input = [...anchor.input, ...anchor.responseItems, ...chained.delta];
34597
+ const { previous_response_id: _previous, ...rest } = payload;
34598
+ return { payload: { ...rest, input }, input };
34599
+ }
34600
+
34328
34601
  // src/pi-dispatch-google.ts
34329
34602
  function piGoogleConversation(payload) {
34330
34603
  if (!payload || typeof payload !== "object")
@@ -34472,12 +34745,12 @@ function piHasManagedSignature(payload, signature) {
34472
34745
  }
34473
34746
 
34474
34747
  // src/pi-dispatch-agent-history.ts
34475
- function object(value) {
34748
+ function object3(value) {
34476
34749
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
34477
34750
  }
34478
34751
  function piAgentHistory(messages, api) {
34479
34752
  return messages.flatMap((value) => {
34480
- const message = object(value);
34753
+ const message = object3(value);
34481
34754
  if (!message)
34482
34755
  return [value];
34483
34756
  if (message.role === "compactionSummary") {
@@ -34502,7 +34775,7 @@ function piAgentHistory(messages, api) {
34502
34775
  const content = typeof message.content === "string" ? [{ type: "text", text: message.content }] : message.content;
34503
34776
  const userInvoked = message.role === "custom" && message.attribution === "user";
34504
34777
  if (userInvoked && message.customType === "collab-prompt") {
34505
- const text = content.filter((part) => object(part)?.type === "text").map((part) => object(part)?.text).join(`
34778
+ const text = content.filter((part) => object3(part)?.type === "text").map((part) => object3(part)?.text).join(`
34506
34779
  `);
34507
34780
  return [
34508
34781
  {
@@ -34513,18 +34786,18 @@ function piAgentHistory(messages, api) {
34513
34786
  type: "text",
34514
34787
  text: text.length ? "User interjection envelope" : ""
34515
34788
  },
34516
- ...content.filter((part) => object(part)?.type === "image")
34789
+ ...content.filter((part) => object3(part)?.type === "image")
34517
34790
  ]
34518
34791
  }
34519
34792
  ];
34520
34793
  }
34521
34794
  if (userInvoked && message.customType === "skill-prompt")
34522
34795
  return [{ ...message, role: "user", content }];
34523
- const images = content.filter((part) => object(part)?.type === "image");
34796
+ const images = content.filter((part) => object3(part)?.type === "image");
34524
34797
  const developerRole = api === "ollama-chat" && message.attribution !== "user" ? "developer" : "user";
34525
34798
  if (!images.length)
34526
34799
  return [{ ...message, role: developerRole, content }];
34527
- const texts = content.filter((part) => object(part)?.type === "text");
34800
+ const texts = content.filter((part) => object3(part)?.type === "text");
34528
34801
  return [
34529
34802
  ...texts.length ? [{ ...message, role: developerRole, content: texts }] : [],
34530
34803
  {
@@ -34542,7 +34815,7 @@ function piAgentHistory(messages, api) {
34542
34815
  // src/pi-dispatch-chat-history.ts
34543
34816
  var MAX_EXACT_UNITS = 32 * 1024 * 1024;
34544
34817
  var IMAGE_CAPTION = "Attached image(s) from tool result:";
34545
- function object2(value) {
34818
+ function object4(value) {
34546
34819
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
34547
34820
  }
34548
34821
  function omitsAssistant(message, model, compat) {
@@ -34551,7 +34824,7 @@ function omitsAssistant(message, model, compat) {
34551
34824
  let thinking = false;
34552
34825
  let hasTextBlock = false;
34553
34826
  for (const value of message.content) {
34554
- const block = object2(value);
34827
+ const block = object4(value);
34555
34828
  if (!block)
34556
34829
  return false;
34557
34830
  if (block.type === "text") {
@@ -34576,14 +34849,14 @@ function omitsAssistant(message, model, compat) {
34576
34849
  function piChatHistoryPlan(messages, model) {
34577
34850
  if (model?.api !== "openai-completions")
34578
34851
  return;
34579
- const compat = object2(model.compat) ?? {};
34852
+ const compat = object4(model.compat) ?? {};
34580
34853
  const calls = new Set;
34581
34854
  for (const value of messages) {
34582
- const message = object2(value);
34855
+ const message = object4(value);
34583
34856
  if (message?.role !== "assistant" || !Array.isArray(message.content))
34584
34857
  continue;
34585
34858
  for (const value of message.content) {
34586
- const block = object2(value);
34859
+ const block = object4(value);
34587
34860
  if (block?.type === "toolCall" && typeof block.id === "string")
34588
34861
  calls.add(block.id);
34589
34862
  }
@@ -34592,7 +34865,7 @@ function piChatHistoryPlan(messages, model) {
34592
34865
  let pending = new Set;
34593
34866
  let exactUnits = 0;
34594
34867
  for (let index = 0;index < messages.length; index++) {
34595
- const message = object2(messages[index]);
34868
+ const message = object4(messages[index]);
34596
34869
  if (!message)
34597
34870
  return;
34598
34871
  if ((message.role === "bashExecution" || message.role === "pythonExecution") && message.excludeFromContext === true)
@@ -34604,7 +34877,7 @@ function piChatHistoryPlan(messages, model) {
34604
34877
  continue;
34605
34878
  if (Array.isArray(message.content))
34606
34879
  for (const value of message.content) {
34607
- const block = object2(value);
34880
+ const block = object4(value);
34608
34881
  if (block?.type === "toolCall" && typeof block.id === "string")
34609
34882
  pending.add(block.id);
34610
34883
  }
@@ -34616,7 +34889,7 @@ function piChatHistoryPlan(messages, model) {
34616
34889
  return;
34617
34890
  const parts = [];
34618
34891
  for (const value of message.content) {
34619
- const part = object2(value);
34892
+ const part = object4(value);
34620
34893
  if (part?.type === "text" && typeof part.text === "string" && part.text.trim())
34621
34894
  parts.push(part.text);
34622
34895
  }
@@ -34649,14 +34922,14 @@ ${parts.join(`
34649
34922
  };
34650
34923
  const vision = model.input?.includes("image") === true && compat.stripImageInput !== true;
34651
34924
  for (const step of transformed) {
34652
- const message = step.kind === "source" ? object2(messages[step.index]) : undefined;
34925
+ const message = step.kind === "source" ? object4(messages[step.index]) : undefined;
34653
34926
  if (message?.role !== "toolResult")
34654
34927
  flushImages();
34655
34928
  steps.push(step);
34656
34929
  if (message?.role !== "toolResult" || !vision || !Array.isArray(message.content))
34657
34930
  continue;
34658
34931
  for (const value of message.content) {
34659
- const block = object2(value);
34932
+ const block = object4(value);
34660
34933
  if (block?.type !== "image")
34661
34934
  continue;
34662
34935
  if (compat.requiresAssistantAfterToolResult === true)
@@ -34680,12 +34953,12 @@ ${parts.join(`
34680
34953
  function piMatchesChatImages(content, urls) {
34681
34954
  if (!Array.isArray(content) || content.length !== urls.length + 1)
34682
34955
  return false;
34683
- const caption = object2(content[0]);
34956
+ const caption = object4(content[0]);
34684
34957
  if (caption?.type !== "text" || caption.text !== IMAGE_CAPTION || Object.keys(caption).length !== 2)
34685
34958
  return false;
34686
34959
  for (let i = 0;i < urls.length; i++) {
34687
- const block = object2(content[i + 1]);
34688
- const image = object2(block?.image_url);
34960
+ const block = object4(content[i + 1]);
34961
+ const image = object4(block?.image_url);
34689
34962
  if (block?.type !== "image_url" || Object.keys(block).length !== 2 || !image || Object.keys(image).length !== 1 || image.url !== urls[i])
34690
34963
  return false;
34691
34964
  }
@@ -34693,22 +34966,22 @@ function piMatchesChatImages(content, urls) {
34693
34966
  }
34694
34967
 
34695
34968
  // src/pi-dispatch-image-budget.ts
34696
- function object3(value) {
34969
+ function object5(value) {
34697
34970
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
34698
34971
  }
34699
34972
  function piImageBudgetPlan(model) {
34700
- if (!model?.input?.includes("image") || object3(model.compat)?.stripImageInput === true)
34973
+ if (!model?.input?.includes("image") || object5(model.compat)?.stripImageInput === true)
34701
34974
  return;
34702
34975
  return {
34703
34976
  count: 0,
34704
34977
  api: model.api,
34705
34978
  rows: new Map,
34706
- hoistToolImages: model.api?.startsWith("google-") === true && object3(model.compat)?.multimodalFunctionResponse !== true || model.api === "bedrock-converse-stream" && model.requiresToolResultImageHoisting === true,
34979
+ hoistToolImages: model.api?.startsWith("google-") === true && object5(model.compat)?.multimodalFunctionResponse !== true || model.api === "bedrock-converse-stream" && model.requiresToolResultImageHoisting === true,
34707
34980
  hoistErrorImages: model.api === "anthropic-messages" || model.api === "bedrock-converse-stream"
34708
34981
  };
34709
34982
  }
34710
34983
  function inputImage(block, api) {
34711
- const file = object3(block.providerFile);
34984
+ const file = object5(block.providerFile);
34712
34985
  if (api === "ollama-chat")
34713
34986
  return { kind: "bytes", value: String(block.data ?? "") };
34714
34987
  if ((api?.endsWith("responses") && file?.provider === "openai" || api === "anthropic-messages" && file?.provider === "anthropic") && typeof file?.id === "string")
@@ -34728,7 +35001,7 @@ function piRecordImages(plan, row, source) {
34728
35001
  return;
34729
35002
  const images = [];
34730
35003
  for (const value of source.content) {
34731
- const block = object3(value);
35004
+ const block = object5(value);
34732
35005
  if (block?.type === "image")
34733
35006
  images.push(inputImage(block, plan.api));
34734
35007
  }
@@ -34754,20 +35027,20 @@ function piWireImages(content, ollamaImages) {
34754
35027
  return [];
34755
35028
  const images = [];
34756
35029
  for (const value of content) {
34757
- const block = object3(value);
35030
+ const block = object5(value);
34758
35031
  if (!block)
34759
35032
  continue;
34760
- const source = object3(block.source);
34761
- const inline = object3(block.inlineData);
34762
- const file = object3(block.fileData);
34763
- const bedrock = object3(block.image);
35033
+ const source = object5(block.source);
35034
+ const inline = object5(block.inlineData);
35035
+ const file = object5(block.fileData);
35036
+ const bedrock = object5(block.image);
34764
35037
  if (block.type === "image_url" || block.type === "input_image") {
34765
35038
  if (typeof block.file_id === "string")
34766
35039
  images.push({ kind: "file", value: block.file_id });
34767
35040
  else
34768
35041
  images.push({
34769
35042
  kind: "url",
34770
- value: String(typeof block.image_url === "string" ? block.image_url : object3(block.image_url)?.url)
35043
+ value: String(typeof block.image_url === "string" ? block.image_url : object5(block.image_url)?.url)
34771
35044
  });
34772
35045
  } else if (block.type === "image") {
34773
35046
  if (source?.type === "file")
@@ -34791,7 +35064,7 @@ function piWireImages(content, ollamaImages) {
34791
35064
  else if (bedrock)
34792
35065
  images.push({
34793
35066
  kind: "data",
34794
- value: String(object3(bedrock.source)?.bytes),
35067
+ value: String(object5(bedrock.source)?.bytes),
34795
35068
  mime: `image/${bedrock.format}`
34796
35069
  });
34797
35070
  }
@@ -34813,11 +35086,11 @@ function piMatchesImages(actual, expected) {
34813
35086
  return true;
34814
35087
  }
34815
35088
  function piWireImageCount(payload) {
34816
- const body = object3(payload);
35089
+ const body = object5(payload);
34817
35090
  const visit = (value) => {
34818
35091
  if (Array.isArray(value))
34819
35092
  return value.reduce((n, item) => n + visit(item), 0);
34820
- const block = object3(value);
35093
+ const block = object5(value);
34821
35094
  if (!block)
34822
35095
  return 0;
34823
35096
  if (["image", "image_url", "input_image"].includes(String(block.type)) || block.inlineData || block.fileData || block.image)
@@ -34831,12 +35104,12 @@ function piWireImageCount(payload) {
34831
35104
  block.response
34832
35105
  ].reduce((n, item) => n + visit(item), Array.isArray(block.images) ? block.images.length : 0);
34833
35106
  };
34834
- return visit(body?.messages ?? body?.input ?? body?.contents ?? object3(body?.request)?.contents);
35107
+ return visit(body?.messages ?? body?.input ?? body?.contents ?? object5(body?.request)?.contents);
34835
35108
  }
34836
35109
 
34837
35110
  // src/pi-dispatch-responses-history.ts
34838
35111
  var MAX_TEXT_UNITS = 32 * 1024 * 1024;
34839
- function object4(value) {
35112
+ function object6(value) {
34840
35113
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
34841
35114
  }
34842
35115
  function wellFormed(text) {
@@ -34851,7 +35124,7 @@ function textIdentity2(text, phase) {
34851
35124
  function signaturePhase(block) {
34852
35125
  try {
34853
35126
  if (typeof block.textSignature === "string") {
34854
- const signature = object4(JSON.parse(block.textSignature));
35127
+ const signature = object6(JSON.parse(block.textSignature));
34855
35128
  if (signature?.v === 1 && typeof signature.id === "string")
34856
35129
  return signature.phase;
34857
35130
  }
@@ -34871,17 +35144,17 @@ ${wellFormed(text)}
34871
35144
  return;
34872
35145
  }
34873
35146
  function piResponsesAssistantTexts(value, model) {
34874
- const message = object4(value);
35147
+ const message = object6(value);
34875
35148
  if (!message || !Array.isArray(message.content))
34876
35149
  return;
34877
- if (["length", "error", "aborted"].includes(String(message.stopReason)) && !message.content.some((value) => ["text", "toolCall"].includes(String(object4(value)?.type))))
35150
+ if (["length", "error", "aborted"].includes(String(message.stopReason)) && !message.content.some((value) => ["text", "toolCall"].includes(String(object6(value)?.type))))
34878
35151
  return [];
34879
35152
  const texts = [];
34880
35153
  const blocks = [];
34881
35154
  const sameModel = model !== undefined && typeof model.api === "string" && typeof model.id === "string" && typeof model.provider === "string" && message.api === model.api && message.model === model.id && message.provider === model.provider;
34882
35155
  let units = 0;
34883
35156
  for (const value of message.content) {
34884
- const block = object4(value);
35157
+ const block = object6(value);
34885
35158
  if (block?.type === "toolCall")
34886
35159
  continue;
34887
35160
  if (block?.type === "thinking") {
@@ -34891,7 +35164,7 @@ function piResponsesAssistantTexts(value, model) {
34891
35164
  return;
34892
35165
  if (!block.thinking.trim())
34893
35166
  continue;
34894
- const compat = object4(model.compat);
35167
+ const compat = object6(model.compat);
34895
35168
  if (block.summary === false && (compat?.requiresReasoningContentForToolCalls === true || compat?.requiresReasoningContentForAllAssistantTurns === true))
34896
35169
  return;
34897
35170
  const text = demotedThinking(block.thinking, model);
@@ -34911,14 +35184,14 @@ function piResponsesAssistantTexts(value, model) {
34911
35184
  texts.push(textIdentity2(wellFormed(block.text), sameModel ? signaturePhase(block) : undefined));
34912
35185
  blocks.push(block);
34913
35186
  }
34914
- const payload = object4(message.providerPayload);
35187
+ const payload = object6(message.providerPayload);
34915
35188
  if (message.api !== model?.api || typeof model?.id !== "string" || typeof model?.provider !== "string" || message.model !== model?.id || (payload?.provider ?? message.provider) !== model?.provider || payload?.type !== "openaiResponsesHistory" || payload.dt !== true || !Array.isArray(payload.items))
34916
35189
  return texts;
34917
35190
  const replay = [];
34918
35191
  let bound = 0;
34919
35192
  let output = false;
34920
35193
  for (const value of payload.items) {
34921
- const item = object4(value);
35194
+ const item = object6(value);
34922
35195
  if (item?.type === "reasoning")
34923
35196
  continue;
34924
35197
  if (item?.type === "function_call" || item?.type === "custom_tool_call") {
@@ -34929,14 +35202,14 @@ function piResponsesAssistantTexts(value, model) {
34929
35202
  return texts;
34930
35203
  const itemTexts = [];
34931
35204
  for (const value of item.content) {
34932
- const part = object4(value);
35205
+ const part = object6(value);
34933
35206
  const block = blocks[bound];
34934
35207
  if (!block || part?.type !== "output_text" || typeof part.text !== "string")
34935
35208
  return texts;
34936
35209
  let signature;
34937
35210
  try {
34938
35211
  if (typeof block.textSignature === "string")
34939
- signature = object4(JSON.parse(block.textSignature));
35212
+ signature = object6(JSON.parse(block.textSignature));
34940
35213
  } catch {
34941
35214
  return texts;
34942
35215
  }
@@ -34963,7 +35236,7 @@ function piResponsesWireTexts(value, phase) {
34963
35236
  const texts = [];
34964
35237
  let units = 0;
34965
35238
  for (const partValue of value) {
34966
- const part = object4(partValue);
35239
+ const part = object6(partValue);
34967
35240
  if (part?.type !== "output_text" || typeof part.text !== "string")
34968
35241
  return;
34969
35242
  units += part.text.length;
@@ -34974,76 +35247,6 @@ function piResponsesWireTexts(value, phase) {
34974
35247
  return texts;
34975
35248
  }
34976
35249
 
34977
- // src/pi-dispatch-tool-ids.ts
34978
- function record4(value) {
34979
- return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
34980
- }
34981
- var sanitize = (id) => id.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
34982
- function hash2(id) {
34983
- return typeof Bun === "undefined" ? undefined : Bun.hash(id).toString(36);
34984
- }
34985
- function responsesComponent(id) {
34986
- const sep = id.search(/[\n|]/);
34987
- return sep > 0 ? id.slice(0, sep) : id;
34988
- }
34989
- function codexCallId(id) {
34990
- if (!id) {
34991
- const suffix = hash2("empty");
34992
- return suffix === undefined ? undefined : `call_${suffix}`;
34993
- }
34994
- const sep = id.search(/[\n|]/);
34995
- const base = sep > 0 ? id.slice(0, sep) : sep === 0 ? id.slice(1) : id;
34996
- const normalized = base.replace(/[^a-zA-Z0-9_-]/g, "_").replace(/_+$/, "");
34997
- if (normalized && normalized.length <= 64 && normalized === base)
34998
- return normalized;
34999
- const suffix = hash2(base || id);
35000
- if (suffix === undefined)
35001
- return;
35002
- return `${(normalized || "call").slice(0, Math.max(0, 63 - suffix.length))}_${suffix}`.slice(0, 64);
35003
- }
35004
- function piToolCallWireId(id, model, source) {
35005
- const origin = record4(source);
35006
- const same = origin !== undefined && origin.provider === model.provider && origin.api === model.api && origin.model === model.id;
35007
- const compat = record4(model.compat);
35008
- switch (model.api) {
35009
- case "openai-completions": {
35010
- if (compat?.requiresMistralToolIds === true) {
35011
- const normalized = id.replace(/[^a-zA-Z0-9]/g, "");
35012
- return (normalized + "ABCDEFGHI".slice(0, Math.max(0, 9 - normalized.length))).slice(0, 9);
35013
- }
35014
- if (!same && id.includes("|"))
35015
- return id.split("|", 1)[0].replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 40);
35016
- return compat?.usesOpenAIToolCallIdLimit === true ? id.slice(0, 40) : id;
35017
- }
35018
- case "anthropic-messages": {
35019
- if (same && compat?.officialEndpoint !== true)
35020
- return id;
35021
- const normalized = sanitize(id);
35022
- if (normalized)
35023
- return normalized;
35024
- const suffix = hash2(id);
35025
- return suffix === undefined ? undefined : `toolu_${suffix}`;
35026
- }
35027
- case "bedrock-converse-stream":
35028
- return sanitize(id);
35029
- case "google-generative-ai":
35030
- case "google-gemini-cli":
35031
- case "google-vertex":
35032
- return same ? id : sanitize(id);
35033
- case "openai-responses":
35034
- case "azure-openai-responses": {
35035
- const sep = id.search(/[\n|]/);
35036
- const simple = sep < 0 && id.length <= 64 && /^[a-zA-Z0-9_-]+$/.test(id);
35037
- const foreign = origin && (origin.provider !== model.provider || origin.api !== model.api);
35038
- return !same && !simple && (foreign || sep >= 0 || id.length > 64) ? codexCallId(responsesComponent(id)) : responsesComponent(id);
35039
- }
35040
- case "openai-codex-responses":
35041
- return codexCallId(responsesComponent(id));
35042
- default:
35043
- return id;
35044
- }
35045
- }
35046
-
35047
35250
  // src/pi-dispatch-structure.ts
35048
35251
  var MAX_MESSAGES = 1e5;
35049
35252
  var ORPHAN_NOTE = Symbol("prepared orphan tool result");
@@ -35063,11 +35266,11 @@ var TRANSFORM_MESSAGES_APIS = new Set([
35063
35266
  "devin-agent",
35064
35267
  "apple-foundation-models"
35065
35268
  ]);
35066
- function object5(value) {
35269
+ function object7(value) {
35067
35270
  return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
35068
35271
  }
35069
35272
  function messageStructure(value) {
35070
- const message = object5(value);
35273
+ const message = object7(value);
35071
35274
  if (!message)
35072
35275
  return;
35073
35276
  const role = [
@@ -35096,7 +35299,7 @@ function messageStructure(value) {
35096
35299
  }
35097
35300
  if (role === "assistant" && Array.isArray(message.content)) {
35098
35301
  for (const value of message.content) {
35099
- const block = object5(value);
35302
+ const block = object7(value);
35100
35303
  if (block?.type !== "toolCall" && block?.type !== "tool_use")
35101
35304
  continue;
35102
35305
  if (typeof block.id !== "string")
@@ -35118,11 +35321,11 @@ function projectMissingToolResults(messages, api) {
35118
35321
  return pipe > 0 ? id.slice(0, pipe) : id;
35119
35322
  };
35120
35323
  for (const value of messages) {
35121
- const message = object5(value);
35324
+ const message = object7(value);
35122
35325
  if (message?.role !== "assistant" || !Array.isArray(message.content))
35123
35326
  continue;
35124
35327
  for (const value of message.content) {
35125
- const block = object5(value);
35328
+ const block = object7(value);
35126
35329
  if (block?.type !== "toolCall" || typeof block.id !== "string")
35127
35330
  continue;
35128
35331
  if ([
@@ -35142,7 +35345,7 @@ function projectMissingToolResults(messages, api) {
35142
35345
  const pairingId = (id) => !opaqueIds.has(id) && responsesComponents.has(component(id)) ? component(id) : id;
35143
35346
  const lastResult = new Map;
35144
35347
  messages.forEach((value, index) => {
35145
- const message = object5(value);
35348
+ const message = object7(value);
35146
35349
  if (message?.role === "toolResult" && typeof message.toolCallId === "string")
35147
35350
  lastResult.set(pairingId(message.toolCallId), index);
35148
35351
  });
@@ -35173,7 +35376,7 @@ function projectMissingToolResults(messages, api) {
35173
35376
  };
35174
35377
  for (let index = 0;index < messages.length; index++) {
35175
35378
  const value = messages[index];
35176
- const message = object5(value);
35379
+ const message = object7(value);
35177
35380
  if ((message?.role === "bashExecution" || message?.role === "pythonExecution") && message.excludeFromContext === true)
35178
35381
  continue;
35179
35382
  if (message?.role !== "toolResult")
@@ -35184,7 +35387,7 @@ function projectMissingToolResults(messages, api) {
35184
35387
  if (pending.some((call) => !resolved.has(pairingId(call.id))))
35185
35388
  continue;
35186
35389
  const parts = message.content.flatMap((value) => {
35187
- const part = object5(value);
35390
+ const part = object7(value);
35188
35391
  return part?.type === "text" && typeof part.text === "string" && part.text.trim() ? [part.text] : [];
35189
35392
  });
35190
35393
  if (parts.length) {
@@ -35211,7 +35414,7 @@ ${parts.join(`
35211
35414
  if (aborted && typeof timestamp !== "number")
35212
35415
  continue;
35213
35416
  for (const value of message.content) {
35214
- const block = object5(value);
35417
+ const block = object7(value);
35215
35418
  if (block?.type === "toolCall" && typeof block.id === "string")
35216
35419
  pending.push({
35217
35420
  id: block.id,
@@ -35225,7 +35428,7 @@ ${parts.join(`
35225
35428
  function preparePiDispatch(messages, model, omp) {
35226
35429
  let output = messages;
35227
35430
  const structure = buildPiPreparedStructure(messages, model, omp ? (index, source) => {
35228
- if (object5(source.providerPayload)?.type !== "openaiResponsesHistory")
35431
+ if (object7(source.providerPayload)?.type !== "openaiResponsesHistory")
35229
35432
  return;
35230
35433
  if (output === messages)
35231
35434
  output = messages.slice();
@@ -35238,7 +35441,7 @@ function buildPiPreparedStructure(messages, model, prepareUser) {
35238
35441
  if (!messages.length || messages.length > MAX_MESSAGES)
35239
35442
  return;
35240
35443
  for (let index = 0;index < messages.length; index++) {
35241
- const source = object5(messages[index]);
35444
+ const source = object7(messages[index]);
35242
35445
  if (source?.role === "user" || source?.role === "compactionSummary")
35243
35446
  prepareUser?.(index, source);
35244
35447
  }
@@ -35254,7 +35457,7 @@ function buildPiPreparedStructure(messages, model, prepareUser) {
35254
35457
  let valid = true;
35255
35458
  for (let index = 0;index < projectedMessages.length; index++) {
35256
35459
  const message = projectedMessages[index];
35257
- const source = object5(message);
35460
+ const source = object7(message);
35258
35461
  if (rows.length === 0 && (source?.role === "system" || source?.role === "developer"))
35259
35462
  continue;
35260
35463
  if ((source?.role === "bashExecution" || source?.role === "pythonExecution") && source.excludeFromContext === true)
@@ -35278,7 +35481,7 @@ function buildPiPreparedStructure(messages, model, prepareUser) {
35278
35481
  "azure-openai-responses",
35279
35482
  "openai-codex-responses"
35280
35483
  ].includes(model?.api ?? "") && (source?.role === "user" || source?.role === "developer") && (typeof source.content === "string" ? !source.content.trim() : Array.isArray(source.content) && !source.content.some((value) => {
35281
- const block = object5(value);
35484
+ const block = object7(value);
35282
35485
  return block?.type === "image" || block?.type === "text" && typeof block.text === "string" && block.text.trim();
35283
35486
  })))
35284
35487
  continue;
@@ -35371,7 +35574,7 @@ function buildPiPreparedStructure(messages, model, prepareUser) {
35371
35574
  ...responsesMessages ? { responsesMessages } : {},
35372
35575
  ...model?.api ? { api: model.api } : {},
35373
35576
  ...model?.api?.startsWith("google-") ? {
35374
- googleFunctionIds: object5(model.compat)?.supportsFunctionPartId === true
35577
+ googleFunctionIds: object7(model.compat)?.supportsFunctionPartId === true
35375
35578
  } : {}
35376
35579
  };
35377
35580
  }
@@ -35383,7 +35586,7 @@ function responsesLane(api) {
35383
35586
  ].includes(api ?? "");
35384
35587
  }
35385
35588
  function payloadStructure(payload, ollama = false, responsesItems = false, imageProjection = false) {
35386
- const body = object5(payload);
35589
+ const body = object7(payload);
35387
35590
  if (!body)
35388
35591
  return;
35389
35592
  const google = piGoogleConversation(payload);
@@ -35398,7 +35601,7 @@ function payloadStructure(payload, ollama = false, responsesItems = false, image
35398
35601
  return;
35399
35602
  const rows = [];
35400
35603
  for (const value of messages) {
35401
- const message = object5(value);
35604
+ const message = object7(value);
35402
35605
  if (!message)
35403
35606
  return;
35404
35607
  if (rows.length === 0 && (message.role === "system" || message.role === "developer"))
@@ -35458,7 +35661,7 @@ function payloadStructure(payload, ollama = false, responsesItems = false, image
35458
35661
  continue;
35459
35662
  }
35460
35663
  if (message.role === "user" && Array.isArray(message.content)) {
35461
- const results = message.content.filter((block) => object5(block)?.type === "tool_result" || bedrock && object5(block)?.toolResult);
35664
+ const results = message.content.filter((block) => object7(block)?.type === "tool_result" || bedrock && object7(block)?.toolResult);
35462
35665
  if (results.length) {
35463
35666
  for (const block of results) {
35464
35667
  const id = bedrock ? block.toolResult?.toolUseId : block.tool_use_id;
@@ -35505,11 +35708,11 @@ function payloadStructure(payload, ollama = false, responsesItems = false, image
35505
35708
  }
35506
35709
  if (Array.isArray(message.tool_calls)) {
35507
35710
  for (const call of message.tool_calls) {
35508
- const source = object5(call);
35711
+ const source = object7(call);
35509
35712
  if (!source)
35510
35713
  return;
35511
35714
  if (source.id === undefined && ollama) {
35512
- const fn = object5(source.function);
35715
+ const fn = object7(source.function);
35513
35716
  if (typeof fn?.name !== "string")
35514
35717
  return;
35515
35718
  row.calls.push("");
@@ -35545,7 +35748,7 @@ function googleStructure(contents, imageProjection = false) {
35545
35748
  return;
35546
35749
  const rows = [];
35547
35750
  for (const value of contents) {
35548
- const message = object5(value);
35751
+ const message = object7(value);
35549
35752
  if (!message || !Array.isArray(message.parts))
35550
35753
  return;
35551
35754
  if (message.role !== "user" && message.role !== "model")
@@ -35560,11 +35763,11 @@ function googleStructure(contents, imageProjection = false) {
35560
35763
  };
35561
35764
  const results = [];
35562
35765
  for (const value of message.parts) {
35563
- const part = object5(value);
35766
+ const part = object7(value);
35564
35767
  if (!part)
35565
35768
  return;
35566
35769
  if (part.functionCall) {
35567
- const call = object5(part.functionCall);
35770
+ const call = object7(part.functionCall);
35568
35771
  if (row.role !== "assistant" || typeof call?.name !== "string" || call.id !== undefined && typeof call.id !== "string")
35569
35772
  return;
35570
35773
  row.calls.push(call.id ?? "");
@@ -35572,7 +35775,7 @@ function googleStructure(contents, imageProjection = false) {
35572
35775
  row.callNames.push(call.name);
35573
35776
  }
35574
35777
  if (part.functionResponse) {
35575
- const result = object5(part.functionResponse);
35778
+ const result = object7(part.functionResponse);
35576
35779
  if (row.role !== "user" || typeof result?.name !== "string" || result.id !== undefined && typeof result.id !== "string")
35577
35780
  return;
35578
35781
  results.push({
@@ -35606,11 +35809,11 @@ function matchesUserText(content, text, api, responses, googleOrBedrock) {
35606
35809
  if (responses || googleOrBedrock) {
35607
35810
  if (!Array.isArray(content) || content.length !== 1)
35608
35811
  return false;
35609
- const block = object5(content[0]);
35812
+ const block = object7(content[0]);
35610
35813
  return !!block && block.text === text && (responses ? block.type === "input_text" : Object.keys(block).length === 1);
35611
35814
  }
35612
35815
  if ((api === "anthropic-messages" || api === "factory-droid-agent") && Array.isArray(content)) {
35613
- const block = content.length === 1 ? object5(content[0]) : undefined;
35816
+ const block = content.length === 1 ? object7(content[0]) : undefined;
35614
35817
  return block?.type === "text" && block.text === text;
35615
35818
  }
35616
35819
  return content === text;
@@ -35678,7 +35881,7 @@ function piPreparedStructureMismatch(payload, prepared, onImageTrim) {
35678
35881
  return "comparison=image count";
35679
35882
  const imageProjection = trimmed > 0;
35680
35883
  stage = "wire rows";
35681
- const body = object5(payload);
35884
+ const body = object7(payload);
35682
35885
  const ollama = prepared?.api === "ollama-chat" && !!body && Array.isArray(body.messages) && body.input === undefined && body.system === undefined && body.inferenceConfig === undefined;
35683
35886
  const responses = body?.messages === undefined && Array.isArray(body?.input);
35684
35887
  rows = payloadStructure(payload, ollama, responses && !!prepared?.responsesMessages, imageProjection);
@@ -37069,8 +37272,10 @@ function releasePiOperationPayloads(operation) {
37069
37272
  operation.inputMessages = undefined;
37070
37273
  operation.inputBranch = undefined;
37071
37274
  operation.dispatchFields = undefined;
37275
+ operation.chainDispatchFields = undefined;
37072
37276
  operation.managedSignature = undefined;
37073
37277
  operation.preparedStructure = undefined;
37278
+ operation.preparedHistory = undefined;
37074
37279
  }
37075
37280
  function operationKey(ctx) {
37076
37281
  return ctx.sessionManager?.getSessionId?.() ?? ctx.sessionManager ?? "no-session";
@@ -37207,6 +37412,8 @@ function registerPiGuardedContext(pi, handler, options = {}) {
37207
37412
  receiptMaps.add(structureWarnings);
37208
37413
  const imageTrimNotices = new Map;
37209
37414
  receiptMaps.add(imageTrimNotices);
37415
+ const chains = new Map;
37416
+ receiptMaps.add(chains);
37210
37417
  const refuse = (ctx, budget, reason, isCurrent) => {
37211
37418
  if (!isCurrent()) {
37212
37419
  log2(`[magic-context][pi] DISCARDED CONTEXT RESULT ${budget.diagnostic()}`, reason);
@@ -37267,6 +37474,19 @@ function registerPiGuardedContext(pi, handler, options = {}) {
37267
37474
  releasePiOperationPayloads(operation);
37268
37475
  }
37269
37476
  });
37477
+ pi.on("assistant_message", (event, ctx) => {
37478
+ const key = operationKey(ctx);
37479
+ try {
37480
+ const awaiting = chains.get(key)?.awaiting;
37481
+ const response = piChainResponse(event?.message);
37482
+ if (awaiting && response)
37483
+ chains.set(key, { anchor: { ...awaiting, ...response } });
37484
+ else
37485
+ chains.delete(key);
37486
+ } catch {
37487
+ chains.delete(key);
37488
+ }
37489
+ });
37270
37490
  pi.on("before_provider_request", (event, ctx) => {
37271
37491
  const cancelledOperation = operations.get(operationKey(ctx));
37272
37492
  const signal = ctx.signal;
@@ -37276,8 +37496,10 @@ function registerPiGuardedContext(pi, handler, options = {}) {
37276
37496
  cancelledOperation.ready = false;
37277
37497
  return;
37278
37498
  }
37279
- if (options.compactionOff?.(ctx))
37499
+ if (options.compactionOff?.(ctx)) {
37500
+ chains.delete(operationKey(ctx));
37280
37501
  return;
37502
+ }
37281
37503
  const payload = event.payload;
37282
37504
  const key = operationKey(ctx);
37283
37505
  if (sideSessions.get(key)?.sides)
@@ -37321,18 +37543,33 @@ function registerPiGuardedContext(pi, handler, options = {}) {
37321
37543
  }
37322
37544
  if (!budget.completed || !active.ready || active.refused || budget.abandoned)
37323
37545
  throw new Error("context pass ran without a managed context receipt");
37324
- if (!piHasManagedSignature(payload, active.managedSignature))
37546
+ const chained = piChainedRequest(payload);
37547
+ let checked = payload;
37548
+ let chainInput;
37549
+ if (chained) {
37550
+ const expanded = piExpandChainedRequest(payload, chained, chains.get(key)?.anchor, active.preparedHistory, {
37551
+ current: active.pass,
37552
+ resend: active.chainDispatchFields !== undefined
37553
+ });
37554
+ if ("refusal" in expanded)
37555
+ throw new Error(`provider request does not match this pass's managed dispatch (chained continuation: ${expanded.refusal})`);
37556
+ checked = expanded.payload;
37557
+ chainInput = expanded.input;
37558
+ }
37559
+ if (!piHasManagedSignature(checked, active.managedSignature))
37325
37560
  throw new Error("provider request does not match this pass's managed dispatch (missing current receipt signature)");
37326
37561
  const fields = piConversationFields(payload);
37327
37562
  if (!fields)
37328
37563
  throw new Error("provider conversation identity could not be established");
37329
- const body = payload;
37564
+ const body = checked;
37330
37565
  const skipReason = active.preparedStructure ? active.preparedStructure.structuralSkipReason ?? (active.preparedStructure.api && body?.messages === undefined && Array.isArray(body?.input) && !active.preparedStructure.responsesMessages ? "provider selected Responses items without a matching history plan" : undefined) : "prepared history representation is not modeled";
37566
+ if (chained && skipReason)
37567
+ throw new Error("provider request does not match this pass's managed dispatch (chained continuation requires a modeled prepared history)");
37331
37568
  if (skipReason && !structureWarnings.has(key)) {
37332
37569
  structureWarnings.set(key, true);
37333
37570
  log2(`[magic-context][pi] OMP structural comparison skipped: ${skipReason}; stale prepared requests are not detected on this pass; session=${String(key)}`);
37334
37571
  }
37335
- const structureMismatch = skipReason ? undefined : piPreparedStructureMismatch(payload, active.preparedStructure, (counts) => {
37572
+ const structureMismatch = skipReason ? undefined : piPreparedStructureMismatch(checked, active.preparedStructure, (counts) => {
37336
37573
  if (imageTrimNotices.has(key))
37337
37574
  return;
37338
37575
  imageTrimNotices.set(key, true);
@@ -37340,19 +37577,31 @@ function registerPiGuardedContext(pi, handler, options = {}) {
37340
37577
  });
37341
37578
  if (structureMismatch)
37342
37579
  throw new Error(`provider request does not match this pass's managed dispatch (prepared turn structure); ${structureMismatch}`);
37343
- if (active.dispatched) {
37344
- if (!active.dispatchFields || exactReusablePrefix([{ id: "conversation", fields }], [{ id: "conversation", fields: active.dispatchFields }]) !== 1)
37345
- throw new Error("provider request does not match this pass's managed dispatch");
37346
- }
37580
+ const admittedFields = chained ? active.chainDispatchFields : active.dispatchFields;
37581
+ if (admittedFields && exactReusablePrefix([{ id: "conversation", fields }], [{ id: "conversation", fields: admittedFields }]) !== 1)
37582
+ throw new Error("provider request does not match this pass's managed dispatch");
37347
37583
  if (!active.dispatched && active.inputMessages && (!active.inputBranch || active.inputBranch.anchorIndex < active.inputMessages.length - 1)) {
37348
37584
  const previous = active.inputBranch;
37349
37585
  const persisted = inputBranch(ctx, active.inputMessages);
37350
37586
  if (!previous || persisted && persisted.anchorIndex > previous.anchorIndex && persisted.entryIds[previous.anchorIndex] === previous.anchorId)
37351
37587
  active.inputBranch = persisted;
37352
37588
  }
37353
- if (!active.dispatched)
37354
- active.dispatchFields = fields;
37589
+ if (chained)
37590
+ active.chainDispatchFields ??= fields;
37591
+ else
37592
+ active.dispatchFields ??= fields;
37355
37593
  active.dispatched = true;
37594
+ const chain = chains.get(key);
37595
+ if (chain?.anchor && active.pass)
37596
+ chain.anchor.supersededBy ??= active.pass;
37597
+ const sentInput = chainInput ?? (Array.isArray(body?.input) && body.messages === undefined ? [...body.input] : undefined);
37598
+ if (sentInput && active.preparedHistory)
37599
+ chains.set(key, {
37600
+ anchor: chain?.anchor,
37601
+ awaiting: { input: sentInput, prepared: active.preparedHistory }
37602
+ });
37603
+ else
37604
+ chains.delete(key);
37356
37605
  } catch (error) {
37357
37606
  if (signal ? signal.aborted : budget.isCancelled(error)) {
37358
37607
  budget.cancel();
@@ -37414,6 +37663,8 @@ function registerPiGuardedContext(pi, handler, options = {}) {
37414
37663
  result.messages = prepared.messages;
37415
37664
  active.managedSignature = piManagedSignature(result.messages);
37416
37665
  active.preparedStructure = prepared.structure;
37666
+ if (fenceEnabled && !budget.sideTurn && piChainCapableApi(ctx.model?.api))
37667
+ active.preparedHistory = piPreparedHistory(result.messages, ctx.model);
37417
37668
  budget.completed = true;
37418
37669
  active.ready = true;
37419
37670
  if (inputs)
@@ -49219,6 +49470,178 @@ function bindStaleBuildNotice(ctx, moduleUrl) {
49219
49470
  });
49220
49471
  }
49221
49472
 
49473
+ // src/stream-tag-prefix-strip.ts
49474
+ var MAX_TAG_DIGITS = 12;
49475
+ var LEADING_NOTATION = new RegExp(`^\\s*(?:§\\d{1,${MAX_TAG_DIGITS}}§\\s*)*`);
49476
+ var UNFINISHED_HANDLE = new RegExp(`^§\\d{0,${MAX_TAG_DIGITS}}$`);
49477
+ function classifyStreamHead(text) {
49478
+ const leading = LEADING_NOTATION.exec(text)?.[0] ?? "";
49479
+ const rest = text.slice(leading.length);
49480
+ if (rest.length === 0 || UNFINISHED_HANDLE.test(rest))
49481
+ return { kind: "hold" };
49482
+ if (leading.includes("§"))
49483
+ return { kind: "strip", prefixLength: leading.length };
49484
+ return { kind: "pass" };
49485
+ }
49486
+ function visibleText(text, state) {
49487
+ if (state?.mode === "pass")
49488
+ return text;
49489
+ if (state?.mode === "stripped") {
49490
+ return text.startsWith(state.prefix) ? text.slice(state.prefix.length) : text;
49491
+ }
49492
+ const decision = classifyStreamHead(text);
49493
+ if (decision.kind === "hold")
49494
+ return "";
49495
+ if (decision.kind === "strip")
49496
+ return text.slice(decision.prefixLength);
49497
+ return text;
49498
+ }
49499
+ function isRecord7(value) {
49500
+ return value !== null && typeof value === "object";
49501
+ }
49502
+ function canWrite(obj, key) {
49503
+ const descriptor = Object.getOwnPropertyDescriptor(obj, key);
49504
+ if (descriptor === undefined)
49505
+ return Object.isExtensible(obj);
49506
+ return descriptor.writable === true;
49507
+ }
49508
+ function visibleContent(content, blocks) {
49509
+ if (!Array.isArray(content))
49510
+ return;
49511
+ let copy;
49512
+ for (let index = 0;index < content.length; index++) {
49513
+ const part = content[index];
49514
+ if (!isRecord7(part) || part.type !== "text" || typeof part.text !== "string")
49515
+ continue;
49516
+ const shown = visibleText(part.text, blocks.get(index));
49517
+ if (shown === part.text)
49518
+ continue;
49519
+ copy ??= content.slice();
49520
+ copy[index] = { ...part, text: shown };
49521
+ }
49522
+ return copy;
49523
+ }
49524
+ function rewriteMessageUpdateEvent(event, state) {
49525
+ if (state.disabled || !isRecord7(event))
49526
+ return;
49527
+ const message = event.message;
49528
+ const update = event.assistantMessageEvent;
49529
+ if (!isRecord7(message) || message.role !== "assistant" || !isRecord7(update))
49530
+ return;
49531
+ if (typeof update.type !== "string")
49532
+ return;
49533
+ const index = update.contentIndex;
49534
+ const hasIndex = typeof index === "number" && Number.isInteger(index) && index >= 0;
49535
+ const writes = [];
49536
+ let nextBlock;
49537
+ if (update.type === "text_start" && hasIndex) {
49538
+ nextBlock = { mode: "holding", held: "" };
49539
+ } else if (update.type === "text_delta" && hasIndex) {
49540
+ if (typeof update.delta !== "string")
49541
+ return;
49542
+ const current = state.blocks.get(index) ?? { mode: "holding", held: "" };
49543
+ if (current.mode === "holding") {
49544
+ const held = current.held + update.delta;
49545
+ const decision = classifyStreamHead(held);
49546
+ let shown;
49547
+ if (decision.kind === "hold") {
49548
+ nextBlock = { mode: "holding", held };
49549
+ shown = "";
49550
+ } else if (decision.kind === "strip") {
49551
+ nextBlock = {
49552
+ mode: "stripped",
49553
+ prefix: held.slice(0, decision.prefixLength)
49554
+ };
49555
+ shown = held.slice(decision.prefixLength);
49556
+ } else {
49557
+ nextBlock = { mode: "pass" };
49558
+ shown = held;
49559
+ }
49560
+ if (shown !== update.delta)
49561
+ writes.push({ target: update, key: "delta", value: shown });
49562
+ }
49563
+ } else if (update.type === "text_end" && hasIndex) {
49564
+ if (typeof update.content !== "string")
49565
+ return;
49566
+ const current = state.blocks.get(index);
49567
+ const shown = visibleText(update.content, current);
49568
+ if (current === undefined || current.mode === "holding") {
49569
+ nextBlock = shown === "" ? { mode: "stripped", prefix: update.content } : shown === update.content ? { mode: "pass" } : {
49570
+ mode: "stripped",
49571
+ prefix: update.content.slice(0, update.content.length - shown.length)
49572
+ };
49573
+ }
49574
+ if (shown !== update.content)
49575
+ writes.push({ target: update, key: "content", value: shown });
49576
+ }
49577
+ let blocks = state.blocks;
49578
+ if (nextBlock !== undefined && hasIndex) {
49579
+ blocks = new Map(state.blocks);
49580
+ blocks.set(index, nextBlock);
49581
+ }
49582
+ const messageContent = visibleContent(message.content, blocks);
49583
+ if (messageContent !== undefined) {
49584
+ writes.push({ target: message, key: "content", value: messageContent });
49585
+ }
49586
+ const partial = update.partial;
49587
+ if (isRecord7(partial)) {
49588
+ const partialContent = visibleContent(partial.content, blocks);
49589
+ if (partialContent !== undefined) {
49590
+ writes.push({
49591
+ target: update,
49592
+ key: "partial",
49593
+ value: { ...partial, content: partialContent }
49594
+ });
49595
+ }
49596
+ }
49597
+ if (!writes.every((write) => canWrite(write.target, write.key))) {
49598
+ state.disabled = true;
49599
+ return;
49600
+ }
49601
+ for (const write of writes) {
49602
+ write.target[write.key] = write.value;
49603
+ }
49604
+ if (nextBlock !== undefined && hasIndex)
49605
+ state.blocks.set(index, nextBlock);
49606
+ }
49607
+ function createMessageStreamState() {
49608
+ return { blocks: new Map, disabled: false };
49609
+ }
49610
+ function registerStreamTagPrefixStrip(pi, isActive) {
49611
+ const states = new WeakMap;
49612
+ const fallbackKey = {};
49613
+ const keyFor = (ctx) => {
49614
+ const sessionManager = isRecord7(ctx) ? ctx.sessionManager : undefined;
49615
+ return isRecord7(sessionManager) ? sessionManager : fallbackKey;
49616
+ };
49617
+ const isAssistant = (event) => isRecord7(event) && isRecord7(event.message) && event.message.role === "assistant";
49618
+ pi.on("message_start", (event, ctx) => {
49619
+ try {
49620
+ if (isAssistant(event))
49621
+ states.set(keyFor(ctx), createMessageStreamState());
49622
+ } catch {}
49623
+ });
49624
+ pi.on("message_update", (event, ctx) => {
49625
+ try {
49626
+ if (!isActive() || !isAssistant(event))
49627
+ return;
49628
+ const key = keyFor(ctx);
49629
+ let state = states.get(key);
49630
+ if (state === undefined) {
49631
+ state = createMessageStreamState();
49632
+ states.set(key, state);
49633
+ }
49634
+ rewriteMessageUpdateEvent(event, state);
49635
+ } catch {}
49636
+ });
49637
+ pi.on("message_end", (event, ctx) => {
49638
+ try {
49639
+ if (isAssistant(event))
49640
+ states.delete(keyFor(ctx));
49641
+ } catch {}
49642
+ });
49643
+ }
49644
+
49222
49645
  // src/strip-tag-prefix.ts
49223
49646
  function stripTagPrefixFromAssistantMessage(message) {
49224
49647
  if (message.role !== "assistant")
@@ -49241,6 +49664,41 @@ function stripTagPrefixFromAssistantMessage(message) {
49241
49664
  }
49242
49665
  return mutated;
49243
49666
  }
49667
+ function strippedAssistantContent(content) {
49668
+ if (!Array.isArray(content))
49669
+ return;
49670
+ let copy;
49671
+ for (let index = 0;index < content.length; index++) {
49672
+ const part = content[index];
49673
+ if (part === null || typeof part !== "object" || part.type !== "text") {
49674
+ continue;
49675
+ }
49676
+ if (typeof part.text !== "string")
49677
+ continue;
49678
+ const stripped = stripPersistedAssistantText(part.text);
49679
+ if (stripped === part.text)
49680
+ continue;
49681
+ copy ??= content.slice();
49682
+ copy[index] = { ...part, text: stripped };
49683
+ }
49684
+ return copy;
49685
+ }
49686
+ function registerOmpAssistantMessageStrip(pi, isActive) {
49687
+ const api = pi;
49688
+ api.on("assistant_message", (event) => {
49689
+ try {
49690
+ if (!isActive())
49691
+ return;
49692
+ const message = event?.message;
49693
+ if (message?.role !== "assistant")
49694
+ return;
49695
+ const content = strippedAssistantContent(message.content);
49696
+ return content === undefined ? undefined : { content };
49697
+ } catch {
49698
+ return;
49699
+ }
49700
+ });
49701
+ }
49244
49702
 
49245
49703
  // src/subagent-host-tools.ts
49246
49704
  function registerPiSubagentHostTools(pi, harness) {
@@ -50645,6 +51103,11 @@ async function startPiMagicContextRuntime(pi, database, dbPath) {
50645
51103
  }
50646
51104
  });
50647
51105
  pi.on("session_before_compact", async (_event, ctx) => handlePiSessionBeforeCompact({ db, compactionOff, ctx }));
51106
+ if (PI_HARNESS_KIND !== "omp") {
51107
+ registerStreamTagPrefixStrip(pi, () => !compactionOff);
51108
+ } else {
51109
+ registerOmpAssistantMessageStrip(pi, () => !compactionOff);
51110
+ }
50648
51111
  pi.on("message_end", async (event, ctx) => {
50649
51112
  try {
50650
51113
  const leafId = ctx.sessionManager.getLeafId();