diff --git a/.env b/.env index 768c8af..53cbd72 100644 --- a/.env +++ b/.env @@ -1,2 +1,3 @@ -VITE_OPENAI_API_KEY='' -VITE_OPENAI_API_BASEURL='' +OPENAI_API_BASEURL='' +OPENAI_API_KEY='' +SERPAPI_API_KEY='' diff --git a/cspell.config.yaml b/cspell.config.yaml index 3505ccc..00b8019 100644 --- a/cspell.config.yaml +++ b/cspell.config.yaml @@ -5,6 +5,7 @@ dictionaries: [] words: - antfu - bumpp + - Cmpl - defu - execa - guiiai diff --git a/docs/package.json b/docs/package.json index 1b8d945..958647c 100644 --- a/docs/package.json +++ b/docs/package.json @@ -12,11 +12,11 @@ "docs:preview": "vitepress preview" }, "devDependencies": { - "@unocss/eslint-config": "^0.65.0", - "@unocss/eslint-plugin": "^0.65.0", - "unocss": "^0.65.0", - "vite": "^6.0.2", - "vite-plugin-inspect": "^0.10.0", + "@unocss/eslint-config": "^0.65.1", + "@unocss/eslint-plugin": "^0.65.1", + "unocss": "^0.65.1", + "vite": "^6.0.3", + "vite-plugin-inspect": "^0.10.3", "vitepress": "^1.5.0", "vue": "^3.5.13" } diff --git a/examples/neuri/documentations-from-unit-tests/package.json b/examples/neuri/documentations-from-unit-tests/package.json index 6ee9f89..c31ead8 100644 --- a/examples/neuri/documentations-from-unit-tests/package.json +++ b/examples/neuri/documentations-from-unit-tests/package.json @@ -3,7 +3,7 @@ "type": "module", "version": "0.0.15", "private": true, - "packageManager": "pnpm@9.14.4", + "packageManager": "pnpm@9.15.0", "description": "", "author": "", "license": "ISC", @@ -14,7 +14,7 @@ }, "dependencies": { "neuri": "workspace:^", - "openai": "^4.74.0" + "openai": "^4.77.0" }, "devDependencies": { "tsx": "^4.19.2" diff --git a/examples/neuri/weather-query/package.json b/examples/neuri/weather-query/package.json index f59d77c..bf6f1db 100644 --- a/examples/neuri/weather-query/package.json +++ b/examples/neuri/weather-query/package.json @@ -3,7 +3,7 @@ "type": "module", "version": "0.0.15", "private": true, - "packageManager": "pnpm@9.14.4", + "packageManager": "pnpm@9.15.0", "description": "", "author": "", "license": "ISC", @@ -18,9 +18,9 @@ "@typeschema/valibot": "^0.14.0", "@typeschema/zod": "^0.14.0", "neuri": "workspace:^", - "openai": "^4.74.0", - "valibot": "^0.42.1", - "zod": "^3.23.8" + "openai": "^4.77.0", + "valibot": "^1.0.0-beta.9", + "zod": "^3.24.1" }, "devDependencies": { "tsx": "^4.19.2" diff --git a/examples/neuri/weather-query/src/valibot.ts b/examples/neuri/weather-query/src/valibot.ts index 31dfd7b..32305e3 100644 --- a/examples/neuri/weather-query/src/valibot.ts +++ b/examples/neuri/weather-query/src/valibot.ts @@ -3,7 +3,7 @@ import { composeAgent, defineToolFunction, - resolveFirstTextMessageFromCompletion, + resolveFirstTextContentFromChatCmpl, system, toolFunction, user, @@ -82,7 +82,7 @@ async function main() { model: 'openai/gpt-3.5-turbo', }) - return resolveFirstTextMessageFromCompletion(res) + return resolveFirstTextContentFromChatCmpl(res) } // eslint-disable-next-line no-console diff --git a/examples/neuri/weather-query/src/zod.ts b/examples/neuri/weather-query/src/zod.ts index eaafdc5..e0608a8 100644 --- a/examples/neuri/weather-query/src/zod.ts +++ b/examples/neuri/weather-query/src/zod.ts @@ -3,7 +3,7 @@ import { env } from 'node:process' import { composeAgent, defineToolFunction, - resolveFirstTextMessageFromCompletion, + resolveFirstTextContentFromChatCmpl, system, toolFunction, user, @@ -82,7 +82,7 @@ async function main() { model: 'openai/gpt-3.5-turbo', }) - return resolveFirstTextMessageFromCompletion(res) + return resolveFirstTextContentFromChatCmpl(res) } // eslint-disable-next-line no-console diff --git a/package.json b/package.json index 0b9e86e..f2b2792 100644 --- a/package.json +++ b/package.json @@ -39,15 +39,15 @@ "typecheck": "tsc --noEmit" }, "devDependencies": { - "@antfu/eslint-config": "^3.11.2", + "@antfu/eslint-config": "^3.12.0", "@antfu/ni": "^0.23.1", - "@types/node": "^22.10.1", + "@types/node": "^22.10.2", "@vitest/coverage-v8": "2.1.8", - "bumpp": "^9.8.1", - "eslint": "^9.16.0", + "bumpp": "^9.9.1", + "eslint": "^9.17.0", "typescript": "^5.7.2", - "unbuild": "^3.0.0-rc.11", - "vite": "^6.0.2", + "unbuild": "3.0.0-rc.11", + "vite": "^6.0.3", "vitest": "^2.1.8" }, "workspaces": [ diff --git a/packages/format-code/package.json b/packages/format-code/package.json index c2429e4..d18d06e 100644 --- a/packages/format-code/package.json +++ b/packages/format-code/package.json @@ -48,13 +48,13 @@ }, "dependencies": { "@guiiai/logg": "^1.0.6", - "@shikijs/core": "^1.24.0", - "@shikijs/engine-oniguruma": "^1.24.0", - "@shikijs/vscode-textmate": "^9.3.0", - "shiki": "^1.24.0", - "tm-grammars": "^1.21.0" + "@shikijs/core": "^1.24.2", + "@shikijs/engine-oniguruma": "^1.24.2", + "@shikijs/vscode-textmate": "^9.3.1", + "shiki": "^1.24.2", + "tm-grammars": "^1.21.7" }, "devDependencies": { - "@types/node": "^22.10.1" + "@types/node": "^22.10.2" } } diff --git a/packages/neuri/package.json b/packages/neuri/package.json index 1c25e04..68bf69c 100644 --- a/packages/neuri/package.json +++ b/packages/neuri/package.json @@ -28,8 +28,8 @@ "import": "./dist/index.mjs" }, "./openai": { - "types": "./dist/openai.d.ts", - "import": "./dist/openai.mjs" + "types": "./dist/openai/index.d.ts", + "import": "./dist/openai/index.mjs" }, "./test": { "types": "./dist/test.d.ts", @@ -54,18 +54,23 @@ "@guiiai/logg": "^1.0.6", "@typeschema/main": "^0.14.1", "@xsai/generate-text": "^0.0.22", + "@xsai/providers": "^0.0.22", + "@xsai/shared-chat": "^0.0.22", + "@xsai/stream-text": "^0.0.22", "@xsai/tool": "^0.0.22", "defu": "^6.1.4", "nanoid": "^5.0.9", - "openai": "^4.74.0" + "openai": "^4.77.0" }, "devDependencies": { + "@gcornut/valibot-json-schema": "^0.42.0", "@types/mdast": "^4.0.4", - "@types/node": "^22.10.1", + "@types/node": "^22.10.2", "@typeschema/zod": "^0.14.0", "json-schema": "^0.4.0", "remark": "^15.0.1", - "zod": "^3.23.8", - "zod-to-json-schema": "^3.23.5" + "valibot": "^1.0.0-beta.9", + "zod": "^3.24.1", + "zod-to-json-schema": "^3.24.1" } } diff --git a/packages/neuri/src/index.test.ts b/packages/neuri/src/index.test.ts index a9d77e8..fa1273e 100644 --- a/packages/neuri/src/index.test.ts +++ b/packages/neuri/src/index.test.ts @@ -1,4 +1,3 @@ -import OpenAI from 'openai' import { describe, expect, it } from 'vitest' import { object, string } from 'zod' @@ -22,10 +21,10 @@ describe('neuri', async () => { .build(), ) .build({ - openAI: new OpenAI({ - apiKey: process.env.OPENAI_API_KEY, - baseURL: process.env.OPENAI_API_BASEURL, - }), + provider: { + apiKey: process.env.OPENAI_API_KEY!, + baseURL: process.env.OPENAI_API_BASEURL!, + }, }) const name = await n.handle(messages( diff --git a/packages/neuri/src/index.ts b/packages/neuri/src/index.ts index 3e186cd..48c3905 100644 --- a/packages/neuri/src/index.ts +++ b/packages/neuri/src/index.ts @@ -1,7 +1,8 @@ import type { Infer, Schema } from '@typeschema/main' -import type OpenAI from 'openai' +import type { CommonProviderOptions } from '@xsai/providers' +import type { Message } from '@xsai/shared-chat' -import type { ChatCompletion, InvokeContext, Tool, ToolHooks } from './openai' +import type { ChatCompletion, DefinedTool, DefinedToolHooks, InvokeContext } from './openai' import { composeAgent, defineToolFunction, toolFunction } from './openai' export interface CallOptions { @@ -9,15 +10,15 @@ export interface CallOptions { } export interface NeuriContext { - message: OpenAI.ChatCompletionMessageParam | OpenAI.ChatCompletionMessageParam[] - messages: OpenAI.ChatCompletionMessageParam[] - reroute: (name: string, messages: OpenAI.ChatCompletionMessageParam[], options: CallOptions) => Promise + message: Message | Message[] + messages: Message[] + reroute: (name: string, messages: Message[], options: CallOptions) => Promise } interface NeuriContextOptions { - openAI: OpenAI - message: OpenAI.ChatCompletionMessageParam | OpenAI.ChatCompletionMessageParam[] - messages?: OpenAI.ChatCompletionMessageParam[] + provider: CommonProviderOptions + message: Message | Message[] + messages?: Message[] agents?: Agent[] } @@ -38,29 +39,29 @@ function newContext(options: NeuriContextOptions): NeuriContext { throw new Error(`Agent "${name}" not found`) } - const { call } = composeAgent({ openAI: options.openAI, tools: agent.tools }) + const { call } = composeAgent({ provider: options.provider, tools: agent.tools }) return await call(messages, { model: rerouteOpts.model }) }, } } export interface Neuri { - handle: (message: OpenAI.ChatCompletionMessageParam | OpenAI.ChatCompletionMessageParam[], handler: (ctx: NeuriContext) => Promise) => Promise + handle: (message: Message | Message[], handler: (ctx: NeuriContext) => Promise) => Promise } interface NeuriInternal extends Neuri { agents: Agent[] - messages: OpenAI.ChatCompletionMessageParam[] + messages: Message[] } export interface Agent { name: string - tools: Tool[] + tools: DefinedTool[] } export interface NeuriBuilder { agent: (agent: Agent | Promise) => NeuriBuilder - build: (options: { openAI: OpenAI }) => Promise + build: (options: { provider: CommonProviderOptions }) => Promise } export interface NeuriBuilderInternal extends Partial { @@ -69,7 +70,7 @@ export interface NeuriBuilderInternal extends Partial { } export type ToolFunc = (ctx: InvokeContext) => R -export interface ToolOption { openAI?: OpenAI, hooks?: Partial>, description?: string } +export interface ToolOption { provider?: CommonProviderOptions, hooks?: Partial>, description?: string } export interface AgentBuilder { tool: (name: string, parameters: S, handle: ToolFunc, R>, options?: ToolOption, R>) => AgentBuilder @@ -78,8 +79,8 @@ export interface AgentBuilder { interface AgentBuilderInternal extends Partial { name: string - tools: Tool[] - promiseTools: Promise>[] + tools: DefinedTool[] + promiseTools: Promise>[] } function newNeuriBuilderAgent(cb: () => NeuriBuilderInternal): (agent: Agent | Promise) => NeuriBuilder { @@ -97,7 +98,7 @@ function newNeuriBuilderAgent(cb: () => NeuriBuilderInternal): (agent: Agent | P } } -function newNeuriBuilderBuild(cb: () => NeuriBuilderInternal): (options: { openAI: OpenAI }) => Promise { +function newNeuriBuilderBuild(cb: () => NeuriBuilderInternal): (options: { provider: CommonProviderOptions }) => Promise { return async (options): Promise => { const neuriBuilder = cb() @@ -122,7 +123,7 @@ function newNeuriBuilderBuild(cb: () => NeuriBuilderInternal): (options: { openA message, messages: neuriInternal.messages, agents: neuriInternal.agents, - openAI: options.openAI, + provider: options.provider, })) }, } diff --git a/packages/neuri/src/openai.ts b/packages/neuri/src/openai.ts deleted file mode 100644 index 32a985d..0000000 --- a/packages/neuri/src/openai.ts +++ /dev/null @@ -1,506 +0,0 @@ -import type { Infer, Schema } from '@typeschema/main' - -import type OpenAI from 'openai' -import { toJSONSchema } from '@typeschema/main' - -/** - * Generate the completion response from LLM API. - * - * @param params - The parameters to generate the completion response. - * @param params.options - The options to create the completion. - * @param params.openAI - The OpenAI instance. - * @returns The completion response. - */ -export async function generate(params: { options: OpenAI.Chat.Completions.ChatCompletionCreateParamsNonStreaming, openAI: OpenAI }) { - const res = await params.openAI.chat.completions.create(params.options) - return chatCompletionFromOpenAIChatCompletion(res) -} - -/** - * Generate the completion response from LLM API. - */ -export interface StreamChunk { - raw: () => Uint8Array - textPart: () => string - chunk: () => OpenAI.Chat.ChatCompletionChunk -} - -function parseChunkFromBuffer(value: Uint8Array) { - const str = new TextDecoder().decode(value) - return JSON.parse(str) as unknown as OpenAI.Chat.ChatCompletionChunk -} - -function newStreamChunk(raw: Uint8Array, resChunk: OpenAI.Chat.ChatCompletionChunk): StreamChunk { - return { - raw: () => raw, - chunk: () => resChunk, - textPart: () => resChunk.choices?.[0]?.delta.content ?? '', - } satisfies StreamChunk -} - -export interface StreamResponse { - /** - * Get the completion response. - * - * @returns The completion response. - */ - response: () => Promise - /** - * Get the entire completion response as a text. - * - * @returns The entire completion response as a text. - */ - text: () => Promise - /** - * - * Get the completion response as a stream of text. - * - * @returns The completion response as a stream of text. - */ - textStream: () => AsyncGenerator - /** - * Get the completion response as a stream of chunks. - * - * @returns The completion response as a stream of chunks. - */ - chunkStream: () => AsyncGenerator - /** - * Get the completion response as a stream of chunks. - * - * @returns The completion response as a stream of chunks. - */ - chunks: () => Promise - /** - * Convert the completion response to a iterable readable stream. - * - * This function is 100% sure to be ok to use even if your browser or environments didn't implemented the `Symbol.asyncIterator` feature. - * - * @param options - * @returns - */ - toReadableStream: () => AsyncGenerator -} - -interface PipeHook { - onValue?: (value: F) => void - onChunk?: (chunk: T) => void - onDone?: () => void -} - -async function* asyncIteratorFromReadableStream(res: ReadableStream, func: (value: F) => Promise, hooks?: PipeHook[]): AsyncGenerator { - // reactjs - TS2504: Type 'ReadableStream' must have a '[Symbol.asyncIterator]()' method that returns an async iterator - Stack Overflow - // https://stackoverflow.com/questions/76700924/ts2504-type-readablestreamuint8array-must-have-a-symbol-asynciterator - const reader = res.getReader() - try { - while (true) { - const { done, value } = await reader.read() - if (done) { - hooks?.forEach(i => i.onDone?.()) - return - } - - const chunk = await func(value) - hooks?.forEach(i => i.onChunk?.(chunk)) - yield chunk - } - } - finally { - reader.releaseLock() - } -} - -/** - * Stream the completion response from LLM API. - * - * @param params - The parameters to stream the completion response. - * @param params.options - The options to create the completion. - * @param params.openAI - The OpenAI instance. - * @returns The completion response stream. - */ -export async function stream(params: { - options: Omit - openAI: OpenAI -}): Promise { - const res = await params.openAI.chat.completions.create({ ...params.options, stream: true, stream_options: { include_usage: true } }) - - const [fullStream, rawStream] = res.tee() - const [textStream, chunkStream] = fullStream.tee() - - const textStreamHooks: PipeHook[] = [] - const accumulatedText = new Promise((resolve) => { - const chunks: string[] = [] - textStreamHooks.push({ - onChunk: (chunk) => { chunks.push(chunk) }, - onDone: () => { resolve(chunks.join('')) }, - }) - }) - - const chunkStreamHooks: PipeHook[] = [] - const accumulatedChunks = new Promise((resolve) => { - const chunks: StreamChunk[] = [] - chunkStreamHooks.push({ - onChunk: (chunk) => { chunks.push(chunk) }, - onDone: () => { resolve(chunks) }, - }) - }) - - return { - response: async () => res, - text: () => accumulatedText, - chunks: () => accumulatedChunks, - textStream: () => asyncIteratorFromReadableStream( - textStream.toReadableStream(), - async (value: Uint8Array) => newStreamChunk(value, parseChunkFromBuffer(value)).textPart(), - textStreamHooks, - ), - chunkStream: () => asyncIteratorFromReadableStream( - chunkStream.toReadableStream(), - async (value: Uint8Array) => newStreamChunk(value, parseChunkFromBuffer(value)), - chunkStreamHooks, - ), - toReadableStream: () => rawStream.toReadableStream() as unknown as AsyncGenerator, - } satisfies StreamResponse -} - -export function system(message: string): OpenAI.ChatCompletionSystemMessageParam { - return { role: 'system', content: message } -} - -export type Parts = PartText | PartImage - -export interface PartImage { - image_url: ImageURL - - /** - * The type of the content part. - */ - type: 'image_url' -} - -export interface ImageURL { - /** - * Either a URL of the image or the base64 encoded image data. - */ - url: string - - /** - * Specifies the detail level of the image. Learn more in the - * [Vision guide](https://platform.openai.com/docs/guides/vision/low-or-high-fidelity-image-understanding). - */ - detail?: 'auto' | 'low' | 'high' -} - -export interface PartText { - /** - * The text content. - */ - text: string - - /** - * The type of the content part. - */ - type: 'text' -} - -export function user(message: string): { role: 'user', content: string, name?: string } -export function user(message: Parts[]): { role: 'user', content: Parts[], name?: string } -export function user(message: string | Parts[]): OpenAI.ChatCompletionUserMessageParam { - if (typeof message === 'string') - return { role: 'user', content: message } - if (Array.isArray(message)) - return { role: 'user', content: message } - - return { role: 'user', content: message } -} - -export function textPart(content: string): PartText { - return { type: 'text', text: content } -} - -export function imagePart(imageUrl: string): PartImage { - return { type: 'image_url', image_url: { url: imageUrl } } -} - -export function assistant(toolCall: OpenAI.Chat.ChatCompletionMessageToolCall | undefined): { role: 'assistant', tool_calls: OpenAI.Chat.ChatCompletionMessageToolCall[], name?: string } -export function assistant(message: string): { role: 'assistant', content: string, name?: string } -export function assistant(body: string | OpenAI.Chat.ChatCompletionMessageToolCall | undefined): OpenAI.ChatCompletionAssistantMessageParam { - if (body == null) - return { role: 'assistant', content: '' } - if (typeof body === 'string') - return { role: 'assistant', content: body } - - return { role: 'assistant', tool_calls: [body] } -} - -export function tool

