UNPKG

@agentica/core

Version:

Agentic AI Library specialized in LLM Function Calling

302 lines 11.4 kB
"use strict"; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.MicroAgentica = void 0; const tstl_1 = require("tstl"); const AgenticaTokenUsage_1 = require("./context/AgenticaTokenUsage"); const AgenticaOperationComposer_1 = require("./context/internal/AgenticaOperationComposer"); const events_1 = require("./factory/events"); const orchestrate_1 = require("./orchestrate"); const transformHistory_1 = require("./transformers/transformHistory"); const __map_take_1 = require("./utils/__map_take"); const assertExecuteFailure_1 = require("./utils/assertExecuteFailure"); const request_1 = require("./utils/request"); /** * Micro AI chatbot. * * `MicroAgentica` is a facade class for the micro AI chatbot agent * which performs LLM (Large Language Model) function calling from the * {@link conversate user's conversation} and manages the * {@link getHistories prompt histories}. * * Different between `MicroAgentica` and {@link Agentica} is that * `MicroAgentica` does not have function selecting filter. It directly * list up every functions to the agent. Besides, {@link Agentica} has * a function selecting mechanism to reduce the number of functions to * be listed up to the agent. * * Therefore, if you have a lot of functions to call, you must not * use this `MicroAgentica` class. Use this `MicroAgentica` class only * when you have a few functions to call. * * - [Multi-agent orchestration of `@agentica`](https://wrtnlabs.io/agentica/docs/concepts/function-calling/#orchestration-strategy) * - Internal agents of `MicroAgentica` * - executor * - describier * - Internal agents of {@link Agentica} * - initializer * - **selector** * - executor * - describer * * @author Samchon */ class MicroAgentica { /* ----------------------------------------------------------- CONSTRUCTOR ----------------------------------------------------------- */ /** * Initializer Constructor. * * @param props Properties to construct the micro agent */ constructor(props) { var _a; this.props = props; this.operations_ = AgenticaOperationComposer_1.AgenticaOperationComposer.compose({ controllers: props.controllers, config: props.config, }); this.histories_ = ((_a = props.histories) !== null && _a !== void 0 ? _a : []).map(input => (0, transformHistory_1.transformHistory)({ operations: this.operations_.group, history: input, })); this.token_usage_ = this.props.tokenUsage !== undefined ? this.props.tokenUsage instanceof AgenticaTokenUsage_1.AgenticaTokenUsage ? this.props.tokenUsage : new AgenticaTokenUsage_1.AgenticaTokenUsage(this.props.tokenUsage) : AgenticaTokenUsage_1.AgenticaTokenUsage.zero(); this.listeners_ = new Map(); this.semaphore_ = props.vendor.semaphore != null ? typeof props.vendor.semaphore === "object" ? props.vendor.semaphore : new tstl_1.Semaphore(props.vendor.semaphore) : null; } /** * @internal */ clone() { var _a; return new MicroAgentica(Object.assign(Object.assign({}, this.props), { histories: (_a = this.props.histories) === null || _a === void 0 ? void 0 : _a.slice() })); } /* ----------------------------------------------------------- ACCESSORS ----------------------------------------------------------- */ /** * Conversate with the micro agent. * * User talks to the AI chatbot with the given content. * * When the user's conversation implies the AI chatbot to execute a * function calling, the returned chat prompts will contain the * function callinng information like {@link AgenticaExecuteHistory} * * @param content The content to talk * @returns List of newly created histories */ conversate(content_1) { return __awaiter(this, arguments, void 0, function* (content, options = {}) { var _a, _b, _c; const histories = []; const dispatch = (event) => __awaiter(this, void 0, void 0, function* () { try { yield this.dispatch(event); if ("toHistory" in event) { if ("join" in event) { histories.push(() => __awaiter(this, void 0, void 0, function* () { yield event.join(); return event.toHistory(); })); } else { histories.push(() => __awaiter(this, void 0, void 0, function* () { return event.toHistory(); })); } } } catch (_a) { } }); const prompt = (0, events_1.createUserMessageEvent)({ contents: Array.isArray(content) ? content : typeof content === "string" ? [{ type: "text", text: content, }] : [content], }); void dispatch(prompt).catch(() => { }); const ctx = this.getContext({ prompt, dispatch, usage: this.token_usage_, abortSignal: options.abortSignal, }); const executes = yield (0, orchestrate_1.call)(ctx, this.operations_.array); // eslint-disable-next-line if (executes.length && !!((_b = (_a = this.props.config) === null || _a === void 0 ? void 0 : _a.executor) === null || _b === void 0 ? void 0 : _b.describe)) { const func = typeof this.props.config.executor.describe === "function" ? this.props.config.executor.describe : orchestrate_1.describe; yield func(ctx, executes); } const completed = yield Promise.all(histories.map((h) => __awaiter(this, void 0, void 0, function* () { return h(); }))); this.histories_.push(...completed); // throw exception about failed execution if (((_c = this.props.config) === null || _c === void 0 ? void 0 : _c.throw) !== false) { for (const execute of executes) { (0, assertExecuteFailure_1.assertExecuteFailure)(execute); } } return completed; }); } /** * Get configuration. */ getConfig() { return this.props.config; } /** * Get LLM vendor. */ getVendor() { return this.props.vendor; } /** * Get operations. * * Get list of operations, which has capsuled the pair of controller * and function from the {@link getControllers controllers}. * * @returns List of operations */ getOperations() { return this.operations_.array; } /** * Get controllers. * * Get list of controllers, which are the collection of functions that * the agent can execute. */ getControllers() { return this.props.controllers; } /** * Get the chatbot's histories. * * Get list of chat histories that the chatbot has been conversated. * * @returns List of chat histories */ getHistories() { return this.histories_; } /** * Get token usage of the AI chatbot. * * Entire token usage of the AI chatbot during the conversating * with the user by {@link conversate} method callings. * * @returns Cost of the AI chatbot */ getTokenUsage() { return this.token_usage_; } /** * @internal */ getContext(props) { const request = (0, request_1.getChatCompletionWithStreamingFunction)({ vendor: this.props.vendor, config: this.props.config, dispatch: props.dispatch, abortSignal: props.abortSignal, usage: this.token_usage_, }); return { operations: this.operations_, config: this.props.config, histories: this.histories_, prompt: props.prompt, dispatch: props.dispatch, request: this.semaphore_ === null ? request : (source, body) => __awaiter(this, void 0, void 0, function* () { yield this.semaphore_.acquire(); try { return yield request(source, body); } finally { void this.semaphore_.release().catch(() => { }); } }), }; } /* ----------------------------------------------------------- EVENT HANDLERS ----------------------------------------------------------- */ /** * Add an event listener. * * Add an event listener to be called whenever the event is emitted. * * @param type Type of event * @param listener Callback function to be called whenever the event is emitted */ on(type, listener) { /** * @TODO remove `as` */ (0, __map_take_1.__map_take)(this.listeners_, type, () => new Set()).add(listener); return this; } /** * Erase an event listener. * * Erase an event listener to stop calling the callback function. * * @param type Type of event * @param listener Callback function to erase */ off(type, listener) { const set = this.listeners_.get(type); if (set !== undefined) { /** * @TODO remove `as` */ set.delete(listener); if (set.size === 0) { this.listeners_.delete(type); } } return this; } dispatch(event) { return __awaiter(this, void 0, void 0, function* () { const set = this.listeners_.get(event.type); if (set !== undefined) { yield Promise.all(Array.from(set).map((listener) => __awaiter(this, void 0, void 0, function* () { try { yield listener(event); } catch (_a) { /* empty */ } }))); } }); } } exports.MicroAgentica = MicroAgentica; //# sourceMappingURL=MicroAgentica.js.map