UNPKG

@autobe/agent

Version:

AI backend server code generator

1,065 lines (1,019 loc) 4.47 MB
import { MicroAgentica, AgenticaJsonParseError, AgenticaValidationError } from "@agentica/core"; import { StringUtil, AutoBeProcessAggregateFactory, TokenUsageComputer, AutoBeOpenApiTypeChecker, writePrismaApplication, AutoBeOpenApiEndpointComparator, AutoBeFunctionCallingMetricFactory, MapUtil, missedOpenApiSchemas, revertOpenApiAccessor, transformOpenApiDocument } from "@autobe/utils"; import { Semaphore, Pair, ConditionVariable, Singleton, sleep_for, HashSet, HashMap, randint } from "tstl"; import { v7, v4 } from "uuid"; import * as __typia_transform__validateReport from "typia/lib/internal/_validateReport"; import * as __typia_transform__llmApplicationFinalize from "typia/lib/internal/_llmApplicationFinalize"; import "typia"; import { APIError, BadRequestError } from "openai"; import * as __typia_transform__isTypeUint32 from "typia/lib/internal/_isTypeUint32"; import { NamingConvention, OpenApiTypeChecker, OpenApiConverter, LlmTypeChecker, HttpMigration } from "@typia/utils"; import pluralize, { singular, plural } from "pluralize"; import * as __typia_transform__accessExpressionAsString from "typia/lib/internal/_accessExpressionAsString"; import YAML from "yaml"; import { createHash } from "node:crypto"; import * as __typia_transform__isUniqueItems from "typia/lib/internal/_isUniqueItems"; import path from "path"; function emplaceMap(dict, key, generator) { const oldbie = dict.get(key); if (oldbie !== undefined) { return oldbie; } const value = generator(); dict.set(key, value); return value; } class AutoBeAgentBase { constructor() { this.listeners_ = new Map; } on(type, listener) { emplaceMap(this.listeners_, type, () => new Set).add(listener); return this; } off(type, listener) { const set = this.listeners_.get(type); if (set === undefined) return this; set.delete(listener); if (set.size === 0) this.listeners_.delete(type); return this; } async dispatch(event) { const set = this.listeners_.get(event.type); if (set === undefined) return; await Promise.all(Array.from(set).map(async listener => { try { await listener(event); } catch {} })); } } class AutoBeTokenUsageComponent { get total() { return this.input.total + this.output.total; } constructor(props) { if (props === undefined) { this.input = { total: 0, cached: 0 }; this.output = { total: 0, reasoning: 0, accepted_prediction: 0, rejected_prediction: 0 }; } else { this.input = props.input; this.output = props.output; } } assign(props) { this.input.total = props.input.total; this.input.cached = props.input.cached; this.output.total = props.output.total; this.output.reasoning = props.output.reasoning; this.output.accepted_prediction = props.output.accepted_prediction; this.output.rejected_prediction = props.output.rejected_prediction; } toJSON() { return { total: this.total, input: { total: this.input.total, cached: this.input.cached }, output: { total: this.output.total, reasoning: this.output.reasoning, accepted_prediction: this.output.accepted_prediction, rejected_prediction: this.output.rejected_prediction } }; } increment(props) { this.input.total += props.input.total; this.input.cached += props.input.cached; this.output.total += props.output.total; this.output.reasoning += props.output.reasoning; this.output.accepted_prediction += props.output.accepted_prediction; this.output.rejected_prediction += props.output.rejected_prediction; } decrement(props) { this.input.total -= props.input.total; this.input.cached -= props.input.cached; this.output.total -= props.output.total; this.output.reasoning -= props.output.reasoning; this.output.accepted_prediction -= props.output.accepted_prediction; this.output.rejected_prediction -= props.output.rejected_prediction; } static plus(a, b) { return new AutoBeTokenUsageComponent({ input: { total: a.input.total + b.input.total, cached: a.input.cached + b.input.cached }, output: { total: a.output.total + b.output.total, reasoning: a.output.reasoning + b.output.reasoning, accepted_prediction: a.output.accepted_prediction + b.output.accepted_prediction, rejected_prediction: a.output.rejected_prediction + b.output.rejected_prediction } }); } static minus(a, b) { return new AutoBeTokenUsageComponent({ input: { total: a.input.total - b.input.total, cached: a.input.cached - b.input.cached }, output: { total: a.output.total - b.output.total, reasoning: a.output.reasoning - b.output.reasoning, accepted_prediction: a.output.accepted_prediction - b.output.accepted_prediction, rejected_prediction: a.output.rejected_prediction - b.output.rejected_prediction } }); } } class AutoBeTokenUsage { get aggregate() { return AutoBeTokenUsage.keys().reduce((acc, cur) => AutoBeTokenUsageComponent.plus(acc, this[cur]), new AutoBeTokenUsageComponent).toJSON(); } constructor(props) { if (props === undefined) { this.facade = new AutoBeTokenUsageComponent; this.analyze = new AutoBeTokenUsageComponent; this.database = new AutoBeTokenUsageComponent; this.interface = new AutoBeTokenUsageComponent; this.test = new AutoBeTokenUsageComponent; this.realize = new AutoBeTokenUsageComponent; return; } else if (props instanceof AutoBeTokenUsage) { this.facade = props.facade; this.analyze = props.analyze; this.database = props.database; this.interface = props.interface; this.test = props.test; this.realize = props.realize; } else { this.facade = new AutoBeTokenUsageComponent(props.facade); this.analyze = new AutoBeTokenUsageComponent(props.analyze); this.database = new AutoBeTokenUsageComponent(props.database); this.interface = new AutoBeTokenUsageComponent(props.interface); this.test = new AutoBeTokenUsageComponent(props.test); this.realize = new AutoBeTokenUsageComponent(props.realize); } } assign(props) { this.facade.assign(props.facade); this.analyze.assign(props.analyze); this.database.assign(props.database); this.interface.assign(props.interface); this.test.assign(props.test); this.realize.assign(props.realize); } toJSON() { return { aggregate: this.aggregate, facade: this.facade.toJSON(), analyze: this.analyze.toJSON(), database: this.database.toJSON(), interface: this.interface.toJSON(), test: this.test.toJSON(), realize: this.realize.toJSON() }; } record(usage, additionalStages = []) { additionalStages.forEach(stage => { this[stage].increment(usage); }); } increment(usage) { AutoBeTokenUsage.keys().forEach(key => { this[key].increment(usage[key]); }); return this; } decrement(usage) { AutoBeTokenUsage.keys().forEach(key => { this[key].decrement(usage[key]); }); return this; } static plus(usageA, usageB) { return new AutoBeTokenUsage({ facade: AutoBeTokenUsageComponent.plus(usageA.facade, usageB.facade), analyze: AutoBeTokenUsageComponent.plus(usageA.analyze, usageB.analyze), database: AutoBeTokenUsageComponent.plus(usageA.database, usageB.database), interface: AutoBeTokenUsageComponent.plus(usageA.interface, usageB.interface), test: AutoBeTokenUsageComponent.plus(usageA.test, usageB.test), realize: AutoBeTokenUsageComponent.plus(usageA.realize, usageB.realize) }); } static keys() { return [ "facade", "analyze", "database", "interface", "test", "realize" ]; } } function createAutoBeUserMessageContent(props) { const {content, description} = props; if (content.type === "image") { if (description !== undefined) { return { type: "text", text: StringUtil.trim` image description: \`\`\`text ${description} \`\`\` ` }; } return { type: "image", image: content.image, description: description ?? "" }; } else if (content.type === "text") return content; else if (content.type === "file") return content; else if (content.type === "audio") return content; else ; throw new Error(`Invalid content type`); } const mergeSystemMessages = (agent, vendor) => { if (vendor.model.includes("qwen")) { agent.on("request", async e => { const body = e.body; const originalMessages = body.messages ?? []; body.messages = consolidateSystemMessages(originalMessages); }); } }; function consolidateSystemMessages(messages) { const systems = []; const others = []; for (const message of messages) { if (message.role === "system") systems.push(message); else others.push(message); } if (systems.length <= 1) return [ ...systems, ...others ]; return [ { role: "system", content: systems.map(msg => flattenSystemContent(msg.content)).filter(str => str.length !== 0).join("\n\n") }, ...others ]; } function flattenSystemContent(content) { if (typeof content === "string") return content; return content.map(part => "text" in part ? part.text : "").filter(str => str.length !== 0).join("\n"); } const supportMistral = (agent, vendor) => { if (vendor.model.includes("mistral") || vendor.model.includes("devstral") || vendor.model.includes("codestral")) { agent.on("request", async e => { const newMessages = []; for (const m of e.body.messages) { newMessages.push(m); if (m.role === "tool") { m.tool_call_id = uuidToShortId(m.tool_call_id); newMessages.push({ role: "assistant", content: "A tool has been called." }); } else if (m.role === "assistant") { for (const call of m.tool_calls ?? []) call.id = uuidToShortId(call.id); } } e.body.messages = newMessages; }); } }; const BASE62_CHARS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; function simpleHash(str) { let h1 = 3735928559; let h2 = 1103547991; for (let i = 0; i < str.length; i++) { const ch = str.charCodeAt(i); h1 = Math.imul(h1 ^ ch, 2654435761); h2 = Math.imul(h2 ^ ch, 1597334677); } h1 = Math.imul(h1 ^ h1 >>> 16, 2246822507) ^ Math.imul(h2 ^ h2 >>> 13, 3266489909); h2 = Math.imul(h2 ^ h2 >>> 16, 2246822507) ^ Math.imul(h1 ^ h1 >>> 13, 3266489909); return 4294967296 * (2097151 & h2) + (h1 >>> 0); } function toBase62(num, length) { let result = ""; let n = num; while (n > 0 && result.length < length) { result = BASE62_CHARS[n % 62] + result; n = Math.floor(n / 62); } return result.padStart(length, "0"); } function uuidToShortId(uuid) { const hash = simpleHash(uuid); return toBase62(hash, 9); } const executeCachedBatch = async (ctx, taskList, promptCacheKey) => { if (taskList.length === 0) return []; promptCacheKey ?? (promptCacheKey = v7()); const semaphore = typeof ctx === "number" ? ctx : ctx.vendor.semaphore && ctx.vendor.semaphore instanceof Semaphore ? ctx.vendor.semaphore.max() : ctx.vendor.semaphore ?? 8; const queue = taskList.map((task, index) => new Pair(task, index)); const results = []; let aborted = false; let firstError = null; await Promise.allSettled(new Array(Math.min(semaphore, queue.length)).fill(0).map(async () => { while (queue.length !== 0 && !aborted) { const item = queue.splice(0, 1)[0]; try { const result = await item.first(promptCacheKey); if (!aborted) results.push(new Pair(result, item.second)); } catch (error) { if (!aborted) { aborted = true; queue.length = 0; firstError = error; } } } })); if (firstError !== null) throw firstError; return results.sort((x, y) => x.second - y.second).map(p => p.first); }; const transformImageDescribeDraftHistories = () => [ { id: v7(), created_at: (new Date).toISOString(), type: "systemMessage", text: '\x3c!--\nfilename: IMAGE_DESCRIBE_DRAFT.md\n--\x3e\n# Image Analysis Agent\n\n## Overview\n\nYou are an Image Analysis Agent that examines images and generates comprehensive descriptions. Your role is to systematically observe, analyze, and document visual content to help others understand images without seeing them.\n\nThis agent achieves its goal through function calling. **Function calling is MANDATORY** - you MUST call the provided function immediately without asking for confirmation or permission.\n\n## Sequential Analysis Process\n\nYou will analyze images through 5 sequential steps, each building on the previous:\n\n### Observation\nFirst, observe everything visible in the image without interpretation.\n\n### Analysis \nThen, interpret what these observations mean and their relationships.\n\n### Topics\nExtract key themes from your analysis.\n\n### Summary\nSummarize the image\'s essence concisely.\n\n### Description\nWrite comprehensive documentation.\n\n**REQUIRED ACTIONS:**\n- ✅ Execute the function immediately\n- ✅ Complete ALL 5 steps sequentially\n- ✅ Be thorough and detailed in each step\n\n**ABSOLUTE PROHIBITIONS:**\n- ❌ NEVER skip any step\n- ❌ NEVER ask for permission\n- ❌ NEVER make assumptions about hidden content\n\n## Step-by-Step Guide\n\n### Observation (What do I see?)\n\nDocument everything visible WITHOUT interpretation:\n- List all objects and their locations\n- Record all text exactly as shown\n- Note UI elements (buttons, menus, forms)\n- Describe colors, shapes, sizes\n- Document layout and positioning\n\nWrite like you\'re describing to someone who can\'t see the image.\n\n### Analysis (What does it mean?)\n\nInterpret your observations:\n- What type of image is this?\n- What is its purpose?\n- How do elements relate to each other?\n- What functionality is available?\n- What domain or context does it belong to?\n\nConnect the dots between what you observed.\n\n### Topics (What are the key themes?)\n\nExtract 3-5 main topics using kebab-case:\n- Focus on primary functions and features\n- Use specific, searchable terms\n- Examples: "user-authentication", "data-visualization", "inventory-management"\n\n### Summary (What\'s the essence?)\n\nWrite 2-3 sentences that capture:\n- What the image shows\n- Its primary purpose\n- Key characteristics\n\nSomeone should understand the image from this alone.\n\n### Description (Full documentation)\n\nWrite comprehensive markdown documentation with sections like:\n\n```markdown\n## Overview\n[General description of what the image contains]\n\n## Main Components\n[Detailed breakdown of major elements]\n\n## Content Details\n[Specific information, data, or text shown]\n\n## Functionality\n[Available actions or interactions]\n\n## Technical Aspects\n[Any technical details if applicable]\n```\n\nBe detailed enough that someone could recreate or fully understand the image.\n\n## Quality Guidelines\n\n### For Observation:\n- Be exhaustive - miss nothing\n- Stay factual - no interpretation\n- Be systematic - top to bottom, left to right\n\n### For Analysis:\n- Make logical connections\n- Identify purposes and functions\n- Consider user perspective\n\n### For Description:\n- Use clear markdown formatting\n- Organize into logical sections\n- Include all significant details\n- Write professionally\n\n## Image Type Examples\n\n### UI/UX Screenshots:\n- List all interactive elements\n- Note navigation structure\n- Document form fields\n- Describe data displayed\n\n### Diagrams:\n- Identify all components\n- Trace connections\n- Note flow direction\n- Extract labels and annotations\n\n### Data Visualizations:\n- Identify chart type\n- Extract data points\n- Note scales and units\n- Describe trends\n\n### Documents:\n- Extract all text\n- Maintain structure\n- Note formatting\n- Preserve hierarchy\n\n## Execution\n\nWhen you receive an image:\n1. Process it completely\n2. Work through all 5 steps sequentially\n3. Call the function with your complete analysis\n4. Do not ask questions or seek confirmation\n\nYour goal is to help others understand images through clear, structured documentation.' } ]; const orchestrateImageDescribeDrafts = async (ctx, props) => { const [imageContents, otherContents] = props.content.reduce((acc, cur) => { if (cur.type === "image") { acc[0].push(cur); } else { acc[1].push(cur); } return acc; }, [ [], [] ]); const progress = { total: imageContents.length, completed: 0 }; const drafts = await executeCachedBatch(ctx, imageContents.map(imageContent => async promptCacheKey => { try { const event = await process$r(ctx, { imageContents: [ imageContent ], userContents: otherContents, progress, promptCacheKey }); ctx.dispatch(event); return { ...event, image: imageContent, description: event.draft }; } catch { return null; } })); return drafts.filter(d => d !== null); }; async function process$r(ctx, props) { const pointer = { value: null }; const content = [ ...props.imageContents, ...props.userContents ]; const agent = new MicroAgentica({ vendor: ctx.vendor, config: { executor: { describe: false }, retry: ctx.retry }, histories: transformImageDescribeDraftHistories(), controllers: [ createController$B({ build: next => { pointer.value = next; } }) ] }); supportMistral(agent, { api: ctx.vendor.api, model: ctx.vendor.model, options: ctx.vendor.options, semaphore: typeof ctx.vendor.semaphore === "number" ? ctx.vendor.semaphore : ctx.vendor.semaphore?.max() }); mergeSystemMessages(agent, { api: ctx.vendor.api, model: ctx.vendor.model, options: ctx.vendor.options, semaphore: typeof ctx.vendor.semaphore === "number" ? ctx.vendor.semaphore : ctx.vendor.semaphore?.max() }); agent.on("request", e => { if (!!e.body.tools?.length) { e.body.tool_choice = "required"; } }); await agent.conversate(content.map(c => createAutoBeUserMessageContent({ content: c }))); const tokenUsage = agent.getTokenUsage().toJSON().aggregate; ctx.usage().record(tokenUsage, [ "facade" ]); props.progress.completed += props.imageContents.length; if (pointer.value === null) throw new Error("Failed to analyze image."); const event = { type: "imageDescribeDraft", id: v7(), observation: pointer.value.observation, analysis: pointer.value.analysis, topics: pointer.value.topics, summary: pointer.value.summary, draft: pointer.value.description, completed: props.progress.completed, tokenUsage, total: props.progress.total, created_at: (new Date).toISOString() }; return event; } function createController$B(props) { const validate = next => { const result = (() => { const _io0 = input => "string" === typeof input.observation && "string" === typeof input.analysis && (Array.isArray(input.topics) && input.topics.every(elem => "string" === typeof elem)) && "string" === typeof input.summary && "string" === typeof input.description; const _vo0 = (input, _path, _exceptionable = true) => [ "string" === typeof input.observation || _report(_exceptionable, { path: _path + ".observation", expected: "string", value: input.observation }), "string" === typeof input.analysis || _report(_exceptionable, { path: _path + ".analysis", expected: "string", value: input.analysis }), (Array.isArray(input.topics) || _report(_exceptionable, { path: _path + ".topics", expected: "Array<string>", value: input.topics })) && input.topics.map((elem, _index2) => "string" === typeof elem || _report(_exceptionable, { path: _path + ".topics[" + _index2 + "]", expected: "string", value: elem })).every(flag => flag) || _report(_exceptionable, { path: _path + ".topics", expected: "Array<string>", value: input.topics }), "string" === typeof input.summary || _report(_exceptionable, { path: _path + ".summary", expected: "string", value: input.summary }), "string" === typeof input.description || _report(_exceptionable, { path: _path + ".description", expected: "string", value: input.description }) ].every(flag => flag); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => { if (false === __is(input)) { errors = []; _report = __typia_transform__validateReport._validateReport(errors); ((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, { path: _path + "", expected: "IAutoBeImageDescribeDraftApplication.IProps", value: input })) && _vo0(input, _path + "", true) || _report(true, { path: _path + "", expected: "IAutoBeImageDescribeDraftApplication.IProps", value: input }))(input, "$input", true); const success = 0 === errors.length; return success ? { success, data: input } : { success, errors, data: input }; } return { success: true, data: input }; }; })()(next); if (result.success === false) return result; return result; }; const application = __typia_transform__llmApplicationFinalize._llmApplicationFinalize({ functions: [ { name: "analyzeImage", parameters: { description: "Current Type: {@link IAutoBeImageDescribeDraftApplication.IProps}", type: "object", properties: { observation: { description: "Step 1: Raw observation of all visible elements (objects, text, UI,\nlayout) without interpretation.", type: "string" }, analysis: { description: "Step 2: Interpret observed elements — purpose, relationships, workflows,\ndomain context.", type: "string" }, topics: { description: 'Step 3: 3-5 main topics/themes in kebab-case (e.g., "user-dashboard",\n"payment-flow").', type: "array", items: { type: "string" } }, summary: { description: "Step 4: Concise 2-3 sentence summary capturing what the image shows and\nits purpose.", type: "string" }, description: { description: "Step 5: Comprehensive markdown description enabling understanding without\nseeing the image.", type: "string" } }, required: [ "observation", "analysis", "topics", "summary", "description" ], additionalProperties: false, $defs: {} }, description: "Analyze an image through observation, interpretation, and documentation\nphases.", validate: (() => { const _io0 = input => "string" === typeof input.observation && "string" === typeof input.analysis && (Array.isArray(input.topics) && input.topics.every(elem => "string" === typeof elem)) && "string" === typeof input.summary && "string" === typeof input.description; const _vo0 = (input, _path, _exceptionable = true) => [ "string" === typeof input.observation || _report(_exceptionable, { path: _path + ".observation", expected: "string", value: input.observation }), "string" === typeof input.analysis || _report(_exceptionable, { path: _path + ".analysis", expected: "string", value: input.analysis }), (Array.isArray(input.topics) || _report(_exceptionable, { path: _path + ".topics", expected: "Array<string>", value: input.topics })) && input.topics.map((elem, _index2) => "string" === typeof elem || _report(_exceptionable, { path: _path + ".topics[" + _index2 + "]", expected: "string", value: elem })).every(flag => flag) || _report(_exceptionable, { path: _path + ".topics", expected: "Array<string>", value: input.topics }), "string" === typeof input.summary || _report(_exceptionable, { path: _path + ".summary", expected: "string", value: input.summary }), "string" === typeof input.description || _report(_exceptionable, { path: _path + ".description", expected: "string", value: input.description }) ].every(flag => flag); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => { if (false === __is(input)) { errors = []; _report = __typia_transform__validateReport._validateReport(errors); ((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, { path: _path + "", expected: "IAutoBeImageDescribeDraftApplication.IProps", value: input })) && _vo0(input, _path + "", true) || _report(true, { path: _path + "", expected: "IAutoBeImageDescribeDraftApplication.IProps", value: input }))(input, "$input", true); const success = 0 === errors.length; return success ? { success, data: input } : { success, errors, data: input }; } return { success: true, data: input }; }; })() } ] }, { validate: { analyzeImage: validate } }); return { protocol: "class", name: "image", application, execute: { analyzeImage: next => { props.build(next); } } }; } const imageDescribe = async (ctx, props) => { const start = new Date; const imageContents = props.content.filter(m => m.type === "image"); const imageCount = imageContents.length; if (imageCount === 0) throw new Error("No image content found"); ctx.dispatch({ type: "imageDescribeStart", id: v7(), imageCount, created_at: (new Date).toISOString() }); const drafts = await orchestrateImageDescribeDrafts(ctx, { content: props.content }); const draftContents = drafts.map(d => createAutoBeUserMessageContent({ content: d.image, description: d.description })); const userInput = props.content.filter(c => c.type !== "image").map(c => createAutoBeUserMessageContent({ content: c })); const query = { type: "text", text: userInput.length > 0 ? "Please analyze the user's input and the image descriptions provided, and write a comprehensive requirements specification document." : "Please analyze the image descriptions provided and write a comprehensive requirements specification document." }; const complete = { type: "imageDescribeComplete", id: v7(), contents: [ ...userInput, ...draftContents, query ], elapsed: (new Date).getTime() - start.getTime(), created_at: (new Date).toISOString() }; ctx.dispatch(complete); return { ...complete, type: "userMessage" }; }; const describe$1 = async (ctx, props) => { if (typeof props.content === "string") return { type: "userMessage", id: v7(), contents: [ { type: "text", text: props.content } ], created_at: (new Date).toISOString() }; const contents = Array.isArray(props.content) ? props.content : [ props.content ]; if (contents.some(c => c.type === "image")) return await imageDescribe(ctx, { content: contents }); return { type: "userMessage", id: v7(), contents: contents.map(c => createAutoBeUserMessageContent({ content: c })), created_at: (new Date).toISOString() }; }; function createAgenticaHistory(props) { if (props.history.type === "userMessage") { const history = { ...props.history, contents: props.history.contents.map(c => { if (c.type === "image") { return { type: "text", text: c.description }; } else return c; }) }; return { ...history, toJSON: () => history }; } else if (props.history.type === "assistantMessage") return { ...props.history, toJSON: () => props.history }; const operation = props.operations.find(op => op.function.name === props.history.type); if (operation === undefined) return null; const partial = { id: props.history.id, created_at: props.history.created_at, type: "execute", arguments: { instruction: props.history.type === "analyze" ? undefined : props.history.instruction }, value: { success: props.history.type === "analyze" || props.history.type === "interface" ? true : props.history.compiled.type === "success" }, success: true }; return { ...partial, protocol: operation.protocol, operation, toJSON: () => ({ ...partial, protocol: operation.protocol, operation: operation.toJSON() }) }; } class AutoBeTimeoutError extends Error { constructor(message) { super(message); const proto = new.target.prototype; if (Object.setPrototypeOf) Object.setPrototypeOf(this, proto); else { this.__proto__ = proto; } } get name() { return this.constructor.name; } } var TimedConversation; (function(TimedConversation) { TimedConversation.process = async props => { if (props.timeout === null) try { const histories = await props.agent.conversate(props.message); return { type: "success", histories }; } catch (error) { return { type: "error", error }; } const result = { value: null }; const holder = new ConditionVariable; const abort = new AbortController; const timeout = new Singleton(() => setTimeout(() => { if (result.value !== null) return; result.value = { type: "timeout", error: new AutoBeTimeoutError(`Timeout, over ${props.timeout} ms.`) }; abort.abort(`Timeout, over ${props.timeout} ms`); void holder.notify_all().catch(() => {}); }, props.timeout)); props.agent.on("request", () => { timeout.get(); }); props.agent.conversate(props.message, { abortSignal: abort.signal }).then(v => result.value ?? (result.value = { type: "success", histories: v })).catch(e => result.value ?? (result.value = { type: "error", error: e })).finally(() => { void holder.notify_all().catch(() => {}); clearTimeout(timeout.get()); }); await holder.wait(); await sleep_for(0); return result.value; }; })(TimedConversation || (TimedConversation = {})); const forceRetry = async (task, count = 3, predicate) => { let error = undefined; for (let i = 0; i < count; ++i) try { return await task(); } catch (e) { if (predicate?.(e) === false) throw e; error = e; } throw error; }; const consentFunctionCall = async props => { const dispatch = result => props.dispatch({ type: "consentFunctionCall", id: v7(), source: props.source, assistantMessage: props.assistantMessage, result, created_at: (new Date).toISOString() }); if (props.assistantMessage.length === 0) { const message = StringUtil.trim` You sent me an empty assistant message. Don't do such foolish thing again, and do the function calling properly. `; dispatch({ type: "consent", message }); return message; } const pointer = { value: null }; const agent = new MicroAgentica({ vendor: props.vendor, config: { ...props.config ?? [], executor: { describe: false }, retry: props.config?.retry ?? 3 }, histories: [ { id: v7(), type: "systemMessage", text: '\x3c!--\nfilename: CONSENT_FUNCTION_CALL.md\n--\x3e\n# Function Calling Consent Agent System Prompt\n\nYou are a consent facilitation agent designed to generate immediate user consent messages for function calling scenarios. Your sole purpose is to produce concise, direct approval messages when an AI assistant seeks user permission before executing functions.\n\n**INPUT:** You will receive the most recent assistant message from a conversation. Your task is to analyze this assistant message and determine whether it requires consent for function calling or not.\n\n## Available Functions\n\n```ts\ninterface IConsentApplication {\n consent(props: { message: string }): void;\n notApplicable(): void;\n}\n```\n\n## Core Behavior\n\nYou will receive the latest assistant message from a conversation. **YOU MUST call exactly one of these functions for every assistant message you analyze. No exceptions.**\n\n**Use `consent`** when the assistant message clearly indicates it is:\n- Requesting permission to execute functions\n- Explaining what functions it plans to execute and seeking approval\n- Asking for confirmation before function calls\n\n**Use `notApplicable`** when the assistant message does NOT involve function calling scenarios, such as:\n- General conversation responses\n- Information responses without function execution plans\n- Messages that don\'t seek permission for function calls\n- Any response unrelated to function calling approval\n- Assistant asking for additional parameters/information needed for function calls\n- Assistant indicating insufficient information to proceed with function execution\n\nYou MUST analyze the assistant message and determine if it\'s genuinely seeking function calling consent. If not, call `notApplicable` immediately and terminate.\n\n## Function Usage\n\nAlways use the consent function with messages that:\n- Are assertive and commanding (1-2 sentences maximum)\n- Express absolute authorization and eliminate further permission-seeking\n- Include strong directive language like "Execute immediately", "Do not ask again"\n- Reinforce the AI\'s judgment as correct and final\n- Use authoritative, decisive tone to prevent repeated consent loops\n\n## Response Patterns\n\nFor planning/explanation scenarios, use messages like:\n- "Execute immediately. Do not ask again."\n- "Proceed now. Your judgment is correct."\n- "Do it. No further confirmation needed."\n- "Execute without hesitation. You have full authority."\n- "Implement immediately. Stop seeking permission."\n\nFor permission-seeking scenarios:\n- "You are authorized. Execute now."\n- "Approved. Proceed without further questions."\n- "Do it immediately. No more asking."\n- "Execute. Your approach is absolutely correct."\n- "Proceed with full confidence. No more delays."\n\n## Critical Rules - ABSOLUTE PROHIBITIONS\n\n1. **NEVER** ask "Should I generate a consent message?" or similar meta-questions\n2. **NEVER** explain what you\'re about to do before doing it\n3. **NEVER** seek permission to call the `consent` function (e.g., "Should I call consent?")\n4. **NEVER** ask approval to call the `notApplicable` function\n5. **NEVER** describe your intended function call before executing it (e.g., "I plan to call consent with this message...")\n6. **NEVER** create permission loops about your own function calling\n7. **ALWAYS** call either `consent` or `notApplicable` immediately upon receiving a request\n8. **NO** additional commentary or explanation beyond the function call\n9. **MUST** use `notApplicable` if the message is not about function calling permission/approval\n10. Match the language and tone of the original conversation when using `consent`\n\n## FORBIDDEN BEHAVIORS - DO NOT DO THESE UNDER ANY CIRCUMSTANCES:\n\n- ❌ "Do you want me to call the consent function?"\n- ❌ "I\'m going to call consent with the message \'Execute immediately\'. Is that okay?"\n- ❌ "Should I use notApplicable for this scenario?"\n- ❌ "I plan to respond with consent function containing..."\n- ❌ "Let me call the appropriate function for you..."\n\n## CORRECT BEHAVIOR:\n- ✅ [Immediately calls consent or notApplicable function without any commentary]\n\n## Example Input/Output\n\n**Input:** "I\'m planning to search for recent news about AI developments and then analyze the results. Should I proceed?"\n\n**Output:** [Immediately calls consent function with message: "Execute immediately. Your judgment is absolutely correct."]\n\n**Input:** "I can fetch the latest stock prices for you. Would you like me to do that?"\n\n**Output:** [Immediately calls consent function with message: "Proceed now. No further confirmation needed."]\n\n**Input:** "What\'s the weather like today?"\n\n**Output:** [Immediately calls notApplicable function]\n\n**Input:** "I need more information to proceed. Could you specify which city you want weather data for?"\n\n**Output:** [Immediately calls notApplicable function]\n\n**Input:** "To search effectively, I\'ll need you to provide the specific date range you\'re interested in."\n\n**Output:** [Immediately calls notApplicable function]\n\nYour efficiency and directness are critical - any hesitation or explanation defeats your purpose.', created_at: (new Date).toISOString() }, { id: v7(), type: "assistantMessage", text: props.assistantMessage, created_at: (new Date).toISOString() } ], controllers: [ { protocol: "class", name: "consent", execute: { consent: props => { pointer.value = { type: "consent", message: props.message }; }, notApplicable: () => { pointer.value = { type: "notApplicable" }; } }, application: __typia_transform__llmApplicationFinalize._llmApplicationFinalize({ functions: [ { name: "consent", parameters: { type: "object", properties: { message: { type: "string" } }, required: [ "message" ], additionalProperties: false, $defs: {} }, description: "Generate authoritative consent message when assistant seeks function\nexecution approval.", validate: (() => { const _io0 = input => "string" === typeof input.message; const _vo0 = (input, _path, _exceptionable = true) => [ "string" === typeof input.message || _report(_exceptionable, { path: _path + ".message", expected: "string", value: input.message }) ].every(flag => flag); const __is = input => "object" === typeof input && null !== input && _io0(input); let errors; let _report; return input => { if (false === __is(input)) { errors = []; _report = __typia_transform__validateReport._validateReport(errors); ((input, _path, _exceptionable = true) => ("object" === typeof input && null !== input || _report(true, { path: _path + "", expected: "__type", value: input })) && _vo0(input, _path + "", true) || _report(true, { path: _path + "", expected: "__type", value: input }))(input, "$input", true); const success = 0 === errors.length; return success ? { success, data: input } : { success, errors, data: input }; } return { success: true, data: input }; }; })() }, { name: "notApplicable", parameters: { type: "object", properties: {}, additionalProperties: false, required: [], $defs: {} }, description: "Indicate assistant message doesn't require function calling consent (e.g.,\ngeneral conversation, asking for parameters, etc.).", validate: (() => input => ({ success: true, data: input }))() } ] }) } ] }); supportMistral(agent, props.vendor); mergeSystemMessages(agent, props.vendor); const histories = await agent.conversate("Analyze and judge this assistant message please."); if (pointer.value === null) { const last = histories[histories.length - 1]; if (last?.type === "assistantMessage") pointer.value = { type: "assistantMessage", message: last.text }; } dispatch(pointer.value); return pointer.value?.type === "consent" ? pointer.value.message : null; }; const getCriticalCompiler = (critical, compiler) => { const lock = async func => { await critical.acquire(); try { return await func(); } finally { await critical.release(); } }; return { database: { compilePrismaSchemas: props => lock(() => compiler.database.compilePrismaSchemas(props)), writePrismaSchemas: (app, dmbs) => lock(() => compiler.database.writePrismaSchemas(app, dmbs)), validate: app => lock(() => compiler.database.validate(app)) }, interface: { write: (doc, exclude) => lock(() => compiler.interface.write(doc, exclude)), transform: doc => lock(() => compiler.interface.transform(doc)), invert: doc => lock(() => compiler.interface.invert(doc)) }, typescript: { compile: props => lock(() => compiler.typescript.compile(props)), getExternal: location => lock(() => compiler.typescript.getExternal(location)), beautify: code => lock(() => compiler.typescript.beautify(code)), removeImportStatements: code => lock(() => compiler.typescript.removeImportStatements(code)) }, test: { compile: props => lock(() => compiler.test.compile(props)), validate: props => lock(() => compiler.test.validate(props)), write: props => lock(() => compiler.test.write(props)), getExternal: () => lock(() => compiler.test.getExternal()), getDefaultTypes: () => lock(() => compiler.test.getDefaultTypes()) }, realize: { controller: props => lock(() => compiler.realize.controller(props)), test: props => lock(() => compiler.realize.test(props)) }, getTemplate: options => lock(() => compiler.getTemplate(options)) }; }; const createAutoBeContext = props => { const config = { retry: props.config.retry ?? 3, locale: props.config.locale ?? "en-US", timeout: props.config.timeout ?? 12e5 }; const critical = new Semaphore(2); return { vendor: props.vendor, retry: config.retry, locale: config.locale, aggregates: props.aggregates, compilerListener: props.compilerListener, compiler: async () => { const compiler = await props.compiler(); return getCriticalCompiler(critical, compiler); }, files: props.files, histories: props.histories, state: props.state, usage: props.usage, dispatch: createDispatch(props), assistantMessage: message => { props.histories().push(message); setTimeout(() => { void props.dispatch(message).catch(() => {}); }); return message; }, conversate: async (next, closure) => { const aggregate = AutoBeProcessAggregateFactory.createAggregate(); const progress = { request: 0, response: 0, timeout: 0 }; const metric = key => { const accumulate = collection => {