@wayai/cli 0.3.162 → 0.3.164
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 +3097 -227
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4624,6 +4624,327 @@ function normalizeAuthType(raw) {
|
|
|
4624
4624
|
if (VALID_AUTH_TYPES.has(raw)) return raw;
|
|
4625
4625
|
return LEGACY_AUTH_TYPE_MAP[raw] ?? raw;
|
|
4626
4626
|
}
|
|
4627
|
+
function schemaToQuestions(schema) {
|
|
4628
|
+
const classified = classifySchema(schema);
|
|
4629
|
+
if (classified.refusals.length > 0) return { ok: false, refusals: classified.refusals };
|
|
4630
|
+
const questions = {};
|
|
4631
|
+
for (const [field, primitive] of classified.fields) {
|
|
4632
|
+
questions[field] = toQuestion(primitive);
|
|
4633
|
+
}
|
|
4634
|
+
return { ok: true, questions };
|
|
4635
|
+
}
|
|
4636
|
+
function classifySchema(schema) {
|
|
4637
|
+
const fields = /* @__PURE__ */ new Map();
|
|
4638
|
+
if (!isRecord(schema) || schema.type !== "object") {
|
|
4639
|
+
return { fields, refusals: [{ field: null, reason: "schema_not_object" }] };
|
|
4640
|
+
}
|
|
4641
|
+
const properties = schema.properties;
|
|
4642
|
+
if (!isRecord(properties) || Object.keys(properties).length === 0) {
|
|
4643
|
+
return { fields, refusals: [{ field: null, reason: "schema_has_no_properties" }] };
|
|
4644
|
+
}
|
|
4645
|
+
const refusals = [];
|
|
4646
|
+
for (const [field, property] of Object.entries(properties)) {
|
|
4647
|
+
const primitive = classifyField(field, property);
|
|
4648
|
+
if ("reason" in primitive) {
|
|
4649
|
+
refusals.push({ field, reason: primitive.reason });
|
|
4650
|
+
continue;
|
|
4651
|
+
}
|
|
4652
|
+
fields.set(field, primitive);
|
|
4653
|
+
}
|
|
4654
|
+
return refusals.length > 0 ? { fields: /* @__PURE__ */ new Map(), refusals } : { fields, refusals };
|
|
4655
|
+
}
|
|
4656
|
+
function classifyField(field, property) {
|
|
4657
|
+
if (!isRecord(property)) return { reason: "unsupported_type" };
|
|
4658
|
+
const instructions = describeField(field, property);
|
|
4659
|
+
if (property.enum !== void 0) {
|
|
4660
|
+
const declared = property.enum;
|
|
4661
|
+
if (!Array.isArray(declared) || declared.some((option) => typeof option !== "string")) {
|
|
4662
|
+
return { reason: "unsupported_type" };
|
|
4663
|
+
}
|
|
4664
|
+
const options = [...new Set(declared)];
|
|
4665
|
+
if (options.length < 2) return { reason: "too_few_options" };
|
|
4666
|
+
return { kind: "choice", instructions, options };
|
|
4667
|
+
}
|
|
4668
|
+
if (property.type === "boolean") return { kind: "noul", instructions };
|
|
4669
|
+
if (property.type === "integer") {
|
|
4670
|
+
const minimum = property.minimum;
|
|
4671
|
+
const maximum = property.maximum;
|
|
4672
|
+
if (!Number.isInteger(minimum) || !Number.isInteger(maximum)) {
|
|
4673
|
+
return { reason: "integer_not_bounded" };
|
|
4674
|
+
}
|
|
4675
|
+
const levels = maximum - minimum + 1;
|
|
4676
|
+
if (levels < DECISION_SCORE_MIN_LEVELS) return { reason: "too_few_options" };
|
|
4677
|
+
if (levels > DECISION_SCORE_MAX_LEVELS) return { reason: "integer_range_too_large" };
|
|
4678
|
+
return { kind: "score", instructions, minimum, levels };
|
|
4679
|
+
}
|
|
4680
|
+
return { reason: "unsupported_type" };
|
|
4681
|
+
}
|
|
4682
|
+
function toQuestion(primitive) {
|
|
4683
|
+
switch (primitive.kind) {
|
|
4684
|
+
case "choice":
|
|
4685
|
+
return {
|
|
4686
|
+
type: "choice",
|
|
4687
|
+
instructions: primitive.instructions,
|
|
4688
|
+
// A JSON Schema enum carries no per-option text, so each option stands as
|
|
4689
|
+
// its own description. The distinguishing detail an option needs belongs
|
|
4690
|
+
// in the field's `description`, which is the instructions.
|
|
4691
|
+
criteria: Object.fromEntries(primitive.options.map((option) => [option, option]))
|
|
4692
|
+
};
|
|
4693
|
+
case "noul":
|
|
4694
|
+
return { type: "noul", instructions: primitive.instructions };
|
|
4695
|
+
case "score":
|
|
4696
|
+
return {
|
|
4697
|
+
type: "score",
|
|
4698
|
+
instructions: primitive.instructions,
|
|
4699
|
+
criteria: scoreLevels(primitive.minimum, primitive.levels)
|
|
4700
|
+
};
|
|
4701
|
+
}
|
|
4702
|
+
}
|
|
4703
|
+
function describeField(field, property) {
|
|
4704
|
+
const description = isRecord(property) ? property.description : void 0;
|
|
4705
|
+
return typeof description === "string" && description.trim() !== "" ? description : field;
|
|
4706
|
+
}
|
|
4707
|
+
function scoreLevels(minimum, levels) {
|
|
4708
|
+
return Array.from({ length: levels }, (_, index) => String(minimum + index));
|
|
4709
|
+
}
|
|
4710
|
+
function isRecord(value) {
|
|
4711
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4712
|
+
}
|
|
4713
|
+
function isDecisionsModel(modelId) {
|
|
4714
|
+
if (typeof modelId !== "string") return false;
|
|
4715
|
+
const normalized = modelId.trim().toLowerCase();
|
|
4716
|
+
return DECISIONS_MODEL_PREFIXES.some((prefix) => normalized.startsWith(prefix));
|
|
4717
|
+
}
|
|
4718
|
+
function checkDecisionsModelBinding(agent) {
|
|
4719
|
+
if (!isDecisionsModel(agent.model)) return null;
|
|
4720
|
+
const model = String(agent.model);
|
|
4721
|
+
const role = agent.agent_role;
|
|
4722
|
+
if (!DECISION_CAPABLE_AGENT_ROLES.includes(role)) {
|
|
4723
|
+
return refuse(
|
|
4724
|
+
"role_produces_text",
|
|
4725
|
+
`agent_role "${String(role)}" produces text, which the decisions model "${model}" does not return. A decisions model binds to: ${DECISION_CAPABLE_AGENT_ROLES.join(", ")}.`
|
|
4726
|
+
);
|
|
4727
|
+
}
|
|
4728
|
+
if (agent.response_format !== "json_schema") {
|
|
4729
|
+
return refuse(
|
|
4730
|
+
"response_format_not_json_schema",
|
|
4731
|
+
`response_format must be "json_schema" to bind the decisions model "${model}".`
|
|
4732
|
+
);
|
|
4733
|
+
}
|
|
4734
|
+
if (agent.schema_json === null || agent.schema_json === void 0 || agent.schema_json === "") {
|
|
4735
|
+
return refuse(
|
|
4736
|
+
"schema_missing",
|
|
4737
|
+
`schema_json is required to bind the decisions model "${model}": a decisions model answers questions, and the schema is where they come from.`
|
|
4738
|
+
);
|
|
4739
|
+
}
|
|
4740
|
+
let schema = agent.schema_json;
|
|
4741
|
+
if (typeof schema === "string") {
|
|
4742
|
+
try {
|
|
4743
|
+
schema = JSON.parse(schema);
|
|
4744
|
+
} catch {
|
|
4745
|
+
return refuse(
|
|
4746
|
+
"schema_unreadable",
|
|
4747
|
+
`schema_json is not valid JSON, so the decisions model "${model}" cannot be bound.`
|
|
4748
|
+
);
|
|
4749
|
+
}
|
|
4750
|
+
}
|
|
4751
|
+
const mapped = schemaToQuestions(schema);
|
|
4752
|
+
if (mapped.ok) return null;
|
|
4753
|
+
const detail = mapped.refusals.map((refusal2) => `${refusal2.field ?? "(schema)"}: ${refusal2.reason}`).join("; ");
|
|
4754
|
+
return {
|
|
4755
|
+
reason: "schema_not_closed_set",
|
|
4756
|
+
schema_refusals: mapped.refusals,
|
|
4757
|
+
message: `schema_json is not closed-set, so the decisions model "${model}" cannot answer it \u2014 ${detail}. A decisions model answers enum, boolean and bounded-integer fields only.`
|
|
4758
|
+
};
|
|
4759
|
+
}
|
|
4760
|
+
function refuse(reason, message) {
|
|
4761
|
+
return { reason, schema_refusals: [], message };
|
|
4762
|
+
}
|
|
4763
|
+
function readAgentSettingsModel(agentSettings) {
|
|
4764
|
+
let settings = agentSettings;
|
|
4765
|
+
if (typeof settings === "string") {
|
|
4766
|
+
try {
|
|
4767
|
+
settings = JSON.parse(settings);
|
|
4768
|
+
} catch {
|
|
4769
|
+
return null;
|
|
4770
|
+
}
|
|
4771
|
+
}
|
|
4772
|
+
if (typeof settings !== "object" || settings === null || Array.isArray(settings)) return null;
|
|
4773
|
+
const model = settings.model;
|
|
4774
|
+
return typeof model === "string" ? model : null;
|
|
4775
|
+
}
|
|
4776
|
+
function resolveMonitorTrigger(monitorConfig) {
|
|
4777
|
+
if (!monitorConfig || typeof monitorConfig !== "object") return "idle";
|
|
4778
|
+
const raw = monitorConfig.trigger;
|
|
4779
|
+
return MONITOR_TRIGGERS.includes(raw) ? raw : "idle";
|
|
4780
|
+
}
|
|
4781
|
+
function isFiringTrigger(trigger) {
|
|
4782
|
+
return trigger !== "manual";
|
|
4783
|
+
}
|
|
4784
|
+
function monitorConfigNeedsDelay(monitorConfig) {
|
|
4785
|
+
if (!monitorConfig || typeof monitorConfig !== "object") return false;
|
|
4786
|
+
return resolveMonitorTrigger(monitorConfig) === "idle" && monitorConfig.delay_seconds === void 0;
|
|
4787
|
+
}
|
|
4788
|
+
function monitorInputShapingKeysOnIdle(monitorConfig) {
|
|
4789
|
+
if (!monitorConfig || typeof monitorConfig !== "object") return [];
|
|
4790
|
+
if (resolveMonitorTrigger(monitorConfig) !== "idle") return [];
|
|
4791
|
+
const config = monitorConfig;
|
|
4792
|
+
return MONITOR_INPUT_SHAPING_KEYS.filter((key) => config[key] !== void 0);
|
|
4793
|
+
}
|
|
4794
|
+
function monitorRuleKeysOffTrigger(monitorConfig) {
|
|
4795
|
+
if (!monitorConfig || typeof monitorConfig !== "object") return [];
|
|
4796
|
+
if (MONITOR_RULE_TRIGGERS.includes(resolveMonitorTrigger(monitorConfig))) return [];
|
|
4797
|
+
const config = monitorConfig;
|
|
4798
|
+
return MONITOR_RULE_KEYS.filter((key) => config[key] !== void 0);
|
|
4799
|
+
}
|
|
4800
|
+
function monitorRuleActionKinds(trigger) {
|
|
4801
|
+
return trigger === "assistant_reply" ? MONITOR_ASSISTANT_REPLY_ACTION_KINDS : MONITOR_USER_MESSAGE_ACTION_KINDS;
|
|
4802
|
+
}
|
|
4803
|
+
function monitorActionKindMessage(kind, trigger) {
|
|
4804
|
+
const allowed = monitorRuleActionKinds(trigger).join(", ");
|
|
4805
|
+
if (trigger === "assistant_reply") {
|
|
4806
|
+
return `an assistant_reply rule cannot select "${kind}". Use one of: ${allowed}.`;
|
|
4807
|
+
}
|
|
4808
|
+
return `a monitor rule cannot select "${kind}": it acts before the reply exists. Use one of: ${allowed}.`;
|
|
4809
|
+
}
|
|
4810
|
+
function monitorRuleReentryTrack(toolName) {
|
|
4811
|
+
return MONITOR_RULE_REENTRY_TRACKS.get(toolName);
|
|
4812
|
+
}
|
|
4813
|
+
function monitorRuleToolNotAllowedMessage(toolName, trigger) {
|
|
4814
|
+
if (trigger === "assistant_reply" && isReplyGateRefusedToolName(toolName)) {
|
|
4815
|
+
return `an assistant_reply rule cannot call "${toolName}": the reply already exists when this monitor runs, so there is no turn left for it to act on. Put it on a user_message monitor instead, which runs before the answering agent.`;
|
|
4816
|
+
}
|
|
4817
|
+
const callable = trigger === "assistant_reply" ? MONITOR_RULE_ALLOWED_NATIVE_TOOLS.filter((name) => !isReplyGateRefusedToolName(name)) : MONITOR_RULE_ALLOWED_NATIVE_TOOLS;
|
|
4818
|
+
return `a ${trigger} rule cannot call "${toolName}". Rules can call ${callable.join(", ")}, and this hub's own external HTTP and MCP tools. Assign anything else to the answering agent instead.`;
|
|
4819
|
+
}
|
|
4820
|
+
function isReplyGateRefusedToolName(toolName) {
|
|
4821
|
+
return monitorRuleReentryTrack(toolName) === "agent" || toolName === INSERT_NOTE_TOOL_NAME;
|
|
4822
|
+
}
|
|
4823
|
+
function isRefusedNativeToolName(toolName, trigger) {
|
|
4824
|
+
if (!NATIVE_TOOL_NAMES.has(toolName)) return false;
|
|
4825
|
+
if (!MONITOR_RULE_ALLOWED_NATIVE_TOOLS.includes(toolName)) return true;
|
|
4826
|
+
return trigger === "assistant_reply" && isReplyGateRefusedToolName(toolName);
|
|
4827
|
+
}
|
|
4828
|
+
function monitorRuleActions(monitorConfig) {
|
|
4829
|
+
if (!monitorConfig || typeof monitorConfig !== "object") return [];
|
|
4830
|
+
const config = monitorConfig;
|
|
4831
|
+
const found = [];
|
|
4832
|
+
const visit = (action, path35) => {
|
|
4833
|
+
if (!action || typeof action !== "object" || Array.isArray(action)) return;
|
|
4834
|
+
found.push({ action, path: path35 });
|
|
4835
|
+
};
|
|
4836
|
+
if (Array.isArray(config.rules)) {
|
|
4837
|
+
config.rules.forEach((rule, index) => {
|
|
4838
|
+
if (!rule || typeof rule !== "object" || Array.isArray(rule)) return;
|
|
4839
|
+
visit(rule.action, ["rules", index, "action"]);
|
|
4840
|
+
});
|
|
4841
|
+
}
|
|
4842
|
+
visit(config.fallback, ["fallback"]);
|
|
4843
|
+
return found;
|
|
4844
|
+
}
|
|
4845
|
+
function collectMonitorRuleIssues(monitorConfig) {
|
|
4846
|
+
const offTrigger = monitorRuleKeysOffTrigger(monitorConfig).map((key) => ({ path: [key], message: MONITOR_RULE_TRIGGER_MESSAGE }));
|
|
4847
|
+
if (offTrigger.length > 0) return offTrigger;
|
|
4848
|
+
const trigger = resolveMonitorTrigger(monitorConfig);
|
|
4849
|
+
const kinds = monitorRuleActionKinds(trigger);
|
|
4850
|
+
const issues = [];
|
|
4851
|
+
for (const { action, path: path35 } of monitorRuleActions(monitorConfig)) {
|
|
4852
|
+
const kind = action.kind;
|
|
4853
|
+
if (typeof kind === "string" && !kinds.includes(kind)) {
|
|
4854
|
+
issues.push({ path: [...path35, "kind"], message: monitorActionKindMessage(kind, trigger) });
|
|
4855
|
+
}
|
|
4856
|
+
const toolName = action.tool_name;
|
|
4857
|
+
if (kind === "call_tool" && typeof toolName === "string" && isRefusedNativeToolName(toolName, trigger)) {
|
|
4858
|
+
issues.push({ path: [...path35, "tool_name"], message: monitorRuleToolNotAllowedMessage(toolName, trigger) });
|
|
4859
|
+
continue;
|
|
4860
|
+
}
|
|
4861
|
+
if (kind === "call_tool" && toolName === INSERT_NOTE_TOOL_NAME) {
|
|
4862
|
+
issues.push(...insertNoteArgumentIssues(action, path35));
|
|
4863
|
+
}
|
|
4864
|
+
if (kind === "call_tool" && toolName === RUN_MONITOR_TOOL_NAME) {
|
|
4865
|
+
const callee = readRunMonitorCallee(action);
|
|
4866
|
+
if (!callee.ok) {
|
|
4867
|
+
issues.push({
|
|
4868
|
+
path: [...path35, "args", "monitor_name"],
|
|
4869
|
+
message: runMonitorCalleeMessage(callee.reason)
|
|
4870
|
+
});
|
|
4871
|
+
}
|
|
4872
|
+
}
|
|
4873
|
+
}
|
|
4874
|
+
return issues;
|
|
4875
|
+
}
|
|
4876
|
+
function readInsertNoteTemplate(action) {
|
|
4877
|
+
const read = readConstStringArg(action, "template");
|
|
4878
|
+
if (!read.ok) {
|
|
4879
|
+
return {
|
|
4880
|
+
ok: false,
|
|
4881
|
+
reason: read.reason === "missing" ? "note_template_missing" : read.reason === "not_const" ? "note_template_not_const" : "note_template_empty"
|
|
4882
|
+
};
|
|
4883
|
+
}
|
|
4884
|
+
if (read.value.length > MONITOR_NOTE_TEMPLATE_MAX) {
|
|
4885
|
+
return { ok: false, reason: "note_template_too_long" };
|
|
4886
|
+
}
|
|
4887
|
+
return { ok: true, template: read.value };
|
|
4888
|
+
}
|
|
4889
|
+
function readConstStringArg(action, argName) {
|
|
4890
|
+
const args2 = action && typeof action === "object" ? action.args : void 0;
|
|
4891
|
+
const arg = args2 && typeof args2 === "object" ? args2[argName] : void 0;
|
|
4892
|
+
if (arg === void 0) return { ok: false, reason: "missing" };
|
|
4893
|
+
const constValue = arg && typeof arg === "object" && !Array.isArray(arg) ? arg.const : void 0;
|
|
4894
|
+
if (typeof constValue !== "string") return { ok: false, reason: "not_const" };
|
|
4895
|
+
if (constValue.trim() === "") return { ok: false, reason: "empty" };
|
|
4896
|
+
return { ok: true, value: constValue };
|
|
4897
|
+
}
|
|
4898
|
+
function readRunMonitorCallee(action) {
|
|
4899
|
+
const read = readConstStringArg(action, "monitor_name");
|
|
4900
|
+
if (read.ok) return { ok: true, name: read.value };
|
|
4901
|
+
return {
|
|
4902
|
+
ok: false,
|
|
4903
|
+
reason: read.reason === "missing" ? "callee_missing" : read.reason === "not_const" ? "callee_not_const" : "callee_empty"
|
|
4904
|
+
};
|
|
4905
|
+
}
|
|
4906
|
+
function runMonitorCalleeMessage(reason) {
|
|
4907
|
+
switch (reason) {
|
|
4908
|
+
case "callee_missing":
|
|
4909
|
+
return "run_monitor needs a monitor_name: the monitor to run.";
|
|
4910
|
+
case "callee_not_const":
|
|
4911
|
+
return "run_monitor's monitor_name must be a const you write \u2014 it chooses which monitor runs, so it cannot come from a variable.";
|
|
4912
|
+
case "callee_empty":
|
|
4913
|
+
return "run_monitor's monitor_name is empty \u2014 name the monitor to run.";
|
|
4914
|
+
}
|
|
4915
|
+
}
|
|
4916
|
+
function insertNoteTemplateMessage(reason) {
|
|
4917
|
+
switch (reason) {
|
|
4918
|
+
case "note_template_missing":
|
|
4919
|
+
return "insert_note needs a template: the note text to put in front of the answering agent.";
|
|
4920
|
+
case "note_template_not_const":
|
|
4921
|
+
return "insert_note's template must be a const string you write \u2014 the answering agent reads it as instructions, so it cannot come from a variable. Use {{variable_name}} inside it to substitute this monitor's variables.";
|
|
4922
|
+
case "note_template_empty":
|
|
4923
|
+
return "insert_note's template is empty \u2014 remove the rule, or give it something to say.";
|
|
4924
|
+
case "note_template_too_long":
|
|
4925
|
+
return `insert_note's template is longer than the ${MONITOR_NOTE_TEMPLATE_MAX}-character limit.`;
|
|
4926
|
+
}
|
|
4927
|
+
}
|
|
4928
|
+
function insertNoteArgumentIssues(action, path35) {
|
|
4929
|
+
const result = readInsertNoteTemplate(action);
|
|
4930
|
+
if (result.ok) return [];
|
|
4931
|
+
return [{
|
|
4932
|
+
path: [...path35, "args", "template"],
|
|
4933
|
+
message: insertNoteTemplateMessage(result.reason)
|
|
4934
|
+
}];
|
|
4935
|
+
}
|
|
4936
|
+
function refineDecisionsModelBinding(body, ctx) {
|
|
4937
|
+
const agent = body;
|
|
4938
|
+
const refusal2 = checkDecisionsModelBinding({
|
|
4939
|
+
model: readAgentSettingsModel(agent.agent_settings),
|
|
4940
|
+
agent_role: agent.agent_role,
|
|
4941
|
+
response_format: agent.response_format,
|
|
4942
|
+
schema_json: agent.schema_json
|
|
4943
|
+
});
|
|
4944
|
+
if (refusal2) {
|
|
4945
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["agent_settings", "model"], message: refusal2.message });
|
|
4946
|
+
}
|
|
4947
|
+
}
|
|
4627
4948
|
function visibleLength(s) {
|
|
4628
4949
|
return s.replace(INVISIBLE_NAME_CHARS, "").length;
|
|
4629
4950
|
}
|
|
@@ -4743,7 +5064,7 @@ function extractToolParameters(toolConfig) {
|
|
|
4743
5064
|
if (!cfg || typeof cfg !== "object" || Array.isArray(cfg)) return void 0;
|
|
4744
5065
|
return cfg.parameters;
|
|
4745
5066
|
}
|
|
4746
|
-
function
|
|
5067
|
+
function isRecord2(v) {
|
|
4747
5068
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
4748
5069
|
}
|
|
4749
5070
|
function isPrimitive(v) {
|
|
@@ -4765,7 +5086,7 @@ function validateSchema(schema, path35, errors, opts = {}) {
|
|
|
4765
5086
|
});
|
|
4766
5087
|
return;
|
|
4767
5088
|
}
|
|
4768
|
-
if (!
|
|
5089
|
+
if (!isRecord2(schema)) {
|
|
4769
5090
|
errors.push({
|
|
4770
5091
|
path: path35,
|
|
4771
5092
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
@@ -4827,7 +5148,7 @@ function validateSchema(schema, path35, errors, opts = {}) {
|
|
|
4827
5148
|
}
|
|
4828
5149
|
}
|
|
4829
5150
|
if ("properties" in schema) {
|
|
4830
|
-
if (!
|
|
5151
|
+
if (!isRecord2(schema.properties)) {
|
|
4831
5152
|
errors.push({
|
|
4832
5153
|
path: `${path35}.properties`,
|
|
4833
5154
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
@@ -4846,7 +5167,7 @@ function validateSchema(schema, path35, errors, opts = {}) {
|
|
|
4846
5167
|
}
|
|
4847
5168
|
}
|
|
4848
5169
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS) {
|
|
4849
|
-
if (key in schema &&
|
|
5170
|
+
if (key in schema && isRecord2(schema[key])) {
|
|
4850
5171
|
validateSchema(schema[key], `${path35}.${key}`, errors, { depth: depth + 1 });
|
|
4851
5172
|
}
|
|
4852
5173
|
}
|
|
@@ -4858,7 +5179,7 @@ function validateSchema(schema, path35, errors, opts = {}) {
|
|
|
4858
5179
|
}
|
|
4859
5180
|
for (const key of SUBSCHEMA_MAP_KEYWORDS) {
|
|
4860
5181
|
const map = schema[key];
|
|
4861
|
-
if (
|
|
5182
|
+
if (isRecord2(map)) {
|
|
4862
5183
|
for (const [name, sub] of Object.entries(map)) {
|
|
4863
5184
|
validateSchema(sub, `${path35}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
4864
5185
|
}
|
|
@@ -4888,7 +5209,7 @@ function schemaTypeIncludes(schema, wanted) {
|
|
|
4888
5209
|
}
|
|
4889
5210
|
function validateToolInputSchema(schema) {
|
|
4890
5211
|
const errors = [];
|
|
4891
|
-
if (!
|
|
5212
|
+
if (!isRecord2(schema)) {
|
|
4892
5213
|
errors.push({
|
|
4893
5214
|
path: "",
|
|
4894
5215
|
message: `expected object at root, got ${schema === null ? "null" : typeof schema}`
|
|
@@ -5369,7 +5690,120 @@ function refineHubAsCodeDelegation(config, ctx) {
|
|
|
5369
5690
|
});
|
|
5370
5691
|
});
|
|
5371
5692
|
}
|
|
5372
|
-
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, previousConversationsCountField, summarizationThresholdField, monitorConfigField, 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, 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, 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, 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;
|
|
5693
|
+
function refineHubAsCodeFlagConditions(config, ctx) {
|
|
5694
|
+
const agents = config?.agents;
|
|
5695
|
+
if (!Array.isArray(agents)) return;
|
|
5696
|
+
const checkList = (list, basePath) => {
|
|
5697
|
+
if (!Array.isArray(list)) return;
|
|
5698
|
+
list.forEach((row, rowIndex) => {
|
|
5699
|
+
const operator = row?.operator;
|
|
5700
|
+
if (!FLAG_CONDITION_OPERATORS.includes(operator)) {
|
|
5701
|
+
ctx.addIssue({
|
|
5702
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5703
|
+
path: [...basePath, rowIndex, "operator"],
|
|
5704
|
+
message: `operator must be one of: ${FLAG_CONDITION_OPERATORS.join(", ")}`
|
|
5705
|
+
});
|
|
5706
|
+
}
|
|
5707
|
+
});
|
|
5708
|
+
};
|
|
5709
|
+
agents.forEach((agent, agentIndex) => {
|
|
5710
|
+
const a = agent;
|
|
5711
|
+
checkList(a?.flag_conditions, ["agents", agentIndex, "flag_conditions"]);
|
|
5712
|
+
const monitorConfig = a?.monitor_config;
|
|
5713
|
+
if (monitorConfig && typeof monitorConfig === "object" && !Array.isArray(monitorConfig)) {
|
|
5714
|
+
const base = ["agents", agentIndex, "monitor_config"];
|
|
5715
|
+
checkList(
|
|
5716
|
+
monitorConfig.flag_conditions,
|
|
5717
|
+
[...base, "flag_conditions"]
|
|
5718
|
+
);
|
|
5719
|
+
const rules = monitorConfig.rules;
|
|
5720
|
+
if (Array.isArray(rules)) {
|
|
5721
|
+
rules.forEach((rule, ruleIndex) => {
|
|
5722
|
+
if (!rule || typeof rule !== "object" || Array.isArray(rule)) return;
|
|
5723
|
+
checkList(rule.when, [...base, "rules", ruleIndex, "when"]);
|
|
5724
|
+
});
|
|
5725
|
+
}
|
|
5726
|
+
}
|
|
5727
|
+
});
|
|
5728
|
+
}
|
|
5729
|
+
function refineHubAsCodeMonitorConfig(config, ctx) {
|
|
5730
|
+
const agents = config?.agents;
|
|
5731
|
+
if (!Array.isArray(agents)) return;
|
|
5732
|
+
agents.forEach((agent, agentIndex) => {
|
|
5733
|
+
const monitorConfig = agent?.monitor_config;
|
|
5734
|
+
if (!monitorConfig || typeof monitorConfig !== "object" || Array.isArray(monitorConfig)) return;
|
|
5735
|
+
const basePath = ["agents", agentIndex, "monitor_config"];
|
|
5736
|
+
const checkKeyValues = (keys, schemas) => {
|
|
5737
|
+
for (const key of keys) {
|
|
5738
|
+
const value = monitorConfig[key];
|
|
5739
|
+
if (value === void 0) continue;
|
|
5740
|
+
const parsed = schemas[key].safeParse(value);
|
|
5741
|
+
if (!parsed.success) {
|
|
5742
|
+
ctx.addIssue({
|
|
5743
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5744
|
+
path: [...basePath, key],
|
|
5745
|
+
message: parsed.error?.issues[0]?.message ?? `invalid ${key}`
|
|
5746
|
+
});
|
|
5747
|
+
}
|
|
5748
|
+
}
|
|
5749
|
+
};
|
|
5750
|
+
const trigger = monitorConfig.trigger;
|
|
5751
|
+
if (trigger !== void 0 && !MONITOR_TRIGGERS.includes(trigger)) {
|
|
5752
|
+
ctx.addIssue({
|
|
5753
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5754
|
+
path: [...basePath, "trigger"],
|
|
5755
|
+
message: `trigger must be one of: ${MONITOR_TRIGGERS.join(", ")}`
|
|
5756
|
+
});
|
|
5757
|
+
return;
|
|
5758
|
+
}
|
|
5759
|
+
if (monitorConfigNeedsDelay(monitorConfig)) {
|
|
5760
|
+
ctx.addIssue({
|
|
5761
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5762
|
+
path: [...basePath, "delay_seconds"],
|
|
5763
|
+
message: MONITOR_IDLE_DELAY_REQUIRED_MESSAGE
|
|
5764
|
+
});
|
|
5765
|
+
}
|
|
5766
|
+
for (const key of monitorInputShapingKeysOnIdle(monitorConfig)) {
|
|
5767
|
+
ctx.addIssue({
|
|
5768
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5769
|
+
path: [...basePath, key],
|
|
5770
|
+
message: MONITOR_INPUT_SHAPING_IDLE_MESSAGE
|
|
5771
|
+
});
|
|
5772
|
+
}
|
|
5773
|
+
checkKeyValues(MONITOR_INPUT_SHAPING_KEYS, MONITOR_INPUT_SHAPING_SCHEMAS);
|
|
5774
|
+
checkKeyValues(MONITOR_RULE_KEYS, MONITOR_RULE_SCHEMAS);
|
|
5775
|
+
for (const issue of collectMonitorRuleIssues(monitorConfig)) {
|
|
5776
|
+
ctx.addIssue({
|
|
5777
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5778
|
+
path: [...basePath, ...issue.path],
|
|
5779
|
+
message: issue.message
|
|
5780
|
+
});
|
|
5781
|
+
}
|
|
5782
|
+
});
|
|
5783
|
+
}
|
|
5784
|
+
function refineHubAsCodeDecisionsModel(config, ctx) {
|
|
5785
|
+
const agents = config?.agents;
|
|
5786
|
+
if (!Array.isArray(agents)) return;
|
|
5787
|
+
agents.forEach((agent, agentIndex) => {
|
|
5788
|
+
const a = agent;
|
|
5789
|
+
if (!a) return;
|
|
5790
|
+
const responseFormat = a.response_format;
|
|
5791
|
+
const refusal2 = checkDecisionsModelBinding({
|
|
5792
|
+
model: readAgentSettingsModel(a.settings),
|
|
5793
|
+
agent_role: a.role,
|
|
5794
|
+
response_format: responseFormat ? "json_schema" : "text",
|
|
5795
|
+
schema_json: responseFormat?.schema_json ?? null
|
|
5796
|
+
});
|
|
5797
|
+
if (refusal2) {
|
|
5798
|
+
ctx.addIssue({
|
|
5799
|
+
code: external_exports.ZodIssueCode.custom,
|
|
5800
|
+
path: ["agents", agentIndex, "settings", "model"],
|
|
5801
|
+
message: refusal2.message
|
|
5802
|
+
});
|
|
5803
|
+
}
|
|
5804
|
+
});
|
|
5805
|
+
}
|
|
5806
|
+
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, 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, 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, monitorActionSchema, monitorRuleSchema, MONITOR_RULE_KEYS, MONITOR_RULE_SCHEMAS, MONITOR_RULE_TRIGGERS, MONITOR_RULE_TRIGGER_MESSAGE, MONITOR_USER_MESSAGE_ACTION_KINDS, MONITOR_ASSISTANT_REPLY_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, 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, 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, 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;
|
|
5373
5807
|
var init_contracts = __esm({
|
|
5374
5808
|
"../../packages/core/dist/contracts/index.js"() {
|
|
5375
5809
|
"use strict";
|
|
@@ -5546,18 +5980,993 @@ var init_contracts = __esm({
|
|
|
5546
5980
|
SUMMARIZATION_THRESHOLD_MIN = 1e3;
|
|
5547
5981
|
SUMMARIZATION_THRESHOLD_MAX = 1e6;
|
|
5548
5982
|
PREVIOUS_CONVERSATIONS_MAX = 20;
|
|
5983
|
+
FLAG_CONDITION_OPERATORS = ["=", "!=", ">=", "<=", ">", "<"];
|
|
5984
|
+
DECISION_SCORE_MIN_LEVELS = 2;
|
|
5985
|
+
DECISION_SCORE_MAX_LEVELS = 10;
|
|
5986
|
+
DECISIONS_MODEL_PREFIXES = ["typesafe/jev-", "jev-"];
|
|
5987
|
+
DECISION_CAPABLE_AGENT_ROLES = [
|
|
5988
|
+
"monitor",
|
|
5989
|
+
"conversation_evaluator",
|
|
5990
|
+
"message_evaluator"
|
|
5991
|
+
];
|
|
5992
|
+
NATIVE_TOOL_SCHEMAS = {
|
|
5993
|
+
"close_conversation": {
|
|
5994
|
+
"tool_config": {
|
|
5995
|
+
"name": "close_conversation",
|
|
5996
|
+
"description": "Closes the current conversation and marks it as resolved",
|
|
5997
|
+
// Non-strict, mirroring the `update_kanban_status` sibling below: under strict
|
|
5998
|
+
// mode there are no optional fields, so `outcome` outside `required` makes the
|
|
5999
|
+
// provider reject the definition and `outcome` inside `required` forces the
|
|
6000
|
+
// model to emit it on every call. Requiredness is enforced SERVER-side instead
|
|
6001
|
+
// (ops `outcomeRequired`) — and it must stay out of `required` here, or
|
|
6002
|
+
// validateAndSanitizeToolParams would refuse the "retry without an outcome"
|
|
6003
|
+
// recovery path a re-close depends on.
|
|
6004
|
+
"strict": false,
|
|
6005
|
+
"parameters": {
|
|
6006
|
+
"type": "object",
|
|
6007
|
+
"properties": {
|
|
6008
|
+
"outcome": {
|
|
6009
|
+
"type": "string",
|
|
6010
|
+
"enum": "[KANBAN_OUTCOME_VALUES]",
|
|
6011
|
+
"description": "Required only when the hub's terminal (conversation-ending) status declares outcomes: the closing outcome. Available outcomes: [KANBAN_OUTCOME_NAMES]"
|
|
6012
|
+
}
|
|
6013
|
+
},
|
|
6014
|
+
"required": [],
|
|
6015
|
+
"additionalProperties": false
|
|
6016
|
+
}
|
|
6017
|
+
},
|
|
6018
|
+
"tool_instructions": "Use when the user's issue has been fully resolved."
|
|
6019
|
+
},
|
|
6020
|
+
"transfer_to_team": {
|
|
6021
|
+
"tool_config": {
|
|
6022
|
+
"name": "transfer_to_team",
|
|
6023
|
+
"description": "Hand off conversation to a human support team",
|
|
6024
|
+
"strict": true,
|
|
6025
|
+
"parameters": {
|
|
6026
|
+
"type": "object",
|
|
6027
|
+
"properties": {
|
|
6028
|
+
"team_name": {
|
|
6029
|
+
"type": "string",
|
|
6030
|
+
"description": "Name of the team to transfer to"
|
|
6031
|
+
}
|
|
6032
|
+
},
|
|
6033
|
+
"required": [
|
|
6034
|
+
"team_name"
|
|
6035
|
+
],
|
|
6036
|
+
"additionalProperties": false
|
|
6037
|
+
}
|
|
6038
|
+
},
|
|
6039
|
+
"tool_instructions": "Use when the user needs assistance that requires human intervention. The team will receive the full conversation history."
|
|
6040
|
+
},
|
|
6041
|
+
"delegate_to_hub": {
|
|
6042
|
+
"tool_config": {
|
|
6043
|
+
"name": "delegate_to_hub",
|
|
6044
|
+
"description": "Delegate a request to another hub. The target hub handles it as a task conversation and returns the result asynchronously.",
|
|
6045
|
+
"strict": true,
|
|
6046
|
+
"parameters": {
|
|
6047
|
+
"type": "object",
|
|
6048
|
+
"properties": {
|
|
6049
|
+
"request": {
|
|
6050
|
+
"type": "string",
|
|
6051
|
+
"description": "The request to delegate to the target hub, phrased as a self-contained task."
|
|
6052
|
+
}
|
|
6053
|
+
},
|
|
6054
|
+
"required": [
|
|
6055
|
+
"request"
|
|
6056
|
+
],
|
|
6057
|
+
"additionalProperties": false
|
|
6058
|
+
}
|
|
6059
|
+
},
|
|
6060
|
+
"tool_instructions": "Use to hand a self-contained request to a configured partner hub. The target hub is set by an admin on the tool; you do not choose it. The result comes back asynchronously \u2014 do not wait for it in this turn."
|
|
6061
|
+
},
|
|
6062
|
+
"start_consult_thread": {
|
|
6063
|
+
"tool_config": {
|
|
6064
|
+
"name": "start_consult_thread",
|
|
6065
|
+
"description": "Ask the consultant configured on this tool a question, in a consult thread the support team can see. The answer may come back in this turn or later.",
|
|
6066
|
+
"strict": true,
|
|
6067
|
+
"parameters": {
|
|
6068
|
+
"type": "object",
|
|
6069
|
+
"properties": {
|
|
6070
|
+
"question": {
|
|
6071
|
+
"type": "string",
|
|
6072
|
+
"description": "What you need from the consultant, phrased so it can be answered without further back-and-forth."
|
|
6073
|
+
},
|
|
6074
|
+
"title": {
|
|
6075
|
+
"type": "string",
|
|
6076
|
+
"description": "A short label for the consult thread (a few words), so the support team can tell parallel consults apart."
|
|
6077
|
+
}
|
|
6078
|
+
},
|
|
6079
|
+
"required": [
|
|
6080
|
+
"question",
|
|
6081
|
+
"title"
|
|
6082
|
+
],
|
|
6083
|
+
"additionalProperties": false
|
|
6084
|
+
}
|
|
6085
|
+
},
|
|
6086
|
+
"tool_instructions": "Use when answering needs knowledge you do not have and a consultant is configured for it. The consultant is set by an admin; you do not choose it. If the result says the answer will follow, END YOUR TURN \u2014 tell the customer you are checking and will come back to them. You will be brought back automatically when the answer arrives; do not poll or call this tool again for the same question."
|
|
6087
|
+
},
|
|
6088
|
+
"update_kanban_status": {
|
|
6089
|
+
"tool_config": {
|
|
6090
|
+
"name": "update_kanban_status",
|
|
6091
|
+
"description": "Updates the kanban status of the current conversation to track its progress through workflow stages",
|
|
6092
|
+
"strict": false,
|
|
6093
|
+
"parameters": {
|
|
6094
|
+
"type": "object",
|
|
6095
|
+
"properties": {
|
|
6096
|
+
"new_kanban_status": {
|
|
6097
|
+
"type": "string",
|
|
6098
|
+
"enum": "[KANBAN_STATUS_VALUES]",
|
|
6099
|
+
"description": "The new kanban status for the conversation. Available statuses: [KANBAN_STATUS_NAMES]"
|
|
6100
|
+
},
|
|
6101
|
+
"outcome": {
|
|
6102
|
+
"type": "string",
|
|
6103
|
+
"enum": "[KANBAN_OUTCOME_VALUES]",
|
|
6104
|
+
"description": "Required only when moving to the terminal (conversation-ending) status: the closing outcome. Available outcomes: [KANBAN_OUTCOME_NAMES]"
|
|
6105
|
+
},
|
|
6106
|
+
"scheduled_event_date": {
|
|
6107
|
+
"type": "string",
|
|
6108
|
+
"description": 'Scheduled event date in RFC3339 format with timezone (e.g., "2024-01-01T00:00:00-03:00")'
|
|
6109
|
+
},
|
|
6110
|
+
"event_description": {
|
|
6111
|
+
"type": "string",
|
|
6112
|
+
"description": "Description of the scheduled event"
|
|
6113
|
+
},
|
|
6114
|
+
"event_sid": {
|
|
6115
|
+
"type": "string",
|
|
6116
|
+
"description": "External event ID for integration purposes"
|
|
6117
|
+
}
|
|
6118
|
+
},
|
|
6119
|
+
"required": [
|
|
6120
|
+
"new_kanban_status"
|
|
6121
|
+
],
|
|
6122
|
+
"additionalProperties": false
|
|
6123
|
+
}
|
|
6124
|
+
},
|
|
6125
|
+
"tool_instructions": "Use to update the kanban status of a conversation to reflect its current stage in the workflow."
|
|
6126
|
+
},
|
|
6127
|
+
"schedule_followup": {
|
|
6128
|
+
"tool_config": {
|
|
6129
|
+
"name": "schedule_followup",
|
|
6130
|
+
"description": "Schedules a custom manual followup for the current conversation at an exact future time. The system automatically determines the receiver based on conversation status and hub AI mode.",
|
|
6131
|
+
"strict": true,
|
|
6132
|
+
"parameters": {
|
|
6133
|
+
"type": "object",
|
|
6134
|
+
"properties": {
|
|
6135
|
+
"scheduled_time": {
|
|
6136
|
+
"type": "string",
|
|
6137
|
+
"description": 'Exact time to execute the followup in ISO 8601 format with timezone (e.g., "2024-01-01T14:30:00-03:00"). Must be in the future.'
|
|
6138
|
+
},
|
|
6139
|
+
"message": {
|
|
6140
|
+
"type": "string",
|
|
6141
|
+
"description": 'The followup message to send to the customer. Can include AI instructions in brackets like: "Message text [AI Context: instructions for AI]"'
|
|
6142
|
+
}
|
|
6143
|
+
},
|
|
6144
|
+
"required": [
|
|
6145
|
+
"scheduled_time",
|
|
6146
|
+
"message"
|
|
6147
|
+
],
|
|
6148
|
+
"additionalProperties": false
|
|
6149
|
+
}
|
|
6150
|
+
},
|
|
6151
|
+
"tool_instructions": "Use to schedule a custom followup message at an exact future time. The caller is responsible for choosing appropriate timing (business hours, etc.). This is separate from automatic kanban-based followups."
|
|
6152
|
+
},
|
|
6153
|
+
"transfer_to_agent": {
|
|
6154
|
+
"tool_config": {
|
|
6155
|
+
"name": "transfer_to_agent",
|
|
6156
|
+
"description": "Hand off conversation to another AI agent",
|
|
6157
|
+
"strict": true,
|
|
6158
|
+
"parameters": {
|
|
6159
|
+
"type": "object",
|
|
6160
|
+
"properties": {
|
|
6161
|
+
"agent_name": {
|
|
6162
|
+
"type": "string",
|
|
6163
|
+
"description": "Name of the AI agent to transfer to"
|
|
6164
|
+
}
|
|
6165
|
+
},
|
|
6166
|
+
"required": [
|
|
6167
|
+
"agent_name"
|
|
6168
|
+
],
|
|
6169
|
+
"additionalProperties": false
|
|
6170
|
+
}
|
|
6171
|
+
},
|
|
6172
|
+
"tool_instructions": "Use when you need to hand the conversation to another agent on the same track \u2014 a specialist for a specific domain, or back to the entry pilot/copilot acting as a router for a request outside your domain."
|
|
6173
|
+
},
|
|
6174
|
+
"consult_agent": {
|
|
6175
|
+
"tool_config": {
|
|
6176
|
+
"name": "consult_agent",
|
|
6177
|
+
"description": "Consult an advisor agent for specialized knowledge without transferring the conversation",
|
|
6178
|
+
"strict": true,
|
|
6179
|
+
"parameters": {
|
|
6180
|
+
"type": "object",
|
|
6181
|
+
"properties": {
|
|
6182
|
+
"agent_name": {
|
|
6183
|
+
"type": "string",
|
|
6184
|
+
"description": "Name of the advisor agent to consult for advice"
|
|
6185
|
+
},
|
|
6186
|
+
"consult_question": {
|
|
6187
|
+
"type": "string",
|
|
6188
|
+
"description": "The specific question to ask the advisor agent"
|
|
6189
|
+
}
|
|
6190
|
+
},
|
|
6191
|
+
"required": [
|
|
6192
|
+
"agent_name",
|
|
6193
|
+
"consult_question"
|
|
6194
|
+
],
|
|
6195
|
+
"additionalProperties": false
|
|
6196
|
+
}
|
|
6197
|
+
},
|
|
6198
|
+
"tool_instructions": "Use when you need expert advice from an advisor agent but want to maintain conversation ownership. The consulted advisor will provide advice that you can use to help the user."
|
|
6199
|
+
},
|
|
6200
|
+
"read_file": {
|
|
6201
|
+
"tool_config": {
|
|
6202
|
+
"name": "read_file",
|
|
6203
|
+
"description": "Retrieve a file by path (preferred) or by ID. The file is injected into the conversation context for AI processing.",
|
|
6204
|
+
"strict": false,
|
|
6205
|
+
"parameters": {
|
|
6206
|
+
"type": "object",
|
|
6207
|
+
"properties": {
|
|
6208
|
+
"path": {
|
|
6209
|
+
"type": "string",
|
|
6210
|
+
"description": 'Path to the file. Knowledge and skill files live under "resources/", exactly as listed in your resource structure or in a file listing \u2014 e.g. "resources/product-docs/references/menu.md", where the segment after "resources/" names the resource. Files attached to this conversation live under "conversation/" and are announced in the transcript by that path \u2014 e.g. "conversation/report.pdf". A shorter form also works for those two and is matched across everything you can read, preferring an exact path over one that merely ends with what you wrote ("references/menu.md", or just "menu.md"); dropping a middle segment does not resolve, and a bare name carried by both a resource and this conversation is reported as ambiguous so you can retry with the full path. Files from an EARLIER conversation with the same user live under "conversations/<conversation_id>/" \u2014 e.g. "conversations/1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed/receipt.pdf", exactly as the transcript of that conversation announces them (get_conversation). That form takes no shortening: write the mount, the conversation id and the file name in full. Prefer this over file_id: paths are stable, while IDs are regenerated whenever a hub is published.'
|
|
6211
|
+
},
|
|
6212
|
+
"file_id": {
|
|
6213
|
+
"type": "string",
|
|
6214
|
+
"description": "The file ID to retrieve, from a conversation message or a file listing. Still supported, but prefer path for resource files."
|
|
6215
|
+
},
|
|
6216
|
+
"resource_id": {
|
|
6217
|
+
"type": "string",
|
|
6218
|
+
"description": "Optional. Restricts a path to one resource \u2014 use it when the same file name exists in more than one resource and the tool reports the reference as ambiguous. Must be a resource linked to this agent."
|
|
6219
|
+
}
|
|
6220
|
+
},
|
|
6221
|
+
"required": [],
|
|
6222
|
+
"additionalProperties": false
|
|
6223
|
+
}
|
|
6224
|
+
},
|
|
6225
|
+
"tool_instructions": "Use this tool to read a file for AI analysis. Provide either path (preferred \u2014 the exact paths appear in your resource structure and in list_files output) or file_id. The file will be injected into the conversation context."
|
|
6226
|
+
},
|
|
6227
|
+
"download_file": {
|
|
6228
|
+
"tool_config": {
|
|
6229
|
+
"name": "download_file",
|
|
6230
|
+
"description": "Mount a resource file into the code execution sandbox so you can edit it. Path is provider-specific: Anthropic mounts at /tmp/<filename>, OpenAI mounts at /mnt/data/<filename> \u2014 use the `sandbox_path` returned in the result. After mounting, use the provider's code-execution tool (Anthropic code_execution view/str_replace/create, or OpenAI code_interpreter Python) to read or modify the file. When finished, call upload_file to commit changes back to the resource library. Bytes never enter conversation context.",
|
|
6231
|
+
"strict": true,
|
|
6232
|
+
"parameters": {
|
|
6233
|
+
"type": "object",
|
|
6234
|
+
"properties": {
|
|
6235
|
+
"file_id": {
|
|
6236
|
+
"type": "string",
|
|
6237
|
+
"description": "The resource file_id to mount (from a file listing or read_file \u2014 a listing row carries file_id alongside its path). Must be a text file; binary files are rejected."
|
|
6238
|
+
}
|
|
6239
|
+
},
|
|
6240
|
+
"required": [
|
|
6241
|
+
"file_id"
|
|
6242
|
+
],
|
|
6243
|
+
"additionalProperties": false
|
|
6244
|
+
}
|
|
6245
|
+
},
|
|
6246
|
+
"tool_instructions": "Use to begin editing a resource file. Returns { sandbox_path, filename, sandbox_file_id }. After this, use your provider's code-execution tool to view and modify the file inside the sandbox, then call upload_file with the sandbox_file_id of the modified file to persist changes."
|
|
6247
|
+
},
|
|
6248
|
+
"upload_file": {
|
|
6249
|
+
"tool_config": {
|
|
6250
|
+
"name": "upload_file",
|
|
6251
|
+
"description": "Persist a sandbox file to the resource library. Two modes: (1) UPDATE \u2014 pass file_id of an existing resource file to overwrite it (after download_file + code-execution edits). (2) CREATE \u2014 pass resource_id + filename instead of file_id to add a new file to that resource (after creating the file in the sandbox with code-execution). Requires write_enabled on the agent_resource binding for the target resource. sandbox_file_id is always required.",
|
|
6252
|
+
"strict": false,
|
|
6253
|
+
"parameters": {
|
|
6254
|
+
"type": "object",
|
|
6255
|
+
"properties": {
|
|
6256
|
+
"file_id": {
|
|
6257
|
+
"type": "string",
|
|
6258
|
+
"description": "UPDATE mode only: the existing resource file_id to overwrite. Omit when creating a new file."
|
|
6259
|
+
},
|
|
6260
|
+
"resource_id": {
|
|
6261
|
+
"type": "string",
|
|
6262
|
+
"description": "CREATE mode only: the resource the new file belongs to. Required when file_id is omitted; ignored when file_id is provided."
|
|
6263
|
+
},
|
|
6264
|
+
"filename": {
|
|
6265
|
+
"type": "string",
|
|
6266
|
+
"description": "CREATE mode only: the filename for the new file (e.g. 'pricing_v2.md'). Required when file_id is omitted. MIME type is inferred from the extension; only text files are supported."
|
|
6267
|
+
},
|
|
6268
|
+
"folder_id": {
|
|
6269
|
+
"type": "string",
|
|
6270
|
+
"description": "CREATE mode only: optional folder to place the file in. Omit for resource root."
|
|
6271
|
+
},
|
|
6272
|
+
"sandbox_file_id": {
|
|
6273
|
+
"type": "string",
|
|
6274
|
+
"description": "The provider-specific file_id of the file inside the sandbox. Anthropic: take from bash_code_execution_tool_result content[].file_id. OpenAI: take from the container_file_citation annotations on code_interpreter_call output. Either one identifies the file as it currently exists in the sandbox."
|
|
6275
|
+
}
|
|
6276
|
+
},
|
|
6277
|
+
"required": [
|
|
6278
|
+
"sandbox_file_id"
|
|
6279
|
+
],
|
|
6280
|
+
"additionalProperties": false
|
|
6281
|
+
}
|
|
6282
|
+
},
|
|
6283
|
+
"tool_instructions": "Use to commit either an edit (file_id + sandbox_file_id) or a new file (resource_id + filename + sandbox_file_id). Returns { saved, file_id, file_hash, bytes } on success \u2014 the file_id you can reference later. Errors clearly when write access is denied or when neither identifier set is provided."
|
|
6284
|
+
},
|
|
6285
|
+
"send_files": {
|
|
6286
|
+
"tool_config": {
|
|
6287
|
+
"name": "send_files",
|
|
6288
|
+
"description": "Send files to the end user through their conversation channel (App, WhatsApp, email, etc.)",
|
|
6289
|
+
"strict": false,
|
|
6290
|
+
"parameters": {
|
|
6291
|
+
"type": "object",
|
|
6292
|
+
"properties": {
|
|
6293
|
+
"file_ids": {
|
|
6294
|
+
"type": "array",
|
|
6295
|
+
"items": {
|
|
6296
|
+
"type": "string"
|
|
6297
|
+
},
|
|
6298
|
+
"description": 'Files to send to the user, each named by path (preferred) or by ID. Paths are the addresses announced in the transcript and in your resource structure \u2014 "conversation/report.pdf" for a file attached to this conversation, "conversations/<conversation_id>/receipt.pdf" for one attached to an earlier conversation with the same user, "resources/product-docs/price-list.pdf" for a knowledge or skill file. IDs remain accepted, but they are regenerated whenever a hub is published, so a path is the stable address.'
|
|
6299
|
+
},
|
|
6300
|
+
"folder_ids": {
|
|
6301
|
+
"type": "array",
|
|
6302
|
+
"items": {
|
|
6303
|
+
"type": "string"
|
|
6304
|
+
},
|
|
6305
|
+
"description": "Array of resource folder IDs to send all files from. Alternative to file_ids."
|
|
6306
|
+
},
|
|
6307
|
+
"message_text": {
|
|
6308
|
+
"type": "string",
|
|
6309
|
+
"description": "Message text to accompany the files. For WhatsApp, this becomes the caption on the last file. For email, this becomes the email body."
|
|
6310
|
+
}
|
|
6311
|
+
},
|
|
6312
|
+
"required": [],
|
|
6313
|
+
"additionalProperties": false
|
|
6314
|
+
}
|
|
6315
|
+
},
|
|
6316
|
+
"tool_instructions": "Use this tool to send files to users. WhatsApp sends files individually with optional caption on last file. Email sends all files as attachments in a single email."
|
|
6317
|
+
},
|
|
6318
|
+
"list_files": {
|
|
6319
|
+
"tool_config": {
|
|
6320
|
+
"name": "list_files",
|
|
6321
|
+
"description": "Browse the files you can reach, by path. Call it with no path to see the mounts, then pass a mount or a folder path to list what is inside it. Every row carries the exact path read_file and send_files accept.",
|
|
6322
|
+
"strict": false,
|
|
6323
|
+
"parameters": {
|
|
6324
|
+
"type": "object",
|
|
6325
|
+
"properties": {
|
|
6326
|
+
"path": {
|
|
6327
|
+
"type": "string",
|
|
6328
|
+
"description": 'What to list. Omit it (or pass "") for the mounts you can browse \u2014 the available mounts are listed here at runtime. "conversation" lists the files attached to this conversation. "resources" lists every resource mount. "resources/<resource-slug>" lists the top level of a knowledge resource or skill, and "resources/<resource-slug>/<folder>/<subfolder>" lists that folder. Folder rows come back with their own path, so you drill down by passing back the path of the row you want.'
|
|
6329
|
+
},
|
|
6330
|
+
"query": {
|
|
6331
|
+
"type": "string",
|
|
6332
|
+
"description": "Search text. Matched against a file's title and its file name. Under a resource path this searches the WHOLE subtree below it, not just the level named, and every result is returned as a full path."
|
|
6333
|
+
},
|
|
6334
|
+
"tags": {
|
|
6335
|
+
"type": "array",
|
|
6336
|
+
"items": {
|
|
6337
|
+
"type": "string"
|
|
6338
|
+
},
|
|
6339
|
+
"description": "Return files carrying ANY of these tags. Applies to resource files only \u2014 conversation attachments carry no tags. Searches the whole subtree, like query."
|
|
6340
|
+
},
|
|
6341
|
+
"metadata_filter": {
|
|
6342
|
+
"type": "object",
|
|
6343
|
+
"description": 'Filter resource files by their metadata using MongoDB-style operators. Supported: $eq (equal), $ne (not equal), $gt/$gte/$lt/$lte (comparisons), $in/$nin (in/not in array), $contains (substring for text, membership for a list), $and/$or/$not (logical). Nested paths like "location.city" are supported, and a bare value means equality. Examples: {"status": "active"}, {"priority": {"$gte": 5}}, {"location.city": "Miami"}, {"$and": [{"status": "active"}, {"priority": {"$gt": 3}}]}, {"$not": {"status": "archived"}}. A comparison between different types simply does not match. Schema from resource.file_metadata_schema. Searches the whole subtree, like query.'
|
|
6344
|
+
},
|
|
6345
|
+
"limit": {
|
|
6346
|
+
"type": "integer",
|
|
6347
|
+
"description": "Maximum number of rows to return (default: 50, max: 100). The response reports the total the page was drawn from."
|
|
6348
|
+
},
|
|
6349
|
+
"offset": {
|
|
6350
|
+
"type": "integer",
|
|
6351
|
+
"description": "Number of rows to skip for pagination (default: 0)"
|
|
6352
|
+
}
|
|
6353
|
+
},
|
|
6354
|
+
"required": [],
|
|
6355
|
+
"additionalProperties": false
|
|
6356
|
+
}
|
|
6357
|
+
},
|
|
6358
|
+
"tool_instructions": 'Use to find out which files exist before reading one. Call it with no path first: that returns the mounts \u2014 "conversation" for what the user attached here, and one "resources/<slug>" per knowledge resource or skill linked to you. Then pass a mount or folder path back to list its contents. Every row carries a `path`; pass that path to read_file to open the file, or to send_files to deliver it. Pass query, tags or metadata_filter to search a whole resource at once instead of walking it folder by folder. Files from EARLIER conversations are not listed here \u2014 the transcript of each past conversation announces its own files by path (get_conversation).'
|
|
6359
|
+
},
|
|
6360
|
+
"list_resource_folders": {
|
|
6361
|
+
"tool_config": {
|
|
6362
|
+
"name": "list_resource_folders",
|
|
6363
|
+
"description": "(deprecated \u2014 use list_files) List all folders in resources that this agent has access to. Returns all folders with parent_folder_id for hierarchy reconstruction.",
|
|
6364
|
+
"strict": false,
|
|
6365
|
+
"parameters": {
|
|
6366
|
+
"type": "object",
|
|
6367
|
+
"properties": {
|
|
6368
|
+
"resource_id": {
|
|
6369
|
+
"type": "string",
|
|
6370
|
+
"description": "Resource ID to query folders from. Must be one of the knowledge resources linked to this agent (the available ids are listed here at runtime). Required for access control and performance."
|
|
6371
|
+
},
|
|
6372
|
+
"search_query": {
|
|
6373
|
+
"type": "string",
|
|
6374
|
+
"description": "Search folders by name"
|
|
6375
|
+
},
|
|
6376
|
+
"metadata_filter": {
|
|
6377
|
+
"type": "object",
|
|
6378
|
+
"description": 'Filter by metadata using MongoDB-style operators. Supported: $eq (equal), $ne (not equal), $gt/$gte/$lt/$lte (comparisons), $in/$nin (in/not in array), $contains (contains value), $and/$or/$not (logical). Supports nested paths like "location.city". Returns clear errors for type mismatches. Examples: {"status": "active"} for simple equality, {"priority": {"$gte": 5}} for comparison, {"location.city": "Miami"} for nested path, {"$and": [{"status": "active"}, {"priority": {"$gt": 3}}]} for complex logic, {"$not": {"status": "archived"}} for negation. Schema from resource.folder_metadata_schema.'
|
|
6379
|
+
}
|
|
6380
|
+
},
|
|
6381
|
+
"required": [
|
|
6382
|
+
"resource_id"
|
|
6383
|
+
],
|
|
6384
|
+
"additionalProperties": false
|
|
6385
|
+
}
|
|
6386
|
+
},
|
|
6387
|
+
"tool_instructions": "Deprecated: prefer list_files, which walks the same folders by path and needs no resource_id. Still works \u2014 lists all folders in a resource, filtered by search_query or metadata, returning folder info with parent_folder_id, file counts, and subfolder counts."
|
|
6388
|
+
},
|
|
6389
|
+
"list_resource_files": {
|
|
6390
|
+
"tool_config": {
|
|
6391
|
+
"name": "list_resource_files",
|
|
6392
|
+
"description": "(deprecated \u2014 use list_files) List files in resources that this agent has access to. Each file is returned with its path \u2014 the address read_file accepts \u2014 plus metadata.",
|
|
6393
|
+
"strict": false,
|
|
6394
|
+
"parameters": {
|
|
6395
|
+
"type": "object",
|
|
6396
|
+
"properties": {
|
|
6397
|
+
"resource_id": {
|
|
6398
|
+
"type": "string",
|
|
6399
|
+
"description": "Resource ID to query files from. Must be one of the knowledge resources linked to this agent (the available ids are listed here at runtime). Required for access control and performance."
|
|
6400
|
+
},
|
|
6401
|
+
"folder_id": {
|
|
6402
|
+
"type": "string",
|
|
6403
|
+
"description": "Filter by folder ID. Omit to return ALL files. Use 00000000-0000-0000-0000-000000000000 for root-level files only."
|
|
6404
|
+
},
|
|
6405
|
+
"search_query": {
|
|
6406
|
+
"type": "string",
|
|
6407
|
+
"description": "Search files by title or file name"
|
|
6408
|
+
},
|
|
6409
|
+
"tags": {
|
|
6410
|
+
"type": "array",
|
|
6411
|
+
"items": {
|
|
6412
|
+
"type": "string"
|
|
6413
|
+
},
|
|
6414
|
+
"description": "Filter by tags (matches files with any of the specified tags)"
|
|
6415
|
+
},
|
|
6416
|
+
"metadata_filter": {
|
|
6417
|
+
"type": "object",
|
|
6418
|
+
"description": 'Filter by metadata using MongoDB-style operators. Supported: $eq (equal), $ne (not equal), $gt/$gte/$lt/$lte (comparisons), $in/$nin (in/not in array), $contains (contains value), $and/$or/$not (logical). Supports nested paths like "location.city". Returns clear errors for type mismatches. Examples: {"status": "active"} for simple equality, {"priority": {"$gte": 5}} for comparison, {"location.city": "Miami"} for nested path, {"$and": [{"status": "active"}, {"priority": {"$gt": 3}}]} for complex logic, {"$not": {"status": "archived"}} for negation. Schema from resource.file_metadata_schema.'
|
|
6419
|
+
},
|
|
6420
|
+
"limit": {
|
|
6421
|
+
"type": "integer",
|
|
6422
|
+
"description": "Maximum number of files to return (default: 50, max: 100)"
|
|
6423
|
+
},
|
|
6424
|
+
"offset": {
|
|
6425
|
+
"type": "integer",
|
|
6426
|
+
"description": "Number of files to skip for pagination (default: 0)"
|
|
6427
|
+
}
|
|
6428
|
+
},
|
|
6429
|
+
"required": [
|
|
6430
|
+
"resource_id"
|
|
6431
|
+
],
|
|
6432
|
+
"additionalProperties": false
|
|
6433
|
+
}
|
|
6434
|
+
},
|
|
6435
|
+
"tool_instructions": "Deprecated: prefer list_files, which lists the same files by path, needs no resource_id, and also sees this conversation's attachments. Still works \u2014 each row carries a `path`; pass that path to read_file to retrieve the file's content for AI analysis. `file_id` is also returned and still accepted."
|
|
6436
|
+
},
|
|
6437
|
+
"get_tool_schema": {
|
|
6438
|
+
"tool_config": {
|
|
6439
|
+
"name": "get_tool_schema",
|
|
6440
|
+
"description": "MANDATORY FIRST STEP: Retrieves the complete parameter schema for any tool by name. You MUST call this before using ANY tool to get its exact required parameters. This ensures execute_tool will succeed.",
|
|
6441
|
+
"strict": true,
|
|
6442
|
+
"parameters": {
|
|
6443
|
+
"type": "object",
|
|
6444
|
+
"properties": {
|
|
6445
|
+
"tool_name": {
|
|
6446
|
+
"type": "string",
|
|
6447
|
+
"description": "The name of the tool to retrieve the schema for"
|
|
6448
|
+
}
|
|
6449
|
+
},
|
|
6450
|
+
"required": [
|
|
6451
|
+
"tool_name"
|
|
6452
|
+
],
|
|
6453
|
+
"additionalProperties": false
|
|
6454
|
+
}
|
|
6455
|
+
},
|
|
6456
|
+
"tool_instructions": "Mandatory first step before execute_tool. Returns `function_schema` for the target tool \u2014 pass `function_schema.parameters` (same shape, same keys) as the `parameters` envelope in your execute_tool call."
|
|
6457
|
+
},
|
|
6458
|
+
"execute_tool": {
|
|
6459
|
+
"tool_config": {
|
|
6460
|
+
"name": "execute_tool",
|
|
6461
|
+
"description": "Executes any tool by name. You MUST call get_tool_schema first for the target tool to learn its parameter shape, then pass that shape verbatim under `parameters`.",
|
|
6462
|
+
"strict": false,
|
|
6463
|
+
"parameters": {
|
|
6464
|
+
"type": "object",
|
|
6465
|
+
"required": [
|
|
6466
|
+
"tool_name",
|
|
6467
|
+
"parameters"
|
|
6468
|
+
],
|
|
6469
|
+
"properties": {
|
|
6470
|
+
"tool_name": {
|
|
6471
|
+
"type": "string",
|
|
6472
|
+
"description": "The name of the tool to execute."
|
|
6473
|
+
},
|
|
6474
|
+
"parameters": {
|
|
6475
|
+
"type": "object",
|
|
6476
|
+
"description": "The arguments object for the target tool. Must match `function_schema.parameters` returned by get_tool_schema \u2014 same keys, same shape, same required fields. Inner contents are validated by the target tool, not by execute_tool."
|
|
6477
|
+
}
|
|
6478
|
+
},
|
|
6479
|
+
"additionalProperties": false
|
|
6480
|
+
}
|
|
6481
|
+
},
|
|
6482
|
+
"tool_instructions": "MANDATORY WORKFLOW: 1) Call get_tool_schema(tool_name) to receive the target's `function_schema`. 2) Build a `parameters` object that matches `function_schema.parameters` \u2014 same property keys, same types, all required fields. 3) Call execute_tool({ tool_name, parameters }). The `parameters` envelope here is identical in shape to `function_schema.parameters`."
|
|
6483
|
+
},
|
|
6484
|
+
"expand_summary": {
|
|
6485
|
+
"tool_config": {
|
|
6486
|
+
"name": "expand_summary",
|
|
6487
|
+
"description": "Retrieve the original messages of a section in the conversation summary. The summary block at the top of the conversation lists sections with stable `id`s \u2014 pass one to get the verbatim messages it covers.",
|
|
6488
|
+
"strict": true,
|
|
6489
|
+
"parameters": {
|
|
6490
|
+
"type": "object",
|
|
6491
|
+
"properties": {
|
|
6492
|
+
"section_id": {
|
|
6493
|
+
"type": "string",
|
|
6494
|
+
"description": "The `id` of the section from the <conversation_summary> block at the top of the conversation."
|
|
6495
|
+
}
|
|
6496
|
+
},
|
|
6497
|
+
"required": [
|
|
6498
|
+
"section_id"
|
|
6499
|
+
],
|
|
6500
|
+
"additionalProperties": false
|
|
6501
|
+
}
|
|
6502
|
+
},
|
|
6503
|
+
"tool_instructions": "Use when a summary section is too compressed for the question at hand \u2014 e.g. you need the user's exact wording, the precise text of a previous decision, or a tool result that the summary only references. If you pass an unknown `section_id`, the response will include `available_section_ids` so you can retry with a valid one."
|
|
6504
|
+
},
|
|
6505
|
+
"read_skill": {
|
|
6506
|
+
"tool_config": {
|
|
6507
|
+
"name": "read_skill",
|
|
6508
|
+
"description": "Read a skill's SKILL.md content. Pass a skill_id from the skills linked to this agent (available ids are listed in the skill_id parameter).",
|
|
6509
|
+
"strict": true,
|
|
6510
|
+
"parameters": {
|
|
6511
|
+
"type": "object",
|
|
6512
|
+
"properties": {
|
|
6513
|
+
"skill_id": {
|
|
6514
|
+
"type": "string",
|
|
6515
|
+
"description": "The skill's resource_id. Must be one of the skills linked to this agent (the available ids are listed here at runtime)."
|
|
6516
|
+
}
|
|
6517
|
+
},
|
|
6518
|
+
"required": [
|
|
6519
|
+
"skill_id"
|
|
6520
|
+
],
|
|
6521
|
+
"additionalProperties": false
|
|
6522
|
+
}
|
|
6523
|
+
},
|
|
6524
|
+
"tool_instructions": "Use this tool to read a skill's instructions. Returns the full SKILL.md content as a string. Use read_skill_file to access other files referenced in the skill."
|
|
6525
|
+
},
|
|
6526
|
+
"read_skill_file": {
|
|
6527
|
+
"tool_config": {
|
|
6528
|
+
"name": "read_skill_file",
|
|
6529
|
+
"description": "Read a file from a skill by relative path. No need to call read_skill first if you already know the file path.",
|
|
6530
|
+
"strict": true,
|
|
6531
|
+
"parameters": {
|
|
6532
|
+
"type": "object",
|
|
6533
|
+
"properties": {
|
|
6534
|
+
"skill_id": {
|
|
6535
|
+
"type": "string",
|
|
6536
|
+
"description": "The skill's resource_id. Must be one of the skills linked to this agent (the available ids are listed here at runtime)."
|
|
6537
|
+
},
|
|
6538
|
+
"file_path": {
|
|
6539
|
+
"type": "string",
|
|
6540
|
+
"description": 'Relative path from skill root (e.g., "references/menu.md")'
|
|
6541
|
+
}
|
|
6542
|
+
},
|
|
6543
|
+
"required": [
|
|
6544
|
+
"skill_id",
|
|
6545
|
+
"file_path"
|
|
6546
|
+
],
|
|
6547
|
+
"additionalProperties": false
|
|
6548
|
+
}
|
|
6549
|
+
},
|
|
6550
|
+
"tool_instructions": 'Use this tool to read files referenced in SKILL.md. Provide the relative path as shown in the skill content (e.g., "references/menu.md"). Returns content for text files or signed URL for binary files.'
|
|
6551
|
+
},
|
|
6552
|
+
"update_state": {
|
|
6553
|
+
"tool_config": {
|
|
6554
|
+
"name": "update_state",
|
|
6555
|
+
"description": "Updates a configured state by merging updates with its current value. Scope (conversation vs user) is inferred from the state's definition.",
|
|
6556
|
+
"strict": false,
|
|
6557
|
+
"parameters": {
|
|
6558
|
+
"type": "object",
|
|
6559
|
+
"properties": {
|
|
6560
|
+
"state_slug": {
|
|
6561
|
+
"type": "string",
|
|
6562
|
+
"description": "Stable slug of the state to update. Pass the slug (the left half), not the display name. Available states (slug + display name): [STATE_SLUG_VALUES]"
|
|
6563
|
+
},
|
|
6564
|
+
"updates": {
|
|
6565
|
+
"type": "object",
|
|
6566
|
+
"description": "Object with key-value pairs to merge into the current state"
|
|
6567
|
+
}
|
|
6568
|
+
},
|
|
6569
|
+
"required": [
|
|
6570
|
+
"state_slug",
|
|
6571
|
+
"updates"
|
|
6572
|
+
],
|
|
6573
|
+
"additionalProperties": false
|
|
6574
|
+
}
|
|
6575
|
+
},
|
|
6576
|
+
"tool_instructions": "Use to track and update contextual information during conversations. Examples: updating cart items, recording form answers, saving user preferences. The updates are merged with existing state."
|
|
6577
|
+
},
|
|
6578
|
+
"get_state": {
|
|
6579
|
+
"tool_config": {
|
|
6580
|
+
"name": "get_state",
|
|
6581
|
+
"description": "Retrieves the current value of a configured state. Scope is inferred from the state's definition.",
|
|
6582
|
+
"strict": false,
|
|
6583
|
+
"parameters": {
|
|
6584
|
+
"type": "object",
|
|
6585
|
+
"properties": {
|
|
6586
|
+
"state_slug": {
|
|
6587
|
+
"type": "string",
|
|
6588
|
+
"description": "Stable slug of the state to retrieve. Pass the slug (the left half), not the display name. Available states (slug + display name): [STATE_SLUG_VALUES]"
|
|
6589
|
+
}
|
|
6590
|
+
},
|
|
6591
|
+
"required": [
|
|
6592
|
+
"state_slug"
|
|
6593
|
+
],
|
|
6594
|
+
"additionalProperties": false
|
|
6595
|
+
}
|
|
6596
|
+
},
|
|
6597
|
+
"tool_instructions": "Use to retrieve the current state value. This is useful when you need to check the current state before making decisions or when the state is not already available in the prompt context."
|
|
6598
|
+
},
|
|
6599
|
+
"reset_state": {
|
|
6600
|
+
"tool_config": {
|
|
6601
|
+
"name": "reset_state",
|
|
6602
|
+
"description": "Resets a configured state to its initial value as defined in the state schema. Scope is inferred from the state's definition.",
|
|
6603
|
+
"strict": false,
|
|
6604
|
+
"parameters": {
|
|
6605
|
+
"type": "object",
|
|
6606
|
+
"properties": {
|
|
6607
|
+
"state_slug": {
|
|
6608
|
+
"type": "string",
|
|
6609
|
+
"description": "Stable slug of the state to reset. Pass the slug (the left half), not the display name. Available states (slug + display name): [STATE_SLUG_VALUES]"
|
|
6610
|
+
}
|
|
6611
|
+
},
|
|
6612
|
+
"required": [
|
|
6613
|
+
"state_slug"
|
|
6614
|
+
],
|
|
6615
|
+
"additionalProperties": false
|
|
6616
|
+
}
|
|
6617
|
+
},
|
|
6618
|
+
"tool_instructions": "Use to reset state to its default initial value. This is useful when you need to clear accumulated state and start fresh, such as clearing a shopping cart or resetting form progress."
|
|
6619
|
+
},
|
|
6620
|
+
"get_conversations_summary": {
|
|
6621
|
+
"tool_config": {
|
|
6622
|
+
"name": "get_conversations_summary",
|
|
6623
|
+
"description": "Retrieves a timeline of past conversations with the current user, showing summaries and conversation IDs.",
|
|
6624
|
+
"strict": false,
|
|
6625
|
+
"parameters": {
|
|
6626
|
+
"type": "object",
|
|
6627
|
+
"properties": {
|
|
6628
|
+
"max_conversations": {
|
|
6629
|
+
"type": "integer",
|
|
6630
|
+
"description": "Maximum number of past conversations to return (default: 10)"
|
|
6631
|
+
},
|
|
6632
|
+
"max_characters": {
|
|
6633
|
+
"type": "integer",
|
|
6634
|
+
"description": "Maximum characters in the output (default: 20000, max: 40000). Truncates oldest entries first."
|
|
6635
|
+
}
|
|
6636
|
+
},
|
|
6637
|
+
"required": [],
|
|
6638
|
+
"additionalProperties": false
|
|
6639
|
+
}
|
|
6640
|
+
},
|
|
6641
|
+
"tool_instructions": "Use this tool at the start of a conversation to retrieve the history of past conversations with this user. Returns summaries with conversation IDs that can be used with get_conversation for full transcripts."
|
|
6642
|
+
},
|
|
6643
|
+
"get_conversation": {
|
|
6644
|
+
"tool_config": {
|
|
6645
|
+
"name": "get_conversation",
|
|
6646
|
+
"description": "Retrieves the full transcript of a specific past conversation, plus the IDs of the conversations closed immediately before and after it. Use get_conversations_summary first to find conversation IDs.",
|
|
6647
|
+
"strict": false,
|
|
6648
|
+
"parameters": {
|
|
6649
|
+
"type": "object",
|
|
6650
|
+
"properties": {
|
|
6651
|
+
"conversation_id": {
|
|
6652
|
+
"type": "string",
|
|
6653
|
+
"description": "The ID of the conversation to retrieve (from get_conversations_summary results)"
|
|
6654
|
+
},
|
|
6655
|
+
"max_characters": {
|
|
6656
|
+
"type": "integer",
|
|
6657
|
+
"description": "Maximum characters in the output (default: 30000, max: 60000). Truncates oldest messages first."
|
|
6658
|
+
}
|
|
6659
|
+
},
|
|
6660
|
+
"required": [
|
|
6661
|
+
"conversation_id"
|
|
6662
|
+
],
|
|
6663
|
+
"additionalProperties": false
|
|
6664
|
+
}
|
|
6665
|
+
},
|
|
6666
|
+
"tool_instructions": "Use this tool to read the full transcript of a specific past conversation. First use get_conversations_summary to find conversation IDs, then use this tool to drill into the details. The response may include previous_conversation_id and next_conversation_id \u2014 the conversations closed nearest in time either side of this one, which you can pass straight back to this tool to keep moving through the user's history. They are neighbours by closing time, not a fixed chain, and either may be absent."
|
|
6667
|
+
},
|
|
6668
|
+
// ---------------------------------------------------------------------------
|
|
6669
|
+
// Tools added to the TS catalog after the Supabase migration — schemas
|
|
6670
|
+
// reconstructed from the handler signatures in
|
|
6671
|
+
// apps/backend/src/tools/native/wayai/*.ts.
|
|
6672
|
+
// ---------------------------------------------------------------------------
|
|
6673
|
+
"set_state_path": {
|
|
6674
|
+
"tool_config": {
|
|
6675
|
+
"name": "set_state_path",
|
|
6676
|
+
"description": "Set a specific path within a state object (dot/array path) without overwriting the rest of the state. Scope is inferred from the state's definition.",
|
|
6677
|
+
// strict:false matches the other state ops so legacy composed-tool YAML
|
|
6678
|
+
// mapping `state_scope` (now ignored at runtime) doesn't trip OpenAI
|
|
6679
|
+
// strict-mode validators on in-flight calls.
|
|
6680
|
+
"strict": false,
|
|
6681
|
+
"parameters": {
|
|
6682
|
+
"type": "object",
|
|
6683
|
+
"properties": {
|
|
6684
|
+
"state_slug": {
|
|
6685
|
+
"type": "string",
|
|
6686
|
+
"description": "Stable slug of the state variable to update. Pass the slug (the left half), not the display name. Available states (slug + display name): [STATE_SLUG_VALUES]"
|
|
6687
|
+
},
|
|
6688
|
+
"path": {
|
|
6689
|
+
"type": "array",
|
|
6690
|
+
"items": { "type": "string" },
|
|
6691
|
+
"description": "Path within the state object, as an ordered list of keys."
|
|
6692
|
+
},
|
|
6693
|
+
"value": {
|
|
6694
|
+
"description": "The value to write at the given path. Any JSON value is allowed."
|
|
6695
|
+
}
|
|
6696
|
+
},
|
|
6697
|
+
"required": ["state_slug", "path", "value"],
|
|
6698
|
+
"additionalProperties": false
|
|
6699
|
+
}
|
|
6700
|
+
},
|
|
6701
|
+
"tool_instructions": "Use this tool when you need to update a single field inside a structured state object without replacing the entire state. Provide the full path from the root of the state object."
|
|
6702
|
+
},
|
|
6703
|
+
// NEVER OFFERED TO A MODEL, unlike every other entry in this file — and it is
|
|
6704
|
+
// `model_callable: false` on the catalog entry that delivers that, NOT the role
|
|
6705
|
+
// restriction beside it. An earlier version of this comment credited
|
|
6706
|
+
// `assignable_roles: ['monitor']`, which was wrong: a monitor runs a DISPATCHING
|
|
6707
|
+
// turn on `idle` (only the synchronous side-call sets `omit_tools`), and
|
|
6708
|
+
// `PATCH /api/setup/agents/:id` can re-role an agent that keeps the rows it
|
|
6709
|
+
// holds — so the role gate left the tool offerable on two paths.
|
|
6710
|
+
//
|
|
6711
|
+
// The schema exists because the catalog requires one per tool (the parity check
|
|
6712
|
+
// at the bottom of `native-tools.ts`) and because it is the one place the two
|
|
6713
|
+
// arguments are described for whoever writes the rule.
|
|
6714
|
+
//
|
|
6715
|
+
// `tool_instructions: null` FOLLOWS FROM THAT: instructions are injected into an
|
|
6716
|
+
// agent's system message when the tool is attached, and this tool is attached to
|
|
6717
|
+
// an agent whose model is never told it exists.
|
|
6718
|
+
// NEVER OFFERED TO A MODEL, like `insert_note` below and for the same reason:
|
|
6719
|
+
// `model_callable: false` on the catalog entry. A monitor's RULE selects it and
|
|
6720
|
+
// the monitor runtime carries it out — it never reaches `handleTool`, because
|
|
6721
|
+
// running a callee means re-entering the side-call with the caller's cascade
|
|
6722
|
+
// state, which no `ToolContext` carries.
|
|
6723
|
+
"run_monitor": {
|
|
6724
|
+
"tool_config": {
|
|
6725
|
+
"name": "run_monitor",
|
|
6726
|
+
"description": "Run another monitor on this hub. The named monitor judges the same conversation and acts on its own rules; nothing it finds is returned here.",
|
|
6727
|
+
"strict": false,
|
|
6728
|
+
"parameters": {
|
|
6729
|
+
"type": "object",
|
|
6730
|
+
"properties": {
|
|
6731
|
+
"monitor_name": {
|
|
6732
|
+
"type": "string",
|
|
6733
|
+
"description": "The name of the monitor to run. It must be a monitor on this hub whose trigger is manual."
|
|
6734
|
+
}
|
|
6735
|
+
},
|
|
6736
|
+
"required": ["monitor_name"],
|
|
6737
|
+
"additionalProperties": false
|
|
6738
|
+
}
|
|
6739
|
+
},
|
|
6740
|
+
"tool_instructions": null
|
|
6741
|
+
},
|
|
6742
|
+
"insert_note": {
|
|
6743
|
+
"tool_config": {
|
|
6744
|
+
"name": "insert_note",
|
|
6745
|
+
"description": "Insert an admin-authored note into the answering agent's context for this turn only. The note is written by the administrator, not by a model; the monitor's variables are substituted into it.",
|
|
6746
|
+
"strict": false,
|
|
6747
|
+
"parameters": {
|
|
6748
|
+
"type": "object",
|
|
6749
|
+
"properties": {
|
|
6750
|
+
"template": {
|
|
6751
|
+
"type": "string",
|
|
6752
|
+
"description": "The note text. Write {{variable_name}} to substitute one of this monitor's own variables. Unresolved names render as nothing and are recorded on the audit row."
|
|
6753
|
+
},
|
|
6754
|
+
"keep_in_history": {
|
|
6755
|
+
"type": "boolean",
|
|
6756
|
+
"description": "Default false: the note briefs this turn only and is never stored. Set true to also record it as an internal message the support team can see and the customer never receives."
|
|
6757
|
+
}
|
|
6758
|
+
},
|
|
6759
|
+
"required": ["template"],
|
|
6760
|
+
"additionalProperties": false
|
|
6761
|
+
}
|
|
6762
|
+
},
|
|
6763
|
+
"tool_instructions": null
|
|
6764
|
+
}
|
|
6765
|
+
};
|
|
6766
|
+
WAYAI_CONNECTOR = "b17d9f3a-4e1b-46c9-b648-a2f0c3611aa4";
|
|
6767
|
+
BASE_NATIVE_TOOLS = [
|
|
6768
|
+
// --- Wayai core tools ---
|
|
6769
|
+
{ tool_native_id: "nt-001", tool_name: "transfer_to_agent", tool_display_name: "Transfer to Agent", tool_description: "Transfer the conversation to another AI agent", connector_id: WAYAI_CONNECTOR, operation: "transfer_to_agent", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null },
|
|
6770
|
+
{ tool_native_id: "nt-002", tool_name: "transfer_to_team", tool_display_name: "Transfer to Team", tool_description: "Escalate conversation to a human support team", connector_id: WAYAI_CONNECTOR, operation: "transfer_to_team", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null },
|
|
6771
|
+
{ tool_native_id: "nt-003", tool_name: "close_conversation", tool_display_name: "Close Conversation", tool_description: "Close and end the current conversation", connector_id: WAYAI_CONNECTOR, operation: "close_conversation", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6772
|
+
{ tool_native_id: "nt-004", tool_name: "update_kanban_status", tool_display_name: "Update Kanban Status", tool_description: "Update the kanban status of the conversation", connector_id: WAYAI_CONNECTOR, operation: "update_kanban_status", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6773
|
+
{ tool_native_id: "nt-005", tool_name: "schedule_followup", tool_display_name: "Schedule Follow-up", tool_description: "Schedule a follow-up message for the conversation", connector_id: WAYAI_CONNECTOR, operation: "schedule_followup", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: true, execution_config: null },
|
|
6774
|
+
{ tool_native_id: "nt-006", tool_name: "send_files", tool_display_name: "Send Files", tool_description: "Send files to the user", connector_id: WAYAI_CONNECTOR, operation: "send_files", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6775
|
+
{ tool_native_id: "nt-007", tool_name: "update_state", tool_display_name: "Update State", tool_description: "Update conversation or user state variables", connector_id: WAYAI_CONNECTOR, operation: "update_state", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6776
|
+
{ tool_native_id: "nt-008", tool_name: "get_state", tool_display_name: "Get State", tool_description: "Retrieve conversation or user state values", connector_id: WAYAI_CONNECTOR, operation: "get_state", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6777
|
+
{ tool_native_id: "nt-009", tool_name: "reset_state", tool_display_name: "Reset State", tool_description: "Reset conversation or user state to initial values", connector_id: WAYAI_CONNECTOR, operation: "reset_state", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6778
|
+
{ tool_native_id: "nt-010", tool_name: "set_state_path", tool_display_name: "Set State Path", tool_description: "Set a specific path within state object", connector_id: WAYAI_CONNECTOR, operation: "set_state_path", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6779
|
+
{ tool_native_id: "nt-011", tool_name: "consult_agent", tool_display_name: "Consult Agent", tool_description: "Consult an advisor agent for advice without transferring", connector_id: WAYAI_CONNECTOR, operation: "consult_agent", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6780
|
+
{ tool_native_id: "nt-013", tool_name: "read_skill", tool_display_name: "Read Skill", tool_description: "Read the full specification of a skill", connector_id: WAYAI_CONNECTOR, operation: "read_skill", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6781
|
+
{ tool_native_id: "nt-014", tool_name: "read_skill_file", tool_display_name: "Read Skill File", tool_description: "Read a specific file within a skill", connector_id: WAYAI_CONNECTOR, operation: "read_skill_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6782
|
+
{ tool_native_id: "nt-015", tool_name: "read_file", tool_display_name: "Read File", tool_description: "Read the contents of a resource file", connector_id: WAYAI_CONNECTOR, operation: "read_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6783
|
+
// Superseded by `list_files` (nt-027), which browses the same resource files
|
|
6784
|
+
// by PATH plus this conversation's attachments.
|
|
6785
|
+
//
|
|
6786
|
+
// `ui_assignable: false` — DEPRECATED, not withdrawn. Hiding the Add grid entry
|
|
6787
|
+
// stops a NEW agent from being wired to a tool that addresses files by an id a
|
|
6788
|
+
// publish re-mints and that cannot see a conversation attachment at all (the id
|
|
6789
|
+
// itself is discoverable — `RESOURCE_TOOL_INJECTIONS` still writes the linked
|
|
6790
|
+
// ids into their `resource_id` description every turn), while every hub that
|
|
6791
|
+
// already assigns one keeps
|
|
6792
|
+
// working: the handler still dispatches, CI name resolution still resolves the
|
|
6793
|
+
// name, and `wayai pull` / `push` still round-trips the YAML. There is no
|
|
6794
|
+
// auto-provisioning anywhere in the platform, so an existing agent is never
|
|
6795
|
+
// migrated for free — an author swaps the tool deliberately.
|
|
6796
|
+
{ tool_native_id: "nt-016", tool_name: "list_resource_files", tool_display_name: "List Resource Files", tool_description: "(deprecated \u2014 use list_files) List files in a resource folder", connector_id: WAYAI_CONNECTOR, operation: "list_resource_files", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, ui_assignable: false },
|
|
6797
|
+
{ tool_native_id: "nt-017", tool_name: "list_resource_folders", tool_display_name: "List Resource Folders", tool_description: "(deprecated \u2014 use list_files) List all resource folders", connector_id: WAYAI_CONNECTOR, operation: "list_resource_folders", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, ui_assignable: false },
|
|
6798
|
+
{ tool_native_id: "nt-018", tool_name: "get_conversations_summary", tool_display_name: "Get Conversations Summary", tool_description: "Get a summary of recent conversations", connector_id: WAYAI_CONNECTOR, operation: "get_conversations_summary", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6799
|
+
{ tool_native_id: "nt-019", tool_name: "get_conversation", tool_display_name: "Get Conversation", tool_description: "Retrieve full conversation history", connector_id: WAYAI_CONNECTOR, operation: "get_conversation", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6800
|
+
{ tool_native_id: "nt-020", tool_name: "get_tool_schema", tool_display_name: "Get Tool Schema", tool_description: "Retrieve the JSON schema for a tool", connector_id: WAYAI_CONNECTOR, operation: "get_tool_schema", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6801
|
+
{ tool_native_id: "nt-021", tool_name: "execute_tool", tool_display_name: "Execute Tool", tool_description: "Execute any available tool by name", connector_id: WAYAI_CONNECTOR, operation: "execute_tool", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6802
|
+
{ tool_native_id: "nt-022", tool_name: "expand_summary", tool_display_name: "Expand Summary", tool_description: "Retrieve the original messages of a section in the conversation summary", connector_id: WAYAI_CONNECTOR, operation: "expand_summary", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6803
|
+
{ tool_native_id: "nt-023", tool_name: "download_file", tool_display_name: "Download File for Edit", tool_description: "Mount a resource file into the code execution sandbox for editing", connector_id: WAYAI_CONNECTOR, operation: "download_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6804
|
+
{ tool_native_id: "nt-024", tool_name: "upload_file", tool_display_name: "Upload Edited File", tool_description: "Persist a sandbox-edited file back to the resource library", connector_id: WAYAI_CONNECTOR, operation: "upload_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6805
|
+
// Hub-as-agent delegation (consultant-agents H1.5). UN-GATED in PR 7 (H1.5b): the
|
|
6806
|
+
// spawn + cross-DO completion callback shipped, so the tool is live across the
|
|
6807
|
+
// catalog listing, CI push, the config snapshot, and the handler. (PR 6 shipped it
|
|
6808
|
+
// `assignable: false` so no visible-but-inert tool could reach production between
|
|
6809
|
+
// the two merges.)
|
|
6810
|
+
//
|
|
6811
|
+
// `ui_assignable: false` — CONFIG-AS-CODE ONLY for v1. Attaching this tool requires
|
|
6812
|
+
// two admin decisions the Add dialog cannot yet collect: the target hub and the
|
|
6813
|
+
// `context_boundary` (a data-sensitivity choice). Without a `hub` branch in the
|
|
6814
|
+
// delegation dialog, clicking Add would submit no delegation params and the write
|
|
6815
|
+
// path would reject it — a live button that only ever errors. Assign it via
|
|
6816
|
+
// `wayai push` until the picker + boundary control ship.
|
|
6817
|
+
{ tool_native_id: "nt-025", tool_name: "delegate_to_hub", tool_display_name: "Delegate to Hub", tool_description: "Delegate a request to another hub as a task, and receive the result asynchronously", connector_id: WAYAI_CONNECTOR, operation: "delegate_to_hub", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, ui_assignable: false },
|
|
6818
|
+
// Agent-initiated consults (consultant-agents H1.7b). A delegation tool like the
|
|
6819
|
+
// three above: the TARGET is admin configuration (`delegated_agent_id` for a
|
|
6820
|
+
// same-hub consultant, `delegated_hub_id` for a partner hub) and the model supplies
|
|
6821
|
+
// only the question — so scoping "which consultants may this agent reach" reuses
|
|
6822
|
+
// the existing assignment model with no new config surface.
|
|
6823
|
+
//
|
|
6824
|
+
// `ui_assignable: false` — CONFIG-AS-CODE ONLY for v1, same reasoning as
|
|
6825
|
+
// `delegate_to_hub`: attaching it requires a target the Add dialog cannot yet
|
|
6826
|
+
// collect (and, for a consultant target, the `allow_consultant_chain` opt-in). A
|
|
6827
|
+
// live button that only ever errors is worse than no button. Assign via `wayai push`
|
|
6828
|
+
// until the picker ships.
|
|
6829
|
+
{ tool_native_id: "nt-026", tool_name: "start_consult_thread", tool_display_name: "Start Consult Thread", tool_description: "Ask a configured consultant (or partner hub) a question in a visible consult thread", connector_id: WAYAI_CONNECTOR, operation: "start_consult_thread", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, ui_assignable: false },
|
|
6830
|
+
// One drill-down listing for every file namespace, replacing `list_resource_files`
|
|
6831
|
+
// (nt-016) and `list_resource_folders` (nt-017). Fully visible: it needs no
|
|
6832
|
+
// configuration the Add dialog cannot collect — the mounts an agent may browse
|
|
6833
|
+
// come from its existing resource links and its own conversation, and the only
|
|
6834
|
+
// model-supplied input is a path.
|
|
6835
|
+
{ tool_native_id: "nt-027", tool_name: "list_files", tool_display_name: "List Files", tool_description: "Browse the files this agent can reach, by path", connector_id: WAYAI_CONNECTOR, operation: "list_files", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
6836
|
+
// TWO gates, and BOTH are load-bearing — the first shipped alone and was not
|
|
6837
|
+
// enough. `assignable_roles: ['monitor']` says only a monitor may HOLD it,
|
|
6838
|
+
// because the tool has no meaning off a monitor: a rule SELECTS it and the note
|
|
6839
|
+
// is injected into the ANSWERING agent's prompt for that one turn.
|
|
6840
|
+
// `model_callable: false` says no model is ever TOLD it exists — which the role
|
|
6841
|
+
// restriction does NOT imply, because an `idle` monitor runs a dispatching turn
|
|
6842
|
+
// and a re-roled agent keeps the tools it holds. Offered and called, it reaches
|
|
6843
|
+
// the native dispatcher's `default:` branch: a Sentry event and a provider
|
|
6844
|
+
// re-call. See `NativeTool.model_callable`.
|
|
6845
|
+
{ tool_native_id: "nt-028", tool_name: "insert_note", tool_display_name: "Insert Note", tool_description: "Brief the answering agent with an admin-authored note before it replies", connector_id: WAYAI_CONNECTOR, operation: "insert_note", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, assignable_roles: ["monitor"], model_callable: false },
|
|
6846
|
+
// TWO gates, same pair and same reasons as `insert_note` above — this is the
|
|
6847
|
+
// second tool to need both, which is why they are catalog fields rather than a
|
|
6848
|
+
// check at one site. `assignable_roles: ['monitor']`: only a monitor may hold it,
|
|
6849
|
+
// because only a monitor's RULE can select it. `model_callable: false`: no model
|
|
6850
|
+
// is ever told it exists, which the role restriction does NOT imply — an `idle`
|
|
6851
|
+
// monitor runs a dispatching turn, and a re-roled agent keeps the rows it holds.
|
|
6852
|
+
//
|
|
6853
|
+
// The CALLEE is named, not identified by id (owner decision 9): a hub-relative
|
|
6854
|
+
// name survives every copy path untouched, where a per-hub UUID in a JSON column
|
|
6855
|
+
// would need remapping on both branching mechanisms and normalizing on both CI
|
|
6856
|
+
// directions. `action.tool_name`, one key away in the same object, is the
|
|
6857
|
+
// precedent.
|
|
6858
|
+
{ tool_native_id: "nt-029", tool_name: "run_monitor", tool_display_name: "Run Monitor", tool_description: "Run another monitor on this hub and let it act on its own rules", connector_id: WAYAI_CONNECTOR, operation: "run_monitor", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, assignable_roles: ["monitor"], model_callable: false }
|
|
6859
|
+
];
|
|
6860
|
+
NATIVE_TOOLS = BASE_NATIVE_TOOLS.map((base) => {
|
|
6861
|
+
const schema = NATIVE_TOOL_SCHEMAS[base.tool_name];
|
|
6862
|
+
if (!schema) {
|
|
6863
|
+
throw new Error(
|
|
6864
|
+
`Native tool "${base.tool_name}" (${base.tool_native_id}) is missing an entry in NATIVE_TOOL_SCHEMAS. Add it to workers/shared/src/catalog/native-tool-schemas.ts.`
|
|
6865
|
+
);
|
|
6866
|
+
}
|
|
6867
|
+
return {
|
|
6868
|
+
...base,
|
|
6869
|
+
tool_config: schema.tool_config,
|
|
6870
|
+
tool_instructions: schema.tool_instructions
|
|
6871
|
+
};
|
|
6872
|
+
});
|
|
6873
|
+
NATIVE_TOOL_NAMES = new Set(NATIVE_TOOLS.map((t) => t.tool_name));
|
|
5549
6874
|
previousConversationsCountField = external_exports.number().int().min(0).max(PREVIOUS_CONVERSATIONS_MAX).nullable().optional();
|
|
5550
6875
|
summarizationThresholdField = external_exports.number().int().min(SUMMARIZATION_THRESHOLD_MIN).max(SUMMARIZATION_THRESHOLD_MAX).nullable().optional();
|
|
6876
|
+
flagConditionSchema = external_exports.object({
|
|
6877
|
+
variable: external_exports.string(),
|
|
6878
|
+
operator: external_exports.enum(FLAG_CONDITION_OPERATORS),
|
|
6879
|
+
// `boolean` is admitted for parity with the CI write path, whose refine gates the
|
|
6880
|
+
// operator alone, so `value: false` on a boolean evaluation variable is storable
|
|
6881
|
+
// config today and the evaluator honours it through `String()`. Narrowing here would
|
|
6882
|
+
// reject on PATCH exactly what `wayai push` persists, so any REST caller that reads
|
|
6883
|
+
// an agent and writes it back — the typed clients, the CLI's `ApiClient`, MCP — would
|
|
6884
|
+
// fail on a hub configured through the other surface.
|
|
6885
|
+
value: external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()])
|
|
6886
|
+
});
|
|
6887
|
+
MONITOR_TRIGGERS = ["idle", "user_message", "assistant_reply", "manual"];
|
|
6888
|
+
monitorTriggerSchema = external_exports.enum(MONITOR_TRIGGERS);
|
|
6889
|
+
MONITOR_FIRING_TRIGGERS = MONITOR_TRIGGERS.filter(isFiringTrigger);
|
|
6890
|
+
MONITOR_DELAY_SECONDS_MIN = 10;
|
|
6891
|
+
MONITOR_IDLE_DELAY_REQUIRED_MESSAGE = "delay_seconds is required for an idle monitor (an absent trigger is idle)";
|
|
6892
|
+
MONITOR_HISTORY_MESSAGES_MAX = 100;
|
|
6893
|
+
monitorHistoryMessagesSchema = external_exports.number().int().min(1).max(MONITOR_HISTORY_MESSAGES_MAX);
|
|
6894
|
+
monitorIncludeToolResultsSchema = external_exports.boolean();
|
|
6895
|
+
MONITOR_INPUT_SHAPING_KEYS = ["history_messages", "include_tool_results"];
|
|
6896
|
+
MONITOR_INPUT_SHAPING_SCHEMAS = {
|
|
6897
|
+
history_messages: monitorHistoryMessagesSchema.optional(),
|
|
6898
|
+
include_tool_results: monitorIncludeToolResultsSchema.optional()
|
|
6899
|
+
};
|
|
6900
|
+
MONITOR_INPUT_SHAPING_IDLE_MESSAGE = "only a user_message, assistant_reply or manual monitor reads this \u2014 an idle monitor runs as a full turn and takes the ordinary history window";
|
|
6901
|
+
monitorArgumentSourceSchema = external_exports.union([
|
|
6902
|
+
external_exports.object({ from_variable: external_exports.string().min(1) }).strict(),
|
|
6903
|
+
external_exports.object({ const: external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()]) }).strict()
|
|
6904
|
+
]);
|
|
6905
|
+
MONITOR_NOTE_TEMPLATE_MAX = 2e3;
|
|
6906
|
+
monitorActionSchema = external_exports.discriminatedUnion("kind", [
|
|
6907
|
+
external_exports.object({ kind: external_exports.literal("none") }).strict(),
|
|
6908
|
+
external_exports.object({
|
|
6909
|
+
kind: external_exports.literal("call_tool"),
|
|
6910
|
+
tool_name: external_exports.string().min(1),
|
|
6911
|
+
args: external_exports.record(monitorArgumentSourceSchema).optional()
|
|
6912
|
+
}).strict(),
|
|
6913
|
+
external_exports.object({ kind: external_exports.literal("hold") }).strict(),
|
|
6914
|
+
external_exports.object({ kind: external_exports.literal("rewrite"), note: external_exports.string().min(1).max(MONITOR_NOTE_TEMPLATE_MAX) }).strict()
|
|
6915
|
+
]);
|
|
6916
|
+
monitorRuleSchema = external_exports.object({
|
|
6917
|
+
when: external_exports.array(flagConditionSchema).min(1),
|
|
6918
|
+
action: monitorActionSchema
|
|
6919
|
+
}).strict();
|
|
6920
|
+
MONITOR_RULE_KEYS = ["rules", "fallback"];
|
|
6921
|
+
MONITOR_RULE_SCHEMAS = {
|
|
6922
|
+
rules: external_exports.array(monitorRuleSchema).optional(),
|
|
6923
|
+
fallback: monitorActionSchema.optional()
|
|
6924
|
+
};
|
|
6925
|
+
MONITOR_RULE_TRIGGERS = ["user_message", "assistant_reply", "manual"];
|
|
6926
|
+
MONITOR_RULE_TRIGGER_MESSAGE = "only a user_message, assistant_reply or manual monitor acts on rules \u2014 set one of those triggers, or remove this key. A manual monitor acts on its rules when another monitor runs it.";
|
|
6927
|
+
MONITOR_USER_MESSAGE_ACTION_KINDS = ["none", "call_tool"];
|
|
6928
|
+
MONITOR_ASSISTANT_REPLY_ACTION_KINDS = ["none", "call_tool", "hold", "rewrite"];
|
|
6929
|
+
INSERT_NOTE_TOOL_NAME = "insert_note";
|
|
6930
|
+
RUN_MONITOR_TOOL_NAME = "run_monitor";
|
|
6931
|
+
MONITOR_RULE_ALLOWED_NATIVE_TOOLS = [
|
|
6932
|
+
"update_state",
|
|
6933
|
+
"schedule_followup",
|
|
6934
|
+
"transfer_to_agent",
|
|
6935
|
+
"transfer_to_team",
|
|
6936
|
+
INSERT_NOTE_TOOL_NAME,
|
|
6937
|
+
RUN_MONITOR_TOOL_NAME
|
|
6938
|
+
];
|
|
6939
|
+
MONITOR_RULE_REENTRY_TOOLS = {
|
|
6940
|
+
transfer_to_agent: "agent",
|
|
6941
|
+
transfer_to_team: "team"
|
|
6942
|
+
};
|
|
6943
|
+
MONITOR_RULE_REENTRY_TRACKS = new Map(Object.entries(MONITOR_RULE_REENTRY_TOOLS));
|
|
5551
6944
|
monitorConfigField = external_exports.object({
|
|
5552
|
-
delay_seconds: external_exports.number().int().min(
|
|
5553
|
-
|
|
5554
|
-
|
|
5555
|
-
|
|
5556
|
-
|
|
5557
|
-
|
|
5558
|
-
|
|
5559
|
-
|
|
5560
|
-
|
|
6945
|
+
delay_seconds: external_exports.number().int().min(MONITOR_DELAY_SECONDS_MIN).optional(),
|
|
6946
|
+
trigger: monitorTriggerSchema.optional(),
|
|
6947
|
+
...MONITOR_INPUT_SHAPING_SCHEMAS,
|
|
6948
|
+
...MONITOR_RULE_SCHEMAS,
|
|
6949
|
+
flag_conditions: external_exports.array(flagConditionSchema).optional()
|
|
6950
|
+
}).passthrough().superRefine((config, ctx) => {
|
|
6951
|
+
if (monitorConfigNeedsDelay(config)) {
|
|
6952
|
+
ctx.addIssue({
|
|
6953
|
+
code: external_exports.ZodIssueCode.custom,
|
|
6954
|
+
path: ["delay_seconds"],
|
|
6955
|
+
message: MONITOR_IDLE_DELAY_REQUIRED_MESSAGE
|
|
6956
|
+
});
|
|
6957
|
+
}
|
|
6958
|
+
for (const key of monitorInputShapingKeysOnIdle(config)) {
|
|
6959
|
+
ctx.addIssue({
|
|
6960
|
+
code: external_exports.ZodIssueCode.custom,
|
|
6961
|
+
path: [key],
|
|
6962
|
+
message: MONITOR_INPUT_SHAPING_IDLE_MESSAGE
|
|
6963
|
+
});
|
|
6964
|
+
}
|
|
6965
|
+
for (const issue of collectMonitorRuleIssues(config)) {
|
|
6966
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: issue.path, message: issue.message });
|
|
6967
|
+
}
|
|
6968
|
+
}).nullable().optional();
|
|
6969
|
+
flagConditionsField = external_exports.array(flagConditionSchema).nullable().optional();
|
|
5561
6970
|
agentIdParam = external_exports.object({
|
|
5562
6971
|
id: uuidSchema
|
|
5563
6972
|
});
|
|
@@ -5574,13 +6983,15 @@ var init_contracts = __esm({
|
|
|
5574
6983
|
additional_context_template: external_exports.string().max(2e4).optional(),
|
|
5575
6984
|
summarization_threshold_tokens: summarizationThresholdField,
|
|
5576
6985
|
previous_conversations_count: previousConversationsCountField,
|
|
5577
|
-
monitor_config: monitorConfigField
|
|
5578
|
-
|
|
6986
|
+
monitor_config: monitorConfigField,
|
|
6987
|
+
flag_conditions: flagConditionsField
|
|
6988
|
+
}).passthrough().superRefine(refineDecisionsModelBinding);
|
|
5579
6989
|
updateAgentBody = external_exports.object({
|
|
5580
6990
|
additional_context_template: external_exports.string().max(2e4).optional(),
|
|
5581
6991
|
summarization_threshold_tokens: summarizationThresholdField,
|
|
5582
6992
|
previous_conversations_count: previousConversationsCountField,
|
|
5583
|
-
monitor_config: monitorConfigField
|
|
6993
|
+
monitor_config: monitorConfigField,
|
|
6994
|
+
flag_conditions: flagConditionsField
|
|
5584
6995
|
}).passthrough();
|
|
5585
6996
|
AGENT_PARAMETER_TYPES = ["string", "number", "boolean", "integer", "enum"];
|
|
5586
6997
|
AGENT_PARAMETER_NAME_REGEX = /^[a-zA-Z_][a-zA-Z0-9_]{0,63}$/;
|
|
@@ -7572,11 +8983,11 @@ var init_contracts = __esm({
|
|
|
7572
8983
|
ops_tenths_this_month: external_exports.number().nonnegative(),
|
|
7573
8984
|
records_count: external_exports.number().nonnegative(),
|
|
7574
8985
|
month_key: external_exports.string(),
|
|
7575
|
-
// The closed window's meter reading (
|
|
8986
|
+
// The closed window's meter reading (the prior-window snapshot). OPTIONAL for the same
|
|
7576
8987
|
// reason this object is not `.strict()`: the producer deploys on its own cadence, and a
|
|
7577
8988
|
// required field would fail the parse for every counter on any producer build that predates
|
|
7578
8989
|
// it — turning an additive wire change into an outage of the gauge above. Absence and a
|
|
7579
|
-
// non-matching key are the SAME outcome for a reader (
|
|
8990
|
+
// non-matching key are the SAME outcome for a reader (do not bill), so
|
|
7580
8991
|
// nothing is lost by tolerating it.
|
|
7581
8992
|
prior_window_key: external_exports.string().optional(),
|
|
7582
8993
|
prior_window_ops_tenths: external_exports.number().nonnegative().optional()
|
|
@@ -7588,41 +8999,41 @@ var init_contracts = __esm({
|
|
|
7588
8999
|
* Monotonic per org, WayAI-assigned. An ordering guard for concurrent WayAI
|
|
7589
9000
|
* writers (a plan change racing a token mint) — NOT a cross-repo CAS. Gaps are
|
|
7590
9001
|
* expected: a version is allocated per push attempt, and an idempotency skip
|
|
7591
|
-
*
|
|
9002
|
+
* burns none while a failed KV put burns one.
|
|
7592
9003
|
*/
|
|
7593
9004
|
projection_version: external_exports.number().int().nonnegative(),
|
|
7594
|
-
/** Diagnostic only — never gates. Freshness is `window_resets_at`'s job
|
|
9005
|
+
/** Diagnostic only — never gates. Freshness is `window_resets_at`'s job. */
|
|
7595
9006
|
written_at: external_exports.string().datetime(),
|
|
7596
9007
|
/** The WayAI org UUID. The `account_id` spelling is Rekor's documented carve-out. */
|
|
7597
9008
|
account_id: external_exports.string().uuid(),
|
|
7598
|
-
/** The EFFECTIVE plan, not the subscribed one
|
|
9009
|
+
/** The EFFECTIVE plan, not the subscribed one. Never gates. */
|
|
7599
9010
|
plan_key: planKeySchema,
|
|
7600
|
-
/** Informational only
|
|
9011
|
+
/** Informational only. `cancelled` spelling matches `BillingRecord`. */
|
|
7601
9012
|
billing_status: billingStatusSchema,
|
|
7602
9013
|
/** Tenths, matching Rekor's meter granularity (write 10, point-read 1, list/SQL 10). */
|
|
7603
9014
|
ops_tenths_included: external_exports.number().int().nonnegative(),
|
|
7604
9015
|
max_records: external_exports.number().int().nonnegative(),
|
|
7605
|
-
/** Its own field, no longer derived from `max_records
|
|
9016
|
+
/** Its own field, no longer derived from `max_records`. */
|
|
7606
9017
|
import_rows_included: external_exports.number().int().nonnegative(),
|
|
7607
|
-
/** REQUIRED — absence is malformed, never coerced to `false
|
|
9018
|
+
/** REQUIRED — absence is malformed, never coerced to `false`. */
|
|
7608
9019
|
production_bases: external_exports.boolean(),
|
|
7609
|
-
/** Opaque to Rekor; compared for equality only, to reset `usage:` counters
|
|
9020
|
+
/** Opaque to Rekor; compared for equality only, to reset `usage:` counters. */
|
|
7610
9021
|
window_key: external_exports.string().min(1),
|
|
7611
9022
|
/**
|
|
7612
|
-
* The window's TRUE lower bound, for the reconcile's `operations_log` sum
|
|
9023
|
+
* The window's TRUE lower bound, for the reconcile's `operations_log` sum.
|
|
7613
9024
|
*
|
|
7614
9025
|
* OPTIONAL, and that is not a rollout convenience — it is what "never gates" means
|
|
7615
9026
|
* on the writer's side. The tier sources can be absent (a paid row carrying
|
|
7616
9027
|
* `current_period_end` with no `current_period_start`) and inverted pairs are a
|
|
7617
|
-
*
|
|
7618
|
-
* parse and leave the org with NO projection — permanently stale
|
|
7619
|
-
*
|
|
9028
|
+
* diagnostic, so requiring it here would let an inert field throw the strict
|
|
9029
|
+
* parse and leave the org with NO projection — permanently stale, with the
|
|
9030
|
+
* fail-closed gates refusing base creation and 503-ing every import. The
|
|
7620
9031
|
* writer emits it whenever it has a sound value and omits it otherwise; Rekor's
|
|
7621
9032
|
* observed-flip fallback covers the gap, and rollout step 3 keeps that fallback
|
|
7622
9033
|
* for exactly this reason.
|
|
7623
9034
|
*/
|
|
7624
9035
|
window_start: external_exports.string().datetime().optional(),
|
|
7625
|
-
/** The sole staleness authority
|
|
9036
|
+
/** The sole staleness authority. Never triggers a counter reset. */
|
|
7626
9037
|
window_resets_at: external_exports.string().datetime()
|
|
7627
9038
|
}).strict();
|
|
7628
9039
|
rekorEntitlementRefreshMessageSchema = external_exports.object({
|
|
@@ -7862,6 +9273,9 @@ var init_contracts = __esm({
|
|
|
7862
9273
|
refineHubAsCodeEvalAttachments(config, ctx);
|
|
7863
9274
|
refineHubAsCodeResources(config, ctx);
|
|
7864
9275
|
refineHubAsCodeDelegation(config, ctx);
|
|
9276
|
+
refineHubAsCodeFlagConditions(config, ctx);
|
|
9277
|
+
refineHubAsCodeMonitorConfig(config, ctx);
|
|
9278
|
+
refineHubAsCodeDecisionsModel(config, ctx);
|
|
7865
9279
|
});
|
|
7866
9280
|
ciPullHubIdParam = external_exports.object({
|
|
7867
9281
|
hub_id: ciUuidSchema
|
|
@@ -8089,7 +9503,7 @@ var init_contracts = __esm({
|
|
|
8089
9503
|
*
|
|
8090
9504
|
* Past-or-now only. A future start freezes the org's window permanently:
|
|
8091
9505
|
* `maybeRolloverBillingWindow` derives a NEGATIVE elapsed and so never archives the
|
|
8092
|
-
* metrics nor restamps the column, while the
|
|
9506
|
+
* metrics nor restamps the column, while the rollover sweep selects only windows
|
|
8093
9507
|
* that have already passed — so nothing rolls the org over, its consumed operations
|
|
8094
9508
|
* never reset, and past quota every AI turn is refused until a human re-patches.
|
|
8095
9509
|
*/
|
|
@@ -8184,7 +9598,7 @@ var init_contracts = __esm({
|
|
|
8184
9598
|
seats_per_unit: external_exports.number().int().min(1, "seats_per_unit must be a positive integer").optional(),
|
|
8185
9599
|
seats_scaling: external_exports.enum(["fixed", "per_quantity"]).optional(),
|
|
8186
9600
|
is_active: external_exports.boolean().optional(),
|
|
8187
|
-
// Rekor entitlement allowances
|
|
9601
|
+
// Rekor entitlement allowances. Editable here for the
|
|
8188
9602
|
// same reason `messages_per_unit` is — and this route is the only ROUTINE way to change an
|
|
8189
9603
|
// allowance on a live plan: the seed establishes a plan row and never rewrites one, so a
|
|
8190
9604
|
// seed-version bump no longer moves these values (see `seed.ts`).
|
|
@@ -8321,7 +9735,7 @@ var init_contracts = __esm({
|
|
|
8321
9735
|
cmd: external_exports.string().min(1, "cmd is required").max(SANDBOX_EXEC_MAX_CMD_LENGTH, `cmd must be <= ${SANDBOX_EXEC_MAX_CMD_LENGTH} chars`),
|
|
8322
9736
|
/**
|
|
8323
9737
|
* Egress posture. Omitted ⇒ the driver fails closed to deny-all outbound (the
|
|
8324
|
-
*
|
|
9738
|
+
* safe default). The route re-validates the (policy, allowlist) pair via
|
|
8325
9739
|
* `validateEgressConfig`.
|
|
8326
9740
|
*/
|
|
8327
9741
|
egress_policy: sandboxEgressPolicy.optional(),
|
|
@@ -8912,7 +10326,7 @@ var init_contracts = __esm({
|
|
|
8912
10326
|
base_id: external_exports.string()
|
|
8913
10327
|
});
|
|
8914
10328
|
rekorBaseChangeMessageSchema = external_exports.object({
|
|
8915
|
-
/** The WayAI org UUID — one id namespace
|
|
10329
|
+
/** The WayAI org UUID — one id namespace. */
|
|
8916
10330
|
org_id: external_exports.string().uuid(),
|
|
8917
10331
|
/**
|
|
8918
10332
|
* Not a UUID: a preview base id is `{prod_base_id}--{slug}`. Immutable per base — a
|
|
@@ -9850,6 +11264,327 @@ function withinJsonLength2(value, max) {
|
|
|
9850
11264
|
const length = jsonLengthOrNull2(value);
|
|
9851
11265
|
return length !== null && length <= max;
|
|
9852
11266
|
}
|
|
11267
|
+
function schemaToQuestions2(schema) {
|
|
11268
|
+
const classified = classifySchema2(schema);
|
|
11269
|
+
if (classified.refusals.length > 0) return { ok: false, refusals: classified.refusals };
|
|
11270
|
+
const questions = {};
|
|
11271
|
+
for (const [field, primitive] of classified.fields) {
|
|
11272
|
+
questions[field] = toQuestion2(primitive);
|
|
11273
|
+
}
|
|
11274
|
+
return { ok: true, questions };
|
|
11275
|
+
}
|
|
11276
|
+
function classifySchema2(schema) {
|
|
11277
|
+
const fields = /* @__PURE__ */ new Map();
|
|
11278
|
+
if (!isRecord3(schema) || schema.type !== "object") {
|
|
11279
|
+
return { fields, refusals: [{ field: null, reason: "schema_not_object" }] };
|
|
11280
|
+
}
|
|
11281
|
+
const properties = schema.properties;
|
|
11282
|
+
if (!isRecord3(properties) || Object.keys(properties).length === 0) {
|
|
11283
|
+
return { fields, refusals: [{ field: null, reason: "schema_has_no_properties" }] };
|
|
11284
|
+
}
|
|
11285
|
+
const refusals = [];
|
|
11286
|
+
for (const [field, property] of Object.entries(properties)) {
|
|
11287
|
+
const primitive = classifyField2(field, property);
|
|
11288
|
+
if ("reason" in primitive) {
|
|
11289
|
+
refusals.push({ field, reason: primitive.reason });
|
|
11290
|
+
continue;
|
|
11291
|
+
}
|
|
11292
|
+
fields.set(field, primitive);
|
|
11293
|
+
}
|
|
11294
|
+
return refusals.length > 0 ? { fields: /* @__PURE__ */ new Map(), refusals } : { fields, refusals };
|
|
11295
|
+
}
|
|
11296
|
+
function classifyField2(field, property) {
|
|
11297
|
+
if (!isRecord3(property)) return { reason: "unsupported_type" };
|
|
11298
|
+
const instructions = describeField2(field, property);
|
|
11299
|
+
if (property.enum !== void 0) {
|
|
11300
|
+
const declared = property.enum;
|
|
11301
|
+
if (!Array.isArray(declared) || declared.some((option) => typeof option !== "string")) {
|
|
11302
|
+
return { reason: "unsupported_type" };
|
|
11303
|
+
}
|
|
11304
|
+
const options = [...new Set(declared)];
|
|
11305
|
+
if (options.length < 2) return { reason: "too_few_options" };
|
|
11306
|
+
return { kind: "choice", instructions, options };
|
|
11307
|
+
}
|
|
11308
|
+
if (property.type === "boolean") return { kind: "noul", instructions };
|
|
11309
|
+
if (property.type === "integer") {
|
|
11310
|
+
const minimum = property.minimum;
|
|
11311
|
+
const maximum = property.maximum;
|
|
11312
|
+
if (!Number.isInteger(minimum) || !Number.isInteger(maximum)) {
|
|
11313
|
+
return { reason: "integer_not_bounded" };
|
|
11314
|
+
}
|
|
11315
|
+
const levels = maximum - minimum + 1;
|
|
11316
|
+
if (levels < DECISION_SCORE_MIN_LEVELS2) return { reason: "too_few_options" };
|
|
11317
|
+
if (levels > DECISION_SCORE_MAX_LEVELS2) return { reason: "integer_range_too_large" };
|
|
11318
|
+
return { kind: "score", instructions, minimum, levels };
|
|
11319
|
+
}
|
|
11320
|
+
return { reason: "unsupported_type" };
|
|
11321
|
+
}
|
|
11322
|
+
function toQuestion2(primitive) {
|
|
11323
|
+
switch (primitive.kind) {
|
|
11324
|
+
case "choice":
|
|
11325
|
+
return {
|
|
11326
|
+
type: "choice",
|
|
11327
|
+
instructions: primitive.instructions,
|
|
11328
|
+
// A JSON Schema enum carries no per-option text, so each option stands as
|
|
11329
|
+
// its own description. The distinguishing detail an option needs belongs
|
|
11330
|
+
// in the field's `description`, which is the instructions.
|
|
11331
|
+
criteria: Object.fromEntries(primitive.options.map((option) => [option, option]))
|
|
11332
|
+
};
|
|
11333
|
+
case "noul":
|
|
11334
|
+
return { type: "noul", instructions: primitive.instructions };
|
|
11335
|
+
case "score":
|
|
11336
|
+
return {
|
|
11337
|
+
type: "score",
|
|
11338
|
+
instructions: primitive.instructions,
|
|
11339
|
+
criteria: scoreLevels2(primitive.minimum, primitive.levels)
|
|
11340
|
+
};
|
|
11341
|
+
}
|
|
11342
|
+
}
|
|
11343
|
+
function describeField2(field, property) {
|
|
11344
|
+
const description = isRecord3(property) ? property.description : void 0;
|
|
11345
|
+
return typeof description === "string" && description.trim() !== "" ? description : field;
|
|
11346
|
+
}
|
|
11347
|
+
function scoreLevels2(minimum, levels) {
|
|
11348
|
+
return Array.from({ length: levels }, (_, index) => String(minimum + index));
|
|
11349
|
+
}
|
|
11350
|
+
function isRecord3(value) {
|
|
11351
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
11352
|
+
}
|
|
11353
|
+
function isDecisionsModel2(modelId) {
|
|
11354
|
+
if (typeof modelId !== "string") return false;
|
|
11355
|
+
const normalized = modelId.trim().toLowerCase();
|
|
11356
|
+
return DECISIONS_MODEL_PREFIXES2.some((prefix) => normalized.startsWith(prefix));
|
|
11357
|
+
}
|
|
11358
|
+
function checkDecisionsModelBinding2(agent) {
|
|
11359
|
+
if (!isDecisionsModel2(agent.model)) return null;
|
|
11360
|
+
const model = String(agent.model);
|
|
11361
|
+
const role = agent.agent_role;
|
|
11362
|
+
if (!DECISION_CAPABLE_AGENT_ROLES2.includes(role)) {
|
|
11363
|
+
return refuse2(
|
|
11364
|
+
"role_produces_text",
|
|
11365
|
+
`agent_role "${String(role)}" produces text, which the decisions model "${model}" does not return. A decisions model binds to: ${DECISION_CAPABLE_AGENT_ROLES2.join(", ")}.`
|
|
11366
|
+
);
|
|
11367
|
+
}
|
|
11368
|
+
if (agent.response_format !== "json_schema") {
|
|
11369
|
+
return refuse2(
|
|
11370
|
+
"response_format_not_json_schema",
|
|
11371
|
+
`response_format must be "json_schema" to bind the decisions model "${model}".`
|
|
11372
|
+
);
|
|
11373
|
+
}
|
|
11374
|
+
if (agent.schema_json === null || agent.schema_json === void 0 || agent.schema_json === "") {
|
|
11375
|
+
return refuse2(
|
|
11376
|
+
"schema_missing",
|
|
11377
|
+
`schema_json is required to bind the decisions model "${model}": a decisions model answers questions, and the schema is where they come from.`
|
|
11378
|
+
);
|
|
11379
|
+
}
|
|
11380
|
+
let schema = agent.schema_json;
|
|
11381
|
+
if (typeof schema === "string") {
|
|
11382
|
+
try {
|
|
11383
|
+
schema = JSON.parse(schema);
|
|
11384
|
+
} catch {
|
|
11385
|
+
return refuse2(
|
|
11386
|
+
"schema_unreadable",
|
|
11387
|
+
`schema_json is not valid JSON, so the decisions model "${model}" cannot be bound.`
|
|
11388
|
+
);
|
|
11389
|
+
}
|
|
11390
|
+
}
|
|
11391
|
+
const mapped = schemaToQuestions2(schema);
|
|
11392
|
+
if (mapped.ok) return null;
|
|
11393
|
+
const detail = mapped.refusals.map((refusal2) => `${refusal2.field ?? "(schema)"}: ${refusal2.reason}`).join("; ");
|
|
11394
|
+
return {
|
|
11395
|
+
reason: "schema_not_closed_set",
|
|
11396
|
+
schema_refusals: mapped.refusals,
|
|
11397
|
+
message: `schema_json is not closed-set, so the decisions model "${model}" cannot answer it \u2014 ${detail}. A decisions model answers enum, boolean and bounded-integer fields only.`
|
|
11398
|
+
};
|
|
11399
|
+
}
|
|
11400
|
+
function refuse2(reason, message) {
|
|
11401
|
+
return { reason, schema_refusals: [], message };
|
|
11402
|
+
}
|
|
11403
|
+
function readAgentSettingsModel2(agentSettings) {
|
|
11404
|
+
let settings = agentSettings;
|
|
11405
|
+
if (typeof settings === "string") {
|
|
11406
|
+
try {
|
|
11407
|
+
settings = JSON.parse(settings);
|
|
11408
|
+
} catch {
|
|
11409
|
+
return null;
|
|
11410
|
+
}
|
|
11411
|
+
}
|
|
11412
|
+
if (typeof settings !== "object" || settings === null || Array.isArray(settings)) return null;
|
|
11413
|
+
const model = settings.model;
|
|
11414
|
+
return typeof model === "string" ? model : null;
|
|
11415
|
+
}
|
|
11416
|
+
function resolveMonitorTrigger2(monitorConfig) {
|
|
11417
|
+
if (!monitorConfig || typeof monitorConfig !== "object") return "idle";
|
|
11418
|
+
const raw = monitorConfig.trigger;
|
|
11419
|
+
return MONITOR_TRIGGERS2.includes(raw) ? raw : "idle";
|
|
11420
|
+
}
|
|
11421
|
+
function isFiringTrigger2(trigger) {
|
|
11422
|
+
return trigger !== "manual";
|
|
11423
|
+
}
|
|
11424
|
+
function monitorConfigNeedsDelay2(monitorConfig) {
|
|
11425
|
+
if (!monitorConfig || typeof monitorConfig !== "object") return false;
|
|
11426
|
+
return resolveMonitorTrigger2(monitorConfig) === "idle" && monitorConfig.delay_seconds === void 0;
|
|
11427
|
+
}
|
|
11428
|
+
function monitorInputShapingKeysOnIdle2(monitorConfig) {
|
|
11429
|
+
if (!monitorConfig || typeof monitorConfig !== "object") return [];
|
|
11430
|
+
if (resolveMonitorTrigger2(monitorConfig) !== "idle") return [];
|
|
11431
|
+
const config = monitorConfig;
|
|
11432
|
+
return MONITOR_INPUT_SHAPING_KEYS2.filter((key) => config[key] !== void 0);
|
|
11433
|
+
}
|
|
11434
|
+
function monitorRuleKeysOffTrigger2(monitorConfig) {
|
|
11435
|
+
if (!monitorConfig || typeof monitorConfig !== "object") return [];
|
|
11436
|
+
if (MONITOR_RULE_TRIGGERS2.includes(resolveMonitorTrigger2(monitorConfig))) return [];
|
|
11437
|
+
const config = monitorConfig;
|
|
11438
|
+
return MONITOR_RULE_KEYS2.filter((key) => config[key] !== void 0);
|
|
11439
|
+
}
|
|
11440
|
+
function monitorRuleActionKinds2(trigger) {
|
|
11441
|
+
return trigger === "assistant_reply" ? MONITOR_ASSISTANT_REPLY_ACTION_KINDS2 : MONITOR_USER_MESSAGE_ACTION_KINDS2;
|
|
11442
|
+
}
|
|
11443
|
+
function monitorActionKindMessage2(kind, trigger) {
|
|
11444
|
+
const allowed = monitorRuleActionKinds2(trigger).join(", ");
|
|
11445
|
+
if (trigger === "assistant_reply") {
|
|
11446
|
+
return `an assistant_reply rule cannot select "${kind}". Use one of: ${allowed}.`;
|
|
11447
|
+
}
|
|
11448
|
+
return `a monitor rule cannot select "${kind}": it acts before the reply exists. Use one of: ${allowed}.`;
|
|
11449
|
+
}
|
|
11450
|
+
function monitorRuleReentryTrack2(toolName) {
|
|
11451
|
+
return MONITOR_RULE_REENTRY_TRACKS2.get(toolName);
|
|
11452
|
+
}
|
|
11453
|
+
function monitorRuleToolNotAllowedMessage2(toolName, trigger) {
|
|
11454
|
+
if (trigger === "assistant_reply" && isReplyGateRefusedToolName2(toolName)) {
|
|
11455
|
+
return `an assistant_reply rule cannot call "${toolName}": the reply already exists when this monitor runs, so there is no turn left for it to act on. Put it on a user_message monitor instead, which runs before the answering agent.`;
|
|
11456
|
+
}
|
|
11457
|
+
const callable = trigger === "assistant_reply" ? MONITOR_RULE_ALLOWED_NATIVE_TOOLS2.filter((name) => !isReplyGateRefusedToolName2(name)) : MONITOR_RULE_ALLOWED_NATIVE_TOOLS2;
|
|
11458
|
+
return `a ${trigger} rule cannot call "${toolName}". Rules can call ${callable.join(", ")}, and this hub's own external HTTP and MCP tools. Assign anything else to the answering agent instead.`;
|
|
11459
|
+
}
|
|
11460
|
+
function isReplyGateRefusedToolName2(toolName) {
|
|
11461
|
+
return monitorRuleReentryTrack2(toolName) === "agent" || toolName === INSERT_NOTE_TOOL_NAME2;
|
|
11462
|
+
}
|
|
11463
|
+
function isRefusedNativeToolName2(toolName, trigger) {
|
|
11464
|
+
if (!NATIVE_TOOL_NAMES2.has(toolName)) return false;
|
|
11465
|
+
if (!MONITOR_RULE_ALLOWED_NATIVE_TOOLS2.includes(toolName)) return true;
|
|
11466
|
+
return trigger === "assistant_reply" && isReplyGateRefusedToolName2(toolName);
|
|
11467
|
+
}
|
|
11468
|
+
function monitorRuleActions2(monitorConfig) {
|
|
11469
|
+
if (!monitorConfig || typeof monitorConfig !== "object") return [];
|
|
11470
|
+
const config = monitorConfig;
|
|
11471
|
+
const found = [];
|
|
11472
|
+
const visit = (action, path35) => {
|
|
11473
|
+
if (!action || typeof action !== "object" || Array.isArray(action)) return;
|
|
11474
|
+
found.push({ action, path: path35 });
|
|
11475
|
+
};
|
|
11476
|
+
if (Array.isArray(config.rules)) {
|
|
11477
|
+
config.rules.forEach((rule, index) => {
|
|
11478
|
+
if (!rule || typeof rule !== "object" || Array.isArray(rule)) return;
|
|
11479
|
+
visit(rule.action, ["rules", index, "action"]);
|
|
11480
|
+
});
|
|
11481
|
+
}
|
|
11482
|
+
visit(config.fallback, ["fallback"]);
|
|
11483
|
+
return found;
|
|
11484
|
+
}
|
|
11485
|
+
function collectMonitorRuleIssues2(monitorConfig) {
|
|
11486
|
+
const offTrigger = monitorRuleKeysOffTrigger2(monitorConfig).map((key) => ({ path: [key], message: MONITOR_RULE_TRIGGER_MESSAGE2 }));
|
|
11487
|
+
if (offTrigger.length > 0) return offTrigger;
|
|
11488
|
+
const trigger = resolveMonitorTrigger2(monitorConfig);
|
|
11489
|
+
const kinds = monitorRuleActionKinds2(trigger);
|
|
11490
|
+
const issues = [];
|
|
11491
|
+
for (const { action, path: path35 } of monitorRuleActions2(monitorConfig)) {
|
|
11492
|
+
const kind = action.kind;
|
|
11493
|
+
if (typeof kind === "string" && !kinds.includes(kind)) {
|
|
11494
|
+
issues.push({ path: [...path35, "kind"], message: monitorActionKindMessage2(kind, trigger) });
|
|
11495
|
+
}
|
|
11496
|
+
const toolName = action.tool_name;
|
|
11497
|
+
if (kind === "call_tool" && typeof toolName === "string" && isRefusedNativeToolName2(toolName, trigger)) {
|
|
11498
|
+
issues.push({ path: [...path35, "tool_name"], message: monitorRuleToolNotAllowedMessage2(toolName, trigger) });
|
|
11499
|
+
continue;
|
|
11500
|
+
}
|
|
11501
|
+
if (kind === "call_tool" && toolName === INSERT_NOTE_TOOL_NAME2) {
|
|
11502
|
+
issues.push(...insertNoteArgumentIssues2(action, path35));
|
|
11503
|
+
}
|
|
11504
|
+
if (kind === "call_tool" && toolName === RUN_MONITOR_TOOL_NAME2) {
|
|
11505
|
+
const callee = readRunMonitorCallee2(action);
|
|
11506
|
+
if (!callee.ok) {
|
|
11507
|
+
issues.push({
|
|
11508
|
+
path: [...path35, "args", "monitor_name"],
|
|
11509
|
+
message: runMonitorCalleeMessage2(callee.reason)
|
|
11510
|
+
});
|
|
11511
|
+
}
|
|
11512
|
+
}
|
|
11513
|
+
}
|
|
11514
|
+
return issues;
|
|
11515
|
+
}
|
|
11516
|
+
function readInsertNoteTemplate2(action) {
|
|
11517
|
+
const read = readConstStringArg2(action, "template");
|
|
11518
|
+
if (!read.ok) {
|
|
11519
|
+
return {
|
|
11520
|
+
ok: false,
|
|
11521
|
+
reason: read.reason === "missing" ? "note_template_missing" : read.reason === "not_const" ? "note_template_not_const" : "note_template_empty"
|
|
11522
|
+
};
|
|
11523
|
+
}
|
|
11524
|
+
if (read.value.length > MONITOR_NOTE_TEMPLATE_MAX2) {
|
|
11525
|
+
return { ok: false, reason: "note_template_too_long" };
|
|
11526
|
+
}
|
|
11527
|
+
return { ok: true, template: read.value };
|
|
11528
|
+
}
|
|
11529
|
+
function readConstStringArg2(action, argName) {
|
|
11530
|
+
const args2 = action && typeof action === "object" ? action.args : void 0;
|
|
11531
|
+
const arg = args2 && typeof args2 === "object" ? args2[argName] : void 0;
|
|
11532
|
+
if (arg === void 0) return { ok: false, reason: "missing" };
|
|
11533
|
+
const constValue = arg && typeof arg === "object" && !Array.isArray(arg) ? arg.const : void 0;
|
|
11534
|
+
if (typeof constValue !== "string") return { ok: false, reason: "not_const" };
|
|
11535
|
+
if (constValue.trim() === "") return { ok: false, reason: "empty" };
|
|
11536
|
+
return { ok: true, value: constValue };
|
|
11537
|
+
}
|
|
11538
|
+
function readRunMonitorCallee2(action) {
|
|
11539
|
+
const read = readConstStringArg2(action, "monitor_name");
|
|
11540
|
+
if (read.ok) return { ok: true, name: read.value };
|
|
11541
|
+
return {
|
|
11542
|
+
ok: false,
|
|
11543
|
+
reason: read.reason === "missing" ? "callee_missing" : read.reason === "not_const" ? "callee_not_const" : "callee_empty"
|
|
11544
|
+
};
|
|
11545
|
+
}
|
|
11546
|
+
function runMonitorCalleeMessage2(reason) {
|
|
11547
|
+
switch (reason) {
|
|
11548
|
+
case "callee_missing":
|
|
11549
|
+
return "run_monitor needs a monitor_name: the monitor to run.";
|
|
11550
|
+
case "callee_not_const":
|
|
11551
|
+
return "run_monitor's monitor_name must be a const you write \u2014 it chooses which monitor runs, so it cannot come from a variable.";
|
|
11552
|
+
case "callee_empty":
|
|
11553
|
+
return "run_monitor's monitor_name is empty \u2014 name the monitor to run.";
|
|
11554
|
+
}
|
|
11555
|
+
}
|
|
11556
|
+
function insertNoteTemplateMessage2(reason) {
|
|
11557
|
+
switch (reason) {
|
|
11558
|
+
case "note_template_missing":
|
|
11559
|
+
return "insert_note needs a template: the note text to put in front of the answering agent.";
|
|
11560
|
+
case "note_template_not_const":
|
|
11561
|
+
return "insert_note's template must be a const string you write \u2014 the answering agent reads it as instructions, so it cannot come from a variable. Use {{variable_name}} inside it to substitute this monitor's variables.";
|
|
11562
|
+
case "note_template_empty":
|
|
11563
|
+
return "insert_note's template is empty \u2014 remove the rule, or give it something to say.";
|
|
11564
|
+
case "note_template_too_long":
|
|
11565
|
+
return `insert_note's template is longer than the ${MONITOR_NOTE_TEMPLATE_MAX2}-character limit.`;
|
|
11566
|
+
}
|
|
11567
|
+
}
|
|
11568
|
+
function insertNoteArgumentIssues2(action, path35) {
|
|
11569
|
+
const result = readInsertNoteTemplate2(action);
|
|
11570
|
+
if (result.ok) return [];
|
|
11571
|
+
return [{
|
|
11572
|
+
path: [...path35, "args", "template"],
|
|
11573
|
+
message: insertNoteTemplateMessage2(result.reason)
|
|
11574
|
+
}];
|
|
11575
|
+
}
|
|
11576
|
+
function refineDecisionsModelBinding2(body, ctx) {
|
|
11577
|
+
const agent = body;
|
|
11578
|
+
const refusal2 = checkDecisionsModelBinding2({
|
|
11579
|
+
model: readAgentSettingsModel2(agent.agent_settings),
|
|
11580
|
+
agent_role: agent.agent_role,
|
|
11581
|
+
response_format: agent.response_format,
|
|
11582
|
+
schema_json: agent.schema_json
|
|
11583
|
+
});
|
|
11584
|
+
if (refusal2) {
|
|
11585
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: ["agent_settings", "model"], message: refusal2.message });
|
|
11586
|
+
}
|
|
11587
|
+
}
|
|
9853
11588
|
function visibleLength2(s) {
|
|
9854
11589
|
return s.replace(INVISIBLE_NAME_CHARS2, "").length;
|
|
9855
11590
|
}
|
|
@@ -9969,7 +11704,7 @@ function extractToolParameters2(toolConfig) {
|
|
|
9969
11704
|
if (!cfg || typeof cfg !== "object" || Array.isArray(cfg)) return void 0;
|
|
9970
11705
|
return cfg.parameters;
|
|
9971
11706
|
}
|
|
9972
|
-
function
|
|
11707
|
+
function isRecord22(v) {
|
|
9973
11708
|
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
9974
11709
|
}
|
|
9975
11710
|
function isPrimitive2(v) {
|
|
@@ -9991,7 +11726,7 @@ function validateSchema2(schema, path35, errors, opts = {}) {
|
|
|
9991
11726
|
});
|
|
9992
11727
|
return;
|
|
9993
11728
|
}
|
|
9994
|
-
if (!
|
|
11729
|
+
if (!isRecord22(schema)) {
|
|
9995
11730
|
errors.push({
|
|
9996
11731
|
path: path35,
|
|
9997
11732
|
message: `expected object, got ${schema === null ? "null" : typeof schema}`
|
|
@@ -10053,7 +11788,7 @@ function validateSchema2(schema, path35, errors, opts = {}) {
|
|
|
10053
11788
|
}
|
|
10054
11789
|
}
|
|
10055
11790
|
if ("properties" in schema) {
|
|
10056
|
-
if (!
|
|
11791
|
+
if (!isRecord22(schema.properties)) {
|
|
10057
11792
|
errors.push({
|
|
10058
11793
|
path: `${path35}.properties`,
|
|
10059
11794
|
message: `properties must be an object, got ${Array.isArray(schema.properties) ? "array" : typeof schema.properties}`
|
|
@@ -10072,7 +11807,7 @@ function validateSchema2(schema, path35, errors, opts = {}) {
|
|
|
10072
11807
|
}
|
|
10073
11808
|
}
|
|
10074
11809
|
for (const key of SUBSCHEMA_OBJECT_KEYWORDS2) {
|
|
10075
|
-
if (key in schema &&
|
|
11810
|
+
if (key in schema && isRecord22(schema[key])) {
|
|
10076
11811
|
validateSchema2(schema[key], `${path35}.${key}`, errors, { depth: depth + 1 });
|
|
10077
11812
|
}
|
|
10078
11813
|
}
|
|
@@ -10084,7 +11819,7 @@ function validateSchema2(schema, path35, errors, opts = {}) {
|
|
|
10084
11819
|
}
|
|
10085
11820
|
for (const key of SUBSCHEMA_MAP_KEYWORDS2) {
|
|
10086
11821
|
const map = schema[key];
|
|
10087
|
-
if (
|
|
11822
|
+
if (isRecord22(map)) {
|
|
10088
11823
|
for (const [name, sub] of Object.entries(map)) {
|
|
10089
11824
|
validateSchema2(sub, `${path35}.${key}.${name}`, errors, { depth: depth + 1 });
|
|
10090
11825
|
}
|
|
@@ -10114,7 +11849,7 @@ function schemaTypeIncludes2(schema, wanted) {
|
|
|
10114
11849
|
}
|
|
10115
11850
|
function validateToolInputSchema2(schema) {
|
|
10116
11851
|
const errors = [];
|
|
10117
|
-
if (!
|
|
11852
|
+
if (!isRecord22(schema)) {
|
|
10118
11853
|
errors.push({
|
|
10119
11854
|
path: "",
|
|
10120
11855
|
message: `expected object at root, got ${schema === null ? "null" : typeof schema}`
|
|
@@ -10574,48 +12309,161 @@ function refineHubAsCodeResources2(config, ctx) {
|
|
|
10574
12309
|
});
|
|
10575
12310
|
}
|
|
10576
12311
|
}
|
|
10577
|
-
function refineHubAsCodeDelegation2(config, ctx) {
|
|
12312
|
+
function refineHubAsCodeDelegation2(config, ctx) {
|
|
12313
|
+
const agents = config?.agents;
|
|
12314
|
+
if (!Array.isArray(agents)) return;
|
|
12315
|
+
agents.forEach((agent, agentIndex) => {
|
|
12316
|
+
const delegation = agent?.tools?.delegation;
|
|
12317
|
+
if (!Array.isArray(delegation)) return;
|
|
12318
|
+
delegation.forEach((entry, delIndex) => {
|
|
12319
|
+
const del = entry;
|
|
12320
|
+
if (del.allow_consultant_chain !== void 0) {
|
|
12321
|
+
const chainPath = ["agents", agentIndex, "tools", "delegation", delIndex, "allow_consultant_chain"];
|
|
12322
|
+
if (typeof del.allow_consultant_chain !== "boolean") {
|
|
12323
|
+
ctx.addIssue({
|
|
12324
|
+
code: external_exports.ZodIssueCode.custom,
|
|
12325
|
+
path: chainPath,
|
|
12326
|
+
message: "allow_consultant_chain must be a boolean"
|
|
12327
|
+
});
|
|
12328
|
+
} else if (del.tool !== "start_consult_thread") {
|
|
12329
|
+
ctx.addIssue({
|
|
12330
|
+
code: external_exports.ZodIssueCode.custom,
|
|
12331
|
+
path: chainPath,
|
|
12332
|
+
message: `allow_consultant_chain applies only to \`tool: start_consult_thread\` (got "${String(del.tool)}")`
|
|
12333
|
+
});
|
|
12334
|
+
}
|
|
12335
|
+
}
|
|
12336
|
+
if (del.context_boundary === void 0) return;
|
|
12337
|
+
const path35 = ["agents", agentIndex, "tools", "delegation", delIndex, "context_boundary"];
|
|
12338
|
+
if (del.type !== "hub") {
|
|
12339
|
+
ctx.addIssue({
|
|
12340
|
+
code: external_exports.ZodIssueCode.custom,
|
|
12341
|
+
path: path35,
|
|
12342
|
+
message: `context_boundary applies only to \`type: hub\` delegations (got type "${String(del.type)}")`
|
|
12343
|
+
});
|
|
12344
|
+
return;
|
|
12345
|
+
}
|
|
12346
|
+
if (!CONTEXT_BOUNDARIES2.includes(del.context_boundary)) {
|
|
12347
|
+
ctx.addIssue({
|
|
12348
|
+
code: external_exports.ZodIssueCode.custom,
|
|
12349
|
+
path: path35,
|
|
12350
|
+
message: `context_boundary must be one of: ${CONTEXT_BOUNDARIES2.join(", ")}`
|
|
12351
|
+
});
|
|
12352
|
+
}
|
|
12353
|
+
});
|
|
12354
|
+
});
|
|
12355
|
+
}
|
|
12356
|
+
function refineHubAsCodeFlagConditions2(config, ctx) {
|
|
12357
|
+
const agents = config?.agents;
|
|
12358
|
+
if (!Array.isArray(agents)) return;
|
|
12359
|
+
const checkList = (list, basePath) => {
|
|
12360
|
+
if (!Array.isArray(list)) return;
|
|
12361
|
+
list.forEach((row, rowIndex) => {
|
|
12362
|
+
const operator = row?.operator;
|
|
12363
|
+
if (!FLAG_CONDITION_OPERATORS2.includes(operator)) {
|
|
12364
|
+
ctx.addIssue({
|
|
12365
|
+
code: external_exports.ZodIssueCode.custom,
|
|
12366
|
+
path: [...basePath, rowIndex, "operator"],
|
|
12367
|
+
message: `operator must be one of: ${FLAG_CONDITION_OPERATORS2.join(", ")}`
|
|
12368
|
+
});
|
|
12369
|
+
}
|
|
12370
|
+
});
|
|
12371
|
+
};
|
|
12372
|
+
agents.forEach((agent, agentIndex) => {
|
|
12373
|
+
const a = agent;
|
|
12374
|
+
checkList(a?.flag_conditions, ["agents", agentIndex, "flag_conditions"]);
|
|
12375
|
+
const monitorConfig = a?.monitor_config;
|
|
12376
|
+
if (monitorConfig && typeof monitorConfig === "object" && !Array.isArray(monitorConfig)) {
|
|
12377
|
+
const base = ["agents", agentIndex, "monitor_config"];
|
|
12378
|
+
checkList(
|
|
12379
|
+
monitorConfig.flag_conditions,
|
|
12380
|
+
[...base, "flag_conditions"]
|
|
12381
|
+
);
|
|
12382
|
+
const rules = monitorConfig.rules;
|
|
12383
|
+
if (Array.isArray(rules)) {
|
|
12384
|
+
rules.forEach((rule, ruleIndex) => {
|
|
12385
|
+
if (!rule || typeof rule !== "object" || Array.isArray(rule)) return;
|
|
12386
|
+
checkList(rule.when, [...base, "rules", ruleIndex, "when"]);
|
|
12387
|
+
});
|
|
12388
|
+
}
|
|
12389
|
+
}
|
|
12390
|
+
});
|
|
12391
|
+
}
|
|
12392
|
+
function refineHubAsCodeMonitorConfig2(config, ctx) {
|
|
12393
|
+
const agents = config?.agents;
|
|
12394
|
+
if (!Array.isArray(agents)) return;
|
|
12395
|
+
agents.forEach((agent, agentIndex) => {
|
|
12396
|
+
const monitorConfig = agent?.monitor_config;
|
|
12397
|
+
if (!monitorConfig || typeof monitorConfig !== "object" || Array.isArray(monitorConfig)) return;
|
|
12398
|
+
const basePath = ["agents", agentIndex, "monitor_config"];
|
|
12399
|
+
const checkKeyValues = (keys, schemas) => {
|
|
12400
|
+
for (const key of keys) {
|
|
12401
|
+
const value = monitorConfig[key];
|
|
12402
|
+
if (value === void 0) continue;
|
|
12403
|
+
const parsed = schemas[key].safeParse(value);
|
|
12404
|
+
if (!parsed.success) {
|
|
12405
|
+
ctx.addIssue({
|
|
12406
|
+
code: external_exports.ZodIssueCode.custom,
|
|
12407
|
+
path: [...basePath, key],
|
|
12408
|
+
message: parsed.error?.issues[0]?.message ?? `invalid ${key}`
|
|
12409
|
+
});
|
|
12410
|
+
}
|
|
12411
|
+
}
|
|
12412
|
+
};
|
|
12413
|
+
const trigger = monitorConfig.trigger;
|
|
12414
|
+
if (trigger !== void 0 && !MONITOR_TRIGGERS2.includes(trigger)) {
|
|
12415
|
+
ctx.addIssue({
|
|
12416
|
+
code: external_exports.ZodIssueCode.custom,
|
|
12417
|
+
path: [...basePath, "trigger"],
|
|
12418
|
+
message: `trigger must be one of: ${MONITOR_TRIGGERS2.join(", ")}`
|
|
12419
|
+
});
|
|
12420
|
+
return;
|
|
12421
|
+
}
|
|
12422
|
+
if (monitorConfigNeedsDelay2(monitorConfig)) {
|
|
12423
|
+
ctx.addIssue({
|
|
12424
|
+
code: external_exports.ZodIssueCode.custom,
|
|
12425
|
+
path: [...basePath, "delay_seconds"],
|
|
12426
|
+
message: MONITOR_IDLE_DELAY_REQUIRED_MESSAGE2
|
|
12427
|
+
});
|
|
12428
|
+
}
|
|
12429
|
+
for (const key of monitorInputShapingKeysOnIdle2(monitorConfig)) {
|
|
12430
|
+
ctx.addIssue({
|
|
12431
|
+
code: external_exports.ZodIssueCode.custom,
|
|
12432
|
+
path: [...basePath, key],
|
|
12433
|
+
message: MONITOR_INPUT_SHAPING_IDLE_MESSAGE2
|
|
12434
|
+
});
|
|
12435
|
+
}
|
|
12436
|
+
checkKeyValues(MONITOR_INPUT_SHAPING_KEYS2, MONITOR_INPUT_SHAPING_SCHEMAS2);
|
|
12437
|
+
checkKeyValues(MONITOR_RULE_KEYS2, MONITOR_RULE_SCHEMAS2);
|
|
12438
|
+
for (const issue of collectMonitorRuleIssues2(monitorConfig)) {
|
|
12439
|
+
ctx.addIssue({
|
|
12440
|
+
code: external_exports.ZodIssueCode.custom,
|
|
12441
|
+
path: [...basePath, ...issue.path],
|
|
12442
|
+
message: issue.message
|
|
12443
|
+
});
|
|
12444
|
+
}
|
|
12445
|
+
});
|
|
12446
|
+
}
|
|
12447
|
+
function refineHubAsCodeDecisionsModel2(config, ctx) {
|
|
10578
12448
|
const agents = config?.agents;
|
|
10579
12449
|
if (!Array.isArray(agents)) return;
|
|
10580
12450
|
agents.forEach((agent, agentIndex) => {
|
|
10581
|
-
const
|
|
10582
|
-
if (!
|
|
10583
|
-
|
|
10584
|
-
|
|
10585
|
-
|
|
10586
|
-
|
|
10587
|
-
|
|
10588
|
-
|
|
10589
|
-
|
|
10590
|
-
|
|
10591
|
-
|
|
10592
|
-
|
|
10593
|
-
|
|
10594
|
-
|
|
10595
|
-
|
|
10596
|
-
|
|
10597
|
-
message: `allow_consultant_chain applies only to \`tool: start_consult_thread\` (got "${String(del.tool)}")`
|
|
10598
|
-
});
|
|
10599
|
-
}
|
|
10600
|
-
}
|
|
10601
|
-
if (del.context_boundary === void 0) return;
|
|
10602
|
-
const path35 = ["agents", agentIndex, "tools", "delegation", delIndex, "context_boundary"];
|
|
10603
|
-
if (del.type !== "hub") {
|
|
10604
|
-
ctx.addIssue({
|
|
10605
|
-
code: external_exports.ZodIssueCode.custom,
|
|
10606
|
-
path: path35,
|
|
10607
|
-
message: `context_boundary applies only to \`type: hub\` delegations (got type "${String(del.type)}")`
|
|
10608
|
-
});
|
|
10609
|
-
return;
|
|
10610
|
-
}
|
|
10611
|
-
if (!CONTEXT_BOUNDARIES2.includes(del.context_boundary)) {
|
|
10612
|
-
ctx.addIssue({
|
|
10613
|
-
code: external_exports.ZodIssueCode.custom,
|
|
10614
|
-
path: path35,
|
|
10615
|
-
message: `context_boundary must be one of: ${CONTEXT_BOUNDARIES2.join(", ")}`
|
|
10616
|
-
});
|
|
10617
|
-
}
|
|
10618
|
-
});
|
|
12451
|
+
const a = agent;
|
|
12452
|
+
if (!a) return;
|
|
12453
|
+
const responseFormat = a.response_format;
|
|
12454
|
+
const refusal2 = checkDecisionsModelBinding2({
|
|
12455
|
+
model: readAgentSettingsModel2(a.settings),
|
|
12456
|
+
agent_role: a.role,
|
|
12457
|
+
response_format: responseFormat ? "json_schema" : "text",
|
|
12458
|
+
schema_json: responseFormat?.schema_json ?? null
|
|
12459
|
+
});
|
|
12460
|
+
if (refusal2) {
|
|
12461
|
+
ctx.addIssue({
|
|
12462
|
+
code: external_exports.ZodIssueCode.custom,
|
|
12463
|
+
path: ["agents", agentIndex, "settings", "model"],
|
|
12464
|
+
message: refusal2.message
|
|
12465
|
+
});
|
|
12466
|
+
}
|
|
10619
12467
|
});
|
|
10620
12468
|
}
|
|
10621
12469
|
function identifyTokenType(token) {
|
|
@@ -10657,7 +12505,7 @@ function findStepBoundaries(transcript) {
|
|
|
10657
12505
|
}
|
|
10658
12506
|
return out;
|
|
10659
12507
|
}
|
|
10660
|
-
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, previousConversationsCountField2, summarizationThresholdField2, monitorConfigField2, 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, 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, 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, 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;
|
|
12508
|
+
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, 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, 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, monitorActionSchema2, monitorRuleSchema2, MONITOR_RULE_KEYS2, MONITOR_RULE_SCHEMAS2, MONITOR_RULE_TRIGGERS2, MONITOR_RULE_TRIGGER_MESSAGE2, MONITOR_USER_MESSAGE_ACTION_KINDS2, MONITOR_ASSISTANT_REPLY_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, 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, 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, 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;
|
|
10661
12509
|
var init_dist = __esm({
|
|
10662
12510
|
"../../packages/core/dist/index.js"() {
|
|
10663
12511
|
"use strict";
|
|
@@ -10713,6 +12561,7 @@ var init_dist = __esm({
|
|
|
10713
12561
|
init_zod();
|
|
10714
12562
|
init_zod();
|
|
10715
12563
|
init_zod();
|
|
12564
|
+
init_zod();
|
|
10716
12565
|
UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
|
10717
12566
|
HEX_RE = /^[0-9a-f]{16,}$/;
|
|
10718
12567
|
WORKOS_ID_RE = /^(?:user|org)_[0-9A-HJKMNP-TV-Z]{26}$/;
|
|
@@ -10862,13 +12711,21 @@ var init_dist = __esm({
|
|
|
10862
12711
|
};
|
|
10863
12712
|
MEDIA_PROVIDER_HTTP_BRAND = /* @__PURE__ */ Symbol.for("wayai.MediaProviderHttpError");
|
|
10864
12713
|
MediaProviderHttpError = class extends Error {
|
|
10865
|
-
constructor(provider, status) {
|
|
12714
|
+
constructor(provider, status, options = {}) {
|
|
10866
12715
|
super(`${provider} API error (${status})`);
|
|
10867
12716
|
this.provider = provider;
|
|
10868
12717
|
this.status = status;
|
|
10869
12718
|
this.name = "MediaProviderHttpError";
|
|
12719
|
+
this.credentialRejected = options.credentialRejected ?? false;
|
|
10870
12720
|
}
|
|
10871
12721
|
[MEDIA_PROVIDER_HTTP_BRAND] = true;
|
|
12722
|
+
/**
|
|
12723
|
+
* The provider said the credential itself was rejected, under a status that does not say so
|
|
12724
|
+
* (Google answers an invalid or expired key with 400 `API_KEY_INVALID`, not 401). Read off
|
|
12725
|
+
* the body at the throw site, which carries only this flag on. Alerting keys on it so the
|
|
12726
|
+
* admin is told to re-enter the key, not that the key is fine.
|
|
12727
|
+
*/
|
|
12728
|
+
credentialRejected;
|
|
10872
12729
|
};
|
|
10873
12730
|
REKOR_ACTOR_TYPE_HEADER2 = "X-Rekor-Actor-Type";
|
|
10874
12731
|
REKOR_ACTOR_ID_HEADER2 = "X-Rekor-Actor-Id";
|
|
@@ -11032,7 +12889,7 @@ var init_dist = __esm({
|
|
|
11032
12889
|
"/api/users/me/deletion": { tier: "STRICT", userLimit: 3, userWindow: 3600, failClosed: true },
|
|
11033
12890
|
"/api/users/me/deletion/preflight": { tier: "STANDARD", userLimit: 30, failClosed: true },
|
|
11034
12891
|
"/api/users/deletion/undo": { tier: "STRICT", failClosed: true },
|
|
11035
|
-
// Production-base destruction
|
|
12892
|
+
// Production-base destruction.
|
|
11036
12893
|
//
|
|
11037
12894
|
// Keyed off the CONTRACT constants, not literals: `BASE_DESTRUCTION_CONFIRM_PATH`'s own
|
|
11038
12895
|
// docstring promises that the mount, the `AUTH_BYPASS_PATHS` entry, the rate-limit key and
|
|
@@ -11280,18 +13137,993 @@ var init_dist = __esm({
|
|
|
11280
13137
|
SUMMARIZATION_THRESHOLD_MIN2 = 1e3;
|
|
11281
13138
|
SUMMARIZATION_THRESHOLD_MAX2 = 1e6;
|
|
11282
13139
|
PREVIOUS_CONVERSATIONS_MAX2 = 20;
|
|
13140
|
+
FLAG_CONDITION_OPERATORS2 = ["=", "!=", ">=", "<=", ">", "<"];
|
|
13141
|
+
DECISION_SCORE_MIN_LEVELS2 = 2;
|
|
13142
|
+
DECISION_SCORE_MAX_LEVELS2 = 10;
|
|
13143
|
+
DECISIONS_MODEL_PREFIXES2 = ["typesafe/jev-", "jev-"];
|
|
13144
|
+
DECISION_CAPABLE_AGENT_ROLES2 = [
|
|
13145
|
+
"monitor",
|
|
13146
|
+
"conversation_evaluator",
|
|
13147
|
+
"message_evaluator"
|
|
13148
|
+
];
|
|
13149
|
+
NATIVE_TOOL_SCHEMAS2 = {
|
|
13150
|
+
"close_conversation": {
|
|
13151
|
+
"tool_config": {
|
|
13152
|
+
"name": "close_conversation",
|
|
13153
|
+
"description": "Closes the current conversation and marks it as resolved",
|
|
13154
|
+
// Non-strict, mirroring the `update_kanban_status` sibling below: under strict
|
|
13155
|
+
// mode there are no optional fields, so `outcome` outside `required` makes the
|
|
13156
|
+
// provider reject the definition and `outcome` inside `required` forces the
|
|
13157
|
+
// model to emit it on every call. Requiredness is enforced SERVER-side instead
|
|
13158
|
+
// (ops `outcomeRequired`) — and it must stay out of `required` here, or
|
|
13159
|
+
// validateAndSanitizeToolParams would refuse the "retry without an outcome"
|
|
13160
|
+
// recovery path a re-close depends on.
|
|
13161
|
+
"strict": false,
|
|
13162
|
+
"parameters": {
|
|
13163
|
+
"type": "object",
|
|
13164
|
+
"properties": {
|
|
13165
|
+
"outcome": {
|
|
13166
|
+
"type": "string",
|
|
13167
|
+
"enum": "[KANBAN_OUTCOME_VALUES]",
|
|
13168
|
+
"description": "Required only when the hub's terminal (conversation-ending) status declares outcomes: the closing outcome. Available outcomes: [KANBAN_OUTCOME_NAMES]"
|
|
13169
|
+
}
|
|
13170
|
+
},
|
|
13171
|
+
"required": [],
|
|
13172
|
+
"additionalProperties": false
|
|
13173
|
+
}
|
|
13174
|
+
},
|
|
13175
|
+
"tool_instructions": "Use when the user's issue has been fully resolved."
|
|
13176
|
+
},
|
|
13177
|
+
"transfer_to_team": {
|
|
13178
|
+
"tool_config": {
|
|
13179
|
+
"name": "transfer_to_team",
|
|
13180
|
+
"description": "Hand off conversation to a human support team",
|
|
13181
|
+
"strict": true,
|
|
13182
|
+
"parameters": {
|
|
13183
|
+
"type": "object",
|
|
13184
|
+
"properties": {
|
|
13185
|
+
"team_name": {
|
|
13186
|
+
"type": "string",
|
|
13187
|
+
"description": "Name of the team to transfer to"
|
|
13188
|
+
}
|
|
13189
|
+
},
|
|
13190
|
+
"required": [
|
|
13191
|
+
"team_name"
|
|
13192
|
+
],
|
|
13193
|
+
"additionalProperties": false
|
|
13194
|
+
}
|
|
13195
|
+
},
|
|
13196
|
+
"tool_instructions": "Use when the user needs assistance that requires human intervention. The team will receive the full conversation history."
|
|
13197
|
+
},
|
|
13198
|
+
"delegate_to_hub": {
|
|
13199
|
+
"tool_config": {
|
|
13200
|
+
"name": "delegate_to_hub",
|
|
13201
|
+
"description": "Delegate a request to another hub. The target hub handles it as a task conversation and returns the result asynchronously.",
|
|
13202
|
+
"strict": true,
|
|
13203
|
+
"parameters": {
|
|
13204
|
+
"type": "object",
|
|
13205
|
+
"properties": {
|
|
13206
|
+
"request": {
|
|
13207
|
+
"type": "string",
|
|
13208
|
+
"description": "The request to delegate to the target hub, phrased as a self-contained task."
|
|
13209
|
+
}
|
|
13210
|
+
},
|
|
13211
|
+
"required": [
|
|
13212
|
+
"request"
|
|
13213
|
+
],
|
|
13214
|
+
"additionalProperties": false
|
|
13215
|
+
}
|
|
13216
|
+
},
|
|
13217
|
+
"tool_instructions": "Use to hand a self-contained request to a configured partner hub. The target hub is set by an admin on the tool; you do not choose it. The result comes back asynchronously \u2014 do not wait for it in this turn."
|
|
13218
|
+
},
|
|
13219
|
+
"start_consult_thread": {
|
|
13220
|
+
"tool_config": {
|
|
13221
|
+
"name": "start_consult_thread",
|
|
13222
|
+
"description": "Ask the consultant configured on this tool a question, in a consult thread the support team can see. The answer may come back in this turn or later.",
|
|
13223
|
+
"strict": true,
|
|
13224
|
+
"parameters": {
|
|
13225
|
+
"type": "object",
|
|
13226
|
+
"properties": {
|
|
13227
|
+
"question": {
|
|
13228
|
+
"type": "string",
|
|
13229
|
+
"description": "What you need from the consultant, phrased so it can be answered without further back-and-forth."
|
|
13230
|
+
},
|
|
13231
|
+
"title": {
|
|
13232
|
+
"type": "string",
|
|
13233
|
+
"description": "A short label for the consult thread (a few words), so the support team can tell parallel consults apart."
|
|
13234
|
+
}
|
|
13235
|
+
},
|
|
13236
|
+
"required": [
|
|
13237
|
+
"question",
|
|
13238
|
+
"title"
|
|
13239
|
+
],
|
|
13240
|
+
"additionalProperties": false
|
|
13241
|
+
}
|
|
13242
|
+
},
|
|
13243
|
+
"tool_instructions": "Use when answering needs knowledge you do not have and a consultant is configured for it. The consultant is set by an admin; you do not choose it. If the result says the answer will follow, END YOUR TURN \u2014 tell the customer you are checking and will come back to them. You will be brought back automatically when the answer arrives; do not poll or call this tool again for the same question."
|
|
13244
|
+
},
|
|
13245
|
+
"update_kanban_status": {
|
|
13246
|
+
"tool_config": {
|
|
13247
|
+
"name": "update_kanban_status",
|
|
13248
|
+
"description": "Updates the kanban status of the current conversation to track its progress through workflow stages",
|
|
13249
|
+
"strict": false,
|
|
13250
|
+
"parameters": {
|
|
13251
|
+
"type": "object",
|
|
13252
|
+
"properties": {
|
|
13253
|
+
"new_kanban_status": {
|
|
13254
|
+
"type": "string",
|
|
13255
|
+
"enum": "[KANBAN_STATUS_VALUES]",
|
|
13256
|
+
"description": "The new kanban status for the conversation. Available statuses: [KANBAN_STATUS_NAMES]"
|
|
13257
|
+
},
|
|
13258
|
+
"outcome": {
|
|
13259
|
+
"type": "string",
|
|
13260
|
+
"enum": "[KANBAN_OUTCOME_VALUES]",
|
|
13261
|
+
"description": "Required only when moving to the terminal (conversation-ending) status: the closing outcome. Available outcomes: [KANBAN_OUTCOME_NAMES]"
|
|
13262
|
+
},
|
|
13263
|
+
"scheduled_event_date": {
|
|
13264
|
+
"type": "string",
|
|
13265
|
+
"description": 'Scheduled event date in RFC3339 format with timezone (e.g., "2024-01-01T00:00:00-03:00")'
|
|
13266
|
+
},
|
|
13267
|
+
"event_description": {
|
|
13268
|
+
"type": "string",
|
|
13269
|
+
"description": "Description of the scheduled event"
|
|
13270
|
+
},
|
|
13271
|
+
"event_sid": {
|
|
13272
|
+
"type": "string",
|
|
13273
|
+
"description": "External event ID for integration purposes"
|
|
13274
|
+
}
|
|
13275
|
+
},
|
|
13276
|
+
"required": [
|
|
13277
|
+
"new_kanban_status"
|
|
13278
|
+
],
|
|
13279
|
+
"additionalProperties": false
|
|
13280
|
+
}
|
|
13281
|
+
},
|
|
13282
|
+
"tool_instructions": "Use to update the kanban status of a conversation to reflect its current stage in the workflow."
|
|
13283
|
+
},
|
|
13284
|
+
"schedule_followup": {
|
|
13285
|
+
"tool_config": {
|
|
13286
|
+
"name": "schedule_followup",
|
|
13287
|
+
"description": "Schedules a custom manual followup for the current conversation at an exact future time. The system automatically determines the receiver based on conversation status and hub AI mode.",
|
|
13288
|
+
"strict": true,
|
|
13289
|
+
"parameters": {
|
|
13290
|
+
"type": "object",
|
|
13291
|
+
"properties": {
|
|
13292
|
+
"scheduled_time": {
|
|
13293
|
+
"type": "string",
|
|
13294
|
+
"description": 'Exact time to execute the followup in ISO 8601 format with timezone (e.g., "2024-01-01T14:30:00-03:00"). Must be in the future.'
|
|
13295
|
+
},
|
|
13296
|
+
"message": {
|
|
13297
|
+
"type": "string",
|
|
13298
|
+
"description": 'The followup message to send to the customer. Can include AI instructions in brackets like: "Message text [AI Context: instructions for AI]"'
|
|
13299
|
+
}
|
|
13300
|
+
},
|
|
13301
|
+
"required": [
|
|
13302
|
+
"scheduled_time",
|
|
13303
|
+
"message"
|
|
13304
|
+
],
|
|
13305
|
+
"additionalProperties": false
|
|
13306
|
+
}
|
|
13307
|
+
},
|
|
13308
|
+
"tool_instructions": "Use to schedule a custom followup message at an exact future time. The caller is responsible for choosing appropriate timing (business hours, etc.). This is separate from automatic kanban-based followups."
|
|
13309
|
+
},
|
|
13310
|
+
"transfer_to_agent": {
|
|
13311
|
+
"tool_config": {
|
|
13312
|
+
"name": "transfer_to_agent",
|
|
13313
|
+
"description": "Hand off conversation to another AI agent",
|
|
13314
|
+
"strict": true,
|
|
13315
|
+
"parameters": {
|
|
13316
|
+
"type": "object",
|
|
13317
|
+
"properties": {
|
|
13318
|
+
"agent_name": {
|
|
13319
|
+
"type": "string",
|
|
13320
|
+
"description": "Name of the AI agent to transfer to"
|
|
13321
|
+
}
|
|
13322
|
+
},
|
|
13323
|
+
"required": [
|
|
13324
|
+
"agent_name"
|
|
13325
|
+
],
|
|
13326
|
+
"additionalProperties": false
|
|
13327
|
+
}
|
|
13328
|
+
},
|
|
13329
|
+
"tool_instructions": "Use when you need to hand the conversation to another agent on the same track \u2014 a specialist for a specific domain, or back to the entry pilot/copilot acting as a router for a request outside your domain."
|
|
13330
|
+
},
|
|
13331
|
+
"consult_agent": {
|
|
13332
|
+
"tool_config": {
|
|
13333
|
+
"name": "consult_agent",
|
|
13334
|
+
"description": "Consult an advisor agent for specialized knowledge without transferring the conversation",
|
|
13335
|
+
"strict": true,
|
|
13336
|
+
"parameters": {
|
|
13337
|
+
"type": "object",
|
|
13338
|
+
"properties": {
|
|
13339
|
+
"agent_name": {
|
|
13340
|
+
"type": "string",
|
|
13341
|
+
"description": "Name of the advisor agent to consult for advice"
|
|
13342
|
+
},
|
|
13343
|
+
"consult_question": {
|
|
13344
|
+
"type": "string",
|
|
13345
|
+
"description": "The specific question to ask the advisor agent"
|
|
13346
|
+
}
|
|
13347
|
+
},
|
|
13348
|
+
"required": [
|
|
13349
|
+
"agent_name",
|
|
13350
|
+
"consult_question"
|
|
13351
|
+
],
|
|
13352
|
+
"additionalProperties": false
|
|
13353
|
+
}
|
|
13354
|
+
},
|
|
13355
|
+
"tool_instructions": "Use when you need expert advice from an advisor agent but want to maintain conversation ownership. The consulted advisor will provide advice that you can use to help the user."
|
|
13356
|
+
},
|
|
13357
|
+
"read_file": {
|
|
13358
|
+
"tool_config": {
|
|
13359
|
+
"name": "read_file",
|
|
13360
|
+
"description": "Retrieve a file by path (preferred) or by ID. The file is injected into the conversation context for AI processing.",
|
|
13361
|
+
"strict": false,
|
|
13362
|
+
"parameters": {
|
|
13363
|
+
"type": "object",
|
|
13364
|
+
"properties": {
|
|
13365
|
+
"path": {
|
|
13366
|
+
"type": "string",
|
|
13367
|
+
"description": 'Path to the file. Knowledge and skill files live under "resources/", exactly as listed in your resource structure or in a file listing \u2014 e.g. "resources/product-docs/references/menu.md", where the segment after "resources/" names the resource. Files attached to this conversation live under "conversation/" and are announced in the transcript by that path \u2014 e.g. "conversation/report.pdf". A shorter form also works for those two and is matched across everything you can read, preferring an exact path over one that merely ends with what you wrote ("references/menu.md", or just "menu.md"); dropping a middle segment does not resolve, and a bare name carried by both a resource and this conversation is reported as ambiguous so you can retry with the full path. Files from an EARLIER conversation with the same user live under "conversations/<conversation_id>/" \u2014 e.g. "conversations/1b9d6bcd-bbfd-4b2d-9b5d-ab8dfbbd4bed/receipt.pdf", exactly as the transcript of that conversation announces them (get_conversation). That form takes no shortening: write the mount, the conversation id and the file name in full. Prefer this over file_id: paths are stable, while IDs are regenerated whenever a hub is published.'
|
|
13368
|
+
},
|
|
13369
|
+
"file_id": {
|
|
13370
|
+
"type": "string",
|
|
13371
|
+
"description": "The file ID to retrieve, from a conversation message or a file listing. Still supported, but prefer path for resource files."
|
|
13372
|
+
},
|
|
13373
|
+
"resource_id": {
|
|
13374
|
+
"type": "string",
|
|
13375
|
+
"description": "Optional. Restricts a path to one resource \u2014 use it when the same file name exists in more than one resource and the tool reports the reference as ambiguous. Must be a resource linked to this agent."
|
|
13376
|
+
}
|
|
13377
|
+
},
|
|
13378
|
+
"required": [],
|
|
13379
|
+
"additionalProperties": false
|
|
13380
|
+
}
|
|
13381
|
+
},
|
|
13382
|
+
"tool_instructions": "Use this tool to read a file for AI analysis. Provide either path (preferred \u2014 the exact paths appear in your resource structure and in list_files output) or file_id. The file will be injected into the conversation context."
|
|
13383
|
+
},
|
|
13384
|
+
"download_file": {
|
|
13385
|
+
"tool_config": {
|
|
13386
|
+
"name": "download_file",
|
|
13387
|
+
"description": "Mount a resource file into the code execution sandbox so you can edit it. Path is provider-specific: Anthropic mounts at /tmp/<filename>, OpenAI mounts at /mnt/data/<filename> \u2014 use the `sandbox_path` returned in the result. After mounting, use the provider's code-execution tool (Anthropic code_execution view/str_replace/create, or OpenAI code_interpreter Python) to read or modify the file. When finished, call upload_file to commit changes back to the resource library. Bytes never enter conversation context.",
|
|
13388
|
+
"strict": true,
|
|
13389
|
+
"parameters": {
|
|
13390
|
+
"type": "object",
|
|
13391
|
+
"properties": {
|
|
13392
|
+
"file_id": {
|
|
13393
|
+
"type": "string",
|
|
13394
|
+
"description": "The resource file_id to mount (from a file listing or read_file \u2014 a listing row carries file_id alongside its path). Must be a text file; binary files are rejected."
|
|
13395
|
+
}
|
|
13396
|
+
},
|
|
13397
|
+
"required": [
|
|
13398
|
+
"file_id"
|
|
13399
|
+
],
|
|
13400
|
+
"additionalProperties": false
|
|
13401
|
+
}
|
|
13402
|
+
},
|
|
13403
|
+
"tool_instructions": "Use to begin editing a resource file. Returns { sandbox_path, filename, sandbox_file_id }. After this, use your provider's code-execution tool to view and modify the file inside the sandbox, then call upload_file with the sandbox_file_id of the modified file to persist changes."
|
|
13404
|
+
},
|
|
13405
|
+
"upload_file": {
|
|
13406
|
+
"tool_config": {
|
|
13407
|
+
"name": "upload_file",
|
|
13408
|
+
"description": "Persist a sandbox file to the resource library. Two modes: (1) UPDATE \u2014 pass file_id of an existing resource file to overwrite it (after download_file + code-execution edits). (2) CREATE \u2014 pass resource_id + filename instead of file_id to add a new file to that resource (after creating the file in the sandbox with code-execution). Requires write_enabled on the agent_resource binding for the target resource. sandbox_file_id is always required.",
|
|
13409
|
+
"strict": false,
|
|
13410
|
+
"parameters": {
|
|
13411
|
+
"type": "object",
|
|
13412
|
+
"properties": {
|
|
13413
|
+
"file_id": {
|
|
13414
|
+
"type": "string",
|
|
13415
|
+
"description": "UPDATE mode only: the existing resource file_id to overwrite. Omit when creating a new file."
|
|
13416
|
+
},
|
|
13417
|
+
"resource_id": {
|
|
13418
|
+
"type": "string",
|
|
13419
|
+
"description": "CREATE mode only: the resource the new file belongs to. Required when file_id is omitted; ignored when file_id is provided."
|
|
13420
|
+
},
|
|
13421
|
+
"filename": {
|
|
13422
|
+
"type": "string",
|
|
13423
|
+
"description": "CREATE mode only: the filename for the new file (e.g. 'pricing_v2.md'). Required when file_id is omitted. MIME type is inferred from the extension; only text files are supported."
|
|
13424
|
+
},
|
|
13425
|
+
"folder_id": {
|
|
13426
|
+
"type": "string",
|
|
13427
|
+
"description": "CREATE mode only: optional folder to place the file in. Omit for resource root."
|
|
13428
|
+
},
|
|
13429
|
+
"sandbox_file_id": {
|
|
13430
|
+
"type": "string",
|
|
13431
|
+
"description": "The provider-specific file_id of the file inside the sandbox. Anthropic: take from bash_code_execution_tool_result content[].file_id. OpenAI: take from the container_file_citation annotations on code_interpreter_call output. Either one identifies the file as it currently exists in the sandbox."
|
|
13432
|
+
}
|
|
13433
|
+
},
|
|
13434
|
+
"required": [
|
|
13435
|
+
"sandbox_file_id"
|
|
13436
|
+
],
|
|
13437
|
+
"additionalProperties": false
|
|
13438
|
+
}
|
|
13439
|
+
},
|
|
13440
|
+
"tool_instructions": "Use to commit either an edit (file_id + sandbox_file_id) or a new file (resource_id + filename + sandbox_file_id). Returns { saved, file_id, file_hash, bytes } on success \u2014 the file_id you can reference later. Errors clearly when write access is denied or when neither identifier set is provided."
|
|
13441
|
+
},
|
|
13442
|
+
"send_files": {
|
|
13443
|
+
"tool_config": {
|
|
13444
|
+
"name": "send_files",
|
|
13445
|
+
"description": "Send files to the end user through their conversation channel (App, WhatsApp, email, etc.)",
|
|
13446
|
+
"strict": false,
|
|
13447
|
+
"parameters": {
|
|
13448
|
+
"type": "object",
|
|
13449
|
+
"properties": {
|
|
13450
|
+
"file_ids": {
|
|
13451
|
+
"type": "array",
|
|
13452
|
+
"items": {
|
|
13453
|
+
"type": "string"
|
|
13454
|
+
},
|
|
13455
|
+
"description": 'Files to send to the user, each named by path (preferred) or by ID. Paths are the addresses announced in the transcript and in your resource structure \u2014 "conversation/report.pdf" for a file attached to this conversation, "conversations/<conversation_id>/receipt.pdf" for one attached to an earlier conversation with the same user, "resources/product-docs/price-list.pdf" for a knowledge or skill file. IDs remain accepted, but they are regenerated whenever a hub is published, so a path is the stable address.'
|
|
13456
|
+
},
|
|
13457
|
+
"folder_ids": {
|
|
13458
|
+
"type": "array",
|
|
13459
|
+
"items": {
|
|
13460
|
+
"type": "string"
|
|
13461
|
+
},
|
|
13462
|
+
"description": "Array of resource folder IDs to send all files from. Alternative to file_ids."
|
|
13463
|
+
},
|
|
13464
|
+
"message_text": {
|
|
13465
|
+
"type": "string",
|
|
13466
|
+
"description": "Message text to accompany the files. For WhatsApp, this becomes the caption on the last file. For email, this becomes the email body."
|
|
13467
|
+
}
|
|
13468
|
+
},
|
|
13469
|
+
"required": [],
|
|
13470
|
+
"additionalProperties": false
|
|
13471
|
+
}
|
|
13472
|
+
},
|
|
13473
|
+
"tool_instructions": "Use this tool to send files to users. WhatsApp sends files individually with optional caption on last file. Email sends all files as attachments in a single email."
|
|
13474
|
+
},
|
|
13475
|
+
"list_files": {
|
|
13476
|
+
"tool_config": {
|
|
13477
|
+
"name": "list_files",
|
|
13478
|
+
"description": "Browse the files you can reach, by path. Call it with no path to see the mounts, then pass a mount or a folder path to list what is inside it. Every row carries the exact path read_file and send_files accept.",
|
|
13479
|
+
"strict": false,
|
|
13480
|
+
"parameters": {
|
|
13481
|
+
"type": "object",
|
|
13482
|
+
"properties": {
|
|
13483
|
+
"path": {
|
|
13484
|
+
"type": "string",
|
|
13485
|
+
"description": 'What to list. Omit it (or pass "") for the mounts you can browse \u2014 the available mounts are listed here at runtime. "conversation" lists the files attached to this conversation. "resources" lists every resource mount. "resources/<resource-slug>" lists the top level of a knowledge resource or skill, and "resources/<resource-slug>/<folder>/<subfolder>" lists that folder. Folder rows come back with their own path, so you drill down by passing back the path of the row you want.'
|
|
13486
|
+
},
|
|
13487
|
+
"query": {
|
|
13488
|
+
"type": "string",
|
|
13489
|
+
"description": "Search text. Matched against a file's title and its file name. Under a resource path this searches the WHOLE subtree below it, not just the level named, and every result is returned as a full path."
|
|
13490
|
+
},
|
|
13491
|
+
"tags": {
|
|
13492
|
+
"type": "array",
|
|
13493
|
+
"items": {
|
|
13494
|
+
"type": "string"
|
|
13495
|
+
},
|
|
13496
|
+
"description": "Return files carrying ANY of these tags. Applies to resource files only \u2014 conversation attachments carry no tags. Searches the whole subtree, like query."
|
|
13497
|
+
},
|
|
13498
|
+
"metadata_filter": {
|
|
13499
|
+
"type": "object",
|
|
13500
|
+
"description": 'Filter resource files by their metadata using MongoDB-style operators. Supported: $eq (equal), $ne (not equal), $gt/$gte/$lt/$lte (comparisons), $in/$nin (in/not in array), $contains (substring for text, membership for a list), $and/$or/$not (logical). Nested paths like "location.city" are supported, and a bare value means equality. Examples: {"status": "active"}, {"priority": {"$gte": 5}}, {"location.city": "Miami"}, {"$and": [{"status": "active"}, {"priority": {"$gt": 3}}]}, {"$not": {"status": "archived"}}. A comparison between different types simply does not match. Schema from resource.file_metadata_schema. Searches the whole subtree, like query.'
|
|
13501
|
+
},
|
|
13502
|
+
"limit": {
|
|
13503
|
+
"type": "integer",
|
|
13504
|
+
"description": "Maximum number of rows to return (default: 50, max: 100). The response reports the total the page was drawn from."
|
|
13505
|
+
},
|
|
13506
|
+
"offset": {
|
|
13507
|
+
"type": "integer",
|
|
13508
|
+
"description": "Number of rows to skip for pagination (default: 0)"
|
|
13509
|
+
}
|
|
13510
|
+
},
|
|
13511
|
+
"required": [],
|
|
13512
|
+
"additionalProperties": false
|
|
13513
|
+
}
|
|
13514
|
+
},
|
|
13515
|
+
"tool_instructions": 'Use to find out which files exist before reading one. Call it with no path first: that returns the mounts \u2014 "conversation" for what the user attached here, and one "resources/<slug>" per knowledge resource or skill linked to you. Then pass a mount or folder path back to list its contents. Every row carries a `path`; pass that path to read_file to open the file, or to send_files to deliver it. Pass query, tags or metadata_filter to search a whole resource at once instead of walking it folder by folder. Files from EARLIER conversations are not listed here \u2014 the transcript of each past conversation announces its own files by path (get_conversation).'
|
|
13516
|
+
},
|
|
13517
|
+
"list_resource_folders": {
|
|
13518
|
+
"tool_config": {
|
|
13519
|
+
"name": "list_resource_folders",
|
|
13520
|
+
"description": "(deprecated \u2014 use list_files) List all folders in resources that this agent has access to. Returns all folders with parent_folder_id for hierarchy reconstruction.",
|
|
13521
|
+
"strict": false,
|
|
13522
|
+
"parameters": {
|
|
13523
|
+
"type": "object",
|
|
13524
|
+
"properties": {
|
|
13525
|
+
"resource_id": {
|
|
13526
|
+
"type": "string",
|
|
13527
|
+
"description": "Resource ID to query folders from. Must be one of the knowledge resources linked to this agent (the available ids are listed here at runtime). Required for access control and performance."
|
|
13528
|
+
},
|
|
13529
|
+
"search_query": {
|
|
13530
|
+
"type": "string",
|
|
13531
|
+
"description": "Search folders by name"
|
|
13532
|
+
},
|
|
13533
|
+
"metadata_filter": {
|
|
13534
|
+
"type": "object",
|
|
13535
|
+
"description": 'Filter by metadata using MongoDB-style operators. Supported: $eq (equal), $ne (not equal), $gt/$gte/$lt/$lte (comparisons), $in/$nin (in/not in array), $contains (contains value), $and/$or/$not (logical). Supports nested paths like "location.city". Returns clear errors for type mismatches. Examples: {"status": "active"} for simple equality, {"priority": {"$gte": 5}} for comparison, {"location.city": "Miami"} for nested path, {"$and": [{"status": "active"}, {"priority": {"$gt": 3}}]} for complex logic, {"$not": {"status": "archived"}} for negation. Schema from resource.folder_metadata_schema.'
|
|
13536
|
+
}
|
|
13537
|
+
},
|
|
13538
|
+
"required": [
|
|
13539
|
+
"resource_id"
|
|
13540
|
+
],
|
|
13541
|
+
"additionalProperties": false
|
|
13542
|
+
}
|
|
13543
|
+
},
|
|
13544
|
+
"tool_instructions": "Deprecated: prefer list_files, which walks the same folders by path and needs no resource_id. Still works \u2014 lists all folders in a resource, filtered by search_query or metadata, returning folder info with parent_folder_id, file counts, and subfolder counts."
|
|
13545
|
+
},
|
|
13546
|
+
"list_resource_files": {
|
|
13547
|
+
"tool_config": {
|
|
13548
|
+
"name": "list_resource_files",
|
|
13549
|
+
"description": "(deprecated \u2014 use list_files) List files in resources that this agent has access to. Each file is returned with its path \u2014 the address read_file accepts \u2014 plus metadata.",
|
|
13550
|
+
"strict": false,
|
|
13551
|
+
"parameters": {
|
|
13552
|
+
"type": "object",
|
|
13553
|
+
"properties": {
|
|
13554
|
+
"resource_id": {
|
|
13555
|
+
"type": "string",
|
|
13556
|
+
"description": "Resource ID to query files from. Must be one of the knowledge resources linked to this agent (the available ids are listed here at runtime). Required for access control and performance."
|
|
13557
|
+
},
|
|
13558
|
+
"folder_id": {
|
|
13559
|
+
"type": "string",
|
|
13560
|
+
"description": "Filter by folder ID. Omit to return ALL files. Use 00000000-0000-0000-0000-000000000000 for root-level files only."
|
|
13561
|
+
},
|
|
13562
|
+
"search_query": {
|
|
13563
|
+
"type": "string",
|
|
13564
|
+
"description": "Search files by title or file name"
|
|
13565
|
+
},
|
|
13566
|
+
"tags": {
|
|
13567
|
+
"type": "array",
|
|
13568
|
+
"items": {
|
|
13569
|
+
"type": "string"
|
|
13570
|
+
},
|
|
13571
|
+
"description": "Filter by tags (matches files with any of the specified tags)"
|
|
13572
|
+
},
|
|
13573
|
+
"metadata_filter": {
|
|
13574
|
+
"type": "object",
|
|
13575
|
+
"description": 'Filter by metadata using MongoDB-style operators. Supported: $eq (equal), $ne (not equal), $gt/$gte/$lt/$lte (comparisons), $in/$nin (in/not in array), $contains (contains value), $and/$or/$not (logical). Supports nested paths like "location.city". Returns clear errors for type mismatches. Examples: {"status": "active"} for simple equality, {"priority": {"$gte": 5}} for comparison, {"location.city": "Miami"} for nested path, {"$and": [{"status": "active"}, {"priority": {"$gt": 3}}]} for complex logic, {"$not": {"status": "archived"}} for negation. Schema from resource.file_metadata_schema.'
|
|
13576
|
+
},
|
|
13577
|
+
"limit": {
|
|
13578
|
+
"type": "integer",
|
|
13579
|
+
"description": "Maximum number of files to return (default: 50, max: 100)"
|
|
13580
|
+
},
|
|
13581
|
+
"offset": {
|
|
13582
|
+
"type": "integer",
|
|
13583
|
+
"description": "Number of files to skip for pagination (default: 0)"
|
|
13584
|
+
}
|
|
13585
|
+
},
|
|
13586
|
+
"required": [
|
|
13587
|
+
"resource_id"
|
|
13588
|
+
],
|
|
13589
|
+
"additionalProperties": false
|
|
13590
|
+
}
|
|
13591
|
+
},
|
|
13592
|
+
"tool_instructions": "Deprecated: prefer list_files, which lists the same files by path, needs no resource_id, and also sees this conversation's attachments. Still works \u2014 each row carries a `path`; pass that path to read_file to retrieve the file's content for AI analysis. `file_id` is also returned and still accepted."
|
|
13593
|
+
},
|
|
13594
|
+
"get_tool_schema": {
|
|
13595
|
+
"tool_config": {
|
|
13596
|
+
"name": "get_tool_schema",
|
|
13597
|
+
"description": "MANDATORY FIRST STEP: Retrieves the complete parameter schema for any tool by name. You MUST call this before using ANY tool to get its exact required parameters. This ensures execute_tool will succeed.",
|
|
13598
|
+
"strict": true,
|
|
13599
|
+
"parameters": {
|
|
13600
|
+
"type": "object",
|
|
13601
|
+
"properties": {
|
|
13602
|
+
"tool_name": {
|
|
13603
|
+
"type": "string",
|
|
13604
|
+
"description": "The name of the tool to retrieve the schema for"
|
|
13605
|
+
}
|
|
13606
|
+
},
|
|
13607
|
+
"required": [
|
|
13608
|
+
"tool_name"
|
|
13609
|
+
],
|
|
13610
|
+
"additionalProperties": false
|
|
13611
|
+
}
|
|
13612
|
+
},
|
|
13613
|
+
"tool_instructions": "Mandatory first step before execute_tool. Returns `function_schema` for the target tool \u2014 pass `function_schema.parameters` (same shape, same keys) as the `parameters` envelope in your execute_tool call."
|
|
13614
|
+
},
|
|
13615
|
+
"execute_tool": {
|
|
13616
|
+
"tool_config": {
|
|
13617
|
+
"name": "execute_tool",
|
|
13618
|
+
"description": "Executes any tool by name. You MUST call get_tool_schema first for the target tool to learn its parameter shape, then pass that shape verbatim under `parameters`.",
|
|
13619
|
+
"strict": false,
|
|
13620
|
+
"parameters": {
|
|
13621
|
+
"type": "object",
|
|
13622
|
+
"required": [
|
|
13623
|
+
"tool_name",
|
|
13624
|
+
"parameters"
|
|
13625
|
+
],
|
|
13626
|
+
"properties": {
|
|
13627
|
+
"tool_name": {
|
|
13628
|
+
"type": "string",
|
|
13629
|
+
"description": "The name of the tool to execute."
|
|
13630
|
+
},
|
|
13631
|
+
"parameters": {
|
|
13632
|
+
"type": "object",
|
|
13633
|
+
"description": "The arguments object for the target tool. Must match `function_schema.parameters` returned by get_tool_schema \u2014 same keys, same shape, same required fields. Inner contents are validated by the target tool, not by execute_tool."
|
|
13634
|
+
}
|
|
13635
|
+
},
|
|
13636
|
+
"additionalProperties": false
|
|
13637
|
+
}
|
|
13638
|
+
},
|
|
13639
|
+
"tool_instructions": "MANDATORY WORKFLOW: 1) Call get_tool_schema(tool_name) to receive the target's `function_schema`. 2) Build a `parameters` object that matches `function_schema.parameters` \u2014 same property keys, same types, all required fields. 3) Call execute_tool({ tool_name, parameters }). The `parameters` envelope here is identical in shape to `function_schema.parameters`."
|
|
13640
|
+
},
|
|
13641
|
+
"expand_summary": {
|
|
13642
|
+
"tool_config": {
|
|
13643
|
+
"name": "expand_summary",
|
|
13644
|
+
"description": "Retrieve the original messages of a section in the conversation summary. The summary block at the top of the conversation lists sections with stable `id`s \u2014 pass one to get the verbatim messages it covers.",
|
|
13645
|
+
"strict": true,
|
|
13646
|
+
"parameters": {
|
|
13647
|
+
"type": "object",
|
|
13648
|
+
"properties": {
|
|
13649
|
+
"section_id": {
|
|
13650
|
+
"type": "string",
|
|
13651
|
+
"description": "The `id` of the section from the <conversation_summary> block at the top of the conversation."
|
|
13652
|
+
}
|
|
13653
|
+
},
|
|
13654
|
+
"required": [
|
|
13655
|
+
"section_id"
|
|
13656
|
+
],
|
|
13657
|
+
"additionalProperties": false
|
|
13658
|
+
}
|
|
13659
|
+
},
|
|
13660
|
+
"tool_instructions": "Use when a summary section is too compressed for the question at hand \u2014 e.g. you need the user's exact wording, the precise text of a previous decision, or a tool result that the summary only references. If you pass an unknown `section_id`, the response will include `available_section_ids` so you can retry with a valid one."
|
|
13661
|
+
},
|
|
13662
|
+
"read_skill": {
|
|
13663
|
+
"tool_config": {
|
|
13664
|
+
"name": "read_skill",
|
|
13665
|
+
"description": "Read a skill's SKILL.md content. Pass a skill_id from the skills linked to this agent (available ids are listed in the skill_id parameter).",
|
|
13666
|
+
"strict": true,
|
|
13667
|
+
"parameters": {
|
|
13668
|
+
"type": "object",
|
|
13669
|
+
"properties": {
|
|
13670
|
+
"skill_id": {
|
|
13671
|
+
"type": "string",
|
|
13672
|
+
"description": "The skill's resource_id. Must be one of the skills linked to this agent (the available ids are listed here at runtime)."
|
|
13673
|
+
}
|
|
13674
|
+
},
|
|
13675
|
+
"required": [
|
|
13676
|
+
"skill_id"
|
|
13677
|
+
],
|
|
13678
|
+
"additionalProperties": false
|
|
13679
|
+
}
|
|
13680
|
+
},
|
|
13681
|
+
"tool_instructions": "Use this tool to read a skill's instructions. Returns the full SKILL.md content as a string. Use read_skill_file to access other files referenced in the skill."
|
|
13682
|
+
},
|
|
13683
|
+
"read_skill_file": {
|
|
13684
|
+
"tool_config": {
|
|
13685
|
+
"name": "read_skill_file",
|
|
13686
|
+
"description": "Read a file from a skill by relative path. No need to call read_skill first if you already know the file path.",
|
|
13687
|
+
"strict": true,
|
|
13688
|
+
"parameters": {
|
|
13689
|
+
"type": "object",
|
|
13690
|
+
"properties": {
|
|
13691
|
+
"skill_id": {
|
|
13692
|
+
"type": "string",
|
|
13693
|
+
"description": "The skill's resource_id. Must be one of the skills linked to this agent (the available ids are listed here at runtime)."
|
|
13694
|
+
},
|
|
13695
|
+
"file_path": {
|
|
13696
|
+
"type": "string",
|
|
13697
|
+
"description": 'Relative path from skill root (e.g., "references/menu.md")'
|
|
13698
|
+
}
|
|
13699
|
+
},
|
|
13700
|
+
"required": [
|
|
13701
|
+
"skill_id",
|
|
13702
|
+
"file_path"
|
|
13703
|
+
],
|
|
13704
|
+
"additionalProperties": false
|
|
13705
|
+
}
|
|
13706
|
+
},
|
|
13707
|
+
"tool_instructions": 'Use this tool to read files referenced in SKILL.md. Provide the relative path as shown in the skill content (e.g., "references/menu.md"). Returns content for text files or signed URL for binary files.'
|
|
13708
|
+
},
|
|
13709
|
+
"update_state": {
|
|
13710
|
+
"tool_config": {
|
|
13711
|
+
"name": "update_state",
|
|
13712
|
+
"description": "Updates a configured state by merging updates with its current value. Scope (conversation vs user) is inferred from the state's definition.",
|
|
13713
|
+
"strict": false,
|
|
13714
|
+
"parameters": {
|
|
13715
|
+
"type": "object",
|
|
13716
|
+
"properties": {
|
|
13717
|
+
"state_slug": {
|
|
13718
|
+
"type": "string",
|
|
13719
|
+
"description": "Stable slug of the state to update. Pass the slug (the left half), not the display name. Available states (slug + display name): [STATE_SLUG_VALUES]"
|
|
13720
|
+
},
|
|
13721
|
+
"updates": {
|
|
13722
|
+
"type": "object",
|
|
13723
|
+
"description": "Object with key-value pairs to merge into the current state"
|
|
13724
|
+
}
|
|
13725
|
+
},
|
|
13726
|
+
"required": [
|
|
13727
|
+
"state_slug",
|
|
13728
|
+
"updates"
|
|
13729
|
+
],
|
|
13730
|
+
"additionalProperties": false
|
|
13731
|
+
}
|
|
13732
|
+
},
|
|
13733
|
+
"tool_instructions": "Use to track and update contextual information during conversations. Examples: updating cart items, recording form answers, saving user preferences. The updates are merged with existing state."
|
|
13734
|
+
},
|
|
13735
|
+
"get_state": {
|
|
13736
|
+
"tool_config": {
|
|
13737
|
+
"name": "get_state",
|
|
13738
|
+
"description": "Retrieves the current value of a configured state. Scope is inferred from the state's definition.",
|
|
13739
|
+
"strict": false,
|
|
13740
|
+
"parameters": {
|
|
13741
|
+
"type": "object",
|
|
13742
|
+
"properties": {
|
|
13743
|
+
"state_slug": {
|
|
13744
|
+
"type": "string",
|
|
13745
|
+
"description": "Stable slug of the state to retrieve. Pass the slug (the left half), not the display name. Available states (slug + display name): [STATE_SLUG_VALUES]"
|
|
13746
|
+
}
|
|
13747
|
+
},
|
|
13748
|
+
"required": [
|
|
13749
|
+
"state_slug"
|
|
13750
|
+
],
|
|
13751
|
+
"additionalProperties": false
|
|
13752
|
+
}
|
|
13753
|
+
},
|
|
13754
|
+
"tool_instructions": "Use to retrieve the current state value. This is useful when you need to check the current state before making decisions or when the state is not already available in the prompt context."
|
|
13755
|
+
},
|
|
13756
|
+
"reset_state": {
|
|
13757
|
+
"tool_config": {
|
|
13758
|
+
"name": "reset_state",
|
|
13759
|
+
"description": "Resets a configured state to its initial value as defined in the state schema. Scope is inferred from the state's definition.",
|
|
13760
|
+
"strict": false,
|
|
13761
|
+
"parameters": {
|
|
13762
|
+
"type": "object",
|
|
13763
|
+
"properties": {
|
|
13764
|
+
"state_slug": {
|
|
13765
|
+
"type": "string",
|
|
13766
|
+
"description": "Stable slug of the state to reset. Pass the slug (the left half), not the display name. Available states (slug + display name): [STATE_SLUG_VALUES]"
|
|
13767
|
+
}
|
|
13768
|
+
},
|
|
13769
|
+
"required": [
|
|
13770
|
+
"state_slug"
|
|
13771
|
+
],
|
|
13772
|
+
"additionalProperties": false
|
|
13773
|
+
}
|
|
13774
|
+
},
|
|
13775
|
+
"tool_instructions": "Use to reset state to its default initial value. This is useful when you need to clear accumulated state and start fresh, such as clearing a shopping cart or resetting form progress."
|
|
13776
|
+
},
|
|
13777
|
+
"get_conversations_summary": {
|
|
13778
|
+
"tool_config": {
|
|
13779
|
+
"name": "get_conversations_summary",
|
|
13780
|
+
"description": "Retrieves a timeline of past conversations with the current user, showing summaries and conversation IDs.",
|
|
13781
|
+
"strict": false,
|
|
13782
|
+
"parameters": {
|
|
13783
|
+
"type": "object",
|
|
13784
|
+
"properties": {
|
|
13785
|
+
"max_conversations": {
|
|
13786
|
+
"type": "integer",
|
|
13787
|
+
"description": "Maximum number of past conversations to return (default: 10)"
|
|
13788
|
+
},
|
|
13789
|
+
"max_characters": {
|
|
13790
|
+
"type": "integer",
|
|
13791
|
+
"description": "Maximum characters in the output (default: 20000, max: 40000). Truncates oldest entries first."
|
|
13792
|
+
}
|
|
13793
|
+
},
|
|
13794
|
+
"required": [],
|
|
13795
|
+
"additionalProperties": false
|
|
13796
|
+
}
|
|
13797
|
+
},
|
|
13798
|
+
"tool_instructions": "Use this tool at the start of a conversation to retrieve the history of past conversations with this user. Returns summaries with conversation IDs that can be used with get_conversation for full transcripts."
|
|
13799
|
+
},
|
|
13800
|
+
"get_conversation": {
|
|
13801
|
+
"tool_config": {
|
|
13802
|
+
"name": "get_conversation",
|
|
13803
|
+
"description": "Retrieves the full transcript of a specific past conversation, plus the IDs of the conversations closed immediately before and after it. Use get_conversations_summary first to find conversation IDs.",
|
|
13804
|
+
"strict": false,
|
|
13805
|
+
"parameters": {
|
|
13806
|
+
"type": "object",
|
|
13807
|
+
"properties": {
|
|
13808
|
+
"conversation_id": {
|
|
13809
|
+
"type": "string",
|
|
13810
|
+
"description": "The ID of the conversation to retrieve (from get_conversations_summary results)"
|
|
13811
|
+
},
|
|
13812
|
+
"max_characters": {
|
|
13813
|
+
"type": "integer",
|
|
13814
|
+
"description": "Maximum characters in the output (default: 30000, max: 60000). Truncates oldest messages first."
|
|
13815
|
+
}
|
|
13816
|
+
},
|
|
13817
|
+
"required": [
|
|
13818
|
+
"conversation_id"
|
|
13819
|
+
],
|
|
13820
|
+
"additionalProperties": false
|
|
13821
|
+
}
|
|
13822
|
+
},
|
|
13823
|
+
"tool_instructions": "Use this tool to read the full transcript of a specific past conversation. First use get_conversations_summary to find conversation IDs, then use this tool to drill into the details. The response may include previous_conversation_id and next_conversation_id \u2014 the conversations closed nearest in time either side of this one, which you can pass straight back to this tool to keep moving through the user's history. They are neighbours by closing time, not a fixed chain, and either may be absent."
|
|
13824
|
+
},
|
|
13825
|
+
// ---------------------------------------------------------------------------
|
|
13826
|
+
// Tools added to the TS catalog after the Supabase migration — schemas
|
|
13827
|
+
// reconstructed from the handler signatures in
|
|
13828
|
+
// apps/backend/src/tools/native/wayai/*.ts.
|
|
13829
|
+
// ---------------------------------------------------------------------------
|
|
13830
|
+
"set_state_path": {
|
|
13831
|
+
"tool_config": {
|
|
13832
|
+
"name": "set_state_path",
|
|
13833
|
+
"description": "Set a specific path within a state object (dot/array path) without overwriting the rest of the state. Scope is inferred from the state's definition.",
|
|
13834
|
+
// strict:false matches the other state ops so legacy composed-tool YAML
|
|
13835
|
+
// mapping `state_scope` (now ignored at runtime) doesn't trip OpenAI
|
|
13836
|
+
// strict-mode validators on in-flight calls.
|
|
13837
|
+
"strict": false,
|
|
13838
|
+
"parameters": {
|
|
13839
|
+
"type": "object",
|
|
13840
|
+
"properties": {
|
|
13841
|
+
"state_slug": {
|
|
13842
|
+
"type": "string",
|
|
13843
|
+
"description": "Stable slug of the state variable to update. Pass the slug (the left half), not the display name. Available states (slug + display name): [STATE_SLUG_VALUES]"
|
|
13844
|
+
},
|
|
13845
|
+
"path": {
|
|
13846
|
+
"type": "array",
|
|
13847
|
+
"items": { "type": "string" },
|
|
13848
|
+
"description": "Path within the state object, as an ordered list of keys."
|
|
13849
|
+
},
|
|
13850
|
+
"value": {
|
|
13851
|
+
"description": "The value to write at the given path. Any JSON value is allowed."
|
|
13852
|
+
}
|
|
13853
|
+
},
|
|
13854
|
+
"required": ["state_slug", "path", "value"],
|
|
13855
|
+
"additionalProperties": false
|
|
13856
|
+
}
|
|
13857
|
+
},
|
|
13858
|
+
"tool_instructions": "Use this tool when you need to update a single field inside a structured state object without replacing the entire state. Provide the full path from the root of the state object."
|
|
13859
|
+
},
|
|
13860
|
+
// NEVER OFFERED TO A MODEL, unlike every other entry in this file — and it is
|
|
13861
|
+
// `model_callable: false` on the catalog entry that delivers that, NOT the role
|
|
13862
|
+
// restriction beside it. An earlier version of this comment credited
|
|
13863
|
+
// `assignable_roles: ['monitor']`, which was wrong: a monitor runs a DISPATCHING
|
|
13864
|
+
// turn on `idle` (only the synchronous side-call sets `omit_tools`), and
|
|
13865
|
+
// `PATCH /api/setup/agents/:id` can re-role an agent that keeps the rows it
|
|
13866
|
+
// holds — so the role gate left the tool offerable on two paths.
|
|
13867
|
+
//
|
|
13868
|
+
// The schema exists because the catalog requires one per tool (the parity check
|
|
13869
|
+
// at the bottom of `native-tools.ts`) and because it is the one place the two
|
|
13870
|
+
// arguments are described for whoever writes the rule.
|
|
13871
|
+
//
|
|
13872
|
+
// `tool_instructions: null` FOLLOWS FROM THAT: instructions are injected into an
|
|
13873
|
+
// agent's system message when the tool is attached, and this tool is attached to
|
|
13874
|
+
// an agent whose model is never told it exists.
|
|
13875
|
+
// NEVER OFFERED TO A MODEL, like `insert_note` below and for the same reason:
|
|
13876
|
+
// `model_callable: false` on the catalog entry. A monitor's RULE selects it and
|
|
13877
|
+
// the monitor runtime carries it out — it never reaches `handleTool`, because
|
|
13878
|
+
// running a callee means re-entering the side-call with the caller's cascade
|
|
13879
|
+
// state, which no `ToolContext` carries.
|
|
13880
|
+
"run_monitor": {
|
|
13881
|
+
"tool_config": {
|
|
13882
|
+
"name": "run_monitor",
|
|
13883
|
+
"description": "Run another monitor on this hub. The named monitor judges the same conversation and acts on its own rules; nothing it finds is returned here.",
|
|
13884
|
+
"strict": false,
|
|
13885
|
+
"parameters": {
|
|
13886
|
+
"type": "object",
|
|
13887
|
+
"properties": {
|
|
13888
|
+
"monitor_name": {
|
|
13889
|
+
"type": "string",
|
|
13890
|
+
"description": "The name of the monitor to run. It must be a monitor on this hub whose trigger is manual."
|
|
13891
|
+
}
|
|
13892
|
+
},
|
|
13893
|
+
"required": ["monitor_name"],
|
|
13894
|
+
"additionalProperties": false
|
|
13895
|
+
}
|
|
13896
|
+
},
|
|
13897
|
+
"tool_instructions": null
|
|
13898
|
+
},
|
|
13899
|
+
"insert_note": {
|
|
13900
|
+
"tool_config": {
|
|
13901
|
+
"name": "insert_note",
|
|
13902
|
+
"description": "Insert an admin-authored note into the answering agent's context for this turn only. The note is written by the administrator, not by a model; the monitor's variables are substituted into it.",
|
|
13903
|
+
"strict": false,
|
|
13904
|
+
"parameters": {
|
|
13905
|
+
"type": "object",
|
|
13906
|
+
"properties": {
|
|
13907
|
+
"template": {
|
|
13908
|
+
"type": "string",
|
|
13909
|
+
"description": "The note text. Write {{variable_name}} to substitute one of this monitor's own variables. Unresolved names render as nothing and are recorded on the audit row."
|
|
13910
|
+
},
|
|
13911
|
+
"keep_in_history": {
|
|
13912
|
+
"type": "boolean",
|
|
13913
|
+
"description": "Default false: the note briefs this turn only and is never stored. Set true to also record it as an internal message the support team can see and the customer never receives."
|
|
13914
|
+
}
|
|
13915
|
+
},
|
|
13916
|
+
"required": ["template"],
|
|
13917
|
+
"additionalProperties": false
|
|
13918
|
+
}
|
|
13919
|
+
},
|
|
13920
|
+
"tool_instructions": null
|
|
13921
|
+
}
|
|
13922
|
+
};
|
|
13923
|
+
WAYAI_CONNECTOR2 = "b17d9f3a-4e1b-46c9-b648-a2f0c3611aa4";
|
|
13924
|
+
BASE_NATIVE_TOOLS2 = [
|
|
13925
|
+
// --- Wayai core tools ---
|
|
13926
|
+
{ tool_native_id: "nt-001", tool_name: "transfer_to_agent", tool_display_name: "Transfer to Agent", tool_description: "Transfer the conversation to another AI agent", connector_id: WAYAI_CONNECTOR2, operation: "transfer_to_agent", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null },
|
|
13927
|
+
{ tool_native_id: "nt-002", tool_name: "transfer_to_team", tool_display_name: "Transfer to Team", tool_description: "Escalate conversation to a human support team", connector_id: WAYAI_CONNECTOR2, operation: "transfer_to_team", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null },
|
|
13928
|
+
{ tool_native_id: "nt-003", tool_name: "close_conversation", tool_display_name: "Close Conversation", tool_description: "Close and end the current conversation", connector_id: WAYAI_CONNECTOR2, operation: "close_conversation", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13929
|
+
{ tool_native_id: "nt-004", tool_name: "update_kanban_status", tool_display_name: "Update Kanban Status", tool_description: "Update the kanban status of the conversation", connector_id: WAYAI_CONNECTOR2, operation: "update_kanban_status", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13930
|
+
{ tool_native_id: "nt-005", tool_name: "schedule_followup", tool_display_name: "Schedule Follow-up", tool_description: "Schedule a follow-up message for the conversation", connector_id: WAYAI_CONNECTOR2, operation: "schedule_followup", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: true, execution_config: null },
|
|
13931
|
+
{ tool_native_id: "nt-006", tool_name: "send_files", tool_display_name: "Send Files", tool_description: "Send files to the user", connector_id: WAYAI_CONNECTOR2, operation: "send_files", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13932
|
+
{ tool_native_id: "nt-007", tool_name: "update_state", tool_display_name: "Update State", tool_description: "Update conversation or user state variables", connector_id: WAYAI_CONNECTOR2, operation: "update_state", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13933
|
+
{ tool_native_id: "nt-008", tool_name: "get_state", tool_display_name: "Get State", tool_description: "Retrieve conversation or user state values", connector_id: WAYAI_CONNECTOR2, operation: "get_state", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13934
|
+
{ tool_native_id: "nt-009", tool_name: "reset_state", tool_display_name: "Reset State", tool_description: "Reset conversation or user state to initial values", connector_id: WAYAI_CONNECTOR2, operation: "reset_state", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13935
|
+
{ tool_native_id: "nt-010", tool_name: "set_state_path", tool_display_name: "Set State Path", tool_description: "Set a specific path within state object", connector_id: WAYAI_CONNECTOR2, operation: "set_state_path", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13936
|
+
{ tool_native_id: "nt-011", tool_name: "consult_agent", tool_display_name: "Consult Agent", tool_description: "Consult an advisor agent for advice without transferring", connector_id: WAYAI_CONNECTOR2, operation: "consult_agent", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13937
|
+
{ tool_native_id: "nt-013", tool_name: "read_skill", tool_display_name: "Read Skill", tool_description: "Read the full specification of a skill", connector_id: WAYAI_CONNECTOR2, operation: "read_skill", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13938
|
+
{ tool_native_id: "nt-014", tool_name: "read_skill_file", tool_display_name: "Read Skill File", tool_description: "Read a specific file within a skill", connector_id: WAYAI_CONNECTOR2, operation: "read_skill_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13939
|
+
{ tool_native_id: "nt-015", tool_name: "read_file", tool_display_name: "Read File", tool_description: "Read the contents of a resource file", connector_id: WAYAI_CONNECTOR2, operation: "read_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13940
|
+
// Superseded by `list_files` (nt-027), which browses the same resource files
|
|
13941
|
+
// by PATH plus this conversation's attachments.
|
|
13942
|
+
//
|
|
13943
|
+
// `ui_assignable: false` — DEPRECATED, not withdrawn. Hiding the Add grid entry
|
|
13944
|
+
// stops a NEW agent from being wired to a tool that addresses files by an id a
|
|
13945
|
+
// publish re-mints and that cannot see a conversation attachment at all (the id
|
|
13946
|
+
// itself is discoverable — `RESOURCE_TOOL_INJECTIONS` still writes the linked
|
|
13947
|
+
// ids into their `resource_id` description every turn), while every hub that
|
|
13948
|
+
// already assigns one keeps
|
|
13949
|
+
// working: the handler still dispatches, CI name resolution still resolves the
|
|
13950
|
+
// name, and `wayai pull` / `push` still round-trips the YAML. There is no
|
|
13951
|
+
// auto-provisioning anywhere in the platform, so an existing agent is never
|
|
13952
|
+
// migrated for free — an author swaps the tool deliberately.
|
|
13953
|
+
{ tool_native_id: "nt-016", tool_name: "list_resource_files", tool_display_name: "List Resource Files", tool_description: "(deprecated \u2014 use list_files) List files in a resource folder", connector_id: WAYAI_CONNECTOR2, operation: "list_resource_files", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, ui_assignable: false },
|
|
13954
|
+
{ tool_native_id: "nt-017", tool_name: "list_resource_folders", tool_display_name: "List Resource Folders", tool_description: "(deprecated \u2014 use list_files) List all resource folders", connector_id: WAYAI_CONNECTOR2, operation: "list_resource_folders", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, ui_assignable: false },
|
|
13955
|
+
{ tool_native_id: "nt-018", tool_name: "get_conversations_summary", tool_display_name: "Get Conversations Summary", tool_description: "Get a summary of recent conversations", connector_id: WAYAI_CONNECTOR2, operation: "get_conversations_summary", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13956
|
+
{ tool_native_id: "nt-019", tool_name: "get_conversation", tool_display_name: "Get Conversation", tool_description: "Retrieve full conversation history", connector_id: WAYAI_CONNECTOR2, operation: "get_conversation", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13957
|
+
{ tool_native_id: "nt-020", tool_name: "get_tool_schema", tool_display_name: "Get Tool Schema", tool_description: "Retrieve the JSON schema for a tool", connector_id: WAYAI_CONNECTOR2, operation: "get_tool_schema", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13958
|
+
{ tool_native_id: "nt-021", tool_name: "execute_tool", tool_display_name: "Execute Tool", tool_description: "Execute any available tool by name", connector_id: WAYAI_CONNECTOR2, operation: "execute_tool", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13959
|
+
{ tool_native_id: "nt-022", tool_name: "expand_summary", tool_display_name: "Expand Summary", tool_description: "Retrieve the original messages of a section in the conversation summary", connector_id: WAYAI_CONNECTOR2, operation: "expand_summary", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13960
|
+
{ tool_native_id: "nt-023", tool_name: "download_file", tool_display_name: "Download File for Edit", tool_description: "Mount a resource file into the code execution sandbox for editing", connector_id: WAYAI_CONNECTOR2, operation: "download_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13961
|
+
{ tool_native_id: "nt-024", tool_name: "upload_file", tool_display_name: "Upload Edited File", tool_description: "Persist a sandbox-edited file back to the resource library", connector_id: WAYAI_CONNECTOR2, operation: "upload_file", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13962
|
+
// Hub-as-agent delegation (consultant-agents H1.5). UN-GATED in PR 7 (H1.5b): the
|
|
13963
|
+
// spawn + cross-DO completion callback shipped, so the tool is live across the
|
|
13964
|
+
// catalog listing, CI push, the config snapshot, and the handler. (PR 6 shipped it
|
|
13965
|
+
// `assignable: false` so no visible-but-inert tool could reach production between
|
|
13966
|
+
// the two merges.)
|
|
13967
|
+
//
|
|
13968
|
+
// `ui_assignable: false` — CONFIG-AS-CODE ONLY for v1. Attaching this tool requires
|
|
13969
|
+
// two admin decisions the Add dialog cannot yet collect: the target hub and the
|
|
13970
|
+
// `context_boundary` (a data-sensitivity choice). Without a `hub` branch in the
|
|
13971
|
+
// delegation dialog, clicking Add would submit no delegation params and the write
|
|
13972
|
+
// path would reject it — a live button that only ever errors. Assign it via
|
|
13973
|
+
// `wayai push` until the picker + boundary control ship.
|
|
13974
|
+
{ tool_native_id: "nt-025", tool_name: "delegate_to_hub", tool_display_name: "Delegate to Hub", tool_description: "Delegate a request to another hub as a task, and receive the result asynchronously", connector_id: WAYAI_CONNECTOR2, operation: "delegate_to_hub", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, ui_assignable: false },
|
|
13975
|
+
// Agent-initiated consults (consultant-agents H1.7b). A delegation tool like the
|
|
13976
|
+
// three above: the TARGET is admin configuration (`delegated_agent_id` for a
|
|
13977
|
+
// same-hub consultant, `delegated_hub_id` for a partner hub) and the model supplies
|
|
13978
|
+
// only the question — so scoping "which consultants may this agent reach" reuses
|
|
13979
|
+
// the existing assignment model with no new config surface.
|
|
13980
|
+
//
|
|
13981
|
+
// `ui_assignable: false` — CONFIG-AS-CODE ONLY for v1, same reasoning as
|
|
13982
|
+
// `delegate_to_hub`: attaching it requires a target the Add dialog cannot yet
|
|
13983
|
+
// collect (and, for a consultant target, the `allow_consultant_chain` opt-in). A
|
|
13984
|
+
// live button that only ever errors is worse than no button. Assign via `wayai push`
|
|
13985
|
+
// until the picker ships.
|
|
13986
|
+
{ tool_native_id: "nt-026", tool_name: "start_consult_thread", tool_display_name: "Start Consult Thread", tool_description: "Ask a configured consultant (or partner hub) a question in a visible consult thread", connector_id: WAYAI_CONNECTOR2, operation: "start_consult_thread", tool_method: "internal", tool_group: "Native Tools", is_delegation: true, is_auto_set: false, execution_config: null, ui_assignable: false },
|
|
13987
|
+
// One drill-down listing for every file namespace, replacing `list_resource_files`
|
|
13988
|
+
// (nt-016) and `list_resource_folders` (nt-017). Fully visible: it needs no
|
|
13989
|
+
// configuration the Add dialog cannot collect — the mounts an agent may browse
|
|
13990
|
+
// come from its existing resource links and its own conversation, and the only
|
|
13991
|
+
// model-supplied input is a path.
|
|
13992
|
+
{ tool_native_id: "nt-027", tool_name: "list_files", tool_display_name: "List Files", tool_description: "Browse the files this agent can reach, by path", connector_id: WAYAI_CONNECTOR2, operation: "list_files", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null },
|
|
13993
|
+
// TWO gates, and BOTH are load-bearing — the first shipped alone and was not
|
|
13994
|
+
// enough. `assignable_roles: ['monitor']` says only a monitor may HOLD it,
|
|
13995
|
+
// because the tool has no meaning off a monitor: a rule SELECTS it and the note
|
|
13996
|
+
// is injected into the ANSWERING agent's prompt for that one turn.
|
|
13997
|
+
// `model_callable: false` says no model is ever TOLD it exists — which the role
|
|
13998
|
+
// restriction does NOT imply, because an `idle` monitor runs a dispatching turn
|
|
13999
|
+
// and a re-roled agent keeps the tools it holds. Offered and called, it reaches
|
|
14000
|
+
// the native dispatcher's `default:` branch: a Sentry event and a provider
|
|
14001
|
+
// re-call. See `NativeTool.model_callable`.
|
|
14002
|
+
{ tool_native_id: "nt-028", tool_name: "insert_note", tool_display_name: "Insert Note", tool_description: "Brief the answering agent with an admin-authored note before it replies", connector_id: WAYAI_CONNECTOR2, operation: "insert_note", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, assignable_roles: ["monitor"], model_callable: false },
|
|
14003
|
+
// TWO gates, same pair and same reasons as `insert_note` above — this is the
|
|
14004
|
+
// second tool to need both, which is why they are catalog fields rather than a
|
|
14005
|
+
// check at one site. `assignable_roles: ['monitor']`: only a monitor may hold it,
|
|
14006
|
+
// because only a monitor's RULE can select it. `model_callable: false`: no model
|
|
14007
|
+
// is ever told it exists, which the role restriction does NOT imply — an `idle`
|
|
14008
|
+
// monitor runs a dispatching turn, and a re-roled agent keeps the rows it holds.
|
|
14009
|
+
//
|
|
14010
|
+
// The CALLEE is named, not identified by id (owner decision 9): a hub-relative
|
|
14011
|
+
// name survives every copy path untouched, where a per-hub UUID in a JSON column
|
|
14012
|
+
// would need remapping on both branching mechanisms and normalizing on both CI
|
|
14013
|
+
// directions. `action.tool_name`, one key away in the same object, is the
|
|
14014
|
+
// precedent.
|
|
14015
|
+
{ tool_native_id: "nt-029", tool_name: "run_monitor", tool_display_name: "Run Monitor", tool_description: "Run another monitor on this hub and let it act on its own rules", connector_id: WAYAI_CONNECTOR2, operation: "run_monitor", tool_method: "internal", tool_group: "Native Tools", is_delegation: false, is_auto_set: false, execution_config: null, assignable_roles: ["monitor"], model_callable: false }
|
|
14016
|
+
];
|
|
14017
|
+
NATIVE_TOOLS2 = BASE_NATIVE_TOOLS2.map((base) => {
|
|
14018
|
+
const schema = NATIVE_TOOL_SCHEMAS2[base.tool_name];
|
|
14019
|
+
if (!schema) {
|
|
14020
|
+
throw new Error(
|
|
14021
|
+
`Native tool "${base.tool_name}" (${base.tool_native_id}) is missing an entry in NATIVE_TOOL_SCHEMAS. Add it to workers/shared/src/catalog/native-tool-schemas.ts.`
|
|
14022
|
+
);
|
|
14023
|
+
}
|
|
14024
|
+
return {
|
|
14025
|
+
...base,
|
|
14026
|
+
tool_config: schema.tool_config,
|
|
14027
|
+
tool_instructions: schema.tool_instructions
|
|
14028
|
+
};
|
|
14029
|
+
});
|
|
14030
|
+
NATIVE_TOOL_NAMES2 = new Set(NATIVE_TOOLS2.map((t) => t.tool_name));
|
|
11283
14031
|
previousConversationsCountField2 = external_exports.number().int().min(0).max(PREVIOUS_CONVERSATIONS_MAX2).nullable().optional();
|
|
11284
14032
|
summarizationThresholdField2 = external_exports.number().int().min(SUMMARIZATION_THRESHOLD_MIN2).max(SUMMARIZATION_THRESHOLD_MAX2).nullable().optional();
|
|
14033
|
+
flagConditionSchema2 = external_exports.object({
|
|
14034
|
+
variable: external_exports.string(),
|
|
14035
|
+
operator: external_exports.enum(FLAG_CONDITION_OPERATORS2),
|
|
14036
|
+
// `boolean` is admitted for parity with the CI write path, whose refine gates the
|
|
14037
|
+
// operator alone, so `value: false` on a boolean evaluation variable is storable
|
|
14038
|
+
// config today and the evaluator honours it through `String()`. Narrowing here would
|
|
14039
|
+
// reject on PATCH exactly what `wayai push` persists, so any REST caller that reads
|
|
14040
|
+
// an agent and writes it back — the typed clients, the CLI's `ApiClient`, MCP — would
|
|
14041
|
+
// fail on a hub configured through the other surface.
|
|
14042
|
+
value: external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()])
|
|
14043
|
+
});
|
|
14044
|
+
MONITOR_TRIGGERS2 = ["idle", "user_message", "assistant_reply", "manual"];
|
|
14045
|
+
monitorTriggerSchema2 = external_exports.enum(MONITOR_TRIGGERS2);
|
|
14046
|
+
MONITOR_FIRING_TRIGGERS2 = MONITOR_TRIGGERS2.filter(isFiringTrigger2);
|
|
14047
|
+
MONITOR_DELAY_SECONDS_MIN2 = 10;
|
|
14048
|
+
MONITOR_IDLE_DELAY_REQUIRED_MESSAGE2 = "delay_seconds is required for an idle monitor (an absent trigger is idle)";
|
|
14049
|
+
MONITOR_HISTORY_MESSAGES_MAX2 = 100;
|
|
14050
|
+
monitorHistoryMessagesSchema2 = external_exports.number().int().min(1).max(MONITOR_HISTORY_MESSAGES_MAX2);
|
|
14051
|
+
monitorIncludeToolResultsSchema2 = external_exports.boolean();
|
|
14052
|
+
MONITOR_INPUT_SHAPING_KEYS2 = ["history_messages", "include_tool_results"];
|
|
14053
|
+
MONITOR_INPUT_SHAPING_SCHEMAS2 = {
|
|
14054
|
+
history_messages: monitorHistoryMessagesSchema2.optional(),
|
|
14055
|
+
include_tool_results: monitorIncludeToolResultsSchema2.optional()
|
|
14056
|
+
};
|
|
14057
|
+
MONITOR_INPUT_SHAPING_IDLE_MESSAGE2 = "only a user_message, assistant_reply or manual monitor reads this \u2014 an idle monitor runs as a full turn and takes the ordinary history window";
|
|
14058
|
+
monitorArgumentSourceSchema2 = external_exports.union([
|
|
14059
|
+
external_exports.object({ from_variable: external_exports.string().min(1) }).strict(),
|
|
14060
|
+
external_exports.object({ const: external_exports.union([external_exports.string(), external_exports.number(), external_exports.boolean()]) }).strict()
|
|
14061
|
+
]);
|
|
14062
|
+
MONITOR_NOTE_TEMPLATE_MAX2 = 2e3;
|
|
14063
|
+
monitorActionSchema2 = external_exports.discriminatedUnion("kind", [
|
|
14064
|
+
external_exports.object({ kind: external_exports.literal("none") }).strict(),
|
|
14065
|
+
external_exports.object({
|
|
14066
|
+
kind: external_exports.literal("call_tool"),
|
|
14067
|
+
tool_name: external_exports.string().min(1),
|
|
14068
|
+
args: external_exports.record(monitorArgumentSourceSchema2).optional()
|
|
14069
|
+
}).strict(),
|
|
14070
|
+
external_exports.object({ kind: external_exports.literal("hold") }).strict(),
|
|
14071
|
+
external_exports.object({ kind: external_exports.literal("rewrite"), note: external_exports.string().min(1).max(MONITOR_NOTE_TEMPLATE_MAX2) }).strict()
|
|
14072
|
+
]);
|
|
14073
|
+
monitorRuleSchema2 = external_exports.object({
|
|
14074
|
+
when: external_exports.array(flagConditionSchema2).min(1),
|
|
14075
|
+
action: monitorActionSchema2
|
|
14076
|
+
}).strict();
|
|
14077
|
+
MONITOR_RULE_KEYS2 = ["rules", "fallback"];
|
|
14078
|
+
MONITOR_RULE_SCHEMAS2 = {
|
|
14079
|
+
rules: external_exports.array(monitorRuleSchema2).optional(),
|
|
14080
|
+
fallback: monitorActionSchema2.optional()
|
|
14081
|
+
};
|
|
14082
|
+
MONITOR_RULE_TRIGGERS2 = ["user_message", "assistant_reply", "manual"];
|
|
14083
|
+
MONITOR_RULE_TRIGGER_MESSAGE2 = "only a user_message, assistant_reply or manual monitor acts on rules \u2014 set one of those triggers, or remove this key. A manual monitor acts on its rules when another monitor runs it.";
|
|
14084
|
+
MONITOR_USER_MESSAGE_ACTION_KINDS2 = ["none", "call_tool"];
|
|
14085
|
+
MONITOR_ASSISTANT_REPLY_ACTION_KINDS2 = ["none", "call_tool", "hold", "rewrite"];
|
|
14086
|
+
INSERT_NOTE_TOOL_NAME2 = "insert_note";
|
|
14087
|
+
RUN_MONITOR_TOOL_NAME2 = "run_monitor";
|
|
14088
|
+
MONITOR_RULE_ALLOWED_NATIVE_TOOLS2 = [
|
|
14089
|
+
"update_state",
|
|
14090
|
+
"schedule_followup",
|
|
14091
|
+
"transfer_to_agent",
|
|
14092
|
+
"transfer_to_team",
|
|
14093
|
+
INSERT_NOTE_TOOL_NAME2,
|
|
14094
|
+
RUN_MONITOR_TOOL_NAME2
|
|
14095
|
+
];
|
|
14096
|
+
MONITOR_RULE_REENTRY_TOOLS2 = {
|
|
14097
|
+
transfer_to_agent: "agent",
|
|
14098
|
+
transfer_to_team: "team"
|
|
14099
|
+
};
|
|
14100
|
+
MONITOR_RULE_REENTRY_TRACKS2 = new Map(Object.entries(MONITOR_RULE_REENTRY_TOOLS2));
|
|
11285
14101
|
monitorConfigField2 = external_exports.object({
|
|
11286
|
-
delay_seconds: external_exports.number().int().min(
|
|
11287
|
-
|
|
11288
|
-
|
|
11289
|
-
|
|
11290
|
-
|
|
11291
|
-
|
|
11292
|
-
|
|
11293
|
-
|
|
11294
|
-
|
|
14102
|
+
delay_seconds: external_exports.number().int().min(MONITOR_DELAY_SECONDS_MIN2).optional(),
|
|
14103
|
+
trigger: monitorTriggerSchema2.optional(),
|
|
14104
|
+
...MONITOR_INPUT_SHAPING_SCHEMAS2,
|
|
14105
|
+
...MONITOR_RULE_SCHEMAS2,
|
|
14106
|
+
flag_conditions: external_exports.array(flagConditionSchema2).optional()
|
|
14107
|
+
}).passthrough().superRefine((config, ctx) => {
|
|
14108
|
+
if (monitorConfigNeedsDelay2(config)) {
|
|
14109
|
+
ctx.addIssue({
|
|
14110
|
+
code: external_exports.ZodIssueCode.custom,
|
|
14111
|
+
path: ["delay_seconds"],
|
|
14112
|
+
message: MONITOR_IDLE_DELAY_REQUIRED_MESSAGE2
|
|
14113
|
+
});
|
|
14114
|
+
}
|
|
14115
|
+
for (const key of monitorInputShapingKeysOnIdle2(config)) {
|
|
14116
|
+
ctx.addIssue({
|
|
14117
|
+
code: external_exports.ZodIssueCode.custom,
|
|
14118
|
+
path: [key],
|
|
14119
|
+
message: MONITOR_INPUT_SHAPING_IDLE_MESSAGE2
|
|
14120
|
+
});
|
|
14121
|
+
}
|
|
14122
|
+
for (const issue of collectMonitorRuleIssues2(config)) {
|
|
14123
|
+
ctx.addIssue({ code: external_exports.ZodIssueCode.custom, path: issue.path, message: issue.message });
|
|
14124
|
+
}
|
|
14125
|
+
}).nullable().optional();
|
|
14126
|
+
flagConditionsField2 = external_exports.array(flagConditionSchema2).nullable().optional();
|
|
11295
14127
|
agentIdParam2 = external_exports.object({
|
|
11296
14128
|
id: uuidSchema2
|
|
11297
14129
|
});
|
|
@@ -11308,13 +14140,15 @@ var init_dist = __esm({
|
|
|
11308
14140
|
additional_context_template: external_exports.string().max(2e4).optional(),
|
|
11309
14141
|
summarization_threshold_tokens: summarizationThresholdField2,
|
|
11310
14142
|
previous_conversations_count: previousConversationsCountField2,
|
|
11311
|
-
monitor_config: monitorConfigField2
|
|
11312
|
-
|
|
14143
|
+
monitor_config: monitorConfigField2,
|
|
14144
|
+
flag_conditions: flagConditionsField2
|
|
14145
|
+
}).passthrough().superRefine(refineDecisionsModelBinding2);
|
|
11313
14146
|
updateAgentBody2 = external_exports.object({
|
|
11314
14147
|
additional_context_template: external_exports.string().max(2e4).optional(),
|
|
11315
14148
|
summarization_threshold_tokens: summarizationThresholdField2,
|
|
11316
14149
|
previous_conversations_count: previousConversationsCountField2,
|
|
11317
|
-
monitor_config: monitorConfigField2
|
|
14150
|
+
monitor_config: monitorConfigField2,
|
|
14151
|
+
flag_conditions: flagConditionsField2
|
|
11318
14152
|
}).passthrough();
|
|
11319
14153
|
AGENT_PARAMETER_TYPES2 = ["string", "number", "boolean", "integer", "enum"];
|
|
11320
14154
|
AGENT_PARAMETER_NAME_REGEX2 = /^[a-zA-Z_][a-zA-Z0-9_]{0,63}$/;
|
|
@@ -13301,11 +16135,11 @@ var init_dist = __esm({
|
|
|
13301
16135
|
ops_tenths_this_month: external_exports.number().nonnegative(),
|
|
13302
16136
|
records_count: external_exports.number().nonnegative(),
|
|
13303
16137
|
month_key: external_exports.string(),
|
|
13304
|
-
// The closed window's meter reading (
|
|
16138
|
+
// The closed window's meter reading (the prior-window snapshot). OPTIONAL for the same
|
|
13305
16139
|
// reason this object is not `.strict()`: the producer deploys on its own cadence, and a
|
|
13306
16140
|
// required field would fail the parse for every counter on any producer build that predates
|
|
13307
16141
|
// it — turning an additive wire change into an outage of the gauge above. Absence and a
|
|
13308
|
-
// non-matching key are the SAME outcome for a reader (
|
|
16142
|
+
// non-matching key are the SAME outcome for a reader (do not bill), so
|
|
13309
16143
|
// nothing is lost by tolerating it.
|
|
13310
16144
|
prior_window_key: external_exports.string().optional(),
|
|
13311
16145
|
prior_window_ops_tenths: external_exports.number().nonnegative().optional()
|
|
@@ -13317,41 +16151,41 @@ var init_dist = __esm({
|
|
|
13317
16151
|
* Monotonic per org, WayAI-assigned. An ordering guard for concurrent WayAI
|
|
13318
16152
|
* writers (a plan change racing a token mint) — NOT a cross-repo CAS. Gaps are
|
|
13319
16153
|
* expected: a version is allocated per push attempt, and an idempotency skip
|
|
13320
|
-
*
|
|
16154
|
+
* burns none while a failed KV put burns one.
|
|
13321
16155
|
*/
|
|
13322
16156
|
projection_version: external_exports.number().int().nonnegative(),
|
|
13323
|
-
/** Diagnostic only — never gates. Freshness is `window_resets_at`'s job
|
|
16157
|
+
/** Diagnostic only — never gates. Freshness is `window_resets_at`'s job. */
|
|
13324
16158
|
written_at: external_exports.string().datetime(),
|
|
13325
16159
|
/** The WayAI org UUID. The `account_id` spelling is Rekor's documented carve-out. */
|
|
13326
16160
|
account_id: external_exports.string().uuid(),
|
|
13327
|
-
/** The EFFECTIVE plan, not the subscribed one
|
|
16161
|
+
/** The EFFECTIVE plan, not the subscribed one. Never gates. */
|
|
13328
16162
|
plan_key: planKeySchema2,
|
|
13329
|
-
/** Informational only
|
|
16163
|
+
/** Informational only. `cancelled` spelling matches `BillingRecord`. */
|
|
13330
16164
|
billing_status: billingStatusSchema2,
|
|
13331
16165
|
/** Tenths, matching Rekor's meter granularity (write 10, point-read 1, list/SQL 10). */
|
|
13332
16166
|
ops_tenths_included: external_exports.number().int().nonnegative(),
|
|
13333
16167
|
max_records: external_exports.number().int().nonnegative(),
|
|
13334
|
-
/** Its own field, no longer derived from `max_records
|
|
16168
|
+
/** Its own field, no longer derived from `max_records`. */
|
|
13335
16169
|
import_rows_included: external_exports.number().int().nonnegative(),
|
|
13336
|
-
/** REQUIRED — absence is malformed, never coerced to `false
|
|
16170
|
+
/** REQUIRED — absence is malformed, never coerced to `false`. */
|
|
13337
16171
|
production_bases: external_exports.boolean(),
|
|
13338
|
-
/** Opaque to Rekor; compared for equality only, to reset `usage:` counters
|
|
16172
|
+
/** Opaque to Rekor; compared for equality only, to reset `usage:` counters. */
|
|
13339
16173
|
window_key: external_exports.string().min(1),
|
|
13340
16174
|
/**
|
|
13341
|
-
* The window's TRUE lower bound, for the reconcile's `operations_log` sum
|
|
16175
|
+
* The window's TRUE lower bound, for the reconcile's `operations_log` sum.
|
|
13342
16176
|
*
|
|
13343
16177
|
* OPTIONAL, and that is not a rollout convenience — it is what "never gates" means
|
|
13344
16178
|
* on the writer's side. The tier sources can be absent (a paid row carrying
|
|
13345
16179
|
* `current_period_end` with no `current_period_start`) and inverted pairs are a
|
|
13346
|
-
*
|
|
13347
|
-
* parse and leave the org with NO projection — permanently stale
|
|
13348
|
-
*
|
|
16180
|
+
* diagnostic, so requiring it here would let an inert field throw the strict
|
|
16181
|
+
* parse and leave the org with NO projection — permanently stale, with the
|
|
16182
|
+
* fail-closed gates refusing base creation and 503-ing every import. The
|
|
13349
16183
|
* writer emits it whenever it has a sound value and omits it otherwise; Rekor's
|
|
13350
16184
|
* observed-flip fallback covers the gap, and rollout step 3 keeps that fallback
|
|
13351
16185
|
* for exactly this reason.
|
|
13352
16186
|
*/
|
|
13353
16187
|
window_start: external_exports.string().datetime().optional(),
|
|
13354
|
-
/** The sole staleness authority
|
|
16188
|
+
/** The sole staleness authority. Never triggers a counter reset. */
|
|
13355
16189
|
window_resets_at: external_exports.string().datetime()
|
|
13356
16190
|
}).strict();
|
|
13357
16191
|
rekorEntitlementRefreshMessageSchema2 = external_exports.object({
|
|
@@ -13591,6 +16425,9 @@ var init_dist = __esm({
|
|
|
13591
16425
|
refineHubAsCodeEvalAttachments2(config, ctx);
|
|
13592
16426
|
refineHubAsCodeResources2(config, ctx);
|
|
13593
16427
|
refineHubAsCodeDelegation2(config, ctx);
|
|
16428
|
+
refineHubAsCodeFlagConditions2(config, ctx);
|
|
16429
|
+
refineHubAsCodeMonitorConfig2(config, ctx);
|
|
16430
|
+
refineHubAsCodeDecisionsModel2(config, ctx);
|
|
13594
16431
|
});
|
|
13595
16432
|
ciPullHubIdParam2 = external_exports.object({
|
|
13596
16433
|
hub_id: ciUuidSchema2
|
|
@@ -13818,7 +16655,7 @@ var init_dist = __esm({
|
|
|
13818
16655
|
*
|
|
13819
16656
|
* Past-or-now only. A future start freezes the org's window permanently:
|
|
13820
16657
|
* `maybeRolloverBillingWindow` derives a NEGATIVE elapsed and so never archives the
|
|
13821
|
-
* metrics nor restamps the column, while the
|
|
16658
|
+
* metrics nor restamps the column, while the rollover sweep selects only windows
|
|
13822
16659
|
* that have already passed — so nothing rolls the org over, its consumed operations
|
|
13823
16660
|
* never reset, and past quota every AI turn is refused until a human re-patches.
|
|
13824
16661
|
*/
|
|
@@ -13913,7 +16750,7 @@ var init_dist = __esm({
|
|
|
13913
16750
|
seats_per_unit: external_exports.number().int().min(1, "seats_per_unit must be a positive integer").optional(),
|
|
13914
16751
|
seats_scaling: external_exports.enum(["fixed", "per_quantity"]).optional(),
|
|
13915
16752
|
is_active: external_exports.boolean().optional(),
|
|
13916
|
-
// Rekor entitlement allowances
|
|
16753
|
+
// Rekor entitlement allowances. Editable here for the
|
|
13917
16754
|
// same reason `messages_per_unit` is — and this route is the only ROUTINE way to change an
|
|
13918
16755
|
// allowance on a live plan: the seed establishes a plan row and never rewrites one, so a
|
|
13919
16756
|
// seed-version bump no longer moves these values (see `seed.ts`).
|
|
@@ -14050,7 +16887,7 @@ var init_dist = __esm({
|
|
|
14050
16887
|
cmd: external_exports.string().min(1, "cmd is required").max(SANDBOX_EXEC_MAX_CMD_LENGTH2, `cmd must be <= ${SANDBOX_EXEC_MAX_CMD_LENGTH2} chars`),
|
|
14051
16888
|
/**
|
|
14052
16889
|
* Egress posture. Omitted ⇒ the driver fails closed to deny-all outbound (the
|
|
14053
|
-
*
|
|
16890
|
+
* safe default). The route re-validates the (policy, allowlist) pair via
|
|
14054
16891
|
* `validateEgressConfig`.
|
|
14055
16892
|
*/
|
|
14056
16893
|
egress_policy: sandboxEgressPolicy2.optional(),
|
|
@@ -14549,7 +17386,7 @@ var init_dist = __esm({
|
|
|
14549
17386
|
name: external_exports.string().regex(ADMIN_SKILL_NAME_REGEX2, "invalid skill name")
|
|
14550
17387
|
});
|
|
14551
17388
|
rekorBaseChangeMessageSchema2 = external_exports.object({
|
|
14552
|
-
/** The WayAI org UUID — one id namespace
|
|
17389
|
+
/** The WayAI org UUID — one id namespace. */
|
|
14553
17390
|
org_id: external_exports.string().uuid(),
|
|
14554
17391
|
/**
|
|
14555
17392
|
* Not a UUID: a preview base id is `{prod_base_id}--{slug}`. Immutable per base — a
|
|
@@ -14576,6 +17413,33 @@ var init_dist = __esm({
|
|
|
14576
17413
|
/** Subdir of `wsDir` holding base folders. */
|
|
14577
17414
|
basesSubdir: "bases"
|
|
14578
17415
|
};
|
|
17416
|
+
decisionAnswerSchema = external_exports.discriminatedUnion("type", [
|
|
17417
|
+
external_exports.object({
|
|
17418
|
+
type: external_exports.literal("choice"),
|
|
17419
|
+
choice: external_exports.string(),
|
|
17420
|
+
confidence: external_exports.number().optional()
|
|
17421
|
+
}),
|
|
17422
|
+
external_exports.object({
|
|
17423
|
+
type: external_exports.literal("score"),
|
|
17424
|
+
score: external_exports.number(),
|
|
17425
|
+
confidence: external_exports.number().optional()
|
|
17426
|
+
}),
|
|
17427
|
+
external_exports.object({
|
|
17428
|
+
type: external_exports.literal("noul"),
|
|
17429
|
+
noul: external_exports.number()
|
|
17430
|
+
})
|
|
17431
|
+
]);
|
|
17432
|
+
decisionsResponseSchema = external_exports.object({
|
|
17433
|
+
id: external_exports.string().optional(),
|
|
17434
|
+
model: external_exports.string().optional(),
|
|
17435
|
+
provider: external_exports.string().optional(),
|
|
17436
|
+
answers: external_exports.record(decisionAnswerSchema),
|
|
17437
|
+
usage: external_exports.object({
|
|
17438
|
+
input_tokens: external_exports.number().optional(),
|
|
17439
|
+
output_tokens: external_exports.number().optional(),
|
|
17440
|
+
cost: external_exports.number().optional()
|
|
17441
|
+
}).optional()
|
|
17442
|
+
});
|
|
14579
17443
|
}
|
|
14580
17444
|
});
|
|
14581
17445
|
|
|
@@ -17585,6 +20449,16 @@ function writeFileNoFollow(root, abs, data) {
|
|
|
17585
20449
|
fs9.writeFileSync(abs, data);
|
|
17586
20450
|
return true;
|
|
17587
20451
|
}
|
|
20452
|
+
function createFileNoFollow(root, abs, data) {
|
|
20453
|
+
if (!ensureRealSubdirNoSymlink(root, path10.dirname(abs), true)) return "refused";
|
|
20454
|
+
try {
|
|
20455
|
+
fs9.writeFileSync(abs, data, { flag: "wx" });
|
|
20456
|
+
} catch (err) {
|
|
20457
|
+
if (err.code === "EEXIST") return "exists";
|
|
20458
|
+
throw err;
|
|
20459
|
+
}
|
|
20460
|
+
return "created";
|
|
20461
|
+
}
|
|
17588
20462
|
var init_fs_safety = __esm({
|
|
17589
20463
|
"src/lib/fs-safety.ts"() {
|
|
17590
20464
|
"use strict";
|
|
@@ -18431,7 +21305,6 @@ var init_diff_display = __esm({
|
|
|
18431
21305
|
});
|
|
18432
21306
|
|
|
18433
21307
|
// src/lib/workspace-files.ts
|
|
18434
|
-
import * as fs13 from "fs";
|
|
18435
21308
|
import * as path14 from "path";
|
|
18436
21309
|
function perHubAgentsMd(hubFolderName) {
|
|
18437
21310
|
return [
|
|
@@ -18447,21 +21320,18 @@ function perHubAgentsMd(hubFolderName) {
|
|
|
18447
21320
|
""
|
|
18448
21321
|
].join("\n");
|
|
18449
21322
|
}
|
|
18450
|
-
function writeIfAbsent(filePath, content) {
|
|
18451
|
-
|
|
18452
|
-
fs13.writeFileSync(filePath, content, "utf-8");
|
|
18453
|
-
return path14.basename(filePath);
|
|
21323
|
+
function writeIfAbsent(root, filePath, content) {
|
|
21324
|
+
return createFileNoFollow(root, filePath, Buffer.from(content, "utf-8")) === "created" ? path14.basename(filePath) : null;
|
|
18454
21325
|
}
|
|
18455
|
-
var CLAUDE_MD_SHIM;
|
|
18456
21326
|
var init_workspace_files = __esm({
|
|
18457
21327
|
"src/lib/workspace-files.ts"() {
|
|
18458
21328
|
"use strict";
|
|
18459
|
-
|
|
21329
|
+
init_fs_safety();
|
|
18460
21330
|
}
|
|
18461
21331
|
});
|
|
18462
21332
|
|
|
18463
21333
|
// src/lib/yaml-writer.ts
|
|
18464
|
-
import * as
|
|
21334
|
+
import * as fs13 from "fs";
|
|
18465
21335
|
import * as path15 from "path";
|
|
18466
21336
|
import * as yaml7 from "js-yaml";
|
|
18467
21337
|
function writeFileIfChanged(hubFolder, absPath, content, log) {
|
|
@@ -18512,27 +21382,27 @@ function buildEvalYamlObject(evalEntry, slug) {
|
|
|
18512
21382
|
function writeHubFolder(hubFolder, payload, options = {}) {
|
|
18513
21383
|
const log = { changed: [], removed: [] };
|
|
18514
21384
|
const agentsDir = path15.join(hubFolder, "agents");
|
|
18515
|
-
if (!
|
|
18516
|
-
|
|
21385
|
+
if (!fs13.existsSync(hubFolder)) {
|
|
21386
|
+
fs13.mkdirSync(hubFolder, { recursive: true });
|
|
18517
21387
|
}
|
|
18518
|
-
if (!
|
|
18519
|
-
|
|
21388
|
+
if (!fs13.existsSync(agentsDir)) {
|
|
21389
|
+
fs13.mkdirSync(agentsDir, { recursive: true });
|
|
18520
21390
|
}
|
|
18521
21391
|
const yamlPayload = buildYamlPayload(payload);
|
|
18522
21392
|
const agentFiles = extractAgentFiles(payload);
|
|
18523
21393
|
const yamlContent = yaml7.dump(yamlPayload, YAML_DUMP_OPTIONS);
|
|
18524
21394
|
writeFileIfChanged(hubFolder, path15.join(hubFolder, "hub.yaml"), yamlContent, log);
|
|
18525
21395
|
if (options.seedAgentContext ?? true) {
|
|
18526
|
-
|
|
18527
|
-
|
|
18528
|
-
|
|
18529
|
-
|
|
18530
|
-
|
|
18531
|
-
|
|
21396
|
+
const seeded = writeIfAbsent(
|
|
21397
|
+
hubFolder,
|
|
21398
|
+
path15.join(hubFolder, "AGENTS.md"),
|
|
21399
|
+
perHubAgentsMd(path15.basename(hubFolder))
|
|
21400
|
+
);
|
|
21401
|
+
if (seeded) log.changed.push(seeded);
|
|
18532
21402
|
}
|
|
18533
21403
|
const oldYamlPath = path15.join(hubFolder, "wayai.yaml");
|
|
18534
|
-
if (
|
|
18535
|
-
|
|
21404
|
+
if (fs13.existsSync(oldYamlPath)) {
|
|
21405
|
+
fs13.unlinkSync(oldYamlPath);
|
|
18536
21406
|
log.removed.push(path15.relative(hubFolder, oldYamlPath));
|
|
18537
21407
|
}
|
|
18538
21408
|
const yamlSlugs = writeAgentYamlFiles(hubFolder, agentsDir, payload.agents || [], log);
|
|
@@ -18541,20 +21411,20 @@ function writeHubFolder(hubFolder, payload, options = {}) {
|
|
|
18541
21411
|
mdSlugs.add(slug);
|
|
18542
21412
|
writeFileIfChanged(hubFolder, path15.join(agentsDir, `${slug}.md`), content, log);
|
|
18543
21413
|
}
|
|
18544
|
-
const existingFiles =
|
|
21414
|
+
const existingFiles = fs13.readdirSync(agentsDir);
|
|
18545
21415
|
for (const file of existingFiles) {
|
|
18546
21416
|
if (file.endsWith(".yaml")) {
|
|
18547
21417
|
const slug = file.slice(0, -5);
|
|
18548
21418
|
if (!yamlSlugs.has(slug)) {
|
|
18549
21419
|
const orphan = path15.join(agentsDir, file);
|
|
18550
|
-
|
|
21420
|
+
fs13.unlinkSync(orphan);
|
|
18551
21421
|
log.removed.push(path15.relative(hubFolder, orphan));
|
|
18552
21422
|
}
|
|
18553
21423
|
} else if (file.endsWith(".md")) {
|
|
18554
21424
|
const slug = file.slice(0, -3);
|
|
18555
21425
|
if (!mdSlugs.has(slug)) {
|
|
18556
21426
|
const orphan = path15.join(agentsDir, file);
|
|
18557
|
-
|
|
21427
|
+
fs13.unlinkSync(orphan);
|
|
18558
21428
|
log.removed.push(path15.relative(hubFolder, orphan));
|
|
18559
21429
|
}
|
|
18560
21430
|
}
|
|
@@ -18567,10 +21437,10 @@ function writeHubFolder(hubFolder, payload, options = {}) {
|
|
|
18567
21437
|
function setPreviewLabelInHubYaml(hubFolder, label) {
|
|
18568
21438
|
const yamlPath = resolveHubYamlPath(hubFolder);
|
|
18569
21439
|
if (!yamlPath) return;
|
|
18570
|
-
const obj = yaml7.load(
|
|
21440
|
+
const obj = yaml7.load(fs13.readFileSync(yamlPath, "utf-8")) ?? {};
|
|
18571
21441
|
if (label) obj.preview_label = label;
|
|
18572
21442
|
else delete obj.preview_label;
|
|
18573
|
-
|
|
21443
|
+
fs13.writeFileSync(yamlPath, yaml7.dump(obj, YAML_DUMP_OPTIONS), "utf-8");
|
|
18574
21444
|
}
|
|
18575
21445
|
function buildYamlPayload(payload) {
|
|
18576
21446
|
const result = {
|
|
@@ -18635,17 +21505,17 @@ function extractAgentFiles(payload) {
|
|
|
18635
21505
|
function writeEvalYamlFiles(hubFolder, evals, log) {
|
|
18636
21506
|
const evalsDir = path15.join(hubFolder, "evals");
|
|
18637
21507
|
if (evals.length === 0) {
|
|
18638
|
-
if (
|
|
21508
|
+
if (fs13.existsSync(evalsDir)) {
|
|
18639
21509
|
cleanEvalOrphans(hubFolder, evalsDir, /* @__PURE__ */ new Set(), log);
|
|
18640
21510
|
try {
|
|
18641
|
-
if (
|
|
21511
|
+
if (fs13.readdirSync(evalsDir).length === 0) fs13.rmdirSync(evalsDir);
|
|
18642
21512
|
} catch {
|
|
18643
21513
|
}
|
|
18644
21514
|
}
|
|
18645
21515
|
return;
|
|
18646
21516
|
}
|
|
18647
|
-
if (!
|
|
18648
|
-
|
|
21517
|
+
if (!fs13.existsSync(evalsDir)) {
|
|
21518
|
+
fs13.mkdirSync(evalsDir, { recursive: true });
|
|
18649
21519
|
}
|
|
18650
21520
|
const writtenRelPaths = /* @__PURE__ */ new Set();
|
|
18651
21521
|
for (const evalEntry of evals) {
|
|
@@ -18659,8 +21529,8 @@ function writeEvalYamlFiles(hubFolder, evals, log) {
|
|
|
18659
21529
|
}
|
|
18660
21530
|
if (setName) {
|
|
18661
21531
|
const setDir = path15.join(evalsDir, setName);
|
|
18662
|
-
if (!
|
|
18663
|
-
|
|
21532
|
+
if (!fs13.existsSync(setDir)) {
|
|
21533
|
+
fs13.mkdirSync(setDir, { recursive: true });
|
|
18664
21534
|
}
|
|
18665
21535
|
}
|
|
18666
21536
|
const yamlContent = yaml7.dump(buildEvalYamlObject(evalEntry, slug), YAML_DUMP_OPTIONS);
|
|
@@ -18670,31 +21540,31 @@ function writeEvalYamlFiles(hubFolder, evals, log) {
|
|
|
18670
21540
|
cleanEvalOrphans(hubFolder, evalsDir, writtenRelPaths, log);
|
|
18671
21541
|
}
|
|
18672
21542
|
function cleanEvalOrphans(hubFolder, evalsDir, writtenRelPaths, log) {
|
|
18673
|
-
const entries =
|
|
21543
|
+
const entries = fs13.readdirSync(evalsDir, { withFileTypes: true });
|
|
18674
21544
|
for (const entry of entries) {
|
|
18675
21545
|
const fullPath = path15.join(evalsDir, entry.name);
|
|
18676
21546
|
if (entry.isFile()) {
|
|
18677
21547
|
if (entry.name.endsWith(".yaml") && !writtenRelPaths.has(entry.name)) {
|
|
18678
|
-
|
|
21548
|
+
fs13.unlinkSync(fullPath);
|
|
18679
21549
|
log.removed.push(path15.relative(hubFolder, fullPath));
|
|
18680
21550
|
}
|
|
18681
21551
|
continue;
|
|
18682
21552
|
}
|
|
18683
21553
|
if (entry.isDirectory()) {
|
|
18684
21554
|
const setName = entry.name;
|
|
18685
|
-
const subEntries =
|
|
21555
|
+
const subEntries = fs13.readdirSync(fullPath, { withFileTypes: true });
|
|
18686
21556
|
for (const sub of subEntries) {
|
|
18687
21557
|
if (sub.isFile() && sub.name.endsWith(".yaml")) {
|
|
18688
21558
|
const relPath = `${setName}/${sub.name}`;
|
|
18689
21559
|
if (!writtenRelPaths.has(relPath)) {
|
|
18690
21560
|
const orphan = path15.join(fullPath, sub.name);
|
|
18691
|
-
|
|
21561
|
+
fs13.unlinkSync(orphan);
|
|
18692
21562
|
log.removed.push(path15.relative(hubFolder, orphan));
|
|
18693
21563
|
}
|
|
18694
21564
|
}
|
|
18695
21565
|
}
|
|
18696
21566
|
try {
|
|
18697
|
-
if (
|
|
21567
|
+
if (fs13.readdirSync(fullPath).length === 0) fs13.rmdirSync(fullPath);
|
|
18698
21568
|
} catch {
|
|
18699
21569
|
}
|
|
18700
21570
|
}
|
|
@@ -18733,17 +21603,17 @@ function buildJourneyYamlObject(journeyEntry, slug) {
|
|
|
18733
21603
|
function writeJourneyYamlFiles(hubFolder, journeys, log) {
|
|
18734
21604
|
const journeysDir = path15.join(hubFolder, "journeys");
|
|
18735
21605
|
if (journeys.length === 0) {
|
|
18736
|
-
if (
|
|
21606
|
+
if (fs13.existsSync(journeysDir)) {
|
|
18737
21607
|
cleanJourneyOrphans(hubFolder, journeysDir, /* @__PURE__ */ new Set(), log);
|
|
18738
21608
|
try {
|
|
18739
|
-
if (
|
|
21609
|
+
if (fs13.readdirSync(journeysDir).length === 0) fs13.rmdirSync(journeysDir);
|
|
18740
21610
|
} catch {
|
|
18741
21611
|
}
|
|
18742
21612
|
}
|
|
18743
21613
|
return;
|
|
18744
21614
|
}
|
|
18745
|
-
if (!
|
|
18746
|
-
|
|
21615
|
+
if (!fs13.existsSync(journeysDir)) {
|
|
21616
|
+
fs13.mkdirSync(journeysDir, { recursive: true });
|
|
18747
21617
|
}
|
|
18748
21618
|
const writtenFiles = /* @__PURE__ */ new Set();
|
|
18749
21619
|
const usedSlugs = /* @__PURE__ */ new Set();
|
|
@@ -18757,11 +21627,11 @@ function writeJourneyYamlFiles(hubFolder, journeys, log) {
|
|
|
18757
21627
|
cleanJourneyOrphans(hubFolder, journeysDir, writtenFiles, log);
|
|
18758
21628
|
}
|
|
18759
21629
|
function cleanJourneyOrphans(hubFolder, journeysDir, writtenFiles, log) {
|
|
18760
|
-
const entries =
|
|
21630
|
+
const entries = fs13.readdirSync(journeysDir, { withFileTypes: true });
|
|
18761
21631
|
for (const entry of entries) {
|
|
18762
21632
|
if (entry.isFile() && entry.name.endsWith(".yaml") && !writtenFiles.has(entry.name)) {
|
|
18763
21633
|
const orphan = path15.join(journeysDir, entry.name);
|
|
18764
|
-
|
|
21634
|
+
fs13.unlinkSync(orphan);
|
|
18765
21635
|
log.removed.push(path15.relative(hubFolder, orphan));
|
|
18766
21636
|
}
|
|
18767
21637
|
}
|
|
@@ -18775,12 +21645,12 @@ function writeResourceFiles(hubFolder, resources, log) {
|
|
|
18775
21645
|
const resDir = path15.join(resourcesDir, resSlug);
|
|
18776
21646
|
writeResourceFileTree(resDir, resource.files || [], hubFolder, log);
|
|
18777
21647
|
}
|
|
18778
|
-
if (
|
|
18779
|
-
const existingDirs =
|
|
21648
|
+
if (fs13.existsSync(resourcesDir)) {
|
|
21649
|
+
const existingDirs = fs13.readdirSync(resourcesDir, { withFileTypes: true });
|
|
18780
21650
|
for (const entry of existingDirs) {
|
|
18781
21651
|
if (entry.isDirectory() && !currentSlugs.has(entry.name)) {
|
|
18782
21652
|
const orphanDir = path15.join(resourcesDir, entry.name);
|
|
18783
|
-
|
|
21653
|
+
fs13.rmSync(orphanDir, { recursive: true, force: true });
|
|
18784
21654
|
log.removed.push(`${path15.relative(hubFolder, orphanDir)}/`);
|
|
18785
21655
|
}
|
|
18786
21656
|
}
|
|
@@ -18869,7 +21739,7 @@ var init_terminal_output = __esm({
|
|
|
18869
21739
|
});
|
|
18870
21740
|
|
|
18871
21741
|
// src/lib/base-workspace.ts
|
|
18872
|
-
import * as
|
|
21742
|
+
import * as fs14 from "fs";
|
|
18873
21743
|
import * as path17 from "path";
|
|
18874
21744
|
import * as yaml8 from "js-yaml";
|
|
18875
21745
|
function readBaseMeta(folder) {
|
|
@@ -18887,7 +21757,7 @@ function readBaseMeta(folder) {
|
|
|
18887
21757
|
function listBaseFolders(basesDir) {
|
|
18888
21758
|
let entries;
|
|
18889
21759
|
try {
|
|
18890
|
-
entries =
|
|
21760
|
+
entries = fs14.readdirSync(basesDir).filter((entry) => !entry.startsWith("."));
|
|
18891
21761
|
} catch {
|
|
18892
21762
|
return [];
|
|
18893
21763
|
}
|
|
@@ -18974,7 +21844,7 @@ function resolveBaseSelectorToId(gitRoot, selector) {
|
|
|
18974
21844
|
}
|
|
18975
21845
|
function hasBaseMetaFile(folder) {
|
|
18976
21846
|
try {
|
|
18977
|
-
return
|
|
21847
|
+
return fs14.lstatSync(path17.join(folder, BASE_META_FILE)).isFile();
|
|
18978
21848
|
} catch {
|
|
18979
21849
|
return false;
|
|
18980
21850
|
}
|
|
@@ -19440,7 +22310,7 @@ var init_types2 = __esm({
|
|
|
19440
22310
|
});
|
|
19441
22311
|
|
|
19442
22312
|
// src/data/config-as-code/config-writer.ts
|
|
19443
|
-
import * as
|
|
22313
|
+
import * as fs15 from "fs";
|
|
19444
22314
|
import * as path19 from "path";
|
|
19445
22315
|
import * as yaml9 from "js-yaml";
|
|
19446
22316
|
function dump5(value) {
|
|
@@ -19475,14 +22345,14 @@ function pruneOrphans(folder, dir, keep, log) {
|
|
|
19475
22345
|
if (!ensureRealSubdirNoSymlink(folder, dir, false)) return;
|
|
19476
22346
|
let entries;
|
|
19477
22347
|
try {
|
|
19478
|
-
entries =
|
|
22348
|
+
entries = fs15.readdirSync(dir);
|
|
19479
22349
|
} catch {
|
|
19480
22350
|
return;
|
|
19481
22351
|
}
|
|
19482
22352
|
for (const file of entries) {
|
|
19483
22353
|
if (!file.endsWith(".yaml") || keep.has(file)) continue;
|
|
19484
22354
|
const abs = path19.join(dir, file);
|
|
19485
|
-
|
|
22355
|
+
fs15.rmSync(abs);
|
|
19486
22356
|
log.removed.push(path19.relative(folder, abs));
|
|
19487
22357
|
}
|
|
19488
22358
|
}
|
|
@@ -19496,7 +22366,7 @@ function metaFileObject(meta) {
|
|
|
19496
22366
|
function writeBaseFolder(folder, meta, config) {
|
|
19497
22367
|
const delta = { changed: [], removed: [] };
|
|
19498
22368
|
const parent = path19.dirname(folder);
|
|
19499
|
-
|
|
22369
|
+
fs15.mkdirSync(parent, { recursive: true });
|
|
19500
22370
|
if (!ensureRealSubdirNoSymlink(parent, folder, true)) {
|
|
19501
22371
|
throw expected(
|
|
19502
22372
|
`Refusing to write ${folder}: the path crosses a symlink. Remove it and pull again.`
|
|
@@ -19523,7 +22393,7 @@ function writeBaseFolder(folder, meta, config) {
|
|
|
19523
22393
|
for (const deprecated of DEPRECATED_ENTITY_DIRS) {
|
|
19524
22394
|
const dir = path19.join(folder, deprecated);
|
|
19525
22395
|
if (ensureRealSubdirNoSymlink(folder, dir, false)) {
|
|
19526
|
-
|
|
22396
|
+
fs15.rmSync(dir, { recursive: true, force: true });
|
|
19527
22397
|
}
|
|
19528
22398
|
}
|
|
19529
22399
|
return delta;
|
|
@@ -19675,7 +22545,7 @@ var init_api = __esm({
|
|
|
19675
22545
|
});
|
|
19676
22546
|
|
|
19677
22547
|
// src/data/config-as-code/config-parser.ts
|
|
19678
|
-
import * as
|
|
22548
|
+
import * as fs16 from "fs";
|
|
19679
22549
|
import * as path20 from "path";
|
|
19680
22550
|
import * as yaml10 from "js-yaml";
|
|
19681
22551
|
function readEntityDir(folder, dir) {
|
|
@@ -19684,7 +22554,7 @@ function readEntityDir(folder, dir) {
|
|
|
19684
22554
|
}
|
|
19685
22555
|
if (!isDirectory(dir)) return [];
|
|
19686
22556
|
const out = [];
|
|
19687
|
-
for (const file of
|
|
22557
|
+
for (const file of fs16.readdirSync(dir).sort()) {
|
|
19688
22558
|
if (!file.endsWith(".yaml")) continue;
|
|
19689
22559
|
const abs = path20.join(dir, file);
|
|
19690
22560
|
const bytes = readFileNoFollow(folder, abs);
|
|
@@ -20071,7 +22941,7 @@ __export(push_exports, {
|
|
|
20071
22941
|
shouldWarnIgnoredPreviewLabel: () => shouldWarnIgnoredPreviewLabel,
|
|
20072
22942
|
syncAfterPush: () => syncAfterPush
|
|
20073
22943
|
});
|
|
20074
|
-
import * as
|
|
22944
|
+
import * as fs17 from "fs";
|
|
20075
22945
|
import * as path22 from "path";
|
|
20076
22946
|
import * as yaml11 from "js-yaml";
|
|
20077
22947
|
function parseArgs5(args2) {
|
|
@@ -20182,11 +23052,11 @@ function printLocalFileChanges(delta) {
|
|
|
20182
23052
|
async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, remoteConfig) {
|
|
20183
23053
|
const agentsDir = path22.join(hubFolder, "agents");
|
|
20184
23054
|
let agentsWithIds = [];
|
|
20185
|
-
if (
|
|
20186
|
-
const yamlFiles =
|
|
23055
|
+
if (fs17.existsSync(agentsDir)) {
|
|
23056
|
+
const yamlFiles = fs17.readdirSync(agentsDir).filter((f) => f.endsWith(".yaml"));
|
|
20187
23057
|
for (const file of yamlFiles) {
|
|
20188
23058
|
try {
|
|
20189
|
-
const content =
|
|
23059
|
+
const content = fs17.readFileSync(path22.join(agentsDir, file), "utf-8");
|
|
20190
23060
|
const agent = yaml11.load(content);
|
|
20191
23061
|
if (agent?.id && agent.name) {
|
|
20192
23062
|
agentsWithIds.push({ id: agent.id, name: agent.name });
|
|
@@ -20199,7 +23069,7 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
20199
23069
|
if (agentsWithIds.length === 0) {
|
|
20200
23070
|
const yamlPath = resolveHubYamlPath(hubFolder);
|
|
20201
23071
|
if (!yamlPath) return;
|
|
20202
|
-
const yamlContent =
|
|
23072
|
+
const yamlContent = fs17.readFileSync(yamlPath, "utf-8");
|
|
20203
23073
|
const config = yaml11.load(yamlContent);
|
|
20204
23074
|
agentsWithIds = (config.agents || []).filter((a) => !!a.id && !!a.name);
|
|
20205
23075
|
}
|
|
@@ -20231,18 +23101,18 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
20231
23101
|
}
|
|
20232
23102
|
}
|
|
20233
23103
|
if (renames.length === 0) return;
|
|
20234
|
-
if (!
|
|
20235
|
-
for (const file of
|
|
23104
|
+
if (!fs17.existsSync(agentsDir)) return;
|
|
23105
|
+
for (const file of fs17.readdirSync(agentsDir)) {
|
|
20236
23106
|
if (file.startsWith("__rename_temp_") && (file.endsWith(".md") || file.endsWith(".yaml"))) {
|
|
20237
23107
|
console.warn(` Warning: removing orphaned temp file agents/${file}`);
|
|
20238
|
-
|
|
23108
|
+
fs17.unlinkSync(path22.join(agentsDir, file));
|
|
20239
23109
|
}
|
|
20240
23110
|
}
|
|
20241
23111
|
const renameFileIfExists = (dir, oldName, newName) => {
|
|
20242
23112
|
const oldPath = path22.join(dir, oldName);
|
|
20243
23113
|
const newPath = path22.join(dir, newName);
|
|
20244
|
-
if (!
|
|
20245
|
-
|
|
23114
|
+
if (!fs17.existsSync(oldPath)) return false;
|
|
23115
|
+
fs17.renameSync(oldPath, newPath);
|
|
20246
23116
|
return true;
|
|
20247
23117
|
};
|
|
20248
23118
|
const oldSlugs = new Set(renames.map((r) => r.oldSlug));
|
|
@@ -20275,9 +23145,9 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
20275
23145
|
}
|
|
20276
23146
|
} else {
|
|
20277
23147
|
for (const { oldSlug, newSlug } of renames) {
|
|
20278
|
-
const hasOldFile = extensions.some((ext) =>
|
|
23148
|
+
const hasOldFile = extensions.some((ext) => fs17.existsSync(path22.join(agentsDir, `${oldSlug}${ext}`)));
|
|
20279
23149
|
if (!hasOldFile) continue;
|
|
20280
|
-
const hasNewFile = extensions.some((ext) =>
|
|
23150
|
+
const hasNewFile = extensions.some((ext) => fs17.existsSync(path22.join(agentsDir, `${newSlug}${ext}`)));
|
|
20281
23151
|
if (hasNewFile) {
|
|
20282
23152
|
console.warn(` Warning: skipping rename agents/${oldSlug}.* \u2192 agents/${newSlug}.* (target already exists)`);
|
|
20283
23153
|
continue;
|
|
@@ -20292,7 +23162,7 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
20292
23162
|
if (completedRenames.length === 0) return;
|
|
20293
23163
|
const mainYamlPath = resolveHubYamlPath(hubFolder);
|
|
20294
23164
|
if (mainYamlPath) {
|
|
20295
|
-
const mainYamlContent =
|
|
23165
|
+
const mainYamlContent = fs17.readFileSync(mainYamlPath, "utf-8");
|
|
20296
23166
|
const substitutionMap = /* @__PURE__ */ new Map();
|
|
20297
23167
|
for (const { oldSlug, newSlug } of completedRenames) {
|
|
20298
23168
|
substitutionMap.set(`agents/${oldSlug}.md`, `agents/${newSlug}.md`);
|
|
@@ -20303,7 +23173,7 @@ async function autoRenameAgentFiles(client, hubId, hubFolder, organizationId, re
|
|
|
20303
23173
|
(_match, prefix, pathMatch) => `${prefix}${substitutionMap.get(pathMatch) ?? pathMatch}`
|
|
20304
23174
|
);
|
|
20305
23175
|
if (updatedYaml !== mainYamlContent) {
|
|
20306
|
-
|
|
23176
|
+
fs17.writeFileSync(mainYamlPath, updatedYaml, "utf-8");
|
|
20307
23177
|
console.log(` Updated instructions paths in ${path22.basename(mainYamlPath)}`);
|
|
20308
23178
|
}
|
|
20309
23179
|
}
|
|
@@ -20415,7 +23285,7 @@ New hub: "${newHub.hubName}" (${hubType})`);
|
|
|
20415
23285
|
process.exit(1);
|
|
20416
23286
|
}
|
|
20417
23287
|
console.log(`Hub created: ${createdHub.hub_name} (${hubId})`);
|
|
20418
|
-
const content =
|
|
23288
|
+
const content = fs17.readFileSync(hubYamlPath, "utf-8");
|
|
20419
23289
|
const hasVersion = content.match(/^version:\s/m);
|
|
20420
23290
|
let updated;
|
|
20421
23291
|
if (hasVersion) {
|
|
@@ -20431,7 +23301,7 @@ hub_id: "${hubId}"
|
|
|
20431
23301
|
hub_environment: preview
|
|
20432
23302
|
${content}`;
|
|
20433
23303
|
}
|
|
20434
|
-
|
|
23304
|
+
fs17.writeFileSync(hubYamlPath, updated, "utf-8");
|
|
20435
23305
|
seedScopeIfEmpty("hubs", hubId);
|
|
20436
23306
|
await pushSingleHub(client, hubId, newHub.hubFolder, opts.autoConfirm, opts.organizationId, { skipAgentRename: true });
|
|
20437
23307
|
}
|
|
@@ -20477,7 +23347,7 @@ async function pushCommand(args2) {
|
|
|
20477
23347
|
const client = new ApiClient({ apiUrl: config.api_url, accessToken });
|
|
20478
23348
|
const workspaceDir = resolveWorkspaceDir();
|
|
20479
23349
|
const wsLabel = hubsDirLabel(gitRoot);
|
|
20480
|
-
if (!
|
|
23350
|
+
if (!fs17.existsSync(workspaceDir)) {
|
|
20481
23351
|
console.error(`No ${wsLabel}/ directory found. Run \`wayai pull\` first or create hub files in ${wsLabel}/<hub>/hub.yaml.`);
|
|
20482
23352
|
process.exit(1);
|
|
20483
23353
|
}
|
|
@@ -20533,7 +23403,7 @@ __export(pull_exports, {
|
|
|
20533
23403
|
resolveHubTarget: () => resolveHubTarget,
|
|
20534
23404
|
writeProductionMirror: () => writeProductionMirror2
|
|
20535
23405
|
});
|
|
20536
|
-
import * as
|
|
23406
|
+
import * as fs18 from "fs";
|
|
20537
23407
|
import * as path23 from "path";
|
|
20538
23408
|
function parseArgs6(args2) {
|
|
20539
23409
|
return { autoConfirm: args2.includes("--yes") || args2.includes("-y") };
|
|
@@ -20600,7 +23470,7 @@ async function pullCommand(args2) {
|
|
|
20600
23470
|
payload.preview_label,
|
|
20601
23471
|
payload.branch_name
|
|
20602
23472
|
);
|
|
20603
|
-
|
|
23473
|
+
fs18.mkdirSync(path23.dirname(hubFolder), { recursive: true });
|
|
20604
23474
|
console.log("Writing hub configuration...");
|
|
20605
23475
|
await materializeHubFolder(hubFolder, payload);
|
|
20606
23476
|
const finalFolder = autoRenameHubFolder(hubFolder, payload.hub.name, payload.hub_environment, payload.hub_id, payload.preview_label, payload.branch_name);
|
|
@@ -20654,7 +23524,7 @@ async function pullCommand(args2) {
|
|
|
20654
23524
|
}
|
|
20655
23525
|
async function writeProductionMirror2(workspaceDir, prodPayload) {
|
|
20656
23526
|
const folder = resolveHubFolder(workspaceDir, prodPayload.hub_id, prodPayload.hub.name, "production", null, null);
|
|
20657
|
-
|
|
23527
|
+
fs18.mkdirSync(path23.dirname(folder), { recursive: true });
|
|
20658
23528
|
await materializeHubFolder(folder, prodPayload, { seedAgentContext: false });
|
|
20659
23529
|
const finalFolder = autoRenameHubFolder(folder, prodPayload.hub.name, "production", prodPayload.hub_id, null, null);
|
|
20660
23530
|
prependMirrorMarker(finalFolder, prodPayload.hub_id);
|
|
@@ -20672,11 +23542,11 @@ async function mirrorLinkedProduction2(client, workspaceDir, productionHubId, or
|
|
|
20672
23542
|
function prependMirrorMarker(hubFolder, productionHubId) {
|
|
20673
23543
|
const hubYaml = path23.join(hubFolder, "hub.yaml");
|
|
20674
23544
|
try {
|
|
20675
|
-
const content =
|
|
23545
|
+
const content = fs18.readFileSync(hubYaml, "utf-8");
|
|
20676
23546
|
if (content.startsWith(MIRROR_MARKER_PREFIX2)) return;
|
|
20677
23547
|
const marker = `${MIRROR_MARKER_PREFIX2} ${productionHubId}. Edits are ignored; push is blocked. Edit the linked preview hub instead.
|
|
20678
23548
|
`;
|
|
20679
|
-
|
|
23549
|
+
fs18.writeFileSync(hubYaml, marker + content, "utf-8");
|
|
20680
23550
|
} catch {
|
|
20681
23551
|
}
|
|
20682
23552
|
}
|
|
@@ -20720,7 +23590,7 @@ __export(create_exports, {
|
|
|
20720
23590
|
createCommand: () => createCommand
|
|
20721
23591
|
});
|
|
20722
23592
|
import * as path24 from "path";
|
|
20723
|
-
import * as
|
|
23593
|
+
import * as fs19 from "fs";
|
|
20724
23594
|
function parseArgs7(args2) {
|
|
20725
23595
|
let autoConfirm = false;
|
|
20726
23596
|
let folderSelector;
|
|
@@ -20747,7 +23617,7 @@ async function createCommand(args2) {
|
|
|
20747
23617
|
const gitRoot = findGitRoot();
|
|
20748
23618
|
const wsLabel = hubsDirLabel(gitRoot);
|
|
20749
23619
|
if (gitRoot) warnLayoutOnce(gitRoot);
|
|
20750
|
-
if (!
|
|
23620
|
+
if (!fs19.existsSync(workspaceDir)) {
|
|
20751
23621
|
console.error(`No ${wsLabel}/ directory found. Create hub files in ${wsLabel}/<hub>/hub.yaml with \`hub: { name: ... }\` first.`);
|
|
20752
23622
|
process.exit(1);
|
|
20753
23623
|
}
|
|
@@ -20881,7 +23751,7 @@ var replicate_exports = {};
|
|
|
20881
23751
|
__export(replicate_exports, {
|
|
20882
23752
|
replicateCommand: () => replicateCommand
|
|
20883
23753
|
});
|
|
20884
|
-
import * as
|
|
23754
|
+
import * as fs20 from "fs";
|
|
20885
23755
|
import * as path25 from "path";
|
|
20886
23756
|
function parseArgs9(args2) {
|
|
20887
23757
|
let label;
|
|
@@ -20928,8 +23798,8 @@ async function replicateCommand(args2) {
|
|
|
20928
23798
|
payload.preview_label,
|
|
20929
23799
|
payload.branch_name
|
|
20930
23800
|
);
|
|
20931
|
-
const folderPreExisted =
|
|
20932
|
-
|
|
23801
|
+
const folderPreExisted = fs20.existsSync(hubFolder);
|
|
23802
|
+
fs20.mkdirSync(path25.dirname(hubFolder), { recursive: true });
|
|
20933
23803
|
const delta = await materializeHubFolder(hubFolder, payload);
|
|
20934
23804
|
hubFolder = autoRenameHubFolder(
|
|
20935
23805
|
hubFolder,
|
|
@@ -21356,7 +24226,7 @@ __export(migrate_exports, {
|
|
|
21356
24226
|
migrateCommand: () => migrateCommand
|
|
21357
24227
|
});
|
|
21358
24228
|
import { execFileSync as execFileSync3 } from "child_process";
|
|
21359
|
-
import * as
|
|
24229
|
+
import * as fs21 from "fs";
|
|
21360
24230
|
import * as path29 from "path";
|
|
21361
24231
|
function isTracked(gitRoot, p) {
|
|
21362
24232
|
try {
|
|
@@ -21370,7 +24240,7 @@ function isTracked(gitRoot, p) {
|
|
|
21370
24240
|
}
|
|
21371
24241
|
}
|
|
21372
24242
|
function moveDir(gitRoot, from, to) {
|
|
21373
|
-
|
|
24243
|
+
fs21.mkdirSync(path29.dirname(to), { recursive: true });
|
|
21374
24244
|
if (isTracked(gitRoot, from)) {
|
|
21375
24245
|
try {
|
|
21376
24246
|
execFileSync3("git", ["mv", path29.relative(gitRoot, from), path29.relative(gitRoot, to)], {
|
|
@@ -21381,7 +24251,7 @@ function moveDir(gitRoot, from, to) {
|
|
|
21381
24251
|
} catch {
|
|
21382
24252
|
}
|
|
21383
24253
|
}
|
|
21384
|
-
|
|
24254
|
+
fs21.renameSync(from, to);
|
|
21385
24255
|
return "fs";
|
|
21386
24256
|
}
|
|
21387
24257
|
async function migrateCommand(_args) {
|
|
@@ -21544,12 +24414,12 @@ var send_message_exports = {};
|
|
|
21544
24414
|
__export(send_message_exports, {
|
|
21545
24415
|
sendMessageCommand: () => sendMessageCommand
|
|
21546
24416
|
});
|
|
21547
|
-
import * as
|
|
24417
|
+
import * as fs22 from "fs";
|
|
21548
24418
|
import * as path30 from "path";
|
|
21549
24419
|
function statAttachment(filePath) {
|
|
21550
24420
|
let stat2;
|
|
21551
24421
|
try {
|
|
21552
|
-
stat2 =
|
|
24422
|
+
stat2 = fs22.statSync(filePath);
|
|
21553
24423
|
} catch {
|
|
21554
24424
|
console.error(`Error: file not found: ${filePath}`);
|
|
21555
24425
|
process.exit(1);
|
|
@@ -21565,7 +24435,7 @@ function readAttachment(filePath, size) {
|
|
|
21565
24435
|
const ext = path30.extname(fileName).replace(/^\./, "");
|
|
21566
24436
|
return {
|
|
21567
24437
|
file_name: fileName,
|
|
21568
|
-
file_binary:
|
|
24438
|
+
file_binary: fs22.readFileSync(filePath).toString("base64"),
|
|
21569
24439
|
file_size: size,
|
|
21570
24440
|
...ext && { file_extension: ext }
|
|
21571
24441
|
};
|
|
@@ -23764,7 +26634,7 @@ var eval_capture_exports = {};
|
|
|
23764
26634
|
__export(eval_capture_exports, {
|
|
23765
26635
|
evalCaptureCommand: () => evalCaptureCommand
|
|
23766
26636
|
});
|
|
23767
|
-
import * as
|
|
26637
|
+
import * as fs23 from "fs";
|
|
23768
26638
|
import * as path31 from "path";
|
|
23769
26639
|
import * as yaml12 from "js-yaml";
|
|
23770
26640
|
function isValidSetName(name) {
|
|
@@ -23838,7 +26708,7 @@ async function evalCaptureCommand(args2) {
|
|
|
23838
26708
|
console.error(`Resolved path "${path31.relative(hubFolder, targetPath)}" escapes evals/. Aborting.`);
|
|
23839
26709
|
process.exit(1);
|
|
23840
26710
|
}
|
|
23841
|
-
if (
|
|
26711
|
+
if (fs23.existsSync(targetPath)) {
|
|
23842
26712
|
console.error(`File already exists: ${path31.relative(hubFolder, targetPath)}. Use --name to choose a different name.`);
|
|
23843
26713
|
process.exit(1);
|
|
23844
26714
|
}
|
|
@@ -23871,8 +26741,8 @@ async function evalCaptureCommand(args2) {
|
|
|
23871
26741
|
...captured.evaluator_instructions ? { evaluator_instructions: captured.evaluator_instructions } : {}
|
|
23872
26742
|
};
|
|
23873
26743
|
const yamlObj = buildEvalYamlObject(evalEntry, slug);
|
|
23874
|
-
|
|
23875
|
-
|
|
26744
|
+
fs23.mkdirSync(targetDir, { recursive: true });
|
|
26745
|
+
fs23.writeFileSync(targetPath, yaml12.dump(yamlObj, YAML_DUMP_OPTIONS), "utf-8");
|
|
23876
26746
|
const relPath = path31.relative(process.cwd(), targetPath);
|
|
23877
26747
|
console.log(`
|
|
23878
26748
|
Wrote ${relPath}`);
|
|
@@ -25244,20 +28114,20 @@ var init_set_connection_credential = __esm({
|
|
|
25244
28114
|
});
|
|
25245
28115
|
|
|
25246
28116
|
// src/lib/org-workspace.ts
|
|
25247
|
-
import * as
|
|
28117
|
+
import * as fs24 from "fs";
|
|
25248
28118
|
import * as path32 from "path";
|
|
25249
28119
|
import * as yaml13 from "js-yaml";
|
|
25250
28120
|
function getOrgDir(gitRoot) {
|
|
25251
28121
|
return resolveLayout(gitRoot).orgDir;
|
|
25252
28122
|
}
|
|
25253
28123
|
function orgManifestExists(orgDir) {
|
|
25254
|
-
return
|
|
28124
|
+
return fs24.existsSync(path32.join(orgDir, ORG_MANIFEST_NAME));
|
|
25255
28125
|
}
|
|
25256
28126
|
function parseOrgResources(orgDir) {
|
|
25257
28127
|
const manifestPath = path32.join(orgDir, ORG_MANIFEST_NAME);
|
|
25258
28128
|
let manifest = {};
|
|
25259
|
-
if (
|
|
25260
|
-
manifest = yaml13.load(
|
|
28129
|
+
if (fs24.existsSync(manifestPath)) {
|
|
28130
|
+
manifest = yaml13.load(fs24.readFileSync(manifestPath, "utf-8")) ?? {};
|
|
25261
28131
|
}
|
|
25262
28132
|
const rawResources = Array.isArray(manifest.resources) ? manifest.resources : [];
|
|
25263
28133
|
const resourcesDir = path32.join(orgDir, "resources");
|
|
@@ -25273,7 +28143,7 @@ function parseOrgResources(orgDir) {
|
|
|
25273
28143
|
if (Array.isArray(res.tags)) resource.tags = res.tags;
|
|
25274
28144
|
if (Array.isArray(res.folders)) resource.folders = res.folders;
|
|
25275
28145
|
const resDir = path32.join(resourcesDir, slugify(resource.name));
|
|
25276
|
-
if (
|
|
28146
|
+
if (fs24.existsSync(resDir)) {
|
|
25277
28147
|
const files = scanResourceFiles(resDir, "");
|
|
25278
28148
|
if (files.length > 0) resource.files = files;
|
|
25279
28149
|
}
|
|
@@ -25282,13 +28152,13 @@ function parseOrgResources(orgDir) {
|
|
|
25282
28152
|
return { version: 1, resources };
|
|
25283
28153
|
}
|
|
25284
28154
|
function writeOrgResources(orgDir, payload) {
|
|
25285
|
-
|
|
28155
|
+
fs24.mkdirSync(orgDir, { recursive: true });
|
|
25286
28156
|
const resources = payload.resources ?? [];
|
|
25287
28157
|
const manifestResources = resources.map((r) => {
|
|
25288
28158
|
const { files: _files, ...rest } = r;
|
|
25289
28159
|
return rest;
|
|
25290
28160
|
});
|
|
25291
|
-
|
|
28161
|
+
fs24.writeFileSync(
|
|
25292
28162
|
path32.join(orgDir, ORG_MANIFEST_NAME),
|
|
25293
28163
|
yaml13.dump({ version: 1, resources: manifestResources }, YAML_DUMP_OPTIONS),
|
|
25294
28164
|
"utf-8"
|
|
@@ -25300,10 +28170,10 @@ function writeOrgResources(orgDir, payload) {
|
|
|
25300
28170
|
currentSlugs.add(resSlug);
|
|
25301
28171
|
writeResourceFileTree(path32.join(resourcesDir, resSlug), resource.files || [], orgDir);
|
|
25302
28172
|
}
|
|
25303
|
-
if (
|
|
25304
|
-
for (const entry of
|
|
28173
|
+
if (fs24.existsSync(resourcesDir)) {
|
|
28174
|
+
for (const entry of fs24.readdirSync(resourcesDir, { withFileTypes: true })) {
|
|
25305
28175
|
if (entry.isDirectory() && !currentSlugs.has(entry.name)) {
|
|
25306
|
-
|
|
28176
|
+
fs24.rmSync(path32.join(resourcesDir, entry.name), { recursive: true, force: true });
|
|
25307
28177
|
}
|
|
25308
28178
|
}
|
|
25309
28179
|
}
|
|
@@ -25608,7 +28478,7 @@ var init_report_edit_args = __esm({
|
|
|
25608
28478
|
});
|
|
25609
28479
|
|
|
25610
28480
|
// src/lib/file-map.ts
|
|
25611
|
-
import * as
|
|
28481
|
+
import * as fs25 from "fs";
|
|
25612
28482
|
import * as path33 from "path";
|
|
25613
28483
|
function isSafeRelPath(rel) {
|
|
25614
28484
|
if (rel.length === 0 || rel.length > 300) return false;
|
|
@@ -25625,8 +28495,8 @@ function writeFileMap(targetDir, files) {
|
|
|
25625
28495
|
throw new Error(`Refusing to write unsafe path: ${rel}`);
|
|
25626
28496
|
}
|
|
25627
28497
|
const abs = path33.join(targetDir, rel);
|
|
25628
|
-
|
|
25629
|
-
|
|
28498
|
+
fs25.mkdirSync(path33.dirname(abs), { recursive: true });
|
|
28499
|
+
fs25.writeFileSync(abs, body, "utf-8");
|
|
25630
28500
|
written.push(rel);
|
|
25631
28501
|
}
|
|
25632
28502
|
return written;
|
|
@@ -25642,7 +28512,7 @@ var admin_exports = {};
|
|
|
25642
28512
|
__export(admin_exports, {
|
|
25643
28513
|
adminCommand: () => adminCommand
|
|
25644
28514
|
});
|
|
25645
|
-
import * as
|
|
28515
|
+
import * as fs26 from "fs";
|
|
25646
28516
|
import * as path34 from "path";
|
|
25647
28517
|
async function adminCommand(args2) {
|
|
25648
28518
|
const [group, ...afterGroup] = args2;
|
|
@@ -25958,7 +28828,7 @@ async function runArchiveRead(positional, flagArgs) {
|
|
|
25958
28828
|
exitOnApiError(err);
|
|
25959
28829
|
throw err;
|
|
25960
28830
|
}
|
|
25961
|
-
|
|
28831
|
+
fs26.writeFileSync(outPath, zip);
|
|
25962
28832
|
console.log(`Wrote ${zip.byteLength} bytes to ${outPath}`);
|
|
25963
28833
|
return;
|
|
25964
28834
|
}
|
|
@@ -26100,7 +28970,7 @@ async function runSkillInstall(positional) {
|
|
|
26100
28970
|
throw err;
|
|
26101
28971
|
}
|
|
26102
28972
|
const root = findGitRoot() ?? process.cwd();
|
|
26103
|
-
const present = HARNESS_SKILL_DIRS.filter((dir) =>
|
|
28973
|
+
const present = HARNESS_SKILL_DIRS.filter((dir) => fs26.existsSync(path34.join(root, dir)));
|
|
26104
28974
|
const targets = present.length > 0 ? present : HARNESS_SKILL_DIRS;
|
|
26105
28975
|
const fileCount = Object.keys(res.files).length;
|
|
26106
28976
|
const relDirs = targets.map((harness) => {
|
|
@@ -28099,7 +30969,7 @@ var init_import = __esm({
|
|
|
28099
30969
|
|
|
28100
30970
|
// src/data/commands/providers.ts
|
|
28101
30971
|
import { Command as Command5 } from "commander";
|
|
28102
|
-
import { writeFileSync as
|
|
30972
|
+
import { writeFileSync as writeFileSync14 } from "fs";
|
|
28103
30973
|
function providerSegment(provider) {
|
|
28104
30974
|
if (!VALID_PROVIDERS.includes(provider)) {
|
|
28105
30975
|
throw expected(`Unknown provider ${JSON.stringify(provider)}. Expected one of: ${VALID_PROVIDERS_HELP}.`);
|
|
@@ -28132,7 +31002,7 @@ function buildBasesProvidersCommand() {
|
|
|
28132
31002
|
);
|
|
28133
31003
|
if (opts.to) {
|
|
28134
31004
|
try {
|
|
28135
|
-
|
|
31005
|
+
writeFileSync14(opts.to, JSON.stringify(data, null, 2));
|
|
28136
31006
|
} catch (e) {
|
|
28137
31007
|
throw expected(`--to ${opts.to}: ${e instanceof Error ? e.message : "could not be written"}`);
|
|
28138
31008
|
}
|
|
@@ -29217,7 +32087,7 @@ var init_file_types = __esm({
|
|
|
29217
32087
|
|
|
29218
32088
|
// src/data/commands/files.ts
|
|
29219
32089
|
import { Command as Command12 } from "commander";
|
|
29220
|
-
import { readFileSync as readFileSync24, writeFileSync as
|
|
32090
|
+
import { readFileSync as readFileSync24, writeFileSync as writeFileSync15 } from "fs";
|
|
29221
32091
|
import { basename as basename18 } from "path";
|
|
29222
32092
|
function renderFileDiff(fileType, filePath, from, to, d) {
|
|
29223
32093
|
console.log(sanitizeTerminalText(`${fileType}/${filePath}: v${from} \u2192 v${to}`));
|
|
@@ -29297,7 +32167,7 @@ function buildFilesCommand() {
|
|
|
29297
32167
|
const { bytes } = await client.download(
|
|
29298
32168
|
`/v1/${base}/files/${pathSegment(fileType, "file_type")}/${encoded}${versionQs ? `?${versionQs}` : ""}`
|
|
29299
32169
|
);
|
|
29300
|
-
|
|
32170
|
+
writeFileSync15(out, bytes);
|
|
29301
32171
|
console.log(`Downloaded to ${out}`);
|
|
29302
32172
|
});
|
|
29303
32173
|
files.command("history <file_type> <path>").description("List the content versions of a file (newest first)").option("--limit <n>", "Max versions to return").option("--offset <n>", "Pagination offset").action(async function(fileType, filePath, opts) {
|