eve-hub 0.6.38 → 0.6.41

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # eve-hub
2
2
 
3
+ ## 0.6.41
4
+
5
+ ### Patch Changes
6
+
7
+ - A model call that sends no data for 30 s ends with a timeout instead of waiting 5 minutes per attempt; the clock restarts on every chunk, and the AI SDK's two retries stay, so a brief hang recovers without a hand retry.
8
+
9
+ ## 0.6.40
10
+
11
+ ### Patch Changes
12
+
13
+ - The hub records the size of each input a bot receives and each compaction, from eve's own stream, so the team-model work has a measured before.
14
+
15
+ ## 0.6.39
16
+
17
+ ### Patch Changes
18
+
19
+ - The compact schedule reads each session's last input tokens and prompt-cache gaps from the hub's snapshot, and a compaction's report lines go to the schedule's thread.
20
+
3
21
  ## 0.6.38
4
22
 
5
23
  ### Patch Changes
@@ -0,0 +1,79 @@
1
+ // A model call that gets no response fails fast. Node's fetch waits 300 s for
2
+ // response headers and for each body chunk (undici's default headersTimeout /
3
+ // bodyTimeout), and eve hands the AI SDK no timeout of its own, so one hung
4
+ // gateway request stalled a turn for 5 minutes (15 with retries). Every
5
+ // streaming gateway request now gets an idle limit instead: no headers, or no
6
+ // chunk while a read is waiting, within MODEL_CALL_TIMEOUT_MS ends it with a
7
+ // TimeoutError; the clock restarts on every chunk, so an answer that is still
8
+ // streaming is never cut off. The AI SDK retries that twice (3 x 30 s plus its
9
+ // backoff of 2 s and 4 s, about 1 min 36 s), then eve parks the turn as recoverable, so a transient hang
10
+ // recovers without a hand retry.
11
+ //
12
+ // Streaming calls only: a non-streaming call (eve's compaction `generateText`)
13
+ // legitimately waits for the whole generation, so a hung compaction still waits
14
+ // the 300 s default. Remove this module when eve forwards `timeout`/`maxRetries`
15
+ // to the AI SDK (vercel/eve#3984).
16
+ export const MODEL_CALL_TIMEOUT_MS = 30_000;
17
+
18
+ const INSTALLED = Symbol.for("hub.modelCallTimeout");
19
+ const GATEWAY_HOST = "ai-gateway.vercel.sh";
20
+
21
+ function isStreamingGatewayCall(input, init) {
22
+ let url;
23
+ try {
24
+ url = new URL(typeof input === "string" || input instanceof URL ? input : input.url);
25
+ } catch {
26
+ return false;
27
+ }
28
+ if (url.hostname !== GATEWAY_HOST) return false;
29
+ const headers = new Headers(init?.headers ?? (input instanceof Request ? input.headers : undefined));
30
+ return headers.get("ai-language-model-streaming") === "true";
31
+ }
32
+
33
+ export function withModelCallTimeout(baseFetch, ms) {
34
+ return async function fetchWithModelCallTimeout(input, init) {
35
+ if (!isStreamingGatewayCall(input, init)) return baseFetch(input, init);
36
+ const ctrl = new AbortController();
37
+ const caller = init?.signal ?? (input instanceof Request ? input.signal : undefined);
38
+ const signal = caller ? AbortSignal.any([caller, ctrl.signal]) : ctrl.signal;
39
+ let timer;
40
+ const arm = () => {
41
+ timer = setTimeout(() => ctrl.abort(new DOMException(`model call got no response for ${ms} ms`, "TimeoutError")), ms);
42
+ };
43
+ arm();
44
+ let res;
45
+ try {
46
+ res = await baseFetch(input, { ...init, signal });
47
+ } finally {
48
+ clearTimeout(timer);
49
+ }
50
+ if (!res.body) return res;
51
+ const reader = res.body.getReader();
52
+ const body = new ReadableStream({
53
+ async pull(controller) {
54
+ arm();
55
+ try {
56
+ const { done, value } = await reader.read();
57
+ if (done) controller.close();
58
+ else controller.enqueue(value);
59
+ } catch (error) {
60
+ controller.error(error);
61
+ } finally {
62
+ clearTimeout(timer);
63
+ }
64
+ },
65
+ cancel(reason) {
66
+ clearTimeout(timer);
67
+ return reader.cancel(reason);
68
+ },
69
+ });
70
+ return new Response(body, { status: res.status, statusText: res.statusText, headers: res.headers });
71
+ };
72
+ }
73
+
74
+ export function installModelCallTimeout() {
75
+ if (globalThis.fetch[INSTALLED]) return;
76
+ const wrapped = withModelCallTimeout(globalThis.fetch.bind(globalThis), MODEL_CALL_TIMEOUT_MS);
77
+ wrapped[INSTALLED] = true;
78
+ globalThis.fetch = wrapped;
79
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eve-hub",
3
- "version": "0.6.38",
3
+ "version": "0.6.41",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Bot-side code shared by every hub agent: registry tools, the roster hook, the eve channel, the host sandbox and browser, and model helpers.",
6
6
  "type": "module",
package/roster-model.mjs CHANGED
@@ -16,8 +16,10 @@ import { defineDynamic } from "eve";
16
16
  import { CONTEXT_WINDOW, selectModel } from "./bot-model.mjs";
17
17
  import { DEFAULT_SUBAGENT_CAP } from "./subagent-cap.mjs";
18
18
  import { sessionLimits } from "./session-limits.mjs";
19
+ import { installModelCallTimeout } from "./model-timeout.mjs";
19
20
  import { findWorkspaceRoot, loadWorkspace, parseWorkspace } from "./workspace.mjs";
20
21
  const real = process.env.ROSTER_MODELS !== "mock";
22
+ installModelCallTimeout();
21
23
 
22
24
  export function createRosterModel({ agents, subagentCap }) {
23
25
  return function rosterModel(name, { mock, copyMock } = {}) {
@@ -1,7 +1,7 @@
1
1
  // The decisions behind main's compact schedule (schedules/compact.ts), pure:
2
2
  // each takes the registry's /api/state snapshot (`snap`), the schedule's
3
3
  // and the time. No I/O here; schedules/hub.mjs does that. The report lines
4
- // for the compactions themselves are the hub's (registry/compact-report.mjs).
4
+ // for the compactions themselves are the hub's (hosted-hub/src/domain/compact-report.mjs).
5
5
  //
6
6
  // Plain JS on purpose: the schedule (TypeScript, bundled by eve) and the
7
7
  // tests (plain node) import the same module.
package/world.mjs CHANGED
@@ -442,14 +442,16 @@ var turnId = (session, chunkIndex) => `trn_${session}_${chunkIndex}`;
442
442
 
443
443
  // ../../hosted-hub/src/store/events.ts
444
444
  function eventStatements(threadId2, event, text, at, id = eventId(), only) {
445
+ const expr = (v) => typeof v === "string" ? { sql: "?", args: [v] } : "sql" in v && "args" in v ? v : { sql: "?", args: [JSON.stringify(v)] };
446
+ const [t, e] = [expr(text), expr(event)];
445
447
  return [
446
448
  s(
447
- `INSERT OR IGNORE INTO messages (id, thread_id, author, author_kind, text, created_at, event) SELECT ?, ?, 'system', 'event', ?, ?, ? WHERE ${only?.sql ?? "1"}`,
449
+ `INSERT OR IGNORE INTO messages (id, thread_id, author, author_kind, text, created_at, event) SELECT ?, ?, 'system', 'event', ${t.sql}, ?, ${e.sql} WHERE ${only?.sql ?? "1"}`,
448
450
  id,
449
451
  threadId2,
450
- text,
452
+ ...t.args,
451
453
  at,
452
- JSON.stringify(event),
454
+ ...e.args,
453
455
  ...only?.args ?? []
454
456
  ),
455
457
  s(`INSERT INTO log (thread_id,type,data,at) SELECT ?, 'message.created', ?, ? WHERE changes() > 0`, threadId2, JSON.stringify({ threadId: threadId2, messageId: id, author: "system", authorKind: "event" }), at)
@@ -467,11 +469,11 @@ var PARTICIPANTS = (thread, except = "''") => `SELECT DISTINCT p.bot FROM (
467
469
  AND json_extract(l.event, '$.kind') = 'leave' AND json_extract(l.event, '$.agent') = p.bot), -1)`;
468
470
  var hasJoins = (threadId2) => !threadId2.startsWith("dm-") && !threadId2.startsWith("sch-");
469
471
  function routingStatements(messageId2, threadId2, bots, now, { by, joins }, held = {}, steer = false) {
470
- const quiet = !joins || !hasJoins(threadId2);
472
+ const quiet2 = !joins || !hasJoins(threadId2);
471
473
  const fresh = "EXISTS (SELECT 1 FROM messages WHERE id = ?)";
472
474
  return [
473
475
  ...bots.flatMap((bot) => [
474
- ...quiet ? [] : eventStatements(
476
+ ...quiet2 ? [] : eventStatements(
475
477
  threadId2,
476
478
  { kind: "join", agent: bot, by, message: messageId2 },
477
479
  `@${bot} joined${by !== bot ? ` (added by @${by})` : ""}`,
@@ -545,7 +547,7 @@ function addUsage(bucket, usage = {}) {
545
547
  var HOURS_KEPT_MS = 35 * 24 * 36e5;
546
548
 
547
549
  // ../../hosted-hub/src/store/usage.ts
548
- var STEP_INSERT = "INSERT OR IGNORE INTO usage_steps (session_id, sequence, step_index, at, input_tokens, output_tokens, cache_read_tokens, cache_write_tokens, cost_usd, turn_id)";
550
+ var STEP_INSERT = "INSERT OR IGNORE INTO usage_steps (session_id, sequence, step_index, at, input_tokens, output_tokens, cache_read_tokens, cache_write_tokens, cost_usd, turn_id, model)";
549
551
  function stepValues(sessionId2, step) {
550
552
  const b = addUsage(emptyBucket(), step.usage);
551
553
  return [sessionId2, step.sequence, step.stepIndex, Date.parse(step.at), b.inputTokens, b.outputTokens, b.cacheReadTokens, b.cacheWriteTokens, b.costUsd];
@@ -568,10 +570,10 @@ function codeRanges(text) {
568
570
  const open3 = lines[i].text.match(/^ {0,3}(`{3,}|~{3,})(.*)$/);
569
571
  if (!open3 || open3[1][0] === "`" && open3[2].includes("`")) continue;
570
572
  const close = new RegExp(`^ {0,3}${open3[1][0] === "`" ? "`" : "~"}{${open3[1].length},}\\s*$`);
571
- const j = lines.findIndex((l, k) => k > i && close.test(l.text));
573
+ const j = lines.findIndex((l, k2) => k2 > i && close.test(l.text));
572
574
  if (j < 0) continue;
573
575
  ranges.push([lines[i].start, lines[j].end]);
574
- for (let k = i; k <= j; k++) fenced.add(k);
576
+ for (let k2 = i; k2 <= j; k2++) fenced.add(k2);
575
577
  i = j;
576
578
  }
577
579
  let para = [];
@@ -589,7 +591,7 @@ function codeRanges(text) {
589
591
  n--;
590
592
  if (!n) continue;
591
593
  }
592
- const j = runs.findIndex((r, k) => k > i && r.n === n);
594
+ const j = runs.findIndex((r, k2) => k2 > i && r.n === n);
593
595
  if (j < 0) continue;
594
596
  ranges.push([from + at, from + runs[j].at + n]);
595
597
  i = j;
@@ -624,12 +626,15 @@ var names = (text, { person, names: names2 }) => {
624
626
  var record = (id, person) => s("INSERT OR IGNORE INTO notifications (message_id, person) SELECT ?, ? WHERE EXISTS (SELECT 1 FROM messages WHERE id = ?)", id, person, id);
625
627
  var notificationFor = (messageId2, kind, text, notify) => notify && kind === "agent" && names(text, notify) ? [record(messageId2, notify.person)] : [];
626
628
 
629
+ // ../../hosted-hub/src/dispatch/bot.ts
630
+ var MESSAGE_LINE = "\n[thread ";
631
+
627
632
  // ../../hosted-hub/src/store/subagents.ts
628
633
  var UP = `up(session_id, parent) AS (
629
634
  SELECT session_id, parent FROM subagent_links WHERE session_id = ?
630
635
  UNION SELECT c.session_id, c.parent FROM subagent_links c JOIN up ON c.session_id = up.parent)`;
631
636
  var ROOT = "SELECT t.id, t.thread_id, t.bot FROM up JOIN turns t ON t.id = up.parent";
632
- var subagentStep = (sessionId2, step) => s(`WITH RECURSIVE ${UP} ${STEP_INSERT} SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?, (SELECT id FROM (${ROOT}))`, sessionId2, ...stepValues(sessionId2, step));
637
+ var subagentStep = (sessionId2, step) => s(`WITH RECURSIVE ${UP} ${STEP_INSERT} SELECT ?, ?, ?, ?, ?, ?, ?, ?, ?, (SELECT id FROM (${ROOT})), NULL`, sessionId2, ...stepValues(sessionId2, step));
633
638
  var rootLog = (sessionId2, type, at) => s(`WITH RECURSIVE ${UP} INSERT INTO log (thread_id, type, data, at)
634
639
  SELECT thread_id, ?, json_object('threadId', thread_id, 'agent', bot, 'turnId', id), ? FROM (${ROOT})`, sessionId2, type, at);
635
640
  function linkStatements(sessionId2, parent, callId) {
@@ -1400,7 +1405,7 @@ function assert(_) {
1400
1405
  }
1401
1406
  function getEnumValues(entries) {
1402
1407
  const numericValues = Object.values(entries).filter((v) => typeof v === "number");
1403
- const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
1408
+ const values = Object.entries(entries).filter(([k2, _]) => numericValues.indexOf(+k2) === -1).map(([_, v]) => v);
1404
1409
  return values;
1405
1410
  }
1406
1411
  function joinValues(array3, separator = "|") {
@@ -1744,8 +1749,8 @@ function stringifyPrimitive(value) {
1744
1749
  return `${value}`;
1745
1750
  }
1746
1751
  function optionalKeys(shape) {
1747
- return Object.keys(shape).filter((k) => {
1748
- return shape[k]._zod.optin !== void 0 && shape[k]._zod.optout === "optional";
1752
+ return Object.keys(shape).filter((k2) => {
1753
+ return shape[k2]._zod.optin !== void 0 && shape[k2]._zod.optout === "optional";
1749
1754
  });
1750
1755
  }
1751
1756
  var NUMBER_FORMAT_RANGES = /* @__PURE__ */ (() => ({
@@ -1923,10 +1928,10 @@ function finalizeIssue(iss, ctx, config3) {
1923
1928
  const schemaError = iss.schema !== iss.inst ? iss.schema?._zod.def?.error : void 0;
1924
1929
  const message = iss.message ? iss.message : unwrapMessage(iss.inst?._zod.def?.error?.(iss)) ?? unwrapMessage(schemaError?.(iss)) ?? unwrapMessage(ctx?.error?.(iss)) ?? unwrapMessage(config3.customError?.(iss)) ?? unwrapMessage(config3.localeError?.(iss)) ?? "Invalid input";
1925
1930
  const full = {};
1926
- for (const k of Object.keys(iss)) {
1927
- if (k === "inst" || k === "schema" || k === "continue" || k === "input" || k === "__proto__")
1931
+ for (const k2 of Object.keys(iss)) {
1932
+ if (k2 === "inst" || k2 === "schema" || k2 === "continue" || k2 === "input" || k2 === "__proto__")
1928
1933
  continue;
1929
- full[k] = iss[k];
1934
+ full[k2] = iss[k2];
1930
1935
  }
1931
1936
  full.path ?? (full.path = []);
1932
1937
  full.message = message;
@@ -1949,14 +1954,14 @@ function codePointLength(str) {
1949
1954
  const units = str.length;
1950
1955
  if (!highSurrogate.test(str))
1951
1956
  return units;
1952
- let count = units;
1957
+ let count2 = units;
1953
1958
  for (let i = 0; i < units - 1; i++) {
1954
1959
  if ((str.charCodeAt(i) & 64512) === 55296 && (str.charCodeAt(i + 1) & 64512) === 56320) {
1955
- count--;
1960
+ count2--;
1956
1961
  i++;
1957
1962
  }
1958
1963
  }
1959
- return count;
1964
+ return count2;
1960
1965
  }
1961
1966
  function getLengthableOrigin(input2) {
1962
1967
  if (Array.isArray(input2))
@@ -1999,8 +2004,8 @@ function issue(...args) {
1999
2004
  return { ...iss };
2000
2005
  }
2001
2006
  function cleanEnum(obj) {
2002
- return Object.entries(obj).filter(([k, _]) => {
2003
- return Number.isNaN(Number.parseInt(k, 10));
2007
+ return Object.entries(obj).filter(([k2, _]) => {
2008
+ return Number.isNaN(Number.parseInt(k2, 10));
2004
2009
  }).map((el) => el[1]);
2005
2010
  }
2006
2011
  function base64ToUint8Array(base644) {
@@ -2222,11 +2227,11 @@ function $constructor(name, initializer5, proto, params) {
2222
2227
  }
2223
2228
  }
2224
2229
  const proto2 = _.prototype;
2225
- for (const k in proto2) {
2226
- if (!Object.prototype.hasOwnProperty.call(proto2, k))
2230
+ for (const k2 in proto2) {
2231
+ if (!Object.prototype.hasOwnProperty.call(proto2, k2))
2227
2232
  continue;
2228
- if (!(k in inst)) {
2229
- inst[k] = proto2[k].bind(inst);
2233
+ if (!(k2 in inst)) {
2234
+ inst[k2] = proto2[k2].bind(inst);
2230
2235
  }
2231
2236
  }
2232
2237
  }
@@ -4188,9 +4193,9 @@ function normalizeDef(def) {
4188
4193
  const ownSymbols = Object.getOwnPropertySymbols(def.shape);
4189
4194
  const symbolKeys = ownSymbols.length ? ownSymbols : NO_SYMBOL_KEYS;
4190
4195
  const allKeys = symbolKeys.length ? [...keys, ...symbolKeys] : keys;
4191
- for (const k of allKeys) {
4192
- if (!def.shape?.[k]?._zod?.traits?.has("$ZodType")) {
4193
- throw new Error(`Invalid element at key "${String(k)}": expected a Zod schema`);
4196
+ for (const k2 of allKeys) {
4197
+ if (!def.shape?.[k2]?._zod?.traits?.has("$ZodType")) {
4198
+ throw new Error(`Invalid element at key "${String(k2)}": expected a Zod schema`);
4194
4199
  }
4195
4200
  }
4196
4201
  const okeys = optionalKeys(def.shape);
@@ -4339,12 +4344,12 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
4339
4344
  const normalized = _normalized.value;
4340
4345
  const syms = normalized.symbolKeys;
4341
4346
  const doc = new Doc(["payload", "ctx"], { shape, inst, memo: memo3, syms });
4342
- const parseStr = (k) => `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;
4343
- const prefixStr = (id, k) => `
4347
+ const parseStr = (k2) => `shape[${k2}]._zod.run({ value: input[${k2}], issues: [] }, ctx)`;
4348
+ const prefixStr = (id, k2) => `
4344
4349
  let ${id}_ab = false;
4345
4350
  for (let i = 0; i < ${id}.issues.length; i++) {
4346
4351
  const iss = ${id}.issues[i];
4347
- iss.path = iss.path ? [${k}, ...iss.path] : [${k}];
4352
+ iss.path = iss.path ? [${k2}, ...iss.path] : [${k2}];
4348
4353
  payload.issues.push(iss);
4349
4354
  if (iss.continue !== true) ${id}_ab = true;
4350
4355
  }
@@ -4363,23 +4368,23 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
4363
4368
  if (key === "__proto__")
4364
4369
  continue;
4365
4370
  const id = ids[key];
4366
- const k = typeof key === "symbol" ? `syms[${syms.indexOf(key)}]` : esc(key);
4367
- const isPresent = `${k} in input`;
4371
+ const k2 = typeof key === "symbol" ? `syms[${syms.indexOf(key)}]` : esc(key);
4372
+ const isPresent = `${k2} in input`;
4368
4373
  const schema = shape[key];
4369
4374
  const optin = schema?._zod?.optin;
4370
4375
  const isOptionalIn = optin !== void 0;
4371
4376
  const isOptionalOut = schema?._zod?.optout === "optional";
4372
- doc.write(`const ${id} = ${parseStr(k)};`);
4377
+ doc.write(`const ${id} = ${parseStr(k2)};`);
4373
4378
  if (isOptionalIn && isOptionalOut) {
4374
4379
  const assign = optin === "optional" ? `${id}_present` : `${id}.value !== undefined || ${id}_present`;
4375
4380
  doc.write(`
4376
4381
  const ${id}_present = ${isPresent};
4377
4382
  if (!${id}.issues.length || ${id}_present) {
4378
- if (${id}.issues.length) {${prefixStr(id, k)}
4383
+ if (${id}.issues.length) {${prefixStr(id, k2)}
4379
4384
  }
4380
4385
 
4381
4386
  if (${assign}) {
4382
- newResult[${k}] = ${id}.value;
4387
+ newResult[${k2}] = ${id}.value;
4383
4388
  }
4384
4389
  }
4385
4390
 
@@ -4387,14 +4392,14 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
4387
4392
  } else if (!isOptionalIn) {
4388
4393
  doc.write(`
4389
4394
  const ${id}_present = ${isPresent};
4390
- if (${id}.issues.length) {${prefixStr(id, k)}
4395
+ if (${id}.issues.length) {${prefixStr(id, k2)}
4391
4396
  }
4392
4397
  if (!${id}_present && !${id}.issues.length) {
4393
4398
  payload.issues.push({
4394
4399
  code: "invalid_type",
4395
4400
  expected: "nonoptional",
4396
4401
  input: undefined,
4397
- path: [${k}]
4402
+ path: [${k2}]
4398
4403
  });
4399
4404
  if (ctx && ctx.abortEarly) {
4400
4405
  payload.value = newResult;
@@ -4403,21 +4408,21 @@ var $ZodObjectJIT = /* @__PURE__ */ $constructor("$ZodObjectJIT", (inst, def) =>
4403
4408
  }
4404
4409
 
4405
4410
  if (${id}_present) {
4406
- newResult[${k}] = ${id}.value;
4411
+ newResult[${k2}] = ${id}.value;
4407
4412
  }
4408
4413
 
4409
4414
  `);
4410
4415
  } else {
4411
4416
  doc.write(`
4412
- if (${id}.issues.length) {${prefixStr(id, k)}
4417
+ if (${id}.issues.length) {${prefixStr(id, k2)}
4413
4418
  }
4414
4419
  `);
4415
4420
  if (optin === "defaulted") {
4416
- doc.write(`newResult[${k}] = ${id}.value;`);
4421
+ doc.write(`newResult[${k2}] = ${id}.value;`);
4417
4422
  } else {
4418
4423
  doc.write(`
4419
4424
  if (${id}.value !== undefined || ${isPresent}) {
4420
- newResult[${k}] = ${id}.value;
4425
+ newResult[${k2}] = ${id}.value;
4421
4426
  }
4422
4427
  `);
4423
4428
  }
@@ -4623,12 +4628,12 @@ var $ZodDiscriminatedUnion = /* @__PURE__ */ $constructor("$ZodDiscriminatedUnio
4623
4628
  throw new Error(`Invalid discriminated union option at index "${zod.def.options.indexOf(option)}"`);
4624
4629
  if (pv[zod.def.discriminator]?.has(void 0))
4625
4630
  undefinedCount++;
4626
- for (const [k, v] of Object.entries(pv)) {
4627
- if (!Object.prototype.hasOwnProperty.call(propValues, k)) {
4628
- assignProp(propValues, k, /* @__PURE__ */ new Set());
4631
+ for (const [k2, v] of Object.entries(pv)) {
4632
+ if (!Object.prototype.hasOwnProperty.call(propValues, k2)) {
4633
+ assignProp(propValues, k2, /* @__PURE__ */ new Set());
4629
4634
  }
4630
4635
  for (const val of v) {
4631
- propValues[k].add(val);
4636
+ propValues[k2].add(val);
4632
4637
  }
4633
4638
  }
4634
4639
  }
@@ -4748,17 +4753,17 @@ function handleIntersectionResults(result, left, right) {
4748
4753
  unrecIssue ?? (unrecIssue = iss);
4749
4754
  keys = iss.keys;
4750
4755
  } else if (iss.code === "invalid_key" && iss.origin === "record" && iss.path?.length === 1) {
4751
- const k = String(iss.path[0]);
4752
- if (!keyIssues.has(k))
4753
- keyIssues.set(k, iss);
4754
- keys = [k];
4756
+ const k2 = String(iss.path[0]);
4757
+ if (!keyIssues.has(k2))
4758
+ keyIssues.set(k2, iss);
4759
+ keys = [k2];
4755
4760
  } else {
4756
4761
  return false;
4757
4762
  }
4758
- for (const k of keys) {
4759
- if (!unrecKeys.has(k))
4760
- unrecKeys.set(k, {});
4761
- unrecKeys.get(k)[side] = true;
4763
+ for (const k2 of keys) {
4764
+ if (!unrecKeys.has(k2))
4765
+ unrecKeys.set(k2, {});
4766
+ unrecKeys.get(k2)[side] = true;
4762
4767
  }
4763
4768
  return true;
4764
4769
  };
@@ -4770,14 +4775,14 @@ function handleIntersectionResults(result, left, right) {
4770
4775
  if (!collect(iss, "r"))
4771
4776
  result.issues.push(iss);
4772
4777
  }
4773
- const bothKeys = [...unrecKeys].filter(([, f]) => f.l && f.r).map(([k]) => k);
4778
+ const bothKeys = [...unrecKeys].filter(([, f]) => f.l && f.r).map(([k2]) => k2);
4774
4779
  if (bothKeys.length) {
4775
- const aggregated = unrecIssue ? bothKeys.filter((k) => unrecIssue.keys.includes(k)) : [];
4780
+ const aggregated = unrecIssue ? bothKeys.filter((k2) => unrecIssue.keys.includes(k2)) : [];
4776
4781
  if (aggregated.length)
4777
4782
  result.issues.push({ ...unrecIssue, keys: aggregated });
4778
- for (const k of bothKeys) {
4779
- if (!aggregated.includes(k) && keyIssues.has(k))
4780
- result.issues.push(keyIssues.get(k));
4783
+ for (const k2 of bothKeys) {
4784
+ if (!aggregated.includes(k2) && keyIssues.has(k2))
4785
+ result.issues.push(keyIssues.get(k2));
4781
4786
  }
4782
4787
  }
4783
4788
  const merged = mergeValues(left.value, right.value);
@@ -5187,7 +5192,7 @@ var $ZodEnum = /* @__PURE__ */ $constructor("$ZodEnum", (inst, def) => {
5187
5192
  const valuesSet = new Set(values);
5188
5193
  inst._zod.values = valuesSet;
5189
5194
  defineLazyInternal(inst, "pattern", (zod) => {
5190
- const patternValues = getEnumValues(zod.def.entries).filter((k) => propertyKeyTypes.has(typeof k));
5195
+ const patternValues = getEnumValues(zod.def.entries).filter((k2) => propertyKeyTypes.has(typeof k2));
5191
5196
  return new RegExp(patternValues.length ? `^(${patternValues.map((o) => escapeRegex(o.toString())).join("|")})$` : "^[^\\s\\S]$");
5192
5197
  });
5193
5198
  inst._zod.parse = (payload, _ctx) => {
@@ -6339,8 +6344,8 @@ function az_default() {
6339
6344
  }
6340
6345
 
6341
6346
  // ../../hosted-hub/node_modules/zod/v4/locales/be.js
6342
- function getBelarusianPlural(count, one, few, many) {
6343
- const absCount = Math.abs(count);
6347
+ function getBelarusianPlural(count2, one, few, many) {
6348
+ const absCount = Math.abs(count2);
6344
6349
  const lastDigit = absCount % 10;
6345
6350
  const lastTwoDigits = absCount % 100;
6346
6351
  if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
@@ -8987,8 +8992,8 @@ function hu_default() {
8987
8992
  }
8988
8993
 
8989
8994
  // ../../hosted-hub/node_modules/zod/v4/locales/hy.js
8990
- function getArmenianPlural(count, one, many) {
8991
- return Math.abs(count) === 1 ? one : many;
8995
+ function getArmenianPlural(count2, one, many) {
8996
+ return Math.abs(count2) === 1 ? one : many;
8992
8997
  }
8993
8998
  function withDefiniteArticle(word) {
8994
8999
  if (!word)
@@ -11726,8 +11731,8 @@ function ro_default() {
11726
11731
  }
11727
11732
 
11728
11733
  // ../../hosted-hub/node_modules/zod/v4/locales/ru.js
11729
- function getRussianPlural(count, one, few, many) {
11730
- const absCount = Math.abs(count);
11734
+ function getRussianPlural(count2, one, few, many) {
11735
+ const absCount = Math.abs(count2);
11731
11736
  const lastDigit = absCount % 10;
11732
11737
  const lastTwoDigits = absCount % 100;
11733
11738
  if (lastTwoDigits >= 11 && lastTwoDigits <= 19) {
@@ -13830,8 +13835,8 @@ function compileChild(doc, ctx, schema, accessor, needsValue = true) {
13830
13835
  doc.content.length = contentLen;
13831
13836
  if (ctx.constants.size > constantCount) {
13832
13837
  const trailing = Array.from(ctx.constants.keys()).slice(constantCount);
13833
- for (const k of trailing)
13834
- ctx.constants.delete(k);
13838
+ for (const k2 of trailing)
13839
+ ctx.constants.delete(k2);
13835
13840
  }
13836
13841
  ctx.constantCounter = constantCounter;
13837
13842
  ctx.varCounter = varCounter;
@@ -14427,8 +14432,8 @@ function generateObjectCheck(doc, ctx, schema, accessor, buildsValue = true) {
14427
14432
  const keys = Object.keys(shape);
14428
14433
  const symbolKeys = Object.getOwnPropertySymbols(shape);
14429
14434
  const allKeys = symbolKeys.length ? [...keys, ...symbolKeys] : keys;
14430
- const keyExpr = (k) => typeof k === "symbol" ? addConstant(ctx, k) : esc(k);
14431
- const propKey = (k) => typeof k === "symbol" ? `[${keyExpr(k)}]` : esc(k);
14435
+ const keyExpr = (k2) => typeof k2 === "symbol" ? addConstant(ctx, k2) : esc(k2);
14436
+ const propKey = (k2) => typeof k2 === "symbol" ? `[${keyExpr(k2)}]` : esc(k2);
14432
14437
  const propShape = shape;
14433
14438
  if (keys.includes("__proto__")) {
14434
14439
  throw new ZodCompileUnsupportedError('object shape key "__proto__"');
@@ -14472,7 +14477,7 @@ function generateObjectCheck(doc, ctx, schema, accessor, buildsValue = true) {
14472
14477
  if (catchall) {
14473
14478
  const catchallType = catchall._zod.def.type;
14474
14479
  if (catchallType === "never") {
14475
- const condition = keys.map((k) => `k !== ${esc(k)}`).join(" && ") || "true";
14480
+ const condition = keys.map((k2) => `k !== ${esc(k2)}`).join(" && ") || "true";
14476
14481
  doc.write(`for (const k in ${accessor}) {`);
14477
14482
  doc.indented((d) => {
14478
14483
  d.write(`if (${condition}) return INVALID;`);
@@ -14485,7 +14490,7 @@ function generateObjectCheck(doc, ctx, schema, accessor, buildsValue = true) {
14485
14490
  }
14486
14491
  }
14487
14492
  const outputVar = newVar(ctx);
14488
- const hasConditionalKeys = allKeys.some((k) => mayOmitUndefined(propShape[k]) || dropsWhenAbsent(propShape[k]));
14493
+ const hasConditionalKeys = allKeys.some((k2) => mayOmitUndefined(propShape[k2]) || dropsWhenAbsent(propShape[k2]));
14489
14494
  if (!buildsValue) {
14490
14495
  if (unknownKeysMode === "schema") {
14491
14496
  const knownSet = keys.length > 0 ? addConstant(ctx, new Set(keys)) : null;
@@ -14503,16 +14508,16 @@ function generateObjectCheck(doc, ctx, schema, accessor, buildsValue = true) {
14503
14508
  return null;
14504
14509
  }
14505
14510
  if (!hasConditionalKeys) {
14506
- const propLiterals = allKeys.map((k) => `${propKey(k)}: ${propOutputs.get(k)}`).join(", ");
14511
+ const propLiterals = allKeys.map((k2) => `${propKey(k2)}: ${propOutputs.get(k2)}`).join(", ");
14507
14512
  doc.write(`const ${outputVar} = { ${propLiterals} };`);
14508
14513
  } else {
14509
14514
  doc.write(`const ${outputVar} = {};`);
14510
- for (const k of allKeys) {
14511
- const kx = keyExpr(k);
14512
- const out = propOutputs.get(k);
14513
- if (dropsWhenAbsent(propShape[k])) {
14515
+ for (const k2 of allKeys) {
14516
+ const kx = keyExpr(k2);
14517
+ const out = propOutputs.get(k2);
14518
+ if (dropsWhenAbsent(propShape[k2])) {
14514
14519
  doc.write(`if (${kx} in ${accessor}) ${outputVar}[${kx}] = ${out};`);
14515
- } else if (mayOmitUndefined(propShape[k])) {
14520
+ } else if (mayOmitUndefined(propShape[k2])) {
14516
14521
  doc.write(`if (${out} !== undefined || ${kx} in ${accessor}) ${outputVar}[${kx}] = ${out};`);
14517
14522
  } else {
14518
14523
  doc.write(`${outputVar}[${kx}] = ${out};`);
@@ -16618,13 +16623,13 @@ function foldIntersection(json2) {
16618
16623
  for (const key of FOLDABLE_KEYS)
16619
16624
  if (key in json2)
16620
16625
  return;
16621
- const unions = allOf.filter((m) => UNION_KEYS.some((k) => Array.isArray(m[k])));
16626
+ const unions = allOf.filter((m) => UNION_KEYS.some((k2) => Array.isArray(m[k2])));
16622
16627
  let folded = null;
16623
16628
  if (!unions.length) {
16624
16629
  folded = foldObjects(allOf);
16625
16630
  } else {
16626
16631
  const union3 = unions[0];
16627
- const keyword = UNION_KEYS.find((k) => Array.isArray(union3[k]));
16632
+ const keyword = UNION_KEYS.find((k2) => Array.isArray(union3[k2]));
16628
16633
  if (Object.keys(union3).length !== 1)
16629
16634
  return;
16630
16635
  const rest = allOf.filter((m) => m !== union3);
@@ -19672,11 +19677,11 @@ function canonicalKey(value, seen) {
19672
19677
  }
19673
19678
  const keys = Object.keys(value).sort();
19674
19679
  const parts = [];
19675
- for (const k of keys) {
19676
- const key = canonicalKey(value[k], seen);
19680
+ for (const k2 of keys) {
19681
+ const key = canonicalKey(value[k2], seen);
19677
19682
  if (key === null)
19678
19683
  return null;
19679
- parts.push(`${k.length}:${k}=${key}`);
19684
+ parts.push(`${k2.length}:${k2}=${key}`);
19680
19685
  }
19681
19686
  return `o${parts.length}:{${parts.join(",")}}`;
19682
19687
  } finally {
@@ -20250,11 +20255,11 @@ function visit(schema, fnOrHandlers) {
20250
20255
  const keys = Object.keys(oldShape);
20251
20256
  let changed = false;
20252
20257
  const newShape = {};
20253
- for (const k of keys) {
20254
- const mapped = run(oldShape[k]);
20255
- if (mapped !== oldShape[k])
20258
+ for (const k2 of keys) {
20259
+ const mapped = run(oldShape[k2]);
20260
+ if (mapped !== oldShape[k2])
20256
20261
  changed = true;
20257
- newShape[k] = mapped;
20262
+ newShape[k2] = mapped;
20258
20263
  }
20259
20264
  let newCatchall = def.catchall;
20260
20265
  if (def.catchall) {
@@ -20534,7 +20539,7 @@ function assert2(_) {
20534
20539
  }
20535
20540
  function getEnumValues2(entries) {
20536
20541
  const numericValues = Object.values(entries).filter((v) => typeof v === "number");
20537
- const values = Object.entries(entries).filter(([k, _]) => numericValues.indexOf(+k) === -1).map(([_, v]) => v);
20542
+ const values = Object.entries(entries).filter(([k2, _]) => numericValues.indexOf(+k2) === -1).map(([_, v]) => v);
20538
20543
  return values;
20539
20544
  }
20540
20545
  function joinValues2(array3, separator = "|") {
@@ -20824,8 +20829,8 @@ function stringifyPrimitive2(value) {
20824
20829
  return `${value}`;
20825
20830
  }
20826
20831
  function optionalKeys2(shape) {
20827
- return Object.keys(shape).filter((k) => {
20828
- return shape[k]._zod.optin !== void 0 && shape[k]._zod.optout === "optional";
20832
+ return Object.keys(shape).filter((k2) => {
20833
+ return shape[k2]._zod.optin !== void 0 && shape[k2]._zod.optout === "optional";
20829
20834
  });
20830
20835
  }
20831
20836
  var NUMBER_FORMAT_RANGES2 = /* @__PURE__ */ (() => ({
@@ -21084,14 +21089,14 @@ function codePointLength2(str) {
21084
21089
  const units = str.length;
21085
21090
  if (!highSurrogate2.test(str))
21086
21091
  return units;
21087
- let count = units;
21092
+ let count2 = units;
21088
21093
  for (let i = 0; i < units - 1; i++) {
21089
21094
  if ((str.charCodeAt(i) & 64512) === 55296 && (str.charCodeAt(i + 1) & 64512) === 56320) {
21090
- count--;
21095
+ count2--;
21091
21096
  i++;
21092
21097
  }
21093
21098
  }
21094
- return count;
21099
+ return count2;
21095
21100
  }
21096
21101
  function getLengthableOrigin2(input2) {
21097
21102
  if (Array.isArray(input2))
@@ -21134,8 +21139,8 @@ function issue2(...args) {
21134
21139
  return { ...iss };
21135
21140
  }
21136
21141
  function cleanEnum2(obj) {
21137
- return Object.entries(obj).filter(([k, _]) => {
21138
- return Number.isNaN(Number.parseInt(k, 10));
21142
+ return Object.entries(obj).filter(([k2, _]) => {
21143
+ return Number.isNaN(Number.parseInt(k2, 10));
21139
21144
  }).map((el) => el[1]);
21140
21145
  }
21141
21146
  function base64ToUint8Array2(base644) {
@@ -21338,11 +21343,11 @@ function $constructor2(name, initializer5, proto, params) {
21338
21343
  }
21339
21344
  }
21340
21345
  const proto2 = _.prototype;
21341
- for (const k in proto2) {
21342
- if (!Object.prototype.hasOwnProperty.call(proto2, k))
21346
+ for (const k2 in proto2) {
21347
+ if (!Object.prototype.hasOwnProperty.call(proto2, k2))
21343
21348
  continue;
21344
- if (!(k in inst)) {
21345
- inst[k] = proto2[k].bind(inst);
21349
+ if (!(k2 in inst)) {
21350
+ inst[k2] = proto2[k2].bind(inst);
21346
21351
  }
21347
21352
  }
21348
21353
  }
@@ -22726,9 +22731,9 @@ function normalizeDef2(def) {
22726
22731
  const ownSymbols = Object.getOwnPropertySymbols(def.shape);
22727
22732
  const symbolKeys = ownSymbols.length ? ownSymbols : NO_SYMBOL_KEYS2;
22728
22733
  const allKeys = symbolKeys.length ? [...keys, ...symbolKeys] : keys;
22729
- for (const k of allKeys) {
22730
- if (!def.shape?.[k]?._zod?.traits?.has("$ZodType")) {
22731
- throw new Error(`Invalid element at key "${String(k)}": expected a Zod schema`);
22734
+ for (const k2 of allKeys) {
22735
+ if (!def.shape?.[k2]?._zod?.traits?.has("$ZodType")) {
22736
+ throw new Error(`Invalid element at key "${String(k2)}": expected a Zod schema`);
22732
22737
  }
22733
22738
  }
22734
22739
  const okeys = optionalKeys2(def.shape);
@@ -22868,11 +22873,11 @@ var $ZodObjectJIT2 = /* @__PURE__ */ $constructor2("$ZodObjectJIT", (inst, def)
22868
22873
  const normalized = _normalized.value;
22869
22874
  const syms = normalized.symbolKeys;
22870
22875
  const doc = new Doc2(["payload", "ctx"], { shape, inst, memo: memo3, syms });
22871
- const parseStr = (k) => `shape[${k}]._zod.run({ value: input[${k}], issues: [] }, ctx)`;
22872
- const prefixStr = (id, k) => `
22876
+ const parseStr = (k2) => `shape[${k2}]._zod.run({ value: input[${k2}], issues: [] }, ctx)`;
22877
+ const prefixStr = (id, k2) => `
22873
22878
  for (let i = 0; i < ${id}.issues.length; i++) {
22874
22879
  const iss = ${id}.issues[i];
22875
- iss.path = iss.path ? [${k}, ...iss.path] : [${k}];
22880
+ iss.path = iss.path ? [${k2}, ...iss.path] : [${k2}];
22876
22881
  payload.issues.push(iss);
22877
22882
  }`;
22878
22883
  doc.write(`const input = payload.value;`);
@@ -22886,23 +22891,23 @@ var $ZodObjectJIT2 = /* @__PURE__ */ $constructor2("$ZodObjectJIT", (inst, def)
22886
22891
  if (key === "__proto__")
22887
22892
  continue;
22888
22893
  const id = ids[key];
22889
- const k = typeof key === "symbol" ? `syms[${syms.indexOf(key)}]` : esc2(key);
22890
- const isPresent = `${k} in input`;
22894
+ const k2 = typeof key === "symbol" ? `syms[${syms.indexOf(key)}]` : esc2(key);
22895
+ const isPresent = `${k2} in input`;
22891
22896
  const schema = shape[key];
22892
22897
  const optin = schema?._zod?.optin;
22893
22898
  const isOptionalIn = optin !== void 0;
22894
22899
  const isOptionalOut = schema?._zod?.optout === "optional";
22895
- doc.write(`const ${id} = ${parseStr(k)};`);
22900
+ doc.write(`const ${id} = ${parseStr(k2)};`);
22896
22901
  if (isOptionalIn && isOptionalOut) {
22897
22902
  const assign = optin === "optional" ? `${id}_present` : `${id}.value !== undefined || ${id}_present`;
22898
22903
  doc.write(`
22899
22904
  const ${id}_present = ${isPresent};
22900
22905
  if (!${id}.issues.length || ${id}_present) {
22901
- if (${id}.issues.length) {${prefixStr(id, k)}
22906
+ if (${id}.issues.length) {${prefixStr(id, k2)}
22902
22907
  }
22903
22908
 
22904
22909
  if (${assign}) {
22905
- newResult[${k}] = ${id}.value;
22910
+ newResult[${k2}] = ${id}.value;
22906
22911
  }
22907
22912
  }
22908
22913
 
@@ -22910,33 +22915,33 @@ var $ZodObjectJIT2 = /* @__PURE__ */ $constructor2("$ZodObjectJIT", (inst, def)
22910
22915
  } else if (!isOptionalIn) {
22911
22916
  doc.write(`
22912
22917
  const ${id}_present = ${isPresent};
22913
- if (${id}.issues.length) {${prefixStr(id, k)}
22918
+ if (${id}.issues.length) {${prefixStr(id, k2)}
22914
22919
  }
22915
22920
  if (!${id}_present && !${id}.issues.length) {
22916
22921
  payload.issues.push({
22917
22922
  code: "invalid_type",
22918
22923
  expected: "nonoptional",
22919
22924
  input: undefined,
22920
- path: [${k}]
22925
+ path: [${k2}]
22921
22926
  });
22922
22927
  }
22923
22928
 
22924
22929
  if (${id}_present) {
22925
- newResult[${k}] = ${id}.value;
22930
+ newResult[${k2}] = ${id}.value;
22926
22931
  }
22927
22932
 
22928
22933
  `);
22929
22934
  } else {
22930
22935
  doc.write(`
22931
- if (${id}.issues.length) {${prefixStr(id, k)}
22936
+ if (${id}.issues.length) {${prefixStr(id, k2)}
22932
22937
  }
22933
22938
 
22934
22939
  if (${id}.value === undefined) {
22935
22940
  if (${isPresent}) {
22936
- newResult[${k}] = undefined;
22941
+ newResult[${k2}] = undefined;
22937
22942
  }
22938
22943
  } else {
22939
- newResult[${k}] = ${id}.value;
22944
+ newResult[${k2}] = ${id}.value;
22940
22945
  }
22941
22946
 
22942
22947
  `);
@@ -23114,17 +23119,17 @@ function handleIntersectionResults2(result, left, right) {
23114
23119
  unrecIssue ?? (unrecIssue = iss);
23115
23120
  keys = iss.keys;
23116
23121
  } else if (iss.code === "invalid_key" && iss.origin === "record" && iss.path?.length === 1) {
23117
- const k = String(iss.path[0]);
23118
- if (!keyIssues.has(k))
23119
- keyIssues.set(k, iss);
23120
- keys = [k];
23122
+ const k2 = String(iss.path[0]);
23123
+ if (!keyIssues.has(k2))
23124
+ keyIssues.set(k2, iss);
23125
+ keys = [k2];
23121
23126
  } else {
23122
23127
  return false;
23123
23128
  }
23124
- for (const k of keys) {
23125
- if (!unrecKeys.has(k))
23126
- unrecKeys.set(k, {});
23127
- unrecKeys.get(k)[side] = true;
23129
+ for (const k2 of keys) {
23130
+ if (!unrecKeys.has(k2))
23131
+ unrecKeys.set(k2, {});
23132
+ unrecKeys.get(k2)[side] = true;
23128
23133
  }
23129
23134
  return true;
23130
23135
  };
@@ -23136,14 +23141,14 @@ function handleIntersectionResults2(result, left, right) {
23136
23141
  if (!collect(iss, "r"))
23137
23142
  result.issues.push(iss);
23138
23143
  }
23139
- const bothKeys = [...unrecKeys].filter(([, f]) => f.l && f.r).map(([k]) => k);
23144
+ const bothKeys = [...unrecKeys].filter(([, f]) => f.l && f.r).map(([k2]) => k2);
23140
23145
  if (bothKeys.length) {
23141
- const aggregated = unrecIssue ? bothKeys.filter((k) => unrecIssue.keys.includes(k)) : [];
23146
+ const aggregated = unrecIssue ? bothKeys.filter((k2) => unrecIssue.keys.includes(k2)) : [];
23142
23147
  if (aggregated.length)
23143
23148
  result.issues.push({ ...unrecIssue, keys: aggregated });
23144
- for (const k of bothKeys) {
23145
- if (!aggregated.includes(k) && keyIssues.has(k))
23146
- result.issues.push(keyIssues.get(k));
23149
+ for (const k2 of bothKeys) {
23150
+ if (!aggregated.includes(k2) && keyIssues.has(k2))
23151
+ result.issues.push(keyIssues.get(k2));
23147
23152
  }
23148
23153
  }
23149
23154
  const merged = mergeValues2(left.value, right.value);
@@ -23315,7 +23320,7 @@ var $ZodEnum2 = /* @__PURE__ */ $constructor2("$ZodEnum", (inst, def) => {
23315
23320
  const values = getEnumValues2(def.entries);
23316
23321
  const valuesSet = new Set(values);
23317
23322
  inst._zod.values = valuesSet;
23318
- const patternValues = values.filter((k) => propertyKeyTypes2.has(typeof k));
23323
+ const patternValues = values.filter((k2) => propertyKeyTypes2.has(typeof k2));
23319
23324
  inst._zod.pattern = new RegExp(patternValues.length ? `^(${patternValues.map((o) => escapeRegex2(o.toString())).join("|")})$` : "^[^\\s\\S]$");
23320
23325
  inst._zod.parse = (payload, _ctx) => {
23321
23326
  const input2 = payload.value;
@@ -24829,13 +24834,13 @@ function foldIntersection2(json2) {
24829
24834
  for (const key of FOLDABLE_KEYS2)
24830
24835
  if (key in json2)
24831
24836
  return;
24832
- const unions = allOf.filter((m) => UNION_KEYS2.some((k) => Array.isArray(m[k])));
24837
+ const unions = allOf.filter((m) => UNION_KEYS2.some((k2) => Array.isArray(m[k2])));
24833
24838
  let folded = null;
24834
24839
  if (!unions.length) {
24835
24840
  folded = foldObjects2(allOf);
24836
24841
  } else {
24837
24842
  const union3 = unions[0];
24838
- const keyword = UNION_KEYS2.find((k) => Array.isArray(union3[k]));
24843
+ const keyword = UNION_KEYS2.find((k2) => Array.isArray(union3[k2]));
24839
24844
  if (Object.keys(union3).length !== 1)
24840
24845
  return;
24841
24846
  const rest = allOf.filter((m) => m !== union3);
@@ -27072,6 +27077,8 @@ var Snapshot = object2({
27072
27077
  /** Spend per UTC hour ("2026-10-05T14:00:00.000Z") and bot, last two days. */
27073
27078
  usageHours: maybe(map2("UsageHours", map2("UsageHourRow", Usage))),
27074
27079
  usageHoursSince: maybe(string5()),
27080
+ /** Per model, the newest [gap in ms, cache hit ratio] pairs of its calls a minute or more after the session's previous one: main's compact schedule measures the prompt-cache TTL from them. */
27081
+ cacheGaps: maybe(map2("CacheGaps", array2(array2(number5())))),
27075
27082
  server: maybe(ServerID),
27076
27083
  /** Track summaries by path; the web client reads them (the app doesn't), the hosted hub sends them. */
27077
27084
  pathSummaries: maybe(map2("PathSummaries", object2({ text: string5(), by: string5(), at: string5() }).meta({ id: "PathSummary" })))
@@ -27141,6 +27148,94 @@ var RESTARTED_TURNS_READ = s(`SELECT t.thread_id, t.bot, r.claimed_at FROM turns
27141
27148
  WHERE r.id = 1 AND t.status IN ${OPEN_TURN_STATUSES} AND ${onLocal("t.bot")} AND t.started_at < r.claimed_at
27142
27149
  AND NOT EXISTS (SELECT 1 FROM session_folds f WHERE f.session_id = t.session_id AND f.folded_at >= r.claimed_at)`);
27143
27150
 
27151
+ // ../../hosted-hub/src/domain/cron.mjs
27152
+ var MINUTE = 6e4;
27153
+ var CATCH_UP_MS = 7 * 24 * 60 * MINUTE;
27154
+
27155
+ // ../../hosted-hub/src/store/schedules.ts
27156
+ var scheduleThreadId = (agent, id) => `sch-${agent}-${id.replaceAll("/", ".")}`;
27157
+ var Info = external_exports.object({ schedules: external_exports.array(external_exports.object({ name: external_exports.string().min(1), cron: external_exports.string().min(1), hasRun: external_exports.boolean() })) });
27158
+
27159
+ // ../../hosted-hub/src/domain/compact-report.mjs
27160
+ var quiet = (text) => String(text).replace(/@/g, "\uFF20");
27161
+ var count = (n) => typeof n === "number" ? n.toLocaleString("en-US") : "?";
27162
+ var link = (thread, id) => `[${quiet(String(thread?.title ?? id).replace(/[[\]]/g, ""))}](${id})`;
27163
+ var nextTry = (agent) => `next try: after ${quiet(agent)}'s next turn there, once idle 10+ min (or at 40 turns) with its prompt cache gone cold`;
27164
+ var compactedLine = (r, thread) => `compacted: ${quiet(r.agent)} on ${link(thread, r.threadId)} \xB7 ${quiet(r.trigger)} \xB7 ${count(r.before)} input tokens before`;
27165
+ var afterLine = (r, thread, after) => `after compaction: ${quiet(r.agent)} on ${link(thread, r.threadId)} \xB7 ${count(r.before)} \u2192 ${count(after)} input tokens`;
27166
+ var failureLine = (r, thread, reason) => `compact failed: ${quiet(r.agent)} on ${link(thread, r.threadId)} \xB7 ${quiet(r.trigger)} \xB7 ${quiet(reason)}; ${nextTry(r.agent)}`;
27167
+
27168
+ // ../../hosted-hub/src/store/compactions.ts
27169
+ var ASKED = `(c.attempt_at IS NOT NULL AND c.attempt_at > COALESCE(c.settled_at, 0))`;
27170
+ var k = (tokens) => `CAST((${tokens} + 500) / 1000 AS INTEGER) || 'k'`;
27171
+ var compactedText = (after) => `'Context compacted' || CASE WHEN c.before_tokens IS NULL THEN ''
27172
+ WHEN ${after} IS NULL THEN ' at ' || ${k("c.before_tokens")} || ' input tokens'
27173
+ ELSE ': ' || ${k("c.before_tokens")} || ' \u2192 ' || ${k(after)} || ' input tokens' END`;
27174
+ function compactionStatements(type, session, event, at, messageId2, report = null) {
27175
+ const before = `COALESCE(?, (SELECT input_tokens FROM usage_steps WHERE session_id = ? ORDER BY at DESC, sequence DESC, step_index DESC LIMIT 1))`;
27176
+ if (type === "compaction.requested")
27177
+ return [s(
27178
+ `INSERT INTO compactions (session_id, before_tokens) VALUES (?, ${before}) ON CONFLICT (session_id) DO UPDATE SET before_tokens = excluded.before_tokens,
27179
+ report_phase = CASE WHEN report_phase = 'asked' THEN 'requested' ELSE report_phase END`,
27180
+ session.id,
27181
+ typeof event.usageInputTokens === "number" ? event.usageInputTokens : null,
27182
+ session.id
27183
+ )];
27184
+ if (type === "session.waiting")
27185
+ return [
27186
+ // eve took the request and went idle with no checkpoint: it kept the history (the reason is in the bot's log). A
27187
+ // session.waiting from before eve took the request (the previous turn's, folded late) is not that: only 'requested' counts.
27188
+ ...reportLine(report, session, at, `${messageId2}:waiting`, (r) => failureLine(...r, `eve ended it without a checkpoint and kept the history (the reason is in ${session.bot}'s log)`), `report_phase = 'requested'`, null),
27189
+ s("UPDATE compactions SET settled_at = ? WHERE session_id = ? AND attempt_at IS NOT NULL AND attempt_at > COALESCE(settled_at, 0)", at, session.id)
27190
+ ];
27191
+ return [
27192
+ ...eventStatements(
27193
+ session.thread,
27194
+ {
27195
+ sql: `(SELECT json_object('kind', 'compaction', 'agent', ?, 'by', CASE WHEN ${ASKED} THEN c.attempt_by ELSE 'eve' END) FROM (SELECT 1) LEFT JOIN compactions c ON c.session_id = ?)`,
27196
+ args: [session.bot, session.id]
27197
+ },
27198
+ { sql: `(SELECT ${compactedText("NULL")} FROM (SELECT 1) LEFT JOIN compactions c ON c.session_id = ?)`, args: [session.id] },
27199
+ at,
27200
+ messageId2
27201
+ ),
27202
+ s(
27203
+ `INSERT INTO compactions (session_id, completed_at, turns_at_completion, event_id) VALUES (?, ?, (SELECT turns FROM thread_totals WHERE thread_id = ? AND bot = ?), ?)
27204
+ ON CONFLICT (session_id) DO UPDATE SET completed_at = excluded.completed_at, turns_at_completion = excluded.turns_at_completion, after_tokens = NULL, event_id = excluded.event_id`,
27205
+ session.id,
27206
+ at,
27207
+ session.thread,
27208
+ session.bot,
27209
+ messageId2
27210
+ ),
27211
+ ...reportLine(report, session, at, `${messageId2}:completed`, (r) => compactedLine(...r), `report_phase IN ('asked', 'requested', 'unanswered')`, "compacted")
27212
+ ];
27213
+ }
27214
+ var reportThread = (to) => {
27215
+ const [bot, ...id] = to.split("/");
27216
+ return scheduleThreadId(bot, id.join("/"));
27217
+ };
27218
+ var lineOf = (report, session) => [{ agent: session.bot, threadId: session.thread, trigger: report.trigger, before: report.before }, { title: report.title }];
27219
+ function reportLine(report, session, at, id, text, when, next) {
27220
+ if (!report) return [];
27221
+ const thread = reportThread(report.to), rowId = derivedMessageId(id, "report"), has = `EXISTS (SELECT 1 FROM compactions WHERE session_id = ? AND ${when})`;
27222
+ return [
27223
+ s(`INSERT INTO log (thread_id,type,data,at) SELECT ?, 'thread.created', ?, ? WHERE ${has} AND NOT EXISTS (SELECT 1 FROM threads WHERE id = ?)`, thread, JSON.stringify({ threadId: thread }), at, session.id, thread),
27224
+ s(`INSERT OR IGNORE INTO threads (id,title,created_at) SELECT ?, ?, ? WHERE ${has}`, thread, report.to, at, session.id),
27225
+ ...eventStatements(thread, { kind: "compaction-report", agent: session.bot }, text(lineOf(report, session)), at, rowId, { sql: has, args: [session.id] }),
27226
+ s(`UPDATE compactions SET report_phase = ? WHERE session_id = ? AND ${when}`, next, session.id)
27227
+ ];
27228
+ }
27229
+ function compactedSizeStatements(sessionId2, inputTokens) {
27230
+ const waiting = (c) => `${c}completed_at IS NOT NULL AND ${c}after_tokens IS NULL`;
27231
+ return [
27232
+ s(`UPDATE messages SET text = (SELECT ${compactedText("a")} FROM compactions c, (SELECT ? AS a) WHERE c.session_id = ? AND ${waiting("c.")})
27233
+ WHERE id = (SELECT event_id FROM compactions WHERE session_id = ? AND ${waiting("")})`, inputTokens, sessionId2, sessionId2),
27234
+ s(`UPDATE compactions SET after_tokens = ? WHERE session_id = ? AND ${waiting("")}`, inputTokens, sessionId2)
27235
+ ];
27236
+ }
27237
+ var reportAfterStatements = (report, session, inputTokens, at, id) => reportLine(report, session, at, `${id}:after`, ([r, thread]) => afterLine(r, thread, inputTokens), `report_phase = 'compacted' AND completed_at IS NOT NULL AND after_tokens IS NULL`, null);
27238
+
27144
27239
  // ../../hosted-hub/src/store/fold.ts
27145
27240
  var FOLD_STATE_SQL = `SELECT s.id, s.thread_id, s.bot, COALESCE(f.folded_index, -1) AS folded_index, (SELECT json_group_array(name) FROM (SELECT name FROM bots ORDER BY position)) AS roster,
27146
27241
  (SELECT json_group_array(bot) FROM (${PARTICIPANTS("s.thread_id")})) AS participants,
@@ -27148,7 +27243,9 @@ var FOLD_STATE_SQL = `SELECT s.id, s.thread_id, s.bot, COALESCE(f.folded_index,
27148
27243
  (SELECT json_object('person', person, 'names', json(names)) FROM human_notify) AS notify,
27149
27244
  (SELECT json_object('status', t.status, 'id', t.id, 'text', t.reply_text, 'lastStep', json(t.last_step), 'activity', json(t.activity),
27150
27245
  'trigger', ${triggerOf("t")}) FROM turns t WHERE t.session_id = s.id AND t.status IN ${OPEN_TURN_STATUSES}
27151
- ORDER BY t.started_at DESC LIMIT 1) AS open_turn
27246
+ ORDER BY t.started_at DESC LIMIT 1) AS open_turn,
27247
+ (SELECT json_object('to', c.report_to, 'trigger', c.report_trigger, 'before', c.report_before, 'title', (SELECT title FROM threads WHERE id = s.thread_id))
27248
+ FROM compactions c WHERE c.session_id = s.id AND c.report_to IS NOT NULL) AS report
27152
27249
  FROM sessions s LEFT JOIN session_folds f ON f.session_id = s.id WHERE s.id = ?`;
27153
27250
  function foldState(row) {
27154
27251
  if (!row) return void 0;
@@ -27159,7 +27256,8 @@ function foldState(row) {
27159
27256
  held: row.held == null ? null : String(row.held),
27160
27257
  notify: row.notify ? JSON.parse(String(row.notify)) : null,
27161
27258
  foldedIndex: Number(row.folded_index),
27162
- open: row.open_turn ? JSON.parse(String(row.open_turn)) : null
27259
+ open: row.open_turn ? JSON.parse(String(row.open_turn)) : null,
27260
+ report: row.report ? JSON.parse(String(row.report)) : null
27163
27261
  };
27164
27262
  }
27165
27263
  var REVOKED_TURN = `EXISTS (SELECT 1 FROM turn_deliveries td JOIN deliveries d ON d.id = td.delivery_id
@@ -27216,6 +27314,8 @@ function fold(state, chunks, now = Date.now()) {
27216
27314
  WHERE id = ? AND session_id = ? AND status = 'pending'`, r.outcome ?? "answered", at, r.response?.text ?? null, r.response?.optionId ?? null, r.response?.optionId ?? null, r.requestId, session.id));
27217
27315
  log("request.updated", { requestIds: (data.resolutions ?? []).map((r) => r.requestId) });
27218
27316
  }
27317
+ if (event.type === "compaction.requested" || event.type === "compaction.completed" || event.type === "session.waiting")
27318
+ stmts.push(...compactionStatements(event.type, session, data, at, derivedMessageId(session.id, index, eventIndex), state.report));
27219
27319
  if (event.type === "turn.started") {
27220
27320
  if (!data.turnId) throw new Error("turn.started must name eve turnId");
27221
27321
  flush();
@@ -27226,7 +27326,35 @@ function fold(state, chunks, now = Date.now()) {
27226
27326
  SELECT ?, ?, ?, ?, ?, 'streaming', ? WHERE EXISTS (SELECT 1 FROM sessions WHERE id = ? AND ended_at IS NULL)`, open3.id, session.thread, session.id, data.turnId, session.bot, at, session.id));
27227
27327
  log("turn.status", { turnId: open3.id, status: "streaming" });
27228
27328
  }
27329
+ if (event.type === "compaction.completed")
27330
+ stmts.push(s(
27331
+ "INSERT OR IGNORE INTO compaction_events (session_id, chunk, position, sequence, step_index, at, thread_id, bot) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
27332
+ session.id,
27333
+ index,
27334
+ eventIndex,
27335
+ data.sequence ?? null,
27336
+ data.stepIndex ?? null,
27337
+ at,
27338
+ session.thread,
27339
+ session.bot
27340
+ ));
27229
27341
  if (!open3) continue;
27342
+ if (event.type === "message.received" && typeof data.message === "string") {
27343
+ const cut = data.message.indexOf(MESSAGE_LINE);
27344
+ const state2 = cut < 0 ? 0 : cut;
27345
+ stmts.push(s(
27346
+ "INSERT OR IGNORE INTO inputs (session_id, chunk, position, turn_id, at, thread_id, bot, state_chars, message_chars) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)",
27347
+ session.id,
27348
+ index,
27349
+ eventIndex,
27350
+ open3.id,
27351
+ at,
27352
+ session.thread,
27353
+ session.bot,
27354
+ state2,
27355
+ data.message.length - state2
27356
+ ));
27357
+ }
27230
27358
  for (const deliveryId2 of event.meta?.deliveryIds ?? []) {
27231
27359
  open3.trigger ??= messageOfDelivery(deliveryId2, session.bot);
27232
27360
  stmts.push(s("INSERT OR IGNORE INTO turn_deliveries (delivery_id, turn_id) SELECT id, ? FROM deliveries WHERE id = ? AND session_id = ?", open3.id, deliveryId2, session.id));
@@ -27240,9 +27368,14 @@ function fold(state, chunks, now = Date.now()) {
27240
27368
  if (event.type === "agent.started" && data.sessionId && data.callId)
27241
27369
  stmts.push(...linkStatements(data.sessionId, open3.id, data.callId));
27242
27370
  switch (event.type) {
27371
+ case "step.started": {
27372
+ if (typeof data.modelId === "string") stmts.push(s("UPDATE sessions SET step_model = ? WHERE id = ?", data.modelId, session.id));
27373
+ break;
27374
+ }
27243
27375
  case "step.completed": {
27244
27376
  if (data.sequence === void 0 || data.stepIndex === void 0) break;
27245
- stmts.push(s(`${STEP_INSERT} VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, ...stepValues(session.id, { sequence: data.sequence, stepIndex: data.stepIndex, at: new Date(at).toISOString(), usage: data.usage ?? {} }), open3.id));
27377
+ stmts.push(s(`${STEP_INSERT} VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, (SELECT step_model FROM sessions WHERE id = ?))`, ...stepValues(session.id, { sequence: data.sequence, stepIndex: data.stepIndex, at: new Date(at).toISOString(), usage: data.usage ?? {} }), open3.id, session.id));
27378
+ if (typeof data.usage?.inputTokens === "number") stmts.push(...reportAfterStatements(state.report, session, data.usage.inputTokens, at, derivedMessageId(session.id, index, eventIndex)), ...compactedSizeStatements(session.id, data.usage.inputTokens));
27246
27379
  break;
27247
27380
  }
27248
27381
  case "message.appended": {
@@ -27399,7 +27532,7 @@ function foldSubagent(state, chunks, now = Date.now()) {
27399
27532
  // ../../hosted-hub/bots/world.ts
27400
27533
  async function foldAppend(tx, { runId, name, chunks, firstIndex }) {
27401
27534
  if (name !== sessionCodec.streamName(runId)) return;
27402
- const decoded = await Promise.all(chunks.map(async (c, k) => ({ index: firstIndex + k, events: await sessionCodec.decode(c) })));
27535
+ const decoded = await Promise.all(chunks.map(async (c, k2) => ({ index: firstIndex + k2, events: await sessionCodec.decode(c) })));
27403
27536
  return foldInTx(tx, runId, decoded);
27404
27537
  }
27405
27538
  async function createWorld() {