(message: string, toolCall: ResolvedToolCall): OpenAI.ChatCompletionToolMessageParam { - return { - role: 'tool', - content: message, - tool_call_id: toolCall.toolCall.id, - } -} - -export function messages(...messages: OpenAI.ChatCompletionMessageParam[]): OpenAI.ChatCompletionMessageParam[] { - return messages -} - -export interface ChatCompletion extends OpenAI.Chat.Completions.ChatCompletion { - firstContent: () => Promise - firstChoice: () => OpenAI.ChatCompletion.Choice | undefined -} - -export function chatCompletionFromOpenAIChatCompletion(completions: OpenAI.Chat.Completions.ChatCompletion): ChatCompletion { - return { - ...completions, - firstContent: async () => { - const message = resolveFirstTextMessageFromCompletion(completions) - return message - }, - firstChoice: () => { - if (completions.choices.length === 0) - return undefined - - return completions.choices[0] - }, - } -} - -export function resolveFirstTextMessageFromCompletion(chatCompletion?: OpenAI.Chat.Completions.ChatCompletion): string { - if (!chatCompletion) - return '' - if (chatCompletion.choices.length === 0) - return '' - - const message = chatCompletion.choices[0].message - return message.content ?? '' -} - -export function resolveToolCallsFromCompletion(chatCompletion?: OpenAI.Chat.Completions.ChatCompletion): OpenAI.Chat.ChatCompletionMessageToolCall[][] { - if (!chatCompletion) - return [] - if (!('choices' in chatCompletion)) - return [] - if (chatCompletion.choices.length === 0) - return [] - - return chatCompletion.choices.filter(choice => choice.message.tool_calls != null).map(choice => choice.message.tool_calls!) -} - -export function resolveFirstToolCallFromCompletion(chatCompletion?: OpenAI.Chat.Completions.ChatCompletion): OpenAI.Chat.ChatCompletionMessageToolCall | undefined { - const choices = resolveToolCallsFromCompletion(chatCompletion) - if (choices.length === 0) - return undefined - - return choices[0][0] -} - -export function resolvedToolCall

