diff --git a/apps/dojo/e2e/tests/cloudflareTests/agenticChatPage.spec.ts b/apps/dojo/e2e/tests/cloudflareTests/agenticChatPage.spec.ts new file mode 100644 index 000000000..92a503c3c --- /dev/null +++ b/apps/dojo/e2e/tests/cloudflareTests/agenticChatPage.spec.ts @@ -0,0 +1,66 @@ +import { + test, + expect, + waitForAIResponse, + retryOnAIFailure, +} from "../../test-isolation-helper"; +import { AgenticChatPage } from "../../featurePages/AgenticChatPage"; + +test("[Cloudflare] Agentic Chat sends and receives a greeting message", async ({ + page, +}) => { + await retryOnAIFailure(async () => { + await page.goto("/cloudflare/feature/agentic_chat"); + + const chat = new AgenticChatPage(page); + + await chat.openChat(); + await chat.agentGreeting.waitFor({ state: "visible" }); + await chat.sendMessage("Hi"); + + await waitForAIResponse(page); + await chat.assertUserMessageVisible("Hi"); + await chat.assertAgentReplyVisible(/Hello|Hi|hey/i); + }); +}); + +test("[Cloudflare] Agentic Chat responds to questions", async ({ page }) => { + await retryOnAIFailure(async () => { + await page.goto("/cloudflare/feature/agentic_chat"); + + const chat = new AgenticChatPage(page); + + await chat.openChat(); + await chat.agentGreeting.waitFor({ state: "visible" }); + + await chat.sendMessage("What is 2+2?"); + await chat.assertUserMessageVisible("What is 2+2?"); + await waitForAIResponse(page); + + await chat.assertAgentReplyVisible(/4|four/i); + }); +}); + +test("[Cloudflare] Agentic Chat retains conversation context", async ({ + page, +}) => { + await retryOnAIFailure(async () => { + await page.goto("/cloudflare/feature/agentic_chat"); + + const chat = new AgenticChatPage(page); + await chat.openChat(); + await chat.agentGreeting.waitFor({ state: "visible" }); + + // First message + await chat.sendMessage("My name is Alice"); + await chat.assertUserMessageVisible("My name is Alice"); + await waitForAIResponse(page); + await chat.assertAgentReplyVisible(/Alice/i); + + // Check if agent remembers + await chat.sendMessage("What is my name?"); + await chat.assertUserMessageVisible("What is my name?"); + await waitForAIResponse(page); + await chat.assertAgentReplyVisible(/Alice/i); + }); +}); diff --git a/apps/dojo/e2e/tests/cloudflareTests/agenticGenUI.spec.ts b/apps/dojo/e2e/tests/cloudflareTests/agenticGenUI.spec.ts new file mode 100644 index 000000000..2a09bbd41 --- /dev/null +++ b/apps/dojo/e2e/tests/cloudflareTests/agenticGenUI.spec.ts @@ -0,0 +1,49 @@ +import { + test, + expect, + waitForAIResponse, + retryOnAIFailure, +} from "../../test-isolation-helper"; +import { AgenticChatPage } from "../../featurePages/AgenticChatPage"; + +test("[Cloudflare] Agentic Gen UI breaks down tasks into steps", async ({ + page, +}) => { + await retryOnAIFailure(async () => { + await page.goto("/cloudflare/feature/agentic_generative_ui"); + + const chat = new AgenticChatPage(page); + + await chat.openChat(); + await chat.agentGreeting.waitFor({ state: "visible" }); + + await chat.sendMessage("How do I make a sandwich?"); + await waitForAIResponse(page); + + // Should see numbered steps + await expect(page.getByText(/1\./)).toBeVisible({ timeout: 15000 }); + await expect(page.getByText(/2\./)).toBeVisible({ timeout: 5000 }); + }); +}); + +test("[Cloudflare] Agentic Gen UI generates multiple steps", async ({ + page, +}) => { + await retryOnAIFailure(async () => { + await page.goto("/cloudflare/feature/agentic_generative_ui"); + + const chat = new AgenticChatPage(page); + + await chat.openChat(); + await chat.agentGreeting.waitFor({ state: "visible" }); + + await chat.sendMessage("What are the steps to learn TypeScript?"); + await waitForAIResponse(page); + + // Should see a structured list of steps + const agentMessage = page.locator(".copilotKitAssistantMessage").last(); + await expect(agentMessage).toContainText(/TypeScript|steps/i, { + timeout: 15000, + }); + }); +}); diff --git a/apps/dojo/e2e/tests/cloudflareTests/backendToolRenderingPage.spec.ts b/apps/dojo/e2e/tests/cloudflareTests/backendToolRenderingPage.spec.ts new file mode 100644 index 000000000..382ef9499 --- /dev/null +++ b/apps/dojo/e2e/tests/cloudflareTests/backendToolRenderingPage.spec.ts @@ -0,0 +1,44 @@ +import { + test, + expect, + waitForAIResponse, + retryOnAIFailure, +} from "../../test-isolation-helper"; +import { AgenticChatPage } from "../../featurePages/AgenticChatPage"; + +test("[Cloudflare] Backend Tool Rendering responds to queries", async ({ + page, +}) => { + await retryOnAIFailure(async () => { + await page.goto("/cloudflare/feature/backend_tool_rendering"); + + const chat = new AgenticChatPage(page); + + await chat.openChat(); + await chat.agentGreeting.waitFor({ state: "visible" }); + + await chat.sendMessage("Hello"); + await waitForAIResponse(page); + + await chat.assertAgentReplyVisible(/hello|hi|hey/i); + }); +}); + +test("[Cloudflare] Backend Tool Rendering handles tool calls", async ({ + page, +}) => { + await retryOnAIFailure(async () => { + await page.goto("/cloudflare/feature/backend_tool_rendering"); + + const chat = new AgenticChatPage(page); + + await chat.openChat(); + await chat.agentGreeting.waitFor({ state: "visible" }); + + await chat.sendMessage("Can you help me with information?"); + await waitForAIResponse(page); + + const agentMessage = page.locator(".copilotKitAssistantMessage").last(); + await expect(agentMessage).toBeVisible({ timeout: 15000 }); + }); +}); diff --git a/apps/dojo/e2e/tests/cloudflareTests/humanInTheLoopPage.spec.ts b/apps/dojo/e2e/tests/cloudflareTests/humanInTheLoopPage.spec.ts new file mode 100644 index 000000000..2a91c37d8 --- /dev/null +++ b/apps/dojo/e2e/tests/cloudflareTests/humanInTheLoopPage.spec.ts @@ -0,0 +1,47 @@ +import { + test, + expect, + waitForAIResponse, + retryOnAIFailure, +} from "../../test-isolation-helper"; +import { AgenticChatPage } from "../../featurePages/AgenticChatPage"; + +test("[Cloudflare] Human in the Loop generates task steps for approval", async ({ + page, +}) => { + await retryOnAIFailure(async () => { + await page.goto("/cloudflare/feature/human_in_the_loop"); + + const chat = new AgenticChatPage(page); + + await chat.openChat(); + await chat.agentGreeting.waitFor({ state: "visible" }); + + await chat.sendMessage("Help me plan a website launch"); + await waitForAIResponse(page); + + // Should present steps for user review + await chat.assertAgentReplyVisible(/step|plan|website/i); + }); +}); + +test("[Cloudflare] Human in the Loop responds to task requests", async ({ + page, +}) => { + await retryOnAIFailure(async () => { + await page.goto("/cloudflare/feature/human_in_the_loop"); + + const chat = new AgenticChatPage(page); + + await chat.openChat(); + await chat.agentGreeting.waitFor({ state: "visible" }); + + await chat.sendMessage("I need to organize a team meeting"); + await waitForAIResponse(page); + + const agentMessage = page.locator(".copilotKitAssistantMessage").last(); + await expect(agentMessage).toContainText(/meeting|organize|step/i, { + timeout: 15000, + }); + }); +}); diff --git a/apps/dojo/e2e/tests/cloudflareTests/sharedStatePage.spec.ts b/apps/dojo/e2e/tests/cloudflareTests/sharedStatePage.spec.ts new file mode 100644 index 000000000..605b627c2 --- /dev/null +++ b/apps/dojo/e2e/tests/cloudflareTests/sharedStatePage.spec.ts @@ -0,0 +1,70 @@ +import { + test, + expect, + waitForAIResponse, + retryOnAIFailure, +} from "../../test-isolation-helper"; +import { SharedStatePage } from "../../featurePages/SharedStatePage"; + +test("[Cloudflare] Shared State can add a todo item", async ({ page }) => { + await retryOnAIFailure(async () => { + await page.goto("/cloudflare/feature/shared_state"); + + const sharedState = new SharedStatePage(page); + + await sharedState.openChat(); + await sharedState.agentGreeting.waitFor({ state: "visible" }); + + const todoItem = "Buy groceries"; + await sharedState.sendMessage(`Add todo: ${todoItem}`); + await waitForAIResponse(page); + + // Check that todo appears in the list + await expect(page.getByText(todoItem)).toBeVisible({ timeout: 10000 }); + }); +}); + +test("[Cloudflare] Shared State can list todos", async ({ page }) => { + await retryOnAIFailure(async () => { + await page.goto("/cloudflare/feature/shared_state"); + + const sharedState = new SharedStatePage(page); + + await sharedState.openChat(); + await sharedState.agentGreeting.waitFor({ state: "visible" }); + + // Add a todo + await sharedState.sendMessage("Add todo: Test task"); + await waitForAIResponse(page); + + // Request list + await sharedState.sendMessage("Show my todos"); + await waitForAIResponse(page); + + await sharedState.assertAgentReplyVisible(/Test task/i); + }); +}); + +test("[Cloudflare] Shared State persists todos across messages", async ({ + page, +}) => { + await retryOnAIFailure(async () => { + await page.goto("/cloudflare/feature/shared_state"); + + const sharedState = new SharedStatePage(page); + + await sharedState.openChat(); + await sharedState.agentGreeting.waitFor({ state: "visible" }); + + // Add multiple todos + await sharedState.sendMessage("Add todo: First task"); + await waitForAIResponse(page); + + await sharedState.sendMessage("Add todo: Second task"); + await waitForAIResponse(page); + + // Verify both appear + await expect(page.getByText("First task")).toBeVisible(); + await expect(page.getByText("Second task")).toBeVisible(); + }); +}); diff --git a/apps/dojo/e2e/tests/cloudflareTests/toolBasedGenUIPage.spec.ts b/apps/dojo/e2e/tests/cloudflareTests/toolBasedGenUIPage.spec.ts new file mode 100644 index 000000000..0402b4bd0 --- /dev/null +++ b/apps/dojo/e2e/tests/cloudflareTests/toolBasedGenUIPage.spec.ts @@ -0,0 +1,46 @@ +import { + test, + expect, + waitForAIResponse, + retryOnAIFailure, +} from "../../test-isolation-helper"; +import { ToolBaseGenUIPage } from "../../featurePages/ToolBaseGenUIPage"; + +test("[Cloudflare] Tool-Based Gen UI generates a haiku", async ({ page }) => { + await retryOnAIFailure(async () => { + await page.goto("/cloudflare/feature/tool_based_generative_ui"); + + const toolGenUI = new ToolBaseGenUIPage(page); + + await toolGenUI.openChat(); + await toolGenUI.agentGreeting.waitFor({ state: "visible" }); + + await toolGenUI.sendMessage("Write me a haiku about coding"); + await waitForAIResponse(page); + + // Should see a haiku response with Japanese and English lines + const agentMessage = page + .locator(".copilotKitAssistantMessage") + .last(); + + await expect(agentMessage).toBeVisible({ timeout: 15000 }); + }); +}); + +test("[Cloudflare] Tool-Based Gen UI responds to different topics", async ({ + page, +}) => { + await retryOnAIFailure(async () => { + await page.goto("/cloudflare/feature/tool_based_generative_ui"); + + const toolGenUI = new ToolBaseGenUIPage(page); + + await toolGenUI.openChat(); + await toolGenUI.agentGreeting.waitFor({ state: "visible" }); + + await toolGenUI.sendMessage("Create a haiku about nature"); + await waitForAIResponse(page); + + await toolGenUI.assertAgentReplyVisible(/haiku|nature|poem/i); + }); +}); diff --git a/apps/dojo/package.json b/apps/dojo/package.json index 74805947b..24544b31b 100644 --- a/apps/dojo/package.json +++ b/apps/dojo/package.json @@ -15,6 +15,7 @@ "@ag-ui/a2a-middleware": "workspace:*", "@ag-ui/adk": "workspace:*", "@ag-ui/agno": "workspace:*", + "@ag-ui/cloudflare": "workspace:*", "@ag-ui/crewai": "workspace:*", "@ag-ui/langgraph": "workspace:*", "@ag-ui/llamaindex": "workspace:*", diff --git a/apps/dojo/scripts/generate-content-json.ts b/apps/dojo/scripts/generate-content-json.ts index 237398599..03cb56e7a 100644 --- a/apps/dojo/scripts/generate-content-json.ts +++ b/apps/dojo/scripts/generate-content-json.ts @@ -344,6 +344,21 @@ const agentFilesMapper: Record Record { + return agentKeys.reduce( + (acc, agentId) => ({ + ...acc, + [agentId]: [ + path.join( + __dirname, + integrationsFolderPath, + `/cloudflare/typescript/examples/src/agents/${agentId}/agent.ts`, + ), + ], + }), + {}, + ); + }, }; async function runGenerateContent() { diff --git a/apps/dojo/scripts/prep-dojo-everything.js b/apps/dojo/scripts/prep-dojo-everything.js old mode 100755 new mode 100644 index e3151d9cb..5abf1799e --- a/apps/dojo/scripts/prep-dojo-everything.js +++ b/apps/dojo/scripts/prep-dojo-everything.js @@ -107,6 +107,11 @@ const ALL_TARGETS = { name: "A2A Middleware", cwd: path.join(middlewaresRoot, "a2a-middleware/examples"), }, + cloudflare: { + command: 'pnpm install --no-frozen-lockfile', + name: 'Cloudflare', + cwd: path.join(integrationsRoot, 'cloudflare/typescript/examples') + }, dojo: { command: "pnpm install --no-frozen-lockfile && pnpm build --filter=demo-viewer...", name: "Dojo", diff --git a/apps/dojo/scripts/run-dojo-everything.js b/apps/dojo/scripts/run-dojo-everything.js old mode 100755 new mode 100644 index bcfbea09a..880c4844d --- a/apps/dojo/scripts/run-dojo-everything.js +++ b/apps/dojo/scripts/run-dojo-everything.js @@ -141,6 +141,12 @@ const ALL_SERVICES = { cwd: path.join(middlewaresRoot, "a2a-middleware/examples"), env: { PORT: 8014 }, }], + cloudflare: [{ + command: 'pnpm start', + name: 'Cloudflare', + cwd: path.join(integrationsRoot, 'cloudflare/typescript/examples'), + env: { PORT: 4114, HOST: '0.0.0.0' } + }], 'dojo': [{ command: 'pnpm run start', name: 'Dojo', @@ -157,6 +163,7 @@ const ALL_SERVICES = { LLAMA_INDEX_URL: 'http://localhost:8007', MASTRA_URL: 'http://localhost:8008', PYDANTIC_AI_URL: 'http://localhost:8009', + CLOUDFLARE_URL: 'http://localhost:4114', ADK_MIDDLEWARE_URL: 'http://localhost:8010', A2A_MIDDLEWARE_BUILDINGS_MANAGEMENT_URL: 'http://localhost:8011', A2A_MIDDLEWARE_FINANCE_URL: 'http://localhost:8012', diff --git a/apps/dojo/src/agents.ts b/apps/dojo/src/agents.ts index 18d7e90e8..6fb60c396 100644 --- a/apps/dojo/src/agents.ts +++ b/apps/dojo/src/agents.ts @@ -19,6 +19,7 @@ import { ADKAgent } from "@ag-ui/adk"; import { SpringAiAgent } from '@ag-ui/spring-ai'; import { HttpAgent } from "@ag-ui/client"; import { A2AMiddlewareAgent } from "@ag-ui/a2a-middleware"; +import { CloudflareHttpAgent } from "@ag-ui/cloudflare"; const envVars = getEnvVars(); export const agentsIntegrations: AgentIntegrationConfig[] = [ @@ -375,4 +376,39 @@ export const agentsIntegrations: AgentIntegrationConfig[] = [ }; }, }, + { + id: "cloudflare", + agents: async () => { + return { + agentic_chat: new CloudflareHttpAgent({ + url: `${envVars.cloudflareUrl}/agentic_chat`, + }), + tool_based_generative_ui: new CloudflareHttpAgent({ + url: `${envVars.cloudflareUrl}/tool_based_generative_ui`, + }), + agentic_generative_ui: new CloudflareHttpAgent({ + url: `${envVars.cloudflareUrl}/agentic_generative_ui`, + }), + human_in_the_loop: new CloudflareHttpAgent({ + url: `${envVars.cloudflareUrl}/human_in_the_loop`, + }), + shared_state: new CloudflareHttpAgent({ + url: `${envVars.cloudflareUrl}/shared_state`, + }), + backend_tool_rendering: new CloudflareHttpAgent({ + url: `${envVars.cloudflareUrl}/backend_tool_rendering`, + }), + }; + }, + }, + { + id: "cloudflare-agents-sdk", + agents: async () => { + return { + tool_based_generative_ui: new CloudflareHttpAgent({ + url: `${envVars.cloudflareUrl}/tool_based_generative_ui_sdk`, + }), + }; + }, + }, ]; diff --git a/apps/dojo/src/env.ts b/apps/dojo/src/env.ts index c63344897..57bc715c1 100644 --- a/apps/dojo/src/env.ts +++ b/apps/dojo/src/env.ts @@ -15,6 +15,7 @@ type envVars = { a2aMiddlewareFinanceUrl: string; a2aMiddlewareItUrl: string; a2aMiddlewareOrchestratorUrl: string; + cloudflareUrl: string; customDomainTitle: Record; } @@ -44,6 +45,7 @@ export default function getEnvVars(): envVars { a2aMiddlewareFinanceUrl: process.env.A2A_MIDDLEWARE_FINANCE_URL || 'http://localhost:9002', a2aMiddlewareItUrl: process.env.A2A_MIDDLEWARE_IT_URL || 'http://localhost:9003', a2aMiddlewareOrchestratorUrl: process.env.A2A_MIDDLEWARE_ORCHESTRATOR_URL || 'http://localhost:9000', + cloudflareUrl: process.env.CLOUDFLARE_URL || 'http://localhost:4114', customDomainTitle: customDomainTitle, } } \ No newline at end of file diff --git a/apps/dojo/src/files.json b/apps/dojo/src/files.json index ff3dcf339..742b4c676 100644 --- a/apps/dojo/src/files.json +++ b/apps/dojo/src/files.json @@ -132,7 +132,7 @@ "pydantic-ai::tool_based_generative_ui": [ { "name": "page.tsx", - "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: \"\",\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: \"CSS Gradient color for the background\",\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: image_name || null,\n gradient: gradient || \"\",\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", + "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nconst VALID_GRADIENTS = [\n \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n \"linear-gradient(120deg, #00d2ff 0%, #3a7bd5 100%)\",\n \"linear-gradient(135deg, #f093fb 0%, #f5576c 100%)\",\n \"linear-gradient(120deg, #f6d365 0%, #fda085 100%)\",\n \"linear-gradient(120deg, #a6c0fe 0%, #f68084 100%)\",\n \"linear-gradient(135deg, #1d4350 0%, #a43931 100%)\",\n \"linear-gradient(135deg, #43cea2 0%, #185a9d 100%)\",\n \"linear-gradient(135deg, #13547a 0%, #80d0c7 100%)\",\n \"linear-gradient(135deg, #ff9966 0%, #ff5e62 100%)\",\n \"linear-gradient(135deg, #373b44 0%, #4286f4 100%)\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: VALID_GRADIENTS[0],\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: `CSS Gradient color for the background (one of: ${VALID_GRADIENTS.join(\", \")})`,\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const safeImageName = VALID_IMAGE_NAMES.includes(image_name ?? \"\")\n ? image_name\n : null;\n const safeGradient = VALID_GRADIENTS.includes(gradient ?? \"\")\n ? gradient\n : VALID_GRADIENTS[0];\n\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: safeImageName,\n gradient: safeGradient,\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", "language": "typescript", "type": "file" }, @@ -236,7 +236,7 @@ "adk-middleware::tool_based_generative_ui": [ { "name": "page.tsx", - "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: \"\",\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: \"CSS Gradient color for the background\",\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: image_name || null,\n gradient: gradient || \"\",\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", + "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nconst VALID_GRADIENTS = [\n \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n \"linear-gradient(120deg, #00d2ff 0%, #3a7bd5 100%)\",\n \"linear-gradient(135deg, #f093fb 0%, #f5576c 100%)\",\n \"linear-gradient(120deg, #f6d365 0%, #fda085 100%)\",\n \"linear-gradient(120deg, #a6c0fe 0%, #f68084 100%)\",\n \"linear-gradient(135deg, #1d4350 0%, #a43931 100%)\",\n \"linear-gradient(135deg, #43cea2 0%, #185a9d 100%)\",\n \"linear-gradient(135deg, #13547a 0%, #80d0c7 100%)\",\n \"linear-gradient(135deg, #ff9966 0%, #ff5e62 100%)\",\n \"linear-gradient(135deg, #373b44 0%, #4286f4 100%)\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: VALID_GRADIENTS[0],\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: `CSS Gradient color for the background (one of: ${VALID_GRADIENTS.join(\", \")})`,\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const safeImageName = VALID_IMAGE_NAMES.includes(image_name ?? \"\")\n ? image_name\n : null;\n const safeGradient = VALID_GRADIENTS.includes(gradient ?? \"\")\n ? gradient\n : VALID_GRADIENTS[0];\n\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: safeImageName,\n gradient: safeGradient,\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", "language": "typescript", "type": "file" }, @@ -444,7 +444,7 @@ "server-starter-all-features::tool_based_generative_ui": [ { "name": "page.tsx", - "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: \"\",\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: \"CSS Gradient color for the background\",\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: image_name || null,\n gradient: gradient || \"\",\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", + "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nconst VALID_GRADIENTS = [\n \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n \"linear-gradient(120deg, #00d2ff 0%, #3a7bd5 100%)\",\n \"linear-gradient(135deg, #f093fb 0%, #f5576c 100%)\",\n \"linear-gradient(120deg, #f6d365 0%, #fda085 100%)\",\n \"linear-gradient(120deg, #a6c0fe 0%, #f68084 100%)\",\n \"linear-gradient(135deg, #1d4350 0%, #a43931 100%)\",\n \"linear-gradient(135deg, #43cea2 0%, #185a9d 100%)\",\n \"linear-gradient(135deg, #13547a 0%, #80d0c7 100%)\",\n \"linear-gradient(135deg, #ff9966 0%, #ff5e62 100%)\",\n \"linear-gradient(135deg, #373b44 0%, #4286f4 100%)\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: VALID_GRADIENTS[0],\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: `CSS Gradient color for the background (one of: ${VALID_GRADIENTS.join(\", \")})`,\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const safeImageName = VALID_IMAGE_NAMES.includes(image_name ?? \"\")\n ? image_name\n : null;\n const safeGradient = VALID_GRADIENTS.includes(gradient ?? \"\")\n ? gradient\n : VALID_GRADIENTS[0];\n\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: safeImageName,\n gradient: safeGradient,\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", "language": "typescript", "type": "file" }, @@ -714,7 +714,7 @@ "langgraph::tool_based_generative_ui": [ { "name": "page.tsx", - "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: \"\",\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: \"CSS Gradient color for the background\",\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: image_name || null,\n gradient: gradient || \"\",\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", + "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nconst VALID_GRADIENTS = [\n \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n \"linear-gradient(120deg, #00d2ff 0%, #3a7bd5 100%)\",\n \"linear-gradient(135deg, #f093fb 0%, #f5576c 100%)\",\n \"linear-gradient(120deg, #f6d365 0%, #fda085 100%)\",\n \"linear-gradient(120deg, #a6c0fe 0%, #f68084 100%)\",\n \"linear-gradient(135deg, #1d4350 0%, #a43931 100%)\",\n \"linear-gradient(135deg, #43cea2 0%, #185a9d 100%)\",\n \"linear-gradient(135deg, #13547a 0%, #80d0c7 100%)\",\n \"linear-gradient(135deg, #ff9966 0%, #ff5e62 100%)\",\n \"linear-gradient(135deg, #373b44 0%, #4286f4 100%)\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: VALID_GRADIENTS[0],\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: `CSS Gradient color for the background (one of: ${VALID_GRADIENTS.join(\", \")})`,\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const safeImageName = VALID_IMAGE_NAMES.includes(image_name ?? \"\")\n ? image_name\n : null;\n const safeGradient = VALID_GRADIENTS.includes(gradient ?? \"\")\n ? gradient\n : VALID_GRADIENTS[0];\n\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: safeImageName,\n gradient: safeGradient,\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", "language": "typescript", "type": "file" }, @@ -961,7 +961,7 @@ "langgraph-fastapi::tool_based_generative_ui": [ { "name": "page.tsx", - "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: \"\",\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: \"CSS Gradient color for the background\",\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: image_name || null,\n gradient: gradient || \"\",\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", + "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nconst VALID_GRADIENTS = [\n \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n \"linear-gradient(120deg, #00d2ff 0%, #3a7bd5 100%)\",\n \"linear-gradient(135deg, #f093fb 0%, #f5576c 100%)\",\n \"linear-gradient(120deg, #f6d365 0%, #fda085 100%)\",\n \"linear-gradient(120deg, #a6c0fe 0%, #f68084 100%)\",\n \"linear-gradient(135deg, #1d4350 0%, #a43931 100%)\",\n \"linear-gradient(135deg, #43cea2 0%, #185a9d 100%)\",\n \"linear-gradient(135deg, #13547a 0%, #80d0c7 100%)\",\n \"linear-gradient(135deg, #ff9966 0%, #ff5e62 100%)\",\n \"linear-gradient(135deg, #373b44 0%, #4286f4 100%)\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: VALID_GRADIENTS[0],\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: `CSS Gradient color for the background (one of: ${VALID_GRADIENTS.join(\", \")})`,\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const safeImageName = VALID_IMAGE_NAMES.includes(image_name ?? \"\")\n ? image_name\n : null;\n const safeGradient = VALID_GRADIENTS.includes(gradient ?? \"\")\n ? gradient\n : VALID_GRADIENTS[0];\n\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: safeImageName,\n gradient: safeGradient,\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", "language": "typescript", "type": "file" }, @@ -1199,7 +1199,7 @@ "langgraph-typescript::tool_based_generative_ui": [ { "name": "page.tsx", - "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: \"\",\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: \"CSS Gradient color for the background\",\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: image_name || null,\n gradient: gradient || \"\",\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", + "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nconst VALID_GRADIENTS = [\n \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n \"linear-gradient(120deg, #00d2ff 0%, #3a7bd5 100%)\",\n \"linear-gradient(135deg, #f093fb 0%, #f5576c 100%)\",\n \"linear-gradient(120deg, #f6d365 0%, #fda085 100%)\",\n \"linear-gradient(120deg, #a6c0fe 0%, #f68084 100%)\",\n \"linear-gradient(135deg, #1d4350 0%, #a43931 100%)\",\n \"linear-gradient(135deg, #43cea2 0%, #185a9d 100%)\",\n \"linear-gradient(135deg, #13547a 0%, #80d0c7 100%)\",\n \"linear-gradient(135deg, #ff9966 0%, #ff5e62 100%)\",\n \"linear-gradient(135deg, #373b44 0%, #4286f4 100%)\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: VALID_GRADIENTS[0],\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: `CSS Gradient color for the background (one of: ${VALID_GRADIENTS.join(\", \")})`,\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const safeImageName = VALID_IMAGE_NAMES.includes(image_name ?? \"\")\n ? image_name\n : null;\n const safeGradient = VALID_GRADIENTS.includes(gradient ?? \"\")\n ? gradient\n : VALID_GRADIENTS[0];\n\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: safeImageName,\n gradient: safeGradient,\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", "language": "typescript", "type": "file" }, @@ -1289,7 +1289,7 @@ "agno::tool_based_generative_ui": [ { "name": "page.tsx", - "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: \"\",\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: \"CSS Gradient color for the background\",\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: image_name || null,\n gradient: gradient || \"\",\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", + "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nconst VALID_GRADIENTS = [\n \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n \"linear-gradient(120deg, #00d2ff 0%, #3a7bd5 100%)\",\n \"linear-gradient(135deg, #f093fb 0%, #f5576c 100%)\",\n \"linear-gradient(120deg, #f6d365 0%, #fda085 100%)\",\n \"linear-gradient(120deg, #a6c0fe 0%, #f68084 100%)\",\n \"linear-gradient(135deg, #1d4350 0%, #a43931 100%)\",\n \"linear-gradient(135deg, #43cea2 0%, #185a9d 100%)\",\n \"linear-gradient(135deg, #13547a 0%, #80d0c7 100%)\",\n \"linear-gradient(135deg, #ff9966 0%, #ff5e62 100%)\",\n \"linear-gradient(135deg, #373b44 0%, #4286f4 100%)\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: VALID_GRADIENTS[0],\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: `CSS Gradient color for the background (one of: ${VALID_GRADIENTS.join(\", \")})`,\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const safeImageName = VALID_IMAGE_NAMES.includes(image_name ?? \"\")\n ? image_name\n : null;\n const safeGradient = VALID_GRADIENTS.includes(gradient ?? \"\")\n ? gradient\n : VALID_GRADIENTS[0];\n\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: safeImageName,\n gradient: safeGradient,\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", "language": "typescript", "type": "file" }, @@ -1381,7 +1381,7 @@ "spring-ai::tool_based_generative_ui": [ { "name": "page.tsx", - "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: \"\",\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: \"CSS Gradient color for the background\",\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: image_name || null,\n gradient: gradient || \"\",\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", + "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nconst VALID_GRADIENTS = [\n \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n \"linear-gradient(120deg, #00d2ff 0%, #3a7bd5 100%)\",\n \"linear-gradient(135deg, #f093fb 0%, #f5576c 100%)\",\n \"linear-gradient(120deg, #f6d365 0%, #fda085 100%)\",\n \"linear-gradient(120deg, #a6c0fe 0%, #f68084 100%)\",\n \"linear-gradient(135deg, #1d4350 0%, #a43931 100%)\",\n \"linear-gradient(135deg, #43cea2 0%, #185a9d 100%)\",\n \"linear-gradient(135deg, #13547a 0%, #80d0c7 100%)\",\n \"linear-gradient(135deg, #ff9966 0%, #ff5e62 100%)\",\n \"linear-gradient(135deg, #373b44 0%, #4286f4 100%)\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: VALID_GRADIENTS[0],\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: `CSS Gradient color for the background (one of: ${VALID_GRADIENTS.join(\", \")})`,\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const safeImageName = VALID_IMAGE_NAMES.includes(image_name ?? \"\")\n ? image_name\n : null;\n const safeGradient = VALID_GRADIENTS.includes(gradient ?? \"\")\n ? gradient\n : VALID_GRADIENTS[0];\n\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: safeImageName,\n gradient: safeGradient,\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", "language": "typescript", "type": "file" }, @@ -1623,7 +1623,7 @@ "crewai::tool_based_generative_ui": [ { "name": "page.tsx", - "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: \"\",\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: \"CSS Gradient color for the background\",\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: image_name || null,\n gradient: gradient || \"\",\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", + "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nconst VALID_GRADIENTS = [\n \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n \"linear-gradient(120deg, #00d2ff 0%, #3a7bd5 100%)\",\n \"linear-gradient(135deg, #f093fb 0%, #f5576c 100%)\",\n \"linear-gradient(120deg, #f6d365 0%, #fda085 100%)\",\n \"linear-gradient(120deg, #a6c0fe 0%, #f68084 100%)\",\n \"linear-gradient(135deg, #1d4350 0%, #a43931 100%)\",\n \"linear-gradient(135deg, #43cea2 0%, #185a9d 100%)\",\n \"linear-gradient(135deg, #13547a 0%, #80d0c7 100%)\",\n \"linear-gradient(135deg, #ff9966 0%, #ff5e62 100%)\",\n \"linear-gradient(135deg, #373b44 0%, #4286f4 100%)\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: VALID_GRADIENTS[0],\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: `CSS Gradient color for the background (one of: ${VALID_GRADIENTS.join(\", \")})`,\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const safeImageName = VALID_IMAGE_NAMES.includes(image_name ?? \"\")\n ? image_name\n : null;\n const safeGradient = VALID_GRADIENTS.includes(gradient ?? \"\")\n ? gradient\n : VALID_GRADIENTS[0];\n\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: safeImageName,\n gradient: safeGradient,\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", "language": "typescript", "type": "file" }, @@ -1723,5 +1723,161 @@ "language": "python", "type": "file" } + ], + "cloudflare::agentic_chat": [ + { + "name": "page.tsx", + "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport \"./style.css\";\nimport {\n CopilotKit,\n useFrontendTool,\n} from \"@copilotkit/react-core\";\nimport { CopilotChat } from \"@copilotkit/react-ui\";\n\ninterface AgenticChatProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\nconst AgenticChat: React.FC = ({ params }) => {\n const { integrationId } = React.use(params);\n\n return (\n \n \n \n );\n};\n\nconst Chat = () => {\n const [background, setBackground] = useState(\"--copilot-kit-background-color\");\n\n useFrontendTool({\n name: \"change_background\",\n description:\n \"Change the background color of the chat. Can be anything that the CSS background attribute accepts. Regular colors, linear of radial gradients etc.\",\n parameters: [\n {\n name: \"background\",\n type: \"string\",\n description: \"The background. Prefer gradients. Only use when asked.\",\n },\n ],\n handler: ({ background }) => {\n setBackground(background);\n return {\n status: \"success\",\n message: `Background changed to ${background}`,\n };\n },\n });\n\n return (\n \n
\n \n
\n
\n );\n};\n\nexport default AgenticChat;\n", + "language": "typescript", + "type": "file" + }, + { + "name": "style.css", + "content": ".copilotKitInput {\n border-bottom-left-radius: 0.75rem;\n border-bottom-right-radius: 0.75rem;\n border-top-left-radius: 0.75rem;\n border-top-right-radius: 0.75rem;\n border: 1px solid var(--copilot-kit-separator-color) !important;\n}\n \n.copilotKitChat {\n background-color: #fff !important;\n}\n ", + "language": "css", + "type": "file" + }, + { + "name": "README.mdx", + "content": "# 🤖 Agentic Chat with Frontend Tools\n\n## What This Demo Shows\n\nThis demo showcases CopilotKit's **agentic chat** capabilities with **frontend\ntool integration**:\n\n1. **Natural Conversation**: Chat with your Copilot in a familiar chat interface\n2. **Frontend Tool Execution**: The Copilot can directly interacts with your UI\n by calling frontend functions\n3. **Seamless Integration**: Tools defined in the frontend and automatically\n discovered and made available to the agent\n\n## How to Interact\n\nTry asking your Copilot to:\n\n- \"Can you change the background color to something more vibrant?\"\n- \"Make the background a blue to purple gradient\"\n- \"Set the background to a sunset-themed gradient\"\n- \"Change it back to a simple light color\"\n\nYou can also chat about other topics - the agent will respond conversationally\nwhile having the ability to use your UI tools when appropriate.\n\n## ✨ Frontend Tool Integration in Action\n\n**What's happening technically:**\n\n- The React component defines a frontend function using `useCopilotAction`\n- CopilotKit automatically exposes this function to the agent\n- When you make a request, the agent determines whether to use the tool\n- The agent calls the function with the appropriate parameters\n- The UI immediately updates in response\n\n**What you'll see in this demo:**\n\n- The Copilot understands requests to change the background\n- It generates CSS values for colors and gradients\n- When it calls the tool, the background changes instantly\n- The agent provides a conversational response about the changes it made\n\nThis technique of exposing frontend functions to your Copilot can be extended to\nany UI manipulation you want to enable, from theme changes to data filtering,\nnavigation, or complex UI state management!\n", + "language": "markdown", + "type": "file" + }, + { + "name": "agent.ts", + "content": "/**\n * A simple agentic chat flow using Cloudflare Workers AI.\n *\n * This agent demonstrates basic chat functionality using the ReAct design pattern\n * with Cloudflare's Llama 3.1 8B model.\n *\n * Features:\n * - Streaming text responses\n * - Tool calling support (when tools are provided)\n * - Proper AG-UI protocol event emission\n */\n\nimport { CloudflareAgent, CLOUDFLARE_MODELS } from \"@ag-ui/cloudflare\";\n\n/**\n * Agentic Chat Agent\n *\n * A helpful assistant powered by Cloudflare Workers AI that can engage in\n * natural conversation and use tools when provided.\n */\nexport class AgenticChatAgent extends CloudflareAgent {\n constructor() {\n const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;\n const apiToken = process.env.CLOUDFLARE_API_TOKEN;\n\n if (!accountId || !apiToken) {\n throw new Error(\n \"Missing required environment variables: CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN\"\n );\n }\n\n super({\n accountId,\n apiToken,\n model: CLOUDFLARE_MODELS.LLAMA_3_1_8B, // Using smaller model for simple chat\n systemPrompt: `You are a helpful AI assistant. You provide clear, accurate, and friendly responses to user queries.\n\nIMPORTANT: Only use the available tools when the user explicitly asks you to do something that requires them.\n- For the change_background tool, ONLY use it when the user specifically asks to change the background, modify colors, or adjust the theme.\n- DO NOT call tools for simple greetings, general questions, or casual conversation.\n- When in doubt, just respond conversationally without using tools.`,\n streamingEnabled: true,\n });\n }\n}\n\n// Lazy singleton - created on first use after env vars are loaded\nlet _agenticChatAgent: AgenticChatAgent | null = null;\n\nexport function getAgenticChatAgent(): AgenticChatAgent {\n if (!_agenticChatAgent) {\n _agenticChatAgent = new AgenticChatAgent();\n }\n return _agenticChatAgent;\n}\n", + "language": "ts", + "type": "file" + } + ], + "cloudflare::tool_based_generative_ui": [ + { + "name": "page.tsx", + "content": "\"use client\";\nimport React, { useState } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotSidebar } from \"@copilotkit/react-ui\";\nimport {\n Carousel,\n CarouselContent,\n CarouselItem,\n CarouselNext,\n CarouselPrevious,\n} from \"@/components/ui/carousel\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface ToolBasedGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\ninterface Haiku {\n japanese: string[];\n english: string[];\n image_name: string | null;\n gradient: string;\n}\n\nexport default function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {\n const { integrationId } = React.use(params);\n const { chatDefaultOpen } = useURLParams();\n\n const chatProps = {\n defaultOpen: chatDefaultOpen,\n labels: {\n title: \"Haiku Generator\",\n initial: \"I'm a haiku generator 👋. How can I help you?\",\n },\n clickOutsideToClose: false,\n suggestions: [\n { title: \"Nature Haiku\", message: \"Write me a haiku about nature.\" },\n { title: \"Ocean Haiku\", message: \"Create a haiku about the ocean.\" },\n { title: \"Spring Haiku\", message: \"Generate a haiku about spring.\" },\n ],\n };\n\n return (\n \n \n \n \n );\n}\n\nconst VALID_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n];\n\nconst VALID_GRADIENTS = [\n \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n \"linear-gradient(120deg, #00d2ff 0%, #3a7bd5 100%)\",\n \"linear-gradient(135deg, #f093fb 0%, #f5576c 100%)\",\n \"linear-gradient(120deg, #f6d365 0%, #fda085 100%)\",\n \"linear-gradient(120deg, #a6c0fe 0%, #f68084 100%)\",\n \"linear-gradient(135deg, #1d4350 0%, #a43931 100%)\",\n \"linear-gradient(135deg, #43cea2 0%, #185a9d 100%)\",\n \"linear-gradient(135deg, #13547a 0%, #80d0c7 100%)\",\n \"linear-gradient(135deg, #ff9966 0%, #ff5e62 100%)\",\n \"linear-gradient(135deg, #373b44 0%, #4286f4 100%)\",\n];\n\nfunction HaikuDisplay() {\n const [activeIndex, setActiveIndex] = useState(0);\n const [haikus, setHaikus] = useState([\n {\n japanese: [\"仮の句よ\", \"まっさらながら\", \"花を呼ぶ\"],\n english: [\"A placeholder verse—\", \"even in a blank canvas,\", \"it beckons flowers.\"],\n image_name: null,\n gradient: VALID_GRADIENTS[0],\n },\n ]);\n\n useCopilotAction(\n {\n name: \"generate_haiku\",\n parameters: [\n {\n name: \"japanese\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku in Japanese\",\n },\n {\n name: \"english\",\n type: \"string[]\",\n required: true,\n description: \"3 lines of haiku translated to English\",\n },\n {\n name: \"image_name\",\n type: \"string\",\n required: true,\n description: `One relevant image name from: ${VALID_IMAGE_NAMES.join(\", \")}`,\n },\n {\n name: \"gradient\",\n type: \"string\",\n required: true,\n description: `CSS Gradient color for the background (one of: ${VALID_GRADIENTS.join(\", \")})`,\n },\n ],\n followUp: false,\n handler: async ({ japanese, english, image_name, gradient }) => {\n const safeImageName = VALID_IMAGE_NAMES.includes(image_name ?? \"\")\n ? image_name\n : null;\n const safeGradient = VALID_GRADIENTS.includes(gradient ?? \"\")\n ? gradient\n : VALID_GRADIENTS[0];\n\n const newHaiku: Haiku = {\n japanese: japanese || [],\n english: english || [],\n image_name: safeImageName,\n gradient: safeGradient,\n };\n setHaikus((prev) => [\n newHaiku,\n ...prev.filter((h) => h.english[0] !== \"A placeholder verse—\"),\n ]);\n setActiveIndex(0);\n return \"Haiku generated!\";\n },\n render: ({ args }) => {\n if (!args.japanese) return <>;\n return ;\n },\n },\n [haikus],\n );\n\n const currentHaiku = haikus[activeIndex];\n\n return (\n
\n
\n \n \n {haikus.map((haiku, index) => (\n \n \n \n ))}\n \n {haikus.length > 1 && (\n <>\n \n \n \n )}\n \n
\n
\n );\n}\n\nfunction HaikuCard({ haiku }: { haiku: Partial }) {\n return (\n \n {/* Decorative background elements */}\n
\n
\n\n {/* Haiku Text */}\n
\n {haiku.japanese?.map((line, index) => (\n \n \n {line}\n

\n \n {haiku.english?.[index]}\n

\n
\n ))}\n
\n\n {/* Image */}\n {haiku.image_name && (\n
\n
\n \n
\n
\n
\n )}\n
\n );\n}\n", + "language": "typescript", + "type": "file" + }, + { + "name": "style.css", + "content": ".copilotKitWindow {\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);\n}\n\n.copilotKitHeader {\n border-top-left-radius: 5px !important;\n}\n\n.page-background {\n /* Darker gradient background */\n background: linear-gradient(170deg, #e9ecef 0%, #ced4da 100%);\n}\n\n@keyframes fade-scale-in {\n from {\n opacity: 0;\n transform: translateY(10px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n/* Updated card entry animation */\n@keyframes pop-in {\n 0% {\n opacity: 0;\n transform: translateY(15px) scale(0.95);\n }\n 70% {\n opacity: 1;\n transform: translateY(-2px) scale(1.02);\n }\n 100% {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n}\n\n/* Animation for subtle background gradient movement */\n@keyframes animated-gradient {\n 0% {\n background-position: 0% 50%;\n }\n 50% {\n background-position: 100% 50%;\n }\n 100% {\n background-position: 0% 50%;\n }\n}\n\n/* Animation for flash effect on apply */\n@keyframes flash-border-glow {\n 0% {\n /* Start slightly intensified */\n border-top-color: #ff5b4a !important;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.07),\n inset 0 1px 2px rgba(0, 0, 0, 0.01),\n 0 0 25px rgba(255, 91, 74, 0.5);\n }\n 50% {\n /* Peak intensity */\n border-top-color: #ff4733 !important;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08),\n inset 0 1px 2px rgba(0, 0, 0, 0.01),\n 0 0 35px rgba(255, 71, 51, 0.7);\n }\n 100% {\n /* Return to default state appearance */\n border-top-color: #ff6f61 !important;\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.07),\n inset 0 1px 2px rgba(0, 0, 0, 0.01),\n 0 0 10px rgba(255, 111, 97, 0.15);\n }\n}\n\n/* Existing animation for haiku lines */\n@keyframes fade-slide-in {\n from {\n opacity: 0;\n transform: translateX(-15px);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n}\n\n.animated-fade-in {\n /* Use the new pop-in animation */\n animation: pop-in 0.6s ease-out forwards;\n}\n\n.haiku-card {\n /* Subtle animated gradient background */\n background: linear-gradient(120deg, #ffffff 0%, #fdfdfd 50%, #ffffff 100%);\n background-size: 200% 200%;\n animation: animated-gradient 10s ease infinite;\n\n /* === Explicit Border Override Attempt === */\n /* 1. Set the default grey border for all sides */\n border: 1px solid #dee2e6;\n\n /* 2. Explicitly override the top border immediately after */\n border-top: 10px solid #ff6f61 !important; /* Orange top - Added !important */\n /* === End Explicit Border Override Attempt === */\n\n padding: 2.5rem 3rem;\n border-radius: 20px;\n\n /* Default glow intensity */\n box-shadow: 0 10px 30px rgba(0, 0, 0, 0.07),\n inset 0 1px 2px rgba(0, 0, 0, 0.01),\n 0 0 15px rgba(255, 111, 97, 0.25);\n text-align: left;\n max-width: 745px;\n margin: 3rem auto;\n min-width: 600px;\n\n /* Transition */\n transition: transform 0.35s ease, box-shadow 0.35s ease, border-top-width 0.35s ease, border-top-color 0.35s ease;\n}\n\n.haiku-card:hover {\n transform: translateY(-8px) scale(1.03);\n /* Enhanced shadow + Glow */\n box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1),\n inset 0 1px 2px rgba(0, 0, 0, 0.01),\n 0 0 25px rgba(255, 91, 74, 0.5);\n /* Modify only top border properties */\n border-top-width: 14px !important; /* Added !important */\n border-top-color: #ff5b4a !important; /* Added !important */\n}\n\n.haiku-card .flex {\n margin-bottom: 1.5rem;\n}\n\n.haiku-card .flex.haiku-line { /* Target the lines specifically */\n margin-bottom: 1.5rem;\n opacity: 0; /* Start hidden for animation */\n animation: fade-slide-in 0.5s ease-out forwards;\n /* animation-delay is set inline in page.tsx */\n}\n\n/* Remove previous explicit color overrides - rely on Tailwind */\n/* .haiku-card p.text-4xl {\n color: #212529;\n}\n\n.haiku-card p.text-base {\n color: #495057;\n} */\n\n.haiku-card.applied-flash {\n /* Apply the flash animation once */\n /* Note: animation itself has !important on border-top-color */\n animation: flash-border-glow 0.6s ease-out forwards;\n}\n\n/* Styling for images within the main haiku card */\n.haiku-card-image {\n width: 9.5rem; /* Increased size (approx w-48) */\n height: 9.5rem; /* Increased size (approx h-48) */\n object-fit: cover;\n border-radius: 1.5rem; /* rounded-xl */\n border: 1px solid #e5e7eb;\n /* Enhanced shadow with subtle orange hint */\n box-shadow: 0 8px 15px rgba(0, 0, 0, 0.1),\n 0 3px 6px rgba(0, 0, 0, 0.08),\n 0 0 10px rgba(255, 111, 97, 0.2);\n /* Inherit animation delay from inline style */\n animation-name: fadeIn;\n animation-duration: 0.5s;\n animation-fill-mode: both;\n}\n\n/* Styling for images within the suggestion card */\n.suggestion-card-image {\n width: 6.5rem; /* Increased slightly (w-20) */\n height: 6.5rem; /* Increased slightly (h-20) */\n object-fit: cover;\n border-radius: 1rem; /* Equivalent to rounded-md */\n border: 1px solid #d1d5db; /* Equivalent to border (using Tailwind gray-300) */\n margin-top: 0.5rem;\n /* Added shadow for suggestion images */\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1),\n 0 2px 4px rgba(0, 0, 0, 0.06);\n transition: all 0.2s ease-in-out; /* Added for smooth deselection */\n}\n\n/* Styling for the focused suggestion card image */\n.suggestion-card-image-focus {\n width: 6.5rem;\n height: 6.5rem;\n object-fit: cover;\n border-radius: 1rem;\n margin-top: 0.5rem;\n /* Highlight styles */\n border: 2px solid #ff6f61; /* Thicker, themed border */\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1), /* Base shadow for depth */\n 0 0 12px rgba(255, 111, 97, 0.6); /* Orange glow */\n transform: scale(1.05); /* Slightly scale up */\n transition: all 0.2s ease-in-out; /* Smooth transition for focus */\n}\n\n/* Styling for the suggestion card container in the sidebar */\n.suggestion-card {\n border: 1px solid #dee2e6; /* Same default border as haiku-card */\n border-top: 10px solid #ff6f61; /* Same orange top border */\n border-radius: 0.375rem; /* Default rounded-md */\n /* Note: background-color is set by Tailwind bg-gray-100 */\n /* Other styles like padding, margin, flex are handled by Tailwind */\n}\n\n.suggestion-image-container {\n display: flex;\n gap: 1rem;\n justify-content: space-between;\n width: 100%;\n height: 6.5rem;\n}\n\n/* Mobile responsive styles - matches useMobileView hook breakpoint */\n@media (max-width: 767px) {\n .haiku-card {\n padding: 1rem 1.5rem; /* Reduced from 2.5rem 3rem */\n min-width: auto; /* Remove min-width constraint */\n max-width: 100%; /* Full width on mobile */\n margin: 1rem auto; /* Reduced margin */\n }\n\n .haiku-card-image {\n width: 5.625rem; /* 90px - smaller on mobile */\n height: 5.625rem; /* 90px - smaller on mobile */\n }\n\n .suggestion-card-image {\n width: 5rem; /* Slightly smaller on mobile */\n height: 5rem; /* Slightly smaller on mobile */\n }\n\n .suggestion-card-image-focus {\n width: 5rem; /* Slightly smaller on mobile */\n height: 5rem; /* Slightly smaller on mobile */\n }\n}\n", + "language": "css", + "type": "file" + }, + { + "name": "README.mdx", + "content": "# 🪶 Tool-Based Generative UI Haiku Creator\n\n## What This Demo Shows\n\nThis demo showcases CopilotKit's **tool-based generative UI** capabilities:\n\n1. **Frontend Rendering of Tool Calls**: Backend tool calls are automatically\n rendered in the UI\n2. **Dynamic UI Generation**: The UI updates in real-time as the agent generates\n content\n3. **Elegant Content Presentation**: Complex structured data (haikus) are\n beautifully displayed\n\n## How to Interact\n\nChat with your Copilot and ask for haikus about different topics:\n\n- \"Create a haiku about nature\"\n- \"Write a haiku about technology\"\n- \"Generate a haiku about the changing seasons\"\n- \"Make a humorous haiku about programming\"\n\nEach request will trigger the agent to generate a haiku and display it in a\nvisually appealing card format in the UI.\n\n## ✨ Tool-Based Generative UI in Action\n\n**What's happening technically:**\n\n- The agent processes your request and determines it should create a haiku\n- It calls a backend tool that returns structured haiku data\n- CopilotKit automatically renders this tool call in the frontend\n- The rendering is handled by the registered tool component in your React app\n- No manual state management is required to display the results\n\n**What you'll see in this demo:**\n\n- As you request a haiku, a beautifully formatted card appears in the UI\n- The haiku follows the traditional 5-7-5 syllable structure\n- Each haiku is presented with consistent styling\n- Multiple haikus can be generated in sequence\n- The UI adapts to display each new piece of content\n\nThis pattern of tool-based generative UI can be extended to create any kind of\ndynamic content - from data visualizations to interactive components, all driven\nby your Copilot's tool calls!\n", + "language": "markdown", + "type": "file" + }, + { + "name": "agent.ts", + "content": "/**\n * Tool-based Generative UI Agent using Cloudflare Workers AI\n *\n * This agent demonstrates how frontend-provided tools (via CopilotKit actions)\n * can be used to render custom React components in the UI.\n *\n * Example: A haiku generation tool that the frontend can render as a custom\n * component with special styling or animations.\n *\n * Features:\n * - Tool calling support for frontend-defined actions\n * - Streaming tool call arguments\n * - AG-UI protocol TOOL_CALL_* events\n */\n\nimport { CloudflareAgent, CLOUDFLARE_MODELS } from \"@ag-ui/cloudflare\";\n\nexport const HAIKU_IMAGE_NAMES = [\n \"Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg\",\n \"Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg\",\n \"Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg\",\n \"Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg\",\n \"Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg\",\n \"Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg\",\n \"Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg\",\n \"Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg\",\n \"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\n \"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\n] as const;\n\nexport const HAIKU_GRADIENTS = [\n \"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\",\n \"linear-gradient(120deg, #00d2ff 0%, #3a7bd5 100%)\",\n \"linear-gradient(135deg, #f093fb 0%, #f5576c 100%)\",\n \"linear-gradient(120deg, #f6d365 0%, #fda085 100%)\",\n \"linear-gradient(120deg, #a6c0fe 0%, #f68084 100%)\",\n \"linear-gradient(135deg, #1d4350 0%, #a43931 100%)\",\n \"linear-gradient(135deg, #43cea2 0%, #185a9d 100%)\",\n \"linear-gradient(135deg, #13547a 0%, #80d0c7 100%)\",\n \"linear-gradient(135deg, #ff9966 0%, #ff5e62 100%)\",\n \"linear-gradient(135deg, #373b44 0%, #4286f4 100%)\",\n] as const;\n\n/**\n * Tool-Based Generative UI Agent\n *\n * Helps users with writing haikus. When tools are provided by the frontend\n * (e.g., generate_haiku), the agent will use them and the frontend can\n * render custom UI components for the tool results.\n */\nexport class ToolBasedGenerativeUiAgent extends CloudflareAgent {\n constructor() {\n const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;\n const apiToken = process.env.CLOUDFLARE_API_TOKEN;\n\n if (!accountId || !apiToken) {\n throw new Error(\n \"Missing required environment variables: CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN\"\n );\n }\n\n super({\n accountId,\n apiToken,\n model: CLOUDFLARE_MODELS.LLAMA_3_3_70B_FP8, // Using function-calling capable model\n systemPrompt: buildSystemPrompt(),\n streamingEnabled: true,\n });\n }\n}\n\n// Lazy singleton\nlet _toolBasedAgent: ToolBasedGenerativeUiAgent | null = null;\n\nexport function getToolBasedGenerativeUiAgent(): ToolBasedGenerativeUiAgent {\n if (!_toolBasedAgent) {\n _toolBasedAgent = new ToolBasedGenerativeUiAgent();\n }\n return _toolBasedAgent;\n}\n\nfunction buildSystemPrompt(): string {\n const imagesList = HAIKU_IMAGE_NAMES.map((name) => `- ${name}`).join(\"\\n\");\n const gradientsList = HAIKU_GRADIENTS.map((gradient) => `- ${gradient}`).join(\"\\n\");\n\n return `You are an expert haiku composer. Always respond as a warm, collaborative assistant who\nhelps the user craft traditional Japanese haiku (5-7-5 syllable structure) alongside faithful\nEnglish translations.\n\nYOU MUST ALWAYS CALL THE \\\"generate_haiku\\\" TOOL in order to deliver a finished haiku. Configure\nthe tool call exactly with this JSON shape:\n{\n \"japanese\": [\"\", \"\", \"\"],\n \"english\": [\"\", \"\", \"\"],\n \"image_name\": \"\",\n \"gradient\": \"\"\n}\n\nGuidelines:\n- The Japanese and English arrays must each contain exactly three strings.\n- Pick a single image_name that reinforces the haiku's theme.\n- Choose one gradient value from the approved list to style the UI background.\n- Never invent file names or gradients outside the provided lists.\n- Your conversational reply should reference the haiku, but do not repeat image names or gradient\n strings; those are conveyed through the tool result.\n\nAvailable image file names:\n${imagesList}\n\nApproved CSS gradients (use verbatim):\n${gradientsList}`;\n}\n", + "language": "ts", + "type": "file" + } + ], + "cloudflare::agentic_generative_ui": [ + { + "name": "page.tsx", + "content": "\"use client\";\nimport React from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport \"./style.css\";\nimport { CopilotKit, useCoAgentStateRender } from \"@copilotkit/react-core\";\nimport { CopilotChat } from \"@copilotkit/react-ui\";\nimport { useTheme } from \"next-themes\";\n\ninterface AgenticGenerativeUIProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\nconst AgenticGenerativeUI: React.FC = ({ params }) => {\n const { integrationId } = React.use(params);\n return (\n \n \n \n );\n};\n\ninterface AgentState {\n steps: {\n description: string;\n status: \"pending\" | \"completed\";\n }[];\n}\n\nconst Chat = () => {\n const { theme } = useTheme();\n useCoAgentStateRender({\n name: \"agentic_generative_ui\",\n render: ({ state }) => {\n if (!state.steps || state.steps.length === 0) {\n return null;\n }\n\n const completedCount = state.steps.filter((step) => step.status === \"completed\").length;\n const progressPercentage = (completedCount / state.steps.length) * 100;\n\n return (\n
\n \n {/* Header */}\n
\n
\n

\n Task Progress\n

\n
\n {completedCount}/{state.steps.length} Complete\n
\n
\n\n {/* Progress Bar */}\n \n \n \n
\n
\n\n {/* Steps */}\n
\n {state.steps.map((step, index) => {\n const isCompleted = step.status === \"completed\";\n const isCurrentPending =\n step.status === \"pending\" &&\n index === state.steps.findIndex((s) => s.status === \"pending\");\n const isFuturePending = step.status === \"pending\" && !isCurrentPending;\n\n return (\n \n {/* Connector Line */}\n {index < state.steps.length - 1 && (\n \n )}\n\n {/* Status Icon */}\n \n {isCompleted ? (\n \n ) : isCurrentPending ? (\n \n ) : (\n \n )}\n
\n\n {/* Step Content */}\n
\n \n {step.description}\n
\n {isCurrentPending && (\n \n Processing...\n
\n )}\n
\n\n {/* Animated Background for Current Step */}\n {isCurrentPending && (\n \n )}\n
\n );\n })}\n
\n\n {/* Decorative Elements */}\n \n \n
\n
\n );\n },\n });\n\n return (\n
\n
\n \n
\n
\n );\n};\n\n// Enhanced Icons\nfunction CheckIcon() {\n return (\n \n \n \n );\n}\n\nfunction SpinnerIcon() {\n return (\n \n \n \n \n );\n}\n\nfunction ClockIcon({ theme }: { theme?: string }) {\n return (\n \n \n \n \n );\n}\n\nexport default AgenticGenerativeUI;\n", + "language": "typescript", + "type": "file" + }, + { + "name": "style.css", + "content": ".copilotKitInput {\n border-bottom-left-radius: 0.75rem;\n border-bottom-right-radius: 0.75rem;\n border-top-left-radius: 0.75rem;\n border-top-right-radius: 0.75rem;\n border: 1px solid var(--copilot-kit-separator-color) !important;\n}\n\n.copilotKitChat {\n background-color: #fff !important;\n}\n", + "language": "css", + "type": "file" + }, + { + "name": "README.mdx", + "content": "# 🚀 Agentic Generative UI Task Executor\n\n## What This Demo Shows\n\nThis demo showcases CopilotKit's **agentic generative UI** capabilities:\n\n1. **Real-time Status Updates**: The Copilot provides live feedback as it works\n through complex tasks\n2. **Long-running Task Execution**: See how agents can handle extended processes\n with continuous feedback\n3. **Dynamic UI Generation**: The interface updates in real-time to reflect the\n agent's progress\n\n## How to Interact\n\nSimply ask your Copilot to perform any moderately complex task:\n\n- \"Make me a sandwich\"\n- \"Plan a vacation to Japan\"\n- \"Create a weekly workout routine\"\n\nThe Copilot will break down the task into steps and begin \"executing\" them,\nproviding real-time status updates as it progresses.\n\n## ✨ Agentic Generative UI in Action\n\n**What's happening technically:**\n\n- The agent analyzes your request and creates a detailed execution plan\n- Each step is processed sequentially with realistic timing\n- Status updates are streamed to the frontend using CopilotKit's streaming\n capabilities\n- The UI dynamically renders these updates without page refreshes\n- The entire flow is managed by the agent, requiring no manual intervention\n\n**What you'll see in this demo:**\n\n- The Copilot breaks your task into logical steps\n- A status indicator shows the current progress\n- Each step is highlighted as it's being executed\n- Detailed status messages explain what's happening at each moment\n- Upon completion, you receive a summary of the task execution\n\nThis pattern of providing real-time progress for long-running tasks is perfect\nfor scenarios where users benefit from transparency into complex processes -\nfrom data analysis to content creation, system configurations, or multi-stage\nworkflows!\n", + "language": "markdown", + "type": "file" + }, + { + "name": "agent.ts", + "content": "/**\n * Agentic Generative UI Agent using Cloudflare Workers AI\n *\n * This agent demonstrates progressive state updates where the UI can render\n * structured data as it's being generated by the model.\n *\n * Example: When the agent generates a list of task steps, the frontend can\n * render each step progressively as it's streamed, creating a dynamic UI\n * experience.\n *\n * Features:\n * - STATE_SNAPSHOT events for progressive UI updates\n * - Structured output generation\n * - Real-time state synchronization with frontend\n */\n\nimport { CloudflareAgent, CLOUDFLARE_MODELS } from \"@ag-ui/cloudflare\";\nimport { Observable, Subscriber } from \"rxjs\";\nimport type { RunAgentInput, BaseEvent } from \"@ag-ui/client\";\nimport { EventType, type StateSnapshotEvent } from \"@ag-ui/core\";\n\n/**\n * Agentic Generative UI Agent\n *\n * Generates task steps progressively and emits state updates so the frontend\n * can render the UI as the steps are being created.\n */\nexport class AgenticGenerativeUiAgent extends CloudflareAgent {\n constructor() {\n const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;\n const apiToken = process.env.CLOUDFLARE_API_TOKEN;\n\n if (!accountId || !apiToken) {\n throw new Error(\n \"Missing required environment variables: CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN\"\n );\n }\n\n super({\n accountId,\n apiToken,\n model: CLOUDFLARE_MODELS.LLAMA_3_1_8B,\n systemPrompt: `You are a helpful assistant that breaks down tasks into steps.\nWhen asked to do something, provide 5-10 clear, actionable steps.\nFormat each step as a short phrase in gerund form (e.g., \"Opening the door\", \"Mixing ingredients\").`,\n streamingEnabled: true,\n });\n }\n\n /**\n * Override run() to add STATE_SNAPSHOT events during generation\n */\n run(input: RunAgentInput): Observable {\n return new Observable((subscriber) => {\n this.executeRunWithState(input, subscriber)\n .catch((error) => {\n console.error(\"AgenticGenerativeUiAgent execution error:\", error);\n subscriber.error(error);\n })\n .finally(() => {\n subscriber.complete();\n });\n });\n }\n\n /**\n * Enhanced execution with progressive state updates\n */\n private async executeRunWithState(\n input: RunAgentInput,\n subscriber: Subscriber\n ): Promise {\n // Call parent execute but also emit state snapshots\n const steps: Array<{ description: string; status: string }> = [];\n let currentStepText = \"\";\n\n // First, run the parent's execution\n await this.executeRun(input, subscriber);\n\n // Note: In a real implementation, you would parse the streamed response\n // and extract steps progressively, emitting STATE_SNAPSHOT events.\n // For this demo, we'll emit a final state snapshot after the text completes.\n\n // Emit final state snapshot\n const stateSnapshot: StateSnapshotEvent = {\n type: EventType.STATE_SNAPSHOT,\n snapshot: {\n steps,\n completed: true,\n },\n timestamp: Date.now(),\n };\n subscriber.next(stateSnapshot);\n }\n}\n\n// Lazy singleton\nlet _agenticGenUiAgent: AgenticGenerativeUiAgent | null = null;\n\nexport function getAgenticGenerativeUiAgent(): AgenticGenerativeUiAgent {\n if (!_agenticGenUiAgent) {\n _agenticGenUiAgent = new AgenticGenerativeUiAgent();\n }\n return _agenticGenUiAgent;\n}\n", + "language": "ts", + "type": "file" + } + ], + "cloudflare::human_in_the_loop": [ + { + "name": "page.tsx", + "content": "\"use client\";\nimport React, { useState, useEffect } from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport \"./style.css\";\nimport {\n CopilotKit,\n useHumanInTheLoop,\n useLangGraphInterrupt,\n} from \"@copilotkit/react-core\";\nimport { CopilotChat } from \"@copilotkit/react-ui\";\nimport { useTheme } from \"next-themes\";\n\ninterface HumanInTheLoopProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\nconst HumanInTheLoop: React.FC = ({ params }) => {\n const { integrationId } = React.use(params);\n\n return (\n \n \n \n );\n};\n\ninterface Step {\n description: string;\n status: \"disabled\" | \"enabled\" | \"executing\";\n}\n\n// Shared UI Components\nconst StepContainer = ({ theme, children }: { theme?: string; children: React.ReactNode }) => (\n
\n \n {children}\n
\n
\n);\n\nconst StepHeader = ({\n theme,\n enabledCount,\n totalCount,\n status,\n showStatus = false,\n}: {\n theme?: string;\n enabledCount: number;\n totalCount: number;\n status?: string;\n showStatus?: boolean;\n}) => (\n
\n
\n

\n Select Steps\n

\n
\n
\n {enabledCount}/{totalCount} Selected\n
\n {showStatus && (\n \n {status === \"executing\" ? \"Ready\" : \"Waiting\"}\n
\n )}\n
\n
\n\n \n 0 ? (enabledCount / totalCount) * 100 : 0}%` }}\n />\n
\n
\n);\n\nconst StepItem = ({\n step,\n theme,\n status,\n onToggle,\n disabled = false,\n}: {\n step: { description: string; status: string };\n theme?: string;\n status?: string;\n onToggle: () => void;\n disabled?: boolean;\n}) => (\n \n
\n \n {step.description}\n \n \n
\n);\n\nconst ActionButton = ({\n variant,\n theme,\n disabled,\n onClick,\n children,\n}: {\n variant: \"primary\" | \"secondary\" | \"success\" | \"danger\";\n theme?: string;\n disabled?: boolean;\n onClick: () => void;\n children: React.ReactNode;\n}) => {\n const baseClasses = \"px-6 py-3 rounded-lg font-semibold transition-all duration-200\";\n const enabledClasses = \"hover:scale-105 shadow-md hover:shadow-lg\";\n const disabledClasses = \"opacity-50 cursor-not-allowed\";\n\n const variantClasses = {\n primary:\n \"bg-gradient-to-r from-purple-500 to-purple-700 hover:from-purple-600 hover:to-purple-800 text-white shadow-lg hover:shadow-xl\",\n secondary:\n theme === \"dark\"\n ? \"bg-slate-700 hover:bg-slate-600 text-white border border-slate-600 hover:border-slate-500\"\n : \"bg-gray-100 hover:bg-gray-200 text-gray-800 border border-gray-300 hover:border-gray-400\",\n success:\n \"bg-gradient-to-r from-green-500 to-emerald-600 hover:from-green-600 hover:to-emerald-700 text-white shadow-lg hover:shadow-xl\",\n danger:\n \"bg-gradient-to-r from-red-500 to-red-600 hover:from-red-600 hover:to-red-700 text-white shadow-lg hover:shadow-xl\",\n };\n\n return (\n \n {children}\n \n );\n};\n\nconst DecorativeElements = ({\n theme,\n variant = \"default\",\n}: {\n theme?: string;\n variant?: \"default\" | \"success\" | \"danger\";\n}) => (\n <>\n \n \n \n);\nconst InterruptHumanInTheLoop: React.FC<{\n event: { value: { steps: Step[] } };\n resolve: (value: string) => void;\n}> = ({ event, resolve }) => {\n const { theme } = useTheme();\n\n // Parse and initialize steps data\n let initialSteps: Step[] = [];\n if (event.value && event.value.steps && Array.isArray(event.value.steps)) {\n initialSteps = event.value.steps.map((step: any) => ({\n description: typeof step === \"string\" ? step : step.description || \"\",\n status: typeof step === \"object\" && step.status ? step.status : \"enabled\",\n }));\n }\n\n const [localSteps, setLocalSteps] = useState(initialSteps);\n const enabledCount = localSteps.filter((step) => step.status === \"enabled\").length;\n\n const handleStepToggle = (index: number) => {\n setLocalSteps((prevSteps) =>\n prevSteps.map((step, i) =>\n i === index\n ? { ...step, status: step.status === \"enabled\" ? \"disabled\" : \"enabled\" }\n : step,\n ),\n );\n };\n\n const handlePerformSteps = () => {\n const selectedSteps = localSteps\n .filter((step) => step.status === \"enabled\")\n .map((step) => step.description);\n resolve(\"The user selected the following steps: \" + selectedSteps.join(\", \"));\n };\n\n return (\n \n \n\n
\n {localSteps.map((step, index) => (\n handleStepToggle(index)}\n />\n ))}\n
\n\n
\n \n \n Perform Steps\n \n {enabledCount}\n \n \n
\n\n \n
\n );\n};\n\nconst Chat = ({ integrationId }: { integrationId: string }) => {\n // Langgraph uses it's own hook to handle human-in-the-loop interactions via langgraph interrupts,\n // This hook won't do anything for other integrations.\n useLangGraphInterrupt({\n render: ({ event, resolve }) => ,\n });\n useHumanInTheLoop({\n name: \"generate_task_steps\",\n description: \"Generates a list of steps for the user to perform\",\n parameters: [\n {\n name: \"steps\",\n type: \"object[]\",\n attributes: [\n {\n name: \"description\",\n type: \"string\",\n },\n {\n name: \"status\",\n type: \"string\",\n enum: [\"enabled\", \"disabled\", \"executing\"],\n },\n ],\n },\n ],\n // Langgraph uses it's own hook to handle human-in-the-loop interactions via langgraph interrupts,\n // so don't use this action for langgraph integration.\n available: [\"langgraph\", \"langgraph-fastapi\", \"langgraph-typescript\"].includes(integrationId)\n ? \"disabled\"\n : \"enabled\",\n render: ({ args, respond, status }) => {\n return ;\n },\n });\n\n return (\n
\n
\n \n
\n
\n );\n};\n\nconst StepsFeedback = ({ args, respond, status }: { args: any; respond: any; status: any }) => {\n const { theme } = useTheme();\n const [localSteps, setLocalSteps] = useState([]);\n const [accepted, setAccepted] = useState(null);\n\n useEffect(() => {\n if (status === \"executing\" && localSteps.length === 0) {\n setLocalSteps(args.steps);\n }\n }, [status, args.steps, localSteps]);\n\n if (args.steps === undefined || args.steps.length === 0) {\n return <>;\n }\n\n const steps = localSteps.length > 0 ? localSteps : args.steps;\n const enabledCount = steps.filter((step: any) => step.status === \"enabled\").length;\n\n const handleStepToggle = (index: number) => {\n setLocalSteps((prevSteps) =>\n prevSteps.map((step, i) =>\n i === index\n ? { ...step, status: step.status === \"enabled\" ? \"disabled\" : \"enabled\" }\n : step,\n ),\n );\n };\n\n const handleReject = () => {\n if (respond) {\n setAccepted(false);\n respond({ accepted: false });\n }\n };\n\n const handleConfirm = () => {\n if (respond) {\n setAccepted(true);\n respond({ accepted: true, steps: localSteps.filter((step) => step.status === \"enabled\") });\n }\n };\n\n return (\n \n \n\n
\n {steps.map((step: any, index: any) => (\n handleStepToggle(index)}\n disabled={status !== \"executing\"}\n />\n ))}\n
\n\n {/* Action Buttons - Different logic from InterruptHumanInTheLoop */}\n {accepted === null && (\n
\n \n \n Reject\n \n \n \n Confirm\n \n {enabledCount}\n \n \n
\n )}\n\n {/* Result State - Unique to StepsFeedback */}\n {accepted !== null && (\n
\n \n {accepted ? \"✓\" : \"✗\"}\n {accepted ? \"Accepted\" : \"Rejected\"}\n
\n
\n )}\n\n \n \n );\n};\n\nexport default HumanInTheLoop;\n", + "language": "typescript", + "type": "file" + }, + { + "name": "style.css", + "content": ".copilotKitInput {\n border-bottom-left-radius: 0.75rem;\n border-bottom-right-radius: 0.75rem;\n border-top-left-radius: 0.75rem;\n border-top-right-radius: 0.75rem;\n border: 1px solid var(--copilot-kit-separator-color) !important;\n}\n\n.copilotKitChat {\n background-color: #fff !important;\n}\n", + "language": "css", + "type": "file" + }, + { + "name": "README.mdx", + "content": "# 🤝 Human-in-the-Loop Task Planner\n\n## What This Demo Shows\n\nThis demo showcases CopilotKit's **human-in-the-loop** capabilities:\n\n1. **Collaborative Planning**: The Copilot generates task steps and lets you\n decide which ones to perform\n2. **Interactive Decision Making**: Select or deselect steps to customize the\n execution plan\n3. **Adaptive Responses**: The Copilot adapts its execution based on your\n choices, even handling missing steps\n\n## How to Interact\n\nTry these steps to experience the demo:\n\n1. Ask your Copilot to help with a task, such as:\n\n - \"Make me a sandwich\"\n - \"Plan a weekend trip\"\n - \"Organize a birthday party\"\n - \"Start a garden\"\n\n2. Review the suggested steps provided by your Copilot\n\n3. Select or deselect steps using the checkboxes to customize the plan\n\n - Try removing essential steps to see how the Copilot adapts!\n\n4. Click \"Execute Plan\" to see the outcome based on your selections\n\n## ✨ Human-in-the-Loop Magic in Action\n\n**What's happening technically:**\n\n- The agent analyzes your request and breaks it down into logical steps\n- These steps are presented to you through a dynamic UI component\n- Your selections are captured as user input\n- The agent considers your choices when executing the plan\n- The agent adapts to missing steps with creative problem-solving\n\n**What you'll see in this demo:**\n\n- The Copilot provides a detailed, step-by-step plan for your task\n- You have complete control over which steps to include\n- If you remove essential steps, the Copilot provides entertaining and creative\n workarounds\n- The final execution reflects your choices, showing how human input shapes the\n outcome\n- Each response is tailored to your specific selections\n\nThis human-in-the-loop pattern creates a powerful collaborative experience where\nboth human judgment and AI capabilities work together to achieve better results\nthan either could alone!\n", + "language": "markdown", + "type": "file" + }, + { + "name": "agent.ts", + "content": "/**\n * Human-in-the-Loop Agent using Cloudflare Workers AI\n *\n * This agent demonstrates how to pause execution and request user input\n * before proceeding with a task.\n *\n * Example: When generating a task plan, the agent can ask the user to\n * review and approve/modify the steps before execution.\n *\n * Features:\n * - Tool calling for user confirmation requests\n * - Interactive step selection\n * - User feedback integration\n */\n\nimport { CloudflareAgent, CLOUDFLARE_MODELS } from \"@ag-ui/cloudflare\";\n\n/**\n * Human-in-the-Loop Agent\n *\n * An assistant that requests user confirmation for generated task steps\n * before proceeding with execution.\n */\nexport class HumanInTheLoopAgent extends CloudflareAgent {\n constructor() {\n const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;\n const apiToken = process.env.CLOUDFLARE_API_TOKEN;\n\n if (!accountId || !apiToken) {\n throw new Error(\n \"Missing required environment variables: CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN\"\n );\n }\n\n super({\n accountId,\n apiToken,\n model: CLOUDFLARE_MODELS.HERMES_2_PRO_7B,\n systemPrompt: `You are a helpful assistant that creates task plans.\n\nWhen the user asks you to do something:\n1. Break it down into 5-10 clear, actionable steps\n2. Use the generate_task_steps tool to present the steps to the user for approval\n3. Each step should have a description and status (enabled/disabled)\n4. Wait for the user to review and confirm before proceeding\n\nIMPORTANT: Only use the generate_task_steps tool when you have a complete plan ready.\nDo NOT call the tool for simple greetings or questions.`,\n streamingEnabled: true,\n });\n }\n}\n\n// Lazy singleton\nlet _humanInTheLoopAgent: HumanInTheLoopAgent | null = null;\n\nexport function getHumanInTheLoopAgent(): HumanInTheLoopAgent {\n if (!_humanInTheLoopAgent) {\n _humanInTheLoopAgent = new HumanInTheLoopAgent();\n }\n return _humanInTheLoopAgent;\n}\n", + "language": "ts", + "type": "file" + } + ], + "cloudflare::shared_state": [ + { + "name": "page.tsx", + "content": "\"use client\";\nimport { CopilotKit, useCoAgent, useCopilotChat } from \"@copilotkit/react-core\";\nimport { CopilotChat, CopilotSidebar } from \"@copilotkit/react-ui\";\nimport React, { useState, useEffect, useRef } from \"react\";\nimport { Role, TextMessage } from \"@copilotkit/runtime-client-gql\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport \"./style.css\";\nimport { useMobileView } from \"@/utils/use-mobile-view\";\nimport { useMobileChat } from \"@/utils/use-mobile-chat\";\nimport { useURLParams } from \"@/contexts/url-params-context\";\n\ninterface SharedStateProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\nexport default function SharedState({ params }: SharedStateProps) {\n const { integrationId } = React.use(params);\n const { isMobile } = useMobileView();\n const { chatDefaultOpen } = useURLParams();\n const defaultChatHeight = 50;\n const { isChatOpen, setChatHeight, setIsChatOpen, isDragging, chatHeight, handleDragStart } =\n useMobileChat(defaultChatHeight);\n\n const chatTitle = \"AI Recipe Assistant\";\n const chatDescription = \"Ask me to craft recipes\";\n const initialLabel = \"Hi 👋 How can I help with your recipe?\";\n\n return (\n \n
\n \n {isMobile ? (\n <>\n {/* Chat Toggle Button */}\n
\n
\n {\n if (!isChatOpen) {\n setChatHeight(defaultChatHeight); // Reset to good default when opening\n }\n setIsChatOpen(!isChatOpen);\n }}\n >\n
\n
\n
{chatTitle}
\n
{chatDescription}
\n
\n
\n \n \n \n \n
\n
\n
\n\n {/* Pull-Up Chat Container */}\n \n {/* Drag Handle Bar */}\n \n
\n
\n\n {/* Chat Header */}\n
\n
\n
\n

{chatTitle}

\n
\n setIsChatOpen(false)}\n className=\"p-2 hover:bg-gray-100 rounded-full transition-colors\"\n >\n \n \n \n \n
\n
\n\n {/* Chat Content - Flexible container for messages and input */}\n
\n \n
\n
\n\n {/* Backdrop */}\n {isChatOpen && (\n
setIsChatOpen(false)} />\n )}\n \n ) : (\n \n )}\n
\n \n );\n}\n\nenum SkillLevel {\n BEGINNER = \"Beginner\",\n INTERMEDIATE = \"Intermediate\",\n ADVANCED = \"Advanced\",\n}\n\nenum CookingTime {\n FiveMin = \"5 min\",\n FifteenMin = \"15 min\",\n ThirtyMin = \"30 min\",\n FortyFiveMin = \"45 min\",\n SixtyPlusMin = \"60+ min\",\n}\n\nconst cookingTimeValues = [\n { label: CookingTime.FiveMin, value: 0 },\n { label: CookingTime.FifteenMin, value: 1 },\n { label: CookingTime.ThirtyMin, value: 2 },\n { label: CookingTime.FortyFiveMin, value: 3 },\n { label: CookingTime.SixtyPlusMin, value: 4 },\n];\n\nenum SpecialPreferences {\n HighProtein = \"High Protein\",\n LowCarb = \"Low Carb\",\n Spicy = \"Spicy\",\n BudgetFriendly = \"Budget-Friendly\",\n OnePotMeal = \"One-Pot Meal\",\n Vegetarian = \"Vegetarian\",\n Vegan = \"Vegan\",\n}\n\ninterface Ingredient {\n icon: string;\n name: string;\n amount: string;\n}\n\ninterface Recipe {\n title: string;\n skill_level: SkillLevel;\n cooking_time: CookingTime;\n special_preferences: string[];\n ingredients: Ingredient[];\n instructions: string[];\n}\n\ninterface RecipeAgentState {\n recipe: Recipe;\n}\n\nconst INITIAL_STATE: RecipeAgentState = {\n recipe: {\n title: \"Make Your Recipe\",\n skill_level: SkillLevel.INTERMEDIATE,\n cooking_time: CookingTime.FortyFiveMin,\n special_preferences: [],\n ingredients: [\n { icon: \"🥕\", name: \"Carrots\", amount: \"3 large, grated\" },\n { icon: \"🌾\", name: \"All-Purpose Flour\", amount: \"2 cups\" },\n ],\n instructions: [\"Preheat oven to 350°F (175°C)\"],\n },\n};\n\nfunction Recipe() {\n const { isMobile } = useMobileView();\n const { state: agentState, setState: setAgentState } = useCoAgent({\n name: \"shared_state\",\n initialState: INITIAL_STATE,\n });\n\n const [recipe, setRecipe] = useState(INITIAL_STATE.recipe);\n const { appendMessage, isLoading } = useCopilotChat();\n const [editingInstructionIndex, setEditingInstructionIndex] = useState(null);\n const newInstructionRef = useRef(null);\n\n const updateRecipe = (partialRecipe: Partial) => {\n setAgentState({\n ...agentState,\n recipe: {\n ...recipe,\n ...partialRecipe,\n },\n });\n setRecipe({\n ...recipe,\n ...partialRecipe,\n });\n };\n\n const newRecipeState = { ...recipe };\n const newChangedKeys = [];\n const changedKeysRef = useRef([]);\n\n for (const key in recipe) {\n if (\n agentState &&\n agentState.recipe &&\n (agentState.recipe as any)[key] !== undefined &&\n (agentState.recipe as any)[key] !== null\n ) {\n let agentValue = (agentState.recipe as any)[key];\n const recipeValue = (recipe as any)[key];\n\n // Check if agentValue is a string and replace \\n with actual newlines\n if (typeof agentValue === \"string\") {\n agentValue = agentValue.replace(/\\\\n/g, \"\\n\");\n }\n\n if (JSON.stringify(agentValue) !== JSON.stringify(recipeValue)) {\n (newRecipeState as any)[key] = agentValue;\n newChangedKeys.push(key);\n }\n }\n }\n\n if (newChangedKeys.length > 0) {\n changedKeysRef.current = newChangedKeys;\n } else if (!isLoading) {\n changedKeysRef.current = [];\n }\n\n useEffect(() => {\n setRecipe(newRecipeState);\n }, [JSON.stringify(newRecipeState)]);\n\n const handleTitleChange = (event: React.ChangeEvent) => {\n updateRecipe({\n title: event.target.value,\n });\n };\n\n const handleSkillLevelChange = (event: React.ChangeEvent) => {\n updateRecipe({\n skill_level: event.target.value as SkillLevel,\n });\n };\n\n const handleDietaryChange = (preference: string, checked: boolean) => {\n if (checked) {\n updateRecipe({\n special_preferences: [...recipe.special_preferences, preference],\n });\n } else {\n updateRecipe({\n special_preferences: recipe.special_preferences.filter((p) => p !== preference),\n });\n }\n };\n\n const handleCookingTimeChange = (event: React.ChangeEvent) => {\n updateRecipe({\n cooking_time: cookingTimeValues[Number(event.target.value)].label,\n });\n };\n\n const addIngredient = () => {\n // Pick a random food emoji from our valid list\n updateRecipe({\n ingredients: [...recipe.ingredients, { icon: \"🍴\", name: \"\", amount: \"\" }],\n });\n };\n\n const updateIngredient = (index: number, field: keyof Ingredient, value: string) => {\n const updatedIngredients = [...recipe.ingredients];\n updatedIngredients[index] = {\n ...updatedIngredients[index],\n [field]: value,\n };\n updateRecipe({ ingredients: updatedIngredients });\n };\n\n const removeIngredient = (index: number) => {\n const updatedIngredients = [...recipe.ingredients];\n updatedIngredients.splice(index, 1);\n updateRecipe({ ingredients: updatedIngredients });\n };\n\n const addInstruction = () => {\n const newIndex = recipe.instructions.length;\n updateRecipe({\n instructions: [...recipe.instructions, \"\"],\n });\n // Set the new instruction as the editing one\n setEditingInstructionIndex(newIndex);\n\n // Focus the new instruction after render\n setTimeout(() => {\n const textareas = document.querySelectorAll(\".instructions-container textarea\");\n const newTextarea = textareas[textareas.length - 1] as HTMLTextAreaElement;\n if (newTextarea) {\n newTextarea.focus();\n }\n }, 50);\n };\n\n const updateInstruction = (index: number, value: string) => {\n const updatedInstructions = [...recipe.instructions];\n updatedInstructions[index] = value;\n updateRecipe({ instructions: updatedInstructions });\n };\n\n const removeInstruction = (index: number) => {\n const updatedInstructions = [...recipe.instructions];\n updatedInstructions.splice(index, 1);\n updateRecipe({ instructions: updatedInstructions });\n };\n\n // Simplified icon handler that defaults to a fork/knife for any problematic icons\n const getProperIcon = (icon: string | undefined): string => {\n // If icon is undefined return the default\n if (!icon) {\n return \"🍴\";\n }\n\n return icon;\n };\n\n return (\n \n {/* Recipe Title */}\n
\n \n\n
\n
\n 🕒\n t.label === recipe.cooking_time)?.value || 3}\n onChange={handleCookingTimeChange}\n style={{\n backgroundImage:\n \"url(\\\"data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23555' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3e%3cpolyline points='6 9 12 15 18 9'%3e%3c/polyline%3e%3c/svg%3e\\\")\",\n backgroundRepeat: \"no-repeat\",\n backgroundPosition: \"right 0px center\",\n backgroundSize: \"12px\",\n appearance: \"none\",\n WebkitAppearance: \"none\",\n }}\n >\n {cookingTimeValues.map((time) => (\n \n ))}\n \n
\n\n
\n 🏆\n \n {Object.values(SkillLevel).map((level) => (\n \n ))}\n \n
\n
\n
\n\n {/* Dietary Preferences */}\n
\n {changedKeysRef.current.includes(\"special_preferences\") && }\n

Dietary Preferences

\n
\n {Object.values(SpecialPreferences).map((option) => (\n \n ))}\n
\n
\n\n {/* Ingredients */}\n
\n {changedKeysRef.current.includes(\"ingredients\") && }\n
\n

Ingredients

\n \n + Add Ingredient\n \n
\n
\n {recipe.ingredients.map((ingredient, index) => (\n
\n
{getProperIcon(ingredient.icon)}
\n
\n updateIngredient(index, \"name\", e.target.value)}\n placeholder=\"Ingredient name\"\n className=\"ingredient-name-input\"\n />\n updateIngredient(index, \"amount\", e.target.value)}\n placeholder=\"Amount\"\n className=\"ingredient-amount-input\"\n />\n
\n removeIngredient(index)}\n aria-label=\"Remove ingredient\"\n >\n ×\n \n
\n ))}\n
\n
\n\n {/* Instructions */}\n
\n {changedKeysRef.current.includes(\"instructions\") && }\n
\n

Instructions

\n \n
\n
\n {recipe.instructions.map((instruction, index) => (\n
\n {/* Number Circle */}\n
{index + 1}
\n\n {/* Vertical Line */}\n {index < recipe.instructions.length - 1 &&
}\n\n {/* Instruction Content */}\n setEditingInstructionIndex(index)}\n >\n updateInstruction(index, e.target.value)}\n placeholder={!instruction ? \"Enter cooking instruction...\" : \"\"}\n onFocus={() => setEditingInstructionIndex(index)}\n onBlur={(e) => {\n // Only blur if clicking outside this instruction\n if (!e.relatedTarget || !e.currentTarget.contains(e.relatedTarget as Node)) {\n setEditingInstructionIndex(null);\n }\n }}\n />\n\n {/* Delete Button (only visible on hover) */}\n {\n e.stopPropagation(); // Prevent triggering parent onClick\n removeInstruction(index);\n }}\n aria-label=\"Remove instruction\"\n >\n ×\n \n
\n
\n ))}\n
\n
\n\n {/* Improve with AI Button */}\n
\n {\n if (!isLoading) {\n appendMessage(\n new TextMessage({\n content: \"Improve the recipe\",\n role: Role.User,\n }),\n );\n }\n }}\n disabled={isLoading}\n >\n {isLoading ? \"Please Wait...\" : \"Improve with AI\"}\n \n
\n \n );\n}\n\nfunction Ping() {\n return (\n \n \n \n \n );\n}\n", + "language": "typescript", + "type": "file" + }, + { + "name": "style.css", + "content": ".copilotKitWindow {\n box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);\n}\n\n.copilotKitHeader {\n border-top-left-radius: 5px !important;\n background-color: #fff;\n color: #000;\n border-bottom: 0px;\n}\n\n/* Recipe App Styles */\n.app-container {\n min-height: 100vh;\n width: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n background-size: cover;\n background-position: center;\n background-repeat: no-repeat;\n background-attachment: fixed;\n position: relative;\n overflow: auto;\n}\n\n.recipe-card {\n background-color: rgba(255, 255, 255, 0.97);\n border-radius: 16px;\n box-shadow: 0 15px 30px rgba(0, 0, 0, 0.25), 0 5px 15px rgba(0, 0, 0, 0.15);\n width: 100%;\n max-width: 750px;\n margin: 20px auto;\n padding: 14px 32px;\n position: relative;\n z-index: 1;\n backdrop-filter: blur(5px);\n border: 1px solid rgba(255, 255, 255, 0.3);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n animation: fadeIn 0.5s ease-out forwards;\n box-sizing: border-box;\n overflow: hidden;\n}\n\n.recipe-card:hover {\n transform: translateY(-5px);\n box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3), 0 10px 20px rgba(0, 0, 0, 0.2);\n}\n\n/* Recipe Header */\n.recipe-header {\n margin-bottom: 24px;\n}\n\n.recipe-title-input {\n width: 100%;\n font-size: 24px;\n font-weight: bold;\n border: none;\n outline: none;\n padding: 8px 0;\n margin-bottom: 0px;\n}\n\n.recipe-meta {\n display: flex;\n align-items: center;\n gap: 20px;\n margin-top: 5px;\n margin-bottom: 14px;\n}\n\n.meta-item {\n display: flex;\n align-items: center;\n gap: 8px;\n color: #555;\n}\n\n.meta-icon {\n font-size: 20px;\n color: #777;\n}\n\n.meta-text {\n font-size: 15px;\n}\n\n/* Recipe Meta Selects */\n.meta-item select {\n border: none;\n background: transparent;\n font-size: 15px;\n color: #555;\n cursor: pointer;\n outline: none;\n padding-right: 18px;\n transition: color 0.2s, transform 0.1s;\n font-weight: 500;\n}\n\n.meta-item select:hover,\n.meta-item select:focus {\n color: #FF5722;\n}\n\n.meta-item select:active {\n transform: scale(0.98);\n}\n\n.meta-item select option {\n color: #333;\n background-color: white;\n font-weight: normal;\n padding: 8px;\n}\n\n/* Section Container */\n.section-container {\n margin-bottom: 20px;\n position: relative;\n width: 100%;\n}\n\n.section-title {\n font-size: 20px;\n font-weight: 700;\n margin-bottom: 20px;\n color: #333;\n position: relative;\n display: inline-block;\n}\n\n.section-title:after {\n content: \"\";\n position: absolute;\n bottom: -8px;\n left: 0;\n width: 40px;\n height: 3px;\n background-color: #ff7043;\n border-radius: 3px;\n}\n\n/* Dietary Preferences */\n.dietary-options {\n display: flex;\n flex-wrap: wrap;\n gap: 10px 16px;\n margin-bottom: 16px;\n width: 100%;\n}\n\n.dietary-option {\n display: flex;\n align-items: center;\n gap: 6px;\n font-size: 14px;\n cursor: pointer;\n margin-bottom: 4px;\n}\n\n.dietary-option input {\n cursor: pointer;\n}\n\n/* Ingredients */\n.ingredients-container {\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n margin-bottom: 15px;\n width: 100%;\n box-sizing: border-box;\n}\n\n.ingredient-card {\n display: flex;\n align-items: center;\n background-color: rgba(255, 255, 255, 0.9);\n border-radius: 12px;\n padding: 12px;\n margin-bottom: 10px;\n box-shadow: 0 4px 10px rgba(0, 0, 0, 0.08);\n position: relative;\n transition: all 0.2s ease;\n border: 1px solid rgba(240, 240, 240, 0.8);\n width: calc(33.333% - 7px);\n box-sizing: border-box;\n}\n\n.ingredient-card:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 15px rgba(0, 0, 0, 0.12);\n}\n\n.ingredient-card .remove-button {\n position: absolute;\n right: 10px;\n top: 10px;\n background: none;\n border: none;\n color: #ccc;\n font-size: 16px;\n cursor: pointer;\n display: none;\n padding: 0;\n width: 24px;\n height: 24px;\n line-height: 1;\n}\n\n.ingredient-card:hover .remove-button {\n display: block;\n}\n\n.ingredient-icon {\n font-size: 24px;\n margin-right: 12px;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 40px;\n height: 40px;\n background-color: #f7f7f7;\n border-radius: 50%;\n flex-shrink: 0;\n}\n\n.ingredient-content {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 3px;\n min-width: 0;\n}\n\n.ingredient-name-input,\n.ingredient-amount-input {\n border: none;\n background: transparent;\n outline: none;\n width: 100%;\n padding: 0;\n text-overflow: ellipsis;\n overflow: hidden;\n white-space: nowrap;\n}\n\n.ingredient-name-input {\n font-weight: 500;\n font-size: 14px;\n}\n\n.ingredient-amount-input {\n font-size: 13px;\n color: #666;\n}\n\n.ingredient-name-input::placeholder,\n.ingredient-amount-input::placeholder {\n color: #aaa;\n}\n\n.remove-button {\n background: none;\n border: none;\n color: #999;\n font-size: 20px;\n cursor: pointer;\n padding: 0;\n width: 28px;\n height: 28px;\n display: flex;\n align-items: center;\n justify-content: center;\n margin-left: 10px;\n}\n\n.remove-button:hover {\n color: #FF5722;\n}\n\n/* Instructions */\n.instructions-container {\n display: flex;\n flex-direction: column;\n gap: 6px;\n position: relative;\n margin-bottom: 12px;\n width: 100%;\n}\n\n.instruction-item {\n position: relative;\n display: flex;\n width: 100%;\n box-sizing: border-box;\n margin-bottom: 8px;\n align-items: flex-start;\n}\n\n.instruction-number {\n display: flex;\n align-items: center;\n justify-content: center;\n min-width: 26px;\n height: 26px;\n background-color: #ff7043;\n color: white;\n border-radius: 50%;\n font-weight: 600;\n flex-shrink: 0;\n box-shadow: 0 2px 4px rgba(255, 112, 67, 0.3);\n z-index: 1;\n font-size: 13px;\n margin-top: 2px;\n}\n\n.instruction-line {\n position: absolute;\n left: 13px; /* Half of the number circle width */\n top: 22px;\n bottom: -18px;\n width: 2px;\n background: linear-gradient(to bottom, #ff7043 60%, rgba(255, 112, 67, 0.4));\n z-index: 0;\n}\n\n.instruction-content {\n background-color: white;\n border-radius: 10px;\n padding: 10px 14px;\n margin-left: 12px;\n flex-grow: 1;\n transition: all 0.2s ease;\n box-shadow: 0 2px 6px rgba(0, 0, 0, 0.08);\n border: 1px solid rgba(240, 240, 240, 0.8);\n position: relative;\n width: calc(100% - 38px);\n box-sizing: border-box;\n display: flex;\n align-items: center;\n}\n\n.instruction-content-editing {\n background-color: #fff9f6;\n box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12), 0 0 0 2px rgba(255, 112, 67, 0.2);\n}\n\n.instruction-content:hover {\n transform: translateY(-2px);\n box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12);\n}\n\n.instruction-textarea {\n width: 100%;\n background: transparent;\n border: none;\n resize: vertical;\n font-family: inherit;\n font-size: 14px;\n line-height: 1.4;\n min-height: 20px;\n outline: none;\n padding: 0;\n margin: 0;\n}\n\n.instruction-delete-btn {\n position: absolute;\n background: none;\n border: none;\n color: #ccc;\n font-size: 16px;\n cursor: pointer;\n display: none;\n padding: 0;\n width: 20px;\n height: 20px;\n line-height: 1;\n top: 50%;\n transform: translateY(-50%);\n right: 8px;\n}\n\n.instruction-content:hover .instruction-delete-btn {\n display: flex;\n align-items: center;\n justify-content: center;\n}\n\n/* Action Button */\n.action-container {\n display: flex;\n justify-content: center;\n margin-top: 40px;\n padding-bottom: 20px;\n position: relative;\n}\n\n.improve-button {\n background-color: #ff7043;\n border: none;\n color: white;\n border-radius: 30px;\n font-size: 18px;\n font-weight: 600;\n padding: 14px 28px;\n cursor: pointer;\n transition: all 0.3s ease;\n box-shadow: 0 4px 15px rgba(255, 112, 67, 0.4);\n display: flex;\n align-items: center;\n justify-content: center;\n text-align: center;\n position: relative;\n min-width: 180px;\n}\n\n.improve-button:hover {\n background-color: #ff5722;\n transform: translateY(-2px);\n box-shadow: 0 8px 20px rgba(255, 112, 67, 0.5);\n}\n\n.improve-button.loading {\n background-color: #ff7043;\n opacity: 0.8;\n cursor: not-allowed;\n padding-left: 42px; /* Reduced padding to bring text closer to icon */\n padding-right: 22px; /* Balance the button */\n justify-content: flex-start; /* Left align text for better alignment with icon */\n}\n\n.improve-button.loading:after {\n content: \"\"; /* Add space between icon and text */\n display: inline-block;\n width: 8px; /* Width of the space */\n}\n\n.improve-button:before {\n content: \"\";\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M12 2v4M12 18v4M4.93 4.93l2.83 2.83M16.24 16.24l2.83 2.83M2 12h4M18 12h4M4.93 19.07l2.83-2.83M16.24 7.76l2.83-2.83'/%3E%3C/svg%3E\");\n width: 20px; /* Slightly smaller icon */\n height: 20px;\n background-repeat: no-repeat;\n background-size: contain;\n position: absolute;\n left: 16px; /* Slightly adjusted */\n top: 50%;\n transform: translateY(-50%);\n display: none;\n}\n\n.improve-button.loading:before {\n display: block;\n animation: spin 1.5s linear infinite;\n}\n\n@keyframes spin {\n 0% { transform: translateY(-50%) rotate(0deg); }\n 100% { transform: translateY(-50%) rotate(360deg); }\n}\n\n/* Ping Animation */\n.ping-animation {\n position: absolute;\n display: flex;\n width: 12px;\n height: 12px;\n top: 0;\n right: 0;\n}\n\n.ping-circle {\n position: absolute;\n display: inline-flex;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n background-color: #38BDF8;\n opacity: 0.75;\n animation: ping 1.5s cubic-bezier(0, 0, 0.2, 1) infinite;\n}\n\n.ping-dot {\n position: relative;\n display: inline-flex;\n width: 12px;\n height: 12px;\n border-radius: 50%;\n background-color: #0EA5E9;\n}\n\n@keyframes ping {\n 75%, 100% {\n transform: scale(2);\n opacity: 0;\n }\n}\n\n/* Instruction hover effects */\n.instruction-item:hover .instruction-delete-btn {\n display: flex !important;\n}\n\n/* Add some subtle animations */\n@keyframes fadeIn {\n from { opacity: 0; transform: translateY(20px); }\n to { opacity: 1; transform: translateY(0); }\n}\n\n/* Better center alignment for the recipe card */\n.recipe-card-container {\n display: flex;\n justify-content: center;\n width: 100%;\n position: relative;\n z-index: 1;\n margin: 0 auto;\n box-sizing: border-box;\n}\n\n/* Add Buttons */\n.add-button {\n background-color: transparent;\n color: #FF5722;\n border: 1px dashed #FF5722;\n border-radius: 8px;\n padding: 10px 16px;\n cursor: pointer;\n font-weight: 500;\n display: inline-block;\n font-size: 14px;\n margin-bottom: 0;\n}\n\n.add-step-button {\n background-color: transparent;\n color: #FF5722;\n border: 1px dashed #FF5722;\n border-radius: 6px;\n padding: 6px 12px;\n cursor: pointer;\n font-weight: 500;\n font-size: 13px;\n}\n\n/* Section Headers */\n.section-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 12px;\n}", + "language": "css", + "type": "file" + }, + { + "name": "README.mdx", + "content": "# 🍳 Shared State Recipe Creator\n\n## What This Demo Shows\n\nThis demo showcases CopilotKit's **shared state** functionality - a powerful\nfeature that enables bidirectional data flow between:\n\n1. **Frontend → Agent**: UI controls update the agent's context in real-time\n2. **Agent → Frontend**: The Copilot's recipe creations instantly update the UI\n components\n\nIt's like having a cooking buddy who not only listens to what you want but also\nupdates your recipe card as you chat - no refresh needed! ✨\n\n## How to Interact\n\nMix and match any of these parameters (or none at all - it's up to you!):\n\n- **Skill Level**: Beginner to expert 👨‍🍳\n- **Cooking Time**: Quick meals or slow cooking ⏱️\n- **Special Preferences**: Dietary needs, flavor profiles, health goals 🥗\n- **Ingredients**: Items you want to include 🧅🥩🍄\n- **Instructions**: Any specific steps\n\nThen chat with your Copilot chef with prompts like:\n\n- \"I'm a beginner cook. Can you make me a quick dinner?\"\n- \"I need something spicy with chicken that takes under 30 minutes!\"\n\n## ✨ Shared State Magic in Action\n\n**What's happening technically:**\n\n- The UI and Copilot agent share the same state object (**Agent State = UI\n State**)\n- Changes from either side automatically update the other\n- Neither side needs to manually request updates from the other\n\n**What you'll see in this demo:**\n\n- Set cooking time to 20 minutes in the UI and watch the Copilot immediately\n respect your time constraint\n- Add ingredients through the UI and see them appear in your recipe\n- When the Copilot suggests new ingredients, watch them automatically appear in\n the UI ingredients list\n- Change your skill level and see how the Copilot adapts its instructions in\n real-time\n\nThis synchronized state creates a seamless experience where the agent always has\nyour current preferences, and any updates to the recipe are instantly reflected\nin both places.\n\nThis shared state pattern can be applied to any application where you want your\nUI and Copilot to work together in perfect harmony!\n", + "language": "markdown", + "type": "file" + }, + { + "name": "agent.ts", + "content": "/**\n * Shared State Agent using Cloudflare Workers AI\n *\n * This agent demonstrates persistent state management across multiple\n * messages in a conversation.\n *\n * Example: Maintaining a to-do list that persists across the conversation,\n * allowing the user to add, remove, or modify items over multiple turns.\n *\n * Features:\n * - STATE_SNAPSHOT events for persistent state\n * - STATE_DELTA events for incremental updates\n * - Cross-message state continuity\n */\n\nimport { CloudflareAgent, CLOUDFLARE_MODELS } from \"@ag-ui/cloudflare\";\nimport { Observable, Subscriber } from \"rxjs\";\nimport type { RunAgentInput, BaseEvent } from \"@ag-ui/client\";\nimport { EventType, type StateSnapshotEvent } from \"@ag-ui/core\";\n\n/**\n * Shared State Agent\n *\n * Maintains a shared to-do list state that persists across the conversation.\n * Users can ask to add, remove, or modify items in the list.\n */\nexport class SharedStateAgent extends CloudflareAgent {\n constructor() {\n const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;\n const apiToken = process.env.CLOUDFLARE_API_TOKEN;\n\n if (!accountId || !apiToken) {\n throw new Error(\n \"Missing required environment variables: CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN\"\n );\n }\n\n super({\n accountId,\n apiToken,\n model: CLOUDFLARE_MODELS.LLAMA_3_1_8B,\n systemPrompt: `You are a helpful assistant that manages a to-do list.\n\nThe user can ask you to:\n- Add items to the list\n- Remove items from the list\n- Mark items as complete/incomplete\n- View the current list\n\nAlways acknowledge what you've done and show the updated list state.\nBe conversational and helpful.`,\n streamingEnabled: true,\n });\n }\n\n /**\n * Override run() to manage state across messages\n */\n run(input: RunAgentInput): Observable {\n return new Observable((subscriber) => {\n this.executeRunWithSharedState(input, subscriber)\n .catch((error) => {\n console.error(\"SharedStateAgent execution error:\", error);\n subscriber.error(error);\n })\n .finally(() => {\n subscriber.complete();\n });\n });\n }\n\n /**\n * Enhanced execution with shared state management\n */\n private async executeRunWithSharedState(\n input: RunAgentInput,\n subscriber: Subscriber\n ): Promise {\n // Extract current state from input if available\n const currentState = input.state || { todos: [] };\n\n // Execute the base run\n await this.executeRun(input, subscriber);\n\n // Emit state snapshot to maintain state across messages\n // In a real implementation, you would parse the response and update the state\n const stateSnapshot: StateSnapshotEvent = {\n type: EventType.STATE_SNAPSHOT,\n snapshot: currentState,\n timestamp: Date.now(),\n };\n subscriber.next(stateSnapshot);\n }\n}\n\n// Lazy singleton\nlet _sharedStateAgent: SharedStateAgent | null = null;\n\nexport function getSharedStateAgent(): SharedStateAgent {\n if (!_sharedStateAgent) {\n _sharedStateAgent = new SharedStateAgent();\n }\n return _sharedStateAgent;\n}\n", + "language": "ts", + "type": "file" + } + ], + "cloudflare::backend_tool_rendering": [ + { + "name": "page.tsx", + "content": "\"use client\";\nimport React from \"react\";\nimport \"@copilotkit/react-ui/styles.css\";\nimport \"./style.css\";\nimport { CopilotKit, useCopilotAction } from \"@copilotkit/react-core\";\nimport { CopilotChat } from \"@copilotkit/react-ui\";\n\ninterface AgenticChatProps {\n params: Promise<{\n integrationId: string;\n }>;\n}\n\nconst AgenticChat: React.FC = ({ params }) => {\n const { integrationId } = React.use(params);\n\n return (\n \n \n \n );\n};\n\nconst Chat = () => {\n useCopilotAction({\n name: \"get_weather\",\n available: \"disabled\",\n parameters: [{ name: \"location\", type: \"string\", required: true }],\n render: ({ args, result, status }) => {\n if (status !== \"complete\") {\n return (\n
\n ⚙️ Retrieving weather...\n
\n );\n }\n\n const weatherResult: WeatherToolResult = {\n temperature: result?.temperature || 0,\n conditions: result?.conditions || \"clear\",\n humidity: result?.humidity || 0,\n windSpeed: result?.wind_speed || 0,\n feelsLike: result?.feels_like || result?.temperature || 0,\n };\n\n const themeColor = getThemeColor(weatherResult.conditions);\n\n return (\n \n );\n },\n });\n\n return (\n
\n
\n \n
\n
\n );\n};\n\ninterface WeatherToolResult {\n temperature: number;\n conditions: string;\n humidity: number;\n windSpeed: number;\n feelsLike: number;\n}\n\nfunction getThemeColor(conditions: string): string {\n const conditionLower = conditions.toLowerCase();\n if (conditionLower.includes(\"clear\") || conditionLower.includes(\"sunny\")) {\n return \"#667eea\";\n }\n if (conditionLower.includes(\"rain\") || conditionLower.includes(\"storm\")) {\n return \"#4A5568\";\n }\n if (conditionLower.includes(\"cloud\")) {\n return \"#718096\";\n }\n if (conditionLower.includes(\"snow\")) {\n return \"#63B3ED\";\n }\n return \"#764ba2\";\n}\n\nfunction WeatherCard({\n location,\n themeColor,\n result,\n status,\n}: {\n location?: string;\n themeColor: string;\n result: WeatherToolResult;\n status: \"inProgress\" | \"executing\" | \"complete\";\n}) {\n return (\n \n
\n
\n
\n

\n {location}\n

\n

Current Weather

\n
\n \n
\n\n
\n
\n {result.temperature}° C\n \n {\" / \"}\n {((result.temperature * 9) / 5 + 32).toFixed(1)}° F\n \n
\n
{result.conditions}
\n
\n\n
\n
\n
\n

Humidity

\n

{result.humidity}%

\n
\n
\n

Wind

\n

{result.windSpeed} mph

\n
\n
\n

Feels Like

\n

{result.feelsLike}°

\n
\n
\n
\n
\n
\n );\n}\n\nfunction WeatherIcon({ conditions }: { conditions: string }) {\n if (!conditions) return null;\n\n if (conditions.toLowerCase().includes(\"clear\") || conditions.toLowerCase().includes(\"sunny\")) {\n return ;\n }\n\n if (\n conditions.toLowerCase().includes(\"rain\") ||\n conditions.toLowerCase().includes(\"drizzle\") ||\n conditions.toLowerCase().includes(\"snow\") ||\n conditions.toLowerCase().includes(\"thunderstorm\")\n ) {\n return ;\n }\n\n if (\n conditions.toLowerCase().includes(\"fog\") ||\n conditions.toLowerCase().includes(\"cloud\") ||\n conditions.toLowerCase().includes(\"overcast\")\n ) {\n return ;\n }\n\n return ;\n}\n\n// Simple sun icon for the weather card\nfunction SunIcon() {\n return (\n \n \n \n \n );\n}\n\nfunction RainIcon() {\n return (\n \n {/* Cloud */}\n \n {/* Rain drops */}\n \n \n );\n}\n\nfunction CloudIcon() {\n return (\n \n \n \n );\n}\n\nexport default AgenticChat;\n", + "language": "typescript", + "type": "file" + }, + { + "name": "style.css", + "content": ".copilotKitInput {\n border-bottom-left-radius: 0.75rem;\n border-bottom-right-radius: 0.75rem;\n border-top-left-radius: 0.75rem;\n border-top-right-radius: 0.75rem;\n border: 1px solid var(--copilot-kit-separator-color) !important;\n}\n\n.copilotKitChat {\n background-color: #fff !important;\n}\n", + "language": "css", + "type": "file" + }, + { + "name": "README.mdx", + "content": "# 🤖 Agentic Chat with Frontend Tools\n\n## What This Demo Shows\n\nThis demo showcases CopilotKit's **agentic chat** capabilities with **frontend\ntool integration**:\n\n1. **Natural Conversation**: Chat with your Copilot in a familiar chat interface\n2. **Frontend Tool Execution**: The Copilot can directly interacts with your UI\n by calling frontend functions\n3. **Seamless Integration**: Tools defined in the frontend and automatically\n discovered and made available to the agent\n\n## How to Interact\n\nTry asking your Copilot to:\n\n- \"Can you change the background color to something more vibrant?\"\n- \"Make the background a blue to purple gradient\"\n- \"Set the background to a sunset-themed gradient\"\n- \"Change it back to a simple light color\"\n\nYou can also chat about other topics - the agent will respond conversationally\nwhile having the ability to use your UI tools when appropriate.\n\n## ✨ Frontend Tool Integration in Action\n\n**What's happening technically:**\n\n- The React component defines a frontend function using `useCopilotAction`\n- CopilotKit automatically exposes this function to the agent\n- When you make a request, the agent determines whether to use the tool\n- The agent calls the function with the appropriate parameters\n- The UI immediately updates in response\n\n**What you'll see in this demo:**\n\n- The Copilot understands requests to change the background\n- It generates CSS values for colors and gradients\n- When it calls the tool, the background changes instantly\n- The agent provides a conversational response about the changes it made\n\nThis technique of exposing frontend functions to your Copilot can be extended to\nany UI manipulation you want to enable, from theme changes to data filtering,\nnavigation, or complex UI state management!\n", + "language": "markdown", + "type": "file" + }, + { + "name": "agent.ts", + "content": "/**\n * Backend Tool Rendering Agent using Cloudflare Workers AI\n *\n * This agent demonstrates how the backend can generate and return\n * React components that the frontend will render.\n *\n * Example: Generating a weather widget with custom styling and data\n * that the frontend renders as a React component.\n *\n * Features:\n * - Backend-generated UI components\n * - TOOL_RESULT events with render prop\n * - Rich, interactive UI elements\n */\n\nimport { CloudflareAgent, CLOUDFLARE_MODELS } from \"@ag-ui/cloudflare\";\n\n/**\n * Backend Tool Rendering Agent\n *\n * An assistant that can generate React components on the backend\n * for the frontend to render.\n */\nexport class BackendToolRenderingAgent extends CloudflareAgent {\n constructor() {\n const accountId = process.env.CLOUDFLARE_ACCOUNT_ID;\n const apiToken = process.env.CLOUDFLARE_API_TOKEN;\n\n if (!accountId || !apiToken) {\n throw new Error(\n \"Missing required environment variables: CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN\"\n );\n }\n\n super({\n accountId,\n apiToken,\n model: CLOUDFLARE_MODELS.LLAMA_3_3_70B_FP8, // Using function-calling capable model\n systemPrompt: `You are a helpful assistant with access to various tools.\n\nWhen the user asks for information or actions that can be enhanced with rich UI:\n- Use the available tools when appropriate\n- The frontend will render custom components for tool results\n- Be conversational and explain what you're doing\n\nAvailable capabilities:\n- show_weather: Display weather information in a rich UI card\n- show_stock: Display stock prices with charts\n- show_calendar: Display calendar events\n\nIMPORTANT: Only use tools when the user explicitly asks for them or when they would enhance the response.\nDo NOT call tools for simple greetings or general questions.`,\n streamingEnabled: true,\n });\n }\n}\n\n// Lazy singleton\nlet _backendToolRenderingAgent: BackendToolRenderingAgent | null = null;\n\nexport function getBackendToolRenderingAgent(): BackendToolRenderingAgent {\n if (!_backendToolRenderingAgent) {\n _backendToolRenderingAgent = new BackendToolRenderingAgent();\n }\n return _backendToolRenderingAgent;\n}\n", + "language": "ts", + "type": "file" + } ] } \ No newline at end of file diff --git a/apps/dojo/src/menu.ts b/apps/dojo/src/menu.ts index 25d02f283..b8b9fb695 100644 --- a/apps/dojo/src/menu.ts +++ b/apps/dojo/src/menu.ts @@ -155,6 +155,27 @@ export const menuIntegrations: MenuIntegrationConfig[] = [ "tool_based_generative_ui", ], }, + { + id: "cloudflare", + name: "Cloudflare Workers AI", + features: [ + "agentic_chat", + "tool_based_generative_ui", + "agentic_generative_ui", + "human_in_the_loop", + "shared_state", + "backend_tool_rendering", + ], + }, + { + id: "cloudflare-agents-sdk", + name: "Cloudflare Agents SDK", + features: [ + "tool_based_generative_ui", + // Note: human_in_the_loop not included - incompatible with CopilotKit's action system + // See integrations/cloudflare/HITL-LIMITATIONS.md for details + ], + }, { id: "a2a", name: "A2A", diff --git a/integrations/cloudflare/.gitignore b/integrations/cloudflare/.gitignore new file mode 100644 index 000000000..b39fdd479 --- /dev/null +++ b/integrations/cloudflare/.gitignore @@ -0,0 +1,8 @@ +node_modules +dist +*.log +.env +.DS_Store + +# Development guides (context for AI assistants) +DEVELOPMENT-GUIDE.md diff --git a/integrations/cloudflare/README.md b/integrations/cloudflare/README.md new file mode 100644 index 000000000..239a6ee3d --- /dev/null +++ b/integrations/cloudflare/README.md @@ -0,0 +1,323 @@ +# Cloudflare AG-UI Integration + +AG-UI protocol support for **Cloudflare Workers AI** and **Cloudflare Agents SDK**. + +## Overview + +This package (`@ag-ui/cloudflare`) provides two integration paths: + +1. **Cloudflare Workers AI** - Direct AI model inference +2. **Cloudflare Agents SDK** - Stateful agent framework with Durable Objects + +## Installation + +```bash +npm install @ag-ui/cloudflare +``` + +## Deployment Options + +### Option 1: Local Development (HTTP/Express) + +Perfect for testing and development. Runs agents on Express server with HTTP endpoints. + +**What you get:** +- ✅ Easy local testing +- ✅ HTTP-based communication +- ✅ All AG-UI protocol features +- ❌ No WebSocket state sync +- ❌ No Durable Objects persistence + +**Example:** See `integrations/cloudflare/typescript/examples` (used by Dojo demo) + +### Option 2: Production (Cloudflare Workers) + +Full Cloudflare-native deployment with all platform features. + +**What you get:** +- ✅ WebSocket state synchronization +- ✅ Durable Objects persistence +- ✅ Native `useAgent` / `useAgentChat` React hooks +- ✅ Cloudflare edge network +- ✅ Automatic scaling + +**Requirements:** +- Cloudflare Workers account +- Durable Objects binding configured +- Deploy to Cloudflare Workers + +**Package exports for Workers:** +```typescript +import { + // Workers infrastructure + handleCloudflareWorker, + createCloudflareWorkerHandler, + handleWebSocketConnection, + + // Agents SDK for Workers + CloudflareAgentsSDKAdapter, + createAgentsSDKWorkerHandler, + + // Utilities + isWebSocketUpgrade, + getClientIP, + // ... more utilities +} from '@ag-ui/cloudflare'; +``` + +## Quick Start + +### Local Development Setup + +```bash +cd integrations/cloudflare/typescript/examples +pnpm install + +# Create .env +echo "CLOUDFLARE_ACCOUNT_ID=your_account_id" >> .env +echo "CLOUDFLARE_API_TOKEN=your_api_token" >> .env + +pnpm start +``` + +Server runs on `http://localhost:4114` + +### Production Workers Deployment + +```typescript +// worker.ts +import { + createCloudflareWorkerHandler, + createAgentsSDKWorkerHandler +} from '@ag-ui/cloudflare'; + +export default { + async fetch(request: Request, env: Env) { + // Your agent implementation + const agent = new MyAgent(); + + // Create AG-UI compatible handler + const handler = createAgentsSDKWorkerHandler({ + agent, + syncState: true, + trackSQL: true + }); + + return handler(request, env); + } +}; +``` + +Configure `wrangler.toml`: +```toml +name = "my-agent" +main = "worker.ts" + +[[durable_objects.bindings]] +name = "AGENT" +class_name = "MyAgent" +``` + +## Available Agents + +### Workers AI Agents + +Direct model inference - available via HTTP endpoints for npm package users: + +| Agent | Description | Model | In Dojo Demo | +|-------|-------------|-------|--------------| +| `agentic_chat` | Basic conversational AI | Llama 3.1 8B | ✅ Yes | +| `tool_based_generative_ui` | UI generation with tools | Llama 3.3 70B FP8 | ✅ Yes | +| `backend_tool_rendering` | Backend-generated UI | Llama 3.3 70B FP8 | ❌ No* | +| `agentic_generative_ui` | Progressive UI updates | Llama 3.1 8B | ❌ No* | +| `shared_state` | Persistent state management | Llama 3.1 8B | ❌ No* | +| `human_in_the_loop` | Human approval workflow | Hermes 2 Pro 7B | ❌ No* | + +*Not shown in Dojo demo - requires frontend tools that aren't sent due to CopilotKit limitations + +### Agents SDK Agents + +Framework-based agents using Cloudflare Agents SDK: + +| Agent | Description | In Dojo Demo | Full Features | +|-------|-------------|--------------|---------------| +| `tool_based_generative_ui_sdk` | Haiku generation with UI | ✅ Yes | Works locally | +| `human_in_the_loop_sdk` | Human approval workflow | ❌ No* | Requires Workers** | + +*Not compatible with CopilotKit's action system - see `HITL-LIMITATIONS.md` for details +**Full Agents SDK features (WebSocket state sync, Durable Objects) only available when deployed to Cloudflare Workers + +## Usage Examples + +### Workers AI (Works Everywhere) + +```typescript +import { CloudflareAgent, CLOUDFLARE_MODELS } from '@ag-ui/cloudflare'; + +const agent = new CloudflareAgent({ + accountId: process.env.CLOUDFLARE_ACCOUNT_ID!, + apiToken: process.env.CLOUDFLARE_API_TOKEN!, + model: CLOUDFLARE_MODELS.LLAMA_3_1_8B, + streamingEnabled: true +}); + +agent.run({ + threadId: 'thread-1', + runId: 'run-1', + messages: [{ role: 'user', content: 'Hello!' }] +}).subscribe(event => { + console.log(event); +}); +``` + +### Agents SDK (Local/Testing) + +```typescript +import { CloudflareAgentsSDKAdapter } from '@ag-ui/cloudflare'; + +class MyAgent { + async *onChatMessage(message: string, context: any) { + yield "Processing..."; + + // Emit interrupt for approval + yield { + type: "interrupt", + interrupt: { + name: "requiresApproval", + value: { action: "delete_user" } + } + }; + } +} + +const adapter = new CloudflareAgentsSDKAdapter({ + agent: new MyAgent(), + syncState: false, // No state sync in local mode + threadId: 'thread-123' // Optional: provide threadId for conversation tracking +}); + +// Pass threadId in context to ensure it flows through all events +const context = { threadId: 'thread-123', runId: 'run-456' }; +for await (const event of adapter.execute(messages, context)) { + console.log(event); // All events will include threadId +} +``` + +### Agents SDK (Production Workers) + +```typescript +import { Agent } from 'agents'; // Cloudflare's agents package +import { createAgentsSDKWorkerHandler } from '@ag-ui/cloudflare'; + +export class MyAgent extends Agent { + async *onChatMessage(message: string, context: any) { + // Full state management + await this.setState({ counter: this.state.counter + 1 }); + + // SQL queries + const users = await this.sql`SELECT * FROM users`; + + // Scheduling + await this.schedule('1 hour', 'cleanup', {}); + + yield `Processed ${this.state.counter} messages`; + } +} + +// AG-UI compatible handler +export default createAgentsSDKWorkerHandler(MyAgent); +``` + +## Available Models + +```typescript +import { CLOUDFLARE_MODELS } from '@ag-ui/cloudflare'; + +// Function-calling capable (for tool-based agents) +CLOUDFLARE_MODELS.LLAMA_3_3_70B_FP8 // Best for tools +CLOUDFLARE_MODELS.LLAMA_4_SCOUT_17B // Good for tools +CLOUDFLARE_MODELS.MISTRAL_SMALL_24B // Good for tools + +// General chat (smaller, faster) +CLOUDFLARE_MODELS.LLAMA_3_1_8B // Best for chat +CLOUDFLARE_MODELS.LLAMA_3_1_70B // More capable +CLOUDFLARE_MODELS.HERMES_2_PRO_7B // Good for chat +``` + +## Architecture + +### Local Development Flow +``` +Client → Express → CloudflareAgent → Workers AI API → AG-UI Events +Client → Express → AgentsSDKAdapter → Agent.onChatMessage() → AG-UI Events +``` + +### Production Workers Flow +``` +Client → Cloudflare Workers → Durable Objects → AG-UI Events + ↓ + WebSocket State Sync + ↓ + React useAgent Hook +``` + +## Testing + +```bash +# Test Workers AI +curl -X POST http://localhost:4114/agentic_chat \ + -H "Content-Type: application/json" \ + -H "x-thread-id: thread-123" \ + -d '{"messages":[{"role":"user","content":"Hello"}]}' + +# Test Agents SDK +curl -X POST http://localhost:4114/tool_based_generative_ui_sdk \ + -H "Content-Type: application/json" \ + -H "x-thread-id: thread-123" \ + -d '{"messages":[{"role":"user","content":"Write a haiku"}]}' +``` + +### ThreadId Handling + +All agents properly handle `threadId` for conversation tracking: +- Accept `threadId` via `x-thread-id` header or request body +- Generate unique `threadId` if not provided +- Echo `threadId` in every SSE event for Dojo/CopilotKit compatibility + +See `THREAD-ISSUE.md` for detailed implementation notes. + +## Dojo Integration + +The Dojo demo app uses the local development setup with two menu entries: + +- **Cloudflare Workers AI** - Direct model inference agents +- **Cloudflare Agents SDK** - Framework-based agents + +Both point to `http://localhost:4114` running on Express. + +## Project Structure + +``` +integrations/cloudflare/typescript/ +├── src/ # NPM package source +│ ├── cloudflare-agent.ts # Workers AI client +│ ├── agents-sdk-adapter.ts # Agents SDK adapter +│ ├── workers-adapter.ts # Cloudflare Workers utilities +│ ├── cloudflare-utils.ts # WebSocket & request utilities +│ └── index.ts # Public API +└── examples/ # Local development examples + └── src/ + ├── agents/ # Example agents + └── index.ts # Express server +``` + +## Learn More + +- [Cloudflare Workers AI Docs](https://developers.cloudflare.com/workers-ai/) +- [Cloudflare Agents SDK Docs](https://developers.cloudflare.com/agents/) +- [AG-UI Protocol Spec](https://github.com/CopilotKit/CopilotKit/tree/main/sdks/ag-ui) +- [Durable Objects Guide](https://developers.cloudflare.com/durable-objects/) + +## License + +MIT diff --git a/integrations/cloudflare/typescript/.npmignore b/integrations/cloudflare/typescript/.npmignore new file mode 100644 index 000000000..8d810b090 --- /dev/null +++ b/integrations/cloudflare/typescript/.npmignore @@ -0,0 +1,8 @@ +src/ +examples/ +tsconfig.json +tsup.config.ts +jest.config.js +*.test.ts +*.spec.ts +__tests__/ diff --git a/integrations/cloudflare/typescript/README.md b/integrations/cloudflare/typescript/README.md new file mode 100644 index 000000000..80032a219 --- /dev/null +++ b/integrations/cloudflare/typescript/README.md @@ -0,0 +1,483 @@ +# @ag-ui/cloudflare + +Implementation of the AG-UI protocol for Cloudflare. + +Connects Cloudflare Workers AI models and Agents SDK to frontend applications via the AG-UI protocol. Supports streaming responses, tool calling, edge deployment, and stateful agent patterns with built-in state management and SQL. + +## Installation + +```bash +npm install @ag-ui/cloudflare +pnpm add @ag-ui/cloudflare +yarn add @ag-ui/cloudflare +``` + +## Usage + +### Workers AI Models + +```ts +import { CloudflareAgent } from "@ag-ui/cloudflare"; + +// Create an AG-UI compatible agent +const agent = new CloudflareAgent({ + accountId: process.env.CLOUDFLARE_ACCOUNT_ID, + apiToken: process.env.CLOUDFLARE_API_TOKEN, + model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast", + systemPrompt: "You are a helpful assistant.", +}); + +// Run with streaming +const observable = agent.run({ + threadId: "thread-1", + runId: "run-1", + messages: [{ role: "user", content: "Hello!" }], + tools: [], + context: [], + state: {}, + forwardedProps: {}, +}); + +observable.subscribe({ + next: (event) => console.log(event.type, event), + error: (error) => console.error(error), + complete: () => console.log("Complete"), +}); +``` + +### With Tool Calling + +```ts +import { CloudflareAgent, supportsToolCalling } from "@ag-ui/cloudflare"; + +const tools = [ + { + name: "get_weather", + description: "Get current weather for a location", + parameters: { + type: "object", + properties: { + location: { type: "string", description: "City name" }, + }, + required: ["location"], + }, + }, +]; + +const agent = new CloudflareAgent({ + accountId: process.env.CLOUDFLARE_ACCOUNT_ID, + apiToken: process.env.CLOUDFLARE_API_TOKEN, + model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast", // Supports tools +}); + +const observable = agent.run({ + threadId: "weather-1", + runId: "run-1", + messages: [{ role: "user", content: "What's the weather in Tokyo?" }], + tools, + context: [], + state: {}, + forwardedProps: {}, +}); +``` + +### CopilotKit Integration + +```ts +import { CloudflareAGUIAdapter } from "@ag-ui/cloudflare"; +import { CopilotRuntime } from "@copilotkit/runtime"; + +const adapter = new CloudflareAGUIAdapter({ + accountId: process.env.CLOUDFLARE_ACCOUNT_ID, + apiToken: process.env.CLOUDFLARE_API_TOKEN, + model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast", +}); + +// Use as CopilotKit service adapter +const runtime = new CopilotRuntime(); +const response = await runtime.process({ + messages, + adapter, +}); +``` + +### Cloudflare Agents SDK + +```ts +import { Agent } from "agents"; +import { createAgentsSDKAdapter } from "@ag-ui/cloudflare"; + +export class ChatAgent extends Agent { + async *onChatMessage(message: string) { + // Built-in state management + await this.setState({ thinking: true }); + + // Built-in SQL database + await this.sql`INSERT INTO history VALUES (${message})`; + + // Stream response + yield "Processing: " + message; + } +} + +// Wrap with AG-UI protocol +const agent = new ChatAgent(state, env); +const adapter = createAgentsSDKAdapter(agent, { syncState: true }); + +// Emits AG-UI events +for await (const event of adapter.execute(messages)) { + console.log(event.type, event); +} +``` + +## Available Models + +### Tool-Calling Capable + +- `@cf/meta/llama-3.3-70b-instruct-fp8-fast` – Llama 3.3 70B (fast, function calling) +- `@cf/meta/llama-4-scout-17b-16e-instruct` – Llama 4 Scout 17B (latest, function calling) +- `@cf/mistralai/mistral-small-3.1-24b-instruct` – Mistral Small 24B (function calling) +- `@cf/nousresearch/hermes-2-pro-mistral-7b` – Hermes 2 Pro 7B (function calling) + +### General Purpose + +- `@cf/meta/llama-3.1-8b-instruct` – Llama 3.1 8B (fast, general purpose) +- `@cf/meta/llama-3.1-70b-instruct` – Llama 3.1 70B (large, general purpose) +- `@cf/mistral/mistral-7b-instruct-v0.2` – Mistral 7B (fast, general purpose) + +Check model capabilities: + +```ts +import { supportsToolCalling } from "@ag-ui/cloudflare"; + +if (supportsToolCalling(model)) { + console.log("Model supports tool calling"); +} +``` + +## Features + +- **Workers AI integration** – Access to LLM models running on Cloudflare's edge network +- **Tool calling support** – Function calling with automatic capability detection and validation +- **Streaming responses** – Real-time SSE streaming with proper tool call accumulation +- **CopilotKit compatible** – Drop-in replacement for CopilotKit service adapters +- **Retry logic** – Exponential backoff with jitter for failed requests +- **Type safe** – Full TypeScript support with Zod validation +- **Input validation** – Configuration validated at instantiation with clear error messages +- **Enhanced logging** – Structured error logs with full context (threadId, runId, stack traces) +- **Agents SDK support** – Integration with Cloudflare Agents SDK for stateful agents +- **AI Gateway** – Optional routing through Cloudflare AI Gateway for caching and analytics + +## Configuration + +### Environment Variables + +```bash +CLOUDFLARE_ACCOUNT_ID=your-account-id +CLOUDFLARE_API_TOKEN=your-api-token +``` + +### Agent Options + +```ts +interface CloudflareAgentConfig { + accountId: string; // Required: Cloudflare account ID + apiToken: string; // Required: Cloudflare API token + model?: string; // Optional: Defaults to Llama 3.1 8B + systemPrompt?: string; // Optional: System instructions + streamingEnabled?: boolean; // Optional: Defaults to true + baseURL?: string; // Optional: Custom API endpoint + gatewayId?: string; // Optional: AI Gateway ID for routing +} +``` + +### With AI Gateway + +```ts +const agent = new CloudflareAgent({ + accountId: process.env.CLOUDFLARE_ACCOUNT_ID, + apiToken: process.env.CLOUDFLARE_API_TOKEN, + gatewayId: "my-gateway-id", // Route through AI Gateway + model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast", +}); +``` + +### Custom Retry Configuration + +```ts +import { CloudflareAIClient } from "@ag-ui/cloudflare"; + +const client = new CloudflareAIClient( + { + accountId: process.env.CLOUDFLARE_ACCOUNT_ID, + apiToken: process.env.CLOUDFLARE_API_TOKEN, + }, + { + maxRetries: 5, // Retry up to 5 times + baseDelay: 2000, // Start with 2 second delay + maxDelay: 30000, // Max 30 second delay + retryableStatusCodes: [408, 429, 500, 502, 503, 504], + } +); +``` + +## Express.js Integration + +```ts +import express from "express"; +import { CloudflareAgent } from "@ag-ui/cloudflare"; + +const app = express(); +app.use(express.json()); + +app.post("/api/chat", async (req, res) => { + const { messages, threadId } = req.body; + + // Set SSE headers + res.setHeader("Content-Type", "text/event-stream"); + res.setHeader("Cache-Control", "no-cache"); + res.setHeader("Connection", "keep-alive"); + + const agent = new CloudflareAgent({ + accountId: process.env.CLOUDFLARE_ACCOUNT_ID, + apiToken: process.env.CLOUDFLARE_API_TOKEN, + model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast", + }); + + const observable = agent.run({ + threadId: threadId || `thread-${Date.now()}`, + runId: `run-${Date.now()}`, + messages, + tools: [], + context: [], + state: {}, + forwardedProps: {}, + }); + + const subscription = observable.subscribe({ + next: (event) => { + res.write(`event: ${event.type}\n`); + res.write(`data: ${JSON.stringify(event)}\n\n`); + }, + error: (error) => { + res.write(`event: ERROR\ndata: ${JSON.stringify({ error: error.message })}\n\n`); + res.end(); + }, + complete: () => res.end(), + }); + + req.on("close", () => subscription.unsubscribe()); +}); + +app.listen(3000); +``` + +## Cloudflare Workers Deployment + +```ts +import { CloudflareAgent } from "@ag-ui/cloudflare"; + +export default { + async fetch(request: Request, env: Env): Promise { + const { messages } = await request.json(); + + const agent = new CloudflareAgent({ + accountId: env.CLOUDFLARE_ACCOUNT_ID, + apiToken: env.CLOUDFLARE_API_TOKEN, + model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast", + }); + + const { readable, writable } = new TransformStream(); + const writer = writable.getWriter(); + const encoder = new TextEncoder(); + + (async () => { + const observable = agent.run({ + threadId: `thread-${Date.now()}`, + runId: `run-${Date.now()}`, + messages, + tools: [], + context: [], + state: {}, + forwardedProps: {}, + }); + + observable.subscribe({ + next: async (event) => { + await writer.write( + encoder.encode(`event: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`) + ); + }, + complete: async () => await writer.close(), + }); + })(); + + return new Response(readable, { + headers: { + "Content-Type": "text/event-stream", + "Cache-Control": "no-cache", + }, + }); + }, +}; +``` + +## Error Handling + +Configuration is validated automatically: + +```ts +try { + const agent = new CloudflareAgent({ + accountId: process.env.CLOUDFLARE_ACCOUNT_ID, + apiToken: process.env.CLOUDFLARE_API_TOKEN, + model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast", + }); +} catch (error) { + // Configuration validation errors + console.error("Invalid configuration:", error.message); + // Example: "Invalid accountId: Account ID is required" +} +``` + +Enhanced error logging provides full context: + +```ts +observable.subscribe({ + error: (error) => { + // Error logs automatically include: + // - threadId, runId + // - Stack trace + // - Timestamp + console.error("Error:", error); + }, +}); +``` + +## Tool Capability Warnings + +The agent automatically validates model capabilities: + +```ts +const agent = new CloudflareAgent({ + accountId: process.env.CLOUDFLARE_ACCOUNT_ID, + apiToken: process.env.CLOUDFLARE_API_TOKEN, + model: "@cf/meta/llama-3.1-8b-instruct", // Doesn't support tools +}); + +// When tools are provided, you'll see a warning: +// [CloudflareAgent] Model "..." does not support tool calling. +// Tools will be ignored. Use a compatible model like: ... +``` + +## Migration from OpenAI + +```ts +// Before (OpenAI) +import OpenAI from "openai"; +const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY }); + +// After (Cloudflare) +import { CloudflareAgent } from "@ag-ui/cloudflare"; +const agent = new CloudflareAgent({ + accountId: process.env.CLOUDFLARE_ACCOUNT_ID, + apiToken: process.env.CLOUDFLARE_API_TOKEN, + model: "@cf/meta/llama-3.3-70b-instruct-fp8-fast", +}); +``` + +## Running Examples in the AG-UI Dojo + +The Cloudflare integration includes 6 example agents that run in the AG-UI Dojo demo viewer. + +### Quick Start (Run All Demos) + +From the repository root: + +```bash +cd apps/dojo +pnpm run-everything +``` + +This starts all integrations including Cloudflare on `http://localhost:4114` and the dojo on `http://localhost:9999`. + +### Run Only Cloudflare + Dojo + +To run just the Cloudflare demos: + +```bash +cd apps/dojo +node ./scripts/prep-dojo-everything.js --only cloudflare,dojo +node ./scripts/run-dojo-everything.js --only cloudflare,dojo +``` + +Then visit `http://localhost:9999` and select **Cloudflare Workers AI** from the integration menu. + +### Available Demo Agents + +- **agentic_chat** – Basic conversational agent +- **agentic_generative_ui** – Progressive state updates with UI generation +- **backend_tool_rendering** – Backend-generated UI components +- **human_in_the_loop** – Human approval workflow +- **shared_state** – Persistent state management with todos +- **tool_based_generative_ui** – Frontend tool rendering (haiku generation) + +### Prerequisites + +1. Set up your Cloudflare credentials in `integrations/cloudflare/typescript/examples/.env`: + ```bash + CLOUDFLARE_ACCOUNT_ID=your_account_id + CLOUDFLARE_API_TOKEN=your_api_token + ``` + +2. Install dependencies (done automatically by `prep-dojo-everything.js`) + +## API Reference + +### CloudflareAgent + +Extends `AbstractAgent` from `@ag-ui/client`. + +```ts +class CloudflareAgent { + constructor(config: CloudflareAgentConfig); + run(input: RunAgentInput): Observable; +} +``` + +### CloudflareAGUIAdapter + +Implements `AGUIProtocol` and `CopilotServiceAdapter`. + +```ts +class CloudflareAGUIAdapter { + constructor(options: CloudflareAGUIAdapterOptions); + execute( + messages: CloudflareMessage[], + context?: Record + ): AsyncGenerator; + process( + request: CopilotRuntimeChatCompletionRequest + ): Promise; +} +``` + +### CloudflareAIClient + +Low-level client for Cloudflare Workers AI API. + +```ts +class CloudflareAIClient { + constructor(config: CloudflareAIConfig, retryOptions?: RetryOptions); + complete(options: CloudflareCompletionOptions): Promise; + streamComplete( + options: CloudflareCompletionOptions + ): AsyncGenerator; + listModels(): Promise; + getModelCapabilities(model: string): ModelCapabilities; +} +``` + +## License + +Apache-2.0 diff --git a/integrations/cloudflare/typescript/examples/README.md b/integrations/cloudflare/typescript/examples/README.md new file mode 100644 index 000000000..76e4d261c --- /dev/null +++ b/integrations/cloudflare/typescript/examples/README.md @@ -0,0 +1,209 @@ +# Cloudflare AG-UI Examples Server + +This server provides AG-UI endpoints using Cloudflare Workers AI models, demonstrating all major protocol features. + +## Quick Start + +1. Copy `.env.example` to `.env` and fill in your Cloudflare credentials: + + ```bash + cp .env.example .env + ``` + +2. Get your Cloudflare credentials: + - **Account ID**: Found in Cloudflare dashboard + - **API Token**: Create one at + - Use "Workers AI" template or create custom with "Workers AI:Read" permission + +3. Install dependencies: + + ```bash + pnpm install + ``` + +4. Run the server: + + ```bash + pnpm start + ``` + +5. Server runs on `http://localhost:4114` with 5 available agents + +## Available Agents + +### Core Demos + +#### `POST /agentic_chat` + +Basic conversational chat with streaming responses. + +- **Model**: Llama 3.1 8B Instruct +- **Features**: Text streaming, tool calling support +- **Use Case**: Standard chat interface, Q&A bot + +**Example Request**: + +```bash +curl -X POST http://localhost:4114/agentic_chat \ + -H "Content-Type: application/json" \ + -d '{ + "messages": [ + {"id": "1", "role": "user", "content": "Hello! Tell me about dogs."} + ] + }' +``` + +#### `POST /tool_based_generative_ui` + +Demonstrates frontend-provided tools with generative UI rendering. + +- **Model**: Llama 3.1 70B Instruct +- **Features**: Tool calling, custom UI components +- **Use Case**: Haiku generation, custom component rendering + +**Try It**: Ask "Write me a haiku about coding" to see the `generate_haiku` tool in action. + +#### `POST /agentic_generative_ui` + +Progressive state updates showing task execution steps. + +- **Model**: Llama 3.1 8B Instruct +- **Features**: STATE_SNAPSHOT events, step-by-step progress +- **Use Case**: Multi-step task planning, progress tracking + +**Try It**: Ask "How do I make a sandwich?" to see progressive task breakdown. + +### Advanced Demos + +#### `POST /human_in_the_loop` + +Interactive task planning requiring user confirmation before proceeding. + +- **Model**: Llama 3.1 8B Instruct +- **Features**: User approval workflows, task step selection +- **Use Case**: Critical operations requiring approval, guided workflows + +**Try It**: Ask "Plan a project for building a website" to get an interactive task list. + +#### `POST /shared_state` + +Persistent state management across multiple conversation turns. + +- **Model**: Llama 3.1 8B Instruct +- **Features**: STATE_SNAPSHOT/DELTA events, persistent to-do list +- **Use Case**: Shopping lists, task management, memory across sessions + +**Try It**: "Add milk to my list", then "What's on my list?" to see state persistence. + +#### `POST /backend_tool_rendering` + +Server-generated UI components sent to the frontend for rendering. + +- **Model**: Llama 3.1 8B Instruct +- **Features**: Backend-rendered components, TOOL_RESULT with render prop +- **Use Case**: Weather widgets, charts, rich data displays + +**Try It**: Ask about weather or stock prices to see rich UI components. + +## Testing with AG-UI Dojo + +The recommended way to test these agents is through the AG-UI Dojo: + +```bash +# Terminal 1: Run this examples server +cd integrations/cloudflare/typescript/examples +pnpm start + +# Terminal 2: Run the Dojo +cd apps/dojo +pnpm dev + +# Open browser: http://localhost:3000 +# Navigate to Cloudflare integration +``` + +## Environment Variables + +- `CLOUDFLARE_ACCOUNT_ID` - Your Cloudflare account ID (required) +- `CLOUDFLARE_API_TOKEN` - Your Cloudflare API token (required) +- `PORT` - Server port (default: 4114) +- `HOST` - Server host (default: 0.0.0.0) + +## ThreadId Handling + +All agents properly handle conversation threading: + +- Accept `threadId` via `x-thread-id` header or request body +- Generate unique `threadId` if not provided +- Echo `threadId` in every SSE event for proper Dojo/CopilotKit compatibility + +**Example with threadId**: +```bash +curl -X POST http://localhost:4114/agentic_chat \ + -H "Content-Type: application/json" \ + -H "x-thread-id: my-conversation-123" \ + -d '{"messages": [{"role": "user", "content": "Hello"}]}' +``` + +This ensures the same `threadId` flows through the entire conversation, preventing split-brain state issues. See `../../THREAD-ISSUE.md` for technical details. + +## Architecture + +Each agent follows the same pattern: + +```text +src/agents/ +├── agentic_chat/ +│ ├── agent.ts # Agent implementation (extends CloudflareAgent) +│ └── index.ts # Express route handler +├── human_in_the_loop/ +│ ├── agent.ts +│ └── index.ts +└── ... +``` + +All agents: + +1. Extend `CloudflareAgent` from `@ag-ui/cloudflare` +2. Implement proper AG-UI protocol event emission +3. Use SSE (Server-Sent Events) for streaming +4. Handle tool calls and state management + +## Adding New Agents + +1. Create agent directory: `src/agents/my_agent/` +2. Implement agent class extending `CloudflareAgent` +3. Create Express handler in `index.ts` +4. Register in `src/index.ts` routes +5. Add to `cloudflare.json` configuration +6. Restart server + +See existing agents for reference implementation patterns. + +## Health Check + +```bash +curl http://localhost:4114/health +``` + +Returns list of available agents and server status. + +## Troubleshooting + +**Issue**: `Missing required environment variables` + +- Solution: Ensure `.env` file exists with `CLOUDFLARE_ACCOUNT_ID` and `CLOUDFLARE_API_TOKEN` + +**Issue**: `401 Unauthorized` + +- Solution: Verify API token has "Workers AI:Read" permission + +**Issue**: Model not found + +- Solution: Check model name matches Cloudflare Workers AI available models + +## Learn More + +- [Cloudflare Workers AI Documentation](https://developers.cloudflare.com/workers-ai/) +- [AG-UI Protocol Specification](https://docs.ag-ui.com/) +- [Available Cloudflare AI Models](https://developers.cloudflare.com/workers-ai/models/) diff --git a/integrations/cloudflare/typescript/examples/cloudflare.json b/integrations/cloudflare/typescript/examples/cloudflare.json new file mode 100644 index 000000000..6c684a83d --- /dev/null +++ b/integrations/cloudflare/typescript/examples/cloudflare.json @@ -0,0 +1,46 @@ +{ + "dependencies": ["."], + "agents": { + "agentic_chat": { + "path": "./src/agents/agentic_chat/agent.ts", + "export": "getAgenticChatAgent", + "description": "Basic chat with Llama 3.1 8B", + "model": "@cf/meta/llama-3.1-8b-instruct" + }, + "tool_based_generative_ui": { + "path": "./src/agents/tool_based_generative_ui/agent.ts", + "export": "getToolBasedGenerativeUiAgent", + "description": "Tool-based UI with Llama 3.3 70B (haiku generation)", + "model": "@cf/meta/llama-3.3-70b-instruct" + }, + "agentic_generative_ui": { + "path": "./src/agents/agentic_generative_ui/agent.ts", + "export": "getAgenticGenerativeUiAgent", + "description": "Progressive state updates with task steps", + "model": "@cf/meta/llama-3.1-8b-instruct" + }, + "human_in_the_loop": { + "path": "./src/agents/human_in_the_loop/agent.ts", + "export": "getHumanInTheLoopAgent", + "description": "Interactive task planning with user confirmation", + "model": "@cf/meta/llama-3.1-8b-instruct" + }, + "shared_state": { + "path": "./src/agents/shared_state/agent.ts", + "export": "getSharedStateAgent", + "description": "Persistent to-do list management", + "model": "@cf/meta/llama-3.1-8b-instruct" + }, + "backend_tool_rendering": { + "path": "./src/agents/backend_tool_rendering/agent.ts", + "export": "getBackendToolRenderingAgent", + "description": "Backend-generated UI components", + "model": "@cf/meta/llama-3.1-8b-instruct" + } + }, + "env": ".env", + "server": { + "port": 4114, + "host": "0.0.0.0" + } +} diff --git a/integrations/cloudflare/typescript/examples/package.json b/integrations/cloudflare/typescript/examples/package.json new file mode 100644 index 000000000..30e0bb3c4 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/package.json @@ -0,0 +1,28 @@ +{ + "name": "cloudflare-examples", + "version": "1.0.0", + "type": "module", + "scripts": { + "dev": "tsx watch src/index.ts", + "start": "tsx src/index.ts", + "build": "tsc", + "test": "echo \"no tests to run\" && exit 0" + }, + "dependencies": { + "@ag-ui/cloudflare": "workspace:*", + "@ag-ui/core": "workspace:*", + "express": "^4.18.2", + "cors": "^2.8.5", + "dotenv": "^16.4.5" + }, + "devDependencies": { + "@types/express": "^4.17.21", + "@types/cors": "^2.8.17", + "@types/node": "^20.10.0", + "tsx": "^4.7.0", + "typescript": "^5.3.3" + }, + "engines": { + "node": ">=18.0.0" + } +} diff --git a/integrations/cloudflare/typescript/examples/src/agents/agentic_chat/agent.ts b/integrations/cloudflare/typescript/examples/src/agents/agentic_chat/agent.ts new file mode 100644 index 000000000..d7ef523a2 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/agents/agentic_chat/agent.ts @@ -0,0 +1,50 @@ +/** + * A simple agentic chat flow using Cloudflare Workers AI. + * + * This agent demonstrates basic chat functionality using the ReAct design pattern + * with Cloudflare's Llama 3.1 8B model. + * + * Features: + * - Streaming text responses + * - Tool calling support (when tools are provided) + * - Proper AG-UI protocol event emission + */ + +import { CloudflareAgent, CLOUDFLARE_MODELS } from "@ag-ui/cloudflare"; + +/** + * Agentic Chat Agent + * + * A helpful assistant powered by Cloudflare Workers AI that can engage in + * natural conversation and use tools when provided. + */ +export class AgenticChatAgent extends CloudflareAgent { + constructor() { + const accountId = process.env.CLOUDFLARE_ACCOUNT_ID; + const apiToken = process.env.CLOUDFLARE_API_TOKEN; + + if (!accountId || !apiToken) { + throw new Error( + "Missing required environment variables: CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN" + ); + } + + super({ + accountId, + apiToken, + model: CLOUDFLARE_MODELS.LLAMA_3_1_8B, // Using smaller model for simple chat + systemPrompt: `You are a helpful AI assistant. Provide clear, accurate, and friendly responses. Use tools when they add value to the conversation.`, + streamingEnabled: true, + }); + } +} + +// Lazy singleton - created on first use after env vars are loaded +let _agenticChatAgent: AgenticChatAgent | null = null; + +export function getAgenticChatAgent(): AgenticChatAgent { + if (!_agenticChatAgent) { + _agenticChatAgent = new AgenticChatAgent(); + } + return _agenticChatAgent; +} diff --git a/integrations/cloudflare/typescript/examples/src/agents/agentic_chat/index.ts b/integrations/cloudflare/typescript/examples/src/agents/agentic_chat/index.ts new file mode 100644 index 000000000..22b43fecb --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/agents/agentic_chat/index.ts @@ -0,0 +1,62 @@ +/** + * Express route handler for Agentic Chat agent + */ + +import type { Request, Response } from "express"; +import { getAgenticChatAgent } from "./agent.js"; +import { + validateMessagesRequest, + createAgentInput, + setSSEHeaders, + writeSSEEvent, + createSSEErrorHandler, +} from "../../utils/agent-utils.js"; + +/** + * POST /agentic_chat + * + * Handles chat requests and streams AG-UI protocol events back to the client. + * + * Request body: + * - messages: Array of chat messages + * - context: Optional context object + * - tools: Optional array of tools + */ +export async function agenticChatHandler(req: Request, res: Response) { + // Validate request + if (!validateMessagesRequest(req, res)) { + return; + } + + // Set SSE headers + setSSEHeaders(res); + + try { + // Create agent input + const input = createAgentInput(req); + + // Run the agent and stream events + const agent = getAgenticChatAgent(); + const observable = agent.run(input); + + const subscription = observable.subscribe({ + next: (event) => { + writeSSEEvent(res, event, input.threadId); + }, + error: createSSEErrorHandler(res, input.threadId, { + agentType: "agentic_chat", + runId: input.runId, + }), + complete: () => { + res.end(); + }, + }); + + // Handle client disconnect + req.on("close", () => { + subscription.unsubscribe(); + }); + } catch (error) { + createSSEErrorHandler(res, "", { agentType: "agentic_chat" })(error); + } +} diff --git a/integrations/cloudflare/typescript/examples/src/agents/agentic_generative_ui/agent.ts b/integrations/cloudflare/typescript/examples/src/agents/agentic_generative_ui/agent.ts new file mode 100644 index 000000000..747d79ba1 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/agents/agentic_generative_ui/agent.ts @@ -0,0 +1,189 @@ +/** + * Agentic Generative UI Agent using Cloudflare Workers AI + * + * This agent demonstrates progressive state updates where the UI can render + * structured data as it's being generated by the model. + * + * Example: When the agent generates a list of task steps, the frontend can + * render each step progressively as it's streamed, creating a dynamic UI + * experience. + * + * Features: + * - STATE_SNAPSHOT events for progressive UI updates + * - Structured output generation + * - Real-time state synchronization with frontend + */ + +import { CloudflareAgent, CLOUDFLARE_MODELS } from "@ag-ui/cloudflare"; +import { Observable, Subscriber } from "rxjs"; +import type { RunAgentInput, BaseEvent } from "@ag-ui/client"; +import { + EventType, + type StateSnapshotEvent, + type TextMessageStartEvent, + type TextMessageContentEvent, + type TextMessageEndEvent, +} from "@ag-ui/core"; + +/** + * Agentic Generative UI Agent + * + * Generates task steps progressively and emits state updates so the frontend + * can render the UI as the steps are being created. + */ +export class AgenticGenerativeUiAgent extends CloudflareAgent { + constructor() { + const accountId = process.env.CLOUDFLARE_ACCOUNT_ID; + const apiToken = process.env.CLOUDFLARE_API_TOKEN; + + if (!accountId || !apiToken) { + throw new Error( + "Missing required environment variables: CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN" + ); + } + + super({ + accountId, + apiToken, + model: CLOUDFLARE_MODELS.LLAMA_3_1_8B, + systemPrompt: `You are a helpful assistant that breaks down tasks into 5-10 clear, actionable steps. Format each step as "N. Description".`, + streamingEnabled: true, + }); + } + + /** + * Override run() to add STATE_SNAPSHOT events during generation + */ + run(input: RunAgentInput): Observable { + return new Observable((subscriber) => { + this.executeRunWithState(input, subscriber) + .catch((error) => { + console.error("AgenticGenerativeUiAgent execution error:", error); + subscriber.error(error); + }) + .finally(() => { + subscriber.complete(); + }); + }); + } + + /** + * Enhanced execution with progressive state updates + * Parses numbered lists from the AI response and emits state snapshots + */ + private async executeRunWithState( + input: RunAgentInput, + subscriber: Subscriber + ): Promise { + const steps: Array<{ description: string; status: string }> = []; + let accumulatedText = ""; + let messageId: string | null = null; + + // Create a custom subscriber that intercepts TEXT_MESSAGE events + const customSubscriber = { + next: (event: BaseEvent) => { + // Pass through all events + subscriber.next(event); + + // Track message ID for context + if (event.type === EventType.TEXT_MESSAGE_START) { + const startEvent = event as TextMessageStartEvent; + messageId = startEvent.messageId; + } + + // Extract steps from text content + if (event.type === EventType.TEXT_MESSAGE_CONTENT) { + const contentEvent = event as TextMessageContentEvent; + const delta = contentEvent.delta || ""; + accumulatedText += delta; + + // Parse for numbered step patterns (e.g., "1. Step description") + const stepMatches = accumulatedText.match(/^\s*\d+\.\s*(.+)$/gm); + + if (stepMatches && stepMatches.length > 0) { + // Clear and rebuild steps array + steps.length = 0; + + for (const match of stepMatches) { + // Extract the description (everything after "N. ") + const description = match.replace(/^\s*\d+\.\s*/, "").trim(); + if (description) { + steps.push({ + description, + status: "pending", + }); + } + } + + // Emit progressive state snapshot + const progressSnapshot: StateSnapshotEvent = { + type: EventType.STATE_SNAPSHOT, + snapshot: { + steps: [...steps], + completed: false, + progress: steps.length, + }, + timestamp: Date.now(), + }; + subscriber.next(progressSnapshot); + } + } + + // When message ends, emit final state + if (event.type === EventType.TEXT_MESSAGE_END) { + const finalSnapshot: StateSnapshotEvent = { + type: EventType.STATE_SNAPSHOT, + snapshot: { + steps: [...steps], + completed: true, + totalSteps: steps.length, + }, + timestamp: Date.now(), + }; + subscriber.next(finalSnapshot); + } + }, + error: (error: Error) => { + console.error("AgenticGenerativeUiAgent execution error:", { + agent: "agentic_generative_ui", + threadId: input.threadId, + runId: input.runId, + error: { + message: error.message, + stack: error.stack, + name: error.name, + }, + }); + subscriber.error(error); + }, + complete: () => { + // Ensure final state is emitted even if no TEXT_MESSAGE_END + if (steps.length > 0) { + const finalSnapshot: StateSnapshotEvent = { + type: EventType.STATE_SNAPSHOT, + snapshot: { + steps: [...steps], + completed: true, + totalSteps: steps.length, + }, + timestamp: Date.now(), + }; + subscriber.next(finalSnapshot); + } + }, + }; + + // Execute with custom subscriber + await this.executeRun(input, customSubscriber as Subscriber); + } +} + +// Lazy singleton +let _agenticGenUiAgent: AgenticGenerativeUiAgent | null = null; + +export function getAgenticGenerativeUiAgent(): AgenticGenerativeUiAgent { + if (!_agenticGenUiAgent) { + _agenticGenUiAgent = new AgenticGenerativeUiAgent(); + } + return _agenticGenUiAgent; +} diff --git a/integrations/cloudflare/typescript/examples/src/agents/agentic_generative_ui/index.ts b/integrations/cloudflare/typescript/examples/src/agents/agentic_generative_ui/index.ts new file mode 100644 index 000000000..c93d49db1 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/agents/agentic_generative_ui/index.ts @@ -0,0 +1,63 @@ +/** + * Express route handler for Agentic Generative UI agent + */ + +import type { Request, Response } from "express"; +import { getAgenticGenerativeUiAgent } from "./agent.js"; +import { + validateMessagesRequest, + createAgentInput, + setSSEHeaders, + writeSSEEvent, + createSSEErrorHandler, +} from "../../utils/agent-utils.js"; + +/** + * POST /agentic_generative_ui + * + * Demonstrates agentic generative UI with progressive state updates. + * As the agent generates structured data (like task steps), STATE_SNAPSHOT + * events are emitted so the frontend can render the UI progressively. + * + * Request body: + * - messages: Array of chat messages + * - context: Optional context object + */ +export async function agenticGenerativeUiHandler(req: Request, res: Response) { + // Validate request + if (!validateMessagesRequest(req, res)) { + return; + } + + // Set SSE headers + setSSEHeaders(res); + + try { + // Create agent input + const input = createAgentInput(req); + + // Run the agent and stream events + const agent = getAgenticGenerativeUiAgent(); + const observable = agent.run(input); + + const subscription = observable.subscribe({ + next: (event) => { + writeSSEEvent(res, event, input.threadId); + }, + error: createSSEErrorHandler(res, input.threadId, { + agentType: "agentic_generative_ui", + runId: input.runId, + }), + complete: () => { + res.end(); + }, + }); + + // Handle client disconnect + req.on("close", () => { + subscription.unsubscribe(); + }); + } catch (error) { + createSSEErrorHandler(res, "", { agentType: "agentic_generative_ui" })(error); + } +} diff --git a/integrations/cloudflare/typescript/examples/src/agents/backend_tool_rendering/agent.ts b/integrations/cloudflare/typescript/examples/src/agents/backend_tool_rendering/agent.ts new file mode 100644 index 000000000..424b615e1 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/agents/backend_tool_rendering/agent.ts @@ -0,0 +1,53 @@ +/** + * Backend Tool Rendering Agent using Cloudflare Workers AI + * + * This agent demonstrates how the backend can generate and return + * React components that the frontend will render. + * + * Example: Generating a weather widget with custom styling and data + * that the frontend renders as a React component. + * + * Features: + * - Backend-generated UI components + * - TOOL_RESULT events with render prop + * - Rich, interactive UI elements + */ + +import { CloudflareAgent, CLOUDFLARE_MODELS } from "@ag-ui/cloudflare"; + +/** + * Backend Tool Rendering Agent + * + * An assistant that can generate React components on the backend + * for the frontend to render. + */ +export class BackendToolRenderingAgent extends CloudflareAgent { + constructor() { + const accountId = process.env.CLOUDFLARE_ACCOUNT_ID; + const apiToken = process.env.CLOUDFLARE_API_TOKEN; + + if (!accountId || !apiToken) { + throw new Error( + "Missing required environment variables: CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN" + ); + } + + super({ + accountId, + apiToken, + model: CLOUDFLARE_MODELS.LLAMA_3_3_70B_FP8, // Using function-calling capable model + systemPrompt: `You are a helpful assistant with access to UI rendering tools. Use tools when they enhance the response - the frontend will render beautiful, interactive components.`, + streamingEnabled: true, + }); + } +} + +// Lazy singleton +let _backendToolRenderingAgent: BackendToolRenderingAgent | null = null; + +export function getBackendToolRenderingAgent(): BackendToolRenderingAgent { + if (!_backendToolRenderingAgent) { + _backendToolRenderingAgent = new BackendToolRenderingAgent(); + } + return _backendToolRenderingAgent; +} diff --git a/integrations/cloudflare/typescript/examples/src/agents/backend_tool_rendering/index.ts b/integrations/cloudflare/typescript/examples/src/agents/backend_tool_rendering/index.ts new file mode 100644 index 000000000..f0cc680f4 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/agents/backend_tool_rendering/index.ts @@ -0,0 +1,61 @@ +/** + * Express route handler for Backend Tool Rendering agent + */ + +import type { Request, Response } from "express"; +import { getBackendToolRenderingAgent } from "./agent.js"; +import { + validateMessagesRequest, + createAgentInput, + setSSEHeaders, + writeSSEEvent, + createSSEErrorHandler, +} from "../../utils/agent-utils.js"; +import { + ensureTools, + SHOW_WEATHER_TOOL, + SHOW_STOCK_TOOL, + SHOW_CALENDAR_TOOL, +} from "../../utils/tool-definitions.js"; + +export async function backendToolRenderingHandler(req: Request, res: Response) { + // Validate request + if (!validateMessagesRequest(req, res)) { + return; + } + + // Set SSE headers + setSSEHeaders(res); + + try { + // Create agent input with backend rendering tools + const input = createAgentInput(req); + input.tools = ensureTools(input.tools, [ + SHOW_WEATHER_TOOL, + SHOW_STOCK_TOOL, + SHOW_CALENDAR_TOOL, + ]); + + const agent = getBackendToolRenderingAgent(); + const observable = agent.run(input); + + const subscription = observable.subscribe({ + next: (event) => { + writeSSEEvent(res, event, input.threadId); + }, + error: createSSEErrorHandler(res, input.threadId, { + agentType: "backend_tool_rendering", + runId: input.runId, + }), + complete: () => { + res.end(); + }, + }); + + req.on("close", () => { + subscription.unsubscribe(); + }); + } catch (error) { + createSSEErrorHandler(res, "", { agentType: "backend_tool_rendering" })(error); + } +} diff --git a/integrations/cloudflare/typescript/examples/src/agents/human_in_the_loop/agent.ts b/integrations/cloudflare/typescript/examples/src/agents/human_in_the_loop/agent.ts new file mode 100644 index 000000000..c591e9def --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/agents/human_in_the_loop/agent.ts @@ -0,0 +1,53 @@ +/** + * Human-in-the-Loop Agent using Cloudflare Workers AI + * + * This agent demonstrates how to pause execution and request user input + * before proceeding with a task. + * + * Example: When generating a task plan, the agent can ask the user to + * review and approve/modify the steps before execution. + * + * Features: + * - Tool calling for user confirmation requests + * - Interactive step selection + * - User feedback integration + */ + +import { CloudflareAgent, CLOUDFLARE_MODELS } from "@ag-ui/cloudflare"; + +/** + * Human-in-the-Loop Agent + * + * An assistant that requests user confirmation for generated task steps + * before proceeding with execution. + */ +export class HumanInTheLoopAgent extends CloudflareAgent { + constructor() { + const accountId = process.env.CLOUDFLARE_ACCOUNT_ID; + const apiToken = process.env.CLOUDFLARE_API_TOKEN; + + if (!accountId || !apiToken) { + throw new Error( + "Missing required environment variables: CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN" + ); + } + + super({ + accountId, + apiToken, + model: CLOUDFLARE_MODELS.HERMES_2_PRO_7B, + systemPrompt: `You are a helpful assistant that creates collaborative task plans. When asked to help with a task, use the generate_task_steps tool to present 5-10 clear, actionable steps for user review.`, + streamingEnabled: true, + }); + } +} + +// Lazy singleton +let _humanInTheLoopAgent: HumanInTheLoopAgent | null = null; + +export function getHumanInTheLoopAgent(): HumanInTheLoopAgent { + if (!_humanInTheLoopAgent) { + _humanInTheLoopAgent = new HumanInTheLoopAgent(); + } + return _humanInTheLoopAgent; +} diff --git a/integrations/cloudflare/typescript/examples/src/agents/human_in_the_loop/index.ts b/integrations/cloudflare/typescript/examples/src/agents/human_in_the_loop/index.ts new file mode 100644 index 000000000..3e6d9a8f7 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/agents/human_in_the_loop/index.ts @@ -0,0 +1,52 @@ +/** + * Express route handler for Human-in-the-Loop agent + */ + +import type { Request, Response } from "express"; +import { getHumanInTheLoopAgent } from "./agent.js"; +import { + validateMessagesRequest, + createAgentInput, + setSSEHeaders, + writeSSEEvent, + createSSEErrorHandler, +} from "../../utils/agent-utils.js"; +import { ensureTool, GENERATE_TASK_STEPS_TOOL } from "../../utils/tool-definitions.js"; + +export async function humanInTheLoopHandler(req: Request, res: Response) { + // Validate request + if (!validateMessagesRequest(req, res)) { + return; + } + + // Set SSE headers + setSSEHeaders(res); + + try { + // Create agent input with task steps tool + const input = createAgentInput(req); + input.tools = ensureTool(input.tools, GENERATE_TASK_STEPS_TOOL); + + const agent = getHumanInTheLoopAgent(); + const observable = agent.run(input); + + const subscription = observable.subscribe({ + next: (event) => { + writeSSEEvent(res, event, input.threadId); + }, + error: createSSEErrorHandler(res, input.threadId, { + agentType: "human_in_the_loop", + runId: input.runId, + }), + complete: () => { + res.end(); + }, + }); + + req.on("close", () => { + subscription.unsubscribe(); + }); + } catch (error) { + createSSEErrorHandler(res, "", { agentType: "human_in_the_loop" })(error); + } +} diff --git a/integrations/cloudflare/typescript/examples/src/agents/shared_state/agent.ts b/integrations/cloudflare/typescript/examples/src/agents/shared_state/agent.ts new file mode 100644 index 000000000..823ba7605 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/agents/shared_state/agent.ts @@ -0,0 +1,304 @@ +/** + * Shared State Agent using Cloudflare Workers AI + * + * This agent demonstrates persistent state management across multiple + * messages in a conversation using tool-based state updates. + * + * Example: Maintaining a to-do list that persists across the conversation, + * allowing the user to add, remove, or modify items over multiple turns. + * + * Features: + * - STATE_SNAPSHOT events for persistent state + * - Tool-based state mutations (more reliable than regex parsing) + * - Cross-message state continuity + */ + +import { CloudflareAgent, CLOUDFLARE_MODELS } from "@ag-ui/cloudflare"; +import { Observable, Subscriber } from "rxjs"; +import type { RunAgentInput, BaseEvent } from "@ag-ui/client"; +import { + EventType, + type StateSnapshotEvent, + type ToolCallStartEvent, + type ToolCallArgsEvent, + type ToolCallEndEvent, +} from "@ag-ui/core"; +import { validateTodoItem, sanitizeString } from "../../utils/validation.js"; + +interface TodoItem { + id: string; + text: string; + completed: boolean; + createdAt: number; +} + +interface TodoState { + todos: TodoItem[]; +} + +/** + * Shared State Agent + * + * Maintains a shared to-do list state that persists across the conversation. + * Users can ask to add, remove, or modify items in the list. + */ +export class SharedStateAgent extends CloudflareAgent { + constructor() { + const accountId = process.env.CLOUDFLARE_ACCOUNT_ID; + const apiToken = process.env.CLOUDFLARE_API_TOKEN; + + if (!accountId || !apiToken) { + throw new Error( + "Missing required environment variables: CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN" + ); + } + + super({ + accountId, + apiToken, + model: CLOUDFLARE_MODELS.LLAMA_3_3_70B_FP8, // Using function-calling capable model + systemPrompt: `You are a helpful assistant that manages a to-do list. Use the provided tools (add_todo, remove_todo, toggle_todo, list_todos, clear_todos) to handle user requests. After using a tool, acknowledge what you've done.`, + streamingEnabled: true, + }); + } + + /** + * Override run() to manage state across messages using tool calls + */ + run(input: RunAgentInput): Observable { + return new Observable((subscriber) => { + this.executeRunWithSharedState(input, subscriber) + .catch((error) => { + console.error("SharedStateAgent execution error:", error); + subscriber.error(error); + }) + .finally(() => { + subscriber.complete(); + }); + }); + } + + /** + * Enhanced execution with tool-based state management + * Listens for tool calls and updates state accordingly + */ + private async executeRunWithSharedState( + input: RunAgentInput, + subscriber: Subscriber + ): Promise { + // Extract current state from input if available + const currentState: TodoState = (input.state as TodoState) || { todos: [] }; + let updatedState: TodoState = { todos: [...currentState.todos] }; + + // Track current tool call + let currentToolCall: { name: string; args: any } | null = null; + + // Create custom subscriber to intercept tool calls + const customSubscriber = { + next: (event: BaseEvent) => { + // Pass through all events + subscriber.next(event); + + // Track tool call start + if (event.type === EventType.TOOL_CALL_START) { + const toolCallStart = event as ToolCallStartEvent; + currentToolCall = { name: toolCallStart.toolCallName, args: {} }; + } + + // Accumulate tool call arguments + if (event.type === EventType.TOOL_CALL_ARGS && currentToolCall) { + const argsEvent = event as ToolCallArgsEvent; + try { + const parsedArgs = JSON.parse(argsEvent.delta); + currentToolCall.args = { ...currentToolCall.args, ...parsedArgs }; + } catch { + // If delta is partial JSON, store it and wait for more + currentToolCall.args = argsEvent.delta; + } + } + + // Execute tool and update state when tool call ends + if (event.type === EventType.TOOL_CALL_END && currentToolCall) { + updatedState = this.executeToolCall( + currentToolCall.name, + currentToolCall.args, + updatedState + ); + + // Emit updated state snapshot + const stateSnapshot: StateSnapshotEvent = { + type: EventType.STATE_SNAPSHOT, + snapshot: updatedState, + timestamp: Date.now(), + }; + subscriber.next(stateSnapshot); + + currentToolCall = null; + } + }, + error: (error: Error) => { + console.error("SharedStateAgent execution error:", { + agent: "shared_state", + threadId: input.threadId, + runId: input.runId, + currentState, + error: { + message: error.message, + stack: error.stack, + name: error.name, + }, + }); + subscriber.error(error); + }, + complete: () => { + // Emit final state even if no tool calls + if (updatedState.todos.length !== currentState.todos.length || + JSON.stringify(updatedState) !== JSON.stringify(currentState)) { + const stateSnapshot: StateSnapshotEvent = { + type: EventType.STATE_SNAPSHOT, + snapshot: updatedState, + timestamp: Date.now(), + }; + subscriber.next(stateSnapshot); + } + }, + }; + + // Execute with custom subscriber + await this.executeRun(input, customSubscriber as Subscriber); + } + + /** + * Execute a tool call and return updated state with validation + * Handles: add_todo, remove_todo, toggle_todo, list_todos, clear_todos + */ + private executeToolCall(toolName: string, args: any, currentState: TodoState): TodoState { + const todos = [...currentState.todos]; + + switch (toolName) { + case "add_todo": { + const { text } = args; + if (!text) { + console.warn("add_todo called without text parameter"); + break; + } + + // Validate and sanitize the todo text + const validation = validateTodoItem(text); + if (!validation.valid) { + console.warn(`Invalid todo text: ${validation.error}`); + break; + } + + // Check for duplicates + const isDuplicate = todos.some( + (t) => t.text.toLowerCase() === validation.sanitized.toLowerCase() + ); + if (isDuplicate) { + console.warn(`Duplicate todo: "${validation.sanitized}"`); + break; + } + + const newTodo: TodoItem = { + id: `todo-${Date.now()}-${Math.random().toString(36).substring(7)}`, + text: validation.sanitized, + completed: false, + createdAt: Date.now(), + }; + todos.push(newTodo); + break; + } + + case "remove_todo": { + const { text } = args; + if (!text || typeof text !== "string") { + console.warn("remove_todo called without valid text parameter"); + break; + } + + const searchText = sanitizeString(text).toLowerCase(); + if (searchText.length === 0) { + console.warn("remove_todo called with empty text"); + break; + } + + const index = todos.findIndex((t) => + t.text.toLowerCase().includes(searchText) + ); + if (index !== -1) { + todos.splice(index, 1); + } else { + console.warn(`Todo not found for removal: "${text}"`); + } + break; + } + + case "toggle_todo": { + const { text, completed } = args; + if (!text || typeof text !== "string") { + console.warn("toggle_todo called without valid text parameter"); + break; + } + + if (typeof completed !== "boolean") { + console.warn("toggle_todo called without valid completed parameter"); + break; + } + + const searchText = sanitizeString(text).toLowerCase(); + const todo = todos.find((t) => t.text.toLowerCase().includes(searchText)); + if (todo) { + todo.completed = completed; + } else { + console.warn(`Todo not found for toggle: "${text}"`); + } + break; + } + + case "list_todos": { + // list_todos doesn't modify state, just returns it + // The AI will use the state to respond to the user + const { filter } = args; + if (filter && !["completed", "incomplete", "all"].includes(filter)) { + console.warn(`Invalid filter: "${filter}". Must be: completed, incomplete, or all`); + } + break; + } + + case "clear_todos": { + const { clearAll } = args; + if (typeof clearAll !== "boolean" && clearAll !== undefined) { + console.warn("clear_todos called with invalid clearAll parameter"); + break; + } + + if (clearAll) { + todos.length = 0; // Clear all + } else { + // Remove only completed + for (let i = todos.length - 1; i >= 0; i--) { + if (todos[i].completed) { + todos.splice(i, 1); + } + } + } + break; + } + + default: + console.warn(`Unknown tool: ${toolName}`); + } + + return { todos }; + } +} + +// Lazy singleton +let _sharedStateAgent: SharedStateAgent | null = null; + +export function getSharedStateAgent(): SharedStateAgent { + if (!_sharedStateAgent) { + _sharedStateAgent = new SharedStateAgent(); + } + return _sharedStateAgent; +} diff --git a/integrations/cloudflare/typescript/examples/src/agents/shared_state/index.ts b/integrations/cloudflare/typescript/examples/src/agents/shared_state/index.ts new file mode 100644 index 000000000..01a1e8fa3 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/agents/shared_state/index.ts @@ -0,0 +1,107 @@ +/** + * Express route handler for Shared State agent + */ + +import type { Request, Response } from "express"; +import { EventType, type StateSnapshotEvent } from "@ag-ui/core"; +import { getSharedStateAgent } from "./agent.js"; +import { + validateMessagesRequest, + getOrCreateThreadId, + generateRunId, + setSSEHeaders, + writeSSEEvent, + createSSEErrorHandler, +} from "../../utils/agent-utils.js"; +import { ensureTools, TODO_MANAGEMENT_TOOLS } from "../../utils/tool-definitions.js"; + +/** + * In-memory state storage per thread + * In production, this should be replaced with a persistent store (Redis, DB, etc.) + */ +const threadStates = new Map(); + +/** + * POST /shared_state + * + * Demonstrates persistent state management across multiple messages. + * State is maintained per thread and updated with each interaction. + * + * Request body: + * - messages: Array of chat messages + * - context: Optional context object + * - tools: Optional array of tools + */ +export async function sharedStateHandler(req: Request, res: Response) { + // Validate request + if (!validateMessagesRequest(req, res)) { + return; + } + + // Set SSE headers + setSSEHeaders(res); + + try { + const { messages, context, tools } = req.body; + const threadId = getOrCreateThreadId(req); + + // Retrieve previous state for this thread, or initialize empty + const previousState = threadStates.get(threadId) || { todos: [] }; + + // Create agent input with previous state and todo management tools + const input = { + threadId, + runId: generateRunId(), + messages, + tools: ensureTools(tools, TODO_MANAGEMENT_TOOLS), // Include todo management tools + context: context ? [{ description: "Request context", value: JSON.stringify(context) }] : [], + state: previousState, // Pass previous state + forwardedProps: {}, + }; + + const agent = getSharedStateAgent(); + const observable = agent.run(input); + + const subscription = observable.subscribe({ + next: (event) => { + // Persist state updates + if (event.type === EventType.STATE_SNAPSHOT) { + const stateEvent = event as StateSnapshotEvent; + threadStates.set(threadId, stateEvent.snapshot); + } + + writeSSEEvent(res, event, threadId); + }, + error: createSSEErrorHandler(res, threadId, { + agentType: "shared_state", + runId: input.runId, + }), + complete: () => { + res.end(); + }, + }); + + // Handle client disconnect + req.on("close", () => { + subscription.unsubscribe(); + }); + } catch (error) { + createSSEErrorHandler(res, "", { agentType: "shared_state" })(error); + } +} + +/** + * Optional: Clear state for a specific thread + * Could be exposed as DELETE /shared_state/:threadId + */ +export function clearThreadState(threadId: string): void { + threadStates.delete(threadId); +} + +/** + * Optional: Get current state for a thread + * Could be exposed as GET /shared_state/:threadId + */ +export function getThreadState(threadId: string): any { + return threadStates.get(threadId) || { todos: [] }; +} diff --git a/integrations/cloudflare/typescript/examples/src/agents/tool_based_generative_ui/agent.ts b/integrations/cloudflare/typescript/examples/src/agents/tool_based_generative_ui/agent.ts new file mode 100644 index 000000000..89a494882 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/agents/tool_based_generative_ui/agent.ts @@ -0,0 +1,58 @@ +/** + * Tool-based Generative UI Agent using Cloudflare Workers AI + * + * This agent demonstrates how frontend-provided tools (via CopilotKit actions) + * can be used to render custom React components in the UI. + * + * Example: A haiku generation tool that the frontend can render as a custom + * component with special styling or animations. + * + * Features: + * - Tool calling support for frontend-defined actions + * - Streaming tool call arguments + * - AG-UI protocol TOOL_CALL_* events + */ + +import { CloudflareAgent, CLOUDFLARE_MODELS } from "@ag-ui/cloudflare"; + +/** + * Tool-Based Generative UI Agent + * + * Helps users with writing haikus. When tools are provided by the frontend + * (e.g., generate_haiku), the agent will use them and the frontend can + * render custom UI components for the tool results. + */ +export class ToolBasedGenerativeUiAgent extends CloudflareAgent { + constructor() { + const accountId = process.env.CLOUDFLARE_ACCOUNT_ID; + const apiToken = process.env.CLOUDFLARE_API_TOKEN; + + if (!accountId || !apiToken) { + throw new Error( + "Missing required environment variables: CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN" + ); + } + + super({ + accountId, + apiToken, + model: CLOUDFLARE_MODELS.LLAMA_3_3_70B_FP8, // Using function-calling capable model + systemPrompt: `You are an expert haiku composer. Help users craft traditional Japanese haiku (5-7-5 syllable structure) with English translations. + +Always use the "generate_haiku" tool to deliver the finished haiku. The tool schema defines valid image names and CSS gradients - use those exact values. + +Keep your conversational responses warm and collaborative, but deliver the actual haiku via the tool call.`, + streamingEnabled: true, + }); + } +} + +// Lazy singleton +let _toolBasedAgent: ToolBasedGenerativeUiAgent | null = null; + +export function getToolBasedGenerativeUiAgent(): ToolBasedGenerativeUiAgent { + if (!_toolBasedAgent) { + _toolBasedAgent = new ToolBasedGenerativeUiAgent(); + } + return _toolBasedAgent; +} diff --git a/integrations/cloudflare/typescript/examples/src/agents/tool_based_generative_ui/index.ts b/integrations/cloudflare/typescript/examples/src/agents/tool_based_generative_ui/index.ts new file mode 100644 index 000000000..8c902f249 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/agents/tool_based_generative_ui/index.ts @@ -0,0 +1,65 @@ +/** + * Express route handler for Tool-Based Generative UI agent + */ + +import type { Request, Response } from "express"; +import { getToolBasedGenerativeUiAgent } from "./agent.js"; +import { + validateMessagesRequest, + createAgentInput, + setSSEHeaders, + writeSSEEvent, + createSSEErrorHandler, +} from "../../utils/agent-utils.js"; +import { ensureTool, GENERATE_HAIKU_TOOL } from "../../utils/tool-definitions.js"; + +/** + * POST /tool_based_generative_ui + * + * Demonstrates tool-based generative UI where the frontend provides tools + * (like generate_haiku) and renders custom components for tool results. + * + * Request body: + * - messages: Array of chat messages + * - tools: Array of tools provided by the frontend (CopilotKit actions) + * - context: Optional context object + */ +export async function toolBasedGenerativeUiHandler(req: Request, res: Response) { + // Validate request + if (!validateMessagesRequest(req, res)) { + return; + } + + // Set SSE headers + setSSEHeaders(res); + + try { + // Create agent input with haiku tool + const input = createAgentInput(req); + input.tools = ensureTool(input.tools, GENERATE_HAIKU_TOOL); + + // Run the agent and stream events + const agent = getToolBasedGenerativeUiAgent(); + const observable = agent.run(input); + + const subscription = observable.subscribe({ + next: (event) => { + writeSSEEvent(res, event, input.threadId); + }, + error: createSSEErrorHandler(res, input.threadId, { + agentType: "tool_based_generative_ui", + runId: input.runId, + }), + complete: () => { + res.end(); + }, + }); + + // Handle client disconnect + req.on("close", () => { + subscription.unsubscribe(); + }); + } catch (error) { + createSSEErrorHandler(res, "", { agentType: "tool_based_generative_ui" })(error); + } +} diff --git a/integrations/cloudflare/typescript/examples/src/agents/tool_based_generative_ui_sdk/agent.ts b/integrations/cloudflare/typescript/examples/src/agents/tool_based_generative_ui_sdk/agent.ts new file mode 100644 index 000000000..cf8c2e78b --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/agents/tool_based_generative_ui_sdk/agent.ts @@ -0,0 +1,95 @@ +/** + * Tool-Based Generative UI Agent (Cloudflare Agents SDK version) + * + * Alternative implementation using CloudflareAIClient directly instead of + * extending CloudflareAgent. Demonstrates manual streaming and state management. + * + * @see tool_based_generative_ui/agent.ts for the standard CloudflareAgent approach + */ + +import { CloudflareAIClient } from "@ag-ui/cloudflare"; + +export class ToolBasedGenerativeUiAgent { + id = "tool-based-generative-ui-agent"; + private state: Record = {}; + private client: CloudflareAIClient; + + constructor() { + const accountId = process.env.CLOUDFLARE_ACCOUNT_ID; + const apiToken = process.env.CLOUDFLARE_API_TOKEN; + + if (!accountId || !apiToken) { + throw new Error( + "Missing required environment variables: CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN" + ); + } + + this.client = new CloudflareAIClient({ + accountId, + apiToken, + model: "@cf/meta/llama-3.1-8b-instruct", + }); + } + + async setState(state: Record): Promise { + this.state = { ...this.state, ...state }; + } + + getState(): Record { + return this.state; + } + + async sql(query: TemplateStringsArray, ...values: any[]): Promise { + // Not used for this agent + return []; + } + + async schedule(when: string | Date | number, callback: string, data?: any): Promise { + // Not used for this agent + } + + /** + * Handles chat messages and generates haikus using actual AI + */ + async *onChatMessage(message: string, context: any): AsyncGenerator { + const systemPrompt = `You are an expert haiku composer. Create a traditional Japanese haiku (5-7-5 syllable structure). + +Response format (JSON): +{ + "japanese": ["<5 syllable line>", "<7 syllable line>", "<5 syllable line>"], + "english": ["", "", ""] +}`; + + const messages = [ + { role: "system" as const, content: systemPrompt }, + { role: "user" as const, content: message }, + ]; + + try { + for await (const chunk of this.client.streamComplete({ messages, stream: true })) { + if (chunk.response) { + yield chunk.response; + } + } + } catch (error) { + console.error("Error generating haiku:", error); + yield `Error generating haiku: ${error instanceof Error ? error.message : "Unknown error"}`; + } + } + + async onRequest(request: Request): Promise { + return new Response("Use AG-UI adapter", { status: 501 }); + } +} + +/** + * Singleton instance + */ +let _agent: ToolBasedGenerativeUiAgent | null = null; + +export function getToolBasedGenerativeUiAgent(): ToolBasedGenerativeUiAgent { + if (!_agent) { + _agent = new ToolBasedGenerativeUiAgent(); + } + return _agent; +} diff --git a/integrations/cloudflare/typescript/examples/src/agents/tool_based_generative_ui_sdk/index.ts b/integrations/cloudflare/typescript/examples/src/agents/tool_based_generative_ui_sdk/index.ts new file mode 100644 index 000000000..1def89a71 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/agents/tool_based_generative_ui_sdk/index.ts @@ -0,0 +1,90 @@ +/** + * Tool-Based Generative UI (Agents SDK version) + * + * This handler demonstrates using CloudflareAgentsSDKAdapter to bridge + * the gap between Cloudflare Agents SDK patterns and AG-UI protocol. + * + * ## Adapter Usage: + * + * The CloudflareAgentsSDKAdapter converts Agents SDK method calls + * (onChatMessage, setState, etc.) into AG-UI protocol events automatically. + * + * ## Configuration Options: + * + * ```typescript + * const adapter = new CloudflareAgentsSDKAdapter({ + * agent, // Your Agents SDK agent instance + * syncState: false, // Whether to auto-sync state via STATE_SNAPSHOT events + * trackSQL: false, // Whether to track SQL operations (if your agent uses them) + * }); + * ``` + * + * ## When to Use This Adapter: + * + * - Migrating from pure Cloudflare Agents SDK to AG-UI + * - Need to maintain compatibility with existing Agents SDK code + * - Want to gradually adopt AG-UI protocol features + * + * @see tool_based_generative_ui/index.ts for the standard CloudflareAgent approach + */ + +import { Request, Response } from "express"; +import { CloudflareAgentsSDKAdapter } from "@ag-ui/cloudflare"; +import { getToolBasedGenerativeUiAgent } from "./agent.js"; + +export async function toolBasedGenerativeUiSDKHandler(req: Request, res: Response) { + try { + const { messages, context, threadId, runId } = req.body; + + if (!messages || !Array.isArray(messages)) { + res.status(400).json({ error: "Missing messages array" }); + return; + } + + const finalThreadId = threadId || `thread-${Date.now()}`; + const finalRunId = runId || `run-${Date.now()}-${Math.random().toString(36).substring(7)}`; + + const agent = getToolBasedGenerativeUiAgent(); + + const adapter = new CloudflareAgentsSDKAdapter({ + agent, + syncState: false, + trackSQL: false, + }); + + res.setHeader("Content-Type", "text/event-stream"); + res.setHeader("Cache-Control", "no-cache"); + res.setHeader("Connection", "keep-alive"); + + try { + const executionContext = { + threadId: finalThreadId, + runId: finalRunId, + ...context, + }; + + for await (const event of adapter.execute(messages, executionContext)) { + // Add threadId to event data for SSE stream (CopilotKit/Dojo requirement) + const eventWithThread = { ...event, threadId: finalThreadId }; + res.write(`event: ${event.type}\ndata: ${JSON.stringify(eventWithThread)}\n\n`); + } + + res.end(); + } catch (error) { + const errorEvent = { + type: "RUN_ERROR", + message: error instanceof Error ? error.message : "Unknown error", + threadId: finalThreadId, + timestamp: Date.now(), + }; + res.write( + `event: RUN_ERROR\ndata: ${JSON.stringify(errorEvent)}\n\n` + ); + res.end(); + } + } catch (error) { + res.status(500).json({ + error: error instanceof Error ? error.message : "Unknown error", + }); + } +} diff --git a/integrations/cloudflare/typescript/examples/src/config-loader.ts b/integrations/cloudflare/typescript/examples/src/config-loader.ts new file mode 100644 index 000000000..10e135847 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/config-loader.ts @@ -0,0 +1,71 @@ +/** + * Configuration loader for Cloudflare agents + * + * Reads cloudflare.json and provides utilities for agent discovery + * and dynamic route registration. + */ + +import { readFileSync } from "fs"; +import { join } from "path"; + +export interface AgentConfig { + path: string; + export: string; + description: string; + model: string; +} + +export interface CloudflareConfig { + dependencies: string[]; + agents: Record; + env: string; + server: { + port: number; + host: string; + }; +} + +/** + * Load cloudflare.json configuration + */ +export function loadConfig(): CloudflareConfig { + const configPath = join(process.cwd(), "cloudflare.json"); + const configContent = readFileSync(configPath, "utf-8"); + return JSON.parse(configContent); +} + +/** + * Get list of all agent names + */ +export function getAgentNames(config: CloudflareConfig): string[] { + return Object.keys(config.agents); +} + +/** + * Get agent configuration by name + */ +export function getAgentConfig(config: CloudflareConfig, agentName: string): AgentConfig | undefined { + return config.agents[agentName]; +} + +/** + * Dynamically import an agent getter function + */ +export async function loadAgentGetter(agentName: string, config: CloudflareConfig) { + const agentConfig = getAgentConfig(config, agentName); + if (!agentConfig) { + throw new Error(`Agent "${agentName}" not found in cloudflare.json`); + } + + // Import the module + const modulePath = agentConfig.path.replace("./src/", "../").replace(".ts", ".js"); + const module = await import(modulePath); + + // Get the getter function + const getterFunction = module[agentConfig.export]; + if (typeof getterFunction !== "function") { + throw new Error(`Export "${agentConfig.export}" is not a function in ${agentConfig.path}`); + } + + return getterFunction; +} diff --git a/integrations/cloudflare/typescript/examples/src/index.ts b/integrations/cloudflare/typescript/examples/src/index.ts new file mode 100644 index 000000000..e0575bf6e --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/index.ts @@ -0,0 +1,50 @@ +import * as dotenv from "dotenv"; +import express from "express"; +import cors from "cors"; +import { agenticChatHandler } from "./agents/agentic_chat/index.js"; +import { toolBasedGenerativeUiHandler } from "./agents/tool_based_generative_ui/index.js"; +import { agenticGenerativeUiHandler } from "./agents/agentic_generative_ui/index.js"; +import { toolBasedGenerativeUiSDKHandler } from "./agents/tool_based_generative_ui_sdk/index.js"; +import { sharedStateHandler } from "./agents/shared_state/index.js"; +import { backendToolRenderingHandler } from "./agents/backend_tool_rendering/index.js"; +import { humanInTheLoopHandler } from "./agents/human_in_the_loop/index.js"; + +// Load environment variables +dotenv.config(); + +const app = express(); +const PORT = process.env.PORT ? parseInt(process.env.PORT) : 4114; +const HOST = process.env.HOST || "0.0.0.0"; + +app.use(cors()); +app.use(express.json()); + +// Health check +app.get("/health", (req, res) => { + res.json({ + status: "ok", + integration: "cloudflare", + agents: [ + "agentic_chat", + "tool_based_generative_ui", + "agentic_generative_ui", + "tool_based_generative_ui_sdk", + "shared_state", + "backend_tool_rendering", + "human_in_the_loop" + ] + }); +}); + +// Agent routes +app.post("/agentic_chat", agenticChatHandler); +app.post("/tool_based_generative_ui", toolBasedGenerativeUiHandler); +app.post("/agentic_generative_ui", agenticGenerativeUiHandler); +app.post("/tool_based_generative_ui_sdk", toolBasedGenerativeUiSDKHandler); +app.post("/shared_state", sharedStateHandler); +app.post("/backend_tool_rendering", backendToolRenderingHandler); +app.post("/human_in_the_loop", humanInTheLoopHandler); + +app.listen(PORT, HOST, () => { + console.log(`Server running on http://${HOST}:${PORT}`); +}); diff --git a/integrations/cloudflare/typescript/examples/src/utils/agent-utils.ts b/integrations/cloudflare/typescript/examples/src/utils/agent-utils.ts new file mode 100644 index 000000000..d651a327f --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/utils/agent-utils.ts @@ -0,0 +1,139 @@ +/** + * Shared utilities for Cloudflare agent handlers + * Reduces code duplication across all agent implementations + */ + +import type { Request, Response } from "express"; +import type { BaseEvent } from "@ag-ui/core"; + +/** + * Extract or generate a threadId from the request + * Checks headers first, then falls back to generating a new one + */ +export function getOrCreateThreadId(req: Request): string { + return ( + (req.headers["x-thread-id"] as string) || + `thread-${Date.now()}-${Math.random().toString(36).substring(7)}` + ); +} + +/** + * Generate a unique runId + */ +export function generateRunId(): string { + return `run-${Date.now()}-${Math.random().toString(36).substring(7)}`; +} + +/** + * Add threadId to an AG-UI event + * Required for CopilotKit/Dojo conversation tracking + */ +export function addThreadIdToEvent(event: BaseEvent, threadId: string): BaseEvent & { threadId: string } { + return { ...event, threadId } as BaseEvent & { threadId: string }; +} + +/** + * Set standard SSE (Server-Sent Events) headers + * Used by all streaming agent endpoints + */ +export function setSSEHeaders(res: Response): void { + res.setHeader("Content-Type", "text/event-stream"); + res.setHeader("Cache-Control", "no-cache"); + res.setHeader("Connection", "keep-alive"); + res.setHeader("X-Accel-Buffering", "no"); // Disable nginx buffering +} + +/** + * Create a standardized error handler for SSE streams + * Ensures error events are properly formatted and sent + */ +export function createSSEErrorHandler( + res: Response, + threadId: string, + options?: { agentType?: string; runId?: string } +) { + return (error: unknown) => { + // Enhanced error logging with full context + console.error("Agent execution error:", { + agentType: options?.agentType || "unknown", + threadId, + runId: options?.runId, + error: error instanceof Error ? { + message: error.message, + stack: error.stack, + name: error.name, + } : error, + timestamp: new Date().toISOString(), + }); + + const errorEvent = { + type: "RUN_ERROR", + message: error instanceof Error ? error.message : "Unknown error", + threadId, + runId: options?.runId, + timestamp: Date.now(), + }; + + // Set headers if not already sent + if (!res.headersSent) { + setSSEHeaders(res); + } + + res.write(`event: RUN_ERROR\ndata: ${JSON.stringify(errorEvent)}\n\n`); + res.end(); + }; +} + +/** + * Validate request has required messages array + */ +export function validateMessagesRequest(req: Request, res: Response): boolean { + const { messages } = req.body; + + if (!messages || !Array.isArray(messages)) { + res.status(400).json({ + error: "Missing or invalid 'messages' array in request body" + }); + return false; + } + + return true; +} + +/** + * Create standard AG-UI input object from request + */ +export function createAgentInput(req: Request) { + const { messages, context, tools } = req.body; + const threadId = getOrCreateThreadId(req); + const runId = generateRunId(); + + return { + threadId, + runId, + messages, + tools: tools || [], + context: context ? [{ description: "Request context", value: JSON.stringify(context) }] : [], + state: {}, + forwardedProps: {}, + }; +} + +/** + * Write an event to SSE stream with proper formatting + */ +export function writeSSEEvent(res: Response, event: BaseEvent, threadId: string): void { + const eventWithThread = addThreadIdToEvent(event, threadId); + res.write(`event: ${event.type}\ndata: ${JSON.stringify(eventWithThread)}\n\n`); +} + +/** + * Handle client disconnect cleanup + */ +export function setupClientDisconnectHandler(req: Request, cleanup?: () => void): void { + req.on("close", () => { + if (cleanup) { + cleanup(); + } + }); +} diff --git a/integrations/cloudflare/typescript/examples/src/utils/tool-definitions.ts b/integrations/cloudflare/typescript/examples/src/utils/tool-definitions.ts new file mode 100644 index 000000000..6fe34f638 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/utils/tool-definitions.ts @@ -0,0 +1,317 @@ +/** + * Centralized tool definitions for Cloudflare agents + * Ensures consistency across agent implementations + */ + + +/** + * Todo Management Tools for Shared State Agent + * Using explicit tools instead of regex parsing for reliability + */ + +export const ADD_TODO_TOOL = { + name: "add_todo", + description: "Add a new item to the todo list. Use this when the user asks to add, create, or include a task.", + parameters: { + type: "object", + properties: { + text: { + type: "string", + description: "The todo item text/description", + minLength: 1, + }, + }, + required: ["text"], + }, +}; + +export const REMOVE_TODO_TOOL = { + name: "remove_todo", + description: "Remove an item from the todo list. Use this when the user asks to remove, delete, or drop a task.", + parameters: { + type: "object", + properties: { + text: { + type: "string", + description: "The text of the todo item to remove (partial match supported)", + }, + }, + required: ["text"], + }, +}; + +export const TOGGLE_TODO_TOOL = { + name: "toggle_todo", + description: "Mark a todo item as complete or incomplete. Use this when the user wants to check off or complete a task.", + parameters: { + type: "object", + properties: { + text: { + type: "string", + description: "The text of the todo item to toggle (partial match supported)", + }, + completed: { + type: "boolean", + description: "Whether the item should be marked as completed (true) or incomplete (false)", + }, + }, + required: ["text", "completed"], + }, +}; + +export const LIST_TODOS_TOOL = { + name: "list_todos", + description: "List all current todo items. Use this when the user asks to see, show, or list their tasks.", + parameters: { + type: "object", + properties: { + filter: { + type: "string", + description: "Optional filter: 'completed', 'incomplete', or 'all' (default)", + enum: ["completed", "incomplete", "all"], + }, + }, + }, +}; + +export const CLEAR_TODOS_TOOL = { + name: "clear_todos", + description: "Clear all completed todos or all todos. Use this when the user wants to clean up their list.", + parameters: { + type: "object", + properties: { + clearAll: { + type: "boolean", + description: "If true, clear all todos. If false, clear only completed todos.", + default: false, + }, + }, + }, +}; + +export const TODO_MANAGEMENT_TOOLS = [ + ADD_TODO_TOOL, + REMOVE_TODO_TOOL, + TOGGLE_TODO_TOOL, + LIST_TODOS_TOOL, + CLEAR_TODOS_TOOL, +]; + +/** + * Haiku generation tool for frontend rendering + * Used by: tool_based_generative_ui + */ +export const GENERATE_HAIKU_TOOL = { + name: "generate_haiku", + description: + "Generate a traditional Japanese haiku with English translations, including a themed image and background gradient.", + parameters: { + type: "object", + properties: { + japanese: { + type: "array", + description: "Three lines of a 5-7-5 haiku in Japanese.", + items: { type: "string" }, + minItems: 3, + maxItems: 3, + }, + english: { + type: "array", + description: "Three lines translating the haiku to English.", + items: { type: "string" }, + minItems: 3, + maxItems: 3, + }, + image_name: { + type: "string", + description: "Image filename for the haiku background (e.g., 'cherry-blossoms.jpg')", + }, + gradient: { + type: "string", + description: "CSS gradient string for styling (e.g., 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)')", + }, + }, + required: ["japanese", "english", "image_name", "gradient"], + }, +}; + +/** + * Task steps generation tool for human-in-the-loop approval + * Used by: human_in_the_loop + */ +export const GENERATE_TASK_STEPS_TOOL = { + name: "generate_task_steps", + description: "Present task steps to the user for review and approval before execution.", + parameters: { + type: "object", + properties: { + steps: { + type: "array", + description: "List of task steps for user to review", + items: { + type: "object", + properties: { + description: { + type: "string", + description: "Clear description of the task step" + }, + enabled: { + type: "boolean", + description: "Whether this step is enabled by default" + } + }, + required: ["description", "enabled"] + }, + minItems: 1 + }, + title: { + type: "string", + description: "Title for the task plan" + } + }, + required: ["steps"] + }, +}; + +/** + * Weather display tool for backend-rendered UI + * Used by: backend_tool_rendering + */ +export const SHOW_WEATHER_TOOL = { + name: "show_weather", + description: "Display weather information in a rich UI card with temperature, conditions, and forecast.", + parameters: { + type: "object", + properties: { + location: { + type: "string", + description: "City name or location" + }, + temperature: { + type: "number", + description: "Temperature in Celsius" + }, + condition: { + type: "string", + description: "Weather condition (sunny, cloudy, rainy, etc.)", + enum: ["sunny", "cloudy", "rainy", "snowy", "windy", "foggy"] + }, + humidity: { + type: "number", + description: "Humidity percentage (0-100)", + minimum: 0, + maximum: 100 + }, + windSpeed: { + type: "number", + description: "Wind speed in km/h" + } + }, + required: ["location", "temperature", "condition"] + }, +}; + +/** + * Stock price display tool for backend-rendered UI + * Used by: backend_tool_rendering + */ +export const SHOW_STOCK_TOOL = { + name: "show_stock", + description: "Display stock prices with charts and market data in a rich UI component.", + parameters: { + type: "object", + properties: { + symbol: { + type: "string", + description: "Stock ticker symbol (e.g., AAPL, GOOGL)" + }, + price: { + type: "number", + description: "Current stock price" + }, + change: { + type: "number", + description: "Price change amount" + }, + changePercent: { + type: "number", + description: "Price change percentage" + }, + volume: { + type: "number", + description: "Trading volume" + }, + marketCap: { + type: "string", + description: "Market capitalization (e.g., '2.5T', '100B')" + } + }, + required: ["symbol", "price", "change", "changePercent"] + }, +}; + +/** + * Calendar event display tool for backend-rendered UI + * Used by: backend_tool_rendering + */ +export const SHOW_CALENDAR_TOOL = { + name: "show_calendar", + description: "Display calendar events in a rich UI timeline component.", + parameters: { + type: "object", + properties: { + events: { + type: "array", + description: "List of calendar events", + items: { + type: "object", + properties: { + title: { type: "string" }, + start: { type: "string", description: "ISO 8601 datetime" }, + end: { type: "string", description: "ISO 8601 datetime" }, + location: { type: "string" }, + description: { type: "string" } + }, + required: ["title", "start"] + } + }, + viewMode: { + type: "string", + description: "Calendar view mode", + enum: ["day", "week", "month"], + default: "week" + } + }, + required: ["events"] + }, +}; + +/** + * Helper to ensure a specific tool is included in the tools array + */ +export function ensureTool(tools: any[] | undefined, toolToAdd: any): any[] { + const normalized = Array.isArray(tools) ? [...tools] : []; + + const hasTool = normalized.some((tool) => { + if (!tool) return false; + if (tool.name === toolToAdd.name) return true; + return tool.function?.name === toolToAdd.name; + }); + + if (!hasTool) { + normalized.push(toolToAdd); + } + + return normalized; +} + +/** + * Helper to ensure multiple tools are included + */ +export function ensureTools(tools: any[] | undefined, toolsToAdd: any[]): any[] { + let result = tools || []; + for (const tool of toolsToAdd) { + result = ensureTool(result, tool); + } + return result; +} diff --git a/integrations/cloudflare/typescript/examples/src/utils/validation.ts b/integrations/cloudflare/typescript/examples/src/utils/validation.ts new file mode 100644 index 000000000..74922d8db --- /dev/null +++ b/integrations/cloudflare/typescript/examples/src/utils/validation.ts @@ -0,0 +1,295 @@ +/** + * Input validation utilities for tool parameters and request data + * Ensures data integrity and prevents errors from malformed inputs + */ + +/** + * Validation error with detailed context + */ +export class ValidationError extends Error { + constructor( + message: string, + public field: string, + public value: any, + public constraint: string + ) { + super(message); + this.name = "ValidationError"; + } +} + +/** + * Validation result + */ +export interface ValidationResult { + valid: boolean; + errors: ValidationError[]; +} + +/** + * Schema definition for validation + */ +export interface Schema { + type: "object" | "array" | "string" | "number" | "boolean"; + properties?: Record; + items?: Schema; + required?: string[]; + minLength?: number; + maxLength?: number; + minimum?: number; + maximum?: number; + enum?: any[]; + pattern?: RegExp; +} + +/** + * Validate a value against a schema + */ +export function validate( + value: any, + schema: Schema, + fieldPath: string = "root" +): ValidationResult { + const errors: ValidationError[] = []; + + // Type validation + const actualType = Array.isArray(value) ? "array" : typeof value; + if (actualType !== schema.type && value !== null && value !== undefined) { + errors.push( + new ValidationError( + `Expected type ${schema.type}, got ${actualType}`, + fieldPath, + value, + "type" + ) + ); + return { valid: false, errors }; + } + + // Null/undefined handling + if (value === null || value === undefined) { + return { valid: true, errors: [] }; + } + + // String validation + if (schema.type === "string") { + if (typeof value !== "string") { + errors.push( + new ValidationError( + `Expected string, got ${typeof value}`, + fieldPath, + value, + "type" + ) + ); + } else { + if (schema.minLength !== undefined && value.length < schema.minLength) { + errors.push( + new ValidationError( + `String length ${value.length} is less than minimum ${schema.minLength}`, + fieldPath, + value, + "minLength" + ) + ); + } + if (schema.maxLength !== undefined && value.length > schema.maxLength) { + errors.push( + new ValidationError( + `String length ${value.length} exceeds maximum ${schema.maxLength}`, + fieldPath, + value, + "maxLength" + ) + ); + } + if (schema.pattern && !schema.pattern.test(value)) { + errors.push( + new ValidationError( + `String does not match pattern ${schema.pattern}`, + fieldPath, + value, + "pattern" + ) + ); + } + if (schema.enum && !schema.enum.includes(value)) { + errors.push( + new ValidationError( + `Value must be one of: ${schema.enum.join(", ")}`, + fieldPath, + value, + "enum" + ) + ); + } + } + } + + // Number validation + if (schema.type === "number") { + if (typeof value !== "number") { + errors.push( + new ValidationError( + `Expected number, got ${typeof value}`, + fieldPath, + value, + "type" + ) + ); + } else { + if (schema.minimum !== undefined && value < schema.minimum) { + errors.push( + new ValidationError( + `Value ${value} is less than minimum ${schema.minimum}`, + fieldPath, + value, + "minimum" + ) + ); + } + if (schema.maximum !== undefined && value > schema.maximum) { + errors.push( + new ValidationError( + `Value ${value} exceeds maximum ${schema.maximum}`, + fieldPath, + value, + "maximum" + ) + ); + } + } + } + + // Object validation + if (schema.type === "object" && schema.properties) { + if (typeof value !== "object" || Array.isArray(value)) { + errors.push( + new ValidationError( + `Expected object, got ${Array.isArray(value) ? "array" : typeof value}`, + fieldPath, + value, + "type" + ) + ); + } else { + // Check required fields + if (schema.required) { + for (const requiredField of schema.required) { + if (!(requiredField in value)) { + errors.push( + new ValidationError( + `Required field missing`, + `${fieldPath}.${requiredField}`, + undefined, + "required" + ) + ); + } + } + } + + // Validate each property + for (const [key, propSchema] of Object.entries(schema.properties)) { + if (key in value) { + const result = validate(value[key], propSchema, `${fieldPath}.${key}`); + errors.push(...result.errors); + } + } + } + } + + // Array validation + if (schema.type === "array" && schema.items) { + if (!Array.isArray(value)) { + errors.push( + new ValidationError( + `Expected array, got ${typeof value}`, + fieldPath, + value, + "type" + ) + ); + } else { + value.forEach((item, index) => { + const result = validate(item, schema.items!, `${fieldPath}[${index}]`); + errors.push(...result.errors); + }); + } + } + + return { + valid: errors.length === 0, + errors, + }; +} + +/** + * Validate tool parameters against tool definition + */ +export function validateToolParameters( + toolName: string, + parameters: any, + toolDefinition: any +): ValidationResult { + if (!toolDefinition.parameters) { + return { valid: true, errors: [] }; + } + + const schema: Schema = { + type: toolDefinition.parameters.type || "object", + properties: toolDefinition.parameters.properties || {}, + required: toolDefinition.parameters.required || [], + }; + + const result = validate(parameters, schema, toolName); + + if (!result.valid) { + console.warn(`Validation failed for tool "${toolName}":`, result.errors); + } + + return result; +} + +/** + * Sanitize string input (remove null bytes, trim whitespace) + */ +export function sanitizeString(input: string): string { + return input.replace(/\0/g, "").trim(); +} + +/** + * Sanitize todo text specifically + */ +export function sanitizeTodoText(text: string): string { + const sanitized = sanitizeString(text); + + // Limit length + const maxLength = 500; + if (sanitized.length > maxLength) { + return sanitized.substring(0, maxLength); + } + + return sanitized; +} + +/** + * Validate and sanitize todo item + */ +export function validateTodoItem(text: string): { valid: boolean; sanitized: string; error?: string } { + if (!text || typeof text !== "string") { + return { valid: false, sanitized: "", error: "Todo text must be a non-empty string" }; + } + + const sanitized = sanitizeTodoText(text); + + if (sanitized.length === 0) { + return { valid: false, sanitized: "", error: "Todo text cannot be empty" }; + } + + if (sanitized.length < 1) { + return { valid: false, sanitized, error: "Todo text must be at least 1 character" }; + } + + return { valid: true, sanitized }; +} diff --git a/integrations/cloudflare/typescript/examples/tsconfig.json b/integrations/cloudflare/typescript/examples/tsconfig.json new file mode 100644 index 000000000..2415c3a31 --- /dev/null +++ b/integrations/cloudflare/typescript/examples/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "lib": ["ES2020"], + "moduleResolution": "bundler", + "esModuleInterop": true, + "skipLibCheck": true, + "strict": true, + "resolveJsonModule": true, + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/integrations/cloudflare/typescript/jest.config.js b/integrations/cloudflare/typescript/jest.config.js new file mode 100644 index 000000000..192a82f6d --- /dev/null +++ b/integrations/cloudflare/typescript/jest.config.js @@ -0,0 +1,12 @@ +module.exports = { + preset: 'ts-jest', + testEnvironment: 'node', + roots: ['/src'], + testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'], + moduleFileExtensions: ['ts', 'js', 'json'], + collectCoverageFrom: [ + 'src/**/*.ts', + '!src/**/*.d.ts', + '!src/**/__tests__/**', + ], +}; diff --git a/integrations/cloudflare/typescript/package.json b/integrations/cloudflare/typescript/package.json new file mode 100644 index 000000000..5169cadab --- /dev/null +++ b/integrations/cloudflare/typescript/package.json @@ -0,0 +1,59 @@ +{ + "name": "@ag-ui/cloudflare", + "version": "0.1.1", + "license": "Apache-2.0", + "description": "AG-UI protocol implementation for Cloudflare (Workers AI, Workers Runtime, Agents SDK)", + "author": "Audrey Klammer ", + "repository": { + "type": "git", + "url": "https://github.com/ag-ui-protocol/ag-ui.git", + "directory": "integrations/cloudflare/typescript" + }, + "main": "./dist/index.js", + "module": "./dist/index.mjs", + "types": "./dist/index.d.ts", + "exports": { + ".": { + "types": "./dist/index.d.ts", + "import": "./dist/index.mjs", + "require": "./dist/index.js" + } + }, + "sideEffects": false, + "scripts": { + "build": "tsup", + "dev": "tsup --watch", + "clean": "rm -rf dist .turbo node_modules", + "typecheck": "tsc --noEmit", + "test": "jest" + }, + "peerDependencies": { + "@ag-ui/core": "workspace:*", + "@ag-ui/client": "workspace:*", + "@copilotkit/runtime": "^1.0.0", + "agents": "^0.1.0" + }, + "peerDependenciesMeta": { + "@copilotkit/runtime": { + "optional": true + }, + "agents": { + "optional": true + } + }, + "dependencies": { + "eventsource-parser": "^2.0.1", + "rxjs": "7.8.1", + "uuid": "^11.1.0", + "zod": "^3.23.8" + }, + "devDependencies": { + "@ag-ui/core": "workspace:*", + "@ag-ui/client": "workspace:*", + "@cloudflare/workers-types": "^4.20251011.0", + "@types/node": "^20.0.0", + "typescript": "^5.4.0", + "tsup": "^8.0.0", + "jest": "^29.0.0" + } +} diff --git a/integrations/cloudflare/typescript/src/adapter.ts b/integrations/cloudflare/typescript/src/adapter.ts new file mode 100644 index 000000000..5ea9ea294 --- /dev/null +++ b/integrations/cloudflare/typescript/src/adapter.ts @@ -0,0 +1,459 @@ +import { CloudflareAIClient } from "./client"; +import { + EventType, + type BaseEvent, + type RunStartedEvent, + type RunFinishedEvent, + type RunErrorEvent, + type TextMessageStartEvent, + type TextMessageContentEvent, + type TextMessageEndEvent, + type ToolCallStartEvent, + type ToolCallArgsEvent, + type ToolCallEndEvent, + type CustomEvent, +} from "@ag-ui/core"; +import { CloudflareAIConfig, CloudflareMessage, CloudflareModel, Tool, CloudflareCompletionOptions } from "./types"; +import type { + CopilotRuntimeChatCompletionRequest, + CopilotRuntimeChatCompletionResponse, + CopilotServiceAdapter, +} from "@copilotkit/runtime"; +import { v4 as uuidv4 } from "uuid"; + +export interface CloudflareAGUIAdapterOptions extends CloudflareAIConfig { + systemPrompt?: string; + tools?: Tool[]; + streamingEnabled?: boolean; +} + +export interface AGUIProtocol { + execute(messages: CloudflareMessage[], context?: Record): AsyncGenerator; +} + +export type StreamableResult = AsyncGenerator; + +export class CloudflareAGUIAdapter implements AGUIProtocol, CopilotServiceAdapter { + private client: CloudflareAIClient; + private options: CloudflareAGUIAdapterOptions; + private runCounter = 0; + + constructor(options: CloudflareAGUIAdapterOptions) { + this.options = options; + this.client = new CloudflareAIClient(options); + } + + // CopilotKit ServiceAdapter interface implementation + // CopilotKit v1.10+ expects adapters to handle streaming - it doesn't do it automatically + async process( + request: CopilotRuntimeChatCompletionRequest, + ): Promise { + // Generate a unique thread ID if not provided + const threadId = + request.threadId || `thread-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`; + const runId = this.generateRunId(); + + // Convert CopilotKit messages to Cloudflare format + // Note: Using any here because CopilotKit Message type may vary between versions + const messages: CloudflareMessage[] = request.messages.map((msg: any) => ({ + role: msg.role as "user" | "assistant" | "system", + content: msg.content || msg.text || "", + })); + + // Reuse the execute() streaming logic to maintain consistent behavior + // This ensures CopilotKit receives proper AG-UI event streams + const stream = this.execute(messages, { threadId, runId }); + + // Return response with stream - CopilotKit will consume these events + // and maintain thread state based on the threadId/runId in the events + return { + threadId, + runId, + stream, // ✅ Stream AG-UI events to CopilotKit + } as CopilotRuntimeChatCompletionResponse; + } + + async *execute( + messages: CloudflareMessage[], + context?: Record, + ): AsyncGenerator { + const threadId = context?.threadId || `thread-${Date.now()}`; + const runId = context?.runId || this.generateRunId(); + + try { + // Emit run started event + const runStarted: RunStartedEvent = { + type: EventType.RUN_STARTED, + threadId, + runId, + timestamp: Date.now(), + }; + yield runStarted; + + // Add system prompt if configured + const allMessages = this.options.systemPrompt + ? [{ role: "system" as const, content: this.options.systemPrompt }, ...messages] + : messages; + + const completionOptions: CloudflareCompletionOptions = { + messages: allMessages, + model: this.options.model, + tools: this.options.tools, + stream: this.options.streamingEnabled !== false, + }; + + if (this.options.streamingEnabled !== false) { + yield* this.handleStreaming(completionOptions); + } else { + yield* this.handleNonStreaming(completionOptions); + } + + // Emit run finished event + const runFinished: RunFinishedEvent = { + type: EventType.RUN_FINISHED, + threadId, + runId, + timestamp: Date.now(), + }; + yield runFinished; + } catch (error) { + // ✅ Enhanced error logging with full context + console.error("CloudflareAGUIAdapter execution error:", { + threadId, + runId, + error: error instanceof Error ? { + message: error.message, + stack: error.stack, + name: error.name, + } : error, + timestamp: new Date().toISOString(), + }); + + // Emit error event + const runError: RunErrorEvent = { + type: EventType.RUN_ERROR, + message: error instanceof Error ? error.message : "Unknown error", + timestamp: Date.now(), + }; + yield runError; + throw error; + } + } + + private async *handleStreaming( + options: CloudflareCompletionOptions, + ): AsyncGenerator { + let messageStarted = false; + let currentMessageId: string | null = null; + const toolCallsInProgress = new Set(); + let messageEnded = false; + + for await (const chunk of this.client.streamComplete(options)) { + // Handle text content + if (chunk.response) { + if (!messageStarted) { + currentMessageId = uuidv4(); + const textStart: TextMessageStartEvent = { + type: EventType.TEXT_MESSAGE_START, + messageId: currentMessageId, + role: "assistant", + timestamp: Date.now(), + }; + yield textStart; + messageStarted = true; + messageEnded = false; + } + const textContent: TextMessageContentEvent = { + type: EventType.TEXT_MESSAGE_CONTENT, + messageId: currentMessageId!, + delta: chunk.response, + timestamp: Date.now(), + }; + yield textContent; + } + + // Handle tool calls + if (chunk.tool_calls) { + for (const toolCall of chunk.tool_calls) { + const toolCallId = toolCall.id ?? ""; + const toolName = toolCall.function?.name ?? "tool"; + + if (!toolCallId) { + continue; + } + + if (!toolCallsInProgress.has(toolCallId)) { + // New tool call + const toolStart: ToolCallStartEvent = { + type: EventType.TOOL_CALL_START, + toolCallId, + toolCallName: toolName, + timestamp: Date.now(), + }; + yield toolStart; + toolCallsInProgress.add(toolCallId); + } + + // Stream tool call arguments + const rawArguments = toolCall.function?.arguments; + if (rawArguments !== undefined && rawArguments !== null) { + const args = + typeof rawArguments === "string" + ? rawArguments + : JSON.stringify(rawArguments); + + if (args.length > 0) { + const toolArgs: ToolCallArgsEvent = { + type: EventType.TOOL_CALL_ARGS, + toolCallId, + delta: args, + timestamp: Date.now(), + }; + yield toolArgs; + } + } + } + } + + // Handle completion + if (chunk.done) { + if (messageStarted && currentMessageId) { + if (!messageEnded) { + const textEnd: TextMessageEndEvent = { + type: EventType.TEXT_MESSAGE_END, + messageId: currentMessageId, + timestamp: Date.now(), + }; + yield textEnd; + messageEnded = true; + } + messageStarted = false; + } + + // End all tool calls + for (const toolCallId of toolCallsInProgress) { + const toolEnd: ToolCallEndEvent = { + type: EventType.TOOL_CALL_END, + toolCallId, + timestamp: Date.now(), + }; + yield toolEnd; + } + toolCallsInProgress.clear(); + + // Emit usage metadata if available + if (chunk.usage) { + const metadata: CustomEvent = { + type: EventType.CUSTOM, + name: "usage_metadata", + value: { + usage: chunk.usage, + model: options.model, + }, + timestamp: Date.now(), + }; + yield metadata; + } + } + } + } + + private async *handleNonStreaming( + options: CloudflareCompletionOptions, + ): AsyncGenerator { + const response = await this.client.complete(options); + + // Emit text message events + if (response.content) { + const messageId = uuidv4(); + + const textStart: TextMessageStartEvent = { + type: EventType.TEXT_MESSAGE_START, + messageId, + role: "assistant", + timestamp: Date.now(), + }; + yield textStart; + + const textContent: TextMessageContentEvent = { + type: EventType.TEXT_MESSAGE_CONTENT, + messageId, + delta: response.content, + timestamp: Date.now(), + }; + yield textContent; + + const textEnd: TextMessageEndEvent = { + type: EventType.TEXT_MESSAGE_END, + messageId, + timestamp: Date.now(), + }; + yield textEnd; + } + + // Emit tool call events + if (response.tool_calls) { + for (const toolCall of response.tool_calls) { + const toolStart: ToolCallStartEvent = { + type: EventType.TOOL_CALL_START, + toolCallId: toolCall.id, + toolCallName: toolCall.function.name, + timestamp: Date.now(), + }; + yield toolStart; + + const args = + typeof toolCall.function.arguments === "string" + ? toolCall.function.arguments + : JSON.stringify(toolCall.function.arguments); + + const toolArgs: ToolCallArgsEvent = { + type: EventType.TOOL_CALL_ARGS, + toolCallId: toolCall.id, + delta: args, + timestamp: Date.now(), + }; + yield toolArgs; + + const toolEnd: ToolCallEndEvent = { + type: EventType.TOOL_CALL_END, + toolCallId: toolCall.id, + timestamp: Date.now(), + }; + yield toolEnd; + } + } + } + + async *executeWithTools( + messages: CloudflareMessage[], + tools: Tool[], + context?: Record, + ): AsyncGenerator { + const updatedOptions = { ...this.options, tools }; + const adapter = new CloudflareAGUIAdapter(updatedOptions); + yield* adapter.execute(messages, context); + } + + async *progressiveGeneration( + prompt: string, + stages: Array<{ name: string; instruction: string }>, + ): AsyncGenerator { + const threadId = `thread-${Date.now()}`; + const runId = this.generateRunId(); + + const runStarted: RunStartedEvent = { + type: EventType.RUN_STARTED, + threadId, + runId, + timestamp: Date.now(), + }; + yield runStarted; + + let allContent = ""; + const totalStages = stages.length; + + for (let i = 0; i < stages.length; i++) { + const stage = stages[i]; + + // Emit progress event + const progress: CustomEvent = { + type: EventType.CUSTOM, + name: "progress", + value: { + progress: ((i + 1) / totalStages) * 100, + message: `Processing: ${stage.name}`, + }, + timestamp: Date.now(), + }; + yield progress; + + // Build progressive prompt with context from previous stages + const stagePrompt = + i === 0 + ? `${prompt}\n\n${stage.instruction}` + : `${prompt}\n\nPrevious research/content:\n${allContent}\n\nNow, ${stage.instruction}`; + + const messages: CloudflareMessage[] = [{ role: "user", content: stagePrompt }]; + + // Configure completion options + const completionOptions: CloudflareCompletionOptions = { + messages, + model: this.options.model, + stream: true, + }; + + // Generate content for this stage + const messageId = uuidv4(); + const textStart: TextMessageStartEvent = { + type: EventType.TEXT_MESSAGE_START, + messageId, + role: "assistant", + timestamp: Date.now(), + }; + yield textStart; + + let stageContent = ""; + + // Stream content directly from Cloudflare + for await (const chunk of this.client.streamComplete(completionOptions)) { + if (chunk.response) { + const textContent: TextMessageContentEvent = { + type: EventType.TEXT_MESSAGE_CONTENT, + messageId, + delta: chunk.response, + timestamp: Date.now(), + }; + yield textContent; + stageContent += chunk.response; + } + + if (chunk.done && chunk.usage) { + const metadata: CustomEvent = { + type: EventType.CUSTOM, + name: "stage_metadata", + value: { + stage: stage.name, + usage: chunk.usage, + }, + timestamp: Date.now(), + }; + yield metadata; + } + } + + allContent += `\n\n## ${stage.name}\n\n${stageContent}`; + + const textEnd: TextMessageEndEvent = { + type: EventType.TEXT_MESSAGE_END, + messageId, + timestamp: Date.now(), + }; + yield textEnd; + } + + const runFinished: RunFinishedEvent = { + type: EventType.RUN_FINISHED, + threadId, + runId, + timestamp: Date.now(), + }; + yield runFinished; + } + + setModel(model: CloudflareModel): void { + this.options.model = model; + } + + getCapabilities() { + return this.client.getModelCapabilities(this.options.model || "@cf/meta/llama-3.1-8b-instruct"); + } + + async listAvailableModels(): Promise { + return this.client.listModels(); + } + + private generateRunId(): string { + return `cf-run-${Date.now()}-${++this.runCounter}`; + } +} diff --git a/integrations/cloudflare/typescript/src/agents-sdk-adapter.ts b/integrations/cloudflare/typescript/src/agents-sdk-adapter.ts new file mode 100644 index 000000000..d736b2839 --- /dev/null +++ b/integrations/cloudflare/typescript/src/agents-sdk-adapter.ts @@ -0,0 +1,710 @@ +/** + * Cloudflare Agents SDK Integration for AG-UI + * + * Bridges the Cloudflare Agents SDK with AG-UI protocol, enabling + * stateful agents with built-in SQL, state management, and scheduling + * to work seamlessly with CopilotKit and other AG-UI frontends. + */ + +import { + EventType, + type BaseEvent, + type TextMessageStartEvent, + type TextMessageContentEvent, + type TextMessageEndEvent, + type ToolCallStartEvent, + type ToolCallArgsEvent, + type ToolCallEndEvent, + type ToolCallResultEvent, + type RunStartedEvent, + type RunFinishedEvent, + type RunErrorEvent, + type StateSnapshotEvent, + type CustomEvent, +} from "@ag-ui/core"; +import { v4 as uuidv4 } from "uuid"; +import type { CloudflareMessage } from "./types"; + +/** + * Base interface for Cloudflare Agents SDK Agent class + * This represents the Agent class from 'agents' package + */ +export interface CloudflareAgentsSDKAgent { + /** Agent instance ID */ + id: string; + + /** Set agent state (syncs with clients) */ + setState(state: Record): Promise; + + /** Get current agent state */ + getState(): Record; + + /** Execute SQL queries on agent's embedded database */ + sql(query: TemplateStringsArray, ...values: any[]): Promise; + + /** Schedule a task to run later */ + schedule(when: string | Date | number, callback: string, data?: any): Promise; + + /** Handle HTTP requests */ + onRequest?(request: Request): Promise; + + /** Handle WebSocket connections */ + onConnect?(websocket: WebSocket): void; + + /** Handle WebSocket messages */ + onMessage?(websocket: WebSocket, message: string | ArrayBuffer): void; + + /** Handle WebSocket close */ + onClose?(websocket: WebSocket, code: number, reason: string, wasClean: boolean): void; + + /** Handle chat messages (AIChatAgent) */ + onChatMessage?(message: string, context: any): AsyncGenerator; +} + +/** + * Options for creating an Agents SDK adapter + */ +export interface AgentsSDKAdapterOptions { + /** Agent instance to wrap */ + agent: CloudflareAgentsSDKAgent; + + /** Enable state synchronization via AG-UI events */ + syncState?: boolean; + + /** Emit SQL queries as metadata events */ + trackSQL?: boolean; + + /** Custom event transformer */ + transformEvent?: (event: AgentsSDKChunk) => BaseEvent | null; + + /** Thread ID for conversation tracking */ + threadId?: string; + + /** Run ID for execution tracking */ + runId?: string; +} + +/** + * Adapter that wraps a Cloudflare Agent and exposes AG-UI protocol + * + * @example + * ```typescript + * import { Agent } from 'agents'; + * import { CloudflareAgentsSDKAdapter } from 'ag-ui-cloudflare'; + * + * export class MyAgent extends Agent { + * async onChatMessage(message: string) { + * await this.setState({ thinking: true }); + * const result = await this.ai.chat(message); + * await this.sql`INSERT INTO history VALUES (${message}, ${result})`; + * return result; + * } + * } + * + * // In your Worker + * const agent = new MyAgent(state, env); + * const adapter = new CloudflareAgentsSDKAdapter({ agent }); + * + * for await (const event of adapter.execute(messages)) { + * // Stream AG-UI events + * } + * ``` + */ +/** + * Chunk types that can be received from Agents SDK + */ +interface AgentsSDKChunk { + type?: "text" | "tool_call" | "tool_call_delta" | "tool_call_result" | "interrupt" | "state"; + content?: string; + toolCall?: { + id: string; + name: string; + args?: any; + argsChunk?: string; + done?: boolean; + }; + interrupt?: { + name: string; + value: any; + }; + state?: Record; +} + +export class CloudflareAgentsSDKAdapter { + private agent: CloudflareAgentsSDKAgent; + private options: AgentsSDKAdapterOptions; + private runCounter = 0; + private stateListeners: Set<(state: any) => void> = new Set(); + private currentMessageId: string | null = null; + private currentMessageType: "text" | "tool_call" | null = null; + private currentToolCallId: string | null = null; + private currentToolCallName: string | null = null; + private runPaused = false; + + constructor(options: AgentsSDKAdapterOptions) { + this.agent = options.agent; + this.options = options; + + // Set up state sync if enabled + if (options.syncState) { + this.setupStateSync(); + } + } + + /** + * Execute agent with AG-UI protocol + */ + async *execute( + messages: CloudflareMessage[], + context?: Record, + ): AsyncGenerator { + const threadId = context?.threadId || this.options.threadId || `thread-${Date.now()}`; + const runId = context?.runId || this.options.runId || this.generateRunId(); + + try { + // Emit run started + const runStarted: RunStartedEvent = { + type: EventType.RUN_STARTED, + threadId, + runId, + timestamp: Date.now(), + }; + yield runStarted; + + // Get initial state + if (this.options.syncState) { + const initialState = this.agent.getState(); + const stateSnapshot: StateSnapshotEvent = { + type: EventType.STATE_SNAPSHOT, + snapshot: initialState, + timestamp: Date.now(), + }; + yield stateSnapshot; + } + + // Check if agent has onChatMessage (AIChatAgent) + if (typeof (this.agent as any).onChatMessage === "function") { + yield* this.handleChatAgent(messages, context); + } else { + // Handle as generic agent + yield* this.handleGenericAgent(messages, context); + } + + // Emit final state if changed + if (this.options.syncState) { + const finalState = this.agent.getState(); + const stateSnapshot: StateSnapshotEvent = { + type: EventType.STATE_SNAPSHOT, + snapshot: finalState, + timestamp: Date.now(), + }; + yield stateSnapshot; + } + + // Only emit RUN_FINISHED if run wasn't paused (HITL) + if (!this.runPaused) { + const runFinished: RunFinishedEvent = { + type: EventType.RUN_FINISHED, + threadId, + runId, + timestamp: Date.now(), + }; + yield runFinished; + } + + // Reset pause flag for next run + this.runPaused = false; + } catch (error) { + const runError: RunErrorEvent = { + type: EventType.RUN_ERROR, + message: error instanceof Error ? error.message : "Unknown error", + timestamp: Date.now(), + }; + yield runError; + throw error; + } + } + + /** + * Handle AIChatAgent (has onChatMessage method) + * Enhanced to support tool calls, interrupts, and proper event streaming + * Pattern inspired by LangGraph's handleSingleEvent + */ + private async *handleChatAgent( + messages: CloudflareMessage[], + context?: Record, + ): AsyncGenerator { + const lastMessage = messages[messages.length - 1]; + + if (!lastMessage || lastMessage.role !== "user") { + throw new Error("Last message must be from user"); + } + + // Reset message tracking + this.currentMessageId = null; + this.currentMessageType = null; + this.currentToolCallId = null; + this.currentToolCallName = null; + + // Stream from agent's onChatMessage + const agent = this.agent as any; + const stream = agent.onChatMessage(lastMessage.content, { + messages, + ...context, + }); + + for await (const chunk of stream) { + // Handle different chunk types + yield* this.handleSingleChunk(chunk); + } + + // End any message in progress + if (this.currentMessageType === "text" && this.currentMessageId) { + const textEnd: TextMessageEndEvent = { + type: EventType.TEXT_MESSAGE_END, + messageId: this.currentMessageId, + timestamp: Date.now(), + }; + yield textEnd; + } else if (this.currentMessageType === "tool_call" && this.currentToolCallId) { + const toolEnd: ToolCallEndEvent = { + type: EventType.TOOL_CALL_END, + toolCallId: this.currentToolCallId, + timestamp: Date.now(), + }; + yield toolEnd; + } + this.currentMessageId = null; + this.currentMessageType = null; + this.currentToolCallId = null; + this.currentToolCallName = null; + } + + /** + * Handle a single chunk from the Agents SDK stream + * Detects and emits appropriate AG-UI events + */ + private async *handleSingleChunk( + chunk: any, + ): AsyncGenerator { + // Normalize chunk to our interface + const normalizedChunk = this.normalizeChunk(chunk); + + // Handle tool call start (only if not done) + if (normalizedChunk.type === "tool_call" && normalizedChunk.toolCall && !normalizedChunk.toolCall.done) { + const { id, name } = normalizedChunk.toolCall; + + // End any text message in progress + if (this.currentMessageType === "text" && this.currentMessageId) { + const textEnd: TextMessageEndEvent = { + type: EventType.TEXT_MESSAGE_END, + messageId: this.currentMessageId, + timestamp: Date.now(), + }; + yield textEnd; + } + + // Start tool call only if not already started + if (this.currentToolCallId !== id) { + const toolStart: ToolCallStartEvent = { + type: EventType.TOOL_CALL_START, + toolCallId: id, + toolCallName: name, + timestamp: Date.now(), + }; + yield toolStart; + + this.currentMessageId = this.generateMessageId(); + this.currentMessageType = "tool_call"; + this.currentToolCallId = id; + this.currentToolCallName = name; + } + } + + // Handle tool call arguments (delta) + if (normalizedChunk.type === "tool_call_delta" && normalizedChunk.toolCall) { + if (this.currentMessageType === "tool_call" && this.currentToolCallId) { + const argsChunk = normalizedChunk.toolCall.argsChunk || ""; + + const toolArgs: ToolCallArgsEvent = { + type: EventType.TOOL_CALL_ARGS, + toolCallId: this.currentToolCallId, + delta: argsChunk, + timestamp: Date.now(), + }; + yield toolArgs; + } + } + + // Handle tool call end + if (normalizedChunk.type === "tool_call" && normalizedChunk.toolCall?.done) { + if (this.currentMessageType === "tool_call" && this.currentToolCallId) { + // If we have accumulated args, emit them as final args + if (normalizedChunk.toolCall.args) { + const argsString = typeof normalizedChunk.toolCall.args === "string" + ? normalizedChunk.toolCall.args + : JSON.stringify(normalizedChunk.toolCall.args); + + const toolArgs: ToolCallArgsEvent = { + type: EventType.TOOL_CALL_ARGS, + toolCallId: this.currentToolCallId, + delta: argsString, + timestamp: Date.now(), + }; + yield toolArgs; + } + + const toolEnd: ToolCallEndEvent = { + type: EventType.TOOL_CALL_END, + toolCallId: this.currentToolCallId, + timestamp: Date.now(), + }; + yield toolEnd; + this.currentMessageType = null; + this.currentToolCallId = null; + this.currentToolCallName = null; + } + } + + // Handle tool call result + if (normalizedChunk.type === "tool_call_result" && normalizedChunk.toolCall) { + const result = typeof normalizedChunk.toolCall.args === "string" + ? normalizedChunk.toolCall.args + : JSON.stringify(normalizedChunk.toolCall.args); + + const messageId = uuidv4(); + const toolResult: ToolCallResultEvent = { + type: EventType.TOOL_CALL_RESULT, + messageId, + toolCallId: normalizedChunk.toolCall.id, + content: result, + timestamp: Date.now(), + }; + yield toolResult; + } + + // Handle interrupt (requiresApproval, human-in-the-loop) + if (normalizedChunk.type === "interrupt" && normalizedChunk.interrupt) { + const customEvent: CustomEvent = { + type: EventType.CUSTOM, + name: "OnInterrupt", + value: normalizedChunk.interrupt.value, + timestamp: Date.now(), + }; + yield customEvent; + } + + // Handle text content + if (normalizedChunk.type === "text" && normalizedChunk.content) { + // End any tool call in progress + if (this.currentMessageType === "tool_call" && this.currentToolCallId) { + const toolEnd: ToolCallEndEvent = { + type: EventType.TOOL_CALL_END, + toolCallId: this.currentToolCallId, + timestamp: Date.now(), + }; + yield toolEnd; + this.currentToolCallId = null; + this.currentToolCallName = null; + } + + // Start text message if not in progress + if (this.currentMessageType !== "text") { + this.currentMessageId = this.generateMessageId(); + this.currentMessageType = "text"; + const textStart: TextMessageStartEvent = { + type: EventType.TEXT_MESSAGE_START, + messageId: this.currentMessageId, + role: "assistant", + timestamp: Date.now(), + }; + yield textStart; + } + + // Emit text content + const textContent: TextMessageContentEvent = { + type: EventType.TEXT_MESSAGE_CONTENT, + messageId: this.currentMessageId!, + delta: normalizedChunk.content, + timestamp: Date.now(), + }; + yield textContent; + } + + // Handle state updates + if (normalizedChunk.type === "state" && normalizedChunk.state) { + // Check if run is paused (HITL) + if (normalizedChunk.state.runStatus === "paused_for_approval") { + this.runPaused = true; + } + + const stateSnapshot: StateSnapshotEvent = { + type: EventType.STATE_SNAPSHOT, + snapshot: normalizedChunk.state, + timestamp: Date.now(), + }; + yield stateSnapshot; + } + } + + /** + * Normalize different chunk formats to our standard interface + * Agents SDK might return plain strings, objects, or structured chunks + */ + private normalizeChunk(chunk: any): AgentsSDKChunk { + // Plain string → text chunk + if (typeof chunk === "string") { + return { type: "text", content: chunk }; + } + + // Already normalized + if (chunk.type) { + return chunk as AgentsSDKChunk; + } + + // Object with tool_call field (OpenAI-style) + if (chunk.tool_call || chunk.toolCall) { + const toolCall = chunk.tool_call || chunk.toolCall; + return { + type: toolCall.done ? "tool_call" : "tool_call_delta", + toolCall: { + id: toolCall.id, + name: toolCall.name, + args: toolCall.args || toolCall.arguments, + argsChunk: toolCall.args_chunk || toolCall.argsChunk, + done: toolCall.done, + }, + }; + } + + // Object with interrupt field (requiresApproval) + if (chunk.interrupt || chunk.__interrupt__) { + const interrupt = chunk.interrupt || chunk.__interrupt__; + return { + type: "interrupt", + interrupt: { + name: interrupt.name || "requiresApproval", + value: interrupt.value || interrupt, + }, + }; + } + + // Object with content field + if (chunk.content !== undefined) { + return { type: "text", content: String(chunk.content) }; + } + + // Object with delta field + if (chunk.delta) { + return { type: "text", content: String(chunk.delta) }; + } + + // Default: try to stringify + return { type: "text", content: JSON.stringify(chunk) }; + } + + /** + * Generate a unique message ID + */ + private generateMessageId(): string { + return `msg-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`; + } + + /** + * Handle generic Agent (manual message processing) + */ + private async *handleGenericAgent( + messages: CloudflareMessage[], + context?: Record, + ): AsyncGenerator { + // For generic agents, we need to manually process + // This would typically involve calling agent methods + + const messageId = this.generateMessageId(); + + const textStart: TextMessageStartEvent = { + type: EventType.TEXT_MESSAGE_START, + messageId, + role: "assistant", + timestamp: Date.now(), + }; + yield textStart; + + const response = await this.processMessages(messages, context); + + const textContent: TextMessageContentEvent = { + type: EventType.TEXT_MESSAGE_CONTENT, + messageId, + delta: response, + timestamp: Date.now(), + }; + yield textContent; + + const textEnd: TextMessageEndEvent = { + type: EventType.TEXT_MESSAGE_END, + messageId, + timestamp: Date.now(), + }; + yield textEnd; + } + + /** + * Process messages through the agent + * Override this in subclasses for custom behavior + */ + protected async processMessages( + messages: CloudflareMessage[], + context?: Record, + ): Promise { + // Default implementation - override in subclass + const lastMessage = messages[messages.length - 1]; + return `Agent processed: ${lastMessage?.content || "No message"}`; + } + + /** + * Create WebSocket handler for real-time communication + */ + createWebSocketHandler(): (websocket: WebSocket, message: any) => Promise { + return async (websocket: WebSocket, message: any) => { + try { + const data = JSON.parse( + typeof message === "string" ? message : new TextDecoder().decode(message), + ); + + if (data.type === "chat" && data.messages) { + // Stream AG-UI events over WebSocket + for await (const event of this.execute(data.messages, data.context)) { + websocket.send(JSON.stringify(event)); + } + } else if (data.type === "getState") { + // Send current state + const state = this.agent.getState(); + websocket.send( + JSON.stringify({ + type: "STATE_SYNC", + data: { state }, + }), + ); + } + } catch (error) { + websocket.send( + JSON.stringify({ + type: "RUN_ERROR", + data: { error: error instanceof Error ? error.message : "Unknown error" }, + }), + ); + } + }; + } + + /** + * Set up state synchronization + */ + private setupStateSync(): void { + // Intercept setState calls to emit events + const originalSetState = this.agent.setState.bind(this.agent); + + this.agent.setState = async (state: Record) => { + await originalSetState(state); + + // Notify listeners + for (const listener of this.stateListeners) { + listener(state); + } + }; + } + + /** + * Subscribe to state changes + */ + onStateChange(callback: (state: any) => void): () => void { + this.stateListeners.add(callback); + + // Return unsubscribe function + return () => { + this.stateListeners.delete(callback); + }; + } + + /** + * Execute SQL query and optionally emit as metadata event + */ + async executeSQLWithTracking(query: TemplateStringsArray, ...values: any[]): Promise { + const result = await this.agent.sql(query, ...values); + + // TODO: Implement SQL tracking by emitting metadata events when trackSQL is enabled + // This would require an event emitter or storing events to be yielded later + + return result; + } + + private generateRunId(): string { + return `agent-run-${Date.now()}-${++this.runCounter}`; + } +} + +/** + * Helper function to create an Agents SDK adapter from an agent instance + */ +export function createAgentsSDKAdapter( + agent: CloudflareAgentsSDKAgent, + options?: Partial, +): CloudflareAgentsSDKAdapter { + return new CloudflareAgentsSDKAdapter({ + agent, + syncState: true, + trackSQL: false, + ...options, + }); +} + +/** + * Create a Worker fetch handler that uses Agents SDK + AG-UI + */ +export function createAgentsSDKWorkerHandler( + agentFactory: (state: DurableObjectState, env: any) => CloudflareAgentsSDKAgent, + options?: Partial, +): { + fetch: (request: Request, env: any, ctx: ExecutionContext) => Promise; +} { + return { + async fetch(request, env, ctx) { + // This would typically get the Durable Object instance + // For now, provide a basic HTTP handler structure + + if (request.method === "POST") { + try { + const body = (await request.json()) as { messages: CloudflareMessage[] }; + + // Create agent instance (implementation depends on Durable Objects setup) + // const id = env.AGENT_DO.idFromName('agent-1'); + // const stub = env.AGENT_DO.get(id); + // const agent = await stub.fetch(request); + + // For now, show the structure: + const responseText = JSON.stringify({ + error: "Agent instance creation requires Durable Objects setup", + hint: "See examples/agents-sdk-example.ts for full implementation", + }); + + return new Response(responseText, { + status: 501, + headers: { "Content-Type": "application/json" }, + }); + } catch (error) { + return new Response( + JSON.stringify({ + error: error instanceof Error ? error.message : "Unknown error", + }), + { + status: 500, + headers: { "Content-Type": "application/json" }, + }, + ); + } + } + + return new Response("Method not allowed", { status: 405 }); + }, + }; +} diff --git a/integrations/cloudflare/typescript/src/client.ts b/integrations/cloudflare/typescript/src/client.ts new file mode 100644 index 000000000..2d5c01af6 --- /dev/null +++ b/integrations/cloudflare/typescript/src/client.ts @@ -0,0 +1,344 @@ +import { + CloudflareAIConfig, + CloudflareCompletionOptions, + CloudflareStreamChunk, + CloudflareMessage, + CloudflareModel, + ToolCall, + validateConfig, +} from "./types"; +import { CloudflareStreamParser } from "./stream-parser"; + +// Default model to use as fallback +const DEFAULT_MODEL: CloudflareModel = "@cf/meta/llama-3.1-8b-instruct"; + +// API response types +interface CloudflareAPIResponse { + result?: { + response?: string; + tool_calls?: ToolCall[]; + usage?: { + prompt_tokens: number; + completion_tokens: number; + total_tokens: number; + }; + }; + response?: string; + tool_calls?: ToolCall[]; + choices?: Array<{ + message?: { + content?: string; + }; + }>; + usage?: { + prompt_tokens: number; + completion_tokens: number; + total_tokens: number; + }; +} + +interface ModelListResponse { + result?: { + models?: string[]; + }; + models?: string[]; +} + +interface RetryOptions { + maxRetries?: number; + baseDelay?: number; + maxDelay?: number; + retryableStatusCodes?: number[]; +} + +export class CloudflareAIClient { + private config: CloudflareAIConfig; + private baseURL: string; + private headers: Record; + private retryOptions: Required; + + constructor(config: CloudflareAIConfig, retryOptions?: RetryOptions) { + // ✅ Validate configuration with Zod schema + // This catches invalid configs early and provides clear error messages + this.config = validateConfig(config); + + if (this.config.gatewayId) { + this.baseURL = + this.config.baseURL || + `https://gateway.ai.cloudflare.com/v1/${this.config.accountId}/${this.config.gatewayId}/workers-ai/v1`; + } else { + this.baseURL = + this.config.baseURL || `https://api.cloudflare.com/client/v4/accounts/${this.config.accountId}/ai/v1`; + } + + this.headers = { + Authorization: `Bearer ${this.config.apiToken}`, + "Content-Type": "application/json", + }; + + // Default retry configuration + this.retryOptions = { + maxRetries: retryOptions?.maxRetries ?? 3, + baseDelay: retryOptions?.baseDelay ?? 1000, + maxDelay: retryOptions?.maxDelay ?? 10000, + retryableStatusCodes: retryOptions?.retryableStatusCodes ?? [408, 429, 500, 502, 503, 504], + }; + } + + async complete(options: CloudflareCompletionOptions): Promise { + const response = await this.makeRequest(options); + + if (!response.ok) { + const error = await response.text(); + throw new Error(`Cloudflare AI error: ${error}`); + } + + const data: CloudflareAPIResponse = await response.json(); + return { + role: "assistant", + content: data.result?.response || data.response || "", + tool_calls: data.result?.tool_calls || data.tool_calls, + }; + } + + async *streamComplete( + options: CloudflareCompletionOptions, + ): AsyncGenerator { + const streamOptions = { ...options, stream: true }; + const response = await this.makeRequest(streamOptions); + + if (!response.ok) { + const error = await response.text(); + throw new Error(`Cloudflare AI error: ${error}`); + } + + // Check if response is streaming or not + const contentType = response.headers.get("content-type"); + + if (contentType?.includes("text/event-stream")) { + // SSE streaming response + if (!response.body) { + throw new Error("No response body from Cloudflare AI"); + } + const parser = new CloudflareStreamParser(); + yield* parser.parseStream(response.body); + } else { + // Non-streaming JSON response + const data: CloudflareAPIResponse = await response.json(); + + if (data.choices) { + // OpenAI-compatible format (from /chat/completions endpoint) + for (const choice of data.choices) { + if (choice.message?.content) { + yield { response: choice.message.content, done: false }; + } + } + yield { done: true, usage: data.usage }; + } else if (data.result) { + // Cloudflare Workers AI format (from /ai/run endpoint) + const content = data.result.response || ""; + if (content) { + yield { response: content, done: false }; + } + yield { + done: true, + usage: data.result.usage || this.estimateTokens(content), + }; + } else { + console.warn("Unexpected response format:", data); + yield { done: true }; + } + } + } + + private async makeRequest(options: CloudflareCompletionOptions): Promise { + const model = options.model || this.config.model || DEFAULT_MODEL; + const endpoint = `${this.baseURL}/chat/completions`; + + const body: Record = { + model, + messages: options.messages, + temperature: options.temperature, + max_tokens: options.max_tokens, + top_p: options.top_p, + frequency_penalty: options.frequency_penalty, + presence_penalty: options.presence_penalty, + stream: options.stream || false, + tools: options.tools, + tool_choice: options.tool_choice, + }; + + // Remove undefined values - cleaner approach + const cleanBody = Object.fromEntries( + Object.entries(body).filter(([_, value]) => value !== undefined) + ); + + // Use retry logic for non-streaming requests + if (!options.stream) { + return this.fetchWithRetry(endpoint, { + method: "POST", + headers: this.headers, + body: JSON.stringify(cleanBody), + }); + } + + // For streaming, don't retry (would duplicate stream) + return fetch(endpoint, { + method: "POST", + headers: this.headers, + body: JSON.stringify(cleanBody), + }); + } + + /** + * Fetch with exponential backoff retry logic + */ + private async fetchWithRetry( + url: string, + init: RequestInit, + attempt = 0 + ): Promise { + try { + const response = await fetch(url, init); + + // Check if we should retry based on status code + if ( + !response.ok && + attempt < this.retryOptions.maxRetries && + this.retryOptions.retryableStatusCodes.includes(response.status) + ) { + const delay = this.calculateBackoff(attempt); + console.warn( + `Request failed with status ${response.status}. Retrying in ${delay}ms (attempt ${attempt + 1}/${this.retryOptions.maxRetries})` + ); + await this.sleep(delay); + return this.fetchWithRetry(url, init, attempt + 1); + } + + return response; + } catch (error) { + // Network errors - retry if we have attempts left + if (attempt < this.retryOptions.maxRetries) { + const delay = this.calculateBackoff(attempt); + console.warn( + `Network error: ${error}. Retrying in ${delay}ms (attempt ${attempt + 1}/${this.retryOptions.maxRetries})` + ); + await this.sleep(delay); + return this.fetchWithRetry(url, init, attempt + 1); + } + + // No more retries - throw the error + throw error; + } + } + + /** + * Calculate exponential backoff delay with jitter + */ + private calculateBackoff(attempt: number): number { + const exponentialDelay = this.retryOptions.baseDelay * Math.pow(2, attempt); + const jitter = Math.random() * 0.3 * exponentialDelay; // Add 0-30% jitter + return Math.min(exponentialDelay + jitter, this.retryOptions.maxDelay); + } + + /** + * Sleep helper for retry delays + */ + private sleep(ms: number): Promise { + return new Promise((resolve) => setTimeout(resolve, ms)); + } + + /** + * Estimate token count from text + * Uses rough approximation: 1 token ≈ 4 characters for English text + */ + private estimateTokens(text: string): { + prompt_tokens: number; + completion_tokens: number; + total_tokens: number; + } { + const estimatedTokens = Math.ceil(text.length / 4); + return { + prompt_tokens: 0, + completion_tokens: estimatedTokens, + total_tokens: estimatedTokens, + }; + } + + async listModels(): Promise { + const response = await fetch(`${this.baseURL}/models`, { + headers: this.headers, + }); + + if (!response.ok) { + throw new Error(`Failed to list models: ${response.statusText}`); + } + + const data: ModelListResponse = await response.json(); + return data.result?.models || data.models || []; + } + + getModelCapabilities(model: string): { + streaming: boolean; + functionCalling: boolean; + maxTokens: number; + contextWindow: number; + } { + const capabilities: Record = { + "@cf/meta/llama-3.3-70b-instruct-fp8-fast": { + streaming: true, + functionCalling: true, + maxTokens: 4096, + contextWindow: 128000, + }, + "@cf/meta/llama-4-scout-17b-16e-instruct": { + streaming: true, + functionCalling: true, + maxTokens: 4096, + contextWindow: 128000, + }, + "@cf/mistralai/mistral-small-3.1-24b-instruct": { + streaming: true, + functionCalling: true, + maxTokens: 8192, + contextWindow: 32768, + }, + "@cf/nousresearch/hermes-2-pro-mistral-7b": { + streaming: true, + functionCalling: true, + maxTokens: 4096, + contextWindow: 32768, + }, + "@cf/meta/llama-3.1-70b-instruct": { + streaming: true, + functionCalling: false, + maxTokens: 4096, + contextWindow: 128000, + }, + "@cf/meta/llama-3.1-8b-instruct": { + streaming: true, + functionCalling: false, + maxTokens: 2048, + contextWindow: 128000, + }, + "@cf/mistral/mistral-7b-instruct-v0.2": { + streaming: true, + functionCalling: false, + maxTokens: 2048, + contextWindow: 32768, + }, + }; + + return capabilities[model] || { + streaming: true, + functionCalling: false, + maxTokens: 2048, + contextWindow: 4096, + }; + } +} diff --git a/integrations/cloudflare/typescript/src/cloudflare-agent.ts b/integrations/cloudflare/typescript/src/cloudflare-agent.ts new file mode 100644 index 000000000..9d3e944f4 --- /dev/null +++ b/integrations/cloudflare/typescript/src/cloudflare-agent.ts @@ -0,0 +1,375 @@ +import { AbstractAgent, type RunAgentInput, type BaseEvent } from "@ag-ui/client"; +import { Observable, Subscriber } from "rxjs"; +import { v4 as uuidv4 } from "uuid"; +import { CloudflareAIClient } from "./client"; +import type { CloudflareAIConfig, CloudflareMessage, CloudflareCompletionOptions } from "./types"; +import { supportsToolCalling } from "./types"; +import { + EventType, + type TextMessageStartEvent, + type TextMessageContentEvent, + type TextMessageEndEvent, + type ToolCallStartEvent, + type ToolCallArgsEvent, + type ToolCallEndEvent, + type RunStartedEvent, + type RunFinishedEvent, +} from "@ag-ui/core"; + +export interface CloudflareAgentConfig extends CloudflareAIConfig { + systemPrompt?: string; + streamingEnabled?: boolean; +} + +/** + * Base agent class for Cloudflare Workers AI integration with AG-UI protocol. + * + * This class properly extends AbstractAgent and emits events conforming to the + * AG-UI protocol specifications. + */ +export class CloudflareAgent extends AbstractAgent { + protected client: CloudflareAIClient; + protected config: CloudflareAgentConfig; + + constructor(config: CloudflareAgentConfig) { + super({ + description: `Cloudflare Workers AI Agent using ${config.model}`, + }); + this.config = config; + this.client = new CloudflareAIClient(config); + } + + /** + * Implements the abstract run() method from AbstractAgent. + * Returns an Observable as required by the AG-UI protocol. + */ + run(input: RunAgentInput): Observable { + return new Observable((subscriber) => { + this.executeRun(input, subscriber) + .catch((error) => { + // ✅ Enhanced error logging with full context + console.error("CloudflareAgent execution error:", { + agent: "CloudflareAgent", + model: this.config.model, + threadId: input.threadId, + runId: input.runId, + error: error instanceof Error ? { + message: error.message, + stack: error.stack, + name: error.name, + } : error, + timestamp: new Date().toISOString(), + }); + subscriber.error(error); + }) + .finally(() => { + subscriber.complete(); + }); + }); + } + + /** + * Main execution logic that streams events to the subscriber. + */ + protected async executeRun( + input: RunAgentInput, + subscriber: Subscriber + ): Promise { + const messageId = this.generateMessageId(); + + // Emit RUN_STARTED + const runStarted: RunStartedEvent = { + type: EventType.RUN_STARTED, + threadId: input.threadId, + runId: input.runId, + timestamp: Date.now(), + }; + subscriber.next(runStarted); + + // Convert AG-UI messages to Cloudflare format + const messages = this.convertMessagesToCloudflare(input.messages); + + // Add system prompt if configured + const allMessages = this.config.systemPrompt + ? [{ role: "system" as const, content: this.config.systemPrompt }, ...messages] + : messages; + + // ✅ Validate tool capability before sending tools to model + let toolsToUse: any[] | undefined; + if (input.tools && input.tools.length > 0) { + const modelToUse = this.config.model || "@cf/meta/llama-3.1-8b-instruct"; + if (supportsToolCalling(modelToUse)) { + toolsToUse = this.convertTools(input.tools); + } else { + console.warn( + `[CloudflareAgent] Model "${modelToUse}" does not support tool calling. ` + + `Tools will be ignored. Use a compatible model like: ` + + `@cf/meta/llama-3.3-70b-instruct-fp8-fast, @cf/meta/llama-4-scout-17b-16e-instruct, ` + + `@cf/mistralai/mistral-small-3.1-24b-instruct, or @cf/nousresearch/hermes-2-pro-mistral-7b` + ); + toolsToUse = undefined; + } + } + + // Prepare completion options + const completionOptions: CloudflareCompletionOptions = { + messages: allMessages, + model: this.config.model, + stream: this.config.streamingEnabled !== false, + tools: toolsToUse, + }; + + // Stream from Cloudflare Workers AI + if (this.config.streamingEnabled !== false) { + await this.handleStreaming(messageId, completionOptions, subscriber); + } else { + await this.handleNonStreaming(messageId, completionOptions, subscriber); + } + + // Emit RUN_FINISHED + const runFinished: RunFinishedEvent = { + type: EventType.RUN_FINISHED, + threadId: input.threadId, + runId: input.runId, + timestamp: Date.now(), + }; + subscriber.next(runFinished); + } + + /** + * Handles streaming completion from Cloudflare Workers AI. + */ + protected async handleStreaming( + messageId: string, + options: CloudflareCompletionOptions, + subscriber: Subscriber + ): Promise { + let messageStarted = false; + let accumulatedContent = ""; + const toolCallsInProgress = new Set(); + let messageEnded = false; + + for await (const chunk of this.client.streamComplete(options)) { + // Handle text content + if (chunk.response && chunk.response.length > 0) { + if (!messageStarted) { + // Emit TEXT_MESSAGE_START + const textStart: TextMessageStartEvent = { + type: EventType.TEXT_MESSAGE_START, + messageId, + role: "assistant", + timestamp: Date.now(), + }; + subscriber.next(textStart); + messageStarted = true; + messageEnded = false; + } + + // Emit TEXT_MESSAGE_CONTENT + const textContent: TextMessageContentEvent = { + type: EventType.TEXT_MESSAGE_CONTENT, + messageId, + delta: chunk.response, + timestamp: Date.now(), + }; + subscriber.next(textContent); + + accumulatedContent += chunk.response; + } + + // Handle tool calls + if (chunk.tool_calls) { + // Make sure we have a parent message started for the tool calls + if (!messageStarted) { + const textStart: TextMessageStartEvent = { + type: EventType.TEXT_MESSAGE_START, + messageId, + role: "assistant", + timestamp: Date.now(), + }; + subscriber.next(textStart); + messageStarted = true; + } + + for (const toolCall of chunk.tool_calls) { + const toolCallId = toolCall.id ?? ""; + const toolCallName = toolCall.function?.name ?? "tool"; + + if (!toolCallId) { + continue; + } + + if (!toolCallsInProgress.has(toolCallId)) { + // New tool call - emit TOOL_CALL_START + const toolStart: ToolCallStartEvent = { + type: EventType.TOOL_CALL_START, + toolCallId, + toolCallName, + parentMessageId: messageId, + timestamp: Date.now(), + }; + subscriber.next(toolStart); + toolCallsInProgress.add(toolCallId); + } + + // Stream tool call arguments - emit TOOL_CALL_ARGS + const rawArguments = toolCall.function?.arguments; + if (rawArguments !== undefined && rawArguments !== null && toolCallId) { + let argsToEmit: string; + if (typeof rawArguments === "string") { + argsToEmit = rawArguments; + } else { + try { + argsToEmit = JSON.stringify(rawArguments); + } catch { + argsToEmit = String(rawArguments); + } + } + + if (argsToEmit.length > 0) { + const toolArgs: ToolCallArgsEvent = { + type: EventType.TOOL_CALL_ARGS, + toolCallId, + delta: argsToEmit, + timestamp: Date.now(), + }; + subscriber.next(toolArgs); + } + } + } + } + + // Handle completion + if (chunk.done) { + // End all tool calls first + for (const toolCallId of toolCallsInProgress) { + const toolEnd: ToolCallEndEvent = { + type: EventType.TOOL_CALL_END, + toolCallId, + timestamp: Date.now(), + }; + subscriber.next(toolEnd); + } + toolCallsInProgress.clear(); + + // Then end the parent text message if it was started + if (messageStarted && !messageEnded) { + const textEnd: TextMessageEndEvent = { + type: EventType.TEXT_MESSAGE_END, + messageId, + timestamp: Date.now(), + }; + subscriber.next(textEnd); + messageStarted = false; + messageEnded = true; + } + } + } + } + + /** + * Handles non-streaming completion from Cloudflare Workers AI. + */ + protected async handleNonStreaming( + messageId: string, + options: CloudflareCompletionOptions, + subscriber: Subscriber + ): Promise { + const response = await this.client.complete(options); + + // Emit text message events + if (response.content) { + const textStart: TextMessageStartEvent = { + type: EventType.TEXT_MESSAGE_START, + messageId, + role: "assistant", + timestamp: Date.now(), + }; + subscriber.next(textStart); + + const textContent: TextMessageContentEvent = { + type: EventType.TEXT_MESSAGE_CONTENT, + messageId, + delta: response.content, + timestamp: Date.now(), + }; + subscriber.next(textContent); + + const textEnd: TextMessageEndEvent = { + type: EventType.TEXT_MESSAGE_END, + messageId, + timestamp: Date.now(), + }; + subscriber.next(textEnd); + } + + // Emit tool call events + if (response.tool_calls) { + for (const toolCall of response.tool_calls) { + const toolStart: ToolCallStartEvent = { + type: EventType.TOOL_CALL_START, + toolCallId: toolCall.id, + toolCallName: toolCall.function.name, + parentMessageId: messageId, + timestamp: Date.now(), + }; + subscriber.next(toolStart); + + const rawArguments = toolCall.function.arguments; + const argsToEmit = + typeof rawArguments === "string" ? rawArguments : JSON.stringify(rawArguments); + + const toolArgs: ToolCallArgsEvent = { + type: EventType.TOOL_CALL_ARGS, + toolCallId: toolCall.id, + delta: argsToEmit, + timestamp: Date.now(), + }; + subscriber.next(toolArgs); + + const toolEnd: ToolCallEndEvent = { + type: EventType.TOOL_CALL_END, + toolCallId: toolCall.id, + timestamp: Date.now(), + }; + subscriber.next(toolEnd); + } + } + } + + /** + * Converts AG-UI messages to Cloudflare format. + */ + protected convertMessagesToCloudflare(messages: any[]): CloudflareMessage[] { + return messages + .filter( + (msg) => msg.role === "user" || msg.role === "assistant" || msg.role === "system" + ) + .map((msg) => ({ + role: msg.role as "user" | "assistant" | "system", + content: msg.content || "", + })); + } + + /** + * Converts AG-UI tools to Cloudflare/OpenAI format. + * For the /chat/completions endpoint, tools need to be wrapped in a function object. + */ + protected convertTools(tools: any[]): any[] { + return tools.map((tool) => ({ + type: "function", + function: { + name: tool.name, + description: tool.description, + parameters: tool.parameters, + }, + })); + } + + /** + * Generates a unique message ID for AG-UI events. + */ + protected generateMessageId(): string { + return uuidv4(); + } +} diff --git a/integrations/cloudflare/typescript/src/cloudflare-utils.ts b/integrations/cloudflare/typescript/src/cloudflare-utils.ts new file mode 100644 index 000000000..df3d6e751 --- /dev/null +++ b/integrations/cloudflare/typescript/src/cloudflare-utils.ts @@ -0,0 +1,222 @@ +/** + * Cloudflare Infrastructure Utilities + * + * Handles Cloudflare-specific headers, proxy detection, and request normalization + * for AG-UI instances running behind Cloudflare CDN or on Cloudflare Workers. + */ + +export interface CloudflareHeaders { + /** Real client IP address (most reliable) */ + "cf-connecting-ip"?: string; + /** Cloudflare Ray ID for request tracking */ + "cf-ray"?: string; + /** Visitor's country code */ + "cf-ipcountry"?: string; + /** True if request came through Cloudflare */ + "cf-visitor"?: string; + /** Original protocol (http/https) */ + "x-forwarded-proto"?: string; + /** Chain of proxy IPs */ + "x-forwarded-for"?: string; + /** True Client IP (Enterprise only) */ + "true-client-ip"?: string; +} + +export interface NormalizedRequest { + /** Real client IP address */ + clientIp: string; + /** Original protocol */ + protocol: "http" | "https"; + /** Cloudflare Ray ID (if available) */ + rayId?: string; + /** Client country (if available) */ + country?: string; + /** Whether request came through Cloudflare */ + isBehindCloudflare: boolean; + /** Original headers */ + headers: Record; +} + +/** + * Detect if a request is behind Cloudflare proxy + */ +export function isBehindCloudflare(headers: Record): boolean { + return !!(headers["cf-ray"] || headers["cf-connecting-ip"] || headers["cf-visitor"]); +} + +/** + * Extract real client IP from Cloudflare headers + * Priority: CF-Connecting-IP > True-Client-IP > X-Forwarded-For > fallback + */ +export function getClientIP(headers: Record, fallbackIp = "unknown"): string { + // Priority 1: CF-Connecting-IP (most reliable) + if (headers["cf-connecting-ip"]) { + return headers["cf-connecting-ip"]; + } + + // Priority 2: True-Client-IP (Enterprise feature) + if (headers["true-client-ip"]) { + return headers["true-client-ip"]; + } + + // Priority 3: X-Forwarded-For (first IP in chain) + if (headers["x-forwarded-for"]) { + const ips = headers["x-forwarded-for"].split(","); + return ips[0].trim(); + } + + return fallbackIp; +} + +/** + * Get original protocol from Cloudflare headers + */ +export function getProtocol(headers: Record): "http" | "https" { + // Check CF-Visitor JSON + if (headers["cf-visitor"]) { + try { + const visitor = JSON.parse(headers["cf-visitor"]); + return visitor.scheme === "https" ? "https" : "http"; + } catch { + // Malformed CF-Visitor JSON - fall through to other methods + } + } + + // Check X-Forwarded-Proto + if (headers["x-forwarded-proto"]) { + return headers["x-forwarded-proto"] === "https" ? "https" : "http"; + } + + // Default to https (Cloudflare enforces HTTPS) + return "https"; +} + +/** + * Normalize request from any source to a standard format + * Works with Node.js Request, Cloudflare Workers Request, or plain headers + */ +export function normalizeRequest( + request: Request | { headers: Record }, + options?: { fallbackIp?: string }, +): NormalizedRequest { + // Extract headers (works with both Request and plain object) + const headers: Record = {}; + + if (request instanceof Request) { + // Fetch API Request object (Cloudflare Workers, browsers) + request.headers.forEach((value, key) => { + headers[key.toLowerCase()] = value; + }); + } else if ("headers" in request) { + const requestHeaders = request.headers; + + // Check if it's a Headers-like object with .forEach method + if (typeof (requestHeaders as any).forEach === "function") { + // Headers object from Fetch API + (requestHeaders as any).forEach((value: string, key: string) => { + headers[key.toLowerCase()] = value; + }); + } else { + // Plain object with headers (Node.js-style) + Object.entries(requestHeaders).forEach(([key, value]) => { + // Handle both string and string[] (Express/Node.js can have arrays) + if (typeof value === "string") { + headers[key.toLowerCase()] = value; + } else if (Array.isArray(value) && value.length > 0) { + headers[key.toLowerCase()] = value[0]; + } + }); + } + } + + const clientIp = getClientIP(headers, options?.fallbackIp); + const protocol = getProtocol(headers); + const isBehind = isBehindCloudflare(headers); + + return { + clientIp, + protocol, + rayId: headers["cf-ray"], + country: headers["cf-ipcountry"], + isBehindCloudflare: isBehind, + headers, + }; +} + +/** + * Check if WebSocket upgrade is properly formatted for Cloudflare + */ +export function isWebSocketUpgrade(headers: Record): boolean { + const upgrade = headers["upgrade"]?.toLowerCase(); + const connection = headers["connection"]?.toLowerCase(); + + return upgrade === "websocket" && connection?.includes("upgrade"); +} + +/** + * Validate WebSocket upgrade request for Cloudflare compatibility + * Returns error message if invalid, undefined if valid + */ +export function validateWebSocketUpgrade(headers: Record): string | undefined { + if (!isWebSocketUpgrade(headers)) { + return "Invalid WebSocket upgrade: Missing Upgrade: websocket header"; + } + + // Cloudflare requires Sec-WebSocket-Key + if (!headers["sec-websocket-key"]) { + return "Invalid WebSocket upgrade: Missing Sec-WebSocket-Key"; + } + + // Cloudflare requires Sec-WebSocket-Version: 13 + if (headers["sec-websocket-version"] !== "13") { + return "Invalid WebSocket upgrade: Sec-WebSocket-Version must be 13"; + } + + return undefined; +} + +/** + * Add Cloudflare-specific logging context + */ +export function getLoggingContext(normalized: NormalizedRequest): { + clientIp: string; + protocol: "http" | "https"; + rayId?: string; + country?: string; + isBehindCloudflare: boolean; +} { + return { + clientIp: normalized.clientIp, + protocol: normalized.protocol, + rayId: normalized.rayId, + country: normalized.country, + isBehindCloudflare: normalized.isBehindCloudflare, + }; +} + +/** + * Create response headers compatible with Cloudflare + */ +export function createResponseHeaders(options?: { + /** Enable CORS */ + cors?: boolean; + /** Custom CORS origin */ + corsOrigin?: string; + /** Cache control */ + cacheControl?: string; +}): Record { + const headers: Record = { + "Content-Type": "text/event-stream", + "Cache-Control": options?.cacheControl || "no-cache, no-transform", + Connection: "keep-alive", + "X-Accel-Buffering": "no", // Disable nginx buffering + }; + + if (options?.cors) { + headers["Access-Control-Allow-Origin"] = options.corsOrigin || "*"; + headers["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS"; + headers["Access-Control-Allow-Headers"] = "Content-Type, Authorization"; + } + + return headers; +} diff --git a/integrations/cloudflare/typescript/src/index.ts b/integrations/cloudflare/typescript/src/index.ts new file mode 100644 index 000000000..ace904ed5 --- /dev/null +++ b/integrations/cloudflare/typescript/src/index.ts @@ -0,0 +1,127 @@ +// Core imports for factory functions +import type { CloudflareAIConfig } from "./types"; +import { CloudflareAGUIAdapter } from "./adapter"; +import type { CloudflareAGUIAdapterOptions } from "./adapter"; + +// Core classes +export { CloudflareAGUIAdapter } from "./adapter"; +export { CloudflareAIClient } from "./client"; +export { CloudflareProviders } from "./providers"; +export { CloudflareStreamParser } from "./stream-parser"; + +// CopilotKit compatibility - CloudflareAGUIAdapter already implements CopilotServiceAdapter +export { CloudflareAGUIAdapter as CopilotKitCloudflareAdapter } from "./adapter"; + +// HTTP Agent (re-exported from @ag-ui/client) +export { HttpAgent as CloudflareHttpAgent } from "@ag-ui/client"; + +// Cloudflare-specific agent +export { CloudflareAgent, type CloudflareAgentConfig } from "./cloudflare-agent"; + +// Infrastructure Support (NEW!) +export { + handleCloudflareWorker, + createCloudflareWorkerHandler, + handleWebSocketConnection, + type WorkersAdapterOptions, + type WorkersEnv, +} from "./workers-adapter"; + +export { + isBehindCloudflare, + getClientIP, + getProtocol, + normalizeRequest, + isWebSocketUpgrade, + validateWebSocketUpgrade, + getLoggingContext, + createResponseHeaders, + type CloudflareHeaders, + type NormalizedRequest, +} from "./cloudflare-utils"; + +// Cloudflare Agents SDK Integration (NEW!) +export { + CloudflareAgentsSDKAdapter, + createAgentsSDKAdapter, + createAgentsSDKWorkerHandler, + type CloudflareAgentsSDKAgent, + type AgentsSDKAdapterOptions, +} from "./agents-sdk-adapter"; + +export type { + CloudflareAIConfig, + CloudflareModel, + CloudflareMessage, + CloudflareCompletionOptions, + CloudflareStreamChunk, + Tool, + ToolCall, + ToolParameters, + ModelCapabilities, +} from "./types"; + +export { + CloudflareModelSchema, + CloudflareMessageSchema, + CloudflareAIConfigSchema, + supportsToolCalling, + validateMessages, + validateConfig, +} from "./types"; + +export type { CloudflareAGUIAdapterOptions, AGUIProtocol, StreamableResult } from "./adapter"; +export type { ProviderConfig } from "./providers"; + +// Re-export AG-UI core types +export { EventType, type BaseEvent } from "@ag-ui/core"; + +/** + * Model constants for convenient access + * These match the CloudflareModelSchema in types.ts + * + * @example + * ```typescript + * const adapter = new CloudflareAGUIAdapter({ + * accountId: "...", + * apiToken: "...", + * model: CLOUDFLARE_MODELS.LLAMA_3_3_70B_FP8 + * }); + * ``` + */ +export const CLOUDFLARE_MODELS = { + // Llama 3.1 series (general purpose) + LLAMA_3_1_8B: "@cf/meta/llama-3.1-8b-instruct" as const, + LLAMA_3_1_70B: "@cf/meta/llama-3.1-70b-instruct" as const, + + // Llama 3.3 series (function calling support) + LLAMA_3_3_70B_FP8: "@cf/meta/llama-3.3-70b-instruct-fp8-fast" as const, + + // Llama 4 series (latest, function calling) + LLAMA_4_SCOUT_17B: "@cf/meta/llama-4-scout-17b-16e-instruct" as const, + + // Mistral series + MISTRAL_7B: "@cf/mistral/mistral-7b-instruct-v0.2" as const, + MISTRAL_SMALL_24B: "@cf/mistralai/mistral-small-3.1-24b-instruct" as const, + + // Hermes series (function calling) + HERMES_2_PRO_7B: "@cf/nousresearch/hermes-2-pro-mistral-7b" as const, + + // Legacy models (may be deprecated) + LLAMA_2_7B: "@cf/meta/llama-2-7b-chat-int8" as const, + GEMMA_7B: "@cf/google/gemma-7b-it" as const, + QWEN_14B: "@cf/qwen/qwen1.5-14b-chat-awq" as const, + PHI_2: "@cf/microsoft/phi-2" as const, + DEEPSEEK_MATH_7B: "@cf/deepseek-ai/deepseek-math-7b-instruct" as const, + DEEPSEEK_CODER_6B: "@cf/thebloke/deepseek-coder-6.7b-instruct-awq" as const, +} as const; + +// Convenience factory functions + +export function createCloudflareAdapter(config: CloudflareAIConfig) { + return new CloudflareAGUIAdapter(config); +} + +export function createCopilotKitCloudflareAdapter(options: CloudflareAGUIAdapterOptions) { + return new CloudflareAGUIAdapter(options); +} diff --git a/integrations/cloudflare/typescript/src/providers.ts b/integrations/cloudflare/typescript/src/providers.ts new file mode 100644 index 000000000..630ece861 --- /dev/null +++ b/integrations/cloudflare/typescript/src/providers.ts @@ -0,0 +1,202 @@ +import { CloudflareAGUIAdapter, CloudflareAGUIAdapterOptions } from "./adapter"; +import { CloudflareModel } from "./types"; + +export interface ProviderConfig extends Omit { + model?: CloudflareModel; +} + +export class CloudflareProviders { + /** + * Helper to create adapter with specific model + */ + private static createAdapter(config: ProviderConfig, defaultModel: CloudflareModel): CloudflareAGUIAdapter { + return new CloudflareAGUIAdapter({ + ...config, + model: config.model || defaultModel, + }); + } + + // Llama 3.1 series - General purpose, fast inference + + /** + * Llama 3.1 8B - Fast, general purpose + * - Context: 128K tokens + * - Function calling: No + * - Best for: Quick responses, general chat + */ + static llama3_8b(config: ProviderConfig): CloudflareAGUIAdapter { + return CloudflareProviders.createAdapter(config, "@cf/meta/llama-3.1-8b-instruct"); + } + + /** + * Llama 3.1 70B - Powerful, general purpose + * - Context: 128K tokens + * - Function calling: No + * - Best for: Complex reasoning, detailed responses + */ + static llama3_70b(config: ProviderConfig): CloudflareAGUIAdapter { + return CloudflareProviders.createAdapter(config, "@cf/meta/llama-3.1-70b-instruct"); + } + + // Llama 3.3 series - Function calling support + + /** + * Llama 3.3 70B (FP8 Fast) - Function calling capable + * - Context: 128K tokens + * - Function calling: Yes + * - Best for: Tool use, structured outputs + */ + static llama3_3_70b(config: ProviderConfig): CloudflareAGUIAdapter { + return CloudflareProviders.createAdapter(config, "@cf/meta/llama-3.3-70b-instruct-fp8-fast"); + } + + // Llama 4 series - Latest generation + + /** + * Llama 4 Scout 17B - Latest generation with function calling + * - Context: 128K tokens + * - Function calling: Yes + * - Best for: Latest features, balanced performance + */ + static llama4Scout17b(config: ProviderConfig): CloudflareAGUIAdapter { + return CloudflareProviders.createAdapter(config, "@cf/meta/llama-4-scout-17b-16e-instruct"); + } + + // Mistral series + + /** + * Mistral 7B - Fast, efficient + * - Context: 32K tokens + * - Function calling: No + * - Best for: Quick responses, cost efficiency + */ + static mistral7b(config: ProviderConfig): CloudflareAGUIAdapter { + return CloudflareProviders.createAdapter(config, "@cf/mistral/mistral-7b-instruct-v0.2"); + } + + /** + * Mistral Small 24B - Function calling capable + * - Context: 32K tokens + * - Function calling: Yes + * - Best for: Tool use with faster inference than 70B models + */ + static mistralSmall24b(config: ProviderConfig): CloudflareAGUIAdapter { + return CloudflareProviders.createAdapter(config, "@cf/mistralai/mistral-small-3.1-24b-instruct"); + } + + // Hermes series + + /** + * Hermes 2 Pro 7B - Function calling specialist + * - Context: 32K tokens + * - Function calling: Yes + * - Best for: Tool use, fast inference with function calling + */ + static hermes2Pro7b(config: ProviderConfig): CloudflareAGUIAdapter { + return CloudflareProviders.createAdapter(config, "@cf/nousresearch/hermes-2-pro-mistral-7b"); + } + + // Legacy models - May be deprecated + + /** + * Gemma 7B + * @deprecated This model may be deprecated by Cloudflare + */ + static gemma7b(config: ProviderConfig): CloudflareAGUIAdapter { + return CloudflareProviders.createAdapter(config, "@cf/google/gemma-7b-it"); + } + + /** + * Qwen 1.5 14B + * @deprecated This model may be deprecated by Cloudflare + */ + static qwen14b(config: ProviderConfig): CloudflareAGUIAdapter { + return CloudflareProviders.createAdapter(config, "@cf/qwen/qwen1.5-14b-chat-awq"); + } + + /** + * Phi-2 + * @deprecated This model may be deprecated by Cloudflare + */ + static phi2(config: ProviderConfig): CloudflareAGUIAdapter { + return CloudflareProviders.createAdapter(config, "@cf/microsoft/phi-2"); + } + + /** + * DeepSeek Math 7B - Specialized for mathematical reasoning + * @deprecated This model may be deprecated by Cloudflare + */ + static deepseekMath(config: ProviderConfig): CloudflareAGUIAdapter { + return CloudflareProviders.createAdapter(config, "@cf/deepseek-ai/deepseek-math-7b-instruct"); + } + + /** + * DeepSeek Coder 6.7B - Specialized for code generation + * @deprecated This model may be deprecated by Cloudflare + */ + static deepseekCoder(config: ProviderConfig): CloudflareAGUIAdapter { + return CloudflareProviders.createAdapter(config, "@cf/thebloke/deepseek-coder-6.7b-instruct-awq"); + } + + /** + * Automatically select the best model based on requirements + * + * Selection criteria: + * - With tools/function calling: Llama 4 Scout 17B (latest, balanced) + * - Without tools: Llama 3.1 8B (fast, general purpose) + * + * @example + * ```typescript + * // Auto-selects Llama 4 Scout because tools are provided + * const adapter = CloudflareProviders.auto({ + * accountId: "...", + * apiToken: "...", + * tools: [weatherTool] + * }); + * ``` + */ + static auto(config: ProviderConfig): CloudflareAGUIAdapter { + // Auto-select based on capabilities needed + const needsFunctionCalling = config.tools && config.tools.length > 0; + + if (needsFunctionCalling) { + // Llama 4 Scout 17B offers latest features with good balance of speed and capability + return CloudflareProviders.llama4Scout17b(config); + } + + // Default to fast 8B model for general use + return CloudflareProviders.llama3_8b(config); + } + + /** + * Create adapter with AI Gateway for caching, analytics, and rate limiting + * + * @param accountId - Cloudflare account ID + * @param apiToken - Cloudflare API token + * @param gatewayId - AI Gateway ID + * @param model - Optional model (defaults to Llama 3.1 8B) + * + * @example + * ```typescript + * const adapter = CloudflareProviders.createWithGateway( + * "account-id", + * "api-token", + * "my-gateway", + * "@cf/meta/llama-4-scout-17b-16e-instruct" + * ); + * ``` + */ + static createWithGateway( + accountId: string, + apiToken: string, + gatewayId: string, + model?: CloudflareModel, + ): CloudflareAGUIAdapter { + return new CloudflareAGUIAdapter({ + accountId, + apiToken, + gatewayId, + model: model || "@cf/meta/llama-3.1-8b-instruct", + }); + } +} diff --git a/integrations/cloudflare/typescript/src/stream-parser.ts b/integrations/cloudflare/typescript/src/stream-parser.ts new file mode 100644 index 000000000..4f0891faa --- /dev/null +++ b/integrations/cloudflare/typescript/src/stream-parser.ts @@ -0,0 +1,207 @@ +import { createParser, ParsedEvent, ReconnectInterval } from "eventsource-parser"; +import { CloudflareStreamChunk } from "./types"; + +interface ToolCallAccumulator { + id?: string; + name?: string; + args: string; +} + +interface ToolCallDelta { + index?: number; + id?: string; + type?: string; + function?: { + name?: string; + arguments?: string; + }; +} + +export class CloudflareStreamParser { + private parser; + private buffer: string = ""; + private toolCallAccumulators: Map = new Map(); + private readonly MAX_BUFFER_SIZE = 50000; // 50KB max buffer size + private readonly MAX_TOOL_CALL_ARGS_SIZE = 100000; // 100KB max tool call args + + constructor() { + this.parser = createParser(this.onParse.bind(this)); + } + + private onParse(event: ParsedEvent | ReconnectInterval) { + if (event.type === "event") { + try { + const data = JSON.parse(event.data); + return data as CloudflareStreamChunk; + } catch (error) { + console.error("Failed to parse stream chunk:", error); + } + } + } + + private isCompleteJSON(str: string): boolean { + const trimmed = str.trim(); + if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) return false; + + let depth = 0; + for (const char of trimmed) { + if (char === "{") depth++; + else if (char === "}") depth--; + if (depth < 0) return false; + } + return depth === 0; + } + + async *parseStream(stream: ReadableStream): AsyncGenerator { + const reader = stream.getReader(); + const decoder = new TextDecoder(); + + try { + while (true) { + const { done, value } = await reader.read(); + if (done) break; + + const chunk = decoder.decode(value, { stream: true }); + const lines = chunk.split("\n"); + + for (const line of lines) { + if (line.startsWith("data: ")) { + const data = line.slice(6).trim(); + if (data === "[DONE]") { + // Signal completion + this.toolCallAccumulators.clear(); + yield { done: true }; + return; + } + if (data) { + try { + const parsed = JSON.parse(data); + + // Handle OpenAI streaming format + if (parsed.choices?.[0]?.delta) { + const delta = parsed.choices[0].delta; + + // Handle text content + if (delta.content) { + yield { response: delta.content, done: false }; + } + + // Handle tool call deltas (ACCUMULATE THEM!) + if (delta.tool_calls) { + for (const toolCallDelta of delta.tool_calls as ToolCallDelta[]) { + const index = toolCallDelta.index ?? 0; + + // Get or create accumulator for this tool call + if (!this.toolCallAccumulators.has(index)) { + this.toolCallAccumulators.set(index, { args: "" }); + } + const acc = this.toolCallAccumulators.get(index)!; + + // Accumulate id, name, and arguments + if (toolCallDelta.id) acc.id = toolCallDelta.id; + if (toolCallDelta.function?.name) acc.name = toolCallDelta.function.name; + if (toolCallDelta.function?.arguments) { + const newArgs = acc.args + toolCallDelta.function.arguments; + + // Prevent unbounded growth of tool call arguments + if (newArgs.length > this.MAX_TOOL_CALL_ARGS_SIZE) { + console.error(`Tool call arguments exceeded max size (${this.MAX_TOOL_CALL_ARGS_SIZE} bytes)`); + this.toolCallAccumulators.delete(index); + continue; + } + + acc.args = newArgs; + } + + // Check if we have a complete tool call + if (acc.name && acc.args && this.isCompleteJSON(acc.args)) { + try { + const args = acc.args.trim(); + // Validate JSON before emitting so we do not drop malformed payloads + JSON.parse(args); + + // Yield complete tool call + yield { + tool_calls: [{ + id: acc.id || `tool-${index}`, + type: "function", + function: { + name: acc.name, + arguments: args, + }, + }], + done: false, + }; + + // Clear accumulator + this.toolCallAccumulators.delete(index); + } catch (e) { + // JSON not valid yet, keep accumulating + } + } + } + } + } else if (parsed.response) { + // Handle Cloudflare format + yield { response: parsed.response, done: false }; + } + + // Check for completion + if (parsed.choices?.[0]?.finish_reason) { + this.toolCallAccumulators.clear(); + yield { + done: true, + usage: parsed.usage, + }; + } + } catch (error) { + // Handle partial JSON in buffer + const newBuffer = this.buffer + data; + + // Prevent unbounded buffer growth + if (newBuffer.length > this.MAX_BUFFER_SIZE) { + console.error(`Stream buffer exceeded max size (${this.MAX_BUFFER_SIZE} bytes). Resetting buffer.`); + this.buffer = ""; + continue; + } + + this.buffer = newBuffer; + try { + const parsed = JSON.parse(this.buffer); + if (parsed.choices?.[0]?.delta?.content) { + yield { response: parsed.choices[0].delta.content, done: false }; + } + this.buffer = ""; + } catch { + // Still incomplete, continue buffering + } + } + } + } + } + } + } finally { + reader.releaseLock(); + } + } + + parseSSE(text: string): CloudflareStreamChunk[] { + const chunks: CloudflareStreamChunk[] = []; + const lines = text.split("\n"); + + for (const line of lines) { + if (line.startsWith("data: ")) { + const data = line.slice(6); + if (data !== "[DONE]") { + try { + chunks.push(JSON.parse(data)); + } catch (error) { + console.error("Failed to parse SSE chunk:", error); + } + } + } + } + + return chunks; + } +} diff --git a/integrations/cloudflare/typescript/src/types.ts b/integrations/cloudflare/typescript/src/types.ts new file mode 100644 index 000000000..7eb9b8ef3 --- /dev/null +++ b/integrations/cloudflare/typescript/src/types.ts @@ -0,0 +1,168 @@ +import { z } from "zod"; + +/** + * Cloudflare Workers AI Models + * Updated to match available models as of January 2025 + */ +export const CloudflareModelSchema = z.enum([ + // Llama 3.1 series (general purpose) + "@cf/meta/llama-3.1-8b-instruct", + "@cf/meta/llama-3.1-70b-instruct", + + // Llama 3.3 series (function calling support) + "@cf/meta/llama-3.3-70b-instruct-fp8-fast", + + // Llama 4 series (latest, function calling) + "@cf/meta/llama-4-scout-17b-16e-instruct", + + // Mistral series + "@cf/mistral/mistral-7b-instruct-v0.2", + "@cf/mistralai/mistral-small-3.1-24b-instruct", + + // Hermes series (function calling) + "@cf/nousresearch/hermes-2-pro-mistral-7b", + + // Legacy models (may be deprecated) + "@cf/meta/llama-2-7b-chat-int8", + "@cf/google/gemma-7b-it", + "@cf/qwen/qwen1.5-14b-chat-awq", + "@cf/microsoft/phi-2", + "@cf/deepseek-ai/deepseek-math-7b-instruct", + "@cf/thebloke/deepseek-coder-6.7b-instruct-awq", +]); + +export type CloudflareModel = z.infer; + +/** + * Zod schema for message validation + */ +export const CloudflareMessageSchema = z.object({ + role: z.enum(["system", "user", "assistant", "tool", "function"]), + content: z.string(), + tool_calls: z.array(z.object({ + id: z.string(), + type: z.literal("function"), + function: z.object({ + name: z.string(), + arguments: z.string(), + }), + })).optional(), + tool_call_id: z.string().optional(), + name: z.string().optional(), +}); + +/** + * Zod schema for AI config validation + */ +export const CloudflareAIConfigSchema = z.object({ + accountId: z.string().min(1, "Account ID is required"), + apiToken: z.string().min(1, "API Token is required"), + model: CloudflareModelSchema.optional(), + baseURL: z.string().url().optional(), + gatewayId: z.string().optional(), +}); + +export interface CloudflareAIConfig { + accountId: string; + apiToken: string; + model?: CloudflareModel; + baseURL?: string; + gatewayId?: string; +} + +export interface CloudflareMessage { + role: "system" | "user" | "assistant" | "tool" | "function"; + content: string; + tool_calls?: ToolCall[]; + tool_call_id?: string; + name?: string; +} + +export interface ToolCall { + id: string; + type: "function"; + function: { + name: string; + arguments: string; + }; +} + +export interface CloudflareStreamChunk { + response?: string; + tool_calls?: ToolCall[]; + done?: boolean; + usage?: { + prompt_tokens: number; + completion_tokens: number; + total_tokens: number; + }; +} + +export interface CloudflareCompletionOptions { + messages: CloudflareMessage[]; + model?: CloudflareModel; + temperature?: number; + max_tokens?: number; + top_p?: number; + frequency_penalty?: number; + presence_penalty?: number; + stream?: boolean; + tools?: Tool[]; + tool_choice?: "auto" | "none" | { type: "function"; function: { name: string } }; +} + +/** + * JSON Schema type for tool parameters + * Represents a JSON Schema object describing function parameters + */ +export interface ToolParameters { + type: "object"; + properties: Record; + required?: string[]; + additionalProperties?: boolean; + [key: string]: unknown; +} + +export interface Tool { + type: "function"; + function: { + name: string; + description?: string; + /** JSON Schema describing the function parameters */ + parameters?: ToolParameters | Record; + }; +} + +export interface ModelCapabilities { + streaming: boolean; + functionCalling: boolean; + maxTokens: number; + contextWindow: number; +} + +/** + * Check if a model supports function/tool calling + */ +export function supportsToolCalling(model: CloudflareModel): boolean { + const toolCapableModels: CloudflareModel[] = [ + "@cf/meta/llama-3.3-70b-instruct-fp8-fast", + "@cf/meta/llama-4-scout-17b-16e-instruct", + "@cf/mistralai/mistral-small-3.1-24b-instruct", + "@cf/nousresearch/hermes-2-pro-mistral-7b", + ]; + return toolCapableModels.includes(model); +} + +/** + * Validate messages array with Zod + */ +export function validateMessages(messages: unknown[]): CloudflareMessage[] { + return messages.map((msg) => CloudflareMessageSchema.parse(msg)); +} + +/** + * Validate AI config with Zod + */ +export function validateConfig(config: unknown): CloudflareAIConfig { + return CloudflareAIConfigSchema.parse(config); +} diff --git a/integrations/cloudflare/typescript/src/workers-adapter.ts b/integrations/cloudflare/typescript/src/workers-adapter.ts new file mode 100644 index 000000000..1e40df5fe --- /dev/null +++ b/integrations/cloudflare/typescript/src/workers-adapter.ts @@ -0,0 +1,298 @@ +/** + * Cloudflare Workers Runtime Adapter + * + * Adapts AG-UI to work natively with Cloudflare Workers fetch API + * instead of Node.js Request/Response objects. + */ + +import { CloudflareAGUIAdapter, CloudflareAGUIAdapterOptions } from "./adapter"; +import { + normalizeRequest, + createResponseHeaders, + isWebSocketUpgrade, + validateWebSocketUpgrade, +} from "./cloudflare-utils"; +import { EventType, type BaseEvent, type RunErrorEvent } from "@ag-ui/core"; +import type { Tool, CloudflareModel, CloudflareMessage } from "./types"; + +export interface WorkersAdapterOptions extends CloudflareAGUIAdapterOptions { + /** Enable CORS for cross-origin requests */ + cors?: boolean; + /** Custom CORS origin (default: *) */ + corsOrigin?: string; + /** Handle WebSocket upgrades (requires Durable Objects) */ + websocket?: { + /** Durable Object namespace for WebSocket handling */ + durableObject?: DurableObjectNamespace; + /** Path to handle WebSocket connections */ + path?: string; + }; +} + +/** + * Cloudflare Workers Environment bindings + */ +export interface WorkersEnv { + /** Cloudflare Account ID */ + CLOUDFLARE_ACCOUNT_ID?: string; + /** Cloudflare API Token */ + CLOUDFLARE_API_TOKEN?: string; + /** AI Gateway ID */ + AI_GATEWAY_ID?: string; + /** Durable Object binding for WebSockets */ + WEBSOCKET_DO?: DurableObjectNamespace; + /** KV namespace for session storage */ + SESSIONS_KV?: KVNamespace; +} + +/** + * Main entry point for Cloudflare Workers + * + * @example + * ```typescript + * export default { + * async fetch(request, env, ctx) { + * return handleCloudflareWorker(request, env, { + * model: '@cf/meta/llama-3.1-8b-instruct' + * }); + * } + * }; + * ``` + */ +export async function handleCloudflareWorker( + request: Request, + env: WorkersEnv, + options?: Partial, +): Promise { + // Handle CORS preflight + if (request.method === "OPTIONS") { + return new Response(null, { + status: 204, + headers: createResponseHeaders({ + cors: options?.cors ?? true, + corsOrigin: options?.corsOrigin, + }), + }); + } + + // Normalize request with Cloudflare headers + const normalized = normalizeRequest(request); + + // Handle WebSocket upgrade + if (isWebSocketUpgrade(normalized.headers)) { + const validationError = validateWebSocketUpgrade(normalized.headers); + if (validationError) { + return new Response(validationError, { status: 400 }); + } + + if (options?.websocket?.durableObject) { + return handleWebSocketUpgrade(request, options.websocket.durableObject); + } + + return new Response("WebSocket support not configured", { status: 501 }); + } + + // Handle regular AG-UI requests + if (request.method === "POST") { + return handleAGUIRequest(request, env, options); + } + + return new Response("Method not allowed", { status: 405 }); +} + +/** + * Handle standard AG-UI chat completion requests + */ +async function handleAGUIRequest( + request: Request, + env: WorkersEnv, + options?: Partial, +): Promise { + try { + // Validate environment variables + if (!env.CLOUDFLARE_ACCOUNT_ID || !env.CLOUDFLARE_API_TOKEN) { + return new Response( + JSON.stringify({ error: "Missing CLOUDFLARE_ACCOUNT_ID or CLOUDFLARE_API_TOKEN" }), + { status: 500, headers: { "Content-Type": "application/json" } } + ); + } + + // Parse request body + const body = (await request.json()) as { + messages: CloudflareMessage[]; + model?: CloudflareModel; + tools?: Tool[]; + }; + + // Create adapter with environment variables + const adapter = new CloudflareAGUIAdapter({ + accountId: env.CLOUDFLARE_ACCOUNT_ID, + apiToken: env.CLOUDFLARE_API_TOKEN, + model: (options?.model || body.model || "@cf/meta/llama-3.1-8b-instruct") as CloudflareModel, + gatewayId: env.AI_GATEWAY_ID, + tools: options?.tools || body.tools, + ...options, + }); + + // Create response headers for SSE + const headers = createResponseHeaders({ + cors: options?.cors ?? true, + corsOrigin: options?.corsOrigin, + }); + + // Stream AG-UI events as Server-Sent Events + const { readable, writable } = new TransformStream(); + const writer = writable.getWriter(); + const encoder = new TextEncoder(); + + // Start streaming in background + (async () => { + try { + for await (const event of adapter.execute(body.messages)) { + await writer.write(encoder.encode(formatSSE(event))); + } + } catch (error) { + console.error("Error streaming AG-UI events:", error); + const errorEvent: RunErrorEvent = { + type: EventType.RUN_ERROR, + message: error instanceof Error ? error.message : "Unknown error", + timestamp: Date.now(), + }; + await writer.write(encoder.encode(formatSSE(errorEvent))); + } finally { + await writer.close(); + } + })(); + + return new Response(readable, { + status: 200, + headers, + }); + } catch (error) { + console.error("Error handling AG-UI request:", error); + return new Response( + JSON.stringify({ + error: error instanceof Error ? error.message : "Internal server error", + }), + { + status: 500, + headers: { "Content-Type": "application/json" }, + }, + ); + } +} + +/** + * Handle WebSocket upgrade with Durable Objects + */ +async function handleWebSocketUpgrade( + request: Request, + durableObject: DurableObjectNamespace, +): Promise { + // Create unique Durable Object for each WebSocket connection + const id = durableObject.newUniqueId(); + const stub = durableObject.get(id); + + // Forward upgrade request to Durable Object + return stub.fetch(request); +} + +/** + * Format AG-UI event as Server-Sent Event + */ +function formatSSE(event: BaseEvent): string { + return `event: ${event.type}\ndata: ${JSON.stringify(event)}\n\n`; +} + +/** + * Create a Cloudflare Worker handler with AG-UI support + * + * @example + * ```typescript + * export default createCloudflareWorkerHandler({ + * model: '@cf/meta/llama-3.1-8b-instruct', + * cors: true, + * }); + * ``` + */ +export function createCloudflareWorkerHandler(options?: Partial): { + fetch: (request: Request, env: WorkersEnv, ctx: ExecutionContext) => Promise; +} { + return { + async fetch(request, env, _ctx) { + return handleCloudflareWorker(request, env, options); + }, + }; +} + +/** + * Durable Object for WebSocket handling + * + * @example + * ```typescript + * export class WebSocketDO { + * constructor(state: DurableObjectState, env: WorkersEnv) { + * // Initialize + * } + * + * async fetch(request: Request) { + * return handleWebSocketConnection(request, this.state, this.env); + * } + * } + * ``` + */ +export async function handleWebSocketConnection( + request: Request, + _state: DurableObjectState, + env: WorkersEnv, + options?: Partial, +): Promise { + // Validate environment variables + if (!env.CLOUDFLARE_ACCOUNT_ID || !env.CLOUDFLARE_API_TOKEN) { + return new Response("Missing credentials", { status: 500 }); + } + + // Create adapter once for this connection + const adapter = new CloudflareAGUIAdapter({ + accountId: env.CLOUDFLARE_ACCOUNT_ID, + apiToken: env.CLOUDFLARE_API_TOKEN, + model: options?.model || "@cf/meta/llama-3.1-8b-instruct", + gatewayId: env.AI_GATEWAY_ID, + ...options, + }); + + // Create WebSocket pair + const pair = new WebSocketPair(); + const [client, server] = Object.values(pair) as [WebSocket, WebSocket]; + + // Accept the connection + server.accept(); + + // Handle messages + server.addEventListener("message", async (event: MessageEvent) => { + try { + const message = JSON.parse(event.data as string); + + // Stream events back over WebSocket + for await (const aguiEvent of adapter.execute(message.messages || [])) { + server.send(JSON.stringify(aguiEvent)); + } + } catch (error) { + const errorEvent: RunErrorEvent = { + type: EventType.RUN_ERROR, + message: error instanceof Error ? error.message : "Unknown error", + timestamp: Date.now(), + }; + server.send(JSON.stringify(errorEvent)); + } + }); + + server.addEventListener("close", () => { + // Cleanup + }); + + return new Response(null, { + status: 101, + webSocket: client as any, + } as any); +} diff --git a/integrations/cloudflare/typescript/tsconfig.json b/integrations/cloudflare/typescript/tsconfig.json new file mode 100644 index 000000000..13fa205df --- /dev/null +++ b/integrations/cloudflare/typescript/tsconfig.json @@ -0,0 +1,26 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "esnext", + "lib": ["ES2020"], + "types": ["@cloudflare/workers-types"], + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "moduleResolution": "node", + "skipLibCheck": true, + "strict": true, + "esModuleInterop": true, + "resolveJsonModule": true, + "isolatedModules": true, + "baseUrl": ".", + "paths": { + "@/*": ["./src/*"] + }, + "stripInternal": true, + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src"], + "exclude": ["node_modules", "dist", "examples"] +} diff --git a/integrations/cloudflare/typescript/tsup.config.ts b/integrations/cloudflare/typescript/tsup.config.ts new file mode 100644 index 000000000..59b1dd419 --- /dev/null +++ b/integrations/cloudflare/typescript/tsup.config.ts @@ -0,0 +1,12 @@ +import { defineConfig } from "tsup"; + +export default defineConfig({ + entry: ["src/index.ts"], + format: ["cjs", "esm"], + dts: true, + sourcemap: true, + clean: true, + splitting: false, + minify: false, + external: ["@ag-ui/core", "@ag-ui/client", "@copilotkit/runtime", "agents"], +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 70be6bfa3..9274a63e0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,7 +40,7 @@ importers: version: 0.12.1(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76) '@mastra/libsql': specifier: 0.12.0 - version: 0.12.0(@mastra/core@0.12.1(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76)) + version: 0.12.0(@mastra/core@0.12.1(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76))(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@mastra/loggers': specifier: 0.10.5 version: 0.10.5(@mastra/core@0.12.1(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76)) @@ -78,6 +78,9 @@ importers: '@ag-ui/client': specifier: workspace:* version: link:../../sdks/typescript/packages/client + '@ag-ui/cloudflare': + specifier: workspace:* + version: link:../../integrations/cloudflare/typescript '@ag-ui/core': specifier: workspace:* version: link:../../sdks/typescript/packages/core @@ -128,7 +131,7 @@ importers: version: 1.10.6(@types/react@19.2.2)(graphql@16.11.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@copilotkit/runtime': specifier: 1.10.6 - version: 1.10.6(43a54c62826e391639c20a8a0387b983) + version: 1.10.6(6baa88a9727729a45a3f3165407bbf6b) '@copilotkit/runtime-client-gql': specifier: 1.10.6 version: 1.10.6(graphql@16.11.0)(react@19.2.0) @@ -146,7 +149,7 @@ importers: version: 0.15.6(@mastra/core@0.20.2(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76)) '@mastra/libsql': specifier: ^0.15.1 - version: 0.15.1(@mastra/core@0.20.2(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76)) + version: 0.15.1(@mastra/core@0.20.2(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76))(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@mastra/loggers': specifier: ^0.10.15 version: 0.10.15(@mastra/core@0.20.2(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76)) @@ -233,7 +236,7 @@ importers: version: 0.4.6(react-dom@19.2.0(react@19.2.0))(react@19.2.0) openai: specifier: ^4.98.0 - version: 4.104.0(ws@8.18.3)(zod@3.25.76) + version: 4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) react: specifier: ^19.0.0 version: 19.2.0 @@ -367,6 +370,83 @@ importers: specifier: ^5.3.3 version: 5.9.3 + integrations/cloudflare/typescript: + dependencies: + '@copilotkit/runtime': + specifier: ^1.0.0 + version: 1.10.6(11965aeb7c1575ca0e6e335d73f00c47) + agents: + specifier: ^0.1.0 + version: 0.1.6(@cloudflare/workers-types@4.20251011.0)(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@tanstack/query-core@5.90.3)(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + eventsource-parser: + specifier: ^2.0.1 + version: 2.0.1 + rxjs: + specifier: 7.8.1 + version: 7.8.1 + uuid: + specifier: ^11.1.0 + version: 11.1.0 + zod: + specifier: ^3.23.8 + version: 3.25.76 + devDependencies: + '@ag-ui/client': + specifier: workspace:* + version: link:../../../sdks/typescript/packages/client + '@ag-ui/core': + specifier: workspace:* + version: link:../../../sdks/typescript/packages/core + '@cloudflare/workers-types': + specifier: ^4.20251011.0 + version: 4.20251011.0 + '@types/node': + specifier: ^20.0.0 + version: 20.19.21 + jest: + specifier: ^29.0.0 + version: 29.7.0(@types/node@20.19.21) + tsup: + specifier: ^8.0.0 + version: 8.5.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1) + typescript: + specifier: ^5.4.0 + version: 5.9.3 + + integrations/cloudflare/typescript/examples: + dependencies: + '@ag-ui/cloudflare': + specifier: workspace:* + version: link:.. + '@ag-ui/core': + specifier: workspace:* + version: link:../../../../sdks/typescript/packages/core + cors: + specifier: ^2.8.5 + version: 2.8.5 + dotenv: + specifier: ^16.4.5 + version: 16.6.1 + express: + specifier: ^4.18.2 + version: 4.21.2 + devDependencies: + '@types/cors': + specifier: ^2.8.17 + version: 2.8.19 + '@types/express': + specifier: ^4.17.21 + version: 4.17.23 + '@types/node': + specifier: ^20.10.0 + version: 20.19.21 + tsx: + specifier: ^4.7.0 + version: 4.20.6 + typescript: + specifier: ^5.3.3 + version: 5.9.3 + integrations/community/spring-ai/typescript: dependencies: rxjs: @@ -433,10 +513,10 @@ importers: dependencies: '@langchain/core': specifier: ^0.3.66 - version: 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + version: 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) '@langchain/langgraph-sdk': specifier: ^0.1.2 - version: 0.1.10(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + version: 0.1.10(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) partial-json: specifier: ^0.1.7 version: 0.1.7 @@ -469,6 +549,34 @@ importers: specifier: ^5.3.3 version: 5.9.3 + integrations/langgraph/typescript/examples: + dependencies: + '@langchain/core': + specifier: ^0.3.66 + version: 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/langgraph': + specifier: ^0.2.65 + version: 0.2.74(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react@19.2.0)(zod-to-json-schema@3.24.6(zod@3.25.76)) + '@langchain/openai': + specifier: ^0.6.3 + version: 0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + dotenv: + specifier: ^16.4.5 + version: 16.6.1 + uuid: + specifier: ^10.0.0 + version: 10.0.0 + devDependencies: + '@types/node': + specifier: ^20.0.0 + version: 20.19.21 + '@types/uuid': + specifier: ^10.0.0 + version: 10.0.0 + typescript: + specifier: ^5.0.0 + version: 5.9.3 + integrations/llama-index/typescript: dependencies: rxjs: @@ -507,7 +615,7 @@ importers: version: 1.2.11(zod@3.25.76) '@copilotkit/runtime': specifier: ^1.10.5 - version: 1.10.6(2963fdc46a5185bf1f60e289781c45cd) + version: 1.10.6(11965aeb7c1575ca0e6e335d73f00c47) '@mastra/client-js': specifier: ^0.15.2 version: 0.15.2(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76) @@ -559,7 +667,7 @@ importers: version: 0.20.2(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76) '@mastra/libsql': specifier: ^0.15.1 - version: 0.15.1(@mastra/core@0.20.2(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76)) + version: 0.15.1(@mastra/core@0.20.2(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76))(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@mastra/loggers': specifier: ^0.10.15 version: 0.10.15(@mastra/core@0.20.2(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76)) @@ -950,6 +1058,9 @@ packages: resolution: {integrity: sha512-VTDuRS5V0ATbJ/LkaQlisMnTAeYKXAK6scMguVBstf+KIBQ7HIuKhiXLv+G/hvejkV+THoXzoNifInAkU81P1g==} engines: {node: '>=18'} + '@adraffy/ens-normalize@1.11.1': + resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==} + '@ag-ui/client@0.0.35': resolution: {integrity: sha512-rHtMQSU232dZeVx9qAGt1+j4ar4RWqwFanXcyNxAwbAh0XrY7VZeXFBDUeazy1LtBoViS7xehX8V1Ssf1a+bUw==} @@ -986,6 +1097,12 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/gateway@1.0.25': + resolution: {integrity: sha512-eI/6LLmn1tWFzuhjxgcPEqUFXwLjyRuGFrwkCoqLaTKe/qMYBEAV3iddnGUM0AV+Hp4NEykzP4ly5tibOLDMXw==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4 + '@ai-sdk/gateway@1.0.33': resolution: {integrity: sha512-v9i3GPEo4t3fGcSkQkc07xM6KJN75VUv7C1Mqmmsu2xD8lQwnQfsrgAXyNuWe20yGY0eHuheSPDZhiqsGKtH1g==} engines: {node: '>=18'} @@ -1040,6 +1157,12 @@ packages: peerDependencies: zod: ^3.25.76 || ^4.1.8 + '@ai-sdk/provider-utils@3.0.9': + resolution: {integrity: sha512-Pm571x5efqaI4hf9yW4KsVlDBDme8++UepZRnq+kqVBWWjgvGhQlzU8glaFq0YJEB9kkxZHbRRyVeHoV2sRYaQ==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4 + '@ai-sdk/provider@1.1.3': resolution: {integrity: sha512-qZMxYJ0qqX/RfnuIaab+zp8UAeJn/ygXXAffR5I4N0n1IrvA6qBsjc8hXLmBiMV2zoXlifkacF7sEFnYnjBcqg==} engines: {node: '>=18'} @@ -1452,6 +1575,10 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 + '@babel/runtime-corejs3@7.28.4': + resolution: {integrity: sha512-h7iEYiW4HebClDEhtvFObtPmIvrd1SSfpI9EhOeKk4CtIK/ngBWFpuhCzhdmRKtg71ylcue+9I6dv54XYO1epQ==} + engines: {node: '>=6.9.0'} + '@babel/runtime@7.28.4': resolution: {integrity: sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==} engines: {node: '>=6.9.0'} @@ -1468,6 +1595,9 @@ packages: resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} + '@base-org/account@1.1.1': + resolution: {integrity: sha512-IfVJPrDPhHfqXRDb89472hXkpvJuQQR7FDI9isLPHEqSYt/45whIoBxSPgZ0ssTt379VhQo4+87PWI1DoLSfAQ==} + '@bcoe/v8-coverage@0.2.3': resolution: {integrity: sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==} @@ -1495,6 +1625,15 @@ packages: '@clack/prompts@0.11.0': resolution: {integrity: sha512-pMN5FcrEw9hUkZA4f+zLlzivQSeQf5dRGJjSUbvVYDLvpKCdQx5OaknvKzgbtXOizhP+SJJJjqEbOe55uKKfAw==} + '@cloudflare/workers-types@4.20251011.0': + resolution: {integrity: sha512-gQpih+pbq3sP4uXltUeCSbPgZxTNp2gQd8639SaIbQMwgA6oJNHLhIART1fWy6DQACngiRzDVULA2x0ohmkGTQ==} + + '@coinbase/wallet-sdk@3.9.3': + resolution: {integrity: sha512-N/A2DRIf0Y3PHc1XAMvbBUu4zisna6qAdqABMZwBMNEfWrXpAwx16pZGkYCLGE+Rvv1edbcB2LYDRnACNcmCiw==} + + '@coinbase/wallet-sdk@4.3.6': + resolution: {integrity: sha512-4q8BNG1ViL4mSAAvPAtpwlOs1gpC+67eQtgIwNvT3xyeyFFd+guwkc8bcX5rTmQhXpqnhzC4f0obACbP9CqMSA==} + '@copilotkit/react-core@1.10.6': resolution: {integrity: sha512-sdojpntwgOxP8lWRzaFEiWr0g2wDefjQHtve5GPPie+otseFonV88FZjSqIq5LN+q5BIwDOEhCmDjALsGjXvuQ==} peerDependencies: @@ -1523,6 +1662,12 @@ packages: '@copilotkit/shared@1.10.6': resolution: {integrity: sha512-56Rltf4fDBqCpl1ZXARypt5NdE4LTg3tGPPLurZpgPmm31Lv5EAHpfjC7I55vt9A0mXWlTCHtCrpiaAlTyzGJw==} + '@ecies/ciphers@0.2.4': + resolution: {integrity: sha512-t+iX+Wf5nRKyNzk8dviW3Ikb/280+aEJAnw9YXvCp2tYGPSkMki+NRY+8aNLmVFv3eNtMdvViPNOPxS8SZNP+w==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + peerDependencies: + '@noble/ciphers': ^1.0.0 + '@emnapi/core@1.5.0': resolution: {integrity: sha512-sbP8GzB1WDzacS8fgNPpHlp6C9VZe+SJP3F90W9rLemaQj2PzIuTEl1qDOYQf58YIpyjViI24y9aPWCjEzY2cg==} @@ -1738,6 +1883,22 @@ packages: resolution: {integrity: sha512-sB5uyeq+dwCWyPi31B2gQlVlo+j5brPlWx4yZBrEaRo/nhdDE8Xke1gsGgtiBdaBTxuTkceLVuVt/pclrasb0A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@ethereumjs/common@3.2.0': + resolution: {integrity: sha512-pksvzI0VyLgmuEF2FA/JR/4/y6hcPq8OUail3/AvycBaW1d5VSauOZzqGvJ3RTmR4MU35lWE8KseKOsEhrFRBA==} + + '@ethereumjs/rlp@4.0.1': + resolution: {integrity: sha512-tqsQiBQDQdmPWE1xkkBq4rlSW5QZpLOUJ5RJh2/9fug+q9tnUhuZoVLk7s0scUIKTOzEtR72DFBXI4WiZcMpvw==} + engines: {node: '>=14'} + hasBin: true + + '@ethereumjs/tx@4.2.0': + resolution: {integrity: sha512-1nc6VO4jtFd172BbSnTnDQVr9IYBFl1y4xPzZdtkrkKIncBCkdbgfdRV+MiTkJYAtTxvV12GRZLqBFT1PNK6Yw==} + engines: {node: '>=14'} + + '@ethereumjs/util@8.1.0': + resolution: {integrity: sha512-zQ0IqbdX8FZ9aw11vP+dZkKDkS+kgIvQPHnSAXzP9pLu+Rfu3D3XEeLbicvoXJTYnhZiPmsZUxgdzXwNKxRPbA==} + engines: {node: '>=14'} + '@expo/devcert@1.2.0': resolution: {integrity: sha512-Uilcv3xGELD5t/b0eM4cxBFEKQRIivB3v7i+VhWLV/gL98aw810unLKKJbGAxAIhY6Ipyz8ChWibFsKFXYwstA==} @@ -1768,6 +1929,11 @@ packages: '@floating-ui/utils@0.2.10': resolution: {integrity: sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==} + '@gemini-wallet/core@0.2.0': + resolution: {integrity: sha512-vv9aozWnKrrPWQ3vIFcWk7yta4hQW1Ie0fsNNPeXnjAxkbXr2hqMagEptLuMxpEP2W3mnRu05VDNKzcvAuuZDw==} + peerDependencies: + viem: '>=2.0.0' + '@graphql-tools/executor@1.4.9': resolution: {integrity: sha512-SAUlDT70JAvXeqV87gGzvDzUGofn39nvaVcVhNf12Dt+GfWHtNNO/RCn/Ea4VJaSLGzraUd41ObnN3i80EBU7w==} engines: {node: '>=16.0.0'} @@ -2601,6 +2767,12 @@ packages: peerDependencies: '@langchain/core': '>=0.2.21 <0.4.0' + '@langchain/langgraph-checkpoint@0.0.18': + resolution: {integrity: sha512-IS7zJj36VgY+4pf8ZjsVuUWef7oTwt1y9ylvwu0aLuOn1d0fg05Om9DLm3v2GZ2Df6bhLV1kfWAM0IAl9O5rQQ==} + engines: {node: '>=18'} + peerDependencies: + '@langchain/core': '>=0.2.31 <0.4.0' + '@langchain/langgraph-sdk@0.0.70': resolution: {integrity: sha512-O8I12bfeMVz5fOrXnIcK4IdRf50IqyJTO458V56wAIHLNoi4H8/JHM+2M+Y4H2PtslXIGnvomWqlBd0eY5z/Og==} peerDependencies: @@ -2626,6 +2798,16 @@ packages: react-dom: optional: true + '@langchain/langgraph@0.2.74': + resolution: {integrity: sha512-oHpEi5sTZTPaeZX1UnzfM2OAJ21QGQrwReTV6+QnX7h8nDCBzhtipAw1cK616S+X8zpcVOjgOtJuaJhXa4mN8w==} + engines: {node: '>=18'} + peerDependencies: + '@langchain/core': '>=0.2.36 <0.3.0 || >=0.3.40 < 0.4.0' + zod-to-json-schema: ^3.x + peerDependenciesMeta: + zod-to-json-schema: + optional: true + '@langchain/openai@0.4.9': resolution: {integrity: sha512-NAsaionRHNdqaMjVLPkFCyjUDze+OqRHghA1Cn4fPoAafz+FXcl9c7LlEl9Xo0FH6/8yiCl7Rw2t780C/SBVxQ==} engines: {node: '>=18'} @@ -2711,6 +2893,12 @@ packages: cpu: [x64] os: [win32] + '@lit-labs/ssr-dom-shim@1.4.0': + resolution: {integrity: sha512-ficsEARKnmmW5njugNYKipTm4SFnbik7CXtoencDZzmzo/dQ+2Q0bgkzJuoJP20Aj0F+izzJjOqsnkd6F/o1bw==} + + '@lit/reactive-element@2.1.1': + resolution: {integrity: sha512-N+dm5PAYdQ8e6UlywyyrgI2t++wFGXfHx+dSJ1oBrg6FAxUj40jId++EaRm80MKX5JnlH1sBsyZ5h0bcZKemCg==} + '@lukeed/csprng@1.1.0': resolution: {integrity: sha512-Z7C/xXCiGWsg0KuKsHTKJxbWhpI3Vs5GwLfOean7MGyVFGqdRgBbAjOCh6u4bbjPc/8MJ2pZmK/0DLdCbivLDA==} engines: {node: '>=8'} @@ -2824,6 +3012,86 @@ packages: '@types/react': '>=16' react: '>=16' + '@metamask/eth-json-rpc-provider@1.0.1': + resolution: {integrity: sha512-whiUMPlAOrVGmX8aKYVPvlKyG4CpQXiNNyt74vE1xb5sPvmx5oA7B/kOi/JdBvhGQq97U1/AVdXEdk2zkP8qyA==} + engines: {node: '>=14.0.0'} + + '@metamask/json-rpc-engine@7.3.3': + resolution: {integrity: sha512-dwZPq8wx9yV3IX2caLi9q9xZBw2XeIoYqdyihDDDpuHVCEiqadJLwqM3zy+uwf6F1QYQ65A8aOMQg1Uw7LMLNg==} + engines: {node: '>=16.0.0'} + + '@metamask/json-rpc-engine@8.0.2': + resolution: {integrity: sha512-IoQPmql8q7ABLruW7i4EYVHWUbF74yrp63bRuXV5Zf9BQwcn5H9Ww1eLtROYvI1bUXwOiHZ6qT5CWTrDc/t/AA==} + engines: {node: '>=16.0.0'} + + '@metamask/json-rpc-middleware-stream@7.0.2': + resolution: {integrity: sha512-yUdzsJK04Ev98Ck4D7lmRNQ8FPioXYhEUZOMS01LXW8qTvPGiRVXmVltj2p4wrLkh0vW7u6nv0mNl5xzC5Qmfg==} + engines: {node: '>=16.0.0'} + + '@metamask/object-multiplex@2.1.0': + resolution: {integrity: sha512-4vKIiv0DQxljcXwfpnbsXcfa5glMj5Zg9mqn4xpIWqkv6uJ2ma5/GtUfLFSxhlxnR8asRMv8dDmWya1Tc1sDFA==} + engines: {node: ^16.20 || ^18.16 || >=20} + + '@metamask/onboarding@1.0.1': + resolution: {integrity: sha512-FqHhAsCI+Vacx2qa5mAFcWNSrTcVGMNjzxVgaX8ECSny/BJ9/vgXP9V7WF/8vb9DltPeQkxr+Fnfmm6GHfmdTQ==} + + '@metamask/providers@16.1.0': + resolution: {integrity: sha512-znVCvux30+3SaUwcUGaSf+pUckzT5ukPRpcBmy+muBLC0yaWnBcvDqGfcsw6CBIenUdFrVoAFa8B6jsuCY/a+g==} + engines: {node: ^18.18 || >=20} + + '@metamask/rpc-errors@6.4.0': + resolution: {integrity: sha512-1ugFO1UoirU2esS3juZanS/Fo8C8XYocCuBpfZI5N7ECtoG+zu0wF+uWZASik6CkO6w9n/Iebt4iI4pT0vptpg==} + engines: {node: '>=16.0.0'} + + '@metamask/rpc-errors@7.0.2': + resolution: {integrity: sha512-YYYHsVYd46XwY2QZzpGeU4PSdRhHdxnzkB8piWGvJW2xbikZ3R+epAYEL4q/K8bh9JPTucsUdwRFnACor1aOYw==} + engines: {node: ^18.20 || ^20.17 || >=22} + + '@metamask/safe-event-emitter@2.0.0': + resolution: {integrity: sha512-/kSXhY692qiV1MXu6EeOZvg5nECLclxNXcKCxJ3cXQgYuRymRHpdx/t7JXfsK+JLjwA1e1c1/SBrlQYpusC29Q==} + + '@metamask/safe-event-emitter@3.1.2': + resolution: {integrity: sha512-5yb2gMI1BDm0JybZezeoX/3XhPDOtTbcFvpTXM9kxsoZjPZFh4XciqRbpD6N86HYZqWDhEaKUDuOyR0sQHEjMA==} + engines: {node: '>=12.0.0'} + + '@metamask/sdk-analytics@0.0.5': + resolution: {integrity: sha512-fDah+keS1RjSUlC8GmYXvx6Y26s3Ax1U9hGpWb6GSY5SAdmTSIqp2CvYy6yW0WgLhnYhW+6xERuD0eVqV63QIQ==} + + '@metamask/sdk-communication-layer@0.33.1': + resolution: {integrity: sha512-0bI9hkysxcfbZ/lk0T2+aKVo1j0ynQVTuB3sJ5ssPWlz+Z3VwveCkP1O7EVu1tsVVCb0YV5WxK9zmURu2FIiaA==} + peerDependencies: + cross-fetch: ^4.0.0 + eciesjs: '*' + eventemitter2: ^6.4.9 + readable-stream: ^3.6.2 + socket.io-client: ^4.5.1 + + '@metamask/sdk-install-modal-web@0.32.1': + resolution: {integrity: sha512-MGmAo6qSjf1tuYXhCu2EZLftq+DSt5Z7fsIKr2P+lDgdTPWgLfZB1tJKzNcwKKOdf6q9Qmmxn7lJuI/gq5LrKw==} + + '@metamask/sdk@0.33.1': + resolution: {integrity: sha512-1mcOQVGr9rSrVcbKPNVzbZ8eCl1K0FATsYH3WJ/MH4WcZDWGECWrXJPNMZoEAkLxWiMe8jOQBumg2pmcDa9zpQ==} + + '@metamask/superstruct@3.2.1': + resolution: {integrity: sha512-fLgJnDOXFmuVlB38rUN5SmU7hAFQcCjrg3Vrxz67KTY7YHFnSNEKvX4avmEBdOI0yTCxZjwMCFEqsC8k2+Wd3g==} + engines: {node: '>=16.0.0'} + + '@metamask/utils@11.8.1': + resolution: {integrity: sha512-DIbsNUyqWLFgqJlZxi1OOCMYvI23GqFCvNJAtzv8/WXWzJfnJnvp1M24j7VvUe3URBi3S86UgQ7+7aWU9p/cnQ==} + engines: {node: ^18.18 || ^20.14 || >=22} + + '@metamask/utils@5.0.2': + resolution: {integrity: sha512-yfmE79bRQtnMzarnKfX7AEJBwFTxvTyw3nBQlu/5rmGXrjAeAMltoGxO62TFurxrQAFMNa/fEjIHNvungZp0+g==} + engines: {node: '>=14.0.0'} + + '@metamask/utils@8.5.0': + resolution: {integrity: sha512-I6bkduevXb72TIM9q2LRO63JSsF9EXduh3sBr9oybNX2hNNpr/j1tEjXrsG0Uabm4MJ1xkGAQEMwifvKZIkyxQ==} + engines: {node: '>=16.0.0'} + + '@metamask/utils@9.3.0': + resolution: {integrity: sha512-w8CVbdkDrVXFJbfBSlDfafDR6BAkpDmv1bC1UJVCoVny5tW2RKAdn9i68Xf7asYT4TnUhl/hN4zfUiKQq9II4g==} + engines: {node: '>=16.0.0'} + '@modelcontextprotocol/sdk@1.20.0': resolution: {integrity: sha512-kOQ4+fHuT4KbR2iq2IjeV32HiihueuOf1vJkq18z08CLZ1UQrTc8BXJpVfxZkq45+inLLD+D4xx4nBjUelJa4Q==} engines: {node: '>=18'} @@ -2912,6 +3180,49 @@ packages: cpu: [x64] os: [win32] + '@noble/ciphers@1.2.1': + resolution: {integrity: sha512-rONPWMC7PeExE077uLE4oqWrZ1IvAfz3oH9LibVAcVCopJiA9R62uavnbEzdkVmJYI6M6Zgkbeb07+tWjlq2XA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/ciphers@1.3.0': + resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.4.2': + resolution: {integrity: sha512-TavHr8qycMChk8UwMld0ZDRvatedkzWfH8IiaeGCfymOP5i0hSCozz9vHOL0nkwk7HRMlFnAiKpS2jrUmSybcw==} + + '@noble/curves@1.8.0': + resolution: {integrity: sha512-j84kjAbzEnQHaSIhRPUmB3/eVXu2k3dKPl2LOrR8fSOIL+89U+7lV117EWHtq/GHM3ReGHM46iRBdZfpc4HRUQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.8.1': + resolution: {integrity: sha512-warwspo+UYUPep0Q+vtdVB4Ugn8GGQj8iyB3gnRWsztmUHTI3S1nhdiWNsPUGL0vud7JlRRk1XEu7Lq1KGTnMQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.1': + resolution: {integrity: sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA==} + engines: {node: ^14.21.3 || >=16} + + '@noble/curves@1.9.7': + resolution: {integrity: sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.4.0': + resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} + engines: {node: '>= 16'} + + '@noble/hashes@1.7.0': + resolution: {integrity: sha512-HXydb0DgzTpDPwbVeDGCG1gIu7X6+AuU6Zl6av/E/KG8LMsvPntvq+w17CHRpKBmN6Ybdrt1eP3k4cj8DJa78w==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.7.1': + resolution: {integrity: sha512-B8XBPsn4vT/KJAGqDzbwztd+6Yte3P4V7iafm24bxgDe/mlRuK6xmWPuCNrKt2vDafZ8MfJLlchDG/vYafQEjQ==} + engines: {node: ^14.21.3 || >=16} + + '@noble/hashes@1.8.0': + resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==} + engines: {node: ^14.21.3 || >=16} + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -3430,6 +3741,10 @@ packages: resolution: {integrity: sha512-9+qMSaDpahC0+vX2ChM46/ls6a5Ankqs6RTLrHSaFpm7o1mFanP82e+jm9/0o5D660ueK8dWJGPCXQrBxBNNWA==} engines: {node: '>= 12'} + '@paulmillr/qr@0.2.1': + resolution: {integrity: sha512-IHnV6A+zxU7XwmKFinmYjUcwlyK9+xkG3/s9KcQhI9BjQKycrJ1JRO+FbNYPwZiPKW3je/DR0k7w8/gLa5eaxQ==} + deprecated: 'The package is now available as "qr": npm install qr' + '@phosphor-icons/react@2.1.10': resolution: {integrity: sha512-vt8Tvq8GLjheAZZYa+YG/pW7HDbov8El/MANW8pOAz4eGxrwhnbfrQZq0Cp4q8zBEu8NIhHdnr+r8thnfRSNYA==} engines: {node: '>=10'} @@ -3830,6 +4145,35 @@ packages: '@remirror/core-constants@3.0.0': resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==} + '@reown/appkit-common@1.7.8': + resolution: {integrity: sha512-ridIhc/x6JOp7KbDdwGKY4zwf8/iK8EYBl+HtWrruutSLwZyVi5P8WaZa+8iajL6LcDcDF7LoyLwMTym7SRuwQ==} + + '@reown/appkit-controllers@1.7.8': + resolution: {integrity: sha512-IdXlJlivrlj6m63VsGLsjtPHHsTWvKGVzWIP1fXZHVqmK+rZCBDjCi9j267Rb9/nYRGHWBtlFQhO8dK35WfeDA==} + + '@reown/appkit-pay@1.7.8': + resolution: {integrity: sha512-OSGQ+QJkXx0FEEjlpQqIhT8zGJKOoHzVnyy/0QFrl3WrQTjCzg0L6+i91Ad5Iy1zb6V5JjqtfIFpRVRWN4M3pw==} + + '@reown/appkit-polyfills@1.7.8': + resolution: {integrity: sha512-W/kq786dcHHAuJ3IV2prRLEgD/2iOey4ueMHf1sIFjhhCGMynMkhsOhQMUH0tzodPqUgAC494z4bpIDYjwWXaA==} + + '@reown/appkit-scaffold-ui@1.7.8': + resolution: {integrity: sha512-RCeHhAwOrIgcvHwYlNWMcIDibdI91waaoEYBGw71inE0kDB8uZbE7tE6DAXJmDkvl0qPh+DqlC4QbJLF1FVYdQ==} + + '@reown/appkit-ui@1.7.8': + resolution: {integrity: sha512-1hjCKjf6FLMFzrulhl0Y9Vb9Fu4royE+SXCPSWh4VhZhWqlzUFc7kutnZKx8XZFVQH4pbBvY62SpRC93gqoHow==} + + '@reown/appkit-utils@1.7.8': + resolution: {integrity: sha512-8X7UvmE8GiaoitCwNoB86pttHgQtzy4ryHZM9kQpvjQ0ULpiER44t1qpVLXNM4X35O0v18W0Dk60DnYRMH2WRw==} + peerDependencies: + valtio: 1.13.2 + + '@reown/appkit-wallet@1.7.8': + resolution: {integrity: sha512-kspz32EwHIOT/eg/ZQbFPxgXq0B/olDOj3YMu7gvLEFz4xyOFd/wgzxxAXkp5LbG4Cp++s/elh79rVNmVFdB9A==} + + '@reown/appkit@1.7.8': + resolution: {integrity: sha512-51kTleozhA618T1UvMghkhKfaPcc9JlKwLJ5uV+riHyvSoWPKPRIa5A6M1Wano5puNyW0s3fwywhyqTHSilkaA==} + '@repeaterjs/repeater@3.0.6': resolution: {integrity: sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA==} @@ -4117,9 +4461,43 @@ packages: '@rushstack/eslint-patch@1.14.0': resolution: {integrity: sha512-WJFej426qe4RWOm9MMtP4V3CV4AucXolQty+GRgAWLgQXmpCuwzs7hEpxxhSc/znXUSxum9d/P/32MW0FlAAlA==} + '@safe-global/safe-apps-provider@0.18.6': + resolution: {integrity: sha512-4LhMmjPWlIO8TTDC2AwLk44XKXaK6hfBTWyljDm0HQ6TWlOEijVWNrt2s3OCVMSxlXAcEzYfqyu1daHZooTC2Q==} + + '@safe-global/safe-apps-sdk@9.1.0': + resolution: {integrity: sha512-N5p/ulfnnA2Pi2M3YeWjULeWbjo7ei22JwU/IXnhoHzKq3pYCN6ynL9mJBOlvDVv892EgLPCWCOwQk/uBT2v0Q==} + + '@safe-global/safe-gateway-typescript-sdk@3.23.1': + resolution: {integrity: sha512-6ORQfwtEJYpalCeVO21L4XXGSdbEMfyp2hEv6cP82afKXSwvse6d3sdelgaPWUxHIsFRkWvHDdzh8IyyKHZKxw==} + engines: {node: '>=16'} + '@scarf/scarf@1.4.0': resolution: {integrity: sha512-xxeapPiUXdZAE3che6f3xogoJPeZgig6omHEy1rIY5WVsB3H2BHNnZH+gHG6x91SCWyQCzWGsuL2Hh3ClO5/qQ==} + '@scure/base@1.1.9': + resolution: {integrity: sha512-8YKhl8GHiNI/pU2VMaofa2Tor7PJRAjwQLBBuilkJ9L5+13yVbC7JO/wS7piioAvPSwR3JKM1IJ/u4xQzbcXKg==} + + '@scure/base@1.2.6': + resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} + + '@scure/bip32@1.4.0': + resolution: {integrity: sha512-sVUpc0Vq3tXCkDGYVWGIZTRfnvu8LoTDaev7vbwh0omSvVORONr960MQWdKqJDCReIEmTj3PAr73O3aoxz7OPg==} + + '@scure/bip32@1.6.2': + resolution: {integrity: sha512-t96EPDMbtGgtb7onKKqxRLfE5g05k7uHnHRM2xdE6BP/ZmxaLtPek4J4KfVn/90IQNrU1IOAqMgiDtUdtbe3nw==} + + '@scure/bip32@1.7.0': + resolution: {integrity: sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw==} + + '@scure/bip39@1.3.0': + resolution: {integrity: sha512-disdg7gHuTDZtY+ZdkmLpPCk7fxZSu3gBiEGuoC1XYxv9cGx3Z6cpTggCgW6odSOOIXCiDjuGejW+aJKCY/pIQ==} + + '@scure/bip39@1.5.4': + resolution: {integrity: sha512-TFM4ni0vKvCfBpohoh+/lY05i9gRbSwXWngAsF4CABQxoaOHijxuaZ2R6cStDQ5CHtHO9aGJTr4ksVJASRRyMA==} + + '@scure/bip39@1.6.0': + resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + '@sec-ant/readable-stream@0.4.1': resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} @@ -4354,6 +4732,244 @@ packages: resolution: {integrity: sha512-4aUIteuyxtBUhVdiQqcDhKFitwfd9hqoSDYY2KRXiWtgoWJ9Bmise+KfEPDiVHWeJepvF8xJO9/9+WDIciMFFw==} engines: {node: '>=18.0.0'} + '@socket.io/component-emitter@3.1.2': + resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + + '@solana-program/compute-budget@0.8.0': + resolution: {integrity: sha512-qPKxdxaEsFxebZ4K5RPuy7VQIm/tfJLa1+Nlt3KNA8EYQkz9Xm8htdoEaXVrer9kpgzzp9R3I3Bh6omwCM06tQ==} + peerDependencies: + '@solana/kit': ^2.1.0 + + '@solana-program/token-2022@0.4.2': + resolution: {integrity: sha512-zIpR5t4s9qEU3hZKupzIBxJ6nUV5/UVyIT400tu9vT1HMs5JHxaTTsb5GUhYjiiTvNwU0MQavbwc4Dl29L0Xvw==} + peerDependencies: + '@solana/kit': ^2.1.0 + '@solana/sysvars': ^2.1.0 + + '@solana-program/token@0.5.1': + resolution: {integrity: sha512-bJvynW5q9SFuVOZ5vqGVkmaPGA0MCC+m9jgJj1nk5m20I389/ms69ASnhWGoOPNcie7S9OwBX0gTj2fiyWpfag==} + peerDependencies: + '@solana/kit': ^2.1.0 + + '@solana/accounts@2.3.0': + resolution: {integrity: sha512-QgQTj404Z6PXNOyzaOpSzjgMOuGwG8vC66jSDB+3zHaRcEPRVRd2sVSrd1U6sHtnV3aiaS6YyDuPQMheg4K2jw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/addresses@2.3.0': + resolution: {integrity: sha512-ypTNkY2ZaRFpHLnHAgaW8a83N0/WoqdFvCqf4CQmnMdFsZSdC7qOwcbd7YzdaQn9dy+P2hybewzB+KP7LutxGA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/assertions@2.3.0': + resolution: {integrity: sha512-Ekoet3khNg3XFLN7MIz8W31wPQISpKUGDGTylLptI+JjCDWx3PIa88xjEMqFo02WJ8sBj2NLV64Xg1sBcsHjZQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-core@2.3.0': + resolution: {integrity: sha512-oG+VZzN6YhBHIoSKgS5ESM9VIGzhWjEHEGNPSibiDTxFhsFWxNaz8LbMDPjBUE69r9wmdGLkrQ+wVPbnJcZPvw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-data-structures@2.3.0': + resolution: {integrity: sha512-qvU5LE5DqEdYMYgELRHv+HMOx73sSoV1ZZkwIrclwUmwTbTaH8QAJURBj0RhQ/zCne7VuLLOZFFGv6jGigWhSw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-numbers@2.3.0': + resolution: {integrity: sha512-jFvvwKJKffvG7Iz9dmN51OGB7JBcy2CJ6Xf3NqD/VP90xak66m/Lg48T01u5IQ/hc15mChVHiBm+HHuOFDUrQg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/codecs-strings@2.3.0': + resolution: {integrity: sha512-y5pSBYwzVziXu521hh+VxqUtp0hYGTl1eWGoc1W+8mdvBdC1kTqm/X7aYQw33J42hw03JjryvYOvmGgk3Qz/Ug==} + engines: {node: '>=20.18.0'} + peerDependencies: + fastestsmallesttextencoderdecoder: ^1.0.22 + typescript: '>=5.3.3' + + '@solana/codecs@2.3.0': + resolution: {integrity: sha512-JVqGPkzoeyU262hJGdH64kNLH0M+Oew2CIPOa/9tR3++q2pEd4jU2Rxdfye9sd0Ce3XJrR5AIa8ZfbyQXzjh+g==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/errors@2.3.0': + resolution: {integrity: sha512-66RI9MAbwYV0UtP7kGcTBVLxJgUxoZGm8Fbc0ah+lGiAw17Gugco6+9GrJCV83VyF2mDWyYnYM9qdI3yjgpnaQ==} + engines: {node: '>=20.18.0'} + hasBin: true + peerDependencies: + typescript: '>=5.3.3' + + '@solana/fast-stable-stringify@2.3.0': + resolution: {integrity: sha512-KfJPrMEieUg6D3hfQACoPy0ukrAV8Kio883llt/8chPEG3FVTX9z/Zuf4O01a15xZmBbmQ7toil2Dp0sxMJSxw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/functional@2.3.0': + resolution: {integrity: sha512-AgsPh3W3tE+nK3eEw/W9qiSfTGwLYEvl0rWaxHht/lRcuDVwfKRzeSa5G79eioWFFqr+pTtoCr3D3OLkwKz02Q==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/instructions@2.3.0': + resolution: {integrity: sha512-PLMsmaIKu7hEAzyElrk2T7JJx4D+9eRwebhFZpy2PXziNSmFF929eRHKUsKqBFM3cYR1Yy3m6roBZfA+bGE/oQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/keys@2.3.0': + resolution: {integrity: sha512-ZVVdga79pNH+2pVcm6fr2sWz9HTwfopDVhYb0Lh3dh+WBmJjwkabXEIHey2rUES7NjFa/G7sV8lrUn/v8LDCCQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/kit@2.3.0': + resolution: {integrity: sha512-sb6PgwoW2LjE5oTFu4lhlS/cGt/NB3YrShEyx7JgWFWysfgLdJnhwWThgwy/4HjNsmtMrQGWVls0yVBHcMvlMQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/nominal-types@2.3.0': + resolution: {integrity: sha512-uKlMnlP4PWW5UTXlhKM8lcgIaNj8dvd8xO4Y9l+FVvh9RvW2TO0GwUO6JCo7JBzCB0PSqRJdWWaQ8pu1Ti/OkA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/options@2.3.0': + resolution: {integrity: sha512-PPnnZBRCWWoZQ11exPxf//DRzN2C6AoFsDI/u2AsQfYih434/7Kp4XLpfOMT/XESi+gdBMFNNfbES5zg3wAIkw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/programs@2.3.0': + resolution: {integrity: sha512-UXKujV71VCI5uPs+cFdwxybtHZAIZyQkqDiDnmK+DawtOO9mBn4Nimdb/6RjR2CXT78mzO9ZCZ3qfyX+ydcB7w==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/promises@2.3.0': + resolution: {integrity: sha512-GjVgutZKXVuojd9rWy1PuLnfcRfqsaCm7InCiZc8bqmJpoghlyluweNc7ml9Y5yQn1P2IOyzh9+p/77vIyNybQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-api@2.3.0': + resolution: {integrity: sha512-UUdiRfWoyYhJL9PPvFeJr4aJ554ob2jXcpn4vKmRVn9ire0sCbpQKYx6K8eEKHZWXKrDW8IDspgTl0gT/aJWVg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-parsed-types@2.3.0': + resolution: {integrity: sha512-B5pHzyEIbBJf9KHej+zdr5ZNAdSvu7WLU2lOUPh81KHdHQs6dEb310LGxcpCc7HVE8IEdO20AbckewDiAN6OCg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-spec-types@2.3.0': + resolution: {integrity: sha512-xQsb65lahjr8Wc9dMtP7xa0ZmDS8dOE2ncYjlvfyw/h4mpdXTUdrSMi6RtFwX33/rGuztQ7Hwaid5xLNSLvsFQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-spec@2.3.0': + resolution: {integrity: sha512-fA2LMX4BMixCrNB2n6T83AvjZ3oUQTu7qyPLyt8gHQaoEAXs8k6GZmu6iYcr+FboQCjUmRPgMaABbcr9j2J9Sw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-subscriptions-api@2.3.0': + resolution: {integrity: sha512-9mCjVbum2Hg9KGX3LKsrI5Xs0KX390lS+Z8qB80bxhar6MJPugqIPH8uRgLhCW9GN3JprAfjRNl7our8CPvsPQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-subscriptions-channel-websocket@2.3.0': + resolution: {integrity: sha512-2oL6ceFwejIgeWzbNiUHI2tZZnaOxNTSerszcin7wYQwijxtpVgUHiuItM/Y70DQmH9sKhmikQp+dqeGalaJxw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + ws: ^8.18.0 + + '@solana/rpc-subscriptions-spec@2.3.0': + resolution: {integrity: sha512-rdmVcl4PvNKQeA2l8DorIeALCgJEMSu7U8AXJS1PICeb2lQuMeaR+6cs/iowjvIB0lMVjYN2sFf6Q3dJPu6wWg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-subscriptions@2.3.0': + resolution: {integrity: sha512-Uyr10nZKGVzvCOqwCZgwYrzuoDyUdwtgQRefh13pXIrdo4wYjVmoLykH49Omt6abwStB0a4UL5gX9V4mFdDJZg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-transformers@2.3.0': + resolution: {integrity: sha512-UuHYK3XEpo9nMXdjyGKkPCOr7WsZsxs7zLYDO1A5ELH3P3JoehvrDegYRAGzBS2VKsfApZ86ZpJToP0K3PhmMA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-transport-http@2.3.0': + resolution: {integrity: sha512-HFKydmxGw8nAF5N+S0NLnPBDCe5oMDtI2RAmW8DMqP4U3Zxt2XWhvV1SNkAldT5tF0U1vP+is6fHxyhk4xqEvg==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc-types@2.3.0': + resolution: {integrity: sha512-O09YX2hED2QUyGxrMOxQ9GzH1LlEwwZWu69QbL4oYmIf6P5dzEEHcqRY6L1LsDVqc/dzAdEs/E1FaPrcIaIIPw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/rpc@2.3.0': + resolution: {integrity: sha512-ZWN76iNQAOCpYC7yKfb3UNLIMZf603JckLKOOLTHuy9MZnTN8XV6uwvDFhf42XvhglgUjGCEnbUqWtxQ9pa/pQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/signers@2.3.0': + resolution: {integrity: sha512-OSv6fGr/MFRx6J+ZChQMRqKNPGGmdjkqarKkRzkwmv7v8quWsIRnJT5EV8tBy3LI4DLO/A8vKiNSPzvm1TdaiQ==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/subscribable@2.3.0': + resolution: {integrity: sha512-DkgohEDbMkdTWiKAoatY02Njr56WXx9e/dKKfmne8/Ad6/2llUIrax78nCdlvZW9quXMaXPTxZvdQqo9N669Og==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/sysvars@2.3.0': + resolution: {integrity: sha512-LvjADZrpZ+CnhlHqfI5cmsRzX9Rpyb1Ox2dMHnbsRNzeKAMhu9w4ZBIaeTdO322zsTr509G1B+k2ABD3whvUBA==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/transaction-confirmation@2.3.0': + resolution: {integrity: sha512-UiEuiHCfAAZEKdfne/XljFNJbsKAe701UQHKXEInYzIgBjRbvaeYZlBmkkqtxwcasgBTOmEaEKT44J14N9VZDw==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/transaction-messages@2.3.0': + resolution: {integrity: sha512-bgqvWuy3MqKS5JdNLH649q+ngiyOu5rGS3DizSnWwYUd76RxZl1kN6CoqHSrrMzFMvis6sck/yPGG3wqrMlAww==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + + '@solana/transactions@2.3.0': + resolution: {integrity: sha512-LnTvdi8QnrQtuEZor5Msje61sDpPstTVwKg4y81tNxDhiyomjuvnSNLAq6QsB9gIxUqbNzPZgOG9IU4I4/Uaug==} + engines: {node: '>=20.18.0'} + peerDependencies: + typescript: '>=5.3.3' + '@standard-schema/spec@1.0.0': resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==} @@ -4459,6 +5075,14 @@ packages: peerDependencies: tailwindcss: '>=3.0.0 || insiders || >=4.0.0-alpha.20 || >=4.0.0-beta.1' + '@tanstack/query-core@5.90.3': + resolution: {integrity: sha512-HtPOnCwmx4dd35PfXU8jjkhwYrsHfuqgC8RCJIwWglmhIUIlzPP0ZcEkDAc+UtAWCiLm7T8rxeEfHZlz3hYMCA==} + + '@tanstack/react-query@5.90.3': + resolution: {integrity: sha512-i/LRL6DtuhG6bjGzavIMIVuKKPWx2AnEBIsBfuMm3YoHne0a20nWmsatOCBcVSaT0/8/5YFjNkebHAPLVUSi0Q==} + peerDependencies: + react: ^18 || ^19 + '@tanstack/react-virtual@3.13.12': resolution: {integrity: sha512-Gd13QdxPSukP8ZrkbgS2RwoZseTTbQPLnQEn7HY/rqtM+8Zt95f7xKC7N0EsKs7aoz0WzZ+fditZux+F8EzYxA==} peerDependencies: @@ -4704,6 +5328,9 @@ packages: '@types/linkify-it@5.0.0': resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==} + '@types/lodash@4.17.20': + resolution: {integrity: sha512-H3MHACvFUEiujabxhaI/ImO6gUrd8oOurg7LQtS7mbwIXA/cUqWrvBsaeJ23aZEPk1TAYkurjfMbSELfoCXlGA==} + '@types/markdown-it@14.1.2': resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==} @@ -4802,6 +5429,9 @@ packages: '@types/tough-cookie@4.0.5': resolution: {integrity: sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==} + '@types/trusted-types@2.0.7': + resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} + '@types/unist@2.0.11': resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==} @@ -4993,12 +5623,122 @@ packages: resolution: {integrity: sha512-JekxQ0RApo4gS4un/iMGsIL1/k4KUBe3HmnGcDvzHuFBdQdudEJgTqcsJC7y6Ul4Yw5CeykgvQbX2XeEJd0+DA==} engines: {node: '>= 20'} - '@webcontainer/env@1.1.1': - resolution: {integrity: sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng==} - - '@whatwg-node/disposablestack@0.0.6': - resolution: {integrity: sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==} - engines: {node: '>=18.0.0'} + '@wagmi/connectors@6.0.1': + resolution: {integrity: sha512-ZHvC9GIncOViz6Fi+oCc+8oin+U+GfCKNLj90aNxve8CLw++vQBEcivPIq1mQq2QNo6lay7yjNyGInPoOEIkSg==} + peerDependencies: + '@wagmi/core': 2.22.1 + typescript: '>=5.0.4' + viem: 2.x + peerDependenciesMeta: + typescript: + optional: true + + '@wagmi/core@2.22.1': + resolution: {integrity: sha512-cG/xwQWsBEcKgRTkQVhH29cbpbs/TdcUJVFXCyri3ZknxhMyGv0YEjTcrNpRgt2SaswL1KrvslSNYKKo+5YEAg==} + peerDependencies: + '@tanstack/query-core': '>=5.0.0' + typescript: '>=5.0.4' + viem: 2.x + peerDependenciesMeta: + '@tanstack/query-core': + optional: true + typescript: + optional: true + + '@walletconnect/core@2.21.0': + resolution: {integrity: sha512-o6R7Ua4myxR8aRUAJ1z3gT9nM+jd2B2mfamu6arzy1Cc6vi10fIwFWb6vg3bC8xJ6o9H3n/cN5TOW3aA9Y1XVw==} + engines: {node: '>=18'} + + '@walletconnect/core@2.21.1': + resolution: {integrity: sha512-Tp4MHJYcdWD846PH//2r+Mu4wz1/ZU/fr9av1UWFiaYQ2t2TPLDiZxjLw54AAEpMqlEHemwCgiRiAmjR1NDdTQ==} + engines: {node: '>=18'} + + '@walletconnect/environment@1.0.1': + resolution: {integrity: sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg==} + + '@walletconnect/ethereum-provider@2.21.1': + resolution: {integrity: sha512-SSlIG6QEVxClgl1s0LMk4xr2wg4eT3Zn/Hb81IocyqNSGfXpjtawWxKxiC5/9Z95f1INyBD6MctJbL/R1oBwIw==} + + '@walletconnect/events@1.0.1': + resolution: {integrity: sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ==} + + '@walletconnect/heartbeat@1.2.2': + resolution: {integrity: sha512-uASiRmC5MwhuRuf05vq4AT48Pq8RMi876zV8rr8cV969uTOzWdB/k+Lj5yI2PBtB1bGQisGen7MM1GcZlQTBXw==} + + '@walletconnect/jsonrpc-http-connection@1.0.8': + resolution: {integrity: sha512-+B7cRuaxijLeFDJUq5hAzNyef3e3tBDIxyaCNmFtjwnod5AGis3RToNqzFU33vpVcxFhofkpE7Cx+5MYejbMGw==} + + '@walletconnect/jsonrpc-provider@1.0.14': + resolution: {integrity: sha512-rtsNY1XqHvWj0EtITNeuf8PHMvlCLiS3EjQL+WOkxEOA4KPxsohFnBDeyPYiNm4ZvkQdLnece36opYidmtbmow==} + + '@walletconnect/jsonrpc-types@1.0.4': + resolution: {integrity: sha512-P6679fG/M+wuWg9TY8mh6xFSdYnFyFjwFelxyISxMDrlbXokorEVXYOxiqEbrU3x1BmBoCAJJ+vtEaEoMlpCBQ==} + + '@walletconnect/jsonrpc-utils@1.0.8': + resolution: {integrity: sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw==} + + '@walletconnect/jsonrpc-ws-connection@1.0.16': + resolution: {integrity: sha512-G81JmsMqh5nJheE1mPst1W0WfVv0SG3N7JggwLLGnI7iuDZJq8cRJvQwLGKHn5H1WTW7DEPCo00zz5w62AbL3Q==} + + '@walletconnect/keyvaluestorage@1.1.1': + resolution: {integrity: sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA==} + peerDependencies: + '@react-native-async-storage/async-storage': 1.x + peerDependenciesMeta: + '@react-native-async-storage/async-storage': + optional: true + + '@walletconnect/logger@2.1.2': + resolution: {integrity: sha512-aAb28I3S6pYXZHQm5ESB+V6rDqIYfsnHaQyzFbwUUBFY4H0OXx/YtTl8lvhUNhMMfb9UxbwEBS253TlXUYJWSw==} + + '@walletconnect/relay-api@1.0.11': + resolution: {integrity: sha512-tLPErkze/HmC9aCmdZOhtVmYZq1wKfWTJtygQHoWtgg722Jd4homo54Cs4ak2RUFUZIGO2RsOpIcWipaua5D5Q==} + + '@walletconnect/relay-auth@1.1.0': + resolution: {integrity: sha512-qFw+a9uRz26jRCDgL7Q5TA9qYIgcNY8jpJzI1zAWNZ8i7mQjaijRnWFKsCHAU9CyGjvt6RKrRXyFtFOpWTVmCQ==} + + '@walletconnect/safe-json@1.0.2': + resolution: {integrity: sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA==} + + '@walletconnect/sign-client@2.21.0': + resolution: {integrity: sha512-z7h+PeLa5Au2R591d/8ZlziE0stJvdzP9jNFzFolf2RG/OiXulgFKum8PrIyXy+Rg2q95U9nRVUF9fWcn78yBA==} + + '@walletconnect/sign-client@2.21.1': + resolution: {integrity: sha512-QaXzmPsMnKGV6tc4UcdnQVNOz4zyXgarvdIQibJ4L3EmLat73r5ZVl4c0cCOcoaV7rgM9Wbphgu5E/7jNcd3Zg==} + + '@walletconnect/time@1.0.2': + resolution: {integrity: sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g==} + + '@walletconnect/types@2.21.0': + resolution: {integrity: sha512-ll+9upzqt95ZBWcfkOszXZkfnpbJJ2CmxMfGgE5GmhdxxxCcO5bGhXkI+x8OpiS555RJ/v/sXJYMSOLkmu4fFw==} + + '@walletconnect/types@2.21.1': + resolution: {integrity: sha512-UeefNadqP6IyfwWC1Yi7ux+ljbP2R66PLfDrDm8izmvlPmYlqRerJWJvYO4t0Vvr9wrG4Ko7E0c4M7FaPKT/sQ==} + + '@walletconnect/universal-provider@2.21.0': + resolution: {integrity: sha512-mtUQvewt+X0VBQay/xOJBvxsB3Xsm1lTwFjZ6WUwSOTR1X+FNb71hSApnV5kbsdDIpYPXeQUbGt2se1n5E5UBg==} + + '@walletconnect/universal-provider@2.21.1': + resolution: {integrity: sha512-Wjx9G8gUHVMnYfxtasC9poGm8QMiPCpXpbbLFT+iPoQskDDly8BwueWnqKs4Mx2SdIAWAwuXeZ5ojk5qQOxJJg==} + + '@walletconnect/utils@2.21.0': + resolution: {integrity: sha512-zfHLiUoBrQ8rP57HTPXW7rQMnYxYI4gT9yTACxVW6LhIFROTF6/ytm5SKNoIvi4a5nX5dfXG4D9XwQUCu8Ilig==} + + '@walletconnect/utils@2.21.1': + resolution: {integrity: sha512-VPZvTcrNQCkbGOjFRbC24mm/pzbRMUq2DSQoiHlhh0X1U7ZhuIrzVtAoKsrzu6rqjz0EEtGxCr3K1TGRqDG4NA==} + + '@walletconnect/window-getters@1.0.1': + resolution: {integrity: sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q==} + + '@walletconnect/window-metadata@1.0.1': + resolution: {integrity: sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA==} + + '@webcontainer/env@1.1.1': + resolution: {integrity: sha512-6aN99yL695Hi9SuIk1oC88l9o0gmxL1nGWWQ/kNy81HigJ0FoaoTXpytCj6ItzgyCEwA9kF1wixsTuv5cjsgng==} + + '@whatwg-node/disposablestack@0.0.6': + resolution: {integrity: sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==} + engines: {node: '>=18.0.0'} '@whatwg-node/events@0.1.2': resolution: {integrity: sha512-ApcWxkrs1WmEMS2CaLLFUEem/49erT3sxIVjpzU5f6zmVcnijtDSrhoK2zVobOIikZJdH63jdAXOrvjf6eOUNQ==} @@ -5020,6 +5760,39 @@ packages: resolution: {integrity: sha512-Otmxo+0mp8az3B48pLI1I4msNOXPIoP7TLm6h5wOEQmynqHt8oP9nR6NJUeJk6iI5OtFpQtkbJFwfGkmplvc3Q==} engines: {node: '>=18.0.0'} + abitype@1.0.8: + resolution: {integrity: sha512-ZeiI6h3GnW06uYDLx0etQtX/p8E24UaHHBj57RSjK7YBFe7iuVn07EDpOeP451D06sF27VOz9JJPlIKJmXgkEg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3 >=3.22.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.1.0: + resolution: {integrity: sha512-6Vh4HcRxNMLA0puzPjM5GBgT4aAcFGKZzSgAXvuZ27shJP6NEpielTuqbBmZILR5/xd0PizkBGy5hReKz9jl5A==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3.22.0 || ^4.0.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + + abitype@1.1.1: + resolution: {integrity: sha512-Loe5/6tAgsBukY95eGaPSDmQHIjRZYQq8PB1MpsNccDIK8WiV+Uw6WzaIXipvaxTEL2yEB0OpEaQv3gs8pkS9Q==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3.22.0 || ^4.0.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + abort-controller-x@0.4.3: resolution: {integrity: sha512-VtUwTNU8fpMwvWGn4xE93ywbogTYsuT+AUxAXOeelbXuQVIwNmC5YLeho9sH4vZ4ITW8414TTAOG1nW6uIVHCA==} @@ -5062,6 +5835,11 @@ packages: resolution: {integrity: sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==} engines: {node: '>= 8.0.0'} + agents@0.1.6: + resolution: {integrity: sha512-sJC8WI4/8W1ac+mQAE3vrsEDwXp5X7J4GFYcZiZIFWfTH4ssoJuBrlx8ikhBSPBFswb5qPPicxzWa0w5LrlT6A==} + peerDependencies: + react: '*' + ai@4.3.19: resolution: {integrity: sha512-dIE2bfNpqHN3r6IINp9znguYdhIOheKW2LDigAMrgt/upT3B8eBGPSCblENvaZGoq+hxaN9fSMzjWpbqloP+7Q==} engines: {node: '>=18'} @@ -5072,6 +5850,12 @@ packages: react: optional: true + ai@5.0.48: + resolution: {integrity: sha512-+oYhbN3NGRXayGfTFI8k1Fu4rhiJcQ0mbgiAOJGFkzvCxunRRQu5cyDl7y6cHNTj1QvHmIBROK5u655Ss2oI0g==} + engines: {node: '>=18'} + peerDependencies: + zod: ^3.25.76 || ^4 + ai@5.0.60: resolution: {integrity: sha512-80U/3kmdBW6g+JkLXpz/P2EwkyEaWlPlYtuLUpx/JYK9F7WZh9NnkYoh1KvUi1Sbpo0NyurBTvX0a2AG9mmbDA==} engines: {node: '>=18'} @@ -5176,6 +5960,9 @@ packages: resolution: {integrity: sha512-hsU18Ae8CDTR6Kgu9DYf0EbCr/a5iGL0rytQDobUcdpYOKokk8LEjVphnXkDkgpi0wYVsqrXuP0bZxJaTqdgoA==} engines: {node: '>= 0.4'} + async-mutex@0.2.6: + resolution: {integrity: sha512-Hs4R+4SPgamu6rSGW8C7cV9gaWUKEHykfzCCvIRuaVv636Ju10ZdeUbvb4TBEW0INuq2DHZqXbK4Nd3yG4RaRw==} + async-mutex@0.5.0: resolution: {integrity: sha512-1A94B18jkJ3DYq284ohPxoXbfTA5HsQ7/Mf4DEhcyLx3Bz27Rh59iScbB6EPiP+B+joue6YCxcMXSbFC1tZKwA==} @@ -5232,6 +6019,9 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + base-x@5.0.1: + resolution: {integrity: sha512-M7uio8Zt++eg3jPj+rHMfCC+IuygQHHCOU+IYsVtik6FWjuYpVt/+MRKcgsAMHh8mMFAwnB+Bs+mTrFiXjMzKg==} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -5239,6 +6029,9 @@ packages: resolution: {integrity: sha512-OMu3BGQ4E7P1ErFsIPpbJh0qvDudM/UuJeHgkAvfWe+0HFJCXh+t/l8L6fVLR55RI/UbKrVLnAXZSVwd9ysWYw==} hasBin: true + big.js@6.2.2: + resolution: {integrity: sha512-y/ie+Faknx7sZA5MfGA2xKlu0GDv8RWrXGsmlteyJQ2lvoKv9GBK/fpRMc2qlSoBAgNxrixICFCBefIq8WCQpQ==} + bignumber.js@9.3.1: resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} @@ -5249,6 +6042,9 @@ packages: bl@5.1.0: resolution: {integrity: sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==} + bn.js@5.2.2: + resolution: {integrity: sha512-v2YAxEmKaBLahNwE1mjp4WON6huMNeuDvagFZW+ASCuA/ku0bXR9hSMw0XpiqMoA3+rmnyck/tPRSFQkoC9Cuw==} + body-parser@1.20.3: resolution: {integrity: sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} @@ -5279,6 +6075,9 @@ packages: resolution: {integrity: sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==} engines: {node: '>= 6'} + bs58@6.0.0: + resolution: {integrity: sha512-PD0wEnEYg6ijszw/u8s+iI3H17cTymlrwkKhDhPZq+Sokl3AU4htyBFTjAeNAlCCmg0f53g6ih3jATyCKftTfw==} + bser@2.1.1: resolution: {integrity: sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==} @@ -5291,6 +6090,10 @@ packages: buffer@6.0.3: resolution: {integrity: sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==} + bufferutil@4.0.9: + resolution: {integrity: sha512-WDtdLmJvAuNNPzByAYpRo2rF1Mmradw6gvWsQKf63476DDXmomT9zUiGypLcG4ibIM67vhAj8jJRdbmEws2Aqw==} + engines: {node: '>=6.14.2'} + builtins@5.1.0: resolution: {integrity: sha512-SW9lzGTLvWTP1AY8xeAMZimqDrIaSdLQUcVr9DMef51niJ022Ri87SwRRKYm4A6iHfkPaiVUu/Duw2Wc4J7kKg==} @@ -5432,6 +6235,9 @@ packages: client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -5444,6 +6250,10 @@ packages: resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} engines: {node: '>=0.8'} + clsx@1.2.1: + resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} + engines: {node: '>=6'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -5497,6 +6307,10 @@ packages: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} + commander@14.0.1: + resolution: {integrity: sha512-2JkV3gUZUVrbNA+1sjBOYLsMZ5cEEl8GTFP2a4AVz5hvasAMCQ1D2l2le/cX+pV4N6ZU17zjUahLpIXRrnWL8A==} + engines: {node: '>=20'} + commander@4.1.1: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} @@ -5548,6 +6362,9 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-es@1.2.2: + resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} + cookie-signature@1.0.6: resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} @@ -5563,10 +6380,21 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} + core-js-pure@3.46.0: + resolution: {integrity: sha512-NMCW30bHNofuhwLhYPt66OLOKTMbOhgTTatKVbaQC3KRHpTCiRIBYvtshr+NBYSnBxwAFhjW/RfJ0XbIjS16rw==} + + core-util-is@1.0.3: + resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} + cors@2.8.5: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} engines: {node: '>= 0.10'} + crc-32@1.2.2: + resolution: {integrity: sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==} + engines: {node: '>=0.8'} + hasBin: true + create-jest@29.7.0: resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -5575,9 +6403,16 @@ packages: crelt@1.0.6: resolution: {integrity: sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==} + cron-schedule@5.0.4: + resolution: {integrity: sha512-nH0a49E/kSVk6BeFgKZy4uUsy6D2A16p120h5bYD9ILBhQu7o2sJFH+WI4R731TSBQ0dB1Ik7inB/dRAB4C8QQ==} + engines: {node: '>=18'} + cross-fetch@3.2.0: resolution: {integrity: sha512-Q+xVJLoGOeIMXZmbUK4HYk+69cQH6LudR0Vu/pRm2YlU/hDV9CiS0gKUMaWY5f2NeUH9C1nV3bsTlCo0FsTV1Q==} + cross-fetch@4.1.0: + resolution: {integrity: sha512-uKm5PU+MHTootlWEY+mZ4vvXoCn4fLQxT9dSc1sXVMSFkINTJVN8cAQROpwcKm8bJ/c7rgZVIBWzH5T78sNZZw==} + cross-inspect@1.0.1: resolution: {integrity: sha512-Pcw1JTvZLSJH83iiGWt6fRcT+BjZlCDRVwYLbUcHzv/CRpB7r0MlSrGbIyQvVSNyGnbt7G4AXuyCiDR3POvZ1A==} engines: {node: '>=16.0.0'} @@ -5586,6 +6421,9 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -5613,6 +6451,10 @@ packages: resolution: {integrity: sha512-BS8PfmtDGnrgYdOonGZQdLZslWIeCGFP9tpan0hi1Co2Zr2NKADsvGYA8XxuG/4UWgJ6Cjtv+YJnB6MM69QGlQ==} engines: {node: '>= 0.4'} + date-fns@2.30.0: + resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==} + engines: {node: '>=0.11'} + date-fns@3.6.0: resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} @@ -5622,6 +6464,9 @@ packages: dateformat@4.6.3: resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + dayjs@1.11.13: + resolution: {integrity: sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg==} + debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -5647,6 +6492,15 @@ packages: supports-color: optional: true + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -5663,6 +6517,10 @@ packages: decode-named-character-reference@1.2.0: resolution: {integrity: sha512-c6fcElNV6ShtZXmsgNgFFV5tVX2PaV4g+MOAkb8eXHvn6sryJBrZa9r0zV6+dtTyoCKxtDy5tyQ5ZwQuidtd+Q==} + decode-uri-component@0.2.2: + resolution: {integrity: sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==} + engines: {node: '>=0.10'} + dedent@1.7.0: resolution: {integrity: sha512-HGFtf8yhuhGhqO07SV79tRp+br4MnbdjeVxotpn1QBl30pcLLCQjX5b2295ll0fv8RKDKsmWYrl05usHM9CewQ==} peerDependencies: @@ -5716,10 +6574,21 @@ packages: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} + derive-valtio@0.1.0: + resolution: {integrity: sha512-OCg2UsLbXK7GmmpzMXhYkdO64vhJ1ROUUGaTFyHjVwEdMEcTTRj7W1TxLbSBxdY8QLBPCcp66MTyaSy0RpO17A==} + peerDependencies: + valtio: '*' + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + destroy@1.2.0: resolution: {integrity: sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==} engines: {node: '>= 0.8', npm: 1.2.8000 || >= 1.4.16} + detect-browser@5.3.0: + resolution: {integrity: sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w==} + detect-libc@1.0.3: resolution: {integrity: sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==} engines: {node: '>=0.10'} @@ -5758,6 +6627,9 @@ packages: resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} engines: {node: '>=0.3.1'} + dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + doctrine@2.1.0: resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} engines: {node: '>=0.10.0'} @@ -5780,12 +6652,19 @@ packages: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} + duplexify@4.1.3: + resolution: {integrity: sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} ecdsa-sig-formatter@1.0.11: resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + eciesjs@0.4.16: + resolution: {integrity: sha512-dS5cbA9rA2VR4Ybuvhg6jvdmp46ubLn3E+px8cG/35aEDNclrqoCjg6mt0HYZ/M+OoESS3jSkCrqk1kWAEhWAw==} + engines: {bun: '>=1', deno: '>=2', node: '>=16'} + ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -5822,6 +6701,9 @@ packages: resolution: {integrity: sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==} engines: {node: '>=14'} + encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} @@ -5833,6 +6715,13 @@ packages: end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + engine.io-client@6.6.3: + resolution: {integrity: sha512-T0iLjnyNWahNyv/lcjS2y4oE358tVS/SYQNxYXGAJ9/GLgH4VCvOQ/mhTjqU88mLZCQgiG8RIegFHYCdVC+j5w==} + + engine.io-parser@5.2.3: + resolution: {integrity: sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==} + engines: {node: '>=10.0.0'} + enhanced-resolve@5.18.3: resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} @@ -5883,6 +6772,9 @@ packages: resolution: {integrity: sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==} engines: {node: '>= 0.4'} + es-toolkit@1.33.0: + resolution: {integrity: sha512-X13Q/ZSc+vsO1q600bvNK4bxgXMkHcf//RxCmYDaRY5DAcT+eoXjY5hoAPGMdRnWQjvyLEcyauG3b6hz76LNqg==} + esast-util-from-estree@2.0.0: resolution: {integrity: sha512-4CyanoAudUSBAn5K13H4JhsMH6L9ZP7XbLVe/dKybkxMO7eDyLsT8UHl9TRNrU2Gr9nz+FovfSIjuXWJ81uVwQ==} @@ -6062,17 +6954,47 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} + eth-block-tracker@7.1.0: + resolution: {integrity: sha512-8YdplnuE1IK4xfqpf4iU7oBxnOYAc35934o083G8ao+8WM8QQtt/mVlAY6yIAdY1eMeLqg4Z//PZjJGmWGPMRg==} + engines: {node: '>=14.0.0'} + + eth-json-rpc-filters@6.0.1: + resolution: {integrity: sha512-ITJTvqoCw6OVMLs7pI8f4gG92n/St6x80ACtHodeS+IXmO0w+t1T5OOzfSt7KLSMLRkVUoexV7tztLgDxg+iig==} + engines: {node: '>=14.0.0'} + + eth-query@2.1.2: + resolution: {integrity: sha512-srES0ZcvwkR/wd5OQBRA1bIJMww1skfGS0s8wlwK3/oNP4+wnds60krvu5R1QbpRQjMmpG5OMIWro5s7gvDPsA==} + + eth-rpc-errors@4.0.3: + resolution: {integrity: sha512-Z3ymjopaoft7JDoxZcEb3pwdGh7yiYMhOwm2doUt6ASXlMavpNlK6Cre0+IMl2VSGyEU9rkiperQhp5iRxn5Pg==} + + ethereum-cryptography@2.2.1: + resolution: {integrity: sha512-r/W8lkHSiTLxUxW8Rf3u4HGB0xQweG2RyETjywylKZSzLWoWAijRz8WCuOtJ6wah+avllXBqZuk29HCCvhEIRg==} + + event-target-polyfill@0.0.4: + resolution: {integrity: sha512-Gs6RLjzlLRdT8X9ZipJdIZI/Y6/HhRLyq9RdDlCsnpxr/+Nn6bU2EFGuC94GjxqhM+Nmij2Vcq98yoHrU8uNFQ==} + event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} + eventemitter2@6.4.9: + resolution: {integrity: sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==} + eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} + eventsource-parser@2.0.1: + resolution: {integrity: sha512-gMaRLm5zejEH9mNXC54AnIteFI9YwL/q5JKMdBnoG+lEI1JWVGFVk0Taaj9Xb5SKgzIBDZoQX5IzMe44ILWODg==} + engines: {node: '>=18.0.0'} + eventsource-parser@3.0.6: resolution: {integrity: sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==} engines: {node: '>=18.0.0'} @@ -6128,6 +7050,10 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + extension-port-stream@3.0.0: + resolution: {integrity: sha512-an2S5quJMiy5bnZKEf6AkfH/7r8CzHvhchU40gxN+OM6HPhe7Z9T1FUychcf2M9PpPOO0Hf7BAEfJkw2TDIBDw==} + engines: {node: '>=12.0.0'} + fast-copy@3.0.2: resolution: {integrity: sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==} @@ -6151,6 +7077,10 @@ packages: fast-levenshtein@2.0.6: resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} + fast-redact@3.5.0: + resolution: {integrity: sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==} + engines: {node: '>=6'} + fast-safe-stringify@2.1.1: resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} @@ -6161,6 +7091,9 @@ packages: resolution: {integrity: sha512-pfX9uG9Ki0yekDHx2SiuRIyFdyAr1kMIMitPvb0YBo8SUfKvia7w7FIyd/l6av85pFYRhZscS75MwMnbvY+hcQ==} hasBin: true + fastestsmallesttextencoderdecoder@1.0.22: + resolution: {integrity: sha512-Pb8d48e+oIuY4MaM64Cd7OW1gt4nxCHs7/ddPPZ/Ic3sg8yVGM7O9wDvZ7us6ScaUupzM+pfBolwtYhN1IxBIw==} + fastq@1.19.1: resolution: {integrity: sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==} @@ -6199,6 +7132,10 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + filter-obj@1.1.0: + resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} + engines: {node: '>=0.10.0'} + finalhandler@1.3.1: resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} engines: {node: '>= 0.8'} @@ -6458,6 +7395,9 @@ packages: resolution: {integrity: sha512-4ccGpzz7YAr7lxrT2neugmXQ3hP9ho2gcaityLVkiUecAiwiy60Ii8gRbZeOsXV19fYaRjgBSshs8kXw+NKCPQ==} engines: {node: '>=12.0.0'} + h3@1.15.4: + resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} + handlebars@4.7.8: resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} engines: {node: '>=0.4.7'} @@ -6633,6 +7573,12 @@ packages: resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} engines: {node: '>=0.10.0'} + idb-keyval@6.2.1: + resolution: {integrity: sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg==} + + idb-keyval@6.2.2: + resolution: {integrity: sha512-yjD9nARJ/jb1g+CvD0tlhUHOrJ9Sy0P8T9MF3YaLlHnSRpwPfpTX0XIvpmw3gAJUmEu3FiICLBDPXVwyEvrleg==} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -6694,6 +7640,9 @@ packages: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + is-alphabetical@1.0.4: resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} @@ -6706,6 +7655,10 @@ packages: is-alphanumerical@2.0.1: resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==} + is-arguments@1.2.0: + resolution: {integrity: sha512-7bVbi0huj/wrIAOzb8U1aszg9kdi3KN/CyU19CTI7tAoZYEZoL9yCDXpbXN+uPsuWnP02cyug1gleqq+TU+YCA==} + engines: {node: '>= 0.4'} + is-array-buffer@3.0.5: resolution: {integrity: sha512-DDfANUiiG2wC1qawP66qlTugJeL5HyzMpfr8lLK+jMQirGzNod0B12cFB/9q838Ru27sBwfw78/rdoU7RERz6A==} engines: {node: '>= 0.4'} @@ -6897,12 +7850,25 @@ packages: resolution: {integrity: sha512-rZkHeBn9Zzq52sd9IUIV3a5mfwBY+o2HePMh0wkGBM4z4qjvy2GwVxQ6nNXSfw6MmVP6gf1QIlWjiOavhM3x5g==} engines: {node: '>=v0.10.0'} + isarray@1.0.0: + resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} + isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isows@1.0.6: + resolution: {integrity: sha512-lPHCayd40oW98/I0uvgaHKWCSvkzY27LjWLbtzOm64yQ+G3Q5npjjbdppU65iZXkK1Zt+kH9pfegli0AYfwYYw==} + peerDependencies: + ws: '*' + + isows@1.0.7: + resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==} + peerDependencies: + ws: '*' + isstream@0.1.2: resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} @@ -7108,6 +8074,13 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-rpc-engine@6.1.0: + resolution: {integrity: sha512-NEdLrtrq1jUZyfjkr9OCz9EzCNhnRyWtt1PAnvnhwy6e8XETS0Dtc+ZNCO2gvuAoKsIn2+vCSowXTYE4CkgnAQ==} + engines: {node: '>=10.0.0'} + + json-rpc-random-id@1.0.1: + resolution: {integrity: sha512-RJ9YYNCkhVDBuP4zN5BBtYAzEl03yq/jIIsyif0JY9qyJuQQZNeDK7anAPKKlyEtLSj2s8h6hNh2F8zO5q7ScA==} + json-schema-to-zod@2.6.1: resolution: {integrity: sha512-uiHmWH21h9FjKJkRBntfVGTLpYlCZ1n98D0izIlByqQLqpmkQpNTBtfbdP04Na6+43lgsvrShFh2uWLkQDKJuQ==} hasBin: true @@ -7173,9 +8146,16 @@ packages: resolution: {integrity: sha512-woHRUZ/iF23GBP1dkDQMh1QBad9dmr8/PAwNA54VrSOVYgI12MAcE14TqnDdQOdzyEonGzMepYnqBMYdsoAr8Q==} hasBin: true + keccak@3.0.4: + resolution: {integrity: sha512-3vKuW0jV8J3XNTzvfyicFR5qvxrSAGl7KIhvgOu5cmWwM7tZRj3fMbj/pfIf4be7aznbc+prBWGjywox/g2Y6Q==} + engines: {node: '>=10.0.0'} + keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} + keyvaluestorage-interface@1.0.0: + resolution: {integrity: sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g==} + kleur@3.0.3: resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} engines: {node: '>=6'} @@ -7356,6 +8336,15 @@ packages: linkify-it@5.0.0: resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==} + lit-element@4.2.1: + resolution: {integrity: sha512-WGAWRGzirAgyphK2urmYOV72tlvnxw7YfyLDgQ+OZnM9vQQBQnumQ7jUJe6unEzwGU3ahFOjuz1iz1jjrpCPuw==} + + lit-html@3.3.1: + resolution: {integrity: sha512-S9hbyDu/vs1qNrithiNyeyv64c9yqiW9l+DBgI18fL+MTvOtWoFR0FWiyq1TxaYef5wNlpEmzlXoBlZEO+WjoA==} + + lit@3.3.0: + resolution: {integrity: sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==} + load-tsconfig@0.2.5: resolution: {integrity: sha512-IXO6OCs9yg8tMKzfPZ1YmheJbZCiEsnBdcB03l0OcfK9prKnJb96siuHCr5Fl37/yo9DnKU+TLpxzTUspw9shg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -7409,6 +8398,9 @@ packages: lodash.sortby@4.7.0: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} + lodash@4.17.21: + resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} + log-symbols@5.1.0: resolution: {integrity: sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==} engines: {node: '>=12'} @@ -7576,6 +8568,9 @@ packages: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'} + micro-ftch@0.3.1: + resolution: {integrity: sha512-/0LLxhzP0tfiR5hcQebtudP56gUurs2CLkGarnCiB/OqEyUFQ6U3paQi/tgLv0hBJYt2rnr9MNpxz4fiiugstg==} + micromark-core-commonmark@1.1.0: resolution: {integrity: sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==} @@ -7772,6 +8767,9 @@ packages: engines: {node: '>=4'} hasBin: true + mimetext@3.0.27: + resolution: {integrity: sha512-mUhWAsZD1N/K6dbN4+a5Yq78OPnYQw1ubOSMasBntsLQ2S7KVNlvDEA8dwpr4a7PszWMzeslKahAprtwYMgaBA==} + mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} @@ -7798,6 +8796,14 @@ packages: resolution: {integrity: sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==} engines: {node: '>= 18'} + mipd@0.0.7: + resolution: {integrity: sha512-aAPZPNDQ3uMTdKbuO2YmAw2TxLHO0moa4YKAyETM/DTj5FloZo+a+8tU+iv4GmW+sOxKLSRwcSFuczk+Cpt6fg==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + mlly@1.8.0: resolution: {integrity: sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==} @@ -7823,6 +8829,9 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + multiformats@9.9.0: + resolution: {integrity: sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg==} + mustache@4.2.0: resolution: {integrity: sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ==} hasBin: true @@ -7839,6 +8848,11 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanoid@5.1.6: + resolution: {integrity: sha512-c7+7RQ+dMB5dPwwCp4ee1/iV/q2P6aK1mTZcfr1BTuVlyW9hJYiMPybJCcnBlQtuSmTIWNeazm/zqNoZSSElBg==} + engines: {node: ^18 || >=20} + hasBin: true + napi-postinstall@0.3.4: resolution: {integrity: sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} @@ -7894,6 +8908,9 @@ packages: nice-grpc@2.1.13: resolution: {integrity: sha512-IkXNok2NFyYh0WKp1aJFwFV3Ue2frBkJ16ojrmgX3Tc9n0g7r0VU+ur3H/leDHPPGsEeVozdMynGxYT30k3D/Q==} + node-addon-api@2.0.2: + resolution: {integrity: sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA==} + node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -7919,9 +8936,16 @@ packages: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} + node-gyp-build@4.8.4: + resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} + hasBin: true + node-int64@0.4.0: resolution: {integrity: sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==} + node-mock-http@1.0.3: + resolution: {integrity: sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog==} + node-releases@2.0.23: resolution: {integrity: sha512-cCmFDMSm26S6tQSDpBCg/NR8NENrVPhAJSf+XbxBG4rPFaaonlEoE9wHQmun+cls499TQGSb7ZyPBRlzgKfpeg==} @@ -7946,6 +8970,9 @@ packages: engines: {node: ^14.16.0 || >=16.10.0} hasBin: true + obj-multiplex@1.0.0: + resolution: {integrity: sha512-0GNJAOsHoBHeNTvl5Vt6IWnpUEcc3uSRxzBri7EDyIcMgYvnY2JL2qdeV5zTMjWQX5OHcD5amcW2HFfDh0gjIA==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -7981,6 +9008,12 @@ packages: obliterator@1.6.1: resolution: {integrity: sha512-9WXswnqINnnhOG/5SLimUlzuU1hFJUc8zkwyD59Sd+dPOMf05PmnYG/d6Q7HZ+KmgkZJa1PxRso6QdM3sTNHig==} + ofetch@1.4.1: + resolution: {integrity: sha512-QZj2DfGplQAr2oj9KzceK9Hwz6Whxazmn85yYeVuS3u9XTMOGMRx0kO95MQ+vLsj/S/NwBDMMLU5hpxvI6Tklw==} + + on-exit-leak-free@0.2.0: + resolution: {integrity: sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==} + on-exit-leak-free@2.1.2: resolution: {integrity: sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==} engines: {node: '>=14.0.0'} @@ -8028,9 +9061,15 @@ packages: zod: optional: true + openapi-fetch@0.13.8: + resolution: {integrity: sha512-yJ4QKRyNxE44baQ9mY5+r/kAzZ8yXMemtNAOFwOzRXJscdjSxxzWSNlyBAr+o5JjkUw9Lc3W7OIoca0cY3PYnQ==} + openapi-types@12.1.3: resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + openapi-typescript-helpers@0.0.15: + resolution: {integrity: sha512-opyTPaunsklCBpTK8JGef6mfPhLSnyy5a0IN9vKtx3+4aExf+KxEqYwIy3hqkedXIB97u357uLMJsOnm3GVjsw==} + optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} engines: {node: '>= 0.8.0'} @@ -8046,6 +9085,38 @@ packages: resolution: {integrity: sha512-qFOyK5PjiWZd+QQIh+1jhdb9LpxTF0qs7Pm8o5QHYZ0M3vKqSqzsZaEB6oWlxZ+q2sJBMI/Ktgd2N5ZwQoRHfg==} engines: {node: '>= 0.4'} + ox@0.6.7: + resolution: {integrity: sha512-17Gk/eFsFRAZ80p5eKqv89a57uXjd3NgIf1CaXojATPBuujVc/fQSVhBeAU9JCRB+k7J50WQAyWTxK19T9GgbA==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.6.9: + resolution: {integrity: sha512-wi5ShvzE4eOcTwQVsIPdFr+8ycyX+5le/96iAJutaZAvCes1J0+RvpEPg5QDPDiaR0XQQAvZVl7AwqQcINuUug==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.9.11: + resolution: {integrity: sha512-dbb1XVmxBwbBfjgicD8jHZTNn2esOyAoJWFsaE1dxAQD6qvG8WfdYkRJrAgFZV38WtOMaoPxvq5VXiTdcp58rw==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + + ox@0.9.6: + resolution: {integrity: sha512-8SuCbHPvv2eZLYXrNmC0EC12rdzXQLdhnOMlHDW2wiCPLxBrOOJwX5L5E61by+UjTPOryqQiRSnjIKCI+GykKg==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true + p-finally@1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} @@ -8117,6 +9188,14 @@ packages: partial-json@0.1.7: resolution: {integrity: sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==} + partyserver@0.0.74: + resolution: {integrity: sha512-5cx+Hpg8UWFh/S6azhbnvrTAfM0k+/NxEfyaLwHdqQEzvYVFmLkLCZNbolyc0NKfDhU27a0itEJfz0jF8cFuFw==} + peerDependencies: + '@cloudflare/workers-types': ^4.20240729.0 + + partysocket@1.1.5: + resolution: {integrity: sha512-8uw9foq9bij4sKLCtTSHvyqMrMTQ5FJjrHc7BjoM2s95Vu7xYCN63ABpI7OZHC7ZMP5xaom/A+SsoFPXmTV6ZQ==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -8198,6 +9277,17 @@ packages: resolution: {integrity: sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==} engines: {node: '>=12'} + pify@3.0.0: + resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} + engines: {node: '>=4'} + + pify@5.0.0: + resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} + engines: {node: '>=10'} + + pino-abstract-transport@0.5.0: + resolution: {integrity: sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==} + pino-abstract-transport@2.0.0: resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} @@ -8209,9 +9299,16 @@ packages: resolution: {integrity: sha512-3cN0tCakkT4f3zo9RXDIhy6GTvtYD6bK4CRBLN9j3E/ePqN1tugAXD5rGVfoChW6s0hiek+eyYlLNqc/BG7vBQ==} hasBin: true + pino-std-serializers@4.0.0: + resolution: {integrity: sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==} + pino-std-serializers@7.0.0: resolution: {integrity: sha512-e906FRY0+tV27iq4juKzSYPbUj2do2X2JX4EzSca1631EB2QJQUqGbDuERal7LCtOpxl6x3+nvo9NPZcmjkiFA==} + pino@7.11.0: + resolution: {integrity: sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==} + hasBin: true + pino@9.13.1: resolution: {integrity: sha512-Szuj+ViDTjKPQYiKumGmEn3frdl+ZPSdosHyt9SnUevFosOkMY2b7ipxlEctNKPmMD/VibeBI+ZcZCJK+4DPuw==} hasBin: true @@ -8244,6 +9341,34 @@ packages: engines: {node: '>=18'} hasBin: true + pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + + pony-cause@2.1.11: + resolution: {integrity: sha512-M7LhCsdNbNgiLYiP4WjsfLUuFmCfnjdF6jKe2R9NKl4WFN+HZPGHJZ9lnLP7f9ZnKe3U9nuWD0szirmj+migUg==} + engines: {node: '>=12.0.0'} + + porto@0.2.19: + resolution: {integrity: sha512-q1vEJgdtlEOf6byWgD31GHiMwpfLuxFSfx9f7Sw4RGdvpQs2ANBGfnzzardADZegr87ZXsebSp+3vaaznEUzPQ==} + hasBin: true + peerDependencies: + '@tanstack/react-query': '>=5.59.0' + '@wagmi/core': '>=2.16.3' + react: '>=18' + typescript: '>=5.4.0' + viem: '>=2.37.0' + wagmi: '>=2.0.0' + peerDependenciesMeta: + '@tanstack/react-query': + optional: true + react: + optional: true + typescript: + optional: true + wagmi: + optional: true + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -8302,6 +9427,12 @@ packages: resolution: {integrity: sha512-XROs1h+DNatgKh/AlIlCtDxWzwrKdYDb2mOs58n4yN8BkGN9ewqeQwG5ApS4/IzwCb7HPttUkOVulkYatd2PIw==} engines: {node: '>=15.0.0'} + preact@10.24.2: + resolution: {integrity: sha512-1cSoF0aCC8uaARATfrlz4VCBqE8LwZwRfLgkxJOQwAlQt6ayTmi0D9OF7nXid1POI5SZidFuG9CnlXbDfLqY/Q==} + + preact@10.27.2: + resolution: {integrity: sha512-5SYSgFKSyhCbk6SrXyMpqjb5+MQBgfvEKE/OC+PujcY34sOpqtr+0AZQtPYx5IA6VxynQ7rUPCtKzyovpj9Bpg==} + prelude-ls@1.2.1: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} @@ -8327,6 +9458,12 @@ packages: resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} engines: {node: '>=6'} + process-nextick-args@2.0.1: + resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + + process-warning@1.0.0: + resolution: {integrity: sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==} + process-warning@5.0.0: resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} @@ -8419,6 +9556,9 @@ packages: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} + proxy-compare@2.6.0: + resolution: {integrity: sha512-8xuCeM3l8yqdmbPoYeLbrAXCBWu19XEYc5/F28f5qOaoAIMyfmBUkl5axiK+x9olUvRlcekvnm98AP9RDngOIw==} + proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} @@ -8439,6 +9579,11 @@ packages: pure-rand@6.1.0: resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true + qs@6.13.0: resolution: {integrity: sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==} engines: {node: '>=0.6'} @@ -8450,6 +9595,10 @@ packages: quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + query-string@7.1.3: + resolution: {integrity: sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg==} + engines: {node: '>=6'} + querystringify@2.2.0: resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} @@ -8463,6 +9612,9 @@ packages: resolution: {integrity: sha512-h36JMxKRqrAxVD8201FrCpyeNuUY9Y5zZwujr20fFO77tpUtGa6EZzfKw/3WaiBX95fq7+MpsuMLNdSnORAwSA==} engines: {node: '>=14.18.0'} + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -8537,6 +9689,9 @@ packages: resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==} engines: {node: '>=0.10.0'} + readable-stream@2.3.8: + resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -8553,6 +9708,10 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} + real-require@0.1.0: + resolution: {integrity: sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==} + engines: {node: '>= 12.13.0'} + real-require@0.2.0: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} @@ -8627,6 +9786,9 @@ packages: resolution: {integrity: sha512-gAZ+kLqBdHarXB64XpAe2VCjB7rIRv+mU8tfRWziHRJ5umKsIHN2tLLv6EtMw7WCdP19S0ERVMldNvxYCHnhSQ==} engines: {node: '>=8.6.0'} + require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} @@ -8731,6 +9893,9 @@ packages: resolution: {integrity: sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==} engines: {node: '>=0.4'} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -8783,6 +9948,9 @@ packages: resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} engines: {node: '>= 18'} + set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -8798,6 +9966,11 @@ packages: setprototypeof@1.2.0: resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + sha.js@2.4.12: + resolution: {integrity: sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w==} + engines: {node: '>= 0.10'} + hasBin: true + sharp@0.33.5: resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -8856,6 +10029,17 @@ packages: slow-redact@0.3.2: resolution: {integrity: sha512-MseHyi2+E/hBRqdOi5COy6wZ7j7DxXRz9NkseavNYSvvWC06D8a5cidVZX3tcG5eCW3NIyVU4zT63hw0Q486jw==} + socket.io-client@4.8.1: + resolution: {integrity: sha512-hJVXfu3E28NmzGk8o1sHhN3om52tRvwYeidbj7xKy2eIIse5IoKX3USlS6Tqt3BHAtflLIkCQBkzVrEEfWUyYQ==} + engines: {node: '>=10.0.0'} + + socket.io-parser@4.2.4: + resolution: {integrity: sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==} + engines: {node: '>=10.0.0'} + + sonic-boom@2.8.0: + resolution: {integrity: sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==} + sonic-boom@4.2.0: resolution: {integrity: sha512-INb7TM37/mAcsGmc9hyyI6+QR3rR1zVRu36B0NeGXKnOOLiZOfER5SA+N7X7k3yUYRzLWafduTDvJAfDswwEww==} @@ -8885,6 +10069,10 @@ packages: space-separated-tokens@2.0.2: resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + split-on-first@1.1.0: + resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} + engines: {node: '>=6'} + split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} @@ -8918,10 +10106,17 @@ packages: resolution: {integrity: sha512-eLoXW/DHyl62zxY4SCaIgnRhuMr6ri4juEYARS8E6sCEqzKpOiE521Ucofdx+KnDZl5xmvGYaaKCk5FEOxJCoQ==} engines: {node: '>= 0.4'} + stream-shift@1.0.3: + resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==} + streamsearch@1.1.0: resolution: {integrity: sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==} engines: {node: '>=10.0.0'} + strict-uri-encode@2.0.0: + resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} + engines: {node: '>=4'} + string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} @@ -8957,6 +10152,9 @@ packages: resolution: {integrity: sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==} engines: {node: '>= 0.4'} + string_decoder@1.1.1: + resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -9033,6 +10231,10 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true + superstruct@1.0.4: + resolution: {integrity: sha512-7JpaAoX2NGyoFlI9NBh66BQXGONc+uE+MRS5i2iOBKuS4e+ccgMDjATgZldkah+33DakBxDHiss9kvUcGAO8UQ==} + engines: {node: '>=14.0.0'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -9086,6 +10288,9 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} + thread-stream@0.15.2: + resolution: {integrity: sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==} + thread-stream@3.1.0: resolution: {integrity: sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==} @@ -9109,6 +10314,10 @@ packages: tmpl@1.0.5: resolution: {integrity: sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==} + to-buffer@1.2.2: + resolution: {integrity: sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw==} + engines: {node: '>= 0.4'} + to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} @@ -9193,6 +10402,9 @@ packages: tsconfig-paths@3.15.0: resolution: {integrity: sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==} + tslib@1.14.1: + resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} @@ -9331,6 +10543,9 @@ packages: engines: {node: '>=0.8.0'} hasBin: true + uint8arrays@3.1.0: + resolution: {integrity: sha512-ei5rfKtoRO8OyOIor2Rz5fhzjThwIHJZ3uyDPnDHTXbP0aMQ1RN/6AI5B5d9dBxJOU+BvOAk7ZQ1xphsX8Lrog==} + unbox-primitive@1.1.0: resolution: {integrity: sha512-nWJ91DjeOkej/TA8pXQ3myruKpKEYgqvpw9lz4OPHj/NWFNluYrjbz9j01CJ8yKQd2g4jFoOkINCTW2I5LEEyw==} engines: {node: '>= 0.4'} @@ -9344,6 +10559,9 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.16.0: + resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + unicorn-magic@0.3.0: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} engines: {node: '>=18'} @@ -9412,6 +10630,68 @@ packages: unrs-resolver@1.11.1: resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} + unstorage@1.17.1: + resolution: {integrity: sha512-KKGwRTT0iVBCErKemkJCLs7JdxNVfqTPc/85ae1XES0+bsHbc/sFBfVi5kJp156cc51BHinIH2l3k0EZ24vOBQ==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6.0.3 || ^7.0.0 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1.0.1 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + untruncate-json@0.0.1: resolution: {integrity: sha512-4W9enDK4X1y1s2S/Rz7ysw6kDuMS3VmRjMFg7GZrNO+98OSe+x5Lh7PKYoVjy3lW/1wmhs6HW0lusnQRHgMarA==} @@ -9456,14 +10736,31 @@ packages: '@types/react': optional: true + use-sync-external-store@1.2.0: + resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + + use-sync-external-store@1.4.0: + resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + use-sync-external-store@1.6.0: resolution: {integrity: sha512-Pp6GSwGP/NrPIrxVFAIkOQeyw8lFenOHijQWkUTrDvrF4ALqylP2C/KCkeS9dpUM3KvYRQhna5vt7IL95+ZQ9w==} peerDependencies: react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + utf-8-validate@5.0.10: + resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==} + engines: {node: '>=6.14.2'} + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + util@0.12.5: + resolution: {integrity: sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA==} + utils-merge@1.0.1: resolution: {integrity: sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==} engines: {node: '>= 0.4.0'} @@ -9476,6 +10773,10 @@ packages: resolution: {integrity: sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==} hasBin: true + uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + uuid@9.0.1: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true @@ -9493,6 +10794,18 @@ packages: resolution: {integrity: sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==} engines: {node: '>= 0.10'} + valtio@1.13.2: + resolution: {integrity: sha512-Qik0o+DSy741TmkqmRfjq+0xpZBXi/Y6+fXZLn0xNF1z/waFMbE3rkivv5Zcf9RrMUp6zswf2J7sbh2KBlba5A==} + engines: {node: '>=12.20.0'} + peerDependencies: + '@types/react': '>=16.8' + react: '>=16.8' + peerDependenciesMeta: + '@types/react': + optional: true + react: + optional: true + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -9512,9 +10825,36 @@ packages: vfile@6.0.3: resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + viem@2.23.2: + resolution: {integrity: sha512-NVmW/E0c5crMOtbEAqMF0e3NmvQykFXhLOc/CkLIXOlzHSA6KXVz3CYVmaKqBF8/xtjsjHAGjdJN3Ru1kFJLaA==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + + viem@2.38.2: + resolution: {integrity: sha512-MJDiTDD9gfOT7lPQRimdmw+g46hU/aWJ3loqb+tN6UBOO00XEd0O4LJx+Kp5/uCRnMlJr8zJ1bNzCK7eG6gMjg==} + peerDependencies: + typescript: '>=5.0.4' + peerDependenciesMeta: + typescript: + optional: true + w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + wagmi@2.18.1: + resolution: {integrity: sha512-u+lzv7K7R5Gvw5P8vtmwQ96+tR2UGSJ/wNRrDAZH+2ikLqc6Dt8Lj8L8MaqI0v7+gnHOGh63cgeXAEjOWydsMg==} + peerDependencies: + '@tanstack/react-query': '>=5.0.0' + react: '>=18' + typescript: '>=5.0.4' + viem: 2.x + peerDependenciesMeta: + typescript: + optional: true + wait-port@1.1.0: resolution: {integrity: sha512-3e04qkoN3LxTMLakdqeWth8nih8usyg+sf1Bgdf9wwUkp05iuK1eSY/QpLvscT/+F/gA89+LpUmmgBtesbqI2Q==} engines: {node: '>=10'} @@ -9541,6 +10881,9 @@ packages: resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} engines: {node: '>= 14'} + webextension-polyfill@0.10.0: + resolution: {integrity: sha512-c5s35LgVa5tFaHhrZDnr3FpQpjj1BB+RXhLTYUxGqBVN460HkbM8TBtEqdXWbpTKfzwCcjAZVF7zXCYSKtcp9g==} + webidl-conversions@3.0.1: resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} @@ -9565,6 +10908,9 @@ packages: resolution: {integrity: sha512-K4jVyjnBdgvc86Y6BkaLZEN933SwYOuBFkdmBu9ZfkcAbdVbpITnDmjvZ/aQjRXQrv5EPkTnD1s39GiiqbngCw==} engines: {node: '>= 0.4'} + which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + which-typed-array@1.1.19: resolution: {integrity: sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==} engines: {node: '>= 0.4'} @@ -9603,6 +10949,42 @@ packages: resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + ws@7.5.10: + resolution: {integrity: sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==} + engines: {node: '>=8.3.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.17.1: + resolution: {integrity: sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + + ws@8.18.0: + resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: '>=5.0.2' + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + ws@8.18.3: resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} engines: {node: '>=10.0.0'} @@ -9619,6 +11001,13 @@ packages: resolution: {integrity: sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==} engines: {node: '>=18'} + x402@0.6.6: + resolution: {integrity: sha512-gKkxqKBT0mH7fSLld6Mz9ML52dmu1XeOPhVtiUCA3EzkfY6p0EJ3ijKhIKN0Jh8Q6kVXrFlJ/4iAUS1dNDA2lA==} + + xmlhttprequest-ssl@2.1.2: + resolution: {integrity: sha512-TEU+nJVUUnA4CYJFLvK5X9AOeH4KvDvhIfm0vV1GaQRtchnG0hgK5p8hw/xjv8cunWYCsiPCSDzObPyhEwq3KQ==} + engines: {node: '>=0.4.0'} + xstate@5.23.0: resolution: {integrity: sha512-jo126xWXkU6ySQ91n51+H2xcgnMuZcCQpQoD3FQ79d32a6RQvryRh8rrDHnH4WDdN/yg5xNjlIRol9ispMvzeg==} @@ -9629,6 +11018,9 @@ packages: xxhash-wasm@1.1.0: resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} + y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -9648,10 +11040,18 @@ packages: engines: {node: '>= 14.6'} hasBin: true + yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} + yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} @@ -9683,12 +11083,69 @@ packages: peerDependencies: zod: ^3.24.1 + zod@3.22.4: + resolution: {integrity: sha512-iC+8Io04lddc+mVqQ9AZ7OQ2MrUKGN+oIQyq1vemgt46jwCwLfhq7/pwnBnNXXXZb8VTVLKwp9EDkx+ryxIWmg==} + zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} zod@4.1.12: resolution: {integrity: sha512-JInaHOamG8pt5+Ey8kGmdcAcg3OL9reK8ltczgHTAwNhMys/6ThXHityHxVV2p3fkw/c+MAvBHFVYHFZDmjMCQ==} + zustand@5.0.0: + resolution: {integrity: sha512-LE+VcmbartOPM+auOjCCLQOsQ05zUTp8RkgwRzefUk+2jISdMMFnxvyTjA4YNWr5ZGXYbVsEMZosttuxUBkojQ==} + 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 + + zustand@5.0.3: + resolution: {integrity: sha512-14fwWQtU3pH4dE0dOpdMiWjddcH+QzKIgk1cl8epwSE7yag43k/AD/m4L6+K7DytAOr9gGBe3/EXj9g7cdostg==} + 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 + + zustand@5.0.8: + resolution: {integrity: sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==} + 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 + zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} @@ -9709,6 +11166,8 @@ snapshots: transitivePeerDependencies: - supports-color + '@adraffy/ens-normalize@1.11.1': {} + '@ag-ui/client@0.0.35': dependencies: '@ag-ui/core': 0.0.35 @@ -9746,12 +11205,12 @@ snapshots: '@ag-ui/core': 0.0.39 '@ag-ui/proto': 0.0.39 - '@ag-ui/langgraph@0.0.18(@ag-ui/client@sdks+typescript+packages+client)(@ag-ui/core@sdks+typescript+packages+core)(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@ag-ui/langgraph@0.0.18(@ag-ui/client@sdks+typescript+packages+client)(@ag-ui/core@sdks+typescript+packages+core)(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@ag-ui/client': link:sdks/typescript/packages/client '@ag-ui/core': link:sdks/typescript/packages/core - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) - '@langchain/langgraph-sdk': 0.1.10(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/langgraph-sdk': 0.1.10(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) partial-json: 0.1.7 rxjs: 7.8.1 transitivePeerDependencies: @@ -9779,6 +11238,12 @@ snapshots: '@ai-sdk/provider-utils': 3.0.10(zod@3.25.76) zod: 3.25.76 + '@ai-sdk/gateway@1.0.25(zod@3.25.76)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.9(zod@3.25.76) + zod: 3.25.76 + '@ai-sdk/gateway@1.0.33(zod@3.25.76)': dependencies: '@ai-sdk/provider': 2.0.0 @@ -9837,6 +11302,13 @@ snapshots: eventsource-parser: 3.0.6 zod: 3.25.76 + '@ai-sdk/provider-utils@3.0.9(zod@3.25.76)': + dependencies: + '@ai-sdk/provider': 2.0.0 + '@standard-schema/spec': 1.0.0 + eventsource-parser: 3.0.6 + zod: 3.25.76 + '@ai-sdk/provider@1.1.3': dependencies: json-schema: 0.4.0 @@ -10705,6 +12177,10 @@ snapshots: transitivePeerDependencies: - supports-color + '@babel/runtime-corejs3@7.28.4': + dependencies: + core-js-pure: 3.46.0 + '@babel/runtime@7.28.4': {} '@babel/template@7.27.2': @@ -10730,6 +12206,26 @@ snapshots: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 + '@base-org/account@1.1.1(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@noble/hashes': 1.4.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@5.9.3)(zod@3.25.76) + preact: 10.24.2 + viem: 2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + '@bcoe/v8-coverage@0.2.3': {} '@browserbasehq/sdk@2.6.0': @@ -10744,15 +12240,15 @@ snapshots: transitivePeerDependencies: - encoding - '@browserbasehq/stagehand@1.14.0(@playwright/test@1.56.0)(deepmerge@4.3.1)(dotenv@16.6.1)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(zod@3.25.76)': + '@browserbasehq/stagehand@1.14.0(@playwright/test@1.56.0)(bufferutil@4.0.9)(deepmerge@4.3.1)(dotenv@16.6.1)(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@anthropic-ai/sdk': 0.27.3 '@browserbasehq/sdk': 2.6.0 '@playwright/test': 1.56.0 deepmerge: 4.3.1 dotenv: 16.6.1 - openai: 4.104.0(ws@8.18.3)(zod@3.25.76) - ws: 8.18.3 + openai: 4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) zod: 3.25.76 zod-to-json-schema: 3.24.6(zod@3.25.76) transitivePeerDependencies: @@ -10760,15 +12256,15 @@ snapshots: - encoding - utf-8-validate - '@browserbasehq/stagehand@1.14.0(@playwright/test@1.56.0)(deepmerge@4.3.1)(dotenv@16.6.1)(openai@5.12.2(ws@8.18.3)(zod@3.25.76))(zod@3.25.76)': + '@browserbasehq/stagehand@1.14.0(@playwright/test@1.56.0)(bufferutil@4.0.9)(deepmerge@4.3.1)(dotenv@16.6.1)(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: '@anthropic-ai/sdk': 0.27.3 '@browserbasehq/sdk': 2.6.0 '@playwright/test': 1.56.0 deepmerge: 4.3.1 dotenv: 16.6.1 - openai: 5.12.2(ws@8.18.3)(zod@3.25.76) - ws: 8.18.3 + openai: 5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) zod: 3.25.76 zod-to-json-schema: 3.24.6(zod@3.25.76) transitivePeerDependencies: @@ -10791,6 +12287,42 @@ snapshots: picocolors: 1.1.1 sisteransi: 1.0.5 + '@cloudflare/workers-types@4.20251011.0': {} + + '@coinbase/wallet-sdk@3.9.3': + dependencies: + bn.js: 5.2.2 + buffer: 6.0.3 + clsx: 1.2.1 + eth-block-tracker: 7.1.0 + eth-json-rpc-filters: 6.0.1 + eventemitter3: 5.0.1 + keccak: 3.0.4 + preact: 10.27.2 + sha.js: 2.4.12 + transitivePeerDependencies: + - supports-color + + '@coinbase/wallet-sdk@4.3.6(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@noble/hashes': 1.4.0 + clsx: 1.2.1 + eventemitter3: 5.0.1 + idb-keyval: 6.2.1 + ox: 0.6.9(typescript@5.9.3)(zod@3.25.76) + preact: 10.24.2 + viem: 2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.3(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) + transitivePeerDependencies: + - '@types/react' + - bufferutil + - immer + - react + - typescript + - use-sync-external-store + - utf-8-validate + - zod + '@copilotkit/react-core@1.10.6(@types/react@19.2.2)(graphql@16.11.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@copilotkit/runtime-client-gql': 1.10.6(graphql@16.11.0)(react@19.2.0) @@ -10836,22 +12368,22 @@ snapshots: - encoding - graphql - '@copilotkit/runtime@1.10.6(2963fdc46a5185bf1f60e289781c45cd)': + '@copilotkit/runtime@1.10.6(11965aeb7c1575ca0e6e335d73f00c47)': dependencies: '@ag-ui/client': link:sdks/typescript/packages/client '@ag-ui/core': link:sdks/typescript/packages/core '@ag-ui/encoder': 0.0.39 - '@ag-ui/langgraph': 0.0.18(@ag-ui/client@sdks+typescript+packages+client)(@ag-ui/core@sdks+typescript+packages+core)(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) + '@ag-ui/langgraph': 0.0.18(@ag-ui/client@sdks+typescript+packages+client)(@ag-ui/core@sdks+typescript+packages+core)(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(react-dom@19.2.0(react@19.2.0))(react@19.2.0) '@ag-ui/proto': 0.0.39 '@anthropic-ai/sdk': 0.57.0 '@copilotkit/shared': 1.10.6 '@graphql-yoga/plugin-defer-stream': 3.16.0(graphql-yoga@5.16.0(graphql@16.11.0))(graphql@16.11.0) - '@langchain/aws': 0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))) - '@langchain/community': 0.3.57(8d705aac09841dc81e24dfe2c773558d) - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) - '@langchain/google-gauth': 0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76) - '@langchain/langgraph-sdk': 0.0.70(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(react@19.2.0) - '@langchain/openai': 0.4.9(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) + '@langchain/aws': 0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) + '@langchain/community': 0.3.57(1fb9a837778981b6a1f0807e283b73bb) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/google-gauth': 0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(zod@3.25.76) + '@langchain/langgraph-sdk': 0.0.70(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react@19.2.0) + '@langchain/openai': 0.4.9(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@scarf/scarf': 1.4.0 class-transformer: 0.5.1 class-validator: 0.14.2 @@ -10860,8 +12392,8 @@ snapshots: graphql-scalars: 1.24.2(graphql@16.11.0) graphql-yoga: 5.16.0(graphql@16.11.0) groq-sdk: 0.5.0 - langchain: 0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(ws@8.18.3) - openai: 4.104.0(ws@8.18.3)(zod@3.25.76) + langchain: 0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + openai: 4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) partial-json: 0.1.7 pino: 9.13.1 pino-pretty: 11.3.0 @@ -11018,7 +12550,7 @@ snapshots: - ws - youtubei.js - '@copilotkit/runtime@1.10.6(43a54c62826e391639c20a8a0387b983)': + '@copilotkit/runtime@1.10.6(6baa88a9727729a45a3f3165407bbf6b)': dependencies: '@ag-ui/client': link:sdks/typescript/packages/client '@ag-ui/core': link:sdks/typescript/packages/core @@ -11028,12 +12560,12 @@ snapshots: '@anthropic-ai/sdk': 0.57.0 '@copilotkit/shared': 1.10.6 '@graphql-yoga/plugin-defer-stream': 3.16.0(graphql-yoga@5.16.0(graphql@16.11.0))(graphql@16.11.0) - '@langchain/aws': 0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76))) - '@langchain/community': 0.3.57(a6f05470c76b31786172bd3244671918) - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) - '@langchain/google-gauth': 0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76) - '@langchain/langgraph-sdk': 0.0.70(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(react@19.2.0) - '@langchain/openai': 0.4.9(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) + '@langchain/aws': 0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) + '@langchain/community': 0.3.57(d5009b009fd9ef543398d6116aa865d9) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/google-gauth': 0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(zod@3.25.76) + '@langchain/langgraph-sdk': 0.0.70(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react@19.2.0) + '@langchain/openai': 0.4.9(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) '@scarf/scarf': 1.4.0 class-transformer: 0.5.1 class-validator: 0.14.2 @@ -11042,8 +12574,8 @@ snapshots: graphql-scalars: 1.24.2(graphql@16.11.0) graphql-yoga: 5.16.0(graphql@16.11.0) groq-sdk: 0.5.0 - langchain: 0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(ws@8.18.3) - openai: 4.104.0(ws@8.18.3)(zod@3.25.76) + langchain: 0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + openai: 4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) partial-json: 0.1.7 pino: 9.13.1 pino-pretty: 11.3.0 @@ -11212,6 +12744,10 @@ snapshots: transitivePeerDependencies: - encoding + '@ecies/ciphers@0.2.4(@noble/ciphers@1.3.0)': + dependencies: + '@noble/ciphers': 1.3.0 + '@emnapi/core@1.5.0': dependencies: '@emnapi/wasi-threads': 1.1.0 @@ -11369,6 +12905,26 @@ snapshots: '@eslint/core': 0.16.0 levn: 0.4.1 + '@ethereumjs/common@3.2.0': + dependencies: + '@ethereumjs/util': 8.1.0 + crc-32: 1.2.2 + + '@ethereumjs/rlp@4.0.1': {} + + '@ethereumjs/tx@4.2.0': + dependencies: + '@ethereumjs/common': 3.2.0 + '@ethereumjs/rlp': 4.0.1 + '@ethereumjs/util': 8.1.0 + ethereum-cryptography: 2.2.1 + + '@ethereumjs/util@8.1.0': + dependencies: + '@ethereumjs/rlp': 4.0.1 + ethereum-cryptography: 2.2.1 + micro-ftch: 0.3.1 + '@expo/devcert@1.2.0': dependencies: '@expo/sudo-prompt': 9.3.2 @@ -11406,6 +12962,14 @@ snapshots: '@floating-ui/utils@0.2.10': {} + '@gemini-wallet/core@0.2.0(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': + dependencies: + '@metamask/rpc-errors': 7.0.2 + eventemitter3: 5.0.1 + viem: 2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - supports-color + '@graphql-tools/executor@1.4.9(graphql@16.11.0)': dependencies: '@graphql-tools/utils': 10.9.1(graphql@16.11.0) @@ -11916,41 +13480,41 @@ snapshots: '@jsdevtools/ono@7.1.3': {} - '@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))': + '@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))': dependencies: '@aws-sdk/client-bedrock-agent-runtime': 3.910.0 '@aws-sdk/client-bedrock-runtime': 3.910.0 '@aws-sdk/client-kendra': 3.910.0 '@aws-sdk/credential-provider-node': 3.910.0 - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) transitivePeerDependencies: - aws-crt - '@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))': + '@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))': dependencies: '@aws-sdk/client-bedrock-agent-runtime': 3.910.0 '@aws-sdk/client-bedrock-runtime': 3.910.0 '@aws-sdk/client-kendra': 3.910.0 '@aws-sdk/credential-provider-node': 3.910.0 - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) transitivePeerDependencies: - aws-crt - '@langchain/community@0.3.57(8d705aac09841dc81e24dfe2c773558d)': + '@langchain/community@0.3.57(1fb9a837778981b6a1f0807e283b73bb)': dependencies: - '@browserbasehq/stagehand': 1.14.0(@playwright/test@1.56.0)(deepmerge@4.3.1)(dotenv@16.6.1)(openai@5.12.2(ws@8.18.3)(zod@3.25.76))(zod@3.25.76) + '@browserbasehq/stagehand': 1.14.0(@playwright/test@1.56.0)(bufferutil@4.0.9)(deepmerge@4.3.1)(dotenv@16.6.1)(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(utf-8-validate@5.0.10)(zod@3.25.76) '@ibm-cloud/watsonx-ai': 1.7.0 - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) - '@langchain/openai': 0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) - '@langchain/weaviate': 0.2.3(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/openai': 0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@langchain/weaviate': 0.2.3(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) binary-extensions: 2.3.0 expr-eval: 2.0.2 flat: 5.0.2 ibm-cloud-sdk-core: 5.4.3 js-yaml: 4.1.0 - langchain: 0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(ws@8.18.3) - langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) - openai: 4.104.0(ws@8.18.3)(zod@3.25.76) + langchain: 0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + openai: 4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) uuid: 10.0.0 zod: 3.25.76 optionalDependencies: @@ -11967,11 +13531,12 @@ snapshots: google-auth-library: 8.9.0 ignore: 5.3.2 jsonwebtoken: 9.0.2 + lodash: 4.17.21 pg: 8.16.3 playwright: 1.56.0 redis: 5.8.3 weaviate-client: 3.9.0 - ws: 8.18.3 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - '@langchain/anthropic' - '@langchain/aws' @@ -11993,21 +13558,21 @@ snapshots: - handlebars - peggy - '@langchain/community@0.3.57(a6f05470c76b31786172bd3244671918)': + '@langchain/community@0.3.57(d5009b009fd9ef543398d6116aa865d9)': dependencies: - '@browserbasehq/stagehand': 1.14.0(@playwright/test@1.56.0)(deepmerge@4.3.1)(dotenv@16.6.1)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(zod@3.25.76) + '@browserbasehq/stagehand': 1.14.0(@playwright/test@1.56.0)(bufferutil@4.0.9)(deepmerge@4.3.1)(dotenv@16.6.1)(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(utf-8-validate@5.0.10)(zod@3.25.76) '@ibm-cloud/watsonx-ai': 1.7.0 - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) - '@langchain/openai': 0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) - '@langchain/weaviate': 0.2.3(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76))) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/openai': 0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@langchain/weaviate': 0.2.3(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) binary-extensions: 2.3.0 expr-eval: 2.0.2 flat: 5.0.2 ibm-cloud-sdk-core: 5.4.3 js-yaml: 4.1.0 - langchain: 0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(ws@8.18.3) - langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) - openai: 4.104.0(ws@8.18.3)(zod@3.25.76) + langchain: 0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + openai: 4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) uuid: 10.0.0 zod: 3.25.76 optionalDependencies: @@ -12024,11 +13589,12 @@ snapshots: google-auth-library: 8.9.0 ignore: 5.3.2 jsonwebtoken: 9.0.2 + lodash: 4.17.21 pg: 8.16.3 playwright: 1.56.0 redis: 5.8.3 weaviate-client: 3.9.0 - ws: 8.18.3 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - '@langchain/anthropic' - '@langchain/aws' @@ -12050,14 +13616,14 @@ snapshots: - handlebars - peggy - '@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76))': + '@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': dependencies: '@cfworker/json-schema': 4.1.1 ansi-styles: 5.2.0 camelcase: 6.3.0 decamelize: 1.2.0 js-tiktoken: 1.0.21 - langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) + langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) mustache: 4.2.0 p-queue: 6.6.2 p-retry: 4.6.2 @@ -12070,14 +13636,14 @@ snapshots: - '@opentelemetry/sdk-trace-base' - openai - '@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))': + '@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))': dependencies: '@cfworker/json-schema': 4.1.1 ansi-styles: 5.2.0 camelcase: 6.3.0 decamelize: 1.2.0 js-tiktoken: 1.0.21 - langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) mustache: 4.2.0 p-queue: 6.6.2 p-retry: 4.6.2 @@ -12090,143 +13656,160 @@ snapshots: - '@opentelemetry/sdk-trace-base' - openai - '@langchain/google-common@0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76)': + '@langchain/google-common@0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(zod@3.25.76)': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) uuid: 10.0.0 zod-to-json-schema: 3.24.6(zod@3.25.76) transitivePeerDependencies: - zod - '@langchain/google-common@0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76)': + '@langchain/google-common@0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(zod@3.25.76)': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) uuid: 10.0.0 zod-to-json-schema: 3.24.6(zod@3.25.76) transitivePeerDependencies: - zod - '@langchain/google-gauth@0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76)': + '@langchain/google-gauth@0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(zod@3.25.76)': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) - '@langchain/google-common': 0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/google-common': 0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(zod@3.25.76) google-auth-library: 8.9.0 transitivePeerDependencies: - encoding - supports-color - zod - '@langchain/google-gauth@0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76)': + '@langchain/google-gauth@0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(zod@3.25.76)': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) - '@langchain/google-common': 0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(zod@3.25.76) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/google-common': 0.1.8(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(zod@3.25.76) google-auth-library: 8.9.0 transitivePeerDependencies: - encoding - supports-color - zod - '@langchain/langgraph-sdk@0.0.70(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(react@19.2.0)': + '@langchain/langgraph-checkpoint@0.0.18(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))': + dependencies: + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + uuid: 10.0.0 + + '@langchain/langgraph-sdk@0.0.70(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react@19.2.0)': dependencies: '@types/json-schema': 7.0.15 p-queue: 6.6.2 p-retry: 4.6.2 uuid: 9.0.1 optionalDependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) react: 19.2.0 - '@langchain/langgraph-sdk@0.0.70(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(react@19.2.0)': + '@langchain/langgraph-sdk@0.0.70(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react@19.2.0)': dependencies: '@types/json-schema': 7.0.15 p-queue: 6.6.2 p-retry: 4.6.2 uuid: 9.0.1 optionalDependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) react: 19.2.0 - '@langchain/langgraph-sdk@0.1.10(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@langchain/langgraph-sdk@0.1.10(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@types/json-schema': 7.0.15 p-queue: 6.6.2 p-retry: 4.6.2 uuid: 9.0.1 optionalDependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) react: 19.2.0 react-dom: 19.2.0(react@19.2.0) - '@langchain/openai@0.4.9(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3)': + '@langchain/langgraph@0.2.74(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react@19.2.0)(zod-to-json-schema@3.24.6(zod@3.25.76))': + dependencies: + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/langgraph-checkpoint': 0.0.18(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) + '@langchain/langgraph-sdk': 0.0.70(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(react@19.2.0) + uuid: 10.0.0 + zod: 3.25.76 + optionalDependencies: + zod-to-json-schema: 3.24.6(zod@3.25.76) + transitivePeerDependencies: + - react + + '@langchain/openai@0.4.9(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) js-tiktoken: 1.0.21 - openai: 4.104.0(ws@8.18.3)(zod@3.25.76) + openai: 4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) zod: 3.25.76 zod-to-json-schema: 3.24.6(zod@3.25.76) transitivePeerDependencies: - encoding - ws - '@langchain/openai@0.4.9(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3)': + '@langchain/openai@0.4.9(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) js-tiktoken: 1.0.21 - openai: 4.104.0(ws@8.18.3)(zod@3.25.76) + openai: 4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) zod: 3.25.76 zod-to-json-schema: 3.24.6(zod@3.25.76) transitivePeerDependencies: - encoding - ws - '@langchain/openai@0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3)': + '@langchain/openai@0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) js-tiktoken: 1.0.21 - openai: 5.12.2(ws@8.18.3)(zod@3.25.76) + openai: 5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - ws - '@langchain/openai@0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3)': + '@langchain/openai@0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) js-tiktoken: 1.0.21 - openai: 5.12.2(ws@8.18.3)(zod@3.25.76) + openai: 5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - ws - '@langchain/textsplitters@0.1.0(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))': + '@langchain/textsplitters@0.1.0(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) js-tiktoken: 1.0.21 - '@langchain/textsplitters@0.1.0(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))': + '@langchain/textsplitters@0.1.0(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) js-tiktoken: 1.0.21 - '@langchain/weaviate@0.2.3(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))': + '@langchain/weaviate@0.2.3(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) uuid: 10.0.0 weaviate-client: 3.9.0 transitivePeerDependencies: - encoding - '@langchain/weaviate@0.2.3(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))': + '@langchain/weaviate@0.2.3(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))': dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) uuid: 10.0.0 weaviate-client: 3.9.0 transitivePeerDependencies: - encoding - '@libsql/client@0.15.15': + '@libsql/client@0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@libsql/core': 0.15.15 - '@libsql/hrana-client': 0.7.0 + '@libsql/hrana-client': 0.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) js-base64: 3.7.8 libsql: 0.5.22 promise-limit: 2.7.0 @@ -12244,10 +13827,10 @@ snapshots: '@libsql/darwin-x64@0.5.22': optional: true - '@libsql/hrana-client@0.7.0': + '@libsql/hrana-client@0.7.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@libsql/isomorphic-fetch': 0.3.1 - '@libsql/isomorphic-ws': 0.1.5 + '@libsql/isomorphic-ws': 0.1.5(bufferutil@4.0.9)(utf-8-validate@5.0.10) js-base64: 3.7.8 node-fetch: 3.3.2 transitivePeerDependencies: @@ -12256,10 +13839,10 @@ snapshots: '@libsql/isomorphic-fetch@0.3.1': {} - '@libsql/isomorphic-ws@0.1.5': + '@libsql/isomorphic-ws@0.1.5(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: '@types/ws': 8.18.1 - ws: 8.18.3 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) transitivePeerDependencies: - bufferutil - utf-8-validate @@ -12285,6 +13868,12 @@ snapshots: '@libsql/win32-x64-msvc@0.5.22': optional: true + '@lit-labs/ssr-dom-shim@1.4.0': {} + + '@lit/reactive-element@2.1.1': + dependencies: + '@lit-labs/ssr-dom-shim': 1.4.0 + '@lukeed/csprng@1.1.0': {} '@lukeed/uuid@2.0.1': @@ -12505,17 +14094,17 @@ snapshots: transitivePeerDependencies: - aws-crt - '@mastra/libsql@0.12.0(@mastra/core@0.12.1(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76))': + '@mastra/libsql@0.12.0(@mastra/core@0.12.1(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76))(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: - '@libsql/client': 0.15.15 + '@libsql/client': 0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@mastra/core': 0.12.1(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76) transitivePeerDependencies: - bufferutil - utf-8-validate - '@mastra/libsql@0.15.1(@mastra/core@0.20.2(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76))': + '@mastra/libsql@0.15.1(@mastra/core@0.20.2(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76))(bufferutil@4.0.9)(utf-8-validate@5.0.10)': dependencies: - '@libsql/client': 0.15.15 + '@libsql/client': 0.15.15(bufferutil@4.0.9)(utf-8-validate@5.0.10) '@mastra/core': 0.20.2(openapi-types@12.1.3)(react@19.2.0)(zod@3.25.76) transitivePeerDependencies: - bufferutil @@ -12654,60 +14243,245 @@ snapshots: '@types/react': 19.2.2 react: 19.2.0 - '@modelcontextprotocol/sdk@1.20.0': + '@metamask/eth-json-rpc-provider@1.0.1': dependencies: - ajv: 6.12.6 - content-type: 1.0.5 - cors: 2.8.5 - cross-spawn: 7.0.6 - eventsource: 3.0.7 - eventsource-parser: 3.0.6 - express: 5.1.0 - express-rate-limit: 7.5.1(express@5.1.0) - pkce-challenge: 5.0.0 - raw-body: 3.0.1 - zod: 3.25.76 - zod-to-json-schema: 3.24.6(zod@3.25.76) + '@metamask/json-rpc-engine': 7.3.3 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 5.0.2 transitivePeerDependencies: - supports-color - '@monaco-editor/loader@1.6.1': + '@metamask/json-rpc-engine@7.3.3': dependencies: - state-local: 1.0.7 + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + transitivePeerDependencies: + - supports-color - '@monaco-editor/react@4.7.0(monaco-editor@0.54.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + '@metamask/json-rpc-engine@8.0.2': dependencies: - '@monaco-editor/loader': 1.6.1 - monaco-editor: 0.54.0 - react: 19.2.0 - react-dom: 19.2.0(react@19.2.0) + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + transitivePeerDependencies: + - supports-color - '@napi-rs/wasm-runtime@0.2.12': + '@metamask/json-rpc-middleware-stream@7.0.2': dependencies: - '@emnapi/core': 1.5.0 - '@emnapi/runtime': 1.5.0 - '@tybys/wasm-util': 0.10.1 - optional: true - - '@neon-rs/load@0.0.4': {} + '@metamask/json-rpc-engine': 8.0.2 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + readable-stream: 3.6.2 + transitivePeerDependencies: + - supports-color - '@neon-rs/load@0.1.82': {} + '@metamask/object-multiplex@2.1.0': + dependencies: + once: 1.4.0 + readable-stream: 3.6.2 - '@next/env@15.2.1': {} + '@metamask/onboarding@1.0.1': + dependencies: + bowser: 2.12.1 - '@next/eslint-plugin-next@15.2.1': + '@metamask/providers@16.1.0': dependencies: - fast-glob: 3.3.1 + '@metamask/json-rpc-engine': 8.0.2 + '@metamask/json-rpc-middleware-stream': 7.0.2 + '@metamask/object-multiplex': 2.1.0 + '@metamask/rpc-errors': 6.4.0 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 8.5.0 + detect-browser: 5.3.0 + extension-port-stream: 3.0.0 + fast-deep-equal: 3.1.3 + is-stream: 2.0.1 + readable-stream: 3.6.2 + webextension-polyfill: 0.10.0 + transitivePeerDependencies: + - supports-color - '@next/mdx@15.5.5(@mdx-js/loader@3.1.1)(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@19.2.0))': + '@metamask/rpc-errors@6.4.0': dependencies: - source-map: 0.7.6 - optionalDependencies: - '@mdx-js/loader': 3.1.1 - '@mdx-js/react': 3.1.1(@types/react@19.2.2)(react@19.2.0) + '@metamask/utils': 9.3.0 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - supports-color - '@next/swc-darwin-arm64@15.2.1': - optional: true + '@metamask/rpc-errors@7.0.2': + dependencies: + '@metamask/utils': 11.8.1 + fast-safe-stringify: 2.1.1 + transitivePeerDependencies: + - supports-color + + '@metamask/safe-event-emitter@2.0.0': {} + + '@metamask/safe-event-emitter@3.1.2': {} + + '@metamask/sdk-analytics@0.0.5': + dependencies: + openapi-fetch: 0.13.8 + + '@metamask/sdk-communication-layer@0.33.1(cross-fetch@4.1.0)(eciesjs@0.4.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@metamask/sdk-analytics': 0.0.5 + bufferutil: 4.0.9 + cross-fetch: 4.1.0 + date-fns: 2.30.0 + debug: 4.3.4 + eciesjs: 0.4.16 + eventemitter2: 6.4.9 + readable-stream: 3.6.2 + socket.io-client: 4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + utf-8-validate: 5.0.10 + uuid: 8.3.2 + transitivePeerDependencies: + - supports-color + + '@metamask/sdk-install-modal-web@0.32.1': + dependencies: + '@paulmillr/qr': 0.2.1 + + '@metamask/sdk@0.33.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@babel/runtime': 7.28.4 + '@metamask/onboarding': 1.0.1 + '@metamask/providers': 16.1.0 + '@metamask/sdk-analytics': 0.0.5 + '@metamask/sdk-communication-layer': 0.33.1(cross-fetch@4.1.0)(eciesjs@0.4.16)(eventemitter2@6.4.9)(readable-stream@3.6.2)(socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@metamask/sdk-install-modal-web': 0.32.1 + '@paulmillr/qr': 0.2.1 + bowser: 2.12.1 + cross-fetch: 4.1.0 + debug: 4.3.4 + eciesjs: 0.4.16 + eth-rpc-errors: 4.0.3 + eventemitter2: 6.4.9 + obj-multiplex: 1.0.0 + pump: 3.0.3 + readable-stream: 3.6.2 + socket.io-client: 4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + tslib: 2.8.1 + util: 0.12.5 + uuid: 8.3.2 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + + '@metamask/superstruct@3.2.1': {} + + '@metamask/utils@11.8.1': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/superstruct': 3.2.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.12 + '@types/lodash': 4.17.20 + debug: 4.4.3 + lodash: 4.17.21 + pony-cause: 2.1.11 + semver: 7.7.3 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@metamask/utils@5.0.2': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@types/debug': 4.1.12 + debug: 4.4.3 + semver: 7.7.3 + superstruct: 1.0.4 + transitivePeerDependencies: + - supports-color + + '@metamask/utils@8.5.0': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/superstruct': 3.2.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.12 + debug: 4.4.3 + pony-cause: 2.1.11 + semver: 7.7.3 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@metamask/utils@9.3.0': + dependencies: + '@ethereumjs/tx': 4.2.0 + '@metamask/superstruct': 3.2.1 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + '@types/debug': 4.1.12 + debug: 4.4.3 + pony-cause: 2.1.11 + semver: 7.7.3 + uuid: 9.0.1 + transitivePeerDependencies: + - supports-color + + '@modelcontextprotocol/sdk@1.20.0': + dependencies: + ajv: 6.12.6 + content-type: 1.0.5 + cors: 2.8.5 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.0.6 + express: 5.1.0 + express-rate-limit: 7.5.1(express@5.1.0) + pkce-challenge: 5.0.0 + raw-body: 3.0.1 + zod: 3.25.76 + zod-to-json-schema: 3.24.6(zod@3.25.76) + transitivePeerDependencies: + - supports-color + + '@monaco-editor/loader@1.6.1': + dependencies: + state-local: 1.0.7 + + '@monaco-editor/react@4.7.0(monaco-editor@0.54.0)(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': + dependencies: + '@monaco-editor/loader': 1.6.1 + monaco-editor: 0.54.0 + react: 19.2.0 + react-dom: 19.2.0(react@19.2.0) + + '@napi-rs/wasm-runtime@0.2.12': + dependencies: + '@emnapi/core': 1.5.0 + '@emnapi/runtime': 1.5.0 + '@tybys/wasm-util': 0.10.1 + optional: true + + '@neon-rs/load@0.0.4': {} + + '@neon-rs/load@0.1.82': {} + + '@next/env@15.2.1': {} + + '@next/eslint-plugin-next@15.2.1': + dependencies: + fast-glob: 3.3.1 + + '@next/mdx@15.5.5(@mdx-js/loader@3.1.1)(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@19.2.0))': + dependencies: + source-map: 0.7.6 + optionalDependencies: + '@mdx-js/loader': 3.1.1 + '@mdx-js/react': 3.1.1(@types/react@19.2.2)(react@19.2.0) + + '@next/swc-darwin-arm64@15.2.1': + optional: true '@next/swc-darwin-x64@15.2.1': optional: true @@ -12730,6 +14504,38 @@ snapshots: '@next/swc-win32-x64-msvc@15.2.1': optional: true + '@noble/ciphers@1.2.1': {} + + '@noble/ciphers@1.3.0': {} + + '@noble/curves@1.4.2': + dependencies: + '@noble/hashes': 1.4.0 + + '@noble/curves@1.8.0': + dependencies: + '@noble/hashes': 1.7.0 + + '@noble/curves@1.8.1': + dependencies: + '@noble/hashes': 1.7.1 + + '@noble/curves@1.9.1': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/curves@1.9.7': + dependencies: + '@noble/hashes': 1.8.0 + + '@noble/hashes@1.4.0': {} + + '@noble/hashes@1.7.0': {} + + '@noble/hashes@1.7.1': {} + + '@noble/hashes@1.8.0': {} + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -13462,6 +15268,8 @@ snapshots: estree-walker: 2.0.2 magic-string: 0.30.19 + '@paulmillr/qr@0.2.1': {} + '@phosphor-icons/react@2.1.10(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: react: 19.2.0 @@ -13828,6 +15636,267 @@ snapshots: '@remirror/core-constants@3.0.0': {} + '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-common@1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + big.js: 6.2.2 + dayjs: 1.11.13 + viem: 2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@reown/appkit-controllers@1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) + viem: 2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-pay@1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.76) + lit: 3.3.0 + valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-polyfills@1.7.8': + dependencies: + buffer: 6.0.3 + + '@reown/appkit-scaffold-ui@1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + lit: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - valtio + - zod + + '@reown/appkit-ui@1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + lit: 3.3.0 + qrcode: 1.5.3 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-utils@1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-polyfills': 1.7.8 + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@walletconnect/logger': 2.1.2 + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) + viem: 2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@reown/appkit-wallet@1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4) + '@reown/appkit-polyfills': 1.7.8 + '@walletconnect/logger': 2.1.2 + zod: 3.22.4 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + + '@reown/appkit@1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit-common': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-controllers': 1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-pay': 1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-polyfills': 1.7.8 + '@reown/appkit-scaffold-ui': 1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.76) + '@reown/appkit-ui': 1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@reown/appkit-utils': 1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0))(zod@3.25.76) + '@reown/appkit-wallet': 1.7.8(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.6) + '@walletconnect/universal-provider': 2.21.0(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + bs58: 6.0.0 + valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) + viem: 2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + '@repeaterjs/repeater@3.0.6': {} '@rollup/plugin-alias@5.1.1(rollup@4.50.2)': @@ -14014,14 +16083,73 @@ snapshots: '@rushstack/eslint-patch@1.14.0': {} - '@scarf/scarf@1.4.0': {} - - '@sec-ant/readable-stream@0.4.1': {} + '@safe-global/safe-apps-provider@0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + events: 3.3.0 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod - '@segment/analytics-core@1.8.2': + '@safe-global/safe-apps-sdk@9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': dependencies: - '@lukeed/uuid': 2.0.1 - '@segment/analytics-generic-utils': 1.2.0 + '@safe-global/safe-gateway-typescript-sdk': 3.23.1 + viem: 2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + - zod + + '@safe-global/safe-gateway-typescript-sdk@3.23.1': {} + + '@scarf/scarf@1.4.0': {} + + '@scure/base@1.1.9': {} + + '@scure/base@1.2.6': {} + + '@scure/bip32@1.4.0': + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.9 + + '@scure/bip32@1.6.2': + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/base': 1.2.6 + + '@scure/bip32@1.7.0': + dependencies: + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@scure/bip39@1.3.0': + dependencies: + '@noble/hashes': 1.4.0 + '@scure/base': 1.1.9 + + '@scure/bip39@1.5.4': + dependencies: + '@noble/hashes': 1.7.1 + '@scure/base': 1.2.6 + + '@scure/bip39@1.6.0': + dependencies: + '@noble/hashes': 1.8.0 + '@scure/base': 1.2.6 + + '@sec-ant/readable-stream@0.4.1': {} + + '@segment/analytics-core@1.8.2': + dependencies: + '@lukeed/uuid': 2.0.1 + '@segment/analytics-generic-utils': 1.2.0 dset: 3.1.4 tslib: 2.8.1 @@ -14382,6 +16510,373 @@ snapshots: dependencies: tslib: 2.8.1 + '@socket.io/component-emitter@3.1.2': {} + + '@solana-program/compute-budget@0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + + '@solana-program/token-2022@0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))': + dependencies: + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + + '@solana-program/token@0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))': + dependencies: + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + + '@solana/accounts@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/addresses@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/assertions': 2.3.0(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/assertions@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/codecs-core@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/codecs-data-structures@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/codecs-numbers@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/codecs-strings@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + fastestsmallesttextencoderdecoder: 1.0.22 + typescript: 5.9.3 + + '@solana/codecs@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/options': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/errors@2.3.0(typescript@5.9.3)': + dependencies: + chalk: 5.6.2 + commander: 14.0.1 + typescript: 5.9.3 + + '@solana/fast-stable-stringify@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/functional@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/instructions@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/keys@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/assertions': 2.3.0(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/accounts': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/instructions': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/programs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-parsed-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/signers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/sysvars': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-confirmation': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/nominal-types@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/options@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/programs@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/promises@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/rpc-api@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-parsed-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-parsed-types@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/rpc-spec-types@2.3.0(typescript@5.9.3)': + dependencies: + typescript: 5.9.3 + + '@solana/rpc-spec@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/rpc-subscriptions-api@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-subscriptions-channel-websocket@2.3.0(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.3) + '@solana/subscribable': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + '@solana/rpc-subscriptions-spec@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/promises': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/subscribable': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/rpc-subscriptions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/fast-stable-stringify': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/promises': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-subscriptions-api': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions-channel-websocket': 2.3.0(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-subscriptions-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/subscribable': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/rpc-transformers@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc-transport-http@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + undici-types: 7.16.0 + + '@solana/rpc-types@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/rpc@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/fast-stable-stringify': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/rpc-api': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-spec': 2.3.0(typescript@5.9.3) + '@solana/rpc-spec-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-transformers': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-transport-http': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/signers@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/instructions': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/subscribable@2.3.0(typescript@5.9.3)': + dependencies: + '@solana/errors': 2.3.0(typescript@5.9.3) + typescript: 5.9.3 + + '@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/accounts': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transaction-confirmation@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/promises': 2.3.0(typescript@5.9.3) + '@solana/rpc': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/rpc-subscriptions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transactions': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + - ws + + '@solana/transaction-messages@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/instructions': 2.3.0(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + + '@solana/transactions@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)': + dependencies: + '@solana/addresses': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/codecs-core': 2.3.0(typescript@5.9.3) + '@solana/codecs-data-structures': 2.3.0(typescript@5.9.3) + '@solana/codecs-numbers': 2.3.0(typescript@5.9.3) + '@solana/codecs-strings': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/errors': 2.3.0(typescript@5.9.3) + '@solana/functional': 2.3.0(typescript@5.9.3) + '@solana/instructions': 2.3.0(typescript@5.9.3) + '@solana/keys': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/nominal-types': 2.3.0(typescript@5.9.3) + '@solana/rpc-types': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + '@solana/transaction-messages': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3) + typescript: 5.9.3 + transitivePeerDependencies: + - fastestsmallesttextencoderdecoder + '@standard-schema/spec@1.0.0': {} '@swc/counter@0.1.3': {} @@ -14471,6 +16966,13 @@ snapshots: postcss-selector-parser: 6.0.10 tailwindcss: 4.1.14 + '@tanstack/query-core@5.90.3': {} + + '@tanstack/react-query@5.90.3(react@19.2.0)': + dependencies: + '@tanstack/query-core': 5.90.3 + react: 19.2.0 + '@tanstack/react-virtual@3.13.12(react-dom@19.2.0(react@19.2.0))(react@19.2.0)': dependencies: '@tanstack/virtual-core': 3.13.12 @@ -14760,6 +17262,8 @@ snapshots: '@types/linkify-it@5.0.0': {} + '@types/lodash@4.17.20': {} + '@types/markdown-it@14.1.2': dependencies: '@types/linkify-it': 5.0.0 @@ -14871,6 +17375,8 @@ snapshots: '@types/tough-cookie@4.0.5': {} + '@types/trusted-types@2.0.7': {} + '@types/unist@2.0.11': {} '@types/unist@3.0.3': {} @@ -15022,41 +17528,640 @@ snapshots: '@unrs/resolver-binding-linux-riscv64-musl@1.11.1': optional: true - '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': - optional: true + '@unrs/resolver-binding-linux-s390x-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-gnu@1.11.1': + optional: true + + '@unrs/resolver-binding-linux-x64-musl@1.11.1': + optional: true + + '@unrs/resolver-binding-wasm32-wasi@1.11.1': + dependencies: + '@napi-rs/wasm-runtime': 0.2.12 + optional: true + + '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': + optional: true + + '@unrs/resolver-binding-win32-x64-msvc@1.11.1': + optional: true + + '@upstash/redis@1.35.6': + dependencies: + uncrypto: 0.1.3 + + '@urql/core@5.2.0(graphql@16.11.0)': + dependencies: + '@0no-co/graphql.web': 1.2.0(graphql@16.11.0) + wonka: 6.3.5 + transitivePeerDependencies: + - graphql + + '@vercel/oidc@3.0.2': {} + + '@wagmi/connectors@6.0.1(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@upstash/redis@1.35.6)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.3)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.1(@tanstack/query-core@5.90.3)(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76)': + dependencies: + '@base-org/account': 1.1.1(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.76) + '@coinbase/wallet-sdk': 4.3.6(@types/react@19.2.2)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(zod@3.25.76) + '@gemini-wallet/core': 0.2.0(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@metamask/sdk': 0.33.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@safe-global/safe-apps-provider': 0.18.6(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@safe-global/safe-apps-sdk': 9.1.0(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.3)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + '@walletconnect/ethereum-provider': 2.21.1(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + cbw-sdk: '@coinbase/wallet-sdk@3.9.3' + porto: 0.2.19(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.3)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.1(@tanstack/query-core@5.90.3)(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)) + viem: 2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@tanstack/react-query' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - immer + - ioredis + - react + - supports-color + - uploadthing + - use-sync-external-store + - utf-8-validate + - wagmi + - zod + + '@wagmi/core@2.22.1(@tanstack/query-core@5.90.3)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))': + dependencies: + eventemitter3: 5.0.1 + mipd: 0.0.7(typescript@5.9.3) + viem: 2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zustand: 5.0.0(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) + optionalDependencies: + '@tanstack/query-core': 5.90.3 + typescript: 5.9.3 + transitivePeerDependencies: + - '@types/react' + - immer + - react + - use-sync-external-store + + '@walletconnect/core@2.21.0(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.6) + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.6) + '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/core@2.21.1(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/jsonrpc-ws-connection': 1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10) + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.6) + '@walletconnect/logger': 2.1.2 + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.6) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/window-getters': 1.0.1 + es-toolkit: 1.33.0 + events: 3.3.0 + uint8arrays: 3.1.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/environment@1.0.1': + dependencies: + tslib: 1.14.1 + + '@walletconnect/ethereum-provider@2.21.1(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@reown/appkit': 1.7.8(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/jsonrpc-http-connection': 1.0.8 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.6) + '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.6) + '@walletconnect/universal-provider': 2.21.1(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - react + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/events@1.0.1': + dependencies: + keyvaluestorage-interface: 1.0.0 + tslib: 1.14.1 + + '@walletconnect/heartbeat@1.2.2': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/time': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-http-connection@1.0.8': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + cross-fetch: 3.2.0 + events: 3.3.0 + transitivePeerDependencies: + - encoding + + '@walletconnect/jsonrpc-provider@1.0.14': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + + '@walletconnect/jsonrpc-types@1.0.4': + dependencies: + events: 3.3.0 + keyvaluestorage-interface: 1.0.0 + + '@walletconnect/jsonrpc-utils@1.0.8': + dependencies: + '@walletconnect/environment': 1.0.1 + '@walletconnect/jsonrpc-types': 1.0.4 + tslib: 1.14.1 + + '@walletconnect/jsonrpc-ws-connection@1.0.16(bufferutil@4.0.9)(utf-8-validate@5.0.10)': + dependencies: + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/safe-json': 1.0.2 + events: 3.3.0 + ws: 7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@walletconnect/keyvaluestorage@1.1.1(@upstash/redis@1.35.6)': + dependencies: + '@walletconnect/safe-json': 1.0.2 + idb-keyval: 6.2.2 + unstorage: 1.17.1(@upstash/redis@1.35.6)(idb-keyval@6.2.2) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/logger@2.1.2': + dependencies: + '@walletconnect/safe-json': 1.0.2 + pino: 7.11.0 + + '@walletconnect/relay-api@1.0.11': + dependencies: + '@walletconnect/jsonrpc-types': 1.0.4 + + '@walletconnect/relay-auth@1.1.0': + dependencies: + '@noble/curves': 1.8.0 + '@noble/hashes': 1.7.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + uint8arrays: 3.1.0 + + '@walletconnect/safe-json@1.0.2': + dependencies: + tslib: 1.14.1 + + '@walletconnect/sign-client@2.21.0(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@walletconnect/core': 2.21.0(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.6) + '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod + + '@walletconnect/sign-client@2.21.1(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@walletconnect/core': 2.21.1(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/logger': 2.1.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.6) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod - '@unrs/resolver-binding-linux-x64-gnu@1.11.1': - optional: true + '@walletconnect/time@1.0.2': + dependencies: + tslib: 1.14.1 - '@unrs/resolver-binding-linux-x64-musl@1.11.1': - optional: true + '@walletconnect/types@2.21.0(@upstash/redis@1.35.6)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.6) + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing - '@unrs/resolver-binding-wasm32-wasi@1.11.1': + '@walletconnect/types@2.21.1(@upstash/redis@1.35.6)': dependencies: - '@napi-rs/wasm-runtime': 0.2.12 - optional: true + '@walletconnect/events': 1.0.1 + '@walletconnect/heartbeat': 1.2.2 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.6) + '@walletconnect/logger': 2.1.2 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - db0 + - ioredis + - uploadthing + + '@walletconnect/universal-provider@2.21.0(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/jsonrpc-http-connection': 1.0.8 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.6) + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.21.0(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.6) + '@walletconnect/utils': 2.21.0(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + es-toolkit: 1.33.0 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod - '@unrs/resolver-binding-win32-arm64-msvc@1.11.1': - optional: true + '@walletconnect/universal-provider@2.21.1(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@walletconnect/events': 1.0.1 + '@walletconnect/jsonrpc-http-connection': 1.0.8 + '@walletconnect/jsonrpc-provider': 1.0.14 + '@walletconnect/jsonrpc-types': 1.0.4 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.6) + '@walletconnect/logger': 2.1.2 + '@walletconnect/sign-client': 2.21.1(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.6) + '@walletconnect/utils': 2.21.1(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + es-toolkit: 1.33.0 + events: 3.3.0 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod - '@unrs/resolver-binding-win32-ia32-msvc@1.11.1': - optional: true + '@walletconnect/utils@2.21.0(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@noble/ciphers': 1.2.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.6) + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.0(@upstash/redis@1.35.6) + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.0 + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod - '@unrs/resolver-binding-win32-x64-msvc@1.11.1': - optional: true + '@walletconnect/utils@2.21.1(@upstash/redis@1.35.6)(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)': + dependencies: + '@noble/ciphers': 1.2.1 + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@walletconnect/jsonrpc-utils': 1.0.8 + '@walletconnect/keyvaluestorage': 1.1.1(@upstash/redis@1.35.6) + '@walletconnect/relay-api': 1.0.11 + '@walletconnect/relay-auth': 1.1.0 + '@walletconnect/safe-json': 1.0.2 + '@walletconnect/time': 1.0.2 + '@walletconnect/types': 2.21.1(@upstash/redis@1.35.6) + '@walletconnect/window-getters': 1.0.1 + '@walletconnect/window-metadata': 1.0.1 + bs58: 6.0.0 + detect-browser: 5.3.0 + query-string: 7.1.3 + uint8arrays: 3.1.0 + viem: 2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - ioredis + - typescript + - uploadthing + - utf-8-validate + - zod - '@upstash/redis@1.35.6': + '@walletconnect/window-getters@1.0.1': dependencies: - uncrypto: 0.1.3 + tslib: 1.14.1 - '@urql/core@5.2.0(graphql@16.11.0)': + '@walletconnect/window-metadata@1.0.1': dependencies: - '@0no-co/graphql.web': 1.2.0(graphql@16.11.0) - wonka: 6.3.5 - transitivePeerDependencies: - - graphql - - '@vercel/oidc@3.0.2': {} + '@walletconnect/window-getters': 1.0.1 + tslib: 1.14.1 '@webcontainer/env@1.1.1': {} @@ -15093,6 +18198,36 @@ snapshots: '@whatwg-node/promise-helpers': 1.3.2 tslib: 2.8.1 + abitype@1.0.8(typescript@5.9.3)(zod@3.25.76): + optionalDependencies: + typescript: 5.9.3 + zod: 3.25.76 + + abitype@1.1.0(typescript@5.9.3)(zod@3.22.4): + optionalDependencies: + typescript: 5.9.3 + zod: 3.22.4 + + abitype@1.1.0(typescript@5.9.3)(zod@3.25.76): + optionalDependencies: + typescript: 5.9.3 + zod: 3.25.76 + + abitype@1.1.1(typescript@5.9.3)(zod@3.22.4): + optionalDependencies: + typescript: 5.9.3 + zod: 3.22.4 + + abitype@1.1.1(typescript@5.9.3)(zod@3.25.76): + optionalDependencies: + typescript: 5.9.3 + zod: 3.25.76 + + abitype@1.1.1(typescript@5.9.3)(zod@4.1.12): + optionalDependencies: + typescript: 5.9.3 + zod: 4.1.12 + abort-controller-x@0.4.3: {} abort-controller@3.0.0: @@ -15131,6 +18266,52 @@ snapshots: dependencies: humanize-ms: 1.2.1 + agents@0.1.6(@cloudflare/workers-types@4.20251011.0)(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@tanstack/query-core@5.90.3)(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + '@modelcontextprotocol/sdk': 1.20.0 + ai: 5.0.48(zod@3.25.76) + cron-schedule: 5.0.4 + mimetext: 3.0.27 + nanoid: 5.1.6 + partyserver: 0.0.74(@cloudflare/workers-types@4.20251011.0) + partysocket: 1.1.5 + react: 19.2.0 + x402: 0.6.6(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@tanstack/query-core@5.90.3)(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + zod: 3.25.76 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@cloudflare/workers-types' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@solana/sysvars' + - '@tanstack/query-core' + - '@tanstack/react-query' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - fastestsmallesttextencoderdecoder + - immer + - ioredis + - supports-color + - typescript + - uploadthing + - utf-8-validate + - ws + ai@4.3.19(react@19.2.0)(zod@3.25.76): dependencies: '@ai-sdk/provider': 1.1.3 @@ -15143,6 +18324,14 @@ snapshots: optionalDependencies: react: 19.2.0 + ai@5.0.48(zod@3.25.76): + dependencies: + '@ai-sdk/gateway': 1.0.25(zod@3.25.76) + '@ai-sdk/provider': 2.0.0 + '@ai-sdk/provider-utils': 3.0.9(zod@3.25.76) + '@opentelemetry/api': 1.9.0 + zod: 3.25.76 + ai@5.0.60(zod@3.25.76): dependencies: '@ai-sdk/gateway': 1.0.33(zod@3.25.76) @@ -15270,6 +18459,10 @@ snapshots: async-function@1.0.0: {} + async-mutex@0.2.6: + dependencies: + tslib: 2.8.1 + async-mutex@0.5.0: dependencies: tslib: 2.8.1 @@ -15353,10 +18546,14 @@ snapshots: balanced-match@1.0.2: {} + base-x@5.0.1: {} + base64-js@1.5.1: {} baseline-browser-mapping@2.8.16: {} + big.js@6.2.2: {} + bignumber.js@9.3.1: {} binary-extensions@2.3.0: {} @@ -15367,6 +18564,8 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 + bn.js@5.2.2: {} + body-parser@1.20.3: dependencies: bytes: 3.1.2 @@ -15425,6 +18624,10 @@ snapshots: dependencies: fast-json-stable-stringify: 2.1.0 + bs58@6.0.0: + dependencies: + base-x: 5.0.1 + bser@2.1.1: dependencies: node-int64: 0.4.0 @@ -15438,6 +18641,10 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 + bufferutil@4.0.9: + dependencies: + node-gyp-build: 4.8.4 + builtins@5.1.0: dependencies: semver: 7.7.3 @@ -15551,6 +18758,12 @@ snapshots: client-only@0.0.1: {} + cliui@6.0.0: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -15561,6 +18774,8 @@ snapshots: clone@2.1.2: {} + clsx@1.2.1: {} + clsx@2.1.1: {} cluster-key-slot@1.1.2: {} @@ -15603,6 +18818,8 @@ snapshots: commander@12.1.0: {} + commander@14.0.1: {} + commander@4.1.1: {} commander@8.3.0: {} @@ -15644,6 +18861,8 @@ snapshots: convert-source-map@2.0.0: {} + cookie-es@1.2.2: {} + cookie-signature@1.0.6: {} cookie-signature@1.2.2: {} @@ -15652,11 +18871,17 @@ snapshots: cookie@0.7.2: {} + core-js-pure@3.46.0: {} + + core-util-is@1.0.3: {} + cors@2.8.5: dependencies: object-assign: 4.1.1 vary: 1.1.2 + crc-32@1.2.2: {} + create-jest@29.7.0(@types/node@20.19.21): dependencies: '@jest/types': 29.6.3 @@ -15674,12 +18899,20 @@ snapshots: crelt@1.0.6: {} + cron-schedule@5.0.4: {} + cross-fetch@3.2.0: dependencies: node-fetch: 2.7.0 transitivePeerDependencies: - encoding + cross-fetch@4.1.0: + dependencies: + node-fetch: 2.7.0 + transitivePeerDependencies: + - encoding + cross-inspect@1.0.1: dependencies: tslib: 2.8.1 @@ -15690,6 +18923,10 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + cssesc@3.0.0: {} csstype@3.1.3: {} @@ -15716,12 +18953,18 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 + date-fns@2.30.0: + dependencies: + '@babel/runtime': 7.28.4 + date-fns@3.6.0: {} date-fns@4.1.0: {} dateformat@4.6.3: {} + dayjs@1.11.13: {} + debug@2.6.9: dependencies: ms: 2.0.0 @@ -15734,6 +18977,10 @@ snapshots: dependencies: ms: 2.1.2 + debug@4.3.4: + dependencies: + ms: 2.1.2 + debug@4.4.3: dependencies: ms: 2.1.3 @@ -15744,6 +18991,8 @@ snapshots: dependencies: character-entities: 2.0.2 + decode-uri-component@0.2.2: {} + dedent@1.7.0: {} deep-is@0.1.4: {} @@ -15783,8 +19032,16 @@ snapshots: dequal@2.0.3: {} + derive-valtio@0.1.0(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0)): + dependencies: + valtio: 1.13.2(@types/react@19.2.2)(react@19.2.0) + + destr@2.0.5: {} + destroy@1.2.0: {} + detect-browser@5.3.0: {} + detect-libc@1.0.3: {} detect-libc@2.0.2: {} @@ -15807,6 +19064,8 @@ snapshots: diff@7.0.0: {} + dijkstrajs@1.0.3: {} + doctrine@2.1.0: dependencies: esutils: 2.0.3 @@ -15827,12 +19086,26 @@ snapshots: es-errors: 1.3.0 gopd: 1.2.0 + duplexify@4.1.3: + dependencies: + end-of-stream: 1.4.5 + inherits: 2.0.4 + readable-stream: 3.6.2 + stream-shift: 1.0.3 + eastasianwidth@0.2.0: {} ecdsa-sig-formatter@1.0.11: dependencies: safe-buffer: 5.2.1 + eciesjs@0.4.16: + dependencies: + '@ecies/ciphers': 0.2.4(@noble/ciphers@1.3.0) + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + ee-first@1.1.1: {} electrodb@3.4.7(@aws-sdk/client-dynamodb@3.910.0): @@ -15865,6 +19138,8 @@ snapshots: empathic@2.0.0: {} + encode-utf8@1.0.3: {} + encodeurl@1.0.2: {} encodeurl@2.0.0: {} @@ -15873,6 +19148,20 @@ snapshots: dependencies: once: 1.4.0 + engine.io-client@6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.4 + engine.io-parser: 5.2.3 + ws: 8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10) + xmlhttprequest-ssl: 2.1.2 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + engine.io-parser@5.2.3: {} + enhanced-resolve@5.18.3: dependencies: graceful-fs: 4.2.11 @@ -15989,6 +19278,8 @@ snapshots: is-date-object: 1.1.0 is-symbol: 1.1.1 + es-toolkit@1.33.0: {} + esast-util-from-estree@2.0.0: dependencies: '@types/estree-jsx': 1.0.5 @@ -16278,12 +19569,54 @@ snapshots: etag@1.8.1: {} + eth-block-tracker@7.1.0: + dependencies: + '@metamask/eth-json-rpc-provider': 1.0.1 + '@metamask/safe-event-emitter': 3.1.2 + '@metamask/utils': 5.0.2 + json-rpc-random-id: 1.0.1 + pify: 3.0.0 + transitivePeerDependencies: + - supports-color + + eth-json-rpc-filters@6.0.1: + dependencies: + '@metamask/safe-event-emitter': 3.1.2 + async-mutex: 0.2.6 + eth-query: 2.1.2 + json-rpc-engine: 6.1.0 + pify: 5.0.0 + + eth-query@2.1.2: + dependencies: + json-rpc-random-id: 1.0.1 + xtend: 4.0.2 + + eth-rpc-errors@4.0.3: + dependencies: + fast-safe-stringify: 2.1.1 + + ethereum-cryptography@2.2.1: + dependencies: + '@noble/curves': 1.4.2 + '@noble/hashes': 1.4.0 + '@scure/bip32': 1.4.0 + '@scure/bip39': 1.3.0 + + event-target-polyfill@0.0.4: {} + event-target-shim@5.0.1: {} + eventemitter2@6.4.9: {} + eventemitter3@4.0.7: {} + eventemitter3@5.0.1: {} + events@3.3.0: {} + eventsource-parser@2.0.1: {} + eventsource-parser@3.0.6: {} eventsource@3.0.7: @@ -16419,6 +19752,11 @@ snapshots: extend@3.0.2: {} + extension-port-stream@3.0.0: + dependencies: + readable-stream: 4.7.0 + webextension-polyfill: 0.10.0 + fast-copy@3.0.2: {} fast-deep-equal@3.1.3: {} @@ -16445,6 +19783,8 @@ snapshots: fast-levenshtein@2.0.6: {} + fast-redact@3.5.0: {} + fast-safe-stringify@2.1.1: {} fast-text-encoding@1.0.6: {} @@ -16453,6 +19793,8 @@ snapshots: dependencies: strnum: 2.1.1 + fastestsmallesttextencoderdecoder@1.0.22: {} + fastq@1.19.1: dependencies: reusify: 1.1.0 @@ -16492,6 +19834,8 @@ snapshots: dependencies: to-regex-range: 5.0.1 + filter-obj@1.1.0: {} + finalhandler@1.3.1: dependencies: debug: 2.6.9 @@ -16828,6 +20172,18 @@ snapshots: - encoding - supports-color + h3@1.15.4: + dependencies: + cookie-es: 1.2.2 + crossws: 0.3.5 + defu: 6.1.4 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.3 + radix3: 1.1.2 + ufo: 1.6.1 + uncrypto: 0.1.3 + handlebars@4.7.8: dependencies: minimist: 1.2.8 @@ -17051,6 +20407,10 @@ snapshots: dependencies: safer-buffer: 2.1.2 + idb-keyval@6.2.1: {} + + idb-keyval@6.2.2: {} + ieee754@1.2.1: {} ignore@5.3.2: {} @@ -17109,6 +20469,8 @@ snapshots: ipaddr.js@1.9.1: {} + iron-webcrypto@1.2.1: {} + is-alphabetical@1.0.4: {} is-alphabetical@2.0.1: {} @@ -17123,6 +20485,11 @@ snapshots: is-alphabetical: 2.0.1 is-decimal: 2.0.1 + is-arguments@1.2.0: + dependencies: + call-bound: 1.0.4 + has-tostringtag: 1.0.2 + is-array-buffer@3.0.5: dependencies: call-bind: 1.0.8 @@ -17294,10 +20661,20 @@ snapshots: ip-regex: 4.3.0 is-url: 1.2.4 + isarray@1.0.0: {} + isarray@2.0.5: {} isexe@2.0.0: {} + isows@1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + + isows@1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + isstream@0.1.2: {} istanbul-lib-coverage@3.2.2: {} @@ -17697,6 +21074,13 @@ snapshots: json-parse-even-better-errors@2.3.1: {} + json-rpc-engine@6.1.0: + dependencies: + '@metamask/safe-event-emitter': 2.0.0 + eth-rpc-errors: 4.0.3 + + json-rpc-random-id@1.0.1: {} + json-schema-to-zod@2.6.1: {} json-schema-traverse@0.4.1: {} @@ -17778,30 +21162,38 @@ snapshots: dependencies: commander: 8.3.0 + keccak@3.0.4: + dependencies: + node-addon-api: 2.0.2 + node-gyp-build: 4.8.4 + readable-stream: 3.6.2 + keyv@4.5.4: dependencies: json-buffer: 3.0.1 + keyvaluestorage-interface@1.0.0: {} + kleur@3.0.3: {} kleur@4.1.5: {} - langchain@0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(ws@8.18.3): + langchain@0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) - '@langchain/openai': 0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) - '@langchain/textsplitters': 0.1.0(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76))) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/openai': 0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@langchain/textsplitters': 0.1.0(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) js-tiktoken: 1.0.21 js-yaml: 4.1.0 jsonpointer: 5.0.1 - langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) + langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) openapi-types: 12.1.3 p-retry: 4.6.2 uuid: 10.0.0 yaml: 2.8.1 zod: 3.25.76 optionalDependencies: - '@langchain/aws': 0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76))) + '@langchain/aws': 0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) axios: 1.12.2(debug@4.4.3) handlebars: 4.7.8 transitivePeerDependencies: @@ -17811,22 +21203,22 @@ snapshots: - openai - ws - langchain@0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3)(zod@3.25.76))(ws@8.18.3): + langchain@0.3.36(@langchain/aws@0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))))(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(axios@1.12.2)(handlebars@4.7.8)(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)): dependencies: - '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)) - '@langchain/openai': 0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)))(ws@8.18.3) - '@langchain/textsplitters': 0.1.0(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))) + '@langchain/core': 0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) + '@langchain/openai': 0.6.16(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)))(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@langchain/textsplitters': 0.1.0(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) js-tiktoken: 1.0.21 js-yaml: 4.1.0 jsonpointer: 5.0.1 - langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)) + langsmith: 0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)) openapi-types: 12.1.3 p-retry: 4.6.2 uuid: 10.0.0 yaml: 2.8.1 zod: 3.25.76 optionalDependencies: - '@langchain/aws': 0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76))) + '@langchain/aws': 0.1.15(@langchain/core@0.3.78(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76))) axios: 1.12.2(debug@4.4.3) handlebars: 4.7.8 transitivePeerDependencies: @@ -17836,7 +21228,7 @@ snapshots: - openai - ws - langsmith@0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3)(zod@3.25.76)): + langsmith@0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)): dependencies: '@types/uuid': 10.0.0 chalk: 4.1.2 @@ -17849,9 +21241,9 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/exporter-trace-otlp-proto': 0.203.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) - openai: 4.104.0(ws@8.18.3)(zod@3.25.76) + openai: 4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) - langsmith@0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3)(zod@3.25.76)): + langsmith@0.3.74(@opentelemetry/api@1.9.0)(@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0))(@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0))(openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76)): dependencies: '@types/uuid': 10.0.0 chalk: 4.1.2 @@ -17864,7 +21256,7 @@ snapshots: '@opentelemetry/api': 1.9.0 '@opentelemetry/exporter-trace-otlp-proto': 0.203.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) - openai: 5.12.2(ws@8.18.3)(zod@3.25.76) + openai: 5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76) language-subtag-registry@0.3.23: {} @@ -17949,6 +21341,22 @@ snapshots: dependencies: uc.micro: 2.1.0 + lit-element@4.2.1: + dependencies: + '@lit-labs/ssr-dom-shim': 1.4.0 + '@lit/reactive-element': 2.1.1 + lit-html: 3.3.1 + + lit-html@3.3.1: + dependencies: + '@types/trusted-types': 2.0.7 + + lit@3.3.0: + dependencies: + '@lit/reactive-element': 2.1.1 + lit-element: 4.2.1 + lit-html: 3.3.1 + load-tsconfig@0.2.5: {} local-pkg@1.1.2: @@ -17989,6 +21397,8 @@ snapshots: lodash.sortby@4.7.0: {} + lodash@4.17.21: {} + log-symbols@5.1.0: dependencies: chalk: 5.2.0 @@ -18324,6 +21734,8 @@ snapshots: methods@1.1.2: {} + micro-ftch@0.3.1: {} + micromark-core-commonmark@1.1.0: dependencies: decode-named-character-reference: 1.2.0 @@ -18750,6 +22162,13 @@ snapshots: mime@1.6.0: {} + mimetext@3.0.27: + dependencies: + '@babel/runtime': 7.28.4 + '@babel/runtime-corejs3': 7.28.4 + js-base64: 3.7.8 + mime-types: 2.1.35 + mimic-fn@2.1.0: {} mimic-fn@4.0.0: {} @@ -18770,6 +22189,10 @@ snapshots: dependencies: minipass: 7.1.2 + mipd@0.0.7(typescript@5.9.3): + optionalDependencies: + typescript: 5.9.3 + mlly@1.8.0: dependencies: acorn: 8.15.0 @@ -18796,6 +22219,8 @@ snapshots: ms@2.1.3: {} + multiformats@9.9.0: {} + mustache@4.2.0: {} mute-stream@2.0.0: {} @@ -18808,6 +22233,8 @@ snapshots: nanoid@3.3.11: {} + nanoid@5.1.6: {} + napi-postinstall@0.3.4: {} natural-compare@1.4.0: {} @@ -18865,6 +22292,8 @@ snapshots: abort-controller-x: 0.4.3 nice-grpc-common: 2.0.2 + node-addon-api@2.0.2: {} + node-domexception@1.0.0: {} node-fetch-native@1.6.7: {} @@ -18881,8 +22310,12 @@ snapshots: node-forge@1.3.1: {} + node-gyp-build@4.8.4: {} + node-int64@0.4.0: {} + node-mock-http@1.0.3: {} + node-releases@2.0.23: {} normalize-path@3.0.0: {} @@ -18908,6 +22341,12 @@ snapshots: pkg-types: 2.3.0 tinyexec: 1.0.1 + obj-multiplex@1.0.0: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + readable-stream: 2.3.8 + object-assign@4.1.1: {} object-inspect@1.13.4: {} @@ -18952,6 +22391,14 @@ snapshots: obliterator@1.6.1: {} + ofetch@1.4.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.1 + + on-exit-leak-free@0.2.0: {} + on-exit-leak-free@2.1.2: {} on-finished@2.4.1: @@ -18977,7 +22424,7 @@ snapshots: is-inside-container: 1.0.0 wsl-utils: 0.1.0 - openai@4.104.0(ws@8.18.3)(zod@3.25.76): + openai@4.104.0(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): dependencies: '@types/node': 18.19.130 '@types/node-fetch': 2.6.13 @@ -18987,18 +22434,24 @@ snapshots: formdata-node: 4.4.1 node-fetch: 2.7.0 optionalDependencies: - ws: 8.18.3 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) zod: 3.25.76 transitivePeerDependencies: - encoding - openai@5.12.2(ws@8.18.3)(zod@3.25.76): + openai@5.12.2(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))(zod@3.25.76): optionalDependencies: - ws: 8.18.3 + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) zod: 3.25.76 + openapi-fetch@0.13.8: + dependencies: + openapi-typescript-helpers: 0.0.15 + openapi-types@12.1.3: {} + openapi-typescript-helpers@0.0.15: {} + optionator@0.9.4: dependencies: deep-is: 0.1.4 @@ -19028,6 +22481,79 @@ snapshots: object-keys: 1.1.1 safe-push-apply: 1.0.0 + ox@0.6.7(typescript@5.9.3)(zod@3.25.76): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.1(typescript@5.9.3)(zod@3.25.76) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + ox@0.6.9(typescript@5.9.3)(zod@3.25.76): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/curves': 1.9.7 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.1(typescript@5.9.3)(zod@3.25.76) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + ox@0.9.11(typescript@5.9.3)(zod@4.1.12): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.1(typescript@5.9.3)(zod@4.1.12) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + ox@0.9.6(typescript@5.9.3)(zod@3.22.4): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.1(typescript@5.9.3)(zod@3.22.4) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + ox@0.9.6(typescript@5.9.3)(zod@3.25.76): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.1(typescript@5.9.3)(zod@3.25.76) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + p-finally@1.0.0: {} p-limit@2.3.0: @@ -19106,6 +22632,15 @@ snapshots: partial-json@0.1.7: {} + partyserver@0.0.74(@cloudflare/workers-types@4.20251011.0): + dependencies: + '@cloudflare/workers-types': 4.20251011.0 + nanoid: 5.1.6 + + partysocket@1.1.5: + dependencies: + event-target-polyfill: 0.0.4 + path-exists@4.0.0: {} path-is-absolute@1.0.1: {} @@ -19170,6 +22705,15 @@ snapshots: picomatch@4.0.3: {} + pify@3.0.0: {} + + pify@5.0.0: {} + + pino-abstract-transport@0.5.0: + dependencies: + duplexify: 4.1.3 + split2: 4.2.0 + pino-abstract-transport@2.0.0: dependencies: split2: 4.2.0 @@ -19207,8 +22751,24 @@ snapshots: sonic-boom: 4.2.0 strip-json-comments: 5.0.3 + pino-std-serializers@4.0.0: {} + pino-std-serializers@7.0.0: {} + pino@7.11.0: + dependencies: + atomic-sleep: 1.0.0 + fast-redact: 3.5.0 + on-exit-leak-free: 0.2.0 + pino-abstract-transport: 0.5.0 + pino-std-serializers: 4.0.0 + process-warning: 1.0.0 + quick-format-unescaped: 4.0.4 + real-require: 0.1.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 2.8.0 + thread-stream: 0.15.2 + pino@9.13.1: dependencies: atomic-sleep: 1.0.0 @@ -19251,6 +22811,30 @@ snapshots: optionalDependencies: fsevents: 2.3.2 + pngjs@5.0.0: {} + + pony-cause@2.1.11: {} + + porto@0.2.19(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.3)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.1(@tanstack/query-core@5.90.3)(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76)): + dependencies: + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.3)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + hono: 4.9.12 + idb-keyval: 6.2.2 + mipd: 0.0.7(typescript@5.9.3) + ox: 0.9.11(typescript@5.9.3)(zod@4.1.12) + viem: 2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + zod: 4.1.12 + zustand: 5.0.8(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)) + optionalDependencies: + '@tanstack/react-query': 5.90.3(react@19.2.0) + react: 19.2.0 + typescript: 5.9.3 + wagmi: 2.18.1(@tanstack/query-core@5.90.3)(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + transitivePeerDependencies: + - '@types/react' + - immer + - use-sync-external-store + possible-typed-array-names@1.1.0: {} postcss-load-config@6.0.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(yaml@2.8.1): @@ -19297,6 +22881,10 @@ snapshots: transitivePeerDependencies: - debug + preact@10.24.2: {} + + preact@10.27.2: {} + prelude-ls@1.2.1: {} prettier@3.6.2: {} @@ -19315,6 +22903,10 @@ snapshots: prismjs@1.30.0: {} + process-nextick-args@2.0.1: {} + + process-warning@1.0.0: {} + process-warning@5.0.0: {} process@0.11.10: {} @@ -19463,6 +23055,8 @@ snapshots: forwarded: 0.2.0 ipaddr.js: 1.9.1 + proxy-compare@2.6.0: {} + proxy-from-env@1.1.0: {} psl@1.15.0: @@ -19480,6 +23074,13 @@ snapshots: pure-rand@6.1.0: {} + qrcode@1.5.3: + dependencies: + dijkstrajs: 1.0.3 + encode-utf8: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 + qs@6.13.0: dependencies: side-channel: 1.1.0 @@ -19490,6 +23091,13 @@ snapshots: quansync@0.2.11: {} + query-string@7.1.3: + dependencies: + decode-uri-component: 0.2.2 + filter-obj: 1.1.0 + split-on-first: 1.1.0 + strict-uri-encode: 2.0.0 + querystringify@2.2.0: {} queue-microtask@1.2.3: {} @@ -19498,6 +23106,8 @@ snapshots: radash@12.1.1: {} + radix3@1.1.2: {} + range-parser@1.2.1: {} raw-body@2.5.2: @@ -19602,6 +23212,16 @@ snapshots: react@19.2.0: {} + readable-stream@2.3.8: + dependencies: + core-util-is: 1.0.3 + inherits: 2.0.4 + isarray: 1.0.0 + process-nextick-args: 2.0.1 + safe-buffer: 5.1.2 + string_decoder: 1.1.1 + util-deprecate: 1.0.2 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -19622,6 +23242,8 @@ snapshots: readdirp@4.1.2: {} + real-require@0.1.0: {} + real-require@0.2.0: {} recma-build-jsx@1.0.0: @@ -19778,6 +23400,8 @@ snapshots: transitivePeerDependencies: - supports-color + require-main-filename@2.0.0: {} + requires-port@1.0.0: {} resolve-cwd@3.0.0: @@ -19927,6 +23551,8 @@ snapshots: has-symbols: 1.1.0 isarray: 2.0.5 + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} safe-push-apply@1.0.0: @@ -20006,6 +23632,8 @@ snapshots: transitivePeerDependencies: - supports-color + set-blocking@2.0.0: {} + set-function-length@1.2.2: dependencies: define-data-property: 1.1.4 @@ -20030,6 +23658,12 @@ snapshots: setprototypeof@1.2.0: {} + sha.js@2.4.12: + dependencies: + inherits: 2.0.4 + safe-buffer: 5.2.1 + to-buffer: 1.2.2 + sharp@0.33.5: dependencies: color: 4.2.3 @@ -20112,6 +23746,28 @@ snapshots: slow-redact@0.3.2: {} + socket.io-client@4.8.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.4 + engine.io-client: 6.6.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + socket.io-parser: 4.2.4 + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + socket.io-parser@4.2.4: + dependencies: + '@socket.io/component-emitter': 3.1.2 + debug: 4.3.4 + transitivePeerDependencies: + - supports-color + + sonic-boom@2.8.0: + dependencies: + atomic-sleep: 1.0.0 + sonic-boom@4.2.0: dependencies: atomic-sleep: 1.0.0 @@ -20135,6 +23791,8 @@ snapshots: space-separated-tokens@2.0.2: {} + split-on-first@1.1.0: {} + split2@4.2.0: {} sprintf-js@1.0.3: {} @@ -20160,8 +23818,12 @@ snapshots: es-errors: 1.3.0 internal-slot: 1.1.0 + stream-shift@1.0.3: {} + streamsearch@1.1.0: {} + strict-uri-encode@2.0.0: {} + string-length@4.0.2: dependencies: char-regex: 1.0.2 @@ -20229,6 +23891,10 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.1.1 + string_decoder@1.1.1: + dependencies: + safe-buffer: 5.1.2 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -20294,6 +23960,8 @@ snapshots: pirates: 4.0.7 ts-interface-checker: 0.1.13 + superstruct@1.0.4: {} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -20351,6 +24019,10 @@ snapshots: dependencies: any-promise: 1.3.0 + thread-stream@0.15.2: + dependencies: + real-require: 0.1.0 + thread-stream@3.1.0: dependencies: real-require: 0.2.0 @@ -20372,6 +24044,12 @@ snapshots: tmpl@1.0.5: {} + to-buffer@1.2.2: + dependencies: + isarray: 2.0.5 + safe-buffer: 5.2.1 + typed-array-buffer: 1.0.3 + to-regex-range@5.0.1: dependencies: is-number: 7.0.0 @@ -20452,6 +24130,8 @@ snapshots: minimist: 1.2.8 strip-bom: 3.0.0 + tslib@1.14.1: {} + tslib@2.8.1: {} tsup@8.5.0(jiti@2.6.1)(postcss@8.5.6)(tsx@4.20.6)(typescript@5.9.3)(yaml@2.8.1): @@ -20598,6 +24278,10 @@ snapshots: uglify-js@3.19.3: optional: true + uint8arrays@3.1.0: + dependencies: + multiformats: 9.9.0 + unbox-primitive@1.1.0: dependencies: call-bound: 1.0.4 @@ -20611,6 +24295,8 @@ snapshots: undici-types@6.21.0: {} + undici-types@7.16.0: {} + unicorn-magic@0.3.0: {} unified@10.1.2: @@ -20725,6 +24411,20 @@ snapshots: '@unrs/resolver-binding-win32-ia32-msvc': 1.11.1 '@unrs/resolver-binding-win32-x64-msvc': 1.11.1 + unstorage@1.17.1(@upstash/redis@1.35.6)(idb-keyval@6.2.2): + dependencies: + anymatch: 3.1.3 + chokidar: 4.0.3 + destr: 2.0.5 + h3: 1.15.4 + lru-cache: 10.4.3 + node-fetch-native: 1.6.7 + ofetch: 1.4.1 + ufo: 1.6.1 + optionalDependencies: + '@upstash/redis': 1.35.6 + idb-keyval: 6.2.2 + untruncate-json@0.0.1: {} update-browserslist-db@1.1.3(browserslist@4.26.3): @@ -20765,18 +24465,40 @@ snapshots: optionalDependencies: '@types/react': 19.2.2 + use-sync-external-store@1.2.0(react@19.2.0): + dependencies: + react: 19.2.0 + + use-sync-external-store@1.4.0(react@19.2.0): + dependencies: + react: 19.2.0 + use-sync-external-store@1.6.0(react@19.2.0): dependencies: react: 19.2.0 + utf-8-validate@5.0.10: + dependencies: + node-gyp-build: 4.8.4 + util-deprecate@1.0.2: {} + util@0.12.5: + dependencies: + inherits: 2.0.4 + is-arguments: 1.2.0 + is-generator-function: 1.1.2 + is-typed-array: 1.1.15 + which-typed-array: 1.1.19 + utils-merge@1.0.1: {} uuid@10.0.0: {} uuid@11.1.0: {} + uuid@8.3.2: {} + uuid@9.0.1: {} uvu@0.5.6: @@ -20794,6 +24516,15 @@ snapshots: validator@13.15.15: {} + valtio@1.13.2(@types/react@19.2.2)(react@19.2.0): + dependencies: + derive-valtio: 0.1.0(valtio@1.13.2(@types/react@19.2.2)(react@19.2.0)) + proxy-compare: 2.6.0 + use-sync-external-store: 1.2.0(react@19.2.0) + optionalDependencies: + '@types/react': 19.2.2 + react: 19.2.0 + vary@1.1.2: {} vfile-location@5.0.3: @@ -20823,8 +24554,98 @@ snapshots: '@types/unist': 3.0.3 vfile-message: 4.0.3 + viem@2.23.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): + dependencies: + '@noble/curves': 1.8.1 + '@noble/hashes': 1.7.1 + '@scure/bip32': 1.6.2 + '@scure/bip39': 1.5.4 + abitype: 1.0.8(typescript@5.9.3)(zod@3.25.76) + isows: 1.0.6(ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.6.7(typescript@5.9.3)(zod@3.25.76) + ws: 8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.22.4): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.0(typescript@5.9.3)(zod@3.22.4) + isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.9.6(typescript@5.9.3)(zod@3.22.4) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76): + dependencies: + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.1.0(typescript@5.9.3)(zod@3.25.76) + isows: 1.0.7(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + ox: 0.9.6(typescript@5.9.3)(zod@3.25.76) + ws: 8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + w3c-keyname@2.2.8: {} + wagmi@2.18.1(@tanstack/query-core@5.90.3)(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76): + dependencies: + '@tanstack/react-query': 5.90.3(react@19.2.0) + '@wagmi/connectors': 6.0.1(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@upstash/redis@1.35.6)(@wagmi/core@2.22.1(@tanstack/query-core@5.90.3)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)))(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(utf-8-validate@5.0.10)(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(wagmi@2.18.1(@tanstack/query-core@5.90.3)(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76))(zod@3.25.76) + '@wagmi/core': 2.22.1(@tanstack/query-core@5.90.3)(@types/react@19.2.2)(react@19.2.0)(typescript@5.9.3)(use-sync-external-store@1.4.0(react@19.2.0))(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76)) + react: 19.2.0 + use-sync-external-store: 1.4.0(react@19.2.0) + viem: 2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@tanstack/query-core' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - immer + - ioredis + - supports-color + - uploadthing + - utf-8-validate + - zod + wait-port@1.1.0: dependencies: chalk: 4.1.2 @@ -20860,6 +24681,8 @@ snapshots: web-streams-polyfill@4.0.0-beta.3: {} + webextension-polyfill@0.10.0: {} + webidl-conversions@3.0.1: {} webidl-conversions@4.0.2: {} @@ -20906,6 +24729,8 @@ snapshots: is-weakmap: 2.0.2 is-weakset: 2.0.4 + which-module@2.0.1: {} + which-typed-array@1.1.19: dependencies: available-typed-arrays: 1.0.7 @@ -20951,18 +24776,85 @@ snapshots: imurmurhash: 0.1.4 signal-exit: 3.0.7 - ws@8.18.3: {} + ws@7.5.10(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.17.1(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.18.0(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 + + ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10): + optionalDependencies: + bufferutil: 4.0.9 + utf-8-validate: 5.0.10 wsl-utils@0.1.0: dependencies: is-wsl: 3.1.0 + x402@0.6.6(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3))(@tanstack/query-core@5.90.3)(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(fastestsmallesttextencoderdecoder@1.0.22)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)): + dependencies: + '@scure/base': 1.2.6 + '@solana-program/compute-budget': 0.8.0(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana-program/token': 0.5.1(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10))) + '@solana-program/token-2022': 0.4.2(@solana/kit@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)))(@solana/sysvars@2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)) + '@solana/kit': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + '@solana/transaction-confirmation': 2.3.0(fastestsmallesttextencoderdecoder@1.0.22)(typescript@5.9.3)(ws@8.18.3(bufferutil@4.0.9)(utf-8-validate@5.0.10)) + viem: 2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76) + wagmi: 2.18.1(@tanstack/query-core@5.90.3)(@tanstack/react-query@5.90.3(react@19.2.0))(@types/react@19.2.2)(@upstash/redis@1.35.6)(bufferutil@4.0.9)(react@19.2.0)(typescript@5.9.3)(utf-8-validate@5.0.10)(viem@2.38.2(bufferutil@4.0.9)(typescript@5.9.3)(utf-8-validate@5.0.10)(zod@3.25.76))(zod@3.25.76) + zod: 3.25.76 + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@react-native-async-storage/async-storage' + - '@solana/sysvars' + - '@tanstack/query-core' + - '@tanstack/react-query' + - '@types/react' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - aws4fetch + - bufferutil + - db0 + - encoding + - fastestsmallesttextencoderdecoder + - immer + - ioredis + - react + - supports-color + - typescript + - uploadthing + - utf-8-validate + - ws + + xmlhttprequest-ssl@2.1.2: {} + xstate@5.23.0: {} xtend@4.0.2: {} xxhash-wasm@1.1.0: {} + y18n@4.0.3: {} + y18n@5.0.8: {} yallist@3.1.1: {} @@ -20973,8 +24865,27 @@ snapshots: yaml@2.8.1: {} + yargs-parser@18.1.3: + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + yargs-parser@21.1.1: {} + yargs@15.4.1: + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + yargs@17.7.2: dependencies: cliui: 8.0.1 @@ -21007,8 +24918,28 @@ snapshots: dependencies: zod: 3.25.76 + zod@3.22.4: {} + zod@3.25.76: {} zod@4.1.12: {} + zustand@5.0.0(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)): + optionalDependencies: + '@types/react': 19.2.2 + react: 19.2.0 + use-sync-external-store: 1.4.0(react@19.2.0) + + zustand@5.0.3(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)): + optionalDependencies: + '@types/react': 19.2.2 + react: 19.2.0 + use-sync-external-store: 1.4.0(react@19.2.0) + + zustand@5.0.8(@types/react@19.2.2)(react@19.2.0)(use-sync-external-store@1.4.0(react@19.2.0)): + optionalDependencies: + '@types/react': 19.2.2 + react: 19.2.0 + use-sync-external-store: 1.4.0(react@19.2.0) + zwitch@2.0.4: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 512b27006..011360fa5 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -5,3 +5,4 @@ packages: - "integrations/*/typescript" - "integrations/community/*/typescript" - "integrations/mastra/typescript/examples" + - "integrations/*/typescript/examples"