@workglow/ai 0.2.30 → 0.2.32

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.
Files changed (38) hide show
  1. package/README.md +21 -21
  2. package/dist/browser.js +39 -22
  3. package/dist/browser.js.map +5 -5
  4. package/dist/bun.js +39 -22
  5. package/dist/bun.js.map +5 -5
  6. package/dist/model/ModelRegistry.d.ts +14 -6
  7. package/dist/model/ModelRegistry.d.ts.map +1 -1
  8. package/dist/node.js +39 -22
  9. package/dist/node.js.map +5 -5
  10. package/dist/provider/AiProviderRegistry.d.ts +21 -3
  11. package/dist/provider/AiProviderRegistry.d.ts.map +1 -1
  12. package/dist/provider-utils/BaseCloudProvider.d.ts +46 -0
  13. package/dist/provider-utils/BaseCloudProvider.d.ts.map +1 -0
  14. package/dist/provider-utils/CloudProviderClient.d.ts +40 -0
  15. package/dist/provider-utils/CloudProviderClient.d.ts.map +1 -0
  16. package/dist/provider-utils/HfModelSearch.d.ts +33 -0
  17. package/dist/provider-utils/HfModelSearch.d.ts.map +1 -0
  18. package/dist/provider-utils/OpenAIShapedChat.d.ts +71 -0
  19. package/dist/provider-utils/OpenAIShapedChat.d.ts.map +1 -0
  20. package/dist/provider-utils/PipelineTaskMapping.d.ts +12 -0
  21. package/dist/provider-utils/PipelineTaskMapping.d.ts.map +1 -0
  22. package/dist/provider-utils/ToolCallParsers.d.ts +252 -0
  23. package/dist/provider-utils/ToolCallParsers.d.ts.map +1 -0
  24. package/dist/provider-utils/imageOutputHelpers.d.ts +60 -0
  25. package/dist/provider-utils/imageOutputHelpers.d.ts.map +1 -0
  26. package/dist/provider-utils/modelSearchQuery.d.ts +23 -0
  27. package/dist/provider-utils/modelSearchQuery.d.ts.map +1 -0
  28. package/dist/provider-utils/registerProvider.d.ts +43 -0
  29. package/dist/provider-utils/registerProvider.d.ts.map +1 -0
  30. package/dist/provider-utils.d.ts +23 -0
  31. package/dist/provider-utils.d.ts.map +1 -0
  32. package/dist/provider-utils.js +1247 -0
  33. package/dist/provider-utils.js.map +19 -0
  34. package/dist/task/VectorSimilarityTask.d.ts +1 -1
  35. package/dist/task/VectorSimilarityTask.d.ts.map +1 -1
  36. package/dist/worker.js +17 -8
  37. package/dist/worker.js.map +3 -3
  38. package/package.json +20 -14
