UNPKG

@assistant-ui/react

Version:

Typescript/React library for AI Chat

328 lines (327 loc) 10.8 kB
"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/runtimes/local/LocalThreadRuntimeCore.tsx var LocalThreadRuntimeCore_exports = {}; __export(LocalThreadRuntimeCore_exports, { LocalThreadRuntimeCore: () => LocalThreadRuntimeCore }); module.exports = __toCommonJS(LocalThreadRuntimeCore_exports); var import_internal = require("../../internal.js"); var import_edge = require("../edge/index.js"); var import_shouldContinue = require("./shouldContinue.js"); var import_BaseThreadRuntimeCore = require("../core/BaseThreadRuntimeCore.js"); var LocalThreadRuntimeCore = class extends import_BaseThreadRuntimeCore.BaseThreadRuntimeCore { capabilities = { switchToBranch: true, edit: true, reload: true, cancel: true, unstable_copy: true, speech: false, attachments: false, feedback: false }; abortController = null; isDisabled = false; _suggestions = []; _suggestionsController = null; get suggestions() { return this._suggestions; } get adapters() { return this._options.adapters; } constructor(contextProvider, options) { super(contextProvider); this.__internal_setOptions(options); } _options; _lastRunConfig = {}; get extras() { return void 0; } __internal_setOptions(options) { if (this._options === options) return; this._options = options; let hasUpdates = false; const canSpeak = options.adapters?.speech !== void 0; if (this.capabilities.speech !== canSpeak) { this.capabilities.speech = canSpeak; hasUpdates = true; } const canAttach = options.adapters?.attachments !== void 0; if (this.capabilities.attachments !== canAttach) { this.capabilities.attachments = canAttach; hasUpdates = true; } const canFeedback = options.adapters?.feedback !== void 0; if (this.capabilities.feedback !== canFeedback) { this.capabilities.feedback = canFeedback; hasUpdates = true; } if (hasUpdates) this._notifySubscribers(); } _loadPromise; __internal_load() { if (this._loadPromise) return this._loadPromise; const promise = this.adapters.history?.load() ?? Promise.resolve(null); this._loadPromise = promise.then((repo) => { if (!repo) return; this.repository.import(repo); this._notifySubscribers(); const resume = this.adapters.history?.resume?.bind(this.adapters.history); if (repo.unstable_resume && resume) { this.startRun( { parentId: this.repository.headId, sourceId: this.repository.headId, runConfig: this._lastRunConfig }, resume ); } }); return this._loadPromise; } async append(message) { this.ensureInitialized(); const newMessage = (0, import_edge.fromCoreMessage)(message, { attachments: message.attachments }); this.repository.addOrUpdateMessage(message.parentId, newMessage); this._options.adapters.history?.append({ parentId: message.parentId, message: newMessage }); const startRun = message.startRun ?? message.role === "user"; if (startRun) { await this.startRun({ parentId: newMessage.id, sourceId: message.sourceId, runConfig: message.runConfig ?? {} }); } else { this.repository.resetHead(newMessage.id); this._notifySubscribers(); } } resumeRun({ stream, ...startConfig }) { return this.startRun(startConfig, stream); } async startRun({ parentId, runConfig }, runCallback) { this.ensureInitialized(); this.repository.resetHead(parentId); const id = (0, import_internal.generateId)(); let message = { id, role: "assistant", status: { type: "running" }, content: [], metadata: { unstable_annotations: [], unstable_data: [], steps: [], custom: {} }, createdAt: /* @__PURE__ */ new Date() }; this._notifyEventSubscribers("run-start"); try { this._suggestions = []; this._suggestionsController?.abort(); this._suggestionsController = null; do { message = await this.performRoundtrip( parentId, message, runConfig, runCallback ); runCallback = void 0; } while ((0, import_shouldContinue.shouldContinue)(message, this._options.unstable_humanToolNames)); } finally { this._notifyEventSubscribers("run-end"); } this._suggestionsController = new AbortController(); const signal = this._suggestionsController.signal; if (this.adapters.suggestion && message.status?.type !== "requires-action") { const promiseOrGenerator = this.adapters.suggestion?.generate({ messages: this.messages }); if (Symbol.asyncIterator in promiseOrGenerator) { for await (const r of promiseOrGenerator) { if (signal.aborted) break; this._suggestions = r; } } else { const result = await promiseOrGenerator; if (signal.aborted) return; this._suggestions = result; } } } async performRoundtrip(parentId, message, runConfig, runCallback) { const messages = this.repository.getMessages(); this.abortController?.abort(); this.abortController = new AbortController(); const initialContent = message.content; const initialAnnotations = message.metadata?.unstable_annotations; const initialData = message.metadata?.unstable_data; const initialSteps = message.metadata?.steps; const initalCustom = message.metadata?.custom; const updateMessage = (m) => { const newSteps = m.metadata?.steps; const steps2 = newSteps ? [...initialSteps ?? [], ...newSteps] : void 0; const newAnnotations = m.metadata?.unstable_annotations; const newData = m.metadata?.unstable_data; const annotations = newAnnotations ? [...initialAnnotations ?? [], ...newAnnotations] : void 0; const data = newData ? [...initialData ?? [], ...newData] : void 0; message = { ...message, ...m.content ? { content: [...initialContent, ...m.content ?? []] } : void 0, status: m.status ?? message.status, ...m.metadata ? { metadata: { ...message.metadata, ...annotations ? { unstable_annotations: annotations } : void 0, ...data ? { unstable_data: data } : void 0, ...steps2 ? { steps: steps2 } : void 0, ...m.metadata?.custom ? { custom: { ...initalCustom ?? {}, ...m.metadata.custom } } : void 0 } } : void 0 }; this.repository.addOrUpdateMessage(parentId, message); this._notifySubscribers(); }; const maxSteps = this._options.maxSteps ?? 2; const steps = message.metadata?.steps?.length ?? 0; if (steps >= maxSteps) { updateMessage({ status: { type: "incomplete", reason: "tool-calls" } }); return message; } else { updateMessage({ status: { type: "running" } }); } try { this._lastRunConfig = runConfig ?? {}; const context = this.getModelContext(); runCallback = runCallback ?? this.adapters.chatModel.run.bind(this.adapters.chatModel); const promiseOrGenerator = runCallback({ messages, runConfig: this._lastRunConfig, abortSignal: this.abortController.signal, context, config: context, unstable_assistantMessageId: message.id, unstable_getMessage() { return message; } }); if (Symbol.asyncIterator in promiseOrGenerator) { for await (const r of promiseOrGenerator) { updateMessage(r); } } else { updateMessage(await promiseOrGenerator); } this.abortController = null; if (message.status.type === "running") { updateMessage({ status: { type: "complete", reason: "unknown" } }); } } catch (e) { this.abortController = null; if (e instanceof Error && e.name === "AbortError") { updateMessage({ status: { type: "incomplete", reason: "cancelled" } }); } else { updateMessage({ status: { type: "incomplete", reason: "error", error: e instanceof Error ? e.message : `[${typeof e}] ${new String(e).toString()}` } }); throw e; } } finally { if (message.status.type === "complete" || message.status.type === "incomplete") { await this._options.adapters.history?.append({ parentId, message }); } } return message; } cancelRun() { this.abortController?.abort(); this.abortController = null; } addToolResult({ messageId, toolCallId, result }) { const messageData = this.repository.getMessage(messageId); const { parentId } = messageData; let { message } = messageData; if (message.role !== "assistant") throw new Error("Tried to add tool result to non-assistant message"); let added = false; let found = false; const newContent = message.content.map((c) => { if (c.type !== "tool-call") return c; if (c.toolCallId !== toolCallId) return c; found = true; if (!c.result) added = true; return { ...c, result }; }); if (!found) throw new Error("Tried to add tool result to non-existing tool call"); message = { ...message, content: newContent }; this.repository.addOrUpdateMessage(parentId, message); if (added && (0, import_shouldContinue.shouldContinue)(message, this._options.unstable_humanToolNames)) { this.performRoundtrip(parentId, message, this._lastRunConfig); } } }; // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { LocalThreadRuntimeCore }); //# sourceMappingURL=LocalThreadRuntimeCore.js.map