feat: @llamaindex/server (#1759)

This commit is contained in:
Thuc Pham
2025-03-21 19:14:19 +07:00
committed by GitHub
parent 04f8c96caa
commit f8a86e4eff
28 changed files with 1257 additions and 8 deletions
+7
View File
@@ -0,0 +1,7 @@
---
"@llamaindex/server": patch
"@llamaindex/tools": patch
"@llamaindex/workflow": patch
---
feat: @llamaindex/server
+1
View File
@@ -0,0 +1 @@
server/
+41
View File
@@ -0,0 +1,41 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/versions
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*
# env files (can opt-in for committing if needed)
.env*
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
+3
View File
@@ -0,0 +1,3 @@
{
"trailingComma": "all"
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

+154
View File
@@ -0,0 +1,154 @@
@import "tailwindcss";
@source '../../node_modules/@llamaindex/chat-ui/**/*.{ts,tsx}';
@source '../app/**/*.{ts,tsx}';
@custom-variant dark (&:is(.dark *));
@theme {
--color-border: hsl(var(--border));
--color-input: hsl(var(--input));
--color-ring: hsl(var(--ring));
--color-background: hsl(var(--background));
--color-foreground: hsl(var(--foreground));
--color-primary: hsl(var(--primary));
--color-primary-foreground: hsl(var(--primary-foreground));
--color-secondary: hsl(var(--secondary));
--color-secondary-foreground: hsl(var(--secondary-foreground));
--color-destructive: hsl(var(--destructive));
--color-destructive-foreground: hsl(var(--destructive-foreground));
--color-muted: hsl(var(--muted));
--color-muted-foreground: hsl(var(--muted-foreground));
--color-accent: hsl(var(--accent));
--color-accent-foreground: hsl(var(--accent-foreground));
--color-popover: hsl(var(--popover));
--color-popover-foreground: hsl(var(--popover-foreground));
--color-card: hsl(var(--card));
--color-card-foreground: hsl(var(--card-foreground));
--radius-xl: calc(var(--radius) + 4px);
--radius-lg: var(--radius);
--radius-md: calc(var(--radius) - 2px);
--radius-sm: calc(var(--radius) - 4px);
--font-sans:
var(--font-sans), ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji",
"Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
--animate-accordion-down: accordion-down 0.2s ease-out;
--animate-accordion-up: accordion-up 0.2s ease-out;
--background-image-glow-conic:
radial-gradient(at 21% 11%, rgba(186, 186, 233, 0.53) 0, transparent 50%),
radial-gradient(at 85% 0, hsla(46, 57%, 78%, 0.52) 0, transparent 50%),
radial-gradient(at 91% 36%, rgba(194, 213, 255, 0.68) 0, transparent 50%),
radial-gradient(at 8% 40%, rgba(251, 218, 239, 0.46) 0, transparent 50%);
@keyframes accordion-down {
from {
height: 0;
}
to {
height: var(--radix-accordion-content-height);
}
}
@keyframes accordion-up {
from {
height: var(--radix-accordion-content-height);
}
to {
height: 0;
}
}
}
/*
The default border color has changed to `currentColor` in Tailwind CSS v4,
so we've added these compatibility styles to make sure everything still
looks the same as it did with Tailwind CSS v3.
If we ever want to remove these styles, we need to add an explicit border
color utility to any element that depends on these defaults.
*/
@layer base {
*,
::after,
::before,
::backdrop,
::file-selector-button {
border-color: var(--color-gray-200, currentColor);
}
}
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 240 10% 3.9%;
--card: 0 0% 100%;
--card-foreground: 240 10% 3.9%;
--popover: 0 0% 100%;
--popover-foreground: 240 10% 3.9%;
--primary: 240 5.9% 10%;
--primary-foreground: 0 0% 98%;
--secondary: 240 4.8% 95.9%;
--secondary-foreground: 240 5.9% 10%;
--muted: 240 4.8% 95.9%;
--muted-foreground: 240 3.8% 46.1%;
--accent: 240 4.8% 95.9%;
--accent-foreground: 240 5.9% 10%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 0 0% 98%;
--border: 240 5.9% 90%;
--input: 240 5.9% 90%;
--ring: 240 10% 3.9%;
--radius: 0.5rem;
--chart-1: 12 76% 61%;
--chart-2: 173 58% 39%;
--chart-3: 197 37% 24%;
--chart-4: 43 74% 66%;
--chart-5: 27 87% 67%;
}
.dark {
--background: 240 10% 3.9%;
--foreground: 0 0% 98%;
--card: 240 10% 3.9%;
--card-foreground: 0 0% 98%;
--popover: 240 10% 3.9%;
--popover-foreground: 0 0% 98%;
--primary: 0 0% 98%;
--primary-foreground: 240 5.9% 10%;
--secondary: 240 3.7% 15.9%;
--secondary-foreground: 0 0% 98%;
--muted: 240 3.7% 15.9%;
--muted-foreground: 240 5% 64.9%;
--accent: 240 3.7% 15.9%;
--accent-foreground: 0 0% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 0 0% 98%;
--border: 240 3.7% 15.9%;
--input: 240 3.7% 15.9%;
--ring: 240 4.9% 83.9%;
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
}
}
+20
View File
@@ -0,0 +1,20 @@
import type { Metadata } from "next";
import "./globals.css";
export const metadata: Metadata = {
title: "LlamaIndex Server",
description: "LlamaIndex Server UI",
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body>{children}</body>
<script async src="./config.js"></script>
</html>
);
}
+29
View File
@@ -0,0 +1,29 @@
"use client";
import { ChatSection } from "@llamaindex/chat-ui";
import { useChat } from "ai/react";
import { getConfig } from "./utils";
export default function Page() {
const handler = useChat({
api: getConfig("CHAT_API"),
onError: (error: unknown) => {
if (!(error instanceof Error)) throw error;
let errorMessage: string;
try {
errorMessage = JSON.parse(error.message).detail;
} catch (e) {
console.error(e);
errorMessage = error.message;
}
alert(errorMessage);
},
});
return (
<div className="flex h-screen items-center justify-center">
<ChatSection
className="h-[72vh] w-[72vw] rounded-2xl shadow-2xl"
handler={handler}
/>
</div>
);
}
+7
View File
@@ -0,0 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
"use client";
export const getConfig = (name: string) => {
if (typeof window === "undefined") return undefined;
return (window as any).LLAMAINDEX?.[name];
};
+16
View File
@@ -0,0 +1,16 @@
import { dirname } from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
});
const eslintConfig = [
...compat.extends("next/core-web-vitals", "next/typescript"),
];
export default eslintConfig;
+7
View File
@@ -0,0 +1,7 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
output: "export",
};
export default nextConfig;
+5
View File
@@ -0,0 +1,5 @@
const config = {
plugins: ["@tailwindcss/postcss"],
};
export default config;
+5
View File
@@ -0,0 +1,5 @@
// Override the window.LLAMAINDEX object to customize frontend
window.LLAMAINDEX = {
CHAT_API: "/api/chat",
};
+33
View File
@@ -0,0 +1,33 @@
{
"compilerOptions": {
"target": "ES2017",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": [
"**/*.ts",
"**/*.tsx",
".next/types/**/*.ts",
"next-env.d.ts",
"../.next/types/**/*.ts"
],
"exclude": ["node_modules"]
}
+61
View File
@@ -0,0 +1,61 @@
{
"name": "@llamaindex/server",
"description": "LlamaIndex Server",
"version": "0.0.1",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"exports": {
".": {
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
},
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
}
}
},
"files": [
"dist",
"server"
],
"repository": {
"type": "git",
"url": "git+https://github.com/run-llama/LlamaIndexTS.git",
"directory": "packages/server"
},
"scripts": {
"clean": "rm -rf ./dist ./server next/.next next/out",
"prebuild": "pnpm clean",
"build": "bunchee",
"postbuild": "pnpm copy:next-src && pnpm build:static && pnpm copy:static",
"copy:next-src": "cp -r ./next ./server",
"build:static": "cd ./next && next build",
"copy:static": "cp -r ./next/out ./dist/static",
"dev": "bunchee --watch"
},
"devDependencies": {
"bunchee": "6.4.0",
"vitest": "^2.1.5",
"@types/node": "^22.9.0",
"@types/react": "^19",
"@types/react-dom": "^19",
"@tailwindcss/postcss": "^4",
"tailwindcss": "^4",
"eslint": "^9",
"eslint-config-next": "15.2.3",
"@eslint/eslintrc": "^3",
"tsx": "^4.19.3"
},
"dependencies": {
"@llamaindex/workflow": "workspace:*",
"@llamaindex/core": "workspace:*",
"@llamaindex/chat-ui": "0.3.1",
"ai": "^4.2.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"next": "15.2.3"
}
}
+42
View File
@@ -0,0 +1,42 @@
import type { ChatMessage } from "@llamaindex/core/llms";
import { type Message } from "ai";
import { IncomingMessage, ServerResponse } from "http";
import type { WorkflowFactory } from "../types";
import {
parseRequestBody,
pipeStreamToResponse,
sendJSONResponse,
} from "../utils/request";
import { runWorkflow } from "../utils/workflow";
export const handleChat = async (
workflowFactory: WorkflowFactory,
req: IncomingMessage,
res: ServerResponse,
) => {
try {
const body = await parseRequestBody(req);
const { messages } = body as { messages: Message[] };
const lastMessage = messages[messages.length - 1];
if (lastMessage?.role !== "user") {
return sendJSONResponse(res, 400, {
error: "Messages cannot be empty and last message must be from user",
});
}
const workflow = await workflowFactory(body);
const stream = await runWorkflow(workflow, {
userInput: lastMessage.content,
chatHistory: messages.slice(0, -1) as ChatMessage[],
});
pipeStreamToResponse(res, stream);
} catch (error) {
console.error("Chat error:", error);
return sendJSONResponse(res, 500, {
detail: (error as Error).message || "Internal server error",
});
}
};
+23
View File
@@ -0,0 +1,23 @@
import fs from "fs";
import type { IncomingMessage, ServerResponse } from "http";
import { promisify } from "util";
import { sendJSONResponse } from "../utils/request";
export const handleServeFiles = async (
req: IncomingMessage,
res: ServerResponse,
pathname: string,
) => {
const filePath = pathname.substring("/api/files/".length);
if (!filePath.startsWith("output")) {
return sendJSONResponse(res, 400, { error: "No permission" });
}
const decodedFilePath = decodeURIComponent(filePath);
const fileExists = await promisify(fs.exists)(decodedFilePath);
if (fileExists) {
const fileStream = fs.createReadStream(decodedFilePath);
fileStream.pipe(res);
} else {
return sendJSONResponse(res, 404, { error: "File not found" });
}
};
+2
View File
@@ -0,0 +1,2 @@
export * from "./server";
export * from "./types";
+45
View File
@@ -0,0 +1,45 @@
import { createServer } from "http";
import next from "next";
import path from "path";
import { parse } from "url";
import { handleChat } from "./handlers/chat";
import { handleServeFiles } from "./handlers/files";
import type { LlamaIndexServerOptions, ServerWorkflow } from "./types";
export class LlamaIndexServer {
port: number;
app: ReturnType<typeof next>;
workflowFactory: () => Promise<ServerWorkflow> | ServerWorkflow;
constructor({ workflow, ...nextAppOptions }: LlamaIndexServerOptions) {
const nextDir = path.join(__dirname, "../server");
const dev = process.env.NODE_ENV !== "production";
this.app = next({ ...nextAppOptions, dev, dir: nextDir });
this.port = nextAppOptions.port ?? 3000;
this.workflowFactory = workflow;
}
async start() {
await this.app.prepare();
const server = createServer((req, res) => {
const parsedUrl = parse(req.url!, true);
const pathname = parsedUrl.pathname;
if (pathname === "/api/chat" && req.method === "POST") {
return handleChat(this.workflowFactory, req, res);
}
if (pathname?.startsWith("/api/files") && req.method === "GET") {
return handleServeFiles(req, res, pathname);
}
const handle = this.app.getRequestHandler();
handle(req, res, parsedUrl);
});
server.listen(this.port, () => {
console.log(`> Server listening at http://localhost:${this.port}`);
});
}
}
+25
View File
@@ -0,0 +1,25 @@
import { Workflow, type AgentWorkflowContext } from "@llamaindex/workflow";
import type { AgentInputData, AgentWorkflow } from "@llamaindex/workflow/agent";
import type next from "next";
/**
* ServerWorkflow can be either a custom Workflow or an AgentWorkflow
*/
export type ServerWorkflow =
| Workflow<AgentWorkflowContext, AgentInputData, string>
| AgentWorkflow;
/**
* A factory function that creates a ServerWorkflow instance, possibly asynchronously.
* The requestBody parameter is the body from the request, which can be used to customize the workflow per request.
*/
export type WorkflowFactory = (
// eslint-disable-next-line @typescript-eslint/no-explicit-any
requestBody?: any,
) => Promise<ServerWorkflow> | ServerWorkflow;
export type NextAppOptions = Omit<Parameters<typeof next>[0], "dir">;
export type LlamaIndexServerOptions = NextAppOptions & {
workflow: WorkflowFactory;
};
+41
View File
@@ -0,0 +1,41 @@
import type { IncomingMessage, ServerResponse } from "http";
export async function parseRequestBody(request: IncomingMessage) {
const body = new Promise((resolve) => {
const bodyParts: Buffer[] = [];
let body: string;
request
.on("data", (chunk) => {
bodyParts.push(chunk);
})
.on("end", () => {
body = Buffer.concat(bodyParts).toString();
resolve(body);
});
}) as Promise<string>;
const data = await body;
return JSON.parse(data);
}
export function sendJSONResponse(
response: ServerResponse,
statusCode: number,
body: Record<string, unknown> | string,
) {
response.statusCode = statusCode;
response.setHeader("Content-Type", "application/json");
response.end(typeof body === "string" ? body : JSON.stringify(body));
}
export async function pipeStreamToResponse(
response: ServerResponse,
stream: Response,
) {
if (!stream.body) return;
const reader = stream.body.getReader();
while (true) {
const { done, value } = await reader.read();
if (done) return response.end();
response.write(value);
}
}
+85
View File
@@ -0,0 +1,85 @@
import type { ChatResponseChunk } from "@llamaindex/core/llms";
import type { EngineResponse } from "@llamaindex/core/schema";
import {
StopEvent,
Workflow,
type AgentWorkflowContext,
} from "@llamaindex/workflow";
import {
AgentStream,
AgentWorkflow,
type AgentInputData,
} from "@llamaindex/workflow/agent";
import { LlamaIndexAdapter, StreamData, type JSONValue } from "ai";
import { ReadableStream } from "stream/web";
import type { ServerWorkflow } from "../types";
export async function runWorkflow(
workflow: ServerWorkflow,
agentInput: AgentInputData,
) {
if (workflow instanceof AgentWorkflow) {
return runAgentWorkflow(workflow, agentInput);
}
return runCustomWorkflow(workflow, agentInput);
}
async function runAgentWorkflow(
workflow: AgentWorkflow,
agentInput: AgentInputData,
) {
const { userInput = "", chatHistory = [] } = agentInput;
const context = workflow.run(userInput, { chatHistory });
const dataStream = new StreamData();
const stream = new ReadableStream<EngineResponse>({
async pull(controller) {
for await (const event of context) {
if (event instanceof AgentStream) {
// for agent workflow, get the delta from AgentStream event and enqueue it
const delta = event.data.delta;
if (delta) {
controller.enqueue({ delta } as EngineResponse);
}
} else {
dataStream.appendMessageAnnotation(event.data as JSONValue);
}
}
controller.close();
dataStream.close();
},
});
return LlamaIndexAdapter.toDataStreamResponse(stream, { data: dataStream });
}
async function runCustomWorkflow(
workflow: Workflow<AgentWorkflowContext, AgentInputData, string>,
agentInput: AgentInputData,
) {
const context = workflow.run(agentInput);
const dataStream = new StreamData();
const stream = new ReadableStream<EngineResponse>({
async pull(controller) {
for await (const event of context) {
if (event instanceof StopEvent) {
// for normal workflow, the event data from StopEvent is a generator of ChatResponseChunk
// iterate over the generator and enqueue the delta of each chunk
const generator = event.data as AsyncGenerator<ChatResponseChunk>;
for await (const chunk of generator) {
controller.enqueue({ delta: chunk.delta } as EngineResponse);
}
} else {
// append data of other events to the data stream as message annotations
dataStream.appendMessageAnnotation(event.data as JSONValue);
}
}
controller.close();
dataStream.close();
},
});
return LlamaIndexAdapter.toDataStreamResponse(stream, { data: dataStream });
}
+15
View File
@@ -0,0 +1,15 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"rootDir": "./src",
"outDir": "./dist/type",
"tsBuildInfoFile": "./dist/.tsbuildinfo",
"emitDeclarationOnly": true,
"moduleResolution": "Bundler",
"skipLibCheck": true,
"strict": true,
"types": ["node"]
},
"include": ["./src"],
"exclude": ["node_modules"]
}
+2
View File
@@ -7,3 +7,5 @@ export * from "./tools/interpreter";
export * from "./tools/openapi-action";
export * from "./tools/weather";
export * from "./tools/wiki";
export * from "./tool-call";
+245
View File
@@ -0,0 +1,245 @@
import { callTool } from "@llamaindex/core/agent";
import {
type BaseToolWithCall,
type ChatMessage,
type ChatResponse,
type ChatResponseChunk,
type PartialToolCall,
type ToolCall,
ToolCallLLM,
type ToolCallLLMMessageOptions,
} from "@llamaindex/core/llms";
export async function callTools({
tools,
toolCalls,
writeEvent,
}: {
toolCalls: ToolCall[];
tools: BaseToolWithCall[];
writeEvent?: (text: string, step: number) => void;
}): Promise<ChatMessage[]> {
if (toolCalls.length === 0) return [];
const toolMsgs: ChatMessage[] = [];
const totalSteps = toolCalls.length;
for (let step = 0; step < totalSteps; step++) {
const toolCall = toolCalls[step]!;
const tool = tools.find((tool) => tool.metadata.name === toolCall.name);
if (!tool) throw new Error(`Tool ${toolCall.name} not found`);
const toolMsg = await callSingleTool(tool, toolCall, (text) => {
writeEvent?.(text, step);
});
toolMsgs.push(toolMsg);
}
return toolMsgs;
}
export async function callSingleTool(
tool: BaseToolWithCall,
toolCall: ToolCall,
eventEmitter?: (msg: string) => void,
): Promise<ChatMessage> {
if (eventEmitter) {
eventEmitter(
`Calling tool ${toolCall.name} with input: ${JSON.stringify(toolCall.input)}`,
);
}
const toolOutput = await callTool(tool, toolCall, {
log: () => {},
error: (...args: unknown[]) => {
console.error(`Tool ${toolCall.name} got error:`, ...args);
if (eventEmitter) {
eventEmitter(`Tool ${toolCall.name} got error: ${args.join(" ")}`);
}
return {
content: JSON.stringify({
error: args.join(" "),
}),
role: "user",
options: {
toolResult: {
id: toolCall.id,
result: JSON.stringify({
error: args.join(" "),
}),
isError: true,
},
},
};
},
warn: () => {},
});
return {
content: JSON.stringify(toolOutput.output),
role: "user",
options: {
toolResult: {
result: toolOutput.output,
isError: toolOutput.isError,
id: toolCall.id,
},
},
};
}
class ChatWithToolsResponse {
toolCalls: ToolCall[];
toolCallMessage?: ChatMessage;
responseGenerator?: AsyncGenerator<ChatResponseChunk>;
constructor(options: {
toolCalls: ToolCall[];
toolCallMessage?: ChatMessage;
responseGenerator?: AsyncGenerator<ChatResponseChunk>;
}) {
this.toolCalls = options.toolCalls;
if (options.toolCallMessage) {
this.toolCallMessage = options.toolCallMessage;
}
if (options.responseGenerator) {
this.responseGenerator = options.responseGenerator;
}
}
hasMultipleTools() {
const uniqueToolNames = new Set(this.getToolNames());
return uniqueToolNames.size > 1;
}
hasToolCall() {
return this.toolCalls.length > 0;
}
getToolNames() {
return this.toolCalls.map((toolCall) => toolCall.name);
}
async asFullResponse(): Promise<ChatMessage> {
if (!this.responseGenerator) {
throw new Error("No response generator");
}
let fullResponse = "";
for await (const chunk of this.responseGenerator) {
fullResponse += chunk.delta;
}
return {
role: "user",
content: fullResponse,
};
}
}
export const chatWithTools = async (
llm: ToolCallLLM,
tools: BaseToolWithCall[],
messages: ChatMessage[],
): Promise<ChatWithToolsResponse> => {
const responseGenerator = async function* (): AsyncGenerator<
boolean | ChatResponseChunk,
void,
unknown
> {
const responseStream = await llm.chat({ messages, tools, stream: true });
let fullResponse = null;
let yieldedIndicator = false;
const toolCallMap = new Map();
for await (const chunk of responseStream) {
const hasToolCalls = chunk.options && "toolCall" in chunk.options;
if (!hasToolCalls) {
if (!yieldedIndicator) {
yield false;
yieldedIndicator = true;
}
yield chunk;
} else if (!yieldedIndicator) {
yield true;
yieldedIndicator = true;
}
if (chunk.options && "toolCall" in chunk.options) {
for (const toolCall of chunk.options.toolCall as PartialToolCall[]) {
if (toolCall.id) {
toolCallMap.set(toolCall.id, toolCall);
}
}
}
if (
hasToolCalls &&
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(chunk.raw as any)?.choices?.[0]?.finish_reason !== null
) {
// Update the fullResponse with the tool calls
const toolCalls = Array.from(toolCallMap.values());
fullResponse = {
...chunk,
options: {
...chunk.options,
toolCall: toolCalls,
},
};
}
}
if (fullResponse) {
yield fullResponse;
}
};
const generator = responseGenerator();
const isToolCall = await generator.next();
if (isToolCall.value) {
// If it's a tool call, we need to wait for the full response
let fullResponse = null;
for await (const chunk of generator) {
fullResponse = chunk;
}
if (fullResponse) {
const responseChunk = fullResponse as ChatResponseChunk;
const toolCalls = getToolCallsFromResponse(responseChunk);
return new ChatWithToolsResponse({
toolCalls,
toolCallMessage: {
options: responseChunk.options,
role: "assistant",
content: "",
},
});
} else {
throw new Error("Cannot get tool calls from response");
}
}
return new ChatWithToolsResponse({
toolCalls: [],
responseGenerator: generator as AsyncGenerator<ChatResponseChunk>,
});
};
export const getToolCallsFromResponse = (
response:
| ChatResponse<ToolCallLLMMessageOptions>
| ChatResponseChunk<ToolCallLLMMessageOptions>,
): ToolCall[] => {
let options;
if ("message" in response) {
options = response.message.options;
} else {
options = response.options;
}
if (options && "toolCall" in options) {
return options.toolCall as ToolCall[];
}
return [];
};
+1
View File
@@ -1,3 +1,4 @@
export { type AgentWorkflowContext } from "./agent/base.js";
export {
WorkflowContext,
type HandlerContext,
+339 -8
View File
@@ -1734,6 +1734,64 @@ importers:
specifier: ^13.4.8
version: 13.4.8
packages/server:
dependencies:
'@llamaindex/chat-ui':
specifier: 0.3.1
version: 0.3.1(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@llamaindex/core':
specifier: workspace:*
version: link:../core
'@llamaindex/workflow':
specifier: workspace:*
version: link:../workflow
ai:
specifier: ^4.2.0
version: 4.2.0(react@19.0.0)(zod@3.24.2)
next:
specifier: 15.2.3
version: 15.2.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
react:
specifier: ^19.0.0
version: 19.0.0
react-dom:
specifier: ^19.0.0
version: 19.0.0(react@19.0.0)
devDependencies:
'@eslint/eslintrc':
specifier: ^3
version: 3.3.0
'@tailwindcss/postcss':
specifier: ^4
version: 4.0.9
'@types/node':
specifier: ^22.9.0
version: 22.9.0
'@types/react':
specifier: ^19
version: 19.0.10
'@types/react-dom':
specifier: ^19
version: 19.0.4(@types/react@19.0.10)
bunchee:
specifier: 6.4.0
version: 6.4.0(typescript@5.7.3)
eslint:
specifier: ^9
version: 9.22.0(jiti@2.4.2)
eslint-config-next:
specifier: 15.2.3
version: 15.2.3(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3)
tailwindcss:
specifier: ^4
version: 4.0.9
tsx:
specifier: ^4.19.3
version: 4.19.3
vitest:
specifier: ^2.1.5
version: 2.1.5(@edge-runtime/vm@4.0.4)(@types/node@22.9.0)(happy-dom@15.11.7)(lightningcss@1.29.1)(msw@2.7.0(@types/node@22.9.0)(typescript@5.7.3))(terser@5.38.2)
packages/tools:
dependencies:
'@apidevtools/swagger-parser':
@@ -1917,6 +1975,12 @@ packages:
zod:
optional: true
'@ai-sdk/provider-utils@2.2.0':
resolution: {integrity: sha512-RX5BnDSqudjvZjwwpROcxVQElyX7rUn/xImBgaZLXekSGqq8f7/tefqDcQiRbDZjuCd4CVIfhrK8y/Pta8cPfQ==}
engines: {node: '>=18'}
peerDependencies:
zod: ^3.23.8
'@ai-sdk/provider@0.0.26':
resolution: {integrity: sha512-dQkfBDs2lTYpKM8389oopPdQgIU007GQyCbuPPrV+K6MtSII3HBfE0stUIMXUb44L+LK1t6GXPP7wjSzjO6uKg==}
engines: {node: '>=18'}
@@ -1925,6 +1989,10 @@ packages:
resolution: {integrity: sha512-q1PJEZ0qD9rVR+8JFEd01/QM++csMT5UVwYXSN2u54BrVw/D8TZLTeg2FEfKK00DgAx0UtWd8XOhhwITP9BT5g==}
engines: {node: '>=18'}
'@ai-sdk/provider@1.1.0':
resolution: {integrity: sha512-0M+qjp+clUD0R1E5eWQFhxEvWLNaOtGQRUaBn8CUABnSKredagq92hUS9VjOzGsTm37xLfpaxl97AVtbeOsHew==}
engines: {node: '>=18'}
'@ai-sdk/react@0.0.70':
resolution: {integrity: sha512-GnwbtjW4/4z7MleLiW+TOZC2M29eCg1tOUpuEiYFMmFNZK8mkrqM0PFZMo6UsYeUYMWqEOOcPOU9OQVJMJh7IQ==}
engines: {node: '>=18'}
@@ -1949,6 +2017,16 @@ packages:
zod:
optional: true
'@ai-sdk/react@1.2.0':
resolution: {integrity: sha512-fUTZkAsxOMz8ijjWf87E/GfYkgsH4V5MH2yuj7EXh5ShjWe/oayn2ZJkyoqFMr4Jf8m5kptDaivmbIenDq5OXA==}
engines: {node: '>=18'}
peerDependencies:
react: ^18 || ^19 || ^19.0.0-rc
zod: ^3.23.8
peerDependenciesMeta:
zod:
optional: true
'@ai-sdk/solid@0.0.54':
resolution: {integrity: sha512-96KWTVK+opdFeRubqrgaJXoNiDP89gNxFRWUp0PJOotZW816AbhUf4EnDjBjXTLjXL1n0h8tGSE9sZsRkj9wQQ==}
engines: {node: '>=18'}
@@ -1985,6 +2063,12 @@ packages:
zod:
optional: true
'@ai-sdk/ui-utils@1.2.0':
resolution: {integrity: sha512-0IZwCqe7E+GkCASTDPAbzMr+POm9GDzWvFd37FvzpOeKNeibmge/LZEkTDbGSa+3b928H8wPwOLsOXBWPLUPDQ==}
engines: {node: '>=18'}
peerDependencies:
zod: ^3.23.8
'@ai-sdk/vue@0.0.59':
resolution: {integrity: sha512-+ofYlnqdc8c4F6tM0IKF0+7NagZRAiqBJpGDJ+6EYhDW8FHLUP/JFBgu32SjxSxC6IKFZxEnl68ZoP/Z38EMlw==}
engines: {node: '>=18'}
@@ -3592,6 +3676,11 @@ packages:
peerDependencies:
react: ^18.2.0 || ^19.0.0 || ^19.0.0-rc
'@llamaindex/chat-ui@0.3.1':
resolution: {integrity: sha512-sF6axN9LviewAxvBbqkF3u3K0yvIt74prio7uiVruFVT/AYkRlIk721QXTPBscf+ZvyzAqjh0Nx0BoGiZUzBCw==}
peerDependencies:
react: ^18.2.0 || ^19.0.0 || ^19.0.0-rc
'@llamaindex/pdf-viewer@1.3.0':
resolution: {integrity: sha512-HJtjzmxn+erb3Vq89W5atPq0q6uyZMMCgzOnmstxudzaHW/Yj1dp1ojCuBh/wlP1tUnIRoe9RmvC0ahmqSwRUA==}
peerDependencies:
@@ -3742,9 +3831,15 @@ packages:
'@next/env@15.2.1':
resolution: {integrity: sha512-JmY0qvnPuS2NCWOz2bbby3Pe0VzdAQ7XpEB6uLIHmtXNfAsAO0KLQLkuAoc42Bxbo3/jMC3dcn9cdf+piCcG2Q==}
'@next/env@15.2.3':
resolution: {integrity: sha512-a26KnbW9DFEUsSxAxKBORR/uD9THoYoKbkpFywMN/AFvboTt94b8+g/07T8J6ACsdLag8/PDU60ov4rPxRAixw==}
'@next/eslint-plugin-next@15.1.0':
resolution: {integrity: sha512-+jPT0h+nelBT6HC9ZCHGc7DgGVy04cv4shYdAe6tKlEbjQUtwU3LzQhzbDHQyY2m6g39m6B0kOFVuLGBrxxbGg==}
'@next/eslint-plugin-next@15.2.3':
resolution: {integrity: sha512-eNSOIMJtjs+dp4Ms1tB1PPPJUQHP3uZK+OQ7iFY9qXpGO6ojT6imCL+KcUOqE/GXGidWbBZJzYdgAdPHqeCEPA==}
'@next/swc-darwin-arm64@15.2.0':
resolution: {integrity: sha512-rlp22GZwNJjFCyL7h5wz9vtpBVuCt3ZYjFWpEPBGzG712/uL1bbSkS675rVAUCRZ4hjoTJ26Q7IKhr5DfJrHDA==}
engines: {node: '>= 10'}
@@ -3757,6 +3852,12 @@ packages:
cpu: [arm64]
os: [darwin]
'@next/swc-darwin-arm64@15.2.3':
resolution: {integrity: sha512-uaBhA8aLbXLqwjnsHSkxs353WrRgQgiFjduDpc7YXEU0B54IKx3vU+cxQlYwPCyC8uYEEX7THhtQQsfHnvv8dw==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
'@next/swc-darwin-x64@15.2.0':
resolution: {integrity: sha512-DiU85EqSHogCz80+sgsx90/ecygfCSGl5P3b4XDRVZpgujBm5lp4ts7YaHru7eVTyZMjHInzKr+w0/7+qDrvMA==}
engines: {node: '>= 10'}
@@ -3769,6 +3870,12 @@ packages:
cpu: [x64]
os: [darwin]
'@next/swc-darwin-x64@15.2.3':
resolution: {integrity: sha512-pVwKvJ4Zk7h+4hwhqOUuMx7Ib02u3gDX3HXPKIShBi9JlYllI0nU6TWLbPT94dt7FSi6mSBhfc2JrHViwqbOdw==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
'@next/swc-linux-arm64-gnu@15.2.0':
resolution: {integrity: sha512-VnpoMaGukiNWVxeqKHwi8MN47yKGyki5q+7ql/7p/3ifuU2341i/gDwGK1rivk0pVYbdv5D8z63uu9yMw0QhpQ==}
engines: {node: '>= 10'}
@@ -3781,6 +3888,12 @@ packages:
cpu: [arm64]
os: [linux]
'@next/swc-linux-arm64-gnu@15.2.3':
resolution: {integrity: sha512-50ibWdn2RuFFkOEUmo9NCcQbbV9ViQOrUfG48zHBCONciHjaUKtHcYFiCwBVuzD08fzvzkWuuZkd4AqbvKO7UQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@next/swc-linux-arm64-musl@15.2.0':
resolution: {integrity: sha512-ka97/ssYE5nPH4Qs+8bd8RlYeNeUVBhcnsNUmFM6VWEob4jfN9FTr0NBhXVi1XEJpj3cMfgSRW+LdE3SUZbPrw==}
engines: {node: '>= 10'}
@@ -3793,6 +3906,12 @@ packages:
cpu: [arm64]
os: [linux]
'@next/swc-linux-arm64-musl@15.2.3':
resolution: {integrity: sha512-2gAPA7P652D3HzR4cLyAuVYwYqjG0mt/3pHSWTCyKZq/N/dJcUAEoNQMyUmwTZWCJRKofB+JPuDVP2aD8w2J6Q==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@next/swc-linux-x64-gnu@15.2.0':
resolution: {integrity: sha512-zY1JduE4B3q0k2ZCE+DAF/1efjTXUsKP+VXRtrt/rJCTgDlUyyryx7aOgYXNc1d8gobys/Lof9P9ze8IyRDn7Q==}
engines: {node: '>= 10'}
@@ -3805,6 +3924,12 @@ packages:
cpu: [x64]
os: [linux]
'@next/swc-linux-x64-gnu@15.2.3':
resolution: {integrity: sha512-ODSKvrdMgAJOVU4qElflYy1KSZRM3M45JVbeZu42TINCMG3anp7YCBn80RkISV6bhzKwcUqLBAmOiWkaGtBA9w==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@next/swc-linux-x64-musl@15.2.0':
resolution: {integrity: sha512-QqvLZpurBD46RhaVaVBepkVQzh8xtlUN00RlG4Iq1sBheNugamUNPuZEH1r9X1YGQo1KqAe1iiShF0acva3jHQ==}
engines: {node: '>= 10'}
@@ -3817,6 +3942,12 @@ packages:
cpu: [x64]
os: [linux]
'@next/swc-linux-x64-musl@15.2.3':
resolution: {integrity: sha512-ZR9kLwCWrlYxwEoytqPi1jhPd1TlsSJWAc+H/CJHmHkf2nD92MQpSRIURR1iNgA/kuFSdxB8xIPt4p/T78kwsg==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@next/swc-win32-arm64-msvc@15.2.0':
resolution: {integrity: sha512-ODZ0r9WMyylTHAN6pLtvUtQlGXBL9voljv6ujSlcsjOxhtXPI1Ag6AhZK0SE8hEpR1374WZZ5w33ChpJd5fsjw==}
engines: {node: '>= 10'}
@@ -3829,6 +3960,12 @@ packages:
cpu: [arm64]
os: [win32]
'@next/swc-win32-arm64-msvc@15.2.3':
resolution: {integrity: sha512-+G2FrDcfm2YDbhDiObDU/qPriWeiz/9cRR0yMWJeTLGGX6/x8oryO3tt7HhodA1vZ8r2ddJPCjtLcpaVl7TE2Q==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [win32]
'@next/swc-win32-x64-msvc@15.2.0':
resolution: {integrity: sha512-8+4Z3Z7xa13NdUuUAcpVNA6o76lNPniBd9Xbo02bwXQXnZgFvEopwY2at5+z7yHl47X9qbZpvwatZ2BRo3EdZw==}
engines: {node: '>= 10'}
@@ -3841,6 +3978,12 @@ packages:
cpu: [x64]
os: [win32]
'@next/swc-win32-x64-msvc@15.2.3':
resolution: {integrity: sha512-gHYS9tc+G2W0ZC8rBL+H6RdtXIyk40uLiaos0yj5US85FNhbFEndMA2nW3z47nzOWiSvXTZ5kBClc3rD0zJg0w==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@@ -6006,6 +6149,16 @@ packages:
zod:
optional: true
ai@4.2.0:
resolution: {integrity: sha512-3xJWzBZpBS3n/UY360IopufV5dpfgYoY08eCAV2A2m7CcyJxVOAQ4lXvBGSsB+mR+BYJ8Y/JOesFfc0+k4jz3A==}
engines: {node: '>=18'}
peerDependencies:
react: ^18 || ^19 || ^19.0.0-rc
zod: ^3.23.8
peerDependenciesMeta:
react:
optional: true
ajv-draft-04@1.0.0:
resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==}
peerDependencies:
@@ -7169,6 +7322,15 @@ packages:
typescript:
optional: true
eslint-config-next@15.2.3:
resolution: {integrity: sha512-VDQwbajhNMFmrhLWVyUXCqsGPN+zz5G8Ys/QwFubfsxTIrkqdx3N3x3QPW+pERz8bzGPP0IgEm8cNbZcd8PFRQ==}
peerDependencies:
eslint: ^7.23.0 || ^8.0.0 || ^9.0.0
typescript: '>=3.3.1'
peerDependenciesMeta:
typescript:
optional: true
eslint-config-prettier@9.1.0:
resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==}
hasBin: true
@@ -9598,6 +9760,27 @@ packages:
sass:
optional: true
next@15.2.3:
resolution: {integrity: sha512-x6eDkZxk2rPpu46E1ZVUWIBhYCLszmUY6fvHBFcbzJ9dD+qRX6vcHusaqqDlnY+VngKzKbAiG2iRCkPbmi8f7w==}
engines: {node: ^18.18.0 || ^19.8.0 || >= 20.0.0}
hasBin: true
peerDependencies:
'@opentelemetry/api': ^1.1.0
'@playwright/test': ^1.41.2
babel-plugin-react-compiler: '*'
react: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
react-dom: ^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0
sass: ^1.3.0
peerDependenciesMeta:
'@opentelemetry/api':
optional: true
'@playwright/test':
optional: true
babel-plugin-react-compiler:
optional: true
sass:
optional: true
nice-grpc-client-middleware-retry@3.1.9:
resolution: {integrity: sha512-BgbsNjuppxD6hoeCfO5gkBA/G69Tq5d9QX35QLdA46NSjKllelC+FlcgSPMlO9VQKCAPDfp4zzzDJZTNtbvzVw==}
@@ -12413,6 +12596,14 @@ snapshots:
optionalDependencies:
zod: 3.24.2
'@ai-sdk/provider-utils@2.2.0(zod@3.24.2)':
dependencies:
'@ai-sdk/provider': 1.1.0
eventsource-parser: 3.0.0
nanoid: 3.3.8
secure-json-parse: 2.7.0
zod: 3.24.2
'@ai-sdk/provider@0.0.26':
dependencies:
json-schema: 0.4.0
@@ -12421,6 +12612,10 @@ snapshots:
dependencies:
json-schema: 0.4.0
'@ai-sdk/provider@1.1.0':
dependencies:
json-schema: 0.4.0
'@ai-sdk/react@0.0.70(react@19.0.0)(zod@3.24.2)':
dependencies:
'@ai-sdk/provider-utils': 1.0.22(zod@3.24.2)
@@ -12441,6 +12636,16 @@ snapshots:
react: 19.0.0
zod: 3.24.2
'@ai-sdk/react@1.2.0(react@19.0.0)(zod@3.24.2)':
dependencies:
'@ai-sdk/provider-utils': 2.2.0(zod@3.24.2)
'@ai-sdk/ui-utils': 1.2.0(zod@3.24.2)
react: 19.0.0
swr: 2.3.2(react@19.0.0)
throttleit: 2.1.0
optionalDependencies:
zod: 3.24.2
'@ai-sdk/solid@0.0.54(zod@3.24.2)':
dependencies:
'@ai-sdk/provider-utils': 1.0.22(zod@3.24.2)
@@ -12476,6 +12681,13 @@ snapshots:
optionalDependencies:
zod: 3.24.2
'@ai-sdk/ui-utils@1.2.0(zod@3.24.2)':
dependencies:
'@ai-sdk/provider': 1.1.0
'@ai-sdk/provider-utils': 2.2.0(zod@3.24.2)
zod: 3.24.2
zod-to-json-schema: 3.24.1(zod@3.24.2)
'@ai-sdk/vue@0.0.59(vue@3.5.13(typescript@5.7.3))(zod@3.24.2)':
dependencies:
'@ai-sdk/provider-utils': 1.0.22(zod@3.24.2)
@@ -14531,6 +14743,36 @@ snapshots:
- react-dom
- supports-color
'@llamaindex/chat-ui@0.3.1(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@llamaindex/pdf-viewer': 1.3.0(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-collapsible': 1.1.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-hover-card': 1.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-icons': 1.3.2(react@19.0.0)
'@radix-ui/react-progress': 1.1.2(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-select': 2.1.6(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
'@radix-ui/react-slot': 1.1.2(@types/react@19.0.10)(react@19.0.0)
'@radix-ui/react-tabs': 1.1.3(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
class-variance-authority: 0.7.1
clsx: 2.1.1
highlight.js: 11.11.1
katex: 0.16.21
lucide-react: 0.453.0(react@19.0.0)
react: 19.0.0
react-markdown: 8.0.7(@types/react@19.0.10)(react@19.0.0)
rehype-katex: 7.0.1
remark: 14.0.3
remark-code-import: 1.2.0
remark-gfm: 3.0.1
remark-math: 5.1.1
tailwind-merge: 2.6.0
vaul: 0.9.9(@types/react-dom@19.0.4(@types/react@19.0.10))(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
transitivePeerDependencies:
- '@types/react'
- '@types/react-dom'
- react-dom
- supports-color
'@llamaindex/pdf-viewer@1.3.0(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)':
dependencies:
'@wojtekmaj/react-hooks': 1.17.2(react@19.0.0)
@@ -14715,58 +14957,88 @@ snapshots:
'@next/env@15.2.1': {}
'@next/env@15.2.3': {}
'@next/eslint-plugin-next@15.1.0':
dependencies:
fast-glob: 3.3.1
'@next/eslint-plugin-next@15.2.3':
dependencies:
fast-glob: 3.3.1
'@next/swc-darwin-arm64@15.2.0':
optional: true
'@next/swc-darwin-arm64@15.2.1':
optional: true
'@next/swc-darwin-arm64@15.2.3':
optional: true
'@next/swc-darwin-x64@15.2.0':
optional: true
'@next/swc-darwin-x64@15.2.1':
optional: true
'@next/swc-darwin-x64@15.2.3':
optional: true
'@next/swc-linux-arm64-gnu@15.2.0':
optional: true
'@next/swc-linux-arm64-gnu@15.2.1':
optional: true
'@next/swc-linux-arm64-gnu@15.2.3':
optional: true
'@next/swc-linux-arm64-musl@15.2.0':
optional: true
'@next/swc-linux-arm64-musl@15.2.1':
optional: true
'@next/swc-linux-arm64-musl@15.2.3':
optional: true
'@next/swc-linux-x64-gnu@15.2.0':
optional: true
'@next/swc-linux-x64-gnu@15.2.1':
optional: true
'@next/swc-linux-x64-gnu@15.2.3':
optional: true
'@next/swc-linux-x64-musl@15.2.0':
optional: true
'@next/swc-linux-x64-musl@15.2.1':
optional: true
'@next/swc-linux-x64-musl@15.2.3':
optional: true
'@next/swc-win32-arm64-msvc@15.2.0':
optional: true
'@next/swc-win32-arm64-msvc@15.2.1':
optional: true
'@next/swc-win32-arm64-msvc@15.2.3':
optional: true
'@next/swc-win32-x64-msvc@15.2.0':
optional: true
'@next/swc-win32-x64-msvc@15.2.1':
optional: true
'@next/swc-win32-x64-msvc@15.2.3':
optional: true
'@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
@@ -17384,6 +17656,19 @@ snapshots:
react: 19.0.0
zod: 3.24.2
ai@4.2.0(react@19.0.0)(zod@3.24.2):
dependencies:
'@ai-sdk/provider': 1.1.0
'@ai-sdk/provider-utils': 2.2.0(zod@3.24.2)
'@ai-sdk/react': 1.2.0(react@19.0.0)(zod@3.24.2)
'@ai-sdk/ui-utils': 1.2.0(zod@3.24.2)
'@opentelemetry/api': 1.9.0
eventsource-parser: 3.0.0
jsondiffpatch: 0.6.0
zod: 3.24.2
optionalDependencies:
react: 19.0.0
ajv-draft-04@1.0.0(ajv@8.17.1):
optionalDependencies:
ajv: 8.17.1
@@ -18744,8 +19029,8 @@ snapshots:
'@typescript-eslint/parser': 8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3)
eslint: 9.16.0(jiti@2.4.2)
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2))
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2))
eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@9.16.0(jiti@2.4.2))
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2))
eslint-plugin-jsx-a11y: 6.10.2(eslint@9.16.0(jiti@2.4.2))
eslint-plugin-react: 7.37.2(eslint@9.16.0(jiti@2.4.2))
eslint-plugin-react-hooks: 5.1.0(eslint@9.16.0(jiti@2.4.2))
@@ -18776,6 +19061,26 @@ snapshots:
- eslint-plugin-import-x
- supports-color
eslint-config-next@15.2.3(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3):
dependencies:
'@next/eslint-plugin-next': 15.2.3
'@rushstack/eslint-patch': 1.10.5
'@typescript-eslint/eslint-plugin': 8.24.0(@typescript-eslint/parser@8.24.0(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3)
'@typescript-eslint/parser': 8.24.0(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3)
eslint: 9.22.0(jiti@2.4.2)
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@9.22.0(jiti@2.4.2))
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.22.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.22.0(jiti@2.4.2))
eslint-plugin-jsx-a11y: 6.10.2(eslint@9.22.0(jiti@2.4.2))
eslint-plugin-react: 7.37.2(eslint@9.22.0(jiti@2.4.2))
eslint-plugin-react-hooks: 5.1.0(eslint@9.22.0(jiti@2.4.2))
optionalDependencies:
typescript: 5.7.3
transitivePeerDependencies:
- eslint-import-resolver-webpack
- eslint-plugin-import-x
- supports-color
eslint-config-prettier@9.1.0(eslint@9.22.0(jiti@2.4.2)):
dependencies:
eslint: 9.22.0(jiti@2.4.2)
@@ -18794,7 +19099,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)):
eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0)(eslint@9.16.0(jiti@2.4.2)):
dependencies:
'@nolyfill/is-core-module': 1.0.39
debug: 4.4.0
@@ -18806,7 +19111,7 @@ snapshots:
is-glob: 4.0.3
stable-hash: 0.0.4
optionalDependencies:
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2))
eslint-plugin-import: 2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2))
transitivePeerDependencies:
- supports-color
@@ -18826,14 +19131,14 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)):
eslint-module-utils@2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2)):
dependencies:
debug: 3.2.7
optionalDependencies:
'@typescript-eslint/parser': 8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3)
eslint: 9.16.0(jiti@2.4.2)
eslint-import-resolver-node: 0.3.9
eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2))
eslint-import-resolver-typescript: 3.7.0(eslint-plugin-import@2.31.0)(eslint@9.16.0(jiti@2.4.2))
transitivePeerDependencies:
- supports-color
@@ -18848,7 +19153,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)):
eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2)):
dependencies:
'@rtsao/scc': 1.1.0
array-includes: 3.1.8
@@ -18859,7 +19164,7 @@ snapshots:
doctrine: 2.1.0
eslint: 9.16.0(jiti@2.4.2)
eslint-import-resolver-node: 0.3.9
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0(eslint-plugin-import@2.31.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2)))(eslint@9.16.0(jiti@2.4.2))
eslint-module-utils: 2.12.0(@typescript-eslint/parser@8.24.0(eslint@9.16.0(jiti@2.4.2))(typescript@5.7.3))(eslint-import-resolver-node@0.3.9)(eslint-import-resolver-typescript@3.7.0)(eslint@9.16.0(jiti@2.4.2))
hasown: 2.0.2
is-core-module: 2.16.1
is-glob: 4.0.3
@@ -22274,6 +22579,32 @@ snapshots:
- '@babel/core'
- babel-plugin-macros
next@15.2.3(@opentelemetry/api@1.9.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0):
dependencies:
'@next/env': 15.2.3
'@swc/counter': 0.1.3
'@swc/helpers': 0.5.15
busboy: 1.6.0
caniuse-lite: 1.0.30001701
postcss: 8.4.31
react: 19.0.0
react-dom: 19.0.0(react@19.0.0)
styled-jsx: 5.1.6(react@19.0.0)
optionalDependencies:
'@next/swc-darwin-arm64': 15.2.3
'@next/swc-darwin-x64': 15.2.3
'@next/swc-linux-arm64-gnu': 15.2.3
'@next/swc-linux-arm64-musl': 15.2.3
'@next/swc-linux-x64-gnu': 15.2.3
'@next/swc-linux-x64-musl': 15.2.3
'@next/swc-win32-arm64-msvc': 15.2.3
'@next/swc-win32-x64-msvc': 15.2.3
'@opentelemetry/api': 1.9.0
sharp: 0.33.5
transitivePeerDependencies:
- '@babel/core'
- babel-plugin-macros
nice-grpc-client-middleware-retry@3.1.9:
dependencies:
abort-controller-x: 0.4.3
+3
View File
@@ -193,6 +193,9 @@
},
{
"path": "./packages/tools/tsconfig.json"
},
{
"path": "./packages/server/tsconfig.json"
}
]
}