@@ -0,0 +1,19 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/provider-utils/registerProvider.ts", "../src/provider-utils/modelSearchQuery.ts", "../src/provider-utils/ToolCallParsers.ts", "../src/provider-utils/PipelineTaskMapping.ts", "../src/provider-utils/HfModelSearch.ts", "../src/provider-utils/imageOutputHelpers.ts", "../src/provider-utils/BaseCloudProvider.ts", "../src/provider-utils/CloudProviderClient.ts", "../src/task/ToolCallingUtils.ts", "../src/provider-utils/OpenAIShapedChat.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { AiProviderRegisterOptions } from \"../provider/AiProvider\";\nimport type { WorkerServerBase } from \"@workglow/util/worker\";\nimport { getLogger, globalServiceRegistry, WORKER_SERVER } from \"@workglow/util/worker\";\n\n/**\n * Shared helper for worker-side provider registration.\n * Retrieves the WorkerServer, calls the provider factory to register task\n * run functions, signals readiness, and logs the result.\n *\n * @param createAndRegister - Callback that creates the provider and calls\n * `registerOnWorkerServer(workerServer)`. Receives the WorkerServer instance.\n * @param providerName - Human-readable name for the log message.\n */\nexport async function registerProviderWorker(\n createAndRegister: (workerServer: WorkerServerBase) => void,\n providerName: string\n): Promise<void> {\n const workerServer = globalServiceRegistry.get(WORKER_SERVER);\n createAndRegister(workerServer);\n workerServer.sendReady();\n getLogger().info(`${providerName} worker job run functions registered`);\n}\n\n/**\n * Shared helper for main-thread inline provider registration.\n * Calls `register()` on an already-constructed provider instance.\n *\n * @param provider - A constructed QueuedProvider with task run functions.\n * @param providerName - Human-readable name for the log message.\n * @param options - Registration options (queue concurrency, etc.).\n */\nexport async function registerProviderInline(\n provider: { register(options: AiProviderRegisterOptions): Promise<void> },\n providerName: string,\n options?: AiProviderRegisterOptions\n): Promise<void> {\n await provider.register(options ?? {});\n getLogger().debug(`${providerName} inline job run functions registered`);\n}\n\n/**\n * Shared helper for main-thread worker-backed provider registration.\n * Calls `register()` on a QueuedProvider constructed without task functions\n * (the worker handles execution).\n *\n * @param provider - A constructed QueuedProvider (no task functions).\n * @param providerName - Human-readable name for the log message.\n * @param options - Registration options including the required `worker`.\n */\nexport async function registerProviderWithWorker(\n provider: { register(options: AiProviderRegisterOptions): Promise<void> },\n providerName: string,\n options: AiProviderRegisterOptions & { worker: Worker | (() => Worker) }\n): Promise<void> {\n await provider.register(options);\n getLogger().debug(`${providerName} worker main thread job run functions registered`);\n}\n",
6
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ModelSearchResultItem } from \"../task/ModelSearchTask\";\n\n/**\n * Normalized search string for model search, or undefined when absent or whitespace-only.\n */\nexport function normalizedModelSearchQuery(query: string | undefined): string | undefined {\n const t = query?.trim();\n return t ? t.toLowerCase() : undefined;\n}\n\n/**\n * Filter static/SDK model rows by optional query (substring match on label, value, or description).\n */\nexport function filterLabeledModelsByQuery<\n T extends { label: string; value: string; description?: string },\n>(models: ReadonlyArray<T>, query: string | undefined): T[] {\n const q = normalizedModelSearchQuery(query);\n if (!q) return [...models];\n return models.filter(\n (m) =>\n m.value.toLowerCase().includes(q) ||\n m.label.toLowerCase().includes(q) ||\n m.description?.toLowerCase().includes(q)\n );\n}\n\n/**\n * Filter {@link ModelSearchResultItem} rows by optional query.\n */\nexport function filterModelSearchResultsByQuery(\n results: ModelSearchResultItem[],\n query: string | undefined\n): ModelSearchResultItem[] {\n const q = normalizedModelSearchQuery(query);\n if (!q) return results;\n return results.filter(\n (m) =>\n m.id.toLowerCase().includes(q) ||\n m.label.toLowerCase().includes(q) ||\n m.description.toLowerCase().includes(q)\n );\n}\n",
7
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ToolCallingTaskInput } from \"../task/ToolCallingTask\";\nimport type { ToolCalls } from \"../task/ToolCallingUtils\";\nimport { getLogger } from \"@workglow/util/worker\";\n\n// ============================================================================\n// Types\n// ============================================================================\n\nexport interface ToolCall {\n readonly name: string;\n readonly arguments: Record<string, unknown>;\n readonly id: string | null;\n}\n\nexport interface ToolCallParserResult {\n readonly tool_calls: ReadonlyArray<ToolCall>;\n readonly content: string;\n readonly parser: string;\n}\n\nexport interface ParseToolCallsOptions {\n readonly tokenizer?: TokenizerLike | null;\n readonly model?: string | null;\n readonly parser?: string | null;\n}\n\n/**\n * Minimal tokenizer shape used for model-family detection.\n * Compatible with `PreTrainedTokenizer` from `@huggingface/transformers`.\n */\nexport interface TokenizerLike {\n readonly config?: {\n readonly name_or_path?: string;\n readonly _name_or_path?: string;\n readonly model_type?: string;\n };\n readonly name_or_path?: string;\n}\n\nexport type ParserFn = (text: string) => ToolCallParserResult | null;\n\n// ============================================================================\n// Text cleanup\n// ============================================================================\n\n/**\n * Strip thinking blocks (`<think>...</think>`) and HFT special tokens\n * (`<|im_end|>`, `<|end_of_turn|>`, etc.) from model output.\n * Used to clean up content text returned alongside tool calls.\n */\nexport function stripModelArtifacts(text: string): string {\n return text\n .replace(/<think>(?:[^<]|<(?!\\/think>))*<\\/think>/g, \"\")\n .replace(/<\\|[a-z_]+\\|>/g, \"\")\n .trim();\n}\n\n/**\n * Extract text from a content block that may be a string, array of content\n * blocks, or other structure.\n */\nexport function extractMessageText(content: unknown): string {\n if (typeof content === \"string\") {\n return content;\n }\n if (!Array.isArray(content)) {\n return String(content ?? \"\");\n }\n return content\n .filter(\n (block) => block && typeof block === \"object\" && (block as { type?: unknown }).type === \"text\"\n )\n .map((block) => String((block as { text?: unknown }).text ?? \"\"))\n .join(\"\");\n}\n\n// ============================================================================\n// Shared helpers\n// ============================================================================\n\nexport function makeToolCall(\n name: string,\n args: Record<string, unknown>,\n id: string | null = null\n): ToolCall {\n return { name, arguments: args, id };\n}\n\nexport function tryParseJson(text: string): unknown | undefined {\n try {\n return JSON.parse(text);\n } catch (e) {\n getLogger().debug(\"ToolCallParsers tryParseJson failed\", {\n error: (e as Error).message,\n textPrefix: text.slice(0, 120),\n });\n return undefined;\n }\n}\n\n/**\n * Scan `source` for balanced blocks delimited by `openChar`/`closeChar`\n * (e.g. `{`/`}` or `[`/`]`). Correctly handles JSON string literals so\n * that braces inside strings are not counted.\n *\n * This is a ReDoS-safe alternative to regex patterns like `\\{[\\s\\S]*?\\}`.\n */\nfunction findBalancedBlocks(\n source: string,\n openChar: string,\n closeChar: string,\n startFrom: number = 0\n): Array<{ text: string; start: number; end: number }> {\n const results: Array<{ text: string; start: number; end: number }> = [];\n const length = source.length;\n let i = startFrom;\n while (i < length) {\n if (source[i] !== openChar) {\n i++;\n continue;\n }\n let depth = 1;\n let j = i + 1;\n let inString = false;\n let escape = false;\n while (j < length && depth > 0) {\n const ch = source[j];\n if (inString) {\n if (escape) {\n escape = false;\n } else if (ch === \"\\\\\") {\n escape = true;\n } else if (ch === '\"') {\n inString = false;\n }\n } else {\n if (ch === '\"') {\n inString = true;\n } else if (ch === openChar) {\n depth++;\n } else if (ch === closeChar) {\n depth--;\n }\n }\n j++;\n }\n if (depth === 0) {\n results.push({ text: source.slice(i, j), start: i, end: j });\n i = j;\n } else {\n break;\n }\n }\n return results;\n}\n\nexport function parseJsonToolCallArray(\n jsonStr: string,\n nameKey: string = \"name\",\n argsKeys: ReadonlyArray<string> = [\"arguments\", \"parameters\"]\n): ReadonlyArray<ToolCall> | undefined {\n const parsed = tryParseJson(jsonStr.trim());\n if (!parsed) return undefined;\n\n const arr = Array.isArray(parsed) ? parsed : [parsed];\n const calls = arr\n .filter(\n (c): c is Record<string, unknown> =>\n !!c && typeof c === \"object\" && !!(c as Record<string, unknown>)[nameKey]\n )\n .map((c) => {\n const args = argsKeys.reduce<Record<string, unknown> | undefined>(\n (found, key) => found ?? (c[key] as Record<string, unknown> | undefined),\n undefined\n );\n return makeToolCall(c[nameKey] as string, args ?? {}, (c.id as string | null) ?? null);\n });\n\n return calls.length > 0 ? calls : undefined;\n}\n\n/**\n * Parse key=value argument syntax used by Gorilla, NexusRaven, and Gemma.\n * Handles quoted strings (`\"val\"`, `'val'`) and bare values.\n */\nexport function parseKeyValueArgs(argsStr: string): Record<string, unknown> {\n const args: Record<string, unknown> = {};\n if (!argsStr) return args;\n\n const argRegex = /(?<!\\w)(\\w+)\\s*=\\s*(?:\"([^\"]*)\"|'([^']*)'|([^\\s,]+))/g;\n let match: RegExpExecArray | null;\n while ((match = argRegex.exec(argsStr)) !== null) {\n const key = match[1];\n const value = match[2] ?? match[3] ?? match[4];\n args[key] = coerceArgValue(value);\n }\n return args;\n}\n\nexport function coerceArgValue(value: string): unknown {\n if (value === \"true\") return true;\n if (value === \"false\") return false;\n if (value !== \"\" && !isNaN(Number(value))) return Number(value);\n return value;\n}\n\n// ============================================================================\n// Tool choice utilities\n// ============================================================================\n\nexport function toolChoiceForcesToolCall(toolChoice: ToolCallingTaskInput[\"toolChoice\"]): boolean {\n return (\n toolChoice === \"required\" ||\n (toolChoice !== undefined && toolChoice !== \"auto\" && toolChoice !== \"none\")\n );\n}\n\nexport function forcedToolSelection(input: ToolCallingTaskInput): string | undefined {\n if (\n typeof input.toolChoice === \"string\" &&\n input.toolChoice !== \"auto\" &&\n input.toolChoice !== \"none\"\n ) {\n if (input.toolChoice !== \"required\") {\n return input.toolChoice;\n }\n }\n if (input.toolChoice === \"required\" && input.tools.length === 1) {\n return input.tools[0]?.name;\n }\n return undefined;\n}\n\nexport function resolveParsedToolName(name: string, input: ToolCallingTaskInput): string {\n if (input.tools.some((tool) => tool.name === name)) {\n return name;\n }\n return forcedToolSelection(input) ?? name;\n}\n\n/**\n * Convert a low-level parser result to the workglow `ToolCalls` type.\n * When `input` is provided, tool names are resolved against the available\n * tools list (and forced selection is applied for unrecognized names).\n */\nexport function adaptParserResult(\n result: ToolCallParserResult,\n input?: ToolCallingTaskInput\n): { text: string; toolCalls: ToolCalls } {\n return {\n text: stripModelArtifacts(result.content),\n toolCalls: result.tool_calls.map((call, index) => ({\n id: call.id ?? `call_${index}`,\n name: input ? resolveParsedToolName(call.name, input) : call.name,\n input: call.arguments,\n })),\n };\n}\n\n// ============================================================================\n// Individual parsers for each model family\n// ============================================================================\n\n/**\n * Llama 3.1/3.2/3.3 (Meta)\n *\n * Formats:\n * - `<|python_tag|>{\"name\": \"func\", \"parameters\": {\"arg\": \"val\"}}`\n * - `<function=func>{\"arg\": \"val\"}</function>` (3.2 lightweight 1B/3B)\n * - `{\"name\": \"func\", \"parameters\": {...}}` (bare JSON)\n */\nexport const parseLlama: ParserFn = (text) => {\n const calls: ToolCall[] = [];\n let content = text;\n\n // Try <|python_tag|> format first\n const pythonTagMatch = text.match(\n /<\\|python_tag\\|>((?:[^<]|<(?!\\|eot_id\\|>|\\|eom_id\\|>))*)(?:<\\|eot_id\\|>|<\\|eom_id\\|>|$)/\n );\n if (pythonTagMatch) {\n content = text.slice(0, text.indexOf(\"<|python_tag|>\")).trim();\n const jsonSection = pythonTagMatch[1].trim();\n for (const line of jsonSection.split(\"\\n\")) {\n const trimmed = line.trim();\n if (!trimmed) continue;\n const parsed = tryParseJson(trimmed) as Record<string, unknown> | undefined;\n if (parsed?.name) {\n calls.push(\n makeToolCall(\n parsed.name as string,\n (parsed.parameters ?? parsed.arguments ?? {}) as Record<string, unknown>,\n (parsed.id as string | null) ?? null\n )\n );\n }\n }\n }\n\n // Try <function=name>{args}</function> format (Llama 3.2 lightweight 1B/3B)\n if (calls.length === 0) {\n const funcTagRegex = /<function=(\\w+)>((?:[^<]|<(?!\\/function>))*)<\\/function>/g;\n let funcMatch: RegExpExecArray | null;\n while ((funcMatch = funcTagRegex.exec(text)) !== null) {\n const args = tryParseJson(funcMatch[2].trim()) as Record<string, unknown> | undefined;\n if (args) {\n calls.push(makeToolCall(funcMatch[1], args));\n }\n }\n if (calls.length > 0) {\n content = text.replace(/<function=\\w+>(?:[^<]|<(?!\\/function>))*<\\/function>/g, \"\").trim();\n }\n }\n\n // Check for {\"name\":...} pattern at end of output (no python_tag)\n // Uses balanced-brace scanning instead of regex to avoid ReDoS\n if (calls.length === 0) {\n const blocks = findBalancedBlocks(text, \"{\", \"}\");\n for (const block of blocks) {\n const parsed = tryParseJson(block.text) as Record<string, unknown> | undefined;\n if (parsed?.name && (parsed.parameters !== undefined || parsed.arguments !== undefined)) {\n calls.push(\n makeToolCall(\n parsed.name as string,\n (parsed.parameters ?? parsed.arguments ?? {}) as Record<string, unknown>,\n (parsed.id as string | null) ?? null\n )\n );\n }\n }\n if (calls.length > 0) {\n content = text.slice(0, text.indexOf(calls[0].name) - '{\"name\": \"'.length).trim();\n }\n }\n\n return calls.length > 0 ? { tool_calls: calls, content, parser: \"llama\" } : null;\n};\n\n/**\n * Mistral / Mixtral (Mistral AI)\n *\n * Format: `[TOOL_CALLS] [{\"name\": \"func\", \"arguments\": {...}, \"id\": \"9charID\"}]`\n */\nexport const parseMistral: ParserFn = (text) => {\n const marker = \"[TOOL_CALLS]\";\n const idx = text.indexOf(marker);\n if (idx === -1) return null;\n\n const content = text.slice(0, idx).trim();\n const jsonStr = text.slice(idx + marker.length).trim();\n const calls = parseJsonToolCallArray(jsonStr);\n\n return calls ? { tool_calls: calls, content, parser: \"mistral\" } : null;\n};\n\n/**\n * Hermes (NousResearch) — also used by Qwen 2.5, Qwen 3, SOLAR, and others\n *\n * Format: `<tool_call>\\n{\"name\": \"func\", \"arguments\": {...}}\\n</tool_call>`\n */\nexport const parseHermes: ParserFn = (text) => {\n const regex = /<tool_call>((?:[^<]|<(?!\\/tool_call>))*)<\\/tool_call>/g;\n const calls: ToolCall[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(text)) !== null) {\n const parsed = tryParseJson(match[1].trim()) as Record<string, unknown> | undefined;\n if (parsed) {\n calls.push(\n makeToolCall(\n (parsed.name ?? \"\") as string,\n (parsed.arguments ?? parsed.parameters ?? {}) as Record<string, unknown>,\n (parsed.id as string | null) ?? null\n )\n );\n }\n }\n\n if (calls.length === 0) return null;\n\n const content = text.replace(/<tool_call>(?:[^<]|<(?!\\/tool_call>))*<\\/tool_call>/g, \"\").trim();\n return { tool_calls: calls, content, parser: \"hermes\" };\n};\n\n/**\n * Cohere Command-R / Command-R+\n *\n * Formats:\n * - `Action: ```json\\n[{\"tool_name\": \"func\", \"parameters\": {...}}]\\n````\n * - `Action: [{\"tool_name\": ..., \"parameters\": ...}]`\n */\nexport const parseCohere: ParserFn = (text) => {\n const blockMatch = text.match(/Action:\\s*```(?:json)?\\n?((?:[^`]|`(?!``))*)\\n?```/);\n // Use balanced-bracket scanning for inline format to avoid ReDoS\n let inlineJsonStr: string | undefined;\n if (!blockMatch) {\n const actionIdx = text.indexOf(\"Action:\");\n if (actionIdx !== -1) {\n const afterAction = text.slice(actionIdx + \"Action:\".length).trimStart();\n if (afterAction.startsWith(\"[\")) {\n const blocks = findBalancedBlocks(afterAction, \"[\", \"]\");\n if (blocks.length > 0) {\n inlineJsonStr = blocks[0].text;\n }\n }\n }\n }\n\n const jsonStr = blockMatch?.[1] ?? inlineJsonStr;\n if (!jsonStr) return null;\n\n const calls = parseJsonToolCallArray(jsonStr, \"tool_name\", [\"parameters\", \"arguments\"]);\n if (!calls) {\n // Retry with \"name\" key\n const fallbackCalls = parseJsonToolCallArray(jsonStr);\n if (!fallbackCalls) return null;\n\n const actionIdx = text.indexOf(\"Action:\");\n const content = text.slice(0, actionIdx).trim();\n return { tool_calls: fallbackCalls, content, parser: \"cohere\" };\n }\n\n const actionIdx = text.indexOf(\"Action:\");\n const content = text.slice(0, actionIdx).trim();\n return { tool_calls: calls, content, parser: \"cohere\" };\n};\n\n/**\n * DeepSeek V2/V3/V3.1\n *\n * V2 format: `<|tool▁call▁begin|>function_name\\n```json\\n{...}\\n```<|tool▁call▁end|>`\n * V3.1 format: `<|tool▁calls▁begin|><|tool▁call▁begin|>name<|tool▁sep|>{args}<|tool▁call▁end|><|tool▁calls▁end|>`\n */\nexport const parseDeepSeek: ParserFn = (text) => {\n const calls: ToolCall[] = [];\n\n // Helper to match both fullwidth | and ASCII | bar variants, and ▁ or space\n const bar = \"(?:||\\\\|)\";\n const sep = \"[\\\\s\\u2581]\";\n\n // Try V3.1 format first: name<|tool▁sep|>{args}\n const v31Regex = new RegExp(\n `<${bar}tool${sep}call${sep}begin${bar}>\\\\s*(\\\\w+)\\\\s*<${bar}tool${sep}sep${bar}>\\\\s*([^<]*(?:<(?!${bar}tool${sep}call${sep}end${bar}>)[^<]*)*)\\\\s*<${bar}tool${sep}call${sep}end${bar}>`,\n \"g\"\n );\n let match: RegExpExecArray | null;\n while ((match = v31Regex.exec(text)) !== null) {\n const args = tryParseJson(match[2].trim()) as Record<string, unknown> | undefined;\n if (args) {\n calls.push(makeToolCall(match[1], args));\n }\n }\n\n // Try V2 format: name\\n```json\\n{args}\\n```\n if (calls.length === 0) {\n const v2Regex = new RegExp(\n `<${bar}tool${sep}call${sep}begin${bar}>\\\\s*(\\\\w+)\\\\s*\\\\n\\`\\`\\`(?:json)?\\\\n([^\\`]*(?:\\`(?!\\`\\`)[^\\`]*)*)\\\\n\\`\\`\\`\\\\s*<${bar}tool${sep}call${sep}end${bar}>`,\n \"g\"\n );\n while ((match = v2Regex.exec(text)) !== null) {\n const args = tryParseJson(match[2].trim()) as Record<string, unknown> | undefined;\n if (args) {\n calls.push(makeToolCall(match[1], args));\n }\n }\n }\n\n if (calls.length === 0) return null;\n\n const content = text\n .replace(new RegExp(`<${bar}tool${sep}calls?${sep}(?:begin|end)${bar}>`, \"g\"), \"\")\n .replace(\n new RegExp(\n `<${bar}tool${sep}call${sep}(?:begin|end)${bar}>[^<]*(?:<(?!${bar}tool${sep}call${sep}end${bar}>)[^<]*)*<${bar}tool${sep}call${sep}end${bar}>`,\n \"g\"\n ),\n \"\"\n )\n .replace(new RegExp(`<${bar}tool${sep}sep${bar}>`, \"g\"), \"\")\n .trim();\n return { tool_calls: calls, content, parser: \"deepseek\" };\n};\n\n/**\n * Phi-4 / Phi-4-mini (Microsoft)\n *\n * Format: `<|tool_calls|>[{\"name\": \"func\", \"arguments\": {...}}]<|/tool_calls|>`\n */\nexport const parsePhi: ParserFn = (text) => {\n const match = text.match(/<\\|tool_calls\\|>((?:[^<]|<(?!\\|\\/tool_calls\\|>))*)<\\|\\/tool_calls\\|>/);\n if (!match) return null;\n\n const calls = parseJsonToolCallArray(match[1]);\n if (!calls) return null;\n\n const content = text.slice(0, text.indexOf(\"<|tool_calls|>\")).trim();\n return { tool_calls: calls, content, parser: \"phi\" };\n};\n\n/**\n * Phi-3 functools format (legacy)\n *\n * Format: `functools[{\"name\": \"func\", \"arguments\": {...}}]`\n */\nexport const parsePhiFunctools: ParserFn = (text) => {\n const idx = text.indexOf(\"functools\");\n if (idx === -1) return null;\n\n // Scan forward past optional whitespace to find the opening [\n let start = idx + \"functools\".length;\n while (start < text.length && /\\s/.test(text[start])) start++;\n if (start >= text.length || text[start] !== \"[\") return null;\n\n const blocks = findBalancedBlocks(text, \"[\", \"]\", start);\n if (blocks.length === 0) return null;\n\n const calls = parseJsonToolCallArray(blocks[0].text);\n if (!calls) return null;\n\n const content = text.slice(0, idx).trim();\n return { tool_calls: calls, content, parser: \"phi_functools\" };\n};\n\n/**\n * InternLM 2 / 2.5 (Shanghai AI Lab)\n *\n * Format: `<|action_start|><|plugin|>\\n{\"name\": \"func\", \"parameters\": {...}}<|action_end|>`\n */\nexport const parseInternLM: ParserFn = (text) => {\n const regex =\n /<\\|action_start\\|>\\s*<\\|plugin\\|>((?:[^<]|<(?!\\|action_end\\|>))*)<\\|action_end\\|>/g;\n const calls: ToolCall[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(text)) !== null) {\n const parsed = tryParseJson(match[1].trim()) as Record<string, unknown> | undefined;\n if (parsed) {\n calls.push(\n makeToolCall(\n (parsed.name ?? \"\") as string,\n (parsed.parameters ?? parsed.arguments ?? {}) as Record<string, unknown>,\n (parsed.id as string | null) ?? null\n )\n );\n }\n }\n\n if (calls.length === 0) return null;\n\n const content = text\n .replace(/<\\|action_start\\|>\\s*<\\|plugin\\|>(?:[^<]|<(?!\\|action_end\\|>))*<\\|action_end\\|>/g, \"\")\n .trim();\n return { tool_calls: calls, content, parser: \"internlm\" };\n};\n\n/**\n * ChatGLM / GLM-4 (Zhipu AI)\n *\n * Format: function name followed by newline and JSON arguments.\n * `func_name\\n{\"arg\": \"val\"}`\n */\nexport const parseChatGLM: ParserFn = (text) => {\n const match = text.match(/^(\\w+)\\n(\\{[\\s\\S]*\\})\\s*$/m);\n if (!match) return null;\n\n const args = tryParseJson(match[2].trim()) as Record<string, unknown> | undefined;\n if (!args) return null;\n\n return {\n tool_calls: [makeToolCall(match[1], args)],\n content: \"\",\n parser: \"chatglm\",\n };\n};\n\n/**\n * Functionary (MeetKai)\n *\n * Format: `>>>func_name\\n{\"arg\": \"val\"}`\n * Uses `all` as a special function name for regular text.\n */\nexport const parseFunctionary: ParserFn = (text) => {\n const regex = />>>\\s*(\\w+)\\s*\\n((?:(?!>>>)[\\s\\S])*)/g;\n const calls: ToolCall[] = [];\n let content = \"\";\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(text)) !== null) {\n const funcName = match[1].trim();\n const body = match[2].trim();\n\n if (funcName === \"all\") {\n content += body;\n continue;\n }\n\n const args = tryParseJson(body) as Record<string, unknown> | undefined;\n calls.push(makeToolCall(funcName, args ?? { content: body }));\n }\n\n if (calls.length === 0) return null;\n return { tool_calls: calls, content: content.trim(), parser: \"functionary\" };\n};\n\n/**\n * Gorilla (Berkeley)\n *\n * Format: `<<function>>func_name(arg1=\"val1\", arg2=val2)`\n */\nexport const parseGorilla: ParserFn = (text) => {\n const regex = /<<function>>\\s{0,20}(\\w+)\\(([^)]*)\\)/g;\n const calls: ToolCall[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(text)) !== null) {\n calls.push(makeToolCall(match[1], parseKeyValueArgs(match[2].trim())));\n }\n\n if (calls.length === 0) return null;\n\n const content = text.replace(/<<function>>\\s{0,20}\\w+\\([^)]*\\)/g, \"\").trim();\n return { tool_calls: calls, content, parser: \"gorilla\" };\n};\n\n/**\n * NexusRaven (Nexusflow)\n *\n * Format: `Call: func_name(arg1=\"val1\", arg2=val2)\\nThought: reasoning...`\n */\nexport const parseNexusRaven: ParserFn = (text) => {\n const regex = /Call:\\s{0,20}(\\w+)\\(([^)]*)\\)/g;\n const calls: ToolCall[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(text)) !== null) {\n calls.push(makeToolCall(match[1], parseKeyValueArgs(match[2].trim())));\n }\n\n if (calls.length === 0) return null;\n\n const thoughtMatch = text.match(/Thought:\\s*((?:(?!Call:)[\\s\\S])*)/);\n const content =\n thoughtMatch?.[1]?.trim() ?? text.replace(/Call:\\s{0,20}\\w+\\([^)]*\\)/g, \"\").trim();\n return { tool_calls: calls, content, parser: \"nexusraven\" };\n};\n\n/**\n * xLAM (Salesforce)\n *\n * Format: Raw JSON array of tool calls: `[{\"name\": \"func\", \"arguments\": {...}}]`\n * May be wrapped in ```json code blocks.\n */\nexport const parseXLAM: ParserFn = (text) => {\n // Try code block format first using ReDoS-safe backtick matching\n const codeBlockMatch = text.match(/```(?:json)?\\n?((?:[^`]|`(?!``))*)\\n?```/);\n let jsonStr: string | undefined;\n let isCodeBlock = false;\n\n if (codeBlockMatch) {\n const inner = codeBlockMatch[1].trim();\n if (inner.startsWith(\"[\")) {\n jsonStr = inner;\n isCodeBlock = true;\n }\n }\n\n if (!jsonStr) {\n const trimmed = text.trim();\n if (!trimmed.startsWith(\"[\")) return null;\n jsonStr = trimmed;\n }\n\n const calls = parseJsonToolCallArray(jsonStr);\n if (!calls) return null;\n\n const content = isCodeBlock ? text.slice(0, text.indexOf(\"```\")).trim() : \"\";\n return { tool_calls: calls, content, parser: \"xlam\" };\n};\n\n/**\n * FireFunction (Fireworks AI)\n *\n * Format: `{\"tool_calls\": [{\"function\": {\"name\": \"...\", \"arguments\": \"...\"}}]}`\n */\nexport const parseFireFunction: ParserFn = (text) => {\n // Use balanced-bracket scanning to avoid ReDoS\n const toolCallsIdx = text.indexOf('\"tool_calls\"');\n if (toolCallsIdx === -1) return null;\n\n // Find the opening [ after \"tool_calls\":\n let bracketStart = text.indexOf(\"[\", toolCallsIdx);\n if (bracketStart === -1) return null;\n\n const blocks = findBalancedBlocks(text, \"[\", \"]\", bracketStart);\n if (blocks.length === 0) return null;\n\n const parsed = tryParseJson(blocks[0].text) as Array<Record<string, unknown>> | undefined;\n if (!parsed || !Array.isArray(parsed)) return null;\n\n const calls: ToolCall[] = [];\n for (const c of parsed) {\n const fn = c.function as Record<string, unknown> | undefined;\n if (!fn?.name) continue;\n\n let args = fn.arguments ?? {};\n if (typeof args === \"string\") {\n args = tryParseJson(args) ?? {};\n }\n calls.push(\n makeToolCall(\n fn.name as string,\n args as Record<string, unknown>,\n (c.id as string | null) ?? null\n )\n );\n }\n\n return calls.length > 0 ? { tool_calls: calls, content: \"\", parser: \"firefunction\" } : null;\n};\n\n/**\n * Granite (IBM)\n *\n * Format: `<|tool_call|>{\"name\": \"func\", \"arguments\": {...}}<|/tool_call|>` or `<|end_of_text|>`\n */\nexport const parseGranite: ParserFn = (text) => {\n const regex =\n /<\\|tool_call\\|>((?:[^<]|<(?!\\|\\/tool_call\\|>|\\|end_of_text\\|>))*?)(?:<\\|\\/tool_call\\|>|<\\|end_of_text\\|>|$)/g;\n const calls: ToolCall[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(text)) !== null) {\n const parsed = tryParseJson(match[1].trim()) as Record<string, unknown> | undefined;\n if (parsed) {\n calls.push(\n makeToolCall(\n (parsed.name ?? \"\") as string,\n (parsed.arguments ?? parsed.parameters ?? {}) as Record<string, unknown>,\n (parsed.id as string | null) ?? null\n )\n );\n }\n }\n\n if (calls.length === 0) return null;\n\n const content = text\n .replace(\n /<\\|tool_call\\|>(?:[^<]|<(?!\\|\\/tool_call\\|>|\\|end_of_text\\|>))*(?:<\\|\\/tool_call\\|>|$)/g,\n \"\"\n )\n .trim();\n return { tool_calls: calls, content, parser: \"granite\" };\n};\n\n/**\n * Gemma 2/3 (Google) — prompt-based, no dedicated tokens\n *\n * Formats:\n * - ```tool_code\\nfunc(arg=val)\\n```\n * - `{\"name\": \"func\", \"parameters\": {...}}`\n */\nexport const parseGemma: ParserFn = (text) => {\n // Manual extraction to avoid ReDoS with backtick-matching regexes\n const openMarker = \"```tool_code\";\n const openIdx = text.indexOf(openMarker);\n if (openIdx === -1) return null;\n const lineStart = text.indexOf(\"\\n\", openIdx + openMarker.length);\n if (lineStart === -1) return null;\n // Find closing ``` on its own line after the content\n let closeIdx = -1;\n let searchFrom = lineStart + 1;\n while (searchFrom < text.length) {\n const candidate = text.indexOf(\"```\", searchFrom);\n if (candidate === -1) break;\n // Ensure the ``` is preceded by a newline (possibly with whitespace)\n const lineBegin = text.lastIndexOf(\"\\n\", candidate - 1);\n if (lineBegin >= lineStart && text.slice(lineBegin + 1, candidate).trim() === \"\") {\n closeIdx = candidate;\n break;\n }\n searchFrom = candidate + 3;\n }\n if (closeIdx === -1) return null;\n\n const rawCode = text.slice(lineStart + 1, closeIdx).replace(/\\n[ \\t]*$/, \"\");\n const code = rawCode.trim();\n const funcMatch = code.match(/^(\\w+)\\(([\\s\\S]*)\\)$/);\n if (!funcMatch) return null;\n\n // Remove the entire fenced block from content\n const blockEnd = closeIdx + 3;\n const content = (text.slice(0, openIdx) + text.slice(blockEnd)).trim();\n return {\n tool_calls: [makeToolCall(funcMatch[1], parseKeyValueArgs(funcMatch[2].trim()))],\n content,\n parser: \"gemma\",\n };\n};\n\n/**\n * Parse Liquid/LFM-style Pythonic function call arguments.\n * Handles both `key=val, key2=val2` and `params=JSON` patterns.\n * When a single `params` argument contains a JSON object, spreads it.\n */\nfunction parseLiquidArgs(argsStr: string): Record<string, unknown> {\n const trimmed = argsStr.trim();\n\n // Try params=JSON pattern: params={\"key\": \"val\", ...} or params={'key': 'val', ...}\n const paramsMatch = trimmed.match(/^params\\s*=\\s*(\\{[\\s\\S]*\\})$/);\n if (paramsMatch) {\n const jsonStr = paramsMatch[1].replace(/'/g, '\"');\n const parsed = tryParseJson(jsonStr) as Record<string, unknown> | undefined;\n if (parsed && typeof parsed === \"object\") {\n return parsed;\n }\n }\n\n // Try bare JSON object: { key: \"val\", ... } (JS-style, keys may be unquoted)\n if (trimmed.startsWith(\"{\") && trimmed.endsWith(\"}\")) {\n // Add quotes around unquoted keys for JSON.parse\n const jsonified = trimmed.replace(/([{,]\\s*)(\\w+)\\s*:/g, '$1\"$2\":');\n const parsed = tryParseJson(jsonified) as Record<string, unknown> | undefined;\n if (parsed && typeof parsed === \"object\") {\n return parsed;\n }\n }\n\n // Fall back to key=value parsing\n return parseKeyValueArgs(argsStr);\n}\n\n/**\n * Extract Pythonic function calls from text: `func_name(args)` or `[func(args)]`.\n * Handles balanced parentheses so JSON in args doesn't break matching.\n */\nfunction extractPythonicCalls(text: string): ToolCall[] {\n const calls: ToolCall[] = [];\n const startRegex = /(?<!\\w)(\\w+)\\(/g;\n let startMatch: RegExpExecArray | null;\n while ((startMatch = startRegex.exec(text)) !== null) {\n const funcName = startMatch[1];\n const argsStart = startMatch.index + startMatch[0].length;\n // Balance parentheses to find the closing )\n let depth = 1;\n let i = argsStart;\n while (i < text.length && depth > 0) {\n if (text[i] === \"(\") depth++;\n else if (text[i] === \")\") depth--;\n i++;\n }\n if (depth === 0) {\n const argsStr = text.slice(argsStart, i - 1);\n calls.push(makeToolCall(funcName, parseLiquidArgs(argsStr)));\n // Advance regex scanning position past this complete call to avoid matching inside args\n startRegex.lastIndex = i;\n }\n }\n return calls;\n}\n\n/**\n * LiquidAI LFM / LFM2 / LFM2.5\n *\n * Formats:\n * - `<|tool_call_start|>[func_name(key=\"value\", key2=123)]<|tool_call_end|>`\n * - `[func_name(params={\"key\": \"val\"})]` (bracket-only, no special tokens)\n * Parallel calls: `<|tool_call_start|>[func1(a=\"b\"), func2(c=\"d\")]<|tool_call_end|>`\n * Uses Pythonic function call syntax.\n */\nexport const parseLiquid: ParserFn = (text) => {\n // Try special token format first\n const specialMatch = text.match(\n /<\\|tool_call_start\\|>((?:[^<]|<(?!\\|tool_call_end\\|>))*)<\\|tool_call_end\\|>/\n );\n if (specialMatch) {\n const inner = specialMatch[1].trim();\n const unwrapped = inner.startsWith(\"[\") && inner.endsWith(\"]\") ? inner.slice(1, -1) : inner;\n const calls = extractPythonicCalls(unwrapped);\n if (calls.length > 0) {\n const content = stripModelArtifacts(\n text.replace(\n /<\\|tool_call_start\\|>(?:[^<]|<(?!\\|tool_call_end\\|>))*<\\|tool_call_end\\|>/g,\n \"\"\n )\n );\n return { tool_calls: calls, content, parser: \"liquid\" };\n }\n }\n\n // Try bracket-only format: [func(args)] without special tokens\n // Use manual balanced-paren extraction to avoid ReDoS\n const bracketCalls: ToolCall[] = [];\n const bracketSpans: Array<[number, number]> = [];\n {\n const bracketOpenRegex = /\\[(?=\\w+\\()/g;\n let bm: RegExpExecArray | null;\n while ((bm = bracketOpenRegex.exec(text)) !== null) {\n const innerStart = bm.index + 1;\n // Find balanced closing ] by tracking parens\n let depth = 0;\n let i = innerStart;\n let foundClose = false;\n while (i < text.length) {\n const ch = text[i];\n if (ch === \"(\") depth++;\n else if (ch === \")\") {\n depth--;\n if (depth === 0 && i + 1 < text.length && text[i + 1] === \"]\") {\n const inner = text.slice(innerStart, i + 1);\n const calls = extractPythonicCalls(inner);\n bracketCalls.push(...calls);\n bracketSpans.push([bm.index, i + 2]);\n bracketOpenRegex.lastIndex = i + 2;\n foundClose = true;\n break;\n }\n }\n i++;\n }\n if (!foundClose) break;\n }\n }\n\n if (bracketCalls.length > 0) {\n let content = text;\n for (let k = bracketSpans.length - 1; k >= 0; k--) {\n content = content.slice(0, bracketSpans[k][0]) + content.slice(bracketSpans[k][1]);\n }\n return { tool_calls: bracketCalls, content: stripModelArtifacts(content), parser: \"liquid\" };\n }\n\n // Try ||Call: format (LFM2 text-based variant): ||Call: func_name(args)\n const callPrefixRegex = /\\|?\\|?Call:\\s*/g;\n let callPrefixMatch: RegExpExecArray | null;\n const callCalls: ToolCall[] = [];\n while ((callPrefixMatch = callPrefixRegex.exec(text)) !== null) {\n const afterPrefix = text.slice(callPrefixMatch.index + callPrefixMatch[0].length);\n const calls = extractPythonicCalls(afterPrefix);\n if (calls.length > 0) {\n callCalls.push(calls[0]);\n }\n }\n\n if (callCalls.length > 0) {\n const content = stripModelArtifacts(text.replace(/\\|?\\|?Call:\\s{0,20}\\w+\\([^)]*\\)/g, \"\"));\n return { tool_calls: callCalls, content, parser: \"liquid\" };\n }\n\n return null;\n};\n\n/**\n * Jamba (AI21)\n *\n * Format: `<tool_calls>[{\"name\": \"func\", \"arguments\": {...}}]</tool_calls>`\n * Also supports OpenAI-compatible format via FireFunction fallback.\n */\nexport const parseJamba: ParserFn = (text) => {\n const tagMatch = text.match(/<tool_calls>((?:[^<]|<(?!\\/tool_calls>))*)<\\/tool_calls>/);\n if (tagMatch) {\n const parsed = tryParseJson(tagMatch[1].trim());\n if (parsed) {\n const arr = Array.isArray(parsed) ? parsed : [parsed];\n const calls: ToolCall[] = [];\n for (const c of arr as Array<Record<string, unknown>>) {\n if (!c.name) continue;\n let args = c.arguments ?? c.parameters ?? {};\n if (typeof args === \"string\") {\n args = tryParseJson(args) ?? {};\n }\n calls.push(\n makeToolCall(\n c.name as string,\n args as Record<string, unknown>,\n (c.id as string | null) ?? null\n )\n );\n }\n if (calls.length > 0) {\n const content = text.slice(0, text.indexOf(\"<tool_calls>\")).trim();\n return { tool_calls: calls, content, parser: \"jamba\" };\n }\n }\n }\n\n return parseFireFunction(text);\n};\n\n/**\n * Qwen 3.5 XML format\n *\n * Format:\n * ```\n * <tool_call>\n * <function=function_name>\n * <parameter=param_name>value</parameter>\n * ...\n * </function>\n * </tool_call>\n * ```\n *\n * The special `params` parameter may contain a JSON object to be spread\n * into the arguments.\n */\nexport const parseQwen35Xml: ParserFn = (text) => {\n const toolCallMatches = text.matchAll(/<tool_call>((?:[^<]|<(?!\\/tool_call>))*)<\\/tool_call>/g);\n const calls: ToolCall[] = [];\n for (const [_, toolCallBody] of toolCallMatches) {\n const functionMatch = toolCallBody\n .trim()\n .match(/<function=([^>\\n<]+)>((?:[^<]|<(?!\\/function>))*)<\\/function>/);\n if (!functionMatch) {\n continue;\n }\n const [, rawName, functionBody] = functionMatch;\n const parsedInput: Record<string, unknown> = {};\n const parameterMatches = functionBody.matchAll(\n /<parameter=([^>\\n<]+)>((?:[^<]|<(?!\\/parameter>))*)<\\/parameter>/g\n );\n for (const [__, rawParamName, rawValue] of parameterMatches) {\n const paramName = rawParamName.trim();\n const valueText = rawValue.trim();\n if (paramName === \"params\") {\n try {\n const parsedValue = JSON.parse(valueText);\n if (parsedValue && typeof parsedValue === \"object\" && !Array.isArray(parsedValue)) {\n Object.assign(parsedInput, parsedValue);\n continue;\n }\n } catch {\n // Fall back to keeping the raw string.\n }\n }\n parsedInput[paramName] = valueText;\n }\n calls.push(makeToolCall(rawName.trim(), parsedInput));\n }\n\n if (calls.length === 0) return null;\n\n const content = text.replace(/<tool_call>(?:[^<]|<(?!\\/tool_call>))*<\\/tool_call>/g, \"\").trim();\n return { tool_calls: calls, content, parser: \"qwen35xml\" };\n};\n\n// ============================================================================\n// Model family detection\n// ============================================================================\n\n/**\n * Model-family-specific parser chains.\n *\n * Each chain is ordered by likelihood: the parser matching the model's native\n * tool-call format comes first, followed by fallbacks for common alternative\n * formats the model may produce (most often Hermes `<tool_call>` tags or\n * Llama-style bare JSON).\n *\n * Multiple keys may map to the same chain when model names vary across\n * providers (e.g. `cohere` / `command`, `chatglm` / `glm`).\n */\nconst MODEL_PARSERS: Record<string, ReadonlyArray<ParserFn>> = {\n llama: [parseLlama, parseHermes],\n mistral: [parseMistral, parseHermes],\n mixtral: [parseMistral, parseHermes],\n qwen: [parseHermes, parseLlama],\n qwen2: [parseHermes, parseLlama],\n qwen3: [parseHermes, parseQwen35Xml, parseLlama],\n qwen35: [parseQwen35Xml, parseHermes, parseLlama],\n cohere: [parseCohere, parseHermes],\n command: [parseCohere, parseHermes],\n deepseek: [parseDeepSeek, parseHermes],\n hermes: [parseHermes],\n phi: [parsePhi, parsePhiFunctools, parseHermes],\n internlm: [parseInternLM, parseHermes],\n chatglm: [parseChatGLM],\n glm: [parseChatGLM],\n gemma: [parseGemma, parseHermes],\n functionary: [parseFunctionary],\n gorilla: [parseGorilla],\n nexusraven: [parseNexusRaven],\n xlam: [parseXLAM],\n firefunction: [parseFireFunction, parsePhiFunctools],\n granite: [parseGranite, parseHermes],\n solar: [parseHermes],\n jamba: [parseJamba, parseHermes],\n liquid: [parseLiquid, parseHermes],\n lfm: [parseLiquid, parseHermes],\n yi: [parseHermes, parseLlama],\n falcon: [parseHermes, parseLlama],\n};\n\n/**\n * Default parser chain used when the model family cannot be determined.\n *\n * Ordering rationale — parsers that rely on highly distinctive, unlikely-to-\n * false-positive markers come first; generic / loose formats come last:\n *\n * 1. **Unique delimiters** — Phi (`<|tool_calls|>`), Mistral (`[TOOL_CALLS]`),\n * DeepSeek (`<|tool▁calls|>`), InternLM (`<|action_start|>`),\n * Granite (`<|tool_call_start|>`), FunctionGemma (`<start_function_call>`).\n * Each uses a distinctive tag or token that won't appear in normal text.\n *\n * 2. **Structured tags** — Qwen35 XML (`<tool_call>` with XML children),\n * Hermes (`<tool_call>` with JSON body), Cohere (`Action:` blocks).\n * Hermes is widely adopted but its `<tool_call>` tag is shared by several\n * model families, so it sits after the more unique delimiters.\n *\n * 3. **Specialized formats** — Functionary (`>>>func_name`),\n * Gorilla (`<<function>>` calls), NexusRaven (`Call:`),\n * FireFunction (`<function=>`), PhiFunctools (`functools[...]`),\n * Liquid (pythonic `func_name(args)`).\n *\n * 4. **Loose / generic** — Llama (bare JSON objects), Gemma (key=value args),\n * XLAM (JSON arrays). These match broad patterns and are tried last to\n * avoid false positives when a more specific parser should have matched.\n */\nconst DEFAULT_PARSER_CHAIN: ReadonlyArray<ParserFn> = [\n // 1. Unique delimiters\n parsePhi,\n parseMistral,\n parseDeepSeek,\n parseInternLM,\n parseGranite,\n // 2. Structured tags\n parseQwen35Xml,\n parseHermes,\n parseCohere,\n // 3. Specialized formats\n parseFunctionary,\n parseGorilla,\n parseNexusRaven,\n parseFireFunction,\n parsePhiFunctools,\n parseLiquid,\n // 4. Loose / generic\n parseLlama,\n parseGemma,\n parseXLAM,\n];\n\n/**\n * Detect the model family from a tokenizer instance or model name string.\n */\nfunction detectModelFamily(tokenizerOrName: TokenizerLike | string | null): string | null {\n let name = \"\";\n\n if (typeof tokenizerOrName === \"string\") {\n name = tokenizerOrName.toLowerCase();\n } else if (tokenizerOrName) {\n const config = tokenizerOrName.config ?? {};\n name = (\n config.name_or_path ??\n config._name_or_path ??\n config.model_type ??\n tokenizerOrName.name_or_path ??\n \"\"\n ).toLowerCase();\n }\n\n if (!name) return null;\n\n for (const family of Object.keys(MODEL_PARSERS)) {\n if (name.includes(family)) {\n return family;\n }\n }\n\n return null;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Parse tool calls from LLM output text.\n *\n * Automatically detects the model family from the tokenizer and applies the\n * appropriate parser(s). Falls back to trying all known formats if the model\n * family cannot be determined.\n */\nexport function parseToolCalls(\n text: string,\n { tokenizer = null, model = null, parser = null }: ParseToolCallsOptions = {}\n): ToolCallParserResult {\n if (!text || typeof text !== \"string\") {\n return { tool_calls: [], content: text ?? \"\", parser: \"none\" };\n }\n\n const log = getLogger();\n let parsersToTry: ReadonlyArray<ParserFn>;\n let source: string;\n\n if (parser) {\n const key = parser.toLowerCase();\n const found = MODEL_PARSERS[key];\n if (!found) {\n throw new Error(\n `Unknown parser \"${parser}\". Available parsers: ${Object.keys(MODEL_PARSERS).join(\", \")}`\n );\n }\n parsersToTry = found;\n source = `explicit parser \"${key}\"`;\n } else {\n const family = detectModelFamily(tokenizer ?? model ?? null);\n if (family) {\n parsersToTry = MODEL_PARSERS[family]!;\n source = `model family \"${family}\"`;\n } else {\n parsersToTry = DEFAULT_PARSER_CHAIN;\n source = \"default chain (unknown model)\";\n }\n }\n\n log.debug(\"ToolCallParsers parseToolCalls\", { source, parserCount: parsersToTry.length });\n\n for (const parserFn of parsersToTry) {\n const result = parserFn(text);\n if (result) {\n log.debug(\"ToolCallParsers parseToolCalls matched\", {\n parser: result.parser,\n toolCallCount: result.tool_calls.length,\n });\n return result;\n }\n }\n\n log.debug(\"ToolCallParsers parseToolCalls no parser matched\", {\n source,\n textPrefix: text.slice(0, 120),\n });\n return { tool_calls: [], content: text, parser: \"none\" };\n}\n\n/**\n * Check if text likely contains tool calls without fully parsing them.\n * Faster than `parseToolCalls` when you only need presence detection.\n */\nexport function hasToolCalls(text: string): boolean {\n if (!text) return false;\n return (\n text.includes(\"<tool_call>\") ||\n text.includes(\"[TOOL_CALLS]\") ||\n text.includes(\"<|python_tag|>\") ||\n text.includes(\"<function=\") ||\n text.includes(\"<|tool_calls|>\") ||\n text.includes(\"<tool_calls>\") ||\n text.includes(\"<|action_start|>\") ||\n text.includes(\"<<function>>\") ||\n text.includes(\">>>\") ||\n text.includes(\"Call:\") ||\n text.includes(\"Action:\") ||\n text.includes(\"functools\") ||\n text.includes(\"<start_function_call>\") ||\n text.includes(\"<|tool_call|>\") ||\n text.includes(\"<|tool_call_start|>\") ||\n /tool[\\s\\u2581]call[\\s\\u2581]begin/.test(text)\n );\n}\n\n/**\n * Get the list of available parser names.\n */\nexport function getAvailableParsers(): ReadonlyArray<string> {\n return Object.keys(MODEL_PARSERS);\n}\n\n/**\n * Get a model-family-specific generation prefix that guides the model to\n * produce tool calls. Appended to the prompt before generation and prepended\n * to the decoded output before parsing.\n *\n * @param family - The detected model family (from `getAvailableParsers` / `detectModelFamily`).\n * @param forcedToolName - When a specific tool is forced, include its name in the prefix.\n * @returns The prefix string, or `undefined` if no prefix is needed.\n */\nexport function getGenerationPrefix(\n family: string | null,\n _forcedToolName: string | undefined\n): string | undefined {\n if (!family) return undefined;\n\n switch (family) {\n default:\n return undefined;\n }\n}\n\n// ============================================================================\n// High-level parsing returning workglow ToolCalls type\n// ============================================================================\n\n/**\n * Parse tool calls from model-generated text, returning the workglow `ToolCalls`\n * type directly (with `input` field instead of `arguments`).\n *\n * Tries, in order:\n * 1. `<tool_call>JSON</tool_call>` tags (Qwen/Hermes)\n * 2. Bare JSON objects with `name` + `arguments`/`parameters` keys\n * 3. `{\"function\": {\"name\": ..., \"arguments\": ...}}` format\n *\n * Returns both the cleaned text (with tool-call markup removed) and the parsed\n * ToolCall array.\n */\nexport function parseToolCallsFromText(responseText: string): {\n text: string;\n toolCalls: ToolCalls;\n} {\n // Try Hermes/Qwen tag-based format\n const hermesResult = parseHermes(responseText);\n if (hermesResult && hermesResult.tool_calls.length > 0) {\n return {\n text: hermesResult.content,\n toolCalls: hermesResult.tool_calls.map((call, index) => ({\n id: call.id ?? `call_${index}`,\n name: call.name,\n input: call.arguments,\n })),\n };\n }\n\n // Fallback: brace-balanced scanner for bare JSON objects\n const toolCalls: ToolCalls = [];\n let callIndex = 0;\n\n const jsonCandidates = findBalancedBlocks(responseText, \"{\", \"}\");\n\n const matchedRanges: Array<{ start: number; end: number }> = [];\n for (const candidate of jsonCandidates) {\n try {\n const parsed = JSON.parse(candidate.text);\n if (parsed.name && (parsed.arguments !== undefined || parsed.parameters !== undefined)) {\n const id = `call_${callIndex++}`;\n toolCalls.push({\n id,\n name: parsed.name as string,\n input: (parsed.arguments ?? parsed.parameters ?? {}) as Record<string, unknown>,\n });\n matchedRanges.push({ start: candidate.start, end: candidate.end });\n } else if (parsed.function?.name) {\n let functionArgs: unknown = parsed.function.arguments ?? {};\n if (typeof functionArgs === \"string\") {\n try {\n functionArgs = JSON.parse(functionArgs);\n } catch {\n functionArgs = {};\n }\n }\n const id = `call_${callIndex++}`;\n toolCalls.push({\n id,\n name: parsed.function.name as string,\n input: (functionArgs ?? {}) as Record<string, unknown>,\n });\n matchedRanges.push({ start: candidate.start, end: candidate.end });\n }\n } catch {\n // Not valid JSON, skip\n }\n }\n\n let cleanedText = responseText;\n if (toolCalls.length > 0) {\n let result = \"\";\n let lastIndex = 0;\n for (const range of matchedRanges) {\n result += responseText.slice(lastIndex, range.start);\n lastIndex = range.end;\n }\n result += responseText.slice(lastIndex);\n cleanedText = result.trim();\n }\n\n return { text: cleanedText, toolCalls };\n}\n",
8
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Mapping from app task types to HuggingFace pipeline names.\n * Each task type maps to one or more pipelines (first is primary).\n */\nconst TASK_TO_PIPELINES: Record<string, string[]> = {\n TextEmbeddingTask: [\"feature-extraction\"],\n TextGenerationTask: [\"text-generation\"],\n TextSummaryTask: [\"sentence-similarity\", \"summarization\"],\n TextTranslationTask: [\"translation\"],\n TextClassificationTask: [\"text-classification\", \"zero-shot-classification\"],\n TextQuestionAnswerTask: [\"question-answering\"],\n TextFillMaskTask: [\"fill-mask\"],\n TextLanguageDetectionTask: [\"text-classification\"],\n TextNamedEntityRecognitionTask: [\"token-classification\"],\n TokenClassificationTask: [\"token-classification\"],\n ImageClassificationTask: [\"image-classification\", \"zero-shot-image-classification\"],\n ImageEmbeddingTask: [\"image-feature-extraction\"],\n ImageSegmentationTask: [\"image-segmentation\"],\n ImageToImageTask: [\"image-to-image\"],\n ImageToTextTask: [\"image-to-text\"],\n ObjectDetectionTask: [\"object-detection\", \"zero-shot-object-detection\"],\n DepthEstimationTask: [\"depth-estimation\"],\n AudioClassificationTask: [\"audio-classification\"],\n SpeechRecognitionTask: [\"automatic-speech-recognition\"],\n};\n\n/** Convert an app task type to its primary HuggingFace pipeline name. */\nexport function taskTypeToPipeline(taskType: string): string | undefined {\n return TASK_TO_PIPELINES[taskType]?.[0];\n}\n\n/** Convert an app task type to all matching HuggingFace pipeline names. */\nexport function taskTypeToPipelines(taskType: string): string[] {\n return TASK_TO_PIPELINES[taskType] ?? [];\n}\n\n/** Reverse lookup: given a HuggingFace pipeline name, return all matching app task types. */\nexport function pipelineToTaskTypes(pipeline: string): string[] {\n return Object.entries(TASK_TO_PIPELINES)\n .filter(([, pipelines]) => pipelines.includes(pipeline))\n .map(([task]) => task);\n}\n",
9
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ModelSearchResultItem } from \"../task/ModelSearchTask\";\nimport { pipelineToTaskTypes } from \"./PipelineTaskMapping\";\n\nexport interface HfModelEntry {\n id: string;\n modelId: string;\n pipeline_tag?: string;\n library_name?: string;\n likes: number;\n downloads: number;\n tags?: string[];\n siblings?: Array<{ rfilename: string }>;\n}\n\nconst HF_API_BASE = \"https://huggingface.co/api\";\n\nexport function formatDownloads(n: number): string {\n if (n >= 1_000_000) return `${(n / 1_000_000).toFixed(1)}M`;\n if (n >= 1_000) return `${(n / 1_000).toFixed(1)}k`;\n return String(n);\n}\n\n/**\n * Map an HF model entry to a provider-specific config object.\n */\nexport function mapHfProviderConfig(\n entry: HfModelEntry,\n provider: string\n): Record<string, unknown> {\n switch (provider) {\n case \"HF_TRANSFORMERS_ONNX\":\n return {\n model_path: entry.id,\n ...(entry.pipeline_tag ? { pipeline: entry.pipeline_tag } : {}),\n };\n case \"LOCAL_LLAMACPP\":\n return { model_path: entry.id };\n default:\n return { model_name: entry.id };\n }\n}\n\n/**\n * Map an HF model entry to a ModelSearchResultItem.\n */\nexport function mapHfModelResult(entry: HfModelEntry, provider: string): ModelSearchResultItem {\n const badges = [entry.pipeline_tag, entry.library_name].filter(Boolean).join(\" | \");\n return {\n id: entry.id,\n label: `${entry.id}${badges ? ` ${badges}` : \"\"}`,\n description: `${formatDownloads(entry.downloads)} downloads`,\n record: {\n model_id: entry.id,\n provider,\n title: entry.id.split(\"/\").pop() ?? entry.id,\n description: [entry.pipeline_tag, `${formatDownloads(entry.downloads)} downloads`]\n .filter(Boolean)\n .join(\" \\u2014 \"),\n tasks: entry.pipeline_tag ? pipelineToTaskTypes(entry.pipeline_tag) : [],\n provider_config: mapHfProviderConfig(entry, provider),\n metadata: {},\n },\n raw: entry,\n };\n}\n\n/**\n * Search HuggingFace models API. Returns all results (limit=500, no pagination).\n * An empty `query` lists top models by sort order (no text filter).\n */\nexport async function searchHfModels(\n query: string,\n extraParams?: Record<string, string>,\n expandFields?: string[],\n signal?: AbortSignal,\n credentialKey?: string\n): Promise<HfModelEntry[]> {\n const params = new URLSearchParams({\n search: query,\n limit: \"500\",\n sort: \"downloads\",\n direction: \"-1\",\n ...extraParams,\n });\n params.append(\"expand[]\", \"pipeline_tag\");\n if (expandFields) {\n for (const field of expandFields) {\n params.append(\"expand[]\", field);\n }\n }\n const res = await fetch(`${HF_API_BASE}/models?${params}`, {\n signal,\n headers: credentialKey ? { Authorization: `Bearer ${credentialKey}` } : undefined,\n });\n if (!res.ok) throw new Error(`HuggingFace API returned ${res.status}`);\n return res.json();\n}\n",
10
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Shared helpers for AI provider run/stream functions that produce image\n * outputs. Each helper takes a wire form delivered by a provider SDK\n * (encoded PNG/JPEG bytes, a base64 data URI, or a Blob) and returns a\n * platform-appropriate {@link ImageValue}:\n *\n * - Node / Bun: a {@link NodeImageValue} wrapping the encoded bytes plus\n * dimensions read from a sharp metadata probe. The encoded buffer is\n * retained as-is — no decode/re-encode round trip.\n * - Browser: a {@link BrowserImageValue} wrapping an `ImageBitmap`\n * created via `createImageBitmap(blob)`.\n *\n * Provider responses are always either PNG or JPEG. WebP and other formats\n * are not produced by the supported endpoints and would need explicit\n * mime detection if added later.\n */\n\nimport type { ImageValue, NodeImageFormat } from \"@workglow/util/media\";\nimport {\n encodeRawPixels,\n imageValueFromBitmap,\n imageValueFromBuffer,\n probeImageDimensions,\n} from \"@workglow/util/media\";\n\n// Prefer the browser path when `createImageBitmap` is available — handles\n// browser-like runtimes that polyfill `Buffer` (e.g. some test harnesses).\n// Node bundles tree-shake `createImageBitmap` to undefined.\nconst HAS_BUFFER = typeof Buffer !== \"undefined\";\nconst HAS_CREATE_IMAGE_BITMAP =\n typeof createImageBitmap === \"function\" && typeof fetch === \"function\";\nconst PREFER_BROWSER = HAS_CREATE_IMAGE_BITMAP;\n\nfunction detectFormatFromMime(mime: string): NodeImageFormat {\n if (/jpe?g/i.test(mime)) return \"jpeg\";\n return \"png\";\n}\n\n/**\n * Wrap an encoded image buffer in a Node {@link ImageValue}. Reads\n * width/height via a sharp metadata probe; no pixel decode is performed.\n */\nexport async function pngBytesToImageValue(\n bytes: Uint8Array,\n format: NodeImageFormat = \"png\"\n): Promise<ImageValue> {\n // `imageValueFromBuffer` requires a Buffer; copy the typed-array view\n // into a fresh Buffer so we don't accidentally retain SharedArrayBuffer\n // memory or alias a pool slice.\n const buffer = Buffer.from(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const { width, height } = await probeImageDimensions(buffer);\n return imageValueFromBuffer(buffer, format, width, height);\n}\n\n/**\n * Decode a `data:<mime>;base64,...` URI into an {@link ImageValue}.\n * On node, retains the encoded bytes via {@link pngBytesToImageValue}. In a\n * browser environment, decodes via `createImageBitmap` instead.\n */\nexport async function dataUriToImageValue(dataUri: string): Promise<ImageValue> {\n const match = /^data:([^;,]+);base64,(.+)$/.exec(dataUri);\n if (!match) {\n const preview = dataUri.length > 32 ? `${dataUri.slice(0, 32)}...` : dataUri;\n throw new Error(`dataUriToImageValue: invalid data URI \"${preview}\"`);\n }\n const mime = match[1];\n const base64 = match[2];\n\n if (PREFER_BROWSER) {\n const blob = await (await fetch(dataUri)).blob();\n const bitmap = await createImageBitmap(blob);\n return imageValueFromBitmap(bitmap, bitmap.width, bitmap.height);\n }\n\n if (HAS_BUFFER) {\n const buffer = Buffer.from(base64, \"base64\");\n return pngBytesToImageValue(\n new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength),\n detectFormatFromMime(mime)\n );\n }\n\n throw new Error(\"dataUriToImageValue: no Buffer or createImageBitmap available in this runtime\");\n}\n\n/**\n * Convert a `Blob` (e.g. from the HF Inference SDK) into an\n * {@link ImageValue}. On node uses sharp metadata to size the wrapper; in\n * a browser uses `createImageBitmap` directly.\n */\nexport async function blobToImageValue(blob: Blob): Promise<ImageValue> {\n if (PREFER_BROWSER) {\n const bitmap = await createImageBitmap(blob);\n return imageValueFromBitmap(bitmap, bitmap.width, bitmap.height);\n }\n if (HAS_BUFFER) {\n const arrayBuffer = await blob.arrayBuffer();\n const bytes = new Uint8Array(arrayBuffer);\n return pngBytesToImageValue(bytes, detectFormatFromMime(blob.type || \"image/png\"));\n }\n throw new Error(\"blobToImageValue: no Buffer or createImageBitmap available in this runtime\");\n}\n\n/**\n * Encode an inbound provider-input image into PNG bytes suitable for upload.\n *\n * Accepts the wire forms an `ImageValue` port may carry into a worker:\n * - {@link NodeImageValue} — encodes via sharp (raw-rgba) or returns bytes\n * directly if already PNG/JPEG.\n * - {@link BrowserImageValue} — encodes via canvas/`OffscreenCanvas`.\n * - `data:` URI string — legacy materialization form; base64-decodes the\n * payload.\n *\n * Always returns PNG bytes. Callers wrap the result in whatever transport\n * shape the SDK expects (Blob, File, OpenAI.toFile, inlineData Part).\n */\nexport async function imageValueToPngBytes(image: unknown): Promise<Uint8Array> {\n if (typeof image === \"string\") {\n // Legacy data URI from prior materialization. Decode base64.\n const match = /^data:[^;,]+;base64,(.+)$/.exec(image);\n if (!match) {\n const preview = image.length > 32 ? `${image.slice(0, 32)}...` : image;\n throw new Error(`imageValueToPngBytes: invalid data URI \"${preview}\"`);\n }\n if (typeof Buffer !== \"undefined\") {\n const buf = Buffer.from(match[1], \"base64\");\n return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);\n }\n const bin = atob(match[1]);\n const bytes = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) bytes[i] = bin.charCodeAt(i);\n return bytes;\n }\n\n if (image && typeof image === \"object\") {\n // NodeImageValue path — has a `buffer` and `format`.\n const node = image as {\n buffer?: Buffer;\n format?: NodeImageFormat;\n width?: number;\n height?: number;\n };\n if (\n typeof Buffer !== \"undefined\" &&\n Buffer.isBuffer(node.buffer) &&\n typeof node.format === \"string\"\n ) {\n if (node.format === \"png\" || node.format === \"jpeg\") {\n return new Uint8Array(node.buffer.buffer, node.buffer.byteOffset, node.buffer.byteLength);\n }\n // raw-rgba — re-encode via sharp.\n if (\n node.format === \"raw-rgba\" &&\n typeof node.width === \"number\" &&\n typeof node.height === \"number\"\n ) {\n const out = await encodeRawPixels(\n { data: node.buffer, width: node.width, height: node.height, channels: 4 },\n { format: \"png\" }\n );\n return new Uint8Array(out.buffer, out.byteOffset, out.byteLength);\n }\n }\n // BrowserImageValue path — has a `bitmap`.\n const browser = image as { bitmap?: ImageBitmap; width?: number; height?: number };\n if (\n typeof ImageBitmap !== \"undefined\" &&\n browser.bitmap instanceof ImageBitmap &&\n typeof browser.width === \"number\" &&\n typeof browser.height === \"number\"\n ) {\n return await encodeBitmapToPngBytes(browser.bitmap, browser.width, browser.height);\n }\n }\n\n throw new Error(\"imageValueToPngBytes: unsupported image input shape\");\n}\n\n/**\n * Encode an inbound provider-input image into a PNG `Blob` suitable for SDKs\n * that accept Blob/File-shaped inputs (e.g. HuggingFace Transformers.js\n * pipelines). Thin wrapper around {@link imageValueToPngBytes}.\n */\nexport async function imageValueToBlob(image: unknown): Promise<Blob> {\n const bytes = await imageValueToPngBytes(image);\n // The DOM `BlobPart` type expects `Uint8Array<ArrayBuffer>` (not the\n // wider `ArrayBufferLike` union our `Uint8Array` carries). Cast through\n // `BlobPart` to avoid the spurious SharedArrayBuffer narrowing error;\n // the runtime accepts either backing buffer kind.\n return new Blob([bytes as unknown as BlobPart], { type: \"image/png\" });\n}\n\nasync function encodeBitmapToPngBytes(\n bitmap: ImageBitmap,\n width: number,\n height: number\n): Promise<Uint8Array> {\n if (typeof OffscreenCanvas !== \"undefined\") {\n const canvas = new OffscreenCanvas(width, height);\n const ctx = canvas.getContext(\"2d\");\n if (!ctx) throw new Error(\"encodeBitmapToPngBytes: 2d context unavailable\");\n ctx.drawImage(bitmap, 0, 0);\n const blob = await canvas.convertToBlob({ type: \"image/png\" });\n const arrayBuffer = await blob.arrayBuffer();\n return new Uint8Array(arrayBuffer);\n }\n throw new Error(\"encodeBitmapToPngBytes: OffscreenCanvas not available in this runtime\");\n}\n",
11
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { AiProvider } from \"../provider/AiProvider\";\nimport type {\n AiProviderPreviewRunFn,\n AiProviderRunFn,\n AiProviderStreamFn,\n} from \"../provider/AiProviderRegistry\";\nimport type { ModelConfig } from \"../model/ModelSchema\";\n\n/**\n * Static metadata describing a cloud-backed AI provider.\n *\n * Shared across each provider's worker- and main-thread class shells so the\n * declarations live in one place and only the constructor base differs.\n */\nexport interface CloudProviderMetadata<TaskTypes extends readonly string[] = readonly string[]> {\n readonly name: string;\n readonly displayName: string;\n readonly isLocal?: boolean;\n readonly supportsBrowser?: boolean;\n readonly taskTypes: TaskTypes;\n}\n\n/**\n * Constructor signature mirroring {@link AiProvider}'s public constructor.\n * Declared structurally so callers can pass either the worker or main-thread\n * `AiProvider` import without forcing this module to import either at runtime.\n */\ntype AiProviderCtor<TModelConfig extends ModelConfig> = abstract new (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n tasks?: Record<string, AiProviderRunFn<any, any, TModelConfig>>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n streamTasks?: Record<string, AiProviderStreamFn<any, any, TModelConfig>>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n previewTasks?: Record<string, AiProviderPreviewRunFn<any, any, TModelConfig>>\n) => AiProvider<TModelConfig>;\n\n/**\n * Build a concrete provider class by mixing the shared declarations from\n * {@link CloudProviderMetadata} into a caller-supplied {@link AiProvider} base.\n *\n * Each cloud provider package keeps two thin shells (worker + main-thread)\n * and supplies the appropriate `AiProvider` import to this factory. The\n * generated class implements `name`, `displayName`, `isLocal`,\n * `supportsBrowser`, and `taskTypes` from the metadata literal; the\n * constructor is inherited unchanged from the base.\n */\nexport function createCloudProviderClass<\n TModelConfig extends ModelConfig,\n T extends readonly string[],\n>(Base: AiProviderCtor<TModelConfig>, meta: CloudProviderMetadata<T>) {\n abstract class CloudProvider extends Base {\n readonly name = meta.name;\n readonly displayName = meta.displayName;\n readonly isLocal = meta.isLocal ?? false;\n readonly supportsBrowser = meta.supportsBrowser ?? true;\n readonly taskTypes: T = meta.taskTypes;\n }\n return CloudProvider as unknown as new (\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n tasks?: Record<string, AiProviderRunFn<any, any, TModelConfig>>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n streamTasks?: Record<string, AiProviderStreamFn<any, any, TModelConfig>>,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n previewTasks?: Record<string, AiProviderPreviewRunFn<any, any, TModelConfig>>\n ) => AiProvider<TModelConfig> & {\n readonly name: string;\n readonly displayName: string;\n readonly isLocal: boolean;\n readonly supportsBrowser: boolean;\n readonly taskTypes: T;\n };\n}\n",
12
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\n/**\n * Shared cloud-provider client utilities: API-key resolution and lazy SDK\n * loading. Used by each provider's `*_Client.ts` so the same fallback chain\n * (provider_config → env var) and the same \"package missing\" error message\n * live in one place.\n */\n\nexport interface CloudCredentialConfig {\n readonly credential_key?: string;\n readonly api_key?: string;\n}\n\nexport interface ResolveApiKeyArgs {\n readonly config: CloudCredentialConfig | undefined;\n /** Single env var name, or list of alternatives tried in order. */\n readonly envVar: string | readonly string[];\n /** Human-friendly provider label used in the error message. */\n readonly providerLabel: string;\n}\n\n/**\n * Resolve the API key for a cloud provider.\n *\n * Looks at `config.credential_key`, then `config.api_key`, then each entry in\n * `envVar` (in order). Throws a uniform error if nothing is found.\n */\nexport function resolveApiKey(args: ResolveApiKeyArgs): string {\n const fromConfig = args.config?.credential_key || args.config?.api_key;\n if (fromConfig) return fromConfig;\n\n const envVars = typeof args.envVar === \"string\" ? [args.envVar] : args.envVar;\n if (typeof process !== \"undefined\") {\n for (const name of envVars) {\n const v = process.env?.[name];\n if (v) return v;\n }\n }\n\n const envList = envVars.join(\" / \");\n throw new Error(\n `Missing ${args.providerLabel} API key: set provider_config.credential_key or the ${envList} environment variable.`\n );\n}\n\n/**\n * Dynamically import a provider SDK package, throwing a uniform install hint\n * if the package isn't present.\n */\nexport async function loadProviderSdk<T = unknown>(\n packageName: string,\n friendlyName?: string\n): Promise<T> {\n try {\n return (await import(/* @vite-ignore */ packageName)) as T;\n } catch {\n const label = friendlyName ?? packageName;\n throw new Error(\n `${packageName} is required for ${label} tasks. Install it with: bun add ${packageName}`\n );\n }\n}\n\n/**\n * True when running inside a browser-like environment (window/worker globals\n * present). Cloud SDKs use this to set their `dangerouslyAllowBrowser` flag.\n */\nexport function isBrowserLike(): boolean {\n return typeof globalThis.document !== \"undefined\" || \"WorkerGlobalScope\" in globalThis;\n}\n",
13
+ "/**\n * @license\n * Copyright 2026 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport { getLogger } from \"@workglow/util/worker\";\nimport type { JsonSchema } from \"@workglow/util/worker\";\n\n/**\n * A tool definition that can be passed to an LLM for tool calling.\n * Can be created manually or generated from TaskRegistry entries via `taskTypesToTools` in ToolCallingTask.\n *\n * The `name` is used both as the tool name presented to the LLM and as a\n * lookup key for the backing Task in the TaskRegistry. When a tool is\n * backed by a configurable task (e.g. `McpToolCallTask`, `JavaScriptTask`),\n * `configSchema` describes what configuration the task accepts and `config`\n * provides the concrete values. The LLM never sees `configSchema` or\n * `config` — they are setup-time concerns used when instantiating the task.\n */\nexport interface ToolDefinition {\n name: string;\n description: string;\n inputSchema: JsonSchema;\n outputSchema?: JsonSchema;\n /**\n * Optional discriminator for tool resolution. When specified, skips\n * duck-typing heuristics:\n * - `\"function\"` — uses the `execute` function directly\n * - `\"task\"` — looks up the task by `name` in the TaskRegistry\n *\n * When omitted, resolution falls back to the existing heuristic\n * (check `execute`, then registry lookup, then stub).\n */\n type?: \"function\" | \"task\";\n /** JSON Schema describing the task's configuration options. */\n configSchema?: JsonSchema;\n /** Concrete configuration values matching {@link configSchema}. */\n config?: Record<string, unknown>;\n /**\n * Optional custom executor function. When provided, the tool is executed\n * by calling this function directly instead of instantiating a Task.\n */\n execute?: (input: Record<string, unknown>) => Promise<Record<string, unknown>>;\n}\n\n/**\n * A tool call returned by the LLM, requesting invocation of a specific tool.\n */\nexport interface ToolCall {\n id: string;\n name: string;\n input: Record<string, unknown>;\n}\n\nexport type ToolCalls = Array<ToolCall>;\n\n/**\n * Controls which tools the model may call.\n * - `\"auto\"` — model decides whether to call tools\n * - `\"none\"` — model must not call any tools\n * - `\"required\"` — model must call at least one tool\n * - any other string — model must call the tool with that name\n */\nexport type ToolChoiceOption = \"auto\" | \"none\" | \"required\" | (string & {});\n\n/**\n * Builds a tool description string for provider APIs, appending the output\n * schema when present. Shared across all provider implementations.\n */\nexport function buildToolDescription(tool: ToolDefinition): string {\n let desc = tool.description;\n if (tool.outputSchema && typeof tool.outputSchema === \"object\") {\n desc += `\\n\\nReturns: ${JSON.stringify(tool.outputSchema)}`;\n }\n return desc;\n}\n\n/**\n * Validates that a tool call name returned by the LLM matches one of the\n * allowed tool definitions. Returns true if valid, false otherwise.\n */\nexport function isAllowedToolName(\n name: string,\n allowedTools: ReadonlyArray<ToolDefinition>\n): boolean {\n return allowedTools.some((t) => t.name === name);\n}\n\n/**\n * Filters an array of tool calls, removing any whose name does not appear\n * in the provided tools list. Returns the filtered array.\n */\nexport function filterValidToolCalls(\n toolCalls: ToolCalls,\n allowedTools: ReadonlyArray<ToolDefinition>\n): ToolCalls {\n return toolCalls.filter((tc) => {\n if (tc.name && isAllowedToolName(tc.name, allowedTools)) {\n return true;\n }\n getLogger().warn(`Filtered out tool call with unknown name \"${tc.name ?? \"(missing)\"}\"`, {\n callId: tc.id,\n toolName: tc.name,\n });\n return false;\n });\n}\n",
14
+ "/**\n * @license\n * Copyright 2025 Steven Roussey <sroussey@gmail.com>\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport type { ToolCallingTaskOutput } from \"../task/ToolCallingTask\";\nimport type { ToolCalls, ToolDefinition } from \"../task/ToolCallingUtils\";\nimport { buildToolDescription } from \"../task/ToolCallingUtils\";\nimport type { StreamEvent } from \"@workglow/task-graph\";\nimport { parsePartialJson } from \"@workglow/util/worker\";\n\n/**\n * Shared helpers for providers that expose an OpenAI-compatible chat-completions\n * API (currently OpenAI itself and Hugging Face Inference). They cover:\n *\n * - Building the OpenAI `tools` array from workglow {@link ToolDefinition}s.\n * - Mapping workglow `toolChoice` strings to the OpenAI union, with optional\n * named-function support (HFI accepts only `auto | none | required`).\n * - Streaming a chat-completions response into workglow {@link StreamEvent}s,\n * accumulating fragmented tool-call argument JSON internally and yielding\n * `text-delta` + per-tool-call `object-delta` events. The final `finish`\n * event carries `{}` per the streaming convention in CLAUDE.md — the\n * consumer (`StreamProcessor`) is responsible for accumulating deltas.\n */\n\n/** OpenAI-shape tool entry. Kept loose because each SDK names the type differently. */\nexport interface OpenAIShapedTool {\n readonly type: \"function\";\n readonly function: {\n readonly name: string;\n readonly description: string;\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n readonly parameters: any;\n };\n}\n\nexport type OpenAIShapedToolChoice =\n | \"auto\"\n | \"none\"\n | \"required\"\n | { readonly type: \"function\"; readonly function: { readonly name: string } };\n\nexport function buildOpenAITools(tools: readonly ToolDefinition[]): OpenAIShapedTool[] {\n return tools.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.name,\n description: buildToolDescription(t),\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n parameters: t.inputSchema as any,\n },\n }));\n}\n\n/**\n * Map workglow `toolChoice` to an OpenAI-shaped tool_choice value.\n *\n * @param toolChoice - One of `\"auto\" | \"none\" | \"required\" | <tool_name>` (or undefined).\n * @param allowNamedFunction - When true, an unrecognized value is treated as a\n * tool name and emitted as `{ type: \"function\", function: { name } }`. When\n * false (HFI), it falls back to `\"auto\"` because HFI's API only accepts the\n * three keywords.\n */\nexport function mapOpenAIToolChoice(\n toolChoice: string | undefined,\n allowNamedFunction: boolean\n): OpenAIShapedToolChoice {\n if (!toolChoice || toolChoice === \"auto\") return \"auto\";\n if (toolChoice === \"none\") return \"none\";\n if (toolChoice === \"required\") return \"required\";\n if (allowNamedFunction) return { type: \"function\", function: { name: toolChoice } };\n return \"auto\";\n}\n\n/** Best-effort JSON parse: full parse first, then partial-JSON fallback, then `{}`. */\nfunction parseToolArgs(raw: string): Record<string, unknown> {\n if (!raw) return {};\n try {\n return JSON.parse(raw) as Record<string, unknown>;\n } catch {\n const partial = parsePartialJson(raw);\n return partial && typeof partial === \"object\" ? (partial as Record<string, unknown>) : {};\n }\n}\n\n/**\n * Parse a non-streaming OpenAI-shape chat completion message into workglow\n * {@link ToolCalls}. Used by the synchronous `*_ToolCalling` runFns.\n *\n * Some providers (HFI) don't always return an `id` per tool call; we\n * auto-generate `call_<index>` in that case.\n */\nexport function parseOpenAIToolCallMessage(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n toolCallsRaw: readonly any[] | undefined\n): ToolCalls {\n const result: ToolCalls = [];\n if (!toolCallsRaw) return result;\n let idx = 0;\n for (const tc of toolCallsRaw) {\n if (!tc || !tc.function) {\n idx++;\n continue;\n }\n const id = (tc.id as string | undefined) ?? `call_${idx}`;\n const name = tc.function.name as string;\n const rawArgs = tc.function.arguments;\n const input =\n typeof rawArgs === \"string\"\n ? parseToolArgs(rawArgs)\n : rawArgs && typeof rawArgs === \"object\"\n ? (rawArgs as Record<string, unknown>)\n : {};\n result.push({ id, name, input });\n idx++;\n }\n return result;\n}\n\ninterface ToolCallAccumulatorEntry {\n id: string;\n name: string;\n arguments: string;\n}\n\n/**\n * Adapt an OpenAI-shape streaming response (each chunk has\n * `choices[0].delta.{content?, tool_calls?[]}`) to workglow stream events.\n *\n * Yields:\n * - `text-delta` for each non-empty `delta.content`.\n * - `object-delta` (single-element array) per tool-call delta with the latest\n * parsed input. The downstream `StreamProcessor` upserts by `id`.\n * - `finish` with structural defaults (`{ text: \"\", toolCalls: [] }`) once the\n * stream ends. The defaults are minimal scaffolding so the final output\n * always satisfies {@link ToolCallingTaskOutput} even when the model\n * streams only `tool_calls` (no `content` deltas) — the consumer's\n * `StreamProcessor` overrides any port for which deltas were accumulated.\n */\nexport async function* accumulateOpenAIStream(\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n stream: AsyncIterable<any>\n): AsyncGenerator<StreamEvent<ToolCallingTaskOutput>, void, unknown> {\n const toolCallAccumulator = new Map<number, ToolCallAccumulatorEntry>();\n\n for await (const chunk of stream) {\n const choice = chunk?.choices?.[0];\n if (!choice) continue;\n\n const contentDelta: string = choice.delta?.content ?? \"\";\n if (contentDelta) {\n yield { type: \"text-delta\", port: \"text\", textDelta: contentDelta };\n }\n\n const tcDeltas = choice.delta?.tool_calls;\n if (!Array.isArray(tcDeltas)) continue;\n\n for (const tcDelta of tcDeltas) {\n const idx: number = tcDelta.index ?? 0;\n let acc = toolCallAccumulator.get(idx);\n if (!acc) {\n acc = { id: tcDelta.id ?? \"\", name: tcDelta.function?.name ?? \"\", arguments: \"\" };\n toolCallAccumulator.set(idx, acc);\n }\n if (tcDelta.id) acc.id = tcDelta.id;\n if (tcDelta.function?.name) acc.name = tcDelta.function.name;\n if (tcDelta.function?.arguments) acc.arguments += tcDelta.function.arguments;\n\n // Synthesise a stable id when the provider doesn't emit one, matching\n // the non-streaming `parseOpenAIToolCallMessage` fallback. Without this,\n // multiple tool calls with empty ids would collide under the\n // StreamProcessor's id-based upsert.\n const stableId = acc.id || `call_${idx}`;\n\n yield {\n type: \"object-delta\",\n port: \"toolCalls\",\n objectDelta: [{ id: stableId, name: acc.name, input: parseToolArgs(acc.arguments) }],\n };\n }\n }\n\n yield {\n type: \"finish\",\n data: { text: \"\", toolCalls: [] } as ToolCallingTaskOutput,\n };\n}\n"
15
+ ],
16
+ "mappings": "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",
17
+ "debugId": "4EDF5B6BCACE26D464756E2164756E21",
18
+ "names": []
19
+ }
@@ -84,7 +84,7 @@ export declare class VectorSimilarityTask extends GraphAsTask<VectorSimilarityTa
84
84
  static inputSchema(): DataPortSchema;