(toolCall: OpenAI.Chat.ChatCompletionMessageToolCall | null | undefined, tools: Tool[]): ResolvedToolCall | undefined { - if (toolCall == null) - return undefined - if (toolCall.function == null) - return undefined - - const foundTool = tools.find(tool => toolCall.function.name === tool.tool.function.name) - if (foundTool == null) - return undefined - - return { - tool: { - function: toolCall.function, - type: 'function', - }, - toolCall, - arguments: JSON.parse(toolCall.function.arguments), - openAI: foundTool.openAI, - func: foundTool.func, - hooks: foundTool.hooks, - } -} - -export async function invokeFunctionWithResolvedToolCall

(completions: ChatCompletion, toolCall: ResolvedToolCall | undefined, messages?: OpenAI.ChatCompletionMessageParam[]): Promise { - if (toolCall == null) - return undefined - if (toolCall.toolCall == null) - return undefined - if (toolCall.toolCall.function == null) - return undefined - - const ctx: InvokeContext = { - messages: messages ?? [], - chatCompletion: completions, - parameters: toolCall.arguments, - toolCall, - } - - await toolCall.hooks.preInvoke(ctx) - const res = await toolCall.func(ctx) - await toolCall.hooks.postInvoke({ ...ctx, result: res }) - - return res -} - -export interface ToolCallFunctionResult

{ - result: R | undefined - chatCompletionToolCall?: OpenAI.Chat.Completions.ChatCompletionMessageToolCall - resolvedToolCall: ResolvedToolCall | undefined -} - -export async function invokeFunctionWithTools(chatCompletion: ChatCompletion, tools: Tool[], messages: OpenAI.ChatCompletionMessageParam[]): Promise>> { - const results: Array> = [] - - for (const choice of chatCompletion.choices) { - if (!choice.message.tool_calls) { - continue - } - - for (const toolCall of choice.message.tool_calls) { - const tc = resolvedToolCall(toolCall, tools) - - results.push({ - result: await invokeFunctionWithResolvedToolCall(chatCompletion, tc, messages), - chatCompletionToolCall: toolCall, - resolvedToolCall: tc, - }) - } - } - - return results -} - -type JSONSchema = Awaited> & Record - -// @ts-expect-error - P is helper, R is helper -// eslint-disable-next-line unused-imports/no-unused-vars -interface ToolFunction

extends OpenAI.Chat.ChatCompletionTool { - type: 'function' - function: { - name: string - description?: string - parameters: JSONSchema - } -} - -export async function toolFunction>(name: string, description: string, parameters: S): Promise> { - return { - type: 'function', - function: { - name, - description, - parameters: await toJSONSchema(parameters as any), - }, - } -} - -export interface Tool { - openAI?: OpenAI - tool: OpenAI.Chat.ChatCompletionTool - func: (ctx: InvokeContext) => R - hooks: ToolHooks -} - -export interface ToolHooks { - configureOpenAI: (openAI: OpenAI) => Promise - preInvoke: (ctx: PreInvokeContext) => Promise - postInvoke: (ctx: PostInvokeContext) => Promise -} - -export interface InvokeContext { - messages: OpenAI.ChatCompletionMessageParam[] - chatCompletion: ChatCompletion - parameters: P - toolCall: ResolvedToolCall -} - -export interface PreInvokeContext extends InvokeContext { - -} - -export interface PostInvokeContext extends InvokeContext { - result: R -} - -export interface ResolvedToolCall extends Tool { - arguments: P - toolCall: OpenAI.Chat.ChatCompletionMessageToolCall - hooks: ToolHooks -} - -export function defineToolFunction) => R, P = Parameters, R = ReturnType>( - tool: ToolFunction

, - func: F, - options?: { - openAI?: OpenAI - hooks?: Partial> - }, -): Tool { - const hooks: ToolHooks = { - configureOpenAI: async o => o, - preInvoke: async () => {}, - postInvoke: async () => {}, - } - - if (options?.hooks?.configureOpenAI != null) - hooks.configureOpenAI = options.hooks.configureOpenAI - if (options?.hooks?.preInvoke != null) - hooks.preInvoke = options?.hooks?.preInvoke - if (options?.hooks?.postInvoke != null) - hooks.postInvoke = options?.hooks?.postInvoke - - return { - openAI: options?.openAI, - tool, - func, - hooks, - } -} - -export function tools(tools: Tool[]): OpenAI.Chat.ChatCompletionTool[] { - return tools.map(tool => tool.tool) -} - -export function composeAgent(options: { - openAI: OpenAI - tools: Tool[] -}) { - async function call(messages: OpenAI.ChatCompletionMessageParam[], callOptions: { model: string, maxRoundTrip?: number }): Promise { - let max = callOptions.maxRoundTrip ?? 10 - while (max >= 0) { - max-- - - const res = await generate({ - openAI: options.openAI, - options: { - model: callOptions.model, - messages, - tools: tools(options.tools), - }, - }) - - const chatCompletionToolCall = resolveFirstToolCallFromCompletion(res) - messages.push(assistant(chatCompletionToolCall)) - - const chatCompletion = chatCompletionFromOpenAIChatCompletion(res) - const invokeResults = await invokeFunctionWithTools(chatCompletion, options.tools, messages) - if (!invokeResults.length) - return chatCompletion - - for (const invokeResult of invokeResults) { - const { result, resolvedToolCall: toolCall } = invokeResult - if (!toolCall) - continue - - let strRes = '' - if (typeof result === 'string') - strRes = result - else - strRes = JSON.stringify(result) - - messages.push(tool(strRes, toolCall)) - } - } - } - - return { - call, - } -} diff --git a/packages/neuri/src/openai/agent.ts b/packages/neuri/src/openai/agent.ts new file mode 100644 index 0000000..eddcb25 --- /dev/null +++ b/packages/neuri/src/openai/agent.ts @@ -0,0 +1,59 @@ +import type { CommonProviderOptions } from '@xsai/providers' +import type { Message } from '@xsai/shared-chat' + +import type { ChatCompletion, DefinedTool } from './types' +import { chatCompletionFromResp, resolveFirstToolCallFromCmpl } from './completion' +import { generate } from './generate' +import { invokeFunctionWithTools } from './invoke' +import { assistant, tool } from './messages' +import { tools } from './tools' + +export function composeAgent(options: { + provider: CommonProviderOptions + tools: DefinedTool[] +}) { + async function call(messages: Message[], callOptions: { model: string, maxRoundTrip?: number }): Promise { + let max = callOptions.maxRoundTrip ?? 10 + while (max >= 0) { + max-- + + const res = await generate({ + apiKey: options.provider.apiKey, + baseURL: options.provider.baseURL, + model: callOptions.model, + messages, + tools: tools(options.tools), + }) + + const resChatCompletionToolCall = resolveFirstToolCallFromCmpl(res) + if (!resChatCompletionToolCall) { + return res + } + + messages.push(assistant(resChatCompletionToolCall)) + + const resChatCompletion = chatCompletionFromResp(res) + const invokeResults = await invokeFunctionWithTools(resChatCompletion, options.tools, messages) + if (!invokeResults.length) + return resChatCompletion + + for (const invokeResult of invokeResults) { + const { result, resolvedToolCall: toolCall } = invokeResult + if (!toolCall) + continue + + let strRes = '' + if (typeof result === 'string') + strRes = result + else + strRes = JSON.stringify(result) + + messages.push(tool(strRes, toolCall)) + } + } + } + + return { + call, + } +} diff --git a/packages/neuri/src/openai/completion.ts b/packages/neuri/src/openai/completion.ts new file mode 100644 index 0000000..81fd82b --- /dev/null +++ b/packages/neuri/src/openai/completion.ts @@ -0,0 +1,47 @@ +import type { ToolCall } from '@xsai/shared-chat' +import type { ChatCompletion, ChatCompletionsResponse } from './types' + +export function chatCompletionFromResp(completions: ChatCompletionsResponse): ChatCompletion { + return { + ...completions, + firstContent: async () => { + const message = resolveFirstTextContentFromChatCmpl(completions) + return message + }, + firstChoice: () => { + if (completions.choices.length === 0) + return undefined + + return completions.choices[0] + }, + } +} + +export function resolveFirstTextContentFromChatCmpl(chatCompletion?: ChatCompletionsResponse): string { + if (!chatCompletion) + return '' + if (chatCompletion.choices.length === 0) + return '' + + const message = chatCompletion.choices[0].message + return message.content ?? '' +} + +export function resolveToolCallsFromCmpl(chatCompletion?: ChatCompletionsResponse): ToolCall[][] { + if (!chatCompletion) + return [] + if (!('choices' in chatCompletion)) + return [] + if (chatCompletion.choices.length === 0) + return [] + + return chatCompletion.choices.filter(choice => choice.message.tool_calls != null).map(choice => choice.message.tool_calls!) +} + +export function resolveFirstToolCallFromCmpl(chatCompletion?: ChatCompletionsResponse): ToolCall | undefined { + const choices = resolveToolCallsFromCmpl(chatCompletion) + if (choices.length === 0) + return undefined + + return choices[0][0] +} diff --git a/packages/neuri/src/openai/generate.ts b/packages/neuri/src/openai/generate.ts new file mode 100644 index 0000000..b4d5e64 --- /dev/null +++ b/packages/neuri/src/openai/generate.ts @@ -0,0 +1,16 @@ +import type { GenerateTextOptions } from '@xsai/generate-text' +import type { ChatCompletionsResponse } from './types' + +import { chatCompletion } from '@xsai/shared-chat' +import { chatCompletionFromResp as chatCmplFromResp } from './completion' + +/** + * Generate text + * + * @param params - The parameters to generate text. + * @returns ChatCompletion + */ +export async function generate(params: GenerateTextOptions) { + const reqRes = await chatCompletion(params) + return chatCmplFromResp(await reqRes.json() as ChatCompletionsResponse) +} diff --git a/packages/neuri/src/openai/index.ts b/packages/neuri/src/openai/index.ts new file mode 100644 index 0000000..074c953 --- /dev/null +++ b/packages/neuri/src/openai/index.ts @@ -0,0 +1,7 @@ +export * from './agent' +export * from './completion' +export * from './invoke' +export * from './messages' +export * from './stream' +export * from './tools' +export * from './types' diff --git a/packages/neuri/src/openai/invoke.ts b/packages/neuri/src/openai/invoke.ts new file mode 100644 index 0000000..0269ba0 --- /dev/null +++ b/packages/neuri/src/openai/invoke.ts @@ -0,0 +1,66 @@ +import type { Message, ToolCall } from '@xsai/shared-chat' +import type { ChatCompletion, DefinedTool, InvokeContext, ResolvedToolCall, ToolCallFunctionResult } from './types' + +export function resolvedToolCall

