diff --git a/apps/stage-pocket/package.json b/apps/stage-pocket/package.json index 9c0df2724..8a345ba86 100644 --- a/apps/stage-pocket/package.json +++ b/apps/stage-pocket/package.json @@ -60,7 +60,7 @@ "@xsai/shared": "catalog:", "@xsai/shared-chat": "catalog:", "@xsai/stream-text": "catalog:", - "@xsai/stream-transcription": "0.4.0-beta.8", + "@xsai/stream-transcription": "catalog:", "@xsai/utils-chat": "catalog:", "animejs": "^4.3.6", "capacitor-native-settings": "catalog:", diff --git a/apps/stage-tamagotchi/package.json b/apps/stage-tamagotchi/package.json index e7489e26e..5c5a1cfab 100644 --- a/apps/stage-tamagotchi/package.json +++ b/apps/stage-tamagotchi/package.json @@ -82,7 +82,7 @@ "@xsai/shared": "catalog:", "@xsai/shared-chat": "catalog:", "@xsai/stream-text": "catalog:", - "@xsai/stream-transcription": "0.4.0-beta.8", + "@xsai/stream-transcription": "catalog:", "@xsai/tool": "catalog:", "@xsai/utils-chat": "catalog:", "alien-signals": "catalog:", diff --git a/apps/stage-web/package.json b/apps/stage-web/package.json index 5ec7d303d..13ac0753e 100644 --- a/apps/stage-web/package.json +++ b/apps/stage-web/package.json @@ -55,7 +55,7 @@ "@xsai/shared": "catalog:", "@xsai/shared-chat": "catalog:", "@xsai/stream-text": "catalog:", - "@xsai/stream-transcription": "0.4.0-beta.8", + "@xsai/stream-transcription": "catalog:", "@xsai/utils-chat": "catalog:", "animejs": "^4.3.6", "better-auth": "^1.5.6", diff --git a/nix/assets-hash.txt b/nix/assets-hash.txt index cca565f18..8f255e3f6 100644 --- a/nix/assets-hash.txt +++ b/nix/assets-hash.txt @@ -1 +1 @@ -sha256-ip6zDQU/mZhgDs+FqhjPmBCXRQeH6h34MyKGOTDO8v8= +sha256-69tCpJaxRUnyR9CrHlmWJWEWLDpYzyzska7ui9++QoY= diff --git a/packages/stage-layouts/package.json b/packages/stage-layouts/package.json index 0b0039887..4f640107b 100644 --- a/packages/stage-layouts/package.json +++ b/packages/stage-layouts/package.json @@ -41,7 +41,7 @@ "@vueuse/shared": "^14.2.1", "@xsai-ext/providers": "catalog:", "@xsai/generate-speech": "catalog:", - "@xsai/stream-transcription": "0.4.0-beta.8", + "@xsai/stream-transcription": "catalog:", "animejs": "^4.3.6", "colorjs.io": "^0.6.1", "dompurify": "^3.3.3", diff --git a/packages/stage-pages/package.json b/packages/stage-pages/package.json index efd865941..ede6f33f2 100644 --- a/packages/stage-pages/package.json +++ b/packages/stage-pages/package.json @@ -37,7 +37,7 @@ "@vueuse/shared": "^14.2.1", "@xsai-ext/providers": "catalog:", "@xsai/generate-speech": "catalog:", - "@xsai/stream-transcription": "0.4.0-beta.8", + "@xsai/stream-transcription": "catalog:", "animejs": "^4.3.6", "d3": "catalog:", "dompurify": "^3.3.3", diff --git a/packages/stage-ui/package.json b/packages/stage-ui/package.json index 42137c6b9..c3f21dc5e 100644 --- a/packages/stage-ui/package.json +++ b/packages/stage-ui/package.json @@ -94,7 +94,7 @@ "@xsai/shared": "catalog:", "@xsai/shared-chat": "catalog:", "@xsai/stream-text": "catalog:", - "@xsai/stream-transcription": "0.4.0-beta.8", + "@xsai/stream-transcription": "catalog:", "@xsai/tool": "catalog:", "@xsai/utils-chat": "catalog:", "animejs": "^4.3.6", diff --git a/packages/stage-ui/src/stores/chat.ts b/packages/stage-ui/src/stores/chat.ts index 3e7b20445..df8165726 100644 --- a/packages/stage-ui/src/stores/chat.ts +++ b/packages/stage-ui/src/stores/chat.ts @@ -363,6 +363,15 @@ export const useChatOrchestratorStore = defineStore('chat-orchestrator', () => { result: event.result, }) + break + case 'tool-error': + toolCallQueue.enqueue({ + type: 'tool-call-result', + id: event.toolCallId, + isError: true, + result: event.result, + }) + break case 'text-delta': fullText += event.text diff --git a/packages/stage-ui/src/stores/execute-tool.test.ts b/packages/stage-ui/src/stores/execute-tool.test.ts new file mode 100644 index 000000000..d02ee2f30 --- /dev/null +++ b/packages/stage-ui/src/stores/execute-tool.test.ts @@ -0,0 +1,294 @@ +import type { Message, Tool, ToolCall } from '@xsai/shared-chat' + +import { InvalidToolCallError, InvalidToolInputError, ToolExecutionError } from '@xsai/shared' +import { executeTool } from '@xsai/shared-chat' +import { describe, expect, it, vi } from 'vitest' + +function createToolCall(overrides: Partial & { + function?: Partial & { name?: string, arguments?: string } +} = {}): ToolCall { + const fn = overrides.function ?? {} + return { + id: 'call_1', + type: 'function', + function: { + name: 'myTool', + arguments: '{}', + ...fn, + }, + ...overrides, + } as ToolCall +} + +function createTool(name: string, execute: Tool['execute']): Tool { + return { + type: 'function', + function: { name, description: '', parameters: {} }, + execute, + } +} + +const emptyMessages: Message[] = [] + +describe('executeTool (patched @xsai/shared-chat)', () => { + it('returns success tool message when tool executes', async () => { + const tools = [createTool('myTool', async () => 'ok')] + const toolCall = createToolCall() + + const out = await executeTool({ + messages: emptyMessages, + toolCall, + tools, + }) + + expect(out.completionToolResult.isError).toBeUndefined() + expect(out.completionToolResult.result).toBe('ok') + expect(out.message.role).toBe('tool') + expect(out.message.content).toBe('ok') + expect(out.message.tool_call_id).toBe('call_1') + }) + + it('captures unknown tool as error result instead of throwing', async () => { + const tools = [createTool('other', async () => 'x')] + const toolCall = createToolCall({ function: { name: 'missingTool', arguments: '{}' } }) + + const out = await executeTool({ + captureToolErrors: true, + messages: emptyMessages, + toolCall, + tools, + }) + + expect(out.completionToolResult.isError).toBe(true) + expect(out.completionToolResult.error).toBeDefined() + expect(InvalidToolCallError.isInstance(out.completionToolResult.error)).toBe(true) + expect(String(out.message.content)).toContain('missingTool') + expect(out.message.role).toBe('tool') + }) + + it('captures invalid JSON arguments as error result', async () => { + const tools = [createTool('myTool', async () => 'x')] + const toolCall = createToolCall({ function: { name: 'myTool', arguments: '{broken' } }) + + const out = await executeTool({ + captureToolErrors: true, + messages: emptyMessages, + toolCall, + tools, + }) + + expect(out.completionToolResult.isError).toBe(true) + expect(InvalidToolInputError.isInstance(out.completionToolResult.error)).toBe(true) + expect(String(out.message.content)).toContain('myTool') + }) + + it('captures tool execute rejection as error result', async () => { + const tools = [ + createTool('myTool', async () => { + throw new Error('execute failed') + }), + ] + const toolCall = createToolCall() + + const out = await executeTool({ + captureToolErrors: true, + messages: emptyMessages, + toolCall, + tools, + }) + + expect(out.completionToolResult.isError).toBe(true) + expect(ToolExecutionError.isInstance(out.completionToolResult.error)).toBe(true) + expect(String(out.message.content)).toContain('myTool') + expect(String(out.message.content)).toContain('execute failed') + }) + + it('rethrows AbortError from tool execute', async () => { + const controller = new AbortController() + const tools = [ + createTool('myTool', async () => { + const err = new Error('aborted') + err.name = 'AbortError' + throw err + }), + ] + const toolCall = createToolCall() + + await expect( + executeTool({ + abortSignal: controller.signal, + messages: emptyMessages, + toolCall, + tools, + }), + ).rejects.toMatchObject({ name: 'AbortError' }) + }) + + it('repairs invalid tool call when repairToolCall returns a valid call', async () => { + const tools = [ + createTool('goodTool', async () => 'repaired'), + ] + const toolCall = createToolCall({ function: { name: 'badTool', arguments: '{}' } }) + + const out = await executeTool({ + messages: emptyMessages, + repairToolCall: async () => ({ + id: 'call_1', + type: 'function', + function: { name: 'goodTool', arguments: '{}' }, + }), + toolCall, + tools, + }) + + expect(out.completionToolResult.isError).toBeUndefined() + expect(out.completionToolResult.result).toBe('repaired') + }) + + it('returns error when repairToolCall returns null', async () => { + const tools = [createTool('goodTool', async () => 'x')] + const toolCall = createToolCall({ function: { name: 'badTool', arguments: '{}' } }) + + const out = await executeTool({ + captureToolErrors: true, + messages: emptyMessages, + repairToolCall: async () => null, + toolCall, + tools, + }) + + expect(out.completionToolResult.isError).toBe(true) + expect(InvalidToolCallError.isInstance(out.completionToolResult.error)).toBe(true) + }) + + it('invokes lifecycle callbacks on success and on error', async () => { + const onToolCallStart = vi.fn() + const onToolCallFinish = vi.fn() + const tools = [createTool('myTool', async () => 'done')] + + const successCall = createToolCall() + const successOut = await executeTool({ + messages: emptyMessages, + onToolCallFinish, + onToolCallStart, + toolCall: successCall, + tools, + }) + + expect(onToolCallStart).toHaveBeenCalledOnce() + expect(onToolCallStart).toHaveBeenCalledWith({ + input: {}, + toolCallId: 'call_1', + toolName: 'myTool', + }) + expect(onToolCallFinish).toHaveBeenCalled() + const successFinish = onToolCallFinish.mock.calls[0][0] + expect(successFinish.toolName).toBe('myTool') + expect(successFinish.toolCallId).toBe('call_1') + expect(successFinish.output).toBe(successOut.completionToolResult.result) + expect(successFinish.error).toBeUndefined() + expect(typeof successFinish.durationMs).toBe('number') + + onToolCallStart.mockClear() + onToolCallFinish.mockClear() + + const badCall = createToolCall({ function: { name: 'nope', arguments: '{}' } }) + await executeTool({ + captureToolErrors: true, + messages: emptyMessages, + onToolCallFinish, + onToolCallStart, + toolCall: badCall, + tools, + }) + + expect(onToolCallStart).not.toHaveBeenCalled() + expect(onToolCallFinish).toHaveBeenCalledOnce() + const errFinish = onToolCallFinish.mock.calls[0][0] + expect(errFinish.output).toBeUndefined() + expect(InvalidToolCallError.isInstance(errFinish.error)).toBe(true) + }) + + describe('without captureToolErrors (default upstream behavior)', () => { + it('throws InvalidToolCallError for unknown tool', async () => { + const tools = [createTool('other', async () => 'x')] + const toolCall = createToolCall({ function: { name: 'missingTool', arguments: '{}' } }) + + let thrown: unknown + try { + await executeTool({ + messages: emptyMessages, + toolCall, + tools, + }) + expect.fail('expected executeTool to throw') + } + catch (error) { + thrown = error + } + expect(InvalidToolCallError.isInstance(thrown)).toBe(true) + }) + + it('throws InvalidToolInputError for invalid JSON arguments', async () => { + const tools = [createTool('myTool', async () => 'x')] + const toolCall = createToolCall({ function: { name: 'myTool', arguments: '{broken' } }) + + let thrown: unknown + try { + await executeTool({ + messages: emptyMessages, + toolCall, + tools, + }) + expect.fail('expected executeTool to throw') + } + catch (error) { + thrown = error + } + expect(InvalidToolInputError.isInstance(thrown)).toBe(true) + }) + + it('throws ToolExecutionError when tool execute rejects', async () => { + const tools = [ + createTool('myTool', async () => { + throw new Error('execute failed') + }), + ] + const toolCall = createToolCall() + + let thrown: unknown + try { + await executeTool({ + messages: emptyMessages, + toolCall, + tools, + }) + expect.fail('expected executeTool to throw') + } + catch (error) { + thrown = error + } + expect(ToolExecutionError.isInstance(thrown)).toBe(true) + }) + + it('throws InvalidToolCallError when repairToolCall returns null', async () => { + const tools = [createTool('goodTool', async () => 'x')] + const toolCall = createToolCall({ function: { name: 'badTool', arguments: '{}' } }) + + let thrown: unknown + try { + await executeTool({ + messages: emptyMessages, + repairToolCall: async () => null, + toolCall, + tools, + }) + expect.fail('expected executeTool to throw') + } + catch (error) { + thrown = error + } + expect(InvalidToolCallError.isInstance(thrown)).toBe(true) + }) + }) +}) diff --git a/packages/stage-ui/src/stores/llm.ts b/packages/stage-ui/src/stores/llm.ts index 9320665f5..ee67b7473 100644 --- a/packages/stage-ui/src/stores/llm.ts +++ b/packages/stage-ui/src/stores/llm.ts @@ -1,8 +1,13 @@ import type { WebSocketEvents } from '@proj-airi/server-sdk' import type { ChatProvider } from '@xsai-ext/providers/utils' -import type { CommonContentPart, CompletionToolCall, Message, Tool } from '@xsai/shared-chat' +import type { CommonContentPart, CompletionToolCall, CompletionToolResult, Message, Tool } from '@xsai/shared-chat' import { listModels } from '@xsai/model' +import { + + stepCountAtLeast, + +} from '@xsai/shared-chat' import { streamText } from '@xsai/stream-text' import { defineStore } from 'pinia' import { ref } from 'vue' @@ -14,6 +19,7 @@ export type StreamEvent = | { type: 'text-delta', text: string } | ({ type: 'finish' } & any) | ({ type: 'tool-call' } & CompletionToolCall) + | (CompletionToolResult & { type: 'tool-error' }) | { type: 'tool-result', toolCallId: string, result?: string | CommonContentPart[] } | { type: 'error', error: any } @@ -95,7 +101,8 @@ async function streamFrom(model: string, chatProvider: ChatProvider, messages: M await options?.onStreamEvent?.(event as StreamEvent) if (event && (event as StreamEvent).type === 'finish') { const finishReason = (event as any).finishReason - if (finishReason !== 'tool_calls' || !options?.waitForTools) + const waitingForToolRound = finishReason === 'tool_calls' || finishReason === 'tool-calls' + if (!waitingForToolRound || !options?.waitForTools) resolveOnce() } else if (event && (event as StreamEvent).type === 'error') { @@ -111,10 +118,11 @@ async function streamFrom(model: string, chatProvider: ChatProvider, messages: M const streamResult = streamText({ ...chatConfig, abortSignal: options?.abortSignal, - maxSteps: 10, messages: sanitized, headers: options?.headers, + stopWhen: stepCountAtLeast(10), tools, + captureToolErrors: true, onEvent, }) diff --git a/packages/stage-ui/src/types/chat.ts b/packages/stage-ui/src/types/chat.ts index f753eebaf..b722b31f4 100644 --- a/packages/stage-ui/src/types/chat.ts +++ b/packages/stage-ui/src/types/chat.ts @@ -14,6 +14,7 @@ export interface ChatSlicesToolCall { export interface ChatSlicesToolCallResult { type: 'tool-call-result' id: string + isError?: boolean result?: string | CommonContentPart[] } @@ -23,6 +24,7 @@ export interface ChatAssistantMessage extends AssistantMessage { slices: ChatSlices[] tool_results: { id: string + isError?: boolean result?: string | CommonContentPart[] }[] categorization?: { diff --git a/patches/@xsai__generate-text@0.5.0-beta.2.patch b/patches/@xsai__generate-text@0.5.0-beta.2.patch new file mode 100644 index 000000000..7b6550c95 --- /dev/null +++ b/patches/@xsai__generate-text@0.5.0-beta.2.patch @@ -0,0 +1,34 @@ +diff --git a/dist/index.d.ts b/dist/index.d.ts +index bfa8434ddad32d08af9d9aedaf6a1f1caa21cac8..db248a93025a37d2c0d11d7a6bb31aa9ba6ee63b 100644 +--- a/dist/index.d.ts ++++ b/dist/index.d.ts +@@ -1,9 +1,13 @@ + import { WithUnknown } from '@xsai/shared'; +-import { ChatOptions, CompletionStep, PrepareStep, StopCondition, FinishReason, AssistantMessage, Usage, Message, CompletionToolCall, CompletionToolResult } from '@xsai/shared-chat'; ++import { ChatOptions, CompletionStep, OnToolCallFinishCallback, OnToolCallStartCallback, PrepareStep, RepairToolCallFunction, StopCondition, FinishReason, AssistantMessage, Usage, Message, CompletionToolCall, CompletionToolResult } from '@xsai/shared-chat'; + + interface GenerateTextOptions extends ChatOptions { + onStepFinish?: (step: CompletionStep) => Promise | unknown; ++ captureToolErrors?: boolean; ++ onToolCallFinish?: OnToolCallFinishCallback; ++ onToolCallStart?: OnToolCallStartCallback; + prepareStep?: PrepareStep; ++ repairToolCall?: RepairToolCallFunction; + /** @internal */ + steps?: CompletionStep[]; + /** @default `stepCountAtLeast(1)` */ +diff --git a/dist/index.js b/dist/index.js +index 11940a69300f795caa7b780deba1f61a4d3127f6..2cefa4f4806493b21aae75df2cb1ae4e6ae5f160 100644 +--- a/dist/index.js ++++ b/dist/index.js +@@ -41,6 +41,10 @@ const rawGenerateText = async (options) => { + msgToolCalls.map(async (toolCall) => executeTool({ + abortSignal: options.abortSignal, ++ captureToolErrors: options.captureToolErrors, + messages, ++ onToolCallFinish: options.onToolCallFinish, ++ onToolCallStart: options.onToolCallStart, ++ repairToolCall: options.repairToolCall, + toolCall, + tools: options.tools + })) diff --git a/patches/@xsai__shared-chat@0.5.0-beta.2.patch b/patches/@xsai__shared-chat@0.5.0-beta.2.patch new file mode 100644 index 000000000..e27e24215 --- /dev/null +++ b/patches/@xsai__shared-chat@0.5.0-beta.2.patch @@ -0,0 +1,264 @@ +diff --git a/dist/index.d.ts b/dist/index.d.ts +index 1b8df0289811d82777e853bc4290e35b16b0bd36..4682f7bbf62b1bc3d65abde34d7366c64f9b5eb0 100644 +--- a/dist/index.d.ts ++++ b/dist/index.d.ts +@@ -96,6 +96,8 @@ interface CompletionToolCall { + } + interface CompletionToolResult { + args: Record; ++ error?: Error; ++ isError?: boolean; + result: ToolMessage['content']; + toolCallId: string; + toolName: string; +@@ -222,9 +224,32 @@ interface DetermineStepTypeOptions { + /** @internal */ + declare const determineStepType: ({ finishReason, stepsLength, toolCallsLength, willContinue }: DetermineStepTypeOptions) => CompletionStepType; + ++type OnToolCallFinishCallback = (context: { ++ durationMs: number; ++ error?: unknown; ++ output?: unknown; ++ toolCallId: string; ++ toolName: string; ++}) => Promise | void; ++type OnToolCallStartCallback = (context: { ++ input: unknown; ++ toolCallId: string; ++ toolName: string; ++}) => Promise | void; ++type RepairToolCallFunction = (context: { ++ error: Error; ++ messages: Message[]; ++ toolCall: ToolCall; ++ tools?: Tool[]; ++}) => Promise | ToolCall | null; ++ + interface ExecuteToolOptions { + abortSignal?: AbortSignal; ++ captureToolErrors?: boolean; + messages: Message[]; ++ onToolCallFinish?: OnToolCallFinishCallback; ++ onToolCallStart?: OnToolCallStartCallback; ++ repairToolCall?: RepairToolCallFunction; + toolCall: ToolCall; + tools?: Tool[]; + } +@@ -233,7 +257,7 @@ interface ExecuteToolResult { + completionToolResult: CompletionToolResult; + message: ToolMessage; + } +-declare const executeTool: ({ abortSignal, messages, toolCall, tools }: ExecuteToolOptions) => Promise; ++declare const executeTool: (options: ExecuteToolOptions) => Promise; + + interface ResolvedStepOptions { + messages: Message[]; +@@ -256,4 +280,4 @@ declare const hasToolCall: (name?: string) => StopCondition; + declare const shouldStop: (stopWhen: StopCondition, context: StopContext) => boolean; + + export { and, chat, determineStepType, executeTool, hasToolCall, not, or, resolveStepOptions, shouldStop, stepCountAtLeast }; +-export type { AssistantMessage, AudioContentPart, ChatOptions, CommonContentPart, CompletionStep, CompletionStepType, CompletionToolCall, CompletionToolResult, DetermineStepTypeOptions, DeveloperMessage, ExecuteToolOptions, ExecuteToolResult, FileContentPart, FinishReason, ImageContentPart, Message, PrepareStep, PrepareStepOptions, PrepareStepResult, RefusalContentPart, ResolveStepOptionsOptions, ResolvedStepOptions, StopCondition, StopContext, StopStep, SystemMessage, TextContentPart, Tool, ToolCall, ToolChoice, ToolExecuteOptions, ToolExecuteResult, ToolMessage, Usage, UserMessage }; ++export type { AssistantMessage, AudioContentPart, ChatOptions, CommonContentPart, CompletionStep, CompletionStepType, CompletionToolCall, CompletionToolResult, DetermineStepTypeOptions, DeveloperMessage, ExecuteToolOptions, ExecuteToolResult, FileContentPart, FinishReason, ImageContentPart, Message, OnToolCallFinishCallback, OnToolCallStartCallback, PrepareStep, PrepareStepOptions, PrepareStepResult, RefusalContentPart, RepairToolCallFunction, ResolveStepOptionsOptions, ResolvedStepOptions, StopCondition, StopContext, StopStep, SystemMessage, TextContentPart, Tool, ToolCall, ToolChoice, ToolExecuteOptions, ToolExecuteResult, ToolMessage, Usage, UserMessage }; +diff --git a/dist/index.js b/dist/index.js +index 34e87341ac400dd8c61457c188485b82a1383300..2e7e1fa99fdbccb7a0be0af92504ed903d95c482 100644 +--- a/dist/index.js ++++ b/dist/index.js +@@ -66,57 +66,150 @@ const runTool = async (tool, options) => { + }); + } + }; +-const executeTool = async ({ abortSignal, messages, toolCall, tools }) => { +- const toolName = toolCall.function.name; +- const toolArguments = toolCall.function.arguments; +- if (toolName == null) { +- throw new InvalidToolCallError(`Missing toolCall.function.name: ${JSON.stringify(toolCall)}`, { +- reason: "missing_name", +- toolCall +- }); +- } +- if (toolArguments == null) { +- throw new InvalidToolCallError(`Missing toolCall.function.arguments: ${JSON.stringify(toolCall)}`, { +- reason: "missing_arguments", +- toolCall +- }); +- } +- const tool = tools?.find((tool2) => tool2.function.name === toolName); +- if (!tool) { +- const availableTools = tools?.map((tool2) => tool2.function.name); +- const availableToolsErrorMsg = availableTools == null || availableTools.length === 0 ? "No tools are available" : `Available tools: ${availableTools.join(", ")}`; +- throw new InvalidToolCallError(`Model tried to call unavailable tool "${toolName}", ${availableToolsErrorMsg}.`, { +- availableTools, +- reason: "unknown_tool", +- toolCall, +- toolName +- }); +- } +- const parsedArgs = parseToolInput(toolName, toolArguments); +- const result = await runTool(tool, { abortSignal, messages, parsedArgs, toolCall }); +- const completionToolCall = { +- args: toolArguments, +- toolCallId: toolCall.id, +- toolCallType: toolCall.type, +- toolName +- }; +- const completionToolResult = { +- args: parsedArgs, +- result, +- toolCallId: toolCall.id, +- toolName +- }; +- const message = { +- content: result, +- role: "tool", +- tool_call_id: toolCall.id +- }; ++const buildErrorReturn = (toolCall, toolName, toolCallId, error) => { ++ const errorMessage = error instanceof Error ? error.message : String(error); ++ const errorContent = `Tool call error for "${toolName}": ${errorMessage}`; + return { +- completionToolCall, +- completionToolResult, +- message ++ completionToolCall: { ++ args: toolCall.function?.arguments ?? "{}", ++ toolCallId, ++ toolCallType: toolCall.type ?? "function", ++ toolName ++ }, ++ completionToolResult: { ++ args: {}, ++ error, ++ isError: true, ++ result: errorContent, ++ toolCallId, ++ toolName ++ }, ++ message: { ++ content: errorContent, ++ role: "tool", ++ tool_call_id: toolCallId ++ } + }; + }; ++const executeTool = async ({ ++ abortSignal, ++ captureToolErrors, ++ messages, ++ onToolCallFinish, ++ onToolCallStart, ++ repairToolCall, ++ toolCall, ++ tools ++}) => { ++ const resolvedToolName = toolCall.function?.name ?? "unknown"; ++ const toolCallId = toolCall.id; ++ const startTime = Date.now(); ++ try { ++ const toolName = toolCall.function.name; ++ const toolArguments = toolCall.function.arguments; ++ if (toolName == null) { ++ throw new InvalidToolCallError(`Missing toolCall.function.name: ${JSON.stringify(toolCall)}`, { ++ reason: "missing_name", ++ toolCall ++ }); ++ } ++ if (toolArguments == null) { ++ throw new InvalidToolCallError(`Missing toolCall.function.arguments: ${JSON.stringify(toolCall)}`, { ++ reason: "missing_arguments", ++ toolCall ++ }); ++ } ++ const tool = tools?.find((tool2) => tool2.function.name === toolName); ++ if (!tool) { ++ const availableTools = tools?.map((tool2) => tool2.function.name); ++ const availableToolsErrorMsg = availableTools == null || availableTools.length === 0 ? "No tools are available" : `Available tools: ${availableTools.join(", ")}`; ++ throw new InvalidToolCallError(`Model tried to call unavailable tool "${toolName}", ${availableToolsErrorMsg}.`, { ++ availableTools, ++ reason: "unknown_tool", ++ toolCall, ++ toolName ++ }); ++ } ++ const parsedArgs = parseToolInput(toolName, toolArguments); ++ if (onToolCallStart) { ++ try { ++ await onToolCallStart({ input: parsedArgs, toolCallId, toolName }); ++ } catch { ++ } ++ } ++ const result = await runTool(tool, { abortSignal, messages, parsedArgs, toolCall }); ++ if (onToolCallFinish) { ++ try { ++ await onToolCallFinish({ ++ durationMs: Date.now() - startTime, ++ error: void 0, ++ output: result, ++ toolCallId, ++ toolName ++ }); ++ } catch { ++ } ++ } ++ const completionToolCall = { ++ args: toolArguments, ++ toolCallId: toolCall.id, ++ toolCallType: toolCall.type, ++ toolName ++ }; ++ const completionToolResult = { ++ args: parsedArgs, ++ result, ++ toolCallId: toolCall.id, ++ toolName ++ }; ++ const message = { ++ content: result, ++ role: "tool", ++ tool_call_id: toolCall.id ++ }; ++ return { ++ completionToolCall, ++ completionToolResult, ++ message ++ }; ++ } catch (error) { ++ if (isAbortError(error, abortSignal)) ++ throw error; ++ if (repairToolCall && (InvalidToolCallError.isInstance(error) || InvalidToolInputError.isInstance(error))) { ++ try { ++ const repaired = await repairToolCall({ error, messages, toolCall, tools }); ++ if (repaired != null) { ++ return executeTool({ ++ abortSignal, ++ captureToolErrors, ++ messages, ++ onToolCallFinish, ++ onToolCallStart, ++ repairToolCall: void 0, ++ toolCall: repaired, ++ tools ++ }); ++ } ++ } catch { ++ } ++ } ++ if (onToolCallFinish) { ++ try { ++ await onToolCallFinish({ ++ durationMs: Date.now() - startTime, ++ error, ++ output: void 0, ++ toolCallId, ++ toolName: resolvedToolName ++ }); ++ } catch { ++ } ++ } ++ if (!captureToolErrors) ++ throw error; ++ return buildErrorReturn(toolCall, resolvedToolName, toolCallId, error); ++ } ++}; + + const resolveStepOptions = async ({ messages, model, prepareStep, stepNumber, steps, toolChoice }) => { + const prepared = prepareStep == null ? void 0 : await prepareStep({ diff --git a/patches/@xsai__stream-text@0.5.0-beta.2.patch b/patches/@xsai__stream-text@0.5.0-beta.2.patch new file mode 100644 index 000000000..b88f2248f --- /dev/null +++ b/patches/@xsai__stream-text@0.5.0-beta.2.patch @@ -0,0 +1,55 @@ +diff --git a/dist/index.d.ts b/dist/index.d.ts +index e184d851f8f0dec7456bab129ed90eaad8944125..e363d3d15261fa57831cf4d6fee384644bd45d00 100644 +--- a/dist/index.d.ts ++++ b/dist/index.d.ts +@@ -1,8 +1,10 @@ + import { WithUnknown } from '@xsai/shared'; +-import { CompletionToolCall, CompletionToolResult, FinishReason, Usage, ChatOptions, CompletionStep, PrepareStep, StopCondition, Message } from '@xsai/shared-chat'; ++import { CompletionToolCall, CompletionToolResult, FinishReason, OnToolCallFinishCallback, OnToolCallStartCallback, RepairToolCallFunction, Usage, ChatOptions, CompletionStep, PrepareStep, StopCondition, Message } from '@xsai/shared-chat'; + + type StreamTextEvent = (CompletionToolCall & { + type: 'tool-call'; ++}) | (CompletionToolResult & { ++ type: 'tool-error'; + }) | (CompletionToolResult & { + type: 'tool-result'; + }) | { +@@ -33,7 +35,11 @@ interface StreamTextOptions extends ChatOptions { + onEvent?: (event: StreamTextEvent) => Promise | unknown; + onFinish?: (step?: CompletionStep) => Promise | unknown; + onStepFinish?: (step: CompletionStep) => Promise | unknown; ++ captureToolErrors?: boolean; ++ onToolCallFinish?: OnToolCallFinishCallback; ++ onToolCallStart?: OnToolCallStartCallback; + prepareStep?: PrepareStep; ++ repairToolCall?: RepairToolCallFunction; + /** @default `stepCountAtLeast(1)` */ + stopWhen?: StopCondition; + /** +diff --git a/dist/index.js b/dist/index.js +index 6353da4d45ad65340104530d83b5337bba8d9d77..34e6e4fda7f390be6334fe3eadcbc5199957e998 100644 +--- a/dist/index.js ++++ b/dist/index.js +@@ -139,6 +139,10 @@ const streamText = (options) => { + validToolCalls.map(async (toolCall) => executeTool({ + abortSignal: options.abortSignal, ++ captureToolErrors: options.captureToolErrors, + messages, ++ onToolCallFinish: options.onToolCallFinish, ++ onToolCallStart: options.onToolCallStart, ++ repairToolCall: options.repairToolCall, + toolCall, + tools: options.tools + })) +@@ -148,7 +151,10 @@ const streamText = (options) => { + toolResults.push(completionToolResult); + messages.push(message); + pushEvent({ ...completionToolCall, type: "tool-call" }); +- pushEvent({ ...completionToolResult, type: "tool-result" }); ++ pushEvent({ ++ ...completionToolResult, ++ type: completionToolResult.isError ? "tool-error" : "tool-result" ++ }); + } + } else { + pushEvent({ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ad037b48c..5668bf9b6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -127,38 +127,41 @@ catalogs: specifier: 14.1.0 version: 14.1.0 '@xsai-ext/providers': - specifier: ^0.4.4 - version: 0.4.4 + specifier: 0.5.0-beta.2 + version: 0.5.0-beta.2 '@xsai/embed': - specifier: ^0.4.4 - version: 0.4.4 + specifier: 0.5.0-beta.2 + version: 0.5.0-beta.2 '@xsai/generate-speech': - specifier: 0.4.0-beta.13 - version: 0.4.0-beta.13 + specifier: 0.5.0-beta.2 + version: 0.5.0-beta.2 '@xsai/generate-text': - specifier: ^0.4.4 - version: 0.4.4 + specifier: 0.5.0-beta.2 + version: 0.5.0-beta.2 '@xsai/generate-transcription': - specifier: ^0.4.4 - version: 0.4.4 + specifier: 0.5.0-beta.2 + version: 0.5.0-beta.2 '@xsai/model': - specifier: ^0.4.4 - version: 0.4.4 + specifier: 0.5.0-beta.2 + version: 0.5.0-beta.2 '@xsai/shared': - specifier: 0.4.0-beta.13 - version: 0.4.0-beta.13 + specifier: 0.5.0-beta.2 + version: 0.5.0-beta.2 '@xsai/shared-chat': - specifier: 0.4.0-beta.13 - version: 0.4.0-beta.13 + specifier: 0.5.0-beta.2 + version: 0.5.0-beta.2 '@xsai/stream-text': - specifier: ^0.4.4 - version: 0.4.4 + specifier: 0.5.0-beta.2 + version: 0.5.0-beta.2 + '@xsai/stream-transcription': + specifier: 0.5.0-beta.2 + version: 0.5.0-beta.2 '@xsai/tool': - specifier: ^0.4.4 - version: 0.4.4 + specifier: 0.5.0-beta.2 + version: 0.5.0-beta.2 '@xsai/utils-chat': - specifier: 0.4.0-beta.13 - version: 0.4.0-beta.13 + specifier: 0.5.0-beta.2 + version: 0.5.0-beta.2 alien-signals: specifier: ^3.1.2 version: 3.1.2 @@ -310,8 +313,8 @@ catalogs: specifier: ^8.20.0 version: 8.20.0 xsschema: - specifier: 0.4.0-beta.13 - version: 0.4.0-beta.13 + specifier: 0.5.0-beta.2 + version: 0.5.0-beta.2 yaml: specifier: ^2.8.3 version: 2.8.3 @@ -350,6 +353,15 @@ patchedDependencies: '@mediapipe/tasks-vision': hash: 2014bd232d13f4bfac27f27d61105894bf54aca350379b2816fe05b6d3e27d66 path: patches/@mediapipe__tasks-vision.patch + '@xsai/generate-text@0.5.0-beta.2': + hash: 306bfb723913596b334140f0d6fa48063f336e3b44024efc1d72bf60d54b15e6 + path: patches/@xsai__generate-text@0.5.0-beta.2.patch + '@xsai/shared-chat@0.5.0-beta.2': + hash: 26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01 + path: patches/@xsai__shared-chat@0.5.0-beta.2.patch + '@xsai/stream-text@0.5.0-beta.2': + hash: 90dfe10d02f5946658508ec019937eab600745c93446ce7b2fdb1a0ed70e3e49 + path: patches/@xsai__stream-text@0.5.0-beta.2.patch crossws@0.4.4: hash: 4d79ec736d10d2a81a9e2a31b067d43f0b6665122267981e652ab9923d165958 path: patches/crossws@0.4.4.patch @@ -504,13 +516,13 @@ importers: version: 14.2.1(vue@3.5.30(typescript@5.9.3)) '@xsai/generate-text': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2(patch_hash=306bfb723913596b334140f0d6fa48063f336e3b44024efc1d72bf60d54b15e6) '@xsai/shared-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01) '@xsai/stream-text': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2(patch_hash=90dfe10d02f5946658508ec019937eab600745c93446ce7b2fdb1a0ed70e3e49) valibot: specifier: ^1.3.1 version: 1.3.1(typescript@5.9.3) @@ -519,7 +531,7 @@ importers: version: 3.5.30(typescript@5.9.3) xsschema: specifier: 'catalog:' - version: 0.4.0-beta.13(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + version: 0.5.0-beta.2(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) devDependencies: '@iconify-json/solar': specifier: ^1.2.5 @@ -785,34 +797,34 @@ importers: version: 14.2.1(vue@3.5.30(typescript@5.9.3)) '@xsai-ext/providers': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai-transformers/embed': specifier: ^0.0.11 version: 0.0.11(electron@41.0.3) '@xsai/generate-speech': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 '@xsai/generate-text': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2(patch_hash=306bfb723913596b334140f0d6fa48063f336e3b44024efc1d72bf60d54b15e6) '@xsai/model': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai/shared': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 '@xsai/shared-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01) '@xsai/stream-text': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2(patch_hash=90dfe10d02f5946658508ec019937eab600745c93446ce7b2fdb1a0ed70e3e49) '@xsai/stream-transcription': - specifier: 0.4.0-beta.8 - version: 0.4.0-beta.8 + specifier: 'catalog:' + version: 0.5.0-beta.2 '@xsai/utils-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 animejs: specifier: ^4.3.6 version: 4.3.6 @@ -935,7 +947,7 @@ importers: version: 7.4.0 xsschema: specifier: 'catalog:' - version: 0.4.0-beta.13(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + version: 0.5.0-beta.2(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) yauzl: specifier: ^3.2.1 version: 3.2.1 @@ -1191,7 +1203,7 @@ importers: version: 14.2.1(vue@3.5.30(typescript@5.9.3)) '@xsai-ext/providers': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai-transformers/embed': specifier: ^0.0.11 version: 0.0.11(electron@40.8.3)(h3@2.0.1-rc.19(crossws@0.4.4(patch_hash=4d79ec736d10d2a81a9e2a31b067d43f0b6665122267981e652ab9923d165958)(srvx@0.11.13(patch_hash=c761d25a70e22a0925c88fe91a9dd1c3153dd341d8fd4f260166678156c4df2d)))) @@ -1200,31 +1212,31 @@ importers: version: 0.0.11(electron@40.8.3)(h3@2.0.1-rc.19(crossws@0.4.4(patch_hash=4d79ec736d10d2a81a9e2a31b067d43f0b6665122267981e652ab9923d165958)(srvx@0.11.13(patch_hash=c761d25a70e22a0925c88fe91a9dd1c3153dd341d8fd4f260166678156c4df2d)))) '@xsai/generate-speech': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 '@xsai/generate-text': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2(patch_hash=306bfb723913596b334140f0d6fa48063f336e3b44024efc1d72bf60d54b15e6) '@xsai/model': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai/shared': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 '@xsai/shared-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01) '@xsai/stream-text': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2(patch_hash=90dfe10d02f5946658508ec019937eab600745c93446ce7b2fdb1a0ed70e3e49) '@xsai/stream-transcription': - specifier: 0.4.0-beta.8 - version: 0.4.0-beta.8 + specifier: 'catalog:' + version: 0.5.0-beta.2 '@xsai/tool': specifier: 'catalog:' - version: 0.4.4(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + version: 0.5.0-beta.2(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) '@xsai/utils-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 alien-signals: specifier: 'catalog:' version: 3.1.2 @@ -1356,7 +1368,7 @@ importers: version: 0.0.6(react@19.2.3)(vue@3.5.30(typescript@5.9.3)) xsschema: specifier: 'catalog:' - version: 0.4.0-beta.13(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + version: 0.5.0-beta.2(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) zod: specifier: ^4.3.6 version: 4.3.6 @@ -1648,34 +1660,34 @@ importers: version: 14.2.1(vue@3.5.30(typescript@5.9.3)) '@xsai-ext/providers': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai-transformers/embed': specifier: ^0.0.11 version: 0.0.11(electron@41.0.3) '@xsai/generate-speech': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 '@xsai/generate-text': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2(patch_hash=306bfb723913596b334140f0d6fa48063f336e3b44024efc1d72bf60d54b15e6) '@xsai/model': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai/shared': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 '@xsai/shared-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01) '@xsai/stream-text': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2(patch_hash=90dfe10d02f5946658508ec019937eab600745c93446ce7b2fdb1a0ed70e3e49) '@xsai/stream-transcription': - specifier: 0.4.0-beta.8 - version: 0.4.0-beta.8 + specifier: 'catalog:' + version: 0.5.0-beta.2 '@xsai/utils-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 animejs: specifier: ^4.3.6 version: 4.3.6 @@ -1801,7 +1813,7 @@ importers: version: 7.4.0 xsschema: specifier: 'catalog:' - version: 0.4.0-beta.13(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + version: 0.5.0-beta.2(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) yauzl: specifier: ^3.2.1 version: 3.2.1 @@ -2529,7 +2541,7 @@ importers: version: 1.0.0-beta.3(electron@41.0.3) '@xsai/shared-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01) packages/plugin-sdk: dependencies: @@ -2695,13 +2707,13 @@ importers: version: 14.2.1(vue@3.5.30(typescript@5.9.3)) '@xsai-ext/providers': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai/generate-speech': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 '@xsai/stream-transcription': - specifier: 0.4.0-beta.8 - version: 0.4.0-beta.8 + specifier: 'catalog:' + version: 0.5.0-beta.2 animejs: specifier: ^4.3.6 version: 4.3.6 @@ -2807,13 +2819,13 @@ importers: version: 14.2.1(vue@3.5.30(typescript@5.9.3)) '@xsai-ext/providers': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai/generate-speech': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 '@xsai/stream-transcription': - specifier: 0.4.0-beta.8 - version: 0.4.0-beta.8 + specifier: 'catalog:' + version: 0.5.0-beta.2 animejs: specifier: ^4.3.6 version: 4.3.6 @@ -2858,7 +2870,7 @@ importers: version: 2.0.9(vue@3.5.30(typescript@5.9.3)) xsschema: specifier: 'catalog:' - version: 0.4.0-beta.13(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + version: 0.5.0-beta.2(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) zod: specifier: 'catalog:' version: 4.3.6 @@ -3001,7 +3013,7 @@ importers: version: 14.2.1(vue@3.5.30(typescript@5.9.3)) '@xsai-ext/providers': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai-transformers/embed': specifier: ^0.0.11 version: 0.0.11(electron@41.0.3) @@ -3010,37 +3022,37 @@ importers: version: 0.0.11(electron@41.0.3) '@xsai/embed': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai/generate-speech': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 '@xsai/generate-text': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2(patch_hash=306bfb723913596b334140f0d6fa48063f336e3b44024efc1d72bf60d54b15e6) '@xsai/generate-transcription': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai/model': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai/shared': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 '@xsai/shared-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01) '@xsai/stream-text': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2(patch_hash=90dfe10d02f5946658508ec019937eab600745c93446ce7b2fdb1a0ed70e3e49) '@xsai/stream-transcription': - specifier: 0.4.0-beta.8 - version: 0.4.0-beta.8 + specifier: 'catalog:' + version: 0.5.0-beta.2 '@xsai/tool': specifier: 'catalog:' - version: 0.4.4(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + version: 0.5.0-beta.2(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) '@xsai/utils-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 animejs: specifier: ^4.3.6 version: 4.3.6 @@ -3175,7 +3187,7 @@ importers: version: 4.0.0 xsschema: specifier: 'catalog:' - version: 0.4.0-beta.13(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + version: 0.5.0-beta.2(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) zod: specifier: ^4.3.6 version: 4.3.6 @@ -3359,7 +3371,7 @@ importers: version: 14.2.1(vue@3.5.30(typescript@5.9.3)) '@xsai/tool': specifier: 'catalog:' - version: 0.4.4(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + version: 0.5.0-beta.2(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) animejs: specifier: ^4.3.6 version: 4.3.6 @@ -3759,19 +3771,19 @@ importers: version: 0.1.10 '@xsai-ext/providers': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai/generate-speech': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 '@xsai/generate-text': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2(patch_hash=306bfb723913596b334140f0d6fa48063f336e3b44024efc1d72bf60d54b15e6) '@xsai/generate-transcription': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai/shared-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01) discord.js: specifier: ^14.25.1 version: 14.25.1(bufferutil@4.1.0)(utf-8-validate@5.0.10) @@ -3804,10 +3816,10 @@ importers: version: link:../../packages/server-sdk '@xsai/generate-text': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2(patch_hash=306bfb723913596b334140f0d6fa48063f336e3b44024efc1d72bf60d54b15e6) '@xsai/shared-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01) alien-signals: specifier: ^3.1.2 version: 3.1.2 @@ -3913,13 +3925,13 @@ importers: version: 0.3.4(typescript@5.9.3) '@xsai/generate-text': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2(patch_hash=306bfb723913596b334140f0d6fa48063f336e3b44024efc1d72bf60d54b15e6) '@xsai/shared-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01) '@xsai/utils-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 best-effort-json-parser: specifier: ^1.4.0 version: 1.4.0 @@ -4001,19 +4013,19 @@ importers: version: 0.3.4(typescript@5.9.3) '@xsai/embed': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2 '@xsai/generate-text': specifier: 'catalog:' - version: 0.4.4 + version: 0.5.0-beta.2(patch_hash=306bfb723913596b334140f0d6fa48063f336e3b44024efc1d72bf60d54b15e6) '@xsai/shared-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01) '@xsai/tool': specifier: 'catalog:' - version: 0.4.4(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + version: 0.5.0-beta.2(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) '@xsai/utils-chat': specifier: 'catalog:' - version: 0.4.0-beta.13 + version: 0.5.0-beta.2 best-effort-json-parser: specifier: ^1.4.0 version: 1.4.0 @@ -10392,6 +10404,9 @@ packages: '@xsai-ext/providers@0.4.4': resolution: {integrity: sha512-PVk3IFOPzPyvss9zY6IO6pJ890F5B6LWGWuhU6DzofWMTnqcUzm0hR2Ml/Qo8kZa3Qy/DZkUT0O1T+5g/fZkWw==} + '@xsai-ext/providers@0.5.0-beta.2': + resolution: {integrity: sha512-GwOLUlr+Dicl5UGcd5bidPn+bblBrUJsrB/CfIQXI7czLhDs6DJ3COYU5+i6xDVh/WAC0GD/AkO0NdEMfDwfig==} + '@xsai-ext/shared-providers@0.4.0-beta.12': resolution: {integrity: sha512-ME9L8BtapghM0W2SiTdulq0IvU3WR0h7dZ3k1bg/eXag2XUdbh1jy0zYY3oGmpMBmKXO8JXcArS1mq87gpsK0A==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. @@ -10418,41 +10433,47 @@ packages: '@xsai/embed@0.4.4': resolution: {integrity: sha512-3qKtjjerzola+ggmpfEgESbxQsTkPAKY/Y3hEZiDSFDbRc+3m1AHmMMW+kNiis+Fz+GK8/zDAeVUNMx457XntA==} - '@xsai/generate-speech@0.4.0-beta.13': - resolution: {integrity: sha512-2Nd84TTohnZgm1/l9TYNGHn+vajEavV6wJAvdIVT+5N0m3THPlKbrys2R84NZ1OjD9y3vpqUGdHsdwJyxCXVbg==} + '@xsai/embed@0.5.0-beta.2': + resolution: {integrity: sha512-z2Yfi0TEjzYElWkr61PTsBn13QtPFtBW46+WAOBFdFGhtcpzH7cGpLlbmr+vAosZm6bRdarZF9VqKq9ccp72UA==} - '@xsai/generate-text@0.4.4': - resolution: {integrity: sha512-eDLeRaaeY3SyjrICeIfPXksqfk36oXLTcjinDNLrsiFHqmNvxfbq3WRccy6hjZy4aOWhkV+qPFZnB3ZIyTfs8w==} + '@xsai/generate-speech@0.5.0-beta.2': + resolution: {integrity: sha512-MWVEQJXiwHeVwkF/8ycCNAyRIdGrpqRmeC0LhD0OACla/Bt+AIAnEZsOU7D+OxFrigKqWG1NwH+4Wh1xLhnT1Q==} + + '@xsai/generate-text@0.5.0-beta.2': + resolution: {integrity: sha512-E2yq0mUWtnYNM7JGSd1UbcqQEX57xoND9pCivQVWbyXDwkEEwCgI3pezBqQYwNQlNWd2mtwVZukYXvFfo43+aw==} '@xsai/generate-transcription@0.4.4': resolution: {integrity: sha512-4xAOSHLSV0yAFo0YHxL1F31NbcUj/vIVEUsi+7FSvL/HuKicAvHyEnFoew9+vB0B0e9u9lvgJt8bd5rM0dxgbg==} - '@xsai/model@0.4.4': - resolution: {integrity: sha512-7hjWAOpvv+T7rjbiLw1bKmqdJ78n/iYEcBYh/4wqT2IXDH5TlPw12DgyD5MYonVwA0KxvOtUBejtUroSgsFjMA==} + '@xsai/generate-transcription@0.5.0-beta.2': + resolution: {integrity: sha512-ykeh409PVp6qzAwpUocRinbYmQdF6/6O2dvhH39A7cnYF5P1bLTfrqeYKQTj8GJLK6TW6ODsnfW1Qq7Jxqz5Dg==} - '@xsai/shared-chat@0.4.0-beta.13': - resolution: {integrity: sha512-nvE/lrS50JsZPw09cOaa6vebMfXXuJ7j3/41CN+UqwgJwCWteT4eZRVG55sH1vOAwO8ZOBaPR8pqo88Ph3uy6A==} + '@xsai/model@0.5.0-beta.2': + resolution: {integrity: sha512-FN2AUGGAWTw7XUDf6y1JrcmTRbC8J3FQSE2Sy9HS/pKzEUohBRyiZGc6IEpYzfIE8ShdIa/d5jA070SF8CuZWw==} - '@xsai/shared-chat@0.4.4': - resolution: {integrity: sha512-R/lJDt6SnENVaJcUCO1USVuO/G6qtCbJqopPqARF1n20KWDbchLwW/nvkuZH1TM9vMxaywVNmO9sNJ+uoWJEPA==} + '@xsai/shared-chat@0.5.0-beta.2': + resolution: {integrity: sha512-PyJh49To2+GuY2sVeiVZEs7UF648RYOFZo4jD+qvxX6y/iafLsMtbXnQr3LFt9qcMqqPaQ1Yu2ABsNR+Cr3mAQ==} - '@xsai/shared@0.4.0-beta.13': - resolution: {integrity: sha512-s+CUJcxDNd/IVDDIECIRcCTJimkKNu29skLv3tm21YpSWoFFPuGM682gTNuFoIfSeEy3D3/RTGXzfefgirkNxA==} + '@xsai/shared-stream@0.5.0-beta.2': + resolution: {integrity: sha512-oEmUNpEBx4CBxmFxnN7Btge/9GcON8KTI/Pl6QuT9pjCpK4g0nAG2dddX0BTZCbyMdlDd1ipdnr5Kmh/Yf2JuQ==} '@xsai/shared@0.4.4': resolution: {integrity: sha512-ZrOeRJ0fqV8YRDwyQbYJx1N8Fe2UTl2psjV7ucYJ+gMr3oWzrmNfTX9zrpV9zwzBMUe6VvqhK/iJzz8p4jYlsw==} - '@xsai/stream-text@0.4.4': - resolution: {integrity: sha512-NaJF7PrZzlAtSGP5fIWuTOY5mc4LymwrRvTfdUR+0paJRu66qIP7CGCsDJGpKRBcRdpLakb4/8qn3vqeKG9r8A==} + '@xsai/shared@0.5.0-beta.2': + resolution: {integrity: sha512-4Ljo+yBor8ASBrMT5hRd6vjLlkKVLVvzOVMrdUlxvLVZuMZy7Gcttz17qp/ErqRGX9xkx10UqC0GOce7FpNyzQ==} - '@xsai/stream-transcription@0.4.0-beta.8': - resolution: {integrity: sha512-4V8xHBS7MwnWSuEBaEYOYZE3A3f+Qh9taR+KEui1LJCRH9uq6F4G+s2MTf1GWORaqLNrYmK0yKE0cIImWJ853Q==} + '@xsai/stream-text@0.5.0-beta.2': + resolution: {integrity: sha512-Qm8zlmmlaxm++H/REyER7T9kftOlnNy4TbVIiTye8TEwVwfJrf3PQ32aS2TKbaW+CThgZarNMj+V4E9+YloyeA==} - '@xsai/tool@0.4.4': - resolution: {integrity: sha512-a6w16B6zaOdSEq8iOwfchu20GsYHu3y8QArlxOAk7ej1WOaHr4iVhJBgIguRSTrak4vBKLAljr1OIltGBSAaag==} + '@xsai/stream-transcription@0.5.0-beta.2': + resolution: {integrity: sha512-C5sChW4PvCuMFjbZZ/mry+CBvJu6mQaIbivO39pMBl/MAZIq2kNMFygOugKEwitp8qBJ6iGkcpH0ek5OKjROuA==} - '@xsai/utils-chat@0.4.0-beta.13': - resolution: {integrity: sha512-QlDIFjHT7zHq0Vm+DmgDZpq1vOf2Z5oiSxoIH3EfkN6FGbd9gXsR5JAtzaET7PttORMjv18+IXzvCxAVSOGaiA==} + '@xsai/tool@0.5.0-beta.2': + resolution: {integrity: sha512-M/4vx25FoXjiBiCp+cVXOpwKd7yMBL4R6rgVzKL2YmNVEWqLrREUPn/I2YNp9SyHKsELsk3LTS0IiXOvwXGuuA==} + + '@xsai/utils-chat@0.5.0-beta.2': + resolution: {integrity: sha512-WSjoxY0w+3oRSZQkAWHdhOuidRlaYJR3y6bvELmJje6lCh86a4PQtMIPwJIoTmtuVY13ZgGvvKqoQz/0xS32LA==} abbrev@3.0.1: resolution: {integrity: sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==} @@ -17796,36 +17817,13 @@ packages: resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==} engines: {node: '>=0.4.0'} - xsschema@0.4.0-beta.13: - resolution: {integrity: sha512-gw44icHZnuaY/LqI7aKcHz4rWHI/HmpQJicnZ0+hTYWeJlhwVWzaOaguQTV6QecmAeqwOU5pmClYaFy/9dmMzw==} + xsschema@0.5.0-beta.2: + resolution: {integrity: sha512-zUtk3Ro6Gn39zn7fJRImwmLJmSOpao09dUxdLVyofr+RzfxEEdtm7UVJPe4lUGTJxUCzNptpRp549yD9uKWiug==} peerDependencies: '@valibot/to-json-schema': ^1.0.0 arktype: ^2.1.20 effect: ^3.16.0 - sury: ^10.0.0 - zod: ^3.25.0 || ^4.0.0 - zod-to-json-schema: ^3.25.0 - peerDependenciesMeta: - '@valibot/to-json-schema': - optional: true - arktype: - optional: true - effect: - optional: true - sury: - optional: true - zod: - optional: true - zod-to-json-schema: - optional: true - - xsschema@0.4.4: - resolution: {integrity: sha512-TMhbk8AhxO+YuDOn3rXBjGXQ+Vja3T13UPQkHx/FemhusaOzRfCSj2seykt0mdnFPsOtO9l3ANf4adcp+4NRGw==} - peerDependencies: - '@valibot/to-json-schema': ^1.0.0 - arktype: ^2.1.20 - effect: ^3.16.0 - sury: ^10.0.0 + sury: ^10.0.0 || ^11.0.0-alpha zod: ^3.25.0 || ^4.0.0 zod-to-json-schema: ^3.25.0 peerDependenciesMeta: @@ -24734,6 +24732,10 @@ snapshots: dependencies: '@xsai/shared': 0.4.4 + '@xsai-ext/providers@0.5.0-beta.2': + dependencies: + '@xsai/shared': 0.5.0-beta.2 + '@xsai-ext/shared-providers@0.4.0-beta.12': dependencies: '@xsai/shared': 0.4.4 @@ -24811,49 +24813,59 @@ snapshots: dependencies: '@xsai/shared': 0.4.4 - '@xsai/generate-speech@0.4.0-beta.13': + '@xsai/embed@0.5.0-beta.2': dependencies: - '@xsai/shared': 0.4.4 + '@xsai/shared': 0.5.0-beta.2 - '@xsai/generate-text@0.4.4': + '@xsai/generate-speech@0.5.0-beta.2': dependencies: - '@xsai/shared': 0.4.4 - '@xsai/shared-chat': 0.4.4 + '@xsai/shared': 0.5.0-beta.2 + + '@xsai/generate-text@0.5.0-beta.2(patch_hash=306bfb723913596b334140f0d6fa48063f336e3b44024efc1d72bf60d54b15e6)': + dependencies: + '@xsai/shared': 0.5.0-beta.2 + '@xsai/shared-chat': 0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01) '@xsai/generate-transcription@0.4.4': dependencies: '@xsai/shared': 0.4.4 - '@xsai/model@0.4.4': + '@xsai/generate-transcription@0.5.0-beta.2': dependencies: - '@xsai/shared': 0.4.4 + '@xsai/shared': 0.5.0-beta.2 - '@xsai/shared-chat@0.4.0-beta.13': + '@xsai/model@0.5.0-beta.2': dependencies: - '@xsai/shared': 0.4.4 + '@xsai/shared': 0.5.0-beta.2 - '@xsai/shared-chat@0.4.4': + '@xsai/shared-chat@0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01)': dependencies: - '@xsai/shared': 0.4.4 + '@xsai/shared': 0.5.0-beta.2 - '@xsai/shared@0.4.0-beta.13': {} + '@xsai/shared-stream@0.5.0-beta.2': + dependencies: + '@xsai/shared': 0.5.0-beta.2 '@xsai/shared@0.4.4': {} - '@xsai/stream-text@0.4.4': - dependencies: - '@xsai/shared': 0.4.4 - '@xsai/shared-chat': 0.4.4 + '@xsai/shared@0.5.0-beta.2': {} - '@xsai/stream-transcription@0.4.0-beta.8': + '@xsai/stream-text@0.5.0-beta.2(patch_hash=90dfe10d02f5946658508ec019937eab600745c93446ce7b2fdb1a0ed70e3e49)': dependencies: - '@xsai/shared': 0.4.4 + '@xsai/shared': 0.5.0-beta.2 + '@xsai/shared-chat': 0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01) + '@xsai/shared-stream': 0.5.0-beta.2 - '@xsai/tool@0.4.4(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6)': + '@xsai/stream-transcription@0.5.0-beta.2': dependencies: - '@xsai/shared': 0.4.4 - '@xsai/shared-chat': 0.4.4 - xsschema: 0.4.4(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) + '@xsai/shared': 0.5.0-beta.2 + '@xsai/shared-stream': 0.5.0-beta.2 + + '@xsai/tool@0.5.0-beta.2(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6)': + dependencies: + '@xsai/shared': 0.5.0-beta.2 + '@xsai/shared-chat': 0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01) + xsschema: 0.5.0-beta.2(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6) transitivePeerDependencies: - '@valibot/to-json-schema' - arktype @@ -24862,9 +24874,9 @@ snapshots: - zod - zod-to-json-schema - '@xsai/utils-chat@0.4.0-beta.13': + '@xsai/utils-chat@0.5.0-beta.2': dependencies: - '@xsai/shared-chat': 0.4.4 + '@xsai/shared-chat': 0.5.0-beta.2(patch_hash=26f2819b987245ec85f216b821ddf73aeb28fd7e611238a2d37250e42f838a01) abbrev@3.0.1: {} @@ -33493,17 +33505,12 @@ snapshots: xmlhttprequest-ssl@2.1.2: {} - xsschema@0.4.0-beta.13(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6): + xsschema@0.5.0-beta.2(@valibot/to-json-schema@1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)))(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6): optionalDependencies: '@valibot/to-json-schema': 1.0.0-rc.0(valibot@1.3.1(typescript@5.9.3)) zod: 4.3.6 zod-to-json-schema: 3.25.1(zod@4.3.6) - xsschema@0.4.4(zod-to-json-schema@3.25.1(zod@4.3.6))(zod@4.3.6): - optionalDependencies: - zod: 4.3.6 - zod-to-json-schema: 3.25.1(zod@4.3.6) - xstate@5.28.0: {} xtend@4.0.2: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 285fbe0cc..e5d586efe 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -21,6 +21,9 @@ overrides: string.prototype.matchall: npm:@nolyfill/string.prototype.matchall@^1.0.44 patchedDependencies: '@mediapipe/tasks-vision': patches/@mediapipe__tasks-vision.patch + '@xsai/generate-text@0.5.0-beta.2': patches/@xsai__generate-text@0.5.0-beta.2.patch + '@xsai/shared-chat@0.5.0-beta.2': patches/@xsai__shared-chat@0.5.0-beta.2.patch + '@xsai/stream-text@0.5.0-beta.2': patches/@xsai__stream-text@0.5.0-beta.2.patch crossws@0.4.4: patches/crossws@0.4.4.patch mineflayer-pathfinder: patches/mineflayer-pathfinder.patch mineflayer@4.33.0: patches/mineflayer@4.33.0.patch @@ -67,17 +70,18 @@ catalog: '@types/unist': ^3.0.3 '@types/ws': ^8.18.1 '@vueuse/core': 14.1.0 - '@xsai-ext/providers': ^0.4.4 - '@xsai/embed': ^0.4.4 - '@xsai/generate-speech': 0.4.0-beta.13 - '@xsai/generate-text': ^0.4.4 - '@xsai/generate-transcription': ^0.4.4 - '@xsai/model': ^0.4.4 - '@xsai/shared': 0.4.0-beta.13 - '@xsai/shared-chat': 0.4.0-beta.13 - '@xsai/stream-text': ^0.4.4 - '@xsai/tool': ^0.4.4 - '@xsai/utils-chat': 0.4.0-beta.13 + '@xsai-ext/providers': 0.5.0-beta.2 + '@xsai/embed': 0.5.0-beta.2 + '@xsai/generate-speech': 0.5.0-beta.2 + '@xsai/generate-text': 0.5.0-beta.2 + '@xsai/generate-transcription': 0.5.0-beta.2 + '@xsai/model': 0.5.0-beta.2 + '@xsai/shared': 0.5.0-beta.2 + '@xsai/shared-chat': 0.5.0-beta.2 + '@xsai/stream-text': 0.5.0-beta.2 + '@xsai/stream-transcription': 0.5.0-beta.2 + '@xsai/tool': 0.5.0-beta.2 + '@xsai/utils-chat': 0.5.0-beta.2 alien-signals: ^3.1.2 async-mutex: 0.5.0 better-auth: ^1.5.6 @@ -128,7 +132,7 @@ catalog: vue-sonner: 2.0.9 web-haptics: ^0.0.6 ws: ^8.20.0 - xsschema: 0.4.0-beta.13 + xsschema: 0.5.0-beta.2 yaml: ^2.8.3 zod: ^4.3.6 catalogs: