@page-agent/llms 0.0.14 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,12 +2,6 @@ var __defProp = Object.defineProperty;
2
2
  var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
3
  import chalk from "chalk";
4
4
  import { z } from "zod";
5
- const DEFAULT_MODEL_NAME = "PAGE-AGENT-FREE-TESTING-RANDOM";
6
- const DEFAULT_API_KEY = "PAGE-AGENT-FREE-TESTING-RANDOM";
7
- const DEFAULT_BASE_URL = "https://hwcxiuzfylggtcktqgij.supabase.co/functions/v1/llm-testing-proxy";
8
- const LLM_MAX_RETRIES = 2;
9
- const DEFAULT_TEMPERATURE = 0.7;
10
- const DEFAULT_MAX_TOKENS = 4096;
11
5
  const InvokeErrorType = {
12
6
  // Retryable
13
7
  NETWORK_ERROR: "network_error",
@@ -304,6 +298,12 @@ const _OpenAIClient = class _OpenAIClient {
304
298
  };
305
299
  __name(_OpenAIClient, "OpenAIClient");
306
300
  let OpenAIClient = _OpenAIClient;
301
+ const DEFAULT_MODEL_NAME = "PAGE-AGENT-FREE-TESTING-RANDOM";
302
+ const DEFAULT_API_KEY = "PAGE-AGENT-FREE-TESTING-RANDOM";
303
+ const DEFAULT_BASE_URL = "https://hwcxiuzfylggtcktqgij.supabase.co/functions/v1/llm-testing-proxy";
304
+ const LLM_MAX_RETRIES = 2;
305
+ const DEFAULT_TEMPERATURE = 0.7;
306
+ const DEFAULT_MAX_TOKENS = 4096;
307
307
  function parseLLMConfig(config) {
308
308
  return {
309
309
  baseURL: config.baseURL ?? DEFAULT_BASE_URL,
@@ -1 +1 @@
1
- {"version":3,"file":"page-agent-llms.js","sources":["../../src/constants.ts","../../src/errors.ts","../../src/utils.ts","../../src/OpenAILenientClient.ts","../../src/index.ts"],"sourcesContent":["// Dev environment: use .env config if available, otherwise fallback to testing api\nexport const DEFAULT_MODEL_NAME: string =\n\timport.meta.env.DEV && import.meta.env.LLM_MODEL_NAME\n\t\t? import.meta.env.LLM_MODEL_NAME\n\t\t: 'PAGE-AGENT-FREE-TESTING-RANDOM'\n\nexport const DEFAULT_API_KEY: string =\n\timport.meta.env.DEV && import.meta.env.LLM_API_KEY\n\t\t? import.meta.env.LLM_API_KEY\n\t\t: 'PAGE-AGENT-FREE-TESTING-RANDOM'\n\nexport const DEFAULT_BASE_URL: string =\n\timport.meta.env.DEV && import.meta.env.LLM_BASE_URL\n\t\t? import.meta.env.LLM_BASE_URL\n\t\t: 'https://hwcxiuzfylggtcktqgij.supabase.co/functions/v1/llm-testing-proxy'\n\n// internal\n\nexport const LLM_MAX_RETRIES = 2\nexport const DEFAULT_TEMPERATURE = 0.7 // higher randomness helps auto-recovery\nexport const DEFAULT_MAX_TOKENS = 4096\n","/**\n * Error types and error handling for LLM invocations\n */\n\nexport const InvokeErrorType = {\n\t// Retryable\n\tNETWORK_ERROR: 'network_error', // Network error, retry\n\tRATE_LIMIT: 'rate_limit', // Rate limit, retry\n\tSERVER_ERROR: 'server_error', // 5xx, retry\n\tNO_TOOL_CALL: 'no_tool_call', // Model did not call tool\n\tINVALID_TOOL_ARGS: 'invalid_tool_args', // Tool args don't match schema\n\tTOOL_EXECUTION_ERROR: 'tool_execution_error', // Tool execution error\n\n\tUNKNOWN: 'unknown',\n\n\t// Non-retryable\n\tAUTH_ERROR: 'auth_error', // Authentication failed\n\tCONTEXT_LENGTH: 'context_length', // Prompt too long\n\tCONTENT_FILTER: 'content_filter', // Content filtered\n} as const\n\nexport type InvokeErrorType = (typeof InvokeErrorType)[keyof typeof InvokeErrorType]\n\nexport class InvokeError extends Error {\n\ttype: InvokeErrorType\n\tretryable: boolean\n\tstatusCode?: number\n\trawError?: unknown\n\n\tconstructor(type: InvokeErrorType, message: string, rawError?: unknown) {\n\t\tsuper(message)\n\t\tthis.name = 'InvokeError'\n\t\tthis.type = type\n\t\tthis.retryable = this.isRetryable(type)\n\t\tthis.rawError = rawError\n\t}\n\n\tprivate isRetryable(type: InvokeErrorType): boolean {\n\t\tconst retryableTypes: InvokeErrorType[] = [\n\t\t\tInvokeErrorType.NETWORK_ERROR,\n\t\t\tInvokeErrorType.RATE_LIMIT,\n\t\t\tInvokeErrorType.SERVER_ERROR,\n\t\t\tInvokeErrorType.NO_TOOL_CALL,\n\t\t\tInvokeErrorType.INVALID_TOOL_ARGS,\n\t\t\tInvokeErrorType.TOOL_EXECUTION_ERROR,\n\t\t\tInvokeErrorType.UNKNOWN,\n\t\t]\n\t\treturn retryableTypes.includes(type)\n\t}\n}\n","/**\n * Utility functions for LLM integration\n */\nimport chalk from 'chalk'\nimport { z } from 'zod'\n\nimport { InvokeError, InvokeErrorType } from './errors'\nimport type { MacroToolInput, Tool } from './types'\n\n/**\n * Convert Zod schema to OpenAI tool format\n * Uses Zod 4 native z.toJSONSchema()\n */\nexport function zodToOpenAITool(name: string, tool: Tool) {\n\treturn {\n\t\ttype: 'function' as const,\n\t\tfunction: {\n\t\t\tname,\n\t\t\tdescription: tool.description,\n\t\t\tparameters: z.toJSONSchema(tool.inputSchema, { target: 'openapi-3.0' }),\n\t\t},\n\t}\n}\n\n/**\n * Although some models cannot guarantee correct response. Common issues are fixable:\n * - Instead of returning a proper tool call. Return the tool call parameters in the message content.\n * - Returned tool calls or messages don't follow the nested MacroToolInput format.\n */\nexport function lenientParseMacroToolCall(\n\tresponseData: any,\n\tinputSchema: z.ZodObject<MacroToolInput & Record<string, any>>\n): MacroToolInput {\n\t// check\n\tconst choice = responseData.choices?.[0]\n\tif (!choice) {\n\t\tthrow new InvokeError(InvokeErrorType.UNKNOWN, 'No choices in response', responseData)\n\t}\n\n\t// check\n\tswitch (choice.finish_reason) {\n\t\tcase 'tool_calls':\n\t\tcase 'function_call': // gemini\n\t\tcase 'stop': // will try a robust parse\n\t\t\t// ✅ Normal\n\t\t\tbreak\n\t\tcase 'length':\n\t\t\t// ⚠️ Token limit reached\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.CONTEXT_LENGTH,\n\t\t\t\t'Response truncated: max tokens reached'\n\t\t\t)\n\t\tcase 'content_filter':\n\t\t\t// ❌ Content filtered\n\t\t\tthrow new InvokeError(InvokeErrorType.CONTENT_FILTER, 'Content filtered by safety system')\n\t\tdefault:\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.UNKNOWN,\n\t\t\t\t`Unexpected finish_reason: ${choice.finish_reason}`\n\t\t\t)\n\t}\n\n\t// Extract action schema from MacroToolInput schema\n\tconst actionSchema = inputSchema.shape.action\n\tif (!actionSchema) {\n\t\tthrow new Error('inputSchema must have an \"action\" field')\n\t}\n\n\t// patch stopReason mis-format\n\n\tlet arg: string | null = null\n\n\t// try to use tool call\n\tconst toolCall = choice.message?.tool_calls?.[0]?.function\n\targ = toolCall?.arguments ?? null\n\n\tif (arg && toolCall.name !== 'AgentOutput') {\n\t\t// TODO: check if toolCall.name is a valid action name\n\t\t// case: instead of AgentOutput, the model returned a action name as tool call\n\t\tconsole.log(chalk.yellow('lenientParseMacroToolCall: #1 fixing incorrect tool call'))\n\t\tlet tmpArg\n\t\ttry {\n\t\t\ttmpArg = JSON.parse(arg)\n\t\t} catch (error) {\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.INVALID_TOOL_ARGS,\n\t\t\t\t'Failed to parse tool arguments as JSON',\n\t\t\t\terror\n\t\t\t)\n\t\t}\n\t\targ = JSON.stringify({ action: { [toolCall.name]: tmpArg } })\n\t}\n\n\tif (!arg) {\n\t\t// try to use message content as JSON\n\t\targ = choice.message?.content.trim() || null\n\t}\n\n\tif (!arg) {\n\t\tthrow new InvokeError(\n\t\t\tInvokeErrorType.NO_TOOL_CALL,\n\t\t\t'No tool call or content found in response',\n\t\t\tresponseData\n\t\t)\n\t}\n\n\t// make sure is valid JSON\n\n\tlet parsedArgs: any\n\ttry {\n\t\tparsedArgs = JSON.parse(arg)\n\t} catch (error) {\n\t\tthrow new InvokeError(\n\t\t\tInvokeErrorType.INVALID_TOOL_ARGS,\n\t\t\t'Failed to parse tool arguments as JSON',\n\t\t\terror\n\t\t)\n\t}\n\n\t// patch incomplete formats\n\n\tif (parsedArgs.action || parsedArgs.evaluation_previous_goal || parsedArgs.next_goal) {\n\t\t// case: nested MacroToolInput format (correct format)\n\n\t\t// some models may give a empty action (they may think reasoning and action should be separate)\n\t\tif (!parsedArgs.action) {\n\t\t\tconsole.log(chalk.yellow('lenientParseMacroToolCall: #2 fixing incorrect tool call'))\n\t\t\tparsedArgs.action = {\n\t\t\t\twait: { seconds: 1 },\n\t\t\t}\n\t\t}\n\t} else if (parsedArgs.type && parsedArgs.function) {\n\t\t// case: upper level function call format provided. only keep its arguments\n\t\t// TODO: check if function name is a valid action name\n\t\tif (parsedArgs.function.name !== 'AgentOutput')\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.INVALID_TOOL_ARGS,\n\t\t\t\t`Expected function name \"AgentOutput\", got \"${parsedArgs.function.name}\"`,\n\t\t\t\tnull\n\t\t\t)\n\n\t\tconsole.log(chalk.yellow('lenientParseMacroToolCall: #3 fixing incorrect tool call'))\n\t\tparsedArgs = parsedArgs.function.arguments\n\t} else if (parsedArgs.name && parsedArgs.arguments) {\n\t\t// case: upper level function call format provided. only keep its arguments\n\t\t// TODO: check if function name is a valid action name\n\t\tif (parsedArgs.name !== 'AgentOutput')\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.INVALID_TOOL_ARGS,\n\t\t\t\t`Expected function name \"AgentOutput\", got \"${parsedArgs.name}\"`,\n\t\t\t\tnull\n\t\t\t)\n\n\t\tconsole.log(chalk.yellow('lenientParseMacroToolCall: #4 fixing incorrect tool call'))\n\t\tparsedArgs = parsedArgs.arguments\n\t} else {\n\t\t// case: only action parameters provided, wrap into MacroToolInput\n\t\t// TODO: check if action name is valid\n\t\tconsole.log(chalk.yellow('lenientParseMacroToolCall: #5 fixing incorrect tool call'))\n\t\tparsedArgs = { action: parsedArgs } as MacroToolInput\n\t}\n\n\t// make sure it's not wrapped as string\n\tif (typeof parsedArgs === 'string') {\n\t\tconsole.log(chalk.yellow('lenientParseMacroToolCall: #6 fixing incorrect tool call'))\n\t\ttry {\n\t\t\tparsedArgs = JSON.parse(parsedArgs)\n\t\t} catch (error) {\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.INVALID_TOOL_ARGS,\n\t\t\t\t'Failed to parse nested tool arguments as JSON',\n\t\t\t\terror\n\t\t\t)\n\t\t}\n\t}\n\n\tconst validation = inputSchema.safeParse(parsedArgs)\n\tif (validation.success) {\n\t\treturn validation.data as unknown as MacroToolInput\n\t} else {\n\t\tconst action = parsedArgs.action ?? {}\n\t\tconst actionName = Object.keys(action)[0] || 'unknown'\n\t\tconst actionArgs = JSON.stringify(action[actionName] || 'unknown')\n\n\t\t// TODO: check if action name is valid. give a readable error message\n\n\t\tthrow new InvokeError(\n\t\t\tInvokeErrorType.INVALID_TOOL_ARGS,\n\t\t\t`Tool arguments validation failed: action \"${actionName}\" with args ${actionArgs}`,\n\t\t\tvalidation.error\n\t\t)\n\t}\n}\n\nexport function modelPatch(body: Record<string, any>) {\n\tconst model: string = body.model || ''\n\n\tif (model.toLowerCase().startsWith('claude')) {\n\t\tbody.tool_choice = { type: 'tool', name: 'AgentOutput' }\n\t\tbody.thinking = { type: 'disabled' }\n\t\t// body.reasoning = { enabled: 'disabled' }\n\t}\n\n\tif (model.toLowerCase().includes('grok')) {\n\t\tconsole.log('Applying Grok patch: removing tool_choice')\n\t\tdelete body.tool_choice\n\t\tconsole.log('Applying Grok patch: disable reasoning and thinking')\n\t\tbody.thinking = { type: 'disabled', effort: 'minimal' }\n\t\tbody.reasoning = { enabled: false, effort: 'low' }\n\t}\n\n\treturn body\n}\n","/**\n * OpenAI Client implementation\n */\nimport { InvokeError, InvokeErrorType } from './errors'\nimport type {\n\tInvokeResult,\n\tLLMClient,\n\tMacroToolInput,\n\tMessage,\n\tOpenAIClientConfig,\n\tTool,\n} from './types'\nimport { lenientParseMacroToolCall, modelPatch, zodToOpenAITool } from './utils'\n\nexport class OpenAIClient implements LLMClient {\n\tconfig: OpenAIClientConfig\n\n\tconstructor(config: OpenAIClientConfig) {\n\t\tthis.config = config\n\t}\n\n\tasync invoke(\n\t\tmessages: Message[],\n\t\ttools: { AgentOutput: Tool<MacroToolInput> },\n\t\tabortSignal?: AbortSignal\n\t): Promise<InvokeResult> {\n\t\t// 1. Convert tools to OpenAI format\n\t\tconst openaiTools = Object.entries(tools).map(([name, tool]) => zodToOpenAITool(name, tool))\n\n\t\t// 2. Call API\n\t\tlet response: Response\n\t\ttry {\n\t\t\tresponse = await fetch(`${this.config.baseURL}/chat/completions`, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\tAuthorization: `Bearer ${this.config.apiKey}`,\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(\n\t\t\t\t\tmodelPatch({\n\t\t\t\t\t\tmodel: this.config.model,\n\t\t\t\t\t\ttemperature: this.config.temperature,\n\t\t\t\t\t\tmax_tokens: this.config.maxTokens,\n\t\t\t\t\t\tmessages,\n\n\t\t\t\t\t\ttools: openaiTools,\n\t\t\t\t\t\t// tool_choice: 'required',\n\t\t\t\t\t\ttool_choice: { type: 'function', function: { name: 'AgentOutput' } },\n\n\t\t\t\t\t\t// model specific params\n\n\t\t\t\t\t\t// reasoning_effort: 'minimal',\n\t\t\t\t\t\t// verbosity: 'low',\n\t\t\t\t\t\tparallel_tool_calls: false,\n\t\t\t\t\t})\n\t\t\t\t),\n\t\t\t\tsignal: abortSignal,\n\t\t\t})\n\t\t} catch (error: unknown) {\n\t\t\t// Network error\n\t\t\tthrow new InvokeError(InvokeErrorType.NETWORK_ERROR, 'Network request failed', error)\n\t\t}\n\n\t\t// 3. Handle HTTP errors\n\t\tif (!response.ok) {\n\t\t\tconst errorData = await response.json().catch()\n\t\t\tconst errorMessage =\n\t\t\t\t(errorData as { error?: { message?: string } }).error?.message || response.statusText\n\n\t\t\tif (response.status === 401 || response.status === 403) {\n\t\t\t\tthrow new InvokeError(\n\t\t\t\t\tInvokeErrorType.AUTH_ERROR,\n\t\t\t\t\t`Authentication failed: ${errorMessage}`,\n\t\t\t\t\terrorData\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (response.status === 429) {\n\t\t\t\tthrow new InvokeError(\n\t\t\t\t\tInvokeErrorType.RATE_LIMIT,\n\t\t\t\t\t`Rate limit exceeded: ${errorMessage}`,\n\t\t\t\t\terrorData\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (response.status >= 500) {\n\t\t\t\tthrow new InvokeError(\n\t\t\t\t\tInvokeErrorType.SERVER_ERROR,\n\t\t\t\t\t`Server error: ${errorMessage}`,\n\t\t\t\t\terrorData\n\t\t\t\t)\n\t\t\t}\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.UNKNOWN,\n\t\t\t\t`HTTP ${response.status}: ${errorMessage}`,\n\t\t\t\terrorData\n\t\t\t)\n\t\t}\n\n\t\t// parse response\n\n\t\tconst data = await response.json()\n\t\tconst tool = tools.AgentOutput\n\t\tconst macroToolInput = lenientParseMacroToolCall(data, tool.inputSchema as any)\n\n\t\t// Execute tool\n\t\tlet toolResult: unknown\n\t\ttry {\n\t\t\ttoolResult = await tool.execute(macroToolInput)\n\t\t} catch (e) {\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.TOOL_EXECUTION_ERROR,\n\t\t\t\t`Tool execution failed: ${(e as Error).message}`,\n\t\t\t\te\n\t\t\t)\n\t\t}\n\n\t\t// Return result (including cache tokens)\n\t\treturn {\n\t\t\ttoolCall: {\n\t\t\t\t// id: toolCall.id,\n\t\t\t\tname: 'AgentOutput',\n\t\t\t\targs: macroToolInput,\n\t\t\t},\n\t\t\ttoolResult,\n\t\t\tusage: {\n\t\t\t\tpromptTokens: data.usage?.prompt_tokens ?? 0,\n\t\t\t\tcompletionTokens: data.usage?.completion_tokens ?? 0,\n\t\t\t\ttotalTokens: data.usage?.total_tokens ?? 0,\n\t\t\t\tcachedTokens: data.usage?.prompt_tokens_details?.cached_tokens,\n\t\t\t\treasoningTokens: data.usage?.completion_tokens_details?.reasoning_tokens,\n\t\t\t},\n\t\t\trawResponse: data,\n\t\t}\n\t}\n}\n","/**\n * @topic LLM 与主流程的隔离\n * @reasoning\n * 将 llm 的调用和主流程分开是复杂的,\n * 因为 agent 的 tool call 通常集成在 llm 模块中,而而先得到 llm 返回,然后处理工具调用\n * tools 和 llm 调用的逻辑不可避免地耦合在一起,tool 的执行又和主流程耦合在一起\n * 而 history 的维护和更新逻辑,又必须嵌入多轮 tool call 中\n * @reasoning\n * - 放弃框架提供的自动的多轮调用,每轮调用都由主流程发起\n * - 理想情况下,llm 调用应该获得 structured output,然后由额外的模块触发 tool call,目前模型和框架都无法实现\n * - 当前只能将 llm api 和 本地 tool call 耦合在一起,不关心其中的衔接方式\n * @conclusion\n * - @llm responsibility boundary:\n * - call llm api with given messages and tools\n * - invoke tool call and get the result of the tool\n * - return the result to main loop\n * - @main_loop responsibility boundary:\n * - maintain all behaviors of an **agent**\n * @conclusion\n * - 这里的 llm 模块不是 agent,只负责一轮 llm 调用和工具调用,无状态\n */\n/**\n * @topic 结构化输出\n * @facts\n * - 几乎所有模型都支持 tool call schema\n * - 几乎所有模型都支持返回 json\n * - 只有 openAI/grok/gemini 支持 schema 并保证格式\n * - 主流模型都支持 tool_choice: required\n * - 除了 qwen 必须指定一个函数名 (9月上新后支持)\n * @conclusion\n * - 永远使用 tool call 来返回结构化数据,禁止模型直接返回(视为出错)\n * - 不能假设 tool 参数合法,必须有修复机制,而且修复也应该使用 tool call 返回\n */\nimport {\n\tDEFAULT_API_KEY,\n\tDEFAULT_BASE_URL,\n\tDEFAULT_MAX_TOKENS,\n\tDEFAULT_MODEL_NAME,\n\tDEFAULT_TEMPERATURE,\n\tLLM_MAX_RETRIES,\n} from './constants'\nimport { InvokeError } from './errors'\nimport { OpenAIClient } from './OpenAILenientClient'\nimport type {\n\tAgentBrain,\n\tInvokeResult,\n\tLLMClient,\n\tLLMConfig,\n\tMacroToolInput,\n\tMacroToolResult,\n\tMessage,\n\tTool,\n} from './types'\n\nexport type {\n\tAgentBrain,\n\tInvokeResult,\n\tLLMClient,\n\tLLMConfig,\n\tMacroToolInput,\n\tMacroToolResult,\n\tMessage,\n\tTool,\n}\n\nexport function parseLLMConfig(config: LLMConfig): Required<LLMConfig> {\n\treturn {\n\t\tbaseURL: config.baseURL ?? DEFAULT_BASE_URL,\n\t\tapiKey: config.apiKey ?? DEFAULT_API_KEY,\n\t\tmodel: config.model ?? DEFAULT_MODEL_NAME,\n\t\ttemperature: config.temperature ?? DEFAULT_TEMPERATURE,\n\t\tmaxTokens: config.maxTokens ?? DEFAULT_MAX_TOKENS,\n\t\tmaxRetries: config.maxRetries ?? LLM_MAX_RETRIES,\n\t}\n}\n\nexport class LLM extends EventTarget {\n\tconfig: Required<LLMConfig>\n\tclient: LLMClient\n\n\tconstructor(config: LLMConfig) {\n\t\tsuper()\n\t\tthis.config = parseLLMConfig(config)\n\n\t\t// Default to OpenAI client\n\t\tthis.client = new OpenAIClient({\n\t\t\tmodel: this.config.model,\n\t\t\tapiKey: this.config.apiKey,\n\t\t\tbaseURL: this.config.baseURL,\n\t\t\ttemperature: this.config.temperature,\n\t\t\tmaxTokens: this.config.maxTokens,\n\t\t})\n\t}\n\n\t/**\n\t * - call llm api *once*\n\t * - invoke tool call *once*\n\t * - return the result of the tool\n\t */\n\tasync invoke(\n\t\tmessages: Message[],\n\t\ttools: Record<string, Tool>,\n\t\tabortSignal: AbortSignal\n\t): Promise<InvokeResult> {\n\t\treturn await withRetry(\n\t\t\tasync () => {\n\t\t\t\tconst result = await this.client.invoke(messages, tools, abortSignal)\n\n\t\t\t\treturn result\n\t\t\t},\n\t\t\t// retry settings\n\t\t\t{\n\t\t\t\tmaxRetries: this.config.maxRetries,\n\t\t\t\tonRetry: (current: number) => {\n\t\t\t\t\tthis.dispatchEvent(\n\t\t\t\t\t\tnew CustomEvent('retry', { detail: { current, max: this.config.maxRetries } })\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t\tonError: (error: Error) => {\n\t\t\t\t\tthis.dispatchEvent(new CustomEvent('error', { detail: { error } }))\n\t\t\t\t},\n\t\t\t}\n\t\t)\n\t}\n}\n\nasync function withRetry<T>(\n\tfn: () => Promise<T>,\n\tsettings: {\n\t\tmaxRetries: number\n\t\tonRetry: (retries: number) => void\n\t\tonError: (error: Error) => void\n\t}\n): Promise<T> {\n\tlet retries = 0\n\tlet lastError: Error | null = null\n\twhile (retries <= settings.maxRetries) {\n\t\tif (retries > 0) {\n\t\t\tsettings.onRetry(retries)\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 100))\n\t\t}\n\n\t\ttry {\n\t\t\treturn await fn()\n\t\t} catch (error: unknown) {\n\t\t\tconsole.error(error)\n\t\t\tsettings.onError(error as Error)\n\n\t\t\t// do not retry if aborted by user\n\t\t\tif ((error as { name?: string })?.name === 'AbortError') throw error\n\n\t\t\t// do not retry if error is not retryable (InvokeError)\n\t\t\tif (error instanceof InvokeError && !error.retryable) throw error\n\n\t\t\tlastError = error as Error\n\t\t\tretries++\n\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 100))\n\t\t}\n\t}\n\n\tthrow lastError!\n}\n"],"names":["tool"],"mappings":"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"}
1
+ {"version":3,"file":"page-agent-llms.js","sources":["../../src/errors.ts","../../src/utils.ts","../../src/OpenAILenientClient.ts","../../src/constants.ts","../../src/index.ts"],"sourcesContent":["/**\n * Error types and error handling for LLM invocations\n */\n\nexport const InvokeErrorType = {\n\t// Retryable\n\tNETWORK_ERROR: 'network_error', // Network error, retry\n\tRATE_LIMIT: 'rate_limit', // Rate limit, retry\n\tSERVER_ERROR: 'server_error', // 5xx, retry\n\tNO_TOOL_CALL: 'no_tool_call', // Model did not call tool\n\tINVALID_TOOL_ARGS: 'invalid_tool_args', // Tool args don't match schema\n\tTOOL_EXECUTION_ERROR: 'tool_execution_error', // Tool execution error\n\n\tUNKNOWN: 'unknown',\n\n\t// Non-retryable\n\tAUTH_ERROR: 'auth_error', // Authentication failed\n\tCONTEXT_LENGTH: 'context_length', // Prompt too long\n\tCONTENT_FILTER: 'content_filter', // Content filtered\n} as const\n\nexport type InvokeErrorType = (typeof InvokeErrorType)[keyof typeof InvokeErrorType]\n\nexport class InvokeError extends Error {\n\ttype: InvokeErrorType\n\tretryable: boolean\n\tstatusCode?: number\n\trawError?: unknown\n\n\tconstructor(type: InvokeErrorType, message: string, rawError?: unknown) {\n\t\tsuper(message)\n\t\tthis.name = 'InvokeError'\n\t\tthis.type = type\n\t\tthis.retryable = this.isRetryable(type)\n\t\tthis.rawError = rawError\n\t}\n\n\tprivate isRetryable(type: InvokeErrorType): boolean {\n\t\tconst retryableTypes: InvokeErrorType[] = [\n\t\t\tInvokeErrorType.NETWORK_ERROR,\n\t\t\tInvokeErrorType.RATE_LIMIT,\n\t\t\tInvokeErrorType.SERVER_ERROR,\n\t\t\tInvokeErrorType.NO_TOOL_CALL,\n\t\t\tInvokeErrorType.INVALID_TOOL_ARGS,\n\t\t\tInvokeErrorType.TOOL_EXECUTION_ERROR,\n\t\t\tInvokeErrorType.UNKNOWN,\n\t\t]\n\t\treturn retryableTypes.includes(type)\n\t}\n}\n","/**\n * Utility functions for LLM integration\n */\nimport chalk from 'chalk'\nimport { z } from 'zod'\n\nimport { InvokeError, InvokeErrorType } from './errors'\nimport type { MacroToolInput, Tool } from './types'\n\n/**\n * Convert Zod schema to OpenAI tool format\n * Uses Zod 4 native z.toJSONSchema()\n */\nexport function zodToOpenAITool(name: string, tool: Tool) {\n\treturn {\n\t\ttype: 'function' as const,\n\t\tfunction: {\n\t\t\tname,\n\t\t\tdescription: tool.description,\n\t\t\tparameters: z.toJSONSchema(tool.inputSchema, { target: 'openapi-3.0' }),\n\t\t},\n\t}\n}\n\n/**\n * Although some models cannot guarantee correct response. Common issues are fixable:\n * - Instead of returning a proper tool call. Return the tool call parameters in the message content.\n * - Returned tool calls or messages don't follow the nested MacroToolInput format.\n */\nexport function lenientParseMacroToolCall(\n\tresponseData: any,\n\tinputSchema: z.ZodObject<MacroToolInput & Record<string, any>>\n): MacroToolInput {\n\t// check\n\tconst choice = responseData.choices?.[0]\n\tif (!choice) {\n\t\tthrow new InvokeError(InvokeErrorType.UNKNOWN, 'No choices in response', responseData)\n\t}\n\n\t// check\n\tswitch (choice.finish_reason) {\n\t\tcase 'tool_calls':\n\t\tcase 'function_call': // gemini\n\t\tcase 'stop': // will try a robust parse\n\t\t\t// ✅ Normal\n\t\t\tbreak\n\t\tcase 'length':\n\t\t\t// ⚠️ Token limit reached\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.CONTEXT_LENGTH,\n\t\t\t\t'Response truncated: max tokens reached'\n\t\t\t)\n\t\tcase 'content_filter':\n\t\t\t// ❌ Content filtered\n\t\t\tthrow new InvokeError(InvokeErrorType.CONTENT_FILTER, 'Content filtered by safety system')\n\t\tdefault:\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.UNKNOWN,\n\t\t\t\t`Unexpected finish_reason: ${choice.finish_reason}`\n\t\t\t)\n\t}\n\n\t// Extract action schema from MacroToolInput schema\n\tconst actionSchema = inputSchema.shape.action\n\tif (!actionSchema) {\n\t\tthrow new Error('inputSchema must have an \"action\" field')\n\t}\n\n\t// patch stopReason mis-format\n\n\tlet arg: string | null = null\n\n\t// try to use tool call\n\tconst toolCall = choice.message?.tool_calls?.[0]?.function\n\targ = toolCall?.arguments ?? null\n\n\tif (arg && toolCall.name !== 'AgentOutput') {\n\t\t// TODO: check if toolCall.name is a valid action name\n\t\t// case: instead of AgentOutput, the model returned a action name as tool call\n\t\tconsole.log(chalk.yellow('lenientParseMacroToolCall: #1 fixing incorrect tool call'))\n\t\tlet tmpArg\n\t\ttry {\n\t\t\ttmpArg = JSON.parse(arg)\n\t\t} catch (error) {\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.INVALID_TOOL_ARGS,\n\t\t\t\t'Failed to parse tool arguments as JSON',\n\t\t\t\terror\n\t\t\t)\n\t\t}\n\t\targ = JSON.stringify({ action: { [toolCall.name]: tmpArg } })\n\t}\n\n\tif (!arg) {\n\t\t// try to use message content as JSON\n\t\targ = choice.message?.content.trim() || null\n\t}\n\n\tif (!arg) {\n\t\tthrow new InvokeError(\n\t\t\tInvokeErrorType.NO_TOOL_CALL,\n\t\t\t'No tool call or content found in response',\n\t\t\tresponseData\n\t\t)\n\t}\n\n\t// make sure is valid JSON\n\n\tlet parsedArgs: any\n\ttry {\n\t\tparsedArgs = JSON.parse(arg)\n\t} catch (error) {\n\t\tthrow new InvokeError(\n\t\t\tInvokeErrorType.INVALID_TOOL_ARGS,\n\t\t\t'Failed to parse tool arguments as JSON',\n\t\t\terror\n\t\t)\n\t}\n\n\t// patch incomplete formats\n\n\tif (parsedArgs.action || parsedArgs.evaluation_previous_goal || parsedArgs.next_goal) {\n\t\t// case: nested MacroToolInput format (correct format)\n\n\t\t// some models may give a empty action (they may think reasoning and action should be separate)\n\t\tif (!parsedArgs.action) {\n\t\t\tconsole.log(chalk.yellow('lenientParseMacroToolCall: #2 fixing incorrect tool call'))\n\t\t\tparsedArgs.action = {\n\t\t\t\twait: { seconds: 1 },\n\t\t\t}\n\t\t}\n\t} else if (parsedArgs.type && parsedArgs.function) {\n\t\t// case: upper level function call format provided. only keep its arguments\n\t\t// TODO: check if function name is a valid action name\n\t\tif (parsedArgs.function.name !== 'AgentOutput')\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.INVALID_TOOL_ARGS,\n\t\t\t\t`Expected function name \"AgentOutput\", got \"${parsedArgs.function.name}\"`,\n\t\t\t\tnull\n\t\t\t)\n\n\t\tconsole.log(chalk.yellow('lenientParseMacroToolCall: #3 fixing incorrect tool call'))\n\t\tparsedArgs = parsedArgs.function.arguments\n\t} else if (parsedArgs.name && parsedArgs.arguments) {\n\t\t// case: upper level function call format provided. only keep its arguments\n\t\t// TODO: check if function name is a valid action name\n\t\tif (parsedArgs.name !== 'AgentOutput')\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.INVALID_TOOL_ARGS,\n\t\t\t\t`Expected function name \"AgentOutput\", got \"${parsedArgs.name}\"`,\n\t\t\t\tnull\n\t\t\t)\n\n\t\tconsole.log(chalk.yellow('lenientParseMacroToolCall: #4 fixing incorrect tool call'))\n\t\tparsedArgs = parsedArgs.arguments\n\t} else {\n\t\t// case: only action parameters provided, wrap into MacroToolInput\n\t\t// TODO: check if action name is valid\n\t\tconsole.log(chalk.yellow('lenientParseMacroToolCall: #5 fixing incorrect tool call'))\n\t\tparsedArgs = { action: parsedArgs } as MacroToolInput\n\t}\n\n\t// make sure it's not wrapped as string\n\tif (typeof parsedArgs === 'string') {\n\t\tconsole.log(chalk.yellow('lenientParseMacroToolCall: #6 fixing incorrect tool call'))\n\t\ttry {\n\t\t\tparsedArgs = JSON.parse(parsedArgs)\n\t\t} catch (error) {\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.INVALID_TOOL_ARGS,\n\t\t\t\t'Failed to parse nested tool arguments as JSON',\n\t\t\t\terror\n\t\t\t)\n\t\t}\n\t}\n\n\tconst validation = inputSchema.safeParse(parsedArgs)\n\tif (validation.success) {\n\t\treturn validation.data as unknown as MacroToolInput\n\t} else {\n\t\tconst action = parsedArgs.action ?? {}\n\t\tconst actionName = Object.keys(action)[0] || 'unknown'\n\t\tconst actionArgs = JSON.stringify(action[actionName] || 'unknown')\n\n\t\t// TODO: check if action name is valid. give a readable error message\n\n\t\tthrow new InvokeError(\n\t\t\tInvokeErrorType.INVALID_TOOL_ARGS,\n\t\t\t`Tool arguments validation failed: action \"${actionName}\" with args ${actionArgs}`,\n\t\t\tvalidation.error\n\t\t)\n\t}\n}\n\nexport function modelPatch(body: Record<string, any>) {\n\tconst model: string = body.model || ''\n\n\tif (model.toLowerCase().startsWith('claude')) {\n\t\tbody.tool_choice = { type: 'tool', name: 'AgentOutput' }\n\t\tbody.thinking = { type: 'disabled' }\n\t\t// body.reasoning = { enabled: 'disabled' }\n\t}\n\n\tif (model.toLowerCase().includes('grok')) {\n\t\tconsole.log('Applying Grok patch: removing tool_choice')\n\t\tdelete body.tool_choice\n\t\tconsole.log('Applying Grok patch: disable reasoning and thinking')\n\t\tbody.thinking = { type: 'disabled', effort: 'minimal' }\n\t\tbody.reasoning = { enabled: false, effort: 'low' }\n\t}\n\n\treturn body\n}\n","/**\n * OpenAI Client implementation\n */\nimport { InvokeError, InvokeErrorType } from './errors'\nimport type {\n\tInvokeResult,\n\tLLMClient,\n\tMacroToolInput,\n\tMessage,\n\tOpenAIClientConfig,\n\tTool,\n} from './types'\nimport { lenientParseMacroToolCall, modelPatch, zodToOpenAITool } from './utils'\n\nexport class OpenAIClient implements LLMClient {\n\tconfig: OpenAIClientConfig\n\n\tconstructor(config: OpenAIClientConfig) {\n\t\tthis.config = config\n\t}\n\n\tasync invoke(\n\t\tmessages: Message[],\n\t\ttools: { AgentOutput: Tool<MacroToolInput> },\n\t\tabortSignal?: AbortSignal\n\t): Promise<InvokeResult> {\n\t\t// 1. Convert tools to OpenAI format\n\t\tconst openaiTools = Object.entries(tools).map(([name, tool]) => zodToOpenAITool(name, tool))\n\n\t\t// 2. Call API\n\t\tlet response: Response\n\t\ttry {\n\t\t\tresponse = await fetch(`${this.config.baseURL}/chat/completions`, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders: {\n\t\t\t\t\t'Content-Type': 'application/json',\n\t\t\t\t\tAuthorization: `Bearer ${this.config.apiKey}`,\n\t\t\t\t},\n\t\t\t\tbody: JSON.stringify(\n\t\t\t\t\tmodelPatch({\n\t\t\t\t\t\tmodel: this.config.model,\n\t\t\t\t\t\ttemperature: this.config.temperature,\n\t\t\t\t\t\tmax_tokens: this.config.maxTokens,\n\t\t\t\t\t\tmessages,\n\n\t\t\t\t\t\ttools: openaiTools,\n\t\t\t\t\t\t// tool_choice: 'required',\n\t\t\t\t\t\ttool_choice: { type: 'function', function: { name: 'AgentOutput' } },\n\n\t\t\t\t\t\t// model specific params\n\n\t\t\t\t\t\t// reasoning_effort: 'minimal',\n\t\t\t\t\t\t// verbosity: 'low',\n\t\t\t\t\t\tparallel_tool_calls: false,\n\t\t\t\t\t})\n\t\t\t\t),\n\t\t\t\tsignal: abortSignal,\n\t\t\t})\n\t\t} catch (error: unknown) {\n\t\t\t// Network error\n\t\t\tthrow new InvokeError(InvokeErrorType.NETWORK_ERROR, 'Network request failed', error)\n\t\t}\n\n\t\t// 3. Handle HTTP errors\n\t\tif (!response.ok) {\n\t\t\tconst errorData = await response.json().catch()\n\t\t\tconst errorMessage =\n\t\t\t\t(errorData as { error?: { message?: string } }).error?.message || response.statusText\n\n\t\t\tif (response.status === 401 || response.status === 403) {\n\t\t\t\tthrow new InvokeError(\n\t\t\t\t\tInvokeErrorType.AUTH_ERROR,\n\t\t\t\t\t`Authentication failed: ${errorMessage}`,\n\t\t\t\t\terrorData\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (response.status === 429) {\n\t\t\t\tthrow new InvokeError(\n\t\t\t\t\tInvokeErrorType.RATE_LIMIT,\n\t\t\t\t\t`Rate limit exceeded: ${errorMessage}`,\n\t\t\t\t\terrorData\n\t\t\t\t)\n\t\t\t}\n\t\t\tif (response.status >= 500) {\n\t\t\t\tthrow new InvokeError(\n\t\t\t\t\tInvokeErrorType.SERVER_ERROR,\n\t\t\t\t\t`Server error: ${errorMessage}`,\n\t\t\t\t\terrorData\n\t\t\t\t)\n\t\t\t}\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.UNKNOWN,\n\t\t\t\t`HTTP ${response.status}: ${errorMessage}`,\n\t\t\t\terrorData\n\t\t\t)\n\t\t}\n\n\t\t// parse response\n\n\t\tconst data = await response.json()\n\t\tconst tool = tools.AgentOutput\n\t\tconst macroToolInput = lenientParseMacroToolCall(data, tool.inputSchema as any)\n\n\t\t// Execute tool\n\t\tlet toolResult: unknown\n\t\ttry {\n\t\t\ttoolResult = await tool.execute(macroToolInput)\n\t\t} catch (e) {\n\t\t\tthrow new InvokeError(\n\t\t\t\tInvokeErrorType.TOOL_EXECUTION_ERROR,\n\t\t\t\t`Tool execution failed: ${(e as Error).message}`,\n\t\t\t\te\n\t\t\t)\n\t\t}\n\n\t\t// Return result (including cache tokens)\n\t\treturn {\n\t\t\ttoolCall: {\n\t\t\t\t// id: toolCall.id,\n\t\t\t\tname: 'AgentOutput',\n\t\t\t\targs: macroToolInput,\n\t\t\t},\n\t\t\ttoolResult,\n\t\t\tusage: {\n\t\t\t\tpromptTokens: data.usage?.prompt_tokens ?? 0,\n\t\t\t\tcompletionTokens: data.usage?.completion_tokens ?? 0,\n\t\t\t\ttotalTokens: data.usage?.total_tokens ?? 0,\n\t\t\t\tcachedTokens: data.usage?.prompt_tokens_details?.cached_tokens,\n\t\t\t\treasoningTokens: data.usage?.completion_tokens_details?.reasoning_tokens,\n\t\t\t},\n\t\t\trawResponse: data,\n\t\t}\n\t}\n}\n","// Dev environment: use .env config if available, otherwise fallback to testing api\nexport const DEFAULT_MODEL_NAME: string =\n\timport.meta.env.DEV && import.meta.env.LLM_MODEL_NAME\n\t\t? import.meta.env.LLM_MODEL_NAME\n\t\t: 'PAGE-AGENT-FREE-TESTING-RANDOM'\n\nexport const DEFAULT_API_KEY: string =\n\timport.meta.env.DEV && import.meta.env.LLM_API_KEY\n\t\t? import.meta.env.LLM_API_KEY\n\t\t: 'PAGE-AGENT-FREE-TESTING-RANDOM'\n\nexport const DEFAULT_BASE_URL: string =\n\timport.meta.env.DEV && import.meta.env.LLM_BASE_URL\n\t\t? import.meta.env.LLM_BASE_URL\n\t\t: 'https://hwcxiuzfylggtcktqgij.supabase.co/functions/v1/llm-testing-proxy'\n\n// internal\n\nexport const LLM_MAX_RETRIES = 2\nexport const DEFAULT_TEMPERATURE = 0.7 // higher randomness helps auto-recovery\nexport const DEFAULT_MAX_TOKENS = 4096\n","/**\n * @topic LLM 与主流程的隔离\n * @reasoning\n * 将 llm 的调用和主流程分开是复杂的,\n * 因为 agent 的 tool call 通常集成在 llm 模块中,而而先得到 llm 返回,然后处理工具调用\n * tools 和 llm 调用的逻辑不可避免地耦合在一起,tool 的执行又和主流程耦合在一起\n * 而 history 的维护和更新逻辑,又必须嵌入多轮 tool call 中\n * @reasoning\n * - 放弃框架提供的自动的多轮调用,每轮调用都由主流程发起\n * - 理想情况下,llm 调用应该获得 structured output,然后由额外的模块触发 tool call,目前模型和框架都无法实现\n * - 当前只能将 llm api 和 本地 tool call 耦合在一起,不关心其中的衔接方式\n * @conclusion\n * - @llm responsibility boundary:\n * - call llm api with given messages and tools\n * - invoke tool call and get the result of the tool\n * - return the result to main loop\n * - @main_loop responsibility boundary:\n * - maintain all behaviors of an **agent**\n * @conclusion\n * - 这里的 llm 模块不是 agent,只负责一轮 llm 调用和工具调用,无状态\n */\n/**\n * @topic 结构化输出\n * @facts\n * - 几乎所有模型都支持 tool call schema\n * - 几乎所有模型都支持返回 json\n * - 只有 openAI/grok/gemini 支持 schema 并保证格式\n * - 主流模型都支持 tool_choice: required\n * - 除了 qwen 必须指定一个函数名 (9月上新后支持)\n * @conclusion\n * - 永远使用 tool call 来返回结构化数据,禁止模型直接返回(视为出错)\n * - 不能假设 tool 参数合法,必须有修复机制,而且修复也应该使用 tool call 返回\n */\nimport { OpenAIClient } from './OpenAILenientClient'\nimport {\n\tDEFAULT_API_KEY,\n\tDEFAULT_BASE_URL,\n\tDEFAULT_MAX_TOKENS,\n\tDEFAULT_MODEL_NAME,\n\tDEFAULT_TEMPERATURE,\n\tLLM_MAX_RETRIES,\n} from './constants'\nimport { InvokeError } from './errors'\nimport type {\n\tAgentBrain,\n\tInvokeResult,\n\tLLMClient,\n\tLLMConfig,\n\tMacroToolInput,\n\tMacroToolResult,\n\tMessage,\n\tTool,\n} from './types'\n\nexport type {\n\tAgentBrain,\n\tInvokeResult,\n\tLLMClient,\n\tLLMConfig,\n\tMacroToolInput,\n\tMacroToolResult,\n\tMessage,\n\tTool,\n}\n\nexport function parseLLMConfig(config: LLMConfig): Required<LLMConfig> {\n\treturn {\n\t\tbaseURL: config.baseURL ?? DEFAULT_BASE_URL,\n\t\tapiKey: config.apiKey ?? DEFAULT_API_KEY,\n\t\tmodel: config.model ?? DEFAULT_MODEL_NAME,\n\t\ttemperature: config.temperature ?? DEFAULT_TEMPERATURE,\n\t\tmaxTokens: config.maxTokens ?? DEFAULT_MAX_TOKENS,\n\t\tmaxRetries: config.maxRetries ?? LLM_MAX_RETRIES,\n\t}\n}\n\nexport class LLM extends EventTarget {\n\tconfig: Required<LLMConfig>\n\tclient: LLMClient\n\n\tconstructor(config: LLMConfig) {\n\t\tsuper()\n\t\tthis.config = parseLLMConfig(config)\n\n\t\t// Default to OpenAI client\n\t\tthis.client = new OpenAIClient({\n\t\t\tmodel: this.config.model,\n\t\t\tapiKey: this.config.apiKey,\n\t\t\tbaseURL: this.config.baseURL,\n\t\t\ttemperature: this.config.temperature,\n\t\t\tmaxTokens: this.config.maxTokens,\n\t\t})\n\t}\n\n\t/**\n\t * - call llm api *once*\n\t * - invoke tool call *once*\n\t * - return the result of the tool\n\t */\n\tasync invoke(\n\t\tmessages: Message[],\n\t\ttools: Record<string, Tool>,\n\t\tabortSignal: AbortSignal\n\t): Promise<InvokeResult> {\n\t\treturn await withRetry(\n\t\t\tasync () => {\n\t\t\t\tconst result = await this.client.invoke(messages, tools, abortSignal)\n\n\t\t\t\treturn result\n\t\t\t},\n\t\t\t// retry settings\n\t\t\t{\n\t\t\t\tmaxRetries: this.config.maxRetries,\n\t\t\t\tonRetry: (current: number) => {\n\t\t\t\t\tthis.dispatchEvent(\n\t\t\t\t\t\tnew CustomEvent('retry', { detail: { current, max: this.config.maxRetries } })\n\t\t\t\t\t)\n\t\t\t\t},\n\t\t\t\tonError: (error: Error) => {\n\t\t\t\t\tthis.dispatchEvent(new CustomEvent('error', { detail: { error } }))\n\t\t\t\t},\n\t\t\t}\n\t\t)\n\t}\n}\n\nasync function withRetry<T>(\n\tfn: () => Promise<T>,\n\tsettings: {\n\t\tmaxRetries: number\n\t\tonRetry: (retries: number) => void\n\t\tonError: (error: Error) => void\n\t}\n): Promise<T> {\n\tlet retries = 0\n\tlet lastError: Error | null = null\n\twhile (retries <= settings.maxRetries) {\n\t\tif (retries > 0) {\n\t\t\tsettings.onRetry(retries)\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 100))\n\t\t}\n\n\t\ttry {\n\t\t\treturn await fn()\n\t\t} catch (error: unknown) {\n\t\t\tconsole.error(error)\n\t\t\tsettings.onError(error as Error)\n\n\t\t\t// do not retry if aborted by user\n\t\t\tif ((error as { name?: string })?.name === 'AbortError') throw error\n\n\t\t\t// do not retry if error is not retryable (InvokeError)\n\t\t\tif (error instanceof InvokeError && !error.retryable) throw error\n\n\t\t\tlastError = error as Error\n\t\t\tretries++\n\n\t\t\tawait new Promise((resolve) => setTimeout(resolve, 100))\n\t\t}\n\t}\n\n\tthrow lastError!\n}\n"],"names":["tool"],"mappings":";;;;AAIO,MAAM,kBAAkB;AAAA;AAAA,EAE9B,eAAe;AAAA;AAAA,EACf,YAAY;AAAA;AAAA,EACZ,cAAc;AAAA;AAAA,EACd,cAAc;AAAA;AAAA,EACd,mBAAmB;AAAA;AAAA,EACnB,sBAAsB;AAAA;AAAA,EAEtB,SAAS;AAAA;AAAA,EAGT,YAAY;AAAA;AAAA,EACZ,gBAAgB;AAAA;AAAA,EAChB,gBAAgB;AAAA;AACjB;AAIO,MAAM,eAAN,MAAM,qBAAoB,MAAM;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAEA,YAAY,MAAuB,SAAiB,UAAoB;AACvE,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,OAAO;AACZ,SAAK,YAAY,KAAK,YAAY,IAAI;AACtC,SAAK,WAAW;AAAA,EACjB;AAAA,EAEQ,YAAY,MAAgC;AACnD,UAAM,iBAAoC;AAAA,MACzC,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,MAChB,gBAAgB;AAAA,IAAA;AAEjB,WAAO,eAAe,SAAS,IAAI;AAAA,EACpC;AACD;AA1BuC;AAAhC,IAAM,cAAN;ACVA,SAAS,gBAAgB,MAAc,MAAY;AACzD,SAAO;AAAA,IACN,MAAM;AAAA,IACN,UAAU;AAAA,MACT;AAAA,MACA,aAAa,KAAK;AAAA,MAClB,YAAY,EAAE,aAAa,KAAK,aAAa,EAAE,QAAQ,eAAe;AAAA,IAAA;AAAA,EACvE;AAEF;AATgB;AAgBT,SAAS,0BACf,cACA,aACiB;AAEjB,QAAM,SAAS,aAAa,UAAU,CAAC;AACvC,MAAI,CAAC,QAAQ;AACZ,UAAM,IAAI,YAAY,gBAAgB,SAAS,0BAA0B,YAAY;AAAA,EACtF;AAGA,UAAQ,OAAO,eAAA;AAAA,IACd,KAAK;AAAA,IACL,KAAK;AAAA;AAAA,IACL,KAAK;AAEJ;AAAA,IACD,KAAK;AAEJ,YAAM,IAAI;AAAA,QACT,gBAAgB;AAAA,QAChB;AAAA,MAAA;AAAA,IAEF,KAAK;AAEJ,YAAM,IAAI,YAAY,gBAAgB,gBAAgB,mCAAmC;AAAA,IAC1F;AACC,YAAM,IAAI;AAAA,QACT,gBAAgB;AAAA,QAChB,6BAA6B,OAAO,aAAa;AAAA,MAAA;AAAA,EAClD;AAIF,QAAM,eAAe,YAAY,MAAM;AACvC,MAAI,CAAC,cAAc;AAClB,UAAM,IAAI,MAAM,yCAAyC;AAAA,EAC1D;AAIA,MAAI,MAAqB;AAGzB,QAAM,WAAW,OAAO,SAAS,aAAa,CAAC,GAAG;AAClD,QAAM,UAAU,aAAa;AAE7B,MAAI,OAAO,SAAS,SAAS,eAAe;AAG3C,YAAQ,IAAI,MAAM,OAAO,0DAA0D,CAAC;AACpF,QAAI;AACJ,QAAI;AACH,eAAS,KAAK,MAAM,GAAG;AAAA,IACxB,SAAS,OAAO;AACf,YAAM,IAAI;AAAA,QACT,gBAAgB;AAAA,QAChB;AAAA,QACA;AAAA,MAAA;AAAA,IAEF;AACA,UAAM,KAAK,UAAU,EAAE,QAAQ,EAAE,CAAC,SAAS,IAAI,GAAG,OAAA,GAAU;AAAA,EAC7D;AAEA,MAAI,CAAC,KAAK;AAET,UAAM,OAAO,SAAS,QAAQ,KAAA,KAAU;AAAA,EACzC;AAEA,MAAI,CAAC,KAAK;AACT,UAAM,IAAI;AAAA,MACT,gBAAgB;AAAA,MAChB;AAAA,MACA;AAAA,IAAA;AAAA,EAEF;AAIA,MAAI;AACJ,MAAI;AACH,iBAAa,KAAK,MAAM,GAAG;AAAA,EAC5B,SAAS,OAAO;AACf,UAAM,IAAI;AAAA,MACT,gBAAgB;AAAA,MAChB;AAAA,MACA;AAAA,IAAA;AAAA,EAEF;AAIA,MAAI,WAAW,UAAU,WAAW,4BAA4B,WAAW,WAAW;AAIrF,QAAI,CAAC,WAAW,QAAQ;AACvB,cAAQ,IAAI,MAAM,OAAO,0DAA0D,CAAC;AACpF,iBAAW,SAAS;AAAA,QACnB,MAAM,EAAE,SAAS,EAAA;AAAA,MAAE;AAAA,IAErB;AAAA,EACD,WAAW,WAAW,QAAQ,WAAW,UAAU;AAGlD,QAAI,WAAW,SAAS,SAAS;AAChC,YAAM,IAAI;AAAA,QACT,gBAAgB;AAAA,QAChB,8CAA8C,WAAW,SAAS,IAAI;AAAA,QACtE;AAAA,MAAA;AAGF,YAAQ,IAAI,MAAM,OAAO,0DAA0D,CAAC;AACpF,iBAAa,WAAW,SAAS;AAAA,EAClC,WAAW,WAAW,QAAQ,WAAW,WAAW;AAGnD,QAAI,WAAW,SAAS;AACvB,YAAM,IAAI;AAAA,QACT,gBAAgB;AAAA,QAChB,8CAA8C,WAAW,IAAI;AAAA,QAC7D;AAAA,MAAA;AAGF,YAAQ,IAAI,MAAM,OAAO,0DAA0D,CAAC;AACpF,iBAAa,WAAW;AAAA,EACzB,OAAO;AAGN,YAAQ,IAAI,MAAM,OAAO,0DAA0D,CAAC;AACpF,iBAAa,EAAE,QAAQ,WAAA;AAAA,EACxB;AAGA,MAAI,OAAO,eAAe,UAAU;AACnC,YAAQ,IAAI,MAAM,OAAO,0DAA0D,CAAC;AACpF,QAAI;AACH,mBAAa,KAAK,MAAM,UAAU;AAAA,IACnC,SAAS,OAAO;AACf,YAAM,IAAI;AAAA,QACT,gBAAgB;AAAA,QAChB;AAAA,QACA;AAAA,MAAA;AAAA,IAEF;AAAA,EACD;AAEA,QAAM,aAAa,YAAY,UAAU,UAAU;AACnD,MAAI,WAAW,SAAS;AACvB,WAAO,WAAW;AAAA,EACnB,OAAO;AACN,UAAM,SAAS,WAAW,UAAU,CAAA;AACpC,UAAM,aAAa,OAAO,KAAK,MAAM,EAAE,CAAC,KAAK;AAC7C,UAAM,aAAa,KAAK,UAAU,OAAO,UAAU,KAAK,SAAS;AAIjE,UAAM,IAAI;AAAA,MACT,gBAAgB;AAAA,MAChB,6CAA6C,UAAU,eAAe,UAAU;AAAA,MAChF,WAAW;AAAA,IAAA;AAAA,EAEb;AACD;AAnKgB;AAqKT,SAAS,WAAW,MAA2B;AACrD,QAAM,QAAgB,KAAK,SAAS;AAEpC,MAAI,MAAM,YAAA,EAAc,WAAW,QAAQ,GAAG;AAC7C,SAAK,cAAc,EAAE,MAAM,QAAQ,MAAM,cAAA;AACzC,SAAK,WAAW,EAAE,MAAM,WAAA;AAAA,EAEzB;AAEA,MAAI,MAAM,YAAA,EAAc,SAAS,MAAM,GAAG;AACzC,YAAQ,IAAI,2CAA2C;AACvD,WAAO,KAAK;AACZ,YAAQ,IAAI,qDAAqD;AACjE,SAAK,WAAW,EAAE,MAAM,YAAY,QAAQ,UAAA;AAC5C,SAAK,YAAY,EAAE,SAAS,OAAO,QAAQ,MAAA;AAAA,EAC5C;AAEA,SAAO;AACR;AAlBgB;ACpLT,MAAM,gBAAN,MAAM,cAAkC;AAAA,EAC9C;AAAA,EAEA,YAAY,QAA4B;AACvC,SAAK,SAAS;AAAA,EACf;AAAA,EAEA,MAAM,OACL,UACA,OACA,aACwB;AAExB,UAAM,cAAc,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,MAAMA,KAAI,MAAM,gBAAgB,MAAMA,KAAI,CAAC;AAG3F,QAAI;AACJ,QAAI;AACH,iBAAW,MAAM,MAAM,GAAG,KAAK,OAAO,OAAO,qBAAqB;AAAA,QACjE,QAAQ;AAAA,QACR,SAAS;AAAA,UACR,gBAAgB;AAAA,UAChB,eAAe,UAAU,KAAK,OAAO,MAAM;AAAA,QAAA;AAAA,QAE5C,MAAM,KAAK;AAAA,UACV,WAAW;AAAA,YACV,OAAO,KAAK,OAAO;AAAA,YACnB,aAAa,KAAK,OAAO;AAAA,YACzB,YAAY,KAAK,OAAO;AAAA,YACxB;AAAA,YAEA,OAAO;AAAA;AAAA,YAEP,aAAa,EAAE,MAAM,YAAY,UAAU,EAAE,MAAM,gBAAc;AAAA;AAAA;AAAA;AAAA,YAMjE,qBAAqB;AAAA,UAAA,CACrB;AAAA,QAAA;AAAA,QAEF,QAAQ;AAAA,MAAA,CACR;AAAA,IACF,SAAS,OAAgB;AAExB,YAAM,IAAI,YAAY,gBAAgB,eAAe,0BAA0B,KAAK;AAAA,IACrF;AAGA,QAAI,CAAC,SAAS,IAAI;AACjB,YAAM,YAAY,MAAM,SAAS,KAAA,EAAO,MAAA;AACxC,YAAM,eACJ,UAA+C,OAAO,WAAW,SAAS;AAE5E,UAAI,SAAS,WAAW,OAAO,SAAS,WAAW,KAAK;AACvD,cAAM,IAAI;AAAA,UACT,gBAAgB;AAAA,UAChB,0BAA0B,YAAY;AAAA,UACtC;AAAA,QAAA;AAAA,MAEF;AACA,UAAI,SAAS,WAAW,KAAK;AAC5B,cAAM,IAAI;AAAA,UACT,gBAAgB;AAAA,UAChB,wBAAwB,YAAY;AAAA,UACpC;AAAA,QAAA;AAAA,MAEF;AACA,UAAI,SAAS,UAAU,KAAK;AAC3B,cAAM,IAAI;AAAA,UACT,gBAAgB;AAAA,UAChB,iBAAiB,YAAY;AAAA,UAC7B;AAAA,QAAA;AAAA,MAEF;AACA,YAAM,IAAI;AAAA,QACT,gBAAgB;AAAA,QAChB,QAAQ,SAAS,MAAM,KAAK,YAAY;AAAA,QACxC;AAAA,MAAA;AAAA,IAEF;AAIA,UAAM,OAAO,MAAM,SAAS,KAAA;AAC5B,UAAM,OAAO,MAAM;AACnB,UAAM,iBAAiB,0BAA0B,MAAM,KAAK,WAAkB;AAG9E,QAAI;AACJ,QAAI;AACH,mBAAa,MAAM,KAAK,QAAQ,cAAc;AAAA,IAC/C,SAAS,GAAG;AACX,YAAM,IAAI;AAAA,QACT,gBAAgB;AAAA,QAChB,0BAA2B,EAAY,OAAO;AAAA,QAC9C;AAAA,MAAA;AAAA,IAEF;AAGA,WAAO;AAAA,MACN,UAAU;AAAA;AAAA,QAET,MAAM;AAAA,QACN,MAAM;AAAA,MAAA;AAAA,MAEP;AAAA,MACA,OAAO;AAAA,QACN,cAAc,KAAK,OAAO,iBAAiB;AAAA,QAC3C,kBAAkB,KAAK,OAAO,qBAAqB;AAAA,QACnD,aAAa,KAAK,OAAO,gBAAgB;AAAA,QACzC,cAAc,KAAK,OAAO,uBAAuB;AAAA,QACjD,iBAAiB,KAAK,OAAO,2BAA2B;AAAA,MAAA;AAAA,MAEzD,aAAa;AAAA,IAAA;AAAA,EAEf;AACD;AAvH+C;AAAxC,IAAM,eAAN;ACbA,MAAM,qBAGT;AAEG,MAAM,kBAGT;AAEG,MAAM,mBAGT;AAIG,MAAM,kBAAkB;AACxB,MAAM,sBAAsB;AAC5B,MAAM,qBAAqB;AC6C3B,SAAS,eAAe,QAAwC;AACtE,SAAO;AAAA,IACN,SAAS,OAAO,WAAW;AAAA,IAC3B,QAAQ,OAAO,UAAU;AAAA,IACzB,OAAO,OAAO,SAAS;AAAA,IACvB,aAAa,OAAO,eAAe;AAAA,IACnC,WAAW,OAAO,aAAa;AAAA,IAC/B,YAAY,OAAO,cAAc;AAAA,EAAA;AAEnC;AATgB;AAWT,MAAM,OAAN,MAAM,aAAY,YAAY;AAAA,EACpC;AAAA,EACA;AAAA,EAEA,YAAY,QAAmB;AAC9B,UAAA;AACA,SAAK,SAAS,eAAe,MAAM;AAGnC,SAAK,SAAS,IAAI,aAAa;AAAA,MAC9B,OAAO,KAAK,OAAO;AAAA,MACnB,QAAQ,KAAK,OAAO;AAAA,MACpB,SAAS,KAAK,OAAO;AAAA,MACrB,aAAa,KAAK,OAAO;AAAA,MACzB,WAAW,KAAK,OAAO;AAAA,IAAA,CACvB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,MAAM,OACL,UACA,OACA,aACwB;AACxB,WAAO,MAAM;AAAA,MACZ,YAAY;AACX,cAAM,SAAS,MAAM,KAAK,OAAO,OAAO,UAAU,OAAO,WAAW;AAEpE,eAAO;AAAA,MACR;AAAA;AAAA,MAEA;AAAA,QACC,YAAY,KAAK,OAAO;AAAA,QACxB,SAAS,wBAAC,YAAoB;AAC7B,eAAK;AAAA,YACJ,IAAI,YAAY,SAAS,EAAE,QAAQ,EAAE,SAAS,KAAK,KAAK,OAAO,aAAW,CAAG;AAAA,UAAA;AAAA,QAE/E,GAJS;AAAA,QAKT,SAAS,wBAAC,UAAiB;AAC1B,eAAK,cAAc,IAAI,YAAY,SAAS,EAAE,QAAQ,EAAE,MAAA,EAAM,CAAG,CAAC;AAAA,QACnE,GAFS;AAAA,MAET;AAAA,IACD;AAAA,EAEF;AACD;AAhDqC;AAA9B,IAAM,MAAN;AAkDP,eAAe,UACd,IACA,UAKa;AACb,MAAI,UAAU;AACd,MAAI,YAA0B;AAC9B,SAAO,WAAW,SAAS,YAAY;AACtC,QAAI,UAAU,GAAG;AAChB,eAAS,QAAQ,OAAO;AACxB,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAG,CAAC;AAAA,IACxD;AAEA,QAAI;AACH,aAAO,MAAM,GAAA;AAAA,IACd,SAAS,OAAgB;AACxB,cAAQ,MAAM,KAAK;AACnB,eAAS,QAAQ,KAAc;AAG/B,UAAK,OAA6B,SAAS,aAAc,OAAM;AAG/D,UAAI,iBAAiB,eAAe,CAAC,MAAM,UAAW,OAAM;AAE5D,kBAAY;AACZ;AAEA,YAAM,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,GAAG,CAAC;AAAA,IACxD;AAAA,EACD;AAEA,QAAM;AACP;AApCe;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@page-agent/llms",
3
- "version": "0.0.14",
3
+ "version": "0.0.15",
4
4
  "type": "module",
5
5
  "main": "./dist/lib/page-agent-llms.js",
6
6
  "module": "./dist/lib/page-agent-llms.js",