blun-king-cli 9.1.622 → 9.1.624

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/worker-host.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // BLUN_BUILD_INPUT_SHA256:314627d22c0a877269162b3b0c92dd47eda8cf3e19d218eb28a1ced7d267360e
2
+ // BLUN_BUILD_INPUT_SHA256:6261be0a5a4581dab29357a29f94e361f1eca61f5b4458e64501f26bc604dc3e
3
3
  import { fileURLToPath as __cjsShimFileURLToPath } from 'node:url';
4
4
  import { dirname as __cjsShimDirname } from 'node:path';
5
5
  const __filename = __cjsShimFileURLToPath(import.meta.url);
@@ -1180,13 +1180,13 @@ function isUnknownCapability(capability) {
1180
1180
  * recursion; in that case the referenced definition bucket is preserved so the
1181
1181
  * remaining local `$ref` pointers stay resolvable to a JSON Schema validator.
1182
1182
  */
1183
- function derefJsonSchema$1(schema) {
1184
- const result = resolveNode$1(schema, schema, /* @__PURE__ */ new Set());
1185
- if (!hasUnresolvedDefinitionRef$1(result, "$defs")) delete result["$defs"];
1186
- if (!hasUnresolvedDefinitionRef$1(result, "definitions")) delete result["definitions"];
1183
+ function derefJsonSchema(schema) {
1184
+ const result = resolveNode(schema, schema, /* @__PURE__ */ new Set());
1185
+ if (!hasUnresolvedDefinitionRef(result, "$defs")) delete result["$defs"];
1186
+ if (!hasUnresolvedDefinitionRef(result, "definitions")) delete result["definitions"];
1187
1187
  return result;
1188
1188
  }
1189
- const TYPE_COMPLETION_SKIP_KEYS$1 = new Set([
1189
+ const TYPE_COMPLETION_SKIP_KEYS = new Set([
1190
1190
  "$ref",
1191
1191
  "allOf",
1192
1192
  "anyOf",
@@ -1196,7 +1196,7 @@ const TYPE_COMPLETION_SKIP_KEYS$1 = new Set([
1196
1196
  "oneOf",
1197
1197
  "then"
1198
1198
  ]);
1199
- const CHILD_SCHEMA_SLOTS$1 = [
1199
+ const CHILD_SCHEMA_SLOTS = [
1200
1200
  {
1201
1201
  key: "$defs",
1202
1202
  kind: "map"
@@ -1299,23 +1299,23 @@ const CHILD_SCHEMA_SLOTS$1 = [
1299
1299
  parentType: "array"
1300
1300
  }
1301
1301
  ];
1302
- const OBJECT_STRUCTURE_KEYS$1 = new Set([
1303
- ...childSchemaKeysForParentType$1("object"),
1302
+ const OBJECT_STRUCTURE_KEYS = new Set([
1303
+ ...childSchemaKeysForParentType("object"),
1304
1304
  "dependentRequired",
1305
1305
  "maxProperties",
1306
1306
  "minProperties",
1307
1307
  "required"
1308
1308
  ]);
1309
- const ARRAY_STRUCTURE_KEYS$1 = new Set([
1310
- ...childSchemaKeysForParentType$1("array"),
1309
+ const ARRAY_STRUCTURE_KEYS = new Set([
1310
+ ...childSchemaKeysForParentType("array"),
1311
1311
  "maxContains",
1312
1312
  "maxItems",
1313
1313
  "minContains",
1314
1314
  "minItems",
1315
1315
  "uniqueItems"
1316
1316
  ]);
1317
- const STRING_STRUCTURE_KEYS$1 = new Set([
1318
- ...childSchemaKeysForParentType$1("string"),
1317
+ const STRING_STRUCTURE_KEYS = new Set([
1318
+ ...childSchemaKeysForParentType("string"),
1319
1319
  "contentEncoding",
1320
1320
  "contentMediaType",
1321
1321
  "format",
@@ -1323,7 +1323,7 @@ const STRING_STRUCTURE_KEYS$1 = new Set([
1323
1323
  "minLength",
1324
1324
  "pattern"
1325
1325
  ]);
1326
- const NUMERIC_STRUCTURE_KEYS$1 = new Set([
1326
+ const NUMERIC_STRUCTURE_KEYS = new Set([
1327
1327
  "exclusiveMaximum",
1328
1328
  "exclusiveMinimum",
1329
1329
  "maximum",
@@ -1342,47 +1342,47 @@ const NUMERIC_STRUCTURE_KEYS$1 = new Set([
1342
1342
  * typeless property schemas. The root schema object is treated as a container
1343
1343
  * and is not itself normalized.
1344
1344
  */
1345
- function normalizeBlunToolSchema$1(schema) {
1346
- return ensureBlunPropertyTypes$1(derefJsonSchema$1(schema));
1345
+ function normalizeBlunToolSchema(schema) {
1346
+ return ensureBlunPropertyTypes(derefJsonSchema(schema));
1347
1347
  }
1348
- function ensureBlunPropertyTypes$1(schema) {
1349
- const normalized = cloneJsonValue$1(schema);
1350
- if (!isRecord$11(normalized)) throw new Error("JSON Schema root must normalize to an object.");
1351
- recurseSchema$1(normalized);
1348
+ function ensureBlunPropertyTypes(schema) {
1349
+ const normalized = cloneJsonValue(schema);
1350
+ if (!isRecord$10(normalized)) throw new Error("JSON Schema root must normalize to an object.");
1351
+ recurseSchema(normalized);
1352
1352
  return normalized;
1353
1353
  }
1354
- function hasUnresolvedDefinitionRef$1(node, bucketKey) {
1355
- if (Array.isArray(node)) return node.some((child) => hasUnresolvedDefinitionRef$1(child, bucketKey));
1354
+ function hasUnresolvedDefinitionRef(node, bucketKey) {
1355
+ if (Array.isArray(node)) return node.some((child) => hasUnresolvedDefinitionRef(child, bucketKey));
1356
1356
  if (typeof node === "object" && node !== null) {
1357
1357
  const obj = node;
1358
1358
  const ref = obj["$ref"];
1359
1359
  if (typeof ref === "string" && ref.startsWith(`#/${bucketKey}/`)) return true;
1360
1360
  for (const [key, value] of Object.entries(obj)) {
1361
1361
  if (key === bucketKey) continue;
1362
- if (hasUnresolvedDefinitionRef$1(value, bucketKey)) return true;
1362
+ if (hasUnresolvedDefinitionRef(value, bucketKey)) return true;
1363
1363
  }
1364
1364
  return false;
1365
1365
  }
1366
1366
  return false;
1367
1367
  }
1368
- function resolveNode$1(node, root, visited) {
1369
- if (Array.isArray(node)) return node.map((item) => resolveNode$1(item, root, visited));
1368
+ function resolveNode(node, root, visited) {
1369
+ if (Array.isArray(node)) return node.map((item) => resolveNode(item, root, visited));
1370
1370
  if (typeof node === "object" && node !== null) {
1371
1371
  const obj = node;
1372
1372
  if (typeof obj["$ref"] === "string") {
1373
1373
  const ref = obj["$ref"];
1374
- if (isLocalJsonPointerRef$1(ref)) {
1374
+ if (isLocalJsonPointerRef(ref)) {
1375
1375
  if (visited.has(ref)) return obj;
1376
- const resolvedRef = resolveLocalJsonPointer$1(root, ref);
1376
+ const resolvedRef = resolveLocalJsonPointer(root, ref);
1377
1377
  if (resolvedRef.found) {
1378
1378
  visited.add(ref);
1379
- const resolved = resolveNode$1(resolvedRef.value, root, visited);
1379
+ const resolved = resolveNode(resolvedRef.value, root, visited);
1380
1380
  visited.delete(ref);
1381
1381
  if (typeof resolved === "object" && resolved !== null && !Array.isArray(resolved)) {
1382
1382
  const merged = { ...resolved };
1383
1383
  for (const [key, value] of Object.entries(obj)) {
1384
1384
  if (key === "$ref") continue;
1385
- merged[key] = resolveNode$1(value, root, visited);
1385
+ merged[key] = resolveNode(value, root, visited);
1386
1386
  }
1387
1387
  return merged;
1388
1388
  }
@@ -1392,27 +1392,27 @@ function resolveNode$1(node, root, visited) {
1392
1392
  return obj;
1393
1393
  }
1394
1394
  const resolved = {};
1395
- for (const [key, value] of Object.entries(obj)) resolved[key] = resolveNode$1(value, root, visited);
1395
+ for (const [key, value] of Object.entries(obj)) resolved[key] = resolveNode(value, root, visited);
1396
1396
  return resolved;
1397
1397
  }
1398
1398
  return node;
1399
1399
  }
1400
- function isLocalJsonPointerRef$1(ref) {
1400
+ function isLocalJsonPointerRef(ref) {
1401
1401
  return ref === "#" || ref.startsWith("#/");
1402
1402
  }
1403
- function resolveLocalJsonPointer$1(root, ref) {
1403
+ function resolveLocalJsonPointer(root, ref) {
1404
1404
  if (ref === "#") return {
1405
1405
  found: true,
1406
1406
  value: root
1407
1407
  };
1408
1408
  let current = root;
1409
1409
  for (const rawPart of ref.slice(2).split("/")) {
1410
- const part = unescapeJsonPointerPart$1(rawPart);
1411
- if (isRecord$11(current)) {
1412
- if (!hasOwn$1(current, part)) return { found: false };
1410
+ const part = unescapeJsonPointerPart(rawPart);
1411
+ if (isRecord$10(current)) {
1412
+ if (!hasOwn(current, part)) return { found: false };
1413
1413
  current = current[part];
1414
1414
  } else if (Array.isArray(current)) {
1415
- const index = parseJsonPointerArrayIndex$1(part);
1415
+ const index = parseJsonPointerArrayIndex(part);
1416
1416
  if (index === null || index >= current.length) return { found: false };
1417
1417
  current = current[index];
1418
1418
  } else return { found: false };
@@ -1422,83 +1422,83 @@ function resolveLocalJsonPointer$1(root, ref) {
1422
1422
  value: current
1423
1423
  };
1424
1424
  }
1425
- function unescapeJsonPointerPart$1(part) {
1425
+ function unescapeJsonPointerPart(part) {
1426
1426
  return part.replaceAll("~1", "/").replaceAll("~0", "~");
1427
1427
  }
1428
- function parseJsonPointerArrayIndex$1(part) {
1428
+ function parseJsonPointerArrayIndex(part) {
1429
1429
  if (!/^(0|[1-9]\d*)$/.test(part)) return null;
1430
1430
  return Number(part);
1431
1431
  }
1432
- function recurseSchema$1(node) {
1433
- if (!isRecord$11(node)) return;
1434
- visitChildSchemas$1(node, normalizeProperty$1);
1432
+ function recurseSchema(node) {
1433
+ if (!isRecord$10(node)) return;
1434
+ visitChildSchemas(node, normalizeProperty);
1435
1435
  }
1436
- function visitChildSchemas$1(node, visit) {
1437
- for (const { key, kind } of CHILD_SCHEMA_SLOTS$1) {
1436
+ function visitChildSchemas(node, visit) {
1437
+ for (const { key, kind } of CHILD_SCHEMA_SLOTS) {
1438
1438
  const value = node[key];
1439
1439
  if (kind === "single") {
1440
- if (isRecord$11(value)) visit(value);
1440
+ if (isRecord$10(value)) visit(value);
1441
1441
  } else if (kind === "array") {
1442
1442
  if (Array.isArray(value)) for (const item of value) visit(item);
1443
1443
  } else if (kind === "map") {
1444
- if (isRecord$11(value)) for (const item of Object.values(value)) visit(item);
1444
+ if (isRecord$10(value)) for (const item of Object.values(value)) visit(item);
1445
1445
  } else if (kind === "schema-or-array") {
1446
- if (isRecord$11(value)) visit(value);
1446
+ if (isRecord$10(value)) visit(value);
1447
1447
  else if (Array.isArray(value)) for (const item of value) visit(item);
1448
1448
  }
1449
1449
  }
1450
1450
  }
1451
- function childSchemaKeysForParentType$1(parentType) {
1452
- return CHILD_SCHEMA_SLOTS$1.flatMap((slot) => {
1451
+ function childSchemaKeysForParentType(parentType) {
1452
+ return CHILD_SCHEMA_SLOTS.flatMap((slot) => {
1453
1453
  if (!("parentType" in slot) || slot.parentType !== parentType) return [];
1454
1454
  return [slot.key];
1455
1455
  });
1456
1456
  }
1457
- function normalizeProperty$1(node) {
1458
- if (!isRecord$11(node)) return;
1459
- if (!hasOwn$1(node, "type") && !hasAnyKey$1(node, TYPE_COMPLETION_SKIP_KEYS$1)) {
1457
+ function normalizeProperty(node) {
1458
+ if (!isRecord$10(node)) return;
1459
+ if (!hasOwn(node, "type") && !hasAnyKey(node, TYPE_COMPLETION_SKIP_KEYS)) {
1460
1460
  const enumValues = node["enum"];
1461
- if (Array.isArray(enumValues) && enumValues.length > 0) node["type"] = inferTypeFromValues$1(enumValues);
1462
- else if (hasOwn$1(node, "const")) node["type"] = inferTypeFromValues$1([node["const"]]);
1463
- else node["type"] = inferTypeFromStructure$1(node);
1464
- } else if (!hasAnyKey$1(node, TYPE_COMPLETION_SKIP_KEYS$1) && typeof node["type"] === "string") {
1461
+ if (Array.isArray(enumValues) && enumValues.length > 0) node["type"] = inferTypeFromValues(enumValues);
1462
+ else if (hasOwn(node, "const")) node["type"] = inferTypeFromValues([node["const"]]);
1463
+ else node["type"] = inferTypeFromStructure(node);
1464
+ } else if (!hasAnyKey(node, TYPE_COMPLETION_SKIP_KEYS) && typeof node["type"] === "string") {
1465
1465
  const enumValues = node["enum"];
1466
1466
  if (Array.isArray(enumValues) && enumValues.length > 0) try {
1467
- const inferred = inferTypeFromValues$1(enumValues);
1467
+ const inferred = inferTypeFromValues(enumValues);
1468
1468
  if (node["type"] !== inferred) {
1469
1469
  node["type"] = inferred;
1470
- removeIrrelevantStructureKeys$1(node, inferred);
1470
+ removeIrrelevantStructureKeys(node, inferred);
1471
1471
  }
1472
1472
  } catch {}
1473
- else if (hasOwn$1(node, "const")) try {
1474
- const inferred = inferTypeFromValues$1([node["const"]]);
1473
+ else if (hasOwn(node, "const")) try {
1474
+ const inferred = inferTypeFromValues([node["const"]]);
1475
1475
  if (node["type"] !== inferred) {
1476
1476
  node["type"] = inferred;
1477
- removeIrrelevantStructureKeys$1(node, inferred);
1477
+ removeIrrelevantStructureKeys(node, inferred);
1478
1478
  }
1479
1479
  } catch {}
1480
1480
  }
1481
- recurseSchema$1(node);
1481
+ recurseSchema(node);
1482
1482
  }
1483
- function removeIrrelevantStructureKeys$1(node, newType) {
1484
- if (newType !== "object") for (const key of OBJECT_STRUCTURE_KEYS$1) delete node[key];
1485
- if (newType !== "array") for (const key of ARRAY_STRUCTURE_KEYS$1) delete node[key];
1483
+ function removeIrrelevantStructureKeys(node, newType) {
1484
+ if (newType !== "object") for (const key of OBJECT_STRUCTURE_KEYS) delete node[key];
1485
+ if (newType !== "array") for (const key of ARRAY_STRUCTURE_KEYS) delete node[key];
1486
1486
  }
1487
- function inferTypeFromStructure$1(schema) {
1488
- if (hasAnyKey$1(schema, OBJECT_STRUCTURE_KEYS$1)) return "object";
1489
- if (hasAnyKey$1(schema, ARRAY_STRUCTURE_KEYS$1)) return "array";
1490
- if (hasAnyKey$1(schema, STRING_STRUCTURE_KEYS$1)) return "string";
1491
- if (hasAnyKey$1(schema, NUMERIC_STRUCTURE_KEYS$1)) return "number";
1487
+ function inferTypeFromStructure(schema) {
1488
+ if (hasAnyKey(schema, OBJECT_STRUCTURE_KEYS)) return "object";
1489
+ if (hasAnyKey(schema, ARRAY_STRUCTURE_KEYS)) return "array";
1490
+ if (hasAnyKey(schema, STRING_STRUCTURE_KEYS)) return "string";
1491
+ if (hasAnyKey(schema, NUMERIC_STRUCTURE_KEYS)) return "number";
1492
1492
  return "string";
1493
1493
  }
1494
- function inferTypeFromValues$1(values) {
1494
+ function inferTypeFromValues(values) {
1495
1495
  const inferred = /* @__PURE__ */ new Set();
1496
1496
  for (const value of values) {
1497
- const valueType = inferValueType$1(value);
1497
+ const valueType = inferValueType(value);
1498
1498
  if (valueType === void 0) throw new Error("Cannot infer JSON Schema type from non-JSON enum or const value.");
1499
1499
  inferred.add(valueType);
1500
1500
  }
1501
- const types = normalizeInferredTypes$1(inferred);
1501
+ const types = normalizeInferredTypes(inferred);
1502
1502
  if (types.length === 1) {
1503
1503
  const onlyType = types[0];
1504
1504
  if (onlyType === void 0) throw new Error("Cannot infer JSON Schema type from an empty enum.");
@@ -1506,7 +1506,7 @@ function inferTypeFromValues$1(values) {
1506
1506
  }
1507
1507
  throw new Error("Mixed JSON Schema enum or const types are not supported by Blun tool schemas.");
1508
1508
  }
1509
- function inferValueType$1(value) {
1509
+ function inferValueType(value) {
1510
1510
  if (value === null) return "null";
1511
1511
  if (Array.isArray(value)) return "array";
1512
1512
  switch (typeof value) {
@@ -1520,7 +1520,7 @@ function inferValueType$1(value) {
1520
1520
  case "undefined": return;
1521
1521
  }
1522
1522
  }
1523
- function normalizeInferredTypes$1(types) {
1523
+ function normalizeInferredTypes(types) {
1524
1524
  const normalized = new Set(types);
1525
1525
  if (normalized.has("number")) normalized.delete("integer");
1526
1526
  return [
@@ -1533,23 +1533,23 @@ function normalizeInferredTypes$1(types) {
1533
1533
  "null"
1534
1534
  ].filter((type) => normalized.has(type));
1535
1535
  }
1536
- function hasAnyKey$1(obj, keys) {
1537
- for (const key of keys) if (hasOwn$1(obj, key)) return true;
1536
+ function hasAnyKey(obj, keys) {
1537
+ for (const key of keys) if (hasOwn(obj, key)) return true;
1538
1538
  return false;
1539
1539
  }
1540
- function cloneJsonValue$1(value) {
1541
- if (Array.isArray(value)) return value.map((item) => cloneJsonValue$1(item));
1542
- if (isRecord$11(value)) {
1540
+ function cloneJsonValue(value) {
1541
+ if (Array.isArray(value)) return value.map((item) => cloneJsonValue(item));
1542
+ if (isRecord$10(value)) {
1543
1543
  const cloned = {};
1544
- for (const [key, child] of Object.entries(value)) cloned[key] = cloneJsonValue$1(child);
1544
+ for (const [key, child] of Object.entries(value)) cloned[key] = cloneJsonValue(child);
1545
1545
  return cloned;
1546
1546
  }
1547
1547
  return value;
1548
1548
  }
1549
- function isRecord$11(value) {
1549
+ function isRecord$10(value) {
1550
1550
  return typeof value === "object" && value !== null && !Array.isArray(value);
1551
1551
  }
1552
- function hasOwn$1(obj, key) {
1552
+ function hasOwn(obj, key) {
1553
1553
  return Object.prototype.hasOwnProperty.call(obj, key);
1554
1554
  }
1555
1555
  //#endregion
@@ -2328,9 +2328,9 @@ var BlunFiles = class {
2328
2328
  * Falls back to `upload.bin` for unknown types.
2329
2329
  */
2330
2330
  function guessFilename(mimeType) {
2331
- return `upload.${MIME_TO_EXT$1[mimeType.toLowerCase()] ?? "bin"}`;
2331
+ return `upload.${MIME_TO_EXT[mimeType.toLowerCase()] ?? "bin"}`;
2332
2332
  }
2333
- const MIME_TO_EXT$1 = {
2333
+ const MIME_TO_EXT = {
2334
2334
  "video/mp4": "mp4",
2335
2335
  "video/mpeg": "mpeg",
2336
2336
  "video/quicktime": "mov",
@@ -2340,7 +2340,7 @@ const MIME_TO_EXT$1 = {
2340
2340
  "video/x-flv": "flv",
2341
2341
  "video/3gpp": "3gp"
2342
2342
  };
2343
- const EXT_TO_MIME$2 = Object.fromEntries(Object.entries(MIME_TO_EXT$1).map(([mime, ext]) => [ext, mime]));
2343
+ const EXT_TO_MIME$1 = Object.fromEntries(Object.entries(MIME_TO_EXT).map(([mime, ext]) => [ext, mime]));
2344
2344
  /**
2345
2345
  * Guess a MIME type from a filename extension. Only recognises the video
2346
2346
  * types listed in {@link MIME_TO_EXT}; returns `undefined` otherwise.
@@ -2348,11 +2348,11 @@ const EXT_TO_MIME$2 = Object.fromEntries(Object.entries(MIME_TO_EXT$1).map(([mim
2348
2348
  function guessMimeTypeFromExt(filename) {
2349
2349
  const dot = filename.lastIndexOf(".");
2350
2350
  if (dot < 0) return void 0;
2351
- return EXT_TO_MIME$2[filename.slice(dot + 1).toLowerCase()];
2351
+ return EXT_TO_MIME$1[filename.slice(dot + 1).toLowerCase()];
2352
2352
  }
2353
2353
  //#endregion
2354
2354
  //#region ../../packages/kosong/src/providers/chat-completions-wire.ts
2355
- function convertChatCompletionContentPart$1(part) {
2355
+ function convertChatCompletionContentPart(part) {
2356
2356
  switch (part.type) {
2357
2357
  case "text": return {
2358
2358
  type: "text",
@@ -2383,7 +2383,7 @@ function convertChatCompletionContentPart$1(part) {
2383
2383
  default: throw new Error(`Unknown content part type: ${part.type}`);
2384
2384
  }
2385
2385
  }
2386
- function toolToChatCompletion$1(tool) {
2386
+ function toolToChatCompletion(tool) {
2387
2387
  return {
2388
2388
  type: "function",
2389
2389
  function: {
@@ -2510,16 +2510,16 @@ function convertChatCompletionStreamToolCall(toolCall, bufferedByIndex) {
2510
2510
  }
2511
2511
  //#endregion
2512
2512
  //#region ../../packages/kosong/src/providers/tool-call-id.ts
2513
- const EMPTY_TOOL_CALL_ID$1 = "tool_call";
2514
- const TOOL_CALL_ID_SAFE_CHARS$1 = /[^a-zA-Z0-9_-]/g;
2515
- function sanitizeToolCallId$1(id, maxLength) {
2516
- const sanitized = id.replace(TOOL_CALL_ID_SAFE_CHARS$1, "_");
2513
+ const EMPTY_TOOL_CALL_ID = "tool_call";
2514
+ const TOOL_CALL_ID_SAFE_CHARS = /[^a-zA-Z0-9_-]/g;
2515
+ function sanitizeToolCallId(id, maxLength) {
2516
+ const sanitized = id.replace(TOOL_CALL_ID_SAFE_CHARS, "_");
2517
2517
  return maxLength === void 0 ? sanitized : sanitized.slice(0, maxLength);
2518
2518
  }
2519
- function normalizeToolCallIdsForProvider$1(messages, policy) {
2520
- const rawIds = collectToolCallIds$1(messages);
2519
+ function normalizeToolCallIdsForProvider(messages, policy) {
2520
+ const rawIds = collectToolCallIds(messages);
2521
2521
  if (rawIds.length === 0) return messages;
2522
- const mappedIds = buildToolCallIdMap$1(rawIds, policy);
2522
+ const mappedIds = buildToolCallIdMap(rawIds, policy);
2523
2523
  let changed = false;
2524
2524
  const normalizedMessages = messages.map((message) => {
2525
2525
  let messageChanged = false;
@@ -2545,7 +2545,7 @@ function normalizeToolCallIdsForProvider$1(messages, policy) {
2545
2545
  });
2546
2546
  return changed ? normalizedMessages : messages;
2547
2547
  }
2548
- function collectToolCallIds$1(messages) {
2548
+ function collectToolCallIds(messages) {
2549
2549
  const ids = [];
2550
2550
  const seen = /* @__PURE__ */ new Set();
2551
2551
  const append = (id) => {
@@ -2559,7 +2559,7 @@ function collectToolCallIds$1(messages) {
2559
2559
  }
2560
2560
  return ids;
2561
2561
  }
2562
- function buildToolCallIdMap$1(rawIds, policy) {
2562
+ function buildToolCallIdMap(rawIds, policy) {
2563
2563
  const mappedIds = /* @__PURE__ */ new Map();
2564
2564
  const usedIds = /* @__PURE__ */ new Set();
2565
2565
  for (const rawId of rawIds) {
@@ -2571,22 +2571,22 @@ function buildToolCallIdMap$1(rawIds, policy) {
2571
2571
  }
2572
2572
  for (const rawId of rawIds) {
2573
2573
  if (mappedIds.has(rawId)) continue;
2574
- const unique = makeUniqueToolCallId$1(policy.normalize(rawId), usedIds, policy.maxLength);
2574
+ const unique = makeUniqueToolCallId(policy.normalize(rawId), usedIds, policy.maxLength);
2575
2575
  mappedIds.set(rawId, unique);
2576
2576
  usedIds.add(unique);
2577
2577
  }
2578
2578
  return mappedIds;
2579
2579
  }
2580
- function makeUniqueToolCallId$1(normalized, usedIds, maxLength) {
2581
- const base = normalized.length > 0 ? normalized : EMPTY_TOOL_CALL_ID$1;
2582
- const candidate = truncateToolCallId$1(base, maxLength, "");
2580
+ function makeUniqueToolCallId(normalized, usedIds, maxLength) {
2581
+ const base = normalized.length > 0 ? normalized : EMPTY_TOOL_CALL_ID;
2582
+ const candidate = truncateToolCallId(base, maxLength, "");
2583
2583
  if (!usedIds.has(candidate)) return candidate;
2584
2584
  for (let i = 2;; i++) {
2585
- const suffixed = truncateToolCallId$1(base, maxLength, `_${i}`);
2585
+ const suffixed = truncateToolCallId(base, maxLength, `_${i}`);
2586
2586
  if (!usedIds.has(suffixed)) return suffixed;
2587
2587
  }
2588
2588
  }
2589
- function truncateToolCallId$1(base, maxLength, suffix) {
2589
+ function truncateToolCallId(base, maxLength, suffix) {
2590
2590
  if (maxLength === void 0) return `${base}${suffix}`;
2591
2591
  const baseLength = maxLength - suffix.length;
2592
2592
  if (baseLength <= 0) throw new Error(`Tool call id maxLength ${maxLength} is too small for suffix ${suffix}.`);
@@ -2594,8 +2594,8 @@ function truncateToolCallId$1(base, maxLength, suffix) {
2594
2594
  }
2595
2595
  //#endregion
2596
2596
  //#region ../../packages/kosong/src/providers/blun.ts
2597
- const BLUN_TOOL_CALL_ID_POLICY$1 = {
2598
- normalize: (id) => sanitizeToolCallId$1(id, 64),
2597
+ const BLUN_TOOL_CALL_ID_POLICY = {
2598
+ normalize: (id) => sanitizeToolCallId(id, 64),
2599
2599
  maxLength: 64
2600
2600
  };
2601
2601
  function toBlunTemplateEffort(effort) {
@@ -2650,31 +2650,31 @@ function mergeReasoningFieldState(current, next) {
2650
2650
  if (next === "absent") return current;
2651
2651
  return rank[next] > rank[current] ? next : current;
2652
2652
  }
2653
- function isEffectivelyEmptyContent$1(parts) {
2653
+ function isEffectivelyEmptyContent(parts) {
2654
2654
  for (const part of parts) {
2655
2655
  if (part.type !== "text") return false;
2656
2656
  if (part.text.trim() !== "") return false;
2657
2657
  }
2658
2658
  return true;
2659
2659
  }
2660
- function isEmptyAssistantHistoryMessage$1(message) {
2660
+ function isEmptyAssistantHistoryMessage(message) {
2661
2661
  if (message.role !== "assistant" || message.toolCalls.length > 0) return false;
2662
2662
  return message.content.every((part) => part.type === "think" || part.type === "text" && part.text.trim() === "");
2663
2663
  }
2664
- const BLUN_VISION_DATA_URL$1 = /^data:(image\/(?:png|jpeg|webp|gif));base64,([A-Za-z0-9+/]+={0,2})$/;
2665
- const BLUN_VISION_MAX_ATTACHMENTS$1 = 4;
2666
- const BLUN_VISION_MAX_IMAGE_BYTES$1 = 8 * 1024 * 1024;
2667
- function collectBlunVisionAttachments$1(messages) {
2664
+ const BLUN_VISION_DATA_URL = /^data:(image\/(?:png|jpeg|webp|gif));base64,([A-Za-z0-9+/]+={0,2})$/;
2665
+ const BLUN_VISION_MAX_ATTACHMENTS = 4;
2666
+ const BLUN_VISION_MAX_IMAGE_BYTES = 8 * 1024 * 1024;
2667
+ function collectBlunVisionAttachments(messages) {
2668
2668
  const attachments = [];
2669
2669
  for (const message of messages) for (const part of message.content) {
2670
2670
  if (part.type !== "image_url") continue;
2671
- const match = BLUN_VISION_DATA_URL$1.exec(part.imageUrl.url);
2671
+ const match = BLUN_VISION_DATA_URL.exec(part.imageUrl.url);
2672
2672
  if (match === null) continue;
2673
2673
  const mediaType = match[1];
2674
2674
  const data = match[2];
2675
2675
  if (mediaType === void 0 || data === void 0 || data.length % 4 !== 0) continue;
2676
2676
  const bytes = Buffer.from(data, "base64");
2677
- if (bytes.length === 0 || bytes.length > BLUN_VISION_MAX_IMAGE_BYTES$1 || bytes.toString("base64") !== data) continue;
2677
+ if (bytes.length === 0 || bytes.length > BLUN_VISION_MAX_IMAGE_BYTES || bytes.toString("base64") !== data) continue;
2678
2678
  attachments.push({
2679
2679
  type: "image",
2680
2680
  source: {
@@ -2683,38 +2683,38 @@ function collectBlunVisionAttachments$1(messages) {
2683
2683
  data
2684
2684
  }
2685
2685
  });
2686
- if (attachments.length >= BLUN_VISION_MAX_ATTACHMENTS$1) return attachments;
2686
+ if (attachments.length >= BLUN_VISION_MAX_ATTACHMENTS) return attachments;
2687
2687
  }
2688
2688
  return attachments;
2689
2689
  }
2690
- function estimateBlunSerializedBodyBytes$1(systemPrompt, tools, history) {
2691
- const normalizedHistory = normalizeToolCallIdsForProvider$1([...history], BLUN_TOOL_CALL_ID_POLICY$1);
2690
+ function estimateBlunSerializedBodyBytes(systemPrompt, tools, history) {
2691
+ const normalizedHistory = normalizeToolCallIdsForProvider([...history], BLUN_TOOL_CALL_ID_POLICY);
2692
2692
  const messages = systemPrompt ? [{
2693
2693
  role: "system",
2694
2694
  content: systemPrompt
2695
2695
  }] : [];
2696
- for (const message of normalizedHistory) if (!isEmptyAssistantHistoryMessage$1(message)) messages.push(convertMessage$1(message));
2697
- const attachments = collectBlunVisionAttachments$1(normalizedHistory);
2696
+ for (const message of normalizedHistory) if (!isEmptyAssistantHistoryMessage(message)) messages.push(convertMessage(message));
2697
+ const attachments = collectBlunVisionAttachments(normalizedHistory);
2698
2698
  return Buffer.byteLength(JSON.stringify({
2699
2699
  model: "king",
2700
2700
  messages,
2701
2701
  stream: true,
2702
- ...tools.length > 0 ? { tools: tools.map(convertTool$1) } : {},
2702
+ ...tools.length > 0 ? { tools: tools.map(convertTool) } : {},
2703
2703
  ...attachments.length > 0 ? { visionAttachments: attachments } : {},
2704
2704
  stream_options: { include_usage: true }
2705
2705
  }), "utf8");
2706
2706
  }
2707
- function convertMessage$1(message) {
2707
+ function convertMessage(message) {
2708
2708
  let reasoningContent = "";
2709
2709
  const nonThinkParts = [];
2710
2710
  for (const part of message.content) if (part.type === "think") reasoningContent += part.think;
2711
2711
  else nonThinkParts.push(part);
2712
2712
  const result = { role: message.role };
2713
2713
  const hasToolCalls = message.toolCalls.length > 0;
2714
- if (!(message.role === "assistant" && hasToolCalls && isEffectivelyEmptyContent$1(nonThinkParts))) {
2714
+ if (!(message.role === "assistant" && hasToolCalls && isEffectivelyEmptyContent(nonThinkParts))) {
2715
2715
  const firstPart = nonThinkParts[0];
2716
2716
  if (nonThinkParts.length === 1 && firstPart?.type === "text") result.content = firstPart.text;
2717
- else if (nonThinkParts.length > 0) result.content = nonThinkParts.map((p) => convertChatCompletionContentPart$1(p)).filter((p) => p !== null);
2717
+ else if (nonThinkParts.length > 0) result.content = nonThinkParts.map((p) => convertChatCompletionContentPart(p)).filter((p) => p !== null);
2718
2718
  }
2719
2719
  if (message.name !== void 0) result.name = message.name;
2720
2720
  if (hasToolCalls) result.tool_calls = message.toolCalls.map((tc) => {
@@ -2733,17 +2733,17 @@ function convertMessage$1(message) {
2733
2733
  if (reasoningContent) result.reasoning_content = reasoningContent;
2734
2734
  return result;
2735
2735
  }
2736
- function convertTool$1(tool) {
2736
+ function convertTool(tool) {
2737
2737
  if (tool.name.startsWith("$")) return {
2738
2738
  type: "builtin_function",
2739
2739
  function: { name: tool.name }
2740
2740
  };
2741
- const converted = toolToChatCompletion$1(tool);
2741
+ const converted = toolToChatCompletion(tool);
2742
2742
  return {
2743
2743
  ...converted,
2744
2744
  function: {
2745
2745
  ...converted.function,
2746
- parameters: normalizeBlunToolSchema$1(tool.parameters)
2746
+ parameters: normalizeBlunToolSchema(tool.parameters)
2747
2747
  }
2748
2748
  };
2749
2749
  }
@@ -2934,10 +2934,10 @@ var BlunChatProvider = class {
2934
2934
  role: "system",
2935
2935
  content: systemPrompt
2936
2936
  });
2937
- const normalizedHistory = normalizeToolCallIdsForProvider$1(history, BLUN_TOOL_CALL_ID_POLICY$1);
2937
+ const normalizedHistory = normalizeToolCallIdsForProvider(history, BLUN_TOOL_CALL_ID_POLICY);
2938
2938
  for (const msg of normalizedHistory) {
2939
- if (isEmptyAssistantHistoryMessage$1(msg)) continue;
2940
- messages.push(convertMessage$1(msg));
2939
+ if (isEmptyAssistantHistoryMessage(msg)) continue;
2940
+ messages.push(convertMessage(msg));
2941
2941
  }
2942
2942
  const kwargs = { ...this._generationKwargs };
2943
2943
  for (const key of Object.keys(kwargs)) if (kwargs[key] === void 0) delete kwargs[key];
@@ -3007,9 +3007,9 @@ var BlunChatProvider = class {
3007
3007
  ...requestKwargs,
3008
3008
  ...requestExtraBody
3009
3009
  };
3010
- const visionAttachments = collectBlunVisionAttachments$1(normalizedHistory);
3010
+ const visionAttachments = collectBlunVisionAttachments(normalizedHistory);
3011
3011
  if (visionAttachments.length > 0) createParams["visionAttachments"] = visionAttachments;
3012
- if (tools.length > 0) createParams["tools"] = tools.map((t) => convertTool$1(t));
3012
+ if (tools.length > 0) createParams["tools"] = tools.map((t) => convertTool(t));
3013
3013
  if (this._stream) createParams["stream_options"] = { include_usage: true };
3014
3014
  try {
3015
3015
  const client = this._createClient(options?.auth);
@@ -9887,6 +9887,7 @@ const PermissionConfigSchema = object({ rules: array(object({
9887
9887
  })).optional() });
9888
9888
  const LoopControlSchema = object({
9889
9889
  maxStepsPerTurn: number$1().int().min(0).optional(),
9890
+ maxToolExecutionsPerTurn: number$1().int().min(0).optional(),
9890
9891
  maxRetriesPerStep: number$1().int().min(0).optional(),
9891
9892
  maxRalphIterations: number$1().int().min(-1).optional(),
9892
9893
  reservedContextSize: number$1().int().min(0).optional(),
@@ -10605,7 +10606,7 @@ async function acquirePrivatePathWriter(targetPath, options = {}) {
10605
10606
  }
10606
10607
  //#endregion
10607
10608
  //#region ../../packages/oauth/src/utils.ts
10608
- function isRecord$10(value) {
10609
+ function isRecord$9(value) {
10609
10610
  return typeof value === "object" && value !== null && !Array.isArray(value);
10610
10611
  }
10611
10612
  //#endregion
@@ -11192,7 +11193,7 @@ var FileTokenStorage = class {
11192
11193
  } catch {
11193
11194
  return;
11194
11195
  }
11195
- if (!isRecord$10(parsed)) return void 0;
11196
+ if (!isRecord$9(parsed)) return void 0;
11196
11197
  return tokenFromWire(parsed);
11197
11198
  }
11198
11199
  async save(name, token) {
@@ -11308,7 +11309,7 @@ function extractApiErrorMessage(value) {
11308
11309
  }
11309
11310
  return;
11310
11311
  }
11311
- if (!isRecord$10(value)) return void 0;
11312
+ if (!isRecord$9(value)) return void 0;
11312
11313
  for (const key of DIRECT_ERROR_KEYS) {
11313
11314
  const message = stringField$1(value, key);
11314
11315
  if (message !== void 0) return message;
@@ -11316,7 +11317,7 @@ function extractApiErrorMessage(value) {
11316
11317
  const error = value["error"];
11317
11318
  const errorString = nonEmptyString$6(error);
11318
11319
  if (errorString !== void 0) return errorString;
11319
- if (isRecord$10(error)) for (const key of NESTED_ERROR_KEYS) {
11320
+ if (isRecord$9(error)) for (const key of NESTED_ERROR_KEYS) {
11320
11321
  const message = stringField$1(error, key);
11321
11322
  if (message !== void 0) return message;
11322
11323
  }
@@ -11410,7 +11411,7 @@ async function postForm(url, params, deviceHeaders, options) {
11410
11411
  let data = {};
11411
11412
  try {
11412
11413
  const parsed = await response.json();
11413
- if (isRecord$10(parsed)) data = parsed;
11414
+ if (isRecord$9(parsed)) data = parsed;
11414
11415
  } catch {}
11415
11416
  return {
11416
11417
  status,
@@ -13372,9 +13373,9 @@ function blunContextWindowsUrl(oauthHost) {
13372
13373
  return `${(oauthHost ?? process.env["BLUN_OAUTH_HOST"] ?? "https://account.blun.ai").replace(/\/+$/, "")}/api/verbrauch/tarife`;
13373
13374
  }
13374
13375
  function parseManagedContextWindow(payload, plan) {
13375
- if (!isRecord$10(payload)) return void 0;
13376
+ if (!isRecord$9(payload)) return void 0;
13376
13377
  const contextWindows = payload["kontext"];
13377
- if (!isRecord$10(contextWindows)) return void 0;
13378
+ if (!isRecord$9(contextWindows)) return void 0;
13378
13379
  const value = contextWindows[plan];
13379
13380
  return typeof value === "number" && Number.isSafeInteger(value) && value > 0 ? value : void 0;
13380
13381
  }
@@ -13409,7 +13410,7 @@ function parseManagedUsagePayload(payload) {
13409
13410
  const plan = typeof rec["plan"] === "string" && rec["plan"].trim().length > 0 ? rec["plan"].trim() : void 0;
13410
13411
  const contextWindowTokens = managedContextWindowFrom(rec);
13411
13412
  const unlimited = rec["unlimited"] === true;
13412
- const stand = isRecord$10(rec["stand"]) ? rec["stand"] : void 0;
13413
+ const stand = isRecord$9(rec["stand"]) ? rec["stand"] : void 0;
13413
13414
  if (stand !== void 0) for (const [sourceKey, id, label] of ACCOUNT_USAGE_WINDOWS) {
13414
13415
  const row = toAccountUsageRow(stand[sourceKey], id, label, unlimited);
13415
13416
  if (row !== null) limits.push(row);
@@ -13419,9 +13420,9 @@ function parseManagedUsagePayload(payload) {
13419
13420
  const item = rawLimits[idx];
13420
13421
  if (!item || typeof item !== "object") continue;
13421
13422
  const detailRaw = item["detail"];
13422
- const detail = isRecord$10(detailRaw) ? detailRaw : item;
13423
+ const detail = isRecord$9(detailRaw) ? detailRaw : item;
13423
13424
  const windowRaw = item["window"];
13424
- const row = toUsageRow(detail, limitLabel(item, detail, isRecord$10(windowRaw) ? windowRaw : {}, idx));
13425
+ const row = toUsageRow(detail, limitLabel(item, detail, isRecord$9(windowRaw) ? windowRaw : {}, idx));
13425
13426
  if (row !== null) limits.push(row);
13426
13427
  }
13427
13428
  return {
@@ -13462,7 +13463,7 @@ const ACCOUNT_USAGE_WINDOWS = [
13462
13463
  ]
13463
13464
  ];
13464
13465
  function toAccountUsageRow(raw, id, label, accountUnlimited) {
13465
- if (!isRecord$10(raw)) return null;
13466
+ if (!isRecord$9(raw)) return null;
13466
13467
  const used = toInt(raw["verbraucht"]);
13467
13468
  const unlimited = accountUnlimited || raw["unlimited"] === true;
13468
13469
  const fraction = raw["anteil"];
@@ -13495,7 +13496,7 @@ function toAccountUsageRow(raw, id, label, accountUnlimited) {
13495
13496
  };
13496
13497
  }
13497
13498
  function toUsageRow(raw, defaultLabel) {
13498
- if (!isRecord$10(raw)) return null;
13499
+ if (!isRecord$9(raw)) return null;
13499
13500
  const unlimited = raw["unlimited"] === true;
13500
13501
  const limit = toInt(raw["limit"]);
13501
13502
  let used = toInt(raw["used"]);
@@ -13616,7 +13617,7 @@ function isManagedQuotaErrorMessage(message) {
13616
13617
  return /you(?:'|’)?ve reached your usage limit/.test(normalized) && /billing cycle|quota will be (?:refreshed|reset)|purchase extra usage/.test(normalized);
13617
13618
  }
13618
13619
  function hasManagedUsageShape(payload) {
13619
- if (!isRecord$10(payload)) return false;
13620
+ if (!isRecord$9(payload)) return false;
13620
13621
  let recognized = false;
13621
13622
  if ("context_window_tokens" in payload || "contextWindowTokens" in payload) {
13622
13623
  recognized = true;
@@ -13632,15 +13633,15 @@ function hasManagedUsageShape(payload) {
13632
13633
  if (!Array.isArray(limits)) return false;
13633
13634
  for (let index = 0; index < limits.length; index++) {
13634
13635
  const item = limits[index];
13635
- if (!isRecord$10(item)) return false;
13636
- const detail = isRecord$10(item["detail"]) ? item["detail"] : item;
13637
- if (toUsageRow(detail, limitLabel(item, detail, isRecord$10(item["window"]) ? item["window"] : {}, index)) === null) return false;
13636
+ if (!isRecord$9(item)) return false;
13637
+ const detail = isRecord$9(item["detail"]) ? item["detail"] : item;
13638
+ if (toUsageRow(detail, limitLabel(item, detail, isRecord$9(item["window"]) ? item["window"] : {}, index)) === null) return false;
13638
13639
  }
13639
13640
  }
13640
13641
  if ("stand" in payload) {
13641
13642
  recognized = true;
13642
13643
  const stand = payload["stand"];
13643
- if (!isRecord$10(stand)) return false;
13644
+ if (!isRecord$9(stand)) return false;
13644
13645
  const windows = ACCOUNT_USAGE_WINDOWS.filter(([sourceKey]) => sourceKey in stand);
13645
13646
  if (windows.length === 0) return false;
13646
13647
  const unlimited = payload["unlimited"] === true;
@@ -13723,8 +13724,8 @@ function userExtras(existing, remoteOwnedFields) {
13723
13724
  return out;
13724
13725
  }
13725
13726
  function mergeRefreshedModelAlias(existing, remote, remoteOwnedFields) {
13726
- const current = isRecord$10(existing) ? existing : {};
13727
- const overrides = cloneOverrides(isRecord$10(current["overrides"]) ? current["overrides"] : void 0);
13727
+ const current = isRecord$9(existing) ? existing : {};
13728
+ const overrides = cloneOverrides(isRecord$9(current["overrides"]) ? current["overrides"] : void 0);
13728
13729
  return {
13729
13730
  ...userExtras(current, remoteOwnedFields),
13730
13731
  ...remote,
@@ -13933,7 +13934,7 @@ function parseModelContextLength(item, modelId) {
13933
13934
  return values[0];
13934
13935
  }
13935
13936
  function toModelInfo(item) {
13936
- if (!isRecord$10(item) || typeof item["id"] !== "string" || item["id"].length === 0) return;
13937
+ if (!isRecord$9(item) || typeof item["id"] !== "string" || item["id"].length === 0) return;
13937
13938
  const contextLength = parseModelContextLength(item, item["id"]);
13938
13939
  const displayName = item["display_name"];
13939
13940
  const normalizedDisplayName = typeof displayName === "string" && displayName.length > 0 ? displayName : void 0;
@@ -14020,7 +14021,7 @@ async function fetchManagedBlunCodeModels(options) {
14020
14021
  throw new Error(message);
14021
14022
  }
14022
14023
  const payload = await response.json();
14023
- if (!isRecord$10(payload) || !Array.isArray(payload["data"])) throw new Error(`Unexpected models response for ${baseUrl}.`);
14024
+ if (!isRecord$9(payload) || !Array.isArray(payload["data"])) throw new Error(`Unexpected models response for ${baseUrl}.`);
14024
14025
  return payload["data"].map((item) => toModelInfo(item)).filter((item) => item !== void 0);
14025
14026
  }
14026
14027
  throw new Error(`Failed to list BLUN models for ${baseUrl}.`);
@@ -14063,11 +14064,11 @@ function applyManagedBlunCodeConfig(config, options) {
14063
14064
  apiKey
14064
14065
  };
14065
14066
  const upstreamKeys = new Set(options.models.map((m) => managedModelKey(m.id)));
14066
- for (const [key, model] of Object.entries(existingModels)) if (RETIRED_BLUN_MODEL_KEYS.has(key) || isRecord$10(model) && model["provider"] === "managed:blun" && !upstreamKeys.has(key)) delete existingModels[key];
14067
+ for (const [key, model] of Object.entries(existingModels)) if (RETIRED_BLUN_MODEL_KEYS.has(key) || isRecord$9(model) && model["provider"] === "managed:blun" && !upstreamKeys.has(key)) delete existingModels[key];
14067
14068
  for (const model of options.models) {
14068
14069
  const capabilities = capabilitiesForModel(model);
14069
14070
  const key = managedModelKey(model.id);
14070
- const existing = isRecord$10(existingModels[key]) ? existingModels[key] : {};
14071
+ const existing = isRecord$9(existingModels[key]) ? existingModels[key] : {};
14071
14072
  const supportsAdaptiveThinking = capabilities?.includes("thinking") === true || capabilities?.includes("always_thinking") === true;
14072
14073
  existingModels[key] = mergeRefreshedModelAlias(existing, {
14073
14074
  provider: BLUN_PROVIDER_NAME$1,
@@ -14115,7 +14116,7 @@ function applyManagedBlunCodeLogoutConfig(config) {
14115
14116
  let removedDefaultModel = false;
14116
14117
  const existingModels = config.models ?? {};
14117
14118
  for (const [key, model] of Object.entries(existingModels)) {
14118
- if (!isRecord$10(model) || model["provider"] !== "managed:blun") continue;
14119
+ if (!isRecord$9(model) || model["provider"] !== "managed:blun") continue;
14119
14120
  delete existingModels[key];
14120
14121
  if (config.defaultModel === key) removedDefaultModel = true;
14121
14122
  }
@@ -14155,7 +14156,7 @@ function selectDefaultModel(config, models, options) {
14155
14156
  function canPreserveDefaultModel(existingModels, defaultModel, managedModels) {
14156
14157
  if (managedModels.has(defaultModel)) return true;
14157
14158
  const existing = existingModels[defaultModel];
14158
- return isRecord$10(existing) && existing["provider"] !== "managed:blun";
14159
+ return isRecord$9(existing) && existing["provider"] !== "managed:blun";
14159
14160
  }
14160
14161
  function assertPositiveContextLength(model) {
14161
14162
  if (!Number.isInteger(model.contextLength) || model.contextLength <= 0) throw new Error(`BLUN model "${model.id}" must include a positive context_length.`);
@@ -14191,13 +14192,13 @@ function blunManagedQuotaUrl(oauthHost) {
14191
14192
  return `${(oauthHost ?? process.env["BLUN_OAUTH_HOST"] ?? "https://account.blun.ai").replace(/\/+$/, "")}${MANAGED_QUOTA_PATH}`;
14192
14193
  }
14193
14194
  function parseManagedQuotaPayload(payload) {
14194
- if (!isRecord$10(payload)) return void 0;
14195
+ if (!isRecord$9(payload)) return void 0;
14195
14196
  const plan = nonEmptyString$5(payload["plan"]);
14196
14197
  const paid = payload["bezahlt"];
14197
14198
  const creditCents = payload["guthaben_cent"];
14198
14199
  const billingKind = nonEmptyString$5(payload["art"]);
14199
14200
  const globalUnlimited = payload["unlimited"];
14200
- if (plan === void 0 || typeof paid !== "boolean" || !Number.isSafeInteger(creditCents) || creditCents < 0 || billingKind === void 0 || globalUnlimited !== void 0 && typeof globalUnlimited !== "boolean" || !isRecord$10(payload["stand"])) return;
14201
+ if (plan === void 0 || typeof paid !== "boolean" || !Number.isSafeInteger(creditCents) || creditCents < 0 || billingKind === void 0 || globalUnlimited !== void 0 && typeof globalUnlimited !== "boolean" || !isRecord$9(payload["stand"])) return;
14201
14202
  if (!hasStrictQuotaStand(payload["stand"], globalUnlimited === true)) return void 0;
14202
14203
  const limits = parseManagedUsagePayload(payload).limits;
14203
14204
  if (limits.length !== REQUIRED_WINDOWS.length || REQUIRED_WINDOWS.some(([, id]) => limits.filter((row) => row.id === id).length !== 1)) return;
@@ -14267,7 +14268,7 @@ function nonEmptyString$5(value) {
14267
14268
  function hasStrictQuotaStand(stand, globalUnlimited) {
14268
14269
  return REQUIRED_WINDOWS.every(([sourceKey]) => {
14269
14270
  const row = stand[sourceKey];
14270
- if (!isRecord$10(row)) return false;
14271
+ if (!isRecord$9(row)) return false;
14271
14272
  const used = row["verbraucht"];
14272
14273
  const rowUnlimited = row["unlimited"];
14273
14274
  if (rowUnlimited !== void 0 && typeof rowUnlimited !== "boolean") return false;
@@ -17584,629 +17585,6 @@ function resolveGlobalLogPath(homeDir) {
17584
17585
  return join$1(homeDir, "logs", "blun.log");
17585
17586
  }
17586
17587
  //#endregion
17587
- //#region ../../../../king-621-release-20261008-r1/snapshot/packages/kosong/src/providers/blun-schema.ts
17588
- /**
17589
- * Dereference all `$ref` references in a JSON Schema by inlining definitions
17590
- * from local JSON pointers such as `$defs` and draft-7 `definitions`. Resolved
17591
- * top-level definition buckets are removed from the result.
17592
- *
17593
- * Circular references are detected and left as `$ref` to avoid infinite
17594
- * recursion; in that case the referenced definition bucket is preserved so the
17595
- * remaining local `$ref` pointers stay resolvable to a JSON Schema validator.
17596
- */
17597
- function derefJsonSchema(schema) {
17598
- const result = resolveNode(schema, schema, /* @__PURE__ */ new Set());
17599
- if (!hasUnresolvedDefinitionRef(result, "$defs")) delete result["$defs"];
17600
- if (!hasUnresolvedDefinitionRef(result, "definitions")) delete result["definitions"];
17601
- return result;
17602
- }
17603
- const TYPE_COMPLETION_SKIP_KEYS = new Set([
17604
- "$ref",
17605
- "allOf",
17606
- "anyOf",
17607
- "else",
17608
- "if",
17609
- "not",
17610
- "oneOf",
17611
- "then"
17612
- ]);
17613
- const CHILD_SCHEMA_SLOTS = [
17614
- {
17615
- key: "$defs",
17616
- kind: "map"
17617
- },
17618
- {
17619
- key: "definitions",
17620
- kind: "map"
17621
- },
17622
- {
17623
- key: "dependencies",
17624
- kind: "map",
17625
- parentType: "object"
17626
- },
17627
- {
17628
- key: "dependentSchemas",
17629
- kind: "map",
17630
- parentType: "object"
17631
- },
17632
- {
17633
- key: "patternProperties",
17634
- kind: "map",
17635
- parentType: "object"
17636
- },
17637
- {
17638
- key: "properties",
17639
- kind: "map",
17640
- parentType: "object"
17641
- },
17642
- {
17643
- key: "additionalItems",
17644
- kind: "single",
17645
- parentType: "array"
17646
- },
17647
- {
17648
- key: "additionalProperties",
17649
- kind: "single",
17650
- parentType: "object"
17651
- },
17652
- {
17653
- key: "contains",
17654
- kind: "single",
17655
- parentType: "array"
17656
- },
17657
- {
17658
- key: "contentSchema",
17659
- kind: "single",
17660
- parentType: "string"
17661
- },
17662
- {
17663
- key: "else",
17664
- kind: "single"
17665
- },
17666
- {
17667
- key: "if",
17668
- kind: "single"
17669
- },
17670
- {
17671
- key: "not",
17672
- kind: "single"
17673
- },
17674
- {
17675
- key: "propertyNames",
17676
- kind: "single",
17677
- parentType: "object"
17678
- },
17679
- {
17680
- key: "then",
17681
- kind: "single"
17682
- },
17683
- {
17684
- key: "unevaluatedItems",
17685
- kind: "single",
17686
- parentType: "array"
17687
- },
17688
- {
17689
- key: "unevaluatedProperties",
17690
- kind: "single",
17691
- parentType: "object"
17692
- },
17693
- {
17694
- key: "allOf",
17695
- kind: "array"
17696
- },
17697
- {
17698
- key: "anyOf",
17699
- kind: "array"
17700
- },
17701
- {
17702
- key: "oneOf",
17703
- kind: "array"
17704
- },
17705
- {
17706
- key: "prefixItems",
17707
- kind: "array",
17708
- parentType: "array"
17709
- },
17710
- {
17711
- key: "items",
17712
- kind: "schema-or-array",
17713
- parentType: "array"
17714
- }
17715
- ];
17716
- const OBJECT_STRUCTURE_KEYS = new Set([
17717
- ...childSchemaKeysForParentType("object"),
17718
- "dependentRequired",
17719
- "maxProperties",
17720
- "minProperties",
17721
- "required"
17722
- ]);
17723
- const ARRAY_STRUCTURE_KEYS = new Set([
17724
- ...childSchemaKeysForParentType("array"),
17725
- "maxContains",
17726
- "maxItems",
17727
- "minContains",
17728
- "minItems",
17729
- "uniqueItems"
17730
- ]);
17731
- const STRING_STRUCTURE_KEYS = new Set([
17732
- ...childSchemaKeysForParentType("string"),
17733
- "contentEncoding",
17734
- "contentMediaType",
17735
- "format",
17736
- "maxLength",
17737
- "minLength",
17738
- "pattern"
17739
- ]);
17740
- const NUMERIC_STRUCTURE_KEYS = new Set([
17741
- "exclusiveMaximum",
17742
- "exclusiveMinimum",
17743
- "maximum",
17744
- "minimum",
17745
- "multipleOf"
17746
- ]);
17747
- /**
17748
- * Return a deep-cloned JSON Schema with missing `type` fields filled in for
17749
- * Blun tool compatibility.
17750
- *
17751
- * Blun's tool validator rejects some valid JSON Schema shapes when nested
17752
- * property schemas omit `type` (for example enum-only MCP properties). This is
17753
- * a provider-compatibility normalizer, not a complete JSON Schema compiler:
17754
- * it resolves local refs, preserves combinator nodes, infers obvious
17755
- * scalar/object/array types, and falls back to `string` only for nested
17756
- * typeless property schemas. The root schema object is treated as a container
17757
- * and is not itself normalized.
17758
- */
17759
- function normalizeBlunToolSchema(schema) {
17760
- return ensureBlunPropertyTypes(derefJsonSchema(schema));
17761
- }
17762
- function ensureBlunPropertyTypes(schema) {
17763
- const normalized = cloneJsonValue(schema);
17764
- if (!isRecord$9(normalized)) throw new Error("JSON Schema root must normalize to an object.");
17765
- recurseSchema(normalized);
17766
- return normalized;
17767
- }
17768
- function hasUnresolvedDefinitionRef(node, bucketKey) {
17769
- if (Array.isArray(node)) return node.some((child) => hasUnresolvedDefinitionRef(child, bucketKey));
17770
- if (typeof node === "object" && node !== null) {
17771
- const obj = node;
17772
- const ref = obj["$ref"];
17773
- if (typeof ref === "string" && ref.startsWith(`#/${bucketKey}/`)) return true;
17774
- for (const [key, value] of Object.entries(obj)) {
17775
- if (key === bucketKey) continue;
17776
- if (hasUnresolvedDefinitionRef(value, bucketKey)) return true;
17777
- }
17778
- return false;
17779
- }
17780
- return false;
17781
- }
17782
- function resolveNode(node, root, visited) {
17783
- if (Array.isArray(node)) return node.map((item) => resolveNode(item, root, visited));
17784
- if (typeof node === "object" && node !== null) {
17785
- const obj = node;
17786
- if (typeof obj["$ref"] === "string") {
17787
- const ref = obj["$ref"];
17788
- if (isLocalJsonPointerRef(ref)) {
17789
- if (visited.has(ref)) return obj;
17790
- const resolvedRef = resolveLocalJsonPointer(root, ref);
17791
- if (resolvedRef.found) {
17792
- visited.add(ref);
17793
- const resolved = resolveNode(resolvedRef.value, root, visited);
17794
- visited.delete(ref);
17795
- if (typeof resolved === "object" && resolved !== null && !Array.isArray(resolved)) {
17796
- const merged = { ...resolved };
17797
- for (const [key, value] of Object.entries(obj)) {
17798
- if (key === "$ref") continue;
17799
- merged[key] = resolveNode(value, root, visited);
17800
- }
17801
- return merged;
17802
- }
17803
- return resolved;
17804
- }
17805
- }
17806
- return obj;
17807
- }
17808
- const resolved = {};
17809
- for (const [key, value] of Object.entries(obj)) resolved[key] = resolveNode(value, root, visited);
17810
- return resolved;
17811
- }
17812
- return node;
17813
- }
17814
- function isLocalJsonPointerRef(ref) {
17815
- return ref === "#" || ref.startsWith("#/");
17816
- }
17817
- function resolveLocalJsonPointer(root, ref) {
17818
- if (ref === "#") return {
17819
- found: true,
17820
- value: root
17821
- };
17822
- let current = root;
17823
- for (const rawPart of ref.slice(2).split("/")) {
17824
- const part = unescapeJsonPointerPart(rawPart);
17825
- if (isRecord$9(current)) {
17826
- if (!hasOwn(current, part)) return { found: false };
17827
- current = current[part];
17828
- } else if (Array.isArray(current)) {
17829
- const index = parseJsonPointerArrayIndex(part);
17830
- if (index === null || index >= current.length) return { found: false };
17831
- current = current[index];
17832
- } else return { found: false };
17833
- }
17834
- return {
17835
- found: true,
17836
- value: current
17837
- };
17838
- }
17839
- function unescapeJsonPointerPart(part) {
17840
- return part.replaceAll("~1", "/").replaceAll("~0", "~");
17841
- }
17842
- function parseJsonPointerArrayIndex(part) {
17843
- if (!/^(0|[1-9]\d*)$/.test(part)) return null;
17844
- return Number(part);
17845
- }
17846
- function recurseSchema(node) {
17847
- if (!isRecord$9(node)) return;
17848
- visitChildSchemas(node, normalizeProperty);
17849
- }
17850
- function visitChildSchemas(node, visit) {
17851
- for (const { key, kind } of CHILD_SCHEMA_SLOTS) {
17852
- const value = node[key];
17853
- if (kind === "single") {
17854
- if (isRecord$9(value)) visit(value);
17855
- } else if (kind === "array") {
17856
- if (Array.isArray(value)) for (const item of value) visit(item);
17857
- } else if (kind === "map") {
17858
- if (isRecord$9(value)) for (const item of Object.values(value)) visit(item);
17859
- } else if (kind === "schema-or-array") {
17860
- if (isRecord$9(value)) visit(value);
17861
- else if (Array.isArray(value)) for (const item of value) visit(item);
17862
- }
17863
- }
17864
- }
17865
- function childSchemaKeysForParentType(parentType) {
17866
- return CHILD_SCHEMA_SLOTS.flatMap((slot) => {
17867
- if (!("parentType" in slot) || slot.parentType !== parentType) return [];
17868
- return [slot.key];
17869
- });
17870
- }
17871
- function normalizeProperty(node) {
17872
- if (!isRecord$9(node)) return;
17873
- if (!hasOwn(node, "type") && !hasAnyKey(node, TYPE_COMPLETION_SKIP_KEYS)) {
17874
- const enumValues = node["enum"];
17875
- if (Array.isArray(enumValues) && enumValues.length > 0) node["type"] = inferTypeFromValues(enumValues);
17876
- else if (hasOwn(node, "const")) node["type"] = inferTypeFromValues([node["const"]]);
17877
- else node["type"] = inferTypeFromStructure(node);
17878
- } else if (!hasAnyKey(node, TYPE_COMPLETION_SKIP_KEYS) && typeof node["type"] === "string") {
17879
- const enumValues = node["enum"];
17880
- if (Array.isArray(enumValues) && enumValues.length > 0) try {
17881
- const inferred = inferTypeFromValues(enumValues);
17882
- if (node["type"] !== inferred) {
17883
- node["type"] = inferred;
17884
- removeIrrelevantStructureKeys(node, inferred);
17885
- }
17886
- } catch {}
17887
- else if (hasOwn(node, "const")) try {
17888
- const inferred = inferTypeFromValues([node["const"]]);
17889
- if (node["type"] !== inferred) {
17890
- node["type"] = inferred;
17891
- removeIrrelevantStructureKeys(node, inferred);
17892
- }
17893
- } catch {}
17894
- }
17895
- recurseSchema(node);
17896
- }
17897
- function removeIrrelevantStructureKeys(node, newType) {
17898
- if (newType !== "object") for (const key of OBJECT_STRUCTURE_KEYS) delete node[key];
17899
- if (newType !== "array") for (const key of ARRAY_STRUCTURE_KEYS) delete node[key];
17900
- }
17901
- function inferTypeFromStructure(schema) {
17902
- if (hasAnyKey(schema, OBJECT_STRUCTURE_KEYS)) return "object";
17903
- if (hasAnyKey(schema, ARRAY_STRUCTURE_KEYS)) return "array";
17904
- if (hasAnyKey(schema, STRING_STRUCTURE_KEYS)) return "string";
17905
- if (hasAnyKey(schema, NUMERIC_STRUCTURE_KEYS)) return "number";
17906
- return "string";
17907
- }
17908
- function inferTypeFromValues(values) {
17909
- const inferred = /* @__PURE__ */ new Set();
17910
- for (const value of values) {
17911
- const valueType = inferValueType(value);
17912
- if (valueType === void 0) throw new Error("Cannot infer JSON Schema type from non-JSON enum or const value.");
17913
- inferred.add(valueType);
17914
- }
17915
- const types = normalizeInferredTypes(inferred);
17916
- if (types.length === 1) {
17917
- const onlyType = types[0];
17918
- if (onlyType === void 0) throw new Error("Cannot infer JSON Schema type from an empty enum.");
17919
- return onlyType;
17920
- }
17921
- throw new Error("Mixed JSON Schema enum or const types are not supported by Blun tool schemas.");
17922
- }
17923
- function inferValueType(value) {
17924
- if (value === null) return "null";
17925
- if (Array.isArray(value)) return "array";
17926
- switch (typeof value) {
17927
- case "string": return "string";
17928
- case "number": return Number.isInteger(value) ? "integer" : "number";
17929
- case "boolean": return "boolean";
17930
- case "object": return "object";
17931
- case "bigint":
17932
- case "function":
17933
- case "symbol":
17934
- case "undefined": return;
17935
- }
17936
- }
17937
- function normalizeInferredTypes(types) {
17938
- const normalized = new Set(types);
17939
- if (normalized.has("number")) normalized.delete("integer");
17940
- return [
17941
- "string",
17942
- "number",
17943
- "integer",
17944
- "boolean",
17945
- "object",
17946
- "array",
17947
- "null"
17948
- ].filter((type) => normalized.has(type));
17949
- }
17950
- function hasAnyKey(obj, keys) {
17951
- for (const key of keys) if (hasOwn(obj, key)) return true;
17952
- return false;
17953
- }
17954
- function cloneJsonValue(value) {
17955
- if (Array.isArray(value)) return value.map((item) => cloneJsonValue(item));
17956
- if (isRecord$9(value)) {
17957
- const cloned = {};
17958
- for (const [key, child] of Object.entries(value)) cloned[key] = cloneJsonValue(child);
17959
- return cloned;
17960
- }
17961
- return value;
17962
- }
17963
- function isRecord$9(value) {
17964
- return typeof value === "object" && value !== null && !Array.isArray(value);
17965
- }
17966
- function hasOwn(obj, key) {
17967
- return Object.prototype.hasOwnProperty.call(obj, key);
17968
- }
17969
- Object.fromEntries(Object.entries({
17970
- "video/mp4": "mp4",
17971
- "video/mpeg": "mpeg",
17972
- "video/quicktime": "mov",
17973
- "video/webm": "webm",
17974
- "video/x-matroska": "mkv",
17975
- "video/x-msvideo": "avi",
17976
- "video/x-flv": "flv",
17977
- "video/3gpp": "3gp"
17978
- }).map(([mime, ext]) => [ext, mime]));
17979
- //#endregion
17980
- //#region ../../../../king-621-release-20261008-r1/snapshot/packages/kosong/src/providers/chat-completions-wire.ts
17981
- function convertChatCompletionContentPart(part) {
17982
- switch (part.type) {
17983
- case "text": return {
17984
- type: "text",
17985
- text: part.text
17986
- };
17987
- case "think": return null;
17988
- case "image_url": return {
17989
- type: "image_url",
17990
- image_url: part.imageUrl.id === void 0 ? { url: part.imageUrl.url } : {
17991
- url: part.imageUrl.url,
17992
- id: part.imageUrl.id
17993
- }
17994
- };
17995
- case "audio_url": return {
17996
- type: "audio_url",
17997
- audio_url: part.audioUrl.id === void 0 ? { url: part.audioUrl.url } : {
17998
- url: part.audioUrl.url,
17999
- id: part.audioUrl.id
18000
- }
18001
- };
18002
- case "video_url": return {
18003
- type: "video_url",
18004
- video_url: part.videoUrl.id === void 0 ? { url: part.videoUrl.url } : {
18005
- url: part.videoUrl.url,
18006
- id: part.videoUrl.id
18007
- }
18008
- };
18009
- default: throw new Error(`Unknown content part type: ${part.type}`);
18010
- }
18011
- }
18012
- function toolToChatCompletion(tool) {
18013
- return {
18014
- type: "function",
18015
- function: {
18016
- name: tool.name,
18017
- description: tool.description,
18018
- parameters: tool.parameters
18019
- }
18020
- };
18021
- }
18022
- //#endregion
18023
- //#region ../../../../king-621-release-20261008-r1/snapshot/packages/kosong/src/providers/tool-call-id.ts
18024
- const EMPTY_TOOL_CALL_ID = "tool_call";
18025
- const TOOL_CALL_ID_SAFE_CHARS = /[^a-zA-Z0-9_-]/g;
18026
- function sanitizeToolCallId(id, maxLength) {
18027
- const sanitized = id.replace(TOOL_CALL_ID_SAFE_CHARS, "_");
18028
- return maxLength === void 0 ? sanitized : sanitized.slice(0, maxLength);
18029
- }
18030
- function normalizeToolCallIdsForProvider(messages, policy) {
18031
- const rawIds = collectToolCallIds(messages);
18032
- if (rawIds.length === 0) return messages;
18033
- const mappedIds = buildToolCallIdMap(rawIds, policy);
18034
- let changed = false;
18035
- const normalizedMessages = messages.map((message) => {
18036
- let messageChanged = false;
18037
- let toolCalls = message.toolCalls;
18038
- if (message.toolCalls.length > 0) toolCalls = message.toolCalls.map((toolCall) => {
18039
- const mappedId = mappedIds.get(toolCall.id);
18040
- if (mappedId === void 0 || mappedId === toolCall.id) return toolCall;
18041
- messageChanged = true;
18042
- return {
18043
- ...toolCall,
18044
- id: mappedId
18045
- };
18046
- });
18047
- const mappedToolCallId = (message.toolCallId === void 0 ? void 0 : mappedIds.get(message.toolCallId)) ?? message.toolCallId;
18048
- if (mappedToolCallId !== message.toolCallId) messageChanged = true;
18049
- if (!messageChanged) return message;
18050
- changed = true;
18051
- return {
18052
- ...message,
18053
- toolCalls,
18054
- toolCallId: mappedToolCallId
18055
- };
18056
- });
18057
- return changed ? normalizedMessages : messages;
18058
- }
18059
- function collectToolCallIds(messages) {
18060
- const ids = [];
18061
- const seen = /* @__PURE__ */ new Set();
18062
- const append = (id) => {
18063
- if (seen.has(id)) return;
18064
- seen.add(id);
18065
- ids.push(id);
18066
- };
18067
- for (const message of messages) {
18068
- for (const toolCall of message.toolCalls) append(toolCall.id);
18069
- if (message.toolCallId !== void 0) append(message.toolCallId);
18070
- }
18071
- return ids;
18072
- }
18073
- function buildToolCallIdMap(rawIds, policy) {
18074
- const mappedIds = /* @__PURE__ */ new Map();
18075
- const usedIds = /* @__PURE__ */ new Set();
18076
- for (const rawId of rawIds) {
18077
- const normalized = policy.normalize(rawId);
18078
- if (normalized === rawId && normalized.length > 0) {
18079
- mappedIds.set(rawId, normalized);
18080
- usedIds.add(normalized);
18081
- }
18082
- }
18083
- for (const rawId of rawIds) {
18084
- if (mappedIds.has(rawId)) continue;
18085
- const unique = makeUniqueToolCallId(policy.normalize(rawId), usedIds, policy.maxLength);
18086
- mappedIds.set(rawId, unique);
18087
- usedIds.add(unique);
18088
- }
18089
- return mappedIds;
18090
- }
18091
- function makeUniqueToolCallId(normalized, usedIds, maxLength) {
18092
- const base = normalized.length > 0 ? normalized : EMPTY_TOOL_CALL_ID;
18093
- const candidate = truncateToolCallId(base, maxLength, "");
18094
- if (!usedIds.has(candidate)) return candidate;
18095
- for (let i = 2;; i++) {
18096
- const suffixed = truncateToolCallId(base, maxLength, `_${i}`);
18097
- if (!usedIds.has(suffixed)) return suffixed;
18098
- }
18099
- }
18100
- function truncateToolCallId(base, maxLength, suffix) {
18101
- if (maxLength === void 0) return `${base}${suffix}`;
18102
- const baseLength = maxLength - suffix.length;
18103
- if (baseLength <= 0) throw new Error(`Tool call id maxLength ${maxLength} is too small for suffix ${suffix}.`);
18104
- return `${base.slice(0, baseLength)}${suffix}`;
18105
- }
18106
- //#endregion
18107
- //#region ../../../../king-621-release-20261008-r1/snapshot/packages/kosong/src/providers/blun.ts
18108
- const BLUN_TOOL_CALL_ID_POLICY = {
18109
- normalize: (id) => sanitizeToolCallId(id, 64),
18110
- maxLength: 64
18111
- };
18112
- function isEffectivelyEmptyContent(parts) {
18113
- for (const part of parts) {
18114
- if (part.type !== "text") return false;
18115
- if (part.text.trim() !== "") return false;
18116
- }
18117
- return true;
18118
- }
18119
- function isEmptyAssistantHistoryMessage(message) {
18120
- if (message.role !== "assistant" || message.toolCalls.length > 0) return false;
18121
- return message.content.every((part) => part.type === "think" || part.type === "text" && part.text.trim() === "");
18122
- }
18123
- const BLUN_VISION_DATA_URL = /^data:(image\/(?:png|jpeg|webp|gif));base64,([A-Za-z0-9+/]+={0,2})$/;
18124
- const BLUN_VISION_MAX_ATTACHMENTS = 4;
18125
- const BLUN_VISION_MAX_IMAGE_BYTES = 8 * 1024 * 1024;
18126
- function collectBlunVisionAttachments(messages) {
18127
- const attachments = [];
18128
- for (const message of messages) for (const part of message.content) {
18129
- if (part.type !== "image_url") continue;
18130
- const match = BLUN_VISION_DATA_URL.exec(part.imageUrl.url);
18131
- if (match === null) continue;
18132
- const mediaType = match[1];
18133
- const data = match[2];
18134
- if (mediaType === void 0 || data === void 0 || data.length % 4 !== 0) continue;
18135
- const bytes = Buffer.from(data, "base64");
18136
- if (bytes.length === 0 || bytes.length > BLUN_VISION_MAX_IMAGE_BYTES || bytes.toString("base64") !== data) continue;
18137
- attachments.push({
18138
- type: "image",
18139
- source: {
18140
- type: "base64",
18141
- media_type: mediaType,
18142
- data
18143
- }
18144
- });
18145
- if (attachments.length >= BLUN_VISION_MAX_ATTACHMENTS) return attachments;
18146
- }
18147
- return attachments;
18148
- }
18149
- function estimateBlunSerializedBodyBytes(systemPrompt, tools, history) {
18150
- const normalizedHistory = normalizeToolCallIdsForProvider([...history], BLUN_TOOL_CALL_ID_POLICY);
18151
- const messages = systemPrompt ? [{
18152
- role: "system",
18153
- content: systemPrompt
18154
- }] : [];
18155
- for (const message of normalizedHistory) if (!isEmptyAssistantHistoryMessage(message)) messages.push(convertMessage(message));
18156
- const attachments = collectBlunVisionAttachments(normalizedHistory);
18157
- return Buffer.byteLength(JSON.stringify({
18158
- model: "king",
18159
- messages,
18160
- stream: true,
18161
- ...tools.length > 0 ? { tools: tools.map(convertTool) } : {},
18162
- ...attachments.length > 0 ? { visionAttachments: attachments } : {},
18163
- stream_options: { include_usage: true }
18164
- }), "utf8");
18165
- }
18166
- function convertMessage(message) {
18167
- let reasoningContent = "";
18168
- const nonThinkParts = [];
18169
- for (const part of message.content) if (part.type === "think") reasoningContent += part.think;
18170
- else nonThinkParts.push(part);
18171
- const result = { role: message.role };
18172
- const hasToolCalls = message.toolCalls.length > 0;
18173
- if (!(message.role === "assistant" && hasToolCalls && isEffectivelyEmptyContent(nonThinkParts))) {
18174
- const firstPart = nonThinkParts[0];
18175
- if (nonThinkParts.length === 1 && firstPart?.type === "text") result.content = firstPart.text;
18176
- else if (nonThinkParts.length > 0) result.content = nonThinkParts.map((p) => convertChatCompletionContentPart(p)).filter((p) => p !== null);
18177
- }
18178
- if (message.name !== void 0) result.name = message.name;
18179
- if (hasToolCalls) result.tool_calls = message.toolCalls.map((tc) => {
18180
- const mapped = {
18181
- type: tc.type,
18182
- id: tc.id,
18183
- function: {
18184
- name: tc.name,
18185
- arguments: tc.arguments
18186
- }
18187
- };
18188
- if (tc.extras !== void 0) mapped.extras = tc.extras;
18189
- return mapped;
18190
- });
18191
- if (message.toolCallId !== void 0) result.tool_call_id = message.toolCallId;
18192
- if (reasoningContent) result.reasoning_content = reasoningContent;
18193
- return result;
18194
- }
18195
- function convertTool(tool) {
18196
- if (tool.name.startsWith("$")) return {
18197
- type: "builtin_function",
18198
- function: { name: tool.name }
18199
- };
18200
- const converted = toolToChatCompletion(tool);
18201
- return {
18202
- ...converted,
18203
- function: {
18204
- ...converted.function,
18205
- parameters: normalizeBlunToolSchema(tool.parameters)
18206
- }
18207
- };
18208
- }
18209
- //#endregion
18210
17588
  //#region ../../../../king-exact-618-r3-build-20261007-r2/snapshot/node_modules/.pnpm/js-yaml@4.3.1/node_modules/js-yaml/dist/js-yaml.mjs
18211
17589
  function getDefaultExportFromCjs(x) {
18212
17590
  return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x;
@@ -211087,7 +210465,7 @@ function histogram(image) {
211087
210465
  });
211088
210466
  return histogram;
211089
210467
  }
211090
- var ConvolutionMatrixSchema, ConvolutionComplexOptionsSchema, ConvolutionOptionsSchema, ConvoluteComplexOptionsSchema, ConvoluteOptionsSchema, PixelateSize, PixelateComplexOptionsSchema, PixelateOptionsSchema, HueActionSchema, SpinActionSchema, LightenActionSchema, RGBColorSchema, MixActionSchema, TintActionSchema, ShadeActionSchema, XorActionSchema, RedActionSchema, GreenActionSchema, BlueActionSchema, BrightenActionSchema, DarkenActionSchema, DesaturateActionSchema, SaturateActionSchema, GrayscaleActionSchema, ColorActionNameSchema, normalizeValue, getBounds, methods$14;
210468
+ var ConvolutionMatrixSchema, ConvolutionComplexOptionsSchema, ConvolutionOptionsSchema, ConvoluteComplexOptionsSchema, ConvoluteOptionsSchema, PixelateSize, PixelateComplexOptionsSchema, PixelateOptionsSchema, HueActionSchema, SpinActionSchema, LightenActionSchema, RGBColorSchema, MixActionSchema, TintActionSchema, ShadeActionSchema, XorActionSchema, RedActionSchema, GreenActionSchema, BlueActionSchema, BrightenActionSchema, DarkenActionSchema, DesaturateActionSchema, SaturateActionSchema, GrayscaleActionSchema, ColorActionNameSchema, normalizeValue$1, getBounds, methods$14;
211091
210469
  var init_esm$18 = __esmMin((() => {
211092
210470
  init_tinycolor();
211093
210471
  init_esm$28();
@@ -211227,7 +210605,7 @@ var init_esm$18 = __esmMin((() => {
211227
210605
  GREEN: "green",
211228
210606
  BLUE: "blue"
211229
210607
  });
211230
- normalizeValue = function(value, min, max) {
210608
+ normalizeValue$1 = function(value, min, max) {
211231
210609
  return (value - min) * 255 / (max - min);
211232
210610
  };
211233
210611
  getBounds = function(histogramChannel) {
@@ -211256,9 +210634,9 @@ var init_esm$18 = __esmMin((() => {
211256
210634
  const r = image.bitmap.data[idx + 0];
211257
210635
  const g = image.bitmap.data[idx + 1];
211258
210636
  const b = image.bitmap.data[idx + 2];
211259
- image.bitmap.data[idx + 0] = normalizeValue(r, bounds.r[0], bounds.r[1]);
211260
- image.bitmap.data[idx + 1] = normalizeValue(g, bounds.g[0], bounds.g[1]);
211261
- image.bitmap.data[idx + 2] = normalizeValue(b, bounds.b[0], bounds.b[1]);
210637
+ image.bitmap.data[idx + 0] = normalizeValue$1(r, bounds.r[0], bounds.r[1]);
210638
+ image.bitmap.data[idx + 1] = normalizeValue$1(g, bounds.g[0], bounds.g[1]);
210639
+ image.bitmap.data[idx + 2] = normalizeValue$1(b, bounds.b[0], bounds.b[1]);
211262
210640
  });
211263
210641
  return image;
211264
210642
  },
@@ -231667,9 +231045,9 @@ var FullCompaction = class {
231667
231045
  if (model === void 0 || this.agent.config.runtimeModel(model).provider.name !== "blun") return void 0;
231668
231046
  const systemPrompt = context.systemPrompt ?? this.agent.effectiveSystemPrompt;
231669
231047
  const tools = context.tools ?? this.agent.tools.loopTools;
231670
- if (estimateBlunSerializedBodyBytes$1(systemPrompt, [], []) + 4096 >= BLUN_COMPACTION_REQUEST_BUDGET_BYTES) return void 0;
231048
+ if (estimateBlunSerializedBodyBytes(systemPrompt, [], []) + 4096 >= BLUN_COMPACTION_REQUEST_BUDGET_BYTES) return void 0;
231671
231049
  return {
231672
- usedRequestBytesEstimate: estimateBlunSerializedBodyBytes$1(systemPrompt, tools, messages) + 4096,
231050
+ usedRequestBytesEstimate: estimateBlunSerializedBodyBytes(systemPrompt, tools, messages) + 4096,
231673
231051
  thresholdRequestBytes: BLUN_COMPACTION_REQUEST_BUDGET_BYTES
231674
231052
  };
231675
231053
  }
@@ -232084,7 +231462,7 @@ var FullCompaction = class {
232084
231462
  dropOrphanResults: true
232085
231463
  }), createUserMessage(requestInstruction)], capability));
232086
231464
  };
232087
- const estimateRequestBytes = (messages) => estimateBlunSerializedBodyBytes$1(this.agent.effectiveSystemPrompt, compactionTools, messages) + 4096;
231465
+ const estimateRequestBytes = (messages) => estimateBlunSerializedBodyBytes(this.agent.effectiveSystemPrompt, compactionTools, messages) + 4096;
232088
231466
  while (true) {
232089
231467
  signal.throwIfAborted();
232090
231468
  if (hierarchicalPassCount >= MAX_HIERARCHICAL_COMPACTION_PASSES) throw new BlunError(ErrorCodes.COMPACTION_FAILED, `Compaction stopped after ${String(MAX_HIERARCHICAL_COMPACTION_PASSES)} staged requests without reaching a final summary. The conversation history was not changed.`, { details: {
@@ -266722,6 +266100,56 @@ function formatBudget(value, unit) {
266722
266100
  return `${String(value)} ${value === 1 ? singular : unit}`;
266723
266101
  }
266724
266102
  //#endregion
266103
+ //#region ../../packages/agent-core/src/agent/turn/tool-result-progress.ts
266104
+ const VOLATILE_METADATA = new Set([
266105
+ "requestId",
266106
+ "request_id",
266107
+ "traceId",
266108
+ "trace_id",
266109
+ "toolCallId",
266110
+ "tool_call_id",
266111
+ "sessionId",
266112
+ "session_id",
266113
+ "timestamp",
266114
+ "durationMs",
266115
+ "duration_ms",
266116
+ "elapsedMs",
266117
+ "elapsed_ms"
266118
+ ]);
266119
+ function normalizeValue(value, stripMetadata = true) {
266120
+ if (Array.isArray(value)) return value.map((item) => normalizeValue(item, false));
266121
+ if (!isPlainRecord(value)) return value;
266122
+ const out = Object.create(null);
266123
+ for (const key of Object.keys(value).toSorted()) {
266124
+ if (stripMetadata && VOLATILE_METADATA.has(key)) continue;
266125
+ const metadata = key === "metadata" || key === "meta";
266126
+ out[key] = normalizeValue(value[key], metadata);
266127
+ }
266128
+ return out;
266129
+ }
266130
+ function normalizeText(text) {
266131
+ const trimmed = text.trim();
266132
+ if (trimmed === "") return null;
266133
+ try {
266134
+ return normalizeValue(JSON.parse(trimmed));
266135
+ } catch {
266136
+ return trimmed.replace(/\r\n/g, "\n");
266137
+ }
266138
+ }
266139
+ function hasContent(value) {
266140
+ if (value === null || value === void 0) return false;
266141
+ if (typeof value === "string") return value.trim() !== "";
266142
+ if (Array.isArray(value)) return value.some(hasContent);
266143
+ if (isPlainRecord(value)) return Object.values(value).some(hasContent);
266144
+ return true;
266145
+ }
266146
+ function toolProgressFingerprint(result) {
266147
+ if (result.isError === true) return null;
266148
+ const normalized = typeof result.output === "string" ? [normalizeText(result.output)] : result.output.map((part) => part.type === "text" ? normalizeText(part.text) : normalizeValue(part));
266149
+ if (!hasContent(normalized)) return null;
266150
+ return createHash("sha256").update(JSON.stringify(normalized)).digest("hex");
266151
+ }
266152
+ //#endregion
266725
266153
  //#region ../../packages/agent-core/src/agent/turn/tool-dedup.ts
266726
266154
  const REMINDER_TEXT_1 = "\n\n<system-reminder>\nYou are repeating the exact same tool call with identical parameters. Please carefully analyze the previous result. If the task is not yet complete, try a different method or parameters instead of repeating the same call.\n</system-reminder>";
266727
266155
  function makeReminderText2(toolName, repeatCount, args) {
@@ -266830,9 +266258,13 @@ var ToolCallDeduplicator = class {
266830
266258
  callKeyByCallId = /* @__PURE__ */ new Map();
266831
266259
  consecutiveKey = null;
266832
266260
  consecutiveCount = 0;
266261
+ consecutiveOutcome = null;
266262
+ stepOutcomes = /* @__PURE__ */ new Map();
266833
266263
  telemetry;
266264
+ reserveToolExecution;
266834
266265
  constructor(options) {
266835
266266
  this.telemetry = options?.telemetry;
266267
+ this.reserveToolExecution = options?.reserveToolExecution;
266836
266268
  }
266837
266269
  beginStep() {
266838
266270
  for (const deferred of this.stepDeferreds.values()) deferred.resolve({
@@ -266844,13 +266276,35 @@ var ToolCallDeduplicator = class {
266844
266276
  this.originalCallIndex.clear();
266845
266277
  this.syntheticCallIds.clear();
266846
266278
  this.callKeyByCallId.clear();
266279
+ this.stepOutcomes.clear();
266847
266280
  }
266848
266281
  endStep() {
266849
- for (const key of this.stepCalls) if (key === this.consecutiveKey) this.consecutiveCount += 1;
266850
- else {
266851
- this.consecutiveKey = key;
266852
- this.consecutiveCount = 1;
266282
+ const state = this.projectStreak(this.stepCalls.length - 1);
266283
+ this.consecutiveKey = state.key;
266284
+ this.consecutiveCount = state.count;
266285
+ this.consecutiveOutcome = state.outcome;
266286
+ }
266287
+ projectStreak(index) {
266288
+ let key = this.consecutiveKey;
266289
+ let count = this.consecutiveCount;
266290
+ let outcome = this.consecutiveOutcome;
266291
+ for (let i = 0; i <= index; i += 1) {
266292
+ const nextKey = this.stepCalls[i];
266293
+ const nextOutcome = this.stepOutcomes.get(i) ?? null;
266294
+ if (nextKey !== key) {
266295
+ key = nextKey;
266296
+ count = 1;
266297
+ outcome = nextOutcome;
266298
+ } else if (nextOutcome !== null && nextOutcome !== outcome) {
266299
+ count = 1;
266300
+ outcome = nextOutcome;
266301
+ } else count += 1;
266853
266302
  }
266303
+ return {
266304
+ key,
266305
+ count,
266306
+ outcome
266307
+ };
266854
266308
  }
266855
266309
  /**
266856
266310
  * Called from `prepareToolExecution`. If this `(toolName, args)` was already
@@ -266871,6 +266325,14 @@ var ToolCallDeduplicator = class {
266871
266325
  this.syntheticCallIds.add(toolCallId);
266872
266326
  return DEDUP_PLACEHOLDER_RESULT;
266873
266327
  }
266328
+ if (this.reserveToolExecution?.() === false) {
266329
+ this.callKeyByCallId.delete(toolCallId);
266330
+ return {
266331
+ output: "Tool execution limit reached. The work already recorded is retained; continue in a new user turn.",
266332
+ isError: true,
266333
+ stopTurn: true
266334
+ };
266335
+ }
266874
266336
  this.stepDeferreds.set(key, makeDeferred());
266875
266337
  this.originalCallIndex.set(toolCallId, index);
266876
266338
  return null;
@@ -266895,16 +266357,8 @@ var ToolCallDeduplicator = class {
266895
266357
  const index = this.originalCallIndex.get(toolCallId);
266896
266358
  if (index === void 0) return result;
266897
266359
  this.originalCallIndex.delete(toolCallId);
266898
- let lastKey = this.consecutiveKey;
266899
- let streak = this.consecutiveCount;
266900
- for (let i = 0; i <= index; i += 1) {
266901
- const k = this.stepCalls[i];
266902
- if (k === lastKey) streak += 1;
266903
- else {
266904
- lastKey = k;
266905
- streak = 1;
266906
- }
266907
- }
266360
+ this.stepOutcomes.set(index, toolProgressFingerprint(result));
266361
+ const streak = this.projectStreak(index).count;
266908
266362
  let finalResult = result;
266909
266363
  let action = "none";
266910
266364
  if (streak >= REPEAT_FORCE_STOP_STREAK) {
@@ -266929,6 +266383,33 @@ var ToolCallDeduplicator = class {
266929
266383
  return finalResult;
266930
266384
  }
266931
266385
  };
266386
+ function finiteLimit(value, fallback) {
266387
+ return value !== void 0 && Number.isSafeInteger(value) && value > 0 ? value : fallback;
266388
+ }
266389
+ var TurnExecutionBudget = class {
266390
+ maxSteps;
266391
+ maxToolExecutions;
266392
+ steps = 0;
266393
+ toolExecutions = 0;
266394
+ toolLimitReached = false;
266395
+ constructor(config) {
266396
+ this.maxSteps = finiteLimit(config?.maxStepsPerTurn, 128);
266397
+ this.maxToolExecutions = finiteLimit(config?.maxToolExecutionsPerTurn, 256);
266398
+ }
266399
+ reserveStep() {
266400
+ if (this.steps >= this.maxSteps) return false;
266401
+ this.steps += 1;
266402
+ return true;
266403
+ }
266404
+ reserveToolExecution() {
266405
+ if (this.toolExecutions >= this.maxToolExecutions) {
266406
+ this.toolLimitReached = true;
266407
+ return false;
266408
+ }
266409
+ this.toolExecutions += 1;
266410
+ return true;
266411
+ }
266412
+ };
266932
266413
  //#endregion
266933
266414
  //#region ../../packages/agent-core/src/agent/turn/tool-result-budget.ts
266934
266415
  const TOOL_RESULT_MAX_CHARS = 5e4;
@@ -269783,7 +269264,11 @@ var TurnFlow = class {
269783
269264
  async runStepLoop(turnId, signal, input, origin, turnAnchor, onFinalResponse) {
269784
269265
  let stopHookContinuationUsed = false;
269785
269266
  let goalOutcomeMessageContinuationUsed = false;
269786
- const deduper = new ToolCallDeduplicator({ telemetry: this.agent.telemetry });
269267
+ const turnBudget = new TurnExecutionBudget(this.agent.blunConfig?.loopControl);
269268
+ const deduper = new ToolCallDeduplicator({
269269
+ telemetry: this.agent.telemetry,
269270
+ reserveToolExecution: () => turnBudget.reserveToolExecution()
269271
+ });
269787
269272
  const diagnosePreRequest = this.agent.type === "main" && process.env["BLUN_DIAG_PRE_REQUEST_PHASES"] === "1";
269788
269273
  const recordPreRequestPhase = (phase, startedAt) => {
269789
269274
  if (!diagnosePreRequest) return;
@@ -269859,7 +269344,7 @@ var TurnFlow = class {
269859
269344
  recordPreRequestPhase("tool-selection", selectionStartedAt);
269860
269345
  return selectedTools;
269861
269346
  };
269862
- return (await runTurn({
269347
+ const result = await runTurn({
269863
269348
  turnId: String(turnId),
269864
269349
  signal,
269865
269350
  executionObserver: ({ kind, id, completion }) => {
@@ -269890,7 +269375,7 @@ var TurnFlow = class {
269890
269375
  dispatchEvent: this.buildDispatchEvent(turnId, signal, onFinalResponse, () => partialContext),
269891
269376
  tools: selectedTools,
269892
269377
  log: this.agent.log,
269893
- maxSteps: loopControl?.maxStepsPerTurn,
269378
+ maxSteps: turnBudget.maxSteps,
269894
269379
  maxRetryAttempts: loopControl?.maxRetriesPerStep,
269895
269380
  checkpointBeforeRetry: () => this.agent.records.flush(),
269896
269381
  recordStepUsage: async (usage) => {
@@ -269903,6 +269388,7 @@ var TurnFlow = class {
269903
269388
  },
269904
269389
  hooks: {
269905
269390
  beforeStep: async ({ signal: stepSignal, llm }) => {
269391
+ if (!turnBudget.reserveStep()) throw createMaxStepsExceededError(turnBudget.maxSteps);
269906
269392
  const injectionStartedAt = performance.now();
269907
269393
  this.agent.microCompaction.detect();
269908
269394
  await this.agent.injection.inject();
@@ -269924,7 +269410,7 @@ var TurnFlow = class {
269924
269410
  signal.throwIfAborted();
269925
269411
  if (!goalOutcomeMessageContinuationUsed && isGoalOutcomeReminderOrigin(this.agent.context.history.at(-1)?.origin)) {
269926
269412
  goalOutcomeMessageContinuationUsed = true;
269927
- if (!hasStepBudgetRemaining(loopControl?.maxStepsPerTurn, ctx.stepNumber)) {
269413
+ if (!hasStepBudgetRemaining(turnBudget.maxSteps, turnBudget.steps)) {
269928
269414
  this.agent.context.popMatchedMessage(isGoalOutcomeReminderOrigin);
269929
269415
  this.setActiveSteerAcceptance(turnId, false);
269930
269416
  return { continue: false };
@@ -270001,7 +269487,19 @@ var TurnFlow = class {
270001
269487
  });
270002
269488
  }
270003
269489
  }
270004
- })).stopReason;
269490
+ });
269491
+ if (turnBudget.toolLimitReached) {
269492
+ const error = createMaxStepsExceededError(turnBudget.maxSteps, `Tool execution limit reached (${turnBudget.maxToolExecutions}). Recorded work is retained; continue in a new user turn.`);
269493
+ await this.buildDispatchEvent(turnId, signal, onFinalResponse, () => partialContext)({
269494
+ type: "turn.interrupted",
269495
+ reason: "max_steps",
269496
+ attemptedSteps: turnBudget.steps,
269497
+ activeStep: this.currentStep,
269498
+ message: error.message
269499
+ });
269500
+ throw error;
269501
+ }
269502
+ return result.stopReason;
270005
269503
  } catch (error) {
270006
269504
  if (!(isBlunError(error) && error.code === ErrorCodes.CONTEXT_OVERFLOW && error.details?.["contextBrakeBlocked"] === true) && (error instanceof APIContextOverflowError || isBlunError(error) && error.code === ErrorCodes.CONTEXT_OVERFLOW) || this.agent.fullCompaction.shouldRecoverFromContextOverflow(error)) {
270007
269505
  this.agent.fullCompaction.observeContextOverflow(error);
@@ -353615,7 +353113,7 @@ function optionalBuildString(value) {
353615
353113
  return typeof value === "string" && value.length > 0 ? value : void 0;
353616
353114
  }
353617
353115
  const BLUN_BUILD_INFO = {
353618
- version: optionalBuildString("9.1.622"),
353116
+ version: optionalBuildString("9.1.624"),
353619
353117
  channel: typeof __BLUN_CHANNEL__ === "string" ? optionalBuildString(__BLUN_CHANNEL__) : void 0,
353620
353118
  commit: typeof __BLUN_COMMIT__ === "string" ? optionalBuildString(__BLUN_COMMIT__) : void 0,
353621
353119
  buildTarget: typeof __BLUN_BUILD_TARGET__ === "string" ? optionalBuildString(__BLUN_BUILD_TARGET__) : void 0