UNPKG

@botpress/adk-cli

Version:

Command-line interface for the Botpress Agent Development Kit (ADK)

1,169 lines (1,165 loc) 38.8 kB
// @bun import { Tool } from "./chunk-knvm2anf.js"; import { Exit } from "./chunk-65h5trb5.js"; import { LoopExceededError } from "./chunk-nn2jb0x0.js"; import { DualModePrompt, extractType, inspect } from "./chunk-v8xvth6j.js"; import { wrapContent } from "./chunk-kkk13rcb.js"; import { assertValidComponent } from "./chunk-f4bw8q7c.js"; import { cloneDeep_default, exports_exports, isPlainObject_default, omit_default } from "./chunk-54qt5g7m.js"; import { __require } from "./chunk-dhs2bg35.js"; // ../../node_modules/.bun/ulid@2.4.0/node_modules/ulid/dist/index.esm.js function createError(message) { const err = new Error(message); err.source = "ulid"; return err; } var ENCODING = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"; var ENCODING_LEN = ENCODING.length; var TIME_MAX = Math.pow(2, 48) - 1; var TIME_LEN = 10; var RANDOM_LEN = 16; function randomChar(prng) { let rand = Math.floor(prng() * ENCODING_LEN); if (rand === ENCODING_LEN) { rand = ENCODING_LEN - 1; } return ENCODING.charAt(rand); } function encodeTime(now, len) { if (isNaN(now)) { throw new Error(now + " must be a number"); } if (now > TIME_MAX) { throw createError("cannot encode time greater than " + TIME_MAX); } if (now < 0) { throw createError("time must be positive"); } if (Number.isInteger(Number(now)) === false) { throw createError("time must be an integer"); } let mod; let str = ""; for (;len > 0; len--) { mod = now % ENCODING_LEN; str = ENCODING.charAt(mod) + str; now = (now - mod) / ENCODING_LEN; } return str; } function encodeRandom(len, prng) { let str = ""; for (;len > 0; len--) { str = randomChar(prng) + str; } return str; } function detectPrng(allowInsecure = false, root) { if (!root) { root = typeof window !== "undefined" ? window : null; } const browserCrypto = root && (root.crypto || root.msCrypto); if (browserCrypto) { return () => { const buffer = new Uint8Array(1); browserCrypto.getRandomValues(buffer); return buffer[0] / 255; }; } else { try { const nodeCrypto = __require("crypto"); return () => nodeCrypto.randomBytes(1).readUInt8() / 255; } catch (e) {} } if (allowInsecure) { try { console.error("secure crypto unusable, falling back to insecure Math.random()!"); } catch (e) {} return () => Math.random(); } throw createError("secure crypto unusable, insecure Math.random not allowed"); } function factory(currPrng) { if (!currPrng) { currPrng = detectPrng(); } return function ulid(seedTime) { if (isNaN(seedTime)) { seedTime = Date.now(); } return encodeTime(seedTime, TIME_LEN) + encodeRandom(RANDOM_LEN, currPrng); }; } var ulid = factory(); // ../../node_modules/.bun/llmz@0.0.79+b49d396f5ed96e7f/node_modules/llmz/dist/chunk-ESMRQVFC.js function isValuePrimitive(value) { return value === null || value === undefined || typeof value !== "object" || Array.isArray(value); } function generatePossibleWraps(value, shape, discriminator) { const possibleWraps = []; const commonNames = ["result", "value", "data", "message", "error", "output", "response"]; if (shape && typeof shape === "object") { for (const key of Object.keys(shape)) { if (key !== discriminator) { const wrap = discriminator ? { [discriminator]: shape[discriminator]._def.value, [key]: value } : { [key]: value }; possibleWraps.push(wrap); } } } for (const name of commonNames) { const hasName = possibleWraps.some((w) => Object.keys(w).includes(name)); if (!hasName) { const wrap = discriminator && (shape == null ? undefined : shape[discriminator]) ? { [discriminator]: shape[discriminator]._def.value, [name]: value } : { [name]: value }; possibleWraps.push(wrap); } } return possibleWraps; } function tryObjectWrapping(schema, candidateValue) { const possibleWraps = generatePossibleWraps(candidateValue, schema.shape); for (const wrap of possibleWraps) { const testParse = schema.safeParse(wrap); if (testParse.success) { return { success: true, valueToValidate: wrap, parsed: testParse }; } } return { success: false, valueToValidate: candidateValue, parsed: { success: false } }; } function detectDiscriminator(options) { if (options.length === 0 || options[0]._def.typeName !== "ZodObject") { return; } const firstShape = options[0].shape; for (const key in firstShape) { const firstFieldType = firstShape[key]._def.typeName; if (firstFieldType === "ZodLiteral") { const allHaveLiteral = options.every((opt) => { var _a; return ((_a = opt.shape[key]) == null ? undefined : _a._def.typeName) === "ZodLiteral"; }); if (allHaveLiteral) { return key; } } } return; } function tryAddDiscriminator(schema, options, discriminator, valueToValidate) { const matchingOptions = []; for (const option of options) { if (option._def.typeName === "ZodObject" && option.shape[discriminator]) { const discriminatorValue = option.shape[discriminator]._def.value; const wrappedValue = { [discriminator]: discriminatorValue, ...valueToValidate }; const testParse = schema.safeParse(wrappedValue); if (testParse.success) { matchingOptions.push({ wrappedValue }); } } } if (matchingOptions.length === 1) { const wrapped = matchingOptions[0].wrappedValue; return { success: true, valueToValidate: wrapped, parsed: schema.safeParse(wrapped) }; } return { success: false, valueToValidate, parsed: { success: false } }; } function tryUnionPrimitiveWrapping(schema, options, discriminator, valueToValidate) { const allSuccessfulWraps = []; for (const option of options) { if (option._def.typeName === "ZodObject" && option.shape[discriminator]) { const discriminatorValue = option.shape[discriminator]._def.value; const possibleWraps = generatePossibleWraps(valueToValidate, option.shape, discriminator); for (const wrap of possibleWraps) { const finalWrap = { [discriminator]: discriminatorValue, ...wrap }; const testParse = schema.safeParse(finalWrap); if (testParse.success) { allSuccessfulWraps.push({ wrap: finalWrap }); break; } } } } if (allSuccessfulWraps.length === 1) { const wrapped = allSuccessfulWraps[0].wrap; return { success: true, valueToValidate: wrapped, parsed: schema.safeParse(wrapped) }; } return { success: false, valueToValidate, parsed: { success: false } }; } function tryUnionWrapping(schema, valueToValidate) { const options = schema._def.options; let discriminator = schema._def.discriminator; if (!discriminator) { discriminator = detectDiscriminator(options); } if (!discriminator) { return { success: false, valueToValidate, parsed: { success: false } }; } const isValueObject = valueToValidate !== null && typeof valueToValidate === "object" && !Array.isArray(valueToValidate); const isPrimitive = isValuePrimitive(valueToValidate); if (isValueObject && !(discriminator in valueToValidate)) { const result = tryAddDiscriminator(schema, options, discriminator, valueToValidate); if (result.success) { return result; } } if (isPrimitive) { return tryUnionPrimitiveWrapping(schema, options, discriminator, valueToValidate); } return { success: false, valueToValidate, parsed: { success: false } }; } function trySmartWrapping(schema, schemaType, valueToValidate, alternativeValue) { const valuesToTry = [valueToValidate]; if (alternativeValue !== undefined && alternativeValue !== valueToValidate) { valuesToTry.push(alternativeValue); } for (const candidateValue of valuesToTry) { const isPrimitive = isValuePrimitive(candidateValue); if (schemaType === "ZodObject" && isPrimitive) { const result = tryObjectWrapping(schema, candidateValue); if (result.success) { return result; } } } if (alternativeValue !== undefined && alternativeValue !== valueToValidate) { valueToValidate = alternativeValue; } if (schemaType === "ZodDiscriminatedUnion" || schemaType === "ZodUnion") { const result = tryUnionWrapping(schema, valueToValidate); if (result.success) { return result; } } return { valueToValidate, parsed: { success: false } }; } function parseExit(returnValue, exits) { if (!returnValue) { return { success: false, error: "No return value provided", returnValue }; } const returnAction = returnValue.action; if (!returnAction) { return { success: false, error: `Code did not return an action. Valid actions are: ${exits.map((x) => x.name).join(", ")}`, returnValue }; } const returnExit = exits.find((x) => x.name.toLowerCase() === returnAction.toLowerCase()) ?? exits.find((x) => x.aliases.some((a) => a.toLowerCase() === returnAction.toLowerCase())); if (!returnExit) { return { success: false, error: `Exit "${returnAction}" not found. Valid actions are: ${exits.map((x) => x.name).join(", ")}`, returnValue }; } if (!returnExit.zSchema) { const otherProps = omit_default(returnValue, "action"); const value = Object.keys(otherProps).length === 1 ? Object.values(otherProps)[0] : otherProps; return { success: true, exit: returnExit, value }; } let valueToValidate = returnValue.value; let alternativeValue = undefined; if (valueToValidate === undefined) { const otherProps = omit_default(returnValue, "action"); if (Object.keys(otherProps).length > 0) { valueToValidate = otherProps; if (Object.keys(otherProps).length === 1) { alternativeValue = Object.values(otherProps)[0]; } } } const schema = returnExit.zSchema; const schemaType = schema._def.typeName; let parsed = schema.safeParse(valueToValidate); if (!parsed.success && alternativeValue !== undefined && alternativeValue !== valueToValidate) { const altParsed = schema.safeParse(alternativeValue); if (altParsed.success) { parsed = altParsed; valueToValidate = alternativeValue; } } if (!parsed.success) { const result = trySmartWrapping(schema, schemaType, valueToValidate, alternativeValue); valueToValidate = result.valueToValidate; parsed = result.parsed; } if (!parsed.success) { const getValueTypeDescription = (val) => { if (val === null) return "null"; if (val === undefined) return "undefined"; if (Array.isArray(val)) return "array"; return typeof val; }; const generatedType = getValueTypeDescription(valueToValidate); let generatedStatement = `return { action: '${returnAction}'`; if (returnValue.value !== undefined) { generatedStatement += `, value: ${generatedType}`; } else { const otherProps = omit_default(returnValue, "action"); const propKeys = Object.keys(otherProps); if (propKeys.length === 1) { generatedStatement += `, ${propKeys[0]}: ${generatedType}`; } else if (propKeys.length > 1) { generatedStatement += `, ${propKeys.join(", ")}`; } } generatedStatement += " }"; const expectedStatements = []; for (const exit of exits) { let statement = `return { action: '${exit.name}'`; if (exit.zSchema) { const schema2 = exit.zSchema; const typeName = schema2._def.typeName; if (typeName === "ZodObject") { const shape = schema2.shape; const properties = Object.keys(shape).map((key) => { var _a; const field = shape[key]; const fieldType = field._def.typeName || "unknown"; const isOptional = ((_a = field.isOptional) == null ? undefined : _a.call(field)) || false; return `${key}${isOptional ? "?" : ""}: ${fieldType.replace("Zod", "").toLowerCase()}`; }); statement += `, value: { ${properties.join(", ")} }`; } else if (typeName === "ZodUnion" || typeName === "ZodDiscriminatedUnion") { const options = schema2._def.options || []; const variants = options.map((opt) => { if (opt._def.typeName === "ZodObject") { const shape = opt.shape; const properties = Object.keys(shape).map((key) => { const field = shape[key]; const fieldType = field._def.typeName || "unknown"; return `${key}: ${fieldType.replace("Zod", "").toLowerCase()}`; }); return `{ ${properties.join(", ")} }`; } return "unknown"; }); statement += `, value: ${variants.join(" | ")}`; } else { const schemaTypeName = (typeName == null ? undefined : typeName.replace("Zod", "").toLowerCase()) || "unknown"; statement += `, value: ${schemaTypeName}`; } } statement += " }"; expectedStatements.push(statement); } const errorMessage = [ `Invalid return value for exit "${returnExit.name}"`, "", "You generated:", ` ${generatedStatement}`, "", "But expected one of:", ...expectedStatements.map((s) => ` ${s}`) ].join(` `); return { success: false, error: errorMessage, returnValue }; } return { success: true, exit: returnExit, value: parsed.data }; } var MAX_SNAPSHOT_SIZE_BYTES = 4000; var Snapshot = class _Snapshot { id; reason; stack; toolCall; variables; #status; get status() { return Object.freeze({ ...this.#status }); } constructor(props) { this.id = props.id; this.stack = props.stack; this.reason = props.reason; this.variables = props.variables; this.toolCall = props.toolCall; this.#status = props.status; } static fromSignal(signal) { return new _Snapshot({ id: "snapshot_" + ulid(), reason: signal.message, stack: signal.truncatedCode, variables: parseVariables(signal.variables), toolCall: signal.toolCall, status: { type: "pending" } }); } toJSON() { return { id: this.id, reason: this.reason, stack: this.stack, variables: this.variables, toolCall: this.toolCall, status: this.#status }; } static fromJSON(json) { return new _Snapshot({ id: json.id, reason: json.reason, stack: json.stack, variables: json.variables, toolCall: json.toolCall, status: json.status }); } clone() { return new _Snapshot({ id: this.id, reason: this.reason, stack: this.stack, variables: this.variables, toolCall: this.toolCall, status: this.#status }); } reset() { this.#status = { type: "pending" }; } resolve(value) { var _a; if (this.#status.type !== "pending") { throw new Error(`Cannot resolve snapshot because it is already settled: ${this.#status.type}`); } const assignment = (_a = this.toolCall) == null ? undefined : _a.assignment; if (assignment) { try { const fn = new Function(assignment.evalFn); const assignmentValue = fn(value); this.variables = [...this.variables, ...parseVariables(assignmentValue)]; } catch {} } this.#status = { type: "resolved", value }; } reject(error) { if (this.#status.type !== "pending") { throw new Error(`Cannot reject snapshot because it is already settled: ${this.#status.type}`); } this.#status = { type: "rejected", error }; } }; function parseVariables(variableMap) { return Object.entries(variableMap).map(([name, value]) => { const type = extractType(value); const bytes = JSON.stringify(value || "").length; const truncated = bytes > MAX_SNAPSHOT_SIZE_BYTES; return truncated ? { name, type, bytes, truncated: true, preview: inspect(value, name) ?? "N/A" } : { name, type, bytes, truncated: false, value }; }); } var MAX_MESSAGE_LENGTH = 5000; function getMessagePreview(message) { if (message.role === "assistant" || message.role === "user" || message.role === "summary") { return message.content; } if (message.role === "event") { return inspect(message.payload, message.name, { tokens: 1000 }); } return inspect(message, undefined, { tokens: 1000 }); } function getMessageType(message) { if (message.role === "assistant" || message.role === "user" || message.role === "summary") { return message.role; } if (message.role === "event") { return `event:${message.name}`; } return "unknown"; } var TranscriptArray = class extends Array { constructor(items = []) { items = Array.isArray(items) ? items : []; super(...items); items.forEach((item) => { if (!["user", "assistant", "event", "summary"].includes(item.role)) { throw new Error(`Invalid role "${item.role}" in transcript message`); } if ("name" in item && item.name && typeof item.name !== "string") { throw new Error(`Invalid name for transcript message. Expected a string, but got type "${typeof item.name}"`); } if ("content" in item && typeof item.content !== "string") { throw new Error(`Invalid content for transcript message. Expected a string, but got type "${typeof item.content}"`); } }); Object.setPrototypeOf(this, new.target.prototype); } toString() { if (!this.length) { return ""; } return this.map((item, idx) => { var _a, _b; const msgIdx = getMessageType(item) + "-" + String(idx + 1).padStart(3, "0"); let preview = getMessagePreview(item); if (preview.length > MAX_MESSAGE_LENGTH) { preview = preview.slice(0, MAX_MESSAGE_LENGTH) + ` ... (truncated)`; } const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; if ((item.role === "event" || item.role === "user") && ((_a = item.attachments) == null ? undefined : _a.length)) { for (let i = 0;i < item.attachments.length; i++) { const attachmentIdx = alphabet[i % alphabet.length]; preview += ` [Attachment ${msgIdx}-${attachmentIdx}]`; } } const tags = []; tags.push({ key: "role", value: item.role }); if ("name" in item && ((_b = item.name) == null ? undefined : _b.length)) { tags.push({ key: "name", value: item.name }); } const tagsString = tags.map(({ key, value }) => `${key}="${value}"`).join(" "); return `<${msgIdx} ${tagsString}> ${preview.trim()} </${msgIdx}>`; }).join(` `); } }; var ExecutionResult = class { status; context; constructor(status, context) { this.status = status; this.context = context; } isSuccess() { return this.status === "success" && this instanceof SuccessExecutionResult; } isError() { return this.status === "error" && this instanceof ErrorExecutionResult; } isInterrupted() { return this.status === "interrupted" && this instanceof PartialExecutionResult; } is(exit) { return this.status === "success" && this instanceof SuccessExecutionResult && this.result.exit === exit; } get output() { return this.isSuccess() ? this.result.result : null; } get iteration() { return this.context.iterations.at(-1) || null; } get iterations() { return this.context.iterations ?? []; } }; var SuccessExecutionResult = class extends ExecutionResult { result; constructor(context, result) { super("success", context); this.result = result; } get output() { return this.result.result; } get iteration() { return this.context.iterations.at(-1); } toJSON() { return { status: "success", context: this.context.toJSON(), result: { exit: this.result.exit.toJSON(), result: this.result.result } }; } }; var ErrorExecutionResult = class extends ExecutionResult { error; constructor(context, error) { super("error", context); this.error = error; } get output() { return null; } toJSON() { return { status: "error", context: this.context.toJSON(), error: this.error }; } }; var PartialExecutionResult = class extends ExecutionResult { signal; snapshot; constructor(context, signal, snapshot) { super("interrupted", context); this.signal = signal; this.snapshot = snapshot; } get output() { return null; } toJSON() { return { status: "interrupted", context: this.context.toJSON(), snapshot: this.snapshot.toJSON(), signal: { message: this.signal.message, truncatedCode: this.signal.truncatedCode, variables: this.signal.variables } }; } }; var getValue = async (valueOrGetter, ctx) => { if (typeof valueOrGetter === "function") { try { return await valueOrGetter(ctx); } catch (e) { throw new Error(`Error while getting value for ${valueOrGetter}: ${e}`); } } else { return valueOrGetter; } }; var Emitter = class { _handlers = []; subscribe = (fn) => { this._handlers.push(fn); return () => { this._handlers = this._handlers.filter((handler) => handler !== fn); }; }; emit(event) { this._handlers.forEach((handler) => handler(event)); } }; var HookedArray = class extends Array { #listeners = new Emitter; constructor(...items) { super(...items); Object.setPrototypeOf(this, new.target.prototype); } push(...items) { try { this.#listeners.emit(items); } finally { return super.push(...items); } } onPush(fn) { return this.#listeners.subscribe(fn); } }; var ThinkExit = new Exit({ name: "think", description: "Think about the current situation and provide a response" }); var ListenExit = new Exit({ name: "listen", description: "Listen to the user and provide a response" }); var DefaultExit = new Exit({ name: "done", description: "When the execution is sucessfully completed or when error recovery is not possible", schema: exports_exports.discriminatedUnion("success", [ exports_exports.object({ success: exports_exports.literal(true), result: exports_exports.any().describe("The result of the execution") }), exports_exports.object({ success: exports_exports.literal(false), error: exports_exports.string().describe("The error message if the execution failed") }) ]) }); var Iteration = class { id; messages; code; traces; variables; started_ts; ended_ts; status; _mutations; get mutations() { return [...this._mutations.values()]; } trackMutation(mutation) { this._mutations.set(`${mutation.object ?? "global"}:${mutation.property}`, mutation); } _parameters; get transcript() { return this._parameters.transcript; } get tools() { return this._parameters.tools; } get objects() { return this._parameters.objects; } get model() { return this._parameters.model; } set model(value) { this._parameters.model = value; } get temperature() { return this._parameters.temperature; } get reasoningEffort() { return this._parameters.reasoningEffort; } get exits() { const exits = [...this._parameters.exits, ThinkExit]; if (this.isChatEnabled) { exits.push(ListenExit); } return exits; } get instructions() { return this._parameters.instructions; } llm; hasExited() { return ["exit_success"].includes(this.status.type); } hasExitedWith(exit) { return this.status.type === "exit_success" && this.status.exit_success.exit_name === exit.name; } isSuccessful() { return ["callback_requested", "exit_success", "thinking_requested"].includes(this.status.type); } isFailed() { return [ "generation_error", "invalid_code_error", "execution_error", "exit_error", "aborted" ].includes(this.status.type); } get duration() { const ms = (this.ended_ts ?? Date.now()) - this.started_ts; const trailing = this.ended_ts ? "" : " (still running)"; return ms.toLocaleString("en-US", { style: "unit", unit: "millisecond" }) + trailing; } get error() { if (this.status.type === "generation_error") { return `CodeGenerationError: ${this.status.generation_error.message}`; } if (this.status.type === "invalid_code_error") { return `InvalidCodeError: ${this.status.invalid_code_error.message}`; } if (this.status.type === "execution_error") { return `CodeExecutionError: ${this.status.execution_error.message}`; } if (this.status.type === "exit_error") { return `ExitError: ${this.status.exit_error.message}`; } if (this.status.type === "aborted") { return `Aborted: ${this.status.aborted.reason}`; } return null; } get isChatEnabled() { return this._parameters.tools.find((x) => x.name.toLowerCase() === "message") !== undefined; } constructor(props) { this.id = props.id; this.status = { type: "pending" }; this.traces = new HookedArray; this._mutations = /* @__PURE__ */ new Map; this.messages = props.messages; this.variables = props.variables; this._parameters = props.parameters; this.started_ts = Date.now(); } end(status) { if (this.status.type !== "pending") { throw new Error(`Iteration ${this.id} has already ended with status ${this.status.type}`); } this.ended_ts = Date.now(); this.status = status; } toJSON() { return { id: this.id, messages: [...this.messages], code: this.code, model: this.model, temperature: this.temperature, reasoningEffort: this.reasoningEffort, traces: [...this.traces], variables: this.variables, started_ts: this.started_ts, ended_ts: this.ended_ts, status: this.status, mutations: [...this._mutations.values()], llm: this.llm, transcript: [...this._parameters.transcript], tools: this._parameters.tools.map((tool) => tool.toJSON()), objects: this._parameters.objects.map((obj) => obj.toJSON()), exits: this._parameters.exits.map((exit) => exit.toJSON()), instructions: this._parameters.instructions, duration: this.duration, error: this.error, isChatEnabled: this.isChatEnabled }; } }; var Context = class { id; chat; instructions; objects; tools; exits; model; temperature; reasoningEffort; version = DualModePrompt; timeout = 60000; loop; metadata; snapshot; iteration = 0; iterations; async nextIteration() { if (this.iterations.length >= this.loop) { throw new LoopExceededError; } if (this.snapshot && this.snapshot.status.type === "pending") { throw new Error(`Cannot resume execution from a snapshot that is still pending: ${this.snapshot.id}. Please resolve() or reject() it first.`); } const parameters = await this._refreshIterationParameters(); const messages = await this._getIterationMessages(parameters); const iteration = new Iteration({ id: `${this.id}_${this.iterations.length + 1}`, variables: this._getIterationVariables(), parameters, messages }); this.iterations.push(iteration); this.iteration = this.iterations.length; this.snapshot = undefined; return iteration; } _getIterationVariables() { var _a; const lastIteration = this.iterations.at(-1); const variables = {}; if ((lastIteration == null ? undefined : lastIteration.status.type) === "thinking_requested") { const lastThinkingVariables = lastIteration.status.thinking_requested.variables; if (isPlainObject_default(lastThinkingVariables)) { Object.assign(variables, cloneDeep_default(lastThinkingVariables)); } } if (isPlainObject_default(lastIteration == null ? undefined : lastIteration.variables)) { Object.assign(variables, cloneDeep_default((lastIteration == null ? undefined : lastIteration.variables) ?? {})); } if (((_a = this.snapshot) == null ? undefined : _a.status.type) === "resolved") { for (const v of this.snapshot.variables) { if (!v.truncated && v.value !== undefined) { variables[v.name] = v.value; } } } return variables; } async _getIterationMessages(parameters) { var _a, _b, _c, _d, _e, _f; const lastIteration = this.iterations.at(-1); if (((_a = this.snapshot) == null ? undefined : _a.status.type) === "resolved") { return [ await this.version.getSystemMessage({ globalTools: parameters.tools, objects: parameters.objects, instructions: parameters.instructions, transcript: parameters.transcript, exits: parameters.exits, components: parameters.components }), this.version.getSnapshotResolvedMessage({ snapshot: this.snapshot }) ]; } if (((_b = this.snapshot) == null ? undefined : _b.status.type) === "rejected") { return [ await this.version.getSystemMessage({ globalTools: parameters.tools, objects: parameters.objects, instructions: parameters.instructions, transcript: parameters.transcript, exits: parameters.exits, components: parameters.components }), this.version.getSnapshotRejectedMessage({ snapshot: this.snapshot }) ]; } if (!lastIteration) { return [ await this.version.getSystemMessage({ globalTools: parameters.tools, objects: parameters.objects, instructions: parameters.instructions, transcript: parameters.transcript, exits: parameters.exits, components: parameters.components }), await this.version.getInitialUserMessage({ globalTools: parameters.tools, objects: parameters.objects, instructions: parameters.instructions, transcript: parameters.transcript, exits: parameters.exits, components: parameters.components }) ]; } const lastIterationMessages = [ await this.version.getSystemMessage({ globalTools: parameters.tools, objects: parameters.objects, instructions: parameters.instructions, transcript: parameters.transcript, exits: parameters.exits, components: parameters.components }), ...lastIteration.messages.filter((x) => x.role !== "system") ]; if ((lastIteration == null ? undefined : lastIteration.status.type) === "thinking_requested") { return [ ...lastIterationMessages, { role: "assistant", content: wrapContent(((_c = lastIteration.llm) == null ? undefined : _c.output) ?? "", { preserve: "top", flex: 4, minTokens: 25 }) }, await this.version.getThinkingMessage({ reason: lastIteration.status.thinking_requested.reason, variables: lastIteration.status.thinking_requested.variables }) ]; } if ((lastIteration == null ? undefined : lastIteration.status.type) === "exit_error") { return [ ...lastIterationMessages, { role: "assistant", content: wrapContent(((_d = lastIteration.llm) == null ? undefined : _d.output) ?? "", { preserve: "top", flex: 4, minTokens: 25 }) }, await this.version.getInvalidCodeMessage({ code: lastIteration.code ?? "// No code generated", message: `Invalid return statement (action: ${lastIteration.status.exit_error.exit}): ${lastIteration.status.exit_error.message}` }) ]; } if ((lastIteration == null ? undefined : lastIteration.status.type) === "invalid_code_error") { return [ ...lastIterationMessages, { role: "assistant", content: wrapContent(((_e = lastIteration.llm) == null ? undefined : _e.output) ?? "", { preserve: "top", flex: 4, minTokens: 25 }) }, await this.version.getInvalidCodeMessage({ code: lastIteration.code ?? "// No code generated", message: lastIteration.status.invalid_code_error.message }) ]; } if ((lastIteration == null ? undefined : lastIteration.status.type) === "execution_error") { return [ ...lastIterationMessages, { role: "assistant", content: wrapContent(((_f = lastIteration.llm) == null ? undefined : _f.output) ?? "", { preserve: "top", flex: 4, minTokens: 25 }) }, await this.version.getCodeExecutionErrorMessage({ message: lastIteration.status.execution_error.message, stacktrace: lastIteration.status.execution_error.stack }) ]; } throw new Error(`Unexpected iteration status: ${lastIteration == null ? undefined : lastIteration.status.type}. This is likely a bug, please report it.`); } async _refreshIterationParameters() { var _a, _b; const instructions = await getValue(this.instructions, this); const transcript = new TranscriptArray(await getValue(((_a = this.chat) == null ? undefined : _a.transcript) ?? [], this)); const tools = Tool.withUniqueNames(await getValue(this.tools, this) ?? []); const objects = await getValue(this.objects, this) ?? []; const exits = await getValue(this.exits, this) ?? []; const components = await getValue(((_b = this.chat) == null ? undefined : _b.components) ?? [], this); const model = await getValue(this.model, this) ?? "best"; const temperature = await getValue(this.temperature, this); const reasoningEffort = await getValue(this.reasoningEffort, this); if (objects && objects.length > 100) { throw new Error("Too many objects. Expected at most 100 objects."); } if (tools && tools.length > 100) { throw new Error("Too many tools. Expected at most 100 tools."); } for (const component of components) { assertValidComponent(component.definition); } const ReservedToolNames = [ "think", "listen", "return", "exit", "action", "function", "callback", "code", "execute", "jsx", "object", "string", "number", "boolean", "array" ]; const MessageTool = this.chat && components.length ? new Tool({ name: "Message", description: "Send a message to the user", aliases: Array.from(/* @__PURE__ */ new Set(["message", ...components.flatMap((x) => [x.definition.name, ...x.definition.aliases ?? []])])), handler: async (message) => { var _a2, _b2; return await ((_b2 = (_a2 = this.chat) == null ? undefined : _a2.handler) == null ? undefined : _b2.call(_a2, message)); } }) : null; const allTools = MessageTool ? [MessageTool, ...tools] : tools; for (const tool of tools) { for (let name of [...tool.aliases, tool.name]) { name = name.toLowerCase(); if (ReservedToolNames.includes(name)) { throw new Error(`Tool name "${name}" (${tool.name}) is reserved. Please choose a different name.`); } if (components.find((x) => { var _a2; return x.definition.name.toLowerCase() === name || ((_a2 = x.definition.aliases) == null ? undefined : _a2.map((x2) => x2.toLowerCase()).includes(name)); })) { throw new Error(`Tool name "${name}" (${tool.name}) is already used by a component. Please choose a different name.`); } if (exits.find((x) => x.name.toLowerCase() === name) || exits.find((x) => { var _a2; return (_a2 = x.aliases) == null ? undefined : _a2.map((x2) => x2.toLowerCase()).includes(name); })) { throw new Error(`Tool name "${name}" (${tool.name}) is already used by an exit. Please choose a different name.`); } } } if (exits && exits.length > 100) { throw new Error("Too many exits. Expected at most 100 exits."); } if (components && components.length > 100) { throw new Error("Too many components. Expected at most 100 components."); } if (instructions && instructions.length > 1e6) { throw new Error("Instructions are too long. Expected at most 1,000,000 characters."); } if (transcript && transcript.length > 250) { throw new Error("Too many transcript messages. Expected at most 250 messages."); } if (!components.length && !exits.length) { exits.push(DefaultExit); } if (typeof temperature !== "number" || isNaN(temperature) || temperature < 0 || temperature > 2) { throw new Error("Invalid temperature. Expected a number between 0 and 2."); } const isValidModel = (m) => typeof m === "string" && (m === "best" || m === "fast" || m === "auto" || m.includes(":")); if (Array.isArray(model)) { if (model.length === 0 || !model.every(isValidModel)) { throw new Error("Invalid model. Expected a non-empty array of model strings ('best'/'fast'/'auto' or 'provider:model')."); } } else if (!isValidModel(model)) { throw new Error("Invalid model. Expected 'best'/'fast'/'auto' or 'provider:model'."); } return { transcript, tools: allTools, objects, exits, instructions, components, model, temperature, reasoningEffort }; } constructor(props) { this.id = `llmz_${ulid()}`; this.instructions = props.instructions; this.objects = props.objects; this.tools = props.tools; this.exits = props.exits; this.chat = props.chat; this.timeout = Math.min(999999999, Math.max(0, props.timeout ?? 60000)); this.loop = props.loop ?? 3; this.temperature = props.temperature ?? 0.7; this.reasoningEffort = props.reasoningEffort; this.model = props.model ?? "best"; this.iterations = []; this.metadata = props.metadata ?? {}; this.snapshot = props.snapshot; if (this.loop < 1 || this.loop > 100) { throw new Error("Invalid loop. Expected a number between 1 and 100."); } } toJSON() { var _a; return { id: this.id, iterations: this.iterations.map((iteration) => iteration.toJSON()), iteration: this.iteration, timeout: this.timeout, loop: this.loop, metadata: this.metadata, snapshot: (_a = this.snapshot) == null ? undefined : _a.toJSON() }; } }; export { ulid, parseExit, Snapshot, ExecutionResult, SuccessExecutionResult, ErrorExecutionResult, PartialExecutionResult, getValue, ThinkExit, ListenExit, DefaultExit, Context };