(toolCall: ToolCall | null | undefined, tools: DefinedTool[]): ResolvedToolCall | undefined { + if (toolCall == null) + return undefined + if (toolCall.function == null) + return undefined + + const foundTool = tools.find(tool => toolCall.function.name === tool.tool.function.name) + if (foundTool == null) + return undefined + + return { + tool: foundTool.tool, + toolCall, + arguments: JSON.parse(toolCall.function.arguments), + provider: foundTool.provider, + func: foundTool.func, + hooks: foundTool.hooks, + } +} + +export async function invokeFunctionWithResolvedToolCall

(completions: ChatCompletion, toolCall: ResolvedToolCall | undefined, messages?: Message[]): Promise { + if (toolCall == null) + return undefined + if (toolCall.toolCall == null) + return undefined + if (toolCall.toolCall.function == null) + return undefined + + const ctx: InvokeContext = { + messages: messages ?? [], + chatCompletion: completions, + parameters: toolCall.arguments, + toolCall, + } + + await toolCall.hooks.preInvoke(ctx) + const res = await toolCall.func(ctx) + await toolCall.hooks.postInvoke({ ...ctx, result: res }) + + return res +} + +export async function invokeFunctionWithTools(chatCompletion: ChatCompletion, tools: DefinedTool[], messages: Message[]): Promise>> { + const results: Array> = [] + + for (const choice of chatCompletion.choices) { + if (!choice.message.tool_calls) { + continue + } + + for (const toolCall of choice.message.tool_calls) { + const tc = resolvedToolCall(toolCall, tools) + + results.push({ + result: await invokeFunctionWithResolvedToolCall(chatCompletion, tc, messages), + chatCompletionToolCall: toolCall, + resolvedToolCall: tc, + }) + } + } + + return results +} diff --git a/packages/neuri/src/openai/messages.ts b/packages/neuri/src/openai/messages.ts new file mode 100644 index 0000000..16b1ed2 --- /dev/null +++ b/packages/neuri/src/openai/messages.ts @@ -0,0 +1,17 @@ +import type { ToolMessage } from '@xsai/shared-chat' +import type { ResolvedToolCall } from './types' + +export function tool

