@botpress/adk-cli
Version:
Command-line interface for the Botpress Agent Development Kit (ADK)
13,551 lines • 601 kB
JavaScript
// @bun
import {
Uk
} from "./chunk-3xrpxgq4.js";
import {
Cognitive
} from "./chunk-rfm3jr1m.js";
import {
require_lib
} from "./chunk-s2akeqpw.js";
import {
makeGetTokenizer
} from "./chunk-na956zz3.js";
import {
exports_exports,
src_default,
transforms_exports
} from "./chunk-54qt5g7m.js";
import {
__commonJS,
__require,
__toESM
} from "./chunk-dhs2bg35.js";
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/bot-use-cases.js
var require_bot_use_cases = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.BOT_USE_CASES = undefined;
exports.BOT_USE_CASES = {
CUSTOMER_SUPPORT: "customer-support",
BRAND_ASSISTANT: "brand-assistant",
PRODUCT_RECOMMENDATION: "product-recommendation",
OTHER: "other"
};
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/limits.js
var require_limits = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.limitConfigs = undefined;
exports.limitConfigs = {
bot_configuration_bytes: {
value: 20480,
unit: "bytes"
},
bot_installed_integrations_count: {
value: 30,
unit: "count"
},
bot_installed_plugins_count: {
value: 30,
unit: "count"
},
bot_integration_configuration_bytes: {
value: 20480,
unit: "bytes"
},
bot_recurring_event_count: {
value: 50,
unit: "count"
},
bot_recurring_event_payload_bytes: {
value: 131072,
unit: "bytes"
},
event_definition_count: {
value: 20,
unit: "count"
},
integration_channel_count: {
value: 10,
unit: "count"
},
integration_channel_message_type_count: {
value: 20,
unit: "count"
},
integration_identifier_count: {
value: 50,
unit: "count"
},
integration_version_count: {
value: 200,
unit: "count"
},
issue_event_item_payload_bytes: {
value: 131072,
unit: "bytes"
},
message_payload_bytes: {
value: 131072,
unit: "bytes"
},
schema_bytes: {
value: 102400,
unit: "bytes"
},
state_definition_count: {
value: 20,
unit: "count"
},
state_item_payload_bytes: {
value: 131072,
unit: "bytes"
},
tag_definition_count: {
value: 50,
unit: "count"
},
bot_integration_secret_count: {
value: 25,
unit: "count"
},
files_api_query_bytes: {
value: 2048,
unit: "bytes"
},
code_payload_bytes: {
value: 52428800,
unit: "bytes"
},
entity_custom_properties_count: {
value: 50,
unit: "count"
}
};
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/prefixes.js
var require_prefixes = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.objectToPrefixMap = exports.prefixToObjectMap = undefined;
exports.prefixToObjectMap = {
accnt: "account",
accntpf: "accountPreference",
action: "action",
activty: "activity",
anlytic: "analytics",
audit: "audit",
bak: "botApiKey",
bot: "bot",
card: "card",
cfg: "configuration",
channel: "channel",
conv: "conversation",
devbot: "devBot",
devint: "devIntegration",
evt: "event",
file: "file",
flow: "flow",
iak: "integrationApiKey",
int: "integration",
iface: "interface",
ifver: "interfaceVersion",
intver: "integrationVersion",
iss: "issue",
issevt: "issueEvent",
kb: "knowledgeBase",
limit: "limit",
media: "media",
msg: "message",
node: "node",
notif: "notification",
pat: "personalAccessToken",
plugin: "plugin",
plugver: "pluginVersion",
quota: "quota",
recevt: "recurringEvent",
report: "report",
sandbox: "sandbox",
schema: "schema",
script: "script",
state: "state",
table: "table",
tag: "tag",
task: "task",
archrg: "autoRechargeSetting",
archtx: "autoRechargeTransaction",
crgrant: "creditGrant",
job: "job",
pcrgrant: "pendingCreditGrant",
promo: "promoCode",
smgevt: "smaugEvent",
usage: "usage",
user: "user",
webhook: "webhook",
wkspace: "workspace",
wksadd: "workspaceAddon",
wksaddinst: "workspaceAddonAddition",
wksplan: "workspacePlan",
wrkflow: "workflow",
wkspacepf: "workspacePreference",
trial: "trial"
};
exports.objectToPrefixMap = {
account: "accnt",
accountPreference: "accntpf",
action: "action",
activity: "activty",
analytics: "anlytic",
audit: "audit",
bot: "bot",
botApiKey: "bak",
card: "card",
channel: "channel",
configuration: "cfg",
conversation: "conv",
devBot: "devbot",
devIntegration: "devint",
event: "evt",
file: "file",
flow: "flow",
integration: "int",
integrationApiKey: "iak",
integrationVersion: "intver",
interface: "iface",
interfaceVersion: "ifver",
issue: "iss",
issueEvent: "issevt",
knowledgeBase: "kb",
limit: "limit",
media: "media",
message: "msg",
node: "node",
notification: "notif",
personalAccessToken: "pat",
plugin: "plugin",
pluginVersion: "plugver",
quota: "quota",
recurringEvent: "recevt",
report: "report",
sandbox: "sandbox",
schema: "schema",
script: "script",
state: "state",
table: "table",
tag: "tag",
task: "task",
autoRechargeSetting: "archrg",
autoRechargeTransaction: "archtx",
creditGrant: "crgrant",
job: "job",
pendingCreditGrant: "pcrgrant",
promoCode: "promo",
smaugEvent: "smgevt",
usage: "usage",
user: "user",
webhook: "webhook",
workflow: "wrkflow",
workspace: "wkspace",
workspaceAddon: "wksadd",
workspaceAddonAddition: "wksaddinst",
workspacePlan: "wksplan",
workspacePreference: "wkspacepf",
trial: "trial"
};
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/billing-legacy/quotas.js
var require_quotas = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.quotaConfigsV3 = exports.quotaConfigs = exports.quotaTypes = undefined;
exports.quotaTypes = [
"invocation_timeout",
"invocation_calls",
"storage_count",
"bot_count",
"knowledgebase_vector_storage",
"workspace_ratelimit",
"table_row_count",
"workspace_member_count",
"integrations_owned_count",
"ai_spend",
"openai_spend",
"bing_search_spend",
"always_alive",
"indexed_file_count",
"file_max_size_bytes"
];
exports.quotaConfigs = {
invocation_timeout: {
name: "Invocation Timeout",
description: "Maximum time in milliseconds a bot can run before timing out.",
default: 60000,
kind: "workspace",
category: "timeout",
trackUsagePerBot: false
},
storage_count: {
name: "Storage Count",
description: "Maximum number of storage bytes that can be stored.",
default: 500000000,
kind: "workspace",
category: "count",
trackUsagePerBot: true
},
bot_count: {
name: "Bot Count",
description: "Maximum number of bots that can be created.",
default: 5,
kind: "workspace",
category: "count",
trackUsagePerBot: false
},
workspace_member_count: {
name: "Workspace Member Count",
description: "Maximum number of members that can be added to a workspace.",
default: 3,
kind: "workspace",
category: "count",
trackUsagePerBot: false
},
knowledgebase_vector_storage: {
name: "Knowledgebase Vector Storage",
description: "Maximum size of knowledge base documents",
default: 1e8,
kind: "workspace",
category: "count",
trackUsagePerBot: true
},
table_row_count: {
name: "Table Row Count",
description: "Maximum number of rows that can be stored in a table.",
default: 5000,
kind: "workspace",
category: "count",
trackUsagePerBot: true
},
invocation_calls: {
name: "Messages",
description: "Maximum number of messages sent to a bot in a month.",
default: 2000,
kind: "workspace",
category: "calls",
trackUsagePerBot: true
},
workspace_ratelimit: {
name: "Workspace Ratelimit",
description: "Maximum number of API calls per second for a workspace.",
default: 100,
kind: "workspace",
category: "ratelimit",
trackUsagePerBot: false
},
integrations_owned_count: {
name: "Owned Integrations Count",
description: "Maximum number of integrations that can be created.",
default: 20,
kind: "workspace",
category: "count",
trackUsagePerBot: false
},
ai_spend: {
name: "AI Spend",
description: "Maximum amount of AI spend, expressed in nano-dollars (1 nano-dollar = $0.000000001) that can be used in a month.",
default: 5000000000,
kind: "workspace",
category: "credit",
trackUsagePerBot: true
},
openai_spend: {
name: "OpenAI Spend",
description: "Maximum amount of OpenAI spend, expressed in nano-dollars (1 nano-dollar = $0.000000001) that can be used in a month.",
default: 5000000000,
kind: "workspace",
category: "credit",
trackUsagePerBot: true,
parent: "ai_spend"
},
bing_search_spend: {
name: "Bing Search Spend",
description: "Maximum amount of Bing Search spend, expressed in nano-dollars (1 nano-dollar = $0.000000001) that can be used in a month.",
default: 5000000000,
kind: "workspace",
category: "credit",
trackUsagePerBot: true,
parent: "ai_spend"
},
always_alive: {
name: "Always Alive",
description: "Maximum number of bots that can be in always alive mode.",
default: 0,
kind: "workspace",
category: "count",
trackUsagePerBot: false
},
indexed_file_count: {
name: "Indexed File Count",
description: "Maximum number of files that can be indexed.",
default: 1000,
kind: "workspace",
category: "count",
trackUsagePerBot: true
},
file_max_size_bytes: {
name: "Max File Size",
description: "Maximum size of a file in bytes.",
default: 1e8,
kind: "workspace",
category: "limit",
trackUsagePerBot: true
}
};
exports.quotaConfigsV3 = {
invocation_timeout: {
name: "Invocation Timeout",
description: "Maximum time in milliseconds a bot can run before timing out.",
default: 60000,
kind: "workspace",
category: "timeout",
trackUsagePerBot: false
},
storage_count: {
name: "Storage Count",
description: "Maximum number of storage bytes that can be stored.",
default: 1e8,
kind: "workspace",
category: "count",
trackUsagePerBot: true
},
bot_count: {
name: "Bot Count",
description: "Maximum number of bots that can be created.",
default: 1,
kind: "workspace",
category: "count",
trackUsagePerBot: false
},
workspace_member_count: {
name: "Workspace Member Count",
description: "Maximum number of members that can be added to a workspace.",
default: 1,
kind: "workspace",
category: "count",
trackUsagePerBot: false
},
knowledgebase_vector_storage: {
name: "Knowledgebase Vector Storage",
description: "Maximum size of knowledge base documents",
default: 1e8,
kind: "workspace",
category: "count",
trackUsagePerBot: true
},
table_row_count: {
name: "Table Row Count",
description: "Maximum number of rows that can be stored in a table.",
default: 1000,
kind: "workspace",
category: "count",
trackUsagePerBot: true
},
invocation_calls: {
name: "Messages",
description: "Maximum number of messages sent to a bot in a month.",
default: 500,
kind: "workspace",
category: "calls",
trackUsagePerBot: true
},
workspace_ratelimit: {
name: "Workspace Ratelimit",
description: "Maximum number of API calls per second for a workspace.",
default: 100,
kind: "workspace",
category: "ratelimit",
trackUsagePerBot: false
},
integrations_owned_count: {
name: "Owned Integrations Count",
description: "Maximum number of integrations that can be created.",
default: 20,
kind: "workspace",
category: "count",
trackUsagePerBot: false
},
ai_spend: {
name: "AI Spend",
description: "Maximum amount of AI spend, expressed in nano-dollars (1 nano-dollar = $0.000000001) that can be used in a month.",
default: 5000000000,
kind: "workspace",
category: "credit",
trackUsagePerBot: true
},
openai_spend: {
name: "OpenAI Spend",
description: "Maximum amount of OpenAI spend, expressed in nano-dollars (1 nano-dollar = $0.000000001) that can be used in a month.",
default: 5000000000,
kind: "workspace",
category: "credit",
trackUsagePerBot: true,
parent: "ai_spend"
},
bing_search_spend: {
name: "Bing Search Spend",
description: "Maximum amount of Bing Search spend, expressed in nano-dollars (1 nano-dollar = $0.000000001) that can be used in a month.",
default: 5000000000,
kind: "workspace",
category: "credit",
trackUsagePerBot: true,
parent: "ai_spend"
},
always_alive: {
name: "Always Alive",
description: "Maximum number of bots that can be in always alive mode.",
default: 0,
kind: "workspace",
category: "count",
trackUsagePerBot: false
},
indexed_file_count: {
name: "Indexed File Count",
description: "Maximum number of files that can be indexed.",
default: 1000,
kind: "workspace",
category: "count",
trackUsagePerBot: true
},
file_max_size_bytes: {
name: "Max File Size",
description: "Maximum size of a file in bytes.",
default: 1e8,
kind: "workspace",
category: "limit",
trackUsagePerBot: true
}
};
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/billing-legacy/consts.js
var require_consts = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.billingFeatureDefs = exports.BILLING_PLAN_IDS = exports.ALLOWED_TRIAL_PLANS = exports.ALLOWED_TRIAL_LENGTHS_IN_DAYS = undefined;
exports.ALLOWED_TRIAL_LENGTHS_IN_DAYS = 7;
exports.ALLOWED_TRIAL_PLANS = ["plus", "team"];
exports.BILLING_PLAN_IDS = ["community", "plus", "team", "enterprise", "managed"];
exports.billingFeatureDefs = {
human_in_the_loop: {
name: "Human in the Loop"
},
ratelimit: {
name: "Rate Limit"
},
incoming_messages_events: {
name: "Incoming Messages/Events"
},
integration_spend: {
name: "Integration Spend"
},
integration_subscription: {
name: "Integration Subscription"
},
table_rows: {
name: "Table Rows"
},
bot_count: {
name: "Bot Count"
},
always_alive_count: {
name: "Always Alive Count"
},
always_alive_concurrency: {
name: "Always Alive Concurrency"
},
collaborator_count: {
name: "Collaborator Count"
},
file_storage: {
name: "File Storage"
},
vector_db_storage: {
name: "Vector DB Storage"
},
saved_versions: {
name: "Saved Versions"
},
indexed_file_count: {
name: "Indexed File Count"
}
};
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/billing-legacy/index.js
var require_billing_legacy = __commonJS((exports) => {
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
if (k2 === undefined)
k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() {
return m[k];
} };
}
Object.defineProperty(o, k2, desc);
} : function(o, m, k, k2) {
if (k2 === undefined)
k2 = k;
o[k2] = m[k];
});
var __exportStar = exports && exports.__exportStar || function(m, exports2) {
for (var p in m)
if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
__createBinding(exports2, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require_quotas(), exports);
__exportStar(require_consts(), exports);
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/tags.js
var require_tags = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.Tags = undefined;
exports.Tags = {
bot: {},
conversation: {
upstream: {
description: "Used for HITL as a convention. The upstream conversation ID, ie. the conversation ID of the original conversation"
},
downstream: {
description: "Used for HITL as a convention. The downstream conversation ID, ie. the conversation ID of conversation in HITL channel"
}
},
message: {
origin: {
description: 'The origin location of the message in the bot, eg. "workflow://[id]/node/[id]"'
},
iteration: {
description: "The LLMz iteration ID of the message, for tracking and debugging purposes"
}
},
event: {},
workflow: {},
user: {},
file: {
system: {
type: "boolean",
description: "System files are managed by Botpress and should not be modified"
},
purpose: {
description: 'The purpose of the file, eg. "swap"'
},
source: {
description: 'The source of the file, eg. "knowledge-base"'
},
kbId: {
description: "The ID of the knowledge base"
},
favicon: {
description: 'The favicon URL to display for the file, eg. "https://example.com/favicon.ico"'
},
pageUrl: {
description: 'The original page URL of the file, eg. "https://example.com/page"'
},
integrationName: {
description: "The name of the integration that created the file"
},
webchatInjectConfigVersion: {
description: "The version of the webchat inject configuration (used by the dashboard)"
}
},
table: {
system: {
type: "boolean",
description: "System tables are managed by Botpress and should not be modified"
},
"x-studio-title": {
description: "Overrides the table title in the Studio"
},
"x-studio-readonly": {
type: "boolean",
description: "Prevents the table from being modified by the user in the Studio"
},
"x-studio-icon": {
description: 'Overrides the table icon in the Studio. The value can be a lucide icon URL, eg. "lucide://atom"'
},
"x-studio-color": {
description: "Overrides the table color in the Studio."
},
"x-studio-folder": {
description: "Groups the table in a folder in the Studio"
},
"x-studio-deletable": {
type: "boolean",
description: "Prevents the table from being deleted by the user in the Studio"
}
}
};
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/workflow-names.js
var require_workflow_names = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.KNOWLEDGE_WORKFLOW = exports.IDENTITY_WEBSITE_WORKFLOW = exports.IDENTITY_TEXT_WORKFLOW = exports.ONBOARDING_DEPLOY_WORKFLOW = exports.WEBSITE_CRAWL_WORKFLOW = undefined;
exports.WEBSITE_CRAWL_WORKFLOW = "website-crawl";
exports.ONBOARDING_DEPLOY_WORKFLOW = "onboarding-deploy";
exports.IDENTITY_TEXT_WORKFLOW = "identity-text-workflow";
exports.IDENTITY_WEBSITE_WORKFLOW = "identity-website-workflow";
exports.KNOWLEDGE_WORKFLOW = "knowledge-workflow";
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/cancellation-reasons.js
var require_cancellation_reasons = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.CANCELLATION_REASONS = undefined;
exports.CANCELLATION_REASONS = [
"too_expensive",
"not_using_enough",
"missing_feature",
"switched_tool",
"technical_issues",
"support_expectations",
"temporary_need"
];
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/billing-next/features.js
var require_features = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.CREDIT_GRANT_BILLING_FEATURE_IDS = exports.NON_RESETTING_BILLING_FEATURE_IDS = exports.NON_ATOMIC_BILLING_FEATURE_IDS = exports.ATOMIC_BILLING_FEATURE_IDS = exports.BILLING_FEATURE_IDS = exports.billingFeatureDefinitions = undefined;
exports.billingFeatureDefinitions = [
{
id: "incoming_messages_events",
name: "Incoming Messages/Events",
description: "Number of incoming messages and events processed per month",
resetPeriod: "monthly",
consistency: "eventual",
dimensions: {
botId: "Bot ID",
type: "Message or Event type"
}
},
{
id: "integration_spend",
name: "Integration Spend",
description: "Credits spent on integrations (AI, third-party services)",
resetPeriod: "monthly",
consistency: "eventual",
dimensions: {
botId: "Bot ID",
integrationName: "Integration name",
integrationVersionId: "Integration version ID",
actionName: "Action name"
}
},
{
id: "table_rows",
name: "Table Rows",
description: "Number of table rows that can be stored",
resetPeriod: "never",
consistency: "eventual"
},
{
id: "bot_count",
name: "Bot Count",
description: "Number of bots that can be created",
resetPeriod: "never",
consistency: "atomic"
},
{
id: "collaborator_count",
name: "Collaborator Count",
description: "Number of collaborators that can be added to workspace",
resetPeriod: "never",
consistency: "atomic"
},
{
id: "file_storage",
name: "File Storage",
description: "Amount of file storage available",
resetPeriod: "never",
consistency: "eventual"
},
{
id: "vector_db_storage",
name: "Vector DB Storage",
description: "Amount of vector database storage available",
resetPeriod: "never",
consistency: "eventual"
},
{
id: "saved_versions",
name: "Saved Versions",
description: "Number of bot versions that can be saved",
resetPeriod: "never",
consistency: "atomic"
},
{
id: "indexed_file_count",
name: "Indexed File Count",
description: "The number of indexed files in the files api",
resetPeriod: "never",
consistency: "eventual"
},
{
id: "conversation_sessions",
name: "Conversations",
description: "Number of conversation sessions that can occur",
resetPeriod: "monthly",
consistency: "eventual"
},
{
id: "ai_spend",
name: "AI Spend",
description: "Amount that is useable for AI in nano-dollars",
resetPeriod: "monthly",
consistency: "eventual",
grantable: true
}
];
exports.BILLING_FEATURE_IDS = exports.billingFeatureDefinitions.map((def) => def.id);
exports.ATOMIC_BILLING_FEATURE_IDS = exports.billingFeatureDefinitions.filter((def) => def.consistency === "atomic").map((def) => def.id);
exports.NON_ATOMIC_BILLING_FEATURE_IDS = exports.billingFeatureDefinitions.filter((def) => def.consistency === "eventual").map((def) => def.id);
exports.NON_RESETTING_BILLING_FEATURE_IDS = exports.billingFeatureDefinitions.filter((def) => def.resetPeriod === "never").map((def) => def.id);
exports.CREDIT_GRANT_BILLING_FEATURE_IDS = exports.billingFeatureDefinitions.filter((def) => def.grantable).map((def) => def.id);
});
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/util.cjs
var require_util = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.getParsedType = exports.ZodParsedType = exports.objectUtil = exports.util = undefined;
var util;
(function(util2) {
util2.assertEqual = (_) => {};
function assertIs(_arg) {}
util2.assertIs = assertIs;
function assertNever(_x) {
throw new Error;
}
util2.assertNever = assertNever;
util2.arrayToEnum = (items) => {
const obj = {};
for (const item of items) {
obj[item] = item;
}
return obj;
};
util2.getValidEnumValues = (obj) => {
const validKeys = util2.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number");
const filtered = {};
for (const k of validKeys) {
filtered[k] = obj[k];
}
return util2.objectValues(filtered);
};
util2.objectValues = (obj) => {
return util2.objectKeys(obj).map(function(e) {
return obj[e];
});
};
util2.objectKeys = typeof Object.keys === "function" ? (obj) => Object.keys(obj) : (object) => {
const keys = [];
for (const key in object) {
if (Object.prototype.hasOwnProperty.call(object, key)) {
keys.push(key);
}
}
return keys;
};
util2.find = (arr, checker) => {
for (const item of arr) {
if (checker(item))
return item;
}
return;
};
util2.isInteger = typeof Number.isInteger === "function" ? (val) => Number.isInteger(val) : (val) => typeof val === "number" && Number.isFinite(val) && Math.floor(val) === val;
function joinValues(array, separator = " | ") {
return array.map((val) => typeof val === "string" ? `'${val}'` : val).join(separator);
}
util2.joinValues = joinValues;
util2.jsonStringifyReplacer = (_, value) => {
if (typeof value === "bigint") {
return value.toString();
}
return value;
};
})(util || (exports.util = util = {}));
var objectUtil;
(function(objectUtil2) {
objectUtil2.mergeShapes = (first, second) => {
return {
...first,
...second
};
};
})(objectUtil || (exports.objectUtil = objectUtil = {}));
exports.ZodParsedType = util.arrayToEnum([
"string",
"nan",
"number",
"integer",
"float",
"boolean",
"date",
"bigint",
"symbol",
"function",
"undefined",
"null",
"array",
"object",
"unknown",
"promise",
"void",
"never",
"map",
"set"
]);
var getParsedType = (data) => {
const t = typeof data;
switch (t) {
case "undefined":
return exports.ZodParsedType.undefined;
case "string":
return exports.ZodParsedType.string;
case "number":
return Number.isNaN(data) ? exports.ZodParsedType.nan : exports.ZodParsedType.number;
case "boolean":
return exports.ZodParsedType.boolean;
case "function":
return exports.ZodParsedType.function;
case "bigint":
return exports.ZodParsedType.bigint;
case "symbol":
return exports.ZodParsedType.symbol;
case "object":
if (Array.isArray(data)) {
return exports.ZodParsedType.array;
}
if (data === null) {
return exports.ZodParsedType.null;
}
if (data.then && typeof data.then === "function" && data.catch && typeof data.catch === "function") {
return exports.ZodParsedType.promise;
}
if (typeof Map !== "undefined" && data instanceof Map) {
return exports.ZodParsedType.map;
}
if (typeof Set !== "undefined" && data instanceof Set) {
return exports.ZodParsedType.set;
}
if (typeof Date !== "undefined" && data instanceof Date) {
return exports.ZodParsedType.date;
}
return exports.ZodParsedType.object;
default:
return exports.ZodParsedType.unknown;
}
};
exports.getParsedType = getParsedType;
});
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/ZodError.cjs
var require_ZodError = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.ZodError = exports.quotelessJson = exports.ZodIssueCode = undefined;
var util_js_1 = require_util();
exports.ZodIssueCode = util_js_1.util.arrayToEnum([
"invalid_type",
"invalid_literal",
"custom",
"invalid_union",
"invalid_union_discriminator",
"invalid_enum_value",
"unrecognized_keys",
"invalid_arguments",
"invalid_return_type",
"invalid_date",
"invalid_string",
"too_small",
"too_big",
"invalid_intersection_types",
"not_multiple_of",
"not_finite"
]);
var quotelessJson = (obj) => {
const json = JSON.stringify(obj, null, 2);
return json.replace(/"([^"]+)":/g, "$1:");
};
exports.quotelessJson = quotelessJson;
class ZodError extends Error {
get errors() {
return this.issues;
}
constructor(issues) {
super();
this.issues = [];
this.addIssue = (sub) => {
this.issues = [...this.issues, sub];
};
this.addIssues = (subs = []) => {
this.issues = [...this.issues, ...subs];
};
const actualProto = new.target.prototype;
if (Object.setPrototypeOf) {
Object.setPrototypeOf(this, actualProto);
} else {
this.__proto__ = actualProto;
}
this.name = "ZodError";
this.issues = issues;
}
format(_mapper) {
const mapper = _mapper || function(issue) {
return issue.message;
};
const fieldErrors = { _errors: [] };
const processError = (error) => {
for (const issue of error.issues) {
if (issue.code === "invalid_union") {
issue.unionErrors.map(processError);
} else if (issue.code === "invalid_return_type") {
processError(issue.returnTypeError);
} else if (issue.code === "invalid_arguments") {
processError(issue.argumentsError);
} else if (issue.path.length === 0) {
fieldErrors._errors.push(mapper(issue));
} else {
let curr = fieldErrors;
let i = 0;
while (i < issue.path.length) {
const el = issue.path[i];
const terminal = i === issue.path.length - 1;
if (!terminal) {
curr[el] = curr[el] || { _errors: [] };
} else {
curr[el] = curr[el] || { _errors: [] };
curr[el]._errors.push(mapper(issue));
}
curr = curr[el];
i++;
}
}
}
};
processError(this);
return fieldErrors;
}
static assert(value) {
if (!(value instanceof ZodError)) {
throw new Error(`Not a ZodError: ${value}`);
}
}
toString() {
return this.message;
}
get message() {
return JSON.stringify(this.issues, util_js_1.util.jsonStringifyReplacer, 2);
}
get isEmpty() {
return this.issues.length === 0;
}
flatten(mapper = (issue) => issue.message) {
const fieldErrors = {};
const formErrors = [];
for (const sub of this.issues) {
if (sub.path.length > 0) {
const firstEl = sub.path[0];
fieldErrors[firstEl] = fieldErrors[firstEl] || [];
fieldErrors[firstEl].push(mapper(sub));
} else {
formErrors.push(mapper(sub));
}
}
return { formErrors, fieldErrors };
}
get formErrors() {
return this.flatten();
}
}
exports.ZodError = ZodError;
ZodError.create = (issues) => {
const error = new ZodError(issues);
return error;
};
});
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/locales/en.cjs
var require_en = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
var ZodError_js_1 = require_ZodError();
var util_js_1 = require_util();
var errorMap = (issue, _ctx) => {
let message;
switch (issue.code) {
case ZodError_js_1.ZodIssueCode.invalid_type:
if (issue.received === util_js_1.ZodParsedType.undefined) {
message = "Required";
} else {
message = `Expected ${issue.expected}, received ${issue.received}`;
}
break;
case ZodError_js_1.ZodIssueCode.invalid_literal:
message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util_js_1.util.jsonStringifyReplacer)}`;
break;
case ZodError_js_1.ZodIssueCode.unrecognized_keys:
message = `Unrecognized key(s) in object: ${util_js_1.util.joinValues(issue.keys, ", ")}`;
break;
case ZodError_js_1.ZodIssueCode.invalid_union:
message = `Invalid input`;
break;
case ZodError_js_1.ZodIssueCode.invalid_union_discriminator:
message = `Invalid discriminator value. Expected ${util_js_1.util.joinValues(issue.options)}`;
break;
case ZodError_js_1.ZodIssueCode.invalid_enum_value:
message = `Invalid enum value. Expected ${util_js_1.util.joinValues(issue.options)}, received '${issue.received}'`;
break;
case ZodError_js_1.ZodIssueCode.invalid_arguments:
message = `Invalid function arguments`;
break;
case ZodError_js_1.ZodIssueCode.invalid_return_type:
message = `Invalid function return type`;
break;
case ZodError_js_1.ZodIssueCode.invalid_date:
message = `Invalid date`;
break;
case ZodError_js_1.ZodIssueCode.invalid_string:
if (typeof issue.validation === "object") {
if ("includes" in issue.validation) {
message = `Invalid input: must include "${issue.validation.includes}"`;
if (typeof issue.validation.position === "number") {
message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;
}
} else if ("startsWith" in issue.validation) {
message = `Invalid input: must start with "${issue.validation.startsWith}"`;
} else if ("endsWith" in issue.validation) {
message = `Invalid input: must end with "${issue.validation.endsWith}"`;
} else {
util_js_1.util.assertNever(issue.validation);
}
} else if (issue.validation !== "regex") {
message = `Invalid ${issue.validation}`;
} else {
message = "Invalid";
}
break;
case ZodError_js_1.ZodIssueCode.too_small:
if (issue.type === "array")
message = `Array must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;
else if (issue.type === "string")
message = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
else if (issue.type === "number")
message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
else if (issue.type === "bigint")
message = `Number must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${issue.minimum}`;
else if (issue.type === "date")
message = `Date must be ${issue.exact ? `exactly equal to ` : issue.inclusive ? `greater than or equal to ` : `greater than `}${new Date(Number(issue.minimum))}`;
else
message = "Invalid input";
break;
case ZodError_js_1.ZodIssueCode.too_big:
if (issue.type === "array")
message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;
else if (issue.type === "string")
message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;
else if (issue.type === "number")
message = `Number must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
else if (issue.type === "bigint")
message = `BigInt must be ${issue.exact ? `exactly` : issue.inclusive ? `less than or equal to` : `less than`} ${issue.maximum}`;
else if (issue.type === "date")
message = `Date must be ${issue.exact ? `exactly` : issue.inclusive ? `smaller than or equal to` : `smaller than`} ${new Date(Number(issue.maximum))}`;
else
message = "Invalid input";
break;
case ZodError_js_1.ZodIssueCode.custom:
message = `Invalid input`;
break;
case ZodError_js_1.ZodIssueCode.invalid_intersection_types:
message = `Intersection results could not be merged`;
break;
case ZodError_js_1.ZodIssueCode.not_multiple_of:
message = `Number must be a multiple of ${issue.multipleOf}`;
break;
case ZodError_js_1.ZodIssueCode.not_finite:
message = "Number must be finite";
break;
default:
message = _ctx.defaultError;
util_js_1.util.assertNever(issue);
}
return { message };
};
exports.default = errorMap;
});
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/errors.cjs
var require_errors = __commonJS((exports) => {
var __importDefault = exports && exports.__importDefault || function(mod) {
return mod && mod.__esModule ? mod : { default: mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.defaultErrorMap = undefined;
exports.setErrorMap = setErrorMap;
exports.getErrorMap = getErrorMap;
var en_js_1 = __importDefault(require_en());
exports.defaultErrorMap = en_js_1.default;
var overrideErrorMap = en_js_1.default;
function setErrorMap(map) {
overrideErrorMap = map;
}
function getErrorMap() {
return overrideErrorMap;
}
});
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.cjs
var require_parseUtil = __commonJS((exports) => {
var __importDefault = exports && exports.__importDefault || function(mod) {
return mod && mod.__esModule ? mod : { default: mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.isAsync = exports.isValid = exports.isDirty = exports.isAborted = exports.OK = exports.DIRTY = exports.INVALID = exports.ParseStatus = exports.EMPTY_PATH = exports.makeIssue = undefined;
exports.addIssueToContext = addIssueToContext;
var errors_js_1 = require_errors();
var en_js_1 = __importDefault(require_en());
var makeIssue = (params) => {
const { data, path, errorMaps, issueData } = params;
const fullPath = [...path, ...issueData.path || []];
const fullIssue = {
...issueData,
path: fullPath
};
if (issueData.message !== undefined) {
return {
...issueData,
path: fullPath,
message: issueData.message
};
}
let errorMessage = "";
const maps = errorMaps.filter((m) => !!m).slice().reverse();
for (const map of maps) {
errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message;
}
return {
...issueData,
path: fullPath,
message: errorMessage
};
};
exports.makeIssue = makeIssue;
exports.EMPTY_PATH = [];
function addIssueToContext(ctx, issueData) {
const overrideMap = (0, errors_js_1.getErrorMap)();
const issue = (0, exports.makeIssue)({
issueData,
data: ctx.data,
path: ctx.path,
errorMaps: [
ctx.common.contextualErrorMap,
ctx.schemaErrorMap,
overrideMap,
overrideMap === en_js_1.default ? undefined : en_js_1.default
].filter((x) => !!x)
});
ctx.common.issues.push(issue);
}
class ParseStatus {
constructor() {
this.value = "valid";
}
dirty() {
if (this.value === "valid")
this.value = "dirty";
}
abort() {
if (this.value !== "aborted")
this.value = "aborted";
}
static mergeArray(status, results) {
const arrayValue = [];
for (const s of results) {
if (s.status === "aborted")
return exports.INVALID;
if (s.status === "dirty")
status.dirty();
arrayValue.push(s.value);
}
return { status: status.value, value: arrayValue };
}
static async mergeObjectAsync(status, pairs) {
const syncPairs = [];
for (const pair of pairs) {
const key = await pair.key;
const value = await pair.value;
syncPairs.push({
key,
value
});
}
return ParseStatus.mergeObjectSync(status, syncPairs);
}
static mergeObjectSync(status, pairs) {
const finalObject = {};
for (const pair of pairs) {
const { key, value } = pair;
if (key.status === "aborted")
return exports.INVALID;
if (value.status === "aborted")
return exports.INVALID;
if (key.status === "dirty")
status.dirty();
if (value.status === "dirty")
status.dirty();
if (key.value !== "__proto__" && (typeof value.value !== "undefined" || pair.alwaysSet)) {
finalObject[key.value] = value.value;
}
}
return { status: status.value, value: finalObject };
}
}
exports.ParseStatus = ParseStatus;
exports.INVALID = Object.freeze({
status: "aborted"
});
var DIRTY = (value) => ({ status: "dirty", value });
exports.DIRTY = DIRTY;
var OK = (value) => ({ status: "valid", value });
exports.OK = OK;
var isAborted = (x) => x.status === "aborted";
exports.isAborted = isAborted;
var isDirty = (x) => x.status === "dirty";
exports.isDirty = isDirty;
var isValid = (x) => x.status === "valid";
exports.isValid = isValid;
var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
exports.isAsync = isAsync;
});
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/typeAliases.cjs
var require_typeAliases = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
});
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.cjs
var require_errorUtil = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.errorUtil = undefined;
var errorUtil;
(function(errorUtil2) {
errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
})(errorUtil || (exports.errorUtil = errorUtil = {}));
});
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/types.cjs
var require_types = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.discriminatedUnion = exports.date = exports.boolean = exports.bigint = exports.array = exports.any = exports.coerce = exports.ZodFirstPartyTypeKind = exports.late = exports.ZodSchema = exports.Schema = exports.ZodReadonly = exports.ZodPipeline = exports.ZodBranded = exports.BRAND = exports.ZodNaN = exports.ZodCatch = exports.ZodDefault = exports.ZodNullable = exports.ZodOptional = exports.ZodTransformer = exports.ZodEffects = exports.ZodPromise = exports.ZodNativeEnum = exports.ZodEnum = exports.ZodLiteral = exports.ZodLazy = exports.ZodFunction = exports.ZodSet = exports.ZodMap = exports.ZodRecord = exports.ZodTuple = exports.ZodIntersection = exports.ZodDiscriminatedUnion = exports.ZodUnion = exports.ZodObject = exports.ZodArray = exports.ZodVoid = exports.ZodNever = exports.ZodUnknown = exports.ZodAny = exports.ZodNull = exports.ZodUndefined = exports.ZodSymbol = exports.ZodDate = exports.ZodBoolean = exports.ZodBigInt = exports.ZodNumber = exports.ZodString = exports.ZodType = undefined;
exports.NEVER = exports.void = exports.unknown = exports.union = exports.undefined = exports.tuple = exports.transformer = exports.symbol = exports.string = exports.strictObject = exports.set = exports.record = exports.promise = exports.preprocess = exports.pipeline = exports.ostring = exports.optional = exports.onumber = exports.oboolean = exports.object = exports.number = exports.nullable = exports.null = exports.never = exports.nativeEnum = exports.nan = exports.map = exports.literal = exports.lazy = exports.intersection = exports.instanceof = exports.function = exports.enum = exports.effect = undefined;
exports.datetimeRegex = datetimeRegex;
exports.custom = custom;
var ZodError_js_1 = require_ZodError();
var errors_js_1 = require_errors();
var errorUtil_js_1 = require_errorUtil();
var parseUtil_js_1 = require_parseUtil();
var util_js_1 = require_util();
class ParseInputLazyPath {
constructor(parent, value, path, key) {
this._cachedPath = [];
this.parent = parent;
this.data = value;
this._path = path;
this._key = key;
}
get path() {
if (!this._cachedPath.length) {
if (Array.isArray(this._key)) {
this._cachedPath.push(...this._path, ...this._key);
} else {
this._cachedPath.push(...this._path, this._key);
}
}
return this._cachedPath;
}
}
var handleResult = (ctx, result) => {
if ((0, parseUtil_js_1.isValid)(result)) {
return { success: true, data: result.value };
} else {
if (!ctx.common.issues.length) {
throw new Error("Validation failed but no issues detected.");
}
return {
success: false,
get error() {
if (this._error)
return this._error;
const error = new ZodError_js_1.ZodError(ctx.common.issues);
this._error = error;
return this._error;
}
};
}
};
function processCreateParams(params) {
if (!params)
return {};
const { errorMap, invalid_type_error, required_error, description } = params;
if (errorMap && (invalid_type_error || required_error)) {
throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);
}
if (errorMap)
return { errorMap, description };
const customMap = (iss, ctx) => {
const { message } = params;
if (iss.code === "invalid_enum_value") {
return { message: message ?? ctx.defaultError };
}
if (typeof ctx.data === "undefined") {
return { message: message ?? required_error ?? ctx.defaultError };
}
if (iss.code !== "invalid_type")
return { message: ctx.defaultError };
return { message: message ?? invalid_type_error ?? ctx.defaultError };
};
return { errorMap: customMap, description };
}
class ZodType {
get description() {
return this._def.description;
}
_getType(input) {
return (0, util_js_1.getParsedType)(input.data);
}
_getOrReturnCtx(input, ctx) {
return ctx || {
common: input.parent.common,
data: input.data,
parsedType: (0, util_js_1.getParsedType)(input.data),
schemaErrorMap: this._def.errorMap,
path: input.path,
parent: input.parent
};
}
_processInputParams(input) {
return {
status: new parseUtil_js_1.ParseStatus,
ctx: {
common: input.parent.common,
data: input.data,
parsedType: (0, util_js_1.getParsedType)(input.data),
schemaErrorMap: this._def.errorMap,
path: input.path,
parent: input.parent
}
};
}
_parseSync(input) {
const result = this._parse(input);
if ((0, parseUtil_js_1.isAsync)(result)) {
throw new Error("Synchronous parse encountered promise.");
}
return result;
}
_parseAsync(input) {
const result = this._parse(input);
return Promise.resolve(result);
}
parse(data, params) {
const result = this.safeParse(data, params);
if (result.success)
return result.data;
throw result.error;
}
safeParse(data, params) {
const ctx = {
common: {
issues: [],
async: params?.async ?? false,
contextualErrorMap: params?.errorMap
},
path: params?.path || [],
schemaErrorMap: this._def.errorMap,
parent: null,
data,
parsedType: (0, util_js_1.getParsedType)(data)
};
const result = this._parseSync({ data, path: ctx.path, parent: ctx });
return handleResult(ctx, result);
}
"~validate"(data) {
const ctx = {
common: {
issues: [],
async: !!this["~standard"].async
},
path: [],
schemaErrorMap: this._def.errorMap,
parent: null,
data,
parsedType: (0, util_js_1.getParsedType)(data)
};
if (!this["~standard"].async) {
try {
const result = this._parseSync({ data, path: [], parent: ctx });
return (0, parseUtil_js_1.isValid)(result) ? {
value: result.value
} : {
issues: ctx.common.issues
};
} catch (err) {
if (err?.message?.toLowerCase()?.includes("encountered")) {
this["~standard"].async = true;
}
ctx.common = {
issues: [],
async: true
};
}
}
return this._parseAsync({ data, path: [], parent: ctx }).then((result) => (0, parseUtil_js_1.isValid)(result) ? {
value: result.value
} : {
issues: ctx.common.issues
});
}
async parseAsync(data, params) {
const result = await this.safeParseAsync(data, params);
if (result.success)
return result.data;
throw result.error;
}
async safeParseAsync(data, params) {
const ctx = {
common: {
issues: [],
contextualErrorMap: params?.errorMap,
async: true
},
path: params?.path || [],
schemaErrorMap: this._def.errorMap,
parent: null,
data,
parsedType: (0, util_js_1.getParsedType)(data)
};
const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx });
const result = await ((0, parseUtil_js_1.isAsync)(maybeAsyncResult) ? maybeAsyncResult : Promise.resolve(maybeAsyncResult));
return handleResult(ctx, result);
}
refine(check, message) {
const getIssueProperties = (val) => {
if (typeof message === "string" || typeof message === "undefined") {
return { message };
} else if (typeof message === "function") {
return message(val);
} else {
return message;
}
};
return this._refinement((val, ctx) => {
const result = check(val);
const setError = () => ctx.addIssue({
code: ZodError_js_1.ZodIssueCode.custom,
...getIssueProperties(val)
});
if (typeof Promise !== "undefined" && result instanceof Promise) {
return result.then((data) => {
if (!data) {
setError();
return false;
} else {
return true;
}
});
}
if (!result) {
setError();
return false;
} else {
return true;
}
});
}
refinement(check, refinementData) {
return this._refinement((val, ctx) => {
if (!check(val)) {
ctx.addIssue(typeof refinementData === "function" ? refinementData(val, ctx) : refinementData);
return false;
} else {
return true;
}
});
}
_refinement(refinement) {
return new ZodEffects({
schema: this,
typeName: ZodFirstPartyTypeKind.ZodEffects,
effect: { type: "refinement", refinement }
});
}
superRefine(refinement) {
return this._refinement(refinement);
}
constructor(def) {
this.spa = this.safeParseAsync;
this._def = def;
this.parse = this.parse.bind(this);
this.safeParse = this.safeParse.bind(this);
this.parseAsync = this.parseAsync.bind(this);
this.safeParseAsync = this.safeParseAsync.bind(this);
this.spa = this.spa.bind(this);
this.refine = this.refine.bind(this);
this.refinement = this.refinement.bind(this);
this.superRefine = this.superRefine.bind(this);
this.optional = this.optional.bind(this);
this.nullable = this.nullable.bind(this);
this.nullish = this.nullish.bind(this);
this.array = this.array.bind(this);
this.promise = this.promise.bind(this);
this.or = this.or.bind(this);
this.and = this.and.bind(this);
this.transform = this.transform.bind(this);
this.brand = this.brand.bind(this);
this.default = this.default.bind(this);
this.catch = this.catch.bind(this);
this.describe = this.describe.bind(this);
this.pipe = this.pipe.bind(this);
this.readonly = this.readonly.bind(this);
this.isNullable = this.isNullable.bind(this);
this.isOptional = this.isOptional.bind(this);
this["~standard"] = {
version: 1,
vendor: "zod",
validate: (data) => this["~validate"](data)
};
}
optional() {
return ZodOptional.create(this, this._def);
}
nullable() {
return ZodNullable.create(this, this._def);
}
nullish() {
return this.nullable().optional();
}
array() {
return ZodArray.create(this);
}
promise() {
return ZodPromise.create(this, this._def);
}
or(option) {
return ZodUnion.create([this, option], this._def);
}
and(incoming) {
return ZodIntersection.create(this, incoming, this._def);
}
transform(transform) {
return new ZodEffects({
...processCreateParams(this._def),
schema: this,
typeName: ZodFirstPartyTypeKind.ZodEffects,
effect: { type: "transform", transform }
});
}
default(def) {
const defaultValueFunc = typeof def === "function" ? def : () => def;
return new ZodDefault({
...processCreateParams(this._def),
innerType: this,
defaultValue: defaultValueFunc,
typeName: ZodFirstPartyTypeKind.ZodDefault
});
}
brand() {
return new ZodBranded({
typeName: ZodFirstPartyTypeKind.ZodBranded,
type: this,
...processCreateParams(this._def)
});
}
catch(def) {
const catchValueFunc = typeof def === "function" ? def : () => def;
return new ZodCatch({
...processCreateParams(this._def),
innerType: this,
catchValue: catchValueFunc,
typeName: ZodFirstPartyTypeKind.ZodCatch
});
}
describe(description) {
const This = this.constructor;
return new This({
...this._def,
description
});
}
pipe(target) {
return ZodPipeline.create(this, target);
}
readonly() {
return ZodReadonly.create(this);
}
isOptional() {
return this.safeParse(undefined).success;
}
isNullable() {
return this.safeParse(null).success;
}
}
exports.ZodType = ZodType;
exports.Schema = ZodType;
exports.ZodSchema = ZodType;
var cuidRegex = /^c[^\s-]{8,}$/i;
var cuid2Regex = /^[0-9a-z]+$/;
var ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i;
var uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i;
var nanoidRegex = /^[a-z0-9_-]{21}$/i;
var jwtRegex = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/;
var durationRegex = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/;
var emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i;
var _emojiRegex = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`;
var emojiRegex;
var ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/;
var ipv4CidrRegex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\/(3[0-2]|[12]?[0-9])$/;
var ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
var ipv6CidrRegex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])$/;
var base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/;
var base64urlRegex = /^([0-9a-zA-Z-_]{4})*(([0-9a-zA-Z-_]{2}(==)?)|([0-9a-zA-Z-_]{3}(=)?))?$/;
var dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`;
var dateRegex = new RegExp(`^${dateRegexSource}$`);
function timeRegexSource(args) {
let secondsRegexSource = `[0-5]\\d`;
if (args.precision) {
secondsRegexSource = `${secondsRegexSource}\\.\\d{${args.precision}}`;
} else if (args.precision == null) {
secondsRegexSource = `${secondsRegexSource}(\\.\\d+)?`;
}
const secondsQuantifier = args.precision ? "+" : "?";
return `([01]\\d|2[0-3]):[0-5]\\d(:${secondsRegexSource})${secondsQuantifier}`;
}
function timeRegex(args) {
return new RegExp(`^${timeRegexSource(args)}$`);
}
function datetimeRegex(args) {
let regex = `${dateRegexSource}T${timeRegexSource(args)}`;
const opts = [];
opts.push(args.local ? `Z?` : `Z`);
if (args.offset)
opts.push(`([+-]\\d{2}:?\\d{2})`);
regex = `${regex}(${opts.join("|")})`;
return new RegExp(`^${regex}$`);
}
function isValidIP(ip, version) {
if ((version === "v4" || !version) && ipv4Regex.test(ip)) {
return true;
}
if ((version === "v6" || !version) && ipv6Regex.test(ip)) {
return true;
}
return false;
}
function isValidJWT(jwt, alg) {
if (!jwtRegex.test(jwt))
return false;
try {
const [header] = jwt.split(".");
if (!header)
return false;
const base64 = header.replace(/-/g, "+").replace(/_/g, "/").padEnd(header.length + (4 - header.length % 4) % 4, "=");
const decoded = JSON.parse(atob(base64));
if (typeof decoded !== "object" || decoded === null)
return false;
if ("typ" in decoded && decoded?.typ !== "JWT")
return false;
if (!decoded.alg)
return false;
if (alg && decoded.alg !== alg)
return false;
return true;
} catch {
return false;
}
}
function isValidCidr(ip, version) {
if ((version === "v4" || !version) && ipv4CidrRegex.test(ip)) {
return true;
}
if ((version === "v6" || !version) && ipv6CidrRegex.test(ip)) {
return true;
}
return false;
}
class ZodString extends ZodType {
_parse(input) {
if (this._def.coerce) {
input.data = String(input.data);
}
const parsedType = this._getType(input);
if (parsedType !== util_js_1.ZodParsedType.string) {
const ctx2 = this._getOrReturnCtx(input);
(0, parseUtil_js_1.addIssueToContext)(ctx2, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.string,
received: ctx2.parsedType
});
return parseUtil_js_1.INVALID;
}
const status = new parseUtil_js_1.ParseStatus;
let ctx = undefined;
for (const check of this._def.checks) {
if (check.kind === "min") {
if (input.data.length < check.value) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_small,
minimum: check.value,
type: "string",
inclusive: true,
exact: false,
message: check.message
});
status.dirty();
}
} else if (check.kind === "max") {
if (input.data.length > check.value) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_big,
maximum: check.value,
type: "string",
inclusive: true,
exact: false,
message: check.message
});
status.dirty();
}
} else if (check.kind === "length") {
const tooBig = input.data.length > check.value;
const tooSmall = input.data.length < check.value;
if (tooBig || tooSmall) {
ctx = this._getOrReturnCtx(input, ctx);
if (tooBig) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_big,
maximum: check.value,
type: "string",
inclusive: true,
exact: true,
message: check.message
});
} else if (tooSmall) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_small,
minimum: check.value,
type: "string",
inclusive: true,
exact: true,
message: check.message
});
}
status.dirty();
}
} else if (check.kind === "email") {
if (!emailRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "email",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else if (check.kind === "emoji") {
if (!emojiRegex) {
emojiRegex = new RegExp(_emojiRegex, "u");
}
if (!emojiRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "emoji",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else if (check.kind === "uuid") {
if (!uuidRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "uuid",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else if (check.kind === "nanoid") {
if (!nanoidRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "nanoid",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else if (check.kind === "cuid") {
if (!cuidRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "cuid",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else if (check.kind === "cuid2") {
if (!cuid2Regex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "cuid2",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else if (check.kind === "ulid") {
if (!ulidRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "ulid",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else if (check.kind === "url") {
try {
new URL(input.data);
} catch {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "url",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else if (check.kind === "regex") {
check.regex.lastIndex = 0;
const testResult = check.regex.test(input.data);
if (!testResult) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "regex",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else if (check.kind === "trim") {
input.data = input.data.trim();
} else if (check.kind === "includes") {
if (!input.data.includes(check.value, check.position)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_string,
validation: { includes: check.value, position: check.position },
message: check.message
});
status.dirty();
}
} else if (check.kind === "toLowerCase") {
input.data = input.data.toLowerCase();
} else if (check.kind === "toUpperCase") {
input.data = input.data.toUpperCase();
} else if (check.kind === "startsWith") {
if (!input.data.startsWith(check.value)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_string,
validation: { startsWith: check.value },
message: check.message
});
status.dirty();
}
} else if (check.kind === "endsWith") {
if (!input.data.endsWith(check.value)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_string,
validation: { endsWith: check.value },
message: check.message
});
status.dirty();
}
} else if (check.kind === "datetime") {
const regex = datetimeRegex(check);
if (!regex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_string,
validation: "datetime",
message: check.message
});
status.dirty();
}
} else if (check.kind === "date") {
const regex = dateRegex;
if (!regex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_string,
validation: "date",
message: check.message
});
status.dirty();
}
} else if (check.kind === "time") {
const regex = timeRegex(check);
if (!regex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_string,
validation: "time",
message: check.message
});
status.dirty();
}
} else if (check.kind === "duration") {
if (!durationRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "duration",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else if (check.kind === "ip") {
if (!isValidIP(input.data, check.version)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "ip",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else if (check.kind === "jwt") {
if (!isValidJWT(input.data, check.alg)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "jwt",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else if (check.kind === "cidr") {
if (!isValidCidr(input.data, check.version)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "cidr",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else if (check.kind === "base64") {
if (!base64Regex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "base64",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else if (check.kind === "base64url") {
if (!base64urlRegex.test(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
validation: "base64url",
code: ZodError_js_1.ZodIssueCode.invalid_string,
message: check.message
});
status.dirty();
}
} else {
util_js_1.util.assertNever(check);
}
}
return { status: status.value, value: input.data };
}
_regex(regex, validation, message) {
return this.refinement((data) => regex.test(data), {
validation,
code: ZodError_js_1.ZodIssueCode.invalid_string,
...errorUtil_js_1.errorUtil.errToObj(message)
});
}
_addCheck(check) {
return new ZodString({
...this._def,
checks: [...this._def.checks, check]
});
}
email(message) {
return this._addCheck({ kind: "email", ...errorUtil_js_1.errorUtil.errToObj(message) });
}
url(message) {
return this._addCheck({ kind: "url", ...errorUtil_js_1.errorUtil.errToObj(message) });
}
emoji(message) {
return this._addCheck({ kind: "emoji", ...errorUtil_js_1.errorUtil.errToObj(message) });
}
uuid(message) {
return this._addCheck({ kind: "uuid", ...errorUtil_js_1.errorUtil.errToObj(message) });
}
nanoid(message) {
return this._addCheck({ kind: "nanoid", ...errorUtil_js_1.errorUtil.errToObj(message) });
}
cuid(message) {
return this._addCheck({ kind: "cuid", ...errorUtil_js_1.errorUtil.errToObj(message) });
}
cuid2(message) {
return this._addCheck({ kind: "cuid2", ...errorUtil_js_1.errorUtil.errToObj(message) });
}
ulid(message) {
return this._addCheck({ kind: "ulid", ...errorUtil_js_1.errorUtil.errToObj(message) });
}
base64(message) {
return this._addCheck({ kind: "base64", ...errorUtil_js_1.errorUtil.errToObj(message) });
}
base64url(message) {
return this._addCheck({
kind: "base64url",
...errorUtil_js_1.errorUtil.errToObj(message)
});
}
jwt(options) {
return this._addCheck({ kind: "jwt", ...errorUtil_js_1.errorUtil.errToObj(options) });
}
ip(options) {
return this._addCheck({ kind: "ip", ...errorUtil_js_1.errorUtil.errToObj(options) });
}
cidr(options) {
return this._addCheck({ kind: "cidr", ...errorUtil_js_1.errorUtil.errToObj(options) });
}
datetime(options) {
if (typeof options === "string") {
return this._addCheck({
kind: "datetime",
precision: null,
offset: false,
local: false,
message: options
});
}
return this._addCheck({
kind: "datetime",
precision: typeof options?.precision === "undefined" ? null : options?.precision,
offset: options?.offset ?? false,
local: options?.local ?? false,
...errorUtil_js_1.errorUtil.errToObj(options?.message)
});
}
date(message) {
return this._addCheck({ kind: "date", message });
}
time(options) {
if (typeof options === "string") {
return this._addCheck({
kind: "time",
precision: null,
message: options
});
}
return this._addCheck({
kind: "time",
precision: typeof options?.precision === "undefined" ? null : options?.precision,
...errorUtil_js_1.errorUtil.errToObj(options?.message)
});
}
duration(message) {
return this._addCheck({ kind: "duration", ...errorUtil_js_1.errorUtil.errToObj(message) });
}
regex(regex, message) {
return this._addCheck({
kind: "regex",
regex,
...errorUtil_js_1.errorUtil.errToObj(message)
});
}
includes(value, options) {
return this._addCheck({
kind: "includes",
value,
position: options?.position,
...errorUtil_js_1.errorUtil.errToObj(options?.message)
});
}
startsWith(value, message) {
return this._addCheck({
kind: "startsWith",
value,
...errorUtil_js_1.errorUtil.errToObj(message)
});
}
endsWith(value, message) {
return this._addCheck({
kind: "endsWith",
value,
...errorUtil_js_1.errorUtil.errToObj(message)
});
}
min(minLength, message) {
return this._addCheck({
kind: "min",
value: minLength,
...errorUtil_js_1.errorUtil.errToObj(message)
});
}
max(maxLength, message) {
return this._addCheck({
kind: "max",
value: maxLength,
...errorUtil_js_1.errorUtil.errToObj(message)
});
}
length(len, message) {
return this._addCheck({
kind: "length",
value: len,
...errorUtil_js_1.errorUtil.errToObj(message)
});
}
nonempty(message) {
return this.min(1, errorUtil_js_1.errorUtil.errToObj(message));
}
trim() {
return new ZodString({
...this._def,
checks: [...this._def.checks, { kind: "trim" }]
});
}
toLowerCase() {
return new ZodString({
...this._def,
checks: [...this._def.checks, { kind: "toLowerCase" }]
});
}
toUpperCase() {
return new ZodString({
...this._def,
checks: [...this._def.checks, { kind: "toUpperCase" }]
});
}
get isDatetime() {
return !!this._def.checks.find((ch) => ch.kind === "datetime");
}
get isDate() {
return !!this._def.checks.find((ch) => ch.kind === "date");
}
get isTime() {
return !!this._def.checks.find((ch) => ch.kind === "time");
}
get isDuration() {
return !!this._def.checks.find((ch) => ch.kind === "duration");
}
get isEmail() {
return !!this._def.checks.find((ch) => ch.kind === "email");
}
get isURL() {
return !!this._def.checks.find((ch) => ch.kind === "url");
}
get isEmoji() {
return !!this._def.checks.find((ch) => ch.kind === "emoji");
}
get isUUID() {
return !!this._def.checks.find((ch) => ch.kind === "uuid");
}
get isNANOID() {
return !!this._def.checks.find((ch) => ch.kind === "nanoid");
}
get isCUID() {
return !!this._def.checks.find((ch) => ch.kind === "cuid");
}
get isCUID2() {
return !!this._def.checks.find((ch) => ch.kind === "cuid2");
}
get isULID() {
return !!this._def.checks.find((ch) => ch.kind === "ulid");
}
get isIP() {
return !!this._def.checks.find((ch) => ch.kind === "ip");
}
get isCIDR() {
return !!this._def.checks.find((ch) => ch.kind === "cidr");
}
get isBase64() {
return !!this._def.checks.find((ch) => ch.kind === "base64");
}
get isBase64url() {
return !!this._def.checks.find((ch) => ch.kind === "base64url");
}
get minLength() {
let min = null;
for (const ch of this._def.checks) {
if (ch.kind === "min") {
if (min === null || ch.value > min)
min = ch.value;
}
}
return min;
}
get maxLength() {
let max = null;
for (const ch of this._def.checks) {
if (ch.kind === "max") {
if (max === null || ch.value < max)
max = ch.value;
}
}
return max;
}
}
exports.ZodString = ZodString;
ZodString.create = (params) => {
return new ZodString({
checks: [],
typeName: ZodFirstPartyTypeKind.ZodString,
coerce: params?.coerce ?? false,
...processCreateParams(params)
});
};
function floatSafeRemainder(val, step) {
const valDecCount = (val.toString().split(".")[1] || "").length;
const stepDecCount = (step.toString().split(".")[1] || "").length;
const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;
const valInt = Number.parseInt(val.toFixed(decCount).replace(".", ""));
const stepInt = Number.parseInt(step.toFixed(decCount).replace(".", ""));
return valInt % stepInt / 10 ** decCount;
}
class ZodNumber extends ZodType {
constructor() {
super(...arguments);
this.min = this.gte;
this.max = this.lte;
this.step = this.multipleOf;
}
_parse(input) {
if (this._def.coerce) {
input.data = Number(input.data);
}
const parsedType = this._getType(input);
if (parsedType !== util_js_1.ZodParsedType.number) {
const ctx2 = this._getOrReturnCtx(input);
(0, parseUtil_js_1.addIssueToContext)(ctx2, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.number,
received: ctx2.parsedType
});
return parseUtil_js_1.INVALID;
}
let ctx = undefined;
const status = new parseUtil_js_1.ParseStatus;
for (const check of this._def.checks) {
if (check.kind === "int") {
if (!util_js_1.util.isInteger(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: "integer",
received: "float",
message: check.message
});
status.dirty();
}
} else if (check.kind === "min") {
const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;
if (tooSmall) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_small,
minimum: check.value,
type: "number",
inclusive: check.inclusive,
exact: false,
message: check.message
});
status.dirty();
}
} else if (check.kind === "max") {
const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;
if (tooBig) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_big,
maximum: check.value,
type: "number",
inclusive: check.inclusive,
exact: false,
message: check.message
});
status.dirty();
}
} else if (check.kind === "multipleOf") {
if (floatSafeRemainder(input.data, check.value) !== 0) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.not_multiple_of,
multipleOf: check.value,
message: check.message
});
status.dirty();
}
} else if (check.kind === "finite") {
if (!Number.isFinite(input.data)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.not_finite,
message: check.message
});
status.dirty();
}
} else {
util_js_1.util.assertNever(check);
}
}
return { status: status.value, value: input.data };
}
gte(value, message) {
return this.setLimit("min", value, true, errorUtil_js_1.errorUtil.toString(message));
}
gt(value, message) {
return this.setLimit("min", value, false, errorUtil_js_1.errorUtil.toString(message));
}
lte(value, message) {
return this.setLimit("max", value, true, errorUtil_js_1.errorUtil.toString(message));
}
lt(value, message) {
return this.setLimit("max", value, false, errorUtil_js_1.errorUtil.toString(message));
}
setLimit(kind, value, inclusive, message) {
return new ZodNumber({
...this._def,
checks: [
...this._def.checks,
{
kind,
value,
inclusive,
message: errorUtil_js_1.errorUtil.toString(message)
}
]
});
}
_addCheck(check) {
return new ZodNumber({
...this._def,
checks: [...this._def.checks, check]
});
}
int(message) {
return this._addCheck({
kind: "int",
message: errorUtil_js_1.errorUtil.toString(message)
});
}
positive(message) {
return this._addCheck({
kind: "min",
value: 0,
inclusive: false,
message: errorUtil_js_1.errorUtil.toString(message)
});
}
negative(message) {
return this._addCheck({
kind: "max",
value: 0,
inclusive: false,
message: errorUtil_js_1.errorUtil.toString(message)
});
}
nonpositive(message) {
return this._addCheck({
kind: "max",
value: 0,
inclusive: true,
message: errorUtil_js_1.errorUtil.toString(message)
});
}
nonnegative(message) {
return this._addCheck({
kind: "min",
value: 0,
inclusive: true,
message: errorUtil_js_1.errorUtil.toString(message)
});
}
multipleOf(value, message) {
return this._addCheck({
kind: "multipleOf",
value,
message: errorUtil_js_1.errorUtil.toString(message)
});
}
finite(message) {
return this._addCheck({
kind: "finite",
message: errorUtil_js_1.errorUtil.toString(message)
});
}
safe(message) {
return this._addCheck({
kind: "min",
inclusive: true,
value: Number.MIN_SAFE_INTEGER,
message: errorUtil_js_1.errorUtil.toString(message)
})._addCheck({
kind: "max",
inclusive: true,
value: Number.MAX_SAFE_INTEGER,
message: errorUtil_js_1.errorUtil.toString(message)
});
}
get minValue() {
let min = null;
for (const ch of this._def.checks) {
if (ch.kind === "min") {
if (min === null || ch.value > min)
min = ch.value;
}
}
return min;
}
get maxValue() {
let max = null;
for (const ch of this._def.checks) {
if (ch.kind === "max") {
if (max === null || ch.value < max)
max = ch.value;
}
}
return max;
}
get isInt() {
return !!this._def.checks.find((ch) => ch.kind === "int" || ch.kind === "multipleOf" && util_js_1.util.isInteger(ch.value));
}
get isFinite() {
let max = null;
let min = null;
for (const ch of this._def.checks) {
if (ch.kind === "finite" || ch.kind === "int" || ch.kind === "multipleOf") {
return true;
} else if (ch.kind === "min") {
if (min === null || ch.value > min)
min = ch.value;
} else if (ch.kind === "max") {
if (max === null || ch.value < max)
max = ch.value;
}
}
return Number.isFinite(min) && Number.isFinite(max);
}
}
exports.ZodNumber = ZodNumber;
ZodNumber.create = (params) => {
return new ZodNumber({
checks: [],
typeName: ZodFirstPartyTypeKind.ZodNumber,
coerce: params?.coerce || false,
...processCreateParams(params)
});
};
class ZodBigInt extends ZodType {
constructor() {
super(...arguments);
this.min = this.gte;
this.max = this.lte;
}
_parse(input) {
if (this._def.coerce) {
try {
input.data = BigInt(input.data);
} catch {
return this._getInvalidInput(input);
}
}
const parsedType = this._getType(input);
if (parsedType !== util_js_1.ZodParsedType.bigint) {
return this._getInvalidInput(input);
}
let ctx = undefined;
const status = new parseUtil_js_1.ParseStatus;
for (const check of this._def.checks) {
if (check.kind === "min") {
const tooSmall = check.inclusive ? input.data < check.value : input.data <= check.value;
if (tooSmall) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_small,
type: "bigint",
minimum: check.value,
inclusive: check.inclusive,
message: check.message
});
status.dirty();
}
} else if (check.kind === "max") {
const tooBig = check.inclusive ? input.data > check.value : input.data >= check.value;
if (tooBig) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_big,
type: "bigint",
maximum: check.value,
inclusive: check.inclusive,
message: check.message
});
status.dirty();
}
} else if (check.kind === "multipleOf") {
if (input.data % check.value !== BigInt(0)) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.not_multiple_of,
multipleOf: check.value,
message: check.message
});
status.dirty();
}
} else {
util_js_1.util.assertNever(check);
}
}
return { status: status.value, value: input.data };
}
_getInvalidInput(input) {
const ctx = this._getOrReturnCtx(input);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.bigint,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
gte(value, message) {
return this.setLimit("min", value, true, errorUtil_js_1.errorUtil.toString(message));
}
gt(value, message) {
return this.setLimit("min", value, false, errorUtil_js_1.errorUtil.toString(message));
}
lte(value, message) {
return this.setLimit("max", value, true, errorUtil_js_1.errorUtil.toString(message));
}
lt(value, message) {
return this.setLimit("max", value, false, errorUtil_js_1.errorUtil.toString(message));
}
setLimit(kind, value, inclusive, message) {
return new ZodBigInt({
...this._def,
checks: [
...this._def.checks,
{
kind,
value,
inclusive,
message: errorUtil_js_1.errorUtil.toString(message)
}
]
});
}
_addCheck(check) {
return new ZodBigInt({
...this._def,
checks: [...this._def.checks, check]
});
}
positive(message) {
return this._addCheck({
kind: "min",
value: BigInt(0),
inclusive: false,
message: errorUtil_js_1.errorUtil.toString(message)
});
}
negative(message) {
return this._addCheck({
kind: "max",
value: BigInt(0),
inclusive: false,
message: errorUtil_js_1.errorUtil.toString(message)
});
}
nonpositive(message) {
return this._addCheck({
kind: "max",
value: BigInt(0),
inclusive: true,
message: errorUtil_js_1.errorUtil.toString(message)
});
}
nonnegative(message) {
return this._addCheck({
kind: "min",
value: BigInt(0),
inclusive: true,
message: errorUtil_js_1.errorUtil.toString(message)
});
}
multipleOf(value, message) {
return this._addCheck({
kind: "multipleOf",
value,
message: errorUtil_js_1.errorUtil.toString(message)
});
}
get minValue() {
let min = null;
for (const ch of this._def.checks) {
if (ch.kind === "min") {
if (min === null || ch.value > min)
min = ch.value;
}
}
return min;
}
get maxValue() {
let max = null;
for (const ch of this._def.checks) {
if (ch.kind === "max") {
if (max === null || ch.value < max)
max = ch.value;
}
}
return max;
}
}
exports.ZodBigInt = ZodBigInt;
ZodBigInt.create = (params) => {
return new ZodBigInt({
checks: [],
typeName: ZodFirstPartyTypeKind.ZodBigInt,
coerce: params?.coerce ?? false,
...processCreateParams(params)
});
};
class ZodBoolean extends ZodType {
_parse(input) {
if (this._def.coerce) {
input.data = Boolean(input.data);
}
const parsedType = this._getType(input);
if (parsedType !== util_js_1.ZodParsedType.boolean) {
const ctx = this._getOrReturnCtx(input);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.boolean,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
return (0, parseUtil_js_1.OK)(input.data);
}
}
exports.ZodBoolean = ZodBoolean;
ZodBoolean.create = (params) => {
return new ZodBoolean({
typeName: ZodFirstPartyTypeKind.ZodBoolean,
coerce: params?.coerce || false,
...processCreateParams(params)
});
};
class ZodDate extends ZodType {
_parse(input) {
if (this._def.coerce) {
input.data = new Date(input.data);
}
const parsedType = this._getType(input);
if (parsedType !== util_js_1.ZodParsedType.date) {
const ctx2 = this._getOrReturnCtx(input);
(0, parseUtil_js_1.addIssueToContext)(ctx2, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.date,
received: ctx2.parsedType
});
return parseUtil_js_1.INVALID;
}
if (Number.isNaN(input.data.getTime())) {
const ctx2 = this._getOrReturnCtx(input);
(0, parseUtil_js_1.addIssueToContext)(ctx2, {
code: ZodError_js_1.ZodIssueCode.invalid_date
});
return parseUtil_js_1.INVALID;
}
const status = new parseUtil_js_1.ParseStatus;
let ctx = undefined;
for (const check of this._def.checks) {
if (check.kind === "min") {
if (input.data.getTime() < check.value) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_small,
message: check.message,
inclusive: true,
exact: false,
minimum: check.value,
type: "date"
});
status.dirty();
}
} else if (check.kind === "max") {
if (input.data.getTime() > check.value) {
ctx = this._getOrReturnCtx(input, ctx);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_big,
message: check.message,
inclusive: true,
exact: false,
maximum: check.value,
type: "date"
});
status.dirty();
}
} else {
util_js_1.util.assertNever(check);
}
}
return {
status: status.value,
value: new Date(input.data.getTime())
};
}
_addCheck(check) {
return new ZodDate({
...this._def,
checks: [...this._def.checks, check]
});
}
min(minDate, message) {
return this._addCheck({
kind: "min",
value: minDate.getTime(),
message: errorUtil_js_1.errorUtil.toString(message)
});
}
max(maxDate, message) {
return this._addCheck({
kind: "max",
value: maxDate.getTime(),
message: errorUtil_js_1.errorUtil.toString(message)
});
}
get minDate() {
let min = null;
for (const ch of this._def.checks) {
if (ch.kind === "min") {
if (min === null || ch.value > min)
min = ch.value;
}
}
return min != null ? new Date(min) : null;
}
get maxDate() {
let max = null;
for (const ch of this._def.checks) {
if (ch.kind === "max") {
if (max === null || ch.value < max)
max = ch.value;
}
}
return max != null ? new Date(max) : null;
}
}
exports.ZodDate = ZodDate;
ZodDate.create = (params) => {
return new ZodDate({
checks: [],
coerce: params?.coerce || false,
typeName: ZodFirstPartyTypeKind.ZodDate,
...processCreateParams(params)
});
};
class ZodSymbol extends ZodType {
_parse(input) {
const parsedType = this._getType(input);
if (parsedType !== util_js_1.ZodParsedType.symbol) {
const ctx = this._getOrReturnCtx(input);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.symbol,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
return (0, parseUtil_js_1.OK)(input.data);
}
}
exports.ZodSymbol = ZodSymbol;
ZodSymbol.create = (params) => {
return new ZodSymbol({
typeName: ZodFirstPartyTypeKind.ZodSymbol,
...processCreateParams(params)
});
};
class ZodUndefined extends ZodType {
_parse(input) {
const parsedType = this._getType(input);
if (parsedType !== util_js_1.ZodParsedType.undefined) {
const ctx = this._getOrReturnCtx(input);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.undefined,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
return (0, parseUtil_js_1.OK)(input.data);
}
}
exports.ZodUndefined = ZodUndefined;
ZodUndefined.create = (params) => {
return new ZodUndefined({
typeName: ZodFirstPartyTypeKind.ZodUndefined,
...processCreateParams(params)
});
};
class ZodNull extends ZodType {
_parse(input) {
const parsedType = this._getType(input);
if (parsedType !== util_js_1.ZodParsedType.null) {
const ctx = this._getOrReturnCtx(input);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.null,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
return (0, parseUtil_js_1.OK)(input.data);
}
}
exports.ZodNull = ZodNull;
ZodNull.create = (params) => {
return new ZodNull({
typeName: ZodFirstPartyTypeKind.ZodNull,
...processCreateParams(params)
});
};
class ZodAny extends ZodType {
constructor() {
super(...arguments);
this._any = true;
}
_parse(input) {
return (0, parseUtil_js_1.OK)(input.data);
}
}
exports.ZodAny = ZodAny;
ZodAny.create = (params) => {
return new ZodAny({
typeName: ZodFirstPartyTypeKind.ZodAny,
...processCreateParams(params)
});
};
class ZodUnknown extends ZodType {
constructor() {
super(...arguments);
this._unknown = true;
}
_parse(input) {
return (0, parseUtil_js_1.OK)(input.data);
}
}
exports.ZodUnknown = ZodUnknown;
ZodUnknown.create = (params) => {
return new ZodUnknown({
typeName: ZodFirstPartyTypeKind.ZodUnknown,
...processCreateParams(params)
});
};
class ZodNever extends ZodType {
_parse(input) {
const ctx = this._getOrReturnCtx(input);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.never,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
}
exports.ZodNever = ZodNever;
ZodNever.create = (params) => {
return new ZodNever({
typeName: ZodFirstPartyTypeKind.ZodNever,
...processCreateParams(params)
});
};
class ZodVoid extends ZodType {
_parse(input) {
const parsedType = this._getType(input);
if (parsedType !== util_js_1.ZodParsedType.undefined) {
const ctx = this._getOrReturnCtx(input);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.void,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
return (0, parseUtil_js_1.OK)(input.data);
}
}
exports.ZodVoid = ZodVoid;
ZodVoid.create = (params) => {
return new ZodVoid({
typeName: ZodFirstPartyTypeKind.ZodVoid,
...processCreateParams(params)
});
};
class ZodArray extends ZodType {
_parse(input) {
const { ctx, status } = this._processInputParams(input);
const def = this._def;
if (ctx.parsedType !== util_js_1.ZodParsedType.array) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.array,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
if (def.exactLength !== null) {
const tooBig = ctx.data.length > def.exactLength.value;
const tooSmall = ctx.data.length < def.exactLength.value;
if (tooBig || tooSmall) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: tooBig ? ZodError_js_1.ZodIssueCode.too_big : ZodError_js_1.ZodIssueCode.too_small,
minimum: tooSmall ? def.exactLength.value : undefined,
maximum: tooBig ? def.exactLength.value : undefined,
type: "array",
inclusive: true,
exact: true,
message: def.exactLength.message
});
status.dirty();
}
}
if (def.minLength !== null) {
if (ctx.data.length < def.minLength.value) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_small,
minimum: def.minLength.value,
type: "array",
inclusive: true,
exact: false,
message: def.minLength.message
});
status.dirty();
}
}
if (def.maxLength !== null) {
if (ctx.data.length > def.maxLength.value) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_big,
maximum: def.maxLength.value,
type: "array",
inclusive: true,
exact: false,
message: def.maxLength.message
});
status.dirty();
}
}
if (ctx.common.async) {
return Promise.all([...ctx.data].map((item, i) => {
return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));
})).then((result2) => {
return parseUtil_js_1.ParseStatus.mergeArray(status, result2);
});
}
const result = [...ctx.data].map((item, i) => {
return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));
});
return parseUtil_js_1.ParseStatus.mergeArray(status, result);
}
get element() {
return this._def.type;
}
min(minLength, message) {
return new ZodArray({
...this._def,
minLength: { value: minLength, message: errorUtil_js_1.errorUtil.toString(message) }
});
}
max(maxLength, message) {
return new ZodArray({
...this._def,
maxLength: { value: maxLength, message: errorUtil_js_1.errorUtil.toString(message) }
});
}
length(len, message) {
return new ZodArray({
...this._def,
exactLength: { value: len, message: errorUtil_js_1.errorUtil.toString(message) }
});
}
nonempty(message) {
return this.min(1, message);
}
}
exports.ZodArray = ZodArray;
ZodArray.create = (schema, params) => {
return new ZodArray({
type: schema,
minLength: null,
maxLength: null,
exactLength: null,
typeName: ZodFirstPartyTypeKind.ZodArray,
...processCreateParams(params)
});
};
function deepPartialify(schema) {
if (schema instanceof ZodObject) {
const newShape = {};
for (const key in schema.shape) {
const fieldSchema = schema.shape[key];
newShape[key] = ZodOptional.create(deepPartialify(fieldSchema));
}
return new ZodObject({
...schema._def,
shape: () => newShape
});
} else if (schema instanceof ZodArray) {
return new ZodArray({
...schema._def,
type: deepPartialify(schema.element)
});
} else if (schema instanceof ZodOptional) {
return ZodOptional.create(deepPartialify(schema.unwrap()));
} else if (schema instanceof ZodNullable) {
return ZodNullable.create(deepPartialify(schema.unwrap()));
} else if (schema instanceof ZodTuple) {
return ZodTuple.create(schema.items.map((item) => deepPartialify(item)));
} else {
return schema;
}
}
class ZodObject extends ZodType {
constructor() {
super(...arguments);
this._cached = null;
this.nonstrict = this.passthrough;
this.augment = this.extend;
}
_getCached() {
if (this._cached !== null)
return this._cached;
const shape = this._def.shape();
const keys = util_js_1.util.objectKeys(shape);
this._cached = { shape, keys };
return this._cached;
}
_parse(input) {
const parsedType = this._getType(input);
if (parsedType !== util_js_1.ZodParsedType.object) {
const ctx2 = this._getOrReturnCtx(input);
(0, parseUtil_js_1.addIssueToContext)(ctx2, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.object,
received: ctx2.parsedType
});
return parseUtil_js_1.INVALID;
}
const { status, ctx } = this._processInputParams(input);
const { shape, keys: shapeKeys } = this._getCached();
const extraKeys = [];
if (!(this._def.catchall instanceof ZodNever && this._def.unknownKeys === "strip")) {
for (const key in ctx.data) {
if (!shapeKeys.includes(key)) {
extraKeys.push(key);
}
}
}
const pairs = [];
for (const key of shapeKeys) {
const keyValidator = shape[key];
const value = ctx.data[key];
pairs.push({
key: { status: "valid", value: key },
value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)),
alwaysSet: key in ctx.data
});
}
if (this._def.catchall instanceof ZodNever) {
const unknownKeys = this._def.unknownKeys;
if (unknownKeys === "passthrough") {
for (const key of extraKeys) {
pairs.push({
key: { status: "valid", value: key },
value: { status: "valid", value: ctx.data[key] }
});
}
} else if (unknownKeys === "strict") {
if (extraKeys.length > 0) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.unrecognized_keys,
keys: extraKeys
});
status.dirty();
}
} else if (unknownKeys === "strip") {} else {
throw new Error(`Internal ZodObject error: invalid unknownKeys value.`);
}
} else {
const catchall = this._def.catchall;
for (const key of extraKeys) {
const value = ctx.data[key];
pairs.push({
key: { status: "valid", value: key },
value: catchall._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)),
alwaysSet: key in ctx.data
});
}
}
if (ctx.common.async) {
return Promise.resolve().then(async () => {
const syncPairs = [];
for (const pair of pairs) {
const key = await pair.key;
const value = await pair.value;
syncPairs.push({
key,
value,
alwaysSet: pair.alwaysSet
});
}
return syncPairs;
}).then((syncPairs) => {
return parseUtil_js_1.ParseStatus.mergeObjectSync(status, syncPairs);
});
} else {
return parseUtil_js_1.ParseStatus.mergeObjectSync(status, pairs);
}
}
get shape() {
return this._def.shape();
}
strict(message) {
errorUtil_js_1.errorUtil.errToObj;
return new ZodObject({
...this._def,
unknownKeys: "strict",
...message !== undefined ? {
errorMap: (issue, ctx) => {
const defaultError = this._def.errorMap?.(issue, ctx).message ?? ctx.defaultError;
if (issue.code === "unrecognized_keys")
return {
message: errorUtil_js_1.errorUtil.errToObj(message).message ?? defaultError
};
return {
message: defaultError
};
}
} : {}
});
}
strip() {
return new ZodObject({
...this._def,
unknownKeys: "strip"
});
}
passthrough() {
return new ZodObject({
...this._def,
unknownKeys: "passthrough"
});
}
extend(augmentation) {
return new ZodObject({
...this._def,
shape: () => ({
...this._def.shape(),
...augmentation
})
});
}
merge(merging) {
const merged = new ZodObject({
unknownKeys: merging._def.unknownKeys,
catchall: merging._def.catchall,
shape: () => ({
...this._def.shape(),
...merging._def.shape()
}),
typeName: ZodFirstPartyTypeKind.ZodObject
});
return merged;
}
setKey(key, schema) {
return this.augment({ [key]: schema });
}
catchall(index) {
return new ZodObject({
...this._def,
catchall: index
});
}
pick(mask) {
const shape = {};
for (const key of util_js_1.util.objectKeys(mask)) {
if (mask[key] && this.shape[key]) {
shape[key] = this.shape[key];
}
}
return new ZodObject({
...this._def,
shape: () => shape
});
}
omit(mask) {
const shape = {};
for (const key of util_js_1.util.objectKeys(this.shape)) {
if (!mask[key]) {
shape[key] = this.shape[key];
}
}
return new ZodObject({
...this._def,
shape: () => shape
});
}
deepPartial() {
return deepPartialify(this);
}
partial(mask) {
const newShape = {};
for (const key of util_js_1.util.objectKeys(this.shape)) {
const fieldSchema = this.shape[key];
if (mask && !mask[key]) {
newShape[key] = fieldSchema;
} else {
newShape[key] = fieldSchema.optional();
}
}
return new ZodObject({
...this._def,
shape: () => newShape
});
}
required(mask) {
const newShape = {};
for (const key of util_js_1.util.objectKeys(this.shape)) {
if (mask && !mask[key]) {
newShape[key] = this.shape[key];
} else {
const fieldSchema = this.shape[key];
let newField = fieldSchema;
while (newField instanceof ZodOptional) {
newField = newField._def.innerType;
}
newShape[key] = newField;
}
}
return new ZodObject({
...this._def,
shape: () => newShape
});
}
keyof() {
return createZodEnum(util_js_1.util.objectKeys(this.shape));
}
}
exports.ZodObject = ZodObject;
ZodObject.create = (shape, params) => {
return new ZodObject({
shape: () => shape,
unknownKeys: "strip",
catchall: ZodNever.create(),
typeName: ZodFirstPartyTypeKind.ZodObject,
...processCreateParams(params)
});
};
ZodObject.strictCreate = (shape, params) => {
return new ZodObject({
shape: () => shape,
unknownKeys: "strict",
catchall: ZodNever.create(),
typeName: ZodFirstPartyTypeKind.ZodObject,
...processCreateParams(params)
});
};
ZodObject.lazycreate = (shape, params) => {
return new ZodObject({
shape,
unknownKeys: "strip",
catchall: ZodNever.create(),
typeName: ZodFirstPartyTypeKind.ZodObject,
...processCreateParams(params)
});
};
class ZodUnion extends ZodType {
_parse(input) {
const { ctx } = this._processInputParams(input);
const options = this._def.options;
function handleResults(results) {
for (const result of results) {
if (result.result.status === "valid") {
return result.result;
}
}
for (const result of results) {
if (result.result.status === "dirty") {
ctx.common.issues.push(...result.ctx.common.issues);
return result.result;
}
}
const unionErrors = results.map((result) => new ZodError_js_1.ZodError(result.ctx.common.issues));
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_union,
unionErrors
});
return parseUtil_js_1.INVALID;
}
if (ctx.common.async) {
return Promise.all(options.map(async (option) => {
const childCtx = {
...ctx,
common: {
...ctx.common,
issues: []
},
parent: null
};
return {
result: await option._parseAsync({
data: ctx.data,
path: ctx.path,
parent: childCtx
}),
ctx: childCtx
};
})).then(handleResults);
} else {
let dirty = undefined;
const issues = [];
for (const option of options) {
const childCtx = {
...ctx,
common: {
...ctx.common,
issues: []
},
parent: null
};
const result = option._parseSync({
data: ctx.data,
path: ctx.path,
parent: childCtx
});
if (result.status === "valid") {
return result;
} else if (result.status === "dirty" && !dirty) {
dirty = { result, ctx: childCtx };
}
if (childCtx.common.issues.length) {
issues.push(childCtx.common.issues);
}
}
if (dirty) {
ctx.common.issues.push(...dirty.ctx.common.issues);
return dirty.result;
}
const unionErrors = issues.map((issues2) => new ZodError_js_1.ZodError(issues2));
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_union,
unionErrors
});
return parseUtil_js_1.INVALID;
}
}
get options() {
return this._def.options;
}
}
exports.ZodUnion = ZodUnion;
ZodUnion.create = (types, params) => {
return new ZodUnion({
options: types,
typeName: ZodFirstPartyTypeKind.ZodUnion,
...processCreateParams(params)
});
};
var getDiscriminator = (type) => {
if (type instanceof ZodLazy) {
return getDiscriminator(type.schema);
} else if (type instanceof ZodEffects) {
return getDiscriminator(type.innerType());
} else if (type instanceof ZodLiteral) {
return [type.value];
} else if (type instanceof ZodEnum) {
return type.options;
} else if (type instanceof ZodNativeEnum) {
return util_js_1.util.objectValues(type.enum);
} else if (type instanceof ZodDefault) {
return getDiscriminator(type._def.innerType);
} else if (type instanceof ZodUndefined) {
return [undefined];
} else if (type instanceof ZodNull) {
return [null];
} else if (type instanceof ZodOptional) {
return [undefined, ...getDiscriminator(type.unwrap())];
} else if (type instanceof ZodNullable) {
return [null, ...getDiscriminator(type.unwrap())];
} else if (type instanceof ZodBranded) {
return getDiscriminator(type.unwrap());
} else if (type instanceof ZodReadonly) {
return getDiscriminator(type.unwrap());
} else if (type instanceof ZodCatch) {
return getDiscriminator(type._def.innerType);
} else {
return [];
}
};
class ZodDiscriminatedUnion extends ZodType {
_parse(input) {
const { ctx } = this._processInputParams(input);
if (ctx.parsedType !== util_js_1.ZodParsedType.object) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.object,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
const discriminator = this.discriminator;
const discriminatorValue = ctx.data[discriminator];
const option = this.optionsMap.get(discriminatorValue);
if (!option) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_union_discriminator,
options: Array.from(this.optionsMap.keys()),
path: [discriminator]
});
return parseUtil_js_1.INVALID;
}
if (ctx.common.async) {
return option._parseAsync({
data: ctx.data,
path: ctx.path,
parent: ctx
});
} else {
return option._parseSync({
data: ctx.data,
path: ctx.path,
parent: ctx
});
}
}
get discriminator() {
return this._def.discriminator;
}
get options() {
return this._def.options;
}
get optionsMap() {
return this._def.optionsMap;
}
static create(discriminator, options, params) {
const optionsMap = new Map;
for (const type of options) {
const discriminatorValues = getDiscriminator(type.shape[discriminator]);
if (!discriminatorValues.length) {
throw new Error(`A discriminator value for key \`${discriminator}\` could not be extracted from all schema options`);
}
for (const value of discriminatorValues) {
if (optionsMap.has(value)) {
throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`);
}
optionsMap.set(value, type);
}
}
return new ZodDiscriminatedUnion({
typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion,
discriminator,
options,
optionsMap,
...processCreateParams(params)
});
}
}
exports.ZodDiscriminatedUnion = ZodDiscriminatedUnion;
function mergeValues(a, b) {
const aType = (0, util_js_1.getParsedType)(a);
const bType = (0, util_js_1.getParsedType)(b);
if (a === b) {
return { valid: true, data: a };
} else if (aType === util_js_1.ZodParsedType.object && bType === util_js_1.ZodParsedType.object) {
const bKeys = util_js_1.util.objectKeys(b);
const sharedKeys = util_js_1.util.objectKeys(a).filter((key) => bKeys.indexOf(key) !== -1);
const newObj = { ...a, ...b };
for (const key of sharedKeys) {
const sharedValue = mergeValues(a[key], b[key]);
if (!sharedValue.valid) {
return { valid: false };
}
newObj[key] = sharedValue.data;
}
return { valid: true, data: newObj };
} else if (aType === util_js_1.ZodParsedType.array && bType === util_js_1.ZodParsedType.array) {
if (a.length !== b.length) {
return { valid: false };
}
const newArray = [];
for (let index = 0;index < a.length; index++) {
const itemA = a[index];
const itemB = b[index];
const sharedValue = mergeValues(itemA, itemB);
if (!sharedValue.valid) {
return { valid: false };
}
newArray.push(sharedValue.data);
}
return { valid: true, data: newArray };
} else if (aType === util_js_1.ZodParsedType.date && bType === util_js_1.ZodParsedType.date && +a === +b) {
return { valid: true, data: a };
} else {
return { valid: false };
}
}
class ZodIntersection extends ZodType {
_parse(input) {
const { status, ctx } = this._processInputParams(input);
const handleParsed = (parsedLeft, parsedRight) => {
if ((0, parseUtil_js_1.isAborted)(parsedLeft) || (0, parseUtil_js_1.isAborted)(parsedRight)) {
return parseUtil_js_1.INVALID;
}
const merged = mergeValues(parsedLeft.value, parsedRight.value);
if (!merged.valid) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_intersection_types
});
return parseUtil_js_1.INVALID;
}
if ((0, parseUtil_js_1.isDirty)(parsedLeft) || (0, parseUtil_js_1.isDirty)(parsedRight)) {
status.dirty();
}
return { status: status.value, value: merged.data };
};
if (ctx.common.async) {
return Promise.all([
this._def.left._parseAsync({
data: ctx.data,
path: ctx.path,
parent: ctx
}),
this._def.right._parseAsync({
data: ctx.data,
path: ctx.path,
parent: ctx
})
]).then(([left, right]) => handleParsed(left, right));
} else {
return handleParsed(this._def.left._parseSync({
data: ctx.data,
path: ctx.path,
parent: ctx
}), this._def.right._parseSync({
data: ctx.data,
path: ctx.path,
parent: ctx
}));
}
}
}
exports.ZodIntersection = ZodIntersection;
ZodIntersection.create = (left, right, params) => {
return new ZodIntersection({
left,
right,
typeName: ZodFirstPartyTypeKind.ZodIntersection,
...processCreateParams(params)
});
};
class ZodTuple extends ZodType {
_parse(input) {
const { status, ctx } = this._processInputParams(input);
if (ctx.parsedType !== util_js_1.ZodParsedType.array) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.array,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
if (ctx.data.length < this._def.items.length) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_small,
minimum: this._def.items.length,
inclusive: true,
exact: false,
type: "array"
});
return parseUtil_js_1.INVALID;
}
const rest = this._def.rest;
if (!rest && ctx.data.length > this._def.items.length) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_big,
maximum: this._def.items.length,
inclusive: true,
exact: false,
type: "array"
});
status.dirty();
}
const items = [...ctx.data].map((item, itemIndex) => {
const schema = this._def.items[itemIndex] || this._def.rest;
if (!schema)
return null;
return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex));
}).filter((x) => !!x);
if (ctx.common.async) {
return Promise.all(items).then((results) => {
return parseUtil_js_1.ParseStatus.mergeArray(status, results);
});
} else {
return parseUtil_js_1.ParseStatus.mergeArray(status, items);
}
}
get items() {
return this._def.items;
}
rest(rest) {
return new ZodTuple({
...this._def,
rest
});
}
}
exports.ZodTuple = ZodTuple;
ZodTuple.create = (schemas, params) => {
if (!Array.isArray(schemas)) {
throw new Error("You must pass an array of schemas to z.tuple([ ... ])");
}
return new ZodTuple({
items: schemas,
typeName: ZodFirstPartyTypeKind.ZodTuple,
rest: null,
...processCreateParams(params)
});
};
class ZodRecord extends ZodType {
get keySchema() {
return this._def.keyType;
}
get valueSchema() {
return this._def.valueType;
}
_parse(input) {
const { status, ctx } = this._processInputParams(input);
if (ctx.parsedType !== util_js_1.ZodParsedType.object) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.object,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
const pairs = [];
const keyType = this._def.keyType;
const valueType = this._def.valueType;
for (const key in ctx.data) {
pairs.push({
key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)),
value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)),
alwaysSet: key in ctx.data
});
}
if (ctx.common.async) {
return parseUtil_js_1.ParseStatus.mergeObjectAsync(status, pairs);
} else {
return parseUtil_js_1.ParseStatus.mergeObjectSync(status, pairs);
}
}
get element() {
return this._def.valueType;
}
static create(first, second, third) {
if (second instanceof ZodType) {
return new ZodRecord({
keyType: first,
valueType: second,
typeName: ZodFirstPartyTypeKind.ZodRecord,
...processCreateParams(third)
});
}
return new ZodRecord({
keyType: ZodString.create(),
valueType: first,
typeName: ZodFirstPartyTypeKind.ZodRecord,
...processCreateParams(second)
});
}
}
exports.ZodRecord = ZodRecord;
class ZodMap extends ZodType {
get keySchema() {
return this._def.keyType;
}
get valueSchema() {
return this._def.valueType;
}
_parse(input) {
const { status, ctx } = this._processInputParams(input);
if (ctx.parsedType !== util_js_1.ZodParsedType.map) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.map,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
const keyType = this._def.keyType;
const valueType = this._def.valueType;
const pairs = [...ctx.data.entries()].map(([key, value], index) => {
return {
key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, "key"])),
value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, "value"]))
};
});
if (ctx.common.async) {
const finalMap = new Map;
return Promise.resolve().then(async () => {
for (const pair of pairs) {
const key = await pair.key;
const value = await pair.value;
if (key.status === "aborted" || value.status === "aborted") {
return parseUtil_js_1.INVALID;
}
if (key.status === "dirty" || value.status === "dirty") {
status.dirty();
}
finalMap.set(key.value, value.value);
}
return { status: status.value, value: finalMap };
});
} else {
const finalMap = new Map;
for (const pair of pairs) {
const key = pair.key;
const value = pair.value;
if (key.status === "aborted" || value.status === "aborted") {
return parseUtil_js_1.INVALID;
}
if (key.status === "dirty" || value.status === "dirty") {
status.dirty();
}
finalMap.set(key.value, value.value);
}
return { status: status.value, value: finalMap };
}
}
}
exports.ZodMap = ZodMap;
ZodMap.create = (keyType, valueType, params) => {
return new ZodMap({
valueType,
keyType,
typeName: ZodFirstPartyTypeKind.ZodMap,
...processCreateParams(params)
});
};
class ZodSet extends ZodType {
_parse(input) {
const { status, ctx } = this._processInputParams(input);
if (ctx.parsedType !== util_js_1.ZodParsedType.set) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.set,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
const def = this._def;
if (def.minSize !== null) {
if (ctx.data.size < def.minSize.value) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_small,
minimum: def.minSize.value,
type: "set",
inclusive: true,
exact: false,
message: def.minSize.message
});
status.dirty();
}
}
if (def.maxSize !== null) {
if (ctx.data.size > def.maxSize.value) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.too_big,
maximum: def.maxSize.value,
type: "set",
inclusive: true,
exact: false,
message: def.maxSize.message
});
status.dirty();
}
}
const valueType = this._def.valueType;
function finalizeSet(elements2) {
const parsedSet = new Set;
for (const element of elements2) {
if (element.status === "aborted")
return parseUtil_js_1.INVALID;
if (element.status === "dirty")
status.dirty();
parsedSet.add(element.value);
}
return { status: status.value, value: parsedSet };
}
const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)));
if (ctx.common.async) {
return Promise.all(elements).then((elements2) => finalizeSet(elements2));
} else {
return finalizeSet(elements);
}
}
min(minSize, message) {
return new ZodSet({
...this._def,
minSize: { value: minSize, message: errorUtil_js_1.errorUtil.toString(message) }
});
}
max(maxSize, message) {
return new ZodSet({
...this._def,
maxSize: { value: maxSize, message: errorUtil_js_1.errorUtil.toString(message) }
});
}
size(size, message) {
return this.min(size, message).max(size, message);
}
nonempty(message) {
return this.min(1, message);
}
}
exports.ZodSet = ZodSet;
ZodSet.create = (valueType, params) => {
return new ZodSet({
valueType,
minSize: null,
maxSize: null,
typeName: ZodFirstPartyTypeKind.ZodSet,
...processCreateParams(params)
});
};
class ZodFunction extends ZodType {
constructor() {
super(...arguments);
this.validate = this.implement;
}
_parse(input) {
const { ctx } = this._processInputParams(input);
if (ctx.parsedType !== util_js_1.ZodParsedType.function) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.function,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
function makeArgsIssue(args, error) {
return (0, parseUtil_js_1.makeIssue)({
data: args,
path: ctx.path,
errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, (0, errors_js_1.getErrorMap)(), errors_js_1.defaultErrorMap].filter((x) => !!x),
issueData: {
code: ZodError_js_1.ZodIssueCode.invalid_arguments,
argumentsError: error
}
});
}
function makeReturnsIssue(returns, error) {
return (0, parseUtil_js_1.makeIssue)({
data: returns,
path: ctx.path,
errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, (0, errors_js_1.getErrorMap)(), errors_js_1.defaultErrorMap].filter((x) => !!x),
issueData: {
code: ZodError_js_1.ZodIssueCode.invalid_return_type,
returnTypeError: error
}
});
}
const params = { errorMap: ctx.common.contextualErrorMap };
const fn = ctx.data;
if (this._def.returns instanceof ZodPromise) {
const me = this;
return (0, parseUtil_js_1.OK)(async function(...args) {
const error = new ZodError_js_1.ZodError([]);
const parsedArgs = await me._def.args.parseAsync(args, params).catch((e) => {
error.addIssue(makeArgsIssue(args, e));
throw error;
});
const result = await Reflect.apply(fn, this, parsedArgs);
const parsedReturns = await me._def.returns._def.type.parseAsync(result, params).catch((e) => {
error.addIssue(makeReturnsIssue(result, e));
throw error;
});
return parsedReturns;
});
} else {
const me = this;
return (0, parseUtil_js_1.OK)(function(...args) {
const parsedArgs = me._def.args.safeParse(args, params);
if (!parsedArgs.success) {
throw new ZodError_js_1.ZodError([makeArgsIssue(args, parsedArgs.error)]);
}
const result = Reflect.apply(fn, this, parsedArgs.data);
const parsedReturns = me._def.returns.safeParse(result, params);
if (!parsedReturns.success) {
throw new ZodError_js_1.ZodError([makeReturnsIssue(result, parsedReturns.error)]);
}
return parsedReturns.data;
});
}
}
parameters() {
return this._def.args;
}
returnType() {
return this._def.returns;
}
args(...items) {
return new ZodFunction({
...this._def,
args: ZodTuple.create(items).rest(ZodUnknown.create())
});
}
returns(returnType) {
return new ZodFunction({
...this._def,
returns: returnType
});
}
implement(func) {
const validatedFunc = this.parse(func);
return validatedFunc;
}
strictImplement(func) {
const validatedFunc = this.parse(func);
return validatedFunc;
}
static create(args, returns, params) {
return new ZodFunction({
args: args ? args : ZodTuple.create([]).rest(ZodUnknown.create()),
returns: returns || ZodUnknown.create(),
typeName: ZodFirstPartyTypeKind.ZodFunction,
...processCreateParams(params)
});
}
}
exports.ZodFunction = ZodFunction;
class ZodLazy extends ZodType {
get schema() {
return this._def.getter();
}
_parse(input) {
const { ctx } = this._processInputParams(input);
const lazySchema = this._def.getter();
return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx });
}
}
exports.ZodLazy = ZodLazy;
ZodLazy.create = (getter, params) => {
return new ZodLazy({
getter,
typeName: ZodFirstPartyTypeKind.ZodLazy,
...processCreateParams(params)
});
};
class ZodLiteral extends ZodType {
_parse(input) {
if (input.data !== this._def.value) {
const ctx = this._getOrReturnCtx(input);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
received: ctx.data,
code: ZodError_js_1.ZodIssueCode.invalid_literal,
expected: this._def.value
});
return parseUtil_js_1.INVALID;
}
return { status: "valid", value: input.data };
}
get value() {
return this._def.value;
}
}
exports.ZodLiteral = ZodLiteral;
ZodLiteral.create = (value, params) => {
return new ZodLiteral({
value,
typeName: ZodFirstPartyTypeKind.ZodLiteral,
...processCreateParams(params)
});
};
function createZodEnum(values, params) {
return new ZodEnum({
values,
typeName: ZodFirstPartyTypeKind.ZodEnum,
...processCreateParams(params)
});
}
class ZodEnum extends ZodType {
_parse(input) {
if (typeof input.data !== "string") {
const ctx = this._getOrReturnCtx(input);
const expectedValues = this._def.values;
(0, parseUtil_js_1.addIssueToContext)(ctx, {
expected: util_js_1.util.joinValues(expectedValues),
received: ctx.parsedType,
code: ZodError_js_1.ZodIssueCode.invalid_type
});
return parseUtil_js_1.INVALID;
}
if (!this._cache) {
this._cache = new Set(this._def.values);
}
if (!this._cache.has(input.data)) {
const ctx = this._getOrReturnCtx(input);
const expectedValues = this._def.values;
(0, parseUtil_js_1.addIssueToContext)(ctx, {
received: ctx.data,
code: ZodError_js_1.ZodIssueCode.invalid_enum_value,
options: expectedValues
});
return parseUtil_js_1.INVALID;
}
return (0, parseUtil_js_1.OK)(input.data);
}
get options() {
return this._def.values;
}
get enum() {
const enumValues = {};
for (const val of this._def.values) {
enumValues[val] = val;
}
return enumValues;
}
get Values() {
const enumValues = {};
for (const val of this._def.values) {
enumValues[val] = val;
}
return enumValues;
}
get Enum() {
const enumValues = {};
for (const val of this._def.values) {
enumValues[val] = val;
}
return enumValues;
}
extract(values, newDef = this._def) {
return ZodEnum.create(values, {
...this._def,
...newDef
});
}
exclude(values, newDef = this._def) {
return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)), {
...this._def,
...newDef
});
}
}
exports.ZodEnum = ZodEnum;
ZodEnum.create = createZodEnum;
class ZodNativeEnum extends ZodType {
_parse(input) {
const nativeEnumValues = util_js_1.util.getValidEnumValues(this._def.values);
const ctx = this._getOrReturnCtx(input);
if (ctx.parsedType !== util_js_1.ZodParsedType.string && ctx.parsedType !== util_js_1.ZodParsedType.number) {
const expectedValues = util_js_1.util.objectValues(nativeEnumValues);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
expected: util_js_1.util.joinValues(expectedValues),
received: ctx.parsedType,
code: ZodError_js_1.ZodIssueCode.invalid_type
});
return parseUtil_js_1.INVALID;
}
if (!this._cache) {
this._cache = new Set(util_js_1.util.getValidEnumValues(this._def.values));
}
if (!this._cache.has(input.data)) {
const expectedValues = util_js_1.util.objectValues(nativeEnumValues);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
received: ctx.data,
code: ZodError_js_1.ZodIssueCode.invalid_enum_value,
options: expectedValues
});
return parseUtil_js_1.INVALID;
}
return (0, parseUtil_js_1.OK)(input.data);
}
get enum() {
return this._def.values;
}
}
exports.ZodNativeEnum = ZodNativeEnum;
ZodNativeEnum.create = (values, params) => {
return new ZodNativeEnum({
values,
typeName: ZodFirstPartyTypeKind.ZodNativeEnum,
...processCreateParams(params)
});
};
class ZodPromise extends ZodType {
unwrap() {
return this._def.type;
}
_parse(input) {
const { ctx } = this._processInputParams(input);
if (ctx.parsedType !== util_js_1.ZodParsedType.promise && ctx.common.async === false) {
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.promise,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
const promisified = ctx.parsedType === util_js_1.ZodParsedType.promise ? ctx.data : Promise.resolve(ctx.data);
return (0, parseUtil_js_1.OK)(promisified.then((data) => {
return this._def.type.parseAsync(data, {
path: ctx.path,
errorMap: ctx.common.contextualErrorMap
});
}));
}
}
exports.ZodPromise = ZodPromise;
ZodPromise.create = (schema, params) => {
return new ZodPromise({
type: schema,
typeName: ZodFirstPartyTypeKind.ZodPromise,
...processCreateParams(params)
});
};
class ZodEffects extends ZodType {
innerType() {
return this._def.schema;
}
sourceType() {
return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects ? this._def.schema.sourceType() : this._def.schema;
}
_parse(input) {
const { status, ctx } = this._processInputParams(input);
const effect = this._def.effect || null;
const checkCtx = {
addIssue: (arg) => {
(0, parseUtil_js_1.addIssueToContext)(ctx, arg);
if (arg.fatal) {
status.abort();
} else {
status.dirty();
}
},
get path() {
return ctx.path;
}
};
checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);
if (effect.type === "preprocess") {
const processed = effect.transform(ctx.data, checkCtx);
if (ctx.common.async) {
return Promise.resolve(processed).then(async (processed2) => {
if (status.value === "aborted")
return parseUtil_js_1.INVALID;
const result = await this._def.schema._parseAsync({
data: processed2,
path: ctx.path,
parent: ctx
});
if (result.status === "aborted")
return parseUtil_js_1.INVALID;
if (result.status === "dirty")
return (0, parseUtil_js_1.DIRTY)(result.value);
if (status.value === "dirty")
return (0, parseUtil_js_1.DIRTY)(result.value);
return result;
});
} else {
if (status.value === "aborted")
return parseUtil_js_1.INVALID;
const result = this._def.schema._parseSync({
data: processed,
path: ctx.path,
parent: ctx
});
if (result.status === "aborted")
return parseUtil_js_1.INVALID;
if (result.status === "dirty")
return (0, parseUtil_js_1.DIRTY)(result.value);
if (status.value === "dirty")
return (0, parseUtil_js_1.DIRTY)(result.value);
return result;
}
}
if (effect.type === "refinement") {
const executeRefinement = (acc) => {
const result = effect.refinement(acc, checkCtx);
if (ctx.common.async) {
return Promise.resolve(result);
}
if (result instanceof Promise) {
throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");
}
return acc;
};
if (ctx.common.async === false) {
const inner = this._def.schema._parseSync({
data: ctx.data,
path: ctx.path,
parent: ctx
});
if (inner.status === "aborted")
return parseUtil_js_1.INVALID;
if (inner.status === "dirty")
status.dirty();
executeRefinement(inner.value);
return { status: status.value, value: inner.value };
} else {
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((inner) => {
if (inner.status === "aborted")
return parseUtil_js_1.INVALID;
if (inner.status === "dirty")
status.dirty();
return executeRefinement(inner.value).then(() => {
return { status: status.value, value: inner.value };
});
});
}
}
if (effect.type === "transform") {
if (ctx.common.async === false) {
const base = this._def.schema._parseSync({
data: ctx.data,
path: ctx.path,
parent: ctx
});
if (!(0, parseUtil_js_1.isValid)(base))
return parseUtil_js_1.INVALID;
const result = effect.transform(base.value, checkCtx);
if (result instanceof Promise) {
throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
}
return { status: status.value, value: result };
} else {
return this._def.schema._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx }).then((base) => {
if (!(0, parseUtil_js_1.isValid)(base))
return parseUtil_js_1.INVALID;
return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({
status: status.value,
value: result
}));
});
}
}
util_js_1.util.assertNever(effect);
}
}
exports.ZodEffects = ZodEffects;
exports.ZodTransformer = ZodEffects;
ZodEffects.create = (schema, effect, params) => {
return new ZodEffects({
schema,
typeName: ZodFirstPartyTypeKind.ZodEffects,
effect,
...processCreateParams(params)
});
};
ZodEffects.createWithPreprocess = (preprocess, schema, params) => {
return new ZodEffects({
schema,
effect: { type: "preprocess", transform: preprocess },
typeName: ZodFirstPartyTypeKind.ZodEffects,
...processCreateParams(params)
});
};
class ZodOptional extends ZodType {
_parse(input) {
const parsedType = this._getType(input);
if (parsedType === util_js_1.ZodParsedType.undefined) {
return (0, parseUtil_js_1.OK)(undefined);
}
return this._def.innerType._parse(input);
}
unwrap() {
return this._def.innerType;
}
}
exports.ZodOptional = ZodOptional;
ZodOptional.create = (type, params) => {
return new ZodOptional({
innerType: type,
typeName: ZodFirstPartyTypeKind.ZodOptional,
...processCreateParams(params)
});
};
class ZodNullable extends ZodType {
_parse(input) {
const parsedType = this._getType(input);
if (parsedType === util_js_1.ZodParsedType.null) {
return (0, parseUtil_js_1.OK)(null);
}
return this._def.innerType._parse(input);
}
unwrap() {
return this._def.innerType;
}
}
exports.ZodNullable = ZodNullable;
ZodNullable.create = (type, params) => {
return new ZodNullable({
innerType: type,
typeName: ZodFirstPartyTypeKind.ZodNullable,
...processCreateParams(params)
});
};
class ZodDefault extends ZodType {
_parse(input) {
const { ctx } = this._processInputParams(input);
let data = ctx.data;
if (ctx.parsedType === util_js_1.ZodParsedType.undefined) {
data = this._def.defaultValue();
}
return this._def.innerType._parse({
data,
path: ctx.path,
parent: ctx
});
}
removeDefault() {
return this._def.innerType;
}
}
exports.ZodDefault = ZodDefault;
ZodDefault.create = (type, params) => {
return new ZodDefault({
innerType: type,
typeName: ZodFirstPartyTypeKind.ZodDefault,
defaultValue: typeof params.default === "function" ? params.default : () => params.default,
...processCreateParams(params)
});
};
class ZodCatch extends ZodType {
_parse(input) {
const { ctx } = this._processInputParams(input);
const newCtx = {
...ctx,
common: {
...ctx.common,
issues: []
}
};
const result = this._def.innerType._parse({
data: newCtx.data,
path: newCtx.path,
parent: {
...newCtx
}
});
if ((0, parseUtil_js_1.isAsync)(result)) {
return result.then((result2) => {
return {
status: "valid",
value: result2.status === "valid" ? result2.value : this._def.catchValue({
get error() {
return new ZodError_js_1.ZodError(newCtx.common.issues);
},
input: newCtx.data
})
};
});
} else {
return {
status: "valid",
value: result.status === "valid" ? result.value : this._def.catchValue({
get error() {
return new ZodError_js_1.ZodError(newCtx.common.issues);
},
input: newCtx.data
})
};
}
}
removeCatch() {
return this._def.innerType;
}
}
exports.ZodCatch = ZodCatch;
ZodCatch.create = (type, params) => {
return new ZodCatch({
innerType: type,
typeName: ZodFirstPartyTypeKind.ZodCatch,
catchValue: typeof params.catch === "function" ? params.catch : () => params.catch,
...processCreateParams(params)
});
};
class ZodNaN extends ZodType {
_parse(input) {
const parsedType = this._getType(input);
if (parsedType !== util_js_1.ZodParsedType.nan) {
const ctx = this._getOrReturnCtx(input);
(0, parseUtil_js_1.addIssueToContext)(ctx, {
code: ZodError_js_1.ZodIssueCode.invalid_type,
expected: util_js_1.ZodParsedType.nan,
received: ctx.parsedType
});
return parseUtil_js_1.INVALID;
}
return { status: "valid", value: input.data };
}
}
exports.ZodNaN = ZodNaN;
ZodNaN.create = (params) => {
return new ZodNaN({
typeName: ZodFirstPartyTypeKind.ZodNaN,
...processCreateParams(params)
});
};
exports.BRAND = Symbol("zod_brand");
class ZodBranded extends ZodType {
_parse(input) {
const { ctx } = this._processInputParams(input);
const data = ctx.data;
return this._def.type._parse({
data,
path: ctx.path,
parent: ctx
});
}
unwrap() {
return this._def.type;
}
}
exports.ZodBranded = ZodBranded;
class ZodPipeline extends ZodType {
_parse(input) {
const { status, ctx } = this._processInputParams(input);
if (ctx.common.async) {
const handleAsync = async () => {
const inResult = await this._def.in._parseAsync({
data: ctx.data,
path: ctx.path,
parent: ctx
});
if (inResult.status === "aborted")
return parseUtil_js_1.INVALID;
if (inResult.status === "dirty") {
status.dirty();
return (0, parseUtil_js_1.DIRTY)(inResult.value);
} else {
return this._def.out._parseAsync({
data: inResult.value,
path: ctx.path,
parent: ctx
});
}
};
return handleAsync();
} else {
const inResult = this._def.in._parseSync({
data: ctx.data,
path: ctx.path,
parent: ctx
});
if (inResult.status === "aborted")
return parseUtil_js_1.INVALID;
if (inResult.status === "dirty") {
status.dirty();
return {
status: "dirty",
value: inResult.value
};
} else {
return this._def.out._parseSync({
data: inResult.value,
path: ctx.path,
parent: ctx
});
}
}
}
static create(a, b) {
return new ZodPipeline({
in: a,
out: b,
typeName: ZodFirstPartyTypeKind.ZodPipeline
});
}
}
exports.ZodPipeline = ZodPipeline;
class ZodReadonly extends ZodType {
_parse(input) {
const result = this._def.innerType._parse(input);
const freeze = (data) => {
if ((0, parseUtil_js_1.isValid)(data)) {
data.value = Object.freeze(data.value);
}
return data;
};
return (0, parseUtil_js_1.isAsync)(result) ? result.then((data) => freeze(data)) : freeze(result);
}
unwrap() {
return this._def.innerType;
}
}
exports.ZodReadonly = ZodReadonly;
ZodReadonly.create = (type, params) => {
return new ZodReadonly({
innerType: type,
typeName: ZodFirstPartyTypeKind.ZodReadonly,
...processCreateParams(params)
});
};
function cleanParams(params, data) {
const p = typeof params === "function" ? params(data) : typeof params === "string" ? { message: params } : params;
const p2 = typeof p === "string" ? { message: p } : p;
return p2;
}
function custom(check, _params = {}, fatal) {
if (check)
return ZodAny.create().superRefine((data, ctx) => {
const r = check(data);
if (r instanceof Promise) {
return r.then((r2) => {
if (!r2) {
const params = cleanParams(_params, data);
const _fatal = params.fatal ?? fatal ?? true;
ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
}
});
}
if (!r) {
const params = cleanParams(_params, data);
const _fatal = params.fatal ?? fatal ?? true;
ctx.addIssue({ code: "custom", ...params, fatal: _fatal });
}
return;
});
return ZodAny.create();
}
exports.late = {
object: ZodObject.lazycreate
};
var ZodFirstPartyTypeKind;
(function(ZodFirstPartyTypeKind2) {
ZodFirstPartyTypeKind2["ZodString"] = "ZodString";
ZodFirstPartyTypeKind2["ZodNumber"] = "ZodNumber";
ZodFirstPartyTypeKind2["ZodNaN"] = "ZodNaN";
ZodFirstPartyTypeKind2["ZodBigInt"] = "ZodBigInt";
ZodFirstPartyTypeKind2["ZodBoolean"] = "ZodBoolean";
ZodFirstPartyTypeKind2["ZodDate"] = "ZodDate";
ZodFirstPartyTypeKind2["ZodSymbol"] = "ZodSymbol";
ZodFirstPartyTypeKind2["ZodUndefined"] = "ZodUndefined";
ZodFirstPartyTypeKind2["ZodNull"] = "ZodNull";
ZodFirstPartyTypeKind2["ZodAny"] = "ZodAny";
ZodFirstPartyTypeKind2["ZodUnknown"] = "ZodUnknown";
ZodFirstPartyTypeKind2["ZodNever"] = "ZodNever";
ZodFirstPartyTypeKind2["ZodVoid"] = "ZodVoid";
ZodFirstPartyTypeKind2["ZodArray"] = "ZodArray";
ZodFirstPartyTypeKind2["ZodObject"] = "ZodObject";
ZodFirstPartyTypeKind2["ZodUnion"] = "ZodUnion";
ZodFirstPartyTypeKind2["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion";
ZodFirstPartyTypeKind2["ZodIntersection"] = "ZodIntersection";
ZodFirstPartyTypeKind2["ZodTuple"] = "ZodTuple";
ZodFirstPartyTypeKind2["ZodRecord"] = "ZodRecord";
ZodFirstPartyTypeKind2["ZodMap"] = "ZodMap";
ZodFirstPartyTypeKind2["ZodSet"] = "ZodSet";
ZodFirstPartyTypeKind2["ZodFunction"] = "ZodFunction";
ZodFirstPartyTypeKind2["ZodLazy"] = "ZodLazy";
ZodFirstPartyTypeKind2["ZodLiteral"] = "ZodLiteral";
ZodFirstPartyTypeKind2["ZodEnum"] = "ZodEnum";
ZodFirstPartyTypeKind2["ZodEffects"] = "ZodEffects";
ZodFirstPartyTypeKind2["ZodNativeEnum"] = "ZodNativeEnum";
ZodFirstPartyTypeKind2["ZodOptional"] = "ZodOptional";
ZodFirstPartyTypeKind2["ZodNullable"] = "ZodNullable";
ZodFirstPartyTypeKind2["ZodDefault"] = "ZodDefault";
ZodFirstPartyTypeKind2["ZodCatch"] = "ZodCatch";
ZodFirstPartyTypeKind2["ZodPromise"] = "ZodPromise";
ZodFirstPartyTypeKind2["ZodBranded"] = "ZodBranded";
ZodFirstPartyTypeKind2["ZodPipeline"] = "ZodPipeline";
ZodFirstPartyTypeKind2["ZodReadonly"] = "ZodReadonly";
})(ZodFirstPartyTypeKind || (exports.ZodFirstPartyTypeKind = ZodFirstPartyTypeKind = {}));
var instanceOfType = (cls, params = {
message: `Input not instance of ${cls.name}`
}) => custom((data) => data instanceof cls, params);
exports.instanceof = instanceOfType;
var stringType = ZodString.create;
exports.string = stringType;
var numberType = ZodNumber.create;
exports.number = numberType;
var nanType = ZodNaN.create;
exports.nan = nanType;
var bigIntType = ZodBigInt.create;
exports.bigint = bigIntType;
var booleanType = ZodBoolean.create;
exports.boolean = booleanType;
var dateType = ZodDate.create;
exports.date = dateType;
var symbolType = ZodSymbol.create;
exports.symbol = symbolType;
var undefinedType = ZodUndefined.create;
exports.undefined = undefinedType;
var nullType = ZodNull.create;
exports.null = nullType;
var anyType = ZodAny.create;
exports.any = anyType;
var unknownType = ZodUnknown.create;
exports.unknown = unknownType;
var neverType = ZodNever.create;
exports.never = neverType;
var voidType = ZodVoid.create;
exports.void = voidType;
var arrayType = ZodArray.create;
exports.array = arrayType;
var objectType = ZodObject.create;
exports.object = objectType;
var strictObjectType = ZodObject.strictCreate;
exports.strictObject = strictObjectType;
var unionType = ZodUnion.create;
exports.union = unionType;
var discriminatedUnionType = ZodDiscriminatedUnion.create;
exports.discriminatedUnion = discriminatedUnionType;
var intersectionType = ZodIntersection.create;
exports.intersection = intersectionType;
var tupleType = ZodTuple.create;
exports.tuple = tupleType;
var recordType = ZodRecord.create;
exports.record = recordType;
var mapType = ZodMap.create;
exports.map = mapType;
var setType = ZodSet.create;
exports.set = setType;
var functionType = ZodFunction.create;
exports.function = functionType;
var lazyType = ZodLazy.create;
exports.lazy = lazyType;
var literalType = ZodLiteral.create;
exports.literal = literalType;
var enumType = ZodEnum.create;
exports.enum = enumType;
var nativeEnumType = ZodNativeEnum.create;
exports.nativeEnum = nativeEnumType;
var promiseType = ZodPromise.create;
exports.promise = promiseType;
var effectsType = ZodEffects.create;
exports.effect = effectsType;
exports.transformer = effectsType;
var optionalType = ZodOptional.create;
exports.optional = optionalType;
var nullableType = ZodNullable.create;
exports.nullable = nullableType;
var preprocessType = ZodEffects.createWithPreprocess;
exports.preprocess = preprocessType;
var pipelineType = ZodPipeline.create;
exports.pipeline = pipelineType;
var ostring = () => stringType().optional();
exports.ostring = ostring;
var onumber = () => numberType().optional();
exports.onumber = onumber;
var oboolean = () => booleanType().optional();
exports.oboolean = oboolean;
exports.coerce = {
string: (arg) => ZodString.create({ ...arg, coerce: true }),
number: (arg) => ZodNumber.create({ ...arg, coerce: true }),
boolean: (arg) => ZodBoolean.create({
...arg,
coerce: true
}),
bigint: (arg) => ZodBigInt.create({ ...arg, coerce: true }),
date: (arg) => ZodDate.create({ ...arg, coerce: true })
};
exports.NEVER = parseUtil_js_1.INVALID;
});
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.cjs
var require_external = __commonJS((exports) => {
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
if (k2 === undefined)
k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() {
return m[k];
} };
}
Object.defineProperty(o, k2, desc);
} : function(o, m, k, k2) {
if (k2 === undefined)
k2 = k;
o[k2] = m[k];
});
var __exportStar = exports && exports.__exportStar || function(m, exports2) {
for (var p in m)
if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
__createBinding(exports2, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require_errors(), exports);
__exportStar(require_parseUtil(), exports);
__exportStar(require_typeAliases(), exports);
__exportStar(require_util(), exports);
__exportStar(require_types(), exports);
__exportStar(require_ZodError(), exports);
});
// ../../node_modules/.bun/zod@3.25.76/node_modules/zod/index.cjs
var require_zod = __commonJS((exports) => {
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
if (k2 === undefined)
k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() {
return m[k];
} };
}
Object.defineProperty(o, k2, desc);
} : function(o, m, k, k2) {
if (k2 === undefined)
k2 = k;
o[k2] = m[k];
});
var __setModuleDefault = exports && exports.__setModuleDefault || (Object.create ? function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
} : function(o, v) {
o["default"] = v;
});
var __importStar = exports && exports.__importStar || function(mod) {
if (mod && mod.__esModule)
return mod;
var result = {};
if (mod != null) {
for (var k in mod)
if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k))
__createBinding(result, mod, k);
}
__setModuleDefault(result, mod);
return result;
};
var __exportStar = exports && exports.__exportStar || function(m, exports2) {
for (var p in m)
if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
__createBinding(exports2, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.z = undefined;
var z = __importStar(require_external());
exports.z = z;
__exportStar(require_external(), exports);
exports.default = z;
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/billing-next/config/schemas.js
var require_schemas = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.billingConfigSchema = exports.billingVersionConfigSchema = exports.meterSchema = exports.addOnSchema = exports.planSchema = exports.meteredPriceSchema = exports.priceSchema = exports.meterTypeSchema = exports.aggregationSchema = exports.unitAmountSchema = exports.intervalSchema = exports.featureSchema = exports.UNKNOWN_STRIPE_ID = undefined;
var zod_1 = require_zod();
var features_1 = require_features();
exports.UNKNOWN_STRIPE_ID = "__UNKNOWN_STRIPE_ID__";
exports.featureSchema = zod_1.z.enum(features_1.BILLING_FEATURE_IDS);
exports.intervalSchema = zod_1.z.enum(["month", "year"]);
exports.unitAmountSchema = zod_1.z.number().int().min(1);
exports.aggregationSchema = zod_1.z.enum(["sum", "count"]);
exports.meterTypeSchema = zod_1.z.enum(["payAsYouGo", "creditGrant"]);
exports.priceSchema = zod_1.z.object({
amount: zod_1.z.number(),
currency: zod_1.z.enum(["usd"]),
interval: exports.intervalSchema,
metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
providerPriceId: zod_1.z.string()
});
exports.meteredPriceSchema = zod_1.z.object({
unitAmount: exports.unitAmountSchema,
currency: zod_1.z.enum(["usd"]),
interval: exports.intervalSchema,
metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
providerPriceId: zod_1.z.string()
});
exports.planSchema = zod_1.z.object({
id: zod_1.z.string(),
name: zod_1.z.string(),
description: zod_1.z.string(),
tierIndex: zod_1.z.number(),
prices: zod_1.z.record(exports.intervalSchema, exports.priceSchema),
features: zod_1.z.record(exports.featureSchema, zod_1.z.union([zod_1.z.number(), zod_1.z.boolean()])),
metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
providerProductId: zod_1.z.string()
});
exports.addOnSchema = zod_1.z.object({
id: zod_1.z.string(),
name: zod_1.z.string(),
description: zod_1.z.string(),
prices: zod_1.z.record(zod_1.z.string(), exports.priceSchema),
increments: zod_1.z.record(exports.featureSchema, zod_1.z.number().positive()),
prorationDisabled: zod_1.z.boolean().optional(),
metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
autoRechargeable: zod_1.z.boolean().optional(),
hidden: zod_1.z.boolean().optional(),
providerProductId: zod_1.z.string()
});
exports.meterSchema = zod_1.z.object({
id: zod_1.z.string(),
name: zod_1.z.string(),
description: zod_1.z.string(),
defaultAggregation: zod_1.z.object({ formula: exports.aggregationSchema }).optional(),
customerMapping: zod_1.z.object({ eventPayloadKey: zod_1.z.literal("stripe_customer_id"), type: zod_1.z.literal("by_id") }).optional(),
valueSettings: zod_1.z.object({ eventPayloadKey: zod_1.z.literal("value") }).optional(),
prices: zod_1.z.record(exports.intervalSchema, exports.meteredPriceSchema),
meterType: exports.meterTypeSchema,
metadata: zod_1.z.record(zod_1.z.string(), zod_1.z.string()).optional(),
providerProductId: zod_1.z.string(),
providerMeterId: zod_1.z.string()
});
exports.billingVersionConfigSchema = zod_1.z.object({
version: zod_1.z.string(),
name: zod_1.z.string(),
description: zod_1.z.string(),
plans: zod_1.z.record(zod_1.z.string(), exports.planSchema),
addons: zod_1.z.record(zod_1.z.string(), exports.addOnSchema),
meters: zod_1.z.record(zod_1.z.string(), exports.meterSchema),
isActive: zod_1.z.boolean(),
createdAt: zod_1.z.string()
});
exports.billingConfigSchema = zod_1.z.record(zod_1.z.string(), exports.billingVersionConfigSchema);
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/billing-next/consts.js
var require_consts2 = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.AI_SPEND_PER_CONVERSATION = exports.MESSAGES_PER_CONVERSATION = exports.YEAR_MONTHS = exports.NANO_DOLLAR_PER_CENT = exports.BIG_UNLIMITED = exports.SMALL_UNLIMITED = exports.MB = exports.GB = exports.FREE_PRICE = undefined;
exports.FREE_PRICE = -1;
exports.GB = 1e9;
exports.MB = 1e6;
exports.SMALL_UNLIMITED = 5000;
exports.BIG_UNLIMITED = 5000000;
exports.NANO_DOLLAR_PER_CENT = 1e7;
exports.YEAR_MONTHS = 12;
exports.MESSAGES_PER_CONVERSATION = 30000;
exports.AI_SPEND_PER_CONVERSATION = 10 * exports.NANO_DOLLAR_PER_CENT;
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/billing-next/config/plans.js
var require_plans = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.plans = undefined;
var consts_1 = require_consts2();
var schemas_1 = require_schemas();
var ENTERPRISE_PLAN_FEATURES = {
table_rows: 1e7,
bot_count: consts_1.SMALL_UNLIMITED,
collaborator_count: 100,
file_storage: 1000 * consts_1.GB,
vector_db_storage: 500 * consts_1.GB,
saved_versions: 1000,
indexed_file_count: 1e4,
incoming_messages_events: 1e4 * consts_1.MESSAGES_PER_CONVERSATION,
ai_spend: 1e4 * consts_1.AI_SPEND_PER_CONVERSATION,
conversation_sessions: 1e4
};
exports.plans = {
community: {
id: "community",
name: "Plan - Free",
description: "Free plan for trying things out",
tierIndex: 0,
prices: {
month: {
amount: consts_1.FREE_PRICE,
currency: "usd",
interval: "month",
providerPriceId: schemas_1.UNKNOWN_STRIPE_ID
}
},
features: {
table_rows: 1000,
bot_count: 3,
collaborator_count: 1,
file_storage: 100 * consts_1.MB,
vector_db_storage: 100 * consts_1.MB,
saved_versions: 3,
indexed_file_count: 1000,
incoming_messages_events: 100 * consts_1.MESSAGES_PER_CONVERSATION,
ai_spend: 100 * consts_1.AI_SPEND_PER_CONVERSATION,
conversation_sessions: 100
},
providerProductId: schemas_1.UNKNOWN_STRIPE_ID
},
plus: {
id: "plus",
name: "Plan - Plus",
description: "For growing businesses",
tierIndex: 1,
prices: {
month: {
amount: 189,
currency: "usd",
interval: "month",
providerPriceId: schemas_1.UNKNOWN_STRIPE_ID
},
year: {
amount: 150 * consts_1.YEAR_MONTHS,
currency: "usd",
interval: "year",
providerPriceId: schemas_1.UNKNOWN_STRIPE_ID
}
},
features: {
table_rows: 1e5,
bot_count: consts_1.SMALL_UNLIMITED,
collaborator_count: 3,
file_storage: 10 * consts_1.GB,
vector_db_storage: 1 * consts_1.GB,
saved_versions: 50,
indexed_file_count: 2000,
incoming_messages_events: 250 * consts_1.MESSAGES_PER_CONVERSATION,
ai_spend: 250 * consts_1.AI_SPEND_PER_CONVERSATION,
conversation_sessions: 250
},
providerProductId: schemas_1.UNKNOWN_STRIPE_ID
},
team: {
id: "team",
name: "Plan - Team",
description: "For small teams",
tierIndex: 2,
prices: {
month: {
amount: 939,
currency: "usd",
interval: "month",
providerPriceId: schemas_1.UNKNOWN_STRIPE_ID
},
year: {
amount: 750 * consts_1.YEAR_MONTHS,
currency: "usd",
interval: "year",
providerPriceId: schemas_1.UNKNOWN_STRIPE_ID
}
},
features: {
table_rows: 500000,
bot_count: consts_1.SMALL_UNLIMITED,
collaborator_count: consts_1.SMALL_UNLIMITED,
file_storage: 50 * consts_1.GB,
vector_db_storage: 5 * consts_1.GB,
saved_versions: 100,
indexed_file_count: consts_1.BIG_UNLIMITED,
incoming_messages_events: 1500 * consts_1.MESSAGES_PER_CONVERSATION,
ai_spend: 1500 * consts_1.AI_SPEND_PER_CONVERSATION,
conversation_sessions: 1500
},
providerProductId: schemas_1.UNKNOWN_STRIPE_ID
},
enterprise: {
id: "enterprise",
name: "Plan - Enterprise",
description: "Enterprise license subscription",
tierIndex: 3,
prices: {
month: {
amount: consts_1.FREE_PRICE,
currency: "usd",
interval: "month",
providerPriceId: schemas_1.UNKNOWN_STRIPE_ID
}
},
features: ENTERPRISE_PLAN_FEATURES,
providerProductId: schemas_1.UNKNOWN_STRIPE_ID
},
managed: {
id: "managed",
name: "Plan - Managed",
description: "Managed license subscription",
tierIndex: 4,
prices: {
month: {
amount: consts_1.FREE_PRICE,
currency: "usd",
interval: "month",
providerPriceId: schemas_1.UNKNOWN_STRIPE_ID
}
},
features: ENTERPRISE_PLAN_FEATURES,
providerProductId: schemas_1.UNKNOWN_STRIPE_ID
}
};
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/billing-next/config/addons.js
var require_addons = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.addons = undefined;
var consts_1 = require_consts2();
var schemas_1 = require_schemas();
var constantMonthlyPrice = (amount, scope = ["community", "plus", "team", "enterprise", "managed"]) => {
return scope.map((plan) => ({
[plan]: {
amount,
currency: "usd",
interval: "month",
providerPriceId: schemas_1.UNKNOWN_STRIPE_ID
}
})).reduce((acc, curr) => ({ ...acc, ...curr }), {});
};
exports.addons = {
conversation_sessions_addon: {
id: "conversation_sessions_addon",
name: "Add-on - Conversation Sessions",
description: "Adds conversations sessions for the month",
prices: {
plus: {
amount: 65,
currency: "usd",
interval: "month",
providerPriceId: schemas_1.UNKNOWN_STRIPE_ID
},
team: {
amount: 50,
currency: "usd",
interval: "month",
providerPriceId: schemas_1.UNKNOWN_STRIPE_ID
},
enterprise: {
amount: consts_1.FREE_PRICE,
currency: "usd",
interval: "month",
providerPriceId: schemas_1.UNKNOWN_STRIPE_ID
}
},
increments: {
conversation_sessions: 100,
ai_spend: 100 * consts_1.AI_SPEND_PER_CONVERSATION,
incoming_messages_events: 100 * consts_1.MESSAGES_PER_CONVERSATION
},
providerProductId: schemas_1.UNKNOWN_STRIPE_ID,
autoRechargeable: true
},
storage_addon: {
id: "storage_addon",
name: "Add-on - Storage",
description: "Adds table rows, vector db space and files",
prices: {
...constantMonthlyPrice(40, ["plus", "team"]),
...constantMonthlyPrice(consts_1.FREE_PRICE, ["enterprise", "managed"])
},
increments: {
table_rows: 1e5,
vector_db_storage: 1 * consts_1.GB,
file_storage: 10 * consts_1.GB
},
providerProductId: schemas_1.UNKNOWN_STRIPE_ID
}
};
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/billing-next/config/meters.js
var require_meters = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.meters = undefined;
var schemas_1 = require_schemas();
exports.meters = {
ai_spend_credit_grant: {
id: "ai_spend_credit_grant",
name: "AI Spend - Credit grant",
description: "Pre-purchased credits applied toward AI usage",
defaultAggregation: { formula: "sum" },
customerMapping: { eventPayloadKey: "stripe_customer_id", type: "by_id" },
valueSettings: { eventPayloadKey: "value" },
prices: {
month: {
unitAmount: 1,
currency: "usd",
interval: "month",
providerPriceId: schemas_1.UNKNOWN_STRIPE_ID
}
},
meterType: "creditGrant",
providerMeterId: schemas_1.UNKNOWN_STRIPE_ID,
providerProductId: schemas_1.UNKNOWN_STRIPE_ID
},
ai_spend_pay_as_you_go: {
id: "ai_spend_pay_as_you_go",
name: "AI Spend - Pay as you go",
description: "Usage-based charges for AI spend, billed monthly",
defaultAggregation: { formula: "sum" },
customerMapping: { eventPayloadKey: "stripe_customer_id", type: "by_id" },
valueSettings: { eventPayloadKey: "value" },
prices: {
month: {
unitAmount: 1,
currency: "usd",
interval: "month",
providerPriceId: schemas_1.UNKNOWN_STRIPE_ID
}
},
meterType: "payAsYouGo",
providerMeterId: schemas_1.UNKNOWN_STRIPE_ID,
providerProductId: schemas_1.UNKNOWN_STRIPE_ID
}
};
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/billing-next/config/versions.js
var require_versions = __commonJS((exports) => {
Object.defineProperty(exports, "__esModule", { value: true });
exports.billingDefinitions = exports.billingConfig = undefined;
var plans_1 = require_plans();
var addons_1 = require_addons();
var meters_1 = require_meters();
exports.billingConfig = {
v4: {
version: "v4",
name: "Billing Version 4",
description: "New billing system with credit grants and entitlements",
plans: plans_1.plans,
addons: addons_1.addons,
meters: meters_1.meters,
isActive: true,
createdAt: new Date().toISOString()
}
};
exports.billingDefinitions = exports.billingConfig;
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/billing-next/config/index.js
var require_config = __commonJS((exports) => {
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
if (k2 === undefined)
k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() {
return m[k];
} };
}
Object.defineProperty(o, k2, desc);
} : function(o, m, k, k2) {
if (k2 === undefined)
k2 = k;
o[k2] = m[k];
});
var __exportStar = exports && exports.__exportStar || function(m, exports2) {
for (var p in m)
if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
__createBinding(exports2, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require_schemas(), exports);
__exportStar(require_versions(), exports);
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/billing-next/index.js
var require_billing_next = __commonJS((exports) => {
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
if (k2 === undefined)
k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() {
return m[k];
} };
}
Object.defineProperty(o, k2, desc);
} : function(o, m, k, k2) {
if (k2 === undefined)
k2 = k;
o[k2] = m[k];
});
var __exportStar = exports && exports.__exportStar || function(m, exports2) {
for (var p in m)
if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
__createBinding(exports2, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require_features(), exports);
__exportStar(require_config(), exports);
__exportStar(require_consts2(), exports);
});
// ../../node_modules/.bun/@bpinternal+const@0.24.0/node_modules/@bpinternal/const/dist/index.js
var require_dist = __commonJS((exports) => {
var __createBinding = exports && exports.__createBinding || (Object.create ? function(o, m, k, k2) {
if (k2 === undefined)
k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() {
return m[k];
} };
}
Object.defineProperty(o, k2, desc);
} : function(o, m, k, k2) {
if (k2 === undefined)
k2 = k;
o[k2] = m[k];
});
var __exportStar = exports && exports.__exportStar || function(m, exports2) {
for (var p in m)
if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports2, p))
__createBinding(exports2, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
__exportStar(require_bot_use_cases(), exports);
__exportStar(require_limits(), exports);
__exportStar(require_prefixes(), exports);
__exportStar(require_billing_legacy(), exports);
__exportStar(require_tags(), exports);
__exportStar(require_workflow_names(), exports);
__exportStar(require_cancellation_reasons(), exports);
__exportStar(require_billing_next(), exports);
});
// ../evals/dist/index.js
var EVAL_MANIFEST_SCHEMA_VERSION = 1;
var EVAL_MANIFEST_TAGS = {
source: "adk",
type: "eval-manifest",
schemaVersion: `${EVAL_MANIFEST_SCHEMA_VERSION}`
};
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/adapters/adapter.js
class Adapter {
}
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/adapters/botpress-table.js
var CRITICAL_TAGS = {
system: "true",
"schema-purpose": "active-learning",
"schema-version": "Oct-2024"
};
var OPTIONAL_TAGS = {
"x-studio-title": "Active Learning",
"x-studio-description": "Table for storing active learning tasks and examples",
"x-studio-readonly": "true",
"x-studio-icon": "lucide://atom",
"x-studio-color": "green"
};
var FACTOR = 30;
var Props = exports_exports.object({
client: exports_exports.custom(() => true),
tableName: exports_exports.string().regex(/^[a-zA-Z0-9_]{1,45}Table$/i, 'Table name must be lowercase and contain only letters, numbers and underscores. It must also end with "Table". Example: "ActiveLearningTable"')
});
var TableSchema = exports_exports.object({
taskType: exports_exports.string().describe("The type of the task (filter, extract, etc.)"),
taskId: exports_exports.string(),
key: exports_exports.string().describe("A unique key for the task (e.g. a hash of the input, taskId, taskType and instructions)"),
instructions: exports_exports.string(),
input: exports_exports.object({}).passthrough().describe("The input to the task"),
output: exports_exports.object({}).passthrough().describe("The expected output"),
explanation: exports_exports.string().nullable(),
metadata: exports_exports.object({}).passthrough(),
status: exports_exports.enum(["pending", "rejected", "approved"]),
feedback: exports_exports.object({
rating: exports_exports.enum(["very-bad", "bad", "good", "very-good"]),
comment: exports_exports.string().nullable()
}).nullable().default(null)
});
var searchableColumns = ["input"];
var TableJsonSchema = Object.entries(TableSchema.shape).reduce((acc, [key, value]) => {
acc[key] = transforms_exports.toJSONSchemaLegacy(value);
acc[key]["x-zui"] ??= {};
acc[key]["x-zui"].searchable = searchableColumns.includes(key);
return acc;
}, {});
class TableAdapter extends Adapter {
_client;
_tableName;
_status;
constructor(props) {
super();
props = Props.parse(props);
this._client = props.client;
this._tableName = props.tableName;
this._status = "ready";
}
async getExamples({ taskType, taskId, input }) {
await this._assertTableExists();
const { rows } = await this._client.findTableRows({
table: this._tableName,
search: JSON.stringify({ value: input }).substring(0, 1023),
limit: 10,
filter: {
taskType,
taskId,
status: "approved"
}
}).catch((err) => {
console.error(`Error fetching examples: ${err.message}`);
return { rows: [] };
});
return rows.map((row) => ({
key: row.key,
input: row.input.value,
output: row.output.value,
explanation: row.explanation,
similarity: row.similarity ?? 0
}));
}
async saveExample({
key,
taskType,
taskId,
instructions,
input,
output,
explanation,
metadata,
status = "pending"
}) {
await this._assertTableExists();
await this._client.upsertTableRows({
table: this._tableName,
keyColumn: "key",
rows: [
{
key,
taskType,
taskId,
instructions,
input: { value: input },
output: { value: output },
explanation: explanation ?? null,
status,
metadata,
feedback: null
}
]
}).catch(() => {});
}
async _assertTableExists() {
if (this._status !== "ready") {
return;
}
const { table, created } = await this._client.getOrCreateTable({
table: this._tableName,
factor: FACTOR,
frozen: true,
isComputeEnabled: false,
tags: {
...CRITICAL_TAGS,
...OPTIONAL_TAGS
},
schema: TableJsonSchema
}).catch(() => {
this._status = "error";
return { table: null, created: false };
});
if (!table) {
return;
}
if (!created) {
const issues = [];
if (table.factor !== FACTOR) {
issues.push(`Factor is ${table.factor} instead of ${FACTOR}`);
}
if (table.frozen !== true) {
issues.push("Table is not frozen");
}
for (const [key, value] of Object.entries(CRITICAL_TAGS)) {
if (table.tags?.[key] !== value) {
issues.push(`Tag ${key} is ${table.tags?.[key]} instead of ${value}`);
}
}
for (const key of Object.keys(TableJsonSchema)) {
const column = table.schema?.properties[key];
const expected = TableJsonSchema[key];
if (!column) {
issues.push(`Column ${key} is missing`);
continue;
}
if (column.type !== expected.type) {
issues.push(`Column ${key} has type ${column.type} instead of ${expected.type}`);
}
if (expected["x-zui"].searchable && !column["x-zui"].searchable) {
issues.push(`Column ${key} is not searchable but should be`);
}
}
if (issues.length) {
this._status = "error";
}
}
this._status = "initialized";
}
}
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/adapters/memory.js
class MemoryAdapter extends Adapter {
constructor(examples) {
super();
this.examples = examples;
}
async getExamples() {
return this.examples;
}
async saveExample() {}
}
// ../../node_modules/.bun/@bpinternal+thicktoken@3.0.0/node_modules/@bpinternal/thicktoken/dist/micro.mjs
var wasmBase64 = "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";
var bytes;
if (typeof Buffer !== "undefined") {
bytes = Buffer.from(wasmBase64, "base64");
} else {
const bin = atob(wasmBase64);
bytes = new Uint8Array(bin.length);
for (let i = 0;i < bin.length; i++)
bytes[i] = bin.charCodeAt(i);
}
var cl25k_merges_json_default = bytes;
var getWasmTokenizer = makeGetTokenizer(cl25k_merges_json_default);
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/tokenizer.js
var tokenizer = null;
async function getTokenizer() {
if (!tokenizer) {
try {
tokenizer = await getWasmTokenizer();
} catch (err) {
throw new Error("Failed to initialize ThickToken tokenizer", { cause: err });
}
}
return tokenizer;
}
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/zai.js
var _ActiveLearning = exports_exports.object({
enable: exports_exports.boolean().describe("Whether to enable active learning").default(false),
tableName: exports_exports.string().regex(/^[A-Za-z0-9_/-]{1,100}Table$/, "Namespace must be alphanumeric and contain only letters, numbers, underscores, hyphens and slashes").describe("The name of the table to store active learning tasks").default("ActiveLearningTable"),
taskId: exports_exports.string().regex(/^[A-Za-z0-9_/-]{1,100}$/, "Namespace must be alphanumeric and contain only letters, numbers, underscores, hyphens and slashes").describe("The ID of the task").default("default")
});
var _ZaiConfig = exports_exports.object({
client: exports_exports.custom(),
userId: exports_exports.string().describe("The ID of the user consuming the API").optional(),
modelId: exports_exports.custom((value) => {
const isValidSingle = (v) => typeof v === "string" && (v === "best" || v === "fast" || v === "auto" || v.includes(":"));
if (Array.isArray(value)) {
return value.length > 0 && value.every(isValidSingle);
}
return isValidSingle(value);
}, {
message: "At least one model ID is invalid. Expected a model string or an array of model strings."
}).describe("The ID of the model you want to use, or an ordered list of fallback models").default("best"),
activeLearning: _ActiveLearning.default({ enable: false }),
namespace: exports_exports.string().regex(/^[A-Za-z0-9_/-]{1,100}$/, "Namespace must be alphanumeric and contain only letters, numbers, underscores, hyphens and slashes").default("zai")
});
class Zai {
static tokenizer = null;
client;
_originalConfig;
_userId;
Model;
ModelDetails;
namespace;
adapter;
activeLearning;
_memoize;
constructor(config) {
this._originalConfig = config;
const parsed = _ZaiConfig.parse(config);
this.client = Cognitive.isCognitiveClient(parsed.client) ? parsed.client : new Cognitive({ client: parsed.client });
this.namespace = parsed.namespace;
this._userId = parsed.userId;
this.Model = parsed.modelId;
this.activeLearning = parsed.activeLearning;
this.adapter = parsed.activeLearning?.enable ? new TableAdapter({
client: this.client.client,
tableName: parsed.activeLearning.tableName
}) : new MemoryAdapter([]);
this._memoize = config.memoize;
}
async callModel(props) {
return this.client.generateContent({
reasoningEffort: "none",
...props,
model: this.Model,
userId: this._userId
});
}
_resolveMemoizer() {
if (!this._memoize) {
return;
}
return typeof this._memoize === "function" ? this._memoize() : this._memoize;
}
async getTokenizer() {
Zai.tokenizer ??= await getTokenizer();
return Zai.tokenizer;
}
async fetchModelDetails() {
if (!this.ModelDetails) {
const primaryModel = Array.isArray(this.Model) ? this.Model[0] : this.Model;
this.ModelDetails = await this.client.getModelDetails(primaryModel);
}
}
get taskId() {
if (!this.activeLearning.enable) {
return;
}
return `${this.namespace}/${this.activeLearning.taskId}`.replace(/\/+/g, "/");
}
with(options) {
return new Zai({
...this._originalConfig,
...options
});
}
learn(taskId) {
return new Zai({
...this._originalConfig,
activeLearning: { ...this.activeLearning, taskId, enable: true }
});
}
}
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseSlice.js
function baseSlice(array, start, end) {
var index = -1, length = array.length;
if (start < 0) {
start = -start > length ? 0 : length + start;
}
end = end > length ? length : end;
if (end < 0) {
end += length;
}
length = start > end ? 0 : end - start >>> 0;
start >>>= 0;
var result = Array(length);
while (++index < length) {
result[index] = array[index + start];
}
return result;
}
var _baseSlice_default = baseSlice;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/eq.js
function eq(value, other) {
return value === other || value !== value && other !== other;
}
var eq_default = eq;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_freeGlobal.js
var freeGlobal = typeof global == "object" && global && global.Object === Object && global;
var _freeGlobal_default = freeGlobal;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_root.js
var freeSelf = typeof self == "object" && self && self.Object === Object && self;
var root = _freeGlobal_default || freeSelf || Function("return this")();
var _root_default = root;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_Symbol.js
var Symbol2 = _root_default.Symbol;
var _Symbol_default = Symbol2;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_getRawTag.js
var objectProto = Object.prototype;
var hasOwnProperty = objectProto.hasOwnProperty;
var nativeObjectToString = objectProto.toString;
var symToStringTag = _Symbol_default ? _Symbol_default.toStringTag : undefined;
function getRawTag(value) {
var isOwn = hasOwnProperty.call(value, symToStringTag), tag = value[symToStringTag];
try {
value[symToStringTag] = undefined;
var unmasked = true;
} catch (e) {}
var result = nativeObjectToString.call(value);
if (unmasked) {
if (isOwn) {
value[symToStringTag] = tag;
} else {
delete value[symToStringTag];
}
}
return result;
}
var _getRawTag_default = getRawTag;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_objectToString.js
var objectProto2 = Object.prototype;
var nativeObjectToString2 = objectProto2.toString;
function objectToString(value) {
return nativeObjectToString2.call(value);
}
var _objectToString_default = objectToString;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseGetTag.js
var nullTag = "[object Null]";
var undefinedTag = "[object Undefined]";
var symToStringTag2 = _Symbol_default ? _Symbol_default.toStringTag : undefined;
function baseGetTag(value) {
if (value == null) {
return value === undefined ? undefinedTag : nullTag;
}
return symToStringTag2 && symToStringTag2 in Object(value) ? _getRawTag_default(value) : _objectToString_default(value);
}
var _baseGetTag_default = baseGetTag;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isObject.js
function isObject(value) {
var type = typeof value;
return value != null && (type == "object" || type == "function");
}
var isObject_default = isObject;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isFunction.js
var asyncTag = "[object AsyncFunction]";
var funcTag = "[object Function]";
var genTag = "[object GeneratorFunction]";
var proxyTag = "[object Proxy]";
function isFunction(value) {
if (!isObject_default(value)) {
return false;
}
var tag = _baseGetTag_default(value);
return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
}
var isFunction_default = isFunction;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isLength.js
var MAX_SAFE_INTEGER = 9007199254740991;
function isLength(value) {
return typeof value == "number" && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;
}
var isLength_default = isLength;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isArrayLike.js
function isArrayLike(value) {
return value != null && isLength_default(value.length) && !isFunction_default(value);
}
var isArrayLike_default = isArrayLike;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_isIndex.js
var MAX_SAFE_INTEGER2 = 9007199254740991;
var reIsUint = /^(?:0|[1-9]\d*)$/;
function isIndex(value, length) {
var type = typeof value;
length = length == null ? MAX_SAFE_INTEGER2 : length;
return !!length && (type == "number" || type != "symbol" && reIsUint.test(value)) && (value > -1 && value % 1 == 0 && value < length);
}
var _isIndex_default = isIndex;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_isIterateeCall.js
function isIterateeCall(value, index, object) {
if (!isObject_default(object)) {
return false;
}
var type = typeof index;
if (type == "number" ? isArrayLike_default(object) && _isIndex_default(index, object.length) : type == "string" && (index in object)) {
return eq_default(object[index], value);
}
return false;
}
var _isIterateeCall_default = isIterateeCall;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_trimmedEndIndex.js
var reWhitespace = /\s/;
function trimmedEndIndex(string) {
var index = string.length;
while (index-- && reWhitespace.test(string.charAt(index))) {}
return index;
}
var _trimmedEndIndex_default = trimmedEndIndex;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseTrim.js
var reTrimStart = /^\s+/;
function baseTrim(string) {
return string ? string.slice(0, _trimmedEndIndex_default(string) + 1).replace(reTrimStart, "") : string;
}
var _baseTrim_default = baseTrim;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isObjectLike.js
function isObjectLike(value) {
return value != null && typeof value == "object";
}
var isObjectLike_default = isObjectLike;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isSymbol.js
var symbolTag = "[object Symbol]";
function isSymbol(value) {
return typeof value == "symbol" || isObjectLike_default(value) && _baseGetTag_default(value) == symbolTag;
}
var isSymbol_default = isSymbol;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/toNumber.js
var NAN = 0 / 0;
var reIsBadHex = /^[-+]0x[0-9a-f]+$/i;
var reIsBinary = /^0b[01]+$/i;
var reIsOctal = /^0o[0-7]+$/i;
var freeParseInt = parseInt;
function toNumber(value) {
if (typeof value == "number") {
return value;
}
if (isSymbol_default(value)) {
return NAN;
}
if (isObject_default(value)) {
var other = typeof value.valueOf == "function" ? value.valueOf() : value;
value = isObject_default(other) ? other + "" : other;
}
if (typeof value != "string") {
return value === 0 ? value : +value;
}
value = _baseTrim_default(value);
var isBinary = reIsBinary.test(value);
return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value;
}
var toNumber_default = toNumber;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/toFinite.js
var INFINITY = 1 / 0;
var MAX_INTEGER = 179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000;
function toFinite(value) {
if (!value) {
return value === 0 ? value : 0;
}
value = toNumber_default(value);
if (value === INFINITY || value === -INFINITY) {
var sign = value < 0 ? -1 : 1;
return sign * MAX_INTEGER;
}
return value === value ? value : 0;
}
var toFinite_default = toFinite;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/toInteger.js
function toInteger(value) {
var result = toFinite_default(value), remainder = result % 1;
return result === result ? remainder ? result - remainder : result : 0;
}
var toInteger_default = toInteger;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/chunk.js
var nativeCeil = Math.ceil;
var nativeMax = Math.max;
function chunk(array, size, guard) {
if (guard ? _isIterateeCall_default(array, size, guard) : size === undefined) {
size = 1;
} else {
size = nativeMax(toInteger_default(size), 0);
}
var length = array == null ? 0 : array.length;
if (!length || size < 1) {
return [];
}
var index = 0, resIndex = 0, result = Array(nativeCeil(length / size));
while (index < length) {
result[resIndex++] = _baseSlice_default(array, index, index += size);
}
return result;
}
var chunk_default = chunk;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/_baseClamp.js
function baseClamp(number, lower, upper) {
if (number === number) {
if (upper !== undefined) {
number = number <= upper ? number : upper;
}
if (lower !== undefined) {
number = number >= lower ? number : lower;
}
}
return number;
}
var _baseClamp_default = baseClamp;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/clamp.js
function clamp(number, lower, upper) {
if (upper === undefined) {
upper = lower;
lower = undefined;
}
if (upper !== undefined) {
upper = toNumber_default(upper);
upper = upper === upper ? upper : 0;
}
if (lower !== undefined) {
lower = toNumber_default(lower);
lower = lower === lower ? lower : 0;
}
return _baseClamp_default(toNumber_default(number), lower, upper);
}
var clamp_default = clamp;
// ../../node_modules/.bun/lodash-es@4.18.1/node_modules/lodash-es/isArray.js
var isArray = Array.isArray;
var isArray_default = isArray;
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/emitter.js
class EventEmitter {
_listeners = {};
emit(type, event) {
const listeners = this._listeners[type];
if (!listeners) {
return;
}
for (const listener of listeners) {
listener(event);
}
}
once(type, listener) {
const wrapped = (event) => {
this.off(type, wrapped);
listener(event);
};
this.on(type, wrapped);
}
on(type, listener) {
if (!this._listeners[type]) {
this._listeners[type] = [];
}
this._listeners[type].push(listener);
}
off(type, listener) {
const listeners = this._listeners[type];
if (!listeners) {
return;
}
const index = listeners.indexOf(listener);
if (index !== -1) {
listeners.splice(index, 1);
}
}
clear(type) {
if (type) {
delete this._listeners[type];
} else {
this._listeners = {};
}
}
}
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/utils.js
var stringify = (input, beautify = true) => {
return typeof input === "string" && !!input.length ? input : input ? JSON.stringify(input, beautify ? null : undefined, beautify ? 2 : undefined) : "<input is null, false, undefined or empty>";
};
function fastHash(str) {
let hash = 0;
for (let i = 0;i < str.length; i++) {
hash = (hash << 5) - hash + str.charCodeAt(i);
hash |= 0;
}
return (hash >>> 0).toString(16);
}
var takeUntilTokens = (arr, tokens, count) => {
const result = [];
let total = 0;
for (const value of arr) {
const valueTokens = count(value);
if (total + valueTokens > tokens) {
break;
}
total += valueTokens;
result.push(value);
}
return result;
};
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/context.js
class ZaiContext {
_startedAt = Date.now();
_inputCost = 0;
_outputCost = 0;
_inputTokens = 0;
_outputTokens = 0;
_totalCachedResponses = 0;
_totalRequests = 0;
_totalErrors = 0;
_totalResponses = 0;
taskId;
taskType;
modelId;
adapter;
source;
_eventEmitter;
_memoizer;
controller = new AbortController;
_client;
static _noopMemoizer = { run: (_id, fn) => fn() };
constructor(props) {
this._client = props.client.clone();
this.taskId = props.taskId;
this.modelId = props.modelId;
this.adapter = props.adapter;
this.source = props.source;
this.taskType = props.taskType;
this._memoizer = props.memoizer ?? ZaiContext._noopMemoizer;
this._eventEmitter = new EventEmitter;
this._client.on("request", () => {
this._totalRequests++;
this._eventEmitter.emit("update", this.usage);
});
this._client.on("response", (_req, res) => {
this._totalResponses++;
if (res.meta.cached) {
this._totalCachedResponses++;
} else {
this._inputTokens += res.meta.tokens.input || 0;
this._outputTokens += res.meta.tokens.output || 0;
this._inputCost += res.meta.cost.input || 0;
this._outputCost += res.meta.cost.output || 0;
}
this._eventEmitter.emit("update", this.usage);
});
this._client.on("error", () => {
this._totalErrors++;
this._eventEmitter.emit("update", this.usage);
});
}
async getModel() {
const primary = Array.isArray(this.modelId) ? this.modelId[0] : this.modelId;
return this._client.getModelDetails(primary);
}
on(type, listener) {
this._eventEmitter.on(type, listener);
return this;
}
clear() {
this._eventEmitter.clear();
}
async generateContent(props) {
const memoKey = `zai:memo:${this.taskType}:${this.taskId || "default"}:${fastHash(JSON.stringify({
s: props.systemPrompt,
m: props.messages?.map((m) => ("content" in m) ? m.content : ""),
st: props.stopSequences,
mt: props.maxTokens
}))}`;
return this._memoizer.run(memoKey, () => this._generateContentInner(props));
}
async _generateContentInner(props) {
const maxRetries = Math.max(props.maxRetries ?? 3, 0);
const transform = props.transform;
let lastError = null;
const messages = [...props.messages || []];
for (let attempt = 0;attempt <= maxRetries && !this.controller.signal.aborted; attempt++) {
try {
const response = await this._client.generateContent({
...props,
messages,
signal: this.controller.signal,
model: this.modelId,
meta: {
integrationName: props.meta?.integrationName || "zai",
promptCategory: props.meta?.promptCategory || `zai:${this.taskType}`,
promptSource: props.meta?.promptSource || `zai:${this.taskType}:${this.taskId ?? "default"}`
}
});
if (this.controller.signal.aborted) {
throw this.controller.signal.reason;
}
const content = response.output.choices[0]?.content;
const str = typeof content === "string" ? content : content?.[0]?.text || "";
let output;
messages.push({
role: "assistant",
content: str || "<Invalid output, no content provided>"
});
if (!transform) {
output = str;
} else {
output = transform(str, response.output);
}
return { meta: response.meta, output: response.output, text: str, extracted: output };
} catch (error) {
if (this.controller.signal.aborted) {
throw this.controller.signal.reason;
}
lastError = error;
if (attempt === maxRetries) {
throw lastError;
}
messages.push({
role: "user",
content: `ERROR PARSING OUTPUT
${lastError.message}.
Please return a valid response addressing the error above.`
});
}
}
throw lastError;
}
get elapsedTime() {
return Date.now() - this._startedAt;
}
get usage() {
return {
requests: {
errors: this._totalErrors,
requests: this._totalRequests,
responses: this._totalResponses,
cached: this._totalCachedResponses,
percentage: this._totalRequests > 0 ? (this._totalResponses + this._totalErrors) / this._totalRequests : 0
},
tokens: {
input: this._inputTokens,
output: this._outputTokens,
total: this._inputTokens + this._outputTokens
},
cost: {
input: this._inputCost,
output: this._outputCost,
total: this._inputCost + this._outputCost
}
};
}
}
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/response.js
class Response {
_promise;
_eventEmitter;
_context;
_elasped = null;
_simplify;
static reject(context, err) {
return new Response(context, Promise.reject(err), (value) => value);
}
constructor(context, promise, simplify) {
this._context = context;
this._eventEmitter = new EventEmitter;
this._simplify = simplify;
this._promise = promise.then((value) => {
this._elasped ||= this._context.elapsedTime;
this._eventEmitter.emit("complete", value);
this._eventEmitter.clear();
this._context.clear();
return value;
}, (reason) => {
this._elasped ||= this._context.elapsedTime;
this._eventEmitter.emit("error", reason);
this._eventEmitter.clear();
this._context.clear();
throw reason;
});
this._context.on("update", (usage) => {
this._eventEmitter.emit("progress", usage);
});
}
on(type, listener) {
this._eventEmitter.on(type, listener);
return this;
}
off(type, listener) {
this._eventEmitter.off(type, listener);
return this;
}
once(type, listener) {
this._eventEmitter.once(type, listener);
return this;
}
bindSignal(signal) {
if (signal.aborted) {
this.abort(signal.reason);
}
const signalAbort = () => {
this.abort(signal.reason);
};
signal.addEventListener("abort", () => signalAbort());
this.once("complete", () => signal.removeEventListener("abort", signalAbort));
this.once("error", () => signal.removeEventListener("abort", signalAbort));
return this;
}
abort(reason) {
this._context.controller.abort(reason);
}
then(onfulfilled, onrejected) {
return this._promise.then((value) => {
const simplified = this._simplify(value);
return onfulfilled ? onfulfilled(simplified) : simplified;
}, (reason) => {
if (onrejected) {
return onrejected(reason);
}
throw reason;
});
}
catch(onrejected) {
return this._promise.catch(onrejected);
}
async result() {
const output = await this._promise;
const usage = this._context.usage;
return { output, usage, elapsed: this._elasped };
}
}
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/constants.js
var PROMPT_INPUT_BUFFER = 1048;
var PROMPT_OUTPUT_BUFFER = 512;
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/text.js
var Options = exports_exports.object({
length: exports_exports.number().min(1).max(1e5).optional().describe("The maximum number of tokens to generate")
});
var text = async (prompt, _options, ctx) => {
ctx.controller.signal.throwIfAborted();
const options = Options.parse(_options ?? {});
const tokenizer2 = await getTokenizer();
const model = await ctx.getModel();
prompt = tokenizer2.truncate(prompt, Math.max(model.input.maxTokens - PROMPT_INPUT_BUFFER, 100));
if (options.length) {
options.length = Math.min(model.output.maxTokens - PROMPT_OUTPUT_BUFFER, options.length);
}
const instructions = [];
let chart = "";
if (options.length) {
const length = clamp_default(options.length * 0.75, 5, options.length);
instructions.push(`IMPORTANT: Length constraint: ${length} tokens/words`);
instructions.push(`The text must be standalone and complete in less than ${length} tokens/words`);
}
if (options.length && options.length <= 500) {
chart = `
| Tokens | Text Length (approximate) |
|-------------|--------------------------------------|
| < 5 tokens | 1-3 words |
| 5-10 tokens | 3-6 words |
| 10-20 tokens| 6-15 words |
| 20-50 tokens| A short sentence (15-30 words) |
| 50-100 tokens| A medium sentence (30-70 words) |
| 100-200 tokens| A short paragraph (70-150 words) |
| 200-300 tokens| A medium paragraph (150-200 words) |
| 300-500 tokens| A long paragraph (200-300 words) |`.trim();
}
const { extracted } = await ctx.generateContent({
systemPrompt: `
Generate a text that fulfills the user prompt below. Answer directly to the prompt, without any acknowledgements or fluff. Also, make sure the text is standalone and complete.
${instructions.map((x) => `- ${x}`).join(`
`)}
${chart}
`.trim(),
temperature: 0.7,
messages: [{ type: "text", content: prompt, role: "user" }],
transform: (text2) => {
if (!text2.trim().length) {
throw new Error("The model did not return a valid summary. The response was empty.");
}
return text2;
}
});
return extracted;
};
Zai.prototype.text = function(prompt, _options) {
const context = new ZaiContext({
client: this.client,
modelId: this.Model,
taskId: this.taskId,
taskType: "zai.text",
adapter: this.adapter,
memoizer: this._resolveMemoizer()
});
return new Response(context, text(prompt, _options, context), (result) => result);
};
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/rewrite.js
var _Example = exports_exports.object({
input: exports_exports.string(),
output: exports_exports.string()
});
var Options2 = exports_exports.object({
examples: exports_exports.array(_Example).default([]),
length: exports_exports.number().min(10).max(16000).optional().describe("The maximum number of tokens to generate")
});
var START = "\u25A0START\u25A0";
var END = "\u25A0END\u25A0";
var rewrite = async (original, prompt, _options, ctx) => {
ctx.controller.signal.throwIfAborted();
const options = Options2.parse(_options ?? {});
const tokenizer2 = await getTokenizer();
const model = await ctx.getModel();
const taskId = ctx.taskId;
const taskType = "zai.rewrite";
const INPUT_COMPONENT_SIZE = Math.max(100, (model.input.maxTokens - PROMPT_INPUT_BUFFER) / 2);
prompt = tokenizer2.truncate(prompt, INPUT_COMPONENT_SIZE);
const inputSize = tokenizer2.count(original) + tokenizer2.count(prompt);
const maxInputSize = model.input.maxTokens - tokenizer2.count(prompt) - PROMPT_INPUT_BUFFER;
if (inputSize > maxInputSize) {
throw new Error(`The input size is ${inputSize} tokens long, which is more than the maximum of ${maxInputSize} tokens for this model (${model.name} = ${model.input.maxTokens} tokens)`);
}
const instructions = [];
const originalSize = tokenizer2.count(original);
const generationLength = options.length ? Math.min(Math.max(options.length * 10, 500), model.output.maxTokens - PROMPT_OUTPUT_BUFFER) : undefined;
if (options.length && originalSize > options.length) {
instructions.push(`The original text is ${originalSize} tokens long \u2013 it should be less than ${options.length}`);
instructions.push(`The text must be standalone and complete in less than ${options.length} tokens, so it has to be shortened to fit the length as well`);
}
const format = (before, prompt2) => {
return `
Prompt: ${prompt2}
${START}
${before}
${END}
`.trim();
};
const Key = fastHash(stringify({
taskId,
taskType,
input: original,
prompt
}));
const formatExample = ({ input, output, instructions: instructions2 }) => {
return [
{ type: "text", role: "user", content: format(input, instructions2 || prompt) },
{ type: "text", role: "assistant", content: `${START}${output}${END}` }
];
};
const defaultExamples = [
{ input: "Hello, how are you?", output: "Bonjour, comment \xE7a va?", instructions: "translate to French" },
{ input: `1
2
3`, output: `3
2
1`, instructions: "reverse the order" }
];
const tableExamples = taskId && ctx.adapter ? await ctx.adapter.getExamples({
input: original,
taskId,
taskType
}) : [];
const exactMatch = tableExamples.find((x) => x.key === Key);
if (exactMatch) {
return exactMatch.output;
}
const savedExamples = [
...tableExamples.map((x) => ({ input: x.input, output: x.output })),
...options.examples
];
const REMAINING_TOKENS = model.input.maxTokens - tokenizer2.count(prompt) - PROMPT_INPUT_BUFFER;
const examples = takeUntilTokens(savedExamples.length ? savedExamples : defaultExamples, REMAINING_TOKENS, (el) => tokenizer2.count(stringify(el.input)) + tokenizer2.count(stringify(el.output))).map(formatExample).flat();
const { extracted, meta } = await ctx.generateContent({
systemPrompt: `
Rewrite the text between the ${START} and ${END} tags to match the user prompt.
${instructions.map((x) => `\u2022 ${x}`).join(`
`)}
`.trim(),
messages: [...examples, { type: "text", content: format(original, prompt), role: "user" }],
stopSequences: [END],
...generationLength ? { maxTokens: generationLength } : {},
transform: (text2) => {
if (!text2.trim().length) {
throw new Error("The model did not return a valid rewrite. The response was empty.");
}
return text2;
}
});
let result = extracted;
if (result.includes(START)) {
result = result.slice(result.indexOf(START) + START.length);
}
if (result.includes(END)) {
result = result.slice(0, result.indexOf(END));
}
result = result.trim();
if (options.length && tokenizer2.count(result) > options.length) {
result = tokenizer2.truncate(result, options.length).trim();
}
if (taskId && ctx.adapter && !ctx.controller.signal.aborted) {
await ctx.adapter.saveExample({
key: Key,
metadata: {
cost: {
input: meta.cost.input,
output: meta.cost.output
},
latency: meta.latency,
model: ctx.modelId,
tokens: {
input: meta.tokens.input,
output: meta.tokens.output
}
},
instructions: prompt,
input: original,
output: result,
taskType,
taskId
});
}
return result;
};
Zai.prototype.rewrite = function(original, prompt, _options) {
const context = new ZaiContext({
client: this.client,
modelId: this.Model,
taskId: this.taskId,
taskType: "zai.rewrite",
adapter: this.adapter,
memoizer: this._resolveMemoizer()
});
return new Response(context, rewrite(original, prompt, _options, context), (result) => result);
};
// ../../node_modules/.bun/yocto-queue@1.2.2/node_modules/yocto-queue/index.js
class Node {
value;
next;
constructor(value) {
this.value = value;
}
}
class Queue {
#head;
#tail;
#size;
constructor() {
this.clear();
}
enqueue(value) {
const node = new Node(value);
if (this.#head) {
this.#tail.next = node;
this.#tail = node;
} else {
this.#head = node;
this.#tail = node;
}
this.#size++;
}
dequeue() {
const current = this.#head;
if (!current) {
return;
}
this.#head = this.#head.next;
this.#size--;
if (!this.#head) {
this.#tail = undefined;
}
return current.value;
}
peek() {
if (!this.#head) {
return;
}
return this.#head.value;
}
clear() {
this.#head = undefined;
this.#tail = undefined;
this.#size = 0;
}
get size() {
return this.#size;
}
*[Symbol.iterator]() {
let current = this.#head;
while (current) {
yield current.value;
current = current.next;
}
}
*drain() {
while (this.#head) {
yield this.dequeue();
}
}
}
// ../../node_modules/.bun/p-limit@7.3.0/node_modules/p-limit/index.js
function pLimit(concurrency) {
let rejectOnClear = false;
if (typeof concurrency === "object") {
({ concurrency, rejectOnClear = false } = concurrency);
}
validateConcurrency(concurrency);
if (typeof rejectOnClear !== "boolean") {
throw new TypeError("Expected `rejectOnClear` to be a boolean");
}
const queue = new Queue;
let activeCount = 0;
const resumeNext = () => {
if (activeCount < concurrency && queue.size > 0) {
activeCount++;
queue.dequeue().run();
}
};
const next = () => {
activeCount--;
resumeNext();
};
const run = async (function_, resolve, arguments_) => {
const result = (async () => function_(...arguments_))();
resolve(result);
try {
await result;
} catch {}
next();
};
const enqueue = (function_, resolve, reject, arguments_) => {
const queueItem = { reject };
new Promise((internalResolve) => {
queueItem.run = internalResolve;
queue.enqueue(queueItem);
}).then(run.bind(undefined, function_, resolve, arguments_));
if (activeCount < concurrency) {
resumeNext();
}
};
const generator = (function_, ...arguments_) => new Promise((resolve, reject) => {
enqueue(function_, resolve, reject, arguments_);
});
Object.defineProperties(generator, {
activeCount: {
get: () => activeCount
},
pendingCount: {
get: () => queue.size
},
clearQueue: {
value() {
if (!rejectOnClear) {
queue.clear();
return;
}
const abortError = AbortSignal.abort().reason;
while (queue.size > 0) {
queue.dequeue().reject(abortError);
}
}
},
concurrency: {
get: () => concurrency,
set(newConcurrency) {
validateConcurrency(newConcurrency);
concurrency = newConcurrency;
queueMicrotask(() => {
while (activeCount < concurrency && queue.size > 0) {
resumeNext();
}
});
}
},
map: {
async value(iterable, function_) {
const promises = Array.from(iterable, (value, index) => this(function_, value, index));
return Promise.all(promises);
}
}
});
return generator;
}
function validateConcurrency(concurrency) {
if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
throw new TypeError("Expected `concurrency` to be a number from 1 and up");
}
}
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/summarize.js
var Options3 = exports_exports.object({
prompt: exports_exports.string().describe("What should the text be summarized to?").default("New information, concepts and ideas that are deemed important"),
format: exports_exports.string().describe("How to format the example text").default("A normal text with multiple sentences and paragraphs. Use markdown to format the text into sections. Use headings, lists, and other markdown features to make the text more readable. Do not include links, images, or other non-text elements."),
length: exports_exports.number().min(10).max(1e5).describe("The length of the summary in tokens").default(250),
intermediateFactor: exports_exports.number().min(1).max(10).describe("How many times longer (than final length) are the intermediate summaries generated").default(4),
maxIterations: exports_exports.number().min(1).default(100),
sliding: exports_exports.object({
window: exports_exports.number().min(10).max(1e5),
overlap: exports_exports.number().min(0).max(1e5)
}).describe("Sliding window options").default({ window: 50000, overlap: 250 })
});
var START2 = "\u25A0START\u25A0";
var END2 = "\u25A0END\u25A0";
var summarize = async (original, options, ctx) => {
ctx.controller.signal.throwIfAborted();
const tokenizer2 = await getTokenizer();
const model = await ctx.getModel();
const INPUT_COMPONENT_SIZE = Math.max(100, (model.input.maxTokens - PROMPT_INPUT_BUFFER) / 4);
options.prompt = tokenizer2.truncate(options.prompt, INPUT_COMPONENT_SIZE);
options.format = tokenizer2.truncate(options.format, INPUT_COMPONENT_SIZE);
const maxOutputSize = model.output.maxTokens - PROMPT_OUTPUT_BUFFER;
if (options.length > maxOutputSize) {
throw new Error(`The desired output length is ${maxOutputSize} tokens long, which is more than the maximum of ${model.output.maxTokens} tokens for this model (${model.name})`);
}
options.sliding.window = Math.min(options.sliding.window, model.input.maxTokens - PROMPT_INPUT_BUFFER);
options.sliding.overlap = Math.min(options.sliding.overlap, options.sliding.window - 3 * options.sliding.overlap);
const format = (summary, newText) => {
return `
${START2}
${summary.length ? summary : "<summary still empty>"}
${END2}
Please amend the summary between the ${START2} and ${END2} tags to accurately reflect the prompt and the additional text below.
<|start_new_information|>
${newText}
<|new_information|>`.trim();
};
const tokens = tokenizer2.split(original);
const parts = Math.ceil(tokens.length / (options.sliding.window - options.sliding.overlap));
let iteration = 0;
const N = 2;
const useMergeSort = parts >= Math.pow(2, N);
const chunkSize = Math.ceil(tokens.length / (parts * N));
if (useMergeSort) {
const limit = pLimit(10);
const chunks = chunk_default(tokens, chunkSize).map((x) => x.join(""));
const allSummaries = (await Promise.allSettled(chunks.map((chunk2) => limit(() => summarize(chunk2, options, ctx))))).filter((x) => x.status === "fulfilled").map((x) => x.value);
return summarize(allSummaries.join(`
============
`), options, ctx);
}
const summaries = [];
let currentSummary = "";
for (let i = 0;i < tokens.length; i += options.sliding.window) {
const from = Math.max(0, i - options.sliding.overlap);
const to = Math.min(tokens.length, i + options.sliding.window + options.sliding.overlap);
const isFirst = i === 0;
const isLast = to >= tokens.length;
const slice = tokens.slice(from, to).join("");
if (iteration++ >= options.maxIterations) {
break;
}
const instructions = [
`At each step, you will receive a part of the text to summarize. Make sure to reply with the new summary in the tags ${START2} and ${END2}.`,
"Summarize the text and make sure that the main points are included.",
"Ignore any unnecessary details and focus on the main points.",
"Use short and concise sentences to increase readability and information density.",
"When looking at the new information, focus on: " + options.prompt
];
if (isFirst) {
instructions.push("The current summary is empty. You need to generate a summary that covers the main points of the text.");
}
let generationLength = options.length;
if (!isLast) {
generationLength = Math.min(tokenizer2.count(currentSummary) + options.length * options.intermediateFactor, maxOutputSize);
instructions.push("You need to amend the summary to include the new information. Make sure the summary is complete and covers all the main points.");
instructions.push(`The current summary is ${currentSummary.length} tokens long.`);
instructions.push(`You can amend the summary to be up to ${generationLength} tokens long.`);
}
if (isLast) {
instructions.push("This is the last part you will have to summarize. Make sure the summary is complete and covers all the main points.");
instructions.push(`The current summary is ${currentSummary.length} tokens long. You need to make sure it is ${options.length} tokens or less.`);
if (currentSummary.length > options.length) {
instructions.push(`The current summary is already too long, so you need to shorten it to ${options.length} tokens while also including the new information.`);
}
}
let { extracted: result } = await ctx.generateContent({
systemPrompt: `
You are summarizing a text. The text is split into ${parts} parts, and you are currently working on part ${iteration}.
At every step, you will receive the current summary and a new part of the text. You need to amend the summary to include the new information (if needed).
The summary needs to cover the main points of the text and must be concise.
IMPORTANT INSTRUCTIONS:
${instructions.map((x) => `- ${x.trim()}`).join(`
`)}
FORMAT OF THE SUMMARY:
${options.format}
`.trim(),
messages: [{ type: "text", content: format(currentSummary, slice), role: "user" }],
maxTokens: generationLength,
stopSequences: [END2],
transform: (text2) => {
if (!text2.trim().length) {
throw new Error("The model did not return a valid summary. The response was empty.");
}
return text2;
}
});
if (result.includes(START2)) {
result = result.slice(result.indexOf(START2) + START2.length);
}
if (result.includes("\u25A0")) {
result = result.slice(0, result.indexOf("\u25A0"));
}
summaries.push(result);
currentSummary = result;
}
return currentSummary.trim();
};
Zai.prototype.summarize = function(original, _options) {
const options = Options3.parse(_options ?? {});
const context = new ZaiContext({
client: this.client,
modelId: this.Model,
taskId: this.taskId,
taskType: "summarize",
adapter: this.adapter,
memoizer: this._resolveMemoizer()
});
return new Response(context, summarize(original, options, context), (value) => value);
};
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/check.js
var _Example2 = exports_exports.object({
input: exports_exports.any(),
check: exports_exports.boolean(),
reason: exports_exports.string().optional(),
condition: exports_exports.string().optional()
});
var _Options = exports_exports.object({
examples: exports_exports.array(_Example2).describe("Examples to check the condition against").default([])
});
var TRUE = "\u25A0TRUE\u25A0";
var FALSE = "\u25A0FALSE\u25A0";
var END3 = "\u25A0END\u25A0";
var check = async (input, condition, options, ctx) => {
ctx.controller.signal.throwIfAborted();
const tokenizer2 = await getTokenizer();
const model = await ctx.getModel();
const PROMPT_COMPONENT = Math.max(model.input.maxTokens - PROMPT_INPUT_BUFFER, 100);
const taskId = ctx.taskId;
const taskType = "zai.check";
const PROMPT_TOKENS = {
INPUT: Math.floor(0.5 * PROMPT_COMPONENT),
CONDITION: Math.floor(0.2 * PROMPT_COMPONENT)
};
const inputAsString = tokenizer2.truncate(stringify(input), PROMPT_TOKENS.INPUT);
condition = tokenizer2.truncate(condition, PROMPT_TOKENS.CONDITION);
const EXAMPLES_TOKENS = PROMPT_COMPONENT - tokenizer2.count(inputAsString) - tokenizer2.count(condition);
const Key = fastHash(JSON.stringify({
taskType,
taskId,
input: inputAsString,
condition
}));
const examples = taskId && ctx.adapter ? await ctx.adapter.getExamples({
input: inputAsString,
taskType,
taskId
}) : [];
const exactMatch = examples.find((x) => x.key === Key);
if (exactMatch) {
return { explanation: exactMatch.explanation ?? "", value: exactMatch.output };
}
const defaultExamples = [
{
input: "50 Cent",
check: true,
reason: "50 Cent is widely recognized as a public personality.",
condition: "Is the input a public personality?"
},
{
input: ["apple", "banana", "carrot", "house"],
check: false,
reason: "The list contains a house, which is not a fruit. Also, the list contains a carrot, which is a vegetable.",
condition: "Is the input exclusively a list of fruits?"
}
];
const userExamples = [
...examples.map((e) => ({ input: e.input, check: e.output, reason: e.explanation })),
...options.examples
];
let exampleId = 1;
const formatInput = (input2, condition2) => {
const header = userExamples.length ? `Expert Example #${exampleId++}` : `Example of condition: "${condition2}"`;
return `
${header}
<|start_input|>
${input2.trim()}
<|end_input|>
`.trim();
};
const formatOutput = (answer, justification) => {
return `
Analysis: ${justification}
Final Answer: ${answer ? TRUE : FALSE}
${END3}
`.trim();
};
const formatExample = (example) => [
{
type: "text",
content: formatInput(stringify(example.input ?? null), example.condition ?? condition),
role: "user"
},
{
type: "text",
content: formatOutput(example.check, example.reason ?? ""),
role: "assistant"
}
];
const allExamples = takeUntilTokens(userExamples.length ? userExamples : defaultExamples, EXAMPLES_TOKENS, (el) => tokenizer2.count(stringify(el.input)) + tokenizer2.count(el.reason ?? "")).map(formatExample).flat();
const specialInstructions = userExamples.length ? `
- You have been provided with examples from previous experts. Make sure to read them carefully before making your decision.
- Make sure to refer to the examples provided by the experts to justify your decision (when applicable).
- When in doubt, ground your decision on the examples provided by the experts instead of your own intuition.
- When no example is similar to the input, make sure to provide a clear justification for your decision while inferring the decision-making process from the examples provided by the experts.
`.trim() : "";
const {
extracted: { finalAnswer, explanation },
meta
} = await ctx.generateContent({
systemPrompt: `
Check if the following condition is true or false for the given input. Before answering, make sure to read the input and the condition carefully.
Justify your answer, then answer with either ${TRUE} or ${FALSE} at the very end, then add ${END3} to finish the response.
IMPORTANT: Make sure to answer with either ${TRUE} or ${FALSE} at the end of your response, but NOT both.
---
Expert Examples (#1 to #${exampleId - 1}):
${specialInstructions}
`.trim(),
stopSequences: [END3],
messages: [
...allExamples,
{
type: "text",
content: `
Considering the below input and above examples, is the following condition true or false?
${formatInput(inputAsString, condition)}
In your "Analysis", please refer to the Expert Examples # to justify your decision.`.trim(),
role: "user"
}
],
transform: (text2) => {
const hasTrue = text2.includes(TRUE);
const hasFalse = text2.includes(FALSE);
if (!hasTrue && !hasFalse) {
throw new Error(`The model did not return a valid answer. The response was: ${text2}`);
}
let finalAnswer2;
const explanation2 = text2.replace(TRUE, "").replace(FALSE, "").replace(END3, "").replace("Final Answer:", "").replace("Analysis:", "").trim();
if (hasTrue && hasFalse) {
finalAnswer2 = text2.lastIndexOf(TRUE) > text2.lastIndexOf(FALSE);
} else {
finalAnswer2 = hasTrue;
}
return { finalAnswer: finalAnswer2, explanation: explanation2.trim() };
}
});
if (taskId && ctx.adapter && !ctx.controller.signal.aborted) {
await ctx.adapter.saveExample({
key: Key,
taskType,
taskId,
input: inputAsString,
instructions: condition,
metadata: {
cost: {
input: meta.cost.input,
output: meta.cost.output
},
latency: meta.latency,
model: ctx.modelId,
tokens: {
input: meta.tokens.input,
output: meta.tokens.output
}
},
output: finalAnswer,
explanation
});
}
return {
value: finalAnswer,
explanation: explanation.trim()
};
};
Zai.prototype.check = function(input, condition, _options) {
const options = _Options.parse(_options ?? {});
const context = new ZaiContext({
client: this.client,
modelId: this.Model,
taskId: this.taskId,
taskType: "zai.check",
adapter: this.adapter,
memoizer: this._resolveMemoizer()
});
return new Response(context, check(input, condition, options, context), (result) => result.value);
};
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/filter.js
var _Example3 = exports_exports.object({
input: exports_exports.any(),
filter: exports_exports.boolean(),
reason: exports_exports.string().optional()
});
var _Options2 = exports_exports.object({
tokensPerItem: exports_exports.number().min(1).max(1e5).optional().describe("The maximum number of tokens per item").default(250),
examples: exports_exports.array(_Example3).describe("Examples to filter the condition against").default([])
});
var END4 = "\u25A0END\u25A0";
var filter = async (input, condition, _options, ctx) => {
ctx.controller.signal.throwIfAborted();
const options = _Options2.parse(_options ?? {});
const tokenizer2 = await getTokenizer();
const model = await ctx.getModel();
const taskId = ctx.taskId;
const taskType = "zai.filter";
const MAX_ITEMS_PER_CHUNK = 50;
const TOKENS_TOTAL_MAX = model.input.maxTokens - PROMPT_INPUT_BUFFER - PROMPT_OUTPUT_BUFFER;
const TOKENS_EXAMPLES_MAX = Math.floor(Math.max(250, TOKENS_TOTAL_MAX * 0.5));
const TOKENS_CONDITION_MAX = clamp_default(TOKENS_TOTAL_MAX * 0.25, 250, tokenizer2.count(condition));
const TOKENS_INPUT_ARRAY_MAX = TOKENS_TOTAL_MAX - TOKENS_EXAMPLES_MAX - TOKENS_CONDITION_MAX;
condition = tokenizer2.truncate(condition, TOKENS_CONDITION_MAX);
let chunks = [];
let currentChunk = [];
let currentChunkTokens = 0;
for (const element of input) {
const elementAsString = tokenizer2.truncate(stringify(element, false), options.tokensPerItem);
const elementTokens = tokenizer2.count(elementAsString);
if (currentChunkTokens + elementTokens > TOKENS_INPUT_ARRAY_MAX || currentChunk.length >= MAX_ITEMS_PER_CHUNK) {
chunks.push(currentChunk);
currentChunk = [];
currentChunkTokens = 0;
}
currentChunk.push(element);
currentChunkTokens += elementTokens;
}
if (currentChunk.length > 0) {
chunks.push(currentChunk);
}
chunks = chunks.filter((x) => x.length > 0);
const formatInput = (input2, condition2) => {
return `
Condition to check:
${condition2}
Items (from \u25A00 to \u25A0${input2.length - 1})
==============================
${input2.map((x, idx) => `\u25A0${idx} = ${stringify(x.input ?? null, false)}`).join(`
`)}
`.trim();
};
const formatExamples = (examples) => {
return `
${examples.map((x, idx) => `\u25A0${idx}:${x.filter ? "true" : "false"}`).join("")}
${END4}
====
Here's the reasoning behind each example:
${examples.map((x, idx) => `\u25A0${idx}:${x.filter ? "true" : "false"}:${x.reason ?? "No reason provided"}`).join(`
`)}
`.trim();
};
const genericExamples = [
{
input: "apple",
filter: true,
reason: "Apples are fruits"
},
{
input: "Apple Inc.",
filter: false,
reason: "Apple Inc. is a company, not a fruit"
},
{
input: "banana",
filter: true,
reason: "Bananas are fruits"
},
{
input: "potato",
filter: false,
reason: "Potatoes are vegetables"
}
];
const genericExamplesMessages = [
{
type: "text",
content: formatInput(genericExamples, "is a fruit"),
role: "user"
},
{
type: "text",
content: formatExamples(genericExamples),
role: "assistant"
}
];
const filterChunk = async (chunk2) => {
const examples = taskId && ctx.adapter ? await ctx.adapter.getExamples({
input: JSON.stringify(chunk2).slice(0, 1000),
taskType,
taskId
}).then((x) => x.map((y) => ({ filter: y.output, input: y.input, reason: y.explanation }))) : [];
const allExamples = takeUntilTokens([...examples, ...options.examples ?? []], TOKENS_EXAMPLES_MAX, (el) => tokenizer2.count(stringify(el.input)));
const exampleMessages = [
{
type: "text",
content: formatInput(allExamples, condition),
role: "user"
},
{
type: "text",
content: formatExamples(allExamples),
role: "assistant"
}
];
const { extracted: partial, meta } = await ctx.generateContent({
systemPrompt: `
You are given a list of items. Your task is to filter out the items that meet the condition below.
You need to return the full list of items with the format:
\u25A0x:true\u25A0y:false\u25A0z:true (where x, y, z are the indices of the items in the list)
You need to start with "\u25A00" and go up to the last index "\u25A0${chunk2.length - 1}".
If an item meets the condition, you should return ":true", otherwise ":false".
IMPORTANT: Make sure to read the condition and the examples carefully before making your decision.
The condition is: "${condition}"
`.trim(),
stopSequences: [END4],
messages: [
...exampleMessages.length ? exampleMessages : genericExamplesMessages,
{
type: "text",
content: formatInput(chunk2.map((x) => ({ input: x })), condition),
role: "user"
}
],
transform: (text2) => {
const indices = text2.trim().split("\u25A0").filter((x) => x.length > 0).map((x) => {
const [idx, filter2] = x.split(":");
return { idx: parseInt(idx?.trim() ?? ""), filter: filter2?.toLowerCase().trim() === "true" };
});
return chunk2.filter((_, idx) => {
return indices.find((x) => x.idx === idx && x.filter) ?? false;
});
}
});
if (taskId && ctx.adapter && !ctx.controller.signal.aborted) {
const key = fastHash(stringify({
taskId,
taskType,
input: JSON.stringify(chunk2),
condition
}));
await ctx.adapter.saveExample({
key,
taskType,
taskId,
input: JSON.stringify(chunk2),
output: partial,
instructions: condition,
metadata: {
cost: {
input: meta.cost.input,
output: meta.cost.output
},
latency: meta.latency,
model: ctx.modelId,
tokens: {
input: meta.tokens.input,
output: meta.tokens.output
}
}
});
}
return partial;
};
const limit = pLimit(10);
const filteredChunks = await Promise.all(chunks.map((chunk2) => limit(() => filterChunk(chunk2))));
return filteredChunks.flat();
};
Zai.prototype.filter = function(input, condition, _options) {
const context = new ZaiContext({
client: this.client,
modelId: this.Model,
taskId: this.taskId,
taskType: "zai.filter",
adapter: this.adapter,
memoizer: this._resolveMemoizer()
});
return new Response(context, filter(input, condition, _options, context), (result) => result);
};
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/extract.js
var import_json5 = __toESM(require_lib(), 1);
// ../../node_modules/.bun/jsonrepair@3.14.0/node_modules/jsonrepair/lib/esm/utils/JSONRepairError.js
class JSONRepairError extends Error {
constructor(message, position) {
super(`${message} at position ${position}`);
this.position = position;
}
}
// ../../node_modules/.bun/jsonrepair@3.14.0/node_modules/jsonrepair/lib/esm/utils/stringUtils.js
var codeSpace = 32;
var codeNewline = 10;
var codeTab = 9;
var codeReturn = 13;
var codeNonBreakingSpace = 160;
var codeMongolianVowelSeparator = 6158;
var codeEnQuad = 8192;
var codeZeroWidthSpace = 8203;
var codeNarrowNoBreakSpace = 8239;
var codeMediumMathematicalSpace = 8287;
var codeIdeographicSpace = 12288;
var codeZeroWidthNoBreakSpace = 65279;
function isHex(char) {
return /^[0-9A-Fa-f]$/.test(char);
}
function isDigit(char) {
return char >= "0" && char <= "9";
}
function isValidStringCharacter(char) {
return char >= " ";
}
function isDelimiter(char) {
return `,:[]/{}()
+`.includes(char);
}
function isFunctionNameCharStart(char) {
return char >= "a" && char <= "z" || char >= "A" && char <= "Z" || char === "_" || char === "$";
}
function isFunctionNameChar(char) {
return char >= "a" && char <= "z" || char >= "A" && char <= "Z" || char === "_" || char === "$" || char >= "0" && char <= "9";
}
var regexUrlStart = /^(http|https|ftp|mailto|file|data|irc):\/\/$/;
var regexUrlChar = /^[A-Za-z0-9-._~:/?#@!$&'()*+;=]$/;
function isUnquotedStringDelimiter(char) {
return `,[]/{}
+`.includes(char);
}
function isStartOfValue(char) {
return isQuote(char) || regexStartOfValue.test(char);
}
var regexStartOfValue = /^[[{\w-]$/;
function isControlCharacter(char) {
return char === `
` || char === "\r" || char === "\t" || char === "\b" || char === "\f";
}
function isWhitespace(text2, index) {
const code = text2.charCodeAt(index);
return code === codeSpace || code === codeNewline || code === codeTab || code === codeReturn;
}
function isWhitespaceExceptNewline(text2, index) {
const code = text2.charCodeAt(index);
return code === codeSpace || code === codeTab || code === codeReturn;
}
function isSpecialWhitespace(text2, index) {
const code = text2.charCodeAt(index);
return code === codeNonBreakingSpace || code === codeMongolianVowelSeparator || code >= codeEnQuad && code <= codeZeroWidthSpace || code === codeNarrowNoBreakSpace || code === codeMediumMathematicalSpace || code === codeIdeographicSpace || code === codeZeroWidthNoBreakSpace;
}
function isQuote(char) {
return isDoubleQuoteLike(char) || isSingleQuoteLike(char);
}
function isDoubleQuoteLike(char) {
return char === '"' || char === "\u201C" || char === "\u201D";
}
function isDoubleQuote(char) {
return char === '"';
}
function isSingleQuoteLike(char) {
return char === "'" || char === "\u2018" || char === "\u2019" || char === "`" || char === "\xB4";
}
function isSingleQuote(char) {
return char === "'";
}
function stripLastOccurrence(text2, textToStrip) {
let stripRemainingText = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
const index = text2.lastIndexOf(textToStrip);
return index !== -1 ? text2.substring(0, index) + (stripRemainingText ? "" : text2.substring(index + 1)) : text2;
}
function insertBeforeLastWhitespace(text2, textToInsert) {
let index = text2.length;
if (!isWhitespace(text2, index - 1)) {
return text2 + textToInsert;
}
while (isWhitespace(text2, index - 1)) {
index--;
}
return text2.substring(0, index) + textToInsert + text2.substring(index);
}
function removeAtIndex(text2, start, count) {
return text2.substring(0, start) + text2.substring(start + count);
}
function endsWithCommaOrNewline(text2) {
return /[,\n][ \t\r]*$/.test(text2);
}
// ../../node_modules/.bun/jsonrepair@3.14.0/node_modules/jsonrepair/lib/esm/regular/jsonrepair.js
var controlCharacters = {
"\b": "\\b",
"\f": "\\f",
"\n": "\\n",
"\r": "\\r",
"\t": "\\t"
};
var escapeCharacters = {
'"': '"',
"\\": "\\",
"/": "/",
b: "\b",
f: "\f",
n: `
`,
r: "\r",
t: "\t"
};
function jsonrepair(text2) {
let i = 0;
let output = "";
parseMarkdownCodeBlock(["```", "[```", "{```"]);
const processed = parseValue();
if (!processed) {
throwUnexpectedEnd();
}
parseMarkdownCodeBlock(["```", "```]", "```}"]);
const processedComma = parseCharacter(",");
if (processedComma) {
parseWhitespaceAndSkipComments();
}
if (isStartOfValue(text2[i]) && endsWithCommaOrNewline(output)) {
if (!processedComma) {
output = insertBeforeLastWhitespace(output, ",");
}
parseNewlineDelimitedJSON();
} else if (processedComma) {
output = stripLastOccurrence(output, ",");
}
while (text2[i] === "}" || text2[i] === "]") {
i++;
parseWhitespaceAndSkipComments();
}
if (i >= text2.length) {
return output;
}
throwUnexpectedCharacter();
function parseValue() {
parseWhitespaceAndSkipComments();
const processed2 = parseObject() || parseArray() || parseString() || parseNumber() || parseKeywords() || parseUnquotedString(false) || parseRegex();
parseWhitespaceAndSkipComments();
return processed2;
}
function parseWhitespaceAndSkipComments() {
let skipNewline = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
const start = i;
let changed = parseWhitespace(skipNewline);
do {
changed = parseComment();
if (changed) {
changed = parseWhitespace(skipNewline);
}
} while (changed);
return i > start;
}
function parseWhitespace(skipNewline) {
const _isWhiteSpace = skipNewline ? isWhitespace : isWhitespaceExceptNewline;
let whitespace = "";
while (true) {
if (_isWhiteSpace(text2, i)) {
whitespace += text2[i];
i++;
} else if (isSpecialWhitespace(text2, i)) {
whitespace += " ";
i++;
} else {
break;
}
}
if (whitespace.length > 0) {
output += whitespace;
return true;
}
return false;
}
function parseComment() {
if (text2[i] === "/" && text2[i + 1] === "*") {
while (i < text2.length && !atEndOfBlockComment(text2, i)) {
i++;
}
i += 2;
return true;
}
if (text2[i] === "/" && text2[i + 1] === "/") {
while (i < text2.length && text2[i] !== `
`) {
i++;
}
return true;
}
return false;
}
function parseMarkdownCodeBlock(blocks) {
if (skipMarkdownCodeBlock(blocks)) {
if (isFunctionNameCharStart(text2[i])) {
while (i < text2.length && isFunctionNameChar(text2[i])) {
i++;
}
}
parseWhitespaceAndSkipComments();
return true;
}
return false;
}
function skipMarkdownCodeBlock(blocks) {
parseWhitespace(true);
for (const block of blocks) {
const end = i + block.length;
if (text2.slice(i, end) === block) {
i = end;
return true;
}
}
return false;
}
function parseCharacter(char) {
if (text2[i] === char) {
output += text2[i];
i++;
return true;
}
return false;
}
function skipCharacter(char) {
if (text2[i] === char) {
i++;
return true;
}
return false;
}
function skipEscapeCharacter() {
return skipCharacter("\\");
}
function skipEllipsis() {
parseWhitespaceAndSkipComments();
if (text2[i] === "." && text2[i + 1] === "." && text2[i + 2] === ".") {
i += 3;
parseWhitespaceAndSkipComments();
skipCharacter(",");
return true;
}
return false;
}
function parseObject() {
if (text2[i] === "{") {
output += "{";
i++;
parseWhitespaceAndSkipComments();
if (skipCharacter(",")) {
parseWhitespaceAndSkipComments();
}
let initial = true;
while (i < text2.length && text2[i] !== "}") {
let processedComma2;
if (!initial) {
processedComma2 = parseCharacter(",");
if (!processedComma2) {
output = insertBeforeLastWhitespace(output, ",");
}
parseWhitespaceAndSkipComments();
} else {
processedComma2 = true;
initial = false;
}
skipEllipsis();
const processedKey = parseString() || parseUnquotedString(true);
if (!processedKey) {
if (text2[i] === "}" || text2[i] === "{" || text2[i] === "]" || text2[i] === "[" || text2[i] === undefined) {
output = stripLastOccurrence(output, ",");
} else {
throwObjectKeyExpected();
}
break;
}
parseWhitespaceAndSkipComments();
const processedColon = parseCharacter(":");
const truncatedText = i >= text2.length;
if (!processedColon) {
if (isStartOfValue(text2[i]) || truncatedText) {
output = insertBeforeLastWhitespace(output, ":");
} else {
throwColonExpected();
}
}
const processedValue = parseValue();
if (!processedValue) {
if (processedColon || truncatedText) {
output += "null";
} else {
throwColonExpected();
}
}
}
if (text2[i] === "}") {
output += "}";
i++;
} else {
output = insertBeforeLastWhitespace(output, "}");
}
return true;
}
return false;
}
function parseArray() {
if (text2[i] === "[") {
output += "[";
i++;
parseWhitespaceAndSkipComments();
if (skipCharacter(",")) {
parseWhitespaceAndSkipComments();
}
let initial = true;
while (i < text2.length && text2[i] !== "]") {
if (!initial) {
const processedComma2 = parseCharacter(",");
if (!processedComma2) {
output = insertBeforeLastWhitespace(output, ",");
}
} else {
initial = false;
}
skipEllipsis();
const processedValue = parseValue();
if (!processedValue) {
output = stripLastOccurrence(output, ",");
break;
}
}
if (text2[i] === "]") {
output += "]";
i++;
} else {
output = insertBeforeLastWhitespace(output, "]");
}
return true;
}
return false;
}
function parseNewlineDelimitedJSON() {
let initial = true;
let processedValue = true;
while (processedValue) {
if (!initial) {
const processedComma2 = parseCharacter(",");
if (!processedComma2) {
output = insertBeforeLastWhitespace(output, ",");
}
} else {
initial = false;
}
processedValue = parseValue();
}
if (!processedValue) {
output = stripLastOccurrence(output, ",");
}
output = `[
${output}
]`;
}
function parseString() {
let stopAtDelimiter = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
let stopAtIndex = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : -1;
let skipEscapeChars = text2[i] === "\\";
if (skipEscapeChars) {
i++;
skipEscapeChars = true;
}
if (isQuote(text2[i])) {
const isEndQuote = isDoubleQuote(text2[i]) ? isDoubleQuote : isSingleQuote(text2[i]) ? isSingleQuote : isSingleQuoteLike(text2[i]) ? isSingleQuoteLike : isDoubleQuoteLike;
const iBefore = i;
const oBefore = output.length;
let str = '"';
i++;
while (true) {
if (i >= text2.length) {
const iPrev = prevNonWhitespaceIndex(i - 1);
if (!stopAtDelimiter && isDelimiter(text2.charAt(iPrev))) {
i = iBefore;
output = output.substring(0, oBefore);
return parseString(true);
}
str = insertBeforeLastWhitespace(str, '"');
output += str;
return true;
}
if (i === stopAtIndex) {
str = insertBeforeLastWhitespace(str, '"');
output += str;
return true;
}
if (isEndQuote(text2[i])) {
const iQuote = i;
const oQuote = str.length;
str += '"';
i++;
output += str;
parseWhitespaceAndSkipComments(false);
if (stopAtDelimiter || i >= text2.length || isDelimiter(text2[i]) || isQuote(text2[i]) || isDigit(text2[i])) {
parseConcatenatedString();
return true;
}
const iPrevChar = prevNonWhitespaceIndex(iQuote - 1);
const prevChar = text2.charAt(iPrevChar);
if (prevChar === ",") {
i = iBefore;
output = output.substring(0, oBefore);
return parseString(false, iPrevChar);
}
if (isDelimiter(prevChar)) {
i = iBefore;
output = output.substring(0, oBefore);
return parseString(true);
}
output = output.substring(0, oBefore);
i = iQuote + 1;
str = `${str.substring(0, oQuote)}\\${str.substring(oQuote)}`;
} else if (stopAtDelimiter && isUnquotedStringDelimiter(text2[i])) {
if (text2[i - 1] === ":" && regexUrlStart.test(text2.substring(iBefore + 1, i + 2))) {
while (i < text2.length && regexUrlChar.test(text2[i])) {
str += text2[i];
i++;
}
}
str = insertBeforeLastWhitespace(str, '"');
output += str;
parseConcatenatedString();
return true;
} else if (text2[i] === "\\") {
const char = text2.charAt(i + 1);
const escapeChar = escapeCharacters[char];
if (escapeChar !== undefined) {
str += text2.slice(i, i + 2);
i += 2;
} else if (char === "u") {
let j = 2;
while (j < 6 && isHex(text2[i + j])) {
j++;
}
if (j === 6) {
str += text2.slice(i, i + 6);
i += 6;
} else if (i + j >= text2.length) {
i = text2.length;
} else {
throwInvalidUnicodeCharacter();
}
} else if (char === `
`) {
str += "\\n";
i += 2;
} else {
str += char;
i += 2;
}
} else {
const char = text2.charAt(i);
if (char === '"' && text2[i - 1] !== "\\") {
str += `\\${char}`;
i++;
} else if (isControlCharacter(char)) {
str += controlCharacters[char];
i++;
} else {
if (!isValidStringCharacter(char)) {
throwInvalidCharacter(char);
}
str += char;
i++;
}
}
if (skipEscapeChars) {
skipEscapeCharacter();
}
}
}
return false;
}
function parseConcatenatedString() {
let processed2 = false;
parseWhitespaceAndSkipComments();
while (text2[i] === "+") {
processed2 = true;
i++;
parseWhitespaceAndSkipComments();
output = stripLastOccurrence(output, '"', true);
const start = output.length;
const parsedStr = parseString();
if (parsedStr) {
output = removeAtIndex(output, start, 1);
} else {
output = insertBeforeLastWhitespace(output, '"');
}
}
return processed2;
}
function parseNumber() {
const start = i;
if (text2[i] === "-") {
i++;
if (atEndOfNumber()) {
repairNumberEndingWithNumericSymbol(start);
return true;
}
if (!isDigit(text2[i])) {
i = start;
return false;
}
}
while (isDigit(text2[i])) {
i++;
}
if (text2[i] === ".") {
i++;
if (atEndOfNumber()) {
repairNumberEndingWithNumericSymbol(start);
return true;
}
if (!isDigit(text2[i])) {
i = start;
return false;
}
while (isDigit(text2[i])) {
i++;
}
}
if (text2[i] === "e" || text2[i] === "E") {
i++;
if (text2[i] === "-" || text2[i] === "+") {
i++;
}
if (atEndOfNumber()) {
repairNumberEndingWithNumericSymbol(start);
return true;
}
if (!isDigit(text2[i])) {
i = start;
return false;
}
while (isDigit(text2[i])) {
i++;
}
}
if (!atEndOfNumber()) {
i = start;
return false;
}
if (i > start) {
const num = text2.slice(start, i);
const hasInvalidLeadingZero = /^0\d/.test(num);
output += hasInvalidLeadingZero ? `"${num}"` : num;
return true;
}
return false;
}
function parseKeywords() {
return parseKeyword("true", "true") || parseKeyword("false", "false") || parseKeyword("null", "null") || parseKeyword("True", "true") || parseKeyword("False", "false") || parseKeyword("None", "null");
}
function parseKeyword(name, value) {
if (text2.slice(i, i + name.length) === name) {
output += value;
i += name.length;
return true;
}
return false;
}
function parseUnquotedString(isKey) {
const start = i;
if (isFunctionNameCharStart(text2[i])) {
while (i < text2.length && isFunctionNameChar(text2[i])) {
i++;
}
let j = i;
while (isWhitespace(text2, j)) {
j++;
}
if (text2[j] === "(") {
i = j + 1;
parseValue();
if (text2[i] === ")") {
i++;
if (text2[i] === ";") {
i++;
}
}
return true;
}
}
while (i < text2.length && !isUnquotedStringDelimiter(text2[i]) && !isQuote(text2[i]) && (!isKey || text2[i] !== ":")) {
i++;
}
if (text2[i - 1] === ":" && regexUrlStart.test(text2.substring(start, i + 2))) {
while (i < text2.length && regexUrlChar.test(text2[i])) {
i++;
}
}
if (i > start) {
while (isWhitespace(text2, i - 1) && i > 0) {
i--;
}
const symbol = text2.slice(start, i);
output += symbol === "undefined" ? "null" : JSON.stringify(symbol);
if (text2[i] === '"') {
i++;
}
return true;
}
}
function parseRegex() {
if (text2[i] === "/") {
const start = i;
i++;
while (i < text2.length && (text2[i] !== "/" || text2[i - 1] === "\\")) {
i++;
}
i++;
output += JSON.stringify(text2.substring(start, i));
return true;
}
}
function prevNonWhitespaceIndex(start) {
let prev = start;
while (prev > 0 && isWhitespace(text2, prev)) {
prev--;
}
return prev;
}
function atEndOfNumber() {
return i >= text2.length || isDelimiter(text2[i]) || isWhitespace(text2, i);
}
function repairNumberEndingWithNumericSymbol(start) {
output += `${text2.slice(start, i)}0`;
}
function throwInvalidCharacter(char) {
throw new JSONRepairError(`Invalid character ${JSON.stringify(char)}`, i);
}
function throwUnexpectedCharacter() {
throw new JSONRepairError(`Unexpected character ${JSON.stringify(text2[i])}`, i);
}
function throwUnexpectedEnd() {
throw new JSONRepairError("Unexpected end of json string", text2.length);
}
function throwObjectKeyExpected() {
throw new JSONRepairError("Object key expected", i);
}
function throwColonExpected() {
throw new JSONRepairError("Colon expected", i);
}
function throwInvalidUnicodeCharacter() {
const chars = text2.slice(i, i + 6);
throw new JSONRepairError(`Invalid unicode character "${chars}"`, i);
}
}
function atEndOfBlockComment(text2, i) {
return text2[i] === "*" && text2[i + 1] === "/";
}
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/errors.js
class JsonParsingError extends Error {
constructor(json, error) {
const message = JsonParsingError._formatError(json, error);
super(message);
this.json = json;
this.error = error;
}
static _formatError(json, error) {
let errorMessage = `Error parsing JSON:
`;
errorMessage += `---JSON---
${json}
`;
if (src_default.is.zuiError(error)) {
errorMessage += `---Validation Errors---
`;
errorMessage += JsonParsingError._formatZodError(error);
} else {
errorMessage += `---Error---
`;
errorMessage += `The JSON provided is not valid JSON.
`;
errorMessage += `Details: ${error.message}
`;
}
return errorMessage;
}
static _formatZodError(zodError) {
const issues = zodError.issues;
if (issues.length === 0) {
return `Unknown validation error
`;
}
let message = "";
for (let i = 0;i < issues.length; i++) {
const issue = issues[i];
const path = issue.path.length > 0 ? issue.path.join(".") : "root";
message += `${i + 1}. Field: "${path}"
`;
switch (issue.code) {
case "invalid_type":
message += ` Problem: Expected ${issue.expected}, but received ${issue.received}
`;
message += ` Message: ${issue.message}
`;
break;
case "invalid_string":
if ("validation" in issue) {
message += ` Problem: Invalid ${issue.validation} format
`;
}
message += ` Message: ${issue.message}
`;
break;
case "too_small":
if (issue.type === "string") {
if (issue.exact) {
message += ` Problem: String must be exactly ${issue.minimum} characters
`;
} else {
message += ` Problem: String must be at least ${issue.minimum} characters
`;
}
} else if (issue.type === "number") {
message += ` Problem: Number must be ${issue.inclusive ? "at least" : "greater than"} ${issue.minimum}
`;
} else if (issue.type === "array") {
message += ` Problem: Array must contain ${issue.inclusive ? "at least" : "more than"} ${issue.minimum} items
`;
}
message += ` Message: ${issue.message}
`;
break;
case "too_big":
if (issue.type === "string") {
if (issue.exact) {
message += ` Problem: String must be exactly ${issue.maximum} characters
`;
} else {
message += ` Problem: String must be at most ${issue.maximum} characters
`;
}
} else if (issue.type === "number") {
message += ` Problem: Number must be ${issue.inclusive ? "at most" : "less than"} ${issue.maximum}
`;
} else if (issue.type === "array") {
message += ` Problem: Array must contain ${issue.inclusive ? "at most" : "fewer than"} ${issue.maximum} items
`;
}
message += ` Message: ${issue.message}
`;
break;
case "invalid_enum_value":
message += ` Problem: Invalid value "${issue.received}"
`;
message += ` Allowed values: ${issue.options.map((o) => `"${o}"`).join(", ")}
`;
message += ` Message: ${issue.message}
`;
break;
case "invalid_literal":
message += ` Problem: Expected the literal value "${issue.expected}", but received "${issue.received}"
`;
message += ` Message: ${issue.message}
`;
break;
case "invalid_union":
message += ` Problem: Value doesn't match any of the expected formats
`;
message += ` Message: ${issue.message}
`;
break;
default:
message += ` Problem: ${issue.message}
`;
}
if (i < issues.length - 1) {
message += `
`;
}
}
return message;
}
}
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/extract.js
var INVALID_SCHEMA_ERROR = "zai.extract only accepts schemas created with @bpinternal/zui";
var Options4 = exports_exports.object({
instructions: exports_exports.string().optional().describe("Instructions to guide the user on how to extract the data"),
chunkLength: exports_exports.number().min(100).max(1e5).optional().describe("The maximum number of tokens per chunk").default(16000),
strict: exports_exports.boolean().optional().default(true).describe("Whether to strictly follow the schema or not")
});
var SPECIAL_CHAR = "\u25A0";
var START3 = "\u25A0json_start\u25A0";
var END5 = "\u25A0json_end\u25A0";
var NO_MORE = "\u25A0NO_MORE_ELEMENT\u25A0";
var ZERO_ELEMENTS = "\u25A0ZERO_ELEMENTS\u25A0";
var extract = async (input, _schema, _options, ctx) => {
ctx.controller.signal.throwIfAborted();
if (!exports_exports.is.zuiType(_schema)) {
throw new Error(INVALID_SCHEMA_ERROR);
}
let originalSchema;
try {
originalSchema = exports_exports.transforms.fromJSONSchema(exports_exports.transforms.toJSONSchema(_schema));
} catch {
originalSchema = _schema;
}
const options = Options4.parse(_options ?? {});
const tokenizer2 = await getTokenizer();
const model = await ctx.getModel();
const taskId = ctx.taskId;
const taskType = "zai.extract";
const PROMPT_COMPONENT = Math.max(model.input.maxTokens - PROMPT_INPUT_BUFFER, 100);
const { isArrayOfObjects, isWrappedValue, objSchema } = _parsing.parseSchema(originalSchema, {
partial: !options.strict
});
const schemaTypescript = objSchema.toTypescriptType({ declaration: false, treatDefaultAsOptional: true });
const schemaLength = tokenizer2.count(schemaTypescript);
options.chunkLength = Math.min(options.chunkLength, model.input.maxTokens - PROMPT_INPUT_BUFFER - schemaLength);
const keys = Object.keys(objSchema.shape);
const inputAsString = stringify(input);
if (tokenizer2.count(inputAsString) > options.chunkLength) {
const limit = pLimit(10);
const tokens = tokenizer2.split(inputAsString);
const chunks = chunk_default(tokens, options.chunkLength).map((x) => x.join(""));
const all = await Promise.allSettled(chunks.map((chunk2) => limit(() => extract(chunk2, originalSchema, {
...options,
strict: false
}, ctx)))).then((results) => results.filter((x) => x.status === "fulfilled").map((x) => x.value));
ctx.controller.signal.throwIfAborted();
const rows = all.map((x, idx) => `<part-${idx + 1}>
${stringify(x, true)}
</part-${idx + 1}>`).join(`
`);
return extract(`
The result has been split into ${all.length} parts. Recursively merge the result into the final result.
When merging arrays, take unique values.
When merging conflictual (but defined) information, take the most reasonable and frequent value.
Non-defined values are OK and normal. Don't delete fields because of null values. Focus on defined values.
Here's the data:
${rows}
Merge it back into a final result.`.trim(), originalSchema, options, ctx);
}
const instructions = [];
if (options.instructions) {
instructions.push(options.instructions);
}
const shape = `{ ${keys.map((key) => `"${key}": ...`).join(", ")} }`;
const abbv = "{ ... }";
if (isArrayOfObjects) {
instructions.push("You may have multiple elements, or zero elements in the input.");
instructions.push("You must extract each element separately.");
instructions.push(`Each element must be a JSON object with exactly the format: ${START3}${shape}${END5}`);
instructions.push(`If there are no elements to extract, respond with ${ZERO_ELEMENTS}.`);
instructions.push(`When you are done extracting all elements, type "${NO_MORE}" to finish.`);
instructions.push(`For example, if you have zero elements, the output should look like this: ${ZERO_ELEMENTS}${NO_MORE}`);
instructions.push(`For example, if you have two elements, the output should look like this: ${START3}${abbv}${END5}${START3}${abbv}${END5}${NO_MORE}`);
} else {
instructions.push("You may have exactly one element in the input.");
instructions.push(`The element must be a JSON object with exactly the format: ${START3}${shape}${END5}`);
}
if (!options.strict) {
instructions.push("You may ignore any fields that are not present in the input. All keys are optional.");
}
const EXAMPLES_TOKENS = PROMPT_COMPONENT - tokenizer2.count(inputAsString) - tokenizer2.count(instructions.join(`
`));
const Key = fastHash(JSON.stringify({
taskType,
taskId,
input: inputAsString,
instructions: options.instructions
}));
const examples = taskId && ctx.adapter ? await ctx.adapter.getExamples({
input: inputAsString,
taskType,
taskId
}) : [];
const exactMatch = examples.find((x) => x.key === Key);
if (exactMatch) {
return exactMatch.output;
}
const defaultExample = isArrayOfObjects ? {
input: `The story goes as follow.
Once upon a time, there was a person named Alice who was 30 years old.
Then, there was a person named Bob who was 25 years old.
The end.`,
schema: "Array<{ name: string, age: number }>",
instructions: "Extract all people",
extracted: [
{
name: "Alice",
age: 30
},
{
name: "Bob",
age: 25
}
]
} : {
input: `The story goes as follow.
Once upon a time, there was a person named Alice who was 30 years old.
The end.`,
schema: "{ name: string, age: number }",
instructions: "Extract the person",
extracted: { name: "Alice", age: 30 }
};
const userExamples = examples.map((e) => ({
input: e.input,
extracted: e.output,
schema: schemaTypescript,
instructions: options.instructions
}));
let exampleId = 1;
const formatInput = (input2, schema, instructions2) => {
const header = userExamples.length ? `Expert Example #${exampleId++}` : "Here's an example to help you understand the format:";
return `
${header}
<|start_schema|>
${schema}
<|end_schema|>
<|start_instructions|>
${instructions2 ?? "No specific instructions, just follow the schema above."}
<|end_instructions|>
<|start_input|>
${input2.trim()}
<|end_input|>
`.trim();
};
const formatOutput = (extracted2) => {
const extractedArr = isArray_default(extracted2) ? extracted2 : [extracted2];
return extractedArr.map((x) => `
${START3}
${JSON.stringify(x, null, 2)}
${END5}`.trim()).join(`
`) + NO_MORE;
};
const formatExample = (example) => [
{
type: "text",
content: formatInput(stringify(example.input ?? null), example.schema, example.instructions),
role: "user"
},
{
type: "text",
content: formatOutput(example.extracted),
role: "assistant"
}
];
const allExamples = takeUntilTokens(userExamples.length ? userExamples : [defaultExample], EXAMPLES_TOKENS, (el) => tokenizer2.count(stringify(el.input)) + tokenizer2.count(stringify(el.extracted))).map(formatExample).flat();
const { meta, extracted } = await ctx.generateContent({
systemPrompt: `
Extract the following information from the input:
${schemaTypescript}
====
${instructions.map((x) => `\u2022 ${x}`).join(`
`)}
`.trim(),
stopSequences: [isArrayOfObjects ? NO_MORE : END5],
messages: [
...allExamples,
{
role: "user",
type: "text",
content: formatInput(inputAsString, schemaTypescript, options.instructions ?? "")
}
],
transform: (text2) => (text2 || "{}").split(START3).filter((x) => x.trim().length > 0 && x.includes("}")).map((x) => {
try {
let json = x.slice(0, x.indexOf(END5)).trim();
if (json.includes(SPECIAL_CHAR)) {
json = json.slice(0, json.indexOf(SPECIAL_CHAR)).trim();
}
const repairedJson = jsonrepair(json);
const parsedJson = import_json5.default.parse(repairedJson);
const safe = objSchema.safeParse(parsedJson);
if (safe.success) {
return safe.data;
}
if (options.strict) {
throw new JsonParsingError(x, safe.error);
}
return parsedJson;
} catch (error) {
throw new JsonParsingError(x, error instanceof Error ? error : new Error("Unknown error"));
}
}).filter((x) => x !== null)
});
let final;
if (isArrayOfObjects) {
final = extracted;
} else if (extracted.length === 0) {
final = options.strict ? objSchema.parse({}) : {};
} else {
final = extracted[0];
}
if (isWrappedValue) {
if (Array.isArray(final)) {
final = final.map((x) => ("value" in x) ? x.value : x);
} else if (typeof final === "object" && final !== null) {
final = "value" in final ? final.value : final;
}
}
if (taskId && ctx.adapter && !ctx.controller.signal.aborted) {
await ctx.adapter.saveExample({
key: Key,
taskId: `zai/${taskId}`,
taskType,
instructions: options.instructions ?? "No specific instructions",
input: inputAsString,
output: final,
metadata: {
cost: {
input: meta.cost.input,
output: meta.cost.output
},
latency: meta.latency,
model: ctx.modelId,
tokens: {
input: meta.tokens.input,
output: meta.tokens.output
}
}
});
}
return final;
};
Zai.prototype.extract = function(input, schema, _options) {
const context = new ZaiContext({
client: this.client,
modelId: this.Model,
taskId: this.taskId,
taskType: "zai.extract",
adapter: this.adapter,
memoizer: this._resolveMemoizer()
});
return new Response(context, extract(input, schema, _options, context), (result) => result);
};
var _parsing;
((_parsing2) => {
const _getBaseSchema = (schema) => schema.naked ? schema.naked() : schema;
const _maybeWrapObjSchema = (s) => {
if (exports_exports.is.zuiObject(s)) {
return { schema: s, isWrapped: false };
}
return {
schema: exports_exports.object({
value: s
}),
isWrapped: true
};
};
const _applySchemaOptions = (schema, opts) => {
if (!opts.partial) {
return schema;
}
try {
return schema.partial();
} catch {
return schema;
}
};
_parsing2.parseSchema = (originalSchema, opts) => {
const baseType = _getBaseSchema(originalSchema);
if (exports_exports.is.zuiArray(baseType)) {
const elementType = _getBaseSchema(baseType.element);
const { schema: schema2, isWrapped } = _maybeWrapObjSchema(elementType);
return { isArrayOfObjects: true, isWrappedValue: isWrapped, objSchema: _applySchemaOptions(schema2, opts) };
}
const { schema, isWrapped: wrapped } = _maybeWrapObjSchema(baseType);
return { isArrayOfObjects: false, isWrappedValue: wrapped, objSchema: _applySchemaOptions(schema, opts) };
};
})(_parsing || (_parsing = {}));
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/label.js
var LABELS = {
ABSOLUTELY_NOT: "ABSOLUTELY_NOT",
PROBABLY_NOT: "PROBABLY_NOT",
AMBIGUOUS: "AMBIGUOUS",
PROBABLY_YES: "PROBABLY_YES",
ABSOLUTELY_YES: "ABSOLUTELY_YES"
};
var ALL_LABELS = Object.values(LABELS).join(" | ");
var _Options3 = exports_exports.object({
examples: exports_exports.array(exports_exports.object({
input: exports_exports.any(),
labels: exports_exports.record(exports_exports.object({ label: exports_exports.enum(ALL_LABELS), explanation: exports_exports.string().optional() }))
})).default([]).describe("Examples to help the user make a decision"),
instructions: exports_exports.string().optional().describe("Instructions to guide the user on how to extract the data"),
chunkLength: exports_exports.number().min(100).max(1e5).optional().describe("The maximum number of tokens per chunk").default(16000)
});
var _Labels = exports_exports.record(exports_exports.string().min(1).max(250), exports_exports.string()).superRefine((labels, ctx) => {
const keys = Object.keys(labels);
for (const key of keys) {
if (key.length < 1 || key.length > 250) {
ctx.addIssue({ message: `The label key "${key}" must be between 1 and 250 characters long`, code: "custom" });
}
if (keys.lastIndexOf(key) !== keys.indexOf(key)) {
ctx.addIssue({ message: `Duplicate label: ${labels[key]}`, code: "custom" });
}
if (/[^a-zA-Z0-9_]/.test(key)) {
ctx.addIssue({
message: `The label key "${key}" must only contain alphanumeric characters and underscores`,
code: "custom"
});
}
}
return true;
});
var parseLabel = (label2) => {
label2 = label2.toUpperCase().replace(/\s+/g, "_").replace(/_{2,}/g, "_").trim();
if (label2.includes("ABSOLUTELY") && label2.includes("NOT")) {
return LABELS.ABSOLUTELY_NOT;
} else if (label2.includes("NOT")) {
return LABELS.PROBABLY_NOT;
} else if (label2.includes("AMBIGUOUS")) {
return LABELS.AMBIGUOUS;
}
if (label2.includes("YES")) {
return LABELS.PROBABLY_YES;
} else if (label2.includes("ABSOLUTELY") && label2.includes("YES")) {
return LABELS.ABSOLUTELY_YES;
}
return LABELS.AMBIGUOUS;
};
var getConfidence = (label2) => {
switch (label2) {
case LABELS.ABSOLUTELY_NOT:
case LABELS.ABSOLUTELY_YES:
return 1;
case LABELS.PROBABLY_NOT:
case LABELS.PROBABLY_YES:
return 0.5;
default:
return 0;
}
};
var label = async (input, _labels, _options, ctx) => {
ctx.controller.signal.throwIfAborted();
const options = _Options3.parse(_options ?? {});
const labels = _Labels.parse(_labels);
const tokenizer2 = await getTokenizer();
const model = await ctx.getModel();
const taskId = ctx.taskId;
const taskType = "zai.label";
const TOTAL_MAX_TOKENS = clamp_default(options.chunkLength, 1000, model.input.maxTokens - PROMPT_INPUT_BUFFER);
const CHUNK_EXAMPLES_MAX_TOKENS = clamp_default(Math.floor(TOTAL_MAX_TOKENS * 0.5), 250, 1e4);
const CHUNK_INPUT_MAX_TOKENS = clamp_default(TOTAL_MAX_TOKENS - CHUNK_EXAMPLES_MAX_TOKENS, TOTAL_MAX_TOKENS * 0.5, TOTAL_MAX_TOKENS);
const inputAsString = stringify(input);
if (tokenizer2.count(inputAsString) > CHUNK_INPUT_MAX_TOKENS) {
const limit = pLimit(10);
const tokens = tokenizer2.split(inputAsString);
const chunks = chunk_default(tokens, CHUNK_INPUT_MAX_TOKENS).map((x) => x.join(""));
const allLabels = await Promise.all(chunks.map((chunk2) => limit(() => label(chunk2, _labels, _options, ctx))));
return allLabels.reduce((acc, x) => {
Object.keys(x).forEach((key) => {
if (acc[key]?.value === true) {
acc[key] = acc[key];
} else if (x[key]?.value === true) {
acc[key] = x[key];
} else {
acc[key] = acc[key] || x[key];
}
});
return acc;
}, {});
}
const END6 = "\u25A0END\u25A0";
const Key = fastHash(JSON.stringify({
taskType,
taskId,
input: inputAsString,
instructions: options.instructions ?? ""
}));
const convertToAnswer = (mapping) => {
return Object.keys(labels).reduce((acc, key) => {
acc[key] = {
explanation: mapping[key]?.explanation ?? "",
value: mapping[key]?.label === LABELS.ABSOLUTELY_YES || mapping[key]?.label === LABELS.PROBABLY_YES,
confidence: getConfidence(mapping[key]?.label)
};
return acc;
}, {});
};
const examples = taskId && ctx.adapter ? await ctx.adapter.getExamples({
input: inputAsString,
taskType,
taskId
}) : [];
options.examples.forEach((example) => {
examples.push({
key: fastHash(JSON.stringify(example)),
input: stringify(example.input),
similarity: 1,
explanation: "",
output: example.labels
});
});
const exactMatch = examples.find((x) => x.key === Key);
if (exactMatch) {
return convertToAnswer(exactMatch.output);
}
const allExamples = takeUntilTokens(examples, CHUNK_EXAMPLES_MAX_TOKENS, (el) => tokenizer2.count(stringify(el.input)) + tokenizer2.count(stringify(el.output)) + tokenizer2.count(el.explanation ?? "") + 100).map((example, idx) => [
{
type: "text",
role: "user",
content: `
Expert Example #${idx + 1}
<|start_input|>
${stringify(example.input)}
<|end_input|>`.trim()
},
{
type: "text",
role: "assistant",
content: `
Expert Example #${idx + 1}
============
${Object.keys(example.output).map((key) => `
\u25A0${key}:\u3010${example.output[key]?.explanation}\u3011:${example.output[key]?.label}\u25A0
`.trim()).join(`
`)}
${END6}
`.trim()
}
]).flat();
const format = Object.keys(labels).map((key) => {
return `
\u25A0${key}:\u3010explanation (where "explanation" is answering the question "${labels[key]}")\u3011:x\u25A0 (where x is ${ALL_LABELS})
`.trim();
}).join(`
`);
const { extracted, meta } = await ctx.generateContent({
stopSequences: [END6],
systemPrompt: `
You need to tag the input with the following labels based on the question asked:
${LABELS.ABSOLUTELY_NOT}: You are absolutely sure that the answer is "NO" to the question.
${LABELS.PROBABLY_NOT}: You are leaning towards "NO" to the question.
${LABELS.AMBIGUOUS}: You are unsure about the answer to the question.
${LABELS.PROBABLY_YES}: You are leaning towards "YES" to the question.
${LABELS.ABSOLUTELY_YES}: You are absolutely sure that the answer is "YES" to the question.
You need to return a mapping of the labels, an explanation and the answer for each label following the format below:
\`\`\`
${format}
${END6}
\`\`\`
${options.instructions}
===
You should consider the Expert Examples below to help you make your decision.
In your "Analysis", please refer to the Expert Examples # to justify your decision.
`.trim(),
messages: [
...allExamples,
{
type: "text",
role: "user",
content: `
Input to tag:
<|start_input|>
${inputAsString}
<|end_input|>
Answer with this following format:
\`\`\`
${format}
${END6}
\`\`\`
Format cheatsheet:
\`\`\`
\u25A0label:\u3010explanation\u3011:x\u25A0
\`\`\`
Where \`x\` is one of the following: ${ALL_LABELS}
Remember: In your \`explanation\`, please refer to the Expert Examples # (and quote them) that are relevant to ground your decision-making process.
The Expert Examples are there to help you make your decision. They have been provided by experts in the field and their answers (and reasoning) are considered the ground truth and should be used as a reference to make your decision when applicable.
For example, you can say: "According to Expert Example #1, ..."`.trim()
}
],
transform: (text2) => Object.keys(labels).reduce((acc, key) => {
const match = text2.match(new RegExp(`\u25A0${key}:\u3010(.+)\u3011:(\\w{2,})\u25A0`, "i"));
if (match) {
const explanation = match[1].trim();
const label2 = parseLabel(match[2]);
acc[key] = {
explanation,
label: label2
};
} else {
acc[key] = {
explanation: "",
label: LABELS.AMBIGUOUS
};
}
return acc;
}, {})
});
if (taskId && ctx.adapter && !ctx.controller.signal.aborted) {
await ctx.adapter.saveExample({
key: Key,
taskType,
taskId,
instructions: options.instructions ?? "",
metadata: {
cost: {
input: meta.cost.input,
output: meta.cost.output
},
latency: meta.latency,
model: ctx.modelId,
tokens: {
input: meta.tokens.input,
output: meta.tokens.output
}
},
input: inputAsString,
output: extracted
});
}
return convertToAnswer(extracted);
};
Zai.prototype.label = function(input, labels, _options) {
const context = new ZaiContext({
client: this.client,
modelId: this.Model,
taskId: this.taskId,
taskType: "zai.label",
adapter: this.adapter,
memoizer: this._resolveMemoizer()
});
return new Response(context, label(input, labels, _options, context), (result) => Object.keys(result).reduce((acc, key) => {
acc[key] = result[key].value;
return acc;
}, {}));
};
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/group.js
var _InitialGroup = exports_exports.object({
id: exports_exports.string().min(1).max(100),
label: exports_exports.string().min(1).max(250),
elements: exports_exports.array(exports_exports.any()).optional().default([])
});
var _Options4 = exports_exports.object({
instructions: exports_exports.string().optional(),
tokensPerElement: exports_exports.number().min(1).max(1e5).optional().default(250),
chunkLength: exports_exports.number().min(100).max(1e5).optional().default(16000),
initialGroups: exports_exports.array(_InitialGroup).optional().default([]),
maxGroups: exports_exports.number().min(2).optional(),
minElements: exports_exports.number().min(1).optional()
});
var END6 = "\u25A0END\u25A0";
var normalizeLabel = (label2) => {
return label2.trim().toLowerCase().replace(/^(group|new group|new)\s*[-:]\s*/i, "").replace(/^(group|new group|new)\s+/i, "").trim();
};
var group = async (input, _options, ctx) => {
ctx.controller.signal.throwIfAborted();
const options = _Options4.parse(_options ?? {});
const tokenizer2 = await getTokenizer();
const model = await ctx.getModel();
const taskId = ctx.taskId;
const taskType = "zai.group";
if (input.length === 0) {
return [];
}
const groups = /* @__PURE__ */ new Map;
const groupElements = /* @__PURE__ */ new Map;
const elementGroups = /* @__PURE__ */ new Map;
const labelToGroupId = /* @__PURE__ */ new Map;
let groupIdCounter = 0;
options.initialGroups.forEach((ig) => {
const normalized = normalizeLabel(ig.label);
groups.set(ig.id, { id: ig.id, label: ig.label, normalizedLabel: normalized });
groupElements.set(ig.id, /* @__PURE__ */ new Set);
labelToGroupId.set(normalized, ig.id);
});
const elements = input.map((element, idx) => ({
element,
index: idx,
stringified: stringify(element, false)
}));
const TOKENS_TOTAL_MAX = model.input.maxTokens - PROMPT_INPUT_BUFFER - PROMPT_OUTPUT_BUFFER;
const TOKENS_INSTRUCTIONS_MAX = options.instructions ? clamp_default(tokenizer2.count(options.instructions), 100, TOKENS_TOTAL_MAX * 0.2) : 0;
const TOKENS_AVAILABLE = TOKENS_TOTAL_MAX - TOKENS_INSTRUCTIONS_MAX;
const TOKENS_FOR_GROUPS_MAX = Math.floor(TOKENS_AVAILABLE * 0.4);
const TOKENS_FOR_ELEMENTS_MAX = Math.floor(TOKENS_AVAILABLE * 0.6);
const MAX_ELEMENTS_PER_CHUNK = 50;
const elementChunks = [];
let currentChunk = [];
let currentTokens = 0;
for (const elem of elements) {
const truncated = tokenizer2.truncate(elem.stringified, options.tokensPerElement);
const elemTokens = tokenizer2.count(truncated);
if ((currentTokens + elemTokens > TOKENS_FOR_ELEMENTS_MAX || currentChunk.length >= MAX_ELEMENTS_PER_CHUNK) && currentChunk.length > 0) {
elementChunks.push(currentChunk);
currentChunk = [];
currentTokens = 0;
}
currentChunk.push(elem.index);
currentTokens += elemTokens;
}
if (currentChunk.length > 0) {
elementChunks.push(currentChunk);
}
const getGroupChunks = () => {
const allGroupIds2 = Array.from(groups.keys());
if (allGroupIds2.length === 0)
return [[]];
const chunks = [];
let currentChunk2 = [];
let currentTokens2 = 0;
for (const groupId of allGroupIds2) {
const group2 = groups.get(groupId);
const groupTokens = tokenizer2.count(`${group2.label}`) + 10;
if (currentTokens2 + groupTokens > TOKENS_FOR_GROUPS_MAX && currentChunk2.length > 0) {
chunks.push(currentChunk2);
currentChunk2 = [];
currentTokens2 = 0;
}
currentChunk2.push(groupId);
currentTokens2 += groupTokens;
}
if (currentChunk2.length > 0) {
chunks.push(currentChunk2);
}
return chunks.length > 0 ? chunks : [[]];
};
const processChunk = async (elementIndices, groupIds) => {
const chunkElements = elementIndices.map((idx) => elements[idx].element);
const chunkInputStr = JSON.stringify(chunkElements);
const examples = taskId && ctx.adapter ? await ctx.adapter.getExamples({
input: chunkInputStr.slice(0, 1000),
taskType,
taskId
}) : [];
const key = fastHash(stringify({
taskId,
taskType,
input: chunkInputStr,
instructions: options.instructions ?? "",
groupIds: groupIds.join(",")
}));
const exactMatch = examples.find((x) => x.key === key);
if (exactMatch && exactMatch.output) {
return exactMatch.output;
}
const elementsText = elementIndices.map((idx, i) => {
const elem = elements[idx];
const truncated = tokenizer2.truncate(elem.stringified, options.tokensPerElement);
return `\u25A0${i}: ${truncated}\u25A0`;
}).join(`
`);
const groupsList = groupIds.map((gid) => groups.get(gid).label);
const groupsText = groupsList.length > 0 ? `**Existing Groups (prefer reusing these):**
${groupsList.map((l) => `- ${l}`).join(`
`)}
` : "";
const exampleMessages = [];
for (const example of examples.slice(0, 5)) {
try {
const exampleInput = JSON.parse(example.input);
const exampleElements = Array.isArray(exampleInput) ? exampleInput : [exampleInput];
const exampleElementsText = exampleElements.map((el, i) => `\u25A0${i}: ${stringify(el, false).slice(0, 200)}\u25A0`).join(`
`);
exampleMessages.push({
type: "text",
role: "user",
content: `Expert Example - Elements to group:
${exampleElementsText}
Group each element.`
});
const exampleOutput = example.output;
if (Array.isArray(exampleOutput) && exampleOutput.length > 0) {
const formattedAssignments = exampleOutput.map((assignment) => `\u25A0${assignment.elementIndex}:${assignment.label}\u25A0`).join(`
`);
exampleMessages.push({
type: "text",
role: "assistant",
content: `${formattedAssignments}
${END6}`
});
if (example.explanation) {
exampleMessages.push({
type: "text",
role: "assistant",
content: `Reasoning: ${example.explanation}`
});
}
}
} catch {}
}
const systemPrompt = `You are grouping elements into cohesive groups.
${options.instructions ? `**Instructions:** ${options.instructions}
` : "**Instructions:** Group similar elements together."}
**Important:**
- Each element gets exactly ONE group label
- Use EXACT SAME label for similar items (case-sensitive)
- Create new descriptive labels when needed
**Output Format:**
One line per element:
\u25A00:Group Label\u25A0
\u25A01:Group Label\u25A0
${END6}`.trim();
const userPrompt = `${groupsText}**Elements (\u25A00 to \u25A0${elementIndices.length - 1}):**
${elementsText}
**Task:** For each element, output one line with its group label.
${END6}`.trim();
const { extracted } = await ctx.generateContent({
systemPrompt,
stopSequences: [END6],
messages: [...exampleMessages, { type: "text", role: "user", content: userPrompt }],
transform: (text2) => {
const assignments = [];
const regex = /\u25A0(\d+):([^\u25A0]+)\u25A0/g;
let match;
while ((match = regex.exec(text2)) !== null) {
const idx = parseInt(match[1] ?? "", 10);
if (isNaN(idx) || idx < 0 || idx >= elementIndices.length)
continue;
const label2 = (match[2] ?? "").trim();
if (!label2)
continue;
assignments.push({
elementIndex: elementIndices[idx],
label: label2.slice(0, 250)
});
}
return assignments;
}
});
return extracted;
};
const elementLimit = pLimit(10);
const groupLimit = pLimit(10);
const allChunkResults = await Promise.all(elementChunks.map((elementChunk) => elementLimit(async () => {
const groupChunks = getGroupChunks();
const allAssignments = await Promise.all(groupChunks.map((groupChunk) => groupLimit(() => processChunk(elementChunk, groupChunk))));
return allAssignments.flat();
})));
for (const assignments of allChunkResults) {
for (const { elementIndex, label: label2 } of assignments) {
const normalized = normalizeLabel(label2);
let groupId = labelToGroupId.get(normalized);
if (!groupId) {
groupId = `group_${groupIdCounter++}`;
groups.set(groupId, { id: groupId, label: label2, normalizedLabel: normalized });
groupElements.set(groupId, /* @__PURE__ */ new Set);
labelToGroupId.set(normalized, groupId);
}
groupElements.get(groupId).add(elementIndex);
if (!elementGroups.has(elementIndex)) {
elementGroups.set(elementIndex, /* @__PURE__ */ new Set);
}
elementGroups.get(elementIndex).add(groupId);
}
}
const allGroupIds = Array.from(groups.keys());
if (allGroupIds.length > 0) {
const elementsNeedingReview = [];
for (const elem of elements) {
const seenGroups = elementGroups.get(elem.index) ?? /* @__PURE__ */ new Set;
const unseenCount = allGroupIds.filter((gid) => !seenGroups.has(gid)).length;
if (unseenCount > 0) {
elementsNeedingReview.push(elem.index);
}
}
if (elementsNeedingReview.length > 0) {
const reviewChunks = [];
let reviewChunk = [];
let reviewTokens = 0;
for (const elemIdx of elementsNeedingReview) {
const elem = elements[elemIdx];
const truncated = tokenizer2.truncate(elem.stringified, options.tokensPerElement);
const elemTokens = tokenizer2.count(truncated);
const shouldStartNewChunk = (reviewTokens + elemTokens > TOKENS_FOR_ELEMENTS_MAX || reviewChunk.length >= MAX_ELEMENTS_PER_CHUNK) && reviewChunk.length > 0;
if (shouldStartNewChunk) {
reviewChunks.push(reviewChunk);
reviewChunk = [];
reviewTokens = 0;
}
reviewChunk.push(elemIdx);
reviewTokens += elemTokens;
}
if (reviewChunk.length > 0) {
reviewChunks.push(reviewChunk);
}
const reviewResults = await Promise.all(reviewChunks.map((chunk2) => elementLimit(async () => {
const groupChunks = getGroupChunks();
const allAssignments = await Promise.all(groupChunks.map((groupChunk) => groupLimit(() => processChunk(chunk2, groupChunk))));
return allAssignments.flat();
})));
const updateElementGroupAssignment = (elementIndex, label2) => {
const normalized = normalizeLabel(label2);
const groupId = labelToGroupId.get(normalized);
if (!groupId)
return;
groupElements.get(groupId).add(elementIndex);
const elemGroups = elementGroups.get(elementIndex) ?? /* @__PURE__ */ new Set;
if (!elementGroups.has(elementIndex)) {
elementGroups.set(elementIndex, elemGroups);
}
elemGroups.add(groupId);
};
for (const assignments of reviewResults) {
for (const { elementIndex, label: label2 } of assignments) {
updateElementGroupAssignment(elementIndex, label2);
}
}
}
}
for (const [elementIndex, groupSet] of elementGroups.entries()) {
if (groupSet.size > 1) {
const groupIds = Array.from(groupSet);
for (const gid of groupIds) {
groupElements.get(gid)?.delete(elementIndex);
}
const finalGroupId = groupIds[0];
groupElements.get(finalGroupId).add(elementIndex);
}
}
if (options.maxGroups !== undefined) {
const nonEmptyGroupIds = () => Array.from(groupElements.entries()).filter(([, s]) => s.size > 0).map(([id]) => id);
let currentIds = nonEmptyGroupIds();
if (currentIds.length > options.maxGroups) {
const groupSummaries = currentIds.map((gid, idx) => {
const info = groups.get(gid);
const elemIndices = Array.from(groupElements.get(gid));
const sampleElements = elemIndices.slice(0, 3).map((i) => tokenizer2.truncate(elements[i].stringified, 60)).join(", ");
return `\u25A0${idx}:${info.label} (${elemIndices.length} elements, e.g. ${sampleElements})\u25A0`;
});
const mergeSystemPrompt = `You are consolidating groups into fewer, broader categories.
${options.instructions ? `**Original instructions:** ${options.instructions}
` : ""}
**Task:** Merge ${currentIds.length} groups down to at most ${options.maxGroups} groups.
Combine the most semantically related groups together. Give each merged group a new descriptive label.
**Output Format:**
For each input group (\u25A00 to \u25A0${currentIds.length - 1}), output which target label it maps to:
\u25A00:Merged Label\u25A0
\u25A01:Merged Label\u25A0
${END6}
Use the EXACT SAME label for groups that should be merged together.`.trim();
const mergeUserPrompt = `**Current groups:**
${groupSummaries.join(`
`)}
Merge into at most ${options.maxGroups} groups.
${END6}`.trim();
const { extracted: mergeAssignments } = await ctx.generateContent({
systemPrompt: mergeSystemPrompt,
stopSequences: [END6],
messages: [{ type: "text", role: "user", content: mergeUserPrompt }],
transform: (text2) => {
const assignments = [];
const regex = /\u25A0(\d+):([^\u25A0]+)\u25A0/g;
let match;
while ((match = regex.exec(text2)) !== null) {
const idx = parseInt(match[1] ?? "", 10);
if (isNaN(idx) || idx < 0 || idx >= currentIds.length)
continue;
const label2 = (match[2] ?? "").trim();
if (!label2)
continue;
assignments.push({ sourceIdx: idx, label: label2.slice(0, 250) });
}
return assignments;
}
});
const mergeMap = /* @__PURE__ */ new Map;
for (const { sourceIdx, label: label2 } of mergeAssignments) {
const sourceGid = currentIds[sourceIdx];
if (!sourceGid)
continue;
const normalized = normalizeLabel(label2);
if (!mergeMap.has(normalized)) {
mergeMap.set(normalized, { label: label2, sourceGroupIds: [] });
}
mergeMap.get(normalized).sourceGroupIds.push(sourceGid);
}
for (const [, { label: label2, sourceGroupIds }] of mergeMap) {
if (sourceGroupIds.length <= 1)
continue;
const targetGid = sourceGroupIds[0];
const targetSet = groupElements.get(targetGid);
const targetInfo = groups.get(targetGid);
targetInfo.label = label2;
targetInfo.normalizedLabel = normalizeLabel(label2);
for (let i = 1;i < sourceGroupIds.length; i++) {
const sourceGid = sourceGroupIds[i];
const sourceSet = groupElements.get(sourceGid);
sourceSet.forEach((elemIdx) => targetSet.add(elemIdx));
sourceSet.clear();
}
}
currentIds = nonEmptyGroupIds();
while (currentIds.length > options.maxGroups) {
currentIds.sort((a, b) => groupElements.get(a).size - groupElements.get(b).size);
const sourceSet = groupElements.get(currentIds[0]);
const targetSet = groupElements.get(currentIds[1]);
for (const elemIdx of sourceSet) {
targetSet.add(elemIdx);
}
sourceSet.clear();
currentIds = nonEmptyGroupIds();
}
}
}
if (options.minElements !== undefined && options.minElements > 1) {
const getNonEmptyGroupIds = () => Array.from(groupElements.entries()).filter(([, s]) => s.size > 0).map(([id]) => id);
const orphanIndices = [];
for (const gid of getNonEmptyGroupIds()) {
const elemSet = groupElements.get(gid);
if (elemSet.size > 0 && elemSet.size < options.minElements) {
for (const idx of elemSet) {
orphanIndices.push(idx);
}
elemSet.clear();
}
}
if (orphanIndices.length > 0) {
const validGroupIds = getNonEmptyGroupIds();
const orphanChunks = [];
let currentOrphanChunk = [];
let currentOrphanTokens = 0;
for (const elemIdx of orphanIndices) {
const elem = elements[elemIdx];
const truncated = tokenizer2.truncate(elem.stringified, options.tokensPerElement);
const elemTokens = tokenizer2.count(truncated);
if ((currentOrphanTokens + elemTokens > TOKENS_FOR_ELEMENTS_MAX || currentOrphanChunk.length >= MAX_ELEMENTS_PER_CHUNK) && currentOrphanChunk.length > 0) {
orphanChunks.push(currentOrphanChunk);
currentOrphanChunk = [];
currentOrphanTokens = 0;
}
currentOrphanChunk.push(elemIdx);
currentOrphanTokens += elemTokens;
}
if (currentOrphanChunk.length > 0) {
orphanChunks.push(currentOrphanChunk);
}
const orphanResults = await Promise.all(orphanChunks.map((chunk2) => elementLimit(async () => {
const groupChunksForOrphans = validGroupIds.length > 0 ? getGroupChunks() : [[]];
const allAssignments = await Promise.all(groupChunksForOrphans.filter((gc) => gc.length === 0 || gc.some((gid) => validGroupIds.includes(gid))).map((groupChunk) => {
const filteredGroupChunk = groupChunk.filter((gid) => validGroupIds.includes(gid));
return groupLimit(() => processChunk(chunk2, filteredGroupChunk));
}));
return allAssignments.flat();
})));
const flatAssignments = orphanResults.flat();
for (const { elementIndex, label: label2 } of flatAssignments) {
const normalized = normalizeLabel(label2);
let groupId = labelToGroupId.get(normalized);
if (!groupId) {
groupId = `group_${groupIdCounter++}`;
groups.set(groupId, { id: groupId, label: label2, normalizedLabel: normalized });
groupElements.set(groupId, /* @__PURE__ */ new Set);
labelToGroupId.set(normalized, groupId);
}
groupElements.get(groupId).add(elementIndex);
}
const isAssigned = (idx) => {
for (const [, elemSet] of groupElements) {
if (elemSet.has(idx))
return true;
}
return false;
};
const unassigned = orphanIndices.filter((idx) => !isAssigned(idx));
const placeIntoLargest = (indices) => {
const allNonEmpty = getNonEmptyGroupIds();
if (allNonEmpty.length === 0)
return;
const largestGid = allNonEmpty.reduce((a, b) => groupElements.get(a).size >= groupElements.get(b).size ? a : b);
for (const idx of indices) {
groupElements.get(largestGid).add(idx);
}
};
if (unassigned.length > 0) {
placeIntoLargest(unassigned);
}
const mergeUndersizedGroups = () => {
const allNonEmpty = getNonEmptyGroupIds();
if (allNonEmpty.length <= 1)
return false;
const largestGid = allNonEmpty.reduce((a, b) => groupElements.get(a).size >= groupElements.get(b).size ? a : b);
const targetSet = groupElements.get(largestGid);
let merged = false;
for (const gid of allNonEmpty) {
if (gid === largestGid)
continue;
const elemSet = groupElements.get(gid);
if (elemSet.size > 0 && elemSet.size < options.minElements) {
elemSet.forEach((idx) => targetSet.add(idx));
elemSet.clear();
merged = true;
}
}
return merged;
};
while (mergeUndersizedGroups()) {}
}
}
const result = [];
for (const [groupId, elementIndices] of groupElements.entries()) {
if (elementIndices.size > 0) {
const groupInfo = groups.get(groupId);
result.push({
id: groupInfo.id,
label: groupInfo.label,
elements: Array.from(elementIndices).map((idx) => elements[idx].element)
});
}
}
if (taskId && ctx.adapter && !ctx.controller.signal.aborted) {
const key = fastHash(stringify({
taskId,
taskType,
input: JSON.stringify(input),
instructions: options.instructions ?? ""
}));
const outputAssignments = [];
for (const [groupId, elementIndices] of groupElements.entries()) {
const groupInfo = groups.get(groupId);
for (const idx of elementIndices) {
outputAssignments.push({
elementIndex: idx,
label: groupInfo.label
});
}
}
await ctx.adapter.saveExample({
key,
taskType,
taskId,
input: JSON.stringify(input),
output: result,
instructions: options.instructions ?? "",
metadata: {
cost: { input: 0, output: 0 },
latency: 0,
model: ctx.modelId,
tokens: { input: 0, output: 0 }
}
});
}
return result;
};
Zai.prototype.group = function(input, _options) {
const context = new ZaiContext({
client: this.client,
modelId: this.Model,
taskId: this.taskId,
taskType: "zai.group",
adapter: this.adapter,
memoizer: this._resolveMemoizer()
});
return new Response(context, group(input, _options, context), (result) => {
const merged = {};
result.forEach((group2) => {
if (!merged[group2.label]) {
merged[group2.label] = [];
}
merged[group2.label].push(...group2.elements);
});
return merged;
});
};
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/rate.js
var RATING_VALUES = {
very_bad: 1,
bad: 2,
average: 3,
good: 4,
very_good: 5
};
var _Options5 = exports_exports.object({
tokensPerItem: exports_exports.number().min(1).max(1e5).optional().describe("The maximum number of tokens per item").default(250),
maxItemsPerChunk: exports_exports.number().min(1).max(100).optional().describe("The maximum number of items to rate per chunk").default(50)
});
var END7 = "\u25A0END\u25A0";
var rate = async (input, instructions, _options, ctx) => {
ctx.controller.signal.throwIfAborted();
const options = _Options5.parse(_options ?? {});
const tokenizer2 = await getTokenizer();
const model = await ctx.getModel();
if (input.length === 0) {
return [];
}
const taskId = ctx.taskId;
const taskType = "zai.rate";
const TOKENS_TOTAL_MAX = model.input.maxTokens - PROMPT_INPUT_BUFFER - PROMPT_OUTPUT_BUFFER;
const isStringInstructions = typeof instructions === "string";
const criteriaKeys = isStringInstructions ? [] : Object.keys(instructions);
const generateCriteriaPrompt = isStringInstructions ? `Generate 3-5 evaluation criteria for: "${instructions}"
For each criterion, provide 5 labels (very_bad, bad, average, good, very_good) with brief descriptions.
Output format (JSON):
{
"criterion1_name": {
"very_bad": "description",
"bad": "description",
"average": "description",
"good": "description",
"very_good": "description"
},
"criterion2_name": { ... }
}
Keep criterion names short (1-2 words, lowercase, use underscores).
Keep descriptions brief (5-10 words each).` : `For these evaluation criteria, provide 5 labels (very_bad, bad, average, good, very_good) with brief descriptions for each:
${criteriaKeys.map((key) => `- ${key}: ${instructions[key]}`).join(`
`)}
Output format (JSON):
{
"${criteriaKeys[0]}": {
"very_bad": "description",
"bad": "description",
"average": "description",
"good": "description",
"very_good": "description"
}
${criteriaKeys.length > 1 ? "..." : ""}
}
Keep descriptions brief (5-10 words each).`;
const { extracted: evaluationCriteria } = await ctx.generateContent({
systemPrompt: `You are creating evaluation criteria for rating items on a 1-5 scale.
Each criterion must have exactly 5 labels: very_bad (1), bad (2), average (3), good (4), very_good (5).
Output valid JSON only.`,
messages: [
{
type: "text",
role: "user",
content: generateCriteriaPrompt
}
],
transform: (text2) => {
const jsonMatch = text2.match(/```(?:json)?\s*(\{[\s\S]*?\})\s*```/) || text2.match(/(\{[\s\S]*\})/);
if (!jsonMatch) {
throw new Error("Failed to parse evaluation criteria JSON");
}
return JSON.parse(jsonMatch[1]);
}
});
const finalCriteriaKeys = Object.keys(evaluationCriteria);
if (finalCriteriaKeys.length === 0) {
throw new Error("No evaluation criteria generated");
}
const TOKENS_CRITERIA_MAX = Math.floor(TOKENS_TOTAL_MAX * 0.3);
const TOKENS_ITEMS_MAX = TOKENS_TOTAL_MAX - TOKENS_CRITERIA_MAX;
let chunks = [];
let currentChunk = [];
let currentChunkTokens = 0;
for (const element of input) {
const elementAsString = tokenizer2.truncate(stringify(element, false), options.tokensPerItem);
const elementTokens = tokenizer2.count(elementAsString);
if (currentChunkTokens + elementTokens > TOKENS_ITEMS_MAX || currentChunk.length >= options.maxItemsPerChunk) {
if (currentChunk.length > 0) {
chunks.push(currentChunk);
}
currentChunk = [];
currentChunkTokens = 0;
}
currentChunk.push(element);
currentChunkTokens += elementTokens;
}
if (currentChunk.length > 0) {
chunks.push(currentChunk);
}
chunks = chunks.filter((x) => x.length > 0);
const rateChunk = async (chunk2) => {
ctx.controller.signal.throwIfAborted();
const chunkInputStr = JSON.stringify(chunk2);
const examples = taskId && ctx.adapter ? await ctx.adapter.getExamples({
input: chunkInputStr.slice(0, 1000),
taskType,
taskId
}) : [];
const key = fastHash(stringify({
taskId,
taskType,
input: chunkInputStr,
instructions: stringify(instructions)
}));
const exactMatch = examples.find((x) => x.key === key);
if (exactMatch && exactMatch.output) {
return {
ratings: exactMatch.output,
meta: { cost: { input: 0, output: 0 }, latency: 0, tokens: { input: 0, output: 0 } }
};
}
const formatCriteria = () => {
return finalCriteriaKeys.map((key2) => {
const labels = evaluationCriteria[key2];
return `**${key2}**:
- very_bad (1): ${labels?.very_bad}
- bad (2): ${labels?.bad}
- average (3): ${labels?.average}
- good (4): ${labels?.good}
- very_good (5): ${labels?.very_good}`;
}).join(`
`);
};
const formatItems = (items) => {
return items.map((item, idx) => {
const itemStr = tokenizer2.truncate(stringify(item, false), options.tokensPerItem);
return `\u25A0${idx}: ${itemStr}\u25A0`;
}).join(`
`);
};
const exampleMessages = [];
for (const example of examples.slice(0, 5)) {
try {
const exampleInput = JSON.parse(example.input);
exampleMessages.push({
type: "text",
role: "user",
content: `Expert Example - Items to rate:
${formatItems(Array.isArray(exampleInput) ? exampleInput : [exampleInput])}
Rate each item on all criteria.`
});
const exampleOutput = example.output;
if (Array.isArray(exampleOutput) && exampleOutput.length > 0) {
const formattedRatings = exampleOutput.map((rating, idx) => {
const pairs = finalCriteriaKeys.map((key2) => {
const value = rating[key2];
if (typeof value === "number") {
const labelMap = {
1: "very_bad",
2: "bad",
3: "average",
4: "good",
5: "very_good"
};
return `${key2}=${labelMap[value] || "average"}`;
}
return null;
}).filter(Boolean).join(";");
return `\u25A0${idx}:${pairs}\u25A0`;
}).join(`
`);
exampleMessages.push({
type: "text",
role: "assistant",
content: `${formattedRatings}
${END7}`
});
if (example.explanation) {
exampleMessages.push({
type: "text",
role: "assistant",
content: `Reasoning: ${example.explanation}`
});
}
}
} catch {}
}
const { extracted, meta } = await ctx.generateContent({
systemPrompt: `You are rating items based on evaluation criteria.
Evaluation Criteria:
${formatCriteria()}
For each item, rate it on EACH criterion using one of these labels:
very_bad, bad, average, good, very_good
Output format:
\u25A00:criterion1=label;criterion2=label;criterion3=label\u25A0
\u25A01:criterion1=label;criterion2=label;criterion3=label\u25A0
${END7}
IMPORTANT:
- Rate every item (\u25A00 to \u25A0${chunk2.length - 1})
- Use exact criterion names: ${finalCriteriaKeys.join(", ")}
- Use exact label names: very_bad, bad, average, good, very_good
- Use semicolons (;) between criteria
- Use equals (=) between criterion and label`,
stopSequences: [END7],
messages: [
...exampleMessages,
{
type: "text",
role: "user",
content: `Items to rate (\u25A00 to \u25A0${chunk2.length - 1}):
${formatItems(chunk2)}
Rate each item on all criteria.
Output format: \u25A0index:criterion1=label;criterion2=label\u25A0
${END7}`
}
],
transform: (text2) => {
const results = [];
const regex = /\u25A0(\d+):([^\u25A0]+)\u25A0/g;
let match;
while ((match = regex.exec(text2)) !== null) {
const idx = parseInt(match[1] ?? "", 10);
const ratingsStr = match[2] ?? "";
if (isNaN(idx) || idx < 0 || idx >= chunk2.length) {
continue;
}
const itemRatings = {};
let total = 0;
const pairs = ratingsStr.split(";").filter((x) => x.trim().length > 0);
for (const pair of pairs) {
const [criterion, label2] = pair.split("=").map((x) => x.trim());
if (!criterion || !label2)
continue;
const labelLower = label2.toLowerCase().replace(/\s+/g, "_");
const ratingValue = RATING_VALUES[labelLower] ?? 3;
itemRatings[criterion] = ratingValue;
total += ratingValue;
}
itemRatings.total = total;
results[idx] = itemRatings;
}
for (let i = 0;i < chunk2.length; i++) {
if (!results[i]) {
const defaultRatings = {};
let total = 0;
for (const key2 of finalCriteriaKeys) {
defaultRatings[key2] = 3;
total += 3;
}
defaultRatings.total = total;
results[i] = defaultRatings;
}
}
return results;
}
});
return { ratings: extracted, meta };
};
const limit = pLimit(10);
const chunkPromises = chunks.map((chunk2) => limit(() => rateChunk(chunk2)));
const ratedChunks = await Promise.all(chunkPromises);
const allRatings = ratedChunks.flatMap((result) => result.ratings);
const totalMeta = ratedChunks.reduce((acc, result) => ({
cost: {
input: acc.cost.input + result.meta.cost.input,
output: acc.cost.output + result.meta.cost.output
},
latency: Math.max(acc.latency, result.meta.latency),
tokens: {
input: acc.tokens.input + result.meta.tokens.input,
output: acc.tokens.output + result.meta.tokens.output
}
}), {
cost: { input: 0, output: 0 },
latency: 0,
tokens: { input: 0, output: 0 }
});
if (taskId && ctx.adapter && !ctx.controller.signal.aborted) {
const key = fastHash(stringify({
taskId,
taskType,
input: JSON.stringify(input),
instructions: stringify(instructions)
}));
await ctx.adapter.saveExample({
key,
taskType,
taskId,
input: JSON.stringify(input),
output: allRatings,
instructions: typeof instructions === "string" ? instructions : JSON.stringify(instructions),
metadata: {
cost: {
input: totalMeta.cost.input,
output: totalMeta.cost.output
},
latency: totalMeta.latency,
model: ctx.modelId,
tokens: {
input: totalMeta.tokens.input,
output: totalMeta.tokens.output
}
}
});
}
return allRatings;
};
Zai.prototype.rate = function(input, instructions, _options) {
const context = new ZaiContext({
client: this.client,
modelId: this.Model,
taskId: this.taskId,
taskType: "zai.rate",
adapter: this.adapter,
memoizer: this._resolveMemoizer()
});
return new Response(context, rate(input, instructions, _options, context), (result) => {
if (typeof instructions === "string") {
return result.map((r) => r.total);
}
return result;
});
};
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/sort.js
var _Options6 = exports_exports.object({
tokensPerItem: exports_exports.number().min(1).max(1e5).optional().describe("The maximum number of tokens per item").default(250)
});
var END8 = "\u25A0END\u25A0";
var sort = async (input, instructions, _options, ctx) => {
ctx.controller.signal.throwIfAborted();
const options = _Options6.parse(_options ?? {});
const tokenizer2 = await getTokenizer();
const model = await ctx.getModel();
const taskId = ctx.taskId;
const taskType = "zai.sort";
if (input.length === 0) {
return [];
}
if (input.length === 1) {
return input;
}
const TOKENS_TOTAL_MAX = model.input.maxTokens - PROMPT_INPUT_BUFFER - PROMPT_OUTPUT_BUFFER;
const sampleSize = Math.min(5, input.length);
const sampleItems = input.slice(0, sampleSize);
const sampleItemsText = sampleItems.map((item, idx) => `\u25A0${idx}: ${stringify(item, false)}`).join(`
`);
const criteriaInputStr = JSON.stringify({ instructions, sampleItems });
const criteriaExamples = taskId && ctx.adapter ? await ctx.adapter.getExamples({
input: criteriaInputStr.slice(0, 1000),
taskType,
taskId
}) : [];
const criteriaExampleMessages = [];
for (const example of criteriaExamples.slice(0, 2)) {
try {
const exampleInput = JSON.parse(example.input);
const exampleItems = Array.isArray(exampleInput) ? exampleInput : [exampleInput];
criteriaExampleMessages.push({
type: "text",
role: "user",
content: `Expert Example - Analyze sorting instruction: "${instructions}"
Sample items:
${exampleItems.slice(0, 3).map((el, i) => `\u25A0${i}: ${stringify(el, false).slice(0, 200)}`).join(`
`)}
Generate sorting criteria.`
});
if (example.explanation) {
criteriaExampleMessages.push({
type: "text",
role: "assistant",
content: `${example.explanation}
${END8}`
});
}
} catch {}
}
const generateCriteriaPrompt = `Analyze this sorting instruction: "${instructions}"
Sample items to be sorted:
${sampleItemsText}
Create 1-3 sorting criteria with ordered label arrays (3-10 labels each).
**CRITICAL RULES**:
1. Labels are single words, lowercase, no spaces, use underscores
2. Labels are ordered from FIRST to LAST in sorted result
3. If instruction says "from X to Y": first label represents X, last label represents Y
4. If instruction says "prioritize" or "highest/lowest priority":
- First label = HIGHEST priority (top of todo list)
- Last label = LOWEST priority (bottom of todo list)
Examples:
"from slowest to fastest" \u2192 first=slowest, last=fastest
\u25A0speed\u25A0
very_slow;slow;medium;fast;very_fast
\u25A0END\u25A0
"from most dangerous to least dangerous" \u2192 first=most dangerous, last=least dangerous
\u25A0danger\u25A0
extremely_dangerous;very_dangerous;dangerous;moderate;slightly_dangerous;harmless
\u25A0END\u25A0
"from least urgent (spam) to most urgent (bills)" \u2192 first=spam, last=bills
\u25A0urgency\u25A0
spam;promotional;normal;important;urgent;critical
\u25A0END\u25A0
"prioritize: highest priority=open old tickets; lowest priority=closed" \u2192 first=high priority, last=low priority
\u25A0status\u25A0
open_old;open_recent;closed
\u25A0age\u25A0
oldest;old;recent;new
\u25A0END\u25A0
Output format:
\u25A0criterion_name\u25A0
label1;label2;label3;label4
\u25A0END\u25A0
Use 3-10 labels per criterion. Labels should be intuitive and match the domain.
Keep criterion names short (1-2 words, lowercase, underscores).
`;
const { extracted: sortingCriteria } = await ctx.generateContent({
systemPrompt: `You are creating sorting criteria with ordered label arrays.
CRITICAL: Output ordered labels from FIRST to LAST position in sorted result.
- Labels are single words, lowercase, underscores only
- 3-10 labels per criterion
- Order matters: first label = appears first, last label = appears last`,
messages: [
...criteriaExampleMessages,
{
type: "text",
role: "user",
content: generateCriteriaPrompt
}
],
transform: (text2) => {
const criteria = {};
const criterionRegex = /\u25A0([^\u25A0]+)\u25A0\s*([^\n\u25A0]+)/g;
let match;
while ((match = criterionRegex.exec(text2)) !== null) {
const name = (match[1] ?? "").trim().toLowerCase();
const labelsStr = (match[2] ?? "").trim();
if (!name || name === "end")
continue;
const labels = labelsStr.split(";").map((l) => l.trim().toLowerCase().replace(/\s+/g, "_")).filter((l) => l.length > 0 && l.length < 50);
if (labels.length >= 3 && labels.length <= 10) {
criteria[name] = {
description: `${labels.length} ordered labels`,
labels
};
}
}
if (Object.keys(criteria).length === 0) {
throw new Error(`Failed to parse sorting criteria. LLM output: ${text2.slice(0, 500)}`);
}
return criteria;
}
});
const criteriaKeys = Object.keys(sortingCriteria);
if (criteriaKeys.length === 0) {
throw new Error("No sorting criteria generated");
}
const TOKENS_CRITERIA_MAX = Math.floor(TOKENS_TOTAL_MAX * 0.2);
const TOKENS_ITEMS_MAX = TOKENS_TOTAL_MAX - TOKENS_CRITERIA_MAX;
const MAX_ITEMS_PER_CHUNK = 50;
const elements = input.map((element, idx) => ({
element,
index: idx,
stringified: stringify(element, false)
}));
const chunks = [];
let currentChunk = [];
let currentTokens = 0;
for (const elem of elements) {
const truncated = tokenizer2.truncate(elem.stringified, options.tokensPerItem);
const elemTokens = tokenizer2.count(truncated);
if ((currentTokens + elemTokens > TOKENS_ITEMS_MAX || currentChunk.length >= MAX_ITEMS_PER_CHUNK) && currentChunk.length > 0) {
chunks.push(currentChunk);
currentChunk = [];
currentTokens = 0;
}
currentChunk.push(elem);
currentTokens += elemTokens;
}
if (currentChunk.length > 0) {
chunks.push(currentChunk);
}
const scoreChunk = async (chunk2) => {
ctx.controller.signal.throwIfAborted();
const chunkSize = chunk2.length;
const chunkInputStr = JSON.stringify(chunk2.map((c) => c.element));
const examples = taskId && ctx.adapter ? await ctx.adapter.getExamples({
input: chunkInputStr.slice(0, 1000),
taskType,
taskId
}) : [];
const key = fastHash(stringify({
taskId,
taskType,
input: chunkInputStr,
instructions
}));
const exactMatch = examples.find((x) => x.key === key);
if (exactMatch && exactMatch.output) {
return exactMatch.output;
}
const elementsText = chunk2.map((elem, i) => {
const truncated = tokenizer2.truncate(elem.stringified, options.tokensPerItem);
return `\u25A0${i}: ${truncated}\u25A0`;
}).join(`
`);
const criteriaText = criteriaKeys.map((key2) => {
const criterion = sortingCriteria[key2];
const labelsText = criterion.labels.join(";");
return `**${key2}**: ${labelsText}`;
}).join(`
`);
const exampleMessages = [];
for (const example of examples.slice(0, 3)) {
try {
const exampleInput = JSON.parse(example.input);
const exampleItems = Array.isArray(exampleInput) ? exampleInput : [exampleInput];
exampleMessages.push({
type: "text",
role: "user",
content: `Expert Example - Items to score:
${exampleItems.map((el, i) => `\u25A0${i}: ${stringify(el, false).slice(0, 200)}\u25A0`).join(`
`)}
Score each item.`
});
const exampleOutput = example.output;
if (Array.isArray(exampleOutput) && exampleOutput.length > 0) {
const formattedScores = exampleOutput.map((score) => {
const pairs = criteriaKeys.map((key2) => `${key2}=${score.scores[key2] ?? 0}`).join(";");
return `\u25A0${score.elementIndex}:${pairs}\u25A0`;
}).join(`
`);
exampleMessages.push({
type: "text",
role: "assistant",
content: `${formattedScores}
${END8}`
});
if (example.explanation) {
exampleMessages.push({
type: "text",
role: "assistant",
content: `Reasoning: ${example.explanation}`
});
}
}
} catch {}
}
const { extracted } = await ctx.generateContent({
systemPrompt: `You are ranking items for sorting using ordered label arrays.
${criteriaText}
Instructions: "${instructions}"
SCORING RULES:
- For each item and each criterion, assign ONE label from the ordered list
- Labels are ordered: first label = appears FIRST in sorted result, last label = appears LAST
- Choose the label that best describes each item
Output format:
\u25A00:criterion1=label;criterion2=label\u25A0
\u25A01:criterion1=label;criterion2=label\u25A0
${END8}
IMPORTANT:
- Rank every item (\u25A00 to \u25A0${chunkSize - 1})
- Use exact criterion names: ${criteriaKeys.join(", ")}
- Use exact labels from the lists above (lowercase, underscores)
- Use semicolons (;) between criteria
- Use equals (=) between criterion and label`,
stopSequences: [END8],
messages: [
...exampleMessages,
{
type: "text",
role: "user",
content: `Items to rank (\u25A00 to \u25A0${chunkSize - 1}):
${elementsText}
Rank each item using the labeled scales.
Output format: \u25A0index:criterion1=label;criterion2=label\u25A0
${END8}`
}
],
transform: (text2) => {
const results = [];
const regex = /\u25A0(\d+):([^\u25A0]+)\u25A0/g;
let match;
while ((match = regex.exec(text2)) !== null) {
const idx = parseInt(match[1] ?? "", 10);
const labelsStr = match[2] ?? "";
if (isNaN(idx) || idx < 0 || idx >= chunkSize)
continue;
const scores = {};
let total = 0;
const pairs = labelsStr.split(";").filter((x) => x.trim().length > 0);
for (const pair of pairs) {
const [criterion, labelStr] = pair.split("=").map((x) => x.trim().toLowerCase().replace(/\s+/g, "_"));
if (!criterion || !labelStr)
continue;
const labels = sortingCriteria[criterion]?.labels ?? [];
const labelIndex = labels.findIndex((l) => l === labelStr);
if (labelIndex >= 0) {
scores[criterion] = labelIndex;
total += labelIndex;
} else {
const middleIndex = labels.length > 0 ? Math.floor(labels.length / 2) : 5;
scores[criterion] = middleIndex;
total += middleIndex;
}
}
results[idx] = {
elementIndex: chunk2[idx].index,
scores,
totalScore: total
};
}
for (let i = 0;i < chunkSize; i++) {
if (!results[i]) {
const scores = {};
let total = 0;
for (const key2 of criteriaKeys) {
const labels = sortingCriteria[key2]?.labels ?? [];
const middleIndex = labels.length > 0 ? Math.floor(labels.length / 2) : 5;
scores[key2] = middleIndex;
total += middleIndex;
}
results[i] = {
elementIndex: chunk2[i].index,
scores,
totalScore: total
};
}
}
return results;
}
});
return extracted;
};
const limit = pLimit(10);
const chunkPromises = chunks.map((chunk2) => limit(() => scoreChunk(chunk2)));
const allScores = await Promise.all(chunkPromises);
const scoreMap = /* @__PURE__ */ new Map;
for (const chunkScores of allScores) {
for (const itemScore of chunkScores) {
const existing = scoreMap.get(itemScore.elementIndex);
if (existing) {
for (const key of criteriaKeys) {
existing.scores[key] = (existing.scores[key] + (itemScore.scores[key] ?? 0)) / 2;
}
existing.totalScore = (existing.totalScore + itemScore.totalScore) / 2;
} else {
scoreMap.set(itemScore.elementIndex, {
scores: { ...itemScore.scores },
totalScore: itemScore.totalScore
});
}
}
}
if (scoreMap.size !== input.length) {
throw new Error(`Score map size mismatch: expected ${input.length}, got ${scoreMap.size}`);
}
const scoreGroups = /* @__PURE__ */ new Map;
for (const [index, scoreData] of scoreMap.entries()) {
const roundedScore = Math.round(scoreData.totalScore * 100);
const group2 = scoreGroups.get(roundedScore) ?? [];
group2.push(index);
scoreGroups.set(roundedScore, group2);
}
const tiedGroups = Array.from(scoreGroups.values()).filter((group2) => group2.length > 1);
if (tiedGroups.length > 0) {
const tieBreakLimit = pLimit(10);
await Promise.all(tiedGroups.map((tiedIndices) => tieBreakLimit(async () => {
if (tiedIndices.length <= 1)
return;
const tiedElements = tiedIndices.map((idx) => elements[idx]);
const tieBreakText = tiedElements.map((elem, i) => {
const truncated = tokenizer2.truncate(elem.stringified, options.tokensPerItem);
return `\u25A0${i}: ${truncated}\u25A0`;
}).join(`
`);
const tieBreakInputStr = JSON.stringify(tiedElements.map((e) => e.element));
const tieBreakExamples = taskId && ctx.adapter ? await ctx.adapter.getExamples({
input: tieBreakInputStr.slice(0, 1000),
taskType,
taskId
}) : [];
const tieBreakExampleMessages = [];
for (const example of tieBreakExamples.slice(0, 3)) {
try {
const exampleInput = JSON.parse(example.input);
const exampleItems = Array.isArray(exampleInput) ? exampleInput : [exampleInput];
tieBreakExampleMessages.push({
type: "text",
role: "user",
content: `Expert Example - Items to order:
${exampleItems.map((el, i) => `\u25A0${i}: ${stringify(el, false).slice(0, 200)}\u25A0`).join(`
`)}
Order them from first to last.`
});
if (Array.isArray(example.output) && example.output.length > 0) {
const formattedOrder = example.output.map((_, i) => `\u25A0${i}\u25A0`).join(`
`);
tieBreakExampleMessages.push({
type: "text",
role: "assistant",
content: `${formattedOrder}
${END8}`
});
if (example.explanation) {
tieBreakExampleMessages.push({
type: "text",
role: "assistant",
content: `Reasoning: ${example.explanation}`
});
}
}
} catch {}
}
const { extracted: tieBreakOrder } = await ctx.generateContent({
systemPrompt: `You are breaking a tie between items with identical total scores.
Instructions: ${instructions}
Criteria:
${criteriaKeys.map((key) => {
const labels = sortingCriteria[key].labels.join(";");
return `- ${key}: ${labels}`;
}).join(`
`)}
Order these ${tiedElements.length} items from FIRST to LAST based on the instructions.
Earlier labels in each criterion should come FIRST.
Output format:
\u25A0original_index\u25A0
\u25A0original_index\u25A0
${END8}
Output the indices in the order they should appear (first item at top).`,
stopSequences: [END8],
messages: [
...tieBreakExampleMessages,
{
type: "text",
role: "user",
content: `Items with identical scores (need tie-breaking):
${tieBreakText}
Order them from first to last.
Output format: \u25A0index\u25A0 (one per line)
${END8}`
}
],
transform: (text2) => {
const order = [];
const regex = /\u25A0(\d+)\u25A0/g;
let match;
while ((match = regex.exec(text2)) !== null) {
const idx = parseInt(match[1] ?? "", 10);
if (!isNaN(idx) && idx >= 0 && idx < tiedElements.length) {
order.push(idx);
}
}
for (let i = 0;i < tiedElements.length; i++) {
if (!order.includes(i)) {
order.push(i);
}
}
return order;
}
});
for (let i = 0;i < tieBreakOrder.length; i++) {
const elementIndex = tiedElements[tieBreakOrder[i]].index;
const scoreData = scoreMap.get(elementIndex);
if (scoreData) {
scoreData.tieBreakOrder = i;
}
}
})));
}
const sorted = Array.from(scoreMap.entries()).sort((a, b) => {
const scoreDiff = a[1].totalScore - b[1].totalScore;
if (scoreDiff !== 0)
return scoreDiff;
const orderA = a[1].tieBreakOrder ?? 0;
const orderB = b[1].tieBreakOrder ?? 0;
return orderA - orderB;
}).map(([index]) => elements[index].element);
const result = sorted;
if (taskId && ctx.adapter && !ctx.controller.signal.aborted) {
const key = fastHash(stringify({
taskId,
taskType,
input: JSON.stringify(input),
instructions
}));
await ctx.adapter.saveExample({
key,
taskType,
taskId,
input: JSON.stringify(input),
output: result,
instructions,
metadata: {
cost: { input: 0, output: 0 },
latency: 0,
model: ctx.modelId,
tokens: { input: 0, output: 0 }
}
});
}
return result;
};
Zai.prototype.sort = function(input, instructions, _options) {
const context = new ZaiContext({
client: this.client,
modelId: this.Model,
taskId: this.taskId,
taskType: "zai.sort",
adapter: this.adapter,
memoizer: this._resolveMemoizer()
});
return new Response(context, sort(input, instructions, _options, context), (result) => result);
};
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/answer.js
var _Options7 = exports_exports.object({
examples: exports_exports.array(exports_exports.any()).default([]).describe("Examples to help guide answer generation"),
instructions: exports_exports.string().optional().describe("Additional instructions for answer generation"),
chunkLength: exports_exports.number().min(250).max(1e5).optional().describe("Maximum number of tokens per document chunk").default(16000),
maxRefinementPasses: exports_exports.number().min(1).max(10).optional().describe("Maximum number of refinement iterations when merging chunked results").default(3)
});
var ANSWER_START = "\u25A0answer";
var AMBIGUOUS_START = "\u25A0ambiguous";
var OUT_OF_TOPIC_START = "\u25A0out_of_topic";
var INVALID_QUESTION_START = "\u25A0invalid_question";
var MISSING_KNOWLEDGE_START = "\u25A0missing_knowledge";
var END9 = "\u25A0end\u25A0";
var formatDocumentsWithLineNumbers = (documents) => {
const mappings = [];
const allLines = [];
let globalLineNumber = 1;
let totalLines = 0;
documents.forEach((doc) => {
const docString = stringify(doc);
const lines = docString.split(`
`);
totalLines += lines.length;
});
const padding = Math.max(3, totalLines.toString().length);
documents.forEach((doc, docIndex) => {
const docString = stringify(doc);
const lines = docString.split(`
`);
lines.forEach((line, lineInDoc) => {
const paddedNumber = globalLineNumber.toString().padStart(padding, "0");
const formattedLine = `\u25A0${paddedNumber} | ${line}`;
allLines.push(formattedLine);
mappings.push({
lineNumber: globalLineNumber,
documentIndex: docIndex,
lineInDocument: lineInDoc,
text: line,
document: doc
});
globalLineNumber++;
});
});
return {
formatted: allLines.join(`
`),
mappings
};
};
var parseCitations = (answerText, mappings) => {
const citations = [];
const citationPattern = /\u25A0(\d+)(?:-(\d+))?/g;
let match;
const processedRanges = /* @__PURE__ */ new Set;
let cleanAnswer = answerText;
let offsetAdjustment = 0;
while ((match = citationPattern.exec(answerText)) !== null) {
const fullMatch = match[0];
const offset = match.index - offsetAdjustment;
const startLine = parseInt(match[1], 10);
const endLine = match[2] ? parseInt(match[2], 10) : startLine;
const rangeKey = `${offset}:${startLine}-${endLine}`;
if (processedRanges.has(rangeKey)) {
continue;
}
processedRanges.add(rangeKey);
const lineNumbers = [];
for (let i = startLine;i <= endLine; i++) {
lineNumbers.push(i);
}
const relevantMappings = mappings.filter((m) => lineNumbers.includes(m.lineNumber));
if (relevantMappings.length > 0) {
const documentMap = /* @__PURE__ */ new Map;
relevantMappings.forEach((mapping) => {
const existing = documentMap.get(mapping.document) || [];
existing.push(mapping.text);
documentMap.set(mapping.document, existing);
});
documentMap.forEach((lines, document) => {
citations.push({
offset,
item: document,
snippet: lines.join(`
`)
});
});
}
cleanAnswer = cleanAnswer.slice(0, offset) + cleanAnswer.slice(offset + fullMatch.length);
offsetAdjustment += fullMatch.length;
}
return {
cleanAnswer: cleanAnswer.trim(),
citations: citations.sort((a, b) => a.offset - b.offset)
};
};
var processSingleChunk = async (formattedDocs, mappings, question, options, ctx) => {
ctx.controller.signal.throwIfAborted();
const result = await callLLM(formattedDocs, question, options, mappings, ctx);
ctx.controller.signal.throwIfAborted();
return result;
};
var processMultipleChunks = async (documents, question, chunkTokenLimit, options, ctx) => {
const tokenizer2 = await getTokenizer();
const chunks = [];
let currentChunk = [];
let currentTokens = 0;
for (const doc of documents) {
const docString = stringify(doc);
const docTokens = tokenizer2.count(docString);
if (currentTokens + docTokens > chunkTokenLimit && currentChunk.length > 0) {
chunks.push([...currentChunk]);
currentChunk = [doc];
currentTokens = docTokens;
} else {
currentChunk.push(doc);
currentTokens += docTokens;
}
}
if (currentChunk.length > 0) {
chunks.push(currentChunk);
}
const processChunk = async (chunk2) => {
ctx.controller.signal.throwIfAborted();
const { formatted, mappings } = formatDocumentsWithLineNumbers(chunk2);
const result = await callLLM(formatted, question, options, mappings, ctx);
ctx.controller.signal.throwIfAborted();
return result;
};
const limit = pLimit(10);
const chunkResults = await Promise.all(chunks.map((chunk2) => limit(() => processChunk(chunk2))));
ctx.controller.signal.throwIfAborted();
return mergeChunkResults(chunkResults, question, chunkTokenLimit, options, ctx);
};
var mergeChunkResults = async (results, question, chunkTokenLimit, options, ctx) => {
ctx.controller.signal.throwIfAborted();
const answers = results.filter((r) => r.type === "answer");
if (answers.length === 0) {
const nonAnswer = results.find((r) => r.type !== "answer");
return nonAnswer || { type: "missing_knowledge", reason: "No relevant information found in documents." };
}
if (answers.length === 1) {
return answers[0];
}
const citedDocs = /* @__PURE__ */ new Set;
answers.forEach((answer2) => {
answer2.citations.forEach((citation) => {
citedDocs.add(citation.item);
});
});
const citedDocsArray = Array.from(citedDocs);
const tokenizer2 = await getTokenizer();
const { formatted, mappings } = formatDocumentsWithLineNumbers(citedDocsArray);
if (tokenizer2.count(formatted) <= chunkTokenLimit) {
return await callLLM(formatted, question, options, mappings, ctx);
}
return answers.reduce((best, current) => current.citations.length > best.citations.length ? current : best);
};
var callLLM = async (formattedDocs, question, options, mappings, ctx) => {
const systemPrompt = `You are an expert research assistant specialized in answering questions using only the information provided in documents.
# Task
Answer the user's question based ONLY on the information in the provided documents. You MUST cite your sources using line numbers.
# Document Format
Documents are provided with line numbers:
\u25A0001 | First line of text
\u25A0002 | Second line of text
\u25A0003 | Third line of text
# Citation Format
You MUST include citations immediately after statements. Use these formats:
- Single line: \u25A0035
- Range: \u25A0005-010
- Multiple: \u25A0035\u25A0046\u25A0094
# Response Format
Choose ONE of these response types:
**TYPE 1 - ANSWER** (Use this when you can answer the question)
\u25A0answer
[Your answer with inline citations\u25A0001-003. Make sure each part is cited correctly\u25A0013. More text. \u25A0015]
\u25A0end\u25A0
**TYPE 2 - AMBIGUOUS** (Use when the question has multiple valid interpretations)
\u25A0ambiguous
[Explain the ambiguity]
\u25A0follow_up
[Ask a clarifying question]
\u25A0answer
[First interpretation with citations \u25A0001 and part 2 as well.\u25A0002]
\u25A0answer
[Second interpretation with citations \u25A0005 and part 2 of the answer.\u25A0006]
\u25A0end\u25A0
**TYPE 3 - OUT OF TOPIC** (Use when question is completely unrelated to documents)
\u25A0out_of_topic
[Explain why it's unrelated]
\u25A0end\u25A0
**TYPE 4 - INVALID QUESTION** (Use when input is not a proper question, e.g., gibberish, malformed or nonsensical)
\u25A0invalid_question
[Explain why it's invalid, e.g., "The question is incomplete" or "The question contains nonsensical terms", or "Received gibberish"]
\u25A0end\u25A0
**TYPE 5 - MISSING KNOWLEDGE** (Use ONLY when documents lack specific details needed)
\u25A0missing_knowledge
[Explain what specific information is missing]
\u25A0end\u25A0
# Important Rules
- PREFER answering when possible - only use missing_knowledge if truly no relevant info exists
- ALWAYS cite sources with line numbers
- Use ONLY information from the documents
- Be precise and factual
- Do NOT fabricate information
- Do NOT mention "According to the documents" or similar phrases \u2013 just provide a high-quality answer with citations
- Do not be too strict on the question format; assume high-level answers are acceptable unless the question clearly asks for very specific details or requests depth beyond the documents
# Additional Instructions
Here are some additional instructions to follow about how to answer the question:
${options.instructions || "Provide a clear and concise answer based on the documents."}`;
const userPrompt = `<documents>
${formattedDocs}
</documents>
Please answer the below question using the format specified above.
Question to answer: "${question}"`;
const { extracted } = await ctx.generateContent({
reasoningEffort: "none",
systemPrompt,
stopSequences: [END9],
messages: [
{
type: "text",
role: "user",
content: userPrompt
}
],
transform: (text2) => {
text2 = text2.slice(0, text2.lastIndexOf(END9.slice(0, -1)));
return parseResponse(text2 || "", mappings);
}
});
return extracted;
};
var parseResponse = (response, mappings) => {
const text2 = response.trim();
const answersCount = (text2.match(new RegExp(ANSWER_START, "g")) || []).length;
if (text2.includes(AMBIGUOUS_START) || answersCount >= 2) {
return parseAmbiguousResponse(text2, mappings);
} else if (text2.includes(ANSWER_START)) {
return parseAnswerResponse(text2, mappings);
} else if (text2.includes(OUT_OF_TOPIC_START)) {
return parseOutOfTopicResponse(text2);
} else if (text2.includes(INVALID_QUESTION_START)) {
return parseInvalidQuestionResponse(text2);
} else if (text2.includes(MISSING_KNOWLEDGE_START)) {
return parseMissingKnowledgeResponse(text2);
}
return {
type: "missing_knowledge",
reason: "Unable to determine response type from the model output."
};
};
var parseAnswerResponse = (text2, mappings) => {
const answerMatch = text2.match(new RegExp(`${ANSWER_START}(.+)$`, "s"));
if (!answerMatch) {
return {
type: "missing_knowledge",
reason: "Could not extract answer from response."
};
}
const answerText = answerMatch[1].trim();
const { cleanAnswer, citations } = parseCitations(answerText, mappings);
if (citations.length === 0) {
throw new Error("Answer must include citations using the \u25A0XXX format (e.g., \u25A0001, \u25A0001-005). Every statement should be backed by a citation to the source documents.");
}
return {
type: "answer",
answer: cleanAnswer,
citations
};
};
var parseAmbiguousResponse = (text2, mappings) => {
const ambiguityMatch = text2.match(new RegExp(`${AMBIGUOUS_START}(.+?)\u25A0follow_up`, "s"));
const ambiguity = ambiguityMatch ? ambiguityMatch[1].trim() : "The question has multiple interpretations.";
const followUpMatch = text2.match(/\u25A0follow_up(.+?)\u25A0answer/s);
const follow_up = followUpMatch ? followUpMatch[1].trim() : "Please clarify your question.";
const answerPattern = /\u25A0answer(.+?)(?=\u25A0answer|$)/gs;
const answers = [];
let match;
while ((match = answerPattern.exec(text2)) !== null) {
const answerText = match[1].trim();
const { cleanAnswer, citations } = parseCitations(answerText, mappings);
answers.push({ answer: cleanAnswer, citations });
}
const answersWithoutCitations = answers.filter((a) => a.citations.length === 0);
if (answersWithoutCitations.length > 0) {
throw new Error("Each answer in an ambiguous response must include citations using the \u25A0XXX format (e.g., \u25A0001, \u25A0001-005). Every statement should be backed by a citation to the source documents.");
}
return {
type: "ambiguous",
ambiguity,
follow_up,
answers: answers.length >= 2 ? answers.slice(0, 3) : answers
};
};
var parseOutOfTopicResponse = (text2) => {
const reasonMatch = text2.match(new RegExp(`${OUT_OF_TOPIC_START}(.+)$`, "s"));
const reason = reasonMatch ? reasonMatch[1].trim() : "The question is not related to the provided documents.";
return {
type: "out_of_topic",
reason
};
};
var parseInvalidQuestionResponse = (text2) => {
const reasonMatch = text2.match(new RegExp(`${INVALID_QUESTION_START}(.+)$`, "s"));
const reason = reasonMatch ? reasonMatch[1].trim() : "The question is invalid or malformed.";
return {
type: "invalid_question",
reason
};
};
var parseMissingKnowledgeResponse = (text2) => {
const reasonMatch = text2.match(new RegExp(`${MISSING_KNOWLEDGE_START}(.+)$`, "s"));
const reason = reasonMatch ? reasonMatch[1].trim() : "The documents do not contain sufficient information to answer the question.";
return {
type: "missing_knowledge",
reason
};
};
var answer = async (documents, question, options, ctx) => {
ctx.controller.signal.throwIfAborted();
if (documents.length === 0) {
return {
type: "missing_knowledge",
reason: "No documents provided to answer the question."
};
}
if (!question || question.trim().length === 0) {
return {
type: "invalid_question",
reason: "The question is empty or contains no content."
};
}
const tokenizer2 = await getTokenizer();
const model = await ctx.getModel();
const TOTAL_MAX_TOKENS = Math.min(options.chunkLength, model.input.maxTokens - PROMPT_INPUT_BUFFER);
const { formatted: allFormattedDocs, mappings: allMappings } = formatDocumentsWithLineNumbers(documents);
const CHUNK_DOC_TOKENS = Math.floor(TOTAL_MAX_TOKENS * 0.6);
const totalDocTokens = tokenizer2.count(allFormattedDocs);
if (totalDocTokens <= CHUNK_DOC_TOKENS) {
return await processSingleChunk(allFormattedDocs, allMappings, question, options, ctx);
} else {
return await processMultipleChunks(documents, question, CHUNK_DOC_TOKENS, options, ctx);
}
};
Zai.prototype.answer = function(documents, question, _options) {
const parse = _Options7.safeParse(_options ?? {});
const context = new ZaiContext({
client: this.client,
modelId: this.Model,
taskId: this.taskId,
taskType: "zai.answer",
adapter: this.adapter,
memoizer: this._resolveMemoizer()
});
if (!parse.success) {
return Response.reject(context, new Error(`Invalid options: ${parse.error.message}`));
}
return new Response(context, answer(documents, question, parse.data, context), (result) => result);
};
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/json-utils.js
function isJsonFile(path, name) {
return path.endsWith(".json") || name.endsWith(".json");
}
function tryParseJson(content) {
try {
const data = JSON.parse(content);
return { valid: true, data };
} catch (err) {
return { valid: false, error: err instanceof Error ? err.message : String(err) };
}
}
function repairJson(content) {
try {
const repaired = jsonrepair(content);
JSON.parse(repaired);
return repaired;
} catch {
return null;
}
}
function formatError(content, rawError) {
const lines = content.split(/\r?\n/);
let errorLine = null;
let errorCol = null;
const posMatch = rawError.match(/at position (\d+)/);
if (posMatch) {
const position = parseInt(posMatch[1], 10);
let offset = 0;
for (let i = 0;i < lines.length; i++) {
const lineLen = lines[i].length + 1;
if (offset + lineLen > position) {
errorLine = i;
errorCol = position - offset;
break;
}
offset += lineLen;
}
}
let out = `JSON Syntax Error: ${rawError}
`;
const contextRadius = 3;
const startLine = errorLine !== null ? Math.max(0, errorLine - contextRadius) : 0;
const endLine = errorLine !== null ? Math.min(lines.length - 1, errorLine + contextRadius) : lines.length - 1;
const padWidth = String(endLine + 1).length;
for (let i = startLine;i <= endLine; i++) {
const lineNum = String(i + 1).padStart(padWidth, " ");
const marker = i === errorLine ? " \u2190 ERROR" : "";
out += `${lineNum}|${lines[i]}${marker}
`;
if (i === errorLine && errorCol !== null) {
out += `${" ".repeat(padWidth + 1 + errorCol)}^
`;
}
}
return out;
}
function validateOrRepairJson(content) {
const parsed = tryParseJson(content);
if (parsed.valid === false) {
const repaired = repairJson(content);
if (repaired !== null) {
return { valid: true, data: JSON.parse(repaired), repaired: true, content: repaired };
}
return { valid: false, error: formatError(content, parsed.error) };
}
return { valid: true, data: parsed.data, repaired: false, content };
}
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/micropatch.js
class Micropatch {
_text;
_eol;
constructor(source, eol) {
this._text = source;
this._eol = eol ?? Micropatch.detectEOL(source);
}
getText() {
return this._text;
}
setText(source, eol) {
this._text = source;
this._eol = eol ?? Micropatch.detectEOL(source);
}
apply(opsText) {
const ops = Micropatch.parseOps(opsText);
this._text = Micropatch._applyOps(this._text, ops, this._eol);
return this._text;
}
renderNumberedView() {
const NL = this._eol === "lf" ? `
` : `\r
`;
const lines = Micropatch._splitEOL(this._text);
return lines.map((l, i) => `${String(i + 1).padStart(3, "0")}|${l}`).join(NL);
}
static detectEOL(source) {
return /\r\n/.test(source) ? "crlf" : "lf";
}
static _splitEOL(text2) {
const parts = text2.split(/\r?\n/);
return parts;
}
static _joinEOL(lines, eol) {
const NL = eol === "lf" ? `
` : `\r
`;
return lines.join(NL);
}
static _unescapeMarker(s) {
return s.replace(/\\\u25FC\uFE0E/g, "\u25FC\uFE0E");
}
static parseOps(opsText) {
const lines = opsText.split(/\r?\n/);
const ops = [];
const headerRe = /^\u25FC\uFE0E([<>=-])(\d+)(?:-(\d+))?(?:\|(.*))?$/;
let i = 0;
while (i < lines.length) {
const line = lines[i];
if (!line) {
i++;
continue;
}
if (!line.startsWith("\u25FC\uFE0E")) {
i++;
continue;
}
const m = headerRe.exec(line);
if (!m || !m[1] || !m[2]) {
throw new Error(`Invalid op syntax at line ${i + 1}: ${line}`);
}
const op = m[1];
const aNum = parseInt(m[2], 10);
const bNum = m[3] ? parseInt(m[3], 10) : undefined;
const firstPayload = (m[4] ?? "").replace(/^\|\|/, "|");
if (aNum < 1 || bNum !== undefined && bNum < aNum) {
throw new Error(`Invalid line/range at line ${i + 1}: ${line}`);
}
if (op === "<" || op === ">") {
if (bNum !== undefined) {
throw new Error(`Insert cannot target a range (line ${i + 1})`);
}
const text2 = Micropatch._unescapeMarker(firstPayload);
ops.push({ k: op, n: aNum, s: text2 });
i++;
continue;
}
if (op === "-") {
if (firstPayload !== "") {
throw new Error(`Delete must not have a payload (line ${i + 1})`);
}
if (bNum === undefined) {
ops.push({ k: "-", n: aNum });
} else {
ops.push({ k: "--", a: aNum, b: bNum });
}
i++;
continue;
}
if (op === "=") {
const payload = [Micropatch._unescapeMarker(firstPayload)];
let j = i + 1;
while (j < lines.length) {
const nextLine = lines[j];
if (nextLine.startsWith("\u25FC\uFE0E"))
break;
payload.push(Micropatch._unescapeMarker(nextLine));
j++;
}
if (bNum === undefined) {
ops.push({ k: "=", n: aNum, s: payload });
} else {
ops.push({ k: "=-", a: aNum, b: bNum, s: payload });
}
i = j;
continue;
}
i++;
}
return Micropatch._canonicalizeOrder(ops);
}
static _canonicalizeOrder(ops) {
const delS = [];
const delR = [];
const eqS = [];
const eqR = [];
const insB = [];
const insA = [];
for (const o of ops) {
switch (o.k) {
case "-":
delS.push(o);
break;
case "--":
delR.push(o);
break;
case "=":
eqS.push(o);
break;
case "=-":
eqR.push(o);
break;
case "<":
insB.push(o);
break;
case ">":
insA.push(o);
break;
default:
break;
}
}
delS.sort((a, b) => b.n - a.n);
delR.sort((a, b) => b.a - a.a);
eqS.sort((a, b) => a.n - b.n);
eqR.sort((a, b) => a.a - b.a);
insB.sort((a, b) => a.n - b.n);
insA.sort((a, b) => a.n - b.n);
return [].concat(delS, delR, eqS, eqR, insB, insA);
}
static _applyOps(source, ops, eol) {
const lines = Micropatch._splitEOL(source);
const idx = Array.from({ length: lines.length }, (_, i) => i);
const map = (n) => idx[n - 1] ?? -1;
const bump = (from, delta) => {
for (let i = 0;i < idx.length; i++) {
const current = idx[i];
if (current !== undefined && current >= from) {
idx[i] = current + delta;
}
}
};
for (const o of ops) {
switch (o.k) {
case "-": {
const i = map(o.n);
if (i >= 0 && i < lines.length) {
lines.splice(i, 1);
bump(i, -1);
}
break;
}
case "--": {
const a = map(o.a);
const b = map(o.b);
if (a >= 0 && b >= a && b < lines.length) {
lines.splice(a, b - a + 1);
bump(a, -(b - a + 1));
}
break;
}
case "=": {
const i = map(o.n);
if (i >= 0 && i < lines.length) {
const rep = o.s;
lines.splice(i, 1, ...rep);
bump(i + 1, rep.length - 1);
}
break;
}
case "=-": {
const a = map(o.a);
const b = map(o.b);
if (a >= 0 && b >= a && b < lines.length) {
const rep = o.s;
lines.splice(a, b - a + 1, ...rep);
bump(a + 1, rep.length - (b - a + 1));
}
break;
}
case "<": {
const i = Math.max(0, Math.min(map(o.n), lines.length));
if (i >= 0) {
lines.splice(i, 0, o.s);
bump(i, 1);
}
break;
}
case ">": {
const i = Math.max(0, Math.min(map(o.n) + 1, lines.length));
if (i >= 0) {
lines.splice(i, 0, o.s);
bump(i, 1);
}
break;
}
default:
break;
}
}
return Micropatch._joinEOL(lines, eol);
}
static applyText(source, opsText, eol) {
const inst = new Micropatch(source, eol);
return inst.apply(opsText);
}
static validate(opsText) {
const ops = Micropatch.parseOps(opsText);
return { ok: true, count: ops.length };
}
}
// ../../node_modules/.bun/@botpress+zai@2.8.0+dd6e58fd1a87f12b/node_modules/@botpress/zai/dist/operations/patch.js
var _File = exports_exports.object({
path: exports_exports.string(),
name: exports_exports.string(),
content: exports_exports.string()
});
var INVALID_SCHEMA_ERROR2 = "zai.patch only accepts schemas created with @bpinternal/zui";
var Options5 = exports_exports.object({
maxTokensPerChunk: exports_exports.number().optional()
});
var patch = async (files, instructions, _options, ctx) => {
ctx.controller.signal.throwIfAborted();
const options = { ...Options5.parse(_options ?? {}), schema: _options?.schema };
let zSchema = null;
if (options.schema) {
if (!exports_exports.is.zuiType(options.schema)) {
throw new Error(INVALID_SCHEMA_ERROR2);
}
zSchema = options.schema;
}
if (files.length === 0) {
return [];
}
const tokenizer2 = await getTokenizer();
const model = await ctx.getModel();
const taskId = ctx.taskId;
const taskType = "zai.patch";
const TOKENS_TOTAL_MAX = model.input.maxTokens - PROMPT_INPUT_BUFFER - PROMPT_OUTPUT_BUFFER;
const TOKENS_INSTRUCTIONS_MAX = Math.floor(TOKENS_TOTAL_MAX * 0.2);
const TOKENS_FILES_MAX = TOKENS_TOTAL_MAX - TOKENS_INSTRUCTIONS_MAX;
const truncatedInstructions = tokenizer2.truncate(instructions, TOKENS_INSTRUCTIONS_MAX);
const maxTokensPerChunk = options.maxTokensPerChunk ?? TOKENS_FILES_MAX;
const fileTokenCounts = files.map((file) => ({
file,
tokens: tokenizer2.count(file.content),
lines: file.content.split(/\r?\n/).length
}));
const totalInputTokens = fileTokenCounts.reduce((sum, f) => sum + f.tokens, 0);
const splitFileIntoChunks = (file, totalLines, fileTokens) => {
const lines = file.content.split(/\r?\n/);
const tokensPerLine = fileTokens / totalLines;
const linesPerChunk = Math.floor(maxTokensPerChunk / tokensPerLine);
if (linesPerChunk >= totalLines) {
return [
{
path: file.path,
name: file.name,
content: file.content,
startLine: 1,
endLine: totalLines,
totalLines,
isPartial: false
}
];
}
const chunks = [];
for (let start = 0;start < totalLines; start += linesPerChunk) {
const end = Math.min(start + linesPerChunk, totalLines);
const chunkLines = lines.slice(start, end);
const chunkContent = chunkLines.join(`
`);
chunks.push({
path: file.path,
name: file.name,
content: chunkContent,
startLine: start + 1,
endLine: end,
totalLines,
isPartial: true
});
}
return chunks;
};
const createBatches = (chunks) => {
const batches2 = [];
let currentBatch = { items: [], tokenCount: 0 };
for (const chunk2 of chunks) {
const chunkTokens = tokenizer2.count(chunk2.content);
if (currentBatch.tokenCount + chunkTokens > maxTokensPerChunk && currentBatch.items.length > 0) {
batches2.push(currentBatch);
currentBatch = { items: [], tokenCount: 0 };
}
currentBatch.items.push(chunk2);
currentBatch.tokenCount += chunkTokens;
}
if (currentBatch.items.length > 0) {
batches2.push(currentBatch);
}
return batches2;
};
const formatChunksForInput = (chunks) => {
return chunks.map((chunk2) => {
const lines = chunk2.content.split(/\r?\n/);
const numberedView = lines.map((line, idx) => {
const lineNum = chunk2.startLine + idx;
return `${String(lineNum).padStart(3, "0")}|${line}`;
}).join(`
`);
const partialNote = chunk2.isPartial ? ` (PARTIAL: lines ${chunk2.startLine}-${chunk2.endLine} of ${chunk2.totalLines} total lines)` : "";
return `<FILE path="${chunk2.path}" name="${chunk2.name}"${partialNote}>
${numberedView}
</FILE>`;
}).join(`
`);
};
const parsePatchOutput = (output) => {
const patchMap = /* @__PURE__ */ new Map;
const fileBlockRegex = /<FILE[^>]*path="([^"]+)"[^>]*>([\s\S]*?)<\/FILE>/g;
let match;
while ((match = fileBlockRegex.exec(output)) !== null) {
const filePath = match[1];
const patchOps = match[2].trim();
patchMap.set(filePath, patchOps);
}
return patchMap;
};
const ensureValidJson = (content) => {
const result = validateOrRepairJson(content);
if (result.valid) {
return result.content;
}
return null;
};
const applyPatchToFile = async (file, patchOps) => {
if (!patchOps || patchOps.trim().length === 0) {
return { ...file, patch: "" };
}
let patchedContent;
try {
patchedContent = Micropatch.applyText(file.content, patchOps);
} catch (error) {
console.error(`Failed to apply patch to ${file.path}:`, error);
return { ...file, patch: `ERROR: ${error instanceof Error ? error.message : String(error)}` };
}
const jsonMode = isJsonFile(file.path, file.name);
if (!jsonMode) {
return { ...file, content: patchedContent, patch: patchOps };
}
const originalParse = validateOrRepairJson(file.content);
if (!originalParse.valid) {
return { ...file, content: patchedContent, patch: patchOps };
}
const validContent = ensureValidJson(patchedContent);
if (validContent === null) {
return retryJsonPatch(file, patchedContent);
}
if (zSchema) {
const parsed = JSON.parse(validContent);
const safe = zSchema.safeParse(parsed);
if (!safe.success) {
return retrySchemaValidation(file, validContent, safe.error);
}
}
return { ...file, content: validContent, patch: patchOps };
};
const retryJsonPatch = async (file, brokenContent) => {
const parseResult = validateOrRepairJson(brokenContent);
const errorMessage = parseResult.error;
const brokenChunk = {
path: file.path,
name: file.name,
content: brokenContent,
startLine: 1,
endLine: brokenContent.split(/\r?\n/).length,
totalLines: brokenContent.split(/\r?\n/).length,
isPartial: false
};
const brokenFileInput = formatChunksForInput([brokenChunk]);
const { extracted } = await ctx.generateContent({
systemPrompt: getMicropatchSystemPrompt(),
messages: [
{
type: "text",
role: "user",
content: [
"The following JSON file has syntax errors. The original instructions were:",
truncatedInstructions,
"",
"Here is the broken result:",
"",
brokenFileInput,
"",
`JSON parse error: ${errorMessage}`,
"",
"Fix ONLY the JSON syntax errors (missing commas, orphaned braces, etc). Do NOT change the data \u2014 only fix the syntax to make it valid JSON."
].join(`
`)
}
],
stopSequences: [],
transform: (text2) => (text2 ?? "").trim()
});
const retryPatchMap = parsePatchOutput(extracted);
const retryPatchOps = retryPatchMap.get(file.path);
if (!retryPatchOps || retryPatchOps.trim().length === 0) {
throw new Error(`JSON patch retry for "${file.path}" produced no patches.
${errorMessage}`);
}
try {
const retryContent = Micropatch.applyText(brokenContent, retryPatchOps);
const validContent = ensureValidJson(retryContent);
if (validContent !== null) {
if (zSchema) {
const parsed = JSON.parse(validContent);
const safe = zSchema.safeParse(parsed);
if (!safe.success) {
return retrySchemaValidation(file, validContent, safe.error);
}
}
return { ...file, content: validContent, patch: retryPatchOps };
}
} catch {}
throw new Error(`JSON patch retry for "${file.path}" still produced invalid JSON.
${errorMessage}`);
};
const retrySchemaValidation = async (file, content, zodError) => {
const errorMessage = new JsonParsingError(content, zodError).message;
const contentChunk = {
path: file.path,
name: file.name,
content,
startLine: 1,
endLine: content.split(/\r?\n/).length,
totalLines: content.split(/\r?\n/).length,
isPartial: false
};
const fileInput = formatChunksForInput([contentChunk]);
const { extracted } = await ctx.generateContent({
systemPrompt: getMicropatchSystemPrompt(),
messages: [
{
type: "text",
role: "user",
content: [
"The following JSON file is valid JSON but does not match the expected schema.",
"",
fileInput,
"",
errorMessage,
"",
"Fix the JSON to match the schema. Only change what's needed to satisfy the validation errors above."
].join(`
`)
}
],
stopSequences: [],
transform: (text2) => (text2 ?? "").trim()
});
const retryPatchMap = parsePatchOutput(extracted);
const retryPatchOps = retryPatchMap.get(file.path);
if (!retryPatchOps || retryPatchOps.trim().length === 0) {
throw new Error(`Schema validation retry for "${file.path}" produced no patches.
${errorMessage}`);
}
try {
const retryContent = Micropatch.applyText(content, retryPatchOps);
const validContent = ensureValidJson(retryContent);
if (validContent !== null) {
if (zSchema) {
const parsed = JSON.parse(validContent);
const safe = zSchema.safeParse(parsed);
if (safe.success) {
return { ...file, content: validContent, patch: retryPatchOps };
}
} else {
return { ...file, content: validContent, patch: retryPatchOps };
}
}
} catch {}
throw new Error(`Schema validation retry for "${file.path}" still failed.
${errorMessage}`);
};
const processBatch = async (batch) => {
const chunksInput = formatChunksForInput(batch.items);
const { extracted } = await ctx.generateContent({
systemPrompt: getMicropatchSystemPrompt(),
messages: [
{
type: "text",
role: "user",
content: `
Instructions: ${truncatedInstructions}
${chunksInput}
Generate patches for each file that needs modification:
`.trim()
}
],
stopSequences: [],
transform: (text2) => {
return text2.trim();
}
});
return parsePatchOutput(extracted);
};
const needsChunking = totalInputTokens > maxTokensPerChunk || fileTokenCounts.some((f) => f.tokens > maxTokensPerChunk);
if (!needsChunking) {
const Key = fastHash(stringify({
taskId,
taskType,
files: files.map((f) => ({ path: f.path, content: f.content })),
instructions: truncatedInstructions
}));
const tableExamples = taskId && ctx.adapter ? await ctx.adapter.getExamples({
input: files,
taskId,
taskType
}) : [];
const exactMatch = tableExamples.find((x) => x.key === Key);
if (exactMatch) {
return exactMatch.output;
}
const allChunks2 = fileTokenCounts.map(({ file }) => ({
path: file.path,
name: file.name,
content: file.content,
startLine: 1,
endLine: file.content.split(/\r?\n/).length,
totalLines: file.content.split(/\r?\n/).length,
isPartial: false
}));
const batch = { items: allChunks2, tokenCount: totalInputTokens };
const patchMap = await processBatch(batch);
const patchedFiles2 = await Promise.all(files.map((file) => applyPatchToFile(file, patchMap.get(file.path))));
if (taskId && ctx.adapter && !ctx.controller.signal.aborted) {
await ctx.adapter.saveExample({
key: Key,
taskType,
taskId,
input: files,
output: patchedFiles2,
instructions: truncatedInstructions,
metadata: {
cost: {
input: ctx.usage.cost.input,
output: ctx.usage.cost.output
},
latency: Date.now(),
model: ctx.modelId,
tokens: {
input: ctx.usage.tokens.input,
output: ctx.usage.tokens.output
}
}
});
}
return patchedFiles2;
}
const allChunks = [];
for (const { file, tokens, lines } of fileTokenCounts) {
const chunks = splitFileIntoChunks(file, lines, tokens);
allChunks.push(...chunks);
}
const batches = createBatches(allChunks);
const limit = pLimit(10);
const batchResults = await Promise.all(batches.map((batch) => limit(() => processBatch(batch))));
const mergedPatches = /* @__PURE__ */ new Map;
for (const patchMap of batchResults) {
for (const [filePath, patchOps] of patchMap.entries()) {
const existing = mergedPatches.get(filePath) || "";
const combined = existing ? `${existing}
${patchOps}` : patchOps;
mergedPatches.set(filePath, combined);
}
}
const patchedFiles = await Promise.all(files.map((file) => applyPatchToFile(file, mergedPatches.get(file.path))));
return patchedFiles;
};
function getMicropatchSystemPrompt() {
return `
You are a code patching assistant. Your task is to generate precise line-based patches using the Micropatch protocol.
## Input Format
You will receive files in this XML format:
\`\`\`
<FILE path="src/hello.ts" name="hello.ts">
001|const x = 1
002|const y = 2
003|console.log(x + y)
</FILE>
<FILE path="src/utils.ts" name="utils.ts">
001|export function add(a, b) {
002| return a + b
003|}
</FILE>
\`\`\`
Each file has:
- **path**: Full file path
- **name**: File name
- **Numbered lines**: Format is \`NNN|content\` where NNN is the ORIGINAL line number (1-based)
## Output Format
Generate patches for EACH file that needs modification using this EXACT XML format:
\`\`\`
<FILE path="src/hello.ts">
\u25FC\uFE0E=1|const a = 1
\u25FC\uFE0E=2|const b = 2
\u25FC\uFE0E=3|console.log(a + b)
</FILE>
<FILE path="src/utils.ts">
\u25FC\uFE0E<1|/**
* Adds two numbers
*/
</FILE>
\`\`\`
**CRITICAL RULES**:
1. Each \`<FILE>\` tag MUST include the exact \`path\` attribute from the input
2. Put patch operations for EACH file inside its own \`<FILE>...</FILE>\` block
3. If a file doesn't need changes, omit its \`<FILE>\` block entirely
4. DO NOT mix patches from different files
5. DO NOT include line numbers or any text outside the patch operations
## Micropatch Protocol
The Micropatch protocol uses line numbers to reference ORIGINAL lines (before any edits).
### Operations
Each operation starts with the marker \`\u25FC\uFE0E\` at the beginning of a line:
1. **Insert BEFORE line**: \`\u25FC\uFE0E<NNN|text\`
- Inserts \`text\` as a new line BEFORE original line NNN
- Example: \`\u25FC\uFE0E<5|console.log('debug')\`
2. **Insert AFTER line**: \`\u25FC\uFE0E>NNN|text\`
- Inserts \`text\` as a new line AFTER original line NNN
- Example: \`\u25FC\uFE0E>10|}\`
3. **Replace single line**: \`\u25FC\uFE0E=NNN|new text\`
- Replaces original line NNN with \`new text\`
- Can span multiple lines (continue until next \u25FC\uFE0E or end)
- Example:
\`\`\`
\u25FC\uFE0E=7|function newName() {
return 42
}
\`\`\`
4. **Replace range**: \`\u25FC\uFE0E=NNN-MMM|replacement\`
- Replaces lines NNN through MMM with replacement text
- Example: \`\u25FC\uFE0E=5-8|const combined = a + b + c + d\`
5. **Delete single line**: \`\u25FC\uFE0E-NNN\`
- Deletes original line NNN
- Example: \`\u25FC\uFE0E-12\`
6. **Delete range**: \`\u25FC\uFE0E-NNN-MMM\`
- Deletes lines NNN through MMM inclusive
- Example: \`\u25FC\uFE0E-5-10\`
### Escaping
- To include a literal \`\u25FC\uFE0E\` in your text, use \`\\\u25FC\uFE0E\`
- No other escape sequences are recognized
### Important Rules
1. **Use ORIGINAL line numbers**: Always reference the line numbers shown in the input (001, 002, etc.)
2. **One operation per line**: Each operation must start on a new line with \`\u25FC\uFE0E\`
3. **No explanations**: Output ONLY patch operations inside \`<FILE>\` tags
4. **Precise operations**: Use the minimal set of operations to achieve the goal
5. **Verify line numbers**: Double-check that line numbers match the input
## Example
**Input:**
\`\`\`
<FILE path="src/math.ts" name="math.ts">
001|const x = 1
002|const y = 2
003|console.log(x + y)
004|
005|export { x, y }
</FILE>
\`\`\`
**Task:** Change variable names from x,y to a,b
**Output:**
\`\`\`
<FILE path="src/math.ts">
\u25FC\uFE0E=1|const a = 1
\u25FC\uFE0E=2|const b = 2
\u25FC\uFE0E=3|console.log(a + b)
\u25FC\uFE0E=5|export { a, b }
</FILE>
\`\`\`
## Your Task
Generate ONLY the \`<FILE>\` blocks with patch operations. Do not include explanations, comments, or any other text.
`.trim();
}
Zai.prototype.patch = function(files, instructions, _options) {
const context = new ZaiContext({
client: this.client,
modelId: this.Model,
taskId: this.taskId,
taskType: "zai.patch",
adapter: this.adapter,
memoizer: this._resolveMemoizer()
});
return new Response(context, patch(files, instructions, _options, context), (result) => result);
};
// ../evals/dist/runner.js
import { readdirSync, existsSync } from "fs";
import { resolve } from "path";
import { randomUUID } from "crypto";
var Eval = class {
name;
description;
tags;
type;
setup;
conversation;
outcome;
options;
constructor(def) {
this.name = def.name;
this.conversation = def.conversation;
if (def.description !== undefined)
this.description = def.description;
if (def.tags !== undefined)
this.tags = def.tags;
if (def.type !== undefined)
this.type = def.type;
if (def.setup !== undefined)
this.setup = def.setup;
if (def.outcome !== undefined)
this.outcome = def.outcome;
if (def.options !== undefined)
this.options = def.options;
}
};
var defaultLogger = console;
var AdkError = class extends Error {
static __IS_ADK_BASE_ERROR = true;
code;
expected;
details;
suggestion;
constructor(opts) {
super(opts.message, opts.cause !== undefined ? { cause: opts.cause } : undefined);
this.name = this.constructor.name;
this.code = opts.code;
this.expected = opts.expected ?? false;
if (opts.details !== undefined) {
this.details = opts.details;
}
if (opts.suggestion !== undefined) {
this.suggestion = opts.suggestion;
}
}
};
function isAdkError(error) {
if (error instanceof AdkError)
return true;
if (!(error instanceof Error))
return false;
return error.constructor?.__IS_ADK_BASE_ERROR === true;
}
var EvalRunnerError = class extends AdkError {
};
var TRACE_STREAM_PREFLIGHT_TIMEOUT_MS = 1e4;
var ChatSession = class {
constructor(bpClient, botId, _chatWebhookId, _chatBaseUrl, _chatClient) {
this.bpClient = bpClient;
this.botId = botId;
this._chatWebhookId = _chatWebhookId;
this._chatBaseUrl = _chatBaseUrl;
this._chatClient = _chatClient;
}
client = null;
conversationId = null;
async connect() {
const webhookId = this._chatWebhookId ?? await discoverWebhookId(this.bpClient, this.botId);
const ChatClientCtor = this._chatClient ?? (await import("@botpress/chat")).Client;
this.client = await ChatClientCtor.connect({
webhookId,
...this._chatBaseUrl ? { baseApiUrl: this._chatBaseUrl } : {}
});
}
assertConnected() {
if (!this.client) {
throw new EvalRunnerError({
code: "CHAT_NOT_CONNECTED",
message: "ChatSession not connected. Call connect() first."
});
}
return this.client;
}
get userId() {
return this.assertConnected().user.id;
}
async ensureConversation() {
const client = this.assertConnected();
if (!this.conversationId) {
const conv = await client.createConversation({});
this.conversationId = conv.conversation.id;
return conv.conversation.id;
}
return this.conversationId;
}
async newConversation() {
const client = this.assertConnected();
const conv = await client.createConversation({});
this.conversationId = conv.conversation.id;
return conv.conversation.id;
}
async sendMessage(message) {
const client = this.assertConnected();
const conversationId = await this.ensureConversation();
await client.createMessage({ conversationId, payload: { type: "text", text: message } });
}
async sendEvent(payload) {
const client = this.assertConnected();
const conversationId = await this.ensureConversation();
await client.createEvent({ payload, conversationId });
}
};
async function discoverWebhookId(client, botId) {
const { bot } = await client.getBot({ id: botId });
const integrations = bot.integrations || {};
const chat = Object.values(integrations).find((int) => int.name === "chat");
const webhookId = chat?.webhookId;
if (!webhookId || typeof webhookId !== "string") {
throw new EvalRunnerError({
code: "CHAT_INTEGRATION_MISSING",
message: [
"The `chat` integration is not installed on this bot \u2014 evals require it.",
"",
"To fix:",
" 1. Install it: adk integrations add chat",
" 2. Redeploy: adk dev (or: adk deploy)"
].join(`
`),
expected: true
});
}
return webhookId;
}
async function assertTraceStreamReadable(devServerUrl, headers = {}, timeoutMs = TRACE_STREAM_PREFLIGHT_TIMEOUT_MS) {
const url = `${devServerUrl.replace(/\/$/, "")}/api/traces/stream?count=1`;
const abortController = new AbortController;
let timedOut = false;
let reader = null;
const timer = setTimeout(() => {
timedOut = true;
abortController.abort();
}, timeoutMs);
try {
const res = await fetch(url, {
headers: { ...headers, Accept: "text/event-stream" },
signal: abortController.signal
});
if (!res.ok) {
throw traceStreamPreflightError(`Trace stream pre-flight failed: ${res.status} ${res.statusText}`);
}
if (!res.body) {
throw traceStreamPreflightError("Trace stream pre-flight failed: response had no body.");
}
reader = res.body.getReader();
const decoder = new TextDecoder;
let buffer = "";
while (true) {
const { done, value } = await reader.read();
if (done) {
throw traceStreamPreflightError("Trace stream pre-flight failed: stream closed before snapshot.");
}
buffer += decoder.decode(value, { stream: true });
const parts = buffer.split(`
`);
buffer = parts.pop() ?? "";
for (const part of parts) {
if (parseSSEEventName(part) === "snapshot") {
return;
}
}
}
} catch (err) {
if (err instanceof EvalRunnerError) {
throw err;
}
if (timedOut) {
throw traceStreamPreflightError(`Trace stream pre-flight timed out after ${timeoutMs}ms before receiving a snapshot.`);
}
throw traceStreamPreflightError(`Trace stream pre-flight failed: ${err instanceof Error ? err.message : String(err)}`);
} finally {
clearTimeout(timer);
reader?.cancel().catch(() => {});
}
}
function parseSSEEventName(block) {
for (const line of block.split(`
`)) {
if (line.startsWith("event:")) {
return line.slice("event:".length).trim();
}
}
return null;
}
function traceStreamPreflightError(message) {
return new EvalRunnerError({
code: "SSE_CONNECT_FAILED",
message,
expected: true,
suggestion: "Make sure the dev server is running (`adk dev`) and trace streaming is available."
});
}
async function assertChatChannelBound(devServerUrl, headers = {}, logger = defaultLogger) {
let conversations = [];
try {
const res = await fetch(`${devServerUrl}/api/agent`, { headers });
if (!res.ok)
return;
const agent = await res.json();
conversations = agent.conversations ?? [];
} catch (err) {
logger?.warn(`Skipping chat.channel binding pre-flight \u2014 could not query ${devServerUrl}/api/agent: ${err instanceof Error ? err.message : String(err)}`);
return;
}
if (conversations.length === 0)
return;
const matchesChatChannel = (ch) => {
if (!ch)
return false;
if (ch === "*" || ch === "chat.channel")
return true;
return Array.isArray(ch) && (ch.includes("chat.channel") || ch.includes("*"));
};
const bound = conversations.some((c) => matchesChatChannel(c.channel));
if (bound)
return;
throw new EvalRunnerError({
code: "CHAT_CHANNEL_UNBOUND",
message: [
"No Conversation is bound to `chat.channel` \u2014 messages via `@botpress/chat` will time out silently.",
"",
"To fix, bind a Conversation in `src/conversations/` to `chat.channel` (or `*`):",
" channel: 'chat.channel', // explicit",
" channel: '*', // wildcard \u2014 matches every channel",
" channel: ['chat.channel', ...], // array form",
"",
"The `chat` integration is how evals and `adk chat --single` send messages programmatically."
].join(`
`),
expected: true
});
}
function spanKey(span) {
return `${span.id.trace}:${span.id.span}`;
}
function spanData(span) {
return span.data && typeof span.data === "object" ? span.data : {};
}
var TURN_HANDLER_SPAN_NAMES = /* @__PURE__ */ new Set(["handler.conversation", "handler.event"]);
function isTurnHandlerSpan(span) {
return TURN_HANDLER_SPAN_NAMES.has(span.name);
}
var SSECollector = class _SSECollector {
devServerUrl;
headers;
spanMap = /* @__PURE__ */ new Map;
turnStartKeys = /* @__PURE__ */ new Set;
seenHandlerKeys = /* @__PURE__ */ new Set;
waiters = [];
abortController = null;
connected = false;
streamError = null;
updateEventCount = 0;
keepaliveEventCount = 0;
lastEvent = null;
_cancelSettle = null;
constructor(devServerUrl, headers = {}) {
this.devServerUrl = devServerUrl;
this.headers = headers;
}
async connect(filter2) {
const attributeName = "conversationId" in filter2 ? "conversationId" : "workflowId";
const attributeValue = "conversationId" in filter2 ? filter2.conversationId : filter2.workflowId;
const url = `${this.devServerUrl}/api/traces/stream?attributeName=${encodeURIComponent(attributeName)}&attributeValue=${encodeURIComponent(attributeValue)}`;
this.abortController = new AbortController;
const myController = this.abortController;
const response = await fetch(url, {
headers: { ...this.headers, Accept: "text/event-stream" },
signal: myController.signal
});
if (!response.ok) {
throw new EvalRunnerError({
code: "SSE_CONNECT_FAILED",
message: `SSE connection failed: ${response.status} ${response.statusText}`,
expected: true,
suggestion: "Make sure the dev server is running (`adk dev`) and reachable."
});
}
if (!response.body) {
throw new EvalRunnerError({ code: "SSE_NO_BODY", message: "SSE response has no body" });
}
this.connected = true;
this._consumeStream(response.body).catch((err) => {
if (this.connected && this.abortController === myController) {
this.streamError = err instanceof Error ? err : new Error(String(err));
}
});
await this._waitForSnapshot();
}
async repoint(filter2) {
this.connected = false;
this.abortController?.abort();
this.abortController = null;
this._cancelSettle?.();
this._cancelSettle = null;
this.waiters = [];
this.snapshotReceived = false;
this.snapshotResolvers = [];
this.streamError = null;
await this.connect(filter2);
}
startTurn() {
this.turnStartKeys = new Set(this.spanMap.keys());
for (const [key, span] of this.spanMap) {
if (isTurnHandlerSpan(span)) {
this.seenHandlerKeys.add(key);
}
}
}
static SETTLE_MS = 100;
async waitForTurnComplete(opts) {
const accept = opts.acceptSpanNames;
const settle = { quietMs: opts.settleQuietMs, maxMs: opts.settleMaxMs };
if (this._hasNewCompletedHandler(accept)) {
return this._settleAfterHandler(settle);
}
if (opts.abortSignal?.aborted) {
throw new Error("waitForTurnComplete aborted");
}
return new Promise((resolve2, reject) => {
const expected = accept ? [...accept].join(" or ") : "handler.conversation or handler.event";
const timer = setTimeout(() => {
clearStartTimer();
this._removeWaiter(waiter);
opts.abortSignal?.removeEventListener("abort", onAbort);
const reason = this.streamError ? `SSE stream died: ${this.streamError.message}` : `no ${expected} span completed`;
reject(new Error(`waitForTurnComplete timed out after ${opts.timeout}ms \u2014 ${reason}; diagnostics: ${this._formatTurnDiagnostics()}`));
}, opts.timeout);
let startTimer;
const clearStartTimer = () => {
if (startTimer !== undefined)
clearTimeout(startTimer);
startTimer = undefined;
};
if (opts.handlerStartTimeoutMs !== undefined && opts.handlerStartTimeoutMs < opts.timeout) {
startTimer = setTimeout(() => {
if (this._hasNewHandlerSpan(accept))
return;
clearTimeout(timer);
this._removeWaiter(waiter);
opts.abortSignal?.removeEventListener("abort", onAbort);
reject(new Error(`no ${expected} span started within ${opts.handlerStartTimeoutMs}ms \u2014 no handler is subscribed to this turn's trigger, so the turn can never complete; diagnostics: ${this._formatTurnDiagnostics()}`));
}, opts.handlerStartTimeoutMs);
}
const onAbort = () => {
clearTimeout(timer);
clearStartTimer();
this._removeWaiter(waiter);
reject(new Error("waitForTurnComplete aborted"));
};
opts.abortSignal?.addEventListener("abort", onAbort, { once: true });
const waiter = (_span) => {
if (this._hasNewCompletedHandler(accept)) {
clearTimeout(timer);
clearStartTimer();
this._removeWaiter(waiter);
opts.abortSignal?.removeEventListener("abort", onAbort);
this._settleAfterHandler(settle).then(resolve2, reject);
}
};
this.waiters.push(waiter);
});
}
static MAX_SETTLE_MS = 2000;
_settleAfterHandler(settle) {
const quietMs = settle?.quietMs ?? _SSECollector.SETTLE_MS;
const maxMs = settle?.maxMs ?? _SSECollector.MAX_SETTLE_MS;
return new Promise((resolve2) => {
let resolved = false;
const done = () => {
if (resolved)
return;
resolved = true;
clearTimeout(hardCap);
clearTimeout(settleTimer);
this._removeWaiter(settleWaiter);
this._cancelSettle = null;
resolve2();
};
const hardCap = setTimeout(done, maxMs);
let settleTimer = setTimeout(done, quietMs);
const settleWaiter = () => {
if (resolved)
return;
clearTimeout(settleTimer);
settleTimer = setTimeout(done, quietMs);
};
this.waiters.push(settleWaiter);
this._cancelSettle = done;
});
}
async waitForWorkflow(name, opts) {
if (this._matchesWorkflowCondition(name, opts.signal)) {
return;
}
if (opts.abortSignal?.aborted) {
throw new Error(`waitForWorkflow("${name}", { signal: "${opts.signal}" }) aborted`);
}
return new Promise((resolve2, reject) => {
const timer = setTimeout(() => {
this._removeWaiter(waiter);
opts.abortSignal?.removeEventListener("abort", onAbort);
const reason = this.streamError ? `SSE stream died: ${this.streamError.message}` : "span not found";
reject(new Error(`waitForWorkflow("${name}", { signal: "${opts.signal}" }) timed out after ${opts.timeout}ms \u2014 ${reason}`));
}, opts.timeout);
const onAbort = () => {
clearTimeout(timer);
this._removeWaiter(waiter);
reject(new Error(`waitForWorkflow("${name}", { signal: "${opts.signal}" }) aborted`));
};
opts.abortSignal?.addEventListener("abort", onAbort, { once: true });
const waiter = (_span) => {
if (this._matchesWorkflowCondition(name, opts.signal)) {
clearTimeout(timer);
this._removeWaiter(waiter);
opts.abortSignal?.removeEventListener("abort", onAbort);
resolve2();
}
};
this.waiters.push(waiter);
});
}
getTurnSpans() {
const result = [];
for (const [key, span] of this.spanMap) {
if (!this.turnStartKeys.has(key)) {
result.push(span);
}
}
return result;
}
getAllSpans() {
return Array.from(this.spanMap.values());
}
disconnect() {
this.connected = false;
this.abortController?.abort();
this.abortController = null;
this._cancelSettle?.();
this._cancelSettle = null;
this.waiters = [];
this.snapshotResolvers = [];
}
snapshotReceived = false;
snapshotResolvers = [];
static SNAPSHOT_TIMEOUT_MS = 1e4;
_waitForSnapshot() {
if (this.snapshotReceived) {
return Promise.resolve();
}
return new Promise((resolve2, reject) => {
let settled = false;
const resolver = () => {
if (settled)
return;
settled = true;
clearTimeout(timer);
resolve2();
};
const timer = setTimeout(() => {
if (settled)
return;
settled = true;
const idx = this.snapshotResolvers.indexOf(resolver);
if (idx !== -1)
this.snapshotResolvers.splice(idx, 1);
reject(new Error(`SSE snapshot not received within ${_SSECollector.SNAPSHOT_TIMEOUT_MS}ms \u2014 is the dev server healthy?`));
}, _SSECollector.SNAPSHOT_TIMEOUT_MS);
this.snapshotResolvers.push(resolver);
});
}
async _consumeStream(body) {
const decoder = new TextDecoder;
let buffer = "";
const reader = body.getReader();
try {
while (this.connected) {
const { done, value } = await reader.read();
if (done)
break;
buffer += decoder.decode(value, { stream: true });
const parts = buffer.split(`
`);
buffer = parts.pop() ?? "";
for (const part of parts) {
this._parseSSEBlock(part);
}
}
} finally {
reader.releaseLock();
}
}
_parseSSEBlock(block) {
const lines = block.split(`
`);
let eventName = "";
let dataLine = "";
for (const line of lines) {
if (line.startsWith("event:")) {
eventName = line.slice("event:".length).trim();
} else if (line.startsWith("data:")) {
const value = line.slice("data:".length).trim();
dataLine = dataLine ? `${dataLine}
${value}` : value;
}
}
if (!eventName || !dataLine) {
if (!this.snapshotReceived && block.includes("retry:")) {}
return;
}
try {
const payload = JSON.parse(dataLine);
this._handleEvent(eventName, payload);
} catch {}
}
_handleEvent(eventName, payload) {
this._recordEvent(eventName);
if (eventName === "snapshot") {
const data2 = payload;
const spans = Array.isArray(data2.spans) ? data2.spans : [];
for (const span of spans) {
this._upsertSpan(span);
}
this.snapshotReceived = true;
for (const resolve2 of this.snapshotResolvers) {
resolve2();
}
this.snapshotResolvers = [];
} else if (eventName === "update") {
const data2 = payload;
if (data2.span) {
this._upsertSpan(data2.span);
this._notifyWaiters(data2.span);
}
}
}
_recordEvent(eventName) {
this.lastEvent = { name: eventName, at: Date.now() };
if (eventName === "update") {
this.updateEventCount++;
} else if (eventName === "keepalive") {
this.keepaliveEventCount++;
}
}
_formatTurnDiagnostics() {
const turnSpans = this.getTurnSpans();
const spanNames = /* @__PURE__ */ new Set;
const handlerStatuses = /* @__PURE__ */ new Set;
for (const span of turnSpans) {
spanNames.add(span.name);
if (isTurnHandlerSpan(span)) {
handlerStatuses.add(span.status);
}
}
const lastEvent = this.lastEvent ? `${this.lastEvent.name} ${Date.now() - this.lastEvent.at}ms ago` : "none";
return [
`snapshotReceived=${this.snapshotReceived}`,
`totalUpdates=${this.updateEventCount}`,
`totalKeepalives=${this.keepaliveEventCount}`,
`lastEvent=${lastEvent}`,
`totalSpans=${this.spanMap.size}`,
`turnSpans=${turnSpans.length}`,
`turnSpanNames=${this._formatSet(spanNames)}`,
`turnHandlerStatuses=${this._formatSet(handlerStatuses)}`
].join(", ");
}
_formatSet(values, limit = 12) {
if (values.size === 0) {
return "none";
}
const items = Array.from(values);
const suffix = items.length > limit ? `|+${items.length - limit} more` : "";
return `${items.slice(0, limit).join("|")}${suffix}`;
}
_upsertSpan(span) {
this.spanMap.set(spanKey(span), span);
}
_notifyWaiters(span) {
const current = [...this.waiters];
for (const waiter of current) {
waiter(span);
}
}
_removeWaiter(fn) {
const idx = this.waiters.indexOf(fn);
if (idx !== -1) {
this.waiters.splice(idx, 1);
}
}
_hasNewCompletedHandler(acceptSpanNames) {
for (const [key, span] of this.spanMap) {
if (isTurnHandlerSpan(span) && (!acceptSpanNames || acceptSpanNames.has(span.name)) && !this.seenHandlerKeys.has(key) && (span.status === "ok" || span.status === "error")) {
this.seenHandlerKeys.add(key);
return true;
}
}
return false;
}
_hasNewHandlerSpan(acceptSpanNames) {
for (const [key, span] of this.spanMap) {
if (isTurnHandlerSpan(span) && (!acceptSpanNames || acceptSpanNames.has(span.name)) && !this.seenHandlerKeys.has(key)) {
return true;
}
}
return false;
}
_matchesWorkflowCondition(name, signal) {
for (const span of this.spanMap.values()) {
if (span.name !== "handler.workflow")
continue;
const d = spanData(span);
const wfName = d["workflow.name"] || d["workflowName"];
if (wfName !== name)
continue;
if (signal === "entered") {
return true;
}
if (signal === "completed") {
return span.status === "ok" || span.status === "error";
}
}
return false;
}
};
var LocalSpanSource = class {
collector;
constructor(devServerUrl, headers = {}) {
this.collector = new SSECollector(devServerUrl, headers);
}
async connect(filter2) {
await this.collector.connect(filter2);
}
async repoint(filter2) {
await this.collector.repoint(filter2);
}
startTurn() {
this.collector.startTurn();
}
async waitForTurnComplete(opts) {
await this.collector.waitForTurnComplete(opts);
}
async waitForWorkflow(name, opts) {
await this.collector.waitForWorkflow(name, opts);
}
getTurnSpans() {
return this.collector.getTurnSpans();
}
getAllSpans() {
return this.collector.getAllSpans();
}
disconnect() {
this.collector.disconnect();
}
};
function data(span) {
return span.data && typeof span.data === "object" ? span.data : {};
}
function tryParseJson2(value) {
if (value == null)
return;
if (typeof value !== "string")
return value;
try {
return JSON.parse(value);
} catch {
return value;
}
}
function parseJsonOrFallback(value, fallback) {
if (typeof value !== "string")
return fallback;
try {
return JSON.parse(value);
} catch {
return fallback;
}
}
function transformSpans(spans) {
return {
messages: extractMessages(spans),
toolCalls: extractToolCalls(spans),
stateMutations: extractStateMutations(spans),
workflowSpans: extractWorkflowSpans(spans),
...extractHandler(spans)
};
}
function extractMessages(spans) {
return spans.filter((s) => s.name === "chat.sendMessage" && data(s)["message.preview"]).sort((a, b) => a.timing.startedAt - b.timing.startedAt).map((s) => String(data(s)["message.preview"]));
}
function extractToolCalls(spans) {
const toolSpans = spans.filter((s) => s.name === "autonomous.tool" && s.status !== "running" && data(s)["autonomous.tool.name"]);
const seen = /* @__PURE__ */ new Set;
const unique = toolSpans.filter((s) => {
if (seen.has(s.id.span))
return false;
seen.add(s.id.span);
return true;
});
return unique.sort((a, b) => (a.timing.endedAt ?? Infinity) - (b.timing.endedAt ?? Infinity)).map((s) => {
const d = data(s);
const input = parseJsonOrFallback(d["autonomous.tool.input"], {});
return {
name: String(d["autonomous.tool.name"]),
input,
output: String(d["autonomous.tool.output"] ?? ""),
status: String(d["autonomous.tool.status"] ?? "unknown")
};
});
}
function extractStateMutations(spans) {
return spans.filter((s) => {
if (s.name !== "state.save")
return false;
const d = data(s);
const changedKeys = d["state.changed_keys"];
return Array.isArray(changedKeys) && changedKeys.length > 0;
}).map((s) => {
const d = data(s);
return {
type: String(d["type"] ?? "unknown"),
changedKeys: d["state.changed_keys"] ?? [],
previous: tryParseJson2(d["state.previous_value"]),
current: tryParseJson2(d["state.value"]),
swappedToFile: d["swapped_to_file"] === true
};
});
}
function extractWorkflowSpans(spans) {
return spans.filter((s) => s.name === "handler.workflow").map((s) => {
const d = data(s);
const result = {
name: String(d["workflow.name"] || d["workflowName"] || ""),
status: s.status
};
const statusFinal = d["workflow.status.final"];
if (statusFinal) {
result.statusFinal = String(statusFinal);
}
return result;
});
}
function extractHandler(spans) {
const handler = spans.find((s) => (s.name === "handler.conversation" || s.name === "handler.event" || s.name === "handler.workflow") && s.status !== "running");
if (!handler) {
return { handlerDuration: 0, handlerStatus: "ok" };
}
return {
handlerDuration: handler.timing.duration ?? 0,
handlerStatus: handler.status === "error" ? "error" : "ok"
};
}
var MODEL_ALIASES = ["fast", "best"];
var _zai = null;
var _availableModels = [];
var _judgeModel = "fast";
var _failClosed = true;
var _log = defaultLogger;
function _isModelValid(model) {
if (MODEL_ALIASES.includes(model))
return true;
if (_availableModels.length === 0)
return false;
return _availableModels.includes(model);
}
async function initLLMJudge(client, options) {
const log = options?.logger ?? defaultLogger;
_log = log;
_failClosed = options?.failClosed ?? true;
const cognitive = new Cognitive({ client, __experimental_beta: true });
try {
_availableModels = Array.from((await cognitive.fetchRemoteModels()).keys());
} catch (err) {
log.warn(`Failed to fetch available models: ${err.message}. LLM judge will be unavailable.`);
_availableModels = [];
}
_judgeModel = options?.model ?? "fast";
if (_availableModels.length === 0) {
log.warn("No available Cognitive models: cannot validate judge model.");
} else if (!_isModelValid(_judgeModel)) {
log.warn(`Configured LLM judge model "${_judgeModel}" is invalid. Run "adk models" to list available models.`);
}
_zai = new Zai({ client: cognitive, modelId: _judgeModel });
}
async function gradeLLMJudge(botResponse, criteria, context) {
const assertion = `llm_judge: "${criteria}"`;
try {
if (!_zai) {
_log.warn(`LLM judge unavailable for "${criteria}": no credentials configured (initLLMJudge not called)`);
return {
assertion,
pass: !_failClosed,
skipped: true,
expected: criteria,
actual: "FAILED \u2014 LLM judge unavailable: no credentials configured"
};
}
if (!_isModelValid(_judgeModel)) {
return {
assertion,
pass: false,
expected: criteria,
actual: "FAILED \u2014 invalid LLM judge model"
};
}
const { output } = await _zai.check({ userMessage: context.userMessage, botResponse }, criteria).result();
return {
assertion,
pass: output.value,
expected: criteria,
actual: `${output.value ? "Pass" : "Fail"} \u2014 ${output.explanation}`
};
} catch (err) {
_log.warn(`LLM judge failed for "${criteria}": ${err.message}`);
return {
assertion,
pass: !_failClosed,
skipped: true,
expected: criteria,
actual: `FAILED \u2014 LLM judge unavailable: ${err.message}`
};
}
}
async function gradeResponse(botResponse, assertions, context) {
const results = [];
for (const assertion of assertions) {
if ("contains" in assertion) {
const pass = botResponse.toLowerCase().includes(assertion.contains.toLowerCase());
results.push({
assertion: `contains "${assertion.contains}"`,
pass,
expected: `Response contains "${assertion.contains}"`,
actual: pass ? `Found in response` : `Not found in response`
});
continue;
}
if ("not_contains" in assertion) {
const pass = !botResponse.toLowerCase().includes(assertion.not_contains.toLowerCase());
results.push({
assertion: `not_contains "${assertion.not_contains}"`,
pass,
expected: `Response does not contain "${assertion.not_contains}"`,
actual: pass ? `Not found in response` : `Found in response`
});
continue;
}
if ("matches" in assertion) {
const regex = new RegExp(assertion.matches, "i");
const pass = regex.test(botResponse);
results.push({
assertion: `matches ${assertion.matches}`,
pass,
expected: `Response matches /${assertion.matches}/`,
actual: pass ? `Matched` : `No match`
});
continue;
}
if ("llm_judge" in assertion) {
const result = await gradeLLMJudge(botResponse, assertion.llm_judge, {
userMessage: context.userMessage,
...context.judgePassThreshold !== undefined ? { passThreshold: context.judgePassThreshold } : {}
});
results.push(result);
continue;
}
results.push({
assertion: "unknown",
pass: false,
expected: "known assertion type",
actual: `Unknown assertion: ${JSON.stringify(assertion)}`
});
}
return results;
}
function matchValue(operator, actual) {
if (typeof operator === "string") {
return String(actual) === operator;
}
if ("equals" in operator) {
return actual === operator.equals;
}
if ("contains" in operator) {
return String(actual).toLowerCase().includes(operator.contains.toLowerCase());
}
if ("not_contains" in operator) {
return !String(actual).toLowerCase().includes(operator.not_contains.toLowerCase());
}
if ("matches" in operator) {
return new RegExp(operator.matches, "i").test(String(actual));
}
if ("in" in operator) {
return operator.in.includes(actual);
}
if ("exists" in operator) {
return operator.exists ? actual !== undefined && actual !== null : actual === undefined || actual === null;
}
if ("gte" in operator) {
return Number(actual) >= operator.gte;
}
if ("lte" in operator) {
return Number(actual) <= operator.lte;
}
return false;
}
function operatorToString(operator) {
if (typeof operator === "string")
return `equals "${operator}"`;
if ("equals" in operator)
return `equals ${JSON.stringify(operator.equals)}`;
if ("contains" in operator)
return `contains "${operator.contains}"`;
if ("not_contains" in operator)
return `not_contains "${operator.not_contains}"`;
if ("matches" in operator)
return `matches /${operator.matches}/`;
if ("in" in operator)
return `in [${operator.in.map((v) => JSON.stringify(v)).join(", ")}]`;
if ("exists" in operator)
return operator.exists ? "exists" : "does not exist";
if ("gte" in operator)
return `>= ${operator.gte}`;
if ("lte" in operator)
return `<= ${operator.lte}`;
return JSON.stringify(operator);
}
function gradeTools(toolCalls, assertions) {
return assertions.map((assertion) => {
if ("called" in assertion && !("not_called" in assertion) && !("call_order" in assertion)) {
const matches = toolCalls.filter((tc) => tc.name === assertion.called);
const wasCalled = matches.length > 0;
if (!wasCalled) {
return {
assertion: `tool called: ${assertion.called}`,
pass: false,
expected: `${assertion.called} was called`,
actual: `Not called. Tools called: [${toolCalls.map((tc) => tc.name).join(", ") || "none"}]`
};
}
if (assertion.params) {
const paramResults = [];
for (const [key, operator] of Object.entries(assertion.params)) {
const anyMatch = matches.some((tc) => matchValue(operator, tc.input[key]));
paramResults.push({
key,
pass: anyMatch,
detail: anyMatch ? `matched` : `expected ${key} ${operatorToString(operator)}, got ${JSON.stringify(matches.map((tc) => tc.input[key]))}`
});
}
const allParamsPass = paramResults.every((p) => p.pass);
const failedParams = paramResults.filter((p) => !p.pass);
return {
assertion: `tool called: ${assertion.called} with params`,
pass: allParamsPass,
expected: `${assertion.called} called with ${Object.entries(assertion.params).map(([k, v]) => `${k} ${operatorToString(v)}`).join(", ")}`,
actual: allParamsPass ? `Matched` : failedParams.map((p) => p.detail).join("; ")
};
}
return {
assertion: `tool called: ${assertion.called}`,
pass: true,
expected: `${assertion.called} was called`,
actual: `Called ${matches.length} time(s)`
};
}
if ("not_called" in assertion) {
const wasCalled = toolCalls.some((tc) => tc.name === assertion.not_called);
return {
assertion: `tool not_called: ${assertion.not_called}`,
pass: !wasCalled,
expected: `${assertion.not_called} was NOT called`,
actual: wasCalled ? `Was called` : `Not called`
};
}
if ("call_order" in assertion) {
const calledNames = toolCalls.map((tc) => tc.name);
const expectedOrder = assertion.call_order;
let cursor = 0;
for (const name of calledNames) {
if (cursor < expectedOrder.length && name === expectedOrder[cursor]) {
cursor++;
}
}
const inOrder = cursor === expectedOrder.length;
return {
assertion: `call_order: [${expectedOrder.join(" \u2192 ")}]`,
pass: inOrder,
expected: `Tools called in order: [${expectedOrder.join(" \u2192 ")}]`,
actual: `Actual order: [${calledNames.join(" \u2192 ") || "none"}]`
};
}
return {
assertion: "unknown tool assertion",
pass: false,
expected: "known assertion type",
actual: `Unknown: ${JSON.stringify(assertion)}`
};
});
}
function parseStatePath(path) {
const dot = path.indexOf(".");
if (dot === -1) {
throw new Error(`Invalid state path "${path}" \u2014 expected "type.field" format`);
}
const type = path.slice(0, dot);
const field = path.slice(dot + 1);
if (type !== "bot" && type !== "user" && type !== "conversation") {
throw new Error(`Unknown state type "${type}" in path "${path}" \u2014 expected bot, user, or conversation`);
}
return { type, field };
}
function gradeState(mutations, assertions) {
const results = [];
for (const assertion of assertions) {
const parsed = parseStatePath(assertion.path);
const matchingMutations = mutations.filter((m) => m.type === parsed.type);
if (assertion.equals !== undefined) {
if (matchingMutations.length === 0) {
results.push({
assertion: `state: ${assertion.path} equals`,
pass: false,
expected: JSON.stringify(assertion.equals),
actual: `No state.save span found for "${parsed.type}" \u2014 the bot did not mutate this state during the turn. If this state was seeded via setup.state, assert on the tool/action that reads it, or use a conversation turn that triggers a state write.`
});
continue;
}
const lastMutation = matchingMutations[matchingMutations.length - 1];
if (lastMutation.swappedToFile) {
results.push({
assertion: `state: ${assertion.path} equals`,
pass: false,
expected: JSON.stringify(assertion.equals),
actual: "State was too large for trace-based assertion (swapped to file)"
});
continue;
}
const currentState = lastMutation.current;
const actualValue = currentState ? currentState[parsed.field] : undefined;
const pass = deepEqual(actualValue, assertion.equals);
results.push({
assertion: `state: ${assertion.path} equals`,
pass,
expected: JSON.stringify(assertion.equals),
actual: JSON.stringify(actualValue)
});
}
if (assertion.changed !== undefined) {
if (matchingMutations.length === 0) {
results.push({
assertion: `state: ${assertion.path} ${assertion.changed ? "changed" : "unchanged"}`,
pass: !assertion.changed,
expected: assertion.changed ? `Field "${parsed.field}" changed in a "${parsed.type}" state mutation` : `Field "${parsed.field}" unchanged`,
actual: 'No state mutation found for type "' + parsed.type + '"'
});
continue;
}
const hasSwapped = matchingMutations.some((m) => m.swappedToFile);
if (hasSwapped) {
results.push({
assertion: `state: ${assertion.path} ${assertion.changed ? "changed" : "unchanged"}`,
pass: false,
expected: assertion.changed ? `Field "${parsed.field}" changed in a "${parsed.type}" state mutation` : `Field "${parsed.field}" unchanged`,
actual: "State was too large for trace-based assertion (swapped to file)"
});
continue;
}
const fieldChanged = matchingMutations.some((m) => m.changedKeys.includes(parsed.field));
const pass = assertion.changed ? fieldChanged : !fieldChanged;
results.push({
assertion: `state: ${assertion.path} ${assertion.changed ? "changed" : "unchanged"}`,
pass,
expected: assertion.changed ? `Field "${parsed.field}" changed in a "${parsed.type}" state mutation` : `Field "${parsed.field}" unchanged`,
actual: fieldChanged ? `Field "${parsed.field}" was changed` : `Field "${parsed.field}" was not changed`
});
}
}
return results;
}
function deepEqual(a, b) {
if (a === b)
return true;
if (a === null || b === null)
return false;
if (typeof a !== typeof b)
return false;
if (Array.isArray(a) && Array.isArray(b)) {
if (a.length !== b.length)
return false;
return a.every((v, i) => deepEqual(v, b[i]));
}
if (Array.isArray(a) !== Array.isArray(b))
return false;
if (typeof a === "object" && typeof b === "object") {
const keysA = Object.keys(a);
const keysB = Object.keys(b);
if (keysA.length !== keysB.length)
return false;
return keysA.every((k) => deepEqual(a[k], b[k]));
}
return false;
}
function gradeWorkflows(workflows, assertions) {
const results = [];
for (const assertion of assertions) {
const matching = workflows.filter((wf) => wf.name === assertion.name);
if (assertion.entered !== undefined) {
const wasEntered = matching.length > 0;
const pass = assertion.entered ? wasEntered : !wasEntered;
results.push({
assertion: `workflow: ${assertion.name} ${assertion.entered ? "entered" : "not entered"}`,
pass,
expected: assertion.entered ? `Workflow "${assertion.name}" was entered` : `Workflow "${assertion.name}" was not entered`,
actual: wasEntered ? `Found ${matching.length} workflow span(s)` : `No workflow spans found`
});
}
if (assertion.completed !== undefined) {
const didComplete = matching.some((wf) => wf.statusFinal === "completed" || wf.status === "ok" || wf.status === "error");
const pass = assertion.completed ? didComplete : !didComplete;
results.push({
assertion: `workflow: ${assertion.name} ${assertion.completed ? "completed" : "not completed"}`,
pass,
expected: assertion.completed ? `Workflow "${assertion.name}" completed` : `Workflow "${assertion.name}" did not complete`,
actual: didComplete ? `Completed` : `Not completed`
});
}
}
return results;
}
function gradeTiming(botDuration, assertions) {
const results = [];
for (const assertion of assertions) {
const pass = matchValue(assertion.response_time, botDuration);
const expected = operatorToString(assertion.response_time);
results.push({
assertion: `response_time ${expected}`,
pass,
expected: `Response time ${expected}`,
actual: `${botDuration}ms`
});
}
return results;
}
function gradeOutcome(mutations, evalDef, workflowSpans) {
const outcome = evalDef.outcome;
if (!outcome)
return [];
const results = [];
if (outcome.state && outcome.state.length > 0) {
const stateResults = gradeState(mutations, outcome.state);
results.push(...stateResults);
}
if (outcome.workflow && outcome.workflow.length > 0) {
const workflowResults = gradeWorkflows(workflowSpans, outcome.workflow);
results.push(...workflowResults);
}
return results;
}
function isEvalDefinition(value) {
return value !== null && typeof value === "object" && typeof value.name === "string" && value.name !== "" && Array.isArray(value.conversation);
}
async function loadEvalFile(filePath) {
const absPath = resolve(filePath);
let mod;
try {
mod = await import(absPath);
} catch (err) {
const msg = err instanceof Error ? err.message : String(err);
throw new EvalRunnerError({
code: "EVAL_LOAD_FAILED",
message: `Failed to load eval file ${filePath}: ${msg}
Make sure your eval file:
- Has no syntax or type errors
- Exports one or more \`new Eval({...})\` instances
- Has all dependencies installed (\`bun install\`)`,
expected: true,
cause: err
});
}
const results = [];
for (const [key, value] of Object.entries(mod)) {
if (key === "__esModule")
continue;
if (value instanceof Eval || isEvalDefinition(value)) {
results.push(value);
}
}
if (results.length === 0) {
throw new EvalRunnerError({
code: "EVAL_FILE_EMPTY",
message: `Invalid eval file ${filePath}: no valid evals found. Export one or more \`new Eval({...})\` instances (as default or named exports).`,
expected: true
});
}
return results;
}
async function loadEvalsFromDir(dirPath) {
const absDir = resolve(dirPath);
if (!existsSync(absDir)) {
return [];
}
const files = readdirSync(absDir).filter((f) => f.endsWith(".eval.ts"));
const evals = [];
for (const f of files) {
const defs = await loadEvalFile(`${absDir}/${f}`);
evals.push(...defs);
}
const seen = /* @__PURE__ */ new Set;
for (const e of evals) {
if (seen.has(e.name)) {
throw new EvalRunnerError({
code: "EVAL_DUPLICATE_NAME",
message: `Duplicate eval name "${e.name}" found in ${dirPath} \u2014 names must be unique across the evals directory.`,
expected: true,
details: { name: e.name }
});
}
seen.add(e.name);
}
return evals;
}
function filterEvals(evals, filter2) {
if (!filter2)
return evals;
return evals.filter((e) => {
if (filter2.names && filter2.names.length > 0) {
if (!filter2.names.includes(e.name))
return false;
}
if (filter2.tags && filter2.tags.length > 0) {
if (!e.tags || !filter2.tags.some((t) => e.tags.includes(t)))
return false;
}
if (filter2.type) {
if (e.type !== filter2.type)
return false;
}
return true;
});
}
var DEFAULT_IDLE_TIMEOUT = 30000;
var DEFAULT_DEV_SERVER_URL = "http://localhost:3001";
var WORKFLOW_TRIGGER_TIMEOUT_MS = 300000;
var EVENT_HANDLER_START_TIMEOUT_MS = 30000;
var BUILT_IN_STATES = {
conversation: "state",
user: "userState",
bot: "botState"
};
function buildStatePayload(value) {
return {
value,
location: { type: "state" }
};
}
async function seedEvalState(client, ctx, setup) {
const state = setup?.state;
if (!state)
return;
const writes = [];
if (state.bot) {
writes.push(client.setState({
type: "bot",
id: ctx.botId,
name: BUILT_IN_STATES.bot,
payload: buildStatePayload(state.bot)
}));
}
if (state.user) {
writes.push(client.setState({
type: "user",
id: ctx.userId,
name: BUILT_IN_STATES.user,
payload: buildStatePayload(state.user)
}));
}
if (state.conversation) {
if (!ctx.conversationId) {
throw new EvalRunnerError({
code: "EVAL_SEED_NO_CONVERSATION",
message: "Cannot seed conversation state before a conversation is created."
});
}
writes.push(client.setState({
type: "conversation",
id: ctx.conversationId,
name: BUILT_IN_STATES.conversation,
payload: buildStatePayload(state.conversation)
}));
}
await Promise.all(writes);
}
async function triggerEvalWorkflow(client, ctx, setup) {
const workflow = setup?.workflow;
if (!workflow)
return;
await client.createWorkflow({
name: workflow.trigger,
input: workflow.input ?? {},
status: "pending",
userId: ctx.userId,
timeoutAt: new Date(Date.now() + WORKFLOW_TRIGGER_TIMEOUT_MS).toISOString(),
...ctx.conversationId !== undefined ? { conversationId: ctx.conversationId } : {}
});
}
function evalMetadata(evalDef) {
return {
name: evalDef.name,
...evalDef.description !== undefined ? { description: evalDef.description } : {},
...evalDef.type !== undefined ? { type: evalDef.type } : {},
...evalDef.tags !== undefined ? { tags: evalDef.tags } : {}
};
}
async function runEval(evalDef, connection, options = {}) {
const devServerUrl = options.devServerUrl || DEFAULT_DEV_SERVER_URL;
const devServerHeaders = options.devServerHeaders ?? {};
const logger = options.logger ?? defaultLogger;
const idleTimeout = evalDef.options?.idleTimeout ?? options.idleTimeout ?? DEFAULT_IDLE_TIMEOUT;
const judgePassThreshold = evalDef.options?.judgePassThreshold ?? options.judgePassThreshold;
if (options.judge) {
const judgeClient = new Uk(options.judge.credentials);
await initLLMJudge(judgeClient, {
...options.judge.model !== undefined ? { model: options.judge.model } : {},
...options.judge.failClosed !== undefined ? { failClosed: options.judge.failClosed } : {},
logger
});
}
const start = Date.now();
const turns = [];
let outcomeAssertions = [];
const collector = options.spanSource ?? new LocalSpanSource(devServerUrl, devServerHeaders);
try {
const session = new ChatSession(connection.client, connection.botId, options.chatWebhookId, options.chatBaseUrl, options.chatClient);
await session.connect();
let conversationId = "";
if (evalDef.setup?.state?.conversation || evalDef.setup?.workflow) {
conversationId = await session.ensureConversation();
}
await seedEvalState(connection.client, {
botId: connection.botId,
userId: session.userId,
...conversationId ? { conversationId } : {}
}, evalDef.setup);
await triggerEvalWorkflow(connection.client, {
userId: session.userId,
...conversationId ? { conversationId } : {}
}, evalDef.setup);
if (!conversationId && evalDef.conversation.length > 0) {
conversationId = await session.ensureConversation();
}
if (conversationId) {
await collector.connect({ conversationId });
} else if (evalDef.conversation.length > 0) {
throw new EvalRunnerError({
code: "EVAL_NO_CONVERSATION_ID",
message: "Cannot run conversation eval without a conversationId \u2014 no chat session or setup created one."
});
}
for (let i = 0;i < evalDef.conversation.length; i++) {
if (options.signal?.aborted)
break;
const turn = evalDef.conversation[i];
const turnConfigError = (message) => new EvalRunnerError({
code: "EVAL_TURN_CONFIG_INVALID",
message: `Turn ${i + 1}: ${message}`,
expected: true,
details: { turn: i + 1 }
});
if (turn.expectSilence && turn.assert?.response) {
throw turnConfigError(`'expectSilence' and 'assert.response' are mutually exclusive.`);
}
if (turn.user && turn.event) {
throw turnConfigError(`'user' and 'event' are mutually exclusive.`);
}
if (!turn.user && !turn.event) {
throw turnConfigError(`must have either 'user' or 'event'.`);
}
const turnLabel = turn.event ? "[event]" : turn.user;
await options.onProgress?.({
type: "turn_start",
evalName: evalDef.name,
evalIndex: options.evalIndex ?? 0,
turnIndex: i,
totalTurns: evalDef.conversation.length,
userMessage: turnLabel
});
if (turn.newConversation && i > 0) {
const newConversationId = await session.newConversation();
await collector.repoint({ conversationId: newConversationId });
}
collector.startTurn();
if (turn.event) {
await session.sendEvent(turn.event.payload);
} else {
await session.sendMessage(turn.user);
}
try {
await collector.waitForTurnComplete({
timeout: idleTimeout,
acceptSpanNames: turn.event ? /* @__PURE__ */ new Set(["handler.event"]) : /* @__PURE__ */ new Set(["handler.conversation"]),
settleQuietMs: 1500,
settleMaxMs: 15000,
...turn.event ? { handlerStartTimeoutMs: EVENT_HANDLER_START_TIMEOUT_MS } : {},
...options.signal !== undefined ? { abortSignal: options.signal } : {}
});
} catch (err) {
if (options.signal?.aborted)
break;
throw err;
}
if (turn.assert?.workflow) {
for (const wfAssert of turn.assert.workflow) {
const expectsPositive = wfAssert.entered !== false && wfAssert.completed !== false;
if (!expectsPositive)
continue;
const wfSignal = wfAssert.completed ? "completed" : "entered";
await collector.waitForWorkflow(wfAssert.name, {
signal: wfSignal,
timeout: idleTimeout,
...options.signal !== undefined ? { abortSignal: options.signal } : {}
}).catch(() => {});
}
}
let turnData = transformSpans(collector.getTurnSpans());
if (turn.event && !turn.expectSilence && turnData.messages.length === 0 && turnData.handlerDuration > 0) {
for (let waited = 0;waited < 600 && turnData.messages.length === 0; waited += 150) {
await new Promise((resolve2) => setTimeout(resolve2, 150));
turnData = transformSpans(collector.getTurnSpans());
}
}
const botResponse = turnData.messages.join(`
`);
const botDuration = turnData.handlerDuration;
const evalStart = Date.now();
let assertions = [];
const noResponse = !turn.expectSilence && turnData.messages.length === 0;
if (noResponse) {
assertions.push({
assertion: "response",
pass: false,
expected: "Bot produces a response",
actual: `Turn ${i + 1}: bot produced no response.`
});
}
if (turn.expectSilence) {
const wasSilent = turnData.messages.length === 0;
assertions.push({
assertion: "no_response",
pass: wasSilent,
expected: "No response",
actual: wasSilent ? "No response" : `Bot responded: "${botResponse}"`
});
}
if (turn.assert?.response && !noResponse) {
assertions = await gradeResponse(botResponse, turn.assert.response, {
userMessage: turnLabel,
...judgePassThreshold !== undefined ? { judgePassThreshold } : {}
});
}
if (turn.assert?.tools) {
const toolResults = gradeTools(turnData.toolCalls, turn.assert.tools);
assertions = [...assertions, ...toolResults];
}
if (turn.assert?.state) {
try {
const stateResults = gradeState(turnData.stateMutations, turn.assert.state);
assertions.push(...stateResults);
} catch (err) {
assertions.push({
assertion: "state",
pass: false,
expected: "State assertions executed",
actual: `Error: ${err.message}`
});
}
}
if (turn.assert?.workflow) {
const workflowResults = gradeWorkflows(turnData.workflowSpans, turn.assert.workflow);
assertions.push(...workflowResults);
}
if (turn.assert?.timing) {
const timingResults = gradeTiming(botDuration, turn.assert.timing);
assertions.push(...timingResults);
}
const turnPass = assertions.every((a) => a.pass);
const evalDuration = Date.now() - evalStart;
const turnReport = {
turnIndex: i,
userMessage: turnLabel,
botResponse,
assertions,
pass: turnPass,
botDuration,
evalDuration
};
turns.push(turnReport);
await options.onProgress?.({
type: "turn_complete",
evalName: evalDef.name,
evalIndex: options.evalIndex ?? 0,
turnIndex: i,
totalTurns: evalDef.conversation.length,
turnReport
});
}
if (evalDef.outcome && !options.signal?.aborted) {
if (evalDef.outcome.workflow) {
for (const wfAssert of evalDef.outcome.workflow) {
const expectsPositive = wfAssert.entered !== false && wfAssert.completed !== false;
if (!expectsPositive)
continue;
const wfSignal = wfAssert.completed ? "completed" : "entered";
await collector.waitForWorkflow(wfAssert.name, {
signal: wfSignal,
timeout: idleTimeout,
...options.signal !== undefined ? { abortSignal: options.signal } : {}
}).catch(() => {});
}
}
try {
const allTurnData = transformSpans(collector.getAllSpans());
outcomeAssertions = gradeOutcome(allTurnData.stateMutations, evalDef, allTurnData.workflowSpans);
} catch (err) {
outcomeAssertions = [
{
assertion: "outcome",
pass: false,
expected: "Outcome assertions executed",
actual: `Error: ${err.message}`
}
];
}
}
const aborted = options.signal?.aborted === true;
const turnsPass = turns.every((t) => t.pass);
const outcomePass = outcomeAssertions.every((a) => a.pass);
return {
...evalMetadata(evalDef),
turns,
outcomeAssertions,
pass: !aborted && turnsPass && outcomePass,
duration: Date.now() - start,
...aborted ? { error: "Eval aborted" } : {}
};
} catch (err) {
const adkErr = isAdkError(err) ? err : undefined;
if (!adkErr || !adkErr.expected) {
const errMsg = err.message ?? String(err);
const errStack = err.stack ?? "";
logger.error(`Eval "${evalDef.name}" failed unexpectedly: ${errMsg}`);
logger.error(` stack: ${errStack}`);
logger.error(` eval: ${evalDef.name}, turn: ${turns.length}/${evalDef.conversation.length}`);
logger.error(` connection: botId=${connection.botId}`);
logger.error(` spanSource: ${options.spanSource?.constructor?.name ?? "default"}, devServerUrl: ${options.devServerUrl ?? "n/a"}`);
options.onException?.(err, { source: "evals", eval_name: evalDef.name });
}
return {
...evalMetadata(evalDef),
turns,
outcomeAssertions,
pass: false,
duration: Date.now() - start,
error: err.message,
...adkErr ? { errorCode: adkErr.code } : {}
};
} finally {
collector.disconnect();
}
}
async function runEvalSuite(config, filter2) {
const start = Date.now();
const runId = config.runId ?? randomUUID().replace(/-/g, "").slice(0, 26);
let allEvals;
if (config.definitions) {
allEvals = config.definitions;
} else if (config.agentPath) {
allEvals = await loadEvalsFromDir(`${config.agentPath}/evals`);
} else {
throw new Error("Either `definitions` or `agentPath` must be provided in EvalRunnerConfig");
}
const evals = filterEvals(allEvals, filter2);
if (evals.length === 0) {
return {
id: runId,
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
evals: [],
passed: 0,
failed: 0,
total: 0,
duration: 0,
...filter2 !== undefined ? { filter: filter2 } : {}
};
}
await initLLMJudge(config.client, {
...config.evalOptions?.judgeModel !== undefined ? { model: config.evalOptions.judgeModel } : {},
...config.logger !== undefined ? { logger: config.logger } : {}
});
const connection = {
client: config.client,
botId: config.botId
};
const devServerUrl = config.devServerUrl || DEFAULT_DEV_SERVER_URL;
const devServerHeaders = config.devServerHeaders ?? {};
if (!config.createSpanSource) {
await assertChatChannelBound(devServerUrl, devServerHeaders, config.logger);
await assertTraceStreamReadable(devServerUrl, devServerHeaders);
}
const reports = [];
await config.onProgress?.({ type: "suite_start", totalEvals: evals.length });
for (let i = 0;i < evals.length; i++) {
if (config.signal?.aborted)
break;
const evalDef = evals[i];
await config.onProgress?.({
type: "eval_start",
evalName: evalDef.name,
index: i,
totalTurns: evalDef.conversation.length
});
const report = await runEval(evalDef, connection, {
devServerUrl,
devServerHeaders,
evalIndex: i,
...config.evalOptions?.idleTimeout !== undefined ? { idleTimeout: config.evalOptions.idleTimeout } : {},
...config.evalOptions?.judgePassThreshold !== undefined ? { judgePassThreshold: config.evalOptions.judgePassThreshold } : {},
...config.onProgress !== undefined ? { onProgress: config.onProgress } : {},
...config.signal !== undefined ? { signal: config.signal } : {},
...config.chatClient !== undefined ? { chatClient: config.chatClient } : {},
...config.logger !== undefined ? { logger: config.logger } : {},
...config.onException !== undefined ? { onException: config.onException } : {},
...config.createSpanSource !== undefined ? { spanSource: config.createSpanSource() } : {},
...config.chatWebhookId !== undefined ? { chatWebhookId: config.chatWebhookId } : {},
...config.chatBaseUrl !== undefined ? { chatBaseUrl: config.chatBaseUrl } : {}
});
reports.push(report);
await config.onProgress?.({ type: "eval_complete", evalName: evalDef.name, index: i, report });
}
const runReport = {
id: runId,
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
evals: reports,
passed: reports.filter((r) => r.pass).length,
failed: reports.filter((r) => !r.pass).length,
total: reports.length,
duration: Date.now() - start,
...filter2 !== undefined ? { filter: filter2 } : {}
};
if (config.signal?.aborted) {
runReport.aborted = true;
}
await config.onProgress?.({ type: "suite_complete", report: runReport });
return runReport;
}
// ../evals/dist/stores/vortex-eval-store-entry.js
var OUTCOME_TURN_INDEX = -1;
function vortexEntryToEvalReport(entry) {
const outcomeAssertions = entry.results.filter((r) => r.turnIndex === OUTCOME_TURN_INDEX).map((r) => ({
assertion: r.graderName,
pass: r.passed,
expected: r.evidence?.expected ?? "",
actual: r.evidence?.actual ?? ""
}));
const resultsByTurn = /* @__PURE__ */ new Map;
for (const r of entry.results) {
if (r.turnIndex === OUTCOME_TURN_INDEX)
continue;
const existing = resultsByTurn.get(r.turnIndex) ?? [];
existing.push(r);
resultsByTurn.set(r.turnIndex, existing);
}
const turns = [...resultsByTurn.entries()].sort(([a], [b]) => a - b).map(([turnIndex, results]) => {
const assertions = results.map((r) => ({
assertion: r.graderName,
pass: r.passed,
expected: r.evidence?.expected ?? "",
actual: r.evidence?.actual ?? ""
}));
const first = results[0];
return {
turnIndex,
userMessage: first.userMessage,
botResponse: first.botResponse,
assertions,
pass: assertions.every((a) => a.pass),
botDuration: first.botDurationMs ?? 0,
evalDuration: first.graderDurationMs ?? 0
};
});
return {
name: entry.evalName,
description: entry.description || undefined,
type: entry.evalType,
tags: entry.tags,
turns,
outcomeAssertions,
pass: entry.passed ?? false,
duration: entry.durationMs ?? 0,
error: entry.error ?? undefined
};
}
async function mapWithConcurrency(items, concurrency, fn) {
const results = new Array(items.length);
let next = 0;
const workers = Array.from({ length: Math.min(concurrency, items.length) }, async () => {
while (next < items.length) {
const i = next++;
results[i] = await fn(items[i]);
}
});
await Promise.all(workers);
return results;
}
function turnToResultRows(turn) {
return graderResultsToRows(turn.assertions, {
turnIndex: turn.turnIndex,
userMessage: turn.userMessage,
botResponse: turn.botResponse,
botDurationMs: turn.botDuration,
graderDurationMs: turn.evalDuration
});
}
function outcomeToResultRows(assertions) {
return graderResultsToRows(assertions, {
turnIndex: OUTCOME_TURN_INDEX,
userMessage: "",
botResponse: "",
botDurationMs: 0,
graderDurationMs: 0
});
}
function graderResultsToRows(assertions, context) {
return assertions.map((assertion) => ({
...context,
graderName: assertion.assertion,
passed: assertion.pass,
evidence: { expected: assertion.expected, actual: assertion.actual }
}));
}
function runMatchesWatchOptions(run, options) {
if (options.runId && run.id !== options.runId)
return false;
if (options.workflowId && run.metadata?.workflowId !== options.workflowId)
return false;
return true;
}
function vortexRunToReport(run) {
const evals = run.entries.map(vortexEntryToEvalReport);
return {
id: run.id,
timestamp: run.createdAt,
evals,
passed: evals.filter((e) => e.pass).length,
failed: evals.filter((e) => !e.pass).length,
total: evals.length,
duration: evals.reduce((s, e) => s + e.duration, 0)
};
}
function vortexRunToSummary(run) {
const startMs = run.startedAt ? new Date(run.startedAt).getTime() : 0;
const endMs = run.completedAt ? new Date(run.completedAt).getTime() : 0;
if (run.entries) {
const evals = run.entries.map(vortexEntryToEvalReport);
return {
id: run.id,
timestamp: run.createdAt,
passed: evals.filter((e) => e.pass).length,
failed: evals.filter((e) => !e.pass).length,
total: evals.length,
duration: evals.reduce((s, e) => s + e.duration, 0),
botDuration: evals.reduce((s, e) => e.turns.reduce((ts, t) => ts + t.botDuration, s), 0),
evalDuration: evals.reduce((s, e) => e.turns.reduce((ts, t) => ts + t.evalDuration, s), 0),
evalNames: evals.map((e) => e.name),
aborted: false
};
}
return {
id: run.id,
timestamp: run.createdAt,
passed: 0,
failed: 0,
total: 0,
duration: startMs && endMs ? endMs - startMs : 0,
botDuration: 0,
evalDuration: 0,
evalNames: [],
aborted: false
};
}
var VortexEvalStore = class {
url;
botId;
workspaceId;
token;
_evalManifestId;
_loadEvalDefinitions;
constructor(config) {
this.url = config.url.replace(/\/$/, "");
this.botId = config.botId;
if (config.workspaceId)
this.workspaceId = config.workspaceId;
if (config.token)
this.token = config.token;
this._evalManifestId = config.evalManifestId;
this._loadEvalDefinitions = config.loadEvalDefinitions;
}
async listEvals(filter2) {
const defs = await this.getEvalDefinitions();
const filtered = defs.filter((e) => {
if (filter2?.names && !filter2.names.includes(e.name))
return false;
if (filter2?.type && e.type !== filter2.type)
return false;
if (filter2?.tags && !filter2.tags.every((tag) => e.tags?.includes(tag)))
return false;
return true;
});
return filtered.map((e) => ({
name: e.name,
description: e.description,
tags: e.tags || [],
type: e.type || "capability",
turnCount: e.conversation.length,
hasOutcome: !!e.outcome
}));
}
async getEval(name) {
const defs = await this.getEvalDefinitions();
return defs.find((e) => e.name === name) ?? null;
}
async createRun(runType = "scheduled", metadata) {
if (!this.workspaceId) {
throw new Error("workspaceId is required to create Vortex eval runs");
}
const triggerType = runType === "manual" ? "manual" : "scheduled";
const res = await this.fetch(`/v1/evals/bot/${this.botId}/runs`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
evalManifestId: (typeof this._evalManifestId === "function" ? this._evalManifestId() : this._evalManifestId) ?? "",
workspaceId: this.workspaceId,
triggerType,
...metadata ? { metadata } : {}
})
});
if (!res.ok) {
const text2 = await res.text().catch(() => "");
throw new Error(`Vortex create run failed: ${res.status} ${text2}`);
}
const { id } = await res.json();
return id;
}
async addRunResults(runId, evalReport) {
const entry = {
evalName: evalReport.name,
evalType: evalReport.type ?? "capability",
description: evalReport.description ?? "",
tags: evalReport.tags ?? [],
passed: evalReport.pass,
durationMs: evalReport.duration,
error: evalReport.error,
results: [...evalReport.turns.flatMap(turnToResultRows), ...outcomeToResultRows(evalReport.outcomeAssertions)]
};
const res = await this.fetch(`/v1/evals/runs/${runId}/entries`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ entries: [entry] })
});
if (!res.ok) {
const text2 = await res.text().catch(() => "");
throw new Error(`Vortex ingest entries failed: ${res.status} ${text2}`);
}
}
async completeRun(runId, report) {
const hasRunError = report.aborted === true || report.evals.some((e) => e.error !== undefined);
const res = await this.fetch(`/v1/evals/runs/${runId}/entries`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
entries: [],
completed: !hasRunError,
failed: hasRunError
})
});
if (!res.ok) {
const text2 = await res.text().catch(() => "");
throw new Error(`Vortex complete run failed: ${res.status} ${text2}`);
}
}
async startEntry(runId, meta) {
const res = await this.fetch(`/v1/evals/runs/${runId}/entries`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
entries: [
{
evalName: meta.evalName,
evalType: meta.evalType ?? "capability",
description: meta.description ?? "",
tags: meta.tags ?? []
}
]
})
});
if (!res.ok) {
const text2 = await res.text().catch(() => "");
throw new Error(`Vortex start entry failed: ${res.status} ${text2}`);
}
const data2 = await res.json();
const entryId = data2.entries?.[0]?.id ?? data2.id;
if (!entryId) {
throw new Error("Vortex start entry returned no entry id");
}
return entryId;
}
async appendTurnResults(runId, entryId, turn) {
const res = await this.fetch(`/v1/evals/runs/${runId}/entries/${entryId}/results`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ results: turnToResultRows(turn) })
});
if (!res.ok) {
const text2 = await res.text().catch(() => "");
throw new Error(`Vortex append results failed: ${res.status} ${text2}`);
}
}
async appendOutcomeResults(runId, entryId, assertions) {
if (assertions.length === 0)
return;
const res = await this.fetch(`/v1/evals/runs/${runId}/entries/${entryId}/results`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ results: outcomeToResultRows(assertions) })
});
if (!res.ok) {
const text2 = await res.text().catch(() => "");
throw new Error(`Vortex append results failed: ${res.status} ${text2}`);
}
}
async finalizeEntry(runId, entryId, verdict) {
const res = await this.fetch(`/v1/evals/runs/${runId}/entries/${entryId}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
passed: verdict.passed,
...verdict.durationMs !== undefined ? { durationMs: verdict.durationMs } : {},
...verdict.error !== undefined ? { error: verdict.error } : {}
})
});
if (!res.ok) {
const text2 = await res.text().catch(() => "");
throw new Error(`Vortex finalize entry failed: ${res.status} ${text2}`);
}
}
async markRunComplete(runId, opts = {}) {
const res = await this.fetch(`/v1/evals/runs/${runId}/complete`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ...opts.failed !== undefined ? { failed: opts.failed } : {} })
});
if (!res.ok) {
const text2 = await res.text().catch(() => "");
throw new Error(`Vortex complete run failed: ${res.status} ${text2}`);
}
}
async loadRunResult(runId) {
const data2 = await this.fetchJson(`/v1/evals/runs/${runId}`);
return vortexRunToReport(data2);
}
async getLatestRun() {
const data2 = await this.fetchJson(`/v1/evals/bot/${this.botId}/runs`, { limit: "1" });
if (!data2.runs.length)
return null;
const latest = data2.runs[0];
return this.loadRunResult(latest.id);
}
async listRunSummaries(opts) {
const runs = await this.fetchRunsWithEntries(opts?.limit ?? 50, opts?.since);
return runs.map(vortexRunToSummary);
}
async listEvalReportsByName(evalName, opts) {
const limit = opts?.limit ?? 20;
const runs = await this.fetchRunsWithEntries(50, opts?.since);
const entries = [];
for (const run of runs) {
if (entries.length >= limit)
break;
const entry = run.entries.find((e) => e.evalName === evalName);
if (entry) {
entries.push({
runId: run.id,
timestamp: run.createdAt,
report: vortexEntryToEvalReport(entry),
totalEvalsInRun: run.entries.length
});
}
}
return entries;
}
async listEvalReportsBulk(opts) {
const per = opts?.perEval ?? 20;
const runs = await this.fetchRunsWithEntries(50, opts?.since);
const grouped = {};
for (const run of runs) {
for (const entry of run.entries) {
if (!grouped[entry.evalName])
grouped[entry.evalName] = [];
if (grouped[entry.evalName].length < per) {
grouped[entry.evalName].push({
runId: run.id,
timestamp: run.createdAt,
report: vortexEntryToEvalReport(entry),
totalEvalsInRun: run.entries.length
});
}
}
}
return grouped;
}
async* watchRun(signal, options = {}) {
const POLL_INTERVAL = 1500;
const POLL_TIMEOUT = 60 * 60 * 1000;
const start = Date.now();
const hasExpectedRun = !!options.runId || !!options.workflowId;
let baselineRunId = null;
if (!hasExpectedRun) {
try {
const initial = await this.fetchJson(`/v1/evals/bot/${this.botId}/runs`, {
limit: "1"
});
baselineRunId = initial.runs[0]?.id ?? null;
} catch {}
}
const evalMeta = await this.loadEvalMeta();
const startedEvals = /* @__PURE__ */ new Set;
const seenTurns = /* @__PURE__ */ new Set;
const startedTurns = /* @__PURE__ */ new Set;
const finalizedEvals = /* @__PURE__ */ new Set;
while (!signal?.aborted && Date.now() - start < POLL_TIMEOUT) {
try {
const data2 = await this.fetchJson(`/v1/evals/bot/${this.botId}/runs`, {
limit: hasExpectedRun ? "20" : "1"
});
let latest = null;
let raw = null;
for (const candidate of data2.runs) {
if (options.runId && candidate.id !== options.runId)
continue;
if (options.workflowId && candidate.metadata?.workflowId !== options.workflowId) {
const candidateRaw = await this.fetchJson(`/v1/evals/runs/${candidate.id}`);
if (!runMatchesWatchOptions(candidateRaw, options))
continue;
raw = candidateRaw;
}
latest = candidate;
break;
}
if (!latest || !hasExpectedRun && latest.id === baselineRunId) {
await new Promise((r) => setTimeout(r, POLL_INTERVAL));
continue;
}
raw ??= await this.fetchJson(`/v1/evals/runs/${latest.id}`);
const terminal = raw.status === "completed" || raw.status === "failed";
for (let i = 0;i < raw.entries.length; i++) {
const entry = raw.entries[i];
const evalReport = vortexEntryToEvalReport(entry);
const meta = evalMeta.get(entry.evalName);
const totalTurns = meta?.totalTurns ?? evalReport.turns.length;
if (!startedEvals.has(entry.evalName)) {
startedEvals.add(entry.evalName);
yield { type: "eval_start", evalName: entry.evalName, index: i, totalTurns };
}
for (const turn of evalReport.turns) {
const turnKey = `${entry.evalName}::${turn.turnIndex}`;
if (seenTurns.has(turnKey))
continue;
seenTurns.add(turnKey);
yield {
type: "turn_complete",
evalName: entry.evalName,
evalIndex: i,
turnIndex: turn.turnIndex,
totalTurns,
turnReport: turn
};
}
if (entry.passed != null && !finalizedEvals.has(entry.evalName)) {
finalizedEvals.add(entry.evalName);
yield { type: "eval_complete", evalName: entry.evalName, index: i, report: evalReport };
} else if (entry.passed == null && !terminal) {
const nextTurnIndex = evalReport.turns.length;
const startKey = `${entry.evalName}::${nextTurnIndex}`;
if (nextTurnIndex < totalTurns && !startedTurns.has(startKey)) {
startedTurns.add(startKey);
yield {
type: "turn_start",
evalName: entry.evalName,
evalIndex: i,
turnIndex: nextTurnIndex,
totalTurns,
userMessage: meta?.userMessages[nextTurnIndex] ?? ""
};
}
}
}
if (terminal) {
const finalReport = vortexRunToReport(raw);
for (let i = 0;i < finalReport.evals.length; i++) {
const evalReport = finalReport.evals[i];
if (finalizedEvals.has(evalReport.name))
continue;
finalizedEvals.add(evalReport.name);
yield { type: "eval_complete", evalName: evalReport.name, index: i, report: evalReport };
}
yield {
type: "suite_complete",
report: finalReport,
error: raw.status === "failed" ? "Eval run failed" : undefined
};
return;
}
} catch {}
await new Promise((r) => setTimeout(r, POLL_INTERVAL));
}
if (!signal?.aborted) {
yield {
type: "suite_complete",
report: {
id: "timeout",
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
evals: [],
passed: 0,
failed: 0,
total: 0,
duration: 0
},
error: "Eval run timed out"
};
}
}
async getRunnerState() {
try {
const data2 = await this.fetchJson(`/v1/evals/bot/${this.botId}/runs`, {
status: "running",
limit: "1"
});
const active = data2.runs[0] ?? null;
return { running: !!active, runId: active?.id ?? null };
} catch {
return { running: false, runId: null };
}
}
async getEvalDefinitions() {
if (!this._loadEvalDefinitions)
return [];
return this._loadEvalDefinitions();
}
async loadEvalMeta() {
try {
const defs = await this.getEvalDefinitions();
return new Map(defs.map((d) => [
d.name,
{ totalTurns: d.conversation.length, userMessages: d.conversation.map((t) => t.user ?? "") }
]));
} catch {
return /* @__PURE__ */ new Map;
}
}
async fetchRunsWithEntries(limit, since) {
const data2 = await this.fetchJson(`/v1/evals/bot/${this.botId}/runs`, {
limit: String(limit)
});
let runs = data2.runs;
if (since) {
runs = runs.filter((r) => new Date(r.createdAt).getTime() >= since);
}
return mapWithConcurrency(runs, 8, (r) => this.fetchJson(`/v1/evals/runs/${r.id}`));
}
async fetch(path, init) {
const target = new URL(`${this.url}${path}`);
const headers = new Headers(init?.headers);
if (this.token)
headers.set("Authorization", `Bearer ${this.token}`);
return globalThis.fetch(target, { ...init, headers });
}
async fetchJson(path, params) {
const target = new URL(`${this.url}${path}`);
if (params) {
for (const [k, v] of Object.entries(params))
target.searchParams.set(k, v);
}
const headers = new Headers;
if (this.token)
headers.set("Authorization", `Bearer ${this.token}`);
const res = await globalThis.fetch(target, { headers });
if (!res.ok) {
const text2 = await res.text().catch(() => "");
throw new Error(`Vortex ${res.status}: ${text2}`);
}
return res.json();
}
};
// ../evals/dist/spans/index.js
function spanKey2(span) {
return `${span.id.trace}:${span.id.span}`;
}
function spanData2(span) {
return span.data && typeof span.data === "object" ? span.data : {};
}
function normalizeSpan(span) {
if (span.status !== "running")
return span;
const data2 = spanData2(span);
const autonomousStatus = data2["autonomous.status"];
if (autonomousStatus === "generation_error" || autonomousStatus === "execution_error" || autonomousStatus === "invalid_code_error" || autonomousStatus === "exit_error" || autonomousStatus === "aborted") {
return { ...span, status: "error" };
}
if (autonomousStatus === "thinking_requested" || autonomousStatus === "callback_requested" || autonomousStatus === "exit_success") {
return { ...span, status: "ok" };
}
const { startedAt, endedAt } = span.timing;
if (typeof endedAt === "number" && Number.isFinite(endedAt) && endedAt > startedAt) {
return { ...span, status: "ok" };
}
return span;
}
function sleep(ms, signal) {
return new Promise((resolve2, reject) => {
if (signal?.aborted)
return reject(new Error("aborted"));
const onAbort = () => {
clearTimeout(timer);
reject(new Error("aborted"));
};
const timer = setTimeout(() => {
signal?.removeEventListener("abort", onAbort);
resolve2();
}, ms);
signal?.addEventListener("abort", onAbort, { once: true });
});
}
var VortexSpanSource = class _VortexSpanSource {
config;
conversationId = "";
traceIds = /* @__PURE__ */ new Set;
spanMap = /* @__PURE__ */ new Map;
turnStartKeys = /* @__PURE__ */ new Set;
seenHandlerKeys = /* @__PURE__ */ new Set;
consecutiveFailures = 0;
constructor(config) {
this.config = {
url: config.url.replace(/\/$/, ""),
botId: config.botId,
pollIntervalMs: config.pollIntervalMs ?? 500,
...config.workspaceId ? { workspaceId: config.workspaceId } : {},
...config.token ? { token: config.token } : {}
};
}
async connect(filter2) {
this.conversationId = filter2.conversationId;
await this._pollOnce();
}
async repoint(filter2) {
this.conversationId = filter2.conversationId;
this.traceIds = /* @__PURE__ */ new Set;
await this._pollOnce();
}
static TURN_HANDLER_SPAN_NAMES = /* @__PURE__ */ new Set(["handler.conversation", "handler.event"]);
startTurn() {
this.turnStartKeys = new Set(this.spanMap.keys());
for (const [key, span] of this.spanMap) {
if (_VortexSpanSource.TURN_HANDLER_SPAN_NAMES.has(span.name)) {
this.seenHandlerKeys.add(key);
}
}
}
static SETTLE_POLLS = 3;
async waitForTurnComplete(opts) {
const deadline = Date.now() + opts.timeout;
const maxPolls = opts.settleMaxMs ? Math.floor(opts.settleMaxMs / this.config.pollIntervalMs) : Infinity;
const settlePolls = Math.min(maxPolls, Math.max(_VortexSpanSource.SETTLE_POLLS, opts.settleQuietMs ? Math.ceil(opts.settleQuietMs / this.config.pollIntervalMs) : 0));
while (Date.now() < deadline) {
if (opts.abortSignal?.aborted)
throw new Error("waitForTurnComplete aborted");
await this._pollOnce();
if (this._hasNewCompletedHandler(opts.acceptSpanNames)) {
for (let i = 0;i < settlePolls; i++) {
await sleep(this.config.pollIntervalMs, opts.abortSignal).catch(() => {});
await this._pollOnce();
}
return;
}
await sleep(this.config.pollIntervalMs, opts.abortSignal).catch(() => {});
}
throw new Error(`waitForTurnComplete timed out after ${opts.timeout}ms`);
}
async waitForWorkflow(name, opts) {
const deadline = Date.now() + opts.timeout;
while (Date.now() < deadline) {
if (opts.abortSignal?.aborted)
throw new Error(`waitForWorkflow("${name}") aborted`);
await this._pollOnce();
if (this._matchesWorkflowCondition(name, opts.signal))
return;
await sleep(this.config.pollIntervalMs, opts.abortSignal).catch(() => {});
}
throw new Error(`waitForWorkflow("${name}", { signal: "${opts.signal}" }) timed out after ${opts.timeout}ms`);
}
getTurnSpans() {
const result = [];
for (const [key, span] of this.spanMap) {
if (!this.turnStartKeys.has(key)) {
result.push(span);
}
}
return result;
}
getAllSpans() {
return Array.from(this.spanMap.values());
}
disconnect() {}
async _pollOnce() {
const url = new URL(`${this.config.url}/v1/traces/bot/${this.config.botId}/spans/adk`);
url.searchParams.set("conversationId", this.conversationId);
for (const traceId of this.traceIds) {
url.searchParams.append("traceId", traceId);
}
const res = await fetch(url, {
headers: {
Accept: "application/json",
...this.config.token ? { Authorization: `Bearer ${this.config.token}` } : {}
}
});
if (!res.ok) {
this.consecutiveFailures++;
const body = await res.text().catch(() => "");
const msg = `Vortex poll failed: ${res.status} ${body.slice(0, 200)}`;
if (this.consecutiveFailures >= 5) {
throw new Error(`${msg} (${this.consecutiveFailures} consecutive failures)`);
}
console.warn(`[VortexSpanSource] ${msg}`);
return;
}
this.consecutiveFailures = 0;
const payload = await res.json();
const spans = Array.isArray(payload) ? payload : Array.isArray(payload.spans) ? payload.spans : [];
for (const rawSpan of spans) {
const span = normalizeSpan(rawSpan);
this.spanMap.set(spanKey2(span), span);
this.traceIds.add(span.id.trace);
}
}
_hasNewCompletedHandler(acceptSpanNames) {
for (const [key, span] of this.spanMap) {
if (_VortexSpanSource.TURN_HANDLER_SPAN_NAMES.has(span.name) && (!acceptSpanNames || acceptSpanNames.has(span.name)) && !this.seenHandlerKeys.has(key) && (span.status === "ok" || span.status === "error")) {
this.seenHandlerKeys.add(key);
return true;
}
}
return false;
}
_matchesWorkflowCondition(name, signal) {
for (const span of this.spanMap.values()) {
if (span.name !== "handler.workflow")
continue;
const d = spanData2(span);
const wfName = d["workflow.name"] || d["workflowName"];
if (wfName !== name)
continue;
if (signal === "entered")
return true;
if (signal === "completed")
return span.status === "ok" || span.status === "error";
}
return false;
}
};
// ../../node_modules/.bun/ulid@3.0.2/node_modules/ulid/dist/node/index.js
import crypto from "crypto";
var ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ";
var ENCODING_LEN = 32;
var RANDOM_LEN = 16;
var TIME_LEN = 10;
var TIME_MAX = 281474976710655;
var ULIDErrorCode;
(function(ULIDErrorCode2) {
ULIDErrorCode2["Base32IncorrectEncoding"] = "B32_ENC_INVALID";
ULIDErrorCode2["DecodeTimeInvalidCharacter"] = "DEC_TIME_CHAR";
ULIDErrorCode2["DecodeTimeValueMalformed"] = "DEC_TIME_MALFORMED";
ULIDErrorCode2["EncodeTimeNegative"] = "ENC_TIME_NEG";
ULIDErrorCode2["EncodeTimeSizeExceeded"] = "ENC_TIME_SIZE_EXCEED";
ULIDErrorCode2["EncodeTimeValueMalformed"] = "ENC_TIME_MALFORMED";
ULIDErrorCode2["PRNGDetectFailure"] = "PRNG_DETECT";
ULIDErrorCode2["ULIDInvalid"] = "ULID_INVALID";
ULIDErrorCode2["Unexpected"] = "UNEXPECTED";
ULIDErrorCode2["UUIDInvalid"] = "UUID_INVALID";
})(ULIDErrorCode || (ULIDErrorCode = {}));
class ULIDError extends Error {
constructor(errorCode, message) {
super(`${message} (${errorCode})`);
this.name = "ULIDError";
this.code = errorCode;
}
}
function randomChar(prng) {
const randomPosition = Math.floor(prng() * ENCODING_LEN) % ENCODING_LEN;
return ENCODING.charAt(randomPosition);
}
function detectPRNG(root2) {
const rootLookup = detectRoot();
const globalCrypto = rootLookup && (rootLookup.crypto || rootLookup.msCrypto) || (typeof crypto !== "undefined" ? crypto : null);
if (typeof globalCrypto?.getRandomValues === "function") {
return () => {
const buffer = new Uint8Array(1);
globalCrypto.getRandomValues(buffer);
return buffer[0] / 256;
};
} else if (typeof globalCrypto?.randomBytes === "function") {
return () => globalCrypto.randomBytes(1).readUInt8() / 256;
} else if (crypto?.randomBytes) {
return () => crypto.randomBytes(1).readUInt8() / 256;
}
throw new ULIDError(ULIDErrorCode.PRNGDetectFailure, "Failed to find a reliable PRNG");
}
function detectRoot() {
if (inWebWorker())
return self;
if (typeof window !== "undefined") {
return window;
}
if (typeof global !== "undefined") {
return global;
}
if (typeof globalThis !== "undefined") {
return globalThis;
}
return null;
}
function encodeRandom(len, prng) {
let str = "";
for (;len > 0; len--) {
str = randomChar(prng) + str;
}
return str;
}
function encodeTime(now, len = TIME_LEN) {
if (isNaN(now)) {
throw new ULIDError(ULIDErrorCode.EncodeTimeValueMalformed, `Time must be a number: ${now}`);
} else if (now > TIME_MAX) {
throw new ULIDError(ULIDErrorCode.EncodeTimeSizeExceeded, `Cannot encode a time larger than ${TIME_MAX}: ${now}`);
} else if (now < 0) {
throw new ULIDError(ULIDErrorCode.EncodeTimeNegative, `Time must be positive: ${now}`);
} else if (Number.isInteger(now) === false) {
throw new ULIDError(ULIDErrorCode.EncodeTimeValueMalformed, `Time must be an integer: ${now}`);
}
let mod, str = "";
for (let currentLen = len;currentLen > 0; currentLen--) {
mod = now % ENCODING_LEN;
str = ENCODING.charAt(mod) + str;
now = (now - mod) / ENCODING_LEN;
}
return str;
}
function inWebWorker() {
return typeof WorkerGlobalScope !== "undefined" && self instanceof WorkerGlobalScope;
}
function ulid(seedTime, prng) {
const currentPRNG = prng || detectPRNG();
const seed = !seedTime || isNaN(seedTime) ? Date.now() : seedTime;
return encodeTime(seed, TIME_LEN) + encodeRandom(RANDOM_LEN, currentPRNG);
}
export { require_dist, EVAL_MANIFEST_SCHEMA_VERSION, EVAL_MANIFEST_TAGS, Zai, runEvalSuite, VortexEvalStore, VortexSpanSource, ulid };