@wayai/cli 0.3.171 → 0.3.173

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -447,11 +447,11 @@ function captureException2(error, context) {
447
447
  Sentry.captureException(error);
448
448
  });
449
449
  }
450
- function addApiBreadcrumb(method, path35) {
450
+ function addApiBreadcrumb(method, path36) {
451
451
  if (!initialized) return;
452
452
  Sentry.addBreadcrumb({
453
453
  category: "http",
454
- message: `${method} ${path35}`,
454
+ message: `${method} ${path36}`,
455
455
  level: "info"
456
456
  });
457
457
  }
@@ -905,8 +905,8 @@ var init_parseUtil = __esm({
905
905
  init_errors();
906
906
  init_en();
907
907
  makeIssue = (params) => {
908
- const { data, path: path35, errorMaps, issueData } = params;
909
- const fullPath = [...path35, ...issueData.path || []];
908
+ const { data, path: path36, errorMaps, issueData } = params;
909
+ const fullPath = [...path36, ...issueData.path || []];
910
910
  const fullIssue = {
911
911
  ...issueData,
912
912
  path: fullPath
@@ -1217,11 +1217,11 @@ var init_types = __esm({
1217
1217
  init_parseUtil();
1218
1218
  init_util();
1219
1219
  ParseInputLazyPath = class {
1220
- constructor(parent, value, path35, key) {
1220
+ constructor(parent, value, path36, key) {
1221
1221
  this._cachedPath = [];
1222
1222
  this.parent = parent;
1223
1223
  this.data = value;
1224
- this._path = path35;
1224
+ this._path = path36;
1225
1225
  this._key = key;
1226
1226
  }
1227
1227
  get path() {
@@ -4932,9 +4932,9 @@ function monitorRuleActions(monitorConfig) {
4932
4932
  if (!monitorConfig || typeof monitorConfig !== "object") return [];
4933
4933
  const config = monitorConfig;
4934
4934
  const found = [];
4935
- const visit = (action, path35) => {
4935
+ const visit = (action, path36) => {
4936
4936
  if (!action || typeof action !== "object" || Array.isArray(action)) return;
4937
- found.push({ action, path: path35 });
4937
+ found.push({ action, path: path36 });
4938
4938
  };
4939
4939
  if (Array.isArray(config.rules)) {
4940
4940
  config.rules.forEach((rule, index) => {
@@ -4951,25 +4951,25 @@ function collectMonitorRuleIssues(monitorConfig) {
4951
4951
  const trigger = resolveMonitorTrigger(monitorConfig);
4952
4952
  const kinds = monitorRuleActionKinds(trigger);
4953
4953
  const issues = callUtteranceRuleIssues(monitorConfig);
4954
- for (const { action, path: path35 } of monitorRuleActions(monitorConfig)) {
4955
- if (trigger === "call_utterance" && path35[0] === "fallback") continue;
4954
+ for (const { action, path: path36 } of monitorRuleActions(monitorConfig)) {
4955
+ if (trigger === "call_utterance" && path36[0] === "fallback") continue;
4956
4956
  const kind = action.kind;
4957
4957
  if (typeof kind === "string" && !kinds.includes(kind)) {
4958
- issues.push({ path: [...path35, "kind"], message: monitorActionKindMessage(kind, trigger) });
4958
+ issues.push({ path: [...path36, "kind"], message: monitorActionKindMessage(kind, trigger) });
4959
4959
  }
4960
4960
  const toolName = action.tool_name;
4961
4961
  if (kind === "call_tool" && typeof toolName === "string" && isRefusedNativeToolName(toolName, trigger)) {
4962
- issues.push({ path: [...path35, "tool_name"], message: monitorRuleToolNotAllowedMessage(toolName, trigger) });
4962
+ issues.push({ path: [...path36, "tool_name"], message: monitorRuleToolNotAllowedMessage(toolName, trigger) });
4963
4963
  continue;
4964
4964
  }
4965
4965
  if (kind === "call_tool" && toolName === INSERT_NOTE_TOOL_NAME) {
4966
- issues.push(...insertNoteArgumentIssues(action, path35));
4966
+ issues.push(...insertNoteArgumentIssues(action, path36));
4967
4967
  }
4968
4968
  if (kind === "call_tool" && toolName === RUN_MONITOR_TOOL_NAME) {
4969
4969
  const callee = readRunMonitorCallee(action);
4970
4970
  if (!callee.ok) {
4971
4971
  issues.push({
4972
- path: [...path35, "args", "monitor_name"],
4972
+ path: [...path36, "args", "monitor_name"],
4973
4973
  message: runMonitorCalleeMessage(callee.reason)
4974
4974
  });
4975
4975
  }
@@ -5029,11 +5029,11 @@ function insertNoteTemplateMessage(reason) {
5029
5029
  return `insert_note's template is longer than the ${MONITOR_NOTE_TEMPLATE_MAX}-character limit.`;
5030
5030
  }
5031
5031
  }
5032
- function insertNoteArgumentIssues(action, path35) {
5032
+ function insertNoteArgumentIssues(action, path36) {
5033
5033
  const result = readInsertNoteTemplate(action);
5034
5034
  if (result.ok) return [];
5035
5035
  return [{
5036
- path: [...path35, "args", "template"],
5036
+ path: [...path36, "args", "template"],
5037
5037
  message: insertNoteTemplateMessage(result.reason)
5038
5038
  }];
5039
5039
  }
@@ -5063,12 +5063,12 @@ function validateFollowupLinks(followups, label, ctx) {
5063
5063
  const linkTargets = /* @__PURE__ */ new Set();
5064
5064
  followups.forEach((followup, i) => {
5065
5065
  const ref = followup?.after_followup_id;
5066
- const path35 = ["followups", i, "after_followup_id"];
5066
+ const path36 = ["followups", i, "after_followup_id"];
5067
5067
  if (followup?.type !== "inactivity_after_before_event") {
5068
5068
  if (ref !== void 0) {
5069
5069
  ctx.addIssue({
5070
5070
  code: external_exports.ZodIssueCode.custom,
5071
- path: path35,
5071
+ path: path36,
5072
5072
  message: `kanban status ${label}: after_followup_id is only valid on inactivity_after_before_event followups (this one is ${followup?.type})`
5073
5073
  });
5074
5074
  }
@@ -5077,7 +5077,7 @@ function validateFollowupLinks(followups, label, ctx) {
5077
5077
  if (ref === void 0) {
5078
5078
  ctx.addIssue({
5079
5079
  code: external_exports.ZodIssueCode.custom,
5080
- path: path35,
5080
+ path: path36,
5081
5081
  message: `kanban status ${label}: inactivity_after_before_event requires after_followup_id naming the id of a before_event followup in the same status`
5082
5082
  });
5083
5083
  return;
@@ -5087,7 +5087,7 @@ function validateFollowupLinks(followups, label, ctx) {
5087
5087
  if (matches.length > 1) {
5088
5088
  ctx.addIssue({
5089
5089
  code: external_exports.ZodIssueCode.custom,
5090
- path: path35,
5090
+ path: path36,
5091
5091
  message: `kanban status ${label}: after_followup_id "${ref}" matches ${matches.length} followups \u2014 a link must name exactly one`
5092
5092
  });
5093
5093
  return;
@@ -5099,7 +5099,7 @@ function validateFollowupLinks(followups, label, ctx) {
5099
5099
  );
5100
5100
  ctx.addIssue({
5101
5101
  code: external_exports.ZodIssueCode.custom,
5102
- path: path35,
5102
+ path: path36,
5103
5103
  message: hasIdlessBeforeEvent ? `kanban status ${label}: after_followup_id "${ref}" matches no followup \u2014 a link target must declare an explicit id, and this status has before_event followups without one` : `kanban status ${label}: after_followup_id "${ref}" matches no followup in this status`
5104
5104
  });
5105
5105
  return;
@@ -5107,7 +5107,7 @@ function validateFollowupLinks(followups, label, ctx) {
5107
5107
  if (target.type !== "before_event") {
5108
5108
  ctx.addIssue({
5109
5109
  code: external_exports.ZodIssueCode.custom,
5110
- path: path35,
5110
+ path: path36,
5111
5111
  message: `kanban status ${label}: after_followup_id "${ref}" points at a ${target.type} followup \u2014 only before_event followups can anchor a chain`
5112
5112
  });
5113
5113
  }
@@ -5183,12 +5183,12 @@ function typeMatches(typeField, allowed) {
5183
5183
  if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
5184
5184
  return false;
5185
5185
  }
5186
- function validateSchema(schema, path35, errors, opts = {}) {
5186
+ function validateSchema(schema, path36, errors, opts = {}) {
5187
5187
  if (typeof schema === "boolean") return;
5188
5188
  const depth = opts.depth ?? 0;
5189
5189
  if (depth > MAX_SCHEMA_DEPTH) {
5190
5190
  errors.push({
5191
- path: path35 || "<root>",
5191
+ path: path36 || "<root>",
5192
5192
  message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH} levels`,
5193
5193
  suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
5194
5194
  });
@@ -5196,7 +5196,7 @@ function validateSchema(schema, path35, errors, opts = {}) {
5196
5196
  }
5197
5197
  if (!isRecord2(schema)) {
5198
5198
  errors.push({
5199
- path: path35,
5199
+ path: path36,
5200
5200
  message: `expected object, got ${schema === null ? "null" : typeof schema}`
5201
5201
  });
5202
5202
  return;
@@ -5204,14 +5204,14 @@ function validateSchema(schema, path35, errors, opts = {}) {
5204
5204
  if (opts.isRoot) {
5205
5205
  if ("type" in schema && schema.type !== "object") {
5206
5206
  errors.push({
5207
- path: path35 ? `${path35}.type` : "type",
5207
+ path: path36 ? `${path36}.type` : "type",
5208
5208
  message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
5209
5209
  suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
5210
5210
  });
5211
5211
  }
5212
5212
  } else if ("type" in schema && !typeMatches(schema.type, ALLOWED_TYPES)) {
5213
5213
  errors.push({
5214
- path: `${path35}.type`,
5214
+ path: `${path36}.type`,
5215
5215
  message: `type must be one of ${[...ALLOWED_TYPES].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
5216
5216
  });
5217
5217
  }
@@ -5221,25 +5221,25 @@ function validateSchema(schema, path35, errors, opts = {}) {
5221
5221
  const isPlaceholder = PLACEHOLDER_TOKENS.includes(e);
5222
5222
  const isOutcomePlaceholder = e === "[KANBAN_OUTCOME_VALUES]";
5223
5223
  errors.push({
5224
- path: `${path35}.enum`,
5224
+ path: `${path36}.enum`,
5225
5225
  message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
5226
5226
  suggestion: isOutcomePlaceholder ? "Declare `outcomes` on the hub's terminal kanban status so the platform can render the placeholder into a valid array; with none configured the platform drops the parameter instead." : isPlaceholder ? "Set `operation: 'update_kanban_status'` on the tool and ensure at least one hub.kanban_status has `allowsAgentUpdate: true` so the platform can render the placeholder into a valid array." : 'Wrap the value in an array: `enum: ["value"]`.'
5227
5227
  });
5228
5228
  } else if (!Array.isArray(e)) {
5229
5229
  errors.push({
5230
- path: `${path35}.enum`,
5230
+ path: `${path36}.enum`,
5231
5231
  message: `enum must be a non-empty array of primitives, got ${typeof e}`
5232
5232
  });
5233
5233
  } else if (e.length === 0) {
5234
5234
  errors.push({
5235
- path: `${path35}.enum`,
5235
+ path: `${path36}.enum`,
5236
5236
  message: "enum must not be empty"
5237
5237
  });
5238
5238
  } else {
5239
5239
  for (let i = 0; i < e.length; i++) {
5240
5240
  if (!isPrimitive(e[i])) {
5241
5241
  errors.push({
5242
- path: `${path35}.enum[${i}]`,
5242
+ path: `${path36}.enum[${i}]`,
5243
5243
  message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
5244
5244
  });
5245
5245
  }
@@ -5249,7 +5249,7 @@ function validateSchema(schema, path35, errors, opts = {}) {
5249
5249
  for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
5250
5250
  if (key in schema && typeof schema[key] === "boolean") {
5251
5251
  errors.push({
5252
- path: `${path35}.${key}`,
5252
+ path: `${path36}.${key}`,
5253
5253
  message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
5254
5254
  suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
5255
5255
  });
@@ -5258,45 +5258,45 @@ function validateSchema(schema, path35, errors, opts = {}) {
5258
5258
  if ("properties" in schema) {
5259
5259
  if (!isRecord2(schema.properties)) {
5260
5260
  errors.push({
5261
- path: `${path35}.properties`,
5261
+ path: `${path36}.properties`,
5262
5262
  message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
5263
5263
  });
5264
5264
  } else {
5265
5265
  for (const [propName, propSchema] of Object.entries(schema.properties)) {
5266
- validateSchema(propSchema, `${path35}.properties.${propName}`, errors, { depth: depth + 1 });
5266
+ validateSchema(propSchema, `${path36}.properties.${propName}`, errors, { depth: depth + 1 });
5267
5267
  }
5268
5268
  }
5269
5269
  }
5270
5270
  if (schemaTypeIncludes(schema, "array") && "items" in schema) {
5271
5271
  if (Array.isArray(schema.items)) {
5272
- schema.items.forEach((sub, i) => validateSchema(sub, `${path35}.items[${i}]`, errors, { depth: depth + 1 }));
5272
+ schema.items.forEach((sub, i) => validateSchema(sub, `${path36}.items[${i}]`, errors, { depth: depth + 1 }));
5273
5273
  } else {
5274
- validateSchema(schema.items, `${path35}.items`, errors, { depth: depth + 1 });
5274
+ validateSchema(schema.items, `${path36}.items`, errors, { depth: depth + 1 });
5275
5275
  }
5276
5276
  }
5277
5277
  for (const key of SUBSCHEMA_OBJECT_KEYWORDS) {
5278
5278
  if (key in schema && isRecord2(schema[key])) {
5279
- validateSchema(schema[key], `${path35}.${key}`, errors, { depth: depth + 1 });
5279
+ validateSchema(schema[key], `${path36}.${key}`, errors, { depth: depth + 1 });
5280
5280
  }
5281
5281
  }
5282
5282
  for (const key of SUBSCHEMA_LIST_KEYWORDS) {
5283
5283
  const list = schema[key];
5284
5284
  if (Array.isArray(list)) {
5285
- list.forEach((sub, i) => validateSchema(sub, `${path35}.${key}[${i}]`, errors, { depth: depth + 1 }));
5285
+ list.forEach((sub, i) => validateSchema(sub, `${path36}.${key}[${i}]`, errors, { depth: depth + 1 }));
5286
5286
  }
5287
5287
  }
5288
5288
  for (const key of SUBSCHEMA_MAP_KEYWORDS) {
5289
5289
  const map = schema[key];
5290
5290
  if (isRecord2(map)) {
5291
5291
  for (const [name, sub] of Object.entries(map)) {
5292
- validateSchema(sub, `${path35}.${key}.${name}`, errors, { depth: depth + 1 });
5292
+ validateSchema(sub, `${path36}.${key}.${name}`, errors, { depth: depth + 1 });
5293
5293
  }
5294
5294
  }
5295
5295
  }
5296
5296
  const reportedPaths = new Set(errors.map((e) => e.path));
5297
5297
  for (const [k, v] of Object.entries(schema)) {
5298
5298
  if (typeof v !== "string") continue;
5299
- const fieldPath = `${path35}.${k}`;
5299
+ const fieldPath = `${path36}.${k}`;
5300
5300
  if (reportedPaths.has(fieldPath)) continue;
5301
5301
  for (const token of PLACEHOLDER_TOKENS) {
5302
5302
  if (v === token) {
@@ -5441,8 +5441,8 @@ function evalInitialStateError(input) {
5441
5441
  const parsed = evalInitialStateEntry.safeParse(entries[i]);
5442
5442
  if (!parsed.success) {
5443
5443
  const issue = parsed.error.issues[0];
5444
- const path35 = issue?.path.join(".") || "?";
5445
- return `initial_state[${i}].${path35} is invalid: ${issue?.message ?? "malformed"}`;
5444
+ const path36 = issue?.path.join(".") || "?";
5445
+ return `initial_state[${i}].${path36} is invalid: ${issue?.message ?? "malformed"}`;
5446
5446
  }
5447
5447
  if (seenSlugs.has(parsed.data.slug)) {
5448
5448
  return `initial_state[${i}].slug "${parsed.data.slug}" is declared more than once`;
@@ -5451,6 +5451,17 @@ function evalInitialStateError(input) {
5451
5451
  }
5452
5452
  return null;
5453
5453
  }
5454
+ function evalNameError(name) {
5455
+ if (name === void 0) return null;
5456
+ if (typeof name === "string" && name.trim().length > 0) return null;
5457
+ return "eval name must be a non-blank string";
5458
+ }
5459
+ function refineEvalName(value, ctx) {
5460
+ const error = evalNameError(value.eval.eval_name);
5461
+ if (error) {
5462
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["eval", "eval_name"], message: error });
5463
+ }
5464
+ }
5454
5465
  function refineEvalMessageTextRole(value, ctx) {
5455
5466
  const error = evalInputRoleError(value.eval.message_text);
5456
5467
  if (error) {
@@ -5512,6 +5523,9 @@ function unprovenRunCount(counts) {
5512
5523
  function terminalRunCount(counts) {
5513
5524
  return counts.successful_runs + counts.failed_runs;
5514
5525
  }
5526
+ function spokenLineField(label, description) {
5527
+ return { type: "text", label, maxLength: SPOKEN_LINE_MAX_CHARS, default: "", description };
5528
+ }
5515
5529
  function refineHubAsCodeCustomTools(config, ctx) {
5516
5530
  const agents = config.agents;
5517
5531
  if (!Array.isArray(agents)) return;
@@ -5608,6 +5622,14 @@ function refineHubAsCodeEvals(config, ctx) {
5608
5622
  if (!Array.isArray(evals)) return;
5609
5623
  for (let e = 0; e < evals.length; e++) {
5610
5624
  const entry = evals[e];
5625
+ const nameError = evalNameError(entry?.name);
5626
+ if (nameError) {
5627
+ ctx.addIssue({
5628
+ code: external_exports.ZodIssueCode.custom,
5629
+ path: ["evals", e, "name"],
5630
+ message: `evals[${e}]: ${nameError}`
5631
+ });
5632
+ }
5611
5633
  const error = evalInputRoleError(entry?.input);
5612
5634
  if (error) {
5613
5635
  ctx.addIssue({
@@ -5630,10 +5652,10 @@ function refineHubAsCodeEvals(config, ctx) {
5630
5652
  function refineHubAsCodeEvalAttachments(config, ctx) {
5631
5653
  const cfg = config;
5632
5654
  const referencedHashes = /* @__PURE__ */ new Set();
5633
- const addTurnIssue = (path35, turn, name) => {
5655
+ const addTurnIssue = (path36, turn, name) => {
5634
5656
  const error = evalTurnAttachmentsError(turn);
5635
5657
  if (error) {
5636
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path35, message: `${name}: ${error}` });
5658
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path36, message: `${name}: ${error}` });
5637
5659
  return;
5638
5660
  }
5639
5661
  for (const hash of collectTurnAttachmentHashes(turn)) referencedHashes.add(hash);
@@ -5701,6 +5723,72 @@ function refineHubAsCodeEvalAttachments(config, ctx) {
5701
5723
  }
5702
5724
  }
5703
5725
  }
5726
+ function refineHubAsCodeCallOpenings(config, ctx) {
5727
+ const cfg = config;
5728
+ if (Array.isArray(cfg.agents)) {
5729
+ cfg.agents.forEach((entry, a) => {
5730
+ const agent = entry;
5731
+ const openings = agent?.call_openings;
5732
+ if (openings === void 0 || openings === null) return;
5733
+ const path36 = ["agents", a, "call_openings"];
5734
+ const name = `agent "${typeof agent?.name === "string" ? agent.name : "<unnamed>"}"`;
5735
+ if (typeof openings !== "object" || Array.isArray(openings)) {
5736
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path36, message: `${name}: call_openings must map a language to an opening` });
5737
+ return;
5738
+ }
5739
+ if (agent?.role !== "pilot_voice" && Object.keys(openings).length > 0) {
5740
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path36, message: `${name}: only a pilot_voice agent has call_openings` });
5741
+ }
5742
+ for (const [language, raw] of Object.entries(openings)) {
5743
+ const at = [...path36, language];
5744
+ if (!callOpeningLanguage.safeParse(language).success) {
5745
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: at, message: `${name}: call_openings language must be one of ${CALL_OPENING_LANGUAGES.join(", ")}` });
5746
+ continue;
5747
+ }
5748
+ const opening = raw;
5749
+ if (!callOpeningHash.safeParse(opening?.hash).success) {
5750
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: [...at, "hash"], message: `${name}: call_openings.${language} names no audio file` });
5751
+ }
5752
+ if (!callOpeningCaption.safeParse(opening?.caption).success) {
5753
+ ctx.addIssue({
5754
+ code: external_exports.ZodIssueCode.custom,
5755
+ path: [...at, "caption"],
5756
+ message: `${name}: call_openings.${language}.caption must be 1\u2013${CALL_OPENING_CAPTION_MAX_CHARS} characters`
5757
+ });
5758
+ }
5759
+ }
5760
+ });
5761
+ }
5762
+ const files = cfg.call_opening_files;
5763
+ if (!Array.isArray(files)) return;
5764
+ if (files.length > MAX_CALL_OPENING_CARRIERS) {
5765
+ ctx.addIssue({
5766
+ code: external_exports.ZodIssueCode.custom,
5767
+ path: ["call_opening_files"],
5768
+ message: `too many call opening files (${files.length}); the maximum is ${MAX_CALL_OPENING_CARRIERS}`
5769
+ });
5770
+ }
5771
+ let aggregateEncoded = 0;
5772
+ files.forEach((f, i) => {
5773
+ const b64 = f?.content_base64;
5774
+ if (typeof b64 !== "string") return;
5775
+ aggregateEncoded += b64.length;
5776
+ if (b64.length > MAX_CALL_OPENING_ENCODED_BYTES) {
5777
+ ctx.addIssue({
5778
+ code: external_exports.ZodIssueCode.custom,
5779
+ path: ["call_opening_files", i, "content_base64"],
5780
+ message: "a call opening file exceeds the opening size limit"
5781
+ });
5782
+ }
5783
+ });
5784
+ if (aggregateEncoded > MAX_CALL_OPENING_AGGREGATE_ENCODED_BYTES) {
5785
+ ctx.addIssue({
5786
+ code: external_exports.ZodIssueCode.custom,
5787
+ path: ["call_opening_files"],
5788
+ message: `total call opening bytes exceed the ${MAX_CALL_OPENING_AGGREGATE_ENCODED_BYTES / 1024 / 1024}MB per-push limit`
5789
+ });
5790
+ }
5791
+ }
5704
5792
  function utf8ByteLength(value) {
5705
5793
  let bytes = 0;
5706
5794
  for (let i = 0; i < value.length; i++) {
@@ -5779,11 +5867,11 @@ function refineHubAsCodeDelegation(config, ctx) {
5779
5867
  }
5780
5868
  }
5781
5869
  if (del.context_boundary === void 0) return;
5782
- const path35 = ["agents", agentIndex, "tools", "delegation", delIndex, "context_boundary"];
5870
+ const path36 = ["agents", agentIndex, "tools", "delegation", delIndex, "context_boundary"];
5783
5871
  if (del.type !== "hub") {
5784
5872
  ctx.addIssue({
5785
5873
  code: external_exports.ZodIssueCode.custom,
5786
- path: path35,
5874
+ path: path36,
5787
5875
  message: `context_boundary applies only to \`type: hub\` delegations (got type "${String(del.type)}")`
5788
5876
  });
5789
5877
  return;
@@ -5791,7 +5879,7 @@ function refineHubAsCodeDelegation(config, ctx) {
5791
5879
  if (!CONTEXT_BOUNDARIES.includes(del.context_boundary)) {
5792
5880
  ctx.addIssue({
5793
5881
  code: external_exports.ZodIssueCode.custom,
5794
- path: path35,
5882
+ path: path36,
5795
5883
  message: `context_boundary must be one of: ${CONTEXT_BOUNDARIES.join(", ")}`
5796
5884
  });
5797
5885
  }
@@ -5934,7 +6022,7 @@ function refineHubAsCodeMonitorRulesOutput(config, ctx) {
5934
6022
  }
5935
6023
  });
5936
6024
  }
5937
- var uuidSchema, paginationSchema, timestampSchema, idParamSchema, clientOptionalString, clientOptionalBoolean, clientOptionalNumber, messageAttachment, MAX_MESSAGE_BODY_BYTES, MAX_ATTACHMENTS_PER_MESSAGE, MAX_AUDIO_FILE_BASE64_BYTES, primaryRegionSchema, placementSourceSchema, orgIdParam, orgAdminIdParam, createOrganizationBody, updateOrganizationBody, addOrgAdminBody, AUTH_TYPE, ORG_CREDENTIAL_AUTH_TYPES, AUTH_TYPE_DISPLAY, LEGACY_AUTH_TYPE_MAP, VALID_AUTH_TYPES, AGENT_ROLES, SAFE_USER_ID_REGEX, SUPPORTED_LOCALES, SUMMARIZATION_THRESHOLD_MIN, SUMMARIZATION_THRESHOLD_MAX, PREVIOUS_CONVERSATIONS_MAX, FLAG_CONDITION_OPERATORS, CONFIDENCE_VARIABLE_SUFFIX, DECISION_SCORE_MIN_LEVELS, DECISION_SCORE_MAX_LEVELS, DECISIONS_MODEL_PREFIXES, DECISION_CAPABLE_AGENT_ROLES, NATIVE_TOOL_SCHEMAS, WAYAI_CONNECTOR, BASE_NATIVE_TOOLS, NATIVE_TOOLS, CATALOG_SIDE_EFFECTS, NATIVE_TOOL_NAMES, previousConversationsCountField, summarizationThresholdField, flagConditionSchema, MONITOR_TRIGGERS, monitorTriggerSchema, MONITOR_FIRING_TRIGGERS, MONITOR_DELAY_SECONDS_MIN, MONITOR_IDLE_DELAY_REQUIRED_MESSAGE, MONITOR_HISTORY_MESSAGES_MAX, monitorHistoryMessagesSchema, monitorIncludeToolResultsSchema, MONITOR_INPUT_SHAPING_KEYS, MONITOR_INPUT_SHAPING_SCHEMAS, MONITOR_INPUT_SHAPING_IDLE_MESSAGE, monitorArgumentSourceSchema, MONITOR_NOTE_TEMPLATE_MAX, MONITOR_STEER_NOTE_MAX, monitorActionSchema, monitorRuleSchema, MONITOR_RULE_KEYS, MONITOR_RULE_SCHEMAS, MONITOR_RULE_TRIGGERS, MONITOR_RULE_TRIGGER_MESSAGE, CALL_UTTERANCE_SPEAKERS, callUtteranceSpeakerSchema, MONITOR_CALL_KEYS, MONITOR_CALL_SCHEMAS, MONITOR_CALL_KEY_MESSAGE, CALL_STEERING_MIN_CONFIDENCE, CALL_UTTERANCE_RULE_NOT_CONFIDENT_MESSAGE, CALL_UTTERANCE_FALLBACK_MESSAGE, CALL_UTTERANCE_FLAG_CONDITIONS_MESSAGE, CALL_STEER_NOTE_BLANK_MESSAGE, MONITOR_USER_MESSAGE_ACTION_KINDS, MONITOR_ASSISTANT_REPLY_ACTION_KINDS, MONITOR_CALL_UTTERANCE_ACTION_KINDS, INSERT_NOTE_TOOL_NAME, RUN_MONITOR_TOOL_NAME, MONITOR_RULE_ALLOWED_NATIVE_TOOLS, MONITOR_RULE_REENTRY_TOOLS, MONITOR_RULE_REENTRY_TRACKS, monitorConfigField, flagConditionsField, agentIdParam, listAgentsQuery, agentConnectionsQuery, createAgentBody, updateAgentBody, AGENT_PARAMETER_TYPES, AGENT_PARAMETER_NAME_REGEX, agentParameterCreateSchema, MAX_AGENT_PARAMETERS_PER_REQUEST, createAgentParametersBody, SLUG_REGEX, slugSchema, INVISIBLE_NAME_CHARS, MAX_KANBAN_STATUSES, MAX_FOLLOWUPS_PER_STATUS, MAX_LANES, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES, RESERVED_TEMPLATE_DUMP_NAME, kanbanStatusSlugSchema, followupTypeSchema, EVENT_RELATIVE_FOLLOWUP_TYPES, followupTimeUnitSchema, followupIdSchema, SELECTABLE_FOLLOWUP_TYPES, MAX_LINKED_FOLLOWUP_TARGETS_PER_STATUS, followupSchema, MAX_OUTCOMES_PER_STATUS, kanbanOutcomeSchema, EXCLUSIVE_FLAG_PAIRS, kanbanStatusSchema, kanbanStatusesArraySchema, laneSchema, lanesArraySchema, hubIdParam, hubAdminIdParam, hubUserIdParam, hubIdentityIdParam, hubTeamIdParam, hubTeamUserDeleteParam, hubSchemaQuery, PREVIEW_LABEL_MAX_LENGTH, MAX_ENDED_INDEX_RETENTION_DAYS, MAX_EVAL_RETENTION_DAYS, previewLabelField, createHubBody, updateHubBody, addHubAdminBody, addHubIdentityAuthorizationBody, contactDecisionBody, approveContactBody, listContactAccessQuery, createHubTeamBody, updateHubTeamBody, addHubTeamUserBody, reassignHubUserBody, replicatePreviewBody, updateChannelTestIdentitiesBody, claimCodeChannelParam, claimCodeDeleteParam, connectionIdParam, connectorIdParam, listConnectionsQuery, deleteConnectionQuery, addConnectionBody, editConnectionBody, PRODUCTION_DIRECT_FIELDS, setProductionCredentialBody, registerWhatsappQuery, registerWhatsappBody, retryProvisioningQuery, resendDomainStatusQuery, PLACEHOLDER_TOKENS, ALLOWED_TYPES, SUBSCHEMA_OBJECT_KEYWORDS, SUBSCHEMA_LIST_KEYWORDS, SUBSCHEMA_MAP_KEYWORDS, MAX_SCHEMA_DEPTH, toolIdParam, listToolsQuery, toolAgentQuery, deleteToolQuery, toolConnectionsQuery, nativeToolIdSchema, CONTEXT_BOUNDARIES, contextBoundarySchema, addNativeToolBody, addMcpToolBody, createCustomToolBody, updateCustomToolBody, updateToolExecutionConfigBody, initialValueCreateSchema, initialValueUpdateSchema, stateIdParam, listStatesQuery, stateNameSchema, createStateBody, updateStateBody, reorderStatesBody, variantAiModeSchema, experimentStatusSchema, overlayUpdateSchema, experimentIdParam, variantIdParam, listExperimentsQuery, listVariantsQuery, listOverridesQuery, deleteOverrideQuery, createExperimentBody, updateExperimentBody, setExperimentStatusBody, createVariantBody, updateVariantBody, upsertOverrideBody, orgTagIdParam, listOrgTagsQuery, ORG_TAG_NAME_REGEX, ORG_TAG_NAME_MAX_LENGTH, createOrgTagBody, updateOrgTagBody, orgCredentialIdParam, listOrgCredentialsQuery, createOrgCredentialBody, updateOrgCredentialBody, BASE_CREDENTIAL_MANAGED_BY, BASE_CREDENTIAL_NAME_MAX, baseCredentialNameSchema, createBaseCredentialLinkBody, baseCredentialLinkParams, baseCredentialLinkQuery, orgResourceIdParam, orgResourceFileIdParam, orgResourceFolderIdParam, hubOrgResourceParam, listOrgResourcesQuery, orgIdQuery, createOrgResourceBody, updateOrgResourceBody, createOrgResourceFolderBody, updateOrgResourceFolderBody, uploadOrgResourceFileBody, updateOrgResourceFileBody, uploadOrgSkillZipBody, linkOrgResourceBody, resourceIdParam, listResourcesQuery, createResourceBody, updateResourceBody, syncSkillsBody, resourceFileIdParam, listResourceFilesQuery, createResourceFileBody, updateResourceFileBody, uploadResourceFileBody, uploadSkillZipBody, resourceFolderIdParam, listResourceFoldersQuery, createResourceFolderBody, updateResourceFolderBody, agentResourceQuery, hubResourceQuery, linkAgentResourceBody, updateAgentResourceBody, unlinkAgentResourceQuery, navItemSchema, hubCountResetBody, navItemCountResetBody, typingBody, analyticsHubIdParam, analyticsVariableIdParam, updateVariablePinBody, updateAnalyticsViewBody, NUMERIC_FILTER_OPS, TEXT_FILTER_OPS, CATEGORICAL_FILTER_OPS, VARIABLE_FILTER_OPS, STRUCTURED_QUERY_OPS, STRUCTURED_QUERY_AGGREGATIONS, filterValueSchema, conversationsBody, analyticsConversationIdParam, messagesQuery, conversationDetailDataQuery, analyticsDataBody, structuredQueryBody, analyticsSqlBody, analyticsSqlTable, analyticsSqlSchemaQuery, EVAL_PACING_PRESET_NAMES, PACING_INTERVAL_MIN_MS, PACING_INTERVAL_MAX_MS, EVAL_MAX_RUNS_PER_SCENARIO, EVAL_RUN_DEADLINE_MIN_MS, EVAL_RUN_DEADLINE_MAX_MS, ISO_UTC_RE, paginationSchema2, evalIdParam, sessionIdParam, scenarioSetIdParam, hubIdQuery, evalDateContextSchema, EVAL_FIXTURE_NAME_MAX_LENGTH, evalFixtureOverrideSchema, runSessionQuery, runJourneyQuery, EVAL_INPUT_ROLES, EVAL_INPUT_ROLE_LIST, ROLE_ECHO_MAX, EVAL_INITIAL_STATE_SCOPES, MAX_INITIAL_STATE_ENTRIES, evalInitialStateEntry, createEvalBody, updateEvalBody, EVAL_LIST_MAX_LIMIT, evalListLimit, getEvalsQuery, toggleEvalBody, bulkToggleEvalsBody, pacingConfigSchema, EVAL_MAX_SELECTED_SCENARIOS, evalScenarioSelectionEntrySchema, evalScenarioSelectionSchema, sessionConfigSchema, createSessionBody, getSessionsQuery, getSessionResultsQuery, getSessionRunsQuery, evalAnalyticsQuery, getSessionCostQuery, compareSessionsQuery, evalsSqlBody, evalsSqlSchemaQuery, exportResultsQuery, validateEvalBody, hubAgentsQuery, createScenarioSetBody, updateScenarioSetBody, scenarioSetsHubQuery, createScenarioFromConversationBody, createJourneyFromConversationBody, EVAL_ATTACHMENT_HASH_REGEX, evalAttachmentRef, turnMayCarryAttachments, ATTACHMENTS_USER_ONLY_MESSAGE, journeyIdParam, journeyToolCallSchema, journeyTurnSchema, journeyStepOverrideSchema, fixtureField, createJourneyBody, updateJourneyBody, evalSessionConfigResponseSchema, evalSessionResponseSchema, evalSessionListConfigSchema, evalSessionListItemSchema, seedReleaseStatusSchema, EVAL_SESSION_NOT_QUIESCENT, getConversationsQuery, getMessagesQuery, appMessageSenderType, appMessageReceiverType, apiChannelMessage, apiChannelMessageBody, appMessageBody, appMessageResponse, CALL_STATUSES, callStatus, CALL_END_REASONS, callEndReason, CALL_TRANSPORTS, callTransport, CALL_PARTICIPANT_TYPES, callParticipantType, callInstant, MAX_SDP_OFFER_LENGTH, sdpDescription, sdpOffer, MAX_CALL_REQUEST_BODY_BYTES, hubScoped, callSummaryFields, callSummary, callIdParam, createCallBody, createCallResponse, callReadyBody, callHangupBody, callStatusQuery, MAX_REPORTED_DELEGATION_IDS, callDelegationId, callDelegationsBody, callResponse, MAX_CALL_RECORDING_GAPS, callRecordingGap, callRecordingNoteMetadata, TTS_VOICE_REPLY_ENABLED_FIELD, COPILOT_TRIGGER_FIELD, AUDIO_LANGUAGE_OPTIONS, whatsapp, instagram, resend, telegram, API_CHANNEL_DELIVERY_EVENTS, apiChannel, OPENAI_REASONING_MODELS, openai, anthropic, googleAiStudio, openRouter, xai, groqStt, openaiStt, elevenLabsStt, openaiTts, groqTts, elevenLabsTts, GEMINI_TTS_VOICES, googleTts, wayai, externalResources, restApiTool, mcpServer, e2b, CLAUDE_HARNESS_MODELS, CLAUDE_HARNESS_MODEL_OPTIONS, HARNESS_MCP_SERVERS_FIELD, HARNESS_EGRESS_FIELDS, claudeAgentSdk, claudeManagedAgents, rekorMemory, gptLive, CONNECTORS, evalCallInstant, EVAL_CALL_MIN_SECONDS, EVAL_CALL_MAX_SECONDS, hubScoped2, createEvalCallBody, createEvalCallResponse, evalCallConversationQuery, evalCallSpeaker, evalCallUtterance, evalCallTurn, evalCallRecordResponse, evalCallFinishResponse, updateUserBody, updateProfileBody, pathnameRegex, updatePreferencesBody, registerPushTokenBody, deletePushTokenQuery, activityQuery, deletionModeSchema, deletionRequestBody, archiveHubIdParam, archiveConversationParams, archiveListQuery, archiveMessageObservabilityParams, conversationIdParam, claimBody, releaseBody, transferBody, closeBody, additionalContextPayloadSchema, kanbanUpdateBody, annotateConversationBody, observabilityParams, observabilityListParams, deleteUserConversationsBody, deleteUserConversationsResponse, sendMessageBody, listConversationsQuery, flagSourceSchema, getConversationsResponse, getConversationDetailParams, getConversationDetailQuery, getConversationDetailResponse, listWhatsAppTemplatesQuery, sendWhatsAppTemplateBody, copilotSuggestBody, copilotSuggestResponse, CONSULT_THREAD_STATUSES, consultThreadStatus, CONSULT_THREAD_TITLE_MAX, consultThreadTitle, consultThreadSummary, listConsultThreadsQuery, listConsultThreadsResponse, createConsultThreadBody, createConsultThreadResponse, consultThreadIdParam, updateConsultThreadBody, updateConsultThreadResponse, CONSULT_AWAIT_TIMEOUT_MS, billingOrgIdParam, subscriptionItemParams, spendCapBody, growthPacksBody, portalSessionBody, checkoutSessionBody, updateBillingCurrencyBody, invoicesQuery, planKeySchema, billingStatusSchema, billingPlanTypeSchema, dataUsageCountersSchema, REKOR_ENTITLEMENT_CONTRACT_VERSION, entitlementProjectionSchema, rekorEntitlementRefreshMessageSchema, downloadBody, uploadQuery, signUrlBody, outboundSchemaQuery, templateIdParam, listTemplatesQuery, deleteTemplateQuery, templateStatusQuery, createTemplateBody, updateTemplateBody, submitTemplateBody, testTemplateBody, contactIdParam, listContactsQuery, createContactBody, updateContactBody, listIdParam, listListsQuery, listListContactsQuery, createListBody, updateListBody, addListContactsBody, removeListContactsBody, scheduleIdParam, listSchedulesQuery, listExecutionsQuery, createScheduleBody, updateScheduleBody, MAX_RESOURCE_FILE_SIZE, MAX_10MB_BASE64_ENCODED_BYTES, MAX_EVAL_ATTACHMENT_ENCODED_BYTES, MAX_EVAL_ATTACHMENT_CARRIERS, MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES, MAX_RESOURCE_ENCODED_BYTES, MAX_HUB_AS_CODE_RESOURCES, MAX_HUB_AS_CODE_RESOURCE_FILES, MAX_RESOURCE_AGGREGATE_ENCODED_BYTES, MAX_CI_CONFIG_BODY_BYTES, hubAsCodeStateSchema, hubAsCodeResourceFileSchema, hubAsCodeResourceSchema, uuidPattern, ciUuidSchema, boundedHubAsCodeResourcesSchema, hubAsCodeConfigSchema, ciPullHubIdParam, ciBranchParam, ciPullQuery, ciHubsQuery, ciLookupQuery, ciBranchesQuery, ciSyncBody, ciPushBody, ciDiffBody, ciPublishBody, ciPublishPreviewBody, ciSyncMcpBody, ciOrgResourcesParam, orgResourcesConfigSchema, ciOrgResourcesPushBody, ciOrgResourcesDiffBody, CI_APPLY_ENTITY_KINDS, CI_APPLY_OPERATIONS, ciApplyErrorBaseSchema, ciApplyErrorSchema, ciSyncCountSchema, ciSyncChangesSchema, ciSyncWarningSchema, ciSyncResponseSchema, adminOrgIdParam, adminOrgAdminIdParam, adminUserIdParam, PRICING_PLAN_ID_RE, adminPlanIdParam, adminOrganizationsQuery, adminUserSearchQuery, kanbanSlugMigrationQuery, adjustQuotaBody, updatePlanBody, addAdminUserBody, MAX_VOICE_CALL_MINUTE_OPS, voiceCallMinuteOps, updatePlatformConfigBody, updateFreeOrgLimitBody, adminScopedTargetBody, adminRepairLegacyOrgGrantsBody, adminRepairCompedPlansBody, updatePricingPlanBody, dataExplorerSearchQuery, dataExplorerOrgIdParam, dataExplorerHubIdParam, dataExplorerConvIdParam, dataExplorerDoInstancesQuery, dataExplorerNsIdParam, dataExplorerKvKeysBody, dataExplorerKvKeyBody, uuidOrHexId, dataExplorerDeleteOrgParam, dataExplorerDeleteHubParam, dataExplorerDeleteConvParam, dataExplorerDeleteUserParam, dataExplorerDeleteQuery, dataExplorerKvDeleteBody, pitrDoNamespace, pitrBookmarkParam, pitrRestoreBody, healthSamplingTriggerBody, dataExplorerDebugDoType, DEBUG_READ_MAX_LIMIT, DEBUG_READ_DEFAULT_LIMIT, DEBUG_DO_HEX_PREFIX, debugDoEntityId, debugTableName, dataExplorerDebugTablesParam, dataExplorerDebugRowsParam, dataExplorerDebugRowsQuery, dataExplorerDebugAnalyticsTable, debugUuid, dataExplorerDebugAnalyticsRowsParam, dataExplorerDebugAnalyticsRowsQuery, debugHubConvParam, debugMessageIdQuery, sandboxEgressPolicy, SANDBOX_EXEC_MAX_CMD_LENGTH, SANDBOX_EXEC_MAX_ALLOWLIST, SANDBOX_EXEC_MAX_TIMEOUT_MS, adminSandboxExecBody, META_ENTITY_ID_PATTERN, metaEntityId, whatsappCallbackBody, authMeResponse, wsTicketResponse, sessionCheckResponse, logoutResponse, magicCodeSendBody, magicCodeSendResponse, magicCodeVerifyBody, magicCodeVerifyResponse, passwordLoginBody, browserParams, browserFoldersQuery, browserFilesQuery, stateOperationBody, conversationListResourcesQuery, conversationReadResourceQuery, listPendingSchedulesQuery, listHubAggregateSchedulesQuery, reportSourceSchema, intakeReportSourceSchema, reportClassificationSchema, reportStatusSchema, reportLocaleSchema, reportMessageAuthorRoleSchema, reportMessageSchema, sentryRefStatusSchema, createReportBody, editReportBody, reporterReportSummarySchema, reporterListResponseSchema, getReportResponseSchema, reporterTransitionResponseSchema, contestReportBody, reporterListQuery, listReportsQuery, GITHUB_ISSUE_URL_REGEX, githubIssueUrlSchema, transitionReportBody, groupReportsBody, holdReportBody, clickhouseReadyResponse, bootstrapQuery, requestSnapshotChunkMessage, MAX_NAME_LENGTH, MAX_VALUE_LENGTH, MAX_TAGS, MAX_TAG_LENGTH, MAX_SCOPE_HUBS, MAX_SCOPE_TAGS, vaultSecretScopeSchema, vaultCreateBody, vaultUpdateBody, PERMISSIONS, MAX_NAME_LENGTH2, MAX_HUBS_PER_GRANT, MAX_HUB_TAGS_PER_GRANT, MAX_GRANTS, permissionEnum, grantScopeSchema, grantSchema, createTokenBody, tokenOrgIdParam, tokenGrantScopeSchema, tokenGrantSchema, tokenMetadataSchema, listTokensResponse, createTokenResponse, orgTokenSummarySchema, listOrgTokensResponse, invitePreviewQuery, invitePreviewResponse, jsonSchemaSchema, hubUserIdentity, stateValueEntry, getHubUserContextResponse, updateHubUserBody, updateHubUserResponse, unlockHubUserNameResponse, stateResetParams, stateResetResponse, hubAlertsParam, hubAlertSeverity, hubAlert, hubAlertsListResponse, noticeSeveritySchema, noticeStatusSchema, NOTICE_SCOPE_REGEX, noticeScopeSchema, noticeLinkSchema, createNoticeBody, updateNoticeBody, listNoticesQuery, noticeIdParamSchema, ADMIN_SKILL_NAME_REGEX, adminSkillNameParam, REKOR_ACTOR_TYPE_HEADER, REKOR_ACTOR_ID_HEADER, REKOR_ACTOR_LABEL_HEADER, REKOR_ACTOR_ORG_HEADER, REKOR_ACTOR_ADMIN_HEADER, REKOR_CLIENT_HEADER, REKOR_TOOL_ID_HEADER, REKOR_CLIENTS, rekorClientSchema, MAX_REKOR_TOOL_ID_LENGTH, rekorToolIdSchema, DATA_PROXY_MOUNT, DATA_PROXY_PREFIX, REKOR_V1_PREFIX, DATA_PROXY_ORG_QUERY_PARAM, MAX_PROVISIONING_BODY_BYTES, dataProxyQuery, rekorAttestation, REQUIRED_REKOR_ATTESTATION_HEADERS, BASE_DESTRUCTION_MOUNT, BASE_DESTRUCTION_PREFIX, BASE_DESTRUCTION_CONFIRM_PATH, baseDestructionConfirmBody, BASE_DESTRUCTION_GRACE_MS, BASE_DESTRUCTION_CONFIRM_TTL_MS, BASE_DESTRUCTION_ORG_QUERY_PARAM, baseDestructionQuery, baseDestructionParam, baseDestructionInitiateBody, baseDestructionStatus, baseDestructionRequest, baseDestructionListResponse, baseDestructionInitiateResponse, baseDestructionConfirmResponse, baseDestructionCancelResponse, rekorBaseChangeMessageSchema;
6025
+ var uuidSchema, paginationSchema, timestampSchema, idParamSchema, clientOptionalString, clientOptionalBoolean, clientOptionalNumber, messageAttachment, MAX_MESSAGE_BODY_BYTES, MAX_ATTACHMENTS_PER_MESSAGE, MAX_AUDIO_FILE_BASE64_BYTES, primaryRegionSchema, placementSourceSchema, orgIdParam, orgAdminIdParam, createOrganizationBody, updateOrganizationBody, addOrgAdminBody, AUTH_TYPE, ORG_CREDENTIAL_AUTH_TYPES, AUTH_TYPE_DISPLAY, LEGACY_AUTH_TYPE_MAP, VALID_AUTH_TYPES, AGENT_ROLES, SAFE_USER_ID_REGEX, SUPPORTED_LOCALES, SUMMARIZATION_THRESHOLD_MIN, SUMMARIZATION_THRESHOLD_MAX, PREVIOUS_CONVERSATIONS_MAX, FLAG_CONDITION_OPERATORS, CONFIDENCE_VARIABLE_SUFFIX, DECISION_SCORE_MIN_LEVELS, DECISION_SCORE_MAX_LEVELS, DECISIONS_MODEL_PREFIXES, DECISION_CAPABLE_AGENT_ROLES, NATIVE_TOOL_SCHEMAS, WAYAI_CONNECTOR, BASE_NATIVE_TOOLS, NATIVE_TOOLS, CATALOG_SIDE_EFFECTS, NATIVE_TOOL_NAMES, previousConversationsCountField, summarizationThresholdField, flagConditionSchema, MONITOR_TRIGGERS, monitorTriggerSchema, MONITOR_FIRING_TRIGGERS, MONITOR_DELAY_SECONDS_MIN, MONITOR_IDLE_DELAY_REQUIRED_MESSAGE, MONITOR_HISTORY_MESSAGES_MAX, monitorHistoryMessagesSchema, monitorIncludeToolResultsSchema, MONITOR_INPUT_SHAPING_KEYS, MONITOR_INPUT_SHAPING_SCHEMAS, MONITOR_INPUT_SHAPING_IDLE_MESSAGE, monitorArgumentSourceSchema, MONITOR_NOTE_TEMPLATE_MAX, MONITOR_STEER_NOTE_MAX, monitorActionSchema, monitorRuleSchema, MONITOR_RULE_KEYS, MONITOR_RULE_SCHEMAS, MONITOR_RULE_TRIGGERS, MONITOR_RULE_TRIGGER_MESSAGE, CALL_UTTERANCE_SPEAKERS, callUtteranceSpeakerSchema, MONITOR_CALL_KEYS, MONITOR_CALL_SCHEMAS, MONITOR_CALL_KEY_MESSAGE, CALL_STEERING_MIN_CONFIDENCE, CALL_UTTERANCE_RULE_NOT_CONFIDENT_MESSAGE, CALL_UTTERANCE_FALLBACK_MESSAGE, CALL_UTTERANCE_FLAG_CONDITIONS_MESSAGE, CALL_STEER_NOTE_BLANK_MESSAGE, MONITOR_USER_MESSAGE_ACTION_KINDS, MONITOR_ASSISTANT_REPLY_ACTION_KINDS, MONITOR_CALL_UTTERANCE_ACTION_KINDS, INSERT_NOTE_TOOL_NAME, RUN_MONITOR_TOOL_NAME, MONITOR_RULE_ALLOWED_NATIVE_TOOLS, MONITOR_RULE_REENTRY_TOOLS, MONITOR_RULE_REENTRY_TRACKS, monitorConfigField, flagConditionsField, agentIdParam, listAgentsQuery, agentConnectionsQuery, createAgentBody, updateAgentBody, AGENT_PARAMETER_TYPES, AGENT_PARAMETER_NAME_REGEX, agentParameterCreateSchema, MAX_AGENT_PARAMETERS_PER_REQUEST, createAgentParametersBody, SLUG_REGEX, slugSchema, INVISIBLE_NAME_CHARS, MAX_KANBAN_STATUSES, MAX_FOLLOWUPS_PER_STATUS, MAX_LANES, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES, RESERVED_TEMPLATE_DUMP_NAME, kanbanStatusSlugSchema, followupTypeSchema, EVENT_RELATIVE_FOLLOWUP_TYPES, followupTimeUnitSchema, followupIdSchema, SELECTABLE_FOLLOWUP_TYPES, MAX_LINKED_FOLLOWUP_TARGETS_PER_STATUS, followupSchema, MAX_OUTCOMES_PER_STATUS, kanbanOutcomeSchema, EXCLUSIVE_FLAG_PAIRS, kanbanStatusSchema, kanbanStatusesArraySchema, laneSchema, lanesArraySchema, hubIdParam, hubAdminIdParam, hubUserIdParam, hubIdentityIdParam, hubTeamIdParam, hubTeamUserDeleteParam, hubSchemaQuery, PREVIEW_LABEL_MAX_LENGTH, MAX_ENDED_INDEX_RETENTION_DAYS, MAX_EVAL_RETENTION_DAYS, previewLabelField, createHubBody, updateHubBody, addHubAdminBody, addHubIdentityAuthorizationBody, contactDecisionBody, approveContactBody, listContactAccessQuery, createHubTeamBody, updateHubTeamBody, addHubTeamUserBody, reassignHubUserBody, replicatePreviewBody, updateChannelTestIdentitiesBody, claimCodeChannelParam, claimCodeDeleteParam, connectionIdParam, connectorIdParam, listConnectionsQuery, deleteConnectionQuery, addConnectionBody, editConnectionBody, PRODUCTION_DIRECT_FIELDS, setProductionCredentialBody, registerWhatsappQuery, registerWhatsappBody, retryProvisioningQuery, resendDomainStatusQuery, PLACEHOLDER_TOKENS, ALLOWED_TYPES, SUBSCHEMA_OBJECT_KEYWORDS, SUBSCHEMA_LIST_KEYWORDS, SUBSCHEMA_MAP_KEYWORDS, MAX_SCHEMA_DEPTH, toolIdParam, listToolsQuery, toolAgentQuery, deleteToolQuery, toolConnectionsQuery, nativeToolIdSchema, CONTEXT_BOUNDARIES, contextBoundarySchema, addNativeToolBody, addMcpToolBody, createCustomToolBody, updateCustomToolBody, updateToolExecutionConfigBody, initialValueCreateSchema, initialValueUpdateSchema, stateIdParam, listStatesQuery, stateNameSchema, createStateBody, updateStateBody, reorderStatesBody, variantAiModeSchema, experimentStatusSchema, overlayUpdateSchema, experimentIdParam, variantIdParam, listExperimentsQuery, listVariantsQuery, listOverridesQuery, deleteOverrideQuery, createExperimentBody, updateExperimentBody, setExperimentStatusBody, createVariantBody, updateVariantBody, upsertOverrideBody, orgTagIdParam, listOrgTagsQuery, ORG_TAG_NAME_REGEX, ORG_TAG_NAME_MAX_LENGTH, createOrgTagBody, updateOrgTagBody, orgCredentialIdParam, listOrgCredentialsQuery, createOrgCredentialBody, updateOrgCredentialBody, BASE_CREDENTIAL_MANAGED_BY, BASE_CREDENTIAL_NAME_MAX, baseCredentialNameSchema, createBaseCredentialLinkBody, baseCredentialLinkParams, baseCredentialLinkQuery, orgResourceIdParam, orgResourceFileIdParam, orgResourceFolderIdParam, hubOrgResourceParam, listOrgResourcesQuery, orgIdQuery, createOrgResourceBody, updateOrgResourceBody, createOrgResourceFolderBody, updateOrgResourceFolderBody, uploadOrgResourceFileBody, updateOrgResourceFileBody, uploadOrgSkillZipBody, linkOrgResourceBody, resourceIdParam, listResourcesQuery, createResourceBody, updateResourceBody, syncSkillsBody, resourceFileIdParam, listResourceFilesQuery, createResourceFileBody, updateResourceFileBody, uploadResourceFileBody, uploadSkillZipBody, resourceFolderIdParam, listResourceFoldersQuery, createResourceFolderBody, updateResourceFolderBody, agentResourceQuery, hubResourceQuery, linkAgentResourceBody, updateAgentResourceBody, unlinkAgentResourceQuery, navItemSchema, hubCountResetBody, navItemCountResetBody, typingBody, analyticsHubIdParam, analyticsVariableIdParam, updateVariablePinBody, updateAnalyticsViewBody, NUMERIC_FILTER_OPS, TEXT_FILTER_OPS, CATEGORICAL_FILTER_OPS, VARIABLE_FILTER_OPS, STRUCTURED_QUERY_OPS, STRUCTURED_QUERY_AGGREGATIONS, filterValueSchema, conversationsBody, analyticsConversationIdParam, messagesQuery, conversationDetailDataQuery, analyticsDataBody, structuredQueryBody, analyticsSqlBody, analyticsSqlTable, analyticsSqlSchemaQuery, EVAL_PACING_PRESET_NAMES, PACING_INTERVAL_MIN_MS, PACING_INTERVAL_MAX_MS, EVAL_MAX_RUNS_PER_SCENARIO, EVAL_RUN_DEADLINE_MIN_MS, EVAL_RUN_DEADLINE_MAX_MS, ISO_UTC_RE, paginationSchema2, evalIdParam, sessionIdParam, scenarioSetIdParam, hubIdQuery, evalDateContextSchema, EVAL_FIXTURE_NAME_MAX_LENGTH, evalFixtureOverrideSchema, runSessionQuery, runJourneyQuery, EVAL_INPUT_ROLES, EVAL_INPUT_ROLE_LIST, ROLE_ECHO_MAX, EVAL_INITIAL_STATE_SCOPES, MAX_INITIAL_STATE_ENTRIES, evalInitialStateEntry, evalBody, EVAL_LIST_MAX_LIMIT, evalListLimit, getEvalsQuery, toggleEvalBody, bulkToggleEvalsBody, pacingConfigSchema, EVAL_MAX_SELECTED_SCENARIOS, evalScenarioSelectionEntrySchema, evalScenarioSelectionSchema, sessionConfigSchema, createSessionBody, getSessionsQuery, getSessionResultsQuery, getSessionRunsQuery, evalAnalyticsQuery, getSessionCostQuery, compareSessionsQuery, evalsSqlBody, evalsSqlSchemaQuery, exportResultsQuery, validateEvalBody, hubAgentsQuery, createScenarioSetBody, updateScenarioSetBody, scenarioSetsHubQuery, createScenarioFromConversationBody, createJourneyFromConversationBody, EVAL_ATTACHMENT_HASH_REGEX, evalAttachmentRef, turnMayCarryAttachments, ATTACHMENTS_USER_ONLY_MESSAGE, journeyIdParam, journeyToolCallSchema, journeyTurnSchema, journeyStepOverrideSchema, fixtureField, createJourneyBody, updateJourneyBody, evalSessionConfigResponseSchema, evalSessionResponseSchema, evalSessionListConfigSchema, evalSessionListItemSchema, seedReleaseStatusSchema, EVAL_SESSION_NOT_QUIESCENT, getConversationsQuery, getMessagesQuery, appMessageSenderType, appMessageReceiverType, apiChannelMessage, apiChannelMessageBody, appMessageBody, appMessageResponse, CALL_STATUSES, callStatus, CALL_END_REASONS, callEndReason, CALL_TRANSPORTS, callTransport, CALL_PARTICIPANT_TYPES, callParticipantType, callInstant, MAX_SDP_OFFER_LENGTH, sdpDescription, sdpOffer, MAX_CALL_REQUEST_BODY_BYTES, hubScoped, callSummaryFields, callSummary, callIdParam, createCallBody, createCallResponse, callReadyBody, callHangupBody, callStatusQuery, MAX_REPORTED_DELEGATION_IDS, callDelegationId, callDelegationsBody, callResponse, MAX_CALL_RECORDING_GAPS, callRecordingGap, callRecordingNoteMetadata, CALL_OPENING_LANGUAGES, callOpeningLanguage, CALL_OPENING_MAX_DURATION_MS, CALL_OPENING_MAX_BYTES, CALL_OPENING_CAPTION_MAX_CHARS, CALL_OPENING_CONTENT_TYPES, callOpeningContentType, CALL_OPENING_HASH_REGEX, callOpeningHash, callOpeningCaption, storedCallOpening, MAX_CALL_OPENING_ENCODED_BYTES, MAX_CALL_OPENING_BODY_BYTES, agentCallOpeningParams, putAgentCallOpeningBody, deleteAgentCallOpeningQuery, callOpeningParam, callOpeningQuery, TTS_VOICE_REPLY_ENABLED_FIELD, COPILOT_TRIGGER_FIELD, AUDIO_LANGUAGE_OPTIONS, whatsapp, instagram, resend, telegram, API_CHANNEL_DELIVERY_EVENTS, apiChannel, OPENAI_REASONING_MODELS, openai, anthropic, googleAiStudio, openRouter, xai, groqStt, openaiStt, elevenLabsStt, openaiTts, groqTts, elevenLabsTts, GEMINI_TTS_VOICES, googleTts, wayai, externalResources, restApiTool, mcpServer, e2b, CLAUDE_HARNESS_MODELS, CLAUDE_HARNESS_MODEL_OPTIONS, HARNESS_MCP_SERVERS_FIELD, HARNESS_EGRESS_FIELDS, claudeAgentSdk, claudeManagedAgents, rekorMemory, SPOKEN_LINE_MAX_CHARS, gptLive, CONNECTORS, evalCallInstant, EVAL_CALL_MIN_SECONDS, EVAL_CALL_MAX_SECONDS, EVAL_CALL_SPOKEN_LINE_MAX_CHARS, hubScoped2, createEvalCallBody, createEvalCallResponse, evalCallConversationQuery, evalCallSpeaker, evalCallUtterance, evalCallTurn, evalCallRecordResponse, evalCallFinishResponse, updateUserBody, updateProfileBody, pathnameRegex, updatePreferencesBody, registerPushTokenBody, deletePushTokenQuery, activityQuery, deletionModeSchema, deletionRequestBody, archiveHubIdParam, archiveConversationParams, archiveListQuery, archiveMessageObservabilityParams, conversationIdParam, claimBody, releaseBody, transferBody, closeBody, additionalContextPayloadSchema, kanbanUpdateBody, annotateConversationBody, observabilityParams, observabilityListParams, deleteUserConversationsBody, deleteUserConversationsResponse, sendMessageBody, listConversationsQuery, flagSourceSchema, getConversationsResponse, getConversationDetailParams, getConversationDetailQuery, getConversationDetailResponse, listWhatsAppTemplatesQuery, sendWhatsAppTemplateBody, copilotSuggestBody, copilotSuggestResponse, CONSULT_THREAD_STATUSES, consultThreadStatus, CONSULT_THREAD_TITLE_MAX, consultThreadTitle, consultThreadSummary, listConsultThreadsQuery, listConsultThreadsResponse, createConsultThreadBody, createConsultThreadResponse, consultThreadIdParam, updateConsultThreadBody, updateConsultThreadResponse, CONSULT_AWAIT_TIMEOUT_MS, billingOrgIdParam, subscriptionItemParams, spendCapBody, growthPacksBody, portalSessionBody, checkoutSessionBody, updateBillingCurrencyBody, invoicesQuery, planKeySchema, billingStatusSchema, billingPlanTypeSchema, dataUsageCountersSchema, REKOR_ENTITLEMENT_CONTRACT_VERSION, entitlementProjectionSchema, rekorEntitlementRefreshMessageSchema, downloadBody, uploadQuery, signUrlBody, outboundSchemaQuery, templateIdParam, listTemplatesQuery, deleteTemplateQuery, templateStatusQuery, createTemplateBody, updateTemplateBody, submitTemplateBody, testTemplateBody, contactIdParam, listContactsQuery, createContactBody, updateContactBody, listIdParam, listListsQuery, listListContactsQuery, createListBody, updateListBody, addListContactsBody, removeListContactsBody, scheduleIdParam, listSchedulesQuery, listExecutionsQuery, createScheduleBody, updateScheduleBody, MAX_RESOURCE_FILE_SIZE, MAX_10MB_BASE64_ENCODED_BYTES, MAX_EVAL_ATTACHMENT_ENCODED_BYTES, MAX_EVAL_ATTACHMENT_CARRIERS, MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES, MAX_RESOURCE_ENCODED_BYTES, MAX_HUB_AS_CODE_RESOURCES, MAX_HUB_AS_CODE_RESOURCE_FILES, MAX_RESOURCE_AGGREGATE_ENCODED_BYTES, MAX_CI_CONFIG_BODY_BYTES, MAX_CALL_OPENING_CARRIERS, MAX_CALL_OPENING_AGGREGATE_ENCODED_BYTES, hubAsCodeStateSchema, hubAsCodeResourceFileSchema, hubAsCodeResourceSchema, uuidPattern, ciUuidSchema, boundedHubAsCodeResourcesSchema, hubAsCodeConfigSchema, ciPullHubIdParam, ciBranchParam, ciPullQuery, ciHubsQuery, ciLookupQuery, ciBranchesQuery, ciSyncBody, ciPushBody, ciDiffBody, ciPublishBody, ciPublishPreviewBody, ciSyncMcpBody, ciOrgResourcesParam, orgResourcesConfigSchema, ciOrgResourcesPushBody, ciOrgResourcesDiffBody, CI_APPLY_ENTITY_KINDS, CI_APPLY_OPERATIONS, ciApplyErrorBaseSchema, ciApplyErrorSchema, ciSyncCountSchema, ciSyncChangesSchema, ciSyncWarningSchema, ciSyncResponseSchema, adminOrgIdParam, adminOrgAdminIdParam, adminUserIdParam, PRICING_PLAN_ID_RE, adminPlanIdParam, adminOrganizationsQuery, adminUserSearchQuery, kanbanSlugMigrationQuery, adjustQuotaBody, updatePlanBody, addAdminUserBody, MAX_VOICE_CALL_MINUTE_OPS, voiceCallMinuteOps, updatePlatformConfigBody, updateFreeOrgLimitBody, adminScopedTargetBody, adminRepairLegacyOrgGrantsBody, adminRepairCompedPlansBody, updatePricingPlanBody, dataExplorerSearchQuery, dataExplorerOrgIdParam, dataExplorerHubIdParam, dataExplorerConvIdParam, dataExplorerDoInstancesQuery, dataExplorerNsIdParam, dataExplorerKvKeysBody, dataExplorerKvKeyBody, uuidOrHexId, dataExplorerDeleteOrgParam, dataExplorerDeleteHubParam, dataExplorerDeleteConvParam, dataExplorerDeleteUserParam, dataExplorerDeleteQuery, dataExplorerKvDeleteBody, pitrDoNamespace, pitrBookmarkParam, pitrRestoreBody, healthSamplingTriggerBody, dataExplorerDebugDoType, DEBUG_READ_MAX_LIMIT, DEBUG_READ_DEFAULT_LIMIT, DEBUG_DO_HEX_PREFIX, debugDoEntityId, debugTableName, dataExplorerDebugTablesParam, dataExplorerDebugRowsParam, dataExplorerDebugRowsQuery, dataExplorerDebugAnalyticsTable, debugUuid, dataExplorerDebugAnalyticsRowsParam, dataExplorerDebugAnalyticsRowsQuery, debugHubConvParam, debugMessageIdQuery, sandboxEgressPolicy, SANDBOX_EXEC_MAX_CMD_LENGTH, SANDBOX_EXEC_MAX_ALLOWLIST, SANDBOX_EXEC_MAX_TIMEOUT_MS, adminSandboxExecBody, META_ENTITY_ID_PATTERN, metaEntityId, whatsappCallbackBody, authMeResponse, wsTicketResponse, sessionCheckResponse, logoutResponse, magicCodeSendBody, magicCodeSendResponse, magicCodeVerifyBody, magicCodeVerifyResponse, passwordLoginBody, browserParams, browserFoldersQuery, browserFilesQuery, stateOperationBody, conversationListResourcesQuery, conversationReadResourceQuery, listPendingSchedulesQuery, listHubAggregateSchedulesQuery, reportSourceSchema, intakeReportSourceSchema, reportClassificationSchema, reportStatusSchema, reportLocaleSchema, reportMessageAuthorRoleSchema, reportMessageSchema, sentryRefStatusSchema, createReportBody, editReportBody, reporterReportSummarySchema, reporterListResponseSchema, getReportResponseSchema, reporterTransitionResponseSchema, contestReportBody, reporterListQuery, listReportsQuery, GITHUB_ISSUE_URL_REGEX, githubIssueUrlSchema, transitionReportBody, groupReportsBody, holdReportBody, clickhouseReadyResponse, bootstrapQuery, requestSnapshotChunkMessage, MAX_NAME_LENGTH, MAX_VALUE_LENGTH, MAX_TAGS, MAX_TAG_LENGTH, MAX_SCOPE_HUBS, MAX_SCOPE_TAGS, vaultSecretScopeSchema, vaultCreateBody, vaultUpdateBody, PERMISSIONS, MAX_NAME_LENGTH2, MAX_HUBS_PER_GRANT, MAX_HUB_TAGS_PER_GRANT, MAX_GRANTS, permissionEnum, grantScopeSchema, grantSchema, createTokenBody, tokenOrgIdParam, tokenGrantScopeSchema, tokenGrantSchema, tokenMetadataSchema, listTokensResponse, createTokenResponse, orgTokenSummarySchema, listOrgTokensResponse, invitePreviewQuery, invitePreviewResponse, jsonSchemaSchema, hubUserIdentity, stateValueEntry, getHubUserContextResponse, updateHubUserBody, updateHubUserResponse, unlockHubUserNameResponse, stateResetParams, stateResetResponse, hubAlertsParam, hubAlertSeverity, hubAlert, hubAlertsListResponse, noticeSeveritySchema, noticeStatusSchema, NOTICE_SCOPE_REGEX, noticeScopeSchema, noticeLinkSchema, createNoticeBody, updateNoticeBody, listNoticesQuery, noticeIdParamSchema, ADMIN_SKILL_NAME_REGEX, adminSkillNameParam, REKOR_ACTOR_TYPE_HEADER, REKOR_ACTOR_ID_HEADER, REKOR_ACTOR_LABEL_HEADER, REKOR_ACTOR_ORG_HEADER, REKOR_ACTOR_ADMIN_HEADER, REKOR_CLIENT_HEADER, REKOR_TOOL_ID_HEADER, REKOR_CLIENTS, rekorClientSchema, MAX_REKOR_TOOL_ID_LENGTH, rekorToolIdSchema, DATA_PROXY_MOUNT, DATA_PROXY_PREFIX, REKOR_V1_PREFIX, DATA_PROXY_ORG_QUERY_PARAM, MAX_PROVISIONING_BODY_BYTES, dataProxyQuery, rekorAttestation, REQUIRED_REKOR_ATTESTATION_HEADERS, BASE_DESTRUCTION_MOUNT, BASE_DESTRUCTION_PREFIX, BASE_DESTRUCTION_CONFIRM_PATH, baseDestructionConfirmBody, BASE_DESTRUCTION_GRACE_MS, BASE_DESTRUCTION_CONFIRM_TTL_MS, BASE_DESTRUCTION_ORG_QUERY_PARAM, baseDestructionQuery, baseDestructionParam, baseDestructionInitiateBody, baseDestructionStatus, baseDestructionRequest, baseDestructionListResponse, baseDestructionInitiateResponse, baseDestructionConfirmResponse, baseDestructionCancelResponse, rekorBaseChangeMessageSchema;
5938
6026
  var init_contracts = __esm({
5939
6027
  "../../packages/core/dist/contracts/index.js"() {
5940
6028
  "use strict";
@@ -5992,6 +6080,7 @@ var init_contracts = __esm({
5992
6080
  init_zod();
5993
6081
  init_zod();
5994
6082
  init_zod();
6083
+ init_zod();
5995
6084
  uuidSchema = external_exports.string().uuid();
5996
6085
  paginationSchema = external_exports.object({
5997
6086
  limit: external_exports.coerce.number().int().min(1).max(100).default(50),
@@ -8319,12 +8408,9 @@ var init_contracts = __esm({
8319
8408
  scope: external_exports.enum(EVAL_INITIAL_STATE_SCOPES).default("user"),
8320
8409
  value: external_exports.record(external_exports.unknown())
8321
8410
  });
8322
- createEvalBody = external_exports.object({
8323
- eval: external_exports.record(external_exports.unknown())
8324
- }).superRefine(refineEvalMessageTextRole).superRefine(refineEvalAttachments).superRefine(refineEvalInitialState);
8325
- updateEvalBody = external_exports.object({
8411
+ evalBody = external_exports.object({
8326
8412
  eval: external_exports.record(external_exports.unknown())
8327
- }).superRefine(refineEvalMessageTextRole).superRefine(refineEvalAttachments).superRefine(refineEvalInitialState);
8413
+ }).superRefine(refineEvalName).superRefine(refineEvalMessageTextRole).superRefine(refineEvalAttachments).superRefine(refineEvalInitialState);
8328
8414
  EVAL_LIST_MAX_LIMIT = 1e3;
8329
8415
  evalListLimit = external_exports.string().regex(/^\d+$/).refine((v) => Number(v) <= EVAL_LIST_MAX_LIMIT, {
8330
8416
  message: `limit must be ${EVAL_LIST_MAX_LIMIT} or less`
@@ -8462,7 +8548,8 @@ var init_contracts = __esm({
8462
8548
  hub_id: external_exports.string().uuid(),
8463
8549
  conversation_id: external_exports.string().uuid(),
8464
8550
  scenario_set_id: external_exports.string().uuid(),
8465
- scenario_name: external_exports.string().min(1).max(200),
8551
+ // Becomes the created eval's `eval_name`, so it follows `evalNameError`.
8552
+ scenario_name: external_exports.string().max(200).refine((name) => evalNameError(name) === null, "scenario_name must be a non-blank string"),
8466
8553
  evaluator_instructions: external_exports.string().max(4e3).optional()
8467
8554
  });
8468
8555
  createJourneyFromConversationBody = external_exports.object({
@@ -8815,13 +8902,16 @@ var init_contracts = __esm({
8815
8902
  /** The browser's SDP offer, sent to the provider unchanged. */
8816
8903
  sdp_offer: sdpOffer,
8817
8904
  /**
8818
- * The client plays the RECORDING NOTICE — the disclosure's part that tells the caller the
8819
- * call is recorded — before the voice layer speaks, whenever the answer says `recorded`.
8820
- * A hub that records calls records only a call whose client says so: a client without the
8821
- * notice (one that predates it, or a stale tab) gets an unrecorded call, never a recorded
8822
- * call its caller was not told about. Absent: false.
8905
+ * The caller ACKNOWLEDGED THE RECORDING WARNING: before this create, their client showed
8906
+ * that the call will be recorded, and the caller chose to go on. A hub that records calls
8907
+ * records only a call whose create says so: a client that did not show the warning (one
8908
+ * that predates it, or one whose hub signal said the hub does not record) gets an
8909
+ * unrecorded call, never a recorded call its caller did not acknowledge. Absent: false.
8910
+ *
8911
+ * It replaces `plays_recording_notice` (the audio notice's flag), which no server reads any
8912
+ * more: a client that sends only that one gets an unrecorded call.
8823
8913
  */
8824
- plays_recording_notice: external_exports.boolean().optional()
8914
+ recording_warning_acknowledged: external_exports.boolean().optional()
8825
8915
  });
8826
8916
  createCallResponse = external_exports.object({
8827
8917
  call_id: external_exports.string().uuid(),
@@ -8830,10 +8920,10 @@ var init_contracts = __esm({
8830
8920
  /** The provider's SDP answer, for the browser's `setRemoteDescription`. */
8831
8921
  sdp_answer: sdpDescription,
8832
8922
  /**
8833
- * The call is recorded: its hub records calls and the create said its client plays the
8834
- * recording notice. The client plays the notice before it sends `ready`, and the recording
8835
- * starts only once `ready` arrives. Absent only from a server that predates recording, which
8836
- * records nothing: absent means not recorded.
8923
+ * The call is recorded: its hub records calls and the create said the caller acknowledged
8924
+ * the recording warning. The client shows that the call is recorded for as long as it
8925
+ * lasts, and the recording starts only once `ready` arrives. Absent only from a server that
8926
+ * predates recording, which records nothing: absent means not recorded.
8837
8927
  */
8838
8928
  recorded: external_exports.boolean().optional()
8839
8929
  });
@@ -8867,6 +8957,51 @@ var init_contracts = __esm({
8867
8957
  gaps: external_exports.array(callRecordingGap).max(MAX_CALL_RECORDING_GAPS)
8868
8958
  })
8869
8959
  });
8960
+ CALL_OPENING_LANGUAGES = ["en", "pt", "es"];
8961
+ callOpeningLanguage = external_exports.enum(CALL_OPENING_LANGUAGES);
8962
+ CALL_OPENING_MAX_DURATION_MS = 15e3;
8963
+ CALL_OPENING_MAX_BYTES = 1024 * 1024;
8964
+ CALL_OPENING_CAPTION_MAX_CHARS = 500;
8965
+ CALL_OPENING_CONTENT_TYPES = ["audio/mpeg", "audio/mp4"];
8966
+ callOpeningContentType = external_exports.enum(CALL_OPENING_CONTENT_TYPES);
8967
+ CALL_OPENING_HASH_REGEX = EVAL_ATTACHMENT_HASH_REGEX;
8968
+ callOpeningHash = external_exports.string().regex(CALL_OPENING_HASH_REGEX, "Expected a sha256 hex digest");
8969
+ callOpeningCaption = external_exports.string().trim().min(1).max(CALL_OPENING_CAPTION_MAX_CHARS);
8970
+ storedCallOpening = external_exports.object({
8971
+ hash: callOpeningHash,
8972
+ content_type: callOpeningContentType,
8973
+ duration_ms: external_exports.number().int().positive().max(CALL_OPENING_MAX_DURATION_MS),
8974
+ file_size: external_exports.number().int().positive().max(CALL_OPENING_MAX_BYTES),
8975
+ caption: callOpeningCaption
8976
+ });
8977
+ MAX_CALL_OPENING_ENCODED_BYTES = Math.ceil(CALL_OPENING_MAX_BYTES / 3) * 4 + 16;
8978
+ MAX_CALL_OPENING_BODY_BYTES = MAX_CALL_OPENING_ENCODED_BYTES + 16 * 1024;
8979
+ agentCallOpeningParams = external_exports.object({
8980
+ id: external_exports.string().uuid(),
8981
+ language: callOpeningLanguage
8982
+ });
8983
+ putAgentCallOpeningBody = external_exports.object({
8984
+ hub_id: external_exports.string().uuid(),
8985
+ caption: callOpeningCaption,
8986
+ /**
8987
+ * The audio, base64. Absent: the language's current audio stays and only the caption
8988
+ * changes, which needs an opening already set for the language.
8989
+ */
8990
+ file_data: external_exports.string().min(1).max(MAX_CALL_OPENING_ENCODED_BYTES).optional()
8991
+ });
8992
+ deleteAgentCallOpeningQuery = external_exports.object({
8993
+ hub_id: external_exports.string().uuid()
8994
+ });
8995
+ callOpeningParam = external_exports.object({ language: callOpeningLanguage });
8996
+ callOpeningQuery = external_exports.object({
8997
+ hub_id: external_exports.string().uuid(),
8998
+ /**
8999
+ * The opening the caller's app was told of (`HubCallOpening.version`, `callOpeningVersion`).
9000
+ * Any other answers 404 — the audio or the caption changed since — and the app plays the
9001
+ * platform's opening, so a caption never shows over audio it does not describe.
9002
+ */
9003
+ v: external_exports.string().regex(/^[a-f0-9]{64}\.[a-f0-9]{8}$/, "Expected a call opening version")
9004
+ });
8870
9005
  TTS_VOICE_REPLY_ENABLED_FIELD = {
8871
9006
  voice_reply_enabled: {
8872
9007
  type: "toggle",
@@ -9838,6 +9973,7 @@ var init_contracts = __esm({
9838
9973
  token_refresh_config: { api_key: { strategy: "none" } },
9839
9974
  connector_description: "Durable, shared cross-agent memory backed by a Rekor Base (S3-compatible). Harness agents mount it read-only or read-write; WayAI holds the credential and performs the signed I/O so it never enters the sandbox."
9840
9975
  };
9976
+ SPOKEN_LINE_MAX_CHARS = 300;
9841
9977
  gptLive = {
9842
9978
  connector_id: "01e7b19c-bc94-43f4-a780-ad5a22fb7127",
9843
9979
  service_name: "Openai",
@@ -9862,10 +9998,20 @@ var init_contracts = __esm({
9862
9998
  // The provider ends every session about 2 hours after it starts (`expires_at` is
9863
9999
  // start + 7,199 s), so 119 whole minutes is the most a call can last.
9864
10000
  max_call_minutes: { type: "number", label: "Maximum Call Length (minutes)", min: 1, max: 119, default: 10, description: "A call ends when it reaches this length." },
9865
- inactivity_timeout_seconds: { type: "number", label: "Inactivity Timeout (seconds)", min: 10, max: 600, default: 60, description: "A call ends after this many seconds in which neither side speaks." },
10001
+ inactivity_timeout_seconds: { type: "number", label: "Inactivity Timeout (seconds)", min: 10, max: 600, default: 60, description: "A call ends after this many seconds in which neither side speaks. A wait for the hub's agent to answer, up to the answer timeout, does not count." },
9866
10002
  delegation_timeout_seconds: { type: "number", label: "Answer Timeout (seconds)", min: 5, max: 120, default: 30, description: "How long the voice waits for the hub's agent to answer one question before it gives up on that answer." },
10003
+ // The fixed lines the voice says (`call-texts.ts`), each the builder's wording when set.
10004
+ // Read by the call route (`resolveVoiceCallSettings`), clipped to `maxLength` again there,
10005
+ // and used as written: placeholders are not filled.
10006
+ greeting_text: spokenLineField("Greeting", "What the voice says when the call starts, in the call's language. Empty uses WayAI's greeting, which names the hub."),
10007
+ progress_cues: { type: "toggle", label: "Progress Cues", default: true, description: `While the hub's agent works on an answer, the voice says a short "still checking" line about 5 and 10 seconds after the caller stops speaking. Off: the wait is silent unless the voice's instructions fill it; the answer timeout line still plays.` },
10008
+ first_progress_cue_text: spokenLineField("First Progress Cue", "What the voice says about 5 seconds into a wait for an answer. Empty uses WayAI's line in the call's language."),
10009
+ second_progress_cue_text: spokenLineField("Second Progress Cue", "What the voice says about 10 seconds into a wait for an answer. Empty uses WayAI's line in the call's language."),
10010
+ please_repeat_text: spokenLineField("Please Repeat Line", "What the voice says when it has no words for the caller's question and asks them to repeat it. Empty uses WayAI's line in the call's language."),
10011
+ turn_failed_text: spokenLineField("Couldn't Get That Line", "What the voice says when the hub's agent could not produce an answer. Empty uses WayAI's apology in the call's language."),
10012
+ timed_out_text: spokenLineField("Answer Timeout Line", "What the voice says when an answer is not back within the answer timeout. Empty uses WayAI's apology in the call's language."),
9867
10013
  // Opt-in (D7): off unless turned on. Read by the call route (`resolveVoiceCallSettings`).
9868
- record_calls: { type: "toggle", label: "Record Calls", default: false, description: "Keep each call's audio, both sides, as a recording your team can play from the conversation. Callers hear that the call is recorded before the voice speaks." }
10014
+ record_calls: { type: "toggle", label: "Record Calls", default: false, description: "Keep each call's audio, both sides, as a recording your team can play from the conversation. Before a call starts, the caller is warned that it will be recorded and chooses whether to go on." }
9869
10015
  },
9870
10016
  channel_settings_schema: null,
9871
10017
  tool_settings_schema: null,
@@ -9876,7 +10022,7 @@ var init_contracts = __esm({
9876
10022
  }
9877
10023
  },
9878
10024
  token_refresh_config: { api_key: { strategy: "none" } },
9879
- connector_description: "Live voice calls on OpenAI GPT-Live: a voice that talks with callers and asks your hub's agent for every answer. Requires an OpenAI project API key."
10025
+ connector_description: "Live voice calls on OpenAI GPT-Live: a voice that talks with callers and asks your hub's agent for answers. Requires an OpenAI project API key."
9880
10026
  };
9881
10027
  CONNECTORS = [
9882
10028
  anthropic,
@@ -9912,6 +10058,10 @@ var init_contracts = __esm({
9912
10058
  0,
9913
10059
  ...CONNECTORS.filter((connector) => connector.connector_type === "Realtime").map((connector) => Number(connector.agent_settings_schema?.max_call_minutes?.max) || 0)
9914
10060
  );
10061
+ EVAL_CALL_SPOKEN_LINE_MAX_CHARS = Math.max(
10062
+ 0,
10063
+ ...CONNECTORS.filter((connector) => connector.connector_type === "Realtime").flatMap((connector) => Object.values(connector.agent_settings_schema ?? {})).filter((field) => field.type === "text").map((field) => Number(field.maxLength) || 0)
10064
+ );
9915
10065
  hubScoped2 = { hub_id: external_exports.string().uuid() };
9916
10066
  createEvalCallBody = external_exports.object({
9917
10067
  ...hubScoped2,
@@ -9940,7 +10090,15 @@ var init_contracts = __esm({
9940
10090
  * (`platform_config` `voice_call_minute_ops`); null when it could not be read. With one
9941
10091
  * operation per call turn, it is what a runner counts a live call's WayAI operations by.
9942
10092
  */
9943
- minute_price_ops: external_exports.number().int().nonnegative().nullable()
10093
+ minute_price_ops: external_exports.number().int().nonnegative().nullable(),
10094
+ /**
10095
+ * What the runner plans its waits by, as the call started with them: whether the voice fills
10096
+ * the wait for an answer with progress cues (its agent's `progress_cues`), and how long it
10097
+ * waits for one before its timeout line (`delegation_timeout_seconds`). With the cues off
10098
+ * the wait is silent, so a pause is no sign that the answer has been said.
10099
+ */
10100
+ progress_cues: external_exports.boolean(),
10101
+ delegation_timeout_seconds: external_exports.number().int().positive()
9944
10102
  });
9945
10103
  evalCallConversationQuery = external_exports.object({
9946
10104
  ...hubScoped2,
@@ -10627,6 +10785,8 @@ var init_contracts = __esm({
10627
10785
  MAX_HUB_AS_CODE_RESOURCE_FILES = 5e3;
10628
10786
  MAX_RESOURCE_AGGREGATE_ENCODED_BYTES = 32 * 1024 * 1024;
10629
10787
  MAX_CI_CONFIG_BODY_BYTES = 64 * 1024 * 1024;
10788
+ MAX_CALL_OPENING_CARRIERS = 30;
10789
+ MAX_CALL_OPENING_AGGREGATE_ENCODED_BYTES = 8 * 1024 * 1024;
10630
10790
  hubAsCodeStateSchema = external_exports.object({
10631
10791
  id: external_exports.string().min(1).optional(),
10632
10792
  slug: external_exports.string().optional(),
@@ -10705,6 +10865,7 @@ var init_contracts = __esm({
10705
10865
  refineHubAsCodeLanes(config, ctx);
10706
10866
  refineHubAsCodeEvals(config, ctx);
10707
10867
  refineHubAsCodeEvalAttachments(config, ctx);
10868
+ refineHubAsCodeCallOpenings(config, ctx);
10708
10869
  refineHubAsCodeResources(config, ctx);
10709
10870
  refineHubAsCodeDelegation(config, ctx);
10710
10871
  refineHubAsCodeFlagConditions(config, ctx);
@@ -11814,10 +11975,10 @@ function toDataProxyPath(v1Path) {
11814
11975
  }
11815
11976
  return `${DATA_PROXY_PREFIX}${v1Path.slice(REKOR_V1_PREFIX.length)}`;
11816
11977
  }
11817
- function withOrgSelector(path35, orgId) {
11818
- if (!orgId) return path35;
11819
- const separator = path35.includes("?") ? "&" : "?";
11820
- return `${path35}${separator}${DATA_PROXY_ORG_QUERY_PARAM}=${encodeURIComponent(orgId)}`;
11978
+ function withOrgSelector(path36, orgId) {
11979
+ if (!orgId) return path36;
11980
+ const separator = path36.includes("?") ? "&" : "?";
11981
+ return `${path36}${separator}${DATA_PROXY_ORG_QUERY_PARAM}=${encodeURIComponent(orgId)}`;
11821
11982
  }
11822
11983
  function dataErrorMessage(err) {
11823
11984
  if (!(err instanceof ApiError)) return null;
@@ -11841,7 +12002,7 @@ var init_api_client = __esm({
11841
12002
  init_sentry();
11842
12003
  init_mask_secrets();
11843
12004
  RETRYABLE_BACKOFF_MS = [500, 1e3, 2e3];
11844
- delay = (ms) => new Promise((resolve10) => setTimeout(resolve10, ms));
12005
+ delay = (ms) => new Promise((resolve11) => setTimeout(resolve11, ms));
11845
12006
  ApiError = class extends Error {
11846
12007
  status;
11847
12008
  body;
@@ -11851,13 +12012,13 @@ var init_api_client = __esm({
11851
12012
  * telling them apart by body shape misreads one for the other.
11852
12013
  */
11853
12014
  path;
11854
- constructor(method, path35, status, body) {
12015
+ constructor(method, path36, status, body) {
11855
12016
  const safeBody = maskSecretsInMessage(body);
11856
- super(`API request failed: ${method} ${path35} (${status}): ${safeBody}`);
12017
+ super(`API request failed: ${method} ${path36} (${status}): ${safeBody}`);
11857
12018
  this.name = "ApiError";
11858
12019
  this.status = status;
11859
12020
  this.body = safeBody;
11860
- this.path = path35;
12021
+ this.path = path36;
11861
12022
  }
11862
12023
  /** True when the status code is a 4xx client error (expected user-facing condition, not a bug). */
11863
12024
  get isExpected() {
@@ -11961,8 +12122,8 @@ var init_api_client = __esm({
11961
12122
  ...opts?.check && { check: true }
11962
12123
  });
11963
12124
  }
11964
- async lookup(path35, opts) {
11965
- const params = new URLSearchParams({ path: path35 });
12125
+ async lookup(path36, opts) {
12126
+ const params = new URLSearchParams({ path: path36 });
11966
12127
  if (opts?.organizationId) params.set("organization_id", opts.organizationId);
11967
12128
  return this.request("GET", `/api/ci/lookup?${params.toString()}`);
11968
12129
  }
@@ -12440,9 +12601,9 @@ var init_api_client = __esm({
12440
12601
  * sandbox for this conversation, or the blob was purged).
12441
12602
  */
12442
12603
  async downloadArchiveSandboxFs(hubId, conversationId) {
12443
- const path35 = `/api/archive/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}/sandbox`;
12444
- addApiBreadcrumb("GET", path35);
12445
- const url = `${this.apiUrl}${path35}`;
12604
+ const path36 = `/api/archive/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}/sandbox`;
12605
+ addApiBreadcrumb("GET", path36);
12606
+ const url = `${this.apiUrl}${path36}`;
12446
12607
  let response = await this.send(url, "GET");
12447
12608
  if (response.status === 401 && this.onUnauthorized) {
12448
12609
  let refreshed;
@@ -12456,7 +12617,7 @@ var init_api_client = __esm({
12456
12617
  }
12457
12618
  }
12458
12619
  if (!response.ok) {
12459
- throw new ApiError("GET", path35, response.status, await response.text());
12620
+ throw new ApiError("GET", path36, response.status, await response.text());
12460
12621
  }
12461
12622
  return new Uint8Array(await response.arrayBuffer());
12462
12623
  }
@@ -12496,9 +12657,9 @@ var init_api_client = __esm({
12496
12657
  `/api/admin/data-explorer/debug/observability/${encodeURIComponent(hubId)}/conversations/${encodeURIComponent(conversationId)}${qs}`
12497
12658
  );
12498
12659
  }
12499
- async request(method, path35, body, extraHeaders, contentType) {
12500
- addApiBreadcrumb(method, path35);
12501
- const url = `${this.apiUrl}${path35}`;
12660
+ async request(method, path36, body, extraHeaders, contentType) {
12661
+ addApiBreadcrumb(method, path36);
12662
+ const url = `${this.apiUrl}${path36}`;
12502
12663
  let refreshedOn401 = false;
12503
12664
  for (let retry = 0; ; retry++) {
12504
12665
  let response = await this.send(url, method, body, extraHeaders, contentType);
@@ -12523,7 +12684,7 @@ var init_api_client = __esm({
12523
12684
  await delay(RETRYABLE_BACKOFF_MS[retry]);
12524
12685
  continue;
12525
12686
  }
12526
- throw new ApiError(method, path35, response.status, errorBody);
12687
+ throw new ApiError(method, path36, response.status, errorBody);
12527
12688
  }
12528
12689
  }
12529
12690
  /**
@@ -12585,9 +12746,9 @@ var init_api_client = __esm({
12585
12746
  * transient-retry loop — re-streaming a blob is not worth a cold-start probe.
12586
12747
  */
12587
12748
  async dataDownload(v1Path, orgId) {
12588
- const path35 = withOrgSelector(toDataProxyPath(v1Path), orgId);
12589
- addApiBreadcrumb("GET", path35);
12590
- const url = `${this.apiUrl}${path35}`;
12749
+ const path36 = withOrgSelector(toDataProxyPath(v1Path), orgId);
12750
+ addApiBreadcrumb("GET", path36);
12751
+ const url = `${this.apiUrl}${path36}`;
12591
12752
  let response = await this.send(url, "GET");
12592
12753
  if (response.status === 401 && this.onUnauthorized) {
12593
12754
  let refreshed;
@@ -12601,7 +12762,7 @@ var init_api_client = __esm({
12601
12762
  }
12602
12763
  }
12603
12764
  if (!response.ok) {
12604
- throw new ApiError("GET", path35, response.status, await response.text());
12765
+ throw new ApiError("GET", path36, response.status, await response.text());
12605
12766
  }
12606
12767
  return {
12607
12768
  bytes: new Uint8Array(await response.arrayBuffer()),
@@ -13051,9 +13212,9 @@ function monitorRuleActions2(monitorConfig) {
13051
13212
  if (!monitorConfig || typeof monitorConfig !== "object") return [];
13052
13213
  const config = monitorConfig;
13053
13214
  const found = [];
13054
- const visit = (action, path35) => {
13215
+ const visit = (action, path36) => {
13055
13216
  if (!action || typeof action !== "object" || Array.isArray(action)) return;
13056
- found.push({ action, path: path35 });
13217
+ found.push({ action, path: path36 });
13057
13218
  };
13058
13219
  if (Array.isArray(config.rules)) {
13059
13220
  config.rules.forEach((rule, index) => {
@@ -13070,25 +13231,25 @@ function collectMonitorRuleIssues2(monitorConfig) {
13070
13231
  const trigger = resolveMonitorTrigger2(monitorConfig);
13071
13232
  const kinds = monitorRuleActionKinds2(trigger);
13072
13233
  const issues = callUtteranceRuleIssues2(monitorConfig);
13073
- for (const { action, path: path35 } of monitorRuleActions2(monitorConfig)) {
13074
- if (trigger === "call_utterance" && path35[0] === "fallback") continue;
13234
+ for (const { action, path: path36 } of monitorRuleActions2(monitorConfig)) {
13235
+ if (trigger === "call_utterance" && path36[0] === "fallback") continue;
13075
13236
  const kind = action.kind;
13076
13237
  if (typeof kind === "string" && !kinds.includes(kind)) {
13077
- issues.push({ path: [...path35, "kind"], message: monitorActionKindMessage2(kind, trigger) });
13238
+ issues.push({ path: [...path36, "kind"], message: monitorActionKindMessage2(kind, trigger) });
13078
13239
  }
13079
13240
  const toolName = action.tool_name;
13080
13241
  if (kind === "call_tool" && typeof toolName === "string" && isRefusedNativeToolName2(toolName, trigger)) {
13081
- issues.push({ path: [...path35, "tool_name"], message: monitorRuleToolNotAllowedMessage2(toolName, trigger) });
13242
+ issues.push({ path: [...path36, "tool_name"], message: monitorRuleToolNotAllowedMessage2(toolName, trigger) });
13082
13243
  continue;
13083
13244
  }
13084
13245
  if (kind === "call_tool" && toolName === INSERT_NOTE_TOOL_NAME2) {
13085
- issues.push(...insertNoteArgumentIssues2(action, path35));
13246
+ issues.push(...insertNoteArgumentIssues2(action, path36));
13086
13247
  }
13087
13248
  if (kind === "call_tool" && toolName === RUN_MONITOR_TOOL_NAME2) {
13088
13249
  const callee = readRunMonitorCallee2(action);
13089
13250
  if (!callee.ok) {
13090
13251
  issues.push({
13091
- path: [...path35, "args", "monitor_name"],
13252
+ path: [...path36, "args", "monitor_name"],
13092
13253
  message: runMonitorCalleeMessage2(callee.reason)
13093
13254
  });
13094
13255
  }
@@ -13148,11 +13309,11 @@ function insertNoteTemplateMessage2(reason) {
13148
13309
  return `insert_note's template is longer than the ${MONITOR_NOTE_TEMPLATE_MAX2}-character limit.`;
13149
13310
  }
13150
13311
  }
13151
- function insertNoteArgumentIssues2(action, path35) {
13312
+ function insertNoteArgumentIssues2(action, path36) {
13152
13313
  const result = readInsertNoteTemplate2(action);
13153
13314
  if (result.ok) return [];
13154
13315
  return [{
13155
- path: [...path35, "args", "template"],
13316
+ path: [...path36, "args", "template"],
13156
13317
  message: insertNoteTemplateMessage2(result.reason)
13157
13318
  }];
13158
13319
  }
@@ -13182,12 +13343,12 @@ function validateFollowupLinks2(followups, label, ctx) {
13182
13343
  const linkTargets = /* @__PURE__ */ new Set();
13183
13344
  followups.forEach((followup, i) => {
13184
13345
  const ref = followup?.after_followup_id;
13185
- const path35 = ["followups", i, "after_followup_id"];
13346
+ const path36 = ["followups", i, "after_followup_id"];
13186
13347
  if (followup?.type !== "inactivity_after_before_event") {
13187
13348
  if (ref !== void 0) {
13188
13349
  ctx.addIssue({
13189
13350
  code: external_exports.ZodIssueCode.custom,
13190
- path: path35,
13351
+ path: path36,
13191
13352
  message: `kanban status ${label}: after_followup_id is only valid on inactivity_after_before_event followups (this one is ${followup?.type})`
13192
13353
  });
13193
13354
  }
@@ -13196,7 +13357,7 @@ function validateFollowupLinks2(followups, label, ctx) {
13196
13357
  if (ref === void 0) {
13197
13358
  ctx.addIssue({
13198
13359
  code: external_exports.ZodIssueCode.custom,
13199
- path: path35,
13360
+ path: path36,
13200
13361
  message: `kanban status ${label}: inactivity_after_before_event requires after_followup_id naming the id of a before_event followup in the same status`
13201
13362
  });
13202
13363
  return;
@@ -13206,7 +13367,7 @@ function validateFollowupLinks2(followups, label, ctx) {
13206
13367
  if (matches.length > 1) {
13207
13368
  ctx.addIssue({
13208
13369
  code: external_exports.ZodIssueCode.custom,
13209
- path: path35,
13370
+ path: path36,
13210
13371
  message: `kanban status ${label}: after_followup_id "${ref}" matches ${matches.length} followups \u2014 a link must name exactly one`
13211
13372
  });
13212
13373
  return;
@@ -13218,7 +13379,7 @@ function validateFollowupLinks2(followups, label, ctx) {
13218
13379
  );
13219
13380
  ctx.addIssue({
13220
13381
  code: external_exports.ZodIssueCode.custom,
13221
- path: path35,
13382
+ path: path36,
13222
13383
  message: hasIdlessBeforeEvent ? `kanban status ${label}: after_followup_id "${ref}" matches no followup \u2014 a link target must declare an explicit id, and this status has before_event followups without one` : `kanban status ${label}: after_followup_id "${ref}" matches no followup in this status`
13223
13384
  });
13224
13385
  return;
@@ -13226,7 +13387,7 @@ function validateFollowupLinks2(followups, label, ctx) {
13226
13387
  if (target.type !== "before_event") {
13227
13388
  ctx.addIssue({
13228
13389
  code: external_exports.ZodIssueCode.custom,
13229
- path: path35,
13390
+ path: path36,
13230
13391
  message: `kanban status ${label}: after_followup_id "${ref}" points at a ${target.type} followup \u2014 only before_event followups can anchor a chain`
13231
13392
  });
13232
13393
  }
@@ -13302,12 +13463,12 @@ function typeMatches2(typeField, allowed) {
13302
13463
  if (Array.isArray(typeField)) return typeField.every((t) => typeof t === "string" && allowed.has(t));
13303
13464
  return false;
13304
13465
  }
13305
- function validateSchema2(schema, path35, errors, opts = {}) {
13466
+ function validateSchema2(schema, path36, errors, opts = {}) {
13306
13467
  if (typeof schema === "boolean") return;
13307
13468
  const depth = opts.depth ?? 0;
13308
13469
  if (depth > MAX_SCHEMA_DEPTH2) {
13309
13470
  errors.push({
13310
- path: path35 || "<root>",
13471
+ path: path36 || "<root>",
13311
13472
  message: `schema nesting exceeds ${MAX_SCHEMA_DEPTH2} levels`,
13312
13473
  suggestion: "Flatten the schema; LLM providers reject deeply nested tool input_schemas."
13313
13474
  });
@@ -13315,7 +13476,7 @@ function validateSchema2(schema, path35, errors, opts = {}) {
13315
13476
  }
13316
13477
  if (!isRecord22(schema)) {
13317
13478
  errors.push({
13318
- path: path35,
13479
+ path: path36,
13319
13480
  message: `expected object, got ${schema === null ? "null" : typeof schema}`
13320
13481
  });
13321
13482
  return;
@@ -13323,14 +13484,14 @@ function validateSchema2(schema, path35, errors, opts = {}) {
13323
13484
  if (opts.isRoot) {
13324
13485
  if ("type" in schema && schema.type !== "object") {
13325
13486
  errors.push({
13326
- path: path35 ? `${path35}.type` : "type",
13487
+ path: path36 ? `${path36}.type` : "type",
13327
13488
  message: `root type must be 'object', got ${JSON.stringify(schema.type)}`,
13328
13489
  suggestion: "Tool parameters at the root must be an object: `{ type: 'object', properties: { ... } }`."
13329
13490
  });
13330
13491
  }
13331
13492
  } else if ("type" in schema && !typeMatches2(schema.type, ALLOWED_TYPES2)) {
13332
13493
  errors.push({
13333
- path: `${path35}.type`,
13494
+ path: `${path36}.type`,
13334
13495
  message: `type must be one of ${[...ALLOWED_TYPES2].join("/")} or an array of those, got ${JSON.stringify(schema.type)}`
13335
13496
  });
13336
13497
  }
@@ -13340,25 +13501,25 @@ function validateSchema2(schema, path35, errors, opts = {}) {
13340
13501
  const isPlaceholder = PLACEHOLDER_TOKENS2.includes(e);
13341
13502
  const isOutcomePlaceholder = e === "[KANBAN_OUTCOME_VALUES]";
13342
13503
  errors.push({
13343
- path: `${path35}.enum`,
13504
+ path: `${path36}.enum`,
13344
13505
  message: `enum must be a non-empty array of primitives, got string ${JSON.stringify(e)}`,
13345
13506
  suggestion: isOutcomePlaceholder ? "Declare `outcomes` on the hub's terminal kanban status so the platform can render the placeholder into a valid array; with none configured the platform drops the parameter instead." : isPlaceholder ? "Set `operation: 'update_kanban_status'` on the tool and ensure at least one hub.kanban_status has `allowsAgentUpdate: true` so the platform can render the placeholder into a valid array." : 'Wrap the value in an array: `enum: ["value"]`.'
13346
13507
  });
13347
13508
  } else if (!Array.isArray(e)) {
13348
13509
  errors.push({
13349
- path: `${path35}.enum`,
13510
+ path: `${path36}.enum`,
13350
13511
  message: `enum must be a non-empty array of primitives, got ${typeof e}`
13351
13512
  });
13352
13513
  } else if (e.length === 0) {
13353
13514
  errors.push({
13354
- path: `${path35}.enum`,
13515
+ path: `${path36}.enum`,
13355
13516
  message: "enum must not be empty"
13356
13517
  });
13357
13518
  } else {
13358
13519
  for (let i = 0; i < e.length; i++) {
13359
13520
  if (!isPrimitive2(e[i])) {
13360
13521
  errors.push({
13361
- path: `${path35}.enum[${i}]`,
13522
+ path: `${path36}.enum[${i}]`,
13362
13523
  message: `enum entry must be a primitive (string/number/boolean/null), got ${typeof e[i]}`
13363
13524
  });
13364
13525
  }
@@ -13368,7 +13529,7 @@ function validateSchema2(schema, path35, errors, opts = {}) {
13368
13529
  for (const key of ["exclusiveMinimum", "exclusiveMaximum"]) {
13369
13530
  if (key in schema && typeof schema[key] === "boolean") {
13370
13531
  errors.push({
13371
- path: `${path35}.${key}`,
13532
+ path: `${path36}.${key}`,
13372
13533
  message: `${key} as boolean is draft-04 syntax; draft 2020-12 requires a numeric value`,
13373
13534
  suggestion: `Replace with the numeric bound, e.g. \`${key}: 0\`.`
13374
13535
  });
@@ -13377,45 +13538,45 @@ function validateSchema2(schema, path35, errors, opts = {}) {
13377
13538
  if ("properties" in schema) {
13378
13539
  if (!isRecord22(schema.properties)) {
13379
13540
  errors.push({
13380
- path: `${path35}.properties`,
13541
+ path: `${path36}.properties`,
13381
13542
  message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
13382
13543
  });
13383
13544
  } else {
13384
13545
  for (const [propName, propSchema] of Object.entries(schema.properties)) {
13385
- validateSchema2(propSchema, `${path35}.properties.${propName}`, errors, { depth: depth + 1 });
13546
+ validateSchema2(propSchema, `${path36}.properties.${propName}`, errors, { depth: depth + 1 });
13386
13547
  }
13387
13548
  }
13388
13549
  }
13389
13550
  if (schemaTypeIncludes2(schema, "array") && "items" in schema) {
13390
13551
  if (Array.isArray(schema.items)) {
13391
- schema.items.forEach((sub, i) => validateSchema2(sub, `${path35}.items[${i}]`, errors, { depth: depth + 1 }));
13552
+ schema.items.forEach((sub, i) => validateSchema2(sub, `${path36}.items[${i}]`, errors, { depth: depth + 1 }));
13392
13553
  } else {
13393
- validateSchema2(schema.items, `${path35}.items`, errors, { depth: depth + 1 });
13554
+ validateSchema2(schema.items, `${path36}.items`, errors, { depth: depth + 1 });
13394
13555
  }
13395
13556
  }
13396
13557
  for (const key of SUBSCHEMA_OBJECT_KEYWORDS2) {
13397
13558
  if (key in schema && isRecord22(schema[key])) {
13398
- validateSchema2(schema[key], `${path35}.${key}`, errors, { depth: depth + 1 });
13559
+ validateSchema2(schema[key], `${path36}.${key}`, errors, { depth: depth + 1 });
13399
13560
  }
13400
13561
  }
13401
13562
  for (const key of SUBSCHEMA_LIST_KEYWORDS2) {
13402
13563
  const list = schema[key];
13403
13564
  if (Array.isArray(list)) {
13404
- list.forEach((sub, i) => validateSchema2(sub, `${path35}.${key}[${i}]`, errors, { depth: depth + 1 }));
13565
+ list.forEach((sub, i) => validateSchema2(sub, `${path36}.${key}[${i}]`, errors, { depth: depth + 1 }));
13405
13566
  }
13406
13567
  }
13407
13568
  for (const key of SUBSCHEMA_MAP_KEYWORDS2) {
13408
13569
  const map = schema[key];
13409
13570
  if (isRecord22(map)) {
13410
13571
  for (const [name, sub] of Object.entries(map)) {
13411
- validateSchema2(sub, `${path35}.${key}.${name}`, errors, { depth: depth + 1 });
13572
+ validateSchema2(sub, `${path36}.${key}.${name}`, errors, { depth: depth + 1 });
13412
13573
  }
13413
13574
  }
13414
13575
  }
13415
13576
  const reportedPaths = new Set(errors.map((e) => e.path));
13416
13577
  for (const [k, v] of Object.entries(schema)) {
13417
13578
  if (typeof v !== "string") continue;
13418
- const fieldPath = `${path35}.${k}`;
13579
+ const fieldPath = `${path36}.${k}`;
13419
13580
  if (reportedPaths.has(fieldPath)) continue;
13420
13581
  for (const token of PLACEHOLDER_TOKENS2) {
13421
13582
  if (v === token) {
@@ -13566,8 +13727,8 @@ function evalInitialStateError2(input) {
13566
13727
  const parsed = evalInitialStateEntry2.safeParse(entries[i]);
13567
13728
  if (!parsed.success) {
13568
13729
  const issue = parsed.error.issues[0];
13569
- const path35 = issue?.path.join(".") || "?";
13570
- return `initial_state[${i}].${path35} is invalid: ${issue?.message ?? "malformed"}`;
13730
+ const path36 = issue?.path.join(".") || "?";
13731
+ return `initial_state[${i}].${path36} is invalid: ${issue?.message ?? "malformed"}`;
13571
13732
  }
13572
13733
  if (seenSlugs.has(parsed.data.slug)) {
13573
13734
  return `initial_state[${i}].slug "${parsed.data.slug}" is declared more than once`;
@@ -13576,6 +13737,17 @@ function evalInitialStateError2(input) {
13576
13737
  }
13577
13738
  return null;
13578
13739
  }
13740
+ function evalNameError2(name) {
13741
+ if (name === void 0) return null;
13742
+ if (typeof name === "string" && name.trim().length > 0) return null;
13743
+ return "eval name must be a non-blank string";
13744
+ }
13745
+ function refineEvalName2(value, ctx) {
13746
+ const error = evalNameError2(value.eval.eval_name);
13747
+ if (error) {
13748
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["eval", "eval_name"], message: error });
13749
+ }
13750
+ }
13579
13751
  function refineEvalMessageTextRole2(value, ctx) {
13580
13752
  const error = evalInputRoleError2(value.eval.message_text);
13581
13753
  if (error) {
@@ -13628,6 +13800,9 @@ function collectTurnAttachmentHashes2(turn) {
13628
13800
  }
13629
13801
  return hashes;
13630
13802
  }
13803
+ function spokenLineField2(label, description) {
13804
+ return { type: "text", label, maxLength: SPOKEN_LINE_MAX_CHARS2, default: "", description };
13805
+ }
13631
13806
  function foldDiacritics(input) {
13632
13807
  return input.normalize("NFKD").replace(/[̀-ͯ]/g, "");
13633
13808
  }
@@ -13750,6 +13925,14 @@ function refineHubAsCodeEvals2(config, ctx) {
13750
13925
  if (!Array.isArray(evals)) return;
13751
13926
  for (let e = 0; e < evals.length; e++) {
13752
13927
  const entry = evals[e];
13928
+ const nameError = evalNameError2(entry?.name);
13929
+ if (nameError) {
13930
+ ctx.addIssue({
13931
+ code: external_exports.ZodIssueCode.custom,
13932
+ path: ["evals", e, "name"],
13933
+ message: `evals[${e}]: ${nameError}`
13934
+ });
13935
+ }
13753
13936
  const error = evalInputRoleError2(entry?.input);
13754
13937
  if (error) {
13755
13938
  ctx.addIssue({
@@ -13772,10 +13955,10 @@ function refineHubAsCodeEvals2(config, ctx) {
13772
13955
  function refineHubAsCodeEvalAttachments2(config, ctx) {
13773
13956
  const cfg = config;
13774
13957
  const referencedHashes = /* @__PURE__ */ new Set();
13775
- const addTurnIssue = (path35, turn, name) => {
13958
+ const addTurnIssue = (path36, turn, name) => {
13776
13959
  const error = evalTurnAttachmentsError2(turn);
13777
13960
  if (error) {
13778
- ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path35, message: `${name}: ${error}` });
13961
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path36, message: `${name}: ${error}` });
13779
13962
  return;
13780
13963
  }
13781
13964
  for (const hash of collectTurnAttachmentHashes2(turn)) referencedHashes.add(hash);
@@ -13843,6 +14026,72 @@ function refineHubAsCodeEvalAttachments2(config, ctx) {
13843
14026
  }
13844
14027
  }
13845
14028
  }
14029
+ function refineHubAsCodeCallOpenings2(config, ctx) {
14030
+ const cfg = config;
14031
+ if (Array.isArray(cfg.agents)) {
14032
+ cfg.agents.forEach((entry, a) => {
14033
+ const agent = entry;
14034
+ const openings = agent?.call_openings;
14035
+ if (openings === void 0 || openings === null) return;
14036
+ const path36 = ["agents", a, "call_openings"];
14037
+ const name = `agent "${typeof agent?.name === "string" ? agent.name : "<unnamed>"}"`;
14038
+ if (typeof openings !== "object" || Array.isArray(openings)) {
14039
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path36, message: `${name}: call_openings must map a language to an opening` });
14040
+ return;
14041
+ }
14042
+ if (agent?.role !== "pilot_voice" && Object.keys(openings).length > 0) {
14043
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: path36, message: `${name}: only a pilot_voice agent has call_openings` });
14044
+ }
14045
+ for (const [language, raw] of Object.entries(openings)) {
14046
+ const at = [...path36, language];
14047
+ if (!callOpeningLanguage2.safeParse(language).success) {
14048
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: at, message: `${name}: call_openings language must be one of ${CALL_OPENING_LANGUAGES2.join(", ")}` });
14049
+ continue;
14050
+ }
14051
+ const opening = raw;
14052
+ if (!callOpeningHash2.safeParse(opening?.hash).success) {
14053
+ ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: [...at, "hash"], message: `${name}: call_openings.${language} names no audio file` });
14054
+ }
14055
+ if (!callOpeningCaption2.safeParse(opening?.caption).success) {
14056
+ ctx.addIssue({
14057
+ code: external_exports.ZodIssueCode.custom,
14058
+ path: [...at, "caption"],
14059
+ message: `${name}: call_openings.${language}.caption must be 1\u2013${CALL_OPENING_CAPTION_MAX_CHARS2} characters`
14060
+ });
14061
+ }
14062
+ }
14063
+ });
14064
+ }
14065
+ const files = cfg.call_opening_files;
14066
+ if (!Array.isArray(files)) return;
14067
+ if (files.length > MAX_CALL_OPENING_CARRIERS2) {
14068
+ ctx.addIssue({
14069
+ code: external_exports.ZodIssueCode.custom,
14070
+ path: ["call_opening_files"],
14071
+ message: `too many call opening files (${files.length}); the maximum is ${MAX_CALL_OPENING_CARRIERS2}`
14072
+ });
14073
+ }
14074
+ let aggregateEncoded = 0;
14075
+ files.forEach((f, i) => {
14076
+ const b64 = f?.content_base64;
14077
+ if (typeof b64 !== "string") return;
14078
+ aggregateEncoded += b64.length;
14079
+ if (b64.length > MAX_CALL_OPENING_ENCODED_BYTES2) {
14080
+ ctx.addIssue({
14081
+ code: external_exports.ZodIssueCode.custom,
14082
+ path: ["call_opening_files", i, "content_base64"],
14083
+ message: "a call opening file exceeds the opening size limit"
14084
+ });
14085
+ }
14086
+ });
14087
+ if (aggregateEncoded > MAX_CALL_OPENING_AGGREGATE_ENCODED_BYTES2) {
14088
+ ctx.addIssue({
14089
+ code: external_exports.ZodIssueCode.custom,
14090
+ path: ["call_opening_files"],
14091
+ message: `total call opening bytes exceed the ${MAX_CALL_OPENING_AGGREGATE_ENCODED_BYTES2 / 1024 / 1024}MB per-push limit`
14092
+ });
14093
+ }
14094
+ }
13846
14095
  function utf8ByteLength2(value) {
13847
14096
  let bytes = 0;
13848
14097
  for (let i = 0; i < value.length; i++) {
@@ -13921,11 +14170,11 @@ function refineHubAsCodeDelegation2(config, ctx) {
13921
14170
  }
13922
14171
  }
13923
14172
  if (del.context_boundary === void 0) return;
13924
- const path35 = ["agents", agentIndex, "tools", "delegation", delIndex, "context_boundary"];
14173
+ const path36 = ["agents", agentIndex, "tools", "delegation", delIndex, "context_boundary"];
13925
14174
  if (del.type !== "hub") {
13926
14175
  ctx.addIssue({
13927
14176
  code: external_exports.ZodIssueCode.custom,
13928
- path: path35,
14177
+ path: path36,
13929
14178
  message: `context_boundary applies only to \`type: hub\` delegations (got type "${String(del.type)}")`
13930
14179
  });
13931
14180
  return;
@@ -13933,7 +14182,7 @@ function refineHubAsCodeDelegation2(config, ctx) {
13933
14182
  if (!CONTEXT_BOUNDARIES2.includes(del.context_boundary)) {
13934
14183
  ctx.addIssue({
13935
14184
  code: external_exports.ZodIssueCode.custom,
13936
- path: path35,
14185
+ path: path36,
13937
14186
  message: `context_boundary must be one of: ${CONTEXT_BOUNDARIES2.join(", ")}`
13938
14187
  });
13939
14188
  }
@@ -14131,7 +14380,7 @@ function findStepBoundaries(transcript) {
14131
14380
  }
14132
14381
  return out;
14133
14382
  }
14134
- var UUID_RE, HEX_RE, WORKOS_ID_RE, OPAQUE_SECRET_RE, BASE64_SECRET_RE, BASE64_MARKER_RE, TOKEN_RE, SENSITIVE_FIELDS, SENSITIVE_KEY_ALTERNATION, SENSITIVE_KEY_PATTERN, JSON_CREDENTIAL_RE, QUERY_CREDENTIAL_RE, REDACTED, PROVIDER_TOKEN_RE, APP_ERROR_BRAND, AppError, LLM_RATE_LIMIT_BRAND, LlmRateLimitError, LLM_PROVIDER_HTTP_BRAND, LlmProviderHttpError, LLM_PROVIDER_CONTENT_BRAND, LlmProviderContentError, LLM_PROVIDER_TIMEOUT_BRAND, LlmProviderTimeoutError, ExternalServiceError, CHANNEL_PROVIDER_HTTP_BRAND, ChannelProviderHttpError, MEDIA_PROVIDER_HTTP_BRAND, MediaProviderHttpError, REKOR_ACTOR_TYPE_HEADER2, REKOR_ACTOR_ID_HEADER2, REKOR_ACTOR_LABEL_HEADER2, REKOR_ACTOR_ORG_HEADER2, REKOR_ACTOR_ADMIN_HEADER2, REKOR_CLIENT_HEADER2, REKOR_TOOL_ID_HEADER2, REKOR_CLIENTS2, rekorClientSchema2, MAX_REKOR_TOOL_ID_LENGTH2, rekorToolIdSchema2, DATA_PROXY_MOUNT2, DATA_PROXY_PREFIX2, DATA_PROXY_ORG_QUERY_PARAM2, MAX_PROVISIONING_BODY_BYTES2, dataProxyQuery2, rekorAttestation2, REQUIRED_REKOR_ATTESTATION_HEADERS2, BASE_DESTRUCTION_MOUNT2, BASE_DESTRUCTION_PREFIX2, BASE_DESTRUCTION_CONFIRM_PATH2, baseDestructionConfirmBody2, BASE_DESTRUCTION_GRACE_MS2, BASE_DESTRUCTION_CONFIRM_TTL_MS2, BASE_DESTRUCTION_ORG_QUERY_PARAM2, baseDestructionQuery2, baseDestructionParam2, baseDestructionInitiateBody2, baseDestructionStatus2, baseDestructionRequest2, baseDestructionListResponse2, baseDestructionInitiateResponse2, baseDestructionConfirmResponse2, baseDestructionCancelResponse2, ENDPOINT_CONFIGS, AUTH_TYPE2, ORG_CREDENTIAL_AUTH_TYPES2, AUTH_TYPE_DISPLAY2, LEGACY_AUTH_TYPE_MAP2, VALID_AUTH_TYPES2, AGENT_ROLES2, SAFE_USER_ID_REGEX2, SUPPORTED_LOCALES2, uuidSchema2, paginationSchema3, timestampSchema2, idParamSchema2, clientOptionalString2, clientOptionalBoolean2, clientOptionalNumber2, messageAttachment2, MAX_MESSAGE_BODY_BYTES2, MAX_ATTACHMENTS_PER_MESSAGE2, MAX_AUDIO_FILE_BASE64_BYTES2, primaryRegionSchema2, placementSourceSchema2, orgIdParam2, orgAdminIdParam2, createOrganizationBody2, updateOrganizationBody2, addOrgAdminBody2, SUMMARIZATION_THRESHOLD_MIN2, SUMMARIZATION_THRESHOLD_MAX2, PREVIOUS_CONVERSATIONS_MAX2, FLAG_CONDITION_OPERATORS2, CONFIDENCE_VARIABLE_SUFFIX2, DECISION_SCORE_MIN_LEVELS2, DECISION_SCORE_MAX_LEVELS2, DECISIONS_MODEL_PREFIXES2, DECISION_CAPABLE_AGENT_ROLES2, NATIVE_TOOL_SCHEMAS2, WAYAI_CONNECTOR2, BASE_NATIVE_TOOLS2, NATIVE_TOOLS2, CATALOG_SIDE_EFFECTS2, NATIVE_TOOL_NAMES2, previousConversationsCountField2, summarizationThresholdField2, flagConditionSchema2, MONITOR_TRIGGERS2, monitorTriggerSchema2, MONITOR_FIRING_TRIGGERS2, MONITOR_DELAY_SECONDS_MIN2, MONITOR_IDLE_DELAY_REQUIRED_MESSAGE2, MONITOR_HISTORY_MESSAGES_MAX2, monitorHistoryMessagesSchema2, monitorIncludeToolResultsSchema2, MONITOR_INPUT_SHAPING_KEYS2, MONITOR_INPUT_SHAPING_SCHEMAS2, MONITOR_INPUT_SHAPING_IDLE_MESSAGE2, monitorArgumentSourceSchema2, MONITOR_NOTE_TEMPLATE_MAX2, MONITOR_STEER_NOTE_MAX2, monitorActionSchema2, monitorRuleSchema2, MONITOR_RULE_KEYS2, MONITOR_RULE_SCHEMAS2, MONITOR_RULE_TRIGGERS2, MONITOR_RULE_TRIGGER_MESSAGE2, CALL_UTTERANCE_SPEAKERS2, callUtteranceSpeakerSchema2, MONITOR_CALL_KEYS2, MONITOR_CALL_SCHEMAS2, MONITOR_CALL_KEY_MESSAGE2, CALL_STEERING_MIN_CONFIDENCE2, CALL_UTTERANCE_RULE_NOT_CONFIDENT_MESSAGE2, CALL_UTTERANCE_FALLBACK_MESSAGE2, CALL_UTTERANCE_FLAG_CONDITIONS_MESSAGE2, CALL_STEER_NOTE_BLANK_MESSAGE2, MONITOR_USER_MESSAGE_ACTION_KINDS2, MONITOR_ASSISTANT_REPLY_ACTION_KINDS2, MONITOR_CALL_UTTERANCE_ACTION_KINDS2, INSERT_NOTE_TOOL_NAME2, RUN_MONITOR_TOOL_NAME2, MONITOR_RULE_ALLOWED_NATIVE_TOOLS2, MONITOR_RULE_REENTRY_TOOLS2, MONITOR_RULE_REENTRY_TRACKS2, monitorConfigField2, flagConditionsField2, agentIdParam2, listAgentsQuery2, agentConnectionsQuery2, createAgentBody2, updateAgentBody2, AGENT_PARAMETER_TYPES2, AGENT_PARAMETER_NAME_REGEX2, agentParameterCreateSchema2, MAX_AGENT_PARAMETERS_PER_REQUEST2, createAgentParametersBody2, SLUG_REGEX2, slugSchema2, INVISIBLE_NAME_CHARS2, MAX_KANBAN_STATUSES2, MAX_FOLLOWUPS_PER_STATUS2, MAX_LANES2, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES2, RESERVED_TEMPLATE_DUMP_NAME2, kanbanStatusSlugSchema2, followupTypeSchema2, EVENT_RELATIVE_FOLLOWUP_TYPES2, followupTimeUnitSchema2, followupIdSchema2, SELECTABLE_FOLLOWUP_TYPES2, MAX_LINKED_FOLLOWUP_TARGETS_PER_STATUS2, followupSchema2, MAX_OUTCOMES_PER_STATUS2, kanbanOutcomeSchema2, EXCLUSIVE_FLAG_PAIRS2, kanbanStatusSchema2, kanbanStatusesArraySchema2, laneSchema2, lanesArraySchema2, hubIdParam2, hubAdminIdParam2, hubUserIdParam2, hubIdentityIdParam2, hubTeamIdParam2, hubTeamUserDeleteParam2, hubSchemaQuery2, PREVIEW_LABEL_MAX_LENGTH2, MAX_ENDED_INDEX_RETENTION_DAYS2, MAX_EVAL_RETENTION_DAYS2, previewLabelField2, createHubBody2, updateHubBody2, addHubAdminBody2, addHubIdentityAuthorizationBody2, contactDecisionBody2, approveContactBody2, listContactAccessQuery2, createHubTeamBody2, updateHubTeamBody2, addHubTeamUserBody2, reassignHubUserBody2, replicatePreviewBody2, updateChannelTestIdentitiesBody2, claimCodeChannelParam2, claimCodeDeleteParam2, connectionIdParam2, connectorIdParam2, listConnectionsQuery2, deleteConnectionQuery2, addConnectionBody2, editConnectionBody2, PRODUCTION_DIRECT_FIELDS2, setProductionCredentialBody2, registerWhatsappQuery2, registerWhatsappBody2, retryProvisioningQuery2, resendDomainStatusQuery2, PLACEHOLDER_TOKENS2, ALLOWED_TYPES2, SUBSCHEMA_OBJECT_KEYWORDS2, SUBSCHEMA_LIST_KEYWORDS2, SUBSCHEMA_MAP_KEYWORDS2, MAX_SCHEMA_DEPTH2, toolIdParam2, listToolsQuery2, toolAgentQuery2, deleteToolQuery2, toolConnectionsQuery2, nativeToolIdSchema2, CONTEXT_BOUNDARIES2, contextBoundarySchema2, addNativeToolBody2, addMcpToolBody2, createCustomToolBody2, updateCustomToolBody2, updateToolExecutionConfigBody2, initialValueCreateSchema2, initialValueUpdateSchema2, stateIdParam2, listStatesQuery2, stateNameSchema2, createStateBody2, updateStateBody2, reorderStatesBody2, variantAiModeSchema2, experimentStatusSchema2, overlayUpdateSchema2, experimentIdParam2, variantIdParam2, listExperimentsQuery2, listVariantsQuery2, listOverridesQuery2, deleteOverrideQuery2, createExperimentBody2, updateExperimentBody2, setExperimentStatusBody2, createVariantBody2, updateVariantBody2, upsertOverrideBody2, orgTagIdParam2, listOrgTagsQuery2, ORG_TAG_NAME_REGEX2, ORG_TAG_NAME_MAX_LENGTH2, createOrgTagBody2, updateOrgTagBody2, orgCredentialIdParam2, listOrgCredentialsQuery2, createOrgCredentialBody2, updateOrgCredentialBody2, BASE_CREDENTIAL_NAME_MAX2, baseCredentialNameSchema2, createBaseCredentialLinkBody2, baseCredentialLinkParams2, baseCredentialLinkQuery2, orgResourceIdParam2, orgResourceFileIdParam2, orgResourceFolderIdParam2, hubOrgResourceParam2, listOrgResourcesQuery2, orgIdQuery2, createOrgResourceBody2, updateOrgResourceBody2, createOrgResourceFolderBody2, updateOrgResourceFolderBody2, uploadOrgResourceFileBody2, updateOrgResourceFileBody2, uploadOrgSkillZipBody2, linkOrgResourceBody2, resourceIdParam2, listResourcesQuery2, createResourceBody2, updateResourceBody2, syncSkillsBody2, resourceFileIdParam2, listResourceFilesQuery2, createResourceFileBody2, updateResourceFileBody2, uploadResourceFileBody2, uploadSkillZipBody2, resourceFolderIdParam2, listResourceFoldersQuery2, createResourceFolderBody2, updateResourceFolderBody2, agentResourceQuery2, hubResourceQuery2, linkAgentResourceBody2, updateAgentResourceBody2, unlinkAgentResourceQuery2, navItemSchema2, hubCountResetBody2, navItemCountResetBody2, typingBody2, analyticsHubIdParam2, analyticsVariableIdParam2, updateVariablePinBody2, updateAnalyticsViewBody2, NUMERIC_FILTER_OPS2, TEXT_FILTER_OPS2, CATEGORICAL_FILTER_OPS2, VARIABLE_FILTER_OPS2, STRUCTURED_QUERY_OPS2, STRUCTURED_QUERY_AGGREGATIONS2, filterValueSchema2, conversationsBody2, analyticsConversationIdParam2, messagesQuery2, conversationDetailDataQuery2, analyticsDataBody2, structuredQueryBody2, analyticsSqlBody2, analyticsSqlTable2, analyticsSqlSchemaQuery2, EVAL_PACING_PRESET_NAMES2, PACING_INTERVAL_MIN_MS2, PACING_INTERVAL_MAX_MS2, EVAL_MAX_RUNS_PER_SCENARIO2, EVAL_RUN_DEADLINE_MIN_MS2, EVAL_RUN_DEADLINE_MAX_MS2, ISO_UTC_RE2, paginationSchema22, evalIdParam2, sessionIdParam2, scenarioSetIdParam2, hubIdQuery2, evalDateContextSchema2, EVAL_FIXTURE_NAME_MAX_LENGTH2, evalFixtureOverrideSchema2, runSessionQuery2, runJourneyQuery2, EVAL_INPUT_ROLES2, EVAL_INPUT_ROLE_LIST2, ROLE_ECHO_MAX2, EVAL_INITIAL_STATE_SCOPES2, MAX_INITIAL_STATE_ENTRIES2, evalInitialStateEntry2, createEvalBody2, updateEvalBody2, EVAL_LIST_MAX_LIMIT2, evalListLimit2, getEvalsQuery2, toggleEvalBody2, bulkToggleEvalsBody2, pacingConfigSchema2, EVAL_MAX_SELECTED_SCENARIOS2, evalScenarioSelectionEntrySchema2, evalScenarioSelectionSchema2, sessionConfigSchema2, createSessionBody2, getSessionsQuery2, getSessionResultsQuery2, getSessionRunsQuery2, evalAnalyticsQuery2, getSessionCostQuery2, compareSessionsQuery2, evalsSqlBody2, evalsSqlSchemaQuery2, exportResultsQuery2, validateEvalBody2, hubAgentsQuery2, createScenarioSetBody2, updateScenarioSetBody2, scenarioSetsHubQuery2, createScenarioFromConversationBody2, createJourneyFromConversationBody2, EVAL_ATTACHMENT_HASH_REGEX2, evalAttachmentRef2, turnMayCarryAttachments2, ATTACHMENTS_USER_ONLY_MESSAGE2, journeyIdParam2, journeyToolCallSchema2, journeyTurnSchema2, journeyStepOverrideSchema2, fixtureField2, createJourneyBody2, updateJourneyBody2, evalSessionConfigResponseSchema2, evalSessionResponseSchema2, evalSessionListConfigSchema2, evalSessionListItemSchema2, seedReleaseStatusSchema2, getConversationsQuery2, getMessagesQuery2, appMessageSenderType2, appMessageReceiverType2, apiChannelMessage2, apiChannelMessageBody2, appMessageBody2, appMessageResponse2, CALL_STATUSES2, callStatus2, CALL_END_REASONS2, callEndReason2, CALL_TRANSPORTS2, callTransport2, CALL_PARTICIPANT_TYPES2, callParticipantType2, callInstant2, MAX_SDP_OFFER_LENGTH2, sdpDescription2, sdpOffer2, MAX_CALL_REQUEST_BODY_BYTES2, hubScoped3, callSummaryFields2, callSummary2, callIdParam2, createCallBody2, createCallResponse2, callReadyBody2, callHangupBody2, callStatusQuery2, MAX_REPORTED_DELEGATION_IDS2, callDelegationId2, callDelegationsBody2, callResponse2, MAX_CALL_RECORDING_GAPS2, callRecordingGap2, callRecordingNoteMetadata2, TTS_VOICE_REPLY_ENABLED_FIELD2, COPILOT_TRIGGER_FIELD2, AUDIO_LANGUAGE_OPTIONS2, whatsapp2, instagram2, resend2, telegram2, API_CHANNEL_DELIVERY_EVENTS2, apiChannel2, OPENAI_REASONING_MODELS2, openai2, anthropic2, googleAiStudio2, openRouter2, xai2, groqStt2, openaiStt2, elevenLabsStt2, openaiTts2, groqTts2, elevenLabsTts2, GEMINI_TTS_VOICES2, googleTts2, wayai2, externalResources2, restApiTool2, mcpServer2, e2b2, CLAUDE_HARNESS_MODELS2, CLAUDE_HARNESS_MODEL_OPTIONS2, HARNESS_MCP_SERVERS_FIELD2, HARNESS_EGRESS_FIELDS2, claudeAgentSdk2, claudeManagedAgents2, rekorMemory2, gptLive2, CONNECTORS2, evalCallInstant2, EVAL_CALL_MIN_SECONDS2, EVAL_CALL_MAX_SECONDS2, hubScoped22, createEvalCallBody2, createEvalCallResponse2, evalCallConversationQuery2, evalCallSpeaker2, evalCallUtterance2, evalCallTurn2, evalCallRecordResponse2, evalCallFinishResponse2, updateUserBody2, updateProfileBody2, pathnameRegex2, updatePreferencesBody2, registerPushTokenBody2, deletePushTokenQuery2, activityQuery2, deletionModeSchema2, deletionRequestBody2, archiveHubIdParam2, archiveConversationParams2, archiveListQuery2, archiveMessageObservabilityParams2, conversationIdParam2, claimBody2, releaseBody2, transferBody2, closeBody2, additionalContextPayloadSchema2, kanbanUpdateBody2, annotateConversationBody2, observabilityParams2, observabilityListParams2, deleteUserConversationsBody2, deleteUserConversationsResponse2, sendMessageBody2, listConversationsQuery2, flagSourceSchema2, getConversationsResponse2, getConversationDetailParams2, getConversationDetailQuery2, getConversationDetailResponse2, listWhatsAppTemplatesQuery2, sendWhatsAppTemplateBody2, copilotSuggestBody2, copilotSuggestResponse2, CONSULT_THREAD_STATUSES2, consultThreadStatus2, CONSULT_THREAD_TITLE_MAX2, consultThreadTitle2, consultThreadSummary2, listConsultThreadsQuery2, listConsultThreadsResponse2, createConsultThreadBody2, createConsultThreadResponse2, consultThreadIdParam2, updateConsultThreadBody2, updateConsultThreadResponse2, CONSULT_AWAIT_TIMEOUT_MS2, billingOrgIdParam2, subscriptionItemParams2, spendCapBody2, growthPacksBody2, portalSessionBody2, checkoutSessionBody2, updateBillingCurrencyBody2, invoicesQuery2, planKeySchema2, billingStatusSchema2, billingPlanTypeSchema2, dataUsageCountersSchema2, REKOR_ENTITLEMENT_CONTRACT_VERSION2, entitlementProjectionSchema2, rekorEntitlementRefreshMessageSchema2, downloadBody2, uploadQuery2, signUrlBody2, outboundSchemaQuery2, templateIdParam2, listTemplatesQuery2, deleteTemplateQuery2, templateStatusQuery2, createTemplateBody2, updateTemplateBody2, submitTemplateBody2, testTemplateBody2, contactIdParam2, listContactsQuery2, createContactBody2, updateContactBody2, listIdParam2, listListsQuery2, listListContactsQuery2, createListBody2, updateListBody2, addListContactsBody2, removeListContactsBody2, scheduleIdParam2, listSchedulesQuery2, listExecutionsQuery2, createScheduleBody2, updateScheduleBody2, MAX_RESOURCE_FILE_SIZE2, MAX_10MB_BASE64_ENCODED_BYTES2, MAX_EVAL_ATTACHMENT_ENCODED_BYTES2, MAX_EVAL_ATTACHMENT_CARRIERS2, MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES2, MAX_RESOURCE_ENCODED_BYTES2, MAX_HUB_AS_CODE_RESOURCES2, MAX_HUB_AS_CODE_RESOURCE_FILES2, MAX_RESOURCE_AGGREGATE_ENCODED_BYTES2, MAX_CI_CONFIG_BODY_BYTES2, hubAsCodeStateSchema2, hubAsCodeResourceFileSchema2, hubAsCodeResourceSchema2, uuidPattern2, ciUuidSchema2, boundedHubAsCodeResourcesSchema2, hubAsCodeConfigSchema2, ciPullHubIdParam2, ciBranchParam2, ciPullQuery2, ciHubsQuery2, ciLookupQuery2, ciBranchesQuery2, ciSyncBody2, ciPushBody2, ciDiffBody2, ciPublishBody2, ciPublishPreviewBody2, ciSyncMcpBody2, ciOrgResourcesParam2, orgResourcesConfigSchema2, ciOrgResourcesPushBody2, ciOrgResourcesDiffBody2, CI_APPLY_ENTITY_KINDS2, CI_APPLY_OPERATIONS2, ciApplyErrorBaseSchema2, ciApplyErrorSchema2, ciSyncCountSchema2, ciSyncChangesSchema2, ciSyncWarningSchema2, ciSyncResponseSchema2, adminOrgIdParam2, adminOrgAdminIdParam2, adminUserIdParam2, PRICING_PLAN_ID_RE2, adminPlanIdParam2, adminOrganizationsQuery2, adminUserSearchQuery2, kanbanSlugMigrationQuery2, adjustQuotaBody2, updatePlanBody2, addAdminUserBody2, MAX_VOICE_CALL_MINUTE_OPS2, voiceCallMinuteOps2, updatePlatformConfigBody2, updateFreeOrgLimitBody2, adminScopedTargetBody2, adminRepairLegacyOrgGrantsBody2, adminRepairCompedPlansBody2, updatePricingPlanBody2, dataExplorerSearchQuery2, dataExplorerOrgIdParam2, dataExplorerHubIdParam2, dataExplorerConvIdParam2, dataExplorerDoInstancesQuery2, dataExplorerNsIdParam2, dataExplorerKvKeysBody2, dataExplorerKvKeyBody2, uuidOrHexId2, dataExplorerDeleteOrgParam2, dataExplorerDeleteHubParam2, dataExplorerDeleteConvParam2, dataExplorerDeleteUserParam2, dataExplorerDeleteQuery2, dataExplorerKvDeleteBody2, pitrDoNamespace2, pitrBookmarkParam2, pitrRestoreBody2, healthSamplingTriggerBody2, dataExplorerDebugDoType2, DEBUG_READ_MAX_LIMIT2, DEBUG_READ_DEFAULT_LIMIT2, DEBUG_DO_HEX_PREFIX2, debugDoEntityId2, debugTableName2, dataExplorerDebugTablesParam2, dataExplorerDebugRowsParam2, dataExplorerDebugRowsQuery2, dataExplorerDebugAnalyticsTable2, debugUuid2, dataExplorerDebugAnalyticsRowsParam2, dataExplorerDebugAnalyticsRowsQuery2, debugHubConvParam2, debugMessageIdQuery2, sandboxEgressPolicy2, SANDBOX_EXEC_MAX_CMD_LENGTH2, SANDBOX_EXEC_MAX_ALLOWLIST2, SANDBOX_EXEC_MAX_TIMEOUT_MS2, adminSandboxExecBody2, META_ENTITY_ID_PATTERN2, metaEntityId2, whatsappCallbackBody2, authMeResponse2, wsTicketResponse2, sessionCheckResponse2, logoutResponse2, magicCodeSendBody2, magicCodeSendResponse2, magicCodeVerifyBody2, magicCodeVerifyResponse2, passwordLoginBody2, browserParams2, browserFoldersQuery2, browserFilesQuery2, stateOperationBody2, conversationListResourcesQuery2, conversationReadResourceQuery2, listPendingSchedulesQuery2, listHubAggregateSchedulesQuery2, reportSourceSchema2, intakeReportSourceSchema2, reportClassificationSchema2, reportStatusSchema2, reportLocaleSchema2, reportMessageAuthorRoleSchema2, reportMessageSchema2, sentryRefStatusSchema2, createReportBody2, editReportBody2, reporterReportSummarySchema2, reporterListResponseSchema2, getReportResponseSchema2, reporterTransitionResponseSchema2, contestReportBody2, reporterListQuery2, listReportsQuery2, GITHUB_ISSUE_URL_REGEX2, githubIssueUrlSchema2, transitionReportBody2, groupReportsBody2, holdReportBody2, clickhouseReadyResponse2, bootstrapQuery2, requestSnapshotChunkMessage2, MAX_NAME_LENGTH3, MAX_VALUE_LENGTH2, MAX_TAGS2, MAX_TAG_LENGTH2, MAX_SCOPE_HUBS2, MAX_SCOPE_TAGS2, vaultSecretScopeSchema2, vaultCreateBody2, vaultUpdateBody2, PERMISSIONS2, MAX_NAME_LENGTH22, MAX_HUBS_PER_GRANT2, MAX_HUB_TAGS_PER_GRANT2, MAX_GRANTS2, permissionEnum2, grantScopeSchema2, grantSchema2, createTokenBody2, tokenOrgIdParam2, tokenGrantScopeSchema2, tokenGrantSchema2, tokenMetadataSchema2, listTokensResponse2, createTokenResponse2, orgTokenSummarySchema2, listOrgTokensResponse2, invitePreviewQuery2, invitePreviewResponse2, jsonSchemaSchema2, hubUserIdentity2, stateValueEntry2, getHubUserContextResponse2, updateHubUserBody2, updateHubUserResponse2, unlockHubUserNameResponse2, stateResetParams2, stateResetResponse2, hubAlertsParam2, hubAlertSeverity2, hubAlert2, hubAlertsListResponse2, noticeSeveritySchema2, noticeStatusSchema2, NOTICE_SCOPE_REGEX2, noticeScopeSchema2, noticeLinkSchema2, createNoticeBody2, updateNoticeBody2, listNoticesQuery2, noticeIdParamSchema2, ADMIN_SKILL_NAME_REGEX2, adminSkillNameParam2, rekorBaseChangeMessageSchema2, WAYAI_WORKSPACE_LAYOUT, decisionAnswerSchema, decisionsResponseSchema;
14383
+ var UUID_RE, HEX_RE, WORKOS_ID_RE, OPAQUE_SECRET_RE, BASE64_SECRET_RE, BASE64_MARKER_RE, TOKEN_RE, SENSITIVE_FIELDS, SENSITIVE_KEY_ALTERNATION, SENSITIVE_KEY_PATTERN, JSON_CREDENTIAL_RE, QUERY_CREDENTIAL_RE, REDACTED, PROVIDER_TOKEN_RE, APP_ERROR_BRAND, AppError, LLM_RATE_LIMIT_BRAND, LlmRateLimitError, LLM_PROVIDER_HTTP_BRAND, LlmProviderHttpError, LLM_PROVIDER_CONTENT_BRAND, LlmProviderContentError, LLM_PROVIDER_TIMEOUT_BRAND, LlmProviderTimeoutError, ExternalServiceError, CHANNEL_PROVIDER_HTTP_BRAND, ChannelProviderHttpError, MEDIA_PROVIDER_HTTP_BRAND, MediaProviderHttpError, REKOR_ACTOR_TYPE_HEADER2, REKOR_ACTOR_ID_HEADER2, REKOR_ACTOR_LABEL_HEADER2, REKOR_ACTOR_ORG_HEADER2, REKOR_ACTOR_ADMIN_HEADER2, REKOR_CLIENT_HEADER2, REKOR_TOOL_ID_HEADER2, REKOR_CLIENTS2, rekorClientSchema2, MAX_REKOR_TOOL_ID_LENGTH2, rekorToolIdSchema2, DATA_PROXY_MOUNT2, DATA_PROXY_PREFIX2, DATA_PROXY_ORG_QUERY_PARAM2, MAX_PROVISIONING_BODY_BYTES2, dataProxyQuery2, rekorAttestation2, REQUIRED_REKOR_ATTESTATION_HEADERS2, BASE_DESTRUCTION_MOUNT2, BASE_DESTRUCTION_PREFIX2, BASE_DESTRUCTION_CONFIRM_PATH2, baseDestructionConfirmBody2, BASE_DESTRUCTION_GRACE_MS2, BASE_DESTRUCTION_CONFIRM_TTL_MS2, BASE_DESTRUCTION_ORG_QUERY_PARAM2, baseDestructionQuery2, baseDestructionParam2, baseDestructionInitiateBody2, baseDestructionStatus2, baseDestructionRequest2, baseDestructionListResponse2, baseDestructionInitiateResponse2, baseDestructionConfirmResponse2, baseDestructionCancelResponse2, ENDPOINT_CONFIGS, AUTH_TYPE2, ORG_CREDENTIAL_AUTH_TYPES2, AUTH_TYPE_DISPLAY2, LEGACY_AUTH_TYPE_MAP2, VALID_AUTH_TYPES2, AGENT_ROLES2, SAFE_USER_ID_REGEX2, SUPPORTED_LOCALES2, uuidSchema2, paginationSchema3, timestampSchema2, idParamSchema2, clientOptionalString2, clientOptionalBoolean2, clientOptionalNumber2, messageAttachment2, MAX_MESSAGE_BODY_BYTES2, MAX_ATTACHMENTS_PER_MESSAGE2, MAX_AUDIO_FILE_BASE64_BYTES2, primaryRegionSchema2, placementSourceSchema2, orgIdParam2, orgAdminIdParam2, createOrganizationBody2, updateOrganizationBody2, addOrgAdminBody2, SUMMARIZATION_THRESHOLD_MIN2, SUMMARIZATION_THRESHOLD_MAX2, PREVIOUS_CONVERSATIONS_MAX2, FLAG_CONDITION_OPERATORS2, CONFIDENCE_VARIABLE_SUFFIX2, DECISION_SCORE_MIN_LEVELS2, DECISION_SCORE_MAX_LEVELS2, DECISIONS_MODEL_PREFIXES2, DECISION_CAPABLE_AGENT_ROLES2, NATIVE_TOOL_SCHEMAS2, WAYAI_CONNECTOR2, BASE_NATIVE_TOOLS2, NATIVE_TOOLS2, CATALOG_SIDE_EFFECTS2, NATIVE_TOOL_NAMES2, previousConversationsCountField2, summarizationThresholdField2, flagConditionSchema2, MONITOR_TRIGGERS2, monitorTriggerSchema2, MONITOR_FIRING_TRIGGERS2, MONITOR_DELAY_SECONDS_MIN2, MONITOR_IDLE_DELAY_REQUIRED_MESSAGE2, MONITOR_HISTORY_MESSAGES_MAX2, monitorHistoryMessagesSchema2, monitorIncludeToolResultsSchema2, MONITOR_INPUT_SHAPING_KEYS2, MONITOR_INPUT_SHAPING_SCHEMAS2, MONITOR_INPUT_SHAPING_IDLE_MESSAGE2, monitorArgumentSourceSchema2, MONITOR_NOTE_TEMPLATE_MAX2, MONITOR_STEER_NOTE_MAX2, monitorActionSchema2, monitorRuleSchema2, MONITOR_RULE_KEYS2, MONITOR_RULE_SCHEMAS2, MONITOR_RULE_TRIGGERS2, MONITOR_RULE_TRIGGER_MESSAGE2, CALL_UTTERANCE_SPEAKERS2, callUtteranceSpeakerSchema2, MONITOR_CALL_KEYS2, MONITOR_CALL_SCHEMAS2, MONITOR_CALL_KEY_MESSAGE2, CALL_STEERING_MIN_CONFIDENCE2, CALL_UTTERANCE_RULE_NOT_CONFIDENT_MESSAGE2, CALL_UTTERANCE_FALLBACK_MESSAGE2, CALL_UTTERANCE_FLAG_CONDITIONS_MESSAGE2, CALL_STEER_NOTE_BLANK_MESSAGE2, MONITOR_USER_MESSAGE_ACTION_KINDS2, MONITOR_ASSISTANT_REPLY_ACTION_KINDS2, MONITOR_CALL_UTTERANCE_ACTION_KINDS2, INSERT_NOTE_TOOL_NAME2, RUN_MONITOR_TOOL_NAME2, MONITOR_RULE_ALLOWED_NATIVE_TOOLS2, MONITOR_RULE_REENTRY_TOOLS2, MONITOR_RULE_REENTRY_TRACKS2, monitorConfigField2, flagConditionsField2, agentIdParam2, listAgentsQuery2, agentConnectionsQuery2, createAgentBody2, updateAgentBody2, AGENT_PARAMETER_TYPES2, AGENT_PARAMETER_NAME_REGEX2, agentParameterCreateSchema2, MAX_AGENT_PARAMETERS_PER_REQUEST2, createAgentParametersBody2, SLUG_REGEX2, slugSchema2, INVISIBLE_NAME_CHARS2, MAX_KANBAN_STATUSES2, MAX_FOLLOWUPS_PER_STATUS2, MAX_LANES2, MAX_ADDITIONAL_CONTEXT_SCHEMA_BYTES2, RESERVED_TEMPLATE_DUMP_NAME2, kanbanStatusSlugSchema2, followupTypeSchema2, EVENT_RELATIVE_FOLLOWUP_TYPES2, followupTimeUnitSchema2, followupIdSchema2, SELECTABLE_FOLLOWUP_TYPES2, MAX_LINKED_FOLLOWUP_TARGETS_PER_STATUS2, followupSchema2, MAX_OUTCOMES_PER_STATUS2, kanbanOutcomeSchema2, EXCLUSIVE_FLAG_PAIRS2, kanbanStatusSchema2, kanbanStatusesArraySchema2, laneSchema2, lanesArraySchema2, hubIdParam2, hubAdminIdParam2, hubUserIdParam2, hubIdentityIdParam2, hubTeamIdParam2, hubTeamUserDeleteParam2, hubSchemaQuery2, PREVIEW_LABEL_MAX_LENGTH2, MAX_ENDED_INDEX_RETENTION_DAYS2, MAX_EVAL_RETENTION_DAYS2, previewLabelField2, createHubBody2, updateHubBody2, addHubAdminBody2, addHubIdentityAuthorizationBody2, contactDecisionBody2, approveContactBody2, listContactAccessQuery2, createHubTeamBody2, updateHubTeamBody2, addHubTeamUserBody2, reassignHubUserBody2, replicatePreviewBody2, updateChannelTestIdentitiesBody2, claimCodeChannelParam2, claimCodeDeleteParam2, connectionIdParam2, connectorIdParam2, listConnectionsQuery2, deleteConnectionQuery2, addConnectionBody2, editConnectionBody2, PRODUCTION_DIRECT_FIELDS2, setProductionCredentialBody2, registerWhatsappQuery2, registerWhatsappBody2, retryProvisioningQuery2, resendDomainStatusQuery2, PLACEHOLDER_TOKENS2, ALLOWED_TYPES2, SUBSCHEMA_OBJECT_KEYWORDS2, SUBSCHEMA_LIST_KEYWORDS2, SUBSCHEMA_MAP_KEYWORDS2, MAX_SCHEMA_DEPTH2, toolIdParam2, listToolsQuery2, toolAgentQuery2, deleteToolQuery2, toolConnectionsQuery2, nativeToolIdSchema2, CONTEXT_BOUNDARIES2, contextBoundarySchema2, addNativeToolBody2, addMcpToolBody2, createCustomToolBody2, updateCustomToolBody2, updateToolExecutionConfigBody2, initialValueCreateSchema2, initialValueUpdateSchema2, stateIdParam2, listStatesQuery2, stateNameSchema2, createStateBody2, updateStateBody2, reorderStatesBody2, variantAiModeSchema2, experimentStatusSchema2, overlayUpdateSchema2, experimentIdParam2, variantIdParam2, listExperimentsQuery2, listVariantsQuery2, listOverridesQuery2, deleteOverrideQuery2, createExperimentBody2, updateExperimentBody2, setExperimentStatusBody2, createVariantBody2, updateVariantBody2, upsertOverrideBody2, orgTagIdParam2, listOrgTagsQuery2, ORG_TAG_NAME_REGEX2, ORG_TAG_NAME_MAX_LENGTH2, createOrgTagBody2, updateOrgTagBody2, orgCredentialIdParam2, listOrgCredentialsQuery2, createOrgCredentialBody2, updateOrgCredentialBody2, BASE_CREDENTIAL_NAME_MAX2, baseCredentialNameSchema2, createBaseCredentialLinkBody2, baseCredentialLinkParams2, baseCredentialLinkQuery2, orgResourceIdParam2, orgResourceFileIdParam2, orgResourceFolderIdParam2, hubOrgResourceParam2, listOrgResourcesQuery2, orgIdQuery2, createOrgResourceBody2, updateOrgResourceBody2, createOrgResourceFolderBody2, updateOrgResourceFolderBody2, uploadOrgResourceFileBody2, updateOrgResourceFileBody2, uploadOrgSkillZipBody2, linkOrgResourceBody2, resourceIdParam2, listResourcesQuery2, createResourceBody2, updateResourceBody2, syncSkillsBody2, resourceFileIdParam2, listResourceFilesQuery2, createResourceFileBody2, updateResourceFileBody2, uploadResourceFileBody2, uploadSkillZipBody2, resourceFolderIdParam2, listResourceFoldersQuery2, createResourceFolderBody2, updateResourceFolderBody2, agentResourceQuery2, hubResourceQuery2, linkAgentResourceBody2, updateAgentResourceBody2, unlinkAgentResourceQuery2, navItemSchema2, hubCountResetBody2, navItemCountResetBody2, typingBody2, analyticsHubIdParam2, analyticsVariableIdParam2, updateVariablePinBody2, updateAnalyticsViewBody2, NUMERIC_FILTER_OPS2, TEXT_FILTER_OPS2, CATEGORICAL_FILTER_OPS2, VARIABLE_FILTER_OPS2, STRUCTURED_QUERY_OPS2, STRUCTURED_QUERY_AGGREGATIONS2, filterValueSchema2, conversationsBody2, analyticsConversationIdParam2, messagesQuery2, conversationDetailDataQuery2, analyticsDataBody2, structuredQueryBody2, analyticsSqlBody2, analyticsSqlTable2, analyticsSqlSchemaQuery2, EVAL_PACING_PRESET_NAMES2, PACING_INTERVAL_MIN_MS2, PACING_INTERVAL_MAX_MS2, EVAL_MAX_RUNS_PER_SCENARIO2, EVAL_RUN_DEADLINE_MIN_MS2, EVAL_RUN_DEADLINE_MAX_MS2, ISO_UTC_RE2, paginationSchema22, evalIdParam2, sessionIdParam2, scenarioSetIdParam2, hubIdQuery2, evalDateContextSchema2, EVAL_FIXTURE_NAME_MAX_LENGTH2, evalFixtureOverrideSchema2, runSessionQuery2, runJourneyQuery2, EVAL_INPUT_ROLES2, EVAL_INPUT_ROLE_LIST2, ROLE_ECHO_MAX2, EVAL_INITIAL_STATE_SCOPES2, MAX_INITIAL_STATE_ENTRIES2, evalInitialStateEntry2, evalBody2, EVAL_LIST_MAX_LIMIT2, evalListLimit2, getEvalsQuery2, toggleEvalBody2, bulkToggleEvalsBody2, pacingConfigSchema2, EVAL_MAX_SELECTED_SCENARIOS2, evalScenarioSelectionEntrySchema2, evalScenarioSelectionSchema2, sessionConfigSchema2, createSessionBody2, getSessionsQuery2, getSessionResultsQuery2, getSessionRunsQuery2, evalAnalyticsQuery2, getSessionCostQuery2, compareSessionsQuery2, evalsSqlBody2, evalsSqlSchemaQuery2, exportResultsQuery2, validateEvalBody2, hubAgentsQuery2, createScenarioSetBody2, updateScenarioSetBody2, scenarioSetsHubQuery2, createScenarioFromConversationBody2, createJourneyFromConversationBody2, EVAL_ATTACHMENT_HASH_REGEX2, evalAttachmentRef2, turnMayCarryAttachments2, ATTACHMENTS_USER_ONLY_MESSAGE2, journeyIdParam2, journeyToolCallSchema2, journeyTurnSchema2, journeyStepOverrideSchema2, fixtureField2, createJourneyBody2, updateJourneyBody2, evalSessionConfigResponseSchema2, evalSessionResponseSchema2, evalSessionListConfigSchema2, evalSessionListItemSchema2, seedReleaseStatusSchema2, getConversationsQuery2, getMessagesQuery2, appMessageSenderType2, appMessageReceiverType2, apiChannelMessage2, apiChannelMessageBody2, appMessageBody2, appMessageResponse2, CALL_STATUSES2, callStatus2, CALL_END_REASONS2, callEndReason2, CALL_TRANSPORTS2, callTransport2, CALL_PARTICIPANT_TYPES2, callParticipantType2, callInstant2, MAX_SDP_OFFER_LENGTH2, sdpDescription2, sdpOffer2, MAX_CALL_REQUEST_BODY_BYTES2, hubScoped3, callSummaryFields2, callSummary2, callIdParam2, createCallBody2, createCallResponse2, callReadyBody2, callHangupBody2, callStatusQuery2, MAX_REPORTED_DELEGATION_IDS2, callDelegationId2, callDelegationsBody2, callResponse2, MAX_CALL_RECORDING_GAPS2, callRecordingGap2, callRecordingNoteMetadata2, CALL_OPENING_LANGUAGES2, callOpeningLanguage2, CALL_OPENING_MAX_DURATION_MS2, CALL_OPENING_MAX_BYTES2, CALL_OPENING_CAPTION_MAX_CHARS2, CALL_OPENING_CONTENT_TYPES2, callOpeningContentType2, CALL_OPENING_HASH_REGEX2, callOpeningHash2, callOpeningCaption2, storedCallOpening2, MAX_CALL_OPENING_ENCODED_BYTES2, MAX_CALL_OPENING_BODY_BYTES2, agentCallOpeningParams2, putAgentCallOpeningBody2, deleteAgentCallOpeningQuery2, callOpeningParam2, callOpeningQuery2, TTS_VOICE_REPLY_ENABLED_FIELD2, COPILOT_TRIGGER_FIELD2, AUDIO_LANGUAGE_OPTIONS2, whatsapp2, instagram2, resend2, telegram2, API_CHANNEL_DELIVERY_EVENTS2, apiChannel2, OPENAI_REASONING_MODELS2, openai2, anthropic2, googleAiStudio2, openRouter2, xai2, groqStt2, openaiStt2, elevenLabsStt2, openaiTts2, groqTts2, elevenLabsTts2, GEMINI_TTS_VOICES2, googleTts2, wayai2, externalResources2, restApiTool2, mcpServer2, e2b2, CLAUDE_HARNESS_MODELS2, CLAUDE_HARNESS_MODEL_OPTIONS2, HARNESS_MCP_SERVERS_FIELD2, HARNESS_EGRESS_FIELDS2, claudeAgentSdk2, claudeManagedAgents2, rekorMemory2, SPOKEN_LINE_MAX_CHARS2, gptLive2, CONNECTORS2, evalCallInstant2, EVAL_CALL_MIN_SECONDS2, EVAL_CALL_MAX_SECONDS2, EVAL_CALL_SPOKEN_LINE_MAX_CHARS2, hubScoped22, createEvalCallBody2, createEvalCallResponse2, evalCallConversationQuery2, evalCallSpeaker2, evalCallUtterance2, evalCallTurn2, evalCallRecordResponse2, evalCallFinishResponse2, updateUserBody2, updateProfileBody2, pathnameRegex2, updatePreferencesBody2, registerPushTokenBody2, deletePushTokenQuery2, activityQuery2, deletionModeSchema2, deletionRequestBody2, archiveHubIdParam2, archiveConversationParams2, archiveListQuery2, archiveMessageObservabilityParams2, conversationIdParam2, claimBody2, releaseBody2, transferBody2, closeBody2, additionalContextPayloadSchema2, kanbanUpdateBody2, annotateConversationBody2, observabilityParams2, observabilityListParams2, deleteUserConversationsBody2, deleteUserConversationsResponse2, sendMessageBody2, listConversationsQuery2, flagSourceSchema2, getConversationsResponse2, getConversationDetailParams2, getConversationDetailQuery2, getConversationDetailResponse2, listWhatsAppTemplatesQuery2, sendWhatsAppTemplateBody2, copilotSuggestBody2, copilotSuggestResponse2, CONSULT_THREAD_STATUSES2, consultThreadStatus2, CONSULT_THREAD_TITLE_MAX2, consultThreadTitle2, consultThreadSummary2, listConsultThreadsQuery2, listConsultThreadsResponse2, createConsultThreadBody2, createConsultThreadResponse2, consultThreadIdParam2, updateConsultThreadBody2, updateConsultThreadResponse2, CONSULT_AWAIT_TIMEOUT_MS2, billingOrgIdParam2, subscriptionItemParams2, spendCapBody2, growthPacksBody2, portalSessionBody2, checkoutSessionBody2, updateBillingCurrencyBody2, invoicesQuery2, planKeySchema2, billingStatusSchema2, billingPlanTypeSchema2, dataUsageCountersSchema2, REKOR_ENTITLEMENT_CONTRACT_VERSION2, entitlementProjectionSchema2, rekorEntitlementRefreshMessageSchema2, downloadBody2, uploadQuery2, signUrlBody2, outboundSchemaQuery2, templateIdParam2, listTemplatesQuery2, deleteTemplateQuery2, templateStatusQuery2, createTemplateBody2, updateTemplateBody2, submitTemplateBody2, testTemplateBody2, contactIdParam2, listContactsQuery2, createContactBody2, updateContactBody2, listIdParam2, listListsQuery2, listListContactsQuery2, createListBody2, updateListBody2, addListContactsBody2, removeListContactsBody2, scheduleIdParam2, listSchedulesQuery2, listExecutionsQuery2, createScheduleBody2, updateScheduleBody2, MAX_RESOURCE_FILE_SIZE2, MAX_10MB_BASE64_ENCODED_BYTES2, MAX_EVAL_ATTACHMENT_ENCODED_BYTES2, MAX_EVAL_ATTACHMENT_CARRIERS2, MAX_EVAL_ATTACHMENT_AGGREGATE_ENCODED_BYTES2, MAX_RESOURCE_ENCODED_BYTES2, MAX_HUB_AS_CODE_RESOURCES2, MAX_HUB_AS_CODE_RESOURCE_FILES2, MAX_RESOURCE_AGGREGATE_ENCODED_BYTES2, MAX_CI_CONFIG_BODY_BYTES2, MAX_CALL_OPENING_CARRIERS2, MAX_CALL_OPENING_AGGREGATE_ENCODED_BYTES2, hubAsCodeStateSchema2, hubAsCodeResourceFileSchema2, hubAsCodeResourceSchema2, uuidPattern2, ciUuidSchema2, boundedHubAsCodeResourcesSchema2, hubAsCodeConfigSchema2, ciPullHubIdParam2, ciBranchParam2, ciPullQuery2, ciHubsQuery2, ciLookupQuery2, ciBranchesQuery2, ciSyncBody2, ciPushBody2, ciDiffBody2, ciPublishBody2, ciPublishPreviewBody2, ciSyncMcpBody2, ciOrgResourcesParam2, orgResourcesConfigSchema2, ciOrgResourcesPushBody2, ciOrgResourcesDiffBody2, CI_APPLY_ENTITY_KINDS2, CI_APPLY_OPERATIONS2, ciApplyErrorBaseSchema2, ciApplyErrorSchema2, ciSyncCountSchema2, ciSyncChangesSchema2, ciSyncWarningSchema2, ciSyncResponseSchema2, adminOrgIdParam2, adminOrgAdminIdParam2, adminUserIdParam2, PRICING_PLAN_ID_RE2, adminPlanIdParam2, adminOrganizationsQuery2, adminUserSearchQuery2, kanbanSlugMigrationQuery2, adjustQuotaBody2, updatePlanBody2, addAdminUserBody2, MAX_VOICE_CALL_MINUTE_OPS2, voiceCallMinuteOps2, updatePlatformConfigBody2, updateFreeOrgLimitBody2, adminScopedTargetBody2, adminRepairLegacyOrgGrantsBody2, adminRepairCompedPlansBody2, updatePricingPlanBody2, dataExplorerSearchQuery2, dataExplorerOrgIdParam2, dataExplorerHubIdParam2, dataExplorerConvIdParam2, dataExplorerDoInstancesQuery2, dataExplorerNsIdParam2, dataExplorerKvKeysBody2, dataExplorerKvKeyBody2, uuidOrHexId2, dataExplorerDeleteOrgParam2, dataExplorerDeleteHubParam2, dataExplorerDeleteConvParam2, dataExplorerDeleteUserParam2, dataExplorerDeleteQuery2, dataExplorerKvDeleteBody2, pitrDoNamespace2, pitrBookmarkParam2, pitrRestoreBody2, healthSamplingTriggerBody2, dataExplorerDebugDoType2, DEBUG_READ_MAX_LIMIT2, DEBUG_READ_DEFAULT_LIMIT2, DEBUG_DO_HEX_PREFIX2, debugDoEntityId2, debugTableName2, dataExplorerDebugTablesParam2, dataExplorerDebugRowsParam2, dataExplorerDebugRowsQuery2, dataExplorerDebugAnalyticsTable2, debugUuid2, dataExplorerDebugAnalyticsRowsParam2, dataExplorerDebugAnalyticsRowsQuery2, debugHubConvParam2, debugMessageIdQuery2, sandboxEgressPolicy2, SANDBOX_EXEC_MAX_CMD_LENGTH2, SANDBOX_EXEC_MAX_ALLOWLIST2, SANDBOX_EXEC_MAX_TIMEOUT_MS2, adminSandboxExecBody2, META_ENTITY_ID_PATTERN2, metaEntityId2, whatsappCallbackBody2, authMeResponse2, wsTicketResponse2, sessionCheckResponse2, logoutResponse2, magicCodeSendBody2, magicCodeSendResponse2, magicCodeVerifyBody2, magicCodeVerifyResponse2, passwordLoginBody2, browserParams2, browserFoldersQuery2, browserFilesQuery2, stateOperationBody2, conversationListResourcesQuery2, conversationReadResourceQuery2, listPendingSchedulesQuery2, listHubAggregateSchedulesQuery2, reportSourceSchema2, intakeReportSourceSchema2, reportClassificationSchema2, reportStatusSchema2, reportLocaleSchema2, reportMessageAuthorRoleSchema2, reportMessageSchema2, sentryRefStatusSchema2, createReportBody2, editReportBody2, reporterReportSummarySchema2, reporterListResponseSchema2, getReportResponseSchema2, reporterTransitionResponseSchema2, contestReportBody2, reporterListQuery2, listReportsQuery2, GITHUB_ISSUE_URL_REGEX2, githubIssueUrlSchema2, transitionReportBody2, groupReportsBody2, holdReportBody2, clickhouseReadyResponse2, bootstrapQuery2, requestSnapshotChunkMessage2, MAX_NAME_LENGTH3, MAX_VALUE_LENGTH2, MAX_TAGS2, MAX_TAG_LENGTH2, MAX_SCOPE_HUBS2, MAX_SCOPE_TAGS2, vaultSecretScopeSchema2, vaultCreateBody2, vaultUpdateBody2, PERMISSIONS2, MAX_NAME_LENGTH22, MAX_HUBS_PER_GRANT2, MAX_HUB_TAGS_PER_GRANT2, MAX_GRANTS2, permissionEnum2, grantScopeSchema2, grantSchema2, createTokenBody2, tokenOrgIdParam2, tokenGrantScopeSchema2, tokenGrantSchema2, tokenMetadataSchema2, listTokensResponse2, createTokenResponse2, orgTokenSummarySchema2, listOrgTokensResponse2, invitePreviewQuery2, invitePreviewResponse2, jsonSchemaSchema2, hubUserIdentity2, stateValueEntry2, getHubUserContextResponse2, updateHubUserBody2, updateHubUserResponse2, unlockHubUserNameResponse2, stateResetParams2, stateResetResponse2, hubAlertsParam2, hubAlertSeverity2, hubAlert2, hubAlertsListResponse2, noticeSeveritySchema2, noticeStatusSchema2, NOTICE_SCOPE_REGEX2, noticeScopeSchema2, noticeLinkSchema2, createNoticeBody2, updateNoticeBody2, listNoticesQuery2, noticeIdParamSchema2, ADMIN_SKILL_NAME_REGEX2, adminSkillNameParam2, rekorBaseChangeMessageSchema2, WAYAI_WORKSPACE_LAYOUT, decisionAnswerSchema, decisionsResponseSchema;
14135
14384
  var init_dist = __esm({
14136
14385
  "../../packages/core/dist/index.js"() {
14137
14386
  "use strict";
@@ -14190,6 +14439,7 @@ var init_dist = __esm({
14190
14439
  init_zod();
14191
14440
  init_zod();
14192
14441
  init_zod();
14442
+ init_zod();
14193
14443
  UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
14194
14444
  HEX_RE = /^[0-9a-f]{16,}$/;
14195
14445
  WORKOS_ID_RE = /^(?:user|org)_[0-9A-HJKMNP-TV-Z]{26}$/;
@@ -14644,7 +14894,8 @@ var init_dist = __esm({
14644
14894
  skipAuthenticatedUsers: true,
14645
14895
  userLimitKey: "/api/calls"
14646
14896
  },
14647
- // The routes on one call: `ready`, hang-up, the delegation report and the status read.
14897
+ // The routes on one call: `ready`, hang-up, the delegation report and the status read; and
14898
+ // the opening read (`/api/calls/openings/:language`), one per call, before it exists.
14648
14899
  // NEVER fail-closed: a refused hang-up leaves the call running, and billing, until a
14649
14900
  // limit ends it. The 60 s budget runs on the native binding, which fails open. The key is
14650
14901
  // pinned because the paths carry the call id, which would otherwise give every call a
@@ -16994,12 +17245,9 @@ var init_dist = __esm({
16994
17245
  scope: external_exports.enum(EVAL_INITIAL_STATE_SCOPES2).default("user"),
16995
17246
  value: external_exports.record(external_exports.unknown())
16996
17247
  });
16997
- createEvalBody2 = external_exports.object({
17248
+ evalBody2 = external_exports.object({
16998
17249
  eval: external_exports.record(external_exports.unknown())
16999
- }).superRefine(refineEvalMessageTextRole2).superRefine(refineEvalAttachments2).superRefine(refineEvalInitialState2);
17000
- updateEvalBody2 = external_exports.object({
17001
- eval: external_exports.record(external_exports.unknown())
17002
- }).superRefine(refineEvalMessageTextRole2).superRefine(refineEvalAttachments2).superRefine(refineEvalInitialState2);
17250
+ }).superRefine(refineEvalName2).superRefine(refineEvalMessageTextRole2).superRefine(refineEvalAttachments2).superRefine(refineEvalInitialState2);
17003
17251
  EVAL_LIST_MAX_LIMIT2 = 1e3;
17004
17252
  evalListLimit2 = external_exports.string().regex(/^\d+$/).refine((v) => Number(v) <= EVAL_LIST_MAX_LIMIT2, {
17005
17253
  message: `limit must be ${EVAL_LIST_MAX_LIMIT2} or less`
@@ -17137,7 +17385,8 @@ var init_dist = __esm({
17137
17385
  hub_id: external_exports.string().uuid(),
17138
17386
  conversation_id: external_exports.string().uuid(),
17139
17387
  scenario_set_id: external_exports.string().uuid(),
17140
- scenario_name: external_exports.string().min(1).max(200),
17388
+ // Becomes the created eval's `eval_name`, so it follows `evalNameError`.
17389
+ scenario_name: external_exports.string().max(200).refine((name) => evalNameError2(name) === null, "scenario_name must be a non-blank string"),
17141
17390
  evaluator_instructions: external_exports.string().max(4e3).optional()
17142
17391
  });
17143
17392
  createJourneyFromConversationBody2 = external_exports.object({
@@ -17489,13 +17738,16 @@ var init_dist = __esm({
17489
17738
  /** The browser's SDP offer, sent to the provider unchanged. */
17490
17739
  sdp_offer: sdpOffer2,
17491
17740
  /**
17492
- * The client plays the RECORDING NOTICE — the disclosure's part that tells the caller the
17493
- * call is recorded — before the voice layer speaks, whenever the answer says `recorded`.
17494
- * A hub that records calls records only a call whose client says so: a client without the
17495
- * notice (one that predates it, or a stale tab) gets an unrecorded call, never a recorded
17496
- * call its caller was not told about. Absent: false.
17741
+ * The caller ACKNOWLEDGED THE RECORDING WARNING: before this create, their client showed
17742
+ * that the call will be recorded, and the caller chose to go on. A hub that records calls
17743
+ * records only a call whose create says so: a client that did not show the warning (one
17744
+ * that predates it, or one whose hub signal said the hub does not record) gets an
17745
+ * unrecorded call, never a recorded call its caller did not acknowledge. Absent: false.
17746
+ *
17747
+ * It replaces `plays_recording_notice` (the audio notice's flag), which no server reads any
17748
+ * more: a client that sends only that one gets an unrecorded call.
17497
17749
  */
17498
- plays_recording_notice: external_exports.boolean().optional()
17750
+ recording_warning_acknowledged: external_exports.boolean().optional()
17499
17751
  });
17500
17752
  createCallResponse2 = external_exports.object({
17501
17753
  call_id: external_exports.string().uuid(),
@@ -17504,10 +17756,10 @@ var init_dist = __esm({
17504
17756
  /** The provider's SDP answer, for the browser's `setRemoteDescription`. */
17505
17757
  sdp_answer: sdpDescription2,
17506
17758
  /**
17507
- * The call is recorded: its hub records calls and the create said its client plays the
17508
- * recording notice. The client plays the notice before it sends `ready`, and the recording
17509
- * starts only once `ready` arrives. Absent only from a server that predates recording, which
17510
- * records nothing: absent means not recorded.
17759
+ * The call is recorded: its hub records calls and the create said the caller acknowledged
17760
+ * the recording warning. The client shows that the call is recorded for as long as it
17761
+ * lasts, and the recording starts only once `ready` arrives. Absent only from a server that
17762
+ * predates recording, which records nothing: absent means not recorded.
17511
17763
  */
17512
17764
  recorded: external_exports.boolean().optional()
17513
17765
  });
@@ -17541,6 +17793,51 @@ var init_dist = __esm({
17541
17793
  gaps: external_exports.array(callRecordingGap2).max(MAX_CALL_RECORDING_GAPS2)
17542
17794
  })
17543
17795
  });
17796
+ CALL_OPENING_LANGUAGES2 = ["en", "pt", "es"];
17797
+ callOpeningLanguage2 = external_exports.enum(CALL_OPENING_LANGUAGES2);
17798
+ CALL_OPENING_MAX_DURATION_MS2 = 15e3;
17799
+ CALL_OPENING_MAX_BYTES2 = 1024 * 1024;
17800
+ CALL_OPENING_CAPTION_MAX_CHARS2 = 500;
17801
+ CALL_OPENING_CONTENT_TYPES2 = ["audio/mpeg", "audio/mp4"];
17802
+ callOpeningContentType2 = external_exports.enum(CALL_OPENING_CONTENT_TYPES2);
17803
+ CALL_OPENING_HASH_REGEX2 = EVAL_ATTACHMENT_HASH_REGEX2;
17804
+ callOpeningHash2 = external_exports.string().regex(CALL_OPENING_HASH_REGEX2, "Expected a sha256 hex digest");
17805
+ callOpeningCaption2 = external_exports.string().trim().min(1).max(CALL_OPENING_CAPTION_MAX_CHARS2);
17806
+ storedCallOpening2 = external_exports.object({
17807
+ hash: callOpeningHash2,
17808
+ content_type: callOpeningContentType2,
17809
+ duration_ms: external_exports.number().int().positive().max(CALL_OPENING_MAX_DURATION_MS2),
17810
+ file_size: external_exports.number().int().positive().max(CALL_OPENING_MAX_BYTES2),
17811
+ caption: callOpeningCaption2
17812
+ });
17813
+ MAX_CALL_OPENING_ENCODED_BYTES2 = Math.ceil(CALL_OPENING_MAX_BYTES2 / 3) * 4 + 16;
17814
+ MAX_CALL_OPENING_BODY_BYTES2 = MAX_CALL_OPENING_ENCODED_BYTES2 + 16 * 1024;
17815
+ agentCallOpeningParams2 = external_exports.object({
17816
+ id: external_exports.string().uuid(),
17817
+ language: callOpeningLanguage2
17818
+ });
17819
+ putAgentCallOpeningBody2 = external_exports.object({
17820
+ hub_id: external_exports.string().uuid(),
17821
+ caption: callOpeningCaption2,
17822
+ /**
17823
+ * The audio, base64. Absent: the language's current audio stays and only the caption
17824
+ * changes, which needs an opening already set for the language.
17825
+ */
17826
+ file_data: external_exports.string().min(1).max(MAX_CALL_OPENING_ENCODED_BYTES2).optional()
17827
+ });
17828
+ deleteAgentCallOpeningQuery2 = external_exports.object({
17829
+ hub_id: external_exports.string().uuid()
17830
+ });
17831
+ callOpeningParam2 = external_exports.object({ language: callOpeningLanguage2 });
17832
+ callOpeningQuery2 = external_exports.object({
17833
+ hub_id: external_exports.string().uuid(),
17834
+ /**
17835
+ * The opening the caller's app was told of (`HubCallOpening.version`, `callOpeningVersion`).
17836
+ * Any other answers 404 — the audio or the caption changed since — and the app plays the
17837
+ * platform's opening, so a caption never shows over audio it does not describe.
17838
+ */
17839
+ v: external_exports.string().regex(/^[a-f0-9]{64}\.[a-f0-9]{8}$/, "Expected a call opening version")
17840
+ });
17544
17841
  TTS_VOICE_REPLY_ENABLED_FIELD2 = {
17545
17842
  voice_reply_enabled: {
17546
17843
  type: "toggle",
@@ -18512,6 +18809,7 @@ var init_dist = __esm({
18512
18809
  token_refresh_config: { api_key: { strategy: "none" } },
18513
18810
  connector_description: "Durable, shared cross-agent memory backed by a Rekor Base (S3-compatible). Harness agents mount it read-only or read-write; WayAI holds the credential and performs the signed I/O so it never enters the sandbox."
18514
18811
  };
18812
+ SPOKEN_LINE_MAX_CHARS2 = 300;
18515
18813
  gptLive2 = {
18516
18814
  connector_id: "01e7b19c-bc94-43f4-a780-ad5a22fb7127",
18517
18815
  service_name: "Openai",
@@ -18536,10 +18834,20 @@ var init_dist = __esm({
18536
18834
  // The provider ends every session about 2 hours after it starts (`expires_at` is
18537
18835
  // start + 7,199 s), so 119 whole minutes is the most a call can last.
18538
18836
  max_call_minutes: { type: "number", label: "Maximum Call Length (minutes)", min: 1, max: 119, default: 10, description: "A call ends when it reaches this length." },
18539
- inactivity_timeout_seconds: { type: "number", label: "Inactivity Timeout (seconds)", min: 10, max: 600, default: 60, description: "A call ends after this many seconds in which neither side speaks." },
18837
+ inactivity_timeout_seconds: { type: "number", label: "Inactivity Timeout (seconds)", min: 10, max: 600, default: 60, description: "A call ends after this many seconds in which neither side speaks. A wait for the hub's agent to answer, up to the answer timeout, does not count." },
18540
18838
  delegation_timeout_seconds: { type: "number", label: "Answer Timeout (seconds)", min: 5, max: 120, default: 30, description: "How long the voice waits for the hub's agent to answer one question before it gives up on that answer." },
18839
+ // The fixed lines the voice says (`call-texts.ts`), each the builder's wording when set.
18840
+ // Read by the call route (`resolveVoiceCallSettings`), clipped to `maxLength` again there,
18841
+ // and used as written: placeholders are not filled.
18842
+ greeting_text: spokenLineField2("Greeting", "What the voice says when the call starts, in the call's language. Empty uses WayAI's greeting, which names the hub."),
18843
+ progress_cues: { type: "toggle", label: "Progress Cues", default: true, description: `While the hub's agent works on an answer, the voice says a short "still checking" line about 5 and 10 seconds after the caller stops speaking. Off: the wait is silent unless the voice's instructions fill it; the answer timeout line still plays.` },
18844
+ first_progress_cue_text: spokenLineField2("First Progress Cue", "What the voice says about 5 seconds into a wait for an answer. Empty uses WayAI's line in the call's language."),
18845
+ second_progress_cue_text: spokenLineField2("Second Progress Cue", "What the voice says about 10 seconds into a wait for an answer. Empty uses WayAI's line in the call's language."),
18846
+ please_repeat_text: spokenLineField2("Please Repeat Line", "What the voice says when it has no words for the caller's question and asks them to repeat it. Empty uses WayAI's line in the call's language."),
18847
+ turn_failed_text: spokenLineField2("Couldn't Get That Line", "What the voice says when the hub's agent could not produce an answer. Empty uses WayAI's apology in the call's language."),
18848
+ timed_out_text: spokenLineField2("Answer Timeout Line", "What the voice says when an answer is not back within the answer timeout. Empty uses WayAI's apology in the call's language."),
18541
18849
  // Opt-in (D7): off unless turned on. Read by the call route (`resolveVoiceCallSettings`).
18542
- record_calls: { type: "toggle", label: "Record Calls", default: false, description: "Keep each call's audio, both sides, as a recording your team can play from the conversation. Callers hear that the call is recorded before the voice speaks." }
18850
+ record_calls: { type: "toggle", label: "Record Calls", default: false, description: "Keep each call's audio, both sides, as a recording your team can play from the conversation. Before a call starts, the caller is warned that it will be recorded and chooses whether to go on." }
18543
18851
  },
18544
18852
  channel_settings_schema: null,
18545
18853
  tool_settings_schema: null,
@@ -18550,7 +18858,7 @@ var init_dist = __esm({
18550
18858
  }
18551
18859
  },
18552
18860
  token_refresh_config: { api_key: { strategy: "none" } },
18553
- connector_description: "Live voice calls on OpenAI GPT-Live: a voice that talks with callers and asks your hub's agent for every answer. Requires an OpenAI project API key."
18861
+ connector_description: "Live voice calls on OpenAI GPT-Live: a voice that talks with callers and asks your hub's agent for answers. Requires an OpenAI project API key."
18554
18862
  };
18555
18863
  CONNECTORS2 = [
18556
18864
  anthropic2,
@@ -18586,6 +18894,10 @@ var init_dist = __esm({
18586
18894
  0,
18587
18895
  ...CONNECTORS2.filter((connector) => connector.connector_type === "Realtime").map((connector) => Number(connector.agent_settings_schema?.max_call_minutes?.max) || 0)
18588
18896
  );
18897
+ EVAL_CALL_SPOKEN_LINE_MAX_CHARS2 = Math.max(
18898
+ 0,
18899
+ ...CONNECTORS2.filter((connector) => connector.connector_type === "Realtime").flatMap((connector) => Object.values(connector.agent_settings_schema ?? {})).filter((field) => field.type === "text").map((field) => Number(field.maxLength) || 0)
18900
+ );
18589
18901
  hubScoped22 = { hub_id: external_exports.string().uuid() };
18590
18902
  createEvalCallBody2 = external_exports.object({
18591
18903
  ...hubScoped22,
@@ -18614,7 +18926,15 @@ var init_dist = __esm({
18614
18926
  * (`platform_config` `voice_call_minute_ops`); null when it could not be read. With one
18615
18927
  * operation per call turn, it is what a runner counts a live call's WayAI operations by.
18616
18928
  */
18617
- minute_price_ops: external_exports.number().int().nonnegative().nullable()
18929
+ minute_price_ops: external_exports.number().int().nonnegative().nullable(),
18930
+ /**
18931
+ * What the runner plans its waits by, as the call started with them: whether the voice fills
18932
+ * the wait for an answer with progress cues (its agent's `progress_cues`), and how long it
18933
+ * waits for one before its timeout line (`delegation_timeout_seconds`). With the cues off
18934
+ * the wait is silent, so a pause is no sign that the answer has been said.
18935
+ */
18936
+ progress_cues: external_exports.boolean(),
18937
+ delegation_timeout_seconds: external_exports.number().int().positive()
18618
18938
  });
18619
18939
  evalCallConversationQuery2 = external_exports.object({
18620
18940
  ...hubScoped22,
@@ -19301,6 +19621,8 @@ var init_dist = __esm({
19301
19621
  MAX_HUB_AS_CODE_RESOURCE_FILES2 = 5e3;
19302
19622
  MAX_RESOURCE_AGGREGATE_ENCODED_BYTES2 = 32 * 1024 * 1024;
19303
19623
  MAX_CI_CONFIG_BODY_BYTES2 = 64 * 1024 * 1024;
19624
+ MAX_CALL_OPENING_CARRIERS2 = 30;
19625
+ MAX_CALL_OPENING_AGGREGATE_ENCODED_BYTES2 = 8 * 1024 * 1024;
19304
19626
  hubAsCodeStateSchema2 = external_exports.object({
19305
19627
  id: external_exports.string().min(1).optional(),
19306
19628
  slug: external_exports.string().optional(),
@@ -19379,6 +19701,7 @@ var init_dist = __esm({
19379
19701
  refineHubAsCodeLanes2(config, ctx);
19380
19702
  refineHubAsCodeEvals2(config, ctx);
19381
19703
  refineHubAsCodeEvalAttachments2(config, ctx);
19704
+ refineHubAsCodeCallOpenings2(config, ctx);
19382
19705
  refineHubAsCodeResources2(config, ctx);
19383
19706
  refineHubAsCodeDelegation2(config, ctx);
19384
19707
  refineHubAsCodeFlagConditions2(config, ctx);
@@ -20592,7 +20915,7 @@ var init_fs_safety = __esm({
20592
20915
  "src/lib/fs-safety.ts"() {
20593
20916
  "use strict";
20594
20917
  init_expected();
20595
- HUB_MANAGED_SUBDIRS = ["agents", "evals", "journeys", "resources", "attachments"];
20918
+ HUB_MANAGED_SUBDIRS = ["agents", "evals", "journeys", "resources", "attachments", "call-openings"];
20596
20919
  HUB_CONFIG_FILES = ["hub.yaml", "wayai.yaml"];
20597
20920
  }
20598
20921
  });
@@ -21371,24 +21694,24 @@ import * as path6 from "path";
21371
21694
  import * as readline from "readline";
21372
21695
  function prompt(question) {
21373
21696
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
21374
- return new Promise((resolve10) => {
21697
+ return new Promise((resolve11) => {
21375
21698
  rl.question(question, (answer) => {
21376
21699
  rl.close();
21377
- resolve10(answer.trim());
21700
+ resolve11(answer.trim());
21378
21701
  });
21379
21702
  });
21380
21703
  }
21381
21704
  function confirm(question) {
21382
21705
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
21383
- return new Promise((resolve10) => {
21706
+ return new Promise((resolve11) => {
21384
21707
  rl.question(`${question} [y/N]: `, (answer) => {
21385
21708
  rl.close();
21386
- resolve10(answer.trim().toLowerCase() === "y");
21709
+ resolve11(answer.trim().toLowerCase() === "y");
21387
21710
  });
21388
21711
  });
21389
21712
  }
21390
21713
  function promptSecret(question) {
21391
- return new Promise((resolve10) => {
21714
+ return new Promise((resolve11) => {
21392
21715
  const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
21393
21716
  const originalWrite = rl._writeToOutput;
21394
21717
  let firstWrite = true;
@@ -21404,18 +21727,18 @@ function promptSecret(question) {
21404
21727
  rl._writeToOutput = originalWrite;
21405
21728
  process.stdout.write("\n");
21406
21729
  rl.close();
21407
- resolve10(answer);
21730
+ resolve11(answer);
21408
21731
  });
21409
21732
  });
21410
21733
  }
21411
21734
  function readStdin() {
21412
- return new Promise((resolve10, reject) => {
21735
+ return new Promise((resolve11, reject) => {
21413
21736
  let data = "";
21414
21737
  process.stdin.setEncoding("utf-8");
21415
21738
  process.stdin.on("data", (chunk) => {
21416
21739
  data += chunk;
21417
21740
  });
21418
- process.stdin.on("end", () => resolve10(data.trim()));
21741
+ process.stdin.on("end", () => resolve11(data.trim()));
21419
21742
  process.stdin.on("error", reject);
21420
21743
  });
21421
21744
  }
@@ -21895,9 +22218,9 @@ function getVersionCachePath(filename = CLI_CACHE_FILE) {
21895
22218
  }
21896
22219
  function readVersionCache(filename = CLI_CACHE_FILE) {
21897
22220
  try {
21898
- const path35 = getVersionCachePath(filename);
21899
- if (!existsSync3(path35)) return null;
21900
- const parsed = JSON.parse(readFileSync6(path35, "utf-8"));
22221
+ const path36 = getVersionCachePath(filename);
22222
+ if (!existsSync3(path36)) return null;
22223
+ const parsed = JSON.parse(readFileSync6(path36, "utf-8"));
21901
22224
  if (typeof parsed.lastCheck !== "number") return null;
21902
22225
  if (parsed.latest !== null && typeof parsed.latest !== "string") return null;
21903
22226
  return parsed;
@@ -21917,10 +22240,10 @@ function isVersionCacheStale(filename = CLI_CACHE_FILE, maxAgeMs = MAX_AGE_24H_M
21917
22240
  return Date.now() - cache.lastCheck > maxAgeMs;
21918
22241
  }
21919
22242
  function writeVersionCache(filename, cache) {
21920
- const path35 = getVersionCachePath(filename);
21921
- const dir = dirname6(path35);
22243
+ const path36 = getVersionCachePath(filename);
22244
+ const dir = dirname6(path36);
21922
22245
  if (!existsSync3(dir)) mkdirSync2(dir, { recursive: true });
21923
- writeFileSync2(path35, JSON.stringify(cache));
22246
+ writeFileSync2(path36, JSON.stringify(cache));
21924
22247
  }
21925
22248
  function touchVersionCache(filename) {
21926
22249
  writeVersionCache(filename, { lastCheck: Date.now(), latest: readVersionCache(filename)?.latest ?? null });
@@ -21959,14 +22282,14 @@ function parseFrontmatterVersion(content) {
21959
22282
  function findInstalledSkills(projectRoot, paths = SKILL_INSTALL_PATHS) {
21960
22283
  const found = [];
21961
22284
  for (const rel of paths) {
21962
- const path35 = join8(projectRoot, rel);
21963
- if (!existsSync4(path35)) continue;
22285
+ const path36 = join8(projectRoot, rel);
22286
+ if (!existsSync4(path36)) continue;
21964
22287
  let version = null;
21965
22288
  try {
21966
- version = parseFrontmatterVersion(readFileSync7(path35, "utf-8"));
22289
+ version = parseFrontmatterVersion(readFileSync7(path36, "utf-8"));
21967
22290
  } catch {
21968
22291
  }
21969
- found.push({ path: path35, version });
22292
+ found.push({ path: path36, version });
21970
22293
  }
21971
22294
  return found;
21972
22295
  }
@@ -22430,7 +22753,7 @@ async function validateToken(apiUrl, token) {
22430
22753
  }
22431
22754
  }
22432
22755
  function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
22433
- return new Promise((resolve10, reject) => {
22756
+ return new Promise((resolve11, reject) => {
22434
22757
  const server = http.createServer((req, res) => {
22435
22758
  const url = new URL(req.url || "/", `http://127.0.0.1:${port}`);
22436
22759
  if (url.pathname === "/callback") {
@@ -22456,7 +22779,7 @@ function startCallbackServer(port, expectedState, timeoutMs = 12e4) {
22456
22779
  res.writeHead(200, { "Content-Type": "text/html" });
22457
22780
  res.end("<html><body><h2>Login successful!</h2><p>You can close this tab and return to your terminal.</p></body></html>");
22458
22781
  server.close();
22459
- resolve10({ code, port });
22782
+ resolve11({ code, port });
22460
22783
  } else {
22461
22784
  res.writeHead(400, { "Content-Type": "text/html" });
22462
22785
  res.end("<html><body><h2>Login failed</h2><p>No authorization code received</p></body></html>");
@@ -22668,10 +22991,10 @@ import * as readline2 from "readline";
22668
22991
  function prompt2(question, defaultValue) {
22669
22992
  const rl = readline2.createInterface({ input: process.stdin, output: process.stdout });
22670
22993
  const display = defaultValue ? `${question} [${defaultValue}]: ` : `${question}: `;
22671
- return new Promise((resolve10) => {
22994
+ return new Promise((resolve11) => {
22672
22995
  rl.question(display, (answer) => {
22673
22996
  rl.close();
22674
- resolve10(answer.trim() || defaultValue || "");
22997
+ resolve11(answer.trim() || defaultValue || "");
22675
22998
  });
22676
22999
  });
22677
23000
  }
@@ -22799,8 +23122,8 @@ async function tryOpenBrowser(url) {
22799
23122
  cmd = "xdg-open";
22800
23123
  args2 = [url];
22801
23124
  }
22802
- return new Promise((resolve10) => {
22803
- execFile(cmd, args2, (err) => resolve10(!err));
23125
+ return new Promise((resolve11) => {
23126
+ execFile(cmd, args2, (err) => resolve11(!err));
22804
23127
  });
22805
23128
  } catch {
22806
23129
  return false;
@@ -23946,20 +24269,129 @@ var init_eval_attachments = __esm({
23946
24269
  }
23947
24270
  });
23948
24271
 
23949
- // src/lib/parser.ts
24272
+ // src/lib/call-openings.ts
23950
24273
  import * as fs11 from "fs";
23951
24274
  import * as path13 from "path";
24275
+ function applyCallOpeningFiles(hubFolder, payload) {
24276
+ const root = path13.resolve(hubFolder);
24277
+ const carriers = /* @__PURE__ */ new Map();
24278
+ for (const agent of payload.agents ?? []) {
24279
+ const openings = agent.call_openings;
24280
+ if (!openings || typeof openings !== "object") continue;
24281
+ for (const [language, opening] of Object.entries(openings)) {
24282
+ if (!opening || typeof opening !== "object" || typeof opening.file !== "string") continue;
24283
+ const label = `Agent "${agent.name}" call_openings.${language}`;
24284
+ const abs = path13.resolve(root, opening.file);
24285
+ if (!isUnder(root, abs)) {
24286
+ throw expected(`${label}: file "${opening.file}" escapes the hub folder.`);
24287
+ }
24288
+ let stat2;
24289
+ try {
24290
+ stat2 = fs11.statSync(abs);
24291
+ } catch {
24292
+ }
24293
+ if (!stat2?.isFile()) throw expected(`${label}: file "${opening.file}" not found.`);
24294
+ if (!realpathContained(root, abs)) {
24295
+ throw expected(`${label}: file "${opening.file}" resolves outside the hub folder (symlinks are not allowed).`);
24296
+ }
24297
+ if (stat2.size > CALL_OPENING_MAX_BYTES) {
24298
+ throw expected(`${label}: file "${opening.file}" is ${(stat2.size / 1024 / 1024).toFixed(1)} MB, over the ${CALL_OPENING_MAX_BYTES / 1024 / 1024} MB limit.`);
24299
+ }
24300
+ const bytes = fs11.readFileSync(abs);
24301
+ const hash = computeHash(bytes);
24302
+ const { file: _file, ...rest } = opening;
24303
+ openings[language] = { ...rest, hash };
24304
+ if (!carriers.has(hash)) carriers.set(hash, { hash, content_base64: bytes.toString("base64") });
24305
+ }
24306
+ }
24307
+ if (carriers.size > 0) payload.call_opening_files = [...carriers.values()];
24308
+ }
24309
+ function rewriteCallOpeningsToLocalPaths(payload) {
24310
+ const byHash = new Map((payload.call_opening_files ?? []).map((file) => [file.hash, file]));
24311
+ const downloads = [];
24312
+ for (const agent of payload.agents ?? []) {
24313
+ const openings = agent.call_openings;
24314
+ if (!openings || typeof openings !== "object") continue;
24315
+ for (const language of CALL_OPENING_LANGUAGES) {
24316
+ const opening = openings[language];
24317
+ if (!opening || typeof opening.hash !== "string") continue;
24318
+ const carrier = byHash.get(opening.hash);
24319
+ const ext = carrier?.content_type === "audio/mp4" ? ".m4a" : ".mp3";
24320
+ const relPath = `${CALL_OPENINGS_DIR}/${slugify(agent.name)}-${language}${ext}`;
24321
+ const { hash, ...rest } = opening;
24322
+ openings[language] = { ...rest, file: relPath };
24323
+ if (carrier?.download_url) downloads.push({ relPath, url: carrier.download_url, hash });
24324
+ }
24325
+ }
24326
+ delete payload.call_opening_files;
24327
+ return downloads;
24328
+ }
24329
+ async function downloadCallOpenings(hubFolder, downloads) {
24330
+ const dir = path13.resolve(hubFolder, CALL_OPENINGS_DIR);
24331
+ const result = { changed: [], removed: [] };
24332
+ if (!ensureRealSubdirNoSymlink(hubFolder, dir, downloads.length > 0)) {
24333
+ console.warn(` Warning: ${CALL_OPENINGS_DIR}/ is not reachable inside the hub folder without a symlink; skipping call opening sync.`);
24334
+ return result;
24335
+ }
24336
+ if (!fs11.existsSync(dir)) return result;
24337
+ for (const download of downloads) {
24338
+ const abs = path13.resolve(hubFolder, download.relPath);
24339
+ if (abs === dir || !isUnder(dir, abs)) continue;
24340
+ let existing;
24341
+ try {
24342
+ existing = fs11.lstatSync(abs);
24343
+ } catch {
24344
+ }
24345
+ if (existing?.isFile() && !existing.isSymbolicLink() && computeHash(fs11.readFileSync(abs)) === download.hash) continue;
24346
+ try {
24347
+ const res = await fetch(download.url);
24348
+ if (!res.ok) {
24349
+ console.warn(` Warning: failed to download ${download.relPath} (HTTP ${res.status})`);
24350
+ continue;
24351
+ }
24352
+ if (writeFileNoFollow(hubFolder, abs, Buffer.from(await res.arrayBuffer()))) result.changed.push(download.relPath);
24353
+ } catch (err) {
24354
+ console.warn(` Warning: failed to download ${download.relPath}: ${err instanceof Error ? err.message : String(err)}`);
24355
+ }
24356
+ }
24357
+ const keep = new Set(downloads.map((download) => path13.resolve(hubFolder, download.relPath)));
24358
+ for (const name of fs11.readdirSync(dir)) {
24359
+ const abs = path13.join(dir, name);
24360
+ const st = fs11.lstatSync(abs);
24361
+ if ((st.isFile() || st.isSymbolicLink()) && !keep.has(abs)) {
24362
+ fs11.rmSync(abs);
24363
+ result.removed.push(path13.relative(hubFolder, abs));
24364
+ }
24365
+ }
24366
+ return result;
24367
+ }
24368
+ var CALL_OPENINGS_DIR;
24369
+ var init_call_openings = __esm({
24370
+ "src/lib/call-openings.ts"() {
24371
+ "use strict";
24372
+ init_contracts();
24373
+ init_resource_files();
24374
+ init_fs_safety();
24375
+ init_expected();
24376
+ init_utils();
24377
+ CALL_OPENINGS_DIR = "call-openings";
24378
+ }
24379
+ });
24380
+
24381
+ // src/lib/parser.ts
24382
+ import * as fs12 from "fs";
24383
+ import * as path14 from "path";
23952
24384
  import * as yaml6 from "js-yaml";
23953
24385
  function refuseConsumedLink(hubFolder, dir, entry) {
23954
24386
  if (!entry.isSymbolicLink()) return;
23955
- const abs = path13.join(dir, entry.name);
24387
+ const abs = path14.join(dir, entry.name);
23956
24388
  let toDir = false;
23957
24389
  try {
23958
- toDir = fs11.statSync(abs).isDirectory();
24390
+ toDir = fs12.statSync(abs).isDirectory();
23959
24391
  } catch {
23960
24392
  }
23961
24393
  if (toDir || entry.name.endsWith(".yaml")) {
23962
- throw symlinkRefusal(path13.relative(hubFolder, abs), "file or folder");
24394
+ throw symlinkRefusal(path14.relative(hubFolder, abs), "file or folder");
23963
24395
  }
23964
24396
  }
23965
24397
  function parseHubFolder(hubFolder, opts) {
@@ -23995,8 +24427,8 @@ function parseHubFolder(hubFolder, opts) {
23995
24427
  const resolved = { ...agent };
23996
24428
  if (typeof resolved.instructions === "string" && resolved.instructions.endsWith(".md")) {
23997
24429
  const instrValue = resolved.instructions;
23998
- const instructionsPath = instrValue.startsWith("agents/") ? path13.join(hubFolder, instrValue) : path13.join(hubFolder, "agents", instrValue);
23999
- if (!isUnder(path13.join(hubFolder, "agents"), instructionsPath)) {
24430
+ const instructionsPath = instrValue.startsWith("agents/") ? path14.join(hubFolder, instrValue) : path14.join(hubFolder, "agents", instrValue);
24431
+ if (!isUnder(path14.join(hubFolder, "agents"), instructionsPath)) {
24000
24432
  throw workspaceRefusal(
24001
24433
  `Agent instructions path "${instrValue}" (agent "${agent.name}") must stay inside agents/.`
24002
24434
  );
@@ -24010,7 +24442,7 @@ function parseHubFolder(hubFolder, opts) {
24010
24442
  );
24011
24443
  }
24012
24444
  } else if (resolved.instructions === void 0 && typeof agent.name === "string") {
24013
- const conventionPath = path13.join(hubFolder, "agents", `${slugify(agent.name)}.md`);
24445
+ const conventionPath = path14.join(hubFolder, "agents", `${slugify(agent.name)}.md`);
24014
24446
  const instructions = readRealFileOrThrow(hubFolder, conventionPath);
24015
24447
  if (instructions !== null) resolved.instructions = instructions;
24016
24448
  }
@@ -24028,6 +24460,7 @@ function parseHubFolder(hubFolder, opts) {
24028
24460
  }
24029
24461
  if (agents && agents.length > 0) {
24030
24462
  payload.agents = agents;
24463
+ applyCallOpeningFiles(hubFolder, payload);
24031
24464
  }
24032
24465
  if (resources.length > 0) {
24033
24466
  payload.resources = resources;
@@ -24065,28 +24498,28 @@ function parseHubFolder(hubFolder, opts) {
24065
24498
  return payload;
24066
24499
  }
24067
24500
  function scanEvalYamlFiles(hubFolder, bytesByHash) {
24068
- const evalsDir = path13.join(hubFolder, "evals");
24069
- if (!fs11.existsSync(evalsDir)) return [];
24501
+ const evalsDir = path14.join(hubFolder, "evals");
24502
+ if (!fs12.existsSync(evalsDir)) return [];
24070
24503
  const evals = [];
24071
24504
  const seen = /* @__PURE__ */ new Set();
24072
- const topEntries = fs11.readdirSync(evalsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
24505
+ const topEntries = fs12.readdirSync(evalsDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
24073
24506
  for (const entry of topEntries) {
24074
24507
  refuseConsumedLink(hubFolder, evalsDir, entry);
24075
24508
  if (entry.isFile() && entry.name.endsWith(".yaml")) {
24076
- collectEval(evals, seen, path13.join(evalsDir, entry.name), `evals/${entry.name}`, null, hubFolder, bytesByHash);
24509
+ collectEval(evals, seen, path14.join(evalsDir, entry.name), `evals/${entry.name}`, null, hubFolder, bytesByHash);
24077
24510
  } else if (entry.isDirectory()) {
24078
24511
  const setName = entry.name;
24079
- const setDir = path13.join(evalsDir, setName);
24080
- const setEntries = fs11.readdirSync(setDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
24512
+ const setDir = path14.join(evalsDir, setName);
24513
+ const setEntries = fs12.readdirSync(setDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
24081
24514
  for (const sub of setEntries) {
24082
24515
  refuseConsumedLink(hubFolder, setDir, sub);
24083
24516
  if (sub.isDirectory()) {
24084
24517
  throw expected(
24085
- `Nested scenario sets are not supported: ${path13.relative(hubFolder, path13.join(setDir, sub.name))}. Move scenarios up to evals/${setName}/.`
24518
+ `Nested scenario sets are not supported: ${path14.relative(hubFolder, path14.join(setDir, sub.name))}. Move scenarios up to evals/${setName}/.`
24086
24519
  );
24087
24520
  }
24088
24521
  if (sub.isFile() && sub.name.endsWith(".yaml")) {
24089
- collectEval(evals, seen, path13.join(setDir, sub.name), `evals/${setName}/${sub.name}`, setName, hubFolder, bytesByHash);
24522
+ collectEval(evals, seen, path14.join(setDir, sub.name), `evals/${setName}/${sub.name}`, setName, hubFolder, bytesByHash);
24090
24523
  }
24091
24524
  }
24092
24525
  }
@@ -24100,14 +24533,14 @@ function collectEval(evals, seen, filePath, relPath, setName, hubFolder, bytesBy
24100
24533
  if (seen.has(key)) {
24101
24534
  const where = setName ? `scenario set "${setName}"` : "root";
24102
24535
  throw expected(
24103
- `Duplicate eval at ${where}: "${evalEntry.name}" (in ${path13.basename(filePath)}). Each (name, scenario set) pair must be unique.`
24536
+ `Duplicate eval at ${where}: "${evalEntry.name}" (in ${path14.basename(filePath)}). Each (name, scenario set) pair must be unique.`
24104
24537
  );
24105
24538
  }
24106
24539
  seen.add(key);
24107
24540
  evals.push(evalEntry);
24108
24541
  }
24109
24542
  function parseEvalYaml(filePath, relPath, setName, hubFolder, bytesByHash) {
24110
- const content = fs11.readFileSync(filePath, "utf-8");
24543
+ const content = fs12.readFileSync(filePath, "utf-8");
24111
24544
  let raw;
24112
24545
  try {
24113
24546
  raw = yaml6.load(content);
@@ -24122,7 +24555,7 @@ function parseEvalYaml(filePath, relPath, setName, hubFolder, bytesByHash) {
24122
24555
  return null;
24123
24556
  }
24124
24557
  const data = raw;
24125
- const fileSlug = path13.basename(filePath, ".yaml");
24558
+ const fileSlug = path14.basename(filePath, ".yaml");
24126
24559
  const evalName = typeof data.name === "string" && data.name.trim().length > 0 ? data.name : fileSlug;
24127
24560
  if (typeof data.agent !== "string" || data.agent.trim().length === 0) {
24128
24561
  throw expected(`Eval "${evalName}" in ${relPath}: missing required field "agent" (string).`);
@@ -24209,20 +24642,20 @@ function parseFixtureField(raw, label, key) {
24209
24642
  return trimmed.length > 0 ? trimmed : void 0;
24210
24643
  }
24211
24644
  function scanJourneyYamlFiles(hubFolder, bytesByHash) {
24212
- const journeysDir = path13.join(hubFolder, "journeys");
24213
- if (!fs11.existsSync(journeysDir)) return [];
24645
+ const journeysDir = path14.join(hubFolder, "journeys");
24646
+ if (!fs12.existsSync(journeysDir)) return [];
24214
24647
  const journeys = [];
24215
24648
  const seen = /* @__PURE__ */ new Set();
24216
- const entries = fs11.readdirSync(journeysDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
24649
+ const entries = fs12.readdirSync(journeysDir, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name));
24217
24650
  for (const entry of entries) {
24218
24651
  refuseConsumedLink(hubFolder, journeysDir, entry);
24219
24652
  if (entry.isDirectory()) {
24220
24653
  throw expected(
24221
- `Subfolders are not supported under journeys/: ${path13.relative(hubFolder, path13.join(journeysDir, entry.name))}. A journey owns its own managed scenario set \u2014 put each journey in a single journeys/<slug>.yaml file.`
24654
+ `Subfolders are not supported under journeys/: ${path14.relative(hubFolder, path14.join(journeysDir, entry.name))}. A journey owns its own managed scenario set \u2014 put each journey in a single journeys/<slug>.yaml file.`
24222
24655
  );
24223
24656
  }
24224
24657
  if (!entry.isFile() || !entry.name.endsWith(".yaml")) continue;
24225
- const journeyEntry = parseJourneyYaml(path13.join(journeysDir, entry.name), `journeys/${entry.name}`, hubFolder, bytesByHash);
24658
+ const journeyEntry = parseJourneyYaml(path14.join(journeysDir, entry.name), `journeys/${entry.name}`, hubFolder, bytesByHash);
24226
24659
  if (!journeyEntry) continue;
24227
24660
  if (seen.has(journeyEntry.name)) {
24228
24661
  throw expected(
@@ -24235,7 +24668,7 @@ function scanJourneyYamlFiles(hubFolder, bytesByHash) {
24235
24668
  return journeys;
24236
24669
  }
24237
24670
  function parseJourneyYaml(filePath, relPath, hubFolder, bytesByHash) {
24238
- const content = fs11.readFileSync(filePath, "utf-8");
24671
+ const content = fs12.readFileSync(filePath, "utf-8");
24239
24672
  let raw;
24240
24673
  try {
24241
24674
  raw = yaml6.load(content);
@@ -24250,7 +24683,7 @@ function parseJourneyYaml(filePath, relPath, hubFolder, bytesByHash) {
24250
24683
  return null;
24251
24684
  }
24252
24685
  const data = raw;
24253
- const fileSlug = path13.basename(filePath, ".yaml");
24686
+ const fileSlug = path14.basename(filePath, ".yaml");
24254
24687
  const journeyName = typeof data.name === "string" && data.name.trim().length > 0 ? data.name : fileSlug;
24255
24688
  if (typeof data.agent !== "string" || data.agent.trim().length === 0) {
24256
24689
  throw expected(`Journey "${journeyName}" in ${relPath}: missing required field "agent" (string).`);
@@ -24290,13 +24723,13 @@ function parseJourneyYaml(filePath, relPath, hubFolder, bytesByHash) {
24290
24723
  return journeyEntry;
24291
24724
  }
24292
24725
  function scanAgentYamlFiles(hubFolder) {
24293
- const agentsDir = path13.join(hubFolder, "agents");
24294
- if (!fs11.existsSync(agentsDir)) return [];
24295
- const yamlFiles = fs11.readdirSync(agentsDir).filter((f) => f.endsWith(".yaml")).sort();
24726
+ const agentsDir = path14.join(hubFolder, "agents");
24727
+ if (!fs12.existsSync(agentsDir)) return [];
24728
+ const yamlFiles = fs12.readdirSync(agentsDir).filter((f) => f.endsWith(".yaml")).sort();
24296
24729
  if (yamlFiles.length === 0) return [];
24297
24730
  const agents = [];
24298
24731
  for (const file of yamlFiles) {
24299
- const filePath = path13.join(agentsDir, file);
24732
+ const filePath = path14.join(agentsDir, file);
24300
24733
  const content = readRealFileOrThrow(hubFolder, filePath) ?? "";
24301
24734
  let agent;
24302
24735
  try {
@@ -24317,7 +24750,7 @@ function scanAgentYamlFiles(hubFolder) {
24317
24750
  return agents;
24318
24751
  }
24319
24752
  function parseResources(hubFolder, configResources) {
24320
- const resourcesDir = path13.join(hubFolder, "resources");
24753
+ const resourcesDir = path14.join(hubFolder, "resources");
24321
24754
  const results = [];
24322
24755
  for (const res of configResources) {
24323
24756
  const resource = {
@@ -24331,9 +24764,9 @@ function parseResources(hubFolder, configResources) {
24331
24764
  if (res.user_browsable) resource.user_browsable = res.user_browsable;
24332
24765
  if (res.skill_name) resource.skill_name = res.skill_name;
24333
24766
  const resSlug = slugify(resource.name);
24334
- const resDir = path13.join(resourcesDir, resSlug);
24767
+ const resDir = path14.join(resourcesDir, resSlug);
24335
24768
  requireRealSubdirNoSymlink(hubFolder, resDir, false);
24336
- if (fs11.existsSync(resDir)) {
24769
+ if (fs12.existsSync(resDir)) {
24337
24770
  const files = scanResourceFiles(resDir, "");
24338
24771
  if (files.length > 0) {
24339
24772
  resource.files = files;
@@ -24349,6 +24782,7 @@ var init_parser = __esm({
24349
24782
  init_utils();
24350
24783
  init_resource_files();
24351
24784
  init_eval_attachments();
24785
+ init_call_openings();
24352
24786
  init_expected();
24353
24787
  init_fs_safety();
24354
24788
  }
@@ -24382,7 +24816,7 @@ var init_diff_display = __esm({
24382
24816
  });
24383
24817
 
24384
24818
  // src/lib/workspace-files.ts
24385
- import * as path14 from "path";
24819
+ import * as path15 from "path";
24386
24820
  function perHubAgentsMd(hubFolderName) {
24387
24821
  return [
24388
24822
  `# ${hubFolderName}`,
@@ -24398,7 +24832,7 @@ function perHubAgentsMd(hubFolderName) {
24398
24832
  ].join("\n");
24399
24833
  }
24400
24834
  function writeIfAbsent(root, filePath, content) {
24401
- return createFileNoFollow(root, filePath, Buffer.from(content, "utf-8")) === "created" ? path14.basename(filePath) : null;
24835
+ return createFileNoFollow(root, filePath, Buffer.from(content, "utf-8")) === "created" ? path15.basename(filePath) : null;
24402
24836
  }
24403
24837
  var init_workspace_files = __esm({
24404
24838
  "src/lib/workspace-files.ts"() {
@@ -24408,16 +24842,16 @@ var init_workspace_files = __esm({
24408
24842
  });
24409
24843
 
24410
24844
  // src/lib/yaml-writer.ts
24411
- import * as fs12 from "fs";
24412
- import * as path15 from "path";
24845
+ import * as fs13 from "fs";
24846
+ import * as path16 from "path";
24413
24847
  import * as yaml7 from "js-yaml";
24414
24848
  function writeFileIfChanged(hubFolder, absPath, content, log) {
24415
24849
  const buf = Buffer.from(content, "utf-8");
24416
24850
  if (fileHasBytes(absPath, buf)) return;
24417
24851
  if (writeFileNoFollow(hubFolder, absPath, buf)) {
24418
- log.changed.push(path15.relative(hubFolder, absPath));
24852
+ log.changed.push(path16.relative(hubFolder, absPath));
24419
24853
  } else {
24420
- console.warn(` Warning: skipping ${path15.relative(hubFolder, absPath)} (destination escapes the hub folder via a symlink)`);
24854
+ console.warn(` Warning: skipping ${path16.relative(hubFolder, absPath)} (destination escapes the hub folder via a symlink)`);
24421
24855
  }
24422
24856
  }
24423
24857
  function buildEvalYamlObject(evalEntry, slug) {
@@ -24458,51 +24892,51 @@ function buildEvalYamlObject(evalEntry, slug) {
24458
24892
  }
24459
24893
  function writeHubFolder(hubFolder, payload, options = {}) {
24460
24894
  const log = { changed: [], removed: [] };
24461
- const agentsDir = path15.join(hubFolder, "agents");
24462
- if (!fs12.existsSync(hubFolder)) {
24463
- fs12.mkdirSync(hubFolder, { recursive: true });
24895
+ const agentsDir = path16.join(hubFolder, "agents");
24896
+ if (!fs13.existsSync(hubFolder)) {
24897
+ fs13.mkdirSync(hubFolder, { recursive: true });
24464
24898
  }
24465
- if (!fs12.existsSync(agentsDir)) {
24466
- fs12.mkdirSync(agentsDir, { recursive: true });
24899
+ if (!fs13.existsSync(agentsDir)) {
24900
+ fs13.mkdirSync(agentsDir, { recursive: true });
24467
24901
  }
24468
24902
  const yamlPayload = buildYamlPayload(payload);
24469
24903
  const agentFiles = extractAgentFiles(payload);
24470
24904
  const yamlContent = yaml7.dump(yamlPayload, YAML_DUMP_OPTIONS);
24471
- writeFileIfChanged(hubFolder, path15.join(hubFolder, "hub.yaml"), yamlContent, log);
24905
+ writeFileIfChanged(hubFolder, path16.join(hubFolder, "hub.yaml"), yamlContent, log);
24472
24906
  if (options.seedAgentContext ?? true) {
24473
24907
  const seeded = writeIfAbsent(
24474
24908
  hubFolder,
24475
- path15.join(hubFolder, "AGENTS.md"),
24476
- perHubAgentsMd(path15.basename(hubFolder))
24909
+ path16.join(hubFolder, "AGENTS.md"),
24910
+ perHubAgentsMd(path16.basename(hubFolder))
24477
24911
  );
24478
24912
  if (seeded) log.changed.push(seeded);
24479
24913
  }
24480
- const oldYamlPath = path15.join(hubFolder, "wayai.yaml");
24481
- if (fs12.existsSync(oldYamlPath)) {
24482
- fs12.unlinkSync(oldYamlPath);
24483
- log.removed.push(path15.relative(hubFolder, oldYamlPath));
24914
+ const oldYamlPath = path16.join(hubFolder, "wayai.yaml");
24915
+ if (fs13.existsSync(oldYamlPath)) {
24916
+ fs13.unlinkSync(oldYamlPath);
24917
+ log.removed.push(path16.relative(hubFolder, oldYamlPath));
24484
24918
  }
24485
24919
  const yamlSlugs = writeAgentYamlFiles(hubFolder, agentsDir, payload.agents || [], log);
24486
24920
  const mdSlugs = /* @__PURE__ */ new Set();
24487
24921
  for (const { slug, content } of agentFiles) {
24488
24922
  mdSlugs.add(slug);
24489
- writeFileIfChanged(hubFolder, path15.join(agentsDir, `${slug}.md`), content, log);
24923
+ writeFileIfChanged(hubFolder, path16.join(agentsDir, `${slug}.md`), content, log);
24490
24924
  }
24491
- const existingFiles = fs12.readdirSync(agentsDir);
24925
+ const existingFiles = fs13.readdirSync(agentsDir);
24492
24926
  for (const file of existingFiles) {
24493
24927
  if (file.endsWith(".yaml")) {
24494
24928
  const slug = file.slice(0, -5);
24495
24929
  if (!yamlSlugs.has(slug)) {
24496
- const orphan = path15.join(agentsDir, file);
24497
- fs12.unlinkSync(orphan);
24498
- log.removed.push(path15.relative(hubFolder, orphan));
24930
+ const orphan = path16.join(agentsDir, file);
24931
+ fs13.unlinkSync(orphan);
24932
+ log.removed.push(path16.relative(hubFolder, orphan));
24499
24933
  }
24500
24934
  } else if (file.endsWith(".md")) {
24501
24935
  const slug = file.slice(0, -3);
24502
24936
  if (!mdSlugs.has(slug)) {
24503
- const orphan = path15.join(agentsDir, file);
24504
- fs12.unlinkSync(orphan);
24505
- log.removed.push(path15.relative(hubFolder, orphan));
24937
+ const orphan = path16.join(agentsDir, file);
24938
+ fs13.unlinkSync(orphan);
24939
+ log.removed.push(path16.relative(hubFolder, orphan));
24506
24940
  }
24507
24941
  }
24508
24942
  }
@@ -24564,7 +24998,7 @@ function writeAgentYamlFiles(hubFolder, agentsDir, agents, log) {
24564
24998
  const entry = { ...agent };
24565
24999
  delete entry.instructions;
24566
25000
  const yamlContent = yaml7.dump(entry, YAML_DUMP_OPTIONS);
24567
- writeFileIfChanged(hubFolder, path15.join(agentsDir, `${slug}.yaml`), yamlContent, log);
25001
+ writeFileIfChanged(hubFolder, path16.join(agentsDir, `${slug}.yaml`), yamlContent, log);
24568
25002
  }
24569
25003
  return slugs;
24570
25004
  }
@@ -24581,27 +25015,27 @@ function extractAgentFiles(payload) {
24581
25015
  return files;
24582
25016
  }
24583
25017
  function writeEvalYamlFiles(hubFolder, evals, log) {
24584
- const evalsDir = path15.join(hubFolder, "evals");
25018
+ const evalsDir = path16.join(hubFolder, "evals");
24585
25019
  if (evals.length === 0) {
24586
- if (fs12.existsSync(evalsDir)) {
25020
+ if (fs13.existsSync(evalsDir)) {
24587
25021
  cleanEvalOrphans(hubFolder, evalsDir, /* @__PURE__ */ new Set(), log);
24588
25022
  try {
24589
- if (fs12.readdirSync(evalsDir).length === 0) fs12.rmdirSync(evalsDir);
25023
+ if (fs13.readdirSync(evalsDir).length === 0) fs13.rmdirSync(evalsDir);
24590
25024
  } catch {
24591
25025
  }
24592
25026
  }
24593
25027
  return;
24594
25028
  }
24595
- if (!fs12.existsSync(evalsDir)) {
24596
- fs12.mkdirSync(evalsDir, { recursive: true });
25029
+ if (!fs13.existsSync(evalsDir)) {
25030
+ fs13.mkdirSync(evalsDir, { recursive: true });
24597
25031
  }
24598
25032
  const writtenRelPaths = /* @__PURE__ */ new Set();
24599
25033
  for (const evalEntry of evals) {
24600
25034
  const slug = slugify(evalEntry.name);
24601
25035
  const setName = evalEntry.path && evalEntry.path.trim().length > 0 ? evalEntry.path : null;
24602
25036
  const relPath = setName ? `${setName}/${slug}.yaml` : `${slug}.yaml`;
24603
- const targetPath = path15.join(evalsDir, relPath);
24604
- if (!targetPath.startsWith(evalsDir + path15.sep)) {
25037
+ const targetPath = path16.join(evalsDir, relPath);
25038
+ if (!targetPath.startsWith(evalsDir + path16.sep)) {
24605
25039
  console.warn(` Warning: skipping eval "${evalEntry.name}" (scenario set "${setName}" escapes evals/ \u2014 possible bad backend data)`);
24606
25040
  continue;
24607
25041
  }
@@ -24612,31 +25046,31 @@ function writeEvalYamlFiles(hubFolder, evals, log) {
24612
25046
  cleanEvalOrphans(hubFolder, evalsDir, writtenRelPaths, log);
24613
25047
  }
24614
25048
  function cleanEvalOrphans(hubFolder, evalsDir, writtenRelPaths, log) {
24615
- const entries = fs12.readdirSync(evalsDir, { withFileTypes: true });
25049
+ const entries = fs13.readdirSync(evalsDir, { withFileTypes: true });
24616
25050
  for (const entry of entries) {
24617
- const fullPath = path15.join(evalsDir, entry.name);
25051
+ const fullPath = path16.join(evalsDir, entry.name);
24618
25052
  if (entry.isFile()) {
24619
25053
  if (entry.name.endsWith(".yaml") && !writtenRelPaths.has(entry.name)) {
24620
- fs12.unlinkSync(fullPath);
24621
- log.removed.push(path15.relative(hubFolder, fullPath));
25054
+ fs13.unlinkSync(fullPath);
25055
+ log.removed.push(path16.relative(hubFolder, fullPath));
24622
25056
  }
24623
25057
  continue;
24624
25058
  }
24625
25059
  if (entry.isDirectory()) {
24626
25060
  const setName = entry.name;
24627
- const subEntries = fs12.readdirSync(fullPath, { withFileTypes: true });
25061
+ const subEntries = fs13.readdirSync(fullPath, { withFileTypes: true });
24628
25062
  for (const sub of subEntries) {
24629
25063
  if (sub.isFile() && sub.name.endsWith(".yaml")) {
24630
25064
  const relPath = `${setName}/${sub.name}`;
24631
25065
  if (!writtenRelPaths.has(relPath)) {
24632
- const orphan = path15.join(fullPath, sub.name);
24633
- fs12.unlinkSync(orphan);
24634
- log.removed.push(path15.relative(hubFolder, orphan));
25066
+ const orphan = path16.join(fullPath, sub.name);
25067
+ fs13.unlinkSync(orphan);
25068
+ log.removed.push(path16.relative(hubFolder, orphan));
24635
25069
  }
24636
25070
  }
24637
25071
  }
24638
25072
  try {
24639
- if (fs12.readdirSync(fullPath).length === 0) fs12.rmdirSync(fullPath);
25073
+ if (fs13.readdirSync(fullPath).length === 0) fs13.rmdirSync(fullPath);
24640
25074
  } catch {
24641
25075
  }
24642
25076
  }
@@ -24673,19 +25107,19 @@ function buildJourneyYamlObject(journeyEntry, slug) {
24673
25107
  return out;
24674
25108
  }
24675
25109
  function writeJourneyYamlFiles(hubFolder, journeys, log) {
24676
- const journeysDir = path15.join(hubFolder, "journeys");
25110
+ const journeysDir = path16.join(hubFolder, "journeys");
24677
25111
  if (journeys.length === 0) {
24678
- if (fs12.existsSync(journeysDir)) {
25112
+ if (fs13.existsSync(journeysDir)) {
24679
25113
  cleanJourneyOrphans(hubFolder, journeysDir, /* @__PURE__ */ new Set(), log);
24680
25114
  try {
24681
- if (fs12.readdirSync(journeysDir).length === 0) fs12.rmdirSync(journeysDir);
25115
+ if (fs13.readdirSync(journeysDir).length === 0) fs13.rmdirSync(journeysDir);
24682
25116
  } catch {
24683
25117
  }
24684
25118
  }
24685
25119
  return;
24686
25120
  }
24687
- if (!fs12.existsSync(journeysDir)) {
24688
- fs12.mkdirSync(journeysDir, { recursive: true });
25121
+ if (!fs13.existsSync(journeysDir)) {
25122
+ fs13.mkdirSync(journeysDir, { recursive: true });
24689
25123
  }
24690
25124
  const writtenFiles = /* @__PURE__ */ new Set();
24691
25125
  const usedSlugs = /* @__PURE__ */ new Set();
@@ -24693,37 +25127,37 @@ function writeJourneyYamlFiles(hubFolder, journeys, log) {
24693
25127
  const slug = ensureUniqueSlug(slugify(journeyEntry.name), usedSlugs);
24694
25128
  const fileName = `${slug}.yaml`;
24695
25129
  const yamlContent = yaml7.dump(buildJourneyYamlObject(journeyEntry, slug), YAML_DUMP_OPTIONS);
24696
- writeFileIfChanged(hubFolder, path15.join(journeysDir, fileName), yamlContent, log);
25130
+ writeFileIfChanged(hubFolder, path16.join(journeysDir, fileName), yamlContent, log);
24697
25131
  writtenFiles.add(fileName);
24698
25132
  }
24699
25133
  cleanJourneyOrphans(hubFolder, journeysDir, writtenFiles, log);
24700
25134
  }
24701
25135
  function cleanJourneyOrphans(hubFolder, journeysDir, writtenFiles, log) {
24702
- const entries = fs12.readdirSync(journeysDir, { withFileTypes: true });
25136
+ const entries = fs13.readdirSync(journeysDir, { withFileTypes: true });
24703
25137
  for (const entry of entries) {
24704
25138
  if (entry.isFile() && entry.name.endsWith(".yaml") && !writtenFiles.has(entry.name)) {
24705
- const orphan = path15.join(journeysDir, entry.name);
24706
- fs12.unlinkSync(orphan);
24707
- log.removed.push(path15.relative(hubFolder, orphan));
25139
+ const orphan = path16.join(journeysDir, entry.name);
25140
+ fs13.unlinkSync(orphan);
25141
+ log.removed.push(path16.relative(hubFolder, orphan));
24708
25142
  }
24709
25143
  }
24710
25144
  }
24711
25145
  function writeResourceFiles(hubFolder, resources, log) {
24712
- const resourcesDir = path15.join(hubFolder, "resources");
25146
+ const resourcesDir = path16.join(hubFolder, "resources");
24713
25147
  const currentSlugs = /* @__PURE__ */ new Set();
24714
25148
  for (const resource of resources) {
24715
25149
  const resSlug = slugify(resource.name);
24716
25150
  currentSlugs.add(resSlug);
24717
- const resDir = path15.join(resourcesDir, resSlug);
25151
+ const resDir = path16.join(resourcesDir, resSlug);
24718
25152
  writeResourceFileTree(resDir, resource.files || [], hubFolder, log);
24719
25153
  }
24720
- if (fs12.existsSync(resourcesDir)) {
24721
- const existingDirs = fs12.readdirSync(resourcesDir, { withFileTypes: true });
25154
+ if (fs13.existsSync(resourcesDir)) {
25155
+ const existingDirs = fs13.readdirSync(resourcesDir, { withFileTypes: true });
24722
25156
  for (const entry of existingDirs) {
24723
25157
  if (entry.isDirectory() && !currentSlugs.has(entry.name)) {
24724
- const orphanDir = path15.join(resourcesDir, entry.name);
24725
- fs12.rmSync(orphanDir, { recursive: true, force: true });
24726
- log.removed.push(`${path15.relative(hubFolder, orphanDir)}/`);
25158
+ const orphanDir = path16.join(resourcesDir, entry.name);
25159
+ fs13.rmSync(orphanDir, { recursive: true, force: true });
25160
+ log.removed.push(`${path16.relative(hubFolder, orphanDir)}/`);
24727
25161
  }
24728
25162
  }
24729
25163
  }
@@ -24751,7 +25185,7 @@ var init_yaml_writer = __esm({
24751
25185
  });
24752
25186
 
24753
25187
  // src/lib/hub-materializer.ts
24754
- import * as path16 from "path";
25188
+ import * as path17 from "path";
24755
25189
  async function materializeHubFolder(hubFolder, payload, options = {}) {
24756
25190
  if (materialized.has(payload)) {
24757
25191
  throw new Error(
@@ -24761,13 +25195,15 @@ async function materializeHubFolder(hubFolder, payload, options = {}) {
24761
25195
  materialized.add(payload);
24762
25196
  requireRealHubFolder(hubFolder, true);
24763
25197
  const attachmentDownloads = rewriteEvalAttachmentsToLocalPaths(payload);
25198
+ const openingDownloads = rewriteCallOpeningsToLocalPaths(payload);
24764
25199
  const writeLog = writeHubFolder(hubFolder, payload, options);
24765
25200
  const resourceDownloads = await downloadBinaryResourceFiles(hubFolder, payload);
24766
25201
  const attachments = await downloadEvalAttachments(hubFolder, attachmentDownloads);
25202
+ const openings = await downloadCallOpenings(hubFolder, openingDownloads);
24767
25203
  return {
24768
25204
  attachmentsWritten: attachments.written,
24769
- changed: [...writeLog.changed, ...resourceDownloads.changed, ...attachments.changed],
24770
- removed: [...writeLog.removed, ...attachments.removed]
25205
+ changed: [...writeLog.changed, ...resourceDownloads.changed, ...attachments.changed, ...openings.changed],
25206
+ removed: [...writeLog.removed, ...attachments.removed, ...openings.removed]
24771
25207
  };
24772
25208
  }
24773
25209
  async function downloadBinaryResourceFiles(hubFolder, payload) {
@@ -24776,7 +25212,7 @@ async function downloadBinaryResourceFiles(hubFolder, payload) {
24776
25212
  let downloadCount = 0;
24777
25213
  for (const resource of resources) {
24778
25214
  if (!resource.files) continue;
24779
- const resDir = path16.join(hubFolder, "resources", slugify(resource.name));
25215
+ const resDir = path17.join(hubFolder, "resources", slugify(resource.name));
24780
25216
  downloadCount += await downloadBinaryFiles(resDir, resource.files, hubFolder, log);
24781
25217
  }
24782
25218
  if (downloadCount > 0) {
@@ -24790,6 +25226,7 @@ var init_hub_materializer = __esm({
24790
25226
  "use strict";
24791
25227
  init_yaml_writer();
24792
25228
  init_eval_attachments();
25229
+ init_call_openings();
24793
25230
  init_resource_files();
24794
25231
  init_fs_safety();
24795
25232
  init_utils();
@@ -24813,11 +25250,11 @@ var init_terminal_output = __esm({
24813
25250
  });
24814
25251
 
24815
25252
  // src/lib/base-workspace.ts
24816
- import * as fs13 from "fs";
24817
- import * as path17 from "path";
25253
+ import * as fs14 from "fs";
25254
+ import * as path18 from "path";
24818
25255
  import * as yaml8 from "js-yaml";
24819
25256
  function readBaseMeta(folder) {
24820
- const bytes = readFileNoFollow(folder, path17.join(folder, BASE_META_FILE));
25257
+ const bytes = readFileNoFollow(folder, path18.join(folder, BASE_META_FILE));
24821
25258
  if (bytes === null) return null;
24822
25259
  let doc;
24823
25260
  try {
@@ -24831,13 +25268,13 @@ function readBaseMeta(folder) {
24831
25268
  function listBaseFolders(basesDir) {
24832
25269
  let entries;
24833
25270
  try {
24834
- entries = fs13.readdirSync(basesDir).filter((entry) => !entry.startsWith("."));
25271
+ entries = fs14.readdirSync(basesDir).filter((entry) => !entry.startsWith("."));
24835
25272
  } catch {
24836
25273
  return [];
24837
25274
  }
24838
25275
  const out = [];
24839
25276
  for (const name of entries.sort()) {
24840
- const folder = path17.join(basesDir, name);
25277
+ const folder = path18.join(basesDir, name);
24841
25278
  if (!isDirectory(folder)) continue;
24842
25279
  const meta = readBaseMeta(folder);
24843
25280
  if (meta) out.push({ folder, meta });
@@ -24851,12 +25288,12 @@ function filterEditableBases(bases) {
24851
25288
  return bases.filter((b) => !isProductionFolder(b.meta));
24852
25289
  }
24853
25290
  function findEnclosingBaseFolder(basesDir, cwd) {
24854
- let dir = path17.resolve(cwd);
24855
- const stop = path17.resolve(basesDir);
25291
+ let dir = path18.resolve(cwd);
25292
+ const stop = path18.resolve(basesDir);
24856
25293
  while (isUnder(stop, dir)) {
24857
25294
  const meta = readBaseMeta(dir);
24858
25295
  if (meta) return { folder: dir, meta };
24859
- const parent = path17.dirname(dir);
25296
+ const parent = path18.dirname(dir);
24860
25297
  if (parent === dir) break;
24861
25298
  dir = parent;
24862
25299
  }
@@ -24864,7 +25301,7 @@ function findEnclosingBaseFolder(basesDir, cwd) {
24864
25301
  }
24865
25302
  function folderForSelector(basesDir, selector) {
24866
25303
  assertValidBaseSelector(selector);
24867
- return path17.join(basesDir, selector);
25304
+ return path18.join(basesDir, selector);
24868
25305
  }
24869
25306
  function assertValidBaseSelector(selector, source = "base") {
24870
25307
  if (!isPathSafeId(selector)) {
@@ -24897,24 +25334,24 @@ function resolveBaseTarget(gitRoot, selector, cwd = process.cwd()) {
24897
25334
  throw expected(
24898
25335
  [
24899
25336
  `Multiple bases found in ${label}/. Pass --base <id|folder-name> to choose, or run from inside a base folder:`,
24900
- ...editable.map((b) => ` ${path17.basename(b.folder)} (${b.meta.base_id ?? "not created yet"})`)
25337
+ ...editable.map((b) => ` ${path18.basename(b.folder)} (${b.meta.base_id ?? "not created yet"})`)
24901
25338
  ].join("\n")
24902
25339
  );
24903
25340
  }
24904
25341
  function targetBaseId(target, selector) {
24905
25342
  if (target.meta?.base_id) return target.meta.base_id;
24906
- if (selector && !selector.includes("/") && !selector.includes(path17.sep)) return selector;
24907
- return target.exists ? null : path17.basename(target.folder);
25343
+ if (selector && !selector.includes("/") && !selector.includes(path18.sep)) return selector;
25344
+ return target.exists ? null : path18.basename(target.folder);
24908
25345
  }
24909
25346
  function resolveBaseSelectorToId(gitRoot, selector) {
24910
- if (!gitRoot || selector.includes("/") || selector.includes(path17.sep)) return selector;
25347
+ if (!gitRoot || selector.includes("/") || selector.includes(path18.sep)) return selector;
24911
25348
  if (!isPathSafeId(selector)) return selector;
24912
- const id = readBaseMeta(path17.join(resolveBasesDir(gitRoot), selector))?.base_id;
25349
+ const id = readBaseMeta(path18.join(resolveBasesDir(gitRoot), selector))?.base_id;
24913
25350
  return typeof id === "string" && isPathSafeId(id) ? id : selector;
24914
25351
  }
24915
25352
  function hasBaseMetaFile(folder) {
24916
25353
  try {
24917
- return fs13.lstatSync(path17.join(folder, BASE_META_FILE)).isFile();
25354
+ return fs14.lstatSync(path18.join(folder, BASE_META_FILE)).isFile();
24918
25355
  } catch {
24919
25356
  return false;
24920
25357
  }
@@ -24933,7 +25370,7 @@ var init_base_workspace = __esm({
24933
25370
  });
24934
25371
 
24935
25372
  // src/lib/subtree-routing.ts
24936
- import * as path18 from "path";
25373
+ import * as path19 from "path";
24937
25374
  function readRepoDefaults(gitRoot) {
24938
25375
  const load11 = loadWorkspaceManifest(gitRoot);
24939
25376
  if (load11.kind !== "ok") return {};
@@ -24941,7 +25378,7 @@ function readRepoDefaults(gitRoot) {
24941
25378
  const str = (v) => {
24942
25379
  if (typeof v !== "string" || !v.trim()) return void 0;
24943
25380
  const value = v.trim();
24944
- if (value.includes("/") || value.includes(path18.sep) || value === "." || value === "..") {
25381
+ if (value.includes("/") || value.includes(path19.sep) || value === "." || value === "..") {
24945
25382
  console.warn(
24946
25383
  `Warning: ignoring ${JSON.stringify(value)} in ${WORKSPACE_MANIFEST_LABEL} \u2014 a default names a hub or base, not a path.`
24947
25384
  );
@@ -24973,12 +25410,12 @@ function parseRoutingTokens(args2) {
24973
25410
  return tokens2;
24974
25411
  }
24975
25412
  function firstSegment(p) {
24976
- const normalized = p.split(path18.sep).join("/");
25413
+ const normalized = p.split(path19.sep).join("/");
24977
25414
  const [head] = normalized.split("/").filter(Boolean);
24978
25415
  return head ?? p;
24979
25416
  }
24980
25417
  function resolveSelectorSubtree(layout, selector, cwd) {
24981
- const parts = selector.split(path18.sep).join("/").split("/").filter(Boolean);
25418
+ const parts = selector.split(path19.sep).join("/").split("/").filter(Boolean);
24982
25419
  const qualified = parts[0] === WAYAI_LAYOUT.wsDir ? parts.slice(1) : parts;
24983
25420
  if (qualified.length > 1) {
24984
25421
  if (qualified[0] === WAYAI_LAYOUT.hubsSubdir) return { kind: "hubs", target: qualified[1] };
@@ -24986,14 +25423,14 @@ function resolveSelectorSubtree(layout, selector, cwd) {
24986
25423
  }
24987
25424
  if (!layout) return { kind: "unknown" };
24988
25425
  const { hubsDir, basesDir } = layout;
24989
- if (selector.includes("/") || selector.includes(path18.sep)) {
24990
- const abs = path18.resolve(cwd, selector);
24991
- if (isUnder(hubsDir, abs)) return { kind: "hubs", target: firstSegment(path18.relative(hubsDir, abs)) };
24992
- if (isUnder(basesDir, abs)) return { kind: "bases", target: firstSegment(path18.relative(basesDir, abs)) };
25426
+ if (selector.includes("/") || selector.includes(path19.sep)) {
25427
+ const abs = path19.resolve(cwd, selector);
25428
+ if (isUnder(hubsDir, abs)) return { kind: "hubs", target: firstSegment(path19.relative(hubsDir, abs)) };
25429
+ if (isUnder(basesDir, abs)) return { kind: "bases", target: firstSegment(path19.relative(basesDir, abs)) };
24993
25430
  return { kind: "unknown" };
24994
25431
  }
24995
- const inHubs = isDirectory(path18.join(hubsDir, selector));
24996
- const inBases = isDirectory(path18.join(basesDir, selector));
25432
+ const inHubs = isDirectory(path19.join(hubsDir, selector));
25433
+ const inBases = isDirectory(path19.join(basesDir, selector));
24997
25434
  if (inHubs && inBases) return { kind: "both", target: selector };
24998
25435
  if (inHubs) return { kind: "hubs", target: selector };
24999
25436
  if (inBases) return { kind: "bases", target: selector };
@@ -25006,8 +25443,8 @@ function listCandidates(layout) {
25006
25443
  ];
25007
25444
  const bases = filterEditableBases(listBaseFolders(layout.basesDir)).map((b) => b.folder);
25008
25445
  return [
25009
- ...hubs.map((folder) => ({ subtree: "hubs", name: path18.basename(folder) })),
25010
- ...bases.map((folder) => ({ subtree: "bases", name: path18.basename(folder) }))
25446
+ ...hubs.map((folder) => ({ subtree: "hubs", name: path19.basename(folder) })),
25447
+ ...bases.map((folder) => ({ subtree: "bases", name: path19.basename(folder) }))
25011
25448
  ];
25012
25449
  }
25013
25450
  function mixedInvocationRefusal(verb, hubTarget, baseTarget) {
@@ -25148,12 +25585,12 @@ async function createDataClient(orgId) {
25148
25585
  return orgId2;
25149
25586
  }
25150
25587
  return {
25151
- async request(method, path35, body) {
25152
- const envelope = await api.dataRequest(method, path35, body, org);
25588
+ async request(method, path36, body) {
25589
+ const envelope = await api.dataRequest(method, path36, body, org);
25153
25590
  return envelope.data;
25154
25591
  },
25155
- async requestRaw(method, path35, body) {
25156
- const body_ = await api.dataRequest(method, path35, body, org);
25592
+ async requestRaw(method, path36, body) {
25593
+ const body_ = await api.dataRequest(method, path36, body, org);
25157
25594
  return body_;
25158
25595
  },
25159
25596
  async collectPages(makePath) {
@@ -25228,7 +25665,7 @@ var init_client = __esm({
25228
25665
  });
25229
25666
 
25230
25667
  // src/data/helpers.ts
25231
- import { readFileSync as readFileSync14 } from "fs";
25668
+ import { readFileSync as readFileSync15 } from "fs";
25232
25669
  function pathSegment(id, label = "id") {
25233
25670
  if (!isPathSafeId(id)) {
25234
25671
  throw expected(`Invalid ${label}: ${JSON.stringify(id)}. An id may use ${PATH_SAFE_ID_RULE}.`);
@@ -25256,7 +25693,7 @@ function parseData(data, flag) {
25256
25693
  let text = data;
25257
25694
  if (source !== void 0) {
25258
25695
  try {
25259
- text = readFileSync14(source, "utf-8");
25696
+ text = readFileSync15(source, "utf-8");
25260
25697
  } catch (e) {
25261
25698
  throw expected(`${prefix}${source}: ${e instanceof Error ? e.message : "could not be read"}`);
25262
25699
  }
@@ -25381,8 +25818,8 @@ var init_types2 = __esm({
25381
25818
  });
25382
25819
 
25383
25820
  // src/data/config-as-code/config-writer.ts
25384
- import * as fs14 from "fs";
25385
- import * as path19 from "path";
25821
+ import * as fs15 from "fs";
25822
+ import * as path20 from "path";
25386
25823
  import * as yaml9 from "js-yaml";
25387
25824
  function dump5(value) {
25388
25825
  return yaml9.dump(value, YAML_DUMP_OPTIONS);
@@ -25416,15 +25853,15 @@ function pruneOrphans(folder, dir, keep, log) {
25416
25853
  if (!ensureRealSubdirNoSymlink(folder, dir, false)) return;
25417
25854
  let entries;
25418
25855
  try {
25419
- entries = fs14.readdirSync(dir);
25856
+ entries = fs15.readdirSync(dir);
25420
25857
  } catch {
25421
25858
  return;
25422
25859
  }
25423
25860
  for (const file of entries) {
25424
25861
  if (!file.endsWith(".yaml") || keep.has(file)) continue;
25425
- const abs = path19.join(dir, file);
25426
- fs14.rmSync(abs);
25427
- log.removed.push(path19.relative(folder, abs));
25862
+ const abs = path20.join(dir, file);
25863
+ fs15.rmSync(abs);
25864
+ log.removed.push(path20.relative(folder, abs));
25428
25865
  }
25429
25866
  }
25430
25867
  function metaFileObject(meta) {
@@ -25436,16 +25873,16 @@ function metaFileObject(meta) {
25436
25873
  }
25437
25874
  function writeBaseFolder(folder, meta, config) {
25438
25875
  const delta = { changed: [], removed: [] };
25439
- const parent = path19.dirname(folder);
25440
- fs14.mkdirSync(parent, { recursive: true });
25876
+ const parent = path20.dirname(folder);
25877
+ fs15.mkdirSync(parent, { recursive: true });
25441
25878
  if (!ensureRealSubdirNoSymlink(parent, folder, true)) {
25442
25879
  throw expected(
25443
25880
  `Refusing to write ${folder}: the path crosses a symlink. Remove it and pull again.`
25444
25881
  );
25445
25882
  }
25446
- writeFileIfChanged(folder, path19.join(folder, BASE_META_FILE), dump5(metaFileObject(meta)), delta);
25883
+ writeFileIfChanged(folder, path20.join(folder, BASE_META_FILE), dump5(metaFileObject(meta)), delta);
25447
25884
  for (const kind of ENTITY_KINDS) {
25448
- const dir = path19.join(folder, ENTITY_DIRS[kind]);
25885
+ const dir = path20.join(folder, ENTITY_DIRS[kind]);
25449
25886
  const entities = config[kind] ?? [];
25450
25887
  const keep = /* @__PURE__ */ new Set();
25451
25888
  for (const raw of entities) {
@@ -25457,20 +25894,20 @@ function writeBaseFolder(folder, meta, config) {
25457
25894
  }
25458
25895
  const file = `${id}.yaml`;
25459
25896
  keep.add(file);
25460
- writeFileIfChanged(folder, path19.join(dir, file), dump5(toFileObject(kind, entity)), delta);
25897
+ writeFileIfChanged(folder, path20.join(dir, file), dump5(toFileObject(kind, entity)), delta);
25461
25898
  }
25462
25899
  pruneOrphans(folder, dir, keep, delta);
25463
25900
  }
25464
25901
  for (const deprecated of DEPRECATED_ENTITY_DIRS) {
25465
- const dir = path19.join(folder, deprecated);
25902
+ const dir = path20.join(folder, deprecated);
25466
25903
  if (ensureRealSubdirNoSymlink(folder, dir, false)) {
25467
- fs14.rmSync(dir, { recursive: true, force: true });
25904
+ fs15.rmSync(dir, { recursive: true, force: true });
25468
25905
  }
25469
25906
  }
25470
25907
  return delta;
25471
25908
  }
25472
25909
  function markProductionMirror(folder, baseId) {
25473
- const file = path19.join(folder, BASE_META_FILE);
25910
+ const file = path20.join(folder, BASE_META_FILE);
25474
25911
  try {
25475
25912
  const body = readFileNoFollow(folder, file)?.toString("utf-8");
25476
25913
  if (body === void 0 || body.startsWith(MIRROR_MARKER_PREFIX)) return;
@@ -25482,7 +25919,7 @@ function markProductionMirror(folder, baseId) {
25482
25919
  }
25483
25920
  function ensureMirrorIgnored(folder) {
25484
25921
  try {
25485
- writeFileNoFollow(folder, path19.join(folder, ".gitignore"), Buffer.from(MIRROR_GITIGNORE, "utf-8"));
25922
+ writeFileNoFollow(folder, path20.join(folder, ".gitignore"), Buffer.from(MIRROR_GITIGNORE, "utf-8"));
25486
25923
  } catch {
25487
25924
  }
25488
25925
  }
@@ -25616,8 +26053,8 @@ var init_api = __esm({
25616
26053
  });
25617
26054
 
25618
26055
  // src/data/config-as-code/config-parser.ts
25619
- import * as fs15 from "fs";
25620
- import * as path20 from "path";
26056
+ import * as fs16 from "fs";
26057
+ import * as path21 from "path";
25621
26058
  import * as yaml10 from "js-yaml";
25622
26059
  function readEntityDir(folder, dir) {
25623
26060
  if (!ensureRealSubdirNoSymlink(folder, dir, false)) {
@@ -25625,9 +26062,9 @@ function readEntityDir(folder, dir) {
25625
26062
  }
25626
26063
  if (!isDirectory(dir)) return [];
25627
26064
  const out = [];
25628
- for (const file of fs15.readdirSync(dir).sort()) {
26065
+ for (const file of fs16.readdirSync(dir).sort()) {
25629
26066
  if (!file.endsWith(".yaml")) continue;
25630
- const abs = path20.join(dir, file);
26067
+ const abs = path21.join(dir, file);
25631
26068
  const bytes = readFileNoFollow(folder, abs);
25632
26069
  if (bytes === null) {
25633
26070
  throw expected(`Refusing to read ${abs}: it is a symlink, not a config file.`);
@@ -25642,7 +26079,7 @@ function readEntityDir(folder, dir) {
25642
26079
  throw expected(`${abs} is empty or not a YAML object`);
25643
26080
  }
25644
26081
  const entity = parsed;
25645
- const stem = path20.basename(file, ".yaml");
26082
+ const stem = path21.basename(file, ".yaml");
25646
26083
  if (entity.id === void 0) entity.id = stem;
25647
26084
  else if (String(entity.id) !== stem) {
25648
26085
  throw expected(`${abs}: id "${String(entity.id)}" does not match filename "${stem}.yaml"`);
@@ -25655,10 +26092,10 @@ function parseBaseFolder(folder) {
25655
26092
  const meta = readBaseMeta(folder);
25656
26093
  if (!meta) {
25657
26094
  throw expected(
25658
- hasBaseMetaFile(folder) ? `${path20.join(folder, BASE_META_FILE)} could not be parsed as a YAML mapping. Fix it, or delete it and pull again.` : `No ${BASE_META_FILE} found in ${folder}`
26095
+ hasBaseMetaFile(folder) ? `${path21.join(folder, BASE_META_FILE)} could not be parsed as a YAML mapping. Fix it, or delete it and pull again.` : `No ${BASE_META_FILE} found in ${folder}`
25659
26096
  );
25660
26097
  }
25661
- const read = (kind) => readEntityDir(folder, path20.join(folder, ENTITY_DIRS[kind]));
26098
+ const read = (kind) => readEntityDir(folder, path21.join(folder, ENTITY_DIRS[kind]));
25662
26099
  const config = {
25663
26100
  record_types: read("record_types"),
25664
26101
  relationship_types: read("relationship_types"),
@@ -25762,7 +26199,7 @@ __export(sync_exports, {
25762
26199
  pullBase: () => pullBase,
25763
26200
  pushBase: () => pushBase
25764
26201
  });
25765
- import * as path21 from "path";
26202
+ import * as path22 from "path";
25766
26203
  function parseArgs4(args2) {
25767
26204
  return {
25768
26205
  autoConfirm: args2.includes("--yes") || args2.includes("-y"),
@@ -25779,7 +26216,7 @@ async function writeProductionMirror(client, basesDir, prodId, record) {
25779
26216
  throw expected(`Refusing to mirror base ${JSON.stringify(prodId)}: not a usable base id.`);
25780
26217
  }
25781
26218
  const config = await getConfig(client, prodId);
25782
- const folder = path21.join(basesDir, prodId);
26219
+ const folder = path22.join(basesDir, prodId);
25783
26220
  writeBaseFolder(folder, { ...metaFromRecord(record, prodId), environment: "production" }, config);
25784
26221
  markProductionMirror(folder, prodId);
25785
26222
  ensureMirrorIgnored(folder);
@@ -25819,7 +26256,7 @@ async function pullBase(gitRootOrNull, selector, args2) {
25819
26256
  assertInScope("bases", baseId);
25820
26257
  if (target.exists && !autoConfirm) {
25821
26258
  const ok = await confirm(
25822
- `Overwrite local files in ${path21.relative(gitRoot, target.folder)} with the server config for "${sanitizeTerminalText(baseId)}"?`
26259
+ `Overwrite local files in ${path22.relative(gitRoot, target.folder)} with the server config for "${sanitizeTerminalText(baseId)}"?`
25823
26260
  );
25824
26261
  if (!ok) {
25825
26262
  console.log("Cancelled.");
@@ -25859,7 +26296,7 @@ async function createDeclaredPreview(client, target, parsed, autoConfirm) {
25859
26296
  "base.yaml needs a base_id (an existing preview) or an origin_base_id (to create one)."
25860
26297
  );
25861
26298
  }
25862
- const name = meta.name ?? path21.basename(target.folder);
26299
+ const name = meta.name ?? path22.basename(target.folder);
25863
26300
  assertScopeAllowsCreation("bases", name);
25864
26301
  if (!autoConfirm) {
25865
26302
  const ok = await confirm(
@@ -25895,12 +26332,12 @@ async function pushBase(gitRootOrNull, selector, args2) {
25895
26332
  const { meta, config } = parsed;
25896
26333
  if (isProductionFolder(meta)) {
25897
26334
  throw expected(
25898
- `${path21.relative(gitRoot, target.folder)} is a read-only production mirror. Push operates on previews \u2014 edit the linked preview and promote with \`wayai bases promote\`.`
26335
+ `${path22.relative(gitRoot, target.folder)} is a read-only production mirror. Push operates on previews \u2014 edit the linked preview and promote with \`wayai bases promote\`.`
25899
26336
  );
25900
26337
  }
25901
26338
  if (!meta.base_id && dryRun) {
25902
26339
  console.log(
25903
- `Dry run \u2014 nothing applied. ${path21.relative(gitRoot, target.folder)} has no base_id yet, so a real push would first create a preview from "${sanitizeTerminalText(meta.origin_base_id ?? "<origin_base_id>")}".`
26340
+ `Dry run \u2014 nothing applied. ${path22.relative(gitRoot, target.folder)} has no base_id yet, so a real push would first create a preview from "${sanitizeTerminalText(meta.origin_base_id ?? "<origin_base_id>")}".`
25904
26341
  );
25905
26342
  return;
25906
26343
  }
@@ -26012,8 +26449,8 @@ __export(push_exports, {
26012
26449
  shouldWarnIgnoredPreviewLabel: () => shouldWarnIgnoredPreviewLabel,
26013
26450
  syncAfterPush: () => syncAfterPush
26014
26451
  });
26015
- import * as fs16 from "fs";
26016
- import * as path22 from "path";
26452
+ import * as fs17 from "fs";
26453
+ import * as path23 from "path";
26017
26454
  import * as yaml11 from "js-yaml";
26018
26455
  function parseArgs5(args2) {
26019
26456
  let autoConfirm = false;
@@ -26122,12 +26559,12 @@ function printLocalFileChanges(delta) {
26122
26559
  }
26123
26560
  async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, remoteConfig) {
26124
26561
  requireRealHubFolder(hubFolder, false);
26125
- const agentsDir = path22.join(hubFolder, "agents");
26562
+ const agentsDir = path23.join(hubFolder, "agents");
26126
26563
  let agentsWithIds = [];
26127
- if (fs16.existsSync(agentsDir)) {
26128
- const yamlFiles = fs16.readdirSync(agentsDir).filter((f) => f.endsWith(".yaml"));
26564
+ if (fs17.existsSync(agentsDir)) {
26565
+ const yamlFiles = fs17.readdirSync(agentsDir).filter((f) => f.endsWith(".yaml"));
26129
26566
  for (const file of yamlFiles) {
26130
- const content = readRealFileOrThrow(hubFolder, path22.join(agentsDir, file)) ?? "";
26567
+ const content = readRealFileOrThrow(hubFolder, path23.join(agentsDir, file)) ?? "";
26131
26568
  try {
26132
26569
  const agent = yaml11.load(content);
26133
26570
  if (agent?.id && agent.name) {
@@ -26173,18 +26610,18 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
26173
26610
  }
26174
26611
  }
26175
26612
  if (renames.length === 0) return;
26176
- if (!fs16.existsSync(agentsDir)) return;
26177
- for (const file of fs16.readdirSync(agentsDir)) {
26613
+ if (!fs17.existsSync(agentsDir)) return;
26614
+ for (const file of fs17.readdirSync(agentsDir)) {
26178
26615
  if (file.startsWith("__rename_temp_") && (file.endsWith(".md") || file.endsWith(".yaml"))) {
26179
26616
  console.warn(` Warning: removing orphaned temp file agents/${file}`);
26180
- fs16.unlinkSync(path22.join(agentsDir, file));
26617
+ fs17.unlinkSync(path23.join(agentsDir, file));
26181
26618
  }
26182
26619
  }
26183
26620
  const renameFileIfExists = (dir, oldName, newName) => {
26184
- const oldPath = path22.join(dir, oldName);
26185
- const newPath = path22.join(dir, newName);
26186
- if (!fs16.existsSync(oldPath)) return false;
26187
- fs16.renameSync(oldPath, newPath);
26621
+ const oldPath = path23.join(dir, oldName);
26622
+ const newPath = path23.join(dir, newName);
26623
+ if (!fs17.existsSync(oldPath)) return false;
26624
+ fs17.renameSync(oldPath, newPath);
26188
26625
  return true;
26189
26626
  };
26190
26627
  const oldSlugs = new Set(renames.map((r) => r.oldSlug));
@@ -26217,9 +26654,9 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
26217
26654
  }
26218
26655
  } else {
26219
26656
  for (const { oldSlug, newSlug } of renames) {
26220
- const hasOldFile = extensions.some((ext) => fs16.existsSync(path22.join(agentsDir, `${oldSlug}${ext}`)));
26657
+ const hasOldFile = extensions.some((ext) => fs17.existsSync(path23.join(agentsDir, `${oldSlug}${ext}`)));
26221
26658
  if (!hasOldFile) continue;
26222
- const hasNewFile = extensions.some((ext) => fs16.existsSync(path22.join(agentsDir, `${newSlug}${ext}`)));
26659
+ const hasNewFile = extensions.some((ext) => fs17.existsSync(path23.join(agentsDir, `${newSlug}${ext}`)));
26223
26660
  if (hasNewFile) {
26224
26661
  console.warn(` Warning: skipping rename agents/${oldSlug}.* \u2192 agents/${newSlug}.* (target already exists)`);
26225
26662
  continue;
@@ -26246,7 +26683,7 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
26246
26683
  );
26247
26684
  if (updatedYaml !== mainYamlContent) {
26248
26685
  writeFileNoFollow(hubFolder, mainYamlPath, Buffer.from(updatedYaml, "utf-8"));
26249
- console.log(` Updated instructions paths in ${path22.basename(mainYamlPath)}`);
26686
+ console.log(` Updated instructions paths in ${path23.basename(mainYamlPath)}`);
26250
26687
  }
26251
26688
  }
26252
26689
  }
@@ -26314,7 +26751,7 @@ async function pushSingleHub(client, hubId, hubFolder, autoConfirm, organization
26314
26751
  function selectExistingHub(workspaceDir, allHubs, selector, wsLabel) {
26315
26752
  if (selector) {
26316
26753
  const match = allHubs.find(
26317
- (h) => h.hubId === selector || path22.basename(h.hubFolder) === selector
26754
+ (h) => h.hubId === selector || path23.basename(h.hubFolder) === selector
26318
26755
  );
26319
26756
  if (!match) {
26320
26757
  console.error(`No hub matching --hub ${selector} found in ${wsLabel}/.`);
@@ -26383,7 +26820,7 @@ function reportUnresolvedPushTarget(reason, existingHubs, newHubs, selector, wsL
26383
26820
  if (existingHubs.length > 0) {
26384
26821
  console.error(`No pushable hub found in ${wsLabel}/ \u2014 only read-only production mirror folder(s). Edit the linked preview hub, pull one, or create a new hub with \`wayai create\`:`);
26385
26822
  for (const h of existingHubs) {
26386
- console.error(` ${path22.basename(h.hubFolder)} (${h.hubId}, production mirror)`);
26823
+ console.error(` ${path23.basename(h.hubFolder)} (${h.hubId}, production mirror)`);
26387
26824
  }
26388
26825
  } else {
26389
26826
  console.error(`No hub folders found. Create hub files in ${wsLabel}/<hub>/hub.yaml with \`hub: { name: ... }\` and run \`wayai push\` (or \`wayai create\`).`);
@@ -26396,10 +26833,10 @@ function reportUnresolvedPushTarget(reason, existingHubs, newHubs, selector, wsL
26396
26833
  console.error(`Multiple hub folders found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
26397
26834
  }
26398
26835
  for (const h of existingHubs) {
26399
- console.error(` ${path22.basename(h.hubFolder)} (${h.hubId})`);
26836
+ console.error(` ${path23.basename(h.hubFolder)} (${h.hubId})`);
26400
26837
  }
26401
26838
  for (const h of newHubs) {
26402
- console.error(` ${path22.basename(h.hubFolder)} (new \u2014 "${h.hubName}")`);
26839
+ console.error(` ${path23.basename(h.hubFolder)} (new \u2014 "${h.hubName}")`);
26403
26840
  }
26404
26841
  process.exit(1);
26405
26842
  }
@@ -26420,7 +26857,7 @@ async function pushCommand(args2) {
26420
26857
  const client = new ApiClient({ apiUrl: config.api_url, accessToken });
26421
26858
  const workspaceDir = resolveWorkspaceDir();
26422
26859
  const wsLabel = hubsDirLabel(gitRoot);
26423
- if (!fs16.existsSync(workspaceDir)) {
26860
+ if (!fs17.existsSync(workspaceDir)) {
26424
26861
  console.error(`No ${wsLabel}/ directory found. Run \`wayai pull\` first or create hub files in ${wsLabel}/<hub>/hub.yaml.`);
26425
26862
  process.exit(1);
26426
26863
  }
@@ -26439,8 +26876,8 @@ async function pushCommand(args2) {
26439
26876
  if (label) {
26440
26877
  console.warn("Note: --label is only used when creating a new hub. To change an existing hub's label, use `wayai relabel`.");
26441
26878
  }
26442
- console.log(`Target hub: ${path22.basename(existing.hubFolder)} (${existing.hubId})`);
26443
- assertInScope("hubs", existing.hubId, path22.basename(existing.hubFolder));
26879
+ console.log(`Target hub: ${path23.basename(existing.hubFolder)} (${existing.hubId})`);
26880
+ assertInScope("hubs", existing.hubId, path23.basename(existing.hubFolder));
26444
26881
  await pushSingleHub(client, existing.hubId, existing.hubFolder, autoConfirm, organizationId);
26445
26882
  return;
26446
26883
  }
@@ -26477,8 +26914,8 @@ __export(pull_exports, {
26477
26914
  resolveHubTarget: () => resolveHubTarget,
26478
26915
  writeProductionMirror: () => writeProductionMirror2
26479
26916
  });
26480
- import * as fs17 from "fs";
26481
- import * as path23 from "path";
26917
+ import * as fs18 from "fs";
26918
+ import * as path24 from "path";
26482
26919
  function parseArgs6(args2) {
26483
26920
  return { autoConfirm: args2.includes("--yes") || args2.includes("-y") };
26484
26921
  }
@@ -26487,7 +26924,7 @@ function resolveHubTarget(workspaceDir, selector) {
26487
26924
  const allHubs = scanWorkspaceHubs(workspaceDir);
26488
26925
  if (selector) {
26489
26926
  const match = allHubs.find(
26490
- (h) => h.hubId === selector || path23.basename(h.hubFolder) === selector
26927
+ (h) => h.hubId === selector || path24.basename(h.hubFolder) === selector
26491
26928
  );
26492
26929
  if (match) return { hubId: match.hubId, hubFolder: match.hubFolder };
26493
26930
  if (UUID_RE2.test(selector)) return { hubId: selector, hubFolder: null };
@@ -26504,7 +26941,7 @@ function resolveHubTarget(workspaceDir, selector) {
26504
26941
  }
26505
26942
  console.error(`Multiple hubs found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
26506
26943
  for (const h of previewHubs) {
26507
- console.error(` ${path23.basename(h.hubFolder)} (${h.hubId})`);
26944
+ console.error(` ${path24.basename(h.hubFolder)} (${h.hubId})`);
26508
26945
  }
26509
26946
  process.exit(1);
26510
26947
  }
@@ -26544,7 +26981,7 @@ async function pullCommand(args2) {
26544
26981
  payload.preview_label,
26545
26982
  payload.branch_name
26546
26983
  );
26547
- fs17.mkdirSync(path23.dirname(hubFolder), { recursive: true });
26984
+ fs18.mkdirSync(path24.dirname(hubFolder), { recursive: true });
26548
26985
  console.log("Writing hub configuration...");
26549
26986
  await materializeHubFolder(hubFolder, payload);
26550
26987
  const finalFolder = autoRenameHubFolder(hubFolder, payload.hub.name, payload.hub_environment, payload.hub_id, payload.preview_label, payload.branch_name);
@@ -26599,7 +27036,7 @@ async function pullCommand(args2) {
26599
27036
  }
26600
27037
  async function writeProductionMirror2(workspaceDir, prodPayload) {
26601
27038
  const folder = resolveHubFolder(workspaceDir, prodPayload.hub_id, prodPayload.hub.name, "production", null, null);
26602
- fs17.mkdirSync(path23.dirname(folder), { recursive: true });
27039
+ fs18.mkdirSync(path24.dirname(folder), { recursive: true });
26603
27040
  await materializeHubFolder(folder, prodPayload, { seedAgentContext: false });
26604
27041
  const finalFolder = autoRenameHubFolder(folder, prodPayload.hub.name, "production", prodPayload.hub_id, null, null);
26605
27042
  prependMirrorMarker(finalFolder, prodPayload.hub_id);
@@ -26615,13 +27052,13 @@ async function mirrorLinkedProduction2(client, workspaceDir, productionHubId, or
26615
27052
  }
26616
27053
  }
26617
27054
  function prependMirrorMarker(hubFolder, productionHubId) {
26618
- const hubYaml = path23.join(hubFolder, "hub.yaml");
27055
+ const hubYaml = path24.join(hubFolder, "hub.yaml");
26619
27056
  try {
26620
- const content = fs17.readFileSync(hubYaml, "utf-8");
27057
+ const content = fs18.readFileSync(hubYaml, "utf-8");
26621
27058
  if (content.startsWith(MIRROR_MARKER_PREFIX2)) return;
26622
27059
  const marker = `${MIRROR_MARKER_PREFIX2} ${productionHubId}. Edits are ignored; push is blocked. Edit the linked preview hub instead.
26623
27060
  `;
26624
- fs17.writeFileSync(hubYaml, marker + content, "utf-8");
27061
+ fs18.writeFileSync(hubYaml, marker + content, "utf-8");
26625
27062
  } catch {
26626
27063
  }
26627
27064
  }
@@ -26665,8 +27102,8 @@ var create_exports = {};
26665
27102
  __export(create_exports, {
26666
27103
  createCommand: () => createCommand
26667
27104
  });
26668
- import * as path24 from "path";
26669
- import * as fs18 from "fs";
27105
+ import * as path25 from "path";
27106
+ import * as fs19 from "fs";
26670
27107
  function parseArgs7(args2) {
26671
27108
  let autoConfirm = false;
26672
27109
  let folderSelector;
@@ -26693,7 +27130,7 @@ async function createCommand(args2) {
26693
27130
  const gitRoot = findGitRoot();
26694
27131
  const wsLabel = hubsDirLabel(gitRoot);
26695
27132
  if (gitRoot) warnLayoutOnce(gitRoot);
26696
- if (!fs18.existsSync(workspaceDir)) {
27133
+ if (!fs19.existsSync(workspaceDir)) {
26697
27134
  console.error(`No ${wsLabel}/ directory found. Create hub files in ${wsLabel}/<hub>/hub.yaml with \`hub: { name: ... }\` first.`);
26698
27135
  process.exit(1);
26699
27136
  }
@@ -26702,7 +27139,7 @@ async function createCommand(args2) {
26702
27139
  const resolution = resolveNewHubForCreate(workspaceDir, existingHubs, newHubs, folderSelector);
26703
27140
  if (!resolution.ok) {
26704
27141
  if (resolution.reason === "exists") {
26705
- const folder = path24.basename(resolution.existing.hubFolder);
27142
+ const folder = path25.basename(resolution.existing.hubFolder);
26706
27143
  console.error(`Hub "${folder}" already exists (${resolution.existing.hubId}). Use \`wayai push --hub ${folder}\` to update it.`);
26707
27144
  process.exit(1);
26708
27145
  }
@@ -26716,7 +27153,7 @@ async function createCommand(args2) {
26716
27153
  }
26717
27154
  console.error(`Multiple new hub folders found in ${wsLabel}/. Pass the folder name (\`wayai create <folder>\`) or run from inside one:`);
26718
27155
  for (const h of newHubs) {
26719
- console.error(` ${path24.basename(h.hubFolder)} (new \u2014 "${h.hubName}")`);
27156
+ console.error(` ${path25.basename(h.hubFolder)} (new \u2014 "${h.hubName}")`);
26720
27157
  }
26721
27158
  process.exit(1);
26722
27159
  }
@@ -26827,8 +27264,8 @@ var replicate_exports = {};
26827
27264
  __export(replicate_exports, {
26828
27265
  replicateCommand: () => replicateCommand
26829
27266
  });
26830
- import * as fs19 from "fs";
26831
- import * as path25 from "path";
27267
+ import * as fs20 from "fs";
27268
+ import * as path26 from "path";
26832
27269
  function parseArgs9(args2) {
26833
27270
  let label;
26834
27271
  let hubSelector;
@@ -26874,8 +27311,8 @@ async function replicateCommand(args2) {
26874
27311
  payload.preview_label,
26875
27312
  payload.branch_name
26876
27313
  );
26877
- const folderPreExisted = fs19.existsSync(hubFolder);
26878
- fs19.mkdirSync(path25.dirname(hubFolder), { recursive: true });
27314
+ const folderPreExisted = fs20.existsSync(hubFolder);
27315
+ fs20.mkdirSync(path26.dirname(hubFolder), { recursive: true });
26879
27316
  const delta = await materializeHubFolder(hubFolder, payload);
26880
27317
  hubFolder = autoRenameHubFolder(
26881
27318
  hubFolder,
@@ -26887,8 +27324,8 @@ async function replicateCommand(args2) {
26887
27324
  );
26888
27325
  seedScopeIfEmpty("hubs", previewHubId);
26889
27326
  if (folderPreExisted) printLocalFileChanges(delta);
26890
- console.log(`Preview written to ${path25.basename(hubFolder)}`);
26891
- console.log(` Switch to it with: wayai use ${path25.basename(hubFolder)}`);
27327
+ console.log(`Preview written to ${path26.basename(hubFolder)}`);
27328
+ console.log(` Switch to it with: wayai use ${path26.basename(hubFolder)}`);
26892
27329
  }
26893
27330
  var init_replicate = __esm({
26894
27331
  "src/commands/replicate.ts"() {
@@ -26911,7 +27348,7 @@ var relabel_exports = {};
26911
27348
  __export(relabel_exports, {
26912
27349
  relabelCommand: () => relabelCommand
26913
27350
  });
26914
- import * as path26 from "path";
27351
+ import * as path27 from "path";
26915
27352
  function parseArgs10(args2) {
26916
27353
  let label;
26917
27354
  let clear = false;
@@ -26955,7 +27392,7 @@ async function relabelCommand(args2) {
26955
27392
  } else {
26956
27393
  console.error(`Multiple hubs found in ${wsLabel}/. Pass --hub <uuid|folder-name> to choose, or run from inside a hub folder:`);
26957
27394
  for (const h of previewHubs) {
26958
- console.error(` ${path26.basename(h.hubFolder)} (${h.hubId})`);
27395
+ console.error(` ${path27.basename(h.hubFolder)} (${h.hubId})`);
26959
27396
  }
26960
27397
  }
26961
27398
  process.exit(1);
@@ -26964,7 +27401,7 @@ async function relabelCommand(args2) {
26964
27401
  console.log("This is a read-only production mirror \u2014 production hubs have no preview label. Relabel the linked preview hub instead.");
26965
27402
  return;
26966
27403
  }
26967
- assertInScope("hubs", target.hubId, path26.basename(target.hubFolder));
27404
+ assertInScope("hubs", target.hubId, path27.basename(target.hubFolder));
26968
27405
  console.log(normalizedLabel ? `Setting preview label to "${normalizedLabel}"...` : "Clearing preview label...");
26969
27406
  const { data } = await client.relabelPreview(target.hubId, normalizedLabel);
26970
27407
  const row = data[0];
@@ -26980,7 +27417,7 @@ async function relabelCommand(args2) {
26980
27417
  );
26981
27418
  console.log(serverLabel ? `Preview label set to "${serverLabel}".` : "Preview label cleared.");
26982
27419
  if (finalFolder !== target.hubFolder) {
26983
- console.log(`Hub folder is now ${path26.basename(finalFolder)}`);
27420
+ console.log(`Hub folder is now ${path27.basename(finalFolder)}`);
26984
27421
  }
26985
27422
  }
26986
27423
  var init_relabel = __esm({
@@ -27006,7 +27443,7 @@ __export(publish_exports, {
27006
27443
  renderHubDiff: () => renderHubDiff,
27007
27444
  runPublish: () => runPublish
27008
27445
  });
27009
- import * as path27 from "path";
27446
+ import * as path28 from "path";
27010
27447
  function parseArgs11(args2) {
27011
27448
  let autoConfirm = false;
27012
27449
  let hubSelector;
@@ -27120,7 +27557,7 @@ async function publishCommand(args2) {
27120
27557
  return;
27121
27558
  }
27122
27559
  }
27123
- assertInScope("hubs", hubId, hubFolder ? path27.basename(hubFolder) : void 0);
27560
+ assertInScope("hubs", hubId, hubFolder ? path28.basename(hubFolder) : void 0);
27124
27561
  await runPublish(client, { hubId, localConfig, organizationId, autoConfirm });
27125
27562
  }
27126
27563
  var STATUS_STYLE;
@@ -27149,7 +27586,7 @@ var init_publish = __esm({
27149
27586
  });
27150
27587
 
27151
27588
  // src/lib/scope-selector.ts
27152
- import * as path28 from "path";
27589
+ import * as path29 from "path";
27153
27590
  function findAddFlag(args2) {
27154
27591
  return args2.find((arg) => arg === "--add" || arg.startsWith("--add="));
27155
27592
  }
@@ -27203,7 +27640,7 @@ function resolveHubSelectorToId(gitRoot, selector) {
27203
27640
  const match = findHubByFolderName(workspaceDir, selector);
27204
27641
  if (match) return match.hubId;
27205
27642
  const newHubs = scanNewHubs(workspaceDir);
27206
- const pending = newHubs.find((h) => path28.basename(h.hubFolder) === selector);
27643
+ const pending = newHubs.find((h) => path29.basename(h.hubFolder) === selector);
27207
27644
  if (pending) {
27208
27645
  throw expected(
27209
27646
  `"${selector}" is a new hub that hasn't been created on the platform yet, so it has no id to bind to.
@@ -27214,9 +27651,9 @@ Create it first \u2014 the worktree scope picks it up automatically afterward:
27214
27651
  throw expected(
27215
27652
  [
27216
27653
  `No hub matching "${selector}" found in ${hubsDirLabel(gitRoot)}/. Pass a UUID or a folder name from:`,
27217
- ...scanWorkspaceHubs(workspaceDir).map((h) => ` ${path28.basename(h.hubFolder)} (${h.hubId})`),
27654
+ ...scanWorkspaceHubs(workspaceDir).map((h) => ` ${path29.basename(h.hubFolder)} (${h.hubId})`),
27218
27655
  ...newHubs.map(
27219
- (h) => ` ${path28.basename(h.hubFolder)} (new \u2014 "${h.hubName}", run \`wayai create ${path28.basename(h.hubFolder)}\`)`
27656
+ (h) => ` ${path29.basename(h.hubFolder)} (new \u2014 "${h.hubName}", run \`wayai create ${path29.basename(h.hubFolder)}\`)`
27220
27657
  )
27221
27658
  ].join("\n")
27222
27659
  );
@@ -27302,11 +27739,11 @@ __export(migrate_exports, {
27302
27739
  migrateCommand: () => migrateCommand
27303
27740
  });
27304
27741
  import { execFileSync as execFileSync3 } from "child_process";
27305
- import * as fs20 from "fs";
27306
- import * as path29 from "path";
27742
+ import * as fs21 from "fs";
27743
+ import * as path30 from "path";
27307
27744
  function isTracked(gitRoot, p) {
27308
27745
  try {
27309
- execFileSync3("git", ["ls-files", "--error-unmatch", "--", path29.relative(gitRoot, p)], {
27746
+ execFileSync3("git", ["ls-files", "--error-unmatch", "--", path30.relative(gitRoot, p)], {
27310
27747
  cwd: gitRoot,
27311
27748
  stdio: ["pipe", "pipe", "pipe"]
27312
27749
  });
@@ -27316,10 +27753,10 @@ function isTracked(gitRoot, p) {
27316
27753
  }
27317
27754
  }
27318
27755
  function moveDir(gitRoot, from, to) {
27319
- fs20.mkdirSync(path29.dirname(to), { recursive: true });
27756
+ fs21.mkdirSync(path30.dirname(to), { recursive: true });
27320
27757
  if (isTracked(gitRoot, from)) {
27321
27758
  try {
27322
- execFileSync3("git", ["mv", path29.relative(gitRoot, from), path29.relative(gitRoot, to)], {
27759
+ execFileSync3("git", ["mv", path30.relative(gitRoot, from), path30.relative(gitRoot, to)], {
27323
27760
  cwd: gitRoot,
27324
27761
  stdio: ["pipe", "pipe", "pipe"]
27325
27762
  });
@@ -27327,7 +27764,7 @@ function moveDir(gitRoot, from, to) {
27327
27764
  } catch {
27328
27765
  }
27329
27766
  }
27330
- fs20.renameSync(from, to);
27767
+ fs21.renameSync(from, to);
27331
27768
  return "fs";
27332
27769
  }
27333
27770
  async function migrateCommand(_args) {
@@ -27336,12 +27773,12 @@ async function migrateCommand(_args) {
27336
27773
  console.error("Not inside a git repository.");
27337
27774
  process.exit(1);
27338
27775
  }
27339
- const rel = (p) => path29.relative(gitRoot, p);
27340
- const newWs = path29.join(gitRoot, WAYAI_LAYOUT.wsDir);
27341
- const legacyWs = path29.join(gitRoot, WAYAI_LAYOUT.legacy.wsDir);
27342
- const legacyOrg = path29.join(gitRoot, WAYAI_LAYOUT.legacy.orgAtRoot);
27343
- const newHubs = path29.join(newWs, WAYAI_LAYOUT.hubsSubdir);
27344
- const newOrg = path29.join(newWs, WAYAI_LAYOUT.orgSubdir);
27776
+ const rel = (p) => path30.relative(gitRoot, p);
27777
+ const newWs = path30.join(gitRoot, WAYAI_LAYOUT.wsDir);
27778
+ const legacyWs = path30.join(gitRoot, WAYAI_LAYOUT.legacy.wsDir);
27779
+ const legacyOrg = path30.join(gitRoot, WAYAI_LAYOUT.legacy.orgAtRoot);
27780
+ const newHubs = path30.join(newWs, WAYAI_LAYOUT.hubsSubdir);
27781
+ const newOrg = path30.join(newWs, WAYAI_LAYOUT.orgSubdir);
27345
27782
  requireRealSubdirNoSymlink(gitRoot, newHubs, false);
27346
27783
  requireRealSubdirNoSymlink(gitRoot, newOrg, false);
27347
27784
  readRealFileOrThrow(gitRoot, workspaceManifestPath(gitRoot));
@@ -27494,12 +27931,12 @@ var send_message_exports = {};
27494
27931
  __export(send_message_exports, {
27495
27932
  sendMessageCommand: () => sendMessageCommand
27496
27933
  });
27497
- import * as fs21 from "fs";
27498
- import * as path30 from "path";
27934
+ import * as fs22 from "fs";
27935
+ import * as path31 from "path";
27499
27936
  function statAttachment(filePath) {
27500
27937
  let stat2;
27501
27938
  try {
27502
- stat2 = fs21.statSync(filePath);
27939
+ stat2 = fs22.statSync(filePath);
27503
27940
  } catch {
27504
27941
  console.error(`Error: file not found: ${filePath}`);
27505
27942
  process.exit(1);
@@ -27511,11 +27948,11 @@ function statAttachment(filePath) {
27511
27948
  return { filePath, size: stat2.size };
27512
27949
  }
27513
27950
  function readAttachment(filePath, size) {
27514
- const fileName = path30.basename(filePath);
27515
- const ext = path30.extname(fileName).replace(/^\./, "");
27951
+ const fileName = path31.basename(filePath);
27952
+ const ext = path31.extname(fileName).replace(/^\./, "");
27516
27953
  return {
27517
27954
  file_name: fileName,
27518
- file_binary: fs21.readFileSync(filePath).toString("base64"),
27955
+ file_binary: fs22.readFileSync(filePath).toString("base64"),
27519
27956
  file_size: size,
27520
27957
  ...ext && { file_extension: ext }
27521
27958
  };
@@ -27562,7 +27999,7 @@ async function sendMessageCommand(args2) {
27562
27999
  }
27563
28000
  const stats = filePaths.map(statAttachment);
27564
28001
  const filesTotal = stats.reduce((sum, s) => sum + base64Length(s.size), 0);
27565
- const fileDetail = () => stats.map((s) => `${path30.basename(s.filePath)} ${asMb(s.size)} MB`).join(", ");
28002
+ const fileDetail = () => stats.map((s) => `${path31.basename(s.filePath)} ${asMb(s.size)} MB`).join(", ");
27566
28003
  if (filesTotal > MAX_MESSAGE_BODY_BYTES) {
27567
28004
  console.error(
27568
28005
  `Error: ${fileDetail()} encode to ~${asMb(filesTotal)} MB, over the ${asMb(MAX_MESSAGE_BODY_BYTES)} MB per-request limit.`
@@ -27570,10 +28007,10 @@ async function sendMessageCommand(args2) {
27570
28007
  console.error("Base64 inflates a file by about a third, so ~7 MB of files is the practical ceiling.");
27571
28008
  process.exit(1);
27572
28009
  }
27573
- const audioStats = stats.filter((s) => isAudioAttachmentFileName(path30.basename(s.filePath)));
28010
+ const audioStats = stats.filter((s) => isAudioAttachmentFileName(path31.basename(s.filePath)));
27574
28011
  if (audioStats.length > 1) {
27575
28012
  console.error(
27576
- `Error: at most one audio file per message (got ${audioStats.length}: ${audioStats.map((s) => path30.basename(s.filePath)).join(", ")}).`
28013
+ `Error: at most one audio file per message (got ${audioStats.length}: ${audioStats.map((s) => path31.basename(s.filePath)).join(", ")}).`
27577
28014
  );
27578
28015
  console.error("Audio is transcribed via the hub's STT connection, and only one file per message is transcribed.");
27579
28016
  process.exit(1);
@@ -27581,7 +28018,7 @@ async function sendMessageCommand(args2) {
27581
28018
  const oversizeAudio = audioStats.find((s) => base64Length(s.size) > MAX_AUDIO_FILE_BASE64_BYTES);
27582
28019
  if (oversizeAudio) {
27583
28020
  console.error(
27584
- `Error: ${path30.basename(oversizeAudio.filePath)} (${asMb(oversizeAudio.size)} MB) is over the ~${asMb(MAX_AUDIO_FILE_BASE64_BYTES * 3 / 4)} MB audio limit for transcription.`
28021
+ `Error: ${path31.basename(oversizeAudio.filePath)} (${asMb(oversizeAudio.size)} MB) is over the ~${asMb(MAX_AUDIO_FILE_BASE64_BYTES * 3 / 4)} MB audio limit for transcription.`
27585
28022
  );
27586
28023
  process.exit(1);
27587
28024
  }
@@ -29093,8 +29530,8 @@ function installEvalSignalHandlers(input) {
29093
29530
  let signalCount = 0;
29094
29531
  let disposed = false;
29095
29532
  let settle;
29096
- const settled = new Promise((resolve10) => {
29097
- settle = resolve10;
29533
+ const settled = new Promise((resolve11) => {
29534
+ settle = resolve11;
29098
29535
  });
29099
29536
  const listeners = /* @__PURE__ */ new Map();
29100
29537
  const dispose = () => {
@@ -29448,7 +29885,7 @@ Timeout after ${timeoutSeconds}s${queuedSeconds > 0 ? ` (${queuedSeconds}s of it
29448
29885
  process.exit(1);
29449
29886
  }
29450
29887
  function sleep(ms) {
29451
- return new Promise((resolve10) => setTimeout(resolve10, ms));
29888
+ return new Promise((resolve11) => setTimeout(resolve11, ms));
29452
29889
  }
29453
29890
  function parseRunNumbers(raw) {
29454
29891
  if (!raw || raw.startsWith("--")) {
@@ -29715,9 +30152,9 @@ var init_eval_results = __esm({
29715
30152
 
29716
30153
  // src/lib/call-eval/caller-audio.ts
29717
30154
  import { createHash as createHash3 } from "crypto";
29718
- import { mkdirSync as mkdirSync12, readFileSync as readFileSync17, renameSync as renameSync5, writeFileSync as writeFileSync7 } from "fs";
30155
+ import { mkdirSync as mkdirSync12, readFileSync as readFileSync18, renameSync as renameSync5, writeFileSync as writeFileSync7 } from "fs";
29719
30156
  import { homedir as homedir5 } from "os";
29720
- import { dirname as dirname12, isAbsolute as isAbsolute3, join as join26, resolve as resolve8 } from "path";
30157
+ import { dirname as dirname12, isAbsolute as isAbsolute3, join as join27, resolve as resolve9 } from "path";
29721
30158
  function parseWav(buf, name = "clip") {
29722
30159
  if (buf.length < 12 || buf.toString("ascii", 0, 4) !== "RIFF" || buf.toString("ascii", 8, 12) !== "WAVE") {
29723
30160
  throw new Error(`${name} is not a WAV file.`);
@@ -29756,7 +30193,7 @@ function parseWav(buf, name = "clip") {
29756
30193
  throw new Error(`${name} holds no audio data.`);
29757
30194
  }
29758
30195
  function defaultClipCacheDir() {
29759
- return join26(homedir5(), ".wayai", "call-clips");
30196
+ return join27(homedir5(), ".wayai", "call-clips");
29760
30197
  }
29761
30198
  function pcmClip(buf) {
29762
30199
  const samples = new Int16Array(Math.floor(buf.length / 2));
@@ -29788,15 +30225,15 @@ var init_caller_audio = __esm({
29788
30225
  }
29789
30226
  describe;
29790
30227
  async clipFor(line) {
29791
- const path35 = line.clip ? isAbsolute3(line.clip) ? line.clip : resolve8(this.planDir, line.clip) : this.dir ? join26(this.dir, `${line.n}.wav`) : null;
29792
- if (!path35) throw new Error(`Line ${line.n} has no clip: give --clips <dir>, or a "clip" for it in the plan.`);
30228
+ const path36 = line.clip ? isAbsolute3(line.clip) ? line.clip : resolve9(this.planDir, line.clip) : this.dir ? join27(this.dir, `${line.n}.wav`) : null;
30229
+ if (!path36) throw new Error(`Line ${line.n} has no clip: give --clips <dir>, or a "clip" for it in the plan.`);
29793
30230
  let buf;
29794
30231
  try {
29795
- buf = readFileSync17(path35);
30232
+ buf = readFileSync18(path36);
29796
30233
  } catch {
29797
- throw new Error(`Line ${line.n}'s clip ${path35} cannot be read.`);
30234
+ throw new Error(`Line ${line.n}'s clip ${path36} cannot be read.`);
29798
30235
  }
29799
- return parseWav(buf, path35);
30236
+ return parseWav(buf, path36);
29800
30237
  }
29801
30238
  };
29802
30239
  OPENAI_PCM_SAMPLE_RATE = 24e3;
@@ -29823,20 +30260,20 @@ var init_caller_audio = __esm({
29823
30260
  const key = createHash3("sha256").update(`${this.model}
29824
30261
  ${this.voice}
29825
30262
  ${text}`).digest("hex");
29826
- return join26(this.cacheDir, `${key}.pcm`);
30263
+ return join27(this.cacheDir, `${key}.pcm`);
29827
30264
  }
29828
30265
  clipFor(line) {
29829
- const path35 = this.cachePath(line.say);
29830
- let pending = this.inFlight.get(path35);
30266
+ const path36 = this.cachePath(line.say);
30267
+ let pending = this.inFlight.get(path36);
29831
30268
  if (!pending) {
29832
- pending = this.readOrSynthesize(line, path35);
29833
- this.inFlight.set(path35, pending);
30269
+ pending = this.readOrSynthesize(line, path36);
30270
+ this.inFlight.set(path36, pending);
29834
30271
  }
29835
30272
  return pending;
29836
30273
  }
29837
- async readOrSynthesize(line, path35) {
30274
+ async readOrSynthesize(line, path36) {
29838
30275
  try {
29839
- return pcmClip(readFileSync17(path35));
30276
+ return pcmClip(readFileSync18(path36));
29840
30277
  } catch {
29841
30278
  }
29842
30279
  const res = await this.doFetch("https://api.openai.com/v1/audio/speech", {
@@ -29850,10 +30287,10 @@ ${text}`).digest("hex");
29850
30287
  }
29851
30288
  const buf = Buffer.from(await res.arrayBuffer());
29852
30289
  if (buf.length < 2) throw new Error(`OpenAI speech synthesis returned no audio for line ${line.n}.`);
29853
- mkdirSync12(dirname12(path35), { recursive: true });
29854
- const tmp = `${path35}.${process.pid}.tmp`;
30290
+ mkdirSync12(dirname12(path36), { recursive: true });
30291
+ const tmp = `${path36}.${process.pid}.tmp`;
29855
30292
  writeFileSync7(tmp, buf);
29856
- renameSync5(tmp, path35);
30293
+ renameSync5(tmp, path36);
29857
30294
  return pcmClip(buf);
29858
30295
  }
29859
30296
  };
@@ -29880,14 +30317,14 @@ async function loadWrtcRuntime(importPackage = () => import(WRTC_PACKAGE)) {
29880
30317
  function waitFor(ready, timeoutMs, clock = systemClock) {
29881
30318
  if (ready()) return Promise.resolve(true);
29882
30319
  const deadline = clock.now() + timeoutMs;
29883
- return new Promise((resolve10) => {
30320
+ return new Promise((resolve11) => {
29884
30321
  const timer = setInterval(() => {
29885
30322
  if (ready()) {
29886
30323
  clearInterval(timer);
29887
- resolve10(true);
30324
+ resolve11(true);
29888
30325
  } else if (clock.now() >= deadline) {
29889
30326
  clearInterval(timer);
29890
- resolve10(false);
30327
+ resolve11(false);
29891
30328
  }
29892
30329
  }, WAIT_POLL_MS);
29893
30330
  });
@@ -29996,8 +30433,8 @@ var init_call_media = __esm({
29996
30433
  * asked before every frame, answers true — the rest of the clip is then dropped.
29997
30434
  */
29998
30435
  play(clip, abort = () => false) {
29999
- return new Promise((resolve10) => {
30000
- this.queue.push({ samples: resample(clip, PUMP_SAMPLE_RATE), offset: 0, startedAtMs: null, abort, resolve: resolve10 });
30436
+ return new Promise((resolve11) => {
30437
+ this.queue.push({ samples: resample(clip, PUMP_SAMPLE_RATE), offset: 0, startedAtMs: null, abort, resolve: resolve11 });
30001
30438
  });
30002
30439
  }
30003
30440
  /** Send every frame the wall clock says is due. */
@@ -30093,13 +30530,13 @@ var init_call_media = __esm({
30093
30530
  await waitFor(() => this.voice.onsetAfter(afterMs) !== null || abort(), timeoutMs, this.clock);
30094
30531
  return this.voice.onsetAfter(afterMs);
30095
30532
  }
30096
- async waitForVoiceDone(sinceMs, quietMs, timeoutMs, abort = () => false) {
30533
+ async waitForVoiceDone(sinceMs, quietMs, timeoutMs, abort = () => false, notBeforeMs = Number.NEGATIVE_INFINITY) {
30097
30534
  const done = () => {
30098
- if (this.voice.onsetAfter(sinceMs - 1) === null) return false;
30535
+ if (this.clock.now() < notBeforeMs || this.voice.onsetAfter(sinceMs - 1) === null) return false;
30099
30536
  const quiet = this.voice.quietSince();
30100
30537
  return quiet !== null && quiet > sinceMs && this.clock.now() - quiet >= quietMs;
30101
30538
  };
30102
- await waitFor(() => done() || abort(), timeoutMs, this.clock);
30539
+ await waitFor(() => done() || abort(), timeoutMs + Math.max(0, notBeforeMs - this.clock.now()), this.clock);
30103
30540
  return done();
30104
30541
  }
30105
30542
  delegationsSeen() {
@@ -31026,6 +31463,10 @@ async function runOneCall(options, run, clips) {
31026
31463
  result.call_id = created.call_id;
31027
31464
  result.conversation_id = created.conversation_id;
31028
31465
  log(`run ${run}: call ${created.call_id} placed (at most ${created.max_call_seconds} s)`);
31466
+ const silentWaitMs = created.progress_cues === false ? created.delegation_timeout_seconds * 1e3 + timings.silentWaitMarginMs : null;
31467
+ if (silentWaitMs !== null) {
31468
+ log(`run ${run}: progress cues are off: each delegated answer is awaited up to its ${created.delegation_timeout_seconds} s timeout`);
31469
+ }
31029
31470
  await port.connect(created.sdp_answer);
31030
31471
  const connectedAt = clock.now();
31031
31472
  await api.readyEvalCall(created.call_id, hubId);
@@ -31047,6 +31488,10 @@ async function runOneCall(options, run, clips) {
31047
31488
  if (reason) result.stopped_by = reason;
31048
31489
  return reason !== null;
31049
31490
  };
31491
+ const waitForAnswer = (lineEnd, delegated) => {
31492
+ const notBeforeMs = delegated && silentWaitMs !== null ? lineEnd + silentWaitMs : void 0;
31493
+ return port.waitForVoiceDone(lineEnd, quietAfter(delegated), timings.answerDoneTimeoutMs, stop, notBeforeMs);
31494
+ };
31050
31495
  await port.waitForVoiceDone(connectedAt, timings.ownAnswerQuietMs, timings.greetingTimeoutMs, stop);
31051
31496
  let previousEnd = connectedAt;
31052
31497
  let previousDelegated = false;
@@ -31056,7 +31501,7 @@ async function runOneCall(options, run, clips) {
31056
31501
  const onset2 = await port.waitForVoiceOnset(previousEnd, timings.answerOnsetTimeoutMs, stop);
31057
31502
  if (onset2 !== null) await clock.sleep(Math.max(0, onset2 + timings.interruptAfterMs - clock.now()));
31058
31503
  } else if (i > 0) {
31059
- await port.waitForVoiceDone(previousEnd, quietAfter(previousDelegated), timings.answerDoneTimeoutMs, stop);
31504
+ await waitForAnswer(previousEnd, previousDelegated);
31060
31505
  }
31061
31506
  if (stop()) break;
31062
31507
  const span = await port.play(clips[i], stop);
@@ -31068,7 +31513,7 @@ async function runOneCall(options, run, clips) {
31068
31513
  previousDelegated = line.expect_delegation;
31069
31514
  }
31070
31515
  if (!result.stopped_by) {
31071
- await port.waitForVoiceDone(previousEnd, quietAfter(previousDelegated), timings.answerDoneTimeoutMs, stop);
31516
+ await waitForAnswer(previousEnd, previousDelegated);
31072
31517
  }
31073
31518
  if (result.stopped_by) {
31074
31519
  result.status = "stopped";
@@ -31161,23 +31606,26 @@ async function runCallEvalSuite(options) {
31161
31606
  cost: { provider_usd: ledger.spentUsd, operations: ledger.spentOperations }
31162
31607
  };
31163
31608
  }
31164
- var systemRunnerClock, DEFAULT_RUNNER_TIMINGS, RECORD_SETTLE_TIMEOUT_MS, RECORD_POLL_MS;
31609
+ var systemRunnerClock, LONGEST_SPOKEN_LINE_MS, DEFAULT_RUNNER_TIMINGS, RECORD_SETTLE_TIMEOUT_MS, RECORD_POLL_MS;
31165
31610
  var init_runner = __esm({
31166
31611
  "src/lib/call-eval/runner.ts"() {
31167
31612
  "use strict";
31168
31613
  init_dist();
31614
+ init_contracts();
31169
31615
  init_errors2();
31170
31616
  init_cost_cap();
31171
31617
  init_score();
31172
31618
  systemRunnerClock = {
31173
31619
  now: () => Date.now(),
31174
- sleep: (ms) => new Promise((resolve10) => setTimeout(resolve10, ms))
31620
+ sleep: (ms) => new Promise((resolve11) => setTimeout(resolve11, ms))
31175
31621
  };
31622
+ LONGEST_SPOKEN_LINE_MS = Math.ceil(EVAL_CALL_SPOKEN_LINE_MAX_CHARS / 15) * 1e3;
31176
31623
  DEFAULT_RUNNER_TIMINGS = {
31177
- greetingTimeoutMs: 2e4,
31624
+ greetingTimeoutMs: 2e4 + LONGEST_SPOKEN_LINE_MS,
31178
31625
  answerOnsetTimeoutMs: 2e4,
31179
- answerDoneTimeoutMs: 45e3,
31626
+ answerDoneTimeoutMs: 45e3 + 2 * LONGEST_SPOKEN_LINE_MS,
31180
31627
  delegatedAnswerQuietMs: 5500,
31628
+ silentWaitMarginMs: 3e3,
31181
31629
  ownAnswerQuietMs: 2e3,
31182
31630
  interruptAfterMs: 1e3
31183
31631
  };
@@ -31291,8 +31739,8 @@ __export(eval_call_exports, {
31291
31739
  printEvalCallHelp: () => printEvalCallHelp,
31292
31740
  suiteExitCode: () => suiteExitCode
31293
31741
  });
31294
- import { accessSync, constants as fsConstants, existsSync as existsSync15, readFileSync as readFileSync18, statSync as statSync7, writeFileSync as writeFileSync8 } from "fs";
31295
- import { dirname as dirname13, resolve as resolve9 } from "path";
31742
+ import { accessSync, constants as fsConstants, existsSync as existsSync16, readFileSync as readFileSync19, statSync as statSync8, writeFileSync as writeFileSync8 } from "fs";
31743
+ import { dirname as dirname13, resolve as resolve10 } from "path";
31296
31744
  function fail(message) {
31297
31745
  throw new Error(message);
31298
31746
  }
@@ -31367,26 +31815,26 @@ function parseEvalCallArgs(args2) {
31367
31815
  if (parsed.jsonPath) checkReportPath(parsed.jsonPath);
31368
31816
  return parsed;
31369
31817
  }
31370
- function checkReportPath(path35) {
31371
- const target = resolve9(path35);
31818
+ function checkReportPath(path36) {
31819
+ const target = resolve10(path36);
31372
31820
  const dir = dirname13(target);
31373
- if (!existsSync15(dir) || !statSync7(dir).isDirectory()) fail(`--json ${path35}: the folder ${dir} does not exist.`);
31374
- if (existsSync15(target) && statSync7(target).isDirectory()) fail(`--json ${path35} is a folder; name a file.`);
31821
+ if (!existsSync16(dir) || !statSync8(dir).isDirectory()) fail(`--json ${path36}: the folder ${dir} does not exist.`);
31822
+ if (existsSync16(target) && statSync8(target).isDirectory()) fail(`--json ${path36} is a folder; name a file.`);
31375
31823
  try {
31376
- accessSync(existsSync15(target) ? target : dir, fsConstants.W_OK);
31824
+ accessSync(existsSync16(target) ? target : dir, fsConstants.W_OK);
31377
31825
  } catch {
31378
- fail(`--json ${path35} cannot be written here.`);
31826
+ fail(`--json ${path36} cannot be written here.`);
31379
31827
  }
31380
31828
  }
31381
31829
  function suiteExitCode(report2, runs, reportWritten) {
31382
31830
  return report2.pass_rate.passed === runs && reportWritten ? 0 : 1;
31383
31831
  }
31384
31832
  function chooseAudioSource(options, plan, env = process.env) {
31385
- const planDir = options.planPath ? dirname13(resolve9(options.planPath)) : process.cwd();
31833
+ const planDir = options.planPath ? dirname13(resolve10(options.planPath)) : process.cwd();
31386
31834
  const planHasClips = Object.values(plan.lines).some((line) => line.clip);
31387
31835
  if (options.clipsDir || planHasClips) {
31388
- if (options.clipsDir && !existsSync15(options.clipsDir)) fail(`--clips ${options.clipsDir} does not exist.`);
31389
- return new ClipDirectorySource(options.clipsDir ? resolve9(options.clipsDir) : null, planDir);
31836
+ if (options.clipsDir && !existsSync16(options.clipsDir)) fail(`--clips ${options.clipsDir} does not exist.`);
31837
+ return new ClipDirectorySource(options.clipsDir ? resolve10(options.clipsDir) : null, planDir);
31390
31838
  }
31391
31839
  const apiKey = env.OPENAI_API_KEY;
31392
31840
  if (!apiKey) {
@@ -31445,7 +31893,7 @@ async function evalCallCommand(argv) {
31445
31893
  let plan;
31446
31894
  try {
31447
31895
  options = parseEvalCallArgs(args2);
31448
- plan = options.planPath ? parseCallPlan(JSON.parse(readFileSync18(options.planPath, "utf8"))) : { lines: {} };
31896
+ plan = options.planPath ? parseCallPlan(JSON.parse(readFileSync19(options.planPath, "utf8"))) : { lines: {} };
31449
31897
  } catch (err) {
31450
31898
  console.error(extractApiMessage(err));
31451
31899
  process.exit(1);
@@ -31575,8 +32023,8 @@ var eval_capture_exports = {};
31575
32023
  __export(eval_capture_exports, {
31576
32024
  evalCaptureCommand: () => evalCaptureCommand
31577
32025
  });
31578
- import * as fs22 from "fs";
31579
- import * as path31 from "path";
32026
+ import * as fs23 from "fs";
32027
+ import * as path32 from "path";
31580
32028
  import * as yaml12 from "js-yaml";
31581
32029
  function isValidSetName(name) {
31582
32030
  if (name.length === 0 || name === "." || name === "..") return false;
@@ -31642,25 +32090,25 @@ async function evalCaptureCommand(args2) {
31642
32090
  const setFolderName = targetSetName;
31643
32091
  const scenarioName = parsed.evalName ?? `Capture ${parsed.conversationId.slice(0, 8)}`;
31644
32092
  const slug = slugify(scenarioName);
31645
- const evalsDir = path31.join(hubFolder, "evals");
31646
- const targetDir = path31.join(evalsDir, setFolderName);
31647
- const targetPath = path31.join(targetDir, `${slug}.yaml`);
31648
- if (!targetPath.startsWith(evalsDir + path31.sep)) {
31649
- console.error(`Resolved path "${path31.relative(hubFolder, targetPath)}" escapes evals/. Aborting.`);
32093
+ const evalsDir = path32.join(hubFolder, "evals");
32094
+ const targetDir = path32.join(evalsDir, setFolderName);
32095
+ const targetPath = path32.join(targetDir, `${slug}.yaml`);
32096
+ if (!targetPath.startsWith(evalsDir + path32.sep)) {
32097
+ console.error(`Resolved path "${path32.relative(hubFolder, targetPath)}" escapes evals/. Aborting.`);
31650
32098
  process.exit(1);
31651
32099
  }
31652
32100
  if (!ensureRealSubdirNoSymlink(hubFolder, targetDir, false)) {
31653
- console.error(`${path31.relative(hubFolder, targetDir)} is reached through a symlink. Aborting.`);
32101
+ console.error(`${path32.relative(hubFolder, targetDir)} is reached through a symlink. Aborting.`);
31654
32102
  process.exit(1);
31655
32103
  }
31656
32104
  let targetTaken = true;
31657
32105
  try {
31658
- fs22.lstatSync(targetPath);
32106
+ fs23.lstatSync(targetPath);
31659
32107
  } catch {
31660
32108
  targetTaken = false;
31661
32109
  }
31662
32110
  if (targetTaken) {
31663
- console.error(`File already exists: ${path31.relative(hubFolder, targetPath)}. Use --name to choose a different name.`);
32111
+ console.error(`File already exists: ${path32.relative(hubFolder, targetPath)}. Use --name to choose a different name.`);
31664
32112
  process.exit(1);
31665
32113
  }
31666
32114
  console.log("Resolving scenario set...");
@@ -31695,11 +32143,11 @@ async function evalCaptureCommand(args2) {
31695
32143
  const outcome = createFileNoFollow(hubFolder, targetPath, Buffer.from(yaml12.dump(yamlObj, YAML_DUMP_OPTIONS), "utf-8"));
31696
32144
  if (outcome !== "created") {
31697
32145
  console.error(
31698
- `Could not write ${path31.relative(hubFolder, targetPath)} (${outcome === "exists" ? "it appeared meanwhile" : "its folder is reached through a symlink"}). The scenario was created on the platform as ${captured.eval_id} \u2014 run \`wayai pull\` to fetch it.`
32146
+ `Could not write ${path32.relative(hubFolder, targetPath)} (${outcome === "exists" ? "it appeared meanwhile" : "its folder is reached through a symlink"}). The scenario was created on the platform as ${captured.eval_id} \u2014 run \`wayai pull\` to fetch it.`
31699
32147
  );
31700
32148
  process.exit(1);
31701
32149
  }
31702
- const relPath = path31.relative(process.cwd(), targetPath);
32150
+ const relPath = path32.relative(process.cwd(), targetPath);
31703
32151
  console.log(`
31704
32152
  Wrote ${relPath}`);
31705
32153
  console.log("Run `wayai pull` to refresh the agent display name, then commit. The scenario is already on the platform.");
@@ -33079,19 +33527,19 @@ var init_set_connection_credential = __esm({
33079
33527
  });
33080
33528
 
33081
33529
  // src/lib/org-workspace.ts
33082
- import * as fs23 from "fs";
33083
- import * as path32 from "path";
33530
+ import * as fs24 from "fs";
33531
+ import * as path33 from "path";
33084
33532
  import * as yaml13 from "js-yaml";
33085
33533
  function getOrgDir(gitRoot) {
33086
33534
  return resolveLayout(gitRoot).orgDir;
33087
33535
  }
33088
33536
  function orgManifestExists(orgDir) {
33089
- return fs23.existsSync(path32.join(orgDir, ORG_MANIFEST_NAME));
33537
+ return fs24.existsSync(path33.join(orgDir, ORG_MANIFEST_NAME));
33090
33538
  }
33091
33539
  function parseOrgResources(orgDir) {
33092
- const resourcesDir = path32.join(orgDir, "resources");
33540
+ const resourcesDir = path33.join(orgDir, "resources");
33093
33541
  requireRealSubdirNoSymlink(orgDir, resourcesDir, false);
33094
- const manifestText = readRealFileOrThrow(orgDir, path32.join(orgDir, ORG_MANIFEST_NAME));
33542
+ const manifestText = readRealFileOrThrow(orgDir, path33.join(orgDir, ORG_MANIFEST_NAME));
33095
33543
  const manifest = (manifestText !== null ? yaml13.load(manifestText) : null) ?? {};
33096
33544
  const rawResources = Array.isArray(manifest.resources) ? manifest.resources : [];
33097
33545
  const resources = rawResources.map((res) => {
@@ -33105,9 +33553,9 @@ function parseOrgResources(orgDir) {
33105
33553
  if (res.environment) resource.environment = res.environment;
33106
33554
  if (Array.isArray(res.tags)) resource.tags = res.tags;
33107
33555
  if (Array.isArray(res.folders)) resource.folders = res.folders;
33108
- const resDir = path32.join(resourcesDir, slugify(resource.name));
33556
+ const resDir = path33.join(resourcesDir, slugify(resource.name));
33109
33557
  requireRealSubdirNoSymlink(orgDir, resDir, false);
33110
- if (fs23.existsSync(resDir)) {
33558
+ if (fs24.existsSync(resDir)) {
33111
33559
  const files = scanResourceFiles(resDir, "");
33112
33560
  if (files.length > 0) resource.files = files;
33113
33561
  }
@@ -33116,8 +33564,8 @@ function parseOrgResources(orgDir) {
33116
33564
  return { version: 1, resources };
33117
33565
  }
33118
33566
  function writeOrgResources(orgDir, payload) {
33119
- fs23.mkdirSync(orgDir, { recursive: true });
33120
- const resourcesDir = path32.join(orgDir, "resources");
33567
+ fs24.mkdirSync(orgDir, { recursive: true });
33568
+ const resourcesDir = path33.join(orgDir, "resources");
33121
33569
  requireRealSubdirNoSymlink(orgDir, resourcesDir, false);
33122
33570
  const resources = payload.resources ?? [];
33123
33571
  const manifestResources = resources.map((r) => {
@@ -33126,19 +33574,19 @@ function writeOrgResources(orgDir, payload) {
33126
33574
  });
33127
33575
  writeFileNoFollow(
33128
33576
  orgDir,
33129
- path32.join(orgDir, ORG_MANIFEST_NAME),
33577
+ path33.join(orgDir, ORG_MANIFEST_NAME),
33130
33578
  Buffer.from(yaml13.dump({ version: 1, resources: manifestResources }, YAML_DUMP_OPTIONS), "utf-8")
33131
33579
  );
33132
33580
  const currentSlugs = /* @__PURE__ */ new Set();
33133
33581
  for (const resource of resources) {
33134
33582
  const resSlug = slugify(resource.name);
33135
33583
  currentSlugs.add(resSlug);
33136
- writeResourceFileTree(path32.join(resourcesDir, resSlug), resource.files || [], orgDir);
33584
+ writeResourceFileTree(path33.join(resourcesDir, resSlug), resource.files || [], orgDir);
33137
33585
  }
33138
- if (fs23.existsSync(resourcesDir)) {
33139
- for (const entry of fs23.readdirSync(resourcesDir, { withFileTypes: true })) {
33586
+ if (fs24.existsSync(resourcesDir)) {
33587
+ for (const entry of fs24.readdirSync(resourcesDir, { withFileTypes: true })) {
33140
33588
  if (entry.isDirectory() && !currentSlugs.has(entry.name)) {
33141
- fs23.rmSync(path32.join(resourcesDir, entry.name), { recursive: true, force: true });
33589
+ fs24.rmSync(path33.join(resourcesDir, entry.name), { recursive: true, force: true });
33142
33590
  }
33143
33591
  }
33144
33592
  }
@@ -33147,7 +33595,7 @@ async function downloadOrgBinaryFiles(orgDir, payload) {
33147
33595
  let count = 0;
33148
33596
  for (const resource of payload.resources ?? []) {
33149
33597
  if (!resource.files) continue;
33150
- const resDir = path32.join(orgDir, "resources", slugify(resource.name));
33598
+ const resDir = path33.join(orgDir, "resources", slugify(resource.name));
33151
33599
  count += await downloadBinaryFiles(resDir, resource.files, orgDir);
33152
33600
  }
33153
33601
  if (count > 0) console.log(`Downloaded ${count} binary resource file(s).`);
@@ -33444,8 +33892,8 @@ var init_report_edit_args = __esm({
33444
33892
  });
33445
33893
 
33446
33894
  // src/lib/file-map.ts
33447
- import * as fs24 from "fs";
33448
- import * as path33 from "path";
33895
+ import * as fs25 from "fs";
33896
+ import * as path34 from "path";
33449
33897
  function isSafeRelPath(rel) {
33450
33898
  if (rel.length === 0 || rel.length > 300) return false;
33451
33899
  if (rel.startsWith("/") || rel.includes("\\")) return false;
@@ -33460,9 +33908,9 @@ function writeFileMap(targetDir, files) {
33460
33908
  if (!isSafeRelPath(rel)) {
33461
33909
  throw new Error(`Refusing to write unsafe path: ${rel}`);
33462
33910
  }
33463
- const abs = path33.join(targetDir, rel);
33464
- fs24.mkdirSync(path33.dirname(abs), { recursive: true });
33465
- fs24.writeFileSync(abs, body, "utf-8");
33911
+ const abs = path34.join(targetDir, rel);
33912
+ fs25.mkdirSync(path34.dirname(abs), { recursive: true });
33913
+ fs25.writeFileSync(abs, body, "utf-8");
33466
33914
  written.push(rel);
33467
33915
  }
33468
33916
  return written;
@@ -33478,8 +33926,8 @@ var admin_exports = {};
33478
33926
  __export(admin_exports, {
33479
33927
  adminCommand: () => adminCommand
33480
33928
  });
33481
- import * as fs25 from "fs";
33482
- import * as path34 from "path";
33929
+ import * as fs26 from "fs";
33930
+ import * as path35 from "path";
33483
33931
  async function adminCommand(args2) {
33484
33932
  const [group, ...afterGroup] = args2;
33485
33933
  if (!group) {
@@ -33817,7 +34265,7 @@ async function runArchiveRead(positional, flagArgs) {
33817
34265
  exitOnApiError(err);
33818
34266
  throw err;
33819
34267
  }
33820
- fs25.writeFileSync(outPath, zip);
34268
+ fs26.writeFileSync(outPath, zip);
33821
34269
  console.log(`Wrote ${zip.byteLength} bytes to ${outPath}`);
33822
34270
  return;
33823
34271
  }
@@ -33959,13 +34407,13 @@ async function runSkillInstall(positional) {
33959
34407
  throw err;
33960
34408
  }
33961
34409
  const root = findGitRoot() ?? process.cwd();
33962
- const present = HARNESS_SKILL_DIRS.filter((dir) => fs25.existsSync(path34.join(root, dir)));
34410
+ const present = HARNESS_SKILL_DIRS.filter((dir) => fs26.existsSync(path35.join(root, dir)));
33963
34411
  const targets = present.length > 0 ? present : HARNESS_SKILL_DIRS;
33964
34412
  const fileCount = Object.keys(res.files).length;
33965
34413
  const relDirs = targets.map((harness) => {
33966
- const targetDir = path34.join(root, harness, "skills", name);
34414
+ const targetDir = path35.join(root, harness, "skills", name);
33967
34415
  writeFileMap(targetDir, res.files);
33968
- return `${path34.relative(root, targetDir)}/`;
34416
+ return `${path35.relative(root, targetDir)}/`;
33969
34417
  });
33970
34418
  console.log(`Installed skill "${name}" (${fileCount} file${fileCount === 1 ? "" : "s"}) \u2192 ${relDirs.join(", ")}`);
33971
34419
  console.log("Reload your agent (e.g. restart Claude Code) to pick up the skill.");
@@ -35590,7 +36038,7 @@ var init_actions = __esm({
35590
36038
 
35591
36039
  // src/data/commands/attachments.ts
35592
36040
  import { Command as Command2 } from "commander";
35593
- import { readFileSync as readFileSync19 } from "fs";
36041
+ import { readFileSync as readFileSync20 } from "fs";
35594
36042
  function findAttachmentByFilename(attachments, filename) {
35595
36043
  return attachments.find((a) => a.key.endsWith(`/${filename}`)) ?? null;
35596
36044
  }
@@ -35631,7 +36079,7 @@ function buildAttachmentsCommand() {
35631
36079
  printOutput(data, outputFormat(this));
35632
36080
  return;
35633
36081
  }
35634
- const body = readFileSync19(opts.file);
36082
+ const body = readFileSync20(opts.file);
35635
36083
  await client.upload(uploadPathFrom(data?.upload_url), body, opts.contentType);
35636
36084
  printOutput({ ...data, uploaded: true }, outputFormat(this));
35637
36085
  });
@@ -36111,16 +36559,16 @@ var init_providers = __esm({
36111
36559
 
36112
36560
  // src/data/commands/report.ts
36113
36561
  import { Command as Command6 } from "commander";
36114
- import { readFileSync as readFileSync20 } from "fs";
36115
- import { dirname as dirname15, join as join31 } from "path";
36562
+ import { readFileSync as readFileSync21 } from "fs";
36563
+ import { dirname as dirname15, join as join32 } from "path";
36116
36564
  import { fileURLToPath as fileURLToPath2 } from "url";
36117
36565
  function resolveCliVersion() {
36118
36566
  for (const candidate of [
36119
- join31(here, "..", "package.json"),
36120
- join31(here, "..", "..", "..", "package.json")
36567
+ join32(here, "..", "package.json"),
36568
+ join32(here, "..", "..", "..", "package.json")
36121
36569
  ]) {
36122
36570
  try {
36123
- const version = JSON.parse(readFileSync20(candidate, "utf-8")).version;
36571
+ const version = JSON.parse(readFileSync21(candidate, "utf-8")).version;
36124
36572
  if (typeof version === "string" && version) return version;
36125
36573
  } catch {
36126
36574
  }
@@ -36322,7 +36770,7 @@ var init_report3 = __esm({
36322
36770
 
36323
36771
  // src/data/commands/credentials.ts
36324
36772
  import { Command as Command7 } from "commander";
36325
- import { readFileSync as readFileSync21 } from "fs";
36773
+ import { readFileSync as readFileSync22 } from "fs";
36326
36774
  function withValueSourceOptions(cmd, what) {
36327
36775
  return cmd.option(
36328
36776
  "--file <path>",
@@ -36335,7 +36783,7 @@ async function resolveValue(opts, label) {
36335
36783
  throw expected("--file cannot be combined with --value-stdin or --value-prompt \u2014 pass one.");
36336
36784
  }
36337
36785
  try {
36338
- return readFileSync21(opts.file).toString("base64");
36786
+ return readFileSync22(opts.file).toString("base64");
36339
36787
  } catch (e) {
36340
36788
  throw expected(`--file ${opts.file}: ${e instanceof Error ? e.message : "could not be read"}`);
36341
36789
  }
@@ -36484,7 +36932,7 @@ var init_credentials = __esm({
36484
36932
 
36485
36933
  // src/data/commands/sql.ts
36486
36934
  import { Command as Command8 } from "commander";
36487
- import { readFileSync as readFileSync22 } from "fs";
36935
+ import { readFileSync as readFileSync23 } from "fs";
36488
36936
  function buildBasesSqlCommand() {
36489
36937
  return withBaseOption(new Command8("sql")).description("Execute a read-only SQL query against base data").argument("[query]", "SQL query (SELECT only)").option("--file <path>", "Read SQL from a file instead of the argument").option(
36490
36938
  "--param <kv...>",
@@ -36494,7 +36942,7 @@ function buildBasesSqlCommand() {
36494
36942
  let query;
36495
36943
  if (opts.file) {
36496
36944
  try {
36497
- query = readFileSync22(opts.file, "utf-8").trim();
36945
+ query = readFileSync23(opts.file, "utf-8").trim();
36498
36946
  } catch (e) {
36499
36947
  throw expected(`--file ${opts.file}: ${e instanceof Error ? e.message : "could not be read"}`);
36500
36948
  }
@@ -36629,16 +37077,16 @@ MCP URL: ${toolsetMcpUrl(slug)}`);
36629
37077
  ).option("--force", "Revoke even if the token appears to be in live use").action(async function(tokenId, opts) {
36630
37078
  const client = await createDataClient();
36631
37079
  const id = pathSegment(tokenId, "token id");
36632
- const path35 = (force) => `/v1/tokens/${id}${force ? "?force=true" : ""}`;
37080
+ const path36 = (force) => `/v1/tokens/${id}${force ? "?force=true" : ""}`;
36633
37081
  const format = outputFormat(this);
36634
37082
  const revoked = (forced) => printOutput({ token_id: tokenId, revoked: true, forced }, format);
36635
37083
  if (opts.force) {
36636
- await client.request("DELETE", path35(true));
37084
+ await client.request("DELETE", path36(true));
36637
37085
  revoked(true);
36638
37086
  return;
36639
37087
  }
36640
37088
  try {
36641
- await client.request("DELETE", path35(false));
37089
+ await client.request("DELETE", path36(false));
36642
37090
  revoked(false);
36643
37091
  } catch (err) {
36644
37092
  if (!(err instanceof ApiError) || err.status !== 409 || dataErrorDetails(err)?.requires_force !== true) {
@@ -36653,7 +37101,7 @@ MCP URL: ${toolsetMcpUrl(slug)}`);
36653
37101
  console.error("Aborted.");
36654
37102
  return process.exit(1);
36655
37103
  }
36656
- await client.request("DELETE", path35(true));
37104
+ await client.request("DELETE", path36(true));
36657
37105
  revoked(true);
36658
37106
  }
36659
37107
  });
@@ -36801,9 +37249,9 @@ var init_base_tags = __esm({
36801
37249
 
36802
37250
  // src/data/commands/bases.ts
36803
37251
  import { Command as Command10 } from "commander";
36804
- function pageOf(path35, cursor) {
36805
- if (!cursor) return path35;
36806
- return `${path35}${path35.includes("?") ? "&" : "?"}cursor=${encodeURIComponent(cursor)}`;
37252
+ function pageOf(path36, cursor) {
37253
+ if (!cursor) return path36;
37254
+ return `${path36}${path36.includes("?") ? "&" : "?"}cursor=${encodeURIComponent(cursor)}`;
36807
37255
  }
36808
37256
  function parseEnum(flag, value, allowed) {
36809
37257
  if (value === void 0) return void 0;
@@ -36960,9 +37408,9 @@ function buildBasesCommand() {
36960
37408
  });
36961
37409
  bases.command("list-previews <origin-id>").description("List preview bases cloned from a base (production or preview)").action(async function(originId) {
36962
37410
  const client = await createDataClient();
36963
- const path35 = `/v1/${pathSegment(originId, "origin base id")}/previews`;
37411
+ const path36 = `/v1/${pathSegment(originId, "origin base id")}/previews`;
36964
37412
  printOutput(
36965
- await client.collectPages((cursor) => pageOf(path35, cursor)),
37413
+ await client.collectPages((cursor) => pageOf(path36, cursor)),
36966
37414
  outputFormat(this)
36967
37415
  );
36968
37416
  });
@@ -37009,9 +37457,9 @@ function buildBasesCommand() {
37009
37457
  });
37010
37458
  bases.command("promotions <production-id>").description("List promotion history for a production base").action(async function(productionId) {
37011
37459
  const client = await createDataClient();
37012
- const path35 = `/v1/${pathSegment(productionId, "production base id")}/promotions`;
37460
+ const path36 = `/v1/${pathSegment(productionId, "production base id")}/promotions`;
37013
37461
  printOutput(
37014
- await client.collectPages((cursor) => pageOf(path35, cursor)),
37462
+ await client.collectPages((cursor) => pageOf(path36, cursor)),
37015
37463
  outputFormat(this)
37016
37464
  );
37017
37465
  });
@@ -37149,7 +37597,7 @@ var init_file_types = __esm({
37149
37597
 
37150
37598
  // src/data/commands/files.ts
37151
37599
  import { Command as Command12 } from "commander";
37152
- import { readFileSync as readFileSync23, writeFileSync as writeFileSync12 } from "fs";
37600
+ import { readFileSync as readFileSync24, writeFileSync as writeFileSync12 } from "fs";
37153
37601
  import { basename as basename20 } from "path";
37154
37602
  function renderFileDiff(fileType, filePath, from, to, d) {
37155
37603
  console.log(sanitizeTerminalText(`${fileType}/${filePath}: v${from} \u2192 v${to}`));
@@ -37198,7 +37646,7 @@ function buildFilesCommand() {
37198
37646
  "Upload a local file to a path (e.g. wayai files put reports q3/summary.pdf --file ./summary.pdf)"
37199
37647
  ).requiredOption("--file <local>", "Local file to upload").option("--content-type <type>", "MIME type", "application/octet-stream").action(async function(fileType, filePath, opts) {
37200
37648
  const base = pathSegment(requireBase(this), "--base");
37201
- const body = readFileSync23(opts.file);
37649
+ const body = readFileSync24(opts.file);
37202
37650
  const client = await createDataClient();
37203
37651
  printOutput(
37204
37652
  await client.upload(
@@ -37558,8 +38006,8 @@ function buildRecordsCommand() {
37558
38006
  const body = { data: parseData(opts.data) };
37559
38007
  if (opts.externalId) body.external_id = opts.externalId;
37560
38008
  if (opts.externalSource) body.external_source = opts.externalSource;
37561
- const path35 = opts.id ? `/v1/${base}/records/${pathSegment(recordType2, "record_type")}/${pathSegment(opts.id, "--id")}` : `/v1/${base}/records/${pathSegment(recordType2, "record_type")}`;
37562
- printOutput(await client.request("PUT", path35, body), outputFormat(this));
38009
+ const path36 = opts.id ? `/v1/${base}/records/${pathSegment(recordType2, "record_type")}/${pathSegment(opts.id, "--id")}` : `/v1/${base}/records/${pathSegment(recordType2, "record_type")}`;
38010
+ printOutput(await client.request("PUT", path36, body), outputFormat(this));
37563
38011
  });
37564
38012
  records.command("query <record_type>").description("List/search records: exact filters + fuzzy `search`, sorting, pagination").option(
37565
38013
  "--external-source <source>",
@@ -37594,9 +38042,9 @@ function buildRecordsCommand() {
37594
38042
  ).action(async function(recordType2, id, opts) {
37595
38043
  const base = pathSegment(requireBase(this), "--base");
37596
38044
  const client = await createDataClient();
37597
- let path35 = `/v1/${base}/records/${pathSegment(recordType2, "record_type")}/${recordKey(id, opts.externalSource)}`;
37598
- if (opts.externalSource) path35 += `?external_source=${encodeURIComponent(opts.externalSource)}`;
37599
- printOutput(await client.request("GET", path35), outputFormat(this));
38045
+ let path36 = `/v1/${base}/records/${pathSegment(recordType2, "record_type")}/${recordKey(id, opts.externalSource)}`;
38046
+ if (opts.externalSource) path36 += `?external_source=${encodeURIComponent(opts.externalSource)}`;
38047
+ printOutput(await client.request("GET", path36), outputFormat(this));
37600
38048
  });
37601
38049
  records.command("delete <record_type> <id>").description(
37602
38050
  "Delete a record by internal ID, or by external_id (pass --external-source to scope it)"
@@ -37610,11 +38058,11 @@ function buildRecordsCommand() {
37610
38058
  }
37611
38059
  const base = pathSegment(requireBase(this), "--base");
37612
38060
  const client = await createDataClient();
37613
- let path35 = `/v1/${base}/records/${pathSegment(recordType2, "record_type")}/${recordKey(id, opts.externalSource)}`;
38061
+ let path36 = `/v1/${base}/records/${pathSegment(recordType2, "record_type")}/${recordKey(id, opts.externalSource)}`;
37614
38062
  if (opts.externalSource) {
37615
- path35 += `?external_source=${encodeURIComponent(opts.externalSource)}&external_id=${encodeURIComponent(id)}`;
38063
+ path36 += `?external_source=${encodeURIComponent(opts.externalSource)}&external_id=${encodeURIComponent(id)}`;
37616
38064
  }
37617
- await client.request("DELETE", path35);
38065
+ await client.request("DELETE", path36);
37618
38066
  console.log("Deleted");
37619
38067
  });
37620
38068
  records.command("history <id>").description(
@@ -37779,8 +38227,8 @@ function buildRelationshipsCommand() {
37779
38227
  if (opts.data) body.data = parseData(opts.data);
37780
38228
  const base = pathSegment(requireBase(this), "--base");
37781
38229
  const client = await createDataClient();
37782
- const path35 = opts.id ? `/v1/${base}/relationships/${pathSegment(opts.id, "--id")}` : `/v1/${base}/relationships`;
37783
- printOutput(await client.request("PUT", path35, body), outputFormat(this));
38230
+ const path36 = opts.id ? `/v1/${base}/relationships/${pathSegment(opts.id, "--id")}` : `/v1/${base}/relationships`;
38231
+ printOutput(await client.request("PUT", path36, body), outputFormat(this));
37784
38232
  });
37785
38233
  relationships.command("get <id>").description(
37786
38234
  "Get a relationship by ID (or by its external key: pass the external_id with --rel-type)"
@@ -38013,8 +38461,8 @@ function buildToolsetsCommand() {
38013
38461
  toolsets.command("get <slug>").description("Get a toolset").option("--resolved", "Include resolved record_type schemas").action(async function(slug, opts) {
38014
38462
  const base = pathSegment(requireBase(this), "--base");
38015
38463
  const client = await createDataClient();
38016
- const path35 = opts.resolved ? `/v1/${base}/toolsets/${pathSegment(slug, "toolset slug")}/resolved` : `/v1/${base}/toolsets/${pathSegment(slug, "toolset slug")}`;
38017
- printOutput(await client.request("GET", path35), outputFormat(this));
38464
+ const path36 = opts.resolved ? `/v1/${base}/toolsets/${pathSegment(slug, "toolset slug")}/resolved` : `/v1/${base}/toolsets/${pathSegment(slug, "toolset slug")}`;
38465
+ printOutput(await client.request("GET", path36), outputFormat(this));
38018
38466
  });
38019
38467
  toolsets.command("list").description("List all toolsets").action(async function() {
38020
38468
  const base = pathSegment(requireBase(this), "--base");
@@ -38247,9 +38695,9 @@ init_errors2();
38247
38695
  init_mask_secrets();
38248
38696
  init_utils();
38249
38697
  init_registry();
38250
- import { readFileSync as readFileSync24 } from "fs";
38698
+ import { readFileSync as readFileSync25 } from "fs";
38251
38699
  import { fileURLToPath as fileURLToPath3 } from "url";
38252
- import { dirname as dirname16, join as join32 } from "path";
38700
+ import { dirname as dirname16, join as join33 } from "path";
38253
38701
 
38254
38702
  // src/lib/version-refresh.ts
38255
38703
  init_version_cache();
@@ -38257,7 +38705,7 @@ init_skill_version();
38257
38705
  import { exec } from "child_process";
38258
38706
  var REFRESH_TIMEOUT_MS = 1e4;
38259
38707
  function refreshCliCache() {
38260
- return new Promise((resolve10) => {
38708
+ return new Promise((resolve11) => {
38261
38709
  exec("npm view @wayai/cli version", { timeout: REFRESH_TIMEOUT_MS }, (err, stdout) => {
38262
38710
  if (!err) {
38263
38711
  const latest = stdout.trim();
@@ -38268,7 +38716,7 @@ function refreshCliCache() {
38268
38716
  }
38269
38717
  }
38270
38718
  }
38271
- resolve10();
38719
+ resolve11();
38272
38720
  });
38273
38721
  });
38274
38722
  }
@@ -38294,8 +38742,8 @@ async function refreshSkillCache() {
38294
38742
  }
38295
38743
  async function refreshAdminSkillCache() {
38296
38744
  let timer;
38297
- const deadline = new Promise((resolve10) => {
38298
- timer = setTimeout(resolve10, REFRESH_TIMEOUT_MS);
38745
+ const deadline = new Promise((resolve11) => {
38746
+ timer = setTimeout(resolve11, REFRESH_TIMEOUT_MS);
38299
38747
  });
38300
38748
  await Promise.race([deadline, fetchAndCacheAdminSkillVersion().catch(() => {
38301
38749
  })]);
@@ -38405,7 +38853,7 @@ Run \`wayai admin skill install\` to update.`);
38405
38853
 
38406
38854
  // src/index.ts
38407
38855
  var __dirname = dirname16(fileURLToPath3(import.meta.url));
38408
- var pkg = JSON.parse(readFileSync24(join32(__dirname, "..", "package.json"), "utf-8"));
38856
+ var pkg = JSON.parse(readFileSync25(join33(__dirname, "..", "package.json"), "utf-8"));
38409
38857
  var [, , command, ...args] = process.argv;
38410
38858
  var isBackgroundRefresh = command === REFRESH_COMMAND;
38411
38859
  if (!isBackgroundRefresh) initSentry(command, pkg.version);