(message: string, toolCall: ResolvedToolCall): ToolMessage { + return { + role: 'tool', + content: message, + tool_call_id: toolCall.toolCall.id, + } +} + +export { + assistant, + messages, + system, + user, +} from '@xsai/shared-chat' diff --git a/packages/neuri/src/openai.test.ts b/packages/neuri/src/openai/stream.test.ts similarity index 52% rename from packages/neuri/src/openai.test.ts rename to packages/neuri/src/openai/stream.test.ts index 63f02d9..41206a1 100644 --- a/packages/neuri/src/openai.test.ts +++ b/packages/neuri/src/openai/stream.test.ts @@ -1,45 +1,18 @@ import { env } from 'node:process' -import OpenAI from 'openai' - import { describe, expect, it } from 'vitest' -import { object, string } from 'zod' -import { defineToolFunction, messages, stream, type StreamChunk, system, toolFunction, user } from './openai' -import { newTestInvokeContext } from './test' - -describe('neuri/openai', async () => { - it('it works', async () => { - const tf = await defineToolFunction( - await toolFunction('name', 'description', object({ name: string() })), - async ({ parameters: { name } }) => { - expect(name).toBe('name') - - return name - }, - ) - - expect(tf).toBeDefined() - - const name = await tf.func(newTestInvokeContext({ name: 'name' })) - expect(name).toBe('name') - }) -}) +import { messages, system, user } from './messages' +import { stream, type StreamChunk } from './stream' describe('stream', async () => { it('it works', async () => { - const openai = new OpenAI({ - apiKey: env.OPENAI_API_KEY, - baseURL: env.OPENAI_API_BASEURL, - }) - const res = await stream({ - openAI: openai, - options: { - model: 'openai/gpt-3.5-turbo', - messages: messages( - system('You are a helpful assistant.'), - user('What is the meaning of life?'), - ), - }, + apiKey: env.OPENAI_API_KEY!, + baseURL: env.OPENAI_API_BASEURL!, + model: 'openai/gpt-3.5-turbo', + messages: messages( + system('You are a helpful assistant.'), + user('What is the meaning of life?'), + ), }) const readText = async () => { diff --git a/packages/neuri/src/openai/stream.ts b/packages/neuri/src/openai/stream.ts new file mode 100644 index 0000000..61f5d85 --- /dev/null +++ b/packages/neuri/src/openai/stream.ts @@ -0,0 +1,123 @@ +import type { StreamTextOptions, StreamTextResponse } from '@xsai/stream-text' +import { streamText } from '@xsai/stream-text' + +export interface StreamChunk extends StreamTextResponse { + textPart: () => string +} + +export interface StreamResponse { + /** + * Get the completion response. + * + * @returns The completion response. + */ + response: () => Promise + /** + * Get the entire completion response as a text. + * + * @returns The entire completion response as a text. + */ + text: () => Promise + /** + * + * Get the completion response as a stream of text. + * + * @returns The completion response as a stream of text. + */ + textStream: () => AsyncGenerator + /** + * Get the completion response as a stream of chunks. + * + * @returns The completion response as a stream of chunks. + */ + chunkStream: () => AsyncGenerator + /** + * Get the completion response as a stream of chunks. + * + * @returns The completion response as a stream of chunks. + */ + chunks: () => Promise +} + +interface PipeHook { + onValue?: (value: F) => void + onChunk?: (chunk: T) => void + onDone?: () => void +} + +async function* asyncIteratorFromReadableStream(res: ReadableStream, func: (value: F) => Promise, hooks?: PipeHook[]): AsyncGenerator { + // reactjs - TS2504: Type 'ReadableStream' must have a '[Symbol.asyncIterator]()' method that returns an async iterator - Stack Overflow + // https://stackoverflow.com/questions/76700924/ts2504-type-readablestreamuint8array-must-have-a-symbol-asynciterator + const reader = res.getReader() + try { + while (true) { + const { done, value } = await reader.read() + if (done) { + hooks?.forEach(i => i.onDone?.()) + return + } + + const chunk = await func(value) + hooks?.forEach(i => i.onChunk?.(chunk)) + yield chunk + } + } + finally { + reader.releaseLock() + } +} + +/** + * Stream the completion response from LLM API. + * + * @param params - The parameters to stream the completion response. + * @returns The completion response stream. + */ +export async function stream(params: StreamTextOptions): Promise { + const res = await streamText(params) + + const textStreamHooks: PipeHook[] = [] + const accumulatedText = new Promise((resolve) => { + const chunks: string[] = [] + textStreamHooks.push({ + onChunk: (chunk) => { chunks.push(chunk) }, + onDone: () => { resolve(chunks.join('')) }, + }) + }) + + const chunkStreamHooks: PipeHook[] = [] + const accumulatedChunks = new Promise((resolve) => { + const chunks: StreamChunk[] = [] + chunkStreamHooks.push({ + onChunk: (chunk) => { chunks.push(chunk) }, + onDone: () => { resolve(chunks) }, + }) + }) + + return { + response: async () => res, + text: () => accumulatedText, + chunks: () => accumulatedChunks, + textStream: () => asyncIteratorFromReadableStream( + res.textStream, + async (value: string) => value, + textStreamHooks, + ), + chunkStream: () => asyncIteratorFromReadableStream( + res.chunkStream, + async (value: StreamTextResponse): Promise => { + return { + ...value, + textPart: () => { + if (value.choices.length === 0) { + return '' + } + + return value.choices[0].delta.content + }, + } + }, + chunkStreamHooks, + ), + } satisfies StreamResponse +} diff --git a/packages/neuri/src/openai/tools.test.ts b/packages/neuri/src/openai/tools.test.ts new file mode 100644 index 0000000..671e27d --- /dev/null +++ b/packages/neuri/src/openai/tools.test.ts @@ -0,0 +1,22 @@ +import { newTestInvokeContext } from 'neuri/test' +import { describe, expect, it } from 'vitest' +import { object, string } from 'zod' +import { defineToolFunction, toolFunction } from './tools' + +describe('neuri/openai', async () => { + it('it works', async () => { + const tf = await defineToolFunction( + await toolFunction('name', 'description', object({ name: string() })), + async ({ parameters: { name } }) => { + expect(name).toBe('name') + + return name + }, + ) + + expect(tf).toBeDefined() + + const name = await tf.func(newTestInvokeContext({ name: 'name' })) + expect(name).toBe('name') + }) +}) diff --git a/packages/neuri/src/openai/tools.ts b/packages/neuri/src/openai/tools.ts new file mode 100644 index 0000000..05d558c --- /dev/null +++ b/packages/neuri/src/openai/tools.ts @@ -0,0 +1,60 @@ +import type { Infer, Schema } from '@typeschema/main' +import type { CommonProviderOptions } from '@xsai/providers' +import type { DefinedTool, DefinedToolHooks, InvokeContext, Tool } from './types' + +import { toJSONSchema } from '@typeschema/main' + +type JSONSchema = Awaited> & Record + +interface ToolFunction<_P> extends Tool { + type: 'function' + function: { + name: string + description?: string + parameters: JSONSchema + } +} + +export async function toolFunction>(name: string, description: string, parameters: S): Promise> { + return { + type: 'function', + function: { + name, + description, + parameters: await toJSONSchema(parameters as any), + }, + } +} + +export function defineToolFunction) => R, P = Parameters, R = ReturnType>( + tool: ToolFunction

, + func: F, + options?: { + provider?: CommonProviderOptions + hooks?: Partial> + }, +): DefinedTool { + const hooks: DefinedToolHooks = { + configureProvider: async o => o, + preInvoke: async () => {}, + postInvoke: async () => {}, + } + + if (options?.hooks?.configureProvider != null) + hooks.configureProvider = options.hooks.configureProvider + if (options?.hooks?.preInvoke != null) + hooks.preInvoke = options?.hooks?.preInvoke + if (options?.hooks?.postInvoke != null) + hooks.postInvoke = options?.hooks?.postInvoke + + return { + provider: options?.provider ?? { baseURL: 'https://api.openai.com/v1', apiKey: '' }, + tool, + func, + hooks, + } +} + +export function tools(tools: DefinedTool[]): Tool[] { + return tools.map(tool => tool.tool) +} diff --git a/packages/neuri/src/openai/types.ts b/packages/neuri/src/openai/types.ts new file mode 100644 index 0000000..5255613 --- /dev/null +++ b/packages/neuri/src/openai/types.ts @@ -0,0 +1,64 @@ +import type { GenerateTextResponseUsage } from '@xsai/generate-text' +import type { CommonProviderOptions } from '@xsai/providers' +import type { AssistantMessageResponse, FinishReason, Message, ToolCall, Tool as UpstreamTool } from '@xsai/shared-chat' + +export interface Choice { + finish_reason: FinishReason + index: number + message: AssistantMessageResponse +} + +export interface ChatCompletionsResponse { + choices: Choice[] + created: number + id: string + model: string + object: 'chat.completion' + system_fingerprint: string + usage: GenerateTextResponseUsage +} + +export type Tool = Omit + +export interface ChatCompletion extends ChatCompletionsResponse { + firstContent: () => Promise + firstChoice: () => Choice | undefined +} + +export interface ToolCallFunctionResult

{ + result: R | undefined + chatCompletionToolCall?: ToolCall + resolvedToolCall: ResolvedToolCall | undefined +} + +export interface DefinedTool { + provider: CommonProviderOptions + tool: Tool + func: (ctx: InvokeContext) => R + hooks: DefinedToolHooks +} + +export interface DefinedToolHooks { + configureProvider: (provider?: CommonProviderOptions) => Promise + preInvoke: (ctx: PreInvokeContext) => Promise + postInvoke: (ctx: PostInvokeContext) => Promise +} + +export interface InvokeContext { + messages: Message[] + chatCompletion: ChatCompletion + parameters: P + toolCall: ResolvedToolCall +} + +export interface PreInvokeContext extends InvokeContext {} + +export interface PostInvokeContext extends InvokeContext { + result: R +} + +export interface ResolvedToolCall extends DefinedTool { + arguments: P + toolCall: ToolCall + hooks: DefinedToolHooks +} diff --git a/packages/neuri/src/test.ts b/packages/neuri/src/test.ts index 7f2d8c7..03749c2 100644 --- a/packages/neuri/src/test.ts +++ b/packages/neuri/src/test.ts @@ -1,9 +1,9 @@ -import type { InvokeContext, Tool } from './openai' +import type { DefinedTool, InvokeContext } from './openai' export function newTestInvokeContext(parameters?: P): InvokeContext { return { parameters } as InvokeContext } -export async function invoke(tool: Tool, parameters: P): Promise> { +export async function invoke(tool: DefinedTool, parameters: P): Promise> { return await tool.func(newTestInvokeContext(parameters)) } diff --git a/packages/use-fs/package.json b/packages/use-fs/package.json index 68df1f2..ce02920 100644 --- a/packages/use-fs/package.json +++ b/packages/use-fs/package.json @@ -53,13 +53,13 @@ "dependencies": { "@guiiai/logg": "^1.0.6", "defu": "^6.1.4", - "execa": "^9.5.1", + "execa": "^9.5.2", "ignore": "^6.0.2", "neuri": "workspace:*", "ofetch": "^1.4.1", - "zod": "^3.23.8" + "zod": "^3.24.1" }, "devDependencies": { - "@types/node": "^22.10.1" + "@types/node": "^22.10.2" } } diff --git a/packages/use-search/package.json b/packages/use-search/package.json index fb2399e..29678b5 100644 --- a/packages/use-search/package.json +++ b/packages/use-search/package.json @@ -49,15 +49,15 @@ "dependencies": { "@guiiai/logg": "^1.0.6", "defu": "^6.1.4", - "execa": "^9.5.1", + "execa": "^9.5.2", "ignore": "^6.0.2", "neuri": "workspace:*", "ofetch": "^1.4.1", "serpapi": "^2.1.0", - "zod": "^3.23.8", - "zod-to-json-schema": "^3.23.5" + "zod": "^3.24.1", + "zod-to-json-schema": "^3.24.1" }, "devDependencies": { - "@types/node": "^22.10.1" + "@types/node": "^22.10.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 8f7a0da..5c782d6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,31 +9,31 @@ importers: .: devDependencies: '@antfu/eslint-config': - specifier: ^3.11.2 + specifier: ^3.12.0 version: 3.12.0(@typescript-eslint/utils@8.18.1(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.2))(@unocss/eslint-plugin@0.65.1(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.2))(@vue/compiler-sfc@3.5.13)(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.2)(vitest@2.1.8(@types/node@22.10.2)(less@4.2.0)) '@antfu/ni': specifier: ^0.23.1 version: 0.23.1 '@types/node': - specifier: ^22.10.1 + specifier: ^22.10.2 version: 22.10.2 '@vitest/coverage-v8': specifier: 2.1.8 version: 2.1.8(vitest@2.1.8(@types/node@22.10.2)(less@4.2.0)) bumpp: - specifier: ^9.8.1 + specifier: ^9.9.1 version: 9.9.1(magicast@0.3.5) eslint: - specifier: ^9.16.0 + specifier: ^9.17.0 version: 9.17.0(jiti@2.4.2) typescript: specifier: ^5.7.2 version: 5.7.2 unbuild: - specifier: ^3.0.0-rc.11 - version: 3.0.1(typescript@5.7.2)(vue-tsc@2.0.29(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2)) + specifier: 3.0.0-rc.11 + version: 3.0.0-rc.11(typescript@5.7.2)(vue-tsc@2.0.29(typescript@5.7.2)) vite: - specifier: ^6.0.2 + specifier: ^6.0.3 version: 6.0.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.0)(tsx@4.19.2)(yaml@2.6.1) vitest: specifier: ^2.1.8 @@ -42,19 +42,19 @@ importers: docs: devDependencies: '@unocss/eslint-config': - specifier: ^0.65.0 + specifier: ^0.65.1 version: 0.65.1(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.2) '@unocss/eslint-plugin': - specifier: ^0.65.0 + specifier: ^0.65.1 version: 0.65.1(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.2) unocss: - specifier: ^0.65.0 + specifier: ^0.65.1 version: 0.65.1(postcss@8.4.49)(rollup@4.28.1)(vite@6.0.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.0)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2)) vite: - specifier: ^6.0.2 + specifier: ^6.0.3 version: 6.0.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.0)(tsx@4.19.2)(yaml@2.6.1) vite-plugin-inspect: - specifier: ^0.10.0 + specifier: ^0.10.3 version: 0.10.3(rollup@4.28.1)(vite@6.0.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.0)(tsx@4.19.2)(yaml@2.6.1)) vitepress: specifier: ^1.5.0 @@ -69,7 +69,7 @@ importers: specifier: workspace:^ version: link:../../../packages/neuri openai: - specifier: ^4.74.0 + specifier: ^4.77.0 version: 4.77.0(zod@3.24.1) devDependencies: tsx: @@ -80,10 +80,10 @@ importers: dependencies: '@typeschema/main': specifier: ^0.14.1 - version: 0.14.1(@types/json-schema@7.0.15)(@typeschema/valibot@0.14.0(@types/json-schema@7.0.15))(@typeschema/zod@0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.1(zod@3.24.1))(zod@3.24.1)) + version: 0.14.1(@types/json-schema@7.0.15)(@typeschema/valibot@0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.24.0)(typescript@5.7.2))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.2)))(@typeschema/zod@0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.1(zod@3.24.1))(zod@3.24.1)) '@typeschema/valibot': specifier: ^0.14.0 - version: 0.14.0(@types/json-schema@7.0.15)(valibot@0.42.1(typescript@5.7.2)) + version: 0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.24.0)(typescript@5.7.2))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.2)) '@typeschema/zod': specifier: ^0.14.0 version: 0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.1(zod@3.24.1))(zod@3.24.1) @@ -91,13 +91,13 @@ importers: specifier: workspace:^ version: link:../../../packages/neuri openai: - specifier: ^4.74.0 + specifier: ^4.77.0 version: 4.77.0(zod@3.24.1) valibot: - specifier: ^0.42.1 - version: 0.42.1(typescript@5.7.2) + specifier: ^1.0.0-beta.9 + version: 1.0.0-beta.9(typescript@5.7.2) zod: - specifier: ^3.23.8 + specifier: ^3.24.1 version: 3.24.1 devDependencies: tsx: @@ -110,23 +110,23 @@ importers: specifier: ^1.0.6 version: 1.0.6 '@shikijs/core': - specifier: ^1.24.0 + specifier: ^1.24.2 version: 1.24.2 '@shikijs/engine-oniguruma': - specifier: ^1.24.0 + specifier: ^1.24.2 version: 1.24.2 '@shikijs/vscode-textmate': - specifier: ^9.3.0 + specifier: ^9.3.1 version: 9.3.1 shiki: - specifier: ^1.24.0 + specifier: ^1.24.2 version: 1.24.2 tm-grammars: - specifier: ^1.21.0 + specifier: ^1.21.7 version: 1.21.7 devDependencies: '@types/node': - specifier: ^22.10.1 + specifier: ^22.10.2 version: 22.10.2 packages/neuri: @@ -136,13 +136,22 @@ importers: version: 1.0.6 '@typeschema/main': specifier: ^0.14.1 - version: 0.14.1(@types/json-schema@7.0.15)(@typeschema/valibot@0.14.0(@types/json-schema@7.0.15))(@typeschema/zod@0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.1(zod@3.24.1))(zod@3.24.1)) + version: 0.14.1(@types/json-schema@7.0.15)(@typeschema/valibot@0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.24.0)(typescript@5.7.2))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.2)))(@typeschema/zod@0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.1(zod@3.24.1))(zod@3.24.1)) '@xsai/generate-text': specifier: ^0.0.22 version: 0.0.22 + '@xsai/providers': + specifier: ^0.0.22 + version: 0.0.22 + '@xsai/shared-chat': + specifier: ^0.0.22 + version: 0.0.22 + '@xsai/stream-text': + specifier: ^0.0.22 + version: 0.0.22 '@xsai/tool': specifier: ^0.0.22 - version: 0.0.22(@types/json-schema@7.0.15)(@typeschema/valibot@0.14.0(@types/json-schema@7.0.15))(@typeschema/zod@0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.1(zod@3.24.1))(zod@3.24.1))(@xsai/generate-text@0.0.22) + version: 0.0.22(@types/json-schema@7.0.15)(@typeschema/valibot@0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.24.0)(typescript@5.7.2))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.2)))(@typeschema/zod@0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.1(zod@3.24.1))(zod@3.24.1))(@xsai/generate-text@0.0.22) defu: specifier: ^6.1.4 version: 6.1.4 @@ -150,14 +159,17 @@ importers: specifier: ^5.0.9 version: 5.0.9 openai: - specifier: ^4.74.0 + specifier: ^4.77.0 version: 4.77.0(zod@3.24.1) devDependencies: + '@gcornut/valibot-json-schema': + specifier: ^0.42.0 + version: 0.42.0(esbuild@0.24.0)(typescript@5.7.2) '@types/mdast': specifier: ^4.0.4 version: 4.0.4 '@types/node': - specifier: ^22.10.1 + specifier: ^22.10.2 version: 22.10.2 '@typeschema/zod': specifier: ^0.14.0 @@ -168,11 +180,14 @@ importers: remark: specifier: ^15.0.1 version: 15.0.1 + valibot: + specifier: ^1.0.0-beta.9 + version: 1.0.0-beta.9(typescript@5.7.2) zod: - specifier: ^3.23.8 + specifier: ^3.24.1 version: 3.24.1 zod-to-json-schema: - specifier: ^3.23.5 + specifier: ^3.24.1 version: 3.24.1(zod@3.24.1) packages/use-fs: @@ -184,7 +199,7 @@ importers: specifier: ^6.1.4 version: 6.1.4 execa: - specifier: ^9.5.1 + specifier: ^9.5.2 version: 9.5.2 ignore: specifier: ^6.0.2 @@ -196,11 +211,11 @@ importers: specifier: ^1.4.1 version: 1.4.1 zod: - specifier: ^3.23.8 + specifier: ^3.24.1 version: 3.24.1 devDependencies: '@types/node': - specifier: ^22.10.1 + specifier: ^22.10.2 version: 22.10.2 packages/use-search: @@ -212,7 +227,7 @@ importers: specifier: ^6.1.4 version: 6.1.4 execa: - specifier: ^9.5.1 + specifier: ^9.5.2 version: 9.5.2 ignore: specifier: ^6.0.2 @@ -227,14 +242,14 @@ importers: specifier: ^2.1.0 version: 2.1.0 zod: - specifier: ^3.23.8 + specifier: ^3.24.1 version: 3.24.1 zod-to-json-schema: - specifier: ^3.23.5 + specifier: ^3.24.1 version: 3.24.1(zod@3.24.1) devDependencies: '@types/node': - specifier: ^22.10.1 + specifier: ^22.10.2 version: 22.10.2 packages: @@ -965,6 +980,10 @@ packages: resolution: {integrity: sha512-zSkKow6H5Kdm0ZUQUB2kV5JIXqoG0+uH5YADhaEHswm664N9Db8dXSi0nMJpacpMf+MyyglF1vnZohpEg5yUtg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@gcornut/valibot-json-schema@0.42.0': + resolution: {integrity: sha512-4Et4AN6wmqeA0PfU5Clkv/IS27wiefsWf6TemAZrb75uzkClYEFavim7SboeKwbll9Nbsn2Iv0LT/HS5H7orZg==} + hasBin: true + '@guiiai/logg@1.0.6': resolution: {integrity: sha512-x2dibX7Nr3sTCCJTsA3wgFSrZCtFA2k0vbg2fy+eG+fCAHKXjiSUNLAD94PpXcM7Jqbo4cJqzkOeCAgFZSjT0w==} @@ -1095,15 +1114,6 @@ packages: rollup: optional: true - '@rollup/pluginutils@5.1.3': - resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==} - engines: {node: '>=14.0.0'} - peerDependencies: - rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 - peerDependenciesMeta: - rollup: - optional: true - '@rollup/pluginutils@5.1.4': resolution: {integrity: sha512-USm05zrsFxYLPdWWq+K3STlWiT/3ELn3RcV5hJMghpeAIhxfsUIg6mt12CBJBInWMV4VneoV7SfGv8xIwo2qNQ==} engines: {node: '>=14.0.0'} @@ -1605,10 +1615,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' - '@typescript-eslint/scope-manager@8.17.0': - resolution: {integrity: sha512-/ewp4XjvnxaREtqsZjF4Mfn078RD/9GmiEAtTeLQ7yFdKnqwTOgRMSvFz4et9U5RiJQ15WTGXPLj89zGusvxBg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/scope-manager@8.18.1': resolution: {integrity: sha512-HxfHo2b090M5s2+/9Z3gkBhI6xBH8OJCFjH9MhQ+nnoZqxU3wNxkLT+VWXWSFWc3UF3Z+CfPAyqdCTdoXtDPCQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1620,39 +1626,16 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' - '@typescript-eslint/types@8.17.0': - resolution: {integrity: sha512-gY2TVzeve3z6crqh2Ic7Cr+CAv6pfb0Egee7J5UAVWCpVvDI/F71wNfolIim4FE6hT15EbpZFVUj9j5i38jYXA==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/types@8.18.1': resolution: {integrity: sha512-7uoAUsCj66qdNQNpH2G8MyTFlgerum8ubf21s3TSM3XmKXuIn+H2Sifh/ES2nPOPiYSRJWAk0fDkW0APBWcpfw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.17.0': - resolution: {integrity: sha512-JqkOopc1nRKZpX+opvKqnM3XUlM7LpFMD0lYxTqOTKQfCWAmxw45e3qlOCsEqEB2yuacujivudOFpCnqkBDNMw==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/typescript-estree@8.18.1': resolution: {integrity: sha512-z8U21WI5txzl2XYOW7i9hJhxoKKNG1kcU4RzyNvKrdZDmbjkmLBo8bgeiOJmA06kizLI76/CCBAAGlTlEeUfyg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <5.8.0' - '@typescript-eslint/utils@8.17.0': - resolution: {integrity: sha512-bQC8BnEkxqG8HBGKwG9wXlZqg37RKSMY7v/X8VEWD8JG2JuTHuNK0VFvMPMUKQcbk6B+tf05k+4AShAEtCtJ/w==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - peerDependencies: - eslint: ^8.57.0 || ^9.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - '@typescript-eslint/utils@8.18.1': resolution: {integrity: sha512-8vikiIj2ebrC4WRdcAdDcmnu9Q/MXXwg+STf40BVfT8exDqBCUPdypvzcUPxEqRGKg9ALagZ0UWcYCtn+4W2iQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1660,10 +1643,6 @@ packages: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <5.8.0' - '@typescript-eslint/visitor-keys@8.17.0': - resolution: {integrity: sha512-1Hm7THLpO6ww5QU6H/Qp+AusUUl+z/CAm3cNZZ0jQvon9yicgO7Rwd+/WWRpMKLYV6p2UvdbR27c86rzCPpreg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/visitor-keys@8.18.1': resolution: {integrity: sha512-Vj0WLm5/ZsD013YeUKn+K0y8p1M0jPpxOkKdbD1wB0ns53a5piVY02zjf072TblEweAbcYiFiPoSMF3kp+VhhQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -1928,12 +1907,18 @@ packages: '@xsai/generate-text@0.0.22': resolution: {integrity: sha512-3ZkxR3QfN0lkcCD4NM6glkA9+cWxPodHx73qnlSKzFV/m1McAI42JPKWpFOxfQdxkAQAkZ5cD5Et7PZs8Rc7bQ==} + '@xsai/providers@0.0.22': + resolution: {integrity: sha512-TinCtYJvnWB5MY4WuWzL/svbD0vrx3znRQglVUuPIGMqm3MCaGyvQk0hq9GK8FdGkyb/LZikxT2N8lB6NaHPBw==} + '@xsai/shared-chat@0.0.22': resolution: {integrity: sha512-VQHGrUkNrUj50TRho/qClPbeJLNjEbTC+MvDNTxuYrxcGydpkImP+SLmcpvdsSUjbr3GlGeZfpWrq/Y1WbreQQ==} '@xsai/shared@0.0.22': resolution: {integrity: sha512-bqrKOyOlCk+12BRWBRAaXMCSoybyVYV6aGk7uzweJQVRUB0ZRMFBfJuhwPMXKG12WkoSXzMhFaYCI9izekb7Pg==} + '@xsai/stream-text@0.0.22': + resolution: {integrity: sha512-AgFmSMue4VAP/jYrS08axgDkjxb1PVN2QGMvFZDRrKDccEdokTD8CmoYwp3z8mhQjth+TE5botYpuktztgqYdg==} + '@xsai/tool@0.0.22': resolution: {integrity: sha512-4JJRaSJ77rMZrzsqzuPf90KQvquXFApvmKyXAv5InzSLltsTu5muC0YvNGCy9MAN50FCpLuBqt9CXusccLB8DQ==} peerDependencies: @@ -2039,6 +2024,9 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true + buffer-from@1.1.2: + resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + builtin-modules@3.3.0: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} @@ -2386,6 +2374,12 @@ packages: es-module-lexer@1.5.4: resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==} + esbuild-runner@2.2.2: + resolution: {integrity: sha512-fRFVXcmYVmSmtYm2mL8RlUASt2TDkGh3uRcvHFOKNr/T58VrfVeKD9uT9nlgxk96u0LS0ehS/GY7Da/bXWKkhw==} + hasBin: true + peerDependencies: + esbuild: '*' + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -3085,9 +3079,6 @@ packages: magic-string@0.30.13: resolution: {integrity: sha512-8rYBO+MsWkgjDSOvLomYnzhdwEG51olQ4zL5KXnNJWV5MNmrb4rTZdrtkhxjnD/QyZUqR/Z/XDsUs/4ej2nx0g==} - magic-string@0.30.14: - resolution: {integrity: sha512-5c99P1WKTed11ZC0HMJOj6CDIue6F8ySu+bJL+85q1zBEIY8IklrJ1eiKC2NDRh3Ct3FcvmJPyQHb9erXMTJNw==} - magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} @@ -3372,21 +3363,18 @@ packages: engines: {node: '>=10'} hasBin: true - mkdist@2.1.0: - resolution: {integrity: sha512-FhJRzoA2GEZr7X9S8S8SR5BcuGwgGi6IZKnJUHlMkRHUBJAtTU3xfIIcHnK4t9M/B9zK1ffpE+vGSS1003R7Dw==} + mkdist@1.6.0: + resolution: {integrity: sha512-nD7J/mx33Lwm4Q4qoPgRBVA9JQNKgyE7fLo5vdPWVDdjz96pXglGERp/fRnGPCTB37Kykfxs5bDdXa9BWOT9nw==} hasBin: true peerDependencies: - sass: ^1.83.0 - typescript: '>=5.7.2' - vue: ^3.2.13 + sass: ^1.78.0 + typescript: '>=5.5.4' vue-tsc: ^1.8.27 || ^2.0.21 peerDependenciesMeta: sass: optional: true typescript: optional: true - vue: - optional: true vue-tsc: optional: true @@ -3527,9 +3515,6 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} - package-manager-detector@0.2.6: - resolution: {integrity: sha512-9vPH3qooBlYRJdmdYP00nvjZOulm40r5dhtal8st18ctf+6S1k7pi5yIHLvI4w5D70x0Y+xdVD9qITH0QO/A8A==} - package-manager-detector@0.2.7: resolution: {integrity: sha512-g4+387DXDKlZzHkP+9FLt8yKj8+/3tOkPv7DVTJGGRm00RkEWgqbFstX1mXJ4M0VDYhUqsTOiISqNOJnhAu3PQ==} @@ -3689,9 +3674,9 @@ packages: peerDependencies: postcss: ^8.4.31 - postcss-nested@7.0.2: - resolution: {integrity: sha512-5osppouFc0VR9/VYzYxO03VaDa3e8F23Kfd6/9qcZTUI8P58GIYlArOET2Wq0ywSl2o2PjELhYOFI4W7l5QHKw==} - engines: {node: '>=18.0'} + postcss-nested@6.2.0: + resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==} + engines: {node: '>=12.0'} peerDependencies: postcss: ^8.2.14 @@ -3771,10 +3756,6 @@ packages: resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==} engines: {node: '>=4'} - postcss-selector-parser@7.0.0: - resolution: {integrity: sha512-9RbEr1Y7FFfptd/1eEdntyjMwLeghW1bHX9GWjXo19vx4ytPQhANltvVxDggzJl7mnWM+dX28kb6cyS/4iQjlQ==} - engines: {node: '>=4'} - postcss-svgo@7.0.1: resolution: {integrity: sha512-0WBUlSL4lhD9rA5k1e5D8EN5wCEyZD6HJk0jIvRxl+FDVOMlJ7DePHYWGGVc5QRqrJ3/06FTXM0bxjmJpmTPSA==} engines: {node: ^18.12.0 || ^20.9.0 || >= 18} @@ -4004,6 +3985,9 @@ packages: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map-support@0.5.21: + resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} + source-map@0.6.1: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} @@ -4166,18 +4150,15 @@ packages: trough@2.2.0: resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} - ts-api-utils@1.4.0: - resolution: {integrity: sha512-032cPxaEKwM+GT3vA5JXNzIaizx388rhsSW79vGRNGXfRRAdEAn2mvk36PvK5HnOchyWZ7afLEXqYCvPCrzuzQ==} - engines: {node: '>=16'} - peerDependencies: - typescript: '>=4.2.0' - ts-api-utils@1.4.3: resolution: {integrity: sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw==} engines: {node: '>=16'} peerDependencies: typescript: '>=4.2.0' + tslib@2.4.0: + resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -4210,11 +4191,11 @@ packages: ufo@1.5.4: resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==} - unbuild@3.0.1: - resolution: {integrity: sha512-03Fv1B8hmJzYCdL4TDgmgBg1WMU0CB5P2tBqPCW7XAvZG/l275m6JU/xf2tJ4yuUeHtmSzg1G387Te9nlsufFA==} + unbuild@3.0.0-rc.11: + resolution: {integrity: sha512-faBmtdo73jSSoghmf7CuscmAMOr34eri9j674pQP+KKjxvwTKaRol6f2DVhKhNCfceeHdfm2BfDwRxo2L/w0fg==} hasBin: true peerDependencies: - typescript: ^5.7.2 + typescript: ^5.6.2 peerDependenciesMeta: typescript: optional: true @@ -4290,6 +4271,14 @@ packages: typescript: optional: true + valibot@1.0.0-beta.9: + resolution: {integrity: sha512-yEX8gMAZ2R1yI2uwOO4NCtVnJQx36zn3vD0omzzj9FhcoblvPukENIiRZXKZwCnqSeV80bMm8wNiGhQ0S8fiww==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + validate-npm-package-license@3.0.4: resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} @@ -4705,7 +4694,7 @@ snapshots: '@antfu/install-pkg@0.4.1': dependencies: - package-manager-detector: 0.2.6 + package-manager-detector: 0.2.7 tinyexec: 0.3.1 '@antfu/install-pkg@0.5.0': @@ -5142,6 +5131,16 @@ snapshots: dependencies: levn: 0.4.1 + '@gcornut/valibot-json-schema@0.42.0(esbuild@0.24.0)(typescript@5.7.2)': + dependencies: + valibot: 0.42.1(typescript@5.7.2) + optionalDependencies: + '@types/json-schema': 7.0.15 + esbuild-runner: 2.2.2(esbuild@0.24.0) + transitivePeerDependencies: + - esbuild + - typescript + '@guiiai/logg@1.0.6': dependencies: chalk: 5.3.0 @@ -5270,14 +5269,6 @@ snapshots: optionalDependencies: rollup: 4.28.1 - '@rollup/pluginutils@5.1.3(rollup@4.28.1)': - dependencies: - '@types/estree': 1.0.6 - estree-walker: 2.0.2 - picomatch: 4.0.2 - optionalDependencies: - rollup: 4.28.1 - '@rollup/pluginutils@5.1.4(rollup@4.28.1)': dependencies: '@types/estree': 1.0.6 @@ -5581,7 +5572,7 @@ snapshots: '@types/node-fetch@2.6.12': dependencies: - '@types/node': 18.19.68 + '@types/node': 22.10.2 form-data: 4.0.1 '@types/node@18.19.68': @@ -5604,20 +5595,21 @@ snapshots: optionalDependencies: '@types/json-schema': 7.0.15 - '@typeschema/main@0.14.1(@types/json-schema@7.0.15)(@typeschema/valibot@0.14.0(@types/json-schema@7.0.15))(@typeschema/zod@0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.1(zod@3.24.1))(zod@3.24.1))': + '@typeschema/main@0.14.1(@types/json-schema@7.0.15)(@typeschema/valibot@0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.24.0)(typescript@5.7.2))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.2)))(@typeschema/zod@0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.1(zod@3.24.1))(zod@3.24.1))': dependencies: '@typeschema/core': 0.14.0(@types/json-schema@7.0.15) optionalDependencies: - '@typeschema/valibot': 0.14.0(@types/json-schema@7.0.15)(valibot@0.42.1(typescript@5.7.2)) + '@typeschema/valibot': 0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.24.0)(typescript@5.7.2))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.2)) '@typeschema/zod': 0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.1(zod@3.24.1))(zod@3.24.1) transitivePeerDependencies: - '@types/json-schema' - '@typeschema/valibot@0.14.0(@types/json-schema@7.0.15)(valibot@0.42.1(typescript@5.7.2))': + '@typeschema/valibot@0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.24.0)(typescript@5.7.2))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.2))': dependencies: '@typeschema/core': 0.14.0(@types/json-schema@7.0.15) optionalDependencies: - valibot: 0.42.1(typescript@5.7.2) + '@gcornut/valibot-json-schema': 0.42.0(esbuild@0.24.0)(typescript@5.7.2) + valibot: 1.0.0-beta.9(typescript@5.7.2) transitivePeerDependencies: - '@types/json-schema' @@ -5659,11 +5651,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.17.0': - dependencies: - '@typescript-eslint/types': 8.17.0 - '@typescript-eslint/visitor-keys': 8.17.0 - '@typescript-eslint/scope-manager@8.18.1': dependencies: '@typescript-eslint/types': 8.18.1 @@ -5680,25 +5667,8 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.17.0': {} - '@typescript-eslint/types@8.18.1': {} - '@typescript-eslint/typescript-estree@8.17.0(typescript@5.7.2)': - dependencies: - '@typescript-eslint/types': 8.17.0 - '@typescript-eslint/visitor-keys': 8.17.0 - debug: 4.4.0 - fast-glob: 3.3.2 - is-glob: 4.0.3 - minimatch: 9.0.5 - semver: 7.6.3 - ts-api-utils: 1.4.0(typescript@5.7.2) - optionalDependencies: - typescript: 5.7.2 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/typescript-estree@8.18.1(typescript@5.7.2)': dependencies: '@typescript-eslint/types': 8.18.1 @@ -5713,18 +5683,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.17.0(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.2)': - dependencies: - '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0(jiti@2.4.2)) - '@typescript-eslint/scope-manager': 8.17.0 - '@typescript-eslint/types': 8.17.0 - '@typescript-eslint/typescript-estree': 8.17.0(typescript@5.7.2) - eslint: 9.17.0(jiti@2.4.2) - optionalDependencies: - typescript: 5.7.2 - transitivePeerDependencies: - - supports-color - '@typescript-eslint/utils@8.18.1(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.2)': dependencies: '@eslint-community/eslint-utils': 4.4.1(eslint@9.17.0(jiti@2.4.2)) @@ -5736,11 +5694,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.17.0': - dependencies: - '@typescript-eslint/types': 8.17.0 - eslint-visitor-keys: 4.2.0 - '@typescript-eslint/visitor-keys@8.18.1': dependencies: '@typescript-eslint/types': 8.18.1 @@ -5763,7 +5716,7 @@ snapshots: '@unocss/cli@0.65.1(rollup@4.28.1)': dependencies: '@ampproject/remapping': 2.3.0 - '@rollup/pluginutils': 5.1.3(rollup@4.28.1) + '@rollup/pluginutils': 5.1.4(rollup@4.28.1) '@unocss/config': 0.65.1 '@unocss/core': 0.65.1 '@unocss/preset-uno': 0.65.1 @@ -5771,7 +5724,7 @@ snapshots: chokidar: 3.6.0 colorette: 2.0.20 consola: 3.2.3 - magic-string: 0.30.14 + magic-string: 0.30.17 pathe: 1.1.2 perfect-debounce: 1.0.0 tinyglobby: 0.2.10 @@ -5798,10 +5751,10 @@ snapshots: '@unocss/eslint-plugin@0.65.1(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.2)': dependencies: - '@typescript-eslint/utils': 8.17.0(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.2) + '@typescript-eslint/utils': 8.18.1(eslint@9.17.0(jiti@2.4.2))(typescript@5.7.2) '@unocss/config': 0.65.1 '@unocss/core': 0.65.1 - magic-string: 0.30.14 + magic-string: 0.30.17 synckit: 0.9.2 transitivePeerDependencies: - eslint @@ -5883,7 +5836,7 @@ snapshots: '@unocss/rule-utils@0.65.1': dependencies: '@unocss/core': 0.65.1 - magic-string: 0.30.14 + magic-string: 0.30.17 '@unocss/transformer-attributify-jsx@0.65.1': dependencies: @@ -5906,12 +5859,12 @@ snapshots: '@unocss/vite@0.65.1(rollup@4.28.1)(vite@6.0.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.0)(tsx@4.19.2)(yaml@2.6.1))(vue@3.5.13(typescript@5.7.2))': dependencies: '@ampproject/remapping': 2.3.0 - '@rollup/pluginutils': 5.1.3(rollup@4.28.1) + '@rollup/pluginutils': 5.1.4(rollup@4.28.1) '@unocss/config': 0.65.1 '@unocss/core': 0.65.1 '@unocss/inspector': 0.65.1(vue@3.5.13(typescript@5.7.2)) chokidar: 3.6.0 - magic-string: 0.30.14 + magic-string: 0.30.17 tinyglobby: 0.2.10 vite: 6.0.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.0)(tsx@4.19.2)(yaml@2.6.1) transitivePeerDependencies: @@ -6131,15 +6084,23 @@ snapshots: dependencies: '@xsai/shared-chat': 0.0.22 + '@xsai/providers@0.0.22': + dependencies: + '@xsai/shared': 0.0.22 + '@xsai/shared-chat@0.0.22': dependencies: '@xsai/shared': 0.0.22 '@xsai/shared@0.0.22': {} - '@xsai/tool@0.0.22(@types/json-schema@7.0.15)(@typeschema/valibot@0.14.0(@types/json-schema@7.0.15))(@typeschema/zod@0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.1(zod@3.24.1))(zod@3.24.1))(@xsai/generate-text@0.0.22)': + '@xsai/stream-text@0.0.22': + dependencies: + '@xsai/shared-chat': 0.0.22 + + '@xsai/tool@0.0.22(@types/json-schema@7.0.15)(@typeschema/valibot@0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.24.0)(typescript@5.7.2))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.2)))(@typeschema/zod@0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.1(zod@3.24.1))(zod@3.24.1))(@xsai/generate-text@0.0.22)': dependencies: - '@typeschema/main': 0.14.1(@types/json-schema@7.0.15)(@typeschema/valibot@0.14.0(@types/json-schema@7.0.15))(@typeschema/zod@0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.1(zod@3.24.1))(zod@3.24.1)) + '@typeschema/main': 0.14.1(@types/json-schema@7.0.15)(@typeschema/valibot@0.14.0(@gcornut/valibot-json-schema@0.42.0(esbuild@0.24.0)(typescript@5.7.2))(@types/json-schema@7.0.15)(valibot@1.0.0-beta.9(typescript@5.7.2)))(@typeschema/zod@0.14.0(@types/json-schema@7.0.15)(zod-to-json-schema@3.24.1(zod@3.24.1))(zod@3.24.1)) '@xsai/shared': 0.0.22 optionalDependencies: '@xsai/generate-text': 0.0.22 @@ -6265,6 +6226,9 @@ snapshots: node-releases: 2.0.19 update-browserslist-db: 1.1.1(browserslist@4.24.3) + buffer-from@1.1.2: + optional: true + builtin-modules@3.3.0: {} bumpp@9.9.1(magicast@0.3.5): @@ -6616,6 +6580,13 @@ snapshots: es-module-lexer@1.5.4: {} + esbuild-runner@2.2.2(esbuild@0.24.0): + dependencies: + esbuild: 0.24.0 + source-map-support: 0.5.21 + tslib: 2.4.0 + optional: true + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -7470,10 +7441,6 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 - magic-string@0.30.14: - dependencies: - '@jridgewell/sourcemap-codec': 1.5.0 - magic-string@0.30.17: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -8019,7 +7986,7 @@ snapshots: mkdirp@1.0.4: {} - mkdist@2.1.0(typescript@5.7.2)(vue-tsc@2.0.29(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2)): + mkdist@1.6.0(typescript@5.7.2)(vue-tsc@2.0.29(typescript@5.7.2)): dependencies: autoprefixer: 10.4.20(postcss@8.4.49) citty: 0.1.6 @@ -8031,12 +7998,11 @@ snapshots: pathe: 1.1.2 pkg-types: 1.2.1 postcss: 8.4.49 - postcss-nested: 7.0.2(postcss@8.4.49) + postcss-nested: 6.2.0(postcss@8.4.49) semver: 7.6.3 tinyglobby: 0.2.10 optionalDependencies: typescript: 5.7.2 - vue: 3.5.13(typescript@5.7.2) vue-tsc: 2.0.29(typescript@5.7.2) mlly@1.7.3: @@ -8184,8 +8150,6 @@ snapshots: package-json-from-dist@1.0.1: {} - package-manager-detector@0.2.6: {} - package-manager-detector@0.2.7: {} parent-module@1.0.1: @@ -8326,10 +8290,10 @@ snapshots: postcss: 8.4.49 postcss-selector-parser: 6.1.2 - postcss-nested@7.0.2(postcss@8.4.49): + postcss-nested@6.2.0(postcss@8.4.49): dependencies: postcss: 8.4.49 - postcss-selector-parser: 7.0.0 + postcss-selector-parser: 6.1.2 postcss-normalize-charset@7.0.0(postcss@8.4.49): dependencies: @@ -8398,11 +8362,6 @@ snapshots: cssesc: 3.0.0 util-deprecate: 1.0.2 - postcss-selector-parser@7.0.0: - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - postcss-svgo@7.0.1(postcss@8.4.49): dependencies: postcss: 8.4.49 @@ -8701,6 +8660,12 @@ snapshots: source-map-js@1.2.1: {} + source-map-support@0.5.21: + dependencies: + buffer-from: 1.1.2 + source-map: 0.6.1 + optional: true + source-map@0.6.1: optional: true @@ -8855,14 +8820,13 @@ snapshots: trough@2.2.0: {} - ts-api-utils@1.4.0(typescript@5.7.2): - dependencies: - typescript: 5.7.2 - ts-api-utils@1.4.3(typescript@5.7.2): dependencies: typescript: 5.7.2 + tslib@2.4.0: + optional: true + tslib@2.8.1: {} tsx@4.19.2: @@ -8886,7 +8850,7 @@ snapshots: ufo@1.5.4: {} - unbuild@3.0.1(typescript@5.7.2)(vue-tsc@2.0.29(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2)): + unbuild@3.0.0-rc.11(typescript@5.7.2)(vue-tsc@2.0.29(typescript@5.7.2)): dependencies: '@rollup/plugin-alias': 5.1.1(rollup@4.28.1) '@rollup/plugin-commonjs': 28.0.2(rollup@4.28.1) @@ -8901,7 +8865,7 @@ snapshots: hookable: 5.5.3 jiti: 2.4.2 magic-string: 0.30.17 - mkdist: 2.1.0(typescript@5.7.2)(vue-tsc@2.0.29(typescript@5.7.2))(vue@3.5.13(typescript@5.7.2)) + mkdist: 1.6.0(typescript@5.7.2)(vue-tsc@2.0.29(typescript@5.7.2)) mlly: 1.7.3 pathe: 1.1.2 pkg-types: 1.2.1 @@ -8917,7 +8881,6 @@ snapshots: transitivePeerDependencies: - sass - supports-color - - vue - vue-tsc unconfig@0.5.5: @@ -9025,6 +8988,10 @@ snapshots: optionalDependencies: typescript: 5.7.2 + valibot@1.0.0-beta.9(typescript@5.7.2): + optionalDependencies: + typescript: 5.7.2 + validate-npm-package-license@3.0.4: dependencies: spdx-correct: 3.2.0 @@ -9061,8 +9028,8 @@ snapshots: vite-plugin-inspect@0.10.3(rollup@4.28.1)(vite@6.0.3(@types/node@22.10.2)(jiti@2.4.2)(less@4.2.0)(tsx@4.19.2)(yaml@2.6.1)): dependencies: '@antfu/utils': 0.7.10 - '@rollup/pluginutils': 5.1.3(rollup@4.28.1) - debug: 4.3.7 + '@rollup/pluginutils': 5.1.4(rollup@4.28.1) + debug: 4.4.0 error-stack-parser-es: 0.1.5 fs-extra: 11.2.0 open: 10.1.0