@assistant-ui/react-ai-sdk
Advanced tools
Comparing version
@@ -7,3 +7,3 @@ import type { JSONSchema7 } from "json-schema"; | ||
[k: string]: { | ||
parameters: import("@ai-sdk/ui-utils").Schema<unknown>; | ||
parameters: import("ai").Schema<unknown>; | ||
description?: string; | ||
@@ -10,0 +10,0 @@ }; |
@@ -5,4 +5,5 @@ export * from "./rsc"; | ||
export * from "./useCloudRuntime"; | ||
export { toLanguageModelMessages, toLanguageModelTools, fromLanguageModelMessages, fromLanguageModelTools, useDangerousInBrowserRuntime, } from "@assistant-ui/react-edge"; | ||
export * from "./converters"; | ||
export * from "./dangerous-in-browser"; | ||
export { frontendTools } from "./frontendTools"; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -6,18 +6,8 @@ // src/index.ts | ||
export * from "./useCloudRuntime.js"; | ||
import { | ||
toLanguageModelMessages, | ||
toLanguageModelTools, | ||
fromLanguageModelMessages, | ||
fromLanguageModelTools, | ||
useDangerousInBrowserRuntime | ||
} from "@assistant-ui/react-edge"; | ||
export * from "./converters/index.js"; | ||
export * from "./dangerous-in-browser/index.js"; | ||
import { frontendTools } from "./frontendTools.js"; | ||
export { | ||
fromLanguageModelMessages, | ||
fromLanguageModelTools, | ||
frontendTools, | ||
toLanguageModelMessages, | ||
toLanguageModelTools, | ||
useDangerousInBrowserRuntime | ||
frontendTools | ||
}; | ||
//# sourceMappingURL=index.js.map |
@@ -1,4 +0,16 @@ | ||
import { EdgeRuntimeOptions } from "@assistant-ui/react-edge"; | ||
export type UseChatRuntimeOptions = Omit<EdgeRuntimeOptions, "unstable_AISDKInterop">; | ||
export declare const useChatRuntime: (options: UseChatRuntimeOptions) => import("@assistant-ui/react").AssistantRuntime; | ||
import { AssistantRuntime, LocalRuntimeOptions, ThreadMessage } from "@assistant-ui/react"; | ||
type HeadersValue = Record<string, string> | Headers; | ||
export type UseChatRuntimeOptions = { | ||
api: string; | ||
onResponse?: (response: Response) => void | Promise<void>; | ||
onFinish?: (message: ThreadMessage) => void; | ||
onError?: (error: Error) => void; | ||
onCancel?: () => void; | ||
credentials?: RequestCredentials; | ||
headers?: HeadersValue | (() => Promise<HeadersValue>); | ||
body?: object; | ||
sendExtraMessageFields?: boolean; | ||
} & LocalRuntimeOptions; | ||
export declare const useChatRuntime: (options: UseChatRuntimeOptions) => AssistantRuntime; | ||
export {}; | ||
//# sourceMappingURL=useChatRuntime.d.ts.map |
@@ -0,8 +1,102 @@ | ||
"use client"; | ||
// src/useChatRuntime.ts | ||
import { useEdgeRuntime } from "@assistant-ui/react-edge"; | ||
import { toLanguageModelMessages } from "./converters/index.js"; | ||
import { | ||
INTERNAL, | ||
useLocalRuntime | ||
} from "@assistant-ui/react"; | ||
import { z } from "zod"; | ||
import zodToJsonSchema from "zod-to-json-schema"; | ||
import { | ||
AssistantMessageAccumulator, | ||
DataStreamDecoder, | ||
unstable_toolResultStream | ||
} from "assistant-stream"; | ||
import { asAsyncIterableStream } from "assistant-stream/utils"; | ||
var { splitLocalRuntimeOptions } = INTERNAL; | ||
var toAISDKTools = (tools) => { | ||
return Object.fromEntries( | ||
Object.entries(tools).map(([name, tool]) => [ | ||
name, | ||
{ | ||
...tool.description ? { description: tool.description } : void 0, | ||
parameters: tool.parameters instanceof z.ZodType ? zodToJsonSchema(tool.parameters) : tool.parameters | ||
} | ||
]) | ||
); | ||
}; | ||
var getEnabledTools = (tools) => { | ||
return Object.fromEntries( | ||
Object.entries(tools).filter( | ||
([, tool]) => !tool.disabled && tool.type !== "backend" | ||
) | ||
); | ||
}; | ||
var ChatRuntimeAdapter = class { | ||
constructor(options) { | ||
this.options = options; | ||
} | ||
async *run({ | ||
messages, | ||
runConfig, | ||
abortSignal, | ||
context, | ||
unstable_assistantMessageId, | ||
unstable_getMessage | ||
}) { | ||
const headersValue = typeof this.options.headers === "function" ? await this.options.headers() : this.options.headers; | ||
abortSignal.addEventListener( | ||
"abort", | ||
() => { | ||
if (!abortSignal.reason?.detach) this.options.onCancel?.(); | ||
}, | ||
{ once: true } | ||
); | ||
const headers = new Headers(headersValue); | ||
headers.set("Content-Type", "application/json"); | ||
const result = await fetch(this.options.api, { | ||
method: "POST", | ||
headers, | ||
credentials: this.options.credentials ?? "same-origin", | ||
body: JSON.stringify({ | ||
system: context.system, | ||
messages: toLanguageModelMessages(messages, { | ||
unstable_includeId: this.options.sendExtraMessageFields | ||
}), | ||
tools: toAISDKTools( | ||
getEnabledTools(context.tools ?? {}) | ||
), | ||
...unstable_assistantMessageId ? { unstable_assistantMessageId } : {}, | ||
runConfig, | ||
state: unstable_getMessage().metadata.unstable_state || void 0, | ||
...context.callSettings, | ||
...context.config, | ||
...this.options.body | ||
}), | ||
signal: abortSignal | ||
}); | ||
await this.options.onResponse?.(result); | ||
try { | ||
if (!result.ok) { | ||
throw new Error(`Status ${result.status}: ${await result.text()}`); | ||
} | ||
if (!result.body) { | ||
throw new Error("Response body is null"); | ||
} | ||
const stream = result.body.pipeThrough(new DataStreamDecoder()).pipeThrough(unstable_toolResultStream(context.tools, abortSignal)).pipeThrough(new AssistantMessageAccumulator()); | ||
yield* asAsyncIterableStream(stream); | ||
this.options.onFinish?.(unstable_getMessage()); | ||
} catch (error) { | ||
this.options.onError?.(error); | ||
throw error; | ||
} | ||
} | ||
}; | ||
var useChatRuntime = (options) => { | ||
return useEdgeRuntime({ | ||
...options, | ||
unstable_AISDKInterop: "v2" | ||
}); | ||
const { localRuntimeOptions, otherOptions } = splitLocalRuntimeOptions(options); | ||
return useLocalRuntime( | ||
new ChatRuntimeAdapter(otherOptions), | ||
localRuntimeOptions | ||
); | ||
}; | ||
@@ -9,0 +103,0 @@ export { |
{ | ||
"name": "@assistant-ui/react-ai-sdk", | ||
"version": "0.10.15", | ||
"version": "0.10.16", | ||
"license": "MIT", | ||
@@ -21,2 +21,3 @@ "type": "module", | ||
"dependencies": { | ||
"@ai-sdk/provider": "^1.1.3", | ||
"@ai-sdk/react": "*", | ||
@@ -26,8 +27,10 @@ "@ai-sdk/ui-utils": "*", | ||
"@types/json-schema": "^7.0.15", | ||
"assistant-stream": "^0.2.19", | ||
"json-schema": "^0.4.0", | ||
"zod": "^3.25.67", | ||
"zustand": "^5.0.6", | ||
"@assistant-ui/react-edge": "0.2.13" | ||
"zod-to-json-schema": "^3.24.6", | ||
"zustand": "^5.0.6" | ||
}, | ||
"peerDependencies": { | ||
"@assistant-ui/react": "^0.10.25", | ||
"@assistant-ui/react": "^0.10.26", | ||
"@types/react": "*", | ||
@@ -48,2 +51,3 @@ "react": "^18 || ^19 || ^19.0.0-rc" | ||
"tsx": "^4.20.3", | ||
"@assistant-ui/react": "0.10.26", | ||
"@assistant-ui/x-buildutils": "0.0.1" | ||
@@ -50,0 +54,0 @@ }, |
@@ -5,10 +5,4 @@ export * from "./rsc"; | ||
export * from "./useCloudRuntime"; | ||
export { | ||
toLanguageModelMessages, | ||
toLanguageModelTools, | ||
fromLanguageModelMessages, | ||
fromLanguageModelTools, | ||
useDangerousInBrowserRuntime, | ||
} from "@assistant-ui/react-edge"; | ||
export * from "./converters"; | ||
export * from "./dangerous-in-browser"; | ||
export { frontendTools } from "./frontendTools"; |
@@ -1,13 +0,157 @@ | ||
import { EdgeRuntimeOptions, useEdgeRuntime } from "@assistant-ui/react-edge"; | ||
"use client"; | ||
export type UseChatRuntimeOptions = Omit< | ||
EdgeRuntimeOptions, | ||
"unstable_AISDKInterop" | ||
>; | ||
import { toLanguageModelMessages } from "./converters"; | ||
import { | ||
AssistantRuntime, | ||
ChatModelAdapter, | ||
ChatModelRunOptions, | ||
INTERNAL, | ||
LocalRuntimeOptions, | ||
ThreadMessage, | ||
Tool, | ||
useLocalRuntime, | ||
} from "@assistant-ui/react"; | ||
import { z } from "zod"; | ||
import zodToJsonSchema from "zod-to-json-schema"; | ||
import { JSONSchema7 } from "json-schema"; | ||
import { | ||
AssistantMessageAccumulator, | ||
DataStreamDecoder, | ||
unstable_toolResultStream, | ||
} from "assistant-stream"; | ||
import { asAsyncIterableStream } from "assistant-stream/utils"; | ||
export const useChatRuntime = (options: UseChatRuntimeOptions) => { | ||
return useEdgeRuntime({ | ||
...options, | ||
unstable_AISDKInterop: "v2", | ||
}); | ||
const { splitLocalRuntimeOptions } = INTERNAL; | ||
type HeadersValue = Record<string, string> | Headers; | ||
export type UseChatRuntimeOptions = { | ||
api: string; | ||
onResponse?: (response: Response) => void | Promise<void>; | ||
onFinish?: (message: ThreadMessage) => void; | ||
onError?: (error: Error) => void; | ||
onCancel?: () => void; | ||
credentials?: RequestCredentials; | ||
headers?: HeadersValue | (() => Promise<HeadersValue>); | ||
body?: object; | ||
sendExtraMessageFields?: boolean; | ||
} & LocalRuntimeOptions; | ||
type ChatRuntimeRequestOptions = { | ||
messages: any[]; | ||
tools: any; | ||
system?: string | undefined; | ||
runConfig?: any; | ||
unstable_assistantMessageId?: string; | ||
state?: any; | ||
}; | ||
const toAISDKTools = (tools: Record<string, Tool>) => { | ||
return Object.fromEntries( | ||
Object.entries(tools).map(([name, tool]) => [ | ||
name, | ||
{ | ||
...(tool.description ? { description: tool.description } : undefined), | ||
parameters: (tool.parameters instanceof z.ZodType | ||
? zodToJsonSchema(tool.parameters) | ||
: tool.parameters) as JSONSchema7, | ||
}, | ||
]), | ||
); | ||
}; | ||
const getEnabledTools = (tools: Record<string, Tool>) => { | ||
return Object.fromEntries( | ||
Object.entries(tools).filter( | ||
([, tool]) => !tool.disabled && tool.type !== "backend", | ||
), | ||
); | ||
}; | ||
class ChatRuntimeAdapter implements ChatModelAdapter { | ||
constructor( | ||
private options: Omit<UseChatRuntimeOptions, keyof LocalRuntimeOptions>, | ||
) {} | ||
async *run({ | ||
messages, | ||
runConfig, | ||
abortSignal, | ||
context, | ||
unstable_assistantMessageId, | ||
unstable_getMessage, | ||
}: ChatModelRunOptions) { | ||
const headersValue = | ||
typeof this.options.headers === "function" | ||
? await this.options.headers() | ||
: this.options.headers; | ||
abortSignal.addEventListener( | ||
"abort", | ||
() => { | ||
if (!abortSignal.reason?.detach) this.options.onCancel?.(); | ||
}, | ||
{ once: true }, | ||
); | ||
const headers = new Headers(headersValue); | ||
headers.set("Content-Type", "application/json"); | ||
const result = await fetch(this.options.api, { | ||
method: "POST", | ||
headers, | ||
credentials: this.options.credentials ?? "same-origin", | ||
body: JSON.stringify({ | ||
system: context.system, | ||
messages: toLanguageModelMessages(messages, { | ||
unstable_includeId: this.options.sendExtraMessageFields, | ||
}) as ChatRuntimeRequestOptions["messages"], | ||
tools: toAISDKTools( | ||
getEnabledTools(context.tools ?? {}), | ||
) as unknown as ChatRuntimeRequestOptions["tools"], | ||
...(unstable_assistantMessageId ? { unstable_assistantMessageId } : {}), | ||
runConfig, | ||
state: unstable_getMessage().metadata.unstable_state || undefined, | ||
...context.callSettings, | ||
...context.config, | ||
...this.options.body, | ||
} satisfies ChatRuntimeRequestOptions), | ||
signal: abortSignal, | ||
}); | ||
await this.options.onResponse?.(result); | ||
try { | ||
if (!result.ok) { | ||
throw new Error(`Status ${result.status}: ${await result.text()}`); | ||
} | ||
if (!result.body) { | ||
throw new Error("Response body is null"); | ||
} | ||
const stream = result.body | ||
.pipeThrough(new DataStreamDecoder()) | ||
.pipeThrough(unstable_toolResultStream(context.tools, abortSignal)) | ||
.pipeThrough(new AssistantMessageAccumulator()); | ||
yield* asAsyncIterableStream(stream); | ||
this.options.onFinish?.(unstable_getMessage()); | ||
} catch (error: unknown) { | ||
this.options.onError?.(error as Error); | ||
throw error; | ||
} | ||
} | ||
} | ||
export const useChatRuntime = ( | ||
options: UseChatRuntimeOptions, | ||
): AssistantRuntime => { | ||
const { localRuntimeOptions, otherOptions } = | ||
splitLocalRuntimeOptions(options); | ||
return useLocalRuntime( | ||
new ChatRuntimeAdapter(otherOptions), | ||
localRuntimeOptions, | ||
); | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
145206
79.48%138
40.82%2223
85.1%13
30%8
14.29%1
Infinity%4
-20%68
-1.45%+ Added
+ Added
+ Added
+ Added
- Removed
- Removed