@retaw106/mmc-pi 2.3.0 → 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,7 @@ import {
2
2
  getTagIdentityWriteGeneration,
3
3
  Database,
4
4
  getSqliteDatabasePath
5
- } from "./index-3qawqvws.js";
5
+ } from "./index-cr4hzd76.js";
6
6
  import {
7
7
  getHarness,
8
8
  harnessOwnsOpenCodeStore,
@@ -1289,6 +1289,16 @@ function prependTag(tagId, value) {
1289
1289
  return `§${tagId}§ ${stripped}`;
1290
1290
  }
1291
1291
 
1292
+ // ../plugin/src/hooks/magic-context/tail-hygiene-output-count.ts
1293
+ var CURRENT_OUTPUT_COUNT = Symbol.for("magic-context.current-reclaimable-tool-output-count");
1294
+ function countReclaimableToolOutputs(parts) {
1295
+ return parts.filter((part) => part.kind === "toolOutput" && part.uTokens > 0).length;
1296
+ }
1297
+ function rememberCurrentToolOutputCount(baseline, measurement) {
1298
+ return Object.assign(baseline, {
1299
+ [CURRENT_OUTPUT_COUNT]: countReclaimableToolOutputs(measurement.parts)
1300
+ });
1301
+ }
1292
1302
  // ../plugin/src/shared/record-type-guard.ts
1293
1303
  function isRecord(value) {
1294
1304
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -1297,32 +1307,32 @@ function isRecord(value) {
1297
1307
  // ../plugin/src/shared/stable-json.ts
1298
1308
  function stableStringify(value, seen = new WeakSet) {
1299
1309
  const pieces = [];
1300
- writeStable(value, seen, pieces);
1310
+ writeStable(value, seen, (piece) => pieces.push(piece));
1301
1311
  return pieces.join("");
1302
1312
  }
1303
- function writeStable(value, seen, pieces) {
1313
+ function writeStable(value, seen, write) {
1304
1314
  if (value === undefined) {
1305
- pieces.push("undefined");
1315
+ write("undefined");
1306
1316
  return;
1307
1317
  }
1308
1318
  if (value === null || typeof value !== "object") {
1309
- pieces.push(JSON.stringify(value) ?? String(value));
1319
+ write(JSON.stringify(value) ?? String(value));
1310
1320
  return;
1311
1321
  }
1312
1322
  if (seen.has(value)) {
1313
- pieces.push('"[Circular]"');
1323
+ write('"[Circular]"');
1314
1324
  return;
1315
1325
  }
1316
1326
  seen.add(value);
1317
1327
  if (Array.isArray(value)) {
1318
- pieces.push("[");
1328
+ write("[");
1319
1329
  for (let index = 0;index < value.length; index += 1) {
1320
1330
  if (index > 0)
1321
- pieces.push(",");
1331
+ write(",");
1322
1332
  if (index in value)
1323
- writeStable(value[index], seen, pieces);
1333
+ writeStable(value[index], seen, write);
1324
1334
  }
1325
- pieces.push("]");
1335
+ write("]");
1326
1336
  return;
1327
1337
  }
1328
1338
  const entries = Object.entries(value).sort(([a], [b]) => {
@@ -1332,14 +1342,29 @@ function writeStable(value, seen, pieces) {
1332
1342
  return 1;
1333
1343
  return 0;
1334
1344
  });
1335
- pieces.push("{");
1345
+ if (entries.length > 0 && entries.length <= 16 && entries.every(([key, child]) => key.length <= 4096 && !/^(0|[1-9]\d*)$/.test(key) && (child === null || typeof child === "number" || typeof child === "boolean" || typeof child === "string" && child.length <= 4096))) {
1346
+ write(JSON.stringify(Object.fromEntries(entries)));
1347
+ return;
1348
+ }
1349
+ write("{");
1336
1350
  entries.forEach(([key, child], index) => {
1337
1351
  if (index > 0)
1338
- pieces.push(",");
1339
- pieces.push(JSON.stringify(key), ":");
1340
- writeStable(child, seen, pieces);
1352
+ write(",");
1353
+ write(JSON.stringify(key));
1354
+ write(":");
1355
+ writeStable(child, seen, write);
1341
1356
  });
1342
- pieces.push("}");
1357
+ write("}");
1358
+ }
1359
+ function jsonHashSink(prefix = "") {
1360
+ let hash = 2166136261;
1361
+ const write = (piece) => {
1362
+ for (let index = 0;index < piece.length; index++) {
1363
+ hash = Math.imul(hash ^ piece.charCodeAt(index), 16777619);
1364
+ }
1365
+ };
1366
+ write(prefix);
1367
+ return { write, digest: () => (hash >>> 0).toString(16).padStart(8, "0") };
1343
1368
  }
1344
1369
 
1345
1370
  // ../plugin/src/shared/tag-owner-id.ts
@@ -1357,6 +1382,197 @@ function contentTagOwnerMessageId(contentId) {
1357
1382
  return contentId;
1358
1383
  }
1359
1384
 
1385
+ // ../plugin/src/shared/tail-hygiene-json.ts
1386
+ var MAX_MEMO_BYTES = 64 * 1024 * 1024;
1387
+ var MAX_MEMO_ENTRIES = 1e4;
1388
+
1389
+ class TailHygieneJsonMemo {
1390
+ entries = new Map;
1391
+ bytes = 0;
1392
+ passText = new WeakMap;
1393
+ passHash = new WeakMap;
1394
+ beginPass() {
1395
+ this.passText = new WeakMap;
1396
+ this.passHash = new WeakMap;
1397
+ }
1398
+ get(key, value, compute, fingerprint = false) {
1399
+ const pass = fingerprint ? this.passHash : this.passText;
1400
+ const object = value !== null && typeof value === "object" ? value : undefined;
1401
+ const local = object ? pass.get(object) : undefined;
1402
+ if (local !== undefined)
1403
+ return local;
1404
+ const previous = this.entries.get(key);
1405
+ if (previous && sameJson(previous.snapshot, value)) {
1406
+ if (object)
1407
+ pass.set(object, previous.result);
1408
+ return previous.result;
1409
+ }
1410
+ const result = compute();
1411
+ if (previous) {
1412
+ this.bytes -= previous.bytes;
1413
+ this.entries.delete(key);
1414
+ }
1415
+ try {
1416
+ const copy = copyJson(value);
1417
+ const bytes = copy.bytes + (key.length + result.length) * 2;
1418
+ if (bytes <= MAX_MEMO_BYTES) {
1419
+ this.entries.set(key, { snapshot: copy.value, result, bytes });
1420
+ this.bytes += bytes;
1421
+ if (object)
1422
+ pass.set(object, result);
1423
+ }
1424
+ } catch {}
1425
+ while (this.bytes > MAX_MEMO_BYTES || this.entries.size > MAX_MEMO_ENTRIES) {
1426
+ const oldest = this.entries.entries().next().value;
1427
+ if (!oldest)
1428
+ break;
1429
+ this.bytes -= oldest[1].bytes;
1430
+ this.entries.delete(oldest[0]);
1431
+ }
1432
+ return result;
1433
+ }
1434
+ }
1435
+ function copyJson(value) {
1436
+ const seen = new Map;
1437
+ let bytes = 0;
1438
+ const copy = (current) => {
1439
+ bytes += 16;
1440
+ if (typeof current === "string")
1441
+ bytes += current.length * 2;
1442
+ if (bytes > MAX_MEMO_BYTES)
1443
+ throw new Error("memo capacity");
1444
+ if (current === null || typeof current !== "object") {
1445
+ if (["function", "symbol", "bigint"].includes(typeof current))
1446
+ throw new Error("exotic");
1447
+ return current;
1448
+ }
1449
+ if (seen.has(current))
1450
+ return seen.get(current);
1451
+ const prototype = Object.getPrototypeOf(current);
1452
+ if (!Array.isArray(current) && prototype !== Object.prototype && prototype !== null)
1453
+ throw new Error("exotic");
1454
+ const result = Array.isArray(current) ? new Array(current.length) : Object.create(prototype);
1455
+ seen.set(current, result);
1456
+ for (const key of Object.keys(current)) {
1457
+ const descriptor = Object.getOwnPropertyDescriptor(current, key);
1458
+ if (!descriptor || !("value" in descriptor))
1459
+ throw new Error("accessor");
1460
+ bytes += key.length * 2 + 16;
1461
+ if (key === "__proto__") {
1462
+ Object.defineProperty(result, key, {
1463
+ value: copy(descriptor.value),
1464
+ enumerable: true,
1465
+ writable: true,
1466
+ configurable: true
1467
+ });
1468
+ } else
1469
+ result[key] = copy(descriptor.value);
1470
+ }
1471
+ return result;
1472
+ };
1473
+ return { value: copy(value), bytes };
1474
+ }
1475
+ function sameJson(before, after) {
1476
+ const forward = new Map;
1477
+ const reverse = new Set;
1478
+ const same = (left, right) => {
1479
+ if (left === null || right === null || typeof left !== "object" || typeof right !== "object")
1480
+ return Object.is(left, right);
1481
+ if (forward.has(left))
1482
+ return forward.get(left) === right;
1483
+ if (reverse.has(right) || Object.getPrototypeOf(left) !== Object.getPrototypeOf(right))
1484
+ return false;
1485
+ forward.set(left, right);
1486
+ reverse.add(right);
1487
+ if (Array.isArray(left) && (!Array.isArray(right) || left.length !== right.length))
1488
+ return false;
1489
+ const keys = Object.keys(left);
1490
+ const otherKeys = Object.keys(right);
1491
+ if (keys.length !== otherKeys.length)
1492
+ return false;
1493
+ for (let index = 0;index < keys.length; index++) {
1494
+ const key = keys[index];
1495
+ if (key !== otherKeys[index])
1496
+ return false;
1497
+ const descriptor = Object.getOwnPropertyDescriptor(right, key);
1498
+ if (!descriptor || !("value" in descriptor) || !same(left[key], descriptor.value))
1499
+ return false;
1500
+ }
1501
+ return true;
1502
+ };
1503
+ return same(before, after);
1504
+ }
1505
+ function piJsonHash(value, fallback) {
1506
+ const sink = jsonHashSink("excluded\x00");
1507
+ try {
1508
+ const seen = new Set;
1509
+ const arrays = new Set;
1510
+ const write = (current) => {
1511
+ if (current === null || typeof current !== "object") {
1512
+ if (["function", "symbol", "bigint"].includes(typeof current))
1513
+ throw new Error("exotic");
1514
+ sink.write(JSON.stringify(current) ?? "");
1515
+ } else if (Array.isArray(current)) {
1516
+ if (Object.getPrototypeOf(current) !== Array.prototype || Object.hasOwn(current, "toJSON"))
1517
+ throw new Error("exotic array");
1518
+ if (arrays.has(current))
1519
+ throw new Error("array cycle");
1520
+ arrays.add(current);
1521
+ sink.write("[");
1522
+ for (let index = 0;index < current.length; index++) {
1523
+ if (index)
1524
+ sink.write(",");
1525
+ const descriptor = Object.getOwnPropertyDescriptor(current, index);
1526
+ if (descriptor && !("value" in descriptor))
1527
+ throw new Error("accessor");
1528
+ if (!descriptor && index in current)
1529
+ throw new Error("inherited array element");
1530
+ write(descriptor?.value === undefined ? null : descriptor.value);
1531
+ }
1532
+ sink.write("]");
1533
+ arrays.delete(current);
1534
+ } else if (seen.has(current)) {
1535
+ sink.write('"[Circular]"');
1536
+ } else {
1537
+ const prototype = Object.getPrototypeOf(current);
1538
+ if (prototype !== Object.prototype && prototype !== null)
1539
+ throw new Error("exotic");
1540
+ seen.add(current);
1541
+ const entries = Object.keys(current).map((key) => {
1542
+ const descriptor = Object.getOwnPropertyDescriptor(current, key);
1543
+ if (!descriptor || !("value" in descriptor))
1544
+ throw new Error("accessor");
1545
+ return [key, descriptor.value];
1546
+ });
1547
+ const sorted = Object.fromEntries(entries.sort(([a], [b]) => a.localeCompare(b)));
1548
+ if (entries.length <= 16 && entries.every(([key, child]) => key.length <= 4096 && (child === null || child === undefined || typeof child === "number" || typeof child === "boolean" || typeof child === "string" && child.length <= 4096))) {
1549
+ sink.write(JSON.stringify(sorted));
1550
+ return;
1551
+ }
1552
+ sink.write("{");
1553
+ let first = true;
1554
+ for (const [key, child] of Object.entries(sorted)) {
1555
+ if (child === undefined)
1556
+ continue;
1557
+ if (!first)
1558
+ sink.write(",");
1559
+ first = false;
1560
+ sink.write(JSON.stringify(key));
1561
+ sink.write(":");
1562
+ write(child);
1563
+ }
1564
+ sink.write("}");
1565
+ }
1566
+ };
1567
+ write(value);
1568
+ return sink.digest();
1569
+ } catch {
1570
+ const failed = jsonHashSink("excluded\x00");
1571
+ failed.write(fallback());
1572
+ return failed.digest();
1573
+ }
1574
+ }
1575
+
1360
1576
  // ../plugin/src/hooks/magic-context/image-token-estimate.ts
1361
1577
  var IMAGE_TOKEN_DIVISOR = 750;
1362
1578
  var IMAGE_FALLBACK_TOKENS = 1200;
@@ -1394,6 +1610,23 @@ function estimateImageTokensFromDataUrl(url) {
1394
1610
  }
1395
1611
  return IMAGE_FALLBACK_TOKENS;
1396
1612
  }
1613
+ function estimateToolAttachmentImageTokens(state) {
1614
+ if (!state || typeof state !== "object")
1615
+ return 0;
1616
+ const attachments = state.attachments;
1617
+ if (!Array.isArray(attachments))
1618
+ return 0;
1619
+ let tokens = 0;
1620
+ for (const attachment of attachments) {
1621
+ if (!attachment || typeof attachment !== "object")
1622
+ continue;
1623
+ const { mime, url } = attachment;
1624
+ if (typeof mime !== "string" || !mime.startsWith("image/"))
1625
+ continue;
1626
+ tokens += typeof url === "string" && url.startsWith("data:") ? estimateImageTokensFromDataUrl(url) : IMAGE_FALLBACK_TOKENS;
1627
+ }
1628
+ return tokens;
1629
+ }
1397
1630
  function clampImageTokens(n) {
1398
1631
  if (n < 1)
1399
1632
  return 1;
@@ -1532,6 +1765,88 @@ function readUint32BE(b, offset) {
1532
1765
  return (b[offset] << 24 | b[offset + 1] << 16 | b[offset + 2] << 8 | b[offset + 3]) >>> 0;
1533
1766
  }
1534
1767
 
1768
+ // ../plugin/src/hooks/magic-context/provider-visible-parts.ts
1769
+ function isRecord2(value) {
1770
+ return value !== null && typeof value === "object" && !Array.isArray(value);
1771
+ }
1772
+ var KEPT_TOOL_STATE_FIELDS = new Set([
1773
+ "status",
1774
+ "input",
1775
+ "output",
1776
+ "error",
1777
+ "attachments",
1778
+ "content"
1779
+ ]);
1780
+ var KEPT_TOOL_STATE_TIME_FIELD = "compacted";
1781
+ function providerVisiblePart(part) {
1782
+ if (!isRecord2(part) || part.type !== "tool" || !isRecord2(part.state))
1783
+ return part;
1784
+ if (toolStateIsReduced(part.state))
1785
+ return part;
1786
+ return { ...part, state: providerVisibleToolState(part.state) };
1787
+ }
1788
+ var KEPT_ERROR_METADATA_FIELDS = ["interrupted", "output"];
1789
+ function providerVisibleToolState(state) {
1790
+ const view = {};
1791
+ for (const key of Object.keys(state)) {
1792
+ const value = state[key];
1793
+ if (KEPT_TOOL_STATE_FIELDS.has(key)) {
1794
+ view[key] = value;
1795
+ } else if (key === "time" && isRecord2(value)) {
1796
+ view.time = value[KEPT_TOOL_STATE_TIME_FIELD] === undefined ? {} : { [KEPT_TOOL_STATE_TIME_FIELD]: value[KEPT_TOOL_STATE_TIME_FIELD] };
1797
+ } else if (key === "metadata" && state.status === "error" && isRecord2(value)) {
1798
+ const kept = {};
1799
+ for (const field of KEPT_ERROR_METADATA_FIELDS) {
1800
+ if (Object.hasOwn(value, field))
1801
+ kept[field] = value[field];
1802
+ }
1803
+ view.metadata = kept;
1804
+ }
1805
+ }
1806
+ return view;
1807
+ }
1808
+ function toolStateIsReduced(state) {
1809
+ for (const key of Object.keys(state)) {
1810
+ if (KEPT_TOOL_STATE_FIELDS.has(key))
1811
+ continue;
1812
+ const value = state[key];
1813
+ if (key === "time" && isRecord2(value)) {
1814
+ const keys = Object.keys(value);
1815
+ if (keys.length === 0)
1816
+ continue;
1817
+ if (keys.length === 1 && keys[0] === KEPT_TOOL_STATE_TIME_FIELD)
1818
+ continue;
1819
+ return false;
1820
+ }
1821
+ if (key === "metadata" && state.status === "error" && isRecord2(value)) {
1822
+ const extra = Object.keys(value).some((field) => !KEPT_ERROR_METADATA_FIELDS.includes(field));
1823
+ if (!extra)
1824
+ continue;
1825
+ }
1826
+ return false;
1827
+ }
1828
+ return true;
1829
+ }
1830
+ function providerVisibleMessage(message) {
1831
+ return projectMessage(message, providerVisiblePart);
1832
+ }
1833
+ function projectMessage(message, projectPart) {
1834
+ if (!isRecord2(message) || !Array.isArray(message.parts))
1835
+ return message;
1836
+ let parts;
1837
+ for (let index = 0;index < message.parts.length; index += 1) {
1838
+ const part = message.parts[index];
1839
+ const view = projectPart(part);
1840
+ if (view !== part) {
1841
+ parts ??= message.parts.slice(0, index);
1842
+ parts.push(view);
1843
+ } else if (parts) {
1844
+ parts.push(part);
1845
+ }
1846
+ }
1847
+ return parts ? { ...message, parts } : message;
1848
+ }
1849
+
1535
1850
  // ../plugin/src/hooks/magic-context/todo-view.ts
1536
1851
  import { createHash } from "node:crypto";
1537
1852
  var TODO_STATUS_PENDING = "pending";
@@ -1640,7 +1955,7 @@ function isTodoItem(value) {
1640
1955
  }
1641
1956
 
1642
1957
  // ../plugin/src/hooks/magic-context/tail-hygiene-walk.ts
1643
- var MAX_CONTENT_MEMO_BYTES = 64 * 1024 * 1024;
1958
+ var MAX_CONTENT_MEMO_BYTES = 256 * 1024 * 1024;
1644
1959
  var contentMemo = new Map;
1645
1960
  var contentMemoOrder = new Set;
1646
1961
  var CHANNEL1_REMINDER_OPEN = `
@@ -1659,6 +1974,7 @@ function stripChannel1ReminderSpans(output) {
1659
1974
  }
1660
1975
  return stripped;
1661
1976
  }
1977
+ var partJsonMemo = new TailHygieneJsonMemo;
1662
1978
  function messageIdFromPartKey(key) {
1663
1979
  const separator = key.indexOf("\x00");
1664
1980
  return separator > 0 ? key.slice(0, separator) : key;
@@ -1956,7 +2272,7 @@ function formatOldestReclaimableHint(hint) {
1956
2272
  oldest reclaimable: ${rendered}.` : "";
1957
2273
  }
1958
2274
  function reclaimableToolOutputCount(parts) {
1959
- return parts.filter((part) => part.kind === "toolOutput" && part.uTokens > 0).length;
2275
+ return countReclaimableToolOutputs(parts);
1960
2276
  }
1961
2277
  function formatReclaimableOutputSummary(count, tokens) {
1962
2278
  const outputCount = Math.max(0, Math.floor(count));
@@ -2921,6 +3237,19 @@ function insertTag(db, sessionId, messageId, type, byteSize, tagNumber, reasonin
2921
3237
  function updateTagStatus(db, sessionId, tagId, status) {
2922
3238
  getUpdateTagStatusStatement(db).run(status, sessionId, tagId);
2923
3239
  }
3240
+ var droppedTagStatements = new WeakMap;
3241
+ function markTagDropped(db, sessionId, tagId, mode) {
3242
+ if (!mode) {
3243
+ updateTagStatus(db, sessionId, tagId, "dropped");
3244
+ return;
3245
+ }
3246
+ let statement = droppedTagStatements.get(db);
3247
+ if (!statement) {
3248
+ statement = db.prepare("UPDATE tags SET status = ?, drop_mode = ? WHERE session_id = ? AND tag_number = ?");
3249
+ droppedTagStatements.set(db, statement);
3250
+ }
3251
+ statement.run("dropped", mode, sessionId, tagId);
3252
+ }
2924
3253
  var inertWhitespaceStatements = new WeakMap;
2925
3254
  var inertWhitespaceByNumberStatements = new WeakMap;
2926
3255
  function getInertWhitespaceAssistantTagsByNumbers(db, sessionId, tagNumbers) {
@@ -3384,7 +3713,7 @@ function getNewestToolTagNumbers(db, sessionId, limit) {
3384
3713
  let statement = newestToolTagNumberStatements.get(db);
3385
3714
  if (!statement) {
3386
3715
  statement = db.prepare(`SELECT tag_number FROM tags
3387
- WHERE session_id = ? AND type = 'tool'
3716
+ WHERE session_id = ? AND +type = 'tool'
3388
3717
  AND typeof(message_id) = 'text'
3389
3718
  AND typeof(status) = 'text'
3390
3719
  AND typeof(byte_size) IN ('integer', 'real')
@@ -4972,85 +5301,6 @@ function getMessageTimesFromOpenCodeDb(sessionId, messageIds) {
4972
5301
  return result;
4973
5302
  }
4974
5303
 
4975
- // ../plugin/src/hooks/magic-context/provider-visible-parts.ts
4976
- function isRecord2(value) {
4977
- return value !== null && typeof value === "object" && !Array.isArray(value);
4978
- }
4979
- var KEPT_TOOL_STATE_FIELDS = new Set([
4980
- "status",
4981
- "input",
4982
- "output",
4983
- "error",
4984
- "attachments",
4985
- "content"
4986
- ]);
4987
- var KEPT_TOOL_STATE_TIME_FIELD = "compacted";
4988
- var KEPT_ERROR_METADATA_FIELDS = ["interrupted", "output"];
4989
- function providerVisibleToolState(state) {
4990
- const view = {};
4991
- for (const key of Object.keys(state)) {
4992
- const value = state[key];
4993
- if (KEPT_TOOL_STATE_FIELDS.has(key)) {
4994
- view[key] = value;
4995
- } else if (key === "time" && isRecord2(value)) {
4996
- view.time = value[KEPT_TOOL_STATE_TIME_FIELD] === undefined ? {} : { [KEPT_TOOL_STATE_TIME_FIELD]: value[KEPT_TOOL_STATE_TIME_FIELD] };
4997
- } else if (key === "metadata" && state.status === "error" && isRecord2(value)) {
4998
- const kept = {};
4999
- for (const field of KEPT_ERROR_METADATA_FIELDS) {
5000
- if (Object.hasOwn(value, field))
5001
- kept[field] = value[field];
5002
- }
5003
- view.metadata = kept;
5004
- }
5005
- }
5006
- return view;
5007
- }
5008
- function toolStateIsReduced(state) {
5009
- for (const key of Object.keys(state)) {
5010
- if (KEPT_TOOL_STATE_FIELDS.has(key))
5011
- continue;
5012
- const value = state[key];
5013
- if (key === "time" && isRecord2(value)) {
5014
- const keys = Object.keys(value);
5015
- if (keys.length === 0)
5016
- continue;
5017
- if (keys.length === 1 && keys[0] === KEPT_TOOL_STATE_TIME_FIELD)
5018
- continue;
5019
- return false;
5020
- }
5021
- if (key === "metadata" && state.status === "error" && isRecord2(value)) {
5022
- const extra = Object.keys(value).some((field) => !KEPT_ERROR_METADATA_FIELDS.includes(field));
5023
- if (!extra)
5024
- continue;
5025
- }
5026
- return false;
5027
- }
5028
- return true;
5029
- }
5030
- function providerVisiblePart(part) {
5031
- if (!isRecord2(part) || part.type !== "tool" || !isRecord2(part.state))
5032
- return part;
5033
- if (toolStateIsReduced(part.state))
5034
- return part;
5035
- return { ...part, state: providerVisibleToolState(part.state) };
5036
- }
5037
- function providerVisibleMessage(message) {
5038
- if (!isRecord2(message) || !Array.isArray(message.parts))
5039
- return message;
5040
- let parts;
5041
- for (let index = 0;index < message.parts.length; index += 1) {
5042
- const part = message.parts[index];
5043
- const view = providerVisiblePart(part);
5044
- if (view !== part) {
5045
- parts ??= message.parts.slice(0, index);
5046
- parts.push(view);
5047
- } else if (parts) {
5048
- parts.push(part);
5049
- }
5050
- }
5051
- return parts ? { ...message, parts } : message;
5052
- }
5053
-
5054
5304
  // ../plugin/src/hooks/magic-context/read-session-true-raw-tokens.ts
5055
5305
  function completedToolArcCrossesBoundary(invOrdinal, resOrdinal, boundary) {
5056
5306
  return invOrdinal < boundary && boundary <= resOrdinal;
@@ -5914,6 +6164,17 @@ function loadToolDefinitionMeasurements(db) {
5914
6164
 
5915
6165
  // ../plugin/src/hooks/magic-context/final-wire-token-estimate.ts
5916
6166
  var wireTextTokens = createTokenCountMemo(1e5, 128 * 1024 * 1024);
6167
+ function estimatePartImageTokens(raw) {
6168
+ if (!raw || typeof raw !== "object")
6169
+ return 0;
6170
+ const part = raw;
6171
+ if (part.ignored)
6172
+ return 0;
6173
+ if (part.type === "file" && part.mime?.startsWith("image/")) {
6174
+ return typeof part.url === "string" && part.url.startsWith("data:") ? estimateImageTokensFromDataUrl(part.url) : 1200;
6175
+ }
6176
+ return part.type === "tool" ? estimateToolAttachmentImageTokens(part.state) : 0;
6177
+ }
5917
6178
 
5918
6179
  // ../plugin/src/features/magic-context/overflow-detection.ts
5919
6180
  var OVERFLOW_PATTERNS = [
@@ -7107,4 +7368,4 @@ function readSessionChunk2(sessionId, tokenBudget, offset = 1, eligibleEndOrdina
7107
7368
  toolResultBoundaries
7108
7369
  };
7109
7370
  }
7110
- export { canonicalModelIdentity, piModelRefToCanonical, resolveModelRefForPi, modelRefLookupOrder, toolTemplateError, DEFAULT_PROTECTED_TOOLS, normalizeProtectedToolName, mergeProtectedTools, detectThinkingBindingMismatch, detectLatestTurnThinkingMismatch, isPrefixBoundThinkingModel, detectOverflow, stableStringify, UNKNOWN_FIT_RATIO, resolveDecisionCalibration, hasMeasuredDecisionCalibration, providerMass, localBudget, calibrationForModelKey, historyLocalBudget, adoptedProtectedToolsPolicy, protectedToolTagNumbers, protectedToolTokenCount, removeSystemReminders, hasMeaningfulUserText2, extractTexts2, preloadTokenizer, hasTokenizerForFit, tokenCountUsesByteBound, estimateTokens, estimateFixedPromptTokens, stripWellFormedLeadingTagPrefix, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, isRecord, TEXT_TAG_IDENTITY_MARKER, PI_FALLBACK_PREFIXES_JSON, contentTagOwnerMessageId, estimateImageTokensFromDataUrl, TODO_STATUSES, TODO_PRIORITIES, TITLE_DONE_STATUSES, normalizeTodoStateJson, buildSyntheticTodoPart, stripChannel1ReminderSpans, compareMeasuredTailPrefix, formatTailHygienePrefixMismatch, freezeTailHygieneMeasurement, effectiveTailHygiene, CHANNEL1_SENTINEL, CHANNEL1_FLOOR_TOKENS, decideChannel1, evaluateChannel2, reclaimableToolOutputCount, buildChannel2Reminder, buildChannel1Reminder, planEmergencyDrop, measureEmergencyTag, closeQuietly, isKnownAutocommit, installV3PerfSchema, queuePendingOp, queuePendingDropForUnchangedTag, getPendingOps, getPendingOpsCount, clearPendingOps, removePendingOp, tagRevisionIncarnationSql, tagRevisionCountSql, tagRevisionKey, tagIdentityRevisionKey, TAG_INSERT_CONFLICT_ROWS, installTagIdentityRevisionTrigger, updateTagByteSize, getRecentTagOwnerMessageIds, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, updateTagInputByteSize, updateTagTokenCount, getPersistedToolTagAccounting, getAllStatusTagTokenTotalsFlat, getReasoningTokenEstimatesByMessage, updateTagInputTokenCount, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, getInertWhitespaceAssistantTagsByNumbers, updateTagDropMode, updateCavemanDepth, hasPiFallbackMessageTags, findAdoptableFallbackTags, hasPiFallbackToolOwnerTags, findPiFallbackToolOwnerTags, PiTagIdentityConflictError, getPiMessageTagCandidates, findPiTagIdentityConflict, adoptPiFallbackToolOwnerTag, adoptPiFallbackMessageTag, getMaxTagNumberBySession, getTagNumberByMessageId, getAssignableTagNumberByMessageId, deriveTagLoadFloor, TAG_SELECT_COLUMNS, getTagsBySession, getActiveTagsBySession, getTagsForPendingOperations, getTagsByNumbers, getNewestToolTagNumbers, getDroppedTagsByNumbers, getMaxDroppedTagNumber, getTagById, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, resolveOpenCodeDbPath, hasV1MessageTables, assertOpenCodeStoreGeneration, withReadOnlySessionDb, expandToolPart, retreatPastHostUnservedRows, providerVisibleMessage, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, fenceBoundaryForCompletedToolArcs, fenceBoundaryForToolArcs, buildTrueRawTokenIndex, computeRawRangeFingerprint, invalidateTrueRawTokenCache, stripSystemInjection, hasUserAnswerMetadata, droppedInputMarker, createDroppedInputGuard, isEditTool, applyEditMarkerToInput, setDatabase, loadToolDefinitionMeasurements, modelAcceptsEmptyContent, isAnthropicFamilyRoute, variantChangeBustsProviderCache, SKELETON_REAL_INPUT_MAX_BYTES, toolInputStringBytes, resolveHostServedBoundaryId2, hasRawMessageProvider2, setRawMessageProvider2, withRawMessageProvider2, cleanUserText2, withRawSessionMessageCache2, readRawSessionMessages2, readRawSessionMessagePage2, getRawSessionMessageOrdinalCount2, visitRawSessionMessages2, readRawSessionMessageRange2, primeTailRawMessageCache2, getCachedAbsoluteMessageCount2, primeInMemoryTailRawMessageCache2, readRawSessionMessageIdOrdinalsForRange2, hasRawSessionMessageById2, readRawSessionMessageOrdinalById2, compareRawSessionMessageOrder2, readRawSessionMessageById2, getRawSessionMessageCount2, getRawSessionTagKeysThrough2, getLegacyProtectedTailStartOrdinal2, readSessionChunk2 };
7371
+ export { canonicalModelIdentity, piModelRefToCanonical, resolveModelRefForPi, modelRefLookupOrder, toolTemplateError, DEFAULT_PROTECTED_TOOLS, normalizeProtectedToolName, mergeProtectedTools, detectThinkingBindingMismatch, detectLatestTurnThinkingMismatch, isPrefixBoundThinkingModel, detectOverflow, stableStringify, UNKNOWN_FIT_RATIO, resolveDecisionCalibration, hasMeasuredDecisionCalibration, providerMass, localBudget, calibrationForModelKey, historyLocalBudget, adoptedProtectedToolsPolicy, protectedToolTagNumbers, protectedToolTokenCount, removeSystemReminders, hasMeaningfulUserText2, extractTexts2, preloadTokenizer, hasTokenizerForFit, tokenCountUsesByteBound, estimateTokens, estimateFixedPromptTokens, stripWellFormedLeadingTagPrefix, stripPersistedAssistantText, byteSize, stripTagPrefix, peelLeadingMcTagNotation, prependTag, rememberCurrentToolOutputCount, isRecord, TEXT_TAG_IDENTITY_MARKER, PI_FALLBACK_PREFIXES_JSON, contentTagOwnerMessageId, TailHygieneJsonMemo, piJsonHash, estimateImageTokensFromDataUrl, providerVisibleMessage, TODO_STATUSES, TODO_PRIORITIES, TITLE_DONE_STATUSES, normalizeTodoStateJson, buildSyntheticTodoPart, stripChannel1ReminderSpans, compareMeasuredTailPrefix, formatTailHygienePrefixMismatch, freezeTailHygieneMeasurement, effectiveTailHygiene, CHANNEL1_SENTINEL, CHANNEL1_FLOOR_TOKENS, decideChannel1, evaluateChannel2, reclaimableToolOutputCount, buildChannel2Reminder, buildChannel1Reminder, planEmergencyDrop, measureEmergencyTag, closeQuietly, isKnownAutocommit, installV3PerfSchema, queuePendingOp, queuePendingDropForUnchangedTag, getPendingOps, getPendingOpsCount, clearPendingOps, removePendingOp, tagRevisionIncarnationSql, tagRevisionCountSql, tagRevisionKey, tagIdentityRevisionKey, TAG_INSERT_CONFLICT_ROWS, installTagIdentityRevisionTrigger, updateTagByteSize, getRecentTagOwnerMessageIds, AGE_RECLAIM_MIN_TOKENS, getOldestActiveUnprotectedToolTags, getActiveToolTagsForAgeReclaim, getTriggerTagTokenUpperBound, updateTagInputByteSize, updateTagTokenCount, getPersistedToolTagAccounting, getAllStatusTagTokenTotalsFlat, getReasoningTokenEstimatesByMessage, updateTagInputTokenCount, tagTokenCountIsNull, backfillTagTokenCounts, insertTag, updateTagStatus, markTagDropped, getInertWhitespaceAssistantTagsByNumbers, updateTagDropMode, updateCavemanDepth, hasPiFallbackMessageTags, findAdoptableFallbackTags, hasPiFallbackToolOwnerTags, findPiFallbackToolOwnerTags, PiTagIdentityConflictError, getPiMessageTagCandidates, findPiTagIdentityConflict, adoptPiFallbackToolOwnerTag, adoptPiFallbackMessageTag, getMaxTagNumberBySession, getTagNumberByMessageId, getAssignableTagNumberByMessageId, deriveTagLoadFloor, TAG_SELECT_COLUMNS, getTagsBySession, getActiveTagsBySession, getTagsForPendingOperations, getTagsByNumbers, getNewestToolTagNumbers, getDroppedTagsByNumbers, getMaxDroppedTagNumber, getTagById, getToolTagNumberByOwner, getNullOwnerToolTag, adoptNullOwnerToolTag, resolveOpenCodeDbPath, hasV1MessageTables, assertOpenCodeStoreGeneration, withReadOnlySessionDb, expandToolPart, retreatPastHostUnservedRows, completedToolArcCrossesBoundary, estimateTrueRawMessageTokens, buildToolArcs, fenceBoundaryForCompletedToolArcs, fenceBoundaryForToolArcs, buildTrueRawTokenIndex, computeRawRangeFingerprint, invalidateTrueRawTokenCache, stripSystemInjection, hasUserAnswerMetadata, droppedInputMarker, createDroppedInputGuard, isEditTool, applyEditMarkerToInput, setDatabase, loadToolDefinitionMeasurements, estimatePartImageTokens, modelAcceptsEmptyContent, isAnthropicFamilyRoute, variantChangeBustsProviderCache, SKELETON_REAL_INPUT_MAX_BYTES, toolInputStringBytes, resolveHostServedBoundaryId2, hasRawMessageProvider2, setRawMessageProvider2, withRawMessageProvider2, cleanUserText2, withRawSessionMessageCache2, readRawSessionMessages2, readRawSessionMessagePage2, getRawSessionMessageOrdinalCount2, visitRawSessionMessages2, readRawSessionMessageRange2, primeTailRawMessageCache2, getCachedAbsoluteMessageCount2, primeInMemoryTailRawMessageCache2, readRawSessionMessageIdOrdinalsForRange2, hasRawSessionMessageById2, readRawSessionMessageOrdinalById2, compareRawSessionMessageOrder2, readRawSessionMessageById2, getRawSessionMessageCount2, getRawSessionTagKeysThrough2, getLegacyProtectedTailStartOrdinal2, readSessionChunk2 };