diff --git a/docs/content/docs/api-reference/cli.mdx b/docs/content/docs/api-reference/cli.mdx index e118550e0..9f789ea0f 100644 --- a/docs/content/docs/api-reference/cli.mdx +++ b/docs/content/docs/api-reference/cli.mdx @@ -97,7 +97,7 @@ In non-interactive mode, dependencies are installed without starting the long-ru The CLI applies the selected framework's final route/page files, dependencies, and deployment configuration over the base template. Both Vercel AI SDK variants are standard Next.js deployments with `streamText()`, `toUIMessageStreamResponse()`, and `vercelAIAdapter()`. Both LangGraph variants separate the Agent Server described by `langgraph.json` from the Next.js frontend/proxy. The proxy uses `@openuidev/langchain`, and the browser consumes its AG-UI stream with `agUIAdapter()`. Both Eve variants wrap Next.js with `withEve()` and talk to Eve's native `/eve/v1/session*` protocol from the browser; a small client adapter maps Eve events to AG-UI for `agUIAdapter()`. -For Gateway-backed LangGraph and Vercel AI SDK variants, the framework owns orchestration and application tool execution. OpenUI Gateway is attached as the Responses/Chat Completions model provider and conversation store. Reports, presentations, web search, image search, and configured MCP tools remain Gateway-hosted tools. The Eve Gateway overlay uses Gateway as the Chat Completions provider and conversation store, without those hosted tools. For either LangGraph template, `pnpm dev` starts the local Agent Server and Next.js together. Deploy the Next.js frontend to Vercel and point `LANGGRAPH_API_URL` at wherever the Agent Server runs. Eve embeds in the Next.js process, so `pnpm dev` is enough for both Eve variants. +For Gateway-backed LangGraph and Vercel AI SDK variants, the framework owns orchestration and application tool execution. OpenUI Gateway is attached as the Responses/Chat Completions model provider and conversation store. Reports, presentations, web search, image search, and configured MCP tools remain Gateway-hosted tools. The Eve Gateway overlay uses Gateway as the Responses provider and conversation store, without those hosted tools. For either LangGraph template, `pnpm dev` starts the local Agent Server and Next.js together. Deploy the Next.js frontend to Vercel and point `LANGGRAPH_API_URL` at wherever the Agent Server runs. Eve embeds in the Next.js process, so `pnpm dev` is enough for both Eve variants. Every framework overlay includes a `get_weather` example backed by Open-Meteo. Ask “What’s the weather in Berlin?” to verify the selected framework’s native multi-step tool loop. diff --git a/packages/openui-cli/README.md b/packages/openui-cli/README.md index 2d9808cb8..a06f345d6 100644 --- a/packages/openui-cli/README.md +++ b/packages/openui-cli/README.md @@ -129,7 +129,7 @@ Overlay names are loaded from the fetched template's `overlays/` directory (`def The default implementation is part of each base template. For LangGraph or Vercel AI SDK, the CLI applies a framework-specific set of files plus a manifest for its dependencies, scripts, removals, and onboarding text. Both Vercel AI SDK variants are standard Next.js deployments whose `streamText()` result returns `toUIMessageStreamResponse()` for `vercelAIAdapter()`. -In Cloud framework variants, the selected framework owns the agent orchestration and application tool loop. OpenUI Cloud is attached as the model provider and conversation store. Reports, presentations, web search, image search, and configured MCP tools remain provider-executed Cloud tools on the default, LangGraph, and Vercel AI SDK Cloud routes, while application tools such as `get_weather` execute inside the selected framework. The Eve Cloud overlay uses Cloud as the Chat Completions provider and does not attach those provider-executed Cloud tools. Choosing a Cloud framework does not configure a user-owned model provider; choose `openui-self-hosted` for that. +In Cloud framework variants, the selected framework owns the agent orchestration and application tool loop. OpenUI Cloud is attached as the model provider and conversation store. Reports, presentations, web search, image search, and configured MCP tools remain provider-executed Cloud tools on the default, LangGraph, and Vercel AI SDK Cloud routes, while application tools such as `get_weather` execute inside the selected framework. The Eve Cloud overlay uses Cloud as the Responses provider and does not attach those provider-executed Cloud tools. Choosing a Cloud framework does not configure a user-owned model provider; choose `openui-self-hosted` for that. The Cloud graph needs `THESYS_API_KEY`; the self-hosted graph needs the selected provider credentials such as `OPENAI_API_KEY`. @@ -137,7 +137,7 @@ Every framework overlay includes `get_weather` as its example app-owned function #### Conversation storage -Every OpenUI Cloud variant uses OpenUI Cloud as its only durable conversation and artifact store. The browser connects directly through `useOpenuiCloudStorage()` with a short-lived frontend token, and `/api/chat` appends each turn to the same Cloud conversation with `conversation: threadId` and `store: true`. Vercel does not add a second store. Configure a LangGraph checkpointer separately only when the graph itself needs durable state, interrupts, or resumable runs. +Every OpenUI Cloud variant uses OpenUI Cloud as its durable conversation store. The browser connects directly through `useOpenuiCloudStorage()` with a short-lived frontend token. Default, LangGraph, and Vercel AI SDK routes append each turn via `/api/chat` with `conversation: threadId` and `store: true`. The Eve Cloud overlay uses the same Cloud thread store (`features: { artifact: false }`) and appends Responses turns with `conversation: threadId` and `store: true`; it does not use `/api/chat`. Vercel does not add a second store. Configure a LangGraph checkpointer separately only when the graph itself needs durable state, interrupts, or resumable runs. The self-hosted variants do not configure durable storage. `AgentInterface` keeps the conversation in memory for the current page session and sends that history to `/api/chat`; refreshing the page loses it. Pass a storage implementation to `AgentInterface` and back it with your own database when persistence is required; add a LangGraph checkpointer only for graph-specific durable state. diff --git a/templates/openui-cloud/README.md b/templates/openui-cloud/README.md index 290592430..13b27f695 100644 --- a/templates/openui-cloud/README.md +++ b/templates/openui-cloud/README.md @@ -36,11 +36,14 @@ variant. The browser connects directly through `useOpenuiCloudStorage()` with a short-lived token from `/api/frontend-token`. For default, LangGraph, and Vercel AI SDK routes, the `threadId` sent to `/api/chat` is the Cloud conversation id, and the route appends each model turn to it with -`conversation: threadId` and `store: true`. The Eve overlay uses that same Cloud -thread store and maps each Cloud `threadId` to an Eve session cursor in the -browser; it does not use `/api/chat`. -Browser `localStorage` holds only the selected model (and, for Eve, the session -cursor), not conversation messages. +`conversation: threadId` and `store: true`. + +The Eve overlay uses that same Cloud thread store via `useOpenuiCloudStorage()` +(`features: { artifact: false }`) and maps each Cloud `threadId` to an +in-memory Eve session cursor; it does not use `/api/chat`. Each Eve model turn +still appends to the Cloud conversation with `conversation: threadId` and +`store: true`. Provider-executed artifact and search tools are not attached. +Browser `localStorage` holds only the selected model on non-Eve scaffolds. The Vercel AI SDK route does not create a second store. Add a LangGraph checkpointer separately only if the graph needs durable state, interrupts, or @@ -48,10 +51,14 @@ resumable runs. ## Switching Models -Use the model switcher in the chat header to choose a model for new messages. The starter keeps a -small curated model list in `src/lib/models.tsx` and sends the selected `provider/model` id to -`/api/chat`, which validates it against the same list. The built-in list includes Gemini, GPT, -Claude Sonnet, and Claude Opus options; free Gemini variants are marked with a `Free` badge. +Default, LangGraph, and Vercel AI SDK scaffolds put a model switcher in the chat +header. The starter keeps a small curated model list in `src/lib/models.tsx` and +sends the selected `provider/model` id to `/api/chat`, which validates it against +the same list. The built-in list includes Gemini, GPT, Claude Sonnet, and Claude +Opus options; free Gemini variants are marked with a `Free` badge. + +The Vercel Eve scaffold has no dropdown: set `OPENUI_MODEL` in `.env`. The same +ids live in `src/lib/models.ts`. An unknown name fails when the agent loads. The built-in model ids are available on [models.dev's OpenRouter provider list](https://models.dev/providers/openrouter/). diff --git a/templates/openui-cloud/overlays/vercel-eve/README.md b/templates/openui-cloud/overlays/vercel-eve/README.md new file mode 100644 index 000000000..176b5324d --- /dev/null +++ b/templates/openui-cloud/overlays/vercel-eve/README.md @@ -0,0 +1,62 @@ +This is an [OpenUI](https://openui.com) Cloud project bootstrapped with [`openui-cli`](https://openui.com/docs/chat/quick-start), using a [Vercel Eve](https://github.com/vercel/eve) agent. + +## Setup + +The CLI writes `.env` for you. If you cloned the generated project elsewhere, +run `pnpm generate:apiKey` to mint `THESYS_API_KEY`, then add `DEMO_USER_ID` +and `APP_ID`. + +Optional: set `OPENUI_MODEL` to a Cloud model id such as +`google/gemini-3.6-flash-free`. An unknown id fails when the Eve agent loads — +the app will not sit idle until the first message. + +## Prerequisites + +- Node.js 24 + +## Getting Started + +```bash +pnpm dev +``` + +Open [http://localhost:3000](http://localhost:3000). Ask "What's the weather in +Berlin?" to exercise the included Eve tool. + +## Conversation storage + +OpenUI Cloud is the durable conversation store, wired the same way as the other +Cloud scaffolds: `useOpenuiCloudStorage()` with a short-lived token from +`/api/frontend-token` and `features: { artifact: false }`. Each Eve turn +appends to that conversation with `conversation: threadId` and `store: true`. +Provider-executed artifact and search tools are not attached. + +## Switching models + +This scaffold has no model dropdown. Set `OPENUI_MODEL` in `.env`. The built-in +ids live in `src/lib/models.ts`. + +## Eve commands + +The normal development command is `pnpm dev`. The package also exposes Eve +directly: + +```bash +pnpm eve:dev +pnpm eve:build +pnpm eve:start +``` + +## SDK packages + +- `@openuidev/lang-core` — `generateSystemPrompt({ cloud: true })` used by Eve instructions. +- `@openuidev/thesys` — `chatLibrary` and Cloud conversation storage. +- `@openuidev/react-ui` — `AgentInterface`, `eveAdapter`. + +A devtools widget is available automatically in development. + +## Learn More + +- [OpenUI Documentation](https://openui.com/docs) +- [OpenUI GitHub repository](https://github.com/thesysdev/openui) +- [Vercel Eve](https://github.com/vercel/eve) diff --git a/templates/openui-cloud/overlays/vercel-eve/agent/agent.ts b/templates/openui-cloud/overlays/vercel-eve/agent/agent.ts index bcc9cf1d3..5ae6ba26f 100644 --- a/templates/openui-cloud/overlays/vercel-eve/agent/agent.ts +++ b/templates/openui-cloud/overlays/vercel-eve/agent/agent.ts @@ -1,5 +1,7 @@ import { createOpenAI } from "@ai-sdk/openai"; import { defineAgent } from "eve"; +import { withCloudConversation } from "./cloud-conversation.ts"; +import { resolveOpenuiModel, DEFAULT_MODEL } from "../src/lib/models.ts"; const apiKey = process.env.THESYS_API_KEY; if (!apiKey) throw new Error("Missing required env var: THESYS_API_KEY"); @@ -9,8 +11,8 @@ const openai = createOpenAI({ baseURL: "https://api.thesys.dev/v1/embed", }); -const model = openai.chat( - process.env.OPENUI_MODEL ?? "google/gemini-3.6-flash-free", +const model = withCloudConversation( + openai.responses(resolveOpenuiModel(DEFAULT_MODEL)), ); export default defineAgent({ diff --git a/templates/openui-cloud/overlays/vercel-eve/agent/cloud-conversation.ts b/templates/openui-cloud/overlays/vercel-eve/agent/cloud-conversation.ts new file mode 100644 index 000000000..24153fbd4 --- /dev/null +++ b/templates/openui-cloud/overlays/vercel-eve/agent/cloud-conversation.ts @@ -0,0 +1,94 @@ +import { wrapLanguageModel, type LanguageModel } from "ai"; + +/** Eve renders `clientContext` as this prefix plus a JSON object. */ +const CLIENT_CONTEXT_PREFIX = "Client context:\n"; + +type PromptMessage = { role: string; content: unknown }; + +function userText(message: PromptMessage): string { + if (message.role !== "user") return ""; + const content = message.content; + if (typeof content === "string") return content; + if (!Array.isArray(content)) return ""; + return content + .map((part) => + part && typeof part === "object" && "type" in part && part.type === "text" && "text" in part + ? String((part as { text: unknown }).text ?? "") + : "", + ) + .join(""); +} + +function isClientContext(message: PromptMessage): boolean { + return userText(message).startsWith(CLIENT_CONTEXT_PREFIX); +} + +function conversationIdFrom(prompt: readonly PromptMessage[]): string { + for (const message of prompt) { + if (!isClientContext(message)) continue; + try { + const id = JSON.parse(userText(message).slice(CLIENT_CONTEXT_PREFIX.length)).conversationId; + if (typeof id === "string" && id) return id; + } catch { + // ignore malformed client context + } + } + return ""; +} + +/** Cloud already has prior turns. Send only the new user message or tool results. */ +function latestStep(prompt: readonly T[]): T[] { + const system = prompt.filter((message) => message.role === "system"); + const rest = prompt.filter((message) => message.role !== "system"); + if (rest.length === 0) return system; + + const last = rest[rest.length - 1]!; + if (last.role === "tool") { + let start = rest.length - 1; + while (start > 0 && rest[start - 1]!.role === "tool") start -= 1; + return [...system, ...rest.slice(start)]; + } + + const user = [...rest].reverse().find((message) => message.role === "user"); + return user ? [...system, user] : [...system, last]; +} + +/** + * Read `conversationId` from Eve `clientContext`, strip that synthetic user + * message, and set `store` + `conversation` on Responses stream calls. + */ +export function withCloudConversation(model: LanguageModel): LanguageModel { + return wrapLanguageModel({ + model, + middleware: { + async transformParams({ params, type }) { + const prompt = params.prompt as PromptMessage[]; + const conversationId = conversationIdFrom(prompt); + const withoutCtx = prompt.filter((message) => !isClientContext(message)); + + // Compaction uses generateText. Don't write those calls into Cloud. + if (type !== "stream" || !conversationId) { + return { ...params, prompt: withoutCtx }; + } + + const openai = + params.providerOptions && + typeof params.providerOptions === "object" && + "openai" in params.providerOptions && + params.providerOptions.openai && + typeof params.providerOptions.openai === "object" + ? params.providerOptions.openai + : {}; + + return { + ...params, + prompt: latestStep(withoutCtx), + providerOptions: { + ...params.providerOptions, + openai: { ...openai, store: true, conversation: conversationId }, + }, + }; + }, + }, + }); +} diff --git a/templates/openui-cloud/overlays/vercel-eve/manifest.json b/templates/openui-cloud/overlays/vercel-eve/manifest.json index fa3892252..f83943514 100644 --- a/templates/openui-cloud/overlays/vercel-eve/manifest.json +++ b/templates/openui-cloud/overlays/vercel-eve/manifest.json @@ -7,7 +7,7 @@ "@openuidev/react-headless": "^0.9.13", "@vercel/connect": "0.2.2", "ai": "7.0.0-beta.178", - "eve": "^0.11.7", + "eve": "^0.52.2", "lru-cache": "^11.2.6" }, "scripts": { @@ -18,7 +18,12 @@ "removeDependencies": ["openai"] }, "files": { - "remove": ["src/app/api/chat/route.ts", "src/lib/tool-loop.ts"] + "remove": [ + "src/app/api/chat/route.ts", + "src/lib/tool-loop.ts", + "src/lib/models.tsx", + "src/hooks/use-persisted-model.ts" + ] }, - "gettingStarted": "The generated Vercel Eve agent uses OpenUI Cloud as its model provider. `{{packageManager}} run dev` starts Next.js with Eve embedded via withEve(). Ask \"What's the weather in Berlin?\" to exercise the included Eve tool." + "gettingStarted": "The generated Vercel Eve agent uses OpenUI Cloud Responses as its model provider. `{{packageManager}} run dev` starts Next.js with Eve embedded via withEve(). Set OPENUI_MODEL to a Cloud model id — an unknown name fails at agent load. Ask \"What's the weather in Berlin?\" to exercise the included Eve tool." } diff --git a/templates/openui-cloud/overlays/vercel-eve/package-lock.json b/templates/openui-cloud/overlays/vercel-eve/package-lock.json index f5a55bedb..69b73c77b 100644 --- a/templates/openui-cloud/overlays/vercel-eve/package-lock.json +++ b/templates/openui-cloud/overlays/vercel-eve/package-lock.json @@ -17,7 +17,7 @@ "@openuidev/thesys-server": "0.1.3", "@vercel/connect": "0.2.2", "ai": "7.0.0-beta.178", - "eve": "^0.11.7", + "eve": "^0.52.2", "lru-cache": "^11.2.6", "lucide-react": "^0.575.0", "next": "^16.3.0", @@ -3001,12 +3001,12 @@ } }, "node_modules/@oxc-project/types": { - "version": "0.147.0", - "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.147.0.tgz", - "integrity": "sha512-IJ3s6ltHLp45S0bh7phkX+gJO7A1Wuz2EaqpAhb8WjqDwbzMiWKHhyyT42tskaWjEYXtHtVCPpnBJVT9+dcRLg==", + "version": "0.148.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.148.0.tgz", + "integrity": "sha512-Nm4s/jB+4FpFsPhWGEC4h7rzksesmtnMXomo6rCMcg/b8zLQuOziRgkCS1fxDCXOlJB/6Q8oABOZ/OP6RIPj9A==", "license": "MIT", "funding": { - "url": "https://github.com/sponsors/Boshen" + "url": "https://github.com/sponsors/oxc-project" } }, "node_modules/@popperjs/core": { @@ -4070,9 +4070,9 @@ "license": "MIT" }, "node_modules/@rolldown/binding-android-arm-eabi": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.6.tgz", - "integrity": "sha512-b+jTcARdTiFLI6jB4a5XjTm0RWd6KcRfQj/I2356fxUZemiho9zQLxo0RtCuMDAyKcLo6cEltkgbQp6d1+sjjQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm-eabi/-/binding-android-arm-eabi-1.2.7.tgz", + "integrity": "sha512-EypzgnYCwyVY4NDHKzGmNJT5b+XaQEBniHxsMdeIQLB/tcCzZnhqrzHpZFbX9iaxx+5RiB8caATBtfvZP7zVxQ==", "cpu": [ "arm" ], @@ -4086,9 +4086,9 @@ } }, "node_modules/@rolldown/binding-android-arm64": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.6.tgz", - "integrity": "sha512-lkWU8ZJaRk9q3CIEY1Tc7vIFALp3Xw5NfGJo2hQg5oIqNgxWi1zI+IiDEK3r70BF5Dzol1tcXsnzsRc8NLhG+Q==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.2.7.tgz", + "integrity": "sha512-l17HE9EweWaqJZhuUuNBN/FzM62xw+DECVnJyvMsxn8vJFAGLy5QfLDoYAcronkAN8VxKZHezDpulHDPx95vFw==", "cpu": [ "arm64" ], @@ -4102,9 +4102,9 @@ } }, "node_modules/@rolldown/binding-darwin-arm64": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.6.tgz", - "integrity": "sha512-dgR56NYnvAszm7Ob1B2/Vn0e8bUQYZH2UjVaMMtMVOCKFSfjhfLmuA/9+O+F+ajUdG6B/bSssrKW6JJYASa8jA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.2.7.tgz", + "integrity": "sha512-8ED8ELFvHXc6OCETIn4gXObPiaR6bckM/ipXtbzlPVDRMBfEGjCKgO90F9YtfdpDatVx/ZQw7aZ1vUMf/+T3Mw==", "cpu": [ "arm64" ], @@ -4118,9 +4118,9 @@ } }, "node_modules/@rolldown/binding-darwin-x64": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.6.tgz", - "integrity": "sha512-vpVxFvUCFioJqug7OTvqptkc4yb8UX0AwfDmJpaR/0sWz+BUmqSVAf7c8JkUgnN8YLspb4a/N6NhTyMAmdyQ7Q==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.2.7.tgz", + "integrity": "sha512-/WPripjtiAIZ2tWY7ddijORT0Ujg87wxWW/qcoFVCKAWVDPhtY0xr7Dj0M3GyNGz60jGwTElhro/mkF9dT7dDQ==", "cpu": [ "x64" ], @@ -4134,9 +4134,9 @@ } }, "node_modules/@rolldown/binding-freebsd-x64": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.6.tgz", - "integrity": "sha512-h1wG6Y6K3JlRswxsI64qQJqBAy4vrLuHgRbc8CZMGSWTOFRY6ghMApM1NKzB2I0n5xV1fjkE18SuVl2QpLeNpA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.2.7.tgz", + "integrity": "sha512-14DI4NcqpvbICxSnGLx3PmtDaWqRP/KGSGb6C+JLLVPeZRl6dKdHba3pGsqT3vpdTqhEYIPG0MMQ8c0xYqoJxA==", "cpu": [ "x64" ], @@ -4150,9 +4150,9 @@ } }, "node_modules/@rolldown/binding-linux-arm-gnueabihf": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.6.tgz", - "integrity": "sha512-tbCiqub0q2MVWJKgF5PoAlNWCtQydiOYSLIkd8sByqK/6MMYLJRcSXSYodqYtd0O+Fw7QaVmKKlS4oL94YRZ0w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.2.7.tgz", + "integrity": "sha512-bxrWIRvHWQvbJwi+VIie/kDJmQxcNE6xxWwZdqF/ExVAigtHkv54WTLQPb+QsZdnFy18fg7JPfWGL0RH6vwIlQ==", "cpu": [ "arm" ], @@ -4166,12 +4166,15 @@ } }, "node_modules/@rolldown/binding-linux-arm64-gnu": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.6.tgz", - "integrity": "sha512-oxK9+baEBPhZG5HB4URY+uU04zJWeZlH6Tb9rB5DK4DF9XR1uXNLXt5Q5ZsugTKayNCNLhkcwz/ye74hRI98dg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.2.7.tgz", + "integrity": "sha512-toOY2BChBZyuxU7OYX6Tn389di4IzAqPTycVcci0O7FSfBqzRB3RZn+K5Is6ANf4tmgRd/K1yZTsNTXbkXsnLg==", "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -4182,12 +4185,15 @@ } }, "node_modules/@rolldown/binding-linux-arm64-musl": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.6.tgz", - "integrity": "sha512-muWCk27FVBEZtv0MsK8gnfSmgczA8KQ0uRVJbTABKhkRfQc38aUrcb7fhi3BNiyseFmgcRsoMfQsSNJ+DbZdSw==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.2.7.tgz", + "integrity": "sha512-lAIXTH/aiLRLxsTgQvfhjo4K1ydWIp00+V0voOr9beb/9ZmkUFrSIb03dXNFRgMNvkE6oGsF10ioQ6UsI+vS5Q==", "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -4198,12 +4204,15 @@ } }, "node_modules/@rolldown/binding-linux-ppc64-gnu": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.6.tgz", - "integrity": "sha512-eWDoSfU7Co2qj3vgB3Dt4lj1mG6CoWbcJQkRMP3XJplyCMtuaq3LHvPFjS9QIPvMGWVadJC04Xiy0IdcVPtnwQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.2.7.tgz", + "integrity": "sha512-kdnwS28Pkenp/mZMRwjXXXwxQ7pIsm+bF919LUK93BOyhcLsrVKdP2p9fxpiPNPAbNuch8ypQt0pm2P2LYCAGg==", "cpu": [ "ppc64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -4214,12 +4223,15 @@ } }, "node_modules/@rolldown/binding-linux-s390x-gnu": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.6.tgz", - "integrity": "sha512-2bWNjRSIayvupRKxXUY2tWG9fYdoUlTqWywHRvE8Eq3GvuQ+f2HeIkve697fIt+IQs/PV8yFsdWuhp1aJ1PdnA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.2.7.tgz", + "integrity": "sha512-516OdsyLdr5E65paF3yBF55t8mfm9+gmtCsK3xI7XKXIT7EfRlHhxL8K/NR6Hu8BWSgF5+1w74lTL0+nxcc8Qw==", "cpu": [ "s390x" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -4230,12 +4242,15 @@ } }, "node_modules/@rolldown/binding-linux-x64-gnu": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.6.tgz", - "integrity": "sha512-KekI0gS0wLxe1UBSQSjenBVwou/JkcQPDzBPICGZjxUv9k3RteHDPBQaiOicZUFKRIH2wKEimGwVpnJsbPzu7w==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.2.7.tgz", + "integrity": "sha512-r8/z8n7GFaYRln3xmP1Cxy0HH/HLM0uBUPkEuSVEfKGDA89M0FsZRZJRSwe/tJjRx+fpH/gjorfhB8tmEbSFLA==", "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -4246,12 +4261,15 @@ } }, "node_modules/@rolldown/binding-linux-x64-musl": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.6.tgz", - "integrity": "sha512-TvtPnfVr+HtyGiDmPK4VWmlNm7QhNNAcK5Q9A7aOXsI8545yCyaoMaicXrFZ72JzeYjaUVk7yT243zT0jzjFKQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.2.7.tgz", + "integrity": "sha512-pAsE8iiDxUg1xBqdhrTfg45AVDVpirjz00sblEYClGNNcMnDb+e8beQgqIAw6LvauX/APvgxUnwrgun/YYGBhw==", "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -4262,9 +4280,9 @@ } }, "node_modules/@rolldown/binding-openharmony-arm64": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.6.tgz", - "integrity": "sha512-iOo0VEay2XFhaCcH0sps5XIimkSuOnNaZrf6+ZkoSOQBJPKNU48RkmJv0/lSpipexu5P+ouFgafe5IGr/DiQfg==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.2.7.tgz", + "integrity": "sha512-lTcIYmmnQQA8Or/2DatS6oSqcdLHvendjS+zLu+FwgToynWMRSmQdpM65fTANJgIS4mjbMOo5KT2lnT9SAb96w==", "cpu": [ "arm64" ], @@ -4278,9 +4296,9 @@ } }, "node_modules/@rolldown/binding-win32-arm64-msvc": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.6.tgz", - "integrity": "sha512-y5NTmmasMS455JlOCO4ZM9krIchv3Mvm1crL1iUPGOPgEzSkves9n0SdC5Sjz6+qWDFhd8/JpfWMH8NSWNHe+A==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.2.7.tgz", + "integrity": "sha512-e3Gu3WxbNk/UqQhxqU7YIYO+9ZBvWNz3U+h/qRFosscMFzdRPbXYSaSWgSnklv2fz1TgzBTcti2z35c/7irsHw==", "cpu": [ "arm64" ], @@ -4294,9 +4312,9 @@ } }, "node_modules/@rolldown/binding-win32-x64-msvc": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.6.tgz", - "integrity": "sha512-np8iZSLfXlAD4kWhiyq/u0Yt8oZDtRQ8lGhQaCXo2rl37KNjeU0GjJuwr4P3oeZ++ROfofsKNBqR5LTO8aXyWQ==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.2.7.tgz", + "integrity": "sha512-W/jg5qoRSqjsEv0+dZi4e687mcHqmVuU0P4fK6qS/xjetW2Gmc1W8j//z5nAeNcC8Ttm0hV46IjcYeuVwYhuiw==", "cpu": [ "x64" ], @@ -7277,38 +7295,10 @@ "license": "MIT" }, "node_modules/db0": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/db0/-/db0-0.3.4.tgz", - "integrity": "sha512-RiXXi4WaNzPTHEOu8UPQKMooIbqOEyqA1t7Z6MsdxSCeb8iUC9ko3LcmsLmeUt2SM5bctfArZKkRQggKZz7JNw==", - "license": "MIT", - "peerDependencies": { - "@electric-sql/pglite": "*", - "@libsql/client": "*", - "better-sqlite3": "*", - "drizzle-orm": "*", - "mysql2": "*", - "sqlite3": "*" - }, - "peerDependenciesMeta": { - "@electric-sql/pglite": { - "optional": true - }, - "@libsql/client": { - "optional": true - }, - "better-sqlite3": { - "optional": true - }, - "drizzle-orm": { - "optional": true - }, - "mysql2": { - "optional": true - }, - "sqlite3": { - "optional": true - } - } + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/db0/-/db0-0.4.1.tgz", + "integrity": "sha512-6RBY/bSn42UrqATwsiULj2uYFyEykB3XeA/NLIVQeHNXlYV6D4Idxx3/aa6k5Y45Dwzx7sygeLotnqHWSeURYA==", + "license": "MIT" }, "node_modules/debug": { "version": "4.4.3", @@ -7569,38 +7559,18 @@ } }, "node_modules/env-runner": { - "version": "0.1.16", - "resolved": "https://registry.npmjs.org/env-runner/-/env-runner-0.1.16.tgz", - "integrity": "sha512-2LRJM4P2KLX6J83QZZrMqvgCDt/D5ea7wPcI3yYiy5cG/9rX5QwdwZFx0D7ktWnjdRyZxYjttGGorb5nFqb1CA==", + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/env-runner/-/env-runner-0.2.1.tgz", + "integrity": "sha512-2iDP2DfheAMMAKeXBggEuFmpSq+1Xs6wQoHba1g65pZFXlC3VHD1O6/tgVzS6GQLv+P2koPKZPKgKhXkigNBdg==", "license": "MIT", "dependencies": { - "crossws": "^0.4.8", - "exsolve": "^1.1.0", - "httpxy": "^0.5.4", - "srvx": "^0.11.19" + "crossws": "^0.4.12", + "exsolve": "^1.1.1", + "httpxy": "^0.5.5", + "srvx": "^1.0.0" }, "bin": { "env-runner": "dist/cli.mjs" - }, - "peerDependencies": { - "@netlify/runtime": "^4.1.23", - "@vercel/queue": ">=0.2.0", - "miniflare": "^4.20260515.0", - "wrangler": "^4.0.0" - }, - "peerDependenciesMeta": { - "@netlify/runtime": { - "optional": true - }, - "@vercel/queue": { - "optional": true - }, - "miniflare": { - "optional": true - }, - "wrangler": { - "optional": true - } } }, "node_modules/es-abstract": { @@ -8296,12 +8266,13 @@ } }, "node_modules/eve": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/eve/-/eve-0.11.10.tgz", - "integrity": "sha512-vMjqknf+8pSL4kpm8uQI6N1r7KcLDqJuouN6updVqELlfWU7ndVNJ5rxBagM8C202owuh5JtCVnnxyHEz7EPFA==", + "version": "0.52.2", + "resolved": "https://registry.npmjs.org/eve/-/eve-0.52.2.tgz", + "integrity": "sha512-FM3aC2A3SCKQxtyhSNR5+CaIVlKJmTGb7rCqcuHEhZShDKo1IXCTt/F7r4toqkLDG6lW7VcStTku77KWiosLfg==", "license": "Apache-2.0", "dependencies": { - "nitro": "3.0.260610-beta" + "nitro": "3.0.260903-beta", + "undici": "8.9.0" }, "bin": { "eve": "bin/eve.js" @@ -8311,25 +8282,15 @@ }, "peerDependencies": { "@opentelemetry/api": "^1.0.0", - "@sveltejs/kit": "^2.0.0", - "ai": "7.0.0-beta.178", + "ai": "^7.0.82", "braintrust": "^3.0.0", - "just-bash": "^3.0.0", - "microsandbox": "^0.5.0", - "next": "^16.0.0", - "nuxt": "^4.0.0", - "react": "^19.0.0", - "svelte": "^5.0.0", - "vite": "^8.0.0", - "vue": "^3.5.0" + "just-bash": "^3.1.0", + "microsandbox": "^0.5.0" }, "peerDependenciesMeta": { "@opentelemetry/api": { "optional": true }, - "@sveltejs/kit": { - "optional": true - }, "braintrust": { "optional": true }, @@ -8338,27 +8299,18 @@ }, "microsandbox": { "optional": true - }, - "next": { - "optional": true - }, - "nuxt": { - "optional": true - }, - "react": { - "optional": true - }, - "svelte": { - "optional": true - }, - "vite": { - "optional": true - }, - "vue": { - "optional": true } } }, + "node_modules/eve/node_modules/undici": { + "version": "8.9.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-8.9.0.tgz", + "integrity": "sha512-aWZpUj7XoGonMClx4gdDRfgBjqeA+F473aDmROQQbM9n6PRfK/u1q/a0X4wMTgcHfT8H6fpbt98PFuDUwFg2YA==", + "license": "MIT", + "engines": { + "node": ">=22.19.0" + } + }, "node_modules/eventemitter3": { "version": "4.0.7", "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", @@ -8840,13 +8792,13 @@ } }, "node_modules/h3": { - "version": "2.0.1-rc.22", - "resolved": "https://registry.npmjs.org/h3/-/h3-2.0.1-rc.22.tgz", - "integrity": "sha512-Esv0DMIuPkCTSWCA0vO73vcTqwzH1wjSrAO1TXNu/K3up1sZHa9EKMapbmxCDYBeymC3fVTk4qxp7ogQWQ+KgA==", + "version": "2.0.1-rc.31", + "resolved": "https://registry.npmjs.org/h3/-/h3-2.0.1-rc.31.tgz", + "integrity": "sha512-AG7qZzF99a0BSYoXT3evJgIhwSIUKow7R+hwkLRZS06WJ9nbSb7QXUDgs1ByBjp6svTvl++N/GKA7I9YPz9cQQ==", "license": "MIT", "dependencies": { - "rou3": "^0.8.1", - "srvx": "^0.11.15" + "rou3": "^0.9.2", + "srvx": "^1.0.2" }, "bin": { "h3": "bin/h3.mjs" @@ -8855,11 +8807,15 @@ "node": ">=20.11.1" }, "peerDependencies": { - "crossws": "^0.4.1" + "crossws": "^0.4.12", + "ocache": ">=0.3.0" }, "peerDependenciesMeta": { "crossws": { "optional": true + }, + "ocache": { + "optional": true } } }, @@ -11321,67 +11277,30 @@ "license": "MIT" }, "node_modules/nitro": { - "version": "3.0.260610-beta", - "resolved": "https://registry.npmjs.org/nitro/-/nitro-3.0.260610-beta.tgz", - "integrity": "sha512-KPb4L5yaF/Rx/xoGMpgHRJvZhbhGiqbRKOwwPLCH9jKTKTsEUHLjnJas85AeCzaswqa8Wi52eQBtRsODC4PS0Q==", + "version": "3.0.260903-beta", + "resolved": "https://registry.npmjs.org/nitro/-/nitro-3.0.260903-beta.tgz", + "integrity": "sha512-54gANPi62O8rfMvepiJUVuIzEIinYfpeHbebywlLxvVTgIYXDwSvpaU9Id+0sJOBjBx0wC1/CVYXJkH7SY+l0g==", "license": "MIT", "dependencies": { "consola": "^3.4.2", - "crossws": "^0.4.6", - "db0": "^0.3.4", - "env-runner": "^0.1.12", - "h3": "2.0.1-rc.22", + "crossws": "^0.4.12", + "db0": "^0.4.1", + "env-runner": "^0.2.1", + "h3": "^2.0.1-rc.31", "hookable": "^6.1.1", - "nf3": "^0.3.17", - "ocache": "^0.1.5", - "ofetch": "2.0.0-alpha.3", - "ohash": "^2.0.11", - "rolldown": "^1.1.0", - "srvx": "^0.11.16", - "unenv": "2.0.0-rc.24", - "unstorage": "2.0.0-alpha.7" + "nf3": "^0.3.24", + "ocache": "^0.3.0", + "rolldown": "^1.2.7", + "rou3": "^0.9.2", + "srvx": "^1.0.3", + "unenv": "^2.0.0-rc.24", + "unstorage": "^2.0.0-alpha.10" }, "bin": { "nitro": "dist/cli/index.mjs" }, "engines": { "node": "^20.19.0 || >=22.12.0" - }, - "peerDependencies": { - "@vercel/queue": "^0.3.0", - "dotenv": "*", - "giget": "*", - "jiti": "^2.7.0", - "rollup": "^4.61.1", - "vite": "^7 || ^8", - "xml2js": "^0.6.2", - "zephyr-agent": "^0.2.0" - }, - "peerDependenciesMeta": { - "@vercel/queue": { - "optional": true - }, - "dotenv": { - "optional": true - }, - "giget": { - "optional": true - }, - "jiti": { - "optional": true - }, - "rollup": { - "optional": true - }, - "vite": { - "optional": true - }, - "xml2js": { - "optional": true - }, - "zephyr-agent": { - "optional": true - } } }, "node_modules/node-emoji": { @@ -11573,24 +11492,9 @@ } }, "node_modules/ocache": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/ocache/-/ocache-0.1.5.tgz", - "integrity": "sha512-kNNnkkVQup/QDvmTz8Q84wc2ntiyoVHDxa6eHWKt5qdGAmFRBIxy83rxgCYEjW0x06UJ9E3P6VgM2yY4rOBH4w==", - "license": "MIT", - "dependencies": { - "ohash": "^2.0.11" - } - }, - "node_modules/ofetch": { - "version": "2.0.0-alpha.3", - "resolved": "https://registry.npmjs.org/ofetch/-/ofetch-2.0.0-alpha.3.tgz", - "integrity": "sha512-zpYTCs2byOuft65vI3z43Dd6iSdFbOZZLb9/d21aCpx2rGastVU9dOCv0lu4ykc1Ur1anAYjDi3SUvR0vq50JA==", - "license": "MIT" - }, - "node_modules/ohash": { - "version": "2.0.12", - "resolved": "https://registry.npmjs.org/ohash/-/ohash-2.0.12.tgz", - "integrity": "sha512-65S/5gk9YSsaRjcyf7Nfa6h/d3E8/1gslpXfI4W7Dxn/oap8IKRuNT5VXkLQ1YFKIEg4apRY4Pj6aiwFzrDdmw==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/ocache/-/ocache-0.3.0.tgz", + "integrity": "sha512-RS/9P0zeBb0gDJmadGERLH8lZNXK7xbufTDhclkXGvFGTsj0G4M5/cLk+mizcERH29mLXNnocfB5wjcK70wGJg==", "license": "MIT" }, "node_modules/onetime": { @@ -12699,12 +12603,12 @@ "license": "Unlicense" }, "node_modules/rolldown": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.6.tgz", - "integrity": "sha512-vMM4q3aixf46GiF1Kok8jDPFsEpXgFWGjUHXNkNHNm+Y2adXAG2dbX91jkti3i0ZRsOlcmbuzAz1poObSHCmUA==", + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.2.7.tgz", + "integrity": "sha512-g0EtLvBjTUB7jhyV0S/TCup3v/XSVl45vUIGbOGU4QPiyjTenCe4mKuFvW9fEgYmS2Fo42AUssRmNuMziXdrig==", "license": "MIT", "dependencies": { - "@oxc-project/types": "=0.147.0", + "@oxc-project/types": "=0.148.0", "@rolldown/pluginutils": "^1.0.0" }, "bin": { @@ -12714,21 +12618,21 @@ "node": "^20.19.0 || >=22.12.0" }, "optionalDependencies": { - "@rolldown/binding-android-arm-eabi": "1.2.6", - "@rolldown/binding-android-arm64": "1.2.6", - "@rolldown/binding-darwin-arm64": "1.2.6", - "@rolldown/binding-darwin-x64": "1.2.6", - "@rolldown/binding-freebsd-x64": "1.2.6", - "@rolldown/binding-linux-arm-gnueabihf": "1.2.6", - "@rolldown/binding-linux-arm64-gnu": "1.2.6", - "@rolldown/binding-linux-arm64-musl": "1.2.6", - "@rolldown/binding-linux-ppc64-gnu": "1.2.6", - "@rolldown/binding-linux-s390x-gnu": "1.2.6", - "@rolldown/binding-linux-x64-gnu": "1.2.6", - "@rolldown/binding-linux-x64-musl": "1.2.6", - "@rolldown/binding-openharmony-arm64": "1.2.6", - "@rolldown/binding-win32-arm64-msvc": "1.2.6", - "@rolldown/binding-win32-x64-msvc": "1.2.6" + "@rolldown/binding-android-arm-eabi": "1.2.7", + "@rolldown/binding-android-arm64": "1.2.7", + "@rolldown/binding-darwin-arm64": "1.2.7", + "@rolldown/binding-darwin-x64": "1.2.7", + "@rolldown/binding-freebsd-x64": "1.2.7", + "@rolldown/binding-linux-arm-gnueabihf": "1.2.7", + "@rolldown/binding-linux-arm64-gnu": "1.2.7", + "@rolldown/binding-linux-arm64-musl": "1.2.7", + "@rolldown/binding-linux-ppc64-gnu": "1.2.7", + "@rolldown/binding-linux-s390x-gnu": "1.2.7", + "@rolldown/binding-linux-x64-gnu": "1.2.7", + "@rolldown/binding-linux-x64-musl": "1.2.7", + "@rolldown/binding-openharmony-arm64": "1.2.7", + "@rolldown/binding-win32-arm64-msvc": "1.2.7", + "@rolldown/binding-win32-x64-msvc": "1.2.7" } }, "node_modules/rope-sequence": { @@ -12738,9 +12642,9 @@ "license": "MIT" }, "node_modules/rou3": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/rou3/-/rou3-0.8.1.tgz", - "integrity": "sha512-ePa+XGk00/3HuCqrEnK3LxJW7I0SdNg6EFzKUJG73hMAdDcOUC/i/aSz7LSDwLrGr33kal/rqOGydzwl6U7zBA==", + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/rou3/-/rou3-0.9.2.tgz", + "integrity": "sha512-3SOzvaAg8rkHrXtRjpCvCvbyO5to9oOO27Z/XqHEYXfMRVSw/qMIVdmaOk9W2lcRLtR6dlqTjo9hDeJk70QBYQ==", "license": "MIT" }, "node_modules/roughjs": { @@ -13122,9 +13026,9 @@ } }, "node_modules/srvx": { - "version": "0.11.22", - "resolved": "https://registry.npmjs.org/srvx/-/srvx-0.11.22.tgz", - "integrity": "sha512-LqZxxBDMKuMAZzFzJnDCkFOrs9MZQZr0LvHiO/SuSZVdQaXD7xQ5UWTUxheJrQPve1qk9MG2B/yttUvJxw8egQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/srvx/-/srvx-1.0.4.tgz", + "integrity": "sha512-eZmYaxUfZSo7/8m8UdsHRJNmTLSCTPPom9d7a60vMmuVeZvwhbvflRR+00/CxTCjMOFa5+H8tgBeNDVZ+w7AAQ==", "license": "MIT", "bin": { "srvx": "bin/srvx.mjs" @@ -13894,106 +13798,10 @@ } }, "node_modules/unstorage": { - "version": "2.0.0-alpha.7", - "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-2.0.0-alpha.7.tgz", - "integrity": "sha512-ELPztchk2zgFJnakyodVY3vJWGW9jy//keJ32IOJVGUMyaPydwcA1FtVvWqT0TNRch9H+cMNEGllfVFfScImog==", - "license": "MIT", - "peerDependencies": { - "@azure/app-configuration": "^1.11.0", - "@azure/cosmos": "^4.9.1", - "@azure/data-tables": "^13.3.2", - "@azure/identity": "^4.13.0", - "@azure/keyvault-secrets": "^4.10.0", - "@azure/storage-blob": "^12.31.0", - "@capacitor/preferences": "^6 || ^7 || ^8", - "@deno/kv": ">=0.13.0", - "@netlify/blobs": "^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0", - "@planetscale/database": "^1.19.0", - "@upstash/redis": "^1.36.2", - "@vercel/blob": ">=0.27.3", - "@vercel/functions": "^2.2.12 || ^3.0.0", - "@vercel/kv": "^1.0.1", - "aws4fetch": "^1.0.20", - "chokidar": "^4 || ^5", - "db0": ">=0.3.4", - "idb-keyval": "^6.2.2", - "ioredis": "^5.9.3", - "lru-cache": "^11.2.6", - "mongodb": "^6 || ^7", - "ofetch": "*", - "uploadthing": "^7.7.4" - }, - "peerDependenciesMeta": { - "@azure/app-configuration": { - "optional": true - }, - "@azure/cosmos": { - "optional": true - }, - "@azure/data-tables": { - "optional": true - }, - "@azure/identity": { - "optional": true - }, - "@azure/keyvault-secrets": { - "optional": true - }, - "@azure/storage-blob": { - "optional": true - }, - "@capacitor/preferences": { - "optional": true - }, - "@deno/kv": { - "optional": true - }, - "@netlify/blobs": { - "optional": true - }, - "@planetscale/database": { - "optional": true - }, - "@upstash/redis": { - "optional": true - }, - "@vercel/blob": { - "optional": true - }, - "@vercel/functions": { - "optional": true - }, - "@vercel/kv": { - "optional": true - }, - "aws4fetch": { - "optional": true - }, - "chokidar": { - "optional": true - }, - "db0": { - "optional": true - }, - "idb-keyval": { - "optional": true - }, - "ioredis": { - "optional": true - }, - "lru-cache": { - "optional": true - }, - "mongodb": { - "optional": true - }, - "ofetch": { - "optional": true - }, - "uploadthing": { - "optional": true - } - } + "version": "2.0.0-alpha.10", + "resolved": "https://registry.npmjs.org/unstorage/-/unstorage-2.0.0-alpha.10.tgz", + "integrity": "sha512-6h1veZp8gnp4dGllf0tDijoXxDYymJu251IpKKkrSVH+QHL6tXFbwG85KM+CBHSgpkkgtPuIiZ9oLCLP5+1Evw==", + "license": "MIT" }, "node_modules/update-browserslist-db": { "version": "1.3.1", diff --git a/templates/openui-cloud/overlays/vercel-eve/src/components/cloud-chat.tsx b/templates/openui-cloud/overlays/vercel-eve/src/components/cloud-chat.tsx index fba2c3b46..70089d0ec 100644 --- a/templates/openui-cloud/overlays/vercel-eve/src/components/cloud-chat.tsx +++ b/templates/openui-cloud/overlays/vercel-eve/src/components/cloud-chat.tsx @@ -13,6 +13,7 @@ export default function CloudChat() { const storage = useOpenuiCloudStorage({ token: "/api/frontend-token", apiBaseUrl: "https://api.thesys.dev", + features: { artifact: false }, }); const logoPath = mode === "dark" ? OPENUI_LOGOS.DARK : OPENUI_LOGOS.LIGHT; diff --git a/templates/openui-cloud/overlays/vercel-eve/src/eve-chat.ts b/templates/openui-cloud/overlays/vercel-eve/src/eve-chat.ts index 699dbd82a..5f8775449 100644 --- a/templates/openui-cloud/overlays/vercel-eve/src/eve-chat.ts +++ b/templates/openui-cloud/overlays/vercel-eve/src/eve-chat.ts @@ -1,5 +1,4 @@ import { eveAdapter, type ChatLLM, type Message } from "@openuidev/react-ui"; -import type { SessionState } from "eve/client"; // Eve's native HTTP session protocol (same-origin, proxied by `withEve`): // POST /eve/v1/session -> create a session @@ -10,10 +9,12 @@ import type { SessionState } from "eve/client"; const EVE_PREFIX = "/eve/v1"; const SESSION_ID_HEADER = "x-eve-session-id"; -interface KVStorage { - getItem(key: string): string | null; - setItem(key: string, value: string): void; -} +/** Per-thread cursor. Kept local — Eve 0.18+ renamed/narrowed `SessionState`. */ +type EveSessionCursor = { + sessionId?: string; + streamIndex: number; + continuationToken?: string; +}; function messageText(message: Pick): string { const content = message.content as unknown; @@ -33,52 +34,33 @@ function latestUserText(messages: Message[]): string { return user ? messageText(user).trim() : ""; } -const sessionKey = (threadId: string) => `eve-openui:session:${threadId}`; - -function getClientStorage(): KVStorage { - if (typeof window !== "undefined" && window.localStorage) return window.localStorage; - const map = new Map(); - return { - getItem: (key) => (map.has(key) ? (map.get(key) as string) : null), - setItem: (key, value) => { - map.set(key, value); - }, - }; -} - -function loadSession(storage: KVStorage, threadId: string): SessionState { - try { - const raw = storage.getItem(sessionKey(threadId)); - if (raw) return JSON.parse(raw) as SessionState; - } catch { - // fall through to a fresh cursor - } - return { streamIndex: 0 }; -} - -function saveSession(storage: KVStorage, threadId: string, state: SessionState): void { - storage.setItem(sessionKey(threadId), JSON.stringify(state)); -} - /** - * Client-side ChatLLM for Eve. Conversation history lives in OpenUI Cloud; - * this adapter only maps the current turn onto Eve's session protocol and - * keeps the per-thread Eve cursor in localStorage. Stream translation is - * `eveAdapter`'s job; its `onEvent` hook advances the cursor so an - * interrupted or waiting session resumes from `?startIndex=`. + * Client-side ChatLLM for Eve. Conversation history lives in OpenUI Cloud via + * `useOpenuiCloudStorage`. This adapter maps the current turn onto Eve's + * session protocol and holds the per-thread Eve cursor in memory so follow-ups + * resume. Stream translation is `eveAdapter`'s job; its `onEvent` hook advances + * the cursor so an interrupted or waiting session resumes from `?startIndex=`. + * + * `clientContext.conversationId` is the Cloud conversation id (`threadId`). + * Eve does not persist it in session history; the agent reads it and sends + * `conversation` + `store: true` on the Responses call. */ -export function createEveLLM(storage: KVStorage = getClientStorage()): ChatLLM { +export function createEveLLM(): ChatLLM { + const sessions = new Map(); // Cursor for the run in flight. OpenUI finishes consuming one send() stream // before starting the next, so a single slot is enough. - let active: { threadId: string; state: SessionState } | null = null; + let active: { threadId: string; state: EveSessionCursor } | null = null; const send: ChatLLM["send"] = async ({ messages, threadId, signal }): Promise => { - const state = loadSession(storage, threadId); + const state = sessions.get(threadId) ?? { streamIndex: 0 }; const deliverPath = state.sessionId ? `${EVE_PREFIX}/session/${encodeURIComponent(state.sessionId)}` : `${EVE_PREFIX}/session`; - const deliverBody: Record = { message: latestUserText(messages) }; + const deliverBody: Record = { + message: latestUserText(messages), + clientContext: { conversationId: threadId }, + }; if (state.sessionId && state.continuationToken) { deliverBody.continuationToken = state.continuationToken; } @@ -126,11 +108,11 @@ export function createEveLLM(storage: KVStorage = getClientStorage()): ChatLLM { // fresh one. Waiting/failed keep the cursor for a resumable read. if (event.type === "session.completed") { active = null; - saveSession(storage, threadId, { streamIndex: 0 }); + sessions.set(threadId, { streamIndex: 0 }); return; } active.state = { ...state, streamIndex: state.streamIndex + 1 }; - saveSession(storage, threadId, active.state); + sessions.set(threadId, active.state); if (event.type === "session.waiting" || event.type === "session.failed") { active = null; } diff --git a/templates/openui-cloud/overlays/vercel-eve/src/lib/models.ts b/templates/openui-cloud/overlays/vercel-eve/src/lib/models.ts new file mode 100644 index 000000000..36d912c30 --- /dev/null +++ b/templates/openui-cloud/overlays/vercel-eve/src/lib/models.ts @@ -0,0 +1,33 @@ +export const DEFAULT_MODEL = "google/gemini-3.6-flash-free"; + +/** Model ids the Cloud Eve agent accepts via `OPENUI_MODEL`. */ +export const MODEL_IDS = [ + "anthropic/claude-sonnet-5", + "anthropic/claude-sonnet-4.6", + "anthropic/claude-opus-4-7", + "openai/gpt-5.5", + "openai/gpt-5.4", + "openai/gpt-5.4-mini", + "openai/gpt-5.2", + "openai/gpt-5.1", + "openai/gpt-5", + "google/gemini-3.6-flash", + "google/gemini-3.5-flash", + "google/gemini-3.1-pro-preview", + "google/gemini-3.1-pro-free", + "google/gemini-3.1-flash-lite-free", + "google/gemini-3.6-flash-free", + "google/gemini-3.5-flash-free", +] as const; + +const MODEL_ID_SET = new Set(MODEL_IDS); + +export function resolveOpenuiModel(model: string | undefined): string { + const resolved = model?.trim() || DEFAULT_MODEL; + if (!MODEL_ID_SET.has(resolved)) { + throw new Error( + `Unknown OPENUI_MODEL "${resolved}". Use a Cloud model id such as ${DEFAULT_MODEL}.`, + ); + } + return resolved; +} diff --git a/templates/openui-cloud/overlays/vercel-eve/tsconfig.json b/templates/openui-cloud/overlays/vercel-eve/tsconfig.json index 50d96675b..e6f31f0b1 100644 --- a/templates/openui-cloud/overlays/vercel-eve/tsconfig.json +++ b/templates/openui-cloud/overlays/vercel-eve/tsconfig.json @@ -9,6 +9,7 @@ "esModuleInterop": true, "module": "esnext", "moduleResolution": "bundler", + "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "jsx": "react-jsx", @@ -31,5 +32,5 @@ ".eve/**/*.d.ts", "**/*.mts" ], - "exclude": ["node_modules"] + "exclude": ["node_modules", "agent"] } diff --git a/templates/openui-self-hosted/overlays/vercel-eve/tsconfig.json b/templates/openui-self-hosted/overlays/vercel-eve/tsconfig.json index 50d96675b..e6f31f0b1 100644 --- a/templates/openui-self-hosted/overlays/vercel-eve/tsconfig.json +++ b/templates/openui-self-hosted/overlays/vercel-eve/tsconfig.json @@ -9,6 +9,7 @@ "esModuleInterop": true, "module": "esnext", "moduleResolution": "bundler", + "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "jsx": "react-jsx", @@ -31,5 +32,5 @@ ".eve/**/*.d.ts", "**/*.mts" ], - "exclude": ["node_modules"] + "exclude": ["node_modules", "agent"] }