85
85
  static outputSchema(): DataPortSchema;
86
86
  execute(input: VectorSimilarityTaskInput): Promise<VectorSimilarityTaskOutput>;
87
- executePreview({ query, vectors, method, topK }: VectorSimilarityTaskInput): Promise<VectorSimilarityTaskOutput>;
87
+ executePreview({ query, vectors, method, topK, }: VectorSimilarityTaskInput): Promise<VectorSimilarityTaskOutput>;
88
88
  }
89
89
  export declare const similarity: (input: VectorSimilarityTaskInput, config?: VectorSimilarityTaskConfig) => Promise<{
90
90
  output: import("@workglow/util/schema").TypedArray[];
@@ -1 +1 @@
1
- {"version":3,"file":"VectorSimilarityTask.d.ts","sourceRoot":"","sources":["../../src/task/VectorSimilarityTask.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,WAAW,EAAY,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAEL,cAAc,EACd,UAAU,EAIV,uBAAuB,EACxB,MAAM,uBAAuB,CAAC;AAE/B,eAAO,MAAM,YAAY;aACvB,MAAM,EAAE,QAAQ;aAChB,OAAO,EAAE,SAAS;aAClB,OAAO,EAAE,SAAS;CACV,CAAC;AAQX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE5E,QAAA,MAAM,qBAAqB;mBACnB,QAAQ;;iBAEZ,KAAK;;;;;;iBAIL,OAAO;qBACL,IAAI,EAAE,OAAO;qBACb,KAAK;;;;;;;iBAKP,IAAI;qBACF,IAAI,EAAE,QAAQ;qBACd,KAAK,EAAE,OAAO;qBACd,WAAW,EAAE,iCAAiC;qBAC9C,OAAO,EAAE,CAAC;qBACV,OAAO,EAAE,EAAE;;iBAEb,MAAM;qBACJ,IAAI,EAAE,QAAQ;qBACd,IAAI;qBACJ,KAAK,EAAE,yBAAe;qBACtB,WAAW,EAAE,4CAA4C;qBACzD,OAAO;;;;;CAKsB,CAAC;AAEpC,QAAA,MAAM,sBAAsB;mBACpB,QAAQ;;iBAEZ,MAAM;qBACJ,IAAI,EAAE,OAAO;qBACb,KAAK;;;;;;;iBAKP,KAAK;qBACH,IAAI,EAAE,OAAO;qBACb,KAAK;yBACH,IAAI,EAAE,QAAQ;yBACd,KAAK,EAAE,OAAO;yBACd,WAAW,EAAE,0CAA0C;;;;;;CAM5B,CAAC;AAEpC,MAAM,MAAM,yBAAyB,GAAG,UAAU,CAChD,OAAO,qBAAqB,EAC5B,uBAAuB,CACxB,CAAC;AACF,MAAM,MAAM,0BAA0B,GAAG,UAAU,CACjD,OAAO,sBAAsB,EAC7B,uBAAuB,CACxB,CAAC;AACF,MAAM,MAAM,0BAA0B,GAAG,UAAU,CAAC,yBAAyB,CAAC,CAAC;AAE/E,qBAAa,oBAAqB,SAAQ,WAAW,CACnD,yBAAyB,EACzB,0BAA0B,EAC1B,0BAA0B,CAC3B;IACC,gBAAyB,IAAI,0BAA0B;IACvD,gBAAyB,QAAQ,YAAY;IAC7C,gBAAyB,KAAK,uBAAuB;IACrD,OAAuB,WAAW,SAC+C;IACjF,gBAAyB,SAAS,QAAQ;IAE1C,OAAuB,WAAW,IAAI,cAAc,CAEnD;IACD,OAAuB,YAAY,IAAI,cAAc,CAEpD;IAEc,OAAO,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAE5F;IAEc,cAAc,CAAC,EAC5B,KAAK,EACL,OAAO,EACP,MAAM,EACN,IAAI,EACL,EAAE,yBAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAmBjE;CACF;AAED,eAAO,MAAM,UAAU,UACd,yBAAyB,WACvB,0BAA0B;;;EAGpC,CAAC;AAEF,OAAO,QAAQ,sBAAsB,CAAC,CAAC;IACrC,UAAU,QAAQ;QAChB,UAAU,EAAE,cAAc,CACxB,yBAAyB,EACzB,0BAA0B,EAC1B,0BAA0B,CAC3B,CAAC;KACH;CACF"}
1
+ {"version":3,"file":"VectorSimilarityTask.d.ts","sourceRoot":"","sources":["../../src/task/VectorSimilarityTask.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,cAAc,EAAE,WAAW,EAAY,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAEL,cAAc,EACd,UAAU,EAIV,uBAAuB,EACxB,MAAM,uBAAuB,CAAC;AAE/B,eAAO,MAAM,YAAY;aACvB,MAAM,EAAE,QAAQ;aAChB,OAAO,EAAE,SAAS;aAClB,OAAO,EAAE,SAAS;CACV,CAAC;AAQX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,YAAY,CAAC,CAAC,MAAM,OAAO,YAAY,CAAC,CAAC;AAE5E,QAAA,MAAM,qBAAqB;mBACnB,QAAQ;;iBAEZ,KAAK;;;;;;iBAIL,OAAO;qBACL,IAAI,EAAE,OAAO;qBACb,KAAK;;;;;;;iBAKP,IAAI;qBACF,IAAI,EAAE,QAAQ;qBACd,KAAK,EAAE,OAAO;qBACd,WAAW,EAAE,iCAAiC;qBAC9C,OAAO,EAAE,CAAC;qBACV,OAAO,EAAE,EAAE;;iBAEb,MAAM;qBACJ,IAAI,EAAE,QAAQ;qBACd,IAAI;qBACJ,KAAK,EAAE,yBAAe;qBACtB,WAAW,EAAE,4CAA4C;qBACzD,OAAO;;;;;CAKsB,CAAC;AAEpC,QAAA,MAAM,sBAAsB;mBACpB,QAAQ;;iBAEZ,MAAM;qBACJ,IAAI,EAAE,OAAO;qBACb,KAAK;;;;;;;iBAKP,KAAK;qBACH,IAAI,EAAE,OAAO;qBACb,KAAK;yBACH,IAAI,EAAE,QAAQ;yBACd,KAAK,EAAE,OAAO;yBACd,WAAW,EAAE,0CAA0C;;;;;;CAM5B,CAAC;AAEpC,MAAM,MAAM,yBAAyB,GAAG,UAAU,CAChD,OAAO,qBAAqB,EAC5B,uBAAuB,CACxB,CAAC;AACF,MAAM,MAAM,0BAA0B,GAAG,UAAU,CACjD,OAAO,sBAAsB,EAC7B,uBAAuB,CACxB,CAAC;AACF,MAAM,MAAM,0BAA0B,GAAG,UAAU,CAAC,yBAAyB,CAAC,CAAC;AAE/E,qBAAa,oBAAqB,SAAQ,WAAW,CACnD,yBAAyB,EACzB,0BAA0B,EAC1B,0BAA0B,CAC3B;IACC,gBAAyB,IAAI,0BAA0B;IACvD,gBAAyB,QAAQ,YAAY;IAC7C,gBAAyB,KAAK,uBAAuB;IACrD,OAAuB,WAAW,SAC+C;IACjF,gBAAyB,SAAS,QAAQ;IAE1C,OAAuB,WAAW,IAAI,cAAc,CAEnD;IACD,OAAuB,YAAY,IAAI,cAAc,CAEpD;IAEc,OAAO,CAAC,KAAK,EAAE,yBAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAE5F;IAEc,cAAc,CAAC,EAC5B,KAAK,EACL,OAAO,EACP,MAAM,EACN,IAAI,GACL,EAAE,yBAAyB,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAmBjE;CACF;AAED,eAAO,MAAM,UAAU,UACd,yBAAyB,WACvB,0BAA0B;;;EAGpC,CAAC;AAEF,OAAO,QAAQ,sBAAsB,CAAC,CAAC;IACrC,UAAU,QAAQ;QAChB,UAAU,EAAE,cAAc,CACxB,yBAAyB,EACzB,0BAA0B,EAC1B,0BAA0B,CAC3B,CAAC;KACH;CACF"}
package/dist/worker.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import { globalServiceRegistry as globalServiceRegistry2, WORKER_MANAGER as WORKER_MANAGER2 } from "@workglow/util/worker";
3
3
 
4
4
  // src/provider/AiProviderRegistry.ts
5
- import { globalServiceRegistry, WORKER_MANAGER } from "@workglow/util/worker";
5
+ import { createServiceToken, globalServiceRegistry, WORKER_MANAGER } from "@workglow/util/worker";
6
6
 
7
7
  // src/job/AiJob.ts
8
8
  import {
@@ -338,13 +338,20 @@ class AiProviderRegistry {
338
338
  return runFn;
339
339
  }
340
340
  }
341
- var providerRegistry = new AiProviderRegistry;
342
- function getAiProviderRegistry() {
343
- return providerRegistry;
341
+ var AI_PROVIDER_REGISTRY = createServiceToken("ai.provider.registry");
342
+ function getAiProviderRegistry(registry = globalServiceRegistry) {
343
+ if (!registry.has(AI_PROVIDER_REGISTRY)) {
344
+ registerAiProviderDefaults(registry);
345
+ }
346
+ return registry.get(AI_PROVIDER_REGISTRY);
347
+ }
348
+ function setAiProviderRegistry(pr, registry = globalServiceRegistry) {
349
+ registry.registerInstance(AI_PROVIDER_REGISTRY, pr);
344
350
  }
345
- function setAiProviderRegistry(pr) {
346
- providerRegistry = pr;
351
+ function registerAiProviderDefaults(registry = globalServiceRegistry) {
352
+ registry.registerIfAbsent(AI_PROVIDER_REGISTRY, () => new AiProviderRegistry, true);
347
353
  }
354
+ registerAiProviderDefaults();
348
355
 
349
356
  // src/provider/AiProvider.ts
350
357
  var DEFAULT_AI_PROVIDER_WORKER_IDLE_TIMEOUT_MS = 15 * 60 * 1000;
@@ -683,6 +690,7 @@ export {
683
690
  toOpenAIMessages,
684
691
  setAiProviderRegistry,
685
692
  resolveAiProviderGpuQueueConcurrency,
693
+ registerAiProviderDefaults,
686
694
  isAllowedToolName,
687
695
  getAiProviderRegistry,
688
696
  filterValidToolCalls,
@@ -692,7 +700,8 @@ export {
692
700
  ModelConfigSchema,
693
701
  DEFAULT_AI_PROVIDER_WORKER_IDLE_TIMEOUT_MS,
694
702
  AiProviderRegistry,
695
- AiProvider
703
+ AiProvider,
704
+ AI_PROVIDER_REGISTRY
696
705
  };
697
706
 
698
- //# debugId=9DFCF384B0F4AC6E64756E2164756E21
707
+ //# debugId=10E7BFE0CC8E8D6064756E2164756E21