diff --git a/docs/messages.mdx b/docs/messages.mdx
index a0398ec67..79abfac65 100644
--- a/docs/messages.mdx
+++ b/docs/messages.mdx
@@ -50,9 +50,14 @@ If you want to get MessageDocs, you can use `listMessages` instead.
## Showing messages in React
-See [ChatStreaming.tsx](../example/ui/chat/ChatStreaming.tsx) for a streaming
-example, or [ChatBasic.tsx](../example/ui/chat/ChatBasic.tsx) for a
-non-streaming example.
+Examples:
+
+- [ChatBasic.tsx](../example/ui/chat/ChatBasic.tsx): non-streaming messages.
+- [ChatStreaming.tsx](../example/ui/chat/ChatStreaming.tsx): streaming messages
+ with custom React components.
+- [ChatAssistantUI.tsx](../example/ui/chat/ChatAssistantUI.tsx): streaming
+ messages and tool approvals with
+ [assistant-ui](https://www.assistant-ui.com/).
### `useUIMessages` hook
diff --git a/docs/streaming.mdx b/docs/streaming.mdx
index 30a94a017..658ef0af8 100644
--- a/docs/streaming.mdx
+++ b/docs/streaming.mdx
@@ -29,6 +29,8 @@ Example:
- Server: [streaming.ts](../example/convex/chat/streaming.ts)
- Client: [ChatStreaming.tsx](../example/ui/chat/ChatStreaming.tsx)
+- Client with assistant-ui:
+ [ChatAssistantUI.tsx](../example/ui/chat/ChatAssistantUI.tsx)
## Streaming message deltas
diff --git a/docs/tool-approval.mdx b/docs/tool-approval.mdx
index 220d3af82..aa6a0ea4f 100644
--- a/docs/tool-approval.mdx
+++ b/docs/tool-approval.mdx
@@ -12,8 +12,8 @@ action before it happens.
## Defining tools with approval
-Add `needsApproval` to any tool created with `createTool`. It can be a
-boolean or an async function that receives the tool context and input:
+Add `needsApproval` to any tool created with `createTool`. It can be a boolean
+or an async function that receives the tool context and input:
```ts
import { createTool } from "@convex-dev/agent";
@@ -56,11 +56,13 @@ The typical approval flow involves four server functions:
1. **Save the user's message** and schedule generation.
2. **Generate a response.** If the model calls a tool that needs approval,
- generation pauses and the `tool-approval-request` is persisted in the
- thread.
+ generation pauses and the `tool-approval-request` is persisted in the thread.
3. **Submit an approval or denial** for each pending tool call.
`approveToolCall` and `denyToolCall` work from both mutations and actions.
-4. **Continue generation** from the returned message ID.
+4. **Continue generation** by running the same action with the returned message
+ ID as the prompt. Schedule it from the mutation that saves the last pending
+ decision in the step, so continuation does not depend on the client staying
+ connected.
```ts
import { approvalAgent } from "../agents/approval";
@@ -81,7 +83,7 @@ export const sendMessage = mutation({
},
});
-// 2. Generate (stops if approval is needed)
+// 2. Generate (stops if approval is needed). Also continues after approvals.
export const generateResponse = internalAction({
args: { promptMessageId: v.string(), threadId: v.string() },
handler: async (ctx, { promptMessageId, threadId }) => {
@@ -106,29 +108,21 @@ export const submitApproval = mutation({
handler: async (ctx, { threadId, approvalId, approved, reason }) => {
const { messageId } = approved
? await approvalAgent.approveToolCall(ctx, {
- threadId, approvalId, reason,
+ threadId,
+ approvalId,
+ reason,
})
: await approvalAgent.denyToolCall(ctx, {
- threadId, approvalId, reason,
+ threadId,
+ approvalId,
+ reason,
});
+ // 4. If no approval request in this step is still undecided, schedule
+ // generateResponse with promptMessageId: messageId. See the example
+ // files below.
return { messageId };
},
});
-
-// 4. Continue generation from the saved approval decision.
-// Pass the last approval message ID as promptMessageId so the agent
-// resumes generation from where the approval was issued.
-export const continueAfterApprovals = internalAction({
- args: { threadId: v.string(), lastApprovalMessageId: v.string() },
- handler: async (ctx, { threadId, lastApprovalMessageId }) => {
- const result = await approvalAgent.streamText(
- ctx,
- { threadId },
- { promptMessageId: lastApprovalMessageId },
- );
- await result.consumeStream();
- },
-});
```
@@ -142,9 +136,9 @@ For example, an action can call `approveToolCall` and then immediately call
## Handling multiple tool calls
When the model calls several tools in a single step, some or all of them may
-require approval. Submit decisions from the same assistant request together
-with `respondToToolCallApprovals`. The batch uses one bounded lookup and one
-write, and either every decision is saved or none are.
+require approval. Submit decisions from the same assistant request together with
+`respondToToolCallApprovals`. The batch uses one bounded lookup and one write,
+and either every decision is saved or none are.
```ts
const { messageId } = await approvalAgent.respondToToolCallApprovals(ctx, {
@@ -169,12 +163,12 @@ single-decision helpers so the request history is read only once.
If a partial continuation requests another approval, that newer request also
remains pending while you resume an earlier sibling.
-If an unrelated generation starts while approvals are still unresolved, they
-are **automatically denied** with the reason
-`"auto-denied: new generation started"`. This prevents broken message
-histories where tool calls lack results. These denials are synthetic and only
-added to the model's context for that request; they are not saved, so the
-approvals remain pending in storage.
+If an unrelated generation starts while approvals are still unresolved, they are
+**automatically denied** with the reason
+`"auto-denied: new generation started"`. This prevents broken message histories
+where tool calls lack results. These denials are synthetic and only added to the
+model's context for that request; they are not saved, so the approvals remain
+pending in storage.
This does not apply when resuming approvals: on that continuation, earlier
approvals that were not part of the resume are omitted from that model request.
@@ -187,14 +181,11 @@ Approve/Deny buttons. Tool parts with `state === "approval-requested"` are
waiting for a decision.
```tsx
-import { useEffect, useRef } from "react";
import { useMutation } from "convex/react";
import { useUIMessages, type UIMessage } from "@convex-dev/agent/react";
import type { ToolUIPart } from "ai";
function Chat({ threadId }: { threadId: string }) {
- const lastApprovalMessageIdRef = useRef(null);
-
const { results: messages } = useUIMessages(
api.chat.approval.listThreadMessages,
{ threadId },
@@ -202,9 +193,6 @@ function Chat({ threadId }: { threadId: string }) {
);
const submitApproval = useMutation(api.chat.approval.submitApproval);
- const triggerContinuation = useMutation(
- api.chat.approval.triggerContinuation,
- );
const hasPendingApprovals = messages.some((m) =>
m.parts.some(
@@ -214,36 +202,29 @@ function Chat({ threadId }: { threadId: string }) {
),
);
- // When all approvals are resolved, trigger continuation
- useEffect(() => {
- if (!hasPendingApprovals && lastApprovalMessageIdRef.current) {
- void triggerContinuation({
- threadId,
- lastApprovalMessageId: lastApprovalMessageIdRef.current,
- });
- lastApprovalMessageIdRef.current = null;
- }
- }, [hasPendingApprovals, threadId, triggerContinuation]);
-
// Render approval buttons for tool parts with state "approval-requested"
+ // and call submitApproval. The server continues generation.
// ...
}
```
The `ToolUIPart` states relevant to approval are:
-| State | Meaning |
-|-------|---------|
-| `approval-requested` | Waiting for the user to approve or deny |
+| State | Meaning |
+| -------------------- | ---------------------------------------------------- |
+| `approval-requested` | Waiting for the user to approve or deny |
| `approval-responded` | User responded; tool is being executed (if approved) |
-| `output-available` | Tool executed successfully |
-| `output-denied` | Tool was denied |
-| `output-error` | Tool execution failed |
+| `output-available` | Tool executed successfully |
+| `output-denied` | Tool was denied |
+| `output-error` | Tool execution failed |
## Example files
For a complete working example, see:
-- **Agent definition:** [`example/convex/agents/approval.ts`](https://github.com/convex/agent/blob/main/example/convex/agents/approval.ts)
-- **Server functions:** [`example/convex/chat/approval.ts`](https://github.com/convex/agent/blob/main/example/convex/chat/approval.ts)
-- **React UI:** [`example/ui/chat/ChatApproval.tsx`](https://github.com/convex/agent/blob/main/example/ui/chat/ChatApproval.tsx)
+- **Agent definition:**
+ [`example/convex/agents/approval.ts`](https://github.com/convex/agent/blob/main/example/convex/agents/approval.ts)
+- **Server functions:**
+ [`example/convex/chat/approval.ts`](https://github.com/convex/agent/blob/main/example/convex/chat/approval.ts)
+- **React UI:**
+ [`example/ui/chat/ChatApproval.tsx`](https://github.com/convex/agent/blob/main/example/ui/chat/ChatApproval.tsx)
diff --git a/example/README.md b/example/README.md
index 7d3bdf092..2a2674694 100644
--- a/example/README.md
+++ b/example/README.md
@@ -25,3 +25,23 @@ cd agent
npm run setup
npm run dev
```
+
+## assistant-ui chat
+
+`/chat-assistant-ui` renders the tool approval agent with
+[assistant-ui](https://www.assistant-ui.com/) primitives. It uses the same
+backend as the Tool Approval example (`convex/chat/approval.ts`).
+
+- `ui/chat/assistant-ui/useConvexRuntime.ts` connects `useUIMessages` to
+ `useExternalStoreRuntime`. Sending runs `sendMessage` with
+ `optimisticallySendMessage`, and approvals go through `submitApproval`, which
+ resumes generation once every approval in the step is answered. Stop calls
+ `abortStreamByOrder`.
+- `ui/chat/assistant-ui/convertMessage.ts` maps `UIMessage` parts to
+ assistant-ui parts, keyed by the message's stable `key`.
+- `ui/chat/assistant-ui/Thread.tsx` composes the UI from assistant-ui
+ primitives.
+
+With no provider key and no Convex AI gateway, the demo model replies with mock
+text and never calls tools, so approvals need a real model (see
+`convex/modelsForDemo.ts`).
diff --git a/example/convex/chat/approval.test.ts b/example/convex/chat/approval.test.ts
new file mode 100644
index 000000000..13434d51e
--- /dev/null
+++ b/example/convex/chat/approval.test.ts
@@ -0,0 +1,91 @@
+import { describe, expect, test } from "vitest";
+import { createThread, saveMessages } from "@convex-dev/agent";
+import { api, components } from "../_generated/api";
+import { initConvexTest } from "../setup.test";
+
+async function setup(approvalIds: string[]) {
+ const t = initConvexTest();
+ const threadId = await t.run(async (ctx) => {
+ const threadId = await createThread(ctx, components.agent, {});
+ await saveMessages(ctx, components.agent, {
+ threadId,
+ messages: [
+ { role: "user", content: "Delete both files" },
+ {
+ role: "assistant",
+ content: approvalIds.flatMap((approvalId) => [
+ {
+ type: "tool-call" as const,
+ toolCallId: `call-${approvalId}`,
+ toolName: "deleteFile",
+ input: { filename: `${approvalId}.txt` },
+ },
+ {
+ type: "tool-approval-request" as const,
+ toolCallId: `call-${approvalId}`,
+ approvalId,
+ },
+ ]),
+ },
+ ],
+ });
+ return threadId;
+ });
+ const decide = (approvalId: string, approved = true) =>
+ t.mutation(api.chat.approval.submitApproval, {
+ threadId,
+ approvalId,
+ approved,
+ });
+ const scheduled = () =>
+ t.run(async (ctx) =>
+ (await ctx.db.system.query("_scheduled_functions").collect()).map(
+ ({ name, args }) => ({ name, args }),
+ ),
+ );
+ return { threadId, decide, scheduled };
+}
+
+const continuation = (threadId: string, promptMessageId: string) => ({
+ name: "chat/approval:generateResponse",
+ args: [{ threadId, promptMessageId }],
+});
+
+describe("submitApproval", () => {
+ test("continues once, after the last of parallel decisions", async () => {
+ const { threadId, decide, scheduled } = await setup(["a", "b"]);
+ await decide("a");
+ expect(await scheduled()).toEqual([]);
+ const { messageId } = await decide("b");
+ expect(await scheduled()).toEqual([continuation(threadId, messageId)]);
+ });
+
+ test("continues when a step's decisions fill the lookup window", async () => {
+ const ids = Array.from({ length: 100 }, (_, i) => `a${i}`);
+ const { threadId, decide, scheduled } = await setup(ids);
+ for (const id of ids.slice(0, -1)) await decide(id);
+ expect(await scheduled()).toEqual([]);
+ const { messageId } = await decide(ids.at(-1)!);
+ expect(await scheduled()).toEqual([continuation(threadId, messageId)]);
+ }, 30_000);
+
+ test("continues after a single decision", async () => {
+ const { threadId, decide, scheduled } = await setup(["a"]);
+ const { messageId } = await decide("a");
+ expect(await scheduled()).toEqual([continuation(threadId, messageId)]);
+ });
+
+ test("counts a denial as a decision", async () => {
+ const { threadId, decide, scheduled } = await setup(["a", "b"]);
+ await decide("a");
+ const { messageId } = await decide("b", false);
+ expect(await scheduled()).toEqual([continuation(threadId, messageId)]);
+ });
+
+ test("rejects a decision for a step that already continued", async () => {
+ const { threadId, decide, scheduled } = await setup(["a"]);
+ const { messageId } = await decide("a");
+ await expect(decide("a", false)).rejects.toThrow(/already handled/);
+ expect(await scheduled()).toEqual([continuation(threadId, messageId)]);
+ });
+});
diff --git a/example/convex/chat/approval.ts b/example/convex/chat/approval.ts
index edf55b928..c12e05da6 100644
--- a/example/convex/chat/approval.ts
+++ b/example/convex/chat/approval.ts
@@ -4,7 +4,8 @@
// 1. User sends message → model calls a tool with needsApproval
// 2. Generation stops with a tool-approval-request in the response
// 3. Client shows Approve/Deny buttons to the user
-// 4. User clicks Approve or Deny → saves response, schedules continuation
+// 4. User clicks Approve or Deny → saves response; the last decision in the
+// step schedules continuation
// 5. AI SDK automatically handles the approval: executes tool (if approved)
// or creates execution-denied result (if denied), then continues generation
import { paginationOptsValidator } from "convex/server";
@@ -38,8 +39,9 @@ export const sendMessage = mutation({
});
/**
- * Generate a response. If a tool requires approval, generation stops
- * and the approval-request is persisted in the thread.
+ * Generate a response to a prompt, or continue from the last approval
+ * decision in a step. If a tool requires approval, generation stops and the
+ * approval-request is persisted in the thread.
*/
export const generateResponse = internalAction({
args: { promptMessageId: v.string(), threadId: v.string() },
@@ -55,9 +57,10 @@ export const generateResponse = internalAction({
});
/**
- * Submit an approval decision for a single tool call.
- * Saves the decision but does NOT continue generation — the client
- * calls continueAfterApprovals once all pending approvals are resolved.
+ * Submit an approval decision for a single tool call. The decision that
+ * resolves the last pending approval in its step schedules continuation.
+ * Mutations are serializable, so with concurrent decisions exactly one sees
+ * every approval decided.
*/
export const submitApproval = mutation({
args: {
@@ -69,6 +72,23 @@ export const submitApproval = mutation({
returns: v.object({ messageId: v.string() }),
handler: async (ctx, { threadId, approvalId, approved, reason }) => {
await authorizeThreadAccess(ctx, threadId);
+ const { page } = await approvalAgent.listMessages(ctx, {
+ threadId,
+ paginationOpts: { cursor: null, numItems: 100 },
+ });
+ const decided = new Set([approvalId]);
+ let step: string[] | undefined;
+ for (const { message } of page) {
+ if (!Array.isArray(message?.content)) continue;
+ const requested: string[] = [];
+ for (const part of message.content) {
+ if (part.type === "tool-approval-response")
+ decided.add(part.approvalId);
+ if (part.type === "tool-approval-request")
+ requested.push(part.approvalId);
+ }
+ if (requested.includes(approvalId)) step = requested;
+ }
const { messageId } = approved
? await approvalAgent.approveToolCall(ctx, {
threadId,
@@ -76,49 +96,16 @@ export const submitApproval = mutation({
reason,
})
: await approvalAgent.denyToolCall(ctx, { threadId, approvalId, reason });
+ if (step?.every((id) => decided.has(id))) {
+ await ctx.scheduler.runAfter(0, internal.chat.approval.generateResponse, {
+ threadId,
+ promptMessageId: messageId,
+ });
+ }
return { messageId };
},
});
-/**
- * Continue generation after all approvals in a step have been resolved.
- * The client calls this once every pending tool call has been approved or denied.
- */
-export const continueAfterApprovals = internalAction({
- args: {
- threadId: v.string(),
- lastApprovalMessageId: v.string(),
- },
- handler: async (ctx, { threadId, lastApprovalMessageId }) => {
- const result = await approvalAgent.streamText(
- ctx,
- { threadId },
- { promptMessageId: lastApprovalMessageId },
- { saveStreamDeltas: { chunking: "word", throttleMs: 100 } },
- );
- await result.consumeStream();
- },
-});
-
-/**
- * Schedule continuation after all approvals are resolved.
- * Called by the client when hasPendingApprovals becomes false.
- */
-export const triggerContinuation = mutation({
- args: {
- threadId: v.string(),
- lastApprovalMessageId: v.string(),
- },
- handler: async (ctx, { threadId, lastApprovalMessageId }) => {
- await authorizeThreadAccess(ctx, threadId);
- await ctx.scheduler.runAfter(
- 0,
- internal.chat.approval.continueAfterApprovals,
- { threadId, lastApprovalMessageId },
- );
- },
-});
-
/**
* Query messages with streaming support.
*/
diff --git a/example/ui/chat/ChatApproval.tsx b/example/ui/chat/ChatApproval.tsx
index daf7001ed..c78dc75e1 100644
--- a/example/ui/chat/ChatApproval.tsx
+++ b/example/ui/chat/ChatApproval.tsx
@@ -51,15 +51,6 @@ function Chat({ threadId, reset }: { threadId: string; reset: () => void }) {
);
const submitApproval = useMutation(api.chat.approval.submitApproval);
- const triggerContinuation = useMutation(
- api.chat.approval.triggerContinuation,
- );
-
- // Track the last approval messageId so we can use it for continuation.
- const lastApprovalMessageIdRef = useRef(null);
- // Track whether we've already triggered continuation for this batch.
- const continuationTriggeredRef = useRef(false);
-
const hasPendingApprovals = messages.some((m) =>
m.parts.some(
(p) =>
@@ -68,36 +59,6 @@ function Chat({ threadId, reset }: { threadId: string; reset: () => void }) {
),
);
- // When all approvals are resolved (hasPendingApprovals goes false)
- // and we have a saved messageId, trigger continuation.
- useEffect(() => {
- if (
- !hasPendingApprovals &&
- lastApprovalMessageIdRef.current &&
- !continuationTriggeredRef.current
- ) {
- continuationTriggeredRef.current = true;
- void triggerContinuation({
- threadId,
- lastApprovalMessageId: lastApprovalMessageIdRef.current,
- });
- lastApprovalMessageIdRef.current = null;
- }
- if (hasPendingApprovals) {
- continuationTriggeredRef.current = false;
- }
- }, [hasPendingApprovals, threadId, triggerContinuation]);
-
- async function handleApproval(args: {
- threadId: string;
- approvalId: string;
- approved: boolean;
- reason?: string;
- }) {
- const { messageId } = await submitApproval(args);
- lastApprovalMessageIdRef.current = messageId;
- }
-
const [prompt, setPrompt] = useState(
"Delete the file important.txt and transfer $500 to account savings-123",
);
@@ -126,7 +87,7 @@ function Chat({ threadId, reset }: { threadId: string; reset: () => void }) {
key={m.key}
message={m}
threadId={threadId}
- onApproval={handleApproval}
+ onApproval={submitApproval}
/>
))}
@@ -171,8 +132,6 @@ function Chat({ threadId, reset }: { threadId: string; reset: () => void }) {
className="px-4 py-2 rounded-lg bg-red-100 text-red-700 hover:bg-red-200 transition font-medium"
onClick={() => {
reset();
- lastApprovalMessageIdRef.current = null;
- continuationTriggeredRef.current = false;
setPrompt(
"Delete the file important.txt and transfer $500 to account savings-123",
);
diff --git a/example/ui/chat/ChatAssistantUI.tsx b/example/ui/chat/ChatAssistantUI.tsx
new file mode 100644
index 000000000..fd247fbdf
--- /dev/null
+++ b/example/ui/chat/ChatAssistantUI.tsx
@@ -0,0 +1,85 @@
+import { AssistantRuntimeProvider, AuiIf } from "@assistant-ui/react";
+import { useState } from "react";
+import { useDemoThread } from "../hooks/use-demo-thread";
+import { Thread } from "./assistant-ui/Thread";
+import { useConvexRuntime } from "./assistant-ui/useConvexRuntime";
+
+export default function ChatAssistantUI() {
+ const { threadId, resetThread } = useDemoThread("assistant-ui Chat Example");
+ return threadId ? (
+
+ ) : (
+
+ Loading conversation…
+
+ );
+}
+
+function Conversation({
+ threadId,
+ resetThread,
+}: {
+ threadId: string;
+ resetThread: () => Promise;
+}) {
+ const runtime = useConvexRuntime(threadId);
+ const [isCreatingThread, setIsCreatingThread] = useState(false);
+ const [newThreadError, setNewThreadError] = useState();
+
+ const handleNewThread = async () => {
+ setNewThreadError(undefined);
+ setIsCreatingThread(true);
+ try {
+ await resetThread();
+ } catch (cause) {
+ setNewThreadError(
+ cause instanceof Error
+ ? cause.message
+ : "Unable to create a new conversation.",
+ );
+ } finally {
+ setIsCreatingThread(false);
+ }
+ };
+
+ return (
+
+
+
+ {newThreadError && (
+
+ {newThreadError}
+
+ )}
+
+
+
+ );
+}
diff --git a/example/ui/chat/assistant-ui/Thread.tsx b/example/ui/chat/assistant-ui/Thread.tsx
new file mode 100644
index 000000000..e2feb9030
--- /dev/null
+++ b/example/ui/chat/assistant-ui/Thread.tsx
@@ -0,0 +1,240 @@
+import {
+ ActionBarPrimitive,
+ AuiIf,
+ ComposerPrimitive,
+ MessagePrimitive,
+ ThreadPrimitive,
+ type ReasoningMessagePartProps,
+ type ToolApprovalResponse,
+ type ToolCallMessagePartProps,
+} from "@assistant-ui/react";
+import { MarkdownTextPrimitive } from "@assistant-ui/react-markdown";
+import { ArrowDown, ArrowUp, Check, Copy, Square } from "lucide-react";
+import { useState } from "react";
+
+export function Thread() {
+ return (
+
+
+
+
s.thread.isLoading}>
+
+ Loading conversation…
+
+
+
s.thread.hasEarlier}>
+
+ Load earlier messages
+
+
+
s.thread.isEmpty}>
+
+
+ Tools that ask first.
+
+
+ Ask the agent to delete a file, transfer money, or check a
+ balance.
+
+
+ Delete important.txt and transfer $500
+
+
+
+
+
s.thread.isRunning}>
+
+ Working…
+
+
+
+
+
+
+
+
+
+ !s.thread.isRunning}>
+
+
+
+
+ s.thread.isRunning}>
+
+
+
+
+
+
+
+
+ );
+}
+
+function UserMessage() {
+ return (
+
+
+
+ );
+}
+
+function AssistantMessage() {
+ return (
+
+
+
+
+ s.message.status?.type === "incomplete"}>
+
+ This response ended before completion.
+
+
+
+
+ s.message.isCopied}>
+
+
+ !s.message.isCopied}>
+
+
+
+
+
+ );
+}
+
+function Reasoning({ text }: ReasoningMessagePartProps) {
+ return (
+
+ Reasoning
+ {text}
+
+ );
+}
+
+function ToolCall({
+ toolName,
+ argsText,
+ result,
+ isError,
+ status,
+ approval,
+ respondToApproval,
+}: ToolCallMessagePartProps) {
+ const [error, setError] = useState();
+ const [responding, setResponding] = useState(false);
+ const awaitingApproval =
+ approval !== undefined &&
+ approval.approved === undefined &&
+ approval.resolution === undefined;
+ const respond = async (response: ToolApprovalResponse) => {
+ setError(undefined);
+ setResponding(true);
+ try {
+ await respondToApproval(response);
+ } catch (cause) {
+ setError(cause instanceof Error ? cause.message : String(cause));
+ } finally {
+ setResponding(false);
+ }
+ };
+ return (
+
+
+ {toolName} · {toolStatus({ result, isError, status, approval })}
+
+
+ {argsText}
+
+ {result !== undefined && (
+
+ {JSON.stringify(result, null, 2)}
+
+ )}
+ {awaitingApproval && (
+
+
+
+
+ )}
+ {error && (
+
+ {error}
+
+ )}
+
+ );
+}
+
+function toolStatus({
+ result,
+ isError,
+ status,
+ approval,
+}: Pick<
+ ToolCallMessagePartProps,
+ "result" | "isError" | "status" | "approval"
+>) {
+ if (approval?.approved === false) {
+ return `Denied${approval.reason ? `: ${approval.reason}` : ""}`;
+ }
+ if (isError) return "Failed";
+ if (result !== undefined) return "Complete";
+ if (status.type === "running") return "Running…";
+ if (approval && status.type !== "incomplete") {
+ return approval.approved ? "Approved" : "Needs approval";
+ }
+ return status.type === "complete" ? "Complete" : "Stopped";
+}
+
+function MarkdownText() {
+ return ;
+}
diff --git a/example/ui/chat/assistant-ui/convertMessage.test.ts b/example/ui/chat/assistant-ui/convertMessage.test.ts
new file mode 100644
index 000000000..0d550a275
--- /dev/null
+++ b/example/ui/chat/assistant-ui/convertMessage.test.ts
@@ -0,0 +1,301 @@
+import type { UIMessage } from "@convex-dev/agent/react";
+import { describe, expect, it } from "vitest";
+import { convertMessage } from "./convertMessage";
+
+const message: UIMessage = {
+ id: "stream-id",
+ key: "thread-1-0",
+ role: "assistant",
+ parts: [{ type: "text", text: "Once upon a time" }],
+ text: "Once upon a time",
+ status: "streaming",
+ order: 1,
+ stepOrder: 0,
+ _creationTime: 1_700_000_000_000,
+};
+
+describe("convertMessage", () => {
+ it("keeps the same runtime ID when a streamed message is persisted", () => {
+ const streaming = convertMessage(message);
+ const saved = convertMessage({
+ ...message,
+ id: "database-id",
+ status: "success",
+ });
+ expect(streaming.id).toBe(message.key);
+ expect(saved.id).toBe(streaming.id);
+ expect(streaming.status).toEqual({ type: "running" });
+ expect(saved.status).toEqual({ type: "complete", reason: "stop" });
+ expect(saved.createdAt).toEqual(new Date(message._creationTime));
+ });
+
+ it("preserves ordered text, reasoning, and tool results", () => {
+ expect(
+ convertMessage({
+ ...message,
+ status: "success",
+ parts: [
+ { type: "step-start" },
+ { type: "reasoning", text: "I need two characters." },
+ {
+ type: "tool-getCharacterNames",
+ toolCallId: "call-1",
+ state: "output-available",
+ input: { count: 2 },
+ output: ["Alice", "Bob"],
+ },
+ { type: "text", text: "Alice met Bob." },
+ ],
+ }).content,
+ ).toEqual([
+ { type: "reasoning", text: "I need two characters." },
+ {
+ type: "tool-call",
+ toolCallId: "call-1",
+ toolName: "getCharacterNames",
+ argsText: '{"count":2}',
+ result: ["Alice", "Bob"],
+ },
+ { type: "text", text: "Alice met Bob." },
+ ]);
+ });
+
+ it("represents a tool call while its input is still streaming", () => {
+ expect(
+ convertMessage({
+ ...message,
+ parts: [
+ {
+ type: "dynamic-tool",
+ toolName: "getCharacterNames",
+ toolCallId: "call-1",
+ state: "input-streaming",
+ },
+ ],
+ }).content,
+ ).toEqual([
+ {
+ type: "tool-call",
+ toolName: "getCharacterNames",
+ toolCallId: "call-1",
+ argsText: "{}",
+ },
+ ]);
+ });
+
+ it("exposes tool failures and incomplete assistant responses", () => {
+ const result = convertMessage({
+ ...message,
+ status: "failed",
+ parts: [
+ {
+ type: "tool-getCharacterNames",
+ toolCallId: "call-1",
+ state: "output-error",
+ input: {},
+ errorText: "Tool unavailable",
+ },
+ ],
+ });
+ expect(result.content).toEqual([
+ {
+ type: "tool-call",
+ toolName: "getCharacterNames",
+ toolCallId: "call-1",
+ argsText: "{}",
+ result: "Tool unavailable",
+ isError: true,
+ },
+ ]);
+ expect(result.status).toEqual({ type: "incomplete", reason: "error" });
+ });
+
+ it("keeps pending assistant messages running", () => {
+ expect(
+ convertMessage({ ...message, status: "pending", parts: [] }).status,
+ ).toEqual({ type: "running" });
+ });
+
+ it("does not assign assistant status to a user message", () => {
+ const result = convertMessage({
+ ...message,
+ role: "user",
+ status: "success",
+ });
+ expect(result.role).toBe("user");
+ expect(result.content).toEqual(message.parts);
+ expect(result.status).toBeUndefined();
+ });
+ it("maps each approval state to assistant-ui's approval gate", () => {
+ const input = { filename: "important.txt" };
+ const call = {
+ type: "tool-call",
+ toolCallId: "call-1",
+ toolName: "deleteFile",
+ argsText: '{"filename":"important.txt"}',
+ };
+ const result = convertMessage({
+ ...message,
+ status: "success",
+ parts: [
+ {
+ type: "tool-deleteFile",
+ toolCallId: "call-1",
+ state: "approval-requested",
+ input,
+ approval: { id: "approval-1" },
+ },
+ ],
+ });
+ expect(result.status).toEqual({
+ type: "requires-action",
+ reason: "tool-calls",
+ });
+ expect(result.content).toEqual([
+ { ...call, approval: { id: "approval-1" } },
+ ]);
+
+ expect(
+ convertMessage({
+ ...message,
+ status: "success",
+ parts: [
+ {
+ type: "tool-deleteFile",
+ toolCallId: "call-1",
+ state: "approval-responded",
+ input,
+ approval: { id: "approval-1", approved: true },
+ },
+ ],
+ }),
+ ).toMatchObject({
+ status: { type: "complete" },
+ content: [{ ...call, approval: { id: "approval-1", approved: true } }],
+ });
+
+ expect(
+ convertMessage({
+ ...message,
+ status: "success",
+ parts: [
+ {
+ type: "tool-deleteFile",
+ toolCallId: "call-1",
+ state: "output-available",
+ input,
+ output: "Deleted",
+ approval: { id: "approval-1", approved: true },
+ },
+ ],
+ }).content,
+ ).toEqual([
+ {
+ ...call,
+ approval: { id: "approval-1", approved: true },
+ result: "Deleted",
+ },
+ ]);
+ });
+
+ it("reports a denied tool call as an error carrying the reason", () => {
+ const denied = (reason?: string) =>
+ convertMessage({
+ ...message,
+ status: "success",
+ parts: [
+ {
+ type: "dynamic-tool",
+ toolName: "deleteFile",
+ toolCallId: "call-1",
+ state: "output-denied",
+ input: {},
+ approval: { id: "approval-1", approved: false, reason },
+ },
+ ],
+ }).content;
+ expect(denied("Keep that file")).toEqual([
+ {
+ type: "tool-call",
+ toolCallId: "call-1",
+ toolName: "deleteFile",
+ argsText: "{}",
+ approval: {
+ id: "approval-1",
+ approved: false,
+ reason: "Keep that file",
+ },
+ result: { error: "Keep that file" },
+ isError: true,
+ },
+ ]);
+ expect(denied()).toMatchObject([
+ { result: { error: "Tool approval denied" }, isError: true },
+ ]);
+ });
+
+ it("maps sources, files, and data parts, and drops parts with no equivalent", () => {
+ expect(
+ convertMessage({
+ ...message,
+ status: "success",
+ parts: [
+ { type: "step-start" },
+ {
+ type: "source-url",
+ sourceId: "s-1",
+ url: "https://docs.convex.dev",
+ title: "Docs",
+ },
+ {
+ type: "source-document",
+ sourceId: "s-2",
+ mediaType: "application/pdf",
+ title: "Spec",
+ },
+ {
+ type: "file",
+ mediaType: "image/png",
+ url: "https://example.com/a.png",
+ },
+ {
+ type: "file",
+ mediaType: "text/plain",
+ url: "https://example.com/a.txt",
+ filename: "a.txt",
+ },
+ { type: "data-progress", data: { done: 1 } },
+ { type: "custom", kind: "provider.thing" },
+ {
+ type: "reasoning-file",
+ mediaType: "image/png",
+ url: "https://example.com/r.png",
+ },
+ ],
+ }).content,
+ ).toEqual([
+ {
+ type: "source",
+ sourceType: "url",
+ id: "s-1",
+ url: "https://docs.convex.dev",
+ title: "Docs",
+ },
+ {
+ type: "source",
+ sourceType: "document",
+ id: "s-2",
+ mediaType: "application/pdf",
+ title: "Spec",
+ },
+ { type: "image", image: "https://example.com/a.png" },
+ {
+ type: "file",
+ data: "https://example.com/a.txt",
+ mimeType: "text/plain",
+ filename: "a.txt",
+ },
+ { type: "data-progress", data: { done: 1 } },
+ ]);
+ });
+});
diff --git a/example/ui/chat/assistant-ui/convertMessage.ts b/example/ui/chat/assistant-ui/convertMessage.ts
new file mode 100644
index 000000000..c898492dd
--- /dev/null
+++ b/example/ui/chat/assistant-ui/convertMessage.ts
@@ -0,0 +1,128 @@
+import type { MessageStatus, ThreadMessageLike } from "@assistant-ui/react";
+import type { UIMessage } from "@convex-dev/agent/react";
+import {
+ getToolName,
+ isDataUIPart,
+ isToolUIPart,
+ type DynamicToolUIPart,
+ type ToolUIPart,
+} from "ai";
+
+type Part = Exclude[number];
+
+export function convertMessage(message: UIMessage): ThreadMessageLike {
+ return {
+ // Convex's key survives the transition from streamed to persisted messages.
+ id: message.key,
+ role: message.role,
+ createdAt: new Date(message._creationTime),
+ content: message.parts.flatMap(convertPart),
+ ...(message.role === "assistant" ? { status: convertStatus(message) } : {}),
+ };
+}
+
+export function pendingApprovalIds(message: UIMessage | undefined) {
+ return (message?.parts ?? []).flatMap((part) =>
+ isToolUIPart(part) && part.state === "approval-requested"
+ ? [part.approval.id]
+ : [],
+ );
+}
+
+function convertStatus(message: UIMessage): MessageStatus {
+ switch (message.status) {
+ case "pending":
+ case "streaming":
+ return { type: "running" };
+ case "failed":
+ return { type: "incomplete", reason: "error" };
+ case "success":
+ return pendingApprovalIds(message).length
+ ? { type: "requires-action", reason: "tool-calls" }
+ : { type: "complete", reason: "stop" };
+ }
+}
+
+function convertPart(part: UIMessage["parts"][number]): Part[] {
+ switch (part.type) {
+ case "text":
+ case "reasoning":
+ return [{ type: part.type, text: part.text }];
+ case "dynamic-tool":
+ return [convertToolPart(part)];
+ case "source-url":
+ return [
+ {
+ type: "source",
+ sourceType: "url",
+ id: part.sourceId,
+ url: part.url,
+ title: part.title,
+ },
+ ];
+ case "source-document":
+ return [
+ {
+ type: "source",
+ sourceType: "document",
+ id: part.sourceId,
+ title: part.title,
+ mediaType: part.mediaType,
+ filename: part.filename,
+ },
+ ];
+ case "file":
+ return [
+ part.mediaType.startsWith("image")
+ ? { type: "image", image: part.url, filename: part.filename }
+ : {
+ type: "file",
+ data: part.url,
+ mimeType: part.mediaType,
+ filename: part.filename,
+ },
+ ];
+ // assistant-ui has no equivalent for these.
+ case "step-start":
+ case "custom":
+ case "reasoning-file":
+ return [];
+ default:
+ if (isToolUIPart(part)) return [convertToolPart(part)];
+ if (isDataUIPart(part)) return [{ type: part.type, data: part.data }];
+ return part satisfies never;
+ }
+}
+
+function convertToolPart(part: ToolUIPart | DynamicToolUIPart): Part {
+ const call = {
+ type: "tool-call",
+ toolCallId: part.toolCallId,
+ toolName: getToolName(part),
+ argsText: JSON.stringify(part.input ?? {}),
+ } as const;
+ switch (part.state) {
+ case "input-streaming":
+ case "input-available":
+ return call;
+ case "approval-requested":
+ case "approval-responded":
+ return { ...call, approval: part.approval };
+ case "output-available":
+ return { ...call, approval: part.approval, result: part.output };
+ case "output-error":
+ return {
+ ...call,
+ approval: part.approval,
+ result: part.errorText,
+ isError: true,
+ };
+ case "output-denied":
+ return {
+ ...call,
+ approval: part.approval,
+ result: { error: part.approval.reason ?? "Tool approval denied" },
+ isError: true,
+ };
+ }
+}
diff --git a/example/ui/chat/assistant-ui/useConvexRuntime.ts b/example/ui/chat/assistant-ui/useConvexRuntime.ts
new file mode 100644
index 000000000..bd59511c0
--- /dev/null
+++ b/example/ui/chat/assistant-ui/useConvexRuntime.ts
@@ -0,0 +1,58 @@
+import {
+ MessageNotSentError,
+ useExternalStoreRuntime,
+} from "@assistant-ui/react";
+import {
+ optimisticallySendMessage,
+ useUIMessages,
+} from "@convex-dev/agent/react";
+import { useMutation } from "convex/react";
+import { api } from "../../../convex/_generated/api";
+import { convertMessage, pendingApprovalIds } from "./convertMessage";
+
+export function useConvexRuntime(threadId: string) {
+ const { results, status, loadMore } = useUIMessages(
+ api.chat.approval.listThreadMessages,
+ { threadId },
+ { initialNumItems: 10, stream: true },
+ );
+ const sendMessage = useMutation(
+ api.chat.approval.sendMessage,
+ ).withOptimisticUpdate(
+ optimisticallySendMessage(api.chat.approval.listThreadMessages),
+ );
+ const submitApproval = useMutation(api.chat.approval.submitApproval);
+ const abortStream = useMutation(api.chat.streamAbort.abortStreamByOrder);
+ const latest = results.findLast((message) => message.role === "assistant");
+
+ return useExternalStoreRuntime({
+ messages: results,
+ convertMessage,
+ isLoading: status === "LoadingFirstPage",
+ isDisabled: status === "LoadingFirstPage",
+ isSendDisabled: pendingApprovalIds(latest).length > 0,
+ isRunning: latest?.status === "pending" || latest?.status === "streaming",
+ hasEarlier: status === "CanLoadMore",
+ onLoadEarlier: async () => loadMore(10),
+ onNew: async ({ content: [part, ...rest] }) => {
+ if (part?.type !== "text" || rest.length) {
+ throw new MessageNotSentError("This example accepts text only.");
+ }
+ try {
+ await sendMessage({ threadId, prompt: part.text });
+ } catch (cause) {
+ throw new MessageNotSentError(String(cause));
+ }
+ },
+ onRespondToToolApproval: async ({ approvalId, approved, reason }) => {
+ await submitApproval({ threadId, approvalId, approved, reason });
+ },
+ ...(latest?.status === "streaming"
+ ? {
+ onCancel: async () => {
+ await abortStream({ threadId, order: latest.order });
+ },
+ }
+ : {}),
+ });
+}
diff --git a/example/ui/main.tsx b/example/ui/main.tsx
index 23a02b52e..737f8f30e 100644
--- a/example/ui/main.tsx
+++ b/example/ui/main.tsx
@@ -9,9 +9,10 @@ import FilesImages from "./files/FilesImages";
import RateLimiting from "./rate_limiting/RateLimiting";
import { WeatherFashion } from "./workflows/WeatherFashion";
import RagBasic from "./rag/RagBasic";
-import { StrictMode } from "react";
+import { lazy, StrictMode, Suspense } from "react";
import StreamArray from "./objects/StreamArray";
import ChatApproval from "./chat/ChatApproval";
+const ChatAssistantUI = lazy(() => import("./chat/ChatAssistantUI"));
const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL as string);
@@ -42,6 +43,20 @@ export function App() {
} />
} />
} />
+
+ Loading chat…
+
+ }
+ >
+
+
+ }
+ />
} />
} />
} />
@@ -90,6 +105,18 @@ function Index() {
streaming!).
+
+
+ assistant-ui Chat
+
+
+ The tool approval agent in an assistant-ui chat, with streaming,
+ approvals, history, and cancellation.
+
+
=26"
+ }
+ },
+ "node_modules/@assistant-ui/react": {
+ "version": "0.15.25",
+ "resolved": "https://registry.npmjs.org/@assistant-ui/react/-/react-0.15.25.tgz",
+ "integrity": "sha512-uKAtDwMbdF2NY/F1L/sQNuNGU85tf7eyNSCZ2lBX4yddbsjP5FB3v46HxojRiIoeEyxsqe+6GS8p/RBb/YImuQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@assistant-ui/core": "^0.3.24",
+ "@assistant-ui/store": "^0.3.17",
+ "@assistant-ui/tap": "^0.9.21",
+ "assistant-cloud": "^0.2.5",
+ "assistant-stream": "^0.3.48",
+ "radix-ui": "^1.6.7",
+ "react-textarea-autosize": "^8.5.9",
+ "safe-content-frame": "^0.0.33",
+ "zod": "^4.6.5",
+ "zustand": "^5.0.15"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^18 || ^19",
+ "react-dom": "^18 || ^19"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@assistant-ui/react-markdown": {
+ "version": "0.14.19",
+ "resolved": "https://registry.npmjs.org/@assistant-ui/react-markdown/-/react-markdown-0.14.19.tgz",
+ "integrity": "sha512-OO1DbDkLNE+sjqlSW5MxP+KjI0w8QJtOpyfe9ARVfROfuhIalmv64FMGcuUXVCJN0i9axdj+xyz1fJhSM3OUNQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "^2.1.10",
+ "@radix-ui/react-use-callback-ref": "^1.1.4",
+ "@types/hast": "^3.0.5",
+ "classnames": "^2.5.1",
+ "micromark-util-html-tag-name": "^2.0.1",
+ "react-markdown": "^10.1.0"
+ },
+ "peerDependencies": {
+ "@assistant-ui/react": "^0.15.0",
+ "@types/react": "*",
+ "react": "^18 || ^19"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@assistant-ui/react/node_modules/zod": {
+ "version": "4.6.7",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-4.6.7.tgz",
+ "integrity": "sha512-g8W2D2kU6a8untc053fX1uVBKzM7yqAxW/3zwk83+6RyF2+SKOuV+c0wBDhUwzV1PaGapmZH+rmcUzPf+3CGwg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@assistant-ui/store": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/@assistant-ui/store/-/store-0.3.19.tgz",
+ "integrity": "sha512-lxmbfbQCBx7ijIQYmP2OQJMa1aUCvRkvb/Y09fmbkxIhYAcNhSIRcINALe940dGtia+cGn63m8HxYNVoJEcFqg==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@assistant-ui/tap": "^0.9.22",
+ "@types/react": "*",
+ "react": "^18 || ^19"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@assistant-ui/tap": {
+ "version": "0.9.23",
+ "resolved": "https://registry.npmjs.org/@assistant-ui/tap/-/tap-0.9.23.tgz",
+ "integrity": "sha512-VnWoJLDv8/98YknvgB+Cjy+hwM4+BiW9nZMsKvaPdl3dUhuRdLDOZZs6gvE7x6x40NAeP4Wsq9WBDfmus5k31w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^18 || ^19"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/@babel/code-frame": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.7.tgz",
@@ -514,6 +671,16 @@
"node": ">=6.0.0"
}
},
+ "node_modules/@babel/runtime": {
+ "version": "7.29.10",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.10.tgz",
+ "integrity": "sha512-NpugTzbKgGrNe45Ui32cN8vCFFMxVtP/9rtfwv0nP5FRDAjvYBxJcLVpYA9mr1jxP6cnIT7x9LUzuDTbWYYNRA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/template": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.29.7.tgz",
@@ -1049,34 +1216,34 @@
}
},
"node_modules/@floating-ui/core": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.3.tgz",
- "integrity": "sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz",
+ "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@floating-ui/utils": "^0.2.10"
+ "@floating-ui/utils": "^0.2.12"
}
},
"node_modules/@floating-ui/dom": {
- "version": "1.7.4",
- "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.4.tgz",
- "integrity": "sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz",
+ "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@floating-ui/core": "^1.7.3",
- "@floating-ui/utils": "^0.2.10"
+ "@floating-ui/core": "^1.8.0",
+ "@floating-ui/utils": "^0.2.12"
}
},
"node_modules/@floating-ui/react-dom": {
- "version": "2.1.6",
- "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.6.tgz",
- "integrity": "sha512-4JX6rEatQEvlmgU80wZyq9RT96HZJa88q8hp0pBd+LrczeDI4o6uA2M+uvxngVHo4Ihr8uibXxH6+70zhAFrVw==",
+ "version": "2.1.9",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz",
+ "integrity": "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@floating-ui/dom": "^1.7.4"
+ "@floating-ui/dom": "^1.8.0"
},
"peerDependencies": {
"react": ">=16.8.0",
@@ -1084,9 +1251,9 @@
}
},
"node_modules/@floating-ui/utils": {
- "version": "0.2.10",
- "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz",
- "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==",
+ "version": "0.2.12",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz",
+ "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==",
"dev": true,
"license": "MIT"
},
@@ -1732,35 +1899,27 @@
}
},
"node_modules/@radix-ui/number": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.1.tgz",
- "integrity": "sha512-MkKCwxlXTgz6CFoJx3pCwn07GKp36+aZyu/u2Ln2VrA5DcdyCZkASEDBTd8x5whTQQL5CiYf4prXKLcgQdv29g==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.1.3.tgz",
+ "integrity": "sha512-Road2bidD0uu/1BGDOWNdPI06g0lIRy6IF9GZcIrDK2KGItfor8IQwQa+yM2ERgHM1MmHxaxpTzk0/Jp42lNfA==",
"dev": true,
"license": "MIT"
},
"node_modules/@radix-ui/primitive": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.3.tgz",
- "integrity": "sha512-JTF99U/6XIjCBo0wqkU5sK10glYe27MRRsfwoiq5zzOEZLHU3A3KCMa5X/azekYRCJ0HlwI0crAXS/5dEHTzDg==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.2.0.tgz",
+ "integrity": "sha512-KABY+VMIRPJL+Vyzv/335FEhXXD/xDv8BMb1kl48/aXJZMH0LtHCTx5ga5RnxaEP3nZHtmTLf1P9vanmFX46bw==",
"dev": true,
"license": "MIT"
},
- "node_modules/@radix-ui/react-accordion": {
- "version": "1.2.12",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.2.12.tgz",
- "integrity": "sha512-T4nygeh9YE9dLRPhAHSeOZi7HBXo+0kYIPJXayZfvWOWA0+n3dESrZbjfDPUABkUNym6Hd+f2IR113To8D2GPA==",
+ "node_modules/@radix-ui/react-accessible-icon": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-accessible-icon/-/react-accessible-icon-1.2.0.tgz",
+ "integrity": "sha512-BB4+HHkFl3HipEAhm/mLhrpXV+2kRX7MvY4AaImUcQVeWQt5KhV1JEByNs8NGfJOcr95RcQGijt9+OrCo68xGA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-collapsible": "1.1.12",
- "@radix-ui/react-collection": "1.1.7",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-direction": "1.1.1",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-controllable-state": "1.2.2"
+ "@radix-ui/react-visually-hidden": "1.2.13"
},
"peerDependencies": {
"@types/react": "*",
@@ -1777,14 +1936,22 @@
}
}
},
- "node_modules/@radix-ui/react-arrow": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.7.tgz",
- "integrity": "sha512-F+M1tLhO+mlQaOWspE8Wstg+z6PwxwRd8oQ8IXceWz92kfAmalTRf0EjrouQeo7QssEPfCn05B4Ihs1K9WQ/7w==",
+ "node_modules/@radix-ui/react-accordion": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-accordion/-/react-accordion-1.3.1.tgz",
+ "integrity": "sha512-lCZ6sbGS/7WO0j84yx4srIgOf0MRJ/sZ13RonADXxvKBym8xrxNCq5f6DibGcr38sIlwPk8/52uYdXeOPsbEDw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-primitive": "2.1.3"
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-collapsible": "1.2.1",
+ "@radix-ui/react-collection": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-direction": "1.2.0",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-controllable-state": "1.3.0"
},
"peerDependencies": {
"@types/react": "*",
@@ -1801,21 +1968,18 @@
}
}
},
- "node_modules/@radix-ui/react-checkbox": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz",
- "integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==",
+ "node_modules/@radix-ui/react-alert-dialog": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-alert-dialog/-/react-alert-dialog-1.2.1.tgz",
+ "integrity": "sha512-MWC4N7RY+qsbNrFNo7yQ9ZbdoZEW+B5DtpWxJfUnVCqcQxxqqg3qis3RMPTDbCNaTIdHJSn5XDkl9ZdVWXknLg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-presence": "1.1.5",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "@radix-ui/react-use-previous": "1.1.1",
- "@radix-ui/react-use-size": "1.1.1"
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-dialog": "1.3.1",
+ "@radix-ui/react-primitive": "2.2.0"
},
"peerDependencies": {
"@types/react": "*",
@@ -1832,21 +1996,14 @@
}
}
},
- "node_modules/@radix-ui/react-collapsible": {
- "version": "1.1.12",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.1.12.tgz",
- "integrity": "sha512-Uu+mSh4agx2ib1uIGPP4/CKNULyajb3p92LsVXmH2EHVMTfZWpll88XJ0j4W0z3f8NK1eYl1+Mf/szHPmcHzyA==",
+ "node_modules/@radix-ui/react-arrow": {
+ "version": "1.1.17",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.17.tgz",
+ "integrity": "sha512-67jjcVvxjXCCStnTW3Z+M7jmaFMuMR7M2JgpDzH4w7JSRrikmzhjfYgP/09ECb8n7whnsgh1ifJ+Ie96qEj+pQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-presence": "1.1.5",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "@radix-ui/react-use-layout-effect": "1.1.1"
+ "@radix-ui/react-primitive": "2.2.0"
},
"peerDependencies": {
"@types/react": "*",
@@ -1863,17 +2020,14 @@
}
}
},
- "node_modules/@radix-ui/react-collection": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",
- "integrity": "sha512-Fh9rGN0MoI4ZFUNyfFVNU4y9LUz93u9/0K+yLgA2bwRojxM8JU1DyvvMBabnZPBgMWREAJvU2jjVzq+LrFUglw==",
+ "node_modules/@radix-ui/react-aspect-ratio": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-aspect-ratio/-/react-aspect-ratio-1.2.0.tgz",
+ "integrity": "sha512-gHEU+Lx8DlT/FYIjZQvvBJrFSwUngXTjh7FeL9QvJaNALDLez6pgDj2axCUihBjtPBy82LN0gNb25+sTcSXNmA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-slot": "1.2.3"
+ "@radix-ui/react-primitive": "2.2.0"
},
"peerDependencies": {
"@types/react": "*",
@@ -1890,105 +2044,144 @@
}
}
},
- "node_modules/@radix-ui/react-collection/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "node_modules/@radix-ui/react-avatar": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-avatar/-/react-avatar-1.3.1.tgz",
+ "integrity": "sha512-ssZOkfQNkFpYVmCPQlr978xSaU7moSrGXdwg4j2Xs2WlGl/1KsSZtfpK+WnLnx0Rwll1BAh6oUrAy/uR31SBvQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-callback-ref": "1.1.5",
+ "@radix-ui/react-use-is-hydrated": "0.1.3",
+ "@radix-ui/react-use-layout-effect": "1.1.4"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-compose-refs": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.2.tgz",
- "integrity": "sha512-z4eqJvfiNnFMHIIvXP3CY57y2WJs5g2v3X0zm9mEJkrkNv4rDxu+sg9Jh8EkXyeqBkB7SOcboo9dMVqhyrACIg==",
+ "node_modules/@radix-ui/react-checkbox": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.4.1.tgz",
+ "integrity": "sha512-KWtwhh+98ML3seZ9vO9yRY2OwaQG90dCiDAxjpSNY2AaZ3Hik3B0dsk6m0ILywo/no3A9/SozadyPMNweVT8yw==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-presence": "1.1.11",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-size": "1.1.5"
+ },
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-context": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz",
- "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==",
+ "node_modules/@radix-ui/react-collapsible": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collapsible/-/react-collapsible-1.2.1.tgz",
+ "integrity": "sha512-fSzLb/qy1wuZSxQBcxpW0hNXYHDMWiIXDGyJGdA4+FSLknOWZsNRrTCUavxb4PI8b8lvHo/CysO6NVi5zLpo5g==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-presence": "1.1.11",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-layout-effect": "1.1.4"
+ },
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-direction": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.1.tgz",
- "integrity": "sha512-1UEWRX6jnOA2y4H5WczZ44gOOjTEmlqv1uNW4GAJEO5+bauCBhv8snY65Iw5/VOS/ghKN9gr2KjnLKxrsvoMVw==",
+ "node_modules/@radix-ui/react-collection": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.2.0.tgz",
+ "integrity": "sha512-+yiQzqcc7Sy7/5s0jrMCjpPRFB3538VNrXPWdTLZhE/SCfgEws4aI6lHWN/vvcnyhHndROWBzqmqB4QBrITZ9Q==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-slot": "1.5.0",
+ "@radix-ui/react-use-layout-effect": "1.1.4"
+ },
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-dismissable-layer": {
- "version": "1.1.11",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.11.tgz",
- "integrity": "sha512-Nqcp+t5cTB8BinFkZgXiMJniQH0PsUt2k51FUhbdfeKvc4ACcG2uQniY/8+h1Yv6Kza4Q7lD7PQV0z0oicE0Mg==",
+ "node_modules/@radix-ui/react-compose-refs": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.5.tgz",
+ "integrity": "sha512-+48PbAAbq3didjJxa+OaWY2ZwgAKsNiRGyeHKszblZMQ+kcpd9pAaT11cMkGEie0vsOi3QdeTE6d5Fe3Gn61kA==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-callback-ref": "1.1.1",
- "@radix-ui/react-use-escape-keydown": "1.1.1"
- },
"peerDependencies": {
"@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
- },
- "@types/react-dom": {
- "optional": true
}
}
},
- "node_modules/@radix-ui/react-focus-guards": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.1.3.tgz",
- "integrity": "sha512-0rFg/Rj2Q62NCm62jZw0QX7a3sz6QCQU0LpZdNrJX8byRGaGVTqbrW9jAoIAHyMQqsNpeZ81YgSizOt5WXq0Pw==",
+ "node_modules/@radix-ui/react-context": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.3.0.tgz",
+ "integrity": "sha512-v5AYEocMISkbJ+1fTXzZpiFv7NRr3D2WiYbLIKf+FkmJ8VkP6d503eV2n34MFussHXY1pcoq3yfJiQH77dc4Mg==",
"dev": true,
"license": "MIT",
"peerDependencies": {
@@ -2001,16 +2194,18 @@
}
}
},
- "node_modules/@radix-ui/react-focus-scope": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.1.7.tgz",
- "integrity": "sha512-t2ODlkXBQyn7jkl6TNaw/MtVEVvIGelJDCG41Okq/KwUsJBwQ4XVZsHAVUkK4mBv3ewiAS3PGuUWuY2BoK4ZUw==",
+ "node_modules/@radix-ui/react-context-menu": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-context-menu/-/react-context-menu-2.4.1.tgz",
+ "integrity": "sha512-Pddn3Z8lio3/ChxyXaEP3jHTTo1LTHCWwF8+mG1chQlWijP+ttVHBKwezrQTiV6Mj670ojvumqvuGh+mdv33iQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-callback-ref": "1.1.1"
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-menu": "2.2.1",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-controllable-state": "1.3.0"
},
"peerDependencies": {
"@types/react": "*",
@@ -2027,15 +2222,50 @@
}
}
},
- "node_modules/@radix-ui/react-id": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.1.tgz",
- "integrity": "sha512-kGkGegYIdQsOb4XjsfM97rXsiHaBwco+hFI66oO4s9LU+PLAC5oJ7khdOVFxkhsmlbpUqDAvXw11CluXP+jkHg==",
+ "node_modules/@radix-ui/react-dialog": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.3.1.tgz",
+ "integrity": "sha512-+0E4qvVTwjAWra9sEhJ+9BTsvHE00zkUuNw1VGh7S+Gc13dfYk+S1PVQdchWDj+XYHhAai7Z7IpzXVDCGsDplg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-dismissable-layer": "1.2.1",
+ "@radix-ui/react-focus-guards": "1.2.0",
+ "@radix-ui/react-focus-scope": "1.3.1",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-portal": "1.2.0",
+ "@radix-ui/react-presence": "1.1.11",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-slot": "1.5.0",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-layout-effect": "1.1.4",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.7.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-direction": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.2.0.tgz",
+ "integrity": "sha512-FtRA52a/r+LKStFT+neLUm+8vSe7wbzkbQGGeU8ixFiwC8NU14Evoq9ATECqL3eGbcUzJR4fyfA4KkK/q6dfqg==",
"dev": true,
"license": "MIT",
- "dependencies": {
- "@radix-ui/react-use-layout-effect": "1.1.1"
- },
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
@@ -2046,14 +2276,18 @@
}
}
},
- "node_modules/@radix-ui/react-label": {
- "version": "2.1.8",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.8.tgz",
- "integrity": "sha512-FmXs37I6hSBVDlO4y764TNz1rLgKwjJMQ0EGte6F3Cb3f4bIuHB/iLa/8I9VKkmOy+gNHq8rql3j686ACVV21A==",
+ "node_modules/@radix-ui/react-dismissable-layer": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.2.1.tgz",
+ "integrity": "sha512-KIfDcAsx+oVylFZ4xryVKusJUrLLhTQmfnJW4kwk4Km5myvhHCrj04hnWWUC166+xD4DHdH8tQGylwYX1h6+Pg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-primitive": "2.1.4"
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-callback-ref": "1.1.5",
+ "@radix-ui/react-use-effect-event": "0.0.5"
},
"peerDependencies": {
"@types/react": "*",
@@ -2070,14 +2304,20 @@
}
}
},
- "node_modules/@radix-ui/react-label/node_modules/@radix-ui/react-primitive": {
- "version": "2.1.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.4.tgz",
- "integrity": "sha512-9hQc4+GNVtJAIEPEqlYqW5RiYdrr8ea5XQ0ZOnD6fgru+83kqT15mq2OCcbe8KnjRZl5vF3ks69AKz3kh1jrhg==",
+ "node_modules/@radix-ui/react-dropdown-menu": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-dropdown-menu/-/react-dropdown-menu-2.2.1.tgz",
+ "integrity": "sha512-XsHcmYG2AcqnvTqrOXXWcMrhquEIlqucizuDH1MV/qMRW+DndpBCMvNeTRXOxqmG1H5j89M/+I0/34Zdd+zDcQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-slot": "1.2.4"
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-menu": "2.2.1",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-controllable-state": "1.3.0"
},
"peerDependencies": {
"@types/react": "*",
@@ -2094,23 +2334,32 @@
}
}
},
- "node_modules/@radix-ui/react-popper": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.8.tgz",
- "integrity": "sha512-0NJQ4LFFUuWkE7Oxf0htBKS6zLkkjBH+hM1uk7Ng705ReR8m/uelduy1DBo0PyBXPKVnBA6YBlU94MBGXrSBCw==",
+ "node_modules/@radix-ui/react-focus-guards": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.2.0.tgz",
+ "integrity": "sha512-MPm5R0iRGUDrDnPNxmLBkv+X7pN4XKzt+MbWJEuJQsH3NFH4omrbpXpucyYCCKTSt+na/ZxGhEWQrWTZ0285cA==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-focus-scope": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.3.1.tgz",
+ "integrity": "sha512-ugeMhbXt4y5S2T1GnIqbWDKEN962PDwnX1fN0eKOOgf5f63Dh2mn8F1FUySlgW0iF6GiVsRF32DzuDIWTUyQJg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@floating-ui/react-dom": "^2.0.0",
- "@radix-ui/react-arrow": "1.1.7",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-callback-ref": "1.1.1",
- "@radix-ui/react-use-layout-effect": "1.1.1",
- "@radix-ui/react-use-rect": "1.1.1",
- "@radix-ui/react-use-size": "1.1.1",
- "@radix-ui/rect": "1.1.1"
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-callback-ref": "1.1.5"
},
"peerDependencies": {
"@types/react": "*",
@@ -2127,15 +2376,19 @@
}
}
},
- "node_modules/@radix-ui/react-portal": {
- "version": "1.1.9",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.9.tgz",
- "integrity": "sha512-bpIxvq03if6UNwXZ+HTK71JLh4APvnXntDc6XOX8UVq4XQOVl7lwok0AvIl+b8zgCw3fSaVTZMpAPPagXbKmHQ==",
+ "node_modules/@radix-ui/react-form": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-form/-/react-form-0.3.0.tgz",
+ "integrity": "sha512-KnmrCM27m7Jo1R8S6cFDPrEeq20Jfn5dqde0SZrJr2lVXlj6/QZSUCyFoYh1d8ti0uUrMNK5Lx6dUDuINT+f4Q==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-layout-effect": "1.1.1"
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-label": "2.1.17",
+ "@radix-ui/react-primitive": "2.2.0"
},
"peerDependencies": {
"@types/react": "*",
@@ -2152,15 +2405,23 @@
}
}
},
- "node_modules/@radix-ui/react-presence": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.5.tgz",
- "integrity": "sha512-/jfEwNDdQVBCNvjkGit4h6pMOzq8bHkopq458dPt2lMjx+eBQUohZNG9A7DtO/O5ukSbxuaNGXMjHicgwy6rQQ==",
+ "node_modules/@radix-ui/react-hover-card": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-hover-card/-/react-hover-card-1.2.1.tgz",
+ "integrity": "sha512-4QooHxgmpCKRjj1Pft+hETKidYcrbPKcVwMGtk2Oa5DcWY2IH1fHuQt9LG6q5hUQBBV2MhQxSvtx6B/C1xfiTw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-use-layout-effect": "1.1.1"
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-dismissable-layer": "1.2.1",
+ "@radix-ui/react-focus-scope": "1.3.1",
+ "@radix-ui/react-popper": "1.4.0",
+ "@radix-ui/react-portal": "1.2.0",
+ "@radix-ui/react-presence": "1.1.11",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-controllable-state": "1.3.0"
},
"peerDependencies": {
"@types/react": "*",
@@ -2177,77 +2438,721 @@
}
}
},
- "node_modules/@radix-ui/react-primitive": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz",
- "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==",
+ "node_modules/@radix-ui/react-id": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.4.tgz",
+ "integrity": "sha512-TMQp2llA+RYn7JcjnrMnz7wN4pcVttPZnRZo52PLQsoLVKzNlVwUeHmfePgTgRluXFvlD3GD5g5MOVVTJCO0qA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-slot": "1.2.3"
+ "@radix-ui/react-use-layout-effect": "1.1.4"
},
"peerDependencies": {
"@types/react": "*",
- "@types/react-dom": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
- "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
- },
- "@types/react-dom": {
- "optional": true
}
}
},
- "node_modules/@radix-ui/react-primitive/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "node_modules/@radix-ui/react-label": {
+ "version": "2.1.17",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.17.tgz",
+ "integrity": "sha512-xmj7MN/drx1oUAXkfiFIvyDmGNUIN/omGobvA5oAoNqu9zO2MkISYGZOkBcqSzs/UZXXwV+/3ACRE7q7mGcmkA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
+ "@radix-ui/react-primitive": "2.2.0"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-menu": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-menu/-/react-menu-2.2.1.tgz",
+ "integrity": "sha512-G34BsU90SBj5foYpz8pQqq/Q0Dlfyyl6KitWEfRwXC0QvfwhWNAwS49DWP2+rRJ0iwv20Z2Qx7Sk+T03bGo5JA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-collection": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-direction": "1.2.0",
+ "@radix-ui/react-dismissable-layer": "1.2.1",
+ "@radix-ui/react-focus-guards": "1.2.0",
+ "@radix-ui/react-focus-scope": "1.3.1",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-popper": "1.4.0",
+ "@radix-ui/react-portal": "1.2.0",
+ "@radix-ui/react-presence": "1.1.11",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-roving-focus": "1.2.1",
+ "@radix-ui/react-slot": "1.5.0",
+ "@radix-ui/react-use-callback-ref": "1.1.5",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.7.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-menubar": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-menubar/-/react-menubar-1.2.1.tgz",
+ "integrity": "sha512-bRTYtS9JITV2dUYqYZb7+N5SooQBkZrNRejfmyrSKe3Y57aXhKgx//kBUP0kY7pEpsWR/U1AHsAJRzjwCrK3PA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-collection": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-direction": "1.2.0",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-menu": "2.2.1",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-roving-focus": "1.2.1",
+ "@radix-ui/react-use-controllable-state": "1.3.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-navigation-menu": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.4.1.tgz",
+ "integrity": "sha512-XPPZjkeyCSMNNvt0FyDv/PUauG7Ow4GwHQ/XZSwW36F/TS7rR4HFTsXH8ewLnXTOLn3x96/pmTPNQIVoTX/86g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-collection": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-direction": "1.2.0",
+ "@radix-ui/react-dismissable-layer": "1.2.1",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-presence": "1.1.11",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-slot": "1.5.0",
+ "@radix-ui/react-use-callback-ref": "1.1.5",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-layout-effect": "1.1.4",
+ "@radix-ui/react-use-previous": "1.1.4",
+ "@radix-ui/react-visually-hidden": "1.2.13"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-one-time-password-field": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-one-time-password-field/-/react-one-time-password-field-0.2.1.tgz",
+ "integrity": "sha512-KtHdcgnaAK6rohQ/MMJoGYcbgSRJsIuGBdHrFeTB1/9SaKlDs14oSOniW6BL6M43HqvgCO3u4WuVdFLkuc6sqw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/number": "1.1.3",
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-collection": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-direction": "1.2.0",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-roving-focus": "1.2.1",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-effect-event": "0.0.5",
+ "@radix-ui/react-use-is-hydrated": "0.1.3",
+ "@radix-ui/react-use-layout-effect": "1.1.4"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-password-toggle-field": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-password-toggle-field/-/react-password-toggle-field-0.2.1.tgz",
+ "integrity": "sha512-vu4+ZoJAaFjdI7l1lDSZRs+4dEv83Jmu7lyzajPrAeQzX74y84n0rUNWbWSgN9XB5NE8IY86Z02kGH6oRrzR+w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-effect-event": "0.0.5",
+ "@radix-ui/react-use-is-hydrated": "0.1.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popover": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popover/-/react-popover-1.3.1.tgz",
+ "integrity": "sha512-ZNxvXRx5W2Wos4fXCXb5lpdqN0Z5chf+mStOUOTr4ik7d+62MRvoe9rzCA/eGNg36lxXqSrKEKmwuZEcUrIstw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-dismissable-layer": "1.2.1",
+ "@radix-ui/react-focus-guards": "1.2.0",
+ "@radix-ui/react-focus-scope": "1.3.1",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-popper": "1.4.0",
+ "@radix-ui/react-portal": "1.2.0",
+ "@radix-ui/react-presence": "1.1.11",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-slot": "1.5.0",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-layout-effect": "1.1.4",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.7.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-popper": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.4.0.tgz",
+ "integrity": "sha512-yCWRvLeGv9Pz3+efwHqGPp70mZ56r3kfIgQVF56Oj2aAa4uP/Tb+IE59wNcc+758rctqbCKx4LbK8II/r7Bn0Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@floating-ui/react-dom": "^2.0.0",
+ "@radix-ui/react-arrow": "1.1.17",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-callback-ref": "1.1.5",
+ "@radix-ui/react-use-layout-effect": "1.1.4",
+ "@radix-ui/react-use-rect": "1.1.4",
+ "@radix-ui/react-use-size": "1.1.5",
+ "@radix-ui/rect": "1.1.3"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-portal": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.2.0.tgz",
+ "integrity": "sha512-StX7xXnaRU41VvFtMm9zlhVGz8XF6GmWWTXftkQaY+tqVkbs/R9UmAp5mLzHHapk5hM9RMZQvO/3usyIP/g42g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-layout-effect": "1.1.4"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-presence": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.11.tgz",
+ "integrity": "sha512-Z7/atlkab36Z8hm+V8zYc79r0W+tiOB1o0tun1By94JyadkekLQmtEAnBSP9XKXBNQsStoStS4+gX10JpS5akA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.4"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-primitive": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.2.0.tgz",
+ "integrity": "sha512-HCTSPMNqv55Qk0IX4geJbpyXazmqulcimwuyjxTkKi29v+QZbG2Zho9BnbBq4YS2PF+KlNb2CXoLz66uUmblkg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-slot": "1.5.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-progress": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-progress/-/react-progress-1.2.1.tgz",
+ "integrity": "sha512-yQBiM6J3YM8Ums1orkEFpbznK47geKxa0igikzcaS1xHgdba3DdAQBsGbCTt5BVfR8zhEvgxQ0poGcINaD3lvw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-primitive": "2.2.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-radio-group": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-radio-group/-/react-radio-group-1.5.1.tgz",
+ "integrity": "sha512-QbyVT1ddnjqB9H+CUYKkNWdU9fIK3QHCYtjf7mS6ekSqiuXkWtWn5UZW9mhA8qtl3vrVyIsmR9gePstAtKrqkw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-direction": "1.2.0",
+ "@radix-ui/react-presence": "1.1.11",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-roving-focus": "1.2.1",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-size": "1.1.5"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-roving-focus": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.2.1.tgz",
+ "integrity": "sha512-UwraORzVUeEPMclhO1p0vz0qI+TbdDLO9i+FiOqhJyHKwdpCRCck9yVEscUnAMIzCiuNoQa8D4A9bIpOPXGt6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-collection": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-direction": "1.2.0",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-callback-ref": "1.1.5",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-is-hydrated": "0.1.3",
+ "@radix-ui/react-use-layout-effect": "1.1.4"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-scroll-area": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.4.0.tgz",
+ "integrity": "sha512-CFrLqHNejWq5FhKAcj9V/WPGRsol76HBQto81NdOBVFEOqIEkJkKIJt0Z824A/9hHLCtoiR/Kw3euRgzXP2pxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/number": "1.1.3",
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-direction": "1.2.0",
+ "@radix-ui/react-presence": "1.1.11",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-slot": "1.5.0",
+ "@radix-ui/react-use-callback-ref": "1.1.5",
+ "@radix-ui/react-use-layout-effect": "1.1.4"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-select": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.4.1.tgz",
+ "integrity": "sha512-888ZwW0Md6GyptuqYABRX9nLKgoYfcooCyBBvVaX5Jp3e+8Jp2i4Zo/Uy50Hm+Ysn2JfloQXstW4U36w8teVtg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/number": "1.1.3",
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-collection": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-direction": "1.2.0",
+ "@radix-ui/react-dismissable-layer": "1.2.1",
+ "@radix-ui/react-focus-guards": "1.2.0",
+ "@radix-ui/react-focus-scope": "1.3.1",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-popper": "1.4.0",
+ "@radix-ui/react-portal": "1.2.0",
+ "@radix-ui/react-presence": "1.1.11",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-slot": "1.5.0",
+ "@radix-ui/react-use-callback-ref": "1.1.5",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-layout-effect": "1.1.4",
+ "@radix-ui/react-visually-hidden": "1.2.13",
+ "aria-hidden": "^1.2.4",
+ "react-remove-scroll": "^2.7.2"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-separator": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.2.0.tgz",
+ "integrity": "sha512-1jUAap0wZEqVP05Ou7kJgRxe/W+Qftng+rUNWGa0qkKbv9r5pWTG3E7a3ELKo2eJoHKMECnzuYrZpSyO1YgcYQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-primitive": "2.2.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-slider": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slider/-/react-slider-1.6.1.tgz",
+ "integrity": "sha512-IRNRR90moPqxfwCJ0XbMJIxo70W0/1ZExT/sNCxEHMaPx0SF9HoQrcPEC75+H28cFKa0b+KH63anfLYJmwKacw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/number": "1.1.3",
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-collection": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-direction": "1.2.0",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-layout-effect": "1.1.4",
+ "@radix-ui/react-use-size": "1.1.5"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-slot": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.5.0.tgz",
+ "integrity": "sha512-tyYd9ddPXAysAbdbD9eYxgwpCSv6f3PncqVSNKQFSR5lcJVLz3cb/pANDoYrLiHBpXv7skortyUgGUWsYuPPFQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-compose-refs": "1.1.5"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-switch": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.4.1.tgz",
+ "integrity": "sha512-NpBGwc40rY02ZmSvuyeKk0Bvc8ZsNeTMi4qHvJ+ZH4EiYCv0zIXEgdCW4bVdzgIUeP9xxbLJSxKOUfqITYNmkA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-size": "1.1.5"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-tabs": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.2.1.tgz",
+ "integrity": "sha512-hRoJlode+hg5ZNlR+3tkfkUliIybdTpD5lkAvHQ9yaXseGf7XVO9Ib2GPEIOuaJJbo7YWYbNpDDRfo8Dhf6/xA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-direction": "1.2.0",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-presence": "1.1.11",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-roving-focus": "1.2.1",
+ "@radix-ui/react-use-controllable-state": "1.3.0"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-toast": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.3.1.tgz",
+ "integrity": "sha512-iQvL0J7XK4HtJNGkkWMyYrboNseI7vtotFeUkIno8YNxVA9oM7B6//fh0Mc6TSKI96+zioLWi98lQLso88yJmQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-collection": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-dismissable-layer": "1.2.1",
+ "@radix-ui/react-portal": "1.2.0",
+ "@radix-ui/react-presence": "1.1.11",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-callback-ref": "1.1.5",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-layout-effect": "1.1.4",
+ "@radix-ui/react-visually-hidden": "1.2.13"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-select": {
- "version": "2.2.6",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.2.6.tgz",
- "integrity": "sha512-I30RydO+bnn2PQztvo25tswPH+wFBjehVGtmagkU78yMdwTwVf12wnAOF+AeP8S2N8xD+5UPbGhkUfPyvT+mwQ==",
- "dev": true,
- "license": "MIT",
- "dependencies": {
- "@radix-ui/number": "1.1.1",
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-collection": "1.1.7",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-direction": "1.1.1",
- "@radix-ui/react-dismissable-layer": "1.1.11",
- "@radix-ui/react-focus-guards": "1.1.3",
- "@radix-ui/react-focus-scope": "1.1.7",
- "@radix-ui/react-id": "1.1.1",
- "@radix-ui/react-popper": "1.2.8",
- "@radix-ui/react-portal": "1.1.9",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-slot": "1.2.3",
- "@radix-ui/react-use-callback-ref": "1.1.1",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "@radix-ui/react-use-layout-effect": "1.1.1",
- "@radix-ui/react-use-previous": "1.1.1",
- "@radix-ui/react-visually-hidden": "1.2.3",
- "aria-hidden": "^1.2.4",
- "react-remove-scroll": "^2.6.3"
+ "node_modules/@radix-ui/react-toggle": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.2.1.tgz",
+ "integrity": "sha512-+3MUq+WyiBplXYqQ0EIYlq8R4sLQ0T5NbOK7DMdDLCKO93pe2uE0DUJTWWfTBprpJJXxfoF3eMW0xpakVZrYsg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-use-controllable-state": "1.3.0"
},
"peerDependencies": {
"@types/react": "*",
@@ -2264,63 +3169,87 @@
}
}
},
- "node_modules/@radix-ui/react-select/node_modules/@radix-ui/react-slot": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz",
- "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==",
+ "node_modules/@radix-ui/react-toggle-group": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.2.1.tgz",
+ "integrity": "sha512-O8Ldx5ao4p4KoW+DO8/PmkOe5mdKNi3F2SseqjVj88wvDGDHe60cUmO0Zm/uHsKrvNgQGV8Efpuh95Tht/h4vw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-direction": "1.2.0",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-roving-focus": "1.2.1",
+ "@radix-ui/react-toggle": "1.2.1",
+ "@radix-ui/react-use-controllable-state": "1.3.0"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-slot": {
- "version": "1.2.4",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.4.tgz",
- "integrity": "sha512-Jl+bCv8HxKnlTLVrcDE8zTMJ09R9/ukw4qBs/oZClOfoQk/cOTbDn+NceXfV7j09YPVQUryJPHurafcSg6EVKA==",
+ "node_modules/@radix-ui/react-toolbar": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-toolbar/-/react-toolbar-1.2.1.tgz",
+ "integrity": "sha512-Cm8m7JTEeUdbfA6T9xgyu8HfOpyvSx8pB/wj0DlEuWaJe9FilIs4Az9wci/lU9RbthV/UkltszMw5WnnD+m/Ug==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-compose-refs": "1.1.2"
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-direction": "1.2.0",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-roving-focus": "1.2.1",
+ "@radix-ui/react-separator": "1.2.0",
+ "@radix-ui/react-toggle-group": "1.2.1"
},
"peerDependencies": {
"@types/react": "*",
- "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
}
}
},
- "node_modules/@radix-ui/react-toast": {
- "version": "1.2.15",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.2.15.tgz",
- "integrity": "sha512-3OSz3TacUWy4WtOXV38DggwxoqJK4+eDkNMl5Z/MJZaoUPaP4/9lf81xXMe1I2ReTAptverZUpbPY4wWwWyL5g==",
+ "node_modules/@radix-ui/react-tooltip": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.4.1.tgz",
+ "integrity": "sha512-NxLFGSFtZ78zVfcoOhTwR1xwqo5qx1Jh8Pw6FMZ9McCaqfRzz7/gIRahs2Oy5XlPgQ+8QkUcKbN5B0U44J/kCg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/primitive": "1.1.3",
- "@radix-ui/react-collection": "1.1.7",
- "@radix-ui/react-compose-refs": "1.1.2",
- "@radix-ui/react-context": "1.1.2",
- "@radix-ui/react-dismissable-layer": "1.1.11",
- "@radix-ui/react-portal": "1.1.9",
- "@radix-ui/react-presence": "1.1.5",
- "@radix-ui/react-primitive": "2.1.3",
- "@radix-ui/react-use-callback-ref": "1.1.1",
- "@radix-ui/react-use-controllable-state": "1.2.2",
- "@radix-ui/react-use-layout-effect": "1.1.1",
- "@radix-ui/react-visually-hidden": "1.2.3"
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-dismissable-layer": "1.2.1",
+ "@radix-ui/react-focus-scope": "1.3.1",
+ "@radix-ui/react-id": "1.1.4",
+ "@radix-ui/react-popper": "1.4.0",
+ "@radix-ui/react-portal": "1.2.0",
+ "@radix-ui/react-presence": "1.1.11",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-slot": "1.5.0",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-layout-effect": "1.1.4",
+ "@radix-ui/react-visually-hidden": "1.2.13"
},
"peerDependencies": {
"@types/react": "*",
@@ -2338,11 +3267,14 @@
}
},
"node_modules/@radix-ui/react-use-callback-ref": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.1.tgz",
- "integrity": "sha512-FkBMwD+qbGQeMu1cOHnuGB6x4yzPjho8ap5WtbEJ26umhgqVXbhekKUQO+hZEL1vU92a3wHwdp0HAcqAUF5iDg==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.5.tgz",
+ "integrity": "sha512-Y5GBf4NKeADoXI1geiMlMuMoURT3k9MizzzKhGb/m55H94aGigZ01PIpkvsO6lML13BA6XYAXSJ6gza7vTn5nw==",
"dev": true,
"license": "MIT",
+ "dependencies": {
+ "@radix-ui/react-use-layout-effect": "1.1.4"
+ },
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
@@ -2354,14 +3286,15 @@
}
},
"node_modules/@radix-ui/react-use-controllable-state": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.2.2.tgz",
- "integrity": "sha512-BjasUjixPFdS+NKkypcyyN5Pmg83Olst0+c6vGov0diwTEo6mgdqVR6hxcEgFuh4QrAs7Rc+9KuGJ9TVCj0Zzg==",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.3.0.tgz",
+ "integrity": "sha512-TAcBI7bw2ljYCbv4+zuTSd6zICu8pRt6SDN2vJ/Z06K2MXh6I9WYFe/A9ovlFDtR5HVHGm5iDxDoABm/++dbKg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-use-effect-event": "0.0.2",
- "@radix-ui/react-use-layout-effect": "1.1.1"
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-use-effect-event": "0.0.5",
+ "@radix-ui/react-use-layout-effect": "1.1.4"
},
"peerDependencies": {
"@types/react": "*",
@@ -2374,13 +3307,13 @@
}
},
"node_modules/@radix-ui/react-use-effect-event": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.2.tgz",
- "integrity": "sha512-Qp8WbZOBe+blgpuUT+lw2xheLP8q0oatc9UpmiemEICxGvFLYmHm9QowVZGHtJlGbS6A6yJ3iViad/2cVjnOiA==",
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-effect-event/-/react-use-effect-event-0.0.5.tgz",
+ "integrity": "sha512-7cshFL8HGS/7HEiHH+9kL9HBwp2sa9yX18Knwek6KYWmXwM7pegMgta2AXMQKI+rq3JnfSj9x8wYqFMTdG1Jgg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-use-layout-effect": "1.1.1"
+ "@radix-ui/react-use-layout-effect": "1.1.4"
},
"peerDependencies": {
"@types/react": "*",
@@ -2393,14 +3326,30 @@
}
},
"node_modules/@radix-ui/react-use-escape-keydown": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.1.tgz",
- "integrity": "sha512-Il0+boE7w/XebUHyBjroE+DbByORGR9KKmITzbR7MyQ4akpORYP/ZmbhAr0DG7RmmBqoOnZdy2QlvajJ2QA59g==",
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.6.tgz",
+ "integrity": "sha512-9cRullnQRv+kqnRmFlmh0WC3kAPuGmHiQ9VwsXdrYk//sBhgCKEttcpPEPgIQbyx6TGUmooVEHYTyohwz/lSJg==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-use-callback-ref": "1.1.1"
+ "@radix-ui/react-use-callback-ref": "1.1.5"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@radix-ui/react-use-is-hydrated": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-is-hydrated/-/react-use-is-hydrated-0.1.3.tgz",
+ "integrity": "sha512-umO/aJ+82CpOnhDZUTbILCQf7kU/g0iv+oGs/Q8jw7IkhWBzaEP4sA268PhFAJTFetbwp3ICc6ktpI4TqtxcIw==",
+ "dev": true,
+ "license": "MIT",
"peerDependencies": {
"@types/react": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
@@ -2412,9 +3361,9 @@
}
},
"node_modules/@radix-ui/react-use-layout-effect": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.1.tgz",
- "integrity": "sha512-RbJRS4UWQFkzHTTwVymMTUv8EqYhOp8dOOviLj2ugtTiXRaRQS7GLGxZTLL1jWhMeoSCf5zmcZkqTl9IiYfXcQ==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.4.tgz",
+ "integrity": "sha512-K20DkRkUwDnxEYMBPcg3Y6voLkEy5p5QQmszZgLngKKiC7dzBR/aEuK3w1qlx2JWDUNH6FluahYdgR3BP+QbYw==",
"dev": true,
"license": "MIT",
"peerDependencies": {
@@ -2428,9 +3377,9 @@
}
},
"node_modules/@radix-ui/react-use-previous": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.1.tgz",
- "integrity": "sha512-2dHfToCj/pzca2Ck724OZ5L0EVrr3eHRNsG/b3xQJLA2hZpVCS99bLAX+hm1IHXDEnzU6by5z/5MIY794/a8NQ==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.4.tgz",
+ "integrity": "sha512-XoSLhbRbqxFtgJoi2fNHA3C6pDlY34x508vUpUGoFZfvePfHXHbE1lC4FYFMnJWgiCRroSTw6fOsXQoVS9RwZg==",
"dev": true,
"license": "MIT",
"peerDependencies": {
@@ -2444,13 +3393,13 @@
}
},
"node_modules/@radix-ui/react-use-rect": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.1.tgz",
- "integrity": "sha512-QTYuDesS0VtuHNNvMh+CjlKJ4LJickCMUAqjlE3+j8w+RlRpwyX3apEQKGFzbZGdo7XNG1tXa+bQqIE7HIXT2w==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.4.tgz",
+ "integrity": "sha512-cSOCh6JlkmfjLyNcLiu2nB4v+nm+dkZ+Q5KHWk/soo4U7ZLiEQFKHK9/YmtBHjfCEaU43IBKQOc4/uJmCaiCTQ==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/rect": "1.1.1"
+ "@radix-ui/rect": "1.1.3"
},
"peerDependencies": {
"@types/react": "*",
@@ -2463,13 +3412,13 @@
}
},
"node_modules/@radix-ui/react-use-size": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.1.tgz",
- "integrity": "sha512-ewrXRDTAqAXlkl6t/fkXWNAhFX9I+CkKlw6zjEwk86RSPKwZr3xpBRso655aqYafwtnbpHLj6toFzmd6xdVptQ==",
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.5.tgz",
+ "integrity": "sha512-V1McDQkMGzgivwqdu7u96APs7oi0Jvj9LTzgq3WWrDZqxWdAqU9yZnZQqk5OizGFR8badUQwZsrlao7MOlWYOA==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-use-layout-effect": "1.1.1"
+ "@radix-ui/react-use-layout-effect": "1.1.4"
},
"peerDependencies": {
"@types/react": "*",
@@ -2482,13 +3431,13 @@
}
},
"node_modules/@radix-ui/react-visually-hidden": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.3.tgz",
- "integrity": "sha512-pzJq12tEaaIhqjbzpCuv/OypJY/BPavOofm+dbab+MHLajy277+1lLm6JFcGgF5eskJ6mquGirhXY2GD/8u8Ug==",
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.2.13.tgz",
+ "integrity": "sha512-feijiN1oPk4rck4u9Dm9tsU4mT6Wp9oeEEhaz1WUEs1VuqLf8xzsFG+Qk+uWq6TnMH9O+WRECRg0NftyP9E4Fw==",
"dev": true,
"license": "MIT",
"dependencies": {
- "@radix-ui/react-primitive": "2.1.3"
+ "@radix-ui/react-primitive": "2.2.0"
},
"peerDependencies": {
"@types/react": "*",
@@ -2506,9 +3455,9 @@
}
},
"node_modules/@radix-ui/rect": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.1.tgz",
- "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.3.tgz",
+ "integrity": "sha512-JtyZR+mqgBibTo8xea3B6ZRmzZiM/YeVBtUkas6zMuXjAlfIFIW2FgqeM9eLyvEaYX66vr6DJMK+4U6LV0KhNw==",
"dev": true,
"license": "MIT"
},
@@ -3296,6 +4245,72 @@
"node": ">=14.0.0"
}
},
+ "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/core": {
+ "version": "1.11.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.2.2",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/runtime": {
+ "version": "1.11.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@emnapi/wasi-threads": {
+ "version": "1.2.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.1.4",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@tybys/wasm-util": "^0.10.1"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "peerDependencies": {
+ "@emnapi/core": "^1.7.1",
+ "@emnapi/runtime": "^1.7.1"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/@tybys/wasm-util": {
+ "version": "0.10.2",
+ "dev": true,
+ "inBundle": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@tailwindcss/oxide-wasm32-wasi/node_modules/tslib": {
+ "version": "2.8.1",
+ "dev": true,
+ "inBundle": true,
+ "license": "0BSD",
+ "optional": true
+ },
"node_modules/@tailwindcss/oxide-win32-arm64-msvc": {
"version": "4.3.3",
"resolved": "https://registry.npmjs.org/@tailwindcss/oxide-win32-arm64-msvc/-/oxide-win32-arm64-msvc-4.3.3.tgz",
@@ -3404,9 +4419,9 @@
}
},
"node_modules/@types/hast": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz",
- "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.5.tgz",
+ "integrity": "sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -4108,6 +5123,84 @@
"node": ">=12"
}
},
+ "node_modules/assistant-cloud": {
+ "version": "0.2.7",
+ "resolved": "https://registry.npmjs.org/assistant-cloud/-/assistant-cloud-0.2.7.tgz",
+ "integrity": "sha512-w9Nq03JwNVkQovlStrIQb22K/VIyuZ7ioTzjpQTLIggFdL1dUz++DEA1W3VYTFzSHIptseuHvaWSUM05hs5uVg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assistant-stream": "^0.3.49"
+ },
+ "peerDependencies": {
+ "@opentelemetry/api": "^1.9.0",
+ "@opentelemetry/exporter-trace-otlp-http": ">=0.200.0",
+ "@opentelemetry/sdk-trace-base": "^2.1.0",
+ "ai": "^6.0.0 || ^7.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@opentelemetry/api": {
+ "optional": true
+ },
+ "@opentelemetry/exporter-trace-otlp-http": {
+ "optional": true
+ },
+ "@opentelemetry/sdk-trace-base": {
+ "optional": true
+ },
+ "ai": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/assistant-stream": {
+ "version": "0.3.50",
+ "resolved": "https://registry.npmjs.org/assistant-stream/-/assistant-stream-0.3.50.tgz",
+ "integrity": "sha512-IaH+fesbKJE/2R1lH69DPRUfvv87lNE6j3hFf2RZaCCf79UCyF8dtaI1NK5k792p8eIQpxSLbgHs09fX5H8A6A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@standard-schema/spec": "^1.1.0",
+ "@types/json-schema": "^7.0.15",
+ "nanoid": "^6.0.2",
+ "secure-json-parse": "^4.1.0"
+ },
+ "peerDependencies": {
+ "ai": "^6.0.0 || ^7.0.0",
+ "ioredis": "^5.10.1 || ^6.0.0",
+ "redis": "^5.12.1"
+ },
+ "peerDependenciesMeta": {
+ "ai": {
+ "optional": true
+ },
+ "ioredis": {
+ "optional": true
+ },
+ "redis": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/assistant-stream/node_modules/nanoid": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-6.0.2.tgz",
+ "integrity": "sha512-hIvVOb9Qr1p/9CNNLOe0OlWvgx/ziTsVwKN/GDSsuArN2K0wDiafP3s0SWmsm7o2BdnyS8Z9Z64NFBUbn6ziBg==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.js"
+ },
+ "engines": {
+ "node": "^22 || ^24 || >=26"
+ }
+ },
"node_modules/ast-types-flow": {
"version": "0.0.8",
"resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.8.tgz",
@@ -4541,6 +5634,13 @@
"url": "https://polar.sh/cva"
}
},
+ "node_modules/classnames": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz",
+ "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/cliui": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
@@ -9015,6 +10115,84 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/radix-ui": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/radix-ui/-/radix-ui-1.8.1.tgz",
+ "integrity": "sha512-HPfpVGizO9xANlsFSauruLhRe/3+iOt3vPX0MXYle/UQi3gorQrSYtBcdiv0BZYewcl2rvL59qrIuLFMGAmUrw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@radix-ui/primitive": "1.2.0",
+ "@radix-ui/react-accessible-icon": "1.2.0",
+ "@radix-ui/react-accordion": "1.3.1",
+ "@radix-ui/react-alert-dialog": "1.2.1",
+ "@radix-ui/react-arrow": "1.1.17",
+ "@radix-ui/react-aspect-ratio": "1.2.0",
+ "@radix-ui/react-avatar": "1.3.1",
+ "@radix-ui/react-checkbox": "1.4.1",
+ "@radix-ui/react-collapsible": "1.2.1",
+ "@radix-ui/react-collection": "1.2.0",
+ "@radix-ui/react-compose-refs": "1.1.5",
+ "@radix-ui/react-context": "1.3.0",
+ "@radix-ui/react-context-menu": "2.4.1",
+ "@radix-ui/react-dialog": "1.3.1",
+ "@radix-ui/react-direction": "1.2.0",
+ "@radix-ui/react-dismissable-layer": "1.2.1",
+ "@radix-ui/react-dropdown-menu": "2.2.1",
+ "@radix-ui/react-focus-guards": "1.2.0",
+ "@radix-ui/react-focus-scope": "1.3.1",
+ "@radix-ui/react-form": "0.3.0",
+ "@radix-ui/react-hover-card": "1.2.1",
+ "@radix-ui/react-label": "2.1.17",
+ "@radix-ui/react-menu": "2.2.1",
+ "@radix-ui/react-menubar": "1.2.1",
+ "@radix-ui/react-navigation-menu": "1.4.1",
+ "@radix-ui/react-one-time-password-field": "0.2.1",
+ "@radix-ui/react-password-toggle-field": "0.2.1",
+ "@radix-ui/react-popover": "1.3.1",
+ "@radix-ui/react-popper": "1.4.0",
+ "@radix-ui/react-portal": "1.2.0",
+ "@radix-ui/react-presence": "1.1.11",
+ "@radix-ui/react-primitive": "2.2.0",
+ "@radix-ui/react-progress": "1.2.1",
+ "@radix-ui/react-radio-group": "1.5.1",
+ "@radix-ui/react-roving-focus": "1.2.1",
+ "@radix-ui/react-scroll-area": "1.4.0",
+ "@radix-ui/react-select": "2.4.1",
+ "@radix-ui/react-separator": "1.2.0",
+ "@radix-ui/react-slider": "1.6.1",
+ "@radix-ui/react-slot": "1.5.0",
+ "@radix-ui/react-switch": "1.4.1",
+ "@radix-ui/react-tabs": "1.2.1",
+ "@radix-ui/react-toast": "1.3.1",
+ "@radix-ui/react-toggle": "1.2.1",
+ "@radix-ui/react-toggle-group": "1.2.1",
+ "@radix-ui/react-toolbar": "1.2.1",
+ "@radix-ui/react-tooltip": "1.4.1",
+ "@radix-ui/react-use-callback-ref": "1.1.5",
+ "@radix-ui/react-use-controllable-state": "1.3.0",
+ "@radix-ui/react-use-effect-event": "0.0.5",
+ "@radix-ui/react-use-escape-keydown": "1.1.6",
+ "@radix-ui/react-use-is-hydrated": "0.1.3",
+ "@radix-ui/react-use-layout-effect": "1.1.4",
+ "@radix-ui/react-use-size": "1.1.5",
+ "@radix-ui/react-visually-hidden": "1.2.13"
+ },
+ "peerDependencies": {
+ "@types/react": "*",
+ "@types/react-dom": "*",
+ "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
+ "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "@types/react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/react": {
"version": "19.2.4",
"resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz",
@@ -9091,9 +10269,9 @@
}
},
"node_modules/react-remove-scroll": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz",
- "integrity": "sha512-HpMh8+oahmIdOuS5aFKKY6Pyog+FNaZV/XyJOq7b4YFwsFHe5yYfdbIalI4k3vU2nSDql7YskmUseHsRrJqIPA==",
+ "version": "2.7.2",
+ "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.2.tgz",
+ "integrity": "sha512-Iqb9NjCCTt6Hf+vOdNIZGdTiH1QSqr27H/Ek9sv/a97gfueI/5h1s3yRi1nngzMUaOOToin5dI1dXKdXiF+u0Q==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -9202,6 +10380,24 @@
}
}
},
+ "node_modules/react-textarea-autosize": {
+ "version": "8.5.9",
+ "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.5.9.tgz",
+ "integrity": "sha512-U1DGlIQN5AwgjTyOEnI1oCcMuEr1pv1qOtklB2l4nyMGbHzWrI0eFsYK0zos2YWqAolJyG0IWJaqWmWj5ETh0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.20.13",
+ "use-composed-ref": "^1.3.0",
+ "use-latest": "^1.2.1"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
"node_modules/readdirp": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
@@ -9400,6 +10596,13 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/safe-content-frame": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/safe-content-frame/-/safe-content-frame-0.0.33.tgz",
+ "integrity": "sha512-JvBLoQu8rhu80MwijhnJ2zA057uCmatyOxqLbcfpMZ3XM2bI+lmu0x7e1ne92m9wHGi4eB25VcJMnSDeoQNg6w==",
+ "dev": true,
+ "license": "MIT"
+ },
"node_modules/safe-push-apply": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-push-apply/-/safe-push-apply-1.0.0.tgz",
@@ -9442,6 +10645,23 @@
"dev": true,
"license": "MIT"
},
+ "node_modules/secure-json-parse": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.1.1.tgz",
+ "integrity": "sha512-lnd81MQEZKjhW/Gd2TQqdd4XP6QYNdDW/EP+I7nTrFHP9y2LmaGPIHk9xsnzcOiEr1c39c/e84xFgGviQKBTRw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fastify"
+ },
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/fastify"
+ }
+ ],
+ "license": "BSD-3-Clause"
+ },
"node_modules/semver": {
"version": "7.7.3",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz",
@@ -10403,6 +11623,54 @@
}
}
},
+ "node_modules/use-composed-ref": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.4.0.tgz",
+ "integrity": "sha512-djviaxuOOh7wkj0paeO1Q/4wMZ8Zrnag5H6yBvzN7AKKe8beOaED9SF5/ByLqsku8NP4zQqsvM2u3ew/tJK8/w==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/use-isomorphic-layout-effect": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.1.tgz",
+ "integrity": "sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/use-latest": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.3.0.tgz",
+ "integrity": "sha512-mhg3xdm9NaM8q+gLT8KryJPnRFOz1/5XPBhmDEVZK1webPzDjrPk7f/mbpeLqTgB9msytYWANxgALOCJKnLvcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "use-isomorphic-layout-effect": "^1.1.1"
+ },
+ "peerDependencies": {
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ }
+ }
+ },
"node_modules/use-sidecar": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.3.tgz",
@@ -11091,6 +12359,36 @@
"zod": "^3.25.0 || ^4.0.0"
}
},
+ "node_modules/zustand": {
+ "version": "5.0.15",
+ "resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.15.tgz",
+ "integrity": "sha512-MpSEjRiBkA9crSYeOUH32rJC7SVqAbm0Fqcqge/bUi2PPoLcBWKOsG+C8mevmpr8TwXHBVkChbbJiyvkE+i/3A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20.0"
+ },
+ "peerDependencies": {
+ "@types/react": ">=18.0.0",
+ "immer": ">=9.0.6",
+ "react": ">=18.0.0",
+ "use-sync-external-store": ">=1.2.0"
+ },
+ "peerDependenciesMeta": {
+ "@types/react": {
+ "optional": true
+ },
+ "immer": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "use-sync-external-store": {
+ "optional": true
+ }
+ }
+ },
"node_modules/zwitch": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz",
diff --git a/package.json b/package.json
index 25c76d499..29ffd94d4 100644
--- a/package.json
+++ b/package.json
@@ -96,6 +96,8 @@
"@ai-sdk/otel": "1.0.28",
"@ai-sdk/provider": "4.0.3",
"@ai-sdk/provider-utils": "5.0.10",
+ "@assistant-ui/react": "0.15.25",
+ "@assistant-ui/react-markdown": "0.14.19",
"@convex-dev/ai-sdk-provider": "^0.1.0",
"@convex-dev/eslint-plugin": "5.0.0",
"@convex-dev/rag": "0.7.6",
@@ -109,12 +111,12 @@
"@opentelemetry/exporter-trace-otlp-http": "0.219.0",
"@opentelemetry/resources": "2.8.0",
"@opentelemetry/sdk-trace-base": "2.8.0",
- "@radix-ui/react-accordion": "1.2.12",
- "@radix-ui/react-checkbox": "1.3.3",
- "@radix-ui/react-label": "2.1.8",
- "@radix-ui/react-select": "2.2.6",
- "@radix-ui/react-slot": "1.2.4",
- "@radix-ui/react-toast": "1.2.15",
+ "@radix-ui/react-accordion": "1.3.1",
+ "@radix-ui/react-checkbox": "1.4.1",
+ "@radix-ui/react-label": "2.1.17",
+ "@radix-ui/react-select": "2.4.1",
+ "@radix-ui/react-slot": "1.5.0",
+ "@radix-ui/react-toast": "1.3.1",
"@tailwindcss/typography": "0.5.19",
"@tailwindcss/vite": "4.3.3",
"@types/node": "24.13.3",