UNPKG

@botpress/adk-cli

Version:

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

284 lines (281 loc) 10.5 kB
// @bun import { getTypings } from "./chunk-50hzjdck.js"; import { convertObjectToZuiLiterals, isJsonSchema, isValidIdentifier, isZuiSchema } from "./chunk-na956zz3.js"; import { exports_exports, isEmpty_default, transforms_exports, uniq_default } from "./chunk-54qt5g7m.js"; // ../../node_modules/.bun/llmz@0.0.79+b49d396f5ed96e7f/node_modules/llmz/dist/chunk-UI6J4WKQ.js var Tool = class _Tool { _staticInputValues; name; aliases = []; description; metadata; input; output; retry; MAX_RETRIES = 1000; setStaticInputValues(values) { if (values === null || values === undefined) { this._staticInputValues = undefined; return this; } const input = this.input ? transforms_exports.fromJSONSchemaLegacy(this.input) : exports_exports.any(); if (exports_exports.is.zuiObject(input) && typeof values !== "object") { throw new Error(`Invalid static input values for tool ${this.name}. Expected an object, but got type "${typeof values}"`); } if (exports_exports.is.zuiArray(input) && !Array.isArray(values)) { throw new Error(`Invalid static input values for tool ${this.name}. Expected an array, but got type "${typeof values}"`); } this._staticInputValues = values; return this; } get zInput() { let input; if (this.input) { try { input = transforms_exports.fromJSONSchema(this.input); } catch { input = transforms_exports.fromJSONSchemaLegacy(this.input); } } else { input = exports_exports.any(); } if (!isEmpty_default(this._staticInputValues)) { const inputExtensions = convertObjectToZuiLiterals(this._staticInputValues); if (exports_exports.is.zuiObject(input)) { input = input.extend(inputExtensions); } else if (exports_exports.is.zuiArray(input)) { input = exports_exports.array(input.element.extend(inputExtensions)); } else { input = inputExtensions; } } return input; } get zOutput() { let output = exports_exports.void(); if (this.output) { try { output = transforms_exports.fromJSONSchema(this.output); } catch { output = transforms_exports.fromJSONSchemaLegacy(this.output); } } return exports_exports.promise(output); } rename(name) { const before = this.name; if (!isValidIdentifier(name)) { throw new Error(`Invalid name for tool ${name}. A tool name must start with a letter and contain only letters, numbers, and underscores. It must be 1-50 characters long.`); } this.name = name; this.aliases = uniq_default([name, ...this.aliases.map((alias) => alias === before ? name : alias)]); return this; } clone(props = {}) { var _a, _b; try { let zInput; if (this.input) { try { zInput = transforms_exports.fromJSONSchema(this.input); } catch { zInput = transforms_exports.fromJSONSchemaLegacy(this.input); } } let zOutput; if (this.output) { try { zOutput = transforms_exports.fromJSONSchema(this.output); } catch { zOutput = transforms_exports.fromJSONSchemaLegacy(this.output); } } return new _Tool({ name: props.name ?? this.name, aliases: props.aliases ?? [...this.aliases], description: props.description ?? this.description, metadata: JSON.parse(JSON.stringify(props.metadata ?? this.metadata)), input: typeof props.input === "function" ? (_a = props.input) == null ? undefined : _a.call(props, zInput) : exports_exports.is.zuiType(props.input) ? props.input : zInput, output: typeof props.output === "function" ? (_b = props.output) == null ? undefined : _b.call(props, zOutput) : exports_exports.is.zuiType(props.output) ? props.output : zOutput, handler: props.handler ?? this._handler, retry: props.retry ?? this.retry }).setStaticInputValues(props.staticInputValues ?? this._staticInputValues); } catch (e) { throw new Error(`Failed to clone tool "${this.name}": ${e}`); } } _handler; constructor(props) { if (!isValidIdentifier(props.name)) { throw new Error(`Invalid name for tool ${props.name}. A tool name must start with a letter and contain only letters, numbers, and underscores. It must be 1-50 characters long.`); } if (props.description !== undefined && typeof props.description !== "string") { throw new Error(`Invalid description for tool ${props.name}. Expected a string, but got type "${typeof props.description}"`); } if (props.metadata !== undefined && typeof props.metadata !== "object") { throw new Error(`Invalid metadata for tool ${props.name}. Expected an object, but got type "${typeof props.metadata}"`); } if (typeof props.handler !== "function") { throw new Error(`Invalid handler for tool ${props.name}. Expected a function, but got type "${typeof props.handler}"`); } if (props.aliases !== undefined && !Array.isArray(props.aliases)) { throw new Error(`Invalid aliases for tool ${props.name}. Expected an array, but got type "${typeof props.aliases}"`); } if (props.aliases && props.aliases.some((alias) => !isValidIdentifier(alias))) { throw new Error(`Invalid aliases for tool ${props.name}. Expected an array of valid identifiers.`); } if (typeof props.input !== "undefined") { if (isZuiSchema(props.input)) { try { this.input = transforms_exports.toJSONSchema(props.input); } catch { this.input = transforms_exports.toJSONSchemaLegacy(props.input); } } else if (isJsonSchema(props.input)) { this.input = props.input; } else { throw new Error(`Invalid input schema for tool ${props.name}. Expected a ZodType or JSONSchema, but got type "${typeof props.input}"`); } } if (typeof props.output !== "undefined") { if (isZuiSchema(props.output)) { try { this.output = transforms_exports.toJSONSchema(props.output); } catch { this.output = transforms_exports.toJSONSchemaLegacy(props.output); } } else if (isJsonSchema(props.output)) { this.output = props.output; } else { throw new Error(`Invalid output schema for tool ${props.name}. Expected a ZodType or JSONSchema, but got type "${typeof props.output}"`); } } this.name = props.name; this.aliases = uniq_default([props.name, ...props.aliases ?? []]); this.description = props.description; this.metadata = props.metadata ?? {}; this._handler = props.handler; this.setStaticInputValues(props.staticInputValues); this.retry = props.retry; } async _executeHandler(input, ctx, chat, yieldedCount, setYieldedCount) { var _a; const handler = this._handler(input, ctx); const isGen = typeof handler === "object" && handler !== null && "next" in handler; if (!isGen) { return handler; } let yieldIndex = 0; while (true) { const { value, done } = await handler.next(); if (done) { return value; } if (yieldIndex >= yieldedCount) { setYieldedCount(yieldIndex + 1); await ((_a = chat == null ? undefined : chat.handler) == null ? undefined : _a.call(chat, value)); } yieldIndex++; } } async execute(rawInput, ctx, chat) { var _a; const isZodObject = this.zInput._def.typeName === "ZodObject"; const input = isZodObject ? rawInput ?? {} : rawInput; const pInput = this.zInput.safeParse(input); if (!pInput.success) { throw new Error(`Tool "${this.name}" received invalid input: ${pInput.error.message}`); } let attempt = 0; let yieldedCount = 0; while (attempt < this.MAX_RETRIES) { try { const result = await this._executeHandler(pInput.data, ctx, chat, yieldedCount, (n) => { yieldedCount = n; }); const pOutput = this.zOutput.safeParse(result); return pOutput.success ? pOutput.data : result; } catch (err) { const shouldRetry = await ((_a = this.retry) == null ? undefined : _a.call(this, { input: pInput.data, attempt: ++attempt, error: err })); if (!shouldRetry) { throw err; } } } throw new Error(`Tool "${this.name}" failed after ${this.MAX_RETRIES} attempts. Last error: ${JSON.stringify(input)}`); } async getTypings() { let input; if (this.input) { try { input = transforms_exports.fromJSONSchema(this.input); } catch { input = transforms_exports.fromJSONSchemaLegacy(this.input); } } let output; if (!this.output || Object.keys(this.output).length === 0) { output = exports_exports.void(); } else { try { output = transforms_exports.fromJSONSchema(this.output); } catch { output = transforms_exports.fromJSONSchemaLegacy(this.output); } } if (input && exports_exports.is.zuiObject(input.naked()) && typeof this._staticInputValues === "object" && !isEmpty_default(this._staticInputValues)) { const inputExtensions = convertObjectToZuiLiterals(this._staticInputValues); input = input.extend(inputExtensions); } else if (this._staticInputValues !== undefined) { input = convertObjectToZuiLiterals(this._staticInputValues); } const fnType = exports_exports.function(input, exports_exports.promise(output)).title(this.name).describe(this.description ?? ""); return getTypings(fnType, { declaration: true }); } static withUniqueNames = (tools) => { const names = /* @__PURE__ */ new Set; return tools.map((tool) => { if (tools.filter((t) => t.name === tool.name).length === 1) { return tool; } let counter = 1; let toolName = tool.name + counter; while (names.has(toolName)) { toolName = `${tool.name}${++counter}`; } names.add(toolName); return tool.rename(toolName); }); }; toJSON() { return { name: this.name, aliases: [...this.aliases], description: this.description, metadata: this.metadata, input: this.input, output: this.output, staticInputValues: this._staticInputValues, maxRetries: this.MAX_RETRIES }; } }; export { Tool };