├── .github ├── CODEOWNERS └── workflows │ ├── check-generated-files.yml │ ├── dojo-e2e.yml │ └── test.yml ├── .gitignore ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docs ├── .gitignore ├── .prettierignore ├── .prettierrc ├── LICENSE ├── README.md ├── concepts │ ├── agents.mdx │ ├── architecture.mdx │ ├── events.mdx │ ├── messages.mdx │ ├── state.mdx │ └── tools.mdx ├── development │ ├── contributing.mdx │ ├── roadmap.mdx │ └── updates.mdx ├── docs.json ├── favicon.svg ├── integrations.mdx ├── introduction.mdx ├── logo │ ├── dark.png │ ├── dark.svg │ ├── light.png │ └── light.svg ├── package.json ├── pnpm-lock.yaml ├── quickstart │ ├── applications.mdx │ ├── clients.mdx │ ├── introduction.mdx │ ├── middleware.mdx │ └── server.mdx ├── sdk │ ├── js │ │ ├── client │ │ │ ├── abstract-agent.mdx │ │ │ ├── http-agent.mdx │ │ │ ├── overview.mdx │ │ │ └── subscriber.mdx │ │ ├── core │ │ │ ├── events.mdx │ │ │ ├── overview.mdx │ │ │ └── types.mdx │ │ ├── encoder.mdx │ │ ├── overview.mdx │ │ └── proto.mdx │ └── python │ │ ├── core │ │ ├── events.mdx │ │ ├── overview.mdx │ │ └── types.mdx │ │ └── encoder │ │ └── overview.mdx ├── snippets │ └── snippet-intro.mdx └── tutorials │ ├── cursor.mdx │ └── debugging.mdx ├── python-sdk ├── .gitignore ├── LICENSE ├── README.md ├── ag_ui │ ├── core │ │ ├── __init__.py │ │ ├── events.py │ │ └── types.py │ ├── encoder │ │ ├── __init__.py │ │ └── encoder.py │ └── py.typed ├── poetry.lock ├── pyproject.toml └── tests │ ├── __init__.py │ ├── test_encoder.py │ ├── test_events.py │ └── test_types.py └── typescript-sdk ├── .cursor └── rules │ └── project-rules.mdc ├── .gitignore ├── .npmrc ├── .prettierrc ├── .vscode ├── cspell.json └── settings.json ├── LICENSE ├── README.md ├── apps ├── client-cli-example │ ├── .gitignore │ ├── README.md │ ├── package.json │ ├── src │ │ ├── agent.ts │ │ ├── index.ts │ │ └── tools │ │ │ ├── browser.tool.ts │ │ │ └── weather.tool.ts │ └── tsconfig.json └── dojo │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── e2e │ ├── .gitignore │ ├── README.md │ ├── VIDEO_SETUP.md │ ├── clean-reporter.js │ ├── lib │ │ └── upload-video.ts │ ├── package-lock.json │ ├── package.json │ ├── pages │ │ ├── agnoPages │ │ │ ├── AgenticChatPage.ts │ │ │ └── ToolBaseGenUIPage.ts │ │ ├── crewAIPages │ │ │ ├── AgenticChatPage.ts │ │ │ ├── AgenticUIGenPage.ts │ │ │ ├── HumanInLoopPage.ts │ │ │ ├── PredictiveStateUpdatesPage.ts │ │ │ ├── SharedStatePage.ts │ │ │ └── ToolBaseGenUIPage.ts │ │ ├── langGraphFastAPIPages │ │ │ ├── AgenticChatPage.ts │ │ │ ├── AgenticUIGenPage.ts │ │ │ ├── HumanInLoopPage.ts │ │ │ ├── PredictiveStateUpdatesPage.ts │ │ │ ├── SharedStatePage.ts │ │ │ └── ToolBaseGenUIPage.ts │ │ ├── langGraphPages │ │ │ ├── AgenticChatPage.ts │ │ │ ├── AgenticUIGenPage.ts │ │ │ ├── HumanInLoopPage.ts │ │ │ ├── PredictiveStateUpdatesPage.ts │ │ │ ├── SharedStatePage.ts │ │ │ └── ToolBaseGenUIPage.ts │ │ ├── llamaIndexPages │ │ │ ├── AgenticChatPage.ts │ │ │ ├── AgenticUIGenPage.ts │ │ │ ├── HumanInLoopPage.ts │ │ │ └── SharedStatePage.ts │ │ ├── mastraAgentLocalPages │ │ │ ├── AgenticChatPage.ts │ │ │ ├── SharedStatePage.ts │ │ │ └── ToolBaseGenUIPage.ts │ │ ├── mastraPages │ │ │ ├── AgenticChatPage.ts │ │ │ └── ToolBaseGenUIPage.ts │ │ ├── middlewareStarterPages │ │ │ └── AgenticChatPage.ts │ │ ├── pydanticAIPages │ │ │ ├── AgenticChatPage.ts │ │ │ ├── AgenticUIGenPage.ts │ │ │ ├── HumanInLoopPage.ts │ │ │ ├── PredictiveStateUpdatesPage.ts │ │ │ ├── SharedStatePage.ts │ │ │ └── ToolBaseGenUIPage.ts │ │ ├── serverStarterAllFeaturesPages │ │ │ ├── AgenticChatPage.ts │ │ │ ├── AgenticUIGenPage.ts │ │ │ ├── HumanInLoopPage.ts │ │ │ ├── PredictiveStateUpdatesPage.ts │ │ │ ├── SharedStatePage.ts │ │ │ └── ToolBaseGenUIPage.ts │ │ ├── serverStarterPages │ │ │ └── AgenticChatPage.ts │ │ └── vercelAISdkPages │ │ │ └── AgenticChatPage.ts │ ├── playwright.config.ts │ ├── pnpm-lock.yaml │ ├── pnpm-workspace.yaml │ ├── reporters │ │ └── s3-video-reporter.ts │ ├── setup-aws.sh │ ├── slack-layout-simple.ts │ ├── slack-layout.ts │ ├── test-isolation-helper.ts │ ├── test-isolation-setup.ts │ ├── tests │ │ ├── agnoTests │ │ │ ├── agenticChatPage.spec.ts │ │ │ └── toolBasedGenUIPage.spec.ts │ │ ├── copilotkit-home.spec.ts │ │ ├── crewAITests │ │ │ ├── agenticChatPage.spec.ts │ │ │ ├── agenticGenUI.spec.ts │ │ │ ├── humanInTheLoopPage.spec.ts │ │ │ ├── predictvieStateUpdatePage.spec.ts │ │ │ ├── sharedStatePage.spec.ts │ │ │ └── toolBasedGenUIPage.spec.ts │ │ ├── integration │ │ │ └── ai-features.spec.ts │ │ ├── langgraphFastAPITests │ │ │ ├── agenticChatPage.spec.ts │ │ │ ├── agenticGenUI.spec.ts │ │ │ ├── humanInTheLoopPage.spec.ts │ │ │ ├── predictvieStateUpdatePage.spec.ts │ │ │ ├── sharedStatePage.spec.ts │ │ │ └── toolBasedGenUIPage.spec.ts │ │ ├── langgraphTests │ │ │ ├── agenticChatPage.spec.ts │ │ │ ├── agenticGenUI.spec.ts │ │ │ ├── humanInTheLoopPage.spec.ts │ │ │ ├── predictvieStateUpdatePage.spec.ts │ │ │ ├── sharedStatePage.spec.ts │ │ │ └── toolBasedGenUIPage.spec.ts │ │ ├── llamaIndexTests │ │ │ ├── agenticChatPage.spec.ts │ │ │ ├── agenticGenUI.spec.ts │ │ │ ├── humanInTheLoopPage.spec.ts │ │ │ └── sharedStatePage.spec.ts │ │ ├── mastraAgentLocalTests │ │ │ ├── agenticChatPage.spec.ts │ │ │ ├── sharedStatePage.spec.ts │ │ │ └── toolBasedGenUIPage.spec.ts │ │ ├── mastraTests │ │ │ ├── agenticChatPage.spec.ts │ │ │ └── toolBasedGenUIPage.spec.ts │ │ ├── middlewareStarterTests │ │ │ └── agenticChatPage.spec.ts │ │ ├── pydanticAITests │ │ │ ├── agenticChatPage.spec.ts │ │ │ ├── agenticGenUI.spec.ts │ │ │ ├── humanInTheLoopPage.spec.ts │ │ │ ├── predictvieStateUpdatePage.spec.ts │ │ │ ├── sharedStatePage.spec.ts │ │ │ └── toolBasedGenUIPage.spec.ts │ │ ├── serverStarterAllFeaturesTests │ │ │ ├── agenticChatPage.spec.ts │ │ │ ├── agenticGenUI.spec.ts │ │ │ ├── humanInTheLoopPage.spec.ts │ │ │ ├── predictvieStateUpdatePage.spec.ts │ │ │ ├── sharedStatePage.spec.ts │ │ │ └── toolBasedGenUIPage.spec.ts │ │ ├── serverStarterTests │ │ │ └── agenticChatPage.spec.ts │ │ ├── smoke-only │ │ │ └── basic-loading.spec.ts │ │ └── vercelAISdkTests │ │ │ └── agenticChatPage.spec.ts │ └── utils │ │ └── aiWaitHelpers.ts │ ├── e2e2 │ ├── .gitignore │ ├── package.json │ ├── playwright.config.ts │ ├── pnpm-lock.yaml │ ├── pnpm-workspace.yaml │ └── tests │ │ ├── agno-agentic-chat.spec.ts │ │ ├── crewai-agentic-chat.spec.ts │ │ ├── langgraph-agentic-chat.spec.ts │ │ ├── langgraph-fastapi-agentic-chat.spec.ts │ │ ├── langgraph-typescript-agentic-chat.spec.ts │ │ ├── llama-index-agentic-chat.spec.ts │ │ ├── mastra-agentic-chat.spec.ts │ │ ├── pydantic-agentic-chat.spec.ts │ │ └── vercel-ai-sdk-agentic-chat.spec.ts │ ├── eslint.config.mjs │ ├── next.config.ts │ ├── package.json │ ├── postcss.config.mjs │ ├── public │ ├── images │ │ ├── Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg │ │ ├── Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg │ │ ├── Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg │ │ ├── Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg │ │ ├── Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg │ │ ├── Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg │ │ ├── Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg │ │ ├── Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg │ │ ├── Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg │ │ └── Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg │ ├── logo_dark.webp │ ├── logo_light.webp │ └── shared_state_background.png │ ├── scripts │ ├── generate-content-json.ts │ ├── link-cpk.js │ ├── prep-dojo-everything.js │ └── run-dojo-everything.js │ ├── src │ ├── agents.ts │ ├── app │ │ ├── [integrationId] │ │ │ ├── feature │ │ │ │ ├── agentic_chat │ │ │ │ │ ├── README.mdx │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── style.css │ │ │ │ ├── agentic_chat_reasoning │ │ │ │ │ ├── README.mdx │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── style.css │ │ │ │ ├── agentic_generative_ui │ │ │ │ │ ├── README.mdx │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── style.css │ │ │ │ ├── human_in_the_loop │ │ │ │ │ ├── README.mdx │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── style.css │ │ │ │ ├── layout.tsx │ │ │ │ ├── predictive_state_updates │ │ │ │ │ ├── README.mdx │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── style.css │ │ │ │ ├── shared_state │ │ │ │ │ ├── README.mdx │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── style.css │ │ │ │ └── tool_based_generative_ui │ │ │ │ │ ├── README.mdx │ │ │ │ │ ├── page.tsx │ │ │ │ │ └── style.css │ │ │ ├── not-found.tsx │ │ │ └── page.tsx │ │ ├── api │ │ │ └── copilotkit │ │ │ │ └── [integrationId] │ │ │ │ └── route.ts │ │ ├── globals.css │ │ ├── icon.png │ │ ├── layout.tsx │ │ └── page.tsx │ ├── components │ │ ├── code-viewer │ │ │ ├── code-editor.tsx │ │ │ └── code-viewer.tsx │ │ ├── demo-list │ │ │ └── demo-list.tsx │ │ ├── file-tree │ │ │ ├── file-tree-nav.tsx │ │ │ └── file-tree.tsx │ │ ├── layout │ │ │ ├── main-layout.tsx │ │ │ └── viewer-layout.tsx │ │ ├── readme │ │ │ └── readme.tsx │ │ ├── sidebar │ │ │ └── sidebar.tsx │ │ ├── theme-provider.tsx │ │ └── ui │ │ │ ├── badge.tsx │ │ │ ├── button.tsx │ │ │ ├── dropdown-menu.tsx │ │ │ ├── markdown-components.tsx │ │ │ ├── mdx-components.tsx │ │ │ ├── tabs.tsx │ │ │ └── theme-toggle.tsx │ ├── config.ts │ ├── contexts │ │ └── url-params-context.tsx │ ├── env.ts │ ├── files.json │ ├── lib │ │ └── utils.ts │ ├── mastra │ │ └── index.ts │ ├── menu.ts │ ├── styles │ │ └── typography.css │ ├── types │ │ ├── feature.ts │ │ ├── integration.ts │ │ └── interface.ts │ └── utils │ │ ├── domain-config.ts │ │ ├── mdx-utils.tsx │ │ ├── use-mobile-chat.ts │ │ └── use-mobile-view.ts │ ├── tailwind.config.ts │ └── tsconfig.json ├── integrations ├── agno │ ├── .npmignore │ ├── README.md │ ├── examples │ │ ├── .gitignore │ │ ├── README.md │ │ ├── pyproject.toml │ │ ├── requirements.txt │ │ ├── server │ │ │ ├── __init__.py │ │ │ └── api │ │ │ │ ├── __init__.py │ │ │ │ ├── agentic_chat.py │ │ │ │ └── tool_based_generative_ui.py │ │ └── uv.lock │ ├── jest.config.js │ ├── package.json │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── crewai │ ├── .npmignore │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── python │ │ ├── .gitignore │ │ ├── README.md │ │ ├── ag_ui_crewai │ │ │ ├── __init__.py │ │ │ ├── context.py │ │ │ ├── crews.py │ │ │ ├── dojo.py │ │ │ ├── endpoint.py │ │ │ ├── enterprise.py │ │ │ ├── events.py │ │ │ ├── examples │ │ │ │ ├── __init__.py │ │ │ │ ├── agentic_chat.py │ │ │ │ ├── agentic_generative_ui.py │ │ │ │ ├── human_in_the_loop.py │ │ │ │ ├── predictive_state_updates.py │ │ │ │ ├── shared_state.py │ │ │ │ └── tool_based_generative_ui.py │ │ │ ├── sdk.py │ │ │ └── utils.py │ │ ├── poetry.lock │ │ ├── pyproject.toml │ │ └── tests │ │ │ └── __init__.py │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── langgraph │ ├── .npmignore │ ├── README.md │ ├── examples │ │ ├── .gitignore │ │ ├── python │ │ │ ├── .env.example │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── agents │ │ │ │ ├── __init__.py │ │ │ │ ├── agentic_chat │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── agent.py │ │ │ │ ├── agentic_chat_reasoning │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── agent.py │ │ │ │ ├── agentic_generative_ui │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── agent.py │ │ │ │ ├── dojo.py │ │ │ │ ├── human_in_the_loop │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── agent.py │ │ │ │ ├── predictive_state_updates │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── agent.py │ │ │ │ ├── shared_state │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── agent.py │ │ │ │ └── tool_based_generative_ui │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── agent.py │ │ │ ├── langgraph.json │ │ │ ├── poetry.lock │ │ │ └── pyproject.toml │ │ ├── typescript │ │ │ ├── .env.example │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── langgraph.json │ │ │ ├── package.json │ │ │ ├── pnpm-lock.yaml │ │ │ ├── pnpm-workspace.yaml │ │ │ ├── src │ │ │ │ └── agents │ │ │ │ │ ├── agentic_chat │ │ │ │ │ └── agent.ts │ │ │ │ │ ├── agentic_generative_ui │ │ │ │ │ └── agent.ts │ │ │ │ │ ├── human_in_the_loop │ │ │ │ │ └── agent.ts │ │ │ │ │ ├── predictive_state_updates │ │ │ │ │ └── agent.ts │ │ │ │ │ ├── shared_state │ │ │ │ │ └── agent.ts │ │ │ │ │ └── tool_based_generative_ui │ │ │ │ │ └── agent.ts │ │ │ └── tsconfig.json │ │ └── uv.lock │ ├── jest.config.js │ ├── package.json │ ├── python │ │ ├── .gitignore │ │ ├── README.md │ │ ├── ag_ui_langgraph │ │ │ ├── __init__.py │ │ │ ├── agent.py │ │ │ ├── endpoint.py │ │ │ ├── types.py │ │ │ └── utils.py │ │ ├── poetry.lock │ │ ├── pyproject.toml │ │ └── tests │ │ │ └── __init__.py │ ├── src │ │ ├── agent.ts │ │ ├── index.ts │ │ ├── types.ts │ │ └── utils.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── llamaindex │ ├── .gitignore │ ├── .npmignore │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── server-py │ │ ├── README.md │ │ ├── pyproject.toml │ │ ├── server │ │ │ ├── __init__.py │ │ │ └── routers │ │ │ │ ├── agentic_chat.py │ │ │ │ ├── agentic_generative_ui.py │ │ │ │ ├── human_in_the_loop.py │ │ │ │ └── shared_state.py │ │ └── uv.lock │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── mastra │ ├── .npmignore │ ├── README.md │ ├── example │ │ ├── .gitignore │ │ ├── package-lock.json │ │ ├── package.json │ │ ├── src │ │ │ └── mastra │ │ │ │ ├── agents │ │ │ │ ├── agentic-chat.ts │ │ │ │ └── tool-based-generative-ui.ts │ │ │ │ ├── index.ts │ │ │ │ └── tools │ │ │ │ └── weather-tool.ts │ │ └── tsconfig.json │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── index.ts │ │ ├── mastra.ts │ │ └── utils.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── middleware-starter │ ├── .npmignore │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── pydantic-ai │ ├── .npmignore │ ├── README.md │ ├── examples │ │ ├── .gitignore │ │ ├── README.md │ │ ├── pyproject.toml │ │ ├── server │ │ │ ├── __init__.py │ │ │ └── api │ │ │ │ ├── __init__.py │ │ │ │ ├── agentic_chat.py │ │ │ │ ├── agentic_generative_ui.py │ │ │ │ ├── human_in_the_loop.py │ │ │ │ ├── predictive_state_updates.py │ │ │ │ ├── shared_state.py │ │ │ │ └── tool_based_generative_ui.py │ │ └── uv.lock │ ├── jest.config.js │ ├── package.json │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── server-starter-all-features │ ├── .npmignore │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── server │ │ └── python │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── example_server │ │ │ ├── __init__.py │ │ │ ├── agentic_chat.py │ │ │ ├── agentic_generative_ui.py │ │ │ ├── human_in_the_loop.py │ │ │ ├── predictive_state_updates.py │ │ │ ├── shared_state.py │ │ │ └── tool_based_generative_ui.py │ │ │ ├── poetry.lock │ │ │ ├── pyproject.toml │ │ │ └── tests │ │ │ └── __init__.py │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── server-starter │ ├── .npmignore │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── server │ │ └── python │ │ │ ├── .gitignore │ │ │ ├── README.md │ │ │ ├── example_server │ │ │ └── __init__.py │ │ │ ├── poetry.lock │ │ │ ├── pyproject.toml │ │ │ └── tests │ │ │ └── __init__.py │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── tsup.config.ts └── vercel-ai-sdk │ ├── .npmignore │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── src │ └── index.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── package.json ├── packages ├── cli │ ├── .npmignore │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── src │ │ └── index.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── client │ ├── .npmignore │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── agent │ │ │ ├── __tests__ │ │ │ │ ├── agent-mutations.test.ts │ │ │ │ ├── agent-result.test.ts │ │ │ │ ├── http.test.ts │ │ │ │ ├── legacy-bridged.test.ts │ │ │ │ └── subscriber.test.ts │ │ │ ├── agent.ts │ │ │ ├── http.ts │ │ │ ├── index.ts │ │ │ ├── subscriber.ts │ │ │ └── types.ts │ │ ├── apply │ │ │ ├── __tests__ │ │ │ │ ├── default.state.test.ts │ │ │ │ ├── default.text-message.test.ts │ │ │ │ └── default.tool-calls.test.ts │ │ │ ├── default.ts │ │ │ └── index.ts │ │ ├── chunks │ │ │ ├── __tests__ │ │ │ │ └── transform.test.ts │ │ │ ├── index.ts │ │ │ └── transform.ts │ │ ├── index.ts │ │ ├── legacy │ │ │ ├── __tests__ │ │ │ │ ├── convert.predictive.test.ts │ │ │ │ ├── convert.state.test.ts │ │ │ │ └── convert.tool-calls.test.ts │ │ │ ├── convert.ts │ │ │ ├── index.ts │ │ │ └── types.ts │ │ ├── run │ │ │ ├── __tests__ │ │ │ │ └── http-request.test.ts │ │ │ ├── http-request.ts │ │ │ └── index.ts │ │ ├── transform │ │ │ ├── __tests__ │ │ │ │ ├── http.test.ts │ │ │ │ ├── proto.test.ts │ │ │ │ └── sse.test.ts │ │ │ ├── http.ts │ │ │ ├── index.ts │ │ │ ├── proto.ts │ │ │ └── sse.ts │ │ ├── utils.ts │ │ └── verify │ │ │ ├── __tests__ │ │ │ ├── verify.events.test.ts │ │ │ ├── verify.lifecycle.test.ts │ │ │ ├── verify.steps.test.ts │ │ │ ├── verify.text-messages.test.ts │ │ │ └── verify.tool-calls.test.ts │ │ │ ├── index.ts │ │ │ └── verify.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── core │ ├── .npmignore │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ └── index.test.ts │ │ ├── events.ts │ │ ├── index.ts │ │ └── types.ts │ ├── tsconfig.json │ └── tsup.config.ts ├── encoder │ ├── .npmignore │ ├── README.md │ ├── jest.config.js │ ├── package.json │ ├── src │ │ ├── __tests__ │ │ │ └── encoder.test.ts │ │ ├── encoder.ts │ │ ├── index.ts │ │ └── media-type.ts │ ├── tsconfig.json │ └── tsup.config.ts └── proto │ ├── .npmignore │ ├── README.md │ ├── __tests__ │ ├── message-events.test.ts │ ├── proto.test.ts │ ├── run-events.test.ts │ ├── state-events.test.ts │ ├── test-utils.ts │ └── tool-call-events.test.ts │ ├── jest.config.js │ ├── package.json │ ├── src │ ├── index.ts │ ├── proto.ts │ └── proto │ │ ├── events.proto │ │ ├── patch.proto │ │ └── types.proto │ ├── tsconfig.json │ └── tsup.config.ts ├── pnpm-lock.yaml ├── pnpm-workspace.yaml ├── tsconfig.json └── turbo.json /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @mme @ranst91 @ataibarkai @maxkorp @tylerslaton @NathanTarbert 2 | -------------------------------------------------------------------------------- /.github/workflows/check-generated-files.yml: -------------------------------------------------------------------------------- 1 | name: Check Generated Files 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | pull_request: 7 | branches: [main] 8 | 9 | jobs: 10 | check-files-json: 11 | name: Check files.json 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v4 16 | 17 | - name: Regenerate files.json 18 | working-directory: typescript-sdk/apps/dojo 19 | run: npm run generate-content-json 20 | 21 | - name: Check files.json 22 | working-directory: typescript-sdk/apps/dojo 23 | run: | 24 | if git diff --exit-code src/files.json > /dev/null; then 25 | echo "✅ No changes detected in dojo/src/files.json. Everything is up to date." 26 | else 27 | echo "❌ Detected changes in dojo/src/files.json." 28 | echo "" 29 | echo "Please run \`(p)npm run generate-content-json\` in the typescript-sdk/apps/dojo folder and commit the changes." 30 | echo "" 31 | echo "The detected diff was as follows:" 32 | echo "::group::Diff for dojo/src/files.json" 33 | git diff src/files.json 34 | echo "::endgroup::" 35 | exit 1 36 | fi 37 | 38 | 39 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .vscode/ 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Mintlify generated files 2 | .mintlify 3 | 4 | # Dependencies 5 | node_modules/ 6 | .pnpm-store/ 7 | .npm 8 | 9 | # Build output 10 | .next/ 11 | out/ 12 | build/ 13 | dist/ 14 | 15 | # Environment files 16 | .env 17 | .env.local 18 | .env.development.local 19 | .env.test.local 20 | .env.production.local 21 | 22 | # Logs 23 | logs 24 | *.log 25 | npm-debug.log* 26 | yarn-debug.log* 27 | yarn-error.log* 28 | 29 | # Editor directories and files 30 | .idea/ 31 | .vscode/ 32 | *.swp 33 | *.swo 34 | 35 | # OS generated files 36 | .DS_Store 37 | .DS_Store? 38 | ._* 39 | .Spotlight-V100 40 | .Trashes 41 | ehthumbs.db 42 | Thumbs.db 43 | 44 | # Cache 45 | .cache/ 46 | .turbo -------------------------------------------------------------------------------- /docs/.prettierignore: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /docs/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "singleQuote": false, 4 | "semi": true, 5 | "tabWidth": 2, 6 | "overrides": [ 7 | { 8 | "files": "*.mdx", 9 | "options": { 10 | "printWidth": 80, 11 | "proseWrap": "always", 12 | "semi": false, 13 | "singleQuote": false 14 | } 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /docs/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2025 Tawkit Inc. 2 | Copyright (c) 2025 Markus Ecker 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Agent User Interaction Protocol Documentation 2 | 3 | The official documentation for the [Agent User Interaction Protocol](https://ag-ui.com). 4 | 5 | ### Publishing Changes 6 | 7 | Changes will be deployed to production automatically after pushing to the default branch. 8 | -------------------------------------------------------------------------------- /docs/development/contributing.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Contributing 3 | description: How to participate in Agent User Interaction Protocol development 4 | --- 5 | 6 | # Naming conventions 7 | 8 | Add your package under `typescript-sdk/integrations/` with docs and tests. 9 | 10 | If your integration is work in progress, you can still add it to main branch. 11 | You can prefix it with `wip-`, i.e. 12 | (`typescript-sdk/integrations/wip-your-integration`) or if you're a third party 13 | contributor use the `community` prefix, i.e. 14 | (`typescript-sdk/integrations/community-your-integration`). 15 | 16 | For questions and discussions, please use 17 | [GitHub Discussions](https://github.com/orgs/ag-ui-protocol/discussions). 18 | -------------------------------------------------------------------------------- /docs/development/roadmap.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Roadmap 3 | description: Our plans for evolving Agent User Interaction Protocol 4 | --- 5 | 6 | The Agent User Interaction Protocol is rapidly evolving. This page outlines our 7 | current thinking on key priorities and future direction. 8 | 9 | 10 | The ideas presented here are not commitments—we may solve these challenges 11 | differently than described, or some may not materialize at all. This is also 12 | not an _exhaustive_ list; we may incorporate work that isn't mentioned here. 13 | 14 | 15 | ## Get Involved 16 | 17 | We welcome community participation in shaping AG-UI's future. Visit our 18 | [GitHub Discussions](https://github.com/orgs/ag-ui-protocol/discussions) to join 19 | the conversation and contribute your ideas. 20 | -------------------------------------------------------------------------------- /docs/development/updates.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "What's New" 3 | description: "The latest updates and improvements to AG-UI" 4 | --- 5 | 6 | 7 | - Initial release of the Agent User Interaction Protocol 8 | 9 | -------------------------------------------------------------------------------- /docs/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Group 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /docs/integrations.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: Integrations 3 | description: "A list of AG-UI integrations" 4 | --- 5 | 6 | This page showcases various Agent User Interaction Protocol (AG-UI) integrations 7 | that demonstrate the protocol's capabilities and versatility. 8 | 9 | ## Frontend Integrations 10 | 11 | - **[CopilotKit](https://copilotkit.ai)** - AI Copilots for your product. 12 | 13 | ## Agent Frameworks 14 | 15 | - **[Mastra](https://mastra.ai)** - The TypeScript Agent Framework 16 | - **[LangGraph](https://www.langchain.com/langgraph)** - Balance agent control 17 | with agency 18 | - **[CrewAI](https://crewai.com)** - Streamline workflows across industries with 19 | powerful AI agents. 20 | - **[AG2](https://ag2.ai)** - The Open-Source AgentOS 21 | - **[Agno](https://agno.com)** - A full-stack framework for building Multi-Agent Systems 22 | 23 | Visit our 24 | [GitHub Discussions](https://github.com/orgs/ag-ui-protocol/discussions) to 25 | engage with the AG-UI community. 26 | -------------------------------------------------------------------------------- /docs/logo/dark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/docs/logo/dark.png -------------------------------------------------------------------------------- /docs/logo/dark.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | dark 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | AG-UI Protocol 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/logo/light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/docs/logo/light.png -------------------------------------------------------------------------------- /docs/logo/light.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | light 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | AG-UI Protocol 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "scripts": { 4 | "dev": "mintlify dev --port=4000", 5 | "build": "mintlify --help" 6 | }, 7 | "dependencies": { 8 | "mintlify": "^4.0.459" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /docs/quickstart/applications.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Build applications" 3 | description: 4 | "Build agentic applications utilizing compatible event AG-UI event streams" 5 | --- 6 | 7 | # Introduction 8 | 9 | AG-UI provides a concise, event-driven protocol that lets any agent stream rich, 10 | structured output to any client. It can be used to connect any agentic system to 11 | any client. 12 | 13 | A client is defined as any system that can receieve, display, and respond to 14 | AG-UI events. For more information on existing clients and integrations, see 15 | the [integrations](/integrations) page. 16 | 17 | # Automatic Setup 18 | AG-UI provides a CLI tool to automatically create or scaffold a new application with any client and server. 19 | 20 | ```sh 21 | npx create-ag-ui-app@latest 22 | ``` 23 | 24 | 28 | 29 | -------------------------------------------------------------------------------- /docs/sdk/js/encoder.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "@ag-ui/encoder" 3 | description: "" 4 | --- 5 | -------------------------------------------------------------------------------- /docs/sdk/js/overview.mdx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/docs/sdk/js/overview.mdx -------------------------------------------------------------------------------- /docs/sdk/js/proto.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "@ag-ui/proto" 3 | description: "" 4 | --- 5 | -------------------------------------------------------------------------------- /docs/snippets/snippet-intro.mdx: -------------------------------------------------------------------------------- 1 | One of the core principles of software development is DRY (Don't Repeat 2 | Yourself). This is a principle that apply to documentation as well. If you find 3 | yourself repeating the same content in multiple places, you should consider 4 | creating a custom snippet to keep your content in sync. 5 | -------------------------------------------------------------------------------- /docs/tutorials/cursor.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | title: "Developing with Cursor" 3 | description: "Use Cursor to build AG-UI implementations faster" 4 | --- 5 | 6 | This guide will help you set up Cursor to help you build custom Agent User 7 | Interaction Protocol (AG-UI) servers and clients faster. The same principles 8 | apply to other IDE's like Windsurf, VSCode, etc. 9 | 10 | ## Adding the documentation to Cursor 11 | 12 | 1. Open up the Cursor settings 13 | 2. Go to Features > Docs and click "+ Add new Doc" 14 | 3. Paste in the following URL: https://docs.ag-ui.com/llms-full.txt 15 | 4. Click "Add" 16 | 17 | ## Using the documentation 18 | 19 | Now you can use the documentation to help you build your AG-UI project. Load the 20 | docs into the current prompt by typing the `@` symbol, selecting "Docs" and then 21 | selecting "Agent User Interaction Protocol" from the list. Happy coding! 22 | 23 | ## Best practices 24 | 25 | When building AG-UI servers with Cursor: 26 | 27 | - Break down complex problems into smaller steps 28 | - Have a look at what the agent was doing by checking which files it edited 29 | (above the chat input) 30 | - Let the agent write unit tests to verify your implementation 31 | - Follow AG-UI protocol specifications carefully 32 | -------------------------------------------------------------------------------- /python-sdk/.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | MANIFEST 27 | 28 | # PyInstaller 29 | *.manifest 30 | *.spec 31 | 32 | # Installer logs 33 | pip-log.txt 34 | pip-delete-this-directory.txt 35 | 36 | # Unit test / coverage reports 37 | htmlcov/ 38 | .tox/ 39 | .nox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *.cover 46 | .hypothesis/ 47 | .pytest_cache/ 48 | 49 | # Environments 50 | .env 51 | .venv 52 | env/ 53 | venv/ 54 | ENV/ 55 | env.bak/ 56 | venv.bak/ 57 | 58 | # IDE specific files 59 | .idea/ 60 | .vscode/ 61 | *.swp 62 | *.swo 63 | 64 | # Project specific 65 | .DS_Store 66 | -------------------------------------------------------------------------------- /python-sdk/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2025 Tawkit Inc. 2 | Copyright (c) 2025 Markus Ecker 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /python-sdk/ag_ui/encoder/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module contains the EventEncoder class. 3 | """ 4 | 5 | from ag_ui.encoder.encoder import EventEncoder, AGUI_MEDIA_TYPE 6 | 7 | __all__ = ["EventEncoder", "AGUI_MEDIA_TYPE"] 8 | -------------------------------------------------------------------------------- /python-sdk/ag_ui/encoder/encoder.py: -------------------------------------------------------------------------------- 1 | """ 2 | This module contains the EventEncoder class 3 | """ 4 | 5 | from ag_ui.core.events import BaseEvent 6 | 7 | AGUI_MEDIA_TYPE = "application/vnd.ag-ui.event+proto" 8 | 9 | class EventEncoder: 10 | """ 11 | Encodes Agent User Interaction events. 12 | """ 13 | def __init__(self, accept: str = None): 14 | pass 15 | 16 | def get_content_type(self) -> str: 17 | """ 18 | Returns the content type of the encoder. 19 | """ 20 | return "text/event-stream" 21 | 22 | def encode(self, event: BaseEvent) -> str: 23 | """ 24 | Encodes an event. 25 | """ 26 | return self._encode_sse(event) 27 | 28 | def _encode_sse(self, event: BaseEvent) -> str: 29 | """ 30 | Encodes an event into an SSE string. 31 | """ 32 | return f"data: {event.model_dump_json(by_alias=True, exclude_none=True)}\n\n" 33 | -------------------------------------------------------------------------------- /python-sdk/ag_ui/py.typed: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/python-sdk/ag_ui/py.typed -------------------------------------------------------------------------------- /python-sdk/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "ag-ui-protocol" 3 | version = "0.1.8" 4 | description = "" 5 | authors = ["Markus Ecker "] 6 | readme = "README.md" 7 | packages = [{include = "ag_ui", from = "."}] 8 | [tool.poetry.dependencies] 9 | python = "^3.9" 10 | pydantic = "^2.11.2" 11 | 12 | 13 | [build-system] 14 | requires = ["poetry-core"] 15 | build-backend = "poetry.core.masonry.api" 16 | -------------------------------------------------------------------------------- /python-sdk/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/python-sdk/tests/__init__.py -------------------------------------------------------------------------------- /typescript-sdk/.cursor/rules/project-rules.mdc: -------------------------------------------------------------------------------- 1 | --- 2 | description: 3 | globs: 4 | alwaysApply: true 5 | --- 6 | # Project Overview 7 | 8 | This monorepo project utilizes: 9 | - Turborepo for build system orchestration 10 | - PNPM for package management 11 | - Jest for unit testing 12 | 13 | Test files are located in `__tests__` directories alongside their corresponding implementation files. 14 | 15 | Note: To run tests, navigate to the specific package directory and execute `pnpm run test` -------------------------------------------------------------------------------- /typescript-sdk/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # Dependencies 4 | node_modules 5 | .pnp 6 | .pnp.js 7 | 8 | # Local env files 9 | .env 10 | .env.local 11 | .env.development.local 12 | .env.test.local 13 | .env.production.local 14 | 15 | # Testing 16 | coverage 17 | 18 | # Turbo 19 | .turbo 20 | 21 | # Vercel 22 | .vercel 23 | 24 | # Build Outputs 25 | .next/ 26 | out/ 27 | build 28 | dist 29 | 30 | 31 | # Debug 32 | npm-debug.log* 33 | yarn-debug.log* 34 | yarn-error.log* 35 | 36 | # Misc 37 | .DS_Store 38 | *.pem 39 | 40 | # Generated files 41 | packages/proto/src/generated 42 | 43 | # LangGraph API 44 | **/**/.langgraph_api 45 | 46 | # Python 47 | __pycache__/ 48 | -------------------------------------------------------------------------------- /typescript-sdk/.npmrc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/.npmrc -------------------------------------------------------------------------------- /typescript-sdk/.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "printWidth": 100, 3 | "singleQuote": false, 4 | "semi": true, 5 | "tabWidth": 2, 6 | "overrides": [ 7 | { 8 | "files": "*.mdx", 9 | "options": { 10 | "printWidth": 80, 11 | "proseWrap": "always", 12 | "semi": false, 13 | "singleQuote": false 14 | } 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /typescript-sdk/.vscode/cspell.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2", 3 | "language": "en", 4 | "words": ["ag-ui", "uuidv4", "untruncate", "mastra", "agui", "agentic", "agno"], 5 | "ignorePaths": ["node_modules/**", "dist/**", "build/**", ".git/**", "coverage/**"], 6 | "allowCompoundWords": true, 7 | "ignoreRegExpList": ["\\([^)]*\\)", "`[^`]*`", "'[^']*'", "\"[^\"]*\""] 8 | } 9 | -------------------------------------------------------------------------------- /typescript-sdk/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "eslint.workingDirectories": [ 3 | { 4 | "mode": "auto" 5 | } 6 | ], 7 | "files.exclude": { 8 | "**/node_modules": true, 9 | "**/.turbo": true, 10 | "**/dist": true 11 | }, 12 | "search.exclude": { 13 | "**/node_modules": true, 14 | "**/.turbo": true, 15 | "**/dist": true 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /typescript-sdk/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2025 Tawkit Inc. 2 | Copyright (c) 2025 Markus Ecker 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /typescript-sdk/README.md: -------------------------------------------------------------------------------- 1 | # Agent User Interaction Protocol TypeScript SDK 2 | 3 | The TypeScript SDK for the [Agent User Interaction Protocol](https://ag-ui.com). 4 | 5 | For more information visit the [official documentation](https://docs.ag-ui.com/). 6 | -------------------------------------------------------------------------------- /typescript-sdk/apps/client-cli-example/.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | mastra.db* -------------------------------------------------------------------------------- /typescript-sdk/apps/client-cli-example/README.md: -------------------------------------------------------------------------------- 1 | # AG-UI CLI 2 | -------------------------------------------------------------------------------- /typescript-sdk/apps/client-cli-example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "client-cli-example", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "start": "tsx src/index.ts", 7 | "dev": "tsx --watch src/index.ts", 8 | "build": "tsc", 9 | "clean": "rm -rf dist" 10 | }, 11 | "dependencies": { 12 | "@ag-ui/client": "workspace:*", 13 | "@ag-ui/core": "workspace:*", 14 | "@ag-ui/mastra": "workspace:*", 15 | "@ai-sdk/openai": "1.3.22", 16 | "@mastra/client-js": "0.10.18", 17 | "@mastra/core": "0.12.1", 18 | "@mastra/libsql": "0.12.0", 19 | "@mastra/loggers": "0.10.5", 20 | "@mastra/memory": "0.12.0", 21 | "open": "^10.1.2", 22 | "zod": "^3.22.4" 23 | }, 24 | "devDependencies": { 25 | "@types/node": "^20", 26 | "tsx": "^4.7.0", 27 | "typescript": "^5" 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /typescript-sdk/apps/client-cli-example/src/agent.ts: -------------------------------------------------------------------------------- 1 | import { openai } from "@ai-sdk/openai"; 2 | import { Agent } from "@mastra/core/agent"; 3 | import { MastraAgent } from "@ag-ui/mastra"; 4 | import { Memory } from "@mastra/memory"; 5 | import { LibSQLStore } from "@mastra/libsql"; 6 | import { weatherTool } from "./tools/weather.tool"; 7 | import { browserTool } from "./tools/browser.tool"; 8 | 9 | export const agent = new MastraAgent({ 10 | // @ts-ignore 11 | agent: new Agent({ 12 | name: "AG-UI Agent", 13 | instructions: ` 14 | You are a helpful assistant that runs a CLI application. 15 | 16 | When helping users get weather details for specific locations, respond: 17 | - Always ask for a location if none is provided. 18 | - If the location name isn’t in English, please translate it 19 | - If giving a location with multiple parts (e.g. "New York, NY"), use the most relevant part (e.g. "New York") 20 | - Include relevant details like humidity, wind conditions, and precipitation 21 | - Keep responses concise but informative 22 | 23 | Use the weatherTool to fetch current weather data. 24 | 25 | When helping users browse the web, always use a full URL, for example: "https://www.google.com" 26 | Use the browserTool to browse the web. 27 | 28 | `, 29 | model: openai("gpt-4o-mini"), 30 | tools: { weatherTool, browserTool }, 31 | memory: new Memory({ 32 | storage: new LibSQLStore({ 33 | url: "file:./mastra.db", 34 | }), 35 | }), 36 | }), 37 | threadId: "1", 38 | }); 39 | -------------------------------------------------------------------------------- /typescript-sdk/apps/client-cli-example/src/tools/browser.tool.ts: -------------------------------------------------------------------------------- 1 | import { createTool } from "@mastra/core/tools"; 2 | import { z } from "zod"; 3 | import open from "open"; 4 | 5 | export const browserTool = createTool({ 6 | id: "browser", 7 | description: "Browse the web", 8 | inputSchema: z.object({ 9 | url: z.string().describe("URL to browse"), 10 | }), 11 | outputSchema: z.string(), 12 | execute: async ({ context }) => { 13 | open(context.url); 14 | return `Browsed ${context.url}`; 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /typescript-sdk/apps/client-cli-example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "commonjs", 5 | "lib": ["ES2020", "dom"], 6 | "outDir": "./dist", 7 | "rootDir": "./src", 8 | "strict": true, 9 | "esModuleInterop": true, 10 | "skipLibCheck": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "resolveJsonModule": true, 13 | "moduleResolution": "node" 14 | }, 15 | "include": ["src/**/*"], 16 | "exclude": ["node_modules", "dist"] 17 | } 18 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.* 7 | .yarn/* 8 | !.yarn/patches 9 | !.yarn/plugins 10 | !.yarn/releases 11 | !.yarn/versions 12 | 13 | # testing 14 | /coverage 15 | 16 | # next.js 17 | /.next/ 18 | /out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | 27 | # debug 28 | npm-debug.log* 29 | yarn-debug.log* 30 | yarn-error.log* 31 | .pnpm-debug.log* 32 | 33 | # env files (can opt-in for committing if needed) 34 | .env* 35 | 36 | # vercel 37 | .vercel 38 | 39 | # typescript 40 | *.tsbuildinfo 41 | next-env.d.ts 42 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2025 Tawkit Inc. 2 | Copyright (c) 2025 Markus Ecker 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/.gitignore: -------------------------------------------------------------------------------- 1 | playwright-report/ 2 | test-results/ -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/README.md: -------------------------------------------------------------------------------- 1 | # CopilotKit Demo Smoke Tests 2 | 3 | This repository houses Playwright-based smoke tests that run on a 6-hour schedule to make sure CopilotKit demo apps remain live and functional. 4 | 5 | ## 🔧 Local development 6 | 7 | ```bash 8 | # Install deps 9 | npm install 10 | 11 | # Install browsers once 12 | npx playwright install --with-deps 13 | 14 | # Run the full suite 15 | npm test 16 | ``` 17 | 18 | Playwright HTML reports are saved to `./playwright-report`. 19 | 20 | ## ➕ Adding a new smoke test 21 | 22 | 1. Duplicate an existing file in `tests/` or create `tests/.spec.ts`. 23 | 2. Use Playwright's `test` API—keep the test short (<30 s). 24 | 3. Commit and push—GitHub Actions will pick it up on the next scheduled run. 25 | 26 | ## 🚦 CI / CD 27 | 28 | - `.github/workflows/scheduled-tests.yml` executes the suite every 6 hours and on manual trigger. 29 | - Failing runs surface in the Actions tab; the HTML report is uploaded as an artifact. 30 | - (Optional) Slack notifications can be wired by adding a step after the tests. 31 | - Slack alert on failure is baked into the workflow. Just add `SLACK_WEBHOOK_URL` (Incoming Webhook) in repo secrets. 32 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "copilotkit-e2e", 3 | "version": "0.1.0", 4 | "private": true, 5 | "description": "Scheduled Playwright smoke tests for CopilotKit demo apps", 6 | "scripts": { 7 | "postinstall": "playwright install --with-deps", 8 | "test": "playwright test", 9 | "test:ui": "playwright test --ui" 10 | }, 11 | "devDependencies": { 12 | "@playwright/test": "^1.43.1", 13 | "@slack/types": "^2.14.0", 14 | "@types/node": "^22.15.28", 15 | "playwright-slack-report": "^1.1.93" 16 | }, 17 | "dependencies": { 18 | "@aws-sdk/client-s3": "^3.600.0", 19 | "json2md": "^2.0.1" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - '.' -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/test-isolation-setup.ts: -------------------------------------------------------------------------------- 1 | import { chromium, FullConfig } from "@playwright/test"; 2 | 3 | async function globalSetup(config: FullConfig) { 4 | console.log("🧹 Setting up test isolation..."); 5 | 6 | // Launch browser to clear any persistent state 7 | const browser = await chromium.launch(); 8 | const context = await browser.newContext(); 9 | 10 | // Clear all storage 11 | await context.clearCookies(); 12 | await context.clearPermissions(); 13 | 14 | // Clear any cached data 15 | const page = await context.newPage(); 16 | await page.evaluate(() => { 17 | // Clear all storage types 18 | localStorage.clear(); 19 | sessionStorage.clear(); 20 | 21 | // Clear IndexedDB 22 | if (window.indexedDB) { 23 | indexedDB.deleteDatabase("test-db"); 24 | } 25 | 26 | // Clear WebSQL (if supported) 27 | if (window.openDatabase) { 28 | try { 29 | const db = window.openDatabase("", "", "", ""); 30 | db.transaction((tx) => { 31 | tx.executeSql("DELETE FROM test_table"); 32 | }); 33 | } catch (e) { 34 | // Ignore WebSQL errors 35 | } 36 | } 37 | }); 38 | 39 | await browser.close(); 40 | 41 | console.log("✅ Test isolation setup complete"); 42 | } 43 | 44 | export default globalSetup; 45 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/tests/agnoTests/toolBasedGenUIPage.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from "@playwright/test"; 2 | import { ToolBaseGenUIPage } from "../../pages/agnoPages/ToolBaseGenUIPage"; 3 | 4 | const pageURL = 5 | "/agno/feature/tool_based_generative_ui"; 6 | 7 | test.fixme('[Agno] Haiku generation and display verification', async ({ 8 | page, 9 | }) => { 10 | await page.goto(pageURL); 11 | 12 | const genAIAgent = new ToolBaseGenUIPage(page); 13 | 14 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 15 | await genAIAgent.generateHaiku('Generate Haiku for "I will always win"'); 16 | await genAIAgent.checkGeneratedHaiku(); 17 | await genAIAgent.checkHaikuDisplay(page); 18 | }); 19 | 20 | test.fixme('[Agno] Haiku generation and UI consistency for two different prompts', async ({ 21 | page, 22 | }) => { 23 | await page.goto(pageURL); 24 | 25 | const genAIAgent = new ToolBaseGenUIPage(page); 26 | 27 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 28 | 29 | const prompt1 = 'Generate Haiku for "I will always win"'; 30 | await genAIAgent.generateHaiku(prompt1); 31 | await genAIAgent.checkGeneratedHaiku(); 32 | await genAIAgent.checkHaikuDisplay(page); 33 | 34 | const prompt2 = 'Generate Haiku for "The moon shines bright"'; 35 | await genAIAgent.generateHaiku(prompt2); 36 | await genAIAgent.checkGeneratedHaiku(); // Wait for second haiku to be generated 37 | await genAIAgent.checkHaikuDisplay(page); // Now compare the second haiku 38 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/tests/copilotkit-home.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from "@playwright/test"; 2 | 3 | // Smoke test: ensure CopilotKit homepage loads and renders key content. 4 | 5 | test('[Core] CopilotKit homepage renders', async ({ page }) => { 6 | await page.goto("https://copilotkit.ai/", { waitUntil: "domcontentloaded" }); 7 | 8 | await expect(page).toHaveTitle(/CopilotKit/i); 9 | 10 | // Validate hero heading content. 11 | await expect( 12 | page.getByRole("heading", { 13 | name: /Build User-Facing Agentic Applications/i, 14 | exact: false, 15 | }) 16 | ).toBeVisible(); 17 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/tests/crewAITests/toolBasedGenUIPage.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from "@playwright/test"; 2 | import { ToolBaseGenUIPage } from "../../pages/crewAIPages/ToolBaseGenUIPage"; 3 | 4 | const pageURL = 5 | "/crewai/feature/tool_based_generative_ui"; 6 | 7 | test('[CrewAI] Haiku generation and display verification', async ({ 8 | page, 9 | }) => { 10 | await page.goto(pageURL); 11 | 12 | const genAIAgent = new ToolBaseGenUIPage(page); 13 | 14 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 15 | await genAIAgent.generateHaiku('Generate Haiku for "I will always win"'); 16 | await genAIAgent.checkGeneratedHaiku(); 17 | await genAIAgent.checkHaikuDisplay(page); 18 | }); 19 | 20 | test('[CrewAI] Haiku generation and UI consistency for two different prompts', async ({ 21 | page, 22 | }) => { 23 | await page.goto(pageURL); 24 | 25 | const genAIAgent = new ToolBaseGenUIPage(page); 26 | 27 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 28 | 29 | const prompt1 = 'Generate Haiku for "I will always win"'; 30 | await genAIAgent.generateHaiku(prompt1); 31 | await genAIAgent.checkGeneratedHaiku(); 32 | await genAIAgent.checkHaikuDisplay(page); 33 | 34 | const prompt2 = 'Generate Haiku for "The moon shines bright"'; 35 | await genAIAgent.generateHaiku(prompt2); 36 | await genAIAgent.checkGeneratedHaiku(); // Wait for second haiku to be generated 37 | await genAIAgent.checkHaikuDisplay(page); // Now compare the second haiku 38 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/tests/langgraphFastAPITests/toolBasedGenUIPage.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from "@playwright/test"; 2 | import { ToolBaseGenUIPage } from "../../pages/langGraphFastAPIPages/ToolBaseGenUIPage"; 3 | 4 | const pageURL = 5 | "/langgraph-fastapi/feature/tool_based_generative_ui"; 6 | 7 | test.fixme('[LangGraph FastAPI] Haiku generation and display verification', async ({ 8 | page, 9 | }) => { 10 | await page.goto(pageURL); 11 | 12 | const genAIAgent = new ToolBaseGenUIPage(page); 13 | 14 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 15 | await genAIAgent.generateHaiku('Generate Haiku for "I will always win"'); 16 | await genAIAgent.checkGeneratedHaiku(); 17 | await genAIAgent.checkHaikuDisplay(page); 18 | }); 19 | 20 | test.fixme('[LangGraph FastAPI] Haiku generation and UI consistency for two different prompts', async ({ 21 | page, 22 | }) => { 23 | await page.goto(pageURL); 24 | 25 | const genAIAgent = new ToolBaseGenUIPage(page); 26 | 27 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 28 | 29 | const prompt1 = 'Generate Haiku for "I will always win"'; 30 | await genAIAgent.generateHaiku(prompt1); 31 | await genAIAgent.checkGeneratedHaiku(); 32 | await genAIAgent.checkHaikuDisplay(page); 33 | 34 | const prompt2 = 'Generate Haiku for "The moon shines bright"'; 35 | await genAIAgent.generateHaiku(prompt2); 36 | await genAIAgent.checkGeneratedHaiku(); 37 | await genAIAgent.checkHaikuDisplay(page); 38 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/tests/langgraphTests/toolBasedGenUIPage.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from "@playwright/test"; 2 | import { ToolBaseGenUIPage } from "../../pages/langGraphPages/ToolBaseGenUIPage"; 3 | 4 | const pageURL = 5 | "/langgraph/feature/tool_based_generative_ui"; 6 | 7 | test.fixme('[LangGraph] Haiku generation and display verification', async ({ 8 | page, 9 | }) => { 10 | await page.goto(pageURL); 11 | 12 | const genAIAgent = new ToolBaseGenUIPage(page); 13 | 14 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 15 | await genAIAgent.generateHaiku('Generate Haiku for "I will always win"'); 16 | await genAIAgent.checkGeneratedHaiku(); 17 | await genAIAgent.checkHaikuDisplay(page); 18 | }); 19 | 20 | test.fixme('[LangGraph] Haiku generation and UI consistency for two different prompts', async ({ 21 | page, 22 | }) => { 23 | await page.goto(pageURL); 24 | 25 | const genAIAgent = new ToolBaseGenUIPage(page); 26 | 27 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 28 | 29 | const prompt1 = 'Generate Haiku for "I will always win"'; 30 | await genAIAgent.generateHaiku(prompt1); 31 | await genAIAgent.checkGeneratedHaiku(); 32 | await genAIAgent.checkHaikuDisplay(page); 33 | 34 | const prompt2 = 'Generate Haiku for "The moon shines bright"'; 35 | await genAIAgent.generateHaiku(prompt2); 36 | await genAIAgent.checkGeneratedHaiku(); 37 | await genAIAgent.checkHaikuDisplay(page); 38 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/tests/mastraAgentLocalTests/toolBasedGenUIPage.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from "@playwright/test"; 2 | import { ToolBaseGenUIPage } from "../../pages/mastraAgentLocalPages/ToolBaseGenUIPage"; 3 | 4 | const pageURL = 5 | "/mastra-agent-local/feature/tool_based_generative_ui"; 6 | 7 | test.fixme('[Mastra Agent Local] Haiku generation and display verification', async ({ 8 | page, 9 | }) => { 10 | await page.goto(pageURL); 11 | 12 | const genAIAgent = new ToolBaseGenUIPage(page); 13 | 14 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 15 | await genAIAgent.generateHaiku('Generate Haiku for "I will always win"'); 16 | await genAIAgent.checkGeneratedHaiku(); 17 | await genAIAgent.checkHaikuDisplay(page); 18 | }); 19 | 20 | test.fixme('[Mastra Agent Local] Haiku generation and UI consistency for two different prompts', async ({ 21 | page, 22 | }) => { 23 | await page.goto(pageURL); 24 | 25 | const genAIAgent = new ToolBaseGenUIPage(page); 26 | 27 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 28 | 29 | const prompt1 = 'Generate Haiku for "I will always win"'; 30 | await genAIAgent.generateHaiku(prompt1); 31 | await genAIAgent.checkGeneratedHaiku(); 32 | await genAIAgent.checkHaikuDisplay(page); 33 | 34 | const prompt2 = 'Generate Haiku for "The moon shines bright"'; 35 | await genAIAgent.generateHaiku(prompt2); 36 | await genAIAgent.checkGeneratedHaiku(); // Wait for second haiku to be generated 37 | await genAIAgent.checkHaikuDisplay(page); // Now compare the second haiku 38 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/tests/mastraTests/toolBasedGenUIPage.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from "@playwright/test"; 2 | import { ToolBaseGenUIPage } from "../../pages/mastraPages/ToolBaseGenUIPage"; 3 | 4 | const pageURL = 5 | "/mastra/feature/tool_based_generative_ui"; 6 | 7 | test.fixme('[Mastra] Haiku generation and display verification', async ({ 8 | page, 9 | }) => { 10 | await page.goto(pageURL); 11 | 12 | const genAIAgent = new ToolBaseGenUIPage(page); 13 | 14 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 15 | await genAIAgent.generateHaiku('Generate Haiku for "I will always win"'); 16 | await genAIAgent.checkGeneratedHaiku(); 17 | await genAIAgent.checkHaikuDisplay(page); 18 | }); 19 | 20 | test.fixme('[Mastra] Haiku generation and UI consistency for two different prompts', async ({ 21 | page, 22 | }) => { 23 | await page.goto(pageURL); 24 | 25 | const genAIAgent = new ToolBaseGenUIPage(page); 26 | 27 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 28 | 29 | const prompt1 = 'Generate Haiku for "I will always win"'; 30 | await genAIAgent.generateHaiku(prompt1); 31 | await genAIAgent.checkGeneratedHaiku(); 32 | await genAIAgent.checkHaikuDisplay(page); 33 | 34 | const prompt2 = 'Generate Haiku for "The moon shines bright"'; 35 | await genAIAgent.generateHaiku(prompt2); 36 | await genAIAgent.checkGeneratedHaiku(); // Wait for second haiku to be generated 37 | await genAIAgent.checkHaikuDisplay(page); // Now compare the second haiku 38 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/tests/middlewareStarterTests/agenticChatPage.spec.ts: -------------------------------------------------------------------------------- 1 | import { 2 | test, 3 | expect, 4 | waitForAIResponse, 5 | retryOnAIFailure, 6 | } from "../../test-isolation-helper"; 7 | import { AgenticChatPage } from "../../pages/middlewareStarterPages/AgenticChatPage"; 8 | 9 | test("[Middleware Starter] Testing Agentic Chat", async ({ 10 | page, 11 | }) => { 12 | await retryOnAIFailure(async () => { 13 | await page.goto( 14 | "/middleware-starter/feature/agentic_chat" 15 | ); 16 | 17 | const chat = new AgenticChatPage(page); 18 | await chat.openChat(); 19 | await chat.agentGreeting.waitFor({ state: "visible" }); 20 | await chat.sendMessage("Hey there"); 21 | await chat.assertUserMessageVisible("Hey there"); 22 | await waitForAIResponse(page); 23 | await chat.assertAgentReplyVisible(/Hello world!/i); 24 | }); 25 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/tests/pydanticAITests/toolBasedGenUIPage.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from "@playwright/test"; 2 | import { ToolBaseGenUIPage } from "../../pages/pydanticAIPages/ToolBaseGenUIPage"; 3 | 4 | const pageURL = 5 | "/pydantic-ai/feature/tool_based_generative_ui"; 6 | 7 | test.fixme('[PydanticAI] Haiku generation and display verification', async ({ 8 | page, 9 | }) => { 10 | await page.goto(pageURL); 11 | 12 | const genAIAgent = new ToolBaseGenUIPage(page); 13 | 14 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 15 | await genAIAgent.generateHaiku('Generate Haiku for "I will always win"'); 16 | await genAIAgent.checkGeneratedHaiku(); 17 | await genAIAgent.checkHaikuDisplay(page); 18 | }); 19 | 20 | test.fixme('[PydanticAI] Haiku generation and UI consistency for two different prompts', async ({ 21 | page, 22 | }) => { 23 | await page.goto(pageURL); 24 | 25 | const genAIAgent = new ToolBaseGenUIPage(page); 26 | 27 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 28 | 29 | const prompt1 = 'Generate Haiku for "I will always win"'; 30 | await genAIAgent.generateHaiku(prompt1); 31 | await genAIAgent.checkGeneratedHaiku(); 32 | await genAIAgent.checkHaikuDisplay(page); 33 | 34 | const prompt2 = 'Generate Haiku for "The moon shines bright"'; 35 | await genAIAgent.generateHaiku(prompt2); 36 | await genAIAgent.checkGeneratedHaiku(); // Wait for second haiku to be generated 37 | await genAIAgent.checkHaikuDisplay(page); // Now compare the second haiku 38 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/tests/serverStarterAllFeaturesTests/agenticChatPage.spec.ts: -------------------------------------------------------------------------------- 1 | import { 2 | test, 3 | expect, 4 | waitForAIResponse, 5 | retryOnAIFailure, 6 | } from "../../test-isolation-helper"; 7 | import { AgenticChatPage } from "../../pages/serverStarterAllFeaturesPages/AgenticChatPage"; 8 | 9 | test("[Server Starter all features] Agentic Chat displays countdown from 10 to 1 with tick mark", async ({ 10 | page, 11 | }) => { 12 | await retryOnAIFailure(async () => { 13 | await page.goto( 14 | "/server-starter-all-features/feature/agentic_chat" 15 | ); 16 | 17 | const chat = new AgenticChatPage(page); 18 | await chat.openChat(); 19 | await chat.agentGreeting.waitFor({ state: "visible" }); 20 | await chat.sendMessage("Hey there"); 21 | await chat.assertUserMessageVisible("Hey there"); 22 | await waitForAIResponse(page); 23 | 24 | const countdownMessage = page 25 | .locator('.copilotKitAssistantMessage') 26 | .filter({ hasText: 'counting down:' }); 27 | 28 | await expect(countdownMessage).toBeVisible({ timeout: 30000 }); 29 | 30 | // Wait for countdown to complete by checking for the tick mark 31 | await expect(countdownMessage.locator('.copilotKitMarkdownElement')) 32 | .toContainText('✓', { timeout: 15000 }); 33 | 34 | const countdownText = await countdownMessage 35 | .locator('.copilotKitMarkdownElement') 36 | .textContent(); 37 | 38 | expect(countdownText).toContain("counting down:"); 39 | expect(countdownText).toMatch(/counting down:\s*10\s+9\s+8\s+7\s+6\s+5\s+4\s+3\s+2\s+1\s+✓/); 40 | }); 41 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/tests/serverStarterAllFeaturesTests/agenticGenUI.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from "@playwright/test"; 2 | import { AgenticGenUIPage } from "../../pages/serverStarterAllFeaturesPages/AgenticUIGenPage"; 3 | 4 | test.describe("Agent Generative UI Feature", () => { 5 | test("[Server Starter all features] should interact with the chat to get a planner on prompt", async ({ 6 | page, 7 | }) => { 8 | const genUIAgent = new AgenticGenUIPage(page); 9 | 10 | await page.goto( 11 | "/server-starter-all-features/feature/agentic_generative_ui" 12 | ); 13 | 14 | await genUIAgent.openChat(); 15 | await genUIAgent.sendMessage("Hi"); 16 | await genUIAgent.sendButton.click(); 17 | await expect(genUIAgent.agentPlannerContainer).toBeVisible({ timeout: 15000 }); 18 | 19 | await genUIAgent.plan(); 20 | await expect(genUIAgent.agentPlannerContainer).toBeVisible({ timeout: 8000 }); 21 | }); 22 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/tests/serverStarterAllFeaturesTests/humanInTheLoopPage.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect, waitForAIResponse, retryOnAIFailure } from "../../test-isolation-helper"; 2 | import { HumanInLoopPage } from "../../pages/serverStarterAllFeaturesPages/HumanInLoopPage"; 3 | 4 | test.describe("Human in the Loop Feature", () => { 5 | test(" [Server Starter all features] should interact with the chat using predefined prompts and perform steps", async ({ 6 | page, 7 | }) => { 8 | await retryOnAIFailure(async () => { 9 | const humanInLoop = new HumanInLoopPage(page); 10 | 11 | await page.goto( 12 | "/server-starter-all-features/feature/human_in_the_loop" 13 | ); 14 | 15 | await humanInLoop.openChat(); 16 | 17 | await humanInLoop.sendMessage("Hi"); 18 | await humanInLoop.agentGreeting.isVisible(); 19 | await waitForAIResponse(page); 20 | await expect(humanInLoop.plan).toBeVisible({ timeout: 10000 }); 21 | await humanInLoop.performSteps(); 22 | 23 | await page.waitForFunction( 24 | () => { 25 | const messages = Array.from(document.querySelectorAll('.copilotKitAssistantMessage')); 26 | const lastMessage = messages[messages.length - 1]; 27 | const content = lastMessage?.textContent?.trim() || ''; 28 | 29 | return messages.length >= 2 && content.length > 0; 30 | }, 31 | { timeout: 30000 } 32 | ); 33 | }); 34 | }); 35 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/tests/serverStarterAllFeaturesTests/toolBasedGenUIPage.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from "@playwright/test"; 2 | import { ToolBaseGenUIPage } from "../../pages/serverStarterAllFeaturesPages/ToolBaseGenUIPage"; 3 | 4 | const pageURL = 5 | "/server-starter-all-features/feature/tool_based_generative_ui"; 6 | 7 | test('[Server Starter all features] Haiku generation and display verification', async ({ 8 | page, 9 | }) => { 10 | await page.goto(pageURL); 11 | 12 | const genAIAgent = new ToolBaseGenUIPage(page); 13 | 14 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 15 | await genAIAgent.generateHaiku('Generate Haiku for "I will always win"'); 16 | await genAIAgent.checkGeneratedHaiku(); 17 | await genAIAgent.checkHaikuDisplay(page); 18 | }); 19 | 20 | test('[Server Starter all features] Haiku generation and UI consistency for two different prompts', async ({ 21 | page, 22 | }) => { 23 | await page.goto(pageURL); 24 | 25 | const genAIAgent = new ToolBaseGenUIPage(page); 26 | 27 | await expect(genAIAgent.haikuAgentIntro).toBeVisible(); 28 | 29 | const prompt1 = 'Generate Haiku for "I will always win"'; 30 | await genAIAgent.generateHaiku(prompt1); 31 | await genAIAgent.checkGeneratedHaiku(); 32 | await genAIAgent.checkHaikuDisplay(page); 33 | 34 | const prompt2 = 'Generate Haiku for "The moon shines bright"'; 35 | await genAIAgent.generateHaiku(prompt2); 36 | await genAIAgent.checkGeneratedHaiku(); 37 | await genAIAgent.checkHaikuDisplay(page); 38 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e/tests/serverStarterTests/agenticChatPage.spec.ts: -------------------------------------------------------------------------------- 1 | import { 2 | test, 3 | expect, 4 | waitForAIResponse, 5 | retryOnAIFailure, 6 | } from "../../test-isolation-helper"; 7 | import { AgenticChatPage } from "../../pages/serverStarterPages/AgenticChatPage"; 8 | 9 | test("[Server Starter] Testing Agentic Chat", async ({ 10 | page, 11 | }) => { 12 | await retryOnAIFailure(async () => { 13 | await page.goto( 14 | "/server-starter/feature/agentic_chat" 15 | ); 16 | 17 | const chat = new AgenticChatPage(page); 18 | await chat.openChat(); 19 | await chat.agentGreeting.waitFor({ state: "visible" }); 20 | await chat.sendMessage("Hey there"); 21 | await chat.assertUserMessageVisible("Hey there"); 22 | await waitForAIResponse(page); 23 | await chat.assertAgentReplyVisible(/Hello world!/i); 24 | }); 25 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e2/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Playwright 3 | node_modules/ 4 | /test-results/ 5 | /playwright-report/ 6 | /blob-report/ 7 | /playwright/.cache/ 8 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "e2e2", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": {}, 7 | "keywords": [], 8 | "author": "", 9 | "license": "ISC", 10 | "devDependencies": { 11 | "@playwright/test": "^1.54.2", 12 | "@types/node": "^24.1.0" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e2/pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - '.' -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e2/tests/agno-agentic-chat.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '@playwright/test'; 2 | 3 | test('renders initial message', async ({ page }) => { 4 | await page.goto('http://localhost:9999/agno/feature/agentic_chat'); 5 | 6 | await expect(page.getByText('Hi, I\'m an agent. Want to chat?')).toBeVisible(); 7 | }); 8 | 9 | test('responds to user message', async ({ page }) => { 10 | await page.goto('http://localhost:9999/agno/feature/agentic_chat'); 11 | 12 | const textarea = page.getByPlaceholder('Type a message...'); 13 | textarea.fill('How many sides are in a square? Please answer in one word. Do not use any punctuation, just the number in word form.'); 14 | await page.keyboard.press('Enter'); 15 | 16 | page.locator('.copilotKitInputControls button.copilotKitInputControlButton').click(); 17 | 18 | await expect(page.locator('.copilotKitMessage')).toHaveCount(3); 19 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage')).toHaveCount(2); 20 | await expect(page.locator('.copilotKitMessage.copilotKitUserMessage')).toHaveCount(1); 21 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage').last()).toHaveText('four', { ignoreCase: true }); 22 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e2/tests/crewai-agentic-chat.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '@playwright/test'; 2 | 3 | test('renders initial message', async ({ page }) => { 4 | await page.goto('http://localhost:9999/crewai/feature/agentic_chat'); 5 | 6 | await expect(page.getByText('Hi, I\'m an agent. Want to chat?')).toBeVisible(); 7 | }); 8 | 9 | test('responds to user message', async ({ page }) => { 10 | await page.goto('http://localhost:9999/crewai/feature/agentic_chat'); 11 | 12 | const textarea = page.getByPlaceholder('Type a message...'); 13 | textarea.fill('How many sides are in a square? Please answer in one word. Do not use any punctuation, just the number in word form.'); 14 | await page.keyboard.press('Enter'); 15 | 16 | page.locator('.copilotKitInputControls button.copilotKitInputControlButton').click(); 17 | 18 | await expect(page.locator('.copilotKitMessage')).toHaveCount(3); 19 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage')).toHaveCount(2); 20 | await expect(page.locator('.copilotKitMessage.copilotKitUserMessage')).toHaveCount(1); 21 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage').last()).toHaveText('four', { ignoreCase: true }); 22 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e2/tests/langgraph-agentic-chat.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '@playwright/test'; 2 | 3 | test('renders initial message', async ({ page }) => { 4 | await page.goto('http://localhost:9999/langgraph/feature/agentic_chat'); 5 | 6 | await expect(page.getByText('Hi, I\'m an agent. Want to chat?')).toBeVisible(); 7 | }); 8 | 9 | test('responds to user message', async ({ page }) => { 10 | await page.goto('http://localhost:9999/langgraph/feature/agentic_chat'); 11 | 12 | const textarea = page.getByPlaceholder('Type a message...'); 13 | textarea.fill('How many sides are in a square? Please answer in one word. Do not use any punctuation, just the number in word form.'); 14 | await page.keyboard.press('Enter'); 15 | 16 | page.locator('.copilotKitInputControls button.copilotKitInputControlButton').click(); 17 | 18 | await expect(page.locator('.copilotKitMessage')).toHaveCount(3); 19 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage')).toHaveCount(2); 20 | await expect(page.locator('.copilotKitMessage.copilotKitUserMessage')).toHaveCount(1); 21 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage').last()).toHaveText('four', { ignoreCase: true }); 22 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e2/tests/langgraph-fastapi-agentic-chat.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '@playwright/test'; 2 | 3 | test('renders initial message', async ({ page }) => { 4 | await page.goto('http://localhost:9999/langgraph-fastapi/feature/agentic_chat'); 5 | 6 | await expect(page.getByText('Hi, I\'m an agent. Want to chat?')).toBeVisible(); 7 | }); 8 | 9 | test('responds to user message', async ({ page }) => { 10 | await page.goto('http://localhost:9999/langgraph-fastapi/feature/agentic_chat'); 11 | 12 | const textarea = page.getByPlaceholder('Type a message...'); 13 | textarea.fill('How many sides are in a square? Please answer in one word. Do not use any punctuation, just the number in word form.'); 14 | await page.keyboard.press('Enter'); 15 | 16 | page.locator('.copilotKitInputControls button.copilotKitInputControlButton').click(); 17 | 18 | await expect(page.locator('.copilotKitMessage')).toHaveCount(3); 19 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage')).toHaveCount(2); 20 | await expect(page.locator('.copilotKitMessage.copilotKitUserMessage')).toHaveCount(1); 21 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage').last()).toHaveText('four', { ignoreCase: true }); 22 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e2/tests/langgraph-typescript-agentic-chat.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '@playwright/test'; 2 | 3 | test('renders initial message', async ({ page }) => { 4 | await page.goto('http://localhost:9999/langgraph-typescript/feature/agentic_chat'); 5 | 6 | await expect(page.getByText('Hi, I\'m an agent. Want to chat?')).toBeVisible(); 7 | }); 8 | 9 | test('responds to user message', async ({ page }) => { 10 | await page.goto('http://localhost:9999/langgraph-typescript/feature/agentic_chat'); 11 | 12 | const textarea = page.getByPlaceholder('Type a message...'); 13 | textarea.fill('How many sides are in a square? Please answer in one word. Do not use any punctuation, just the number in word form.'); 14 | await page.keyboard.press('Enter'); 15 | 16 | page.locator('.copilotKitInputControls button.copilotKitInputControlButton').click(); 17 | 18 | await expect(page.locator('.copilotKitMessage')).toHaveCount(3); 19 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage')).toHaveCount(2); 20 | await expect(page.locator('.copilotKitMessage.copilotKitUserMessage')).toHaveCount(1); 21 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage').last()).toHaveText('four', { ignoreCase: true }); 22 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e2/tests/llama-index-agentic-chat.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '@playwright/test'; 2 | 3 | test('renders initial message', async ({ page }) => { 4 | await page.goto('http://localhost:9999/llama-index/feature/agentic_chat'); 5 | 6 | await expect(page.getByText('Hi, I\'m an agent. Want to chat?')).toBeVisible(); 7 | }); 8 | 9 | test('responds to user message', async ({ page }) => { 10 | await page.goto('http://localhost:9999/llama-index/feature/agentic_chat'); 11 | 12 | const textarea = page.getByPlaceholder('Type a message...'); 13 | textarea.fill('How many sides are in a square? Please answer in one word. Do not use any punctuation, just the number in word form.'); 14 | await page.keyboard.press('Enter'); 15 | 16 | page.locator('.copilotKitInputControls button.copilotKitInputControlButton').click(); 17 | 18 | await expect(page.locator('.copilotKitMessage')).toHaveCount(3); 19 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage')).toHaveCount(2); 20 | await expect(page.locator('.copilotKitMessage.copilotKitUserMessage')).toHaveCount(1); 21 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage').last()).toHaveText('four', { ignoreCase: true }); 22 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e2/tests/mastra-agentic-chat.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '@playwright/test'; 2 | 3 | test('renders initial message', async ({ page }) => { 4 | await page.goto('http://localhost:9999/mastra/feature/agentic_chat'); 5 | 6 | await expect(page.getByText('Hi, I\'m an agent. Want to chat?')).toBeVisible(); 7 | }); 8 | 9 | test('responds to user message', async ({ page }) => { 10 | await page.goto('http://localhost:9999/mastra/feature/agentic_chat'); 11 | 12 | const textarea = page.getByPlaceholder('Type a message...'); 13 | textarea.fill('How many sides are in a square? Please answer in one word. Do not use any punctuation, just the number in word form.'); 14 | await page.keyboard.press('Enter'); 15 | 16 | page.locator('.copilotKitInputControls button.copilotKitInputControlButton').click(); 17 | 18 | await expect(page.locator('.copilotKitMessage')).toHaveCount(3); 19 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage')).toHaveCount(2); 20 | await expect(page.locator('.copilotKitMessage.copilotKitUserMessage')).toHaveCount(1); 21 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage').last()).toHaveText('four', { ignoreCase: true }); 22 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e2/tests/pydantic-agentic-chat.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '@playwright/test'; 2 | 3 | test('renders initial message', async ({ page }) => { 4 | await page.goto('http://localhost:9999/pydantic-ai/feature/agentic_chat'); 5 | 6 | await expect(page.getByText('Hi, I\'m an agent. Want to chat?')).toBeVisible(); 7 | }); 8 | 9 | test('responds to user message', async ({ page }) => { 10 | await page.goto('http://localhost:9999/pydantic-ai/feature/agentic_chat'); 11 | 12 | const textarea = page.getByPlaceholder('Type a message...'); 13 | textarea.fill('How many sides are in a square? Please answer in one word. Do not use any punctuation, just the number in word form.'); 14 | await page.keyboard.press('Enter'); 15 | 16 | page.locator('.copilotKitInputControls button.copilotKitInputControlButton').click(); 17 | 18 | await expect(page.locator('.copilotKitMessage')).toHaveCount(3); 19 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage')).toHaveCount(2); 20 | await expect(page.locator('.copilotKitMessage.copilotKitUserMessage')).toHaveCount(1); 21 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage').last()).toHaveText('four', { ignoreCase: true }); 22 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/e2e2/tests/vercel-ai-sdk-agentic-chat.spec.ts: -------------------------------------------------------------------------------- 1 | import { test, expect } from '@playwright/test'; 2 | 3 | test('renders initial message', async ({ page }) => { 4 | await page.goto('http://localhost:9999/vercel-ai-sdk/feature/agentic_chat'); 5 | 6 | await expect(page.getByText('Hi, I\'m an agent. Want to chat?')).toBeVisible(); 7 | }); 8 | 9 | test('responds to user message', async ({ page }) => { 10 | await page.goto('http://localhost:9999/vercel-ai-sdk/feature/agentic_chat'); 11 | 12 | const textarea = page.getByPlaceholder('Type a message...'); 13 | textarea.fill('How many sides are in a square? Please answer in one word. Do not use any punctuation, just the number in word form.'); 14 | await page.keyboard.press('Enter'); 15 | 16 | page.locator('.copilotKitInputControls button.copilotKitInputControlButton').click(); 17 | 18 | await expect(page.locator('.copilotKitMessage')).toHaveCount(3); 19 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage')).toHaveCount(2); 20 | await expect(page.locator('.copilotKitMessage.copilotKitUserMessage')).toHaveCount(1); 21 | await expect(page.locator('.copilotKitMessage.copilotKitAssistantMessage').last()).toHaveText('four', { ignoreCase: true }); 22 | }); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/eslint.config.mjs: -------------------------------------------------------------------------------- 1 | import { dirname } from "path"; 2 | import { fileURLToPath } from "url"; 3 | import { FlatCompat } from "@eslint/eslintrc"; 4 | 5 | const __filename = fileURLToPath(import.meta.url); 6 | const __dirname = dirname(__filename); 7 | 8 | const compat = new FlatCompat({ 9 | baseDirectory: __dirname, 10 | }); 11 | 12 | const eslintConfig = [ 13 | // ...compat.extends("next/core-web-vitals", "next/typescript"), 14 | ...compat.config({ 15 | extends: ["next"], 16 | rules: { 17 | "@typescript-eslint/no-unused-vars": "off", 18 | }, 19 | }), 20 | ]; 21 | 22 | export default eslintConfig; 23 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/next.config.ts: -------------------------------------------------------------------------------- 1 | import type { NextConfig } from "next"; 2 | import createMDX from "@next/mdx"; 3 | 4 | const withMDX = createMDX({ 5 | extension: /\.mdx?$/, 6 | options: { 7 | // If you use remark-gfm, you'll need to use next.config.mjs 8 | // as the package is ESM only 9 | // https://github.com/remarkjs/remark-gfm#install 10 | remarkPlugins: [], 11 | rehypePlugins: [], 12 | // If you use `MDXProvider`, uncomment the following line. 13 | providerImportSource: "@mdx-js/react", 14 | }, 15 | }); 16 | 17 | const nextConfig: NextConfig = { 18 | /* config options here */ 19 | // Configure pageExtensions to include md and mdx 20 | pageExtensions: ["ts", "tsx", "js", "jsx", "md", "mdx"], 21 | webpack: (config, { isServer }) => { 22 | // Ignore the demo files during build 23 | config.module.rules.push({ 24 | test: /agent\/demo\/crew_enterprise\/ui\/.*\.(ts|tsx|js|jsx)$/, 25 | loader: "ignore-loader", 26 | }); 27 | 28 | return config; 29 | }, 30 | serverExternalPackages: ["@mastra/libsql"], 31 | }; 32 | 33 | // Merge MDX config with Next.js config 34 | export default withMDX(nextConfig); 35 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/postcss.config.mjs: -------------------------------------------------------------------------------- 1 | const config = { 2 | plugins: ["@tailwindcss/postcss"], 3 | }; 4 | 5 | export default config; 6 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/public/images/Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/apps/dojo/public/images/Bonsai_Tree_Potted_Japanese_Art_Green_Foliage.jpeg -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/public/images/Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/apps/dojo/public/images/Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/public/images/Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/apps/dojo/public/images/Ginkaku-ji_Silver_Pavilion_Kyoto_Japanese_Garden_Pond_Reflection.jpg -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/public/images/Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/apps/dojo/public/images/Itsukushima_Shrine_Miyajima_Floating_Torii_Gate_Sunset_Long_Exposure.jpg -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/public/images/Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/apps/dojo/public/images/Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/public/images/Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/apps/dojo/public/images/Osaka_Castle_Turret_Stone_Wall_Pine_Trees_Daytime.jpg -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/public/images/Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/apps/dojo/public/images/Senso-ji_Temple_Asakusa_Cherry_Blossoms_Kimono_Umbrella.jpg -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/public/images/Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/apps/dojo/public/images/Shirakawa-go_Gassho-zukuri_Thatched_Roof_Village_Aerial_View.jpg -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/public/images/Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/apps/dojo/public/images/Takachiho_Gorge_Waterfall_River_Lush_Greenery_Japan.jpg -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/public/images/Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/apps/dojo/public/images/Tokyo_Skyline_Night_Tokyo_Tower_Mount_Fuji_View.jpg -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/public/logo_dark.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/apps/dojo/public/logo_dark.webp -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/public/logo_light.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/apps/dojo/public/logo_light.webp -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/public/shared_state_background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/apps/dojo/public/shared_state_background.png -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/scripts/link-cpk.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | const fs = require('fs'); 3 | const { execSync } = require('child_process'); 4 | const path = require('path'); 5 | 6 | const cpkPath = process.argv[2]; 7 | if (!cpkPath) { 8 | console.error('Usage: node link-cpk.js '); 9 | process.exit(1); 10 | } 11 | 12 | if (!fs.existsSync(cpkPath)) { 13 | console.error(`copilot kit repo path ${cpkPath} does not exist`); 14 | process.exit(1); 15 | } 16 | 17 | 18 | const gitRoot = execSync('git rev-parse --show-toplevel', { encoding: 'utf-8', cwd: __dirname }).trim(); 19 | const dojoDir = path.join(gitRoot, 'typescript-sdk/apps/dojo'); 20 | const cpkPackageDir = path.join(cpkPath, 'CopilotKit', 'packages'); 21 | const relative = `./${path.relative(dojoDir, cpkPackageDir)}`; 22 | 23 | function linkCopilotKit() { 24 | const pkgPath = path.join(dojoDir, 'package.json'); 25 | const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf8')); 26 | const packages = Object.keys(pkg.dependencies).filter(pkg => pkg.startsWith('@copilotkit/')); 27 | 28 | success = true; 29 | packages.forEach(packageName => { 30 | const packageFolderName = packageName.replace('@copilotkit/', ''); 31 | 32 | if (!fs.existsSync(path.join(cpkPackageDir, packageFolderName))) { 33 | console.error(`Package ${packageName} does not exist in ${cpkPackageDir}!!`); 34 | success = false; 35 | } 36 | 37 | pkg.dependencies[packageName] = path.join(relative, packageFolderName); 38 | }); 39 | 40 | 41 | 42 | if (!success) { 43 | console.error('One or more packages do not exist in the copilot kit repo!'); 44 | process.exit(1); 45 | } 46 | 47 | fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2)); 48 | 49 | } 50 | 51 | linkCopilotKit(); -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/app/[integrationId]/feature/agentic_chat/style.css: -------------------------------------------------------------------------------- 1 | .copilotKitInput { 2 | border-bottom-left-radius: 0.75rem; 3 | border-bottom-right-radius: 0.75rem; 4 | border-top-left-radius: 0.75rem; 5 | border-top-right-radius: 0.75rem; 6 | border: 1px solid var(--copilot-kit-separator-color) !important; 7 | } 8 | 9 | .copilotKitChat { 10 | background-color: #fff !important; 11 | } 12 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/app/[integrationId]/feature/agentic_chat_reasoning/style.css: -------------------------------------------------------------------------------- 1 | .copilotKitInput { 2 | border-bottom-left-radius: 0.75rem; 3 | border-bottom-right-radius: 0.75rem; 4 | border-top-left-radius: 0.75rem; 5 | border-top-right-radius: 0.75rem; 6 | border: 1px solid var(--copilot-kit-separator-color) !important; 7 | } 8 | 9 | .copilotKitChat { 10 | background-color: #fff !important; 11 | } 12 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/app/[integrationId]/feature/agentic_generative_ui/style.css: -------------------------------------------------------------------------------- 1 | .copilotKitInput { 2 | border-bottom-left-radius: 0.75rem; 3 | border-bottom-right-radius: 0.75rem; 4 | border-top-left-radius: 0.75rem; 5 | border-top-right-radius: 0.75rem; 6 | border: 1px solid var(--copilot-kit-separator-color) !important; 7 | } 8 | 9 | .copilotKitChat { 10 | background-color: #fff !important; 11 | } 12 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/app/[integrationId]/feature/human_in_the_loop/style.css: -------------------------------------------------------------------------------- 1 | .copilotKitInput { 2 | border-bottom-left-radius: 0.75rem; 3 | border-bottom-right-radius: 0.75rem; 4 | border-top-left-radius: 0.75rem; 5 | border-top-right-radius: 0.75rem; 6 | border: 1px solid var(--copilot-kit-separator-color) !important; 7 | } 8 | 9 | .copilotKitChat { 10 | background-color: #fff !important; 11 | } 12 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/app/[integrationId]/not-found.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Link from "next/link"; 3 | 4 | export default function NotFound() { 5 | return ( 6 |
7 |

Integration Not Found

8 |

9 | The integration you're looking for doesn't exist. 10 |

11 | 15 | Back to Home 16 | 17 |
18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/app/api/copilotkit/[integrationId]/route.ts: -------------------------------------------------------------------------------- 1 | import { 2 | CopilotRuntime, 3 | ExperimentalEmptyAdapter, 4 | copilotRuntimeNextJSAppRouterEndpoint, 5 | } from "@copilotkit/runtime"; 6 | import { agentsIntegrations } from "@/agents"; 7 | 8 | import { NextRequest } from "next/server"; 9 | 10 | export async function POST(request: NextRequest) { 11 | const integrationId = request.url.split("/").pop(); 12 | 13 | const integration = agentsIntegrations.find((i) => i.id === integrationId); 14 | if (!integration) { 15 | return new Response("Integration not found", { status: 404 }); 16 | } 17 | const agents = await integration.agents(); 18 | const runtime = new CopilotRuntime({ 19 | // @ts-ignore for now 20 | agents, 21 | }); 22 | const { handleRequest } = copilotRuntimeNextJSAppRouterEndpoint({ 23 | runtime, 24 | serviceAdapter: new ExperimentalEmptyAdapter(), 25 | endpoint: `/api/copilotkit/${integrationId}`, 26 | }); 27 | 28 | return handleRequest(request); 29 | } 30 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/app/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/apps/dojo/src/app/icon.png -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/app/layout.tsx: -------------------------------------------------------------------------------- 1 | import { Suspense } from "react"; 2 | import type { Metadata } from "next"; 3 | import { Geist, Geist_Mono } from "next/font/google"; 4 | import "./globals.css"; 5 | import "@copilotkit/react-ui/styles.css"; 6 | import { ThemeProvider } from "@/components/theme-provider"; 7 | import { MainLayout } from "@/components/layout/main-layout"; 8 | import { URLParamsProvider } from "@/contexts/url-params-context"; 9 | 10 | const geistSans = Geist({ 11 | variable: "--font-geist-sans", 12 | subsets: ["latin"], 13 | }); 14 | 15 | const geistMono = Geist_Mono({ 16 | variable: "--font-geist-mono", 17 | subsets: ["latin"], 18 | }); 19 | 20 | export const metadata: Metadata = { 21 | title: "Demo Viewer by CopilotKit", 22 | description: "Demo Viewer by CopilotKit", 23 | }; 24 | 25 | export default function RootLayout({ 26 | children, 27 | }: Readonly<{ 28 | children: React.ReactNode; 29 | }>) { 30 | return ( 31 | 32 | 33 | 39 | 40 | 41 | {children} 42 | 43 | 44 | 45 | 46 | 47 | ); 48 | } 49 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/app/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import React from "react"; 4 | 5 | export default function Home() { 6 | return ( 7 |
8 |

9 | Select an integration to get started 10 |

11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/components/code-viewer/code-editor.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Editor from "@monaco-editor/react"; 3 | import { useTheme } from "next-themes"; 4 | import { FeatureFile } from "@/types/feature"; 5 | interface CodeEditorProps { 6 | file?: FeatureFile; 7 | onFileChange?: (fileName: string, content: string) => void; 8 | } 9 | 10 | export function CodeEditor({ file, onFileChange }: CodeEditorProps) { 11 | const handleEditorChange = (value: string | undefined) => { 12 | if (value && onFileChange) { 13 | onFileChange(file!.name, value); 14 | } 15 | }; 16 | 17 | const theme = useTheme(); 18 | 19 | return file ? ( 20 |
21 | 38 |
39 | ) : ( 40 |
41 | Select a file from the file tree to view its code 42 |
43 | ); 44 | } 45 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/components/code-viewer/code-viewer.tsx: -------------------------------------------------------------------------------- 1 | import { useMemo, useState } from "react"; 2 | import { FileTree } from "@/components/file-tree/file-tree"; 3 | import { CodeEditor } from './code-editor' 4 | import { FeatureFile } from "@/types/feature"; 5 | import { useURLParams } from "@/contexts/url-params-context"; 6 | 7 | export default function CodeViewer({ 8 | codeFiles 9 | }: { 10 | codeFiles: FeatureFile[]; 11 | }) { 12 | const { file, setCodeFile } = useURLParams(); 13 | 14 | const selectedFile = useMemo(() => ( 15 | codeFiles.find(f => f.name === file) ?? codeFiles[0] 16 | ), [codeFiles, file]) 17 | 18 | return ( 19 |
20 |
21 |
22 | 27 |
28 |
29 |
30 | {selectedFile ? ( 31 |
32 | 35 |
36 | ) : ( 37 |
38 | Select a file to view its content. 39 |
40 | )} 41 |
42 |
43 | ) 44 | } -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/components/file-tree/file-tree-nav.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { ChevronRight, FolderOpen } from "lucide-react"; 3 | import { Button } from "@/components/ui/button"; 4 | import { cn } from "@/lib/utils"; 5 | import { relative } from "path"; 6 | 7 | interface FileTreeNavProps { 8 | path: string; 9 | rootPath: string; // The demo's root path 10 | onNavigate?: (path: string) => void; 11 | } 12 | 13 | export function FileTreeNav({ path, rootPath, onNavigate }: FileTreeNavProps) { 14 | const folderName = rootPath.split("/").pop(); 15 | 16 | return ( 17 |
18 | 21 | 28 |
29 | ); 30 | } 31 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/components/readme/readme.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { MDXRenderer } from "@/utils/mdx-utils"; 4 | 5 | export default function Readme({ content }: { content: string }) { 6 | return ( 7 |
8 |
{}
9 |
10 | ); 11 | } 12 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/components/theme-provider.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import * as React from "react"; 4 | import { ThemeProvider as NextThemesProvider } from "next-themes"; 5 | 6 | type ThemeProviderProps = { 7 | children: React.ReactNode; 8 | attribute?: string; 9 | defaultTheme?: string; 10 | enableSystem?: boolean; 11 | disableTransitionOnChange?: boolean; 12 | }; 13 | 14 | export function ThemeProvider({ children, ...props }: ThemeProviderProps) { 15 | // @ts-expect-error -- ignore 16 | return {children}; 17 | } 18 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/components/ui/mdx-components.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { cn } from "@/lib/utils"; 3 | import { MarkdownComponents } from "./markdown-components"; 4 | import type { Components } from "react-markdown"; 5 | 6 | // Video component specifically for MDX 7 | export const VideoPlayer = ({ 8 | src, 9 | width = "100%", 10 | className, 11 | ...props 12 | }: React.VideoHTMLAttributes & { src: string }) => { 13 | return ( 14 |
15 | 19 |
20 | ); 21 | }; 22 | 23 | // Type definition for MDX components that includes our custom components 24 | type CustomMDXComponents = Components & { 25 | Video: typeof VideoPlayer; 26 | video: typeof VideoPlayer; 27 | }; 28 | 29 | // Combine all components for MDX 30 | export const MDXComponents: CustomMDXComponents = { 31 | ...MarkdownComponents, 32 | // Custom components for MDX 33 | Video: VideoPlayer, 34 | video: VideoPlayer, 35 | } as CustomMDXComponents; 36 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/components/ui/theme-toggle.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import * as React from "react"; 4 | import { Moon, Sun } from "lucide-react"; 5 | import { useTheme } from "next-themes"; 6 | 7 | import { Button } from "@/components/ui/button"; 8 | 9 | export function ThemeToggle() { 10 | const { theme, setTheme } = useTheme(); 11 | 12 | return ( 13 | 23 | ); 24 | } 25 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/env.ts: -------------------------------------------------------------------------------- 1 | type envVars = { 2 | serverStarterUrl: string; 3 | serverStarterAllFeaturesUrl: string; 4 | mastraUrl: string; 5 | langgraphPythonUrl: string; 6 | langgraphFastApiUrl: string; 7 | langgraphTypescriptUrl: string; 8 | agnoUrl: string; 9 | llamaIndexUrl: string; 10 | crewAiUrl: string; 11 | pydanticAIUrl: string; 12 | customDomainTitle: Record; 13 | } 14 | 15 | export default function getEnvVars(): envVars { 16 | const customDomainTitle: Record = {}; 17 | if (process.env.NEXT_PUBLIC_CUSTOM_DOMAIN_TITLE) { 18 | const [domain, title] = process.env.NEXT_PUBLIC_CUSTOM_DOMAIN_TITLE.split('___'); 19 | if (domain && title) { 20 | customDomainTitle[domain] = title; 21 | } 22 | } 23 | 24 | return { 25 | serverStarterUrl: process.env.SERVER_STARTER_URL || 'http://localhost:8000', 26 | serverStarterAllFeaturesUrl: process.env.SERVER_STARTER_ALL_FEATURES_URL || 'http://localhost:8000', 27 | mastraUrl: process.env.MASTRA_URL || 'http://localhost:4111', 28 | langgraphPythonUrl: process.env.LANGGRAPH_PYTHON_URL || 'http://localhost:2024', 29 | langgraphFastApiUrl: process.env.LANGGRAPH_FAST_API_URL || 'http://localhost:8000', 30 | langgraphTypescriptUrl: process.env.LANGGRAPH_TYPESCRIPT_URL || 'http://localhost:8000', 31 | agnoUrl: process.env.AGNO_URL || 'http://localhost:9001', 32 | llamaIndexUrl: process.env.LLAMA_INDEX_URL || 'http://localhost:9000', 33 | crewAiUrl: process.env.CREW_AI_URL || 'http://localhost:9002', 34 | pydanticAIUrl: process.env.PYDANTIC_AI_URL || 'http://localhost:9000', 35 | customDomainTitle: customDomainTitle, 36 | } 37 | } -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/lib/utils.ts: -------------------------------------------------------------------------------- 1 | import { type ClassValue, clsx } from "clsx"; 2 | import { twMerge } from "tailwind-merge"; 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/types/feature.ts: -------------------------------------------------------------------------------- 1 | export interface ViewerConfig { 2 | showCodeEditor?: boolean; 3 | showFileTree?: boolean; 4 | showLLMSelector?: boolean; 5 | } 6 | 7 | export interface FeatureFile { 8 | name: string; 9 | content: string; 10 | // path: string; 11 | language: string; 12 | type: string; 13 | } 14 | 15 | export interface FeatureConfig { 16 | id: string; 17 | name: string; 18 | description: string; 19 | path: string; 20 | tags?: string[]; 21 | } 22 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/types/integration.ts: -------------------------------------------------------------------------------- 1 | import { AbstractAgent } from "@ag-ui/client"; 2 | 3 | export type Feature = 4 | | "agentic_chat" 5 | | "agentic_generative_ui" 6 | | "human_in_the_loop" 7 | | "predictive_state_updates" 8 | | "shared_state" 9 | | "tool_based_generative_ui" 10 | | "agentic_chat_reasoning"; 11 | 12 | export interface MenuIntegrationConfig { 13 | id: string; 14 | name: string; 15 | features: Feature[]; 16 | } 17 | 18 | export interface AgentIntegrationConfig { 19 | id: string; 20 | agents: () => Promise>>; 21 | } 22 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/types/interface.ts: -------------------------------------------------------------------------------- 1 | export type View = "preview" | "code" | "readme"; 2 | -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/utils/domain-config.ts: -------------------------------------------------------------------------------- 1 | import getEnvVars from "@/env"; 2 | 3 | 4 | export function getTitleForCurrentDomain(): string | undefined { 5 | const envVars = getEnvVars(); 6 | 7 | // Check if we're in the browser 8 | if (typeof window == "undefined") { 9 | return undefined; 10 | } 11 | 12 | const host = window.location.hostname; 13 | return envVars.customDomainTitle[host] || undefined; 14 | } -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/src/utils/use-mobile-view.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export function useMobileView() { 4 | const [isMobile, setIsMobile] = useState(false); 5 | 6 | useEffect(() => { 7 | const checkMobile = () => { 8 | setIsMobile(window.innerWidth < 768); 9 | }; 10 | 11 | checkMobile(); 12 | window.addEventListener('resize', checkMobile); 13 | return () => window.removeEventListener('resize', checkMobile); 14 | }, []); 15 | 16 | return { 17 | isMobile, 18 | } 19 | } -------------------------------------------------------------------------------- /typescript-sdk/apps/dojo/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2017", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "noEmit": true, 9 | "esModuleInterop": true, 10 | "module": "esnext", 11 | "moduleResolution": "bundler", 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "jsx": "preserve", 15 | "incremental": true, 16 | "plugins": [ 17 | { 18 | "name": "next" 19 | } 20 | ], 21 | "paths": { 22 | "@/*": ["./src/*", "../../packages/client/src/*"], 23 | "@ag-ui/client": ["../../packages/client/src"], 24 | "@ag-ui/client/*": ["../../packages/client/src/*"] 25 | } 26 | }, 27 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 28 | "exclude": ["node_modules", "e2e", "e2e2"] 29 | } 30 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/agno/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/agno/README.md: -------------------------------------------------------------------------------- 1 | # @ag-ui/agno 2 | 3 | Implementation of the AG-UI protocol for Agno. 4 | 5 | Connects Agno agents to frontend applications via the AG-UI protocol using HTTP communication. 6 | 7 | ## Installation 8 | 9 | ```bash 10 | npm install @ag-ui/agno 11 | pnpm add @ag-ui/agno 12 | yarn add @ag-ui/agno 13 | ``` 14 | 15 | ## Usage 16 | 17 | ```ts 18 | import { AgnoAgent } from "@ag-ui/agno"; 19 | 20 | // Create an AG-UI compatible agent 21 | const agent = new AgnoAgent({ 22 | url: "https://your-agno-server.com/agent", 23 | headers: { Authorization: "Bearer your-token" }, 24 | }); 25 | 26 | // Run with streaming 27 | const result = await agent.runAgent({ 28 | messages: [{ role: "user", content: "Hello from Agno!" }], 29 | }); 30 | ``` 31 | 32 | ## Features 33 | 34 | - **HTTP connectivity** – Direct connection to Agno agent servers 35 | - **Multi-agent support** – Works with Agno's multi-agent system architecture 36 | - **Streaming responses** – Real-time communication with full AG-UI event support 37 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/agno/examples/README.md: -------------------------------------------------------------------------------- 1 | # Agno Finance Agent 2 | 3 | An Agno Agent with Finance tools for AG-UI that researches stock prices, analyst recommendations, and stock fundamentals. 4 | 5 | ## Setup 6 | 7 | This project uses [uv](https://github.com/astral-sh/uv) for dependency management. 8 | 9 | ### Prerequisites 10 | 11 | 1. Install uv: `pip install uv` 12 | 2. Set your OpenAI API key: `export OPENAI_API_KEY="your-api-key"` 13 | 14 | ### Installation 15 | 16 | ```bash 17 | # Install dependencies 18 | uv sync 19 | 20 | # Activate the virtual environment 21 | uv shell 22 | ``` 23 | 24 | ### Running the Agent 25 | 26 | ```bash 27 | # Run the agent 28 | uv run python agent.py 29 | ``` 30 | 31 | The agent will be available at `http://localhost:9001` (or the port specified by the `PORT` environment variable). 32 | 33 | ## Development 34 | 35 | ```bash 36 | # Install development dependencies 37 | uv sync --extra dev 38 | 39 | # Run tests 40 | uv run pytest 41 | 42 | # Format code 43 | uv run black . 44 | uv run isort . 45 | 46 | # Lint code 47 | uv run flake8 . 48 | ``` 49 | 50 | ## Features 51 | 52 | - Stock price lookup 53 | - Analyst recommendations 54 | - Stock fundamentals analysis 55 | - AG-UI compatible interface -------------------------------------------------------------------------------- /typescript-sdk/integrations/agno/examples/pyproject.toml: -------------------------------------------------------------------------------- 1 | tool.uv.package = true 2 | 3 | [project] 4 | name = "server" 5 | version = "0.1.0" 6 | description = "Example usage of the AG-UI adapter for Agno" 7 | license = "MIT" 8 | 9 | readme = "README.md" 10 | requires-python = ">=3.12" 11 | dependencies = [ 12 | "agno>=1.7.7", 13 | "openai>=1.99.1", 14 | "yfinance>=0.2.63", 15 | "fastapi>=0.116.1", 16 | "uvicorn>=0.35.0", 17 | "ag-ui-protocol>=0.1.8", 18 | ] 19 | authors = [ 20 | {name = "AG-UI Team"} 21 | ] 22 | 23 | 24 | [project.scripts] 25 | dev = "server:main" -------------------------------------------------------------------------------- /typescript-sdk/integrations/agno/examples/requirements.txt: -------------------------------------------------------------------------------- 1 | agno>=1.6.3 2 | openai>=1.88.0 3 | yfinance>=0.2.63 4 | fastapi>=0.115.13 5 | uvicorn>=0.34.3 6 | ag-ui-protocol>=0.1.5 -------------------------------------------------------------------------------- /typescript-sdk/integrations/agno/examples/server/__init__.py: -------------------------------------------------------------------------------- 1 | """Example usage of the AG-UI adapter for Agno. 2 | 3 | This provides a FastAPI application that demonstrates how to use the 4 | Agno agent with the AG-UI protocol. It includes examples for 5 | AG-UI dojo features: 6 | - Agentic Chat (Investment Analyst with Finance tools) 7 | """ 8 | 9 | from __future__ import annotations 10 | 11 | from fastapi import FastAPI 12 | import uvicorn 13 | import os 14 | 15 | from .api import ( 16 | agentic_chat_app, 17 | tool_based_generative_ui_app, 18 | ) 19 | 20 | app = FastAPI(title='Agno AG-UI server') 21 | app.mount('/agentic_chat', agentic_chat_app, 'Agentic Chat') 22 | app.mount('/tool_based_generative_ui', tool_based_generative_ui_app, 'Tool-based Generative UI') 23 | 24 | def main(): 25 | """Main function to start the FastAPI server.""" 26 | port = int(os.getenv("PORT", "9001")) 27 | uvicorn.run(app, host="0.0.0.0", port=port) 28 | 29 | if __name__ == "__main__": 30 | main() 31 | 32 | __all__ = ["main"] 33 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/agno/examples/server/api/__init__.py: -------------------------------------------------------------------------------- 1 | """Example API for a AG-UI compatible Agno Agent UI.""" 2 | 3 | from __future__ import annotations 4 | 5 | from .agentic_chat import app as agentic_chat_app 6 | from .tool_based_generative_ui import app as tool_based_generative_ui_app 7 | 8 | __all__ = [ 9 | 'agentic_chat_app', 10 | 'tool_based_generative_ui_app', 11 | ] -------------------------------------------------------------------------------- /typescript-sdk/integrations/agno/examples/server/api/agentic_chat.py: -------------------------------------------------------------------------------- 1 | """Example: Agno Agent with Finance tools 2 | 3 | This example shows how to create an Agno Agent with tools (YFinanceTools) and expose it in an AG-UI compatible way. 4 | """ 5 | from agno.agent.agent import Agent 6 | from agno.app.agui.app import AGUIApp 7 | from agno.models.openai import OpenAIChat 8 | from agno.tools.yfinance import YFinanceTools 9 | 10 | agent = Agent( 11 | model=OpenAIChat(id="gpt-4o"), 12 | tools=[ 13 | YFinanceTools( 14 | stock_price=True, analyst_recommendations=True, stock_fundamentals=True 15 | ) 16 | ], 17 | description="You are an investment analyst that researches stock prices, analyst recommendations, and stock fundamentals.", 18 | instructions="Format your response using markdown and use tables to display data where possible.", 19 | ) 20 | 21 | agui_app = AGUIApp( 22 | agent=agent, 23 | name="Investment Analyst", 24 | app_id="agentic_chat", 25 | description="An investment analyst that researches stock prices, analyst recommendations, and stock fundamentals.", 26 | ) 27 | 28 | app = agui_app.get_app() -------------------------------------------------------------------------------- /typescript-sdk/integrations/agno/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | passWithNoTests: true, 7 | moduleNameMapper: { 8 | "^@/(.*)$": "/src/$1", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/agno/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ag-ui/agno", 3 | "author": "Manu Hortet ", 4 | "version": "0.0.2", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "sideEffects": false, 9 | "files": [ 10 | "dist/**", 11 | "README.md" 12 | ], 13 | "private": false, 14 | "publishConfig": { 15 | "access": "public" 16 | }, 17 | "scripts": { 18 | "build": "tsup", 19 | "dev": "tsup --watch", 20 | "clean": "rm -rf dist .turbo node_modules", 21 | "typecheck": "tsc --noEmit", 22 | "test": "jest", 23 | "link:global": "pnpm link --global", 24 | "unlink:global": "pnpm unlink --global" 25 | }, 26 | "dependencies": { 27 | "@ag-ui/client": "workspace:*" 28 | }, 29 | "peerDependencies": { 30 | "rxjs": "7.8.1" 31 | }, 32 | "devDependencies": { 33 | "@types/jest": "^29.5.14", 34 | "@types/node": "^20.11.19", 35 | "jest": "^29.7.0", 36 | "ts-jest": "^29.1.2", 37 | "tsup": "^8.0.2", 38 | "typescript": "^5.3.3" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/agno/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * Agno is a framework for building Multi-Agent Systems with memory, knowledge and reasoning. 3 | * Check more about using Agno: https://docs.agno.com/ 4 | */ 5 | 6 | import { HttpAgent } from "@ag-ui/client"; 7 | 8 | export class AgnoAgent extends HttpAgent {} 9 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/agno/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "moduleResolution": "node", 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "jsx": "react-jsx", 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | "stripInternal": true 21 | }, 22 | "include": ["src"], 23 | "exclude": ["node_modules", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/agno/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | minify: true, 11 | }); 12 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | server 14 | python 15 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/README.md: -------------------------------------------------------------------------------- 1 | # @ag-ui/crewai 2 | 3 | Implementation of the AG-UI protocol for CrewAI. 4 | 5 | Connects CrewAI Flows and Crews to frontend applications via the AG-UI protocol. Supports both TypeScript HTTP clients and Python FastAPI server integration with streaming crew execution. 6 | 7 | ## Installation 8 | 9 | ```bash 10 | npm install @ag-ui/crewai 11 | pnpm add @ag-ui/crewai 12 | yarn add @ag-ui/crewai 13 | ``` 14 | 15 | ## Usage 16 | 17 | ```ts 18 | import { CrewAIAgent } from "@ag-ui/crewai"; 19 | 20 | // Create an AG-UI compatible agent 21 | const agent = new CrewAIAgent({ 22 | url: "http://localhost:8000/crew-endpoint", 23 | headers: { "Content-Type": "application/json" }, 24 | }); 25 | 26 | // Run with streaming 27 | const result = await agent.runAgent({ 28 | messages: [{ role: "user", content: "Execute the research crew" }], 29 | }); 30 | ``` 31 | 32 | ## Features 33 | 34 | - **HTTP connectivity** – Connect to CrewAI FastAPI servers 35 | - **Flow & Crew support** – Works with both CrewAI Flows and traditional Crews 36 | - **Step tracking** – Real-time crew execution progress 37 | - **Python integration** – Full FastAPI server implementation included 38 | 39 | ## To run the example server in the dojo 40 | 41 | ```bash 42 | cd typescript-sdk/integrations/crewai/python 43 | poetry install && poetry run dev 44 | ``` 45 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | passWithNoTests: true, 7 | moduleNameMapper: { 8 | "^@/(.*)$": "/src/$1", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ag-ui/crewai", 3 | "author": "Markus Ecker ", 4 | "version": "0.0.2", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "sideEffects": false, 9 | "files": [ 10 | "dist/**", 11 | "README.md" 12 | ], 13 | "private": false, 14 | "publishConfig": { 15 | "access": "public" 16 | }, 17 | "scripts": { 18 | "build": "tsup", 19 | "dev": "tsup --watch", 20 | "clean": "rm -rf dist", 21 | "typecheck": "tsc --noEmit", 22 | "test": "jest", 23 | "link:global": "pnpm link --global", 24 | "unlink:global": "pnpm unlink --global" 25 | }, 26 | "dependencies": { 27 | "@ag-ui/client": "workspace:*" 28 | }, 29 | "peerDependencies": { 30 | "rxjs": "7.8.1" 31 | }, 32 | "devDependencies": { 33 | "@types/jest": "^29.5.14", 34 | "@types/node": "^20.11.19", 35 | "jest": "^29.7.0", 36 | "ts-jest": "^29.1.2", 37 | "tsup": "^8.0.2", 38 | "typescript": "^5.3.3" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/python/ag_ui_crewai/__init__.py: -------------------------------------------------------------------------------- 1 | from .endpoint import add_crewai_flow_fastapi_endpoint 2 | from .sdk import ( 3 | CopilotKitState, 4 | copilotkit_predict_state, 5 | copilotkit_emit_state, 6 | copilotkit_stream 7 | ) 8 | # from .enterprise import CrewEnterpriseEventListener 9 | 10 | # CREW_ENTERPRISE_EVENT_LISTENER = CrewEnterpriseEventListener() 11 | 12 | __all__ = [ 13 | "add_crewai_flow_fastapi_endpoint", 14 | "CopilotKitState", 15 | "copilotkit_predict_state", 16 | "copilotkit_emit_state", 17 | "copilotkit_stream" 18 | ] 19 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/python/ag_ui_crewai/context.py: -------------------------------------------------------------------------------- 1 | import contextvars 2 | from typing import TYPE_CHECKING 3 | 4 | if TYPE_CHECKING: 5 | from crewai.flow.flow import Flow 6 | 7 | flow_context: contextvars.ContextVar['Flow'] = contextvars.ContextVar('flow') 8 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/python/ag_ui_crewai/dojo.py: -------------------------------------------------------------------------------- 1 | import os 2 | import uvicorn 3 | from fastapi import FastAPI 4 | 5 | from .endpoint import add_crewai_flow_fastapi_endpoint 6 | from .examples.agentic_chat import AgenticChatFlow 7 | from .examples.human_in_the_loop import HumanInTheLoopFlow 8 | from .examples.tool_based_generative_ui import ToolBasedGenerativeUIFlow 9 | from .examples.agentic_generative_ui import AgenticGenerativeUIFlow 10 | from .examples.shared_state import SharedStateFlow 11 | from .examples.predictive_state_updates import PredictiveStateUpdatesFlow 12 | 13 | app = FastAPI(title="CrewAI Dojo Example Server") 14 | 15 | add_crewai_flow_fastapi_endpoint( 16 | app=app, 17 | flow=AgenticChatFlow(), 18 | path="/agentic_chat", 19 | ) 20 | 21 | add_crewai_flow_fastapi_endpoint( 22 | app=app, 23 | flow=HumanInTheLoopFlow(), 24 | path="/human_in_the_loop", 25 | ) 26 | 27 | add_crewai_flow_fastapi_endpoint( 28 | app=app, 29 | flow=ToolBasedGenerativeUIFlow(), 30 | path="/tool_based_generative_ui", 31 | ) 32 | 33 | add_crewai_flow_fastapi_endpoint( 34 | app=app, 35 | flow=AgenticGenerativeUIFlow(), 36 | path="/agentic_generative_ui", 37 | ) 38 | 39 | add_crewai_flow_fastapi_endpoint( 40 | app=app, 41 | flow=SharedStateFlow(), 42 | path="/shared_state", 43 | ) 44 | 45 | add_crewai_flow_fastapi_endpoint( 46 | app=app, 47 | flow=PredictiveStateUpdatesFlow(), 48 | path="/predictive_state_updates", 49 | ) 50 | 51 | def main(): 52 | """Run the uvicorn server.""" 53 | port = int(os.getenv("PORT", "8000")) 54 | uvicorn.run( 55 | "ag_ui_crewai.dojo:app", 56 | host="0.0.0.0", 57 | port=port, 58 | reload=True 59 | ) 60 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/python/ag_ui_crewai/events.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file is used to bridge the events from the crewai event bus to the ag-ui event bus. 3 | """ 4 | 5 | from crewai.utilities.events.base_events import BaseEvent 6 | from ag_ui.core.events import ( 7 | ToolCallChunkEvent, 8 | TextMessageChunkEvent, 9 | CustomEvent, 10 | StateSnapshotEvent 11 | ) 12 | 13 | class BridgedToolCallChunkEvent(BaseEvent, ToolCallChunkEvent): 14 | """Bridged tool call chunk event""" 15 | 16 | class BridgedTextMessageChunkEvent(BaseEvent, TextMessageChunkEvent): 17 | """Bridged text message chunk event""" 18 | 19 | class BridgedCustomEvent(BaseEvent, CustomEvent): 20 | """Bridged custom event""" 21 | 22 | class BridgedStateSnapshotEvent(BaseEvent, StateSnapshotEvent): 23 | """Bridged state snapshot event""" -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/python/ag_ui_crewai/examples/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/crewai/python/ag_ui_crewai/examples/__init__.py -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/python/ag_ui_crewai/utils.py: -------------------------------------------------------------------------------- 1 | import asyncio 2 | 3 | async def yield_control(): 4 | """ 5 | Yield control to the event loop. 6 | """ 7 | loop = asyncio.get_running_loop() 8 | future = loop.create_future() 9 | loop.call_soon(future.set_result, None) 10 | await future 11 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "ag-ui-crewai" 3 | version = "0.1.4" 4 | description = "Implementation of the AG-UI protocol for CrewAI" 5 | authors = ["Markus Ecker "] 6 | readme = "README.md" 7 | exclude = [ 8 | "ag_ui_crewai/dojo.py", 9 | "ag_ui_crewai/examples/**", 10 | ] 11 | 12 | [tool.poetry.dependencies] 13 | python = "<3.14,>=3.10" 14 | ag-ui-protocol = "==0.1.5" 15 | fastapi = "^0.115.12" 16 | uvicorn = "^0.34.3" 17 | crewai = "^0.130.0" 18 | 19 | [build-system] 20 | requires = ["poetry-core"] 21 | build-backend = "poetry.core.masonry.api" 22 | 23 | [tool.poetry.scripts] 24 | dev = "ag_ui_crewai.dojo:main" -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/python/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/crewai/python/tests/__init__.py -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/src/index.ts: -------------------------------------------------------------------------------- 1 | import { HttpAgent } from "@ag-ui/client"; 2 | 3 | export class CrewAIAgent extends HttpAgent {} 4 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "moduleResolution": "node", 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "jsx": "react-jsx", 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | "stripInternal": true 21 | }, 22 | "include": ["src"], 23 | "exclude": ["node_modules", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/crewai/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | minify: true, 11 | }); 12 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | examples -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/README.md: -------------------------------------------------------------------------------- 1 | # @ag-ui/langgraph 2 | 3 | Implementation of the AG-UI protocol for LangGraph. 4 | 5 | Connects LangGraph graphs to frontend applications via the AG-UI protocol. Supports both local TypeScript graphs and remote LangGraph Cloud deployments with full state management and interrupt handling. 6 | 7 | ## Installation 8 | 9 | ```bash 10 | npm install @ag-ui/langgraph 11 | pnpm add @ag-ui/langgraph 12 | yarn add @ag-ui/langgraph 13 | ``` 14 | 15 | ## Usage 16 | 17 | ```ts 18 | import { LangGraphAgent } from "@ag-ui/langgraph"; 19 | 20 | // Create an AG-UI compatible agent 21 | const agent = new LangGraphAgent({ 22 | graphId: "my-graph", 23 | deploymentUrl: "https://your-langgraph-deployment.com", 24 | langsmithApiKey: "your-api-key", 25 | }); 26 | 27 | // Run with streaming 28 | const result = await agent.runAgent({ 29 | messages: [{ role: "user", content: "Start the workflow" }], 30 | }); 31 | ``` 32 | 33 | ## Features 34 | 35 | - **Cloud & local support** – Works with LangGraph Cloud and local graph instances 36 | - **State management** – Bidirectional state synchronization with graph nodes 37 | - **Interrupt handling** – Human-in-the-loop workflow support 38 | - **Step tracking** – Real-time node execution progress 39 | 40 | ## To run the example server in the dojo 41 | 42 | ```bash 43 | cd typescript-sdk/integrations/langgraph/examples 44 | langgraph dev 45 | ``` 46 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/.gitignore: -------------------------------------------------------------------------------- 1 | # LangGraph API 2 | .langgraph_api 3 | __pycache__ 4 | uv.lock -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/python/.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY= 2 | LANGSMITH_API_KEY= 3 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/python/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # LangGraph API 3 | .langgraph_api 4 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/python/README.md: -------------------------------------------------------------------------------- 1 | # LangGraph examples 2 | 3 | ## How to run 4 | 5 | First, make sure to create a new .env file from the .env.example and include the required keys. 6 | 7 | To run the Python examples for langgraph platform, run: 8 | ``` 9 | cd typescript-sdk/integrations/langgraph/examples/python 10 | pnpx @langchain/langgraph-cli@latest dev 11 | ``` 12 | 13 | To run the python examples using FastAPI, run: 14 | ``` 15 | cd typescript-sdk/integrations/langgraph/examples/python 16 | poetry install 17 | poetry run dev 18 | ``` 19 | 20 | Note that when running them both concurrently, poetry and the langgraph-cli will step on eachothers toes and install/uninstall eachothers dependencies. 21 | You can fix this by running the poetry commands with virtualenvs.in-project set to false. You can set this permanently for the project using: 22 | `poetry config virtualenvs.create false --local`, globally using `poetry config virtualenvs.create false`, or temporarily using an environment variable: 23 | 24 | ``` 25 | export POETRY_VIRTUALENVS_IN_PROJECT=false 26 | poetry install 27 | poetry run dev 28 | ``` 29 | or 30 | ``` 31 | POETRY_VIRTUALENVS_IN_PROJECT=false poetry install 32 | POETRY_VIRTUALENVS_IN_PROJECT=false poetry run dev 33 | ``` 34 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/python/agents/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/langgraph/examples/python/agents/__init__.py -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/python/agents/agentic_chat/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/langgraph/examples/python/agents/agentic_chat/__init__.py -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/python/agents/agentic_chat_reasoning/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/langgraph/examples/python/agents/agentic_chat_reasoning/__init__.py -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/python/agents/agentic_generative_ui/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/langgraph/examples/python/agents/agentic_generative_ui/__init__.py -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/python/agents/human_in_the_loop/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/langgraph/examples/python/agents/human_in_the_loop/__init__.py -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/python/agents/predictive_state_updates/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/langgraph/examples/python/agents/predictive_state_updates/__init__.py -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/python/agents/shared_state/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/langgraph/examples/python/agents/shared_state/__init__.py -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/python/agents/tool_based_generative_ui/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/langgraph/examples/python/agents/tool_based_generative_ui/__init__.py -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/python/langgraph.json: -------------------------------------------------------------------------------- 1 | { 2 | "python_version": "3.12", 3 | "dockerfile_lines": [], 4 | "dependencies": ["."], 5 | "graphs": { 6 | "agentic_chat": "./agents/agentic_chat/agent.py:graph", 7 | "agentic_generative_ui": "./agents/agentic_generative_ui/agent.py:graph", 8 | "human_in_the_loop": "./agents/human_in_the_loop/agent.py:graph", 9 | "predictive_state_updates": "./agents/predictive_state_updates/agent.py:graph", 10 | "shared_state": "./agents/shared_state/agent.py:graph", 11 | "tool_based_generative_ui": "./agents/tool_based_generative_ui/agent.py:graph", 12 | "agentic_chat_reasoning": "./agents/agentic_chat_reasoning/agent.py:graph" 13 | }, 14 | "env": ".env" 15 | } 16 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "langgraph_agui_dojo" 3 | version = "0.1.0" 4 | description = "" 5 | readme = "README.md" 6 | packages = [{ include = "agents" }] 7 | 8 | [project] 9 | name = "agents" 10 | version = "0.0.1" 11 | 12 | [tool.poetry.dependencies] 13 | python = ">=3.12,<3.14" 14 | uvicorn = "^0.34.0" 15 | dotenv = "^0.9.9" 16 | langchain = ">=0.1.0" 17 | langchain-anthropic = ">=0.3.18" 18 | langchain-core = ">=0.1.5" 19 | langchain-community = ">=0.0.1" 20 | langchain-experimental = ">=0.0.11" 21 | langchain-google-genai = ">=2.1.9" 22 | langchain-openai = ">=0.0.1" 23 | langgraph = "^0.6.1" 24 | ag-ui-langgraph = { version = "0.0.5", extras = ["fastapi"] } 25 | python-dotenv = "^1.0.0" 26 | fastapi = "^0.115.12" 27 | 28 | [build-system] 29 | requires = ["poetry-core"] 30 | build-backend = "poetry.core.masonry.api" 31 | 32 | [tool.poetry.scripts] 33 | dev = "agents.dojo:main" -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/typescript/.env.example: -------------------------------------------------------------------------------- 1 | OPENAI_API_KEY=your_openai_api_key_here 2 | TAVILY_API_KEY=your_tavily_api_key_here -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/typescript/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # LangGraph API 3 | .langgraph_api 4 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/typescript/langgraph.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": ["."], 3 | "graphs": { 4 | "agentic_chat": "./src/agents/agentic_chat/agent.ts:agenticChatGraph", 5 | "agentic_generative_ui": "./src/agents/agentic_generative_ui/agent.ts:agenticGenerativeUiGraph", 6 | "human_in_the_loop": "./src/agents/human_in_the_loop/agent.ts:humanInTheLoopGraph", 7 | "predictive_state_updates": "./src/agents/predictive_state_updates/agent.ts:predictiveStateUpdatesGraph", 8 | "shared_state": "./src/agents/shared_state/agent.ts:sharedStateGraph", 9 | "tool_based_generative_ui": "./src/agents/tool_based_generative_ui/agent.ts:toolBasedGenerativeUiGraph" 10 | }, 11 | "env": ".env" 12 | } 13 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/typescript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "langgraph-agui-dojo-typescript", 3 | "version": "0.1.0", 4 | "description": "TypeScript examples for LangGraph agents with CopilotKit integration", 5 | "type": "module", 6 | "scripts": { 7 | "build": "tsc", 8 | "dev": "pnpx @langchain/langgraph-cli@latest dev", 9 | "start": "node dist/index.js" 10 | }, 11 | "dependencies": { 12 | "@langchain/core": "^0.3.66", 13 | "@langchain/openai": "^0.6.3", 14 | "@langchain/langgraph": "^0.2.65", 15 | "dotenv": "^16.4.5", 16 | "uuid": "^10.0.0" 17 | }, 18 | "devDependencies": { 19 | "@types/node": "^20.0.0", 20 | "@types/uuid": "^10.0.0", 21 | "typescript": "^5.0.0" 22 | } 23 | } -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/typescript/pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - '.' -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/examples/typescript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2020", 4 | "module": "ESNext", 5 | "moduleResolution": "node", 6 | "esModuleInterop": true, 7 | "allowSyntheticDefaultImports": true, 8 | "strict": true, 9 | "skipLibCheck": true, 10 | "forceConsistentCasingInFileNames": true, 11 | "outDir": "./dist", 12 | "rootDir": "./src", 13 | "declaration": true, 14 | "declarationMap": true, 15 | "sourceMap": true 16 | }, 17 | "include": ["src/**/*"], 18 | "exclude": ["node_modules", "dist"] 19 | } -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | passWithNoTests: true, 7 | moduleNameMapper: { 8 | "^@/(.*)$": "/src/$1", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ag-ui/langgraph", 3 | "version": "0.0.9", 4 | "main": "./dist/index.js", 5 | "module": "./dist/index.mjs", 6 | "types": "./dist/index.d.ts", 7 | "sideEffects": false, 8 | "private": false, 9 | "publishConfig": { 10 | "access": "public" 11 | }, 12 | "files": [ 13 | "dist/**", 14 | "README.md" 15 | ], 16 | "scripts": { 17 | "build": "tsup", 18 | "dev": "tsup --watch", 19 | "clean": "rm -rf dist .turbo node_modules", 20 | "typecheck": "tsc --noEmit", 21 | "test": "jest", 22 | "link:global": "pnpm link --global", 23 | "unlink:global": "pnpm unlink --global" 24 | }, 25 | "dependencies": { 26 | "@ag-ui/client": "workspace:*", 27 | "@langchain/core": "^0.3.66", 28 | "@langchain/langgraph-sdk": "^0.0.105", 29 | "partial-json": "^0.1.7", 30 | "rxjs": "7.8.1" 31 | }, 32 | "devDependencies": { 33 | "@types/jest": "^29.5.14", 34 | "@types/node": "^20.11.19", 35 | "jest": "^29.7.0", 36 | "ts-jest": "^29.1.2", 37 | "tsup": "^8.0.2", 38 | "typescript": "^5.3.3" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/python/README.md: -------------------------------------------------------------------------------- 1 | # ag-ui-langgraph 2 | 3 | Implementation of the AG-UI protocol for LangGraph. 4 | 5 | Provides a complete Python integration for LangGraph agents with the AG-UI protocol, including FastAPI endpoint creation and comprehensive event streaming. 6 | 7 | ## Installation 8 | 9 | ```bash 10 | pip install ag-ui-langgraph 11 | ``` 12 | 13 | ## Usage 14 | 15 | ```python 16 | from langgraph.graph import StateGraph, MessagesState 17 | from langchain_openai import ChatOpenAI 18 | from ag_ui_langgraph import LangGraphAgent, add_langgraph_fastapi_endpoint 19 | from fastapi import FastAPI 20 | from my_langgraph_workflow import graph 21 | 22 | # Add to FastAPI 23 | app = FastAPI() 24 | add_langgraph_fastapi_endpoint(app, graph, "/agent") 25 | ``` 26 | 27 | ## Features 28 | 29 | - **Native LangGraph integration** – Direct support for LangGraph workflows and state management 30 | - **FastAPI endpoint creation** – Automatic HTTP endpoint generation with proper event streaming 31 | - **Advanced event handling** – Comprehensive support for all AG-UI events including thinking, tool calls, and state updates 32 | - **Message translation** – Seamless conversion between AG-UI and LangChain message formats 33 | 34 | ## To run the dojo examples 35 | 36 | ```bash 37 | cd python/ag_ui_langgraph/examples 38 | poetry install 39 | poetry run dev 40 | ``` 41 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/__init__.py: -------------------------------------------------------------------------------- 1 | from .agent import LangGraphAgent 2 | from .types import ( 3 | LangGraphEventTypes, 4 | CustomEventNames, 5 | State, 6 | SchemaKeys, 7 | MessageInProgress, 8 | RunMetadata, 9 | MessagesInProgressRecord, 10 | ToolCall, 11 | BaseLangGraphPlatformMessage, 12 | LangGraphPlatformResultMessage, 13 | LangGraphPlatformActionExecutionMessage, 14 | LangGraphPlatformMessage, 15 | PredictStateTool 16 | ) 17 | from .endpoint import add_langgraph_fastapi_endpoint 18 | 19 | __all__ = [ 20 | "LangGraphAgent", 21 | "LangGraphEventTypes", 22 | "CustomEventNames", 23 | "State", 24 | "SchemaKeys", 25 | "MessageInProgress", 26 | "RunMetadata", 27 | "MessagesInProgressRecord", 28 | "ToolCall", 29 | "BaseLangGraphPlatformMessage", 30 | "LangGraphPlatformResultMessage", 31 | "LangGraphPlatformActionExecutionMessage", 32 | "LangGraphPlatformMessage", 33 | "PredictStateTool", 34 | "add_langgraph_fastapi_endpoint" 35 | ] 36 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/python/ag_ui_langgraph/endpoint.py: -------------------------------------------------------------------------------- 1 | from fastapi import FastAPI, HTTPException, Request 2 | from fastapi.responses import StreamingResponse 3 | 4 | from ag_ui.core.types import RunAgentInput 5 | from ag_ui.encoder import EventEncoder 6 | 7 | from .agent import LangGraphAgent 8 | 9 | def add_langgraph_fastapi_endpoint(app: FastAPI, agent: LangGraphAgent, path: str = "/"): 10 | """Adds an endpoint to the FastAPI app.""" 11 | 12 | @app.post(path) 13 | async def langgraph_agent_endpoint(input_data: RunAgentInput, request: Request): 14 | # Get the accept header from the request 15 | accept_header = request.headers.get("accept") 16 | 17 | # Create an event encoder to properly format SSE events 18 | encoder = EventEncoder(accept=accept_header) 19 | 20 | async def event_generator(): 21 | async for event in agent.run(input_data): 22 | yield encoder.encode(event) 23 | 24 | return StreamingResponse( 25 | event_generator(), 26 | media_type=encoder.get_content_type() 27 | ) -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "ag-ui-langgraph" 3 | version = "0.0.6" 4 | description = "Implementation of the AG-UI protocol for LangGraph." 5 | authors = ["Ran Shem Tov "] 6 | readme = "README.md" 7 | exclude = [ 8 | "ag_ui_langgraph/examples/**", 9 | ] 10 | 11 | [tool.poetry.dependencies] 12 | python = "<3.14,>=3.10" 13 | ag-ui-protocol = "==0.1.7" 14 | fastapi = { version = "^0.115.12", optional = true } 15 | langchain = ">=0.3.0" 16 | langchain-core = ">=0.3.0" 17 | langgraph = ">=0.3.25,<0.7.0" 18 | 19 | [tool.poetry.extras] 20 | fastapi = ["fastapi"] 21 | 22 | [build-system] 23 | requires = ["poetry-core"] 24 | build-backend = "poetry.core.masonry.api" 25 | 26 | [tool.poetry.scripts] 27 | dev = "ag_ui_langgraph.dojo:main" -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/python/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/langgraph/python/tests/__init__.py -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/src/index.ts: -------------------------------------------------------------------------------- 1 | import { HttpAgent } from "@ag-ui/client"; 2 | 3 | export * from './agent' 4 | export class LangGraphHttpAgent extends HttpAgent {} -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "moduleResolution": "node", 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "jsx": "react-jsx", 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | "stripInternal": true 21 | }, 22 | "include": ["src"], 23 | "exclude": ["node_modules", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/langgraph/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | minify: true, 11 | }); 12 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/llamaindex/.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | *egg-info 3 | .venv 4 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/llamaindex/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/llamaindex/README.md: -------------------------------------------------------------------------------- 1 | # @ag-ui/llamaindex 2 | 3 | Implementation of the AG-UI protocol for LlamaIndex. 4 | 5 | Connects LlamaIndex workflows to frontend applications via the AG-UI protocol. Provides HTTP connectivity to LlamaIndex servers with support for RAG pipelines and workflow orchestration. 6 | 7 | ## Installation 8 | 9 | ```bash 10 | npm install @ag-ui/llamaindex 11 | pnpm add @ag-ui/llamaindex 12 | yarn add @ag-ui/llamaindex 13 | ``` 14 | 15 | ## Usage 16 | 17 | ```ts 18 | import { LlamaIndexAgent } from "@ag-ui/llamaindex"; 19 | 20 | // Create an AG-UI compatible agent 21 | const agent = new LlamaIndexAgent({ 22 | url: "http://localhost:9000/agentic_chat", 23 | headers: { "Content-Type": "application/json" }, 24 | }); 25 | 26 | // Run with streaming 27 | const result = await agent.runAgent({ 28 | messages: [{ role: "user", content: "Query my documents" }], 29 | }); 30 | ``` 31 | 32 | ## Features 33 | 34 | - **HTTP connectivity** – Connect to LlamaIndex FastAPI servers 35 | - **Workflow support** – Full integration with LlamaIndex workflow orchestration 36 | - **RAG capabilities** – Document retrieval and reasoning workflows 37 | - **Python integration** – Complete FastAPI server implementation included 38 | 39 | ## To run the example server in the dojo 40 | 41 | ```bash 42 | cd typescript-sdk/integrations/llamaindex/server-py 43 | uv sync && uv run dev 44 | ``` 45 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/llamaindex/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | passWithNoTests: true, 7 | moduleNameMapper: { 8 | "^@/(.*)$": "/src/$1", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/llamaindex/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ag-ui/llamaindex", 3 | "author": "Logan Markewich ", 4 | "version": "0.1.2", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "sideEffects": false, 9 | "files": [ 10 | "dist/**", 11 | "README.md" 12 | ], 13 | "private": false, 14 | "publishConfig": { 15 | "access": "public" 16 | }, 17 | "scripts": { 18 | "build": "tsup", 19 | "dev": "tsup --watch", 20 | "clean": "rm -rf dist", 21 | "typecheck": "tsc --noEmit", 22 | "test": "jest", 23 | "link:global": "pnpm link --global", 24 | "unlink:global": "pnpm unlink --global" 25 | }, 26 | "dependencies": { 27 | "@ag-ui/client": "workspace:*" 28 | }, 29 | "peerDependencies": { 30 | "rxjs": "7.8.1" 31 | }, 32 | "devDependencies": { 33 | "@types/jest": "^29.5.14", 34 | "@types/node": "^20.11.19", 35 | "jest": "^29.7.0", 36 | "ts-jest": "^29.1.2", 37 | "tsup": "^8.0.2", 38 | "typescript": "^5.3.3" 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/llamaindex/server-py/README.md: -------------------------------------------------------------------------------- 1 | # LlamaIndex Python AG-UI Integration 2 | 3 | This package provides a FastAPI server that is bootstrapped with several AG-UI+LlamaIndex endpoints. It can be used to communicate with AG-UI compatible frameworks like [CopilotKit](https://docs.copilotkit.ai/). 4 | 5 | ## Usage 6 | 7 | Launch the server with: 8 | 9 | ```python 10 | uv sync 11 | uv run dev 12 | ``` 13 | 14 | Launch the frontend dojo with: 15 | 16 | ```bash 17 | cd ../../ 18 | pnpm install 19 | turbo run dev 20 | ``` 21 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/llamaindex/server-py/pyproject.toml: -------------------------------------------------------------------------------- 1 | [build-system] 2 | requires = ["hatchling"] 3 | build-backend = "hatchling.build" 4 | 5 | [project] 6 | name = "server" 7 | version = "0.1.0" 8 | description = "Add your description here" 9 | readme = "README.md" 10 | requires-python = ">=3.9, <3.14" 11 | dependencies = [ 12 | "llama-index-core>=0.12.41,<0.13", 13 | "llama-index-agent-openai>=0.4.9,<0.5", 14 | "llama-index-protocols-ag-ui>=0.1.2", 15 | "jsonpatch>=1.33", 16 | "uvicorn>=0.27.0", 17 | "fastapi>=0.100.0", 18 | ] 19 | authors = [ 20 | { name = "Logan Markewich", email = "logan@runllama.ai" }, 21 | ] 22 | 23 | [tool.hatch.build.targets.sdist] 24 | include = ["server/"] 25 | 26 | [tool.hatch.build.targets.wheel] 27 | include = ["server/"] 28 | 29 | [project.scripts] 30 | dev = "server:main" 31 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/llamaindex/server-py/server/__init__.py: -------------------------------------------------------------------------------- 1 | import os 2 | import uvicorn 3 | from fastapi import FastAPI 4 | 5 | from .routers.agentic_chat import agentic_chat_router 6 | from .routers.human_in_the_loop import human_in_the_loop_router 7 | from .routers.agentic_generative_ui import agentic_generative_ui_router 8 | from .routers.shared_state import shared_state_router 9 | 10 | app = FastAPI(title="AG-UI Llama-Index Endpoint") 11 | 12 | app.include_router(agentic_chat_router, prefix="/agentic_chat") 13 | app.include_router(human_in_the_loop_router, prefix="/human_in_the_loop") 14 | app.include_router(agentic_generative_ui_router, prefix="/agentic_generative_ui") 15 | app.include_router(shared_state_router, prefix="/shared_state") 16 | 17 | def main(): 18 | 19 | """Main function to start the FastAPI server.""" 20 | port = int(os.getenv("PORT", "9000")) 21 | 22 | uvicorn.run(app, host="0.0.0.0", port=port) 23 | 24 | if __name__ == "__main__": 25 | main() 26 | 27 | __all__ = ["main"] 28 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/llamaindex/server-py/server/routers/agentic_chat.py: -------------------------------------------------------------------------------- 1 | from llama_index.llms.openai import OpenAI 2 | from llama_index.protocols.ag_ui.router import get_ag_ui_workflow_router 3 | from typing import Annotated 4 | 5 | 6 | # This tool has a client-side version that is actually called to change the background 7 | def change_background( 8 | background: Annotated[str, "The background. Prefer gradients."], 9 | ) -> str: 10 | """Change the background color of the chat. Can be anything that the CSS background attribute accepts. Regular colors, linear of radial gradients etc.""" 11 | return f"Changing background to {background}" 12 | 13 | agentic_chat_router = get_ag_ui_workflow_router( 14 | llm=OpenAI(model="gpt-4.1"), 15 | frontend_tools=[change_background], 16 | ) 17 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/llamaindex/server-py/server/routers/human_in_the_loop.py: -------------------------------------------------------------------------------- 1 | from typing import Literal, List 2 | from pydantic import BaseModel 3 | 4 | from llama_index.llms.openai import OpenAI 5 | from llama_index.protocols.ag_ui.router import get_ag_ui_workflow_router 6 | 7 | 8 | 9 | class Step(BaseModel): 10 | description: str 11 | status: Literal["enabled", "disabled", "executing"] 12 | 13 | 14 | def generate_task_steps(steps: List[Step]) -> str: 15 | return f"Generated {len(steps)} steps" 16 | 17 | 18 | human_in_the_loop_router = get_ag_ui_workflow_router( 19 | llm=OpenAI(model="gpt-4.1"), 20 | frontend_tools=[generate_task_steps], 21 | ) 22 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/llamaindex/server-py/server/routers/shared_state.py: -------------------------------------------------------------------------------- 1 | from typing import Literal, List 2 | from pydantic import BaseModel 3 | 4 | from llama_index.core.workflow import Context 5 | from llama_index.llms.openai import OpenAI 6 | from llama_index.protocols.ag_ui.events import StateSnapshotWorkflowEvent 7 | from llama_index.protocols.ag_ui.router import get_ag_ui_workflow_router 8 | 9 | 10 | class Ingredient(BaseModel): 11 | icon: str 12 | name: str 13 | amount: str 14 | 15 | class Recipe(BaseModel): 16 | skill_level: str 17 | special_preferences: List[str] 18 | cooking_time: str 19 | ingredients: List[Ingredient] 20 | instructions: List[str] 21 | 22 | 23 | async def update_recipe(ctx: Context, recipe: Recipe) -> str: 24 | """Useful for recording a recipe to shared state.""" 25 | recipe = Recipe.model_validate(recipe) 26 | 27 | state = await ctx.get("state") 28 | if state is None: 29 | state = {} 30 | 31 | state["recipe"] = recipe.model_dump() 32 | 33 | ctx.write_event_to_stream( 34 | StateSnapshotWorkflowEvent( 35 | snapshot=state 36 | ) 37 | ) 38 | 39 | await ctx.set("state", state) 40 | 41 | return "Recipe updated!" 42 | 43 | 44 | shared_state_router = get_ag_ui_workflow_router( 45 | llm=OpenAI(model="gpt-4.1"), 46 | frontend_tools=[update_recipe], 47 | initial_state={ 48 | "recipe": None, 49 | } 50 | ) 51 | 52 | 53 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/llamaindex/src/index.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * LlamaIndex is a simple, flexible framework for building agentic generative AI applications that allow large language models to work with your data in any format. 3 | * Check more about using LlamaIndex: https://docs.llamaindex.ai/ 4 | */ 5 | 6 | import { HttpAgent } from "@ag-ui/client"; 7 | 8 | export class LlamaIndexAgent extends HttpAgent {} 9 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/llamaindex/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "moduleResolution": "node", 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "jsx": "react-jsx", 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | "stripInternal": true 21 | }, 22 | "include": ["src"], 23 | "exclude": ["node_modules", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/llamaindex/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | minify: true, 11 | }); 12 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/mastra/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | example 14 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/mastra/README.md: -------------------------------------------------------------------------------- 1 | # @ag-ui/mastra 2 | 3 | Implementation of the AG-UI protocol for Mastra. 4 | 5 | Connects Mastra agents (local and remote) to frontend applications via the AG-UI protocol. Supports streaming responses, memory management, and tool execution. 6 | 7 | ## Installation 8 | 9 | ```bash 10 | npm install @ag-ui/mastra 11 | pnpm add @ag-ui/mastra 12 | yarn add @ag-ui/mastra 13 | ``` 14 | 15 | ## Usage 16 | 17 | ```ts 18 | import { MastraAgent } from "@ag-ui/mastra"; 19 | import { mastra } from "./mastra"; // Your Mastra instance 20 | 21 | // Create an AG-UI compatible agent 22 | const agent = new MastraAgent({ 23 | agent: mastra.getAgent("weather-agent"), 24 | resourceId: "user-123", 25 | }); 26 | 27 | // Run with streaming 28 | const result = await agent.runAgent({ 29 | messages: [{ role: "user", content: "What's the weather like?" }], 30 | }); 31 | ``` 32 | 33 | ## Features 34 | 35 | - **Local & remote agents** – Works with in-process and network Mastra agents 36 | - **Memory integration** – Automatic thread and working memory management 37 | - **Tool streaming** – Real-time tool call execution and results 38 | - **State management** – Bidirectional state synchronization 39 | 40 | ## To run the example server in the dojo 41 | 42 | ```bash 43 | cd typescript-sdk/integrations/mastra/example 44 | pnpm install 45 | pnpm run dev 46 | ``` 47 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/mastra/example/.gitignore: -------------------------------------------------------------------------------- 1 | output.txt 2 | node_modules 3 | dist 4 | .mastra 5 | .env.development 6 | .env 7 | *.db 8 | *.db-* 9 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/mastra/example/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "version": "1.0.0", 4 | "main": "index.js", 5 | "scripts": { 6 | "test": "echo \"Error: no test specified\" && exit 1", 7 | "dev": "mastra dev", 8 | "build": "mastra build" 9 | }, 10 | "keywords": [], 11 | "author": "", 12 | "license": "ISC", 13 | "description": "", 14 | "type": "module", 15 | "engines": { 16 | "node": ">=20.9.0" 17 | }, 18 | "dependencies": { 19 | "@ai-sdk/openai": "^1.3.24", 20 | "@mastra/client-js": "^0.10.20", 21 | "@mastra/core": "^0.13.1", 22 | "@mastra/libsql": "^0.13.1", 23 | "@mastra/loggers": "^0.10.6", 24 | "@mastra/memory": "^0.12.1", 25 | "zod": "^3.25.48" 26 | }, 27 | "devDependencies": { 28 | "@types/node": "^22.15.29", 29 | "mastra": "^0.10.20", 30 | "typescript": "^5.8.3" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/mastra/example/src/mastra/agents/agentic-chat.ts: -------------------------------------------------------------------------------- 1 | import { openai } from "@ai-sdk/openai"; 2 | import { Agent } from "@mastra/core/agent"; 3 | import { Memory } from "@mastra/memory"; 4 | import { LibSQLStore } from "@mastra/libsql"; 5 | import { weatherTool } from "../tools/weather-tool"; 6 | 7 | export const agenticChatAgent = new Agent({ 8 | name: "Weather Agent", 9 | instructions: ` 10 | You are a helpful weather assistant that provides accurate weather information. 11 | 12 | Your primary function is to help users get weather details for specific locations. When responding: 13 | - Always ask for a location if none is provided 14 | - If the location name isn’t in English, please translate it 15 | - If giving a location with multiple parts (e.g. "New York, NY"), use the most relevant part (e.g. "New York") 16 | - Include relevant details like humidity, wind conditions, and precipitation 17 | - Keep responses concise but informative 18 | 19 | Use the weatherTool to fetch current weather data. 20 | `, 21 | model: openai("gpt-4o-mini"), 22 | tools: { weatherTool }, 23 | memory: new Memory({ 24 | storage: new LibSQLStore({ 25 | url: "file:../mastra.db", // path is relative to the .mastra/output directory 26 | }), 27 | }), 28 | }); 29 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/mastra/example/src/mastra/agents/tool-based-generative-ui.ts: -------------------------------------------------------------------------------- 1 | import { openai } from "@ai-sdk/openai"; 2 | import { Agent } from "@mastra/core/agent"; 3 | import { Memory } from "@mastra/memory"; 4 | import { LibSQLStore } from "@mastra/libsql"; 5 | import { createTool } from "@mastra/core"; 6 | import z from "zod"; 7 | 8 | export const toolBasedGenerativeUIAgent = new Agent({ 9 | name: "Haiku Agent", 10 | instructions: ` 11 | You are a helpful haiku assistant that provides the user with a haiku. 12 | `, 13 | model: openai("gpt-4o-mini"), 14 | tools: { 15 | generate_haiku: createTool({ 16 | id: "generate_haiku", 17 | description: 18 | "Generate a haiku in Japanese and its English translation. Also select exactly 3 relevant images from the provided list based on the haiku's theme.", 19 | inputSchema: z.object({ 20 | japanese: z.array(z.string()).describe("An array of three lines of the haiku in Japanese"), 21 | english: z.array(z.string()).describe("An array of three lines of the haiku in English"), 22 | }), 23 | outputSchema: z.string(), 24 | execute: async ({ context }) => { 25 | return "Haiku generated."; 26 | }, 27 | }), 28 | }, 29 | memory: new Memory({ 30 | storage: new LibSQLStore({ 31 | url: "file:../mastra.db", // path is relative to the .mastra/output directory 32 | }), 33 | }), 34 | }); 35 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/mastra/example/src/mastra/index.ts: -------------------------------------------------------------------------------- 1 | import { Mastra } from "@mastra/core/mastra"; 2 | import { PinoLogger } from "@mastra/loggers"; 3 | import { LibSQLStore } from "@mastra/libsql"; 4 | 5 | import { agenticChatAgent } from "./agents/agentic-chat"; 6 | import { toolBasedGenerativeUIAgent } from "./agents/tool-based-generative-ui"; 7 | 8 | export const mastra = new Mastra({ 9 | server: { 10 | port: process.env.PORT ? parseInt(process.env.PORT) : 4111, 11 | host: "0.0.0.0", 12 | }, 13 | agents: { agentic_chat: agenticChatAgent, tool_based_generative_ui: toolBasedGenerativeUIAgent }, 14 | storage: new LibSQLStore({ 15 | // stores telemetry, evals, ... into memory storage, if it needs to persist, change to file:../mastra.db 16 | url: ":memory:", 17 | }), 18 | logger: new PinoLogger({ 19 | name: "Mastra", 20 | level: "info", 21 | }), 22 | }); 23 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/mastra/example/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2022", 4 | "module": "ES2022", 5 | "moduleResolution": "bundler", 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "strict": true, 9 | "skipLibCheck": true, 10 | "noEmit": true, 11 | "outDir": "dist" 12 | }, 13 | "include": [ 14 | "src/**/*" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/mastra/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | passWithNoTests: true, 7 | moduleNameMapper: { 8 | "^@/(.*)$": "/src/$1", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/mastra/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ag-ui/mastra", 3 | "version": "0.0.8", 4 | "license": "Apache-2.0", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "sideEffects": false, 9 | "private": false, 10 | "publishConfig": { 11 | "access": "public" 12 | }, 13 | "files": [ 14 | "dist/**", 15 | "README.md" 16 | ], 17 | "scripts": { 18 | "build": "tsup", 19 | "dev": "tsup --watch", 20 | "clean": "rm -rf dist .turbo node_modules", 21 | "typecheck": "tsc --noEmit", 22 | "test": "jest", 23 | "link:global": "pnpm link --global", 24 | "unlink:global": "pnpm unlink --global" 25 | }, 26 | "dependencies": { 27 | "@ag-ui/client": "workspace:*", 28 | "@ai-sdk/ui-utils": "^1.1.19", 29 | "@mastra/client-js": "^0.10.18", 30 | "rxjs": "7.8.1" 31 | }, 32 | "peerDependencies": { 33 | "@copilotkit/runtime": "^1.9.3", 34 | "@mastra/core": "^0.11.1 || ^0.12.1 || ^0.13.0", 35 | "zod": "^3.25.67" 36 | }, 37 | "devDependencies": { 38 | "@mastra/core": "^0.13.0", 39 | "@types/jest": "^29.5.14", 40 | "@types/node": "^20.11.19", 41 | "jest": "^29.7.0", 42 | "ts-jest": "^29.1.2", 43 | "tsup": "^8.0.2", 44 | "typescript": "^5.3.3" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/mastra/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./mastra"; 2 | export * from "./utils"; 3 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/mastra/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "moduleResolution": "node", 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "jsx": "react-jsx", 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | "stripInternal": true 21 | }, 22 | "include": ["src"], 23 | "exclude": ["node_modules", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/mastra/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | minify: true, 11 | }); 12 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/middleware-starter/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/middleware-starter/README.md: -------------------------------------------------------------------------------- 1 | # Middleware Starter 2 | 3 | This starter kit demonstrates how to set up a middleware server that can be used to proxy events from the agent to the frontend. 4 | 5 | ## Tutorial 6 | 7 | To learn how to set up your own middleware server, please refer to the [tutorial](https://docs.ag-ui.com/quickstart/middleware). 8 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/middleware-starter/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | passWithNoTests: true, 7 | moduleNameMapper: { 8 | "^@/(.*)$": "/src/$1", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/middleware-starter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ag-ui/middleware-starter", 3 | "author": "Markus Ecker ", 4 | "version": "0.0.1", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "sideEffects": false, 9 | "files": [ 10 | "dist/**" 11 | ], 12 | "scripts": { 13 | "build": "tsup", 14 | "dev": "tsup --watch", 15 | "clean": "rm -rf dist .turbo node_modules", 16 | "typecheck": "tsc --noEmit", 17 | "test": "jest", 18 | "link:global": "pnpm link --global", 19 | "unlink:global": "pnpm unlink --global" 20 | }, 21 | "dependencies": { 22 | "@ag-ui/client": "workspace:*" 23 | }, 24 | "peerDependencies": { 25 | "rxjs": "7.8.1" 26 | }, 27 | "devDependencies": { 28 | "@types/jest": "^29.5.14", 29 | "@types/node": "^20.11.19", 30 | "jest": "^29.7.0", 31 | "ts-jest": "^29.1.2", 32 | "tsup": "^8.0.2", 33 | "typescript": "^5.3.3" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/middleware-starter/src/index.ts: -------------------------------------------------------------------------------- 1 | import { AbstractAgent, BaseEvent, EventType, RunAgentInput } from "@ag-ui/client"; 2 | import { Observable } from "rxjs"; 3 | 4 | export class MiddlewareStarterAgent extends AbstractAgent { 5 | protected run(input: RunAgentInput): Observable { 6 | const messageId = Date.now().toString(); 7 | return new Observable((observer) => { 8 | observer.next({ 9 | type: EventType.RUN_STARTED, 10 | threadId: input.threadId, 11 | runId: input.runId, 12 | } as any); 13 | 14 | observer.next({ 15 | type: EventType.TEXT_MESSAGE_START, 16 | messageId, 17 | } as any); 18 | 19 | observer.next({ 20 | type: EventType.TEXT_MESSAGE_CONTENT, 21 | messageId, 22 | delta: "Hello world!", 23 | } as any); 24 | 25 | observer.next({ 26 | type: EventType.TEXT_MESSAGE_END, 27 | messageId, 28 | } as any); 29 | 30 | observer.next({ 31 | type: EventType.RUN_FINISHED, 32 | threadId: input.threadId, 33 | runId: input.runId, 34 | } as any); 35 | 36 | observer.complete(); 37 | }); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/middleware-starter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "moduleResolution": "node", 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "jsx": "react-jsx", 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | "stripInternal": true 21 | }, 22 | "include": ["src"], 23 | "exclude": ["node_modules", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/middleware-starter/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | minify: true, 11 | }); 12 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/pydantic-ai/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/pydantic-ai/examples/.gitignore: -------------------------------------------------------------------------------- 1 | server.egg-info/ 2 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/pydantic-ai/examples/README.md: -------------------------------------------------------------------------------- 1 | # Pydantic AI AG-UI Examples 2 | 3 | This directory contains example usage of the AG-UI adapter for Pydantic AI. It provides a FastAPI application that demonstrates how to use the Pydantic AI agent with the AG-UI protocol. 4 | 5 | ## Features 6 | 7 | The examples include implementations for each of the AG-UI dojo features: 8 | - Agentic Chat 9 | - Human in the Loop 10 | - Agentic Generative UI 11 | - Tool Based Generative UI 12 | - Shared State 13 | - Predictive State Updates 14 | 15 | ## Setup 16 | 17 | 1. Install dependencies: 18 | ```bash 19 | uv sync 20 | ``` 21 | 22 | 2. Run the development server: 23 | ```bash 24 | uv run dev 25 | ``` 26 | 27 | ## Usage 28 | 29 | Once the server is running, launch the frontend dojo with: 30 | 31 | ```bash 32 | cd ../../../ 33 | pnpm install 34 | turbo run dev 35 | ``` 36 | 37 | and view it at http://localhost:3000. 38 | 39 | By default, the agents can be reached at: 40 | 41 | - `http://localhost:9000/agentic_chat` - Agentic Chat 42 | - `http://localhost:9000/agentic_generative_ui` - Agentic Generative UI 43 | - `http://localhost:9000/human_in_the_loop` - Human in the Loop 44 | - `http://localhost:9000/predictive_state_updates` - Predictive State Updates 45 | - `http://localhost:9000/shared_state` - Shared State 46 | - `http://localhost:9000/tool_based_generative_ui` - Tool Based Generative UI 47 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/pydantic-ai/examples/pyproject.toml: -------------------------------------------------------------------------------- 1 | tool.uv.package = true 2 | 3 | [project] 4 | name = "server" 5 | version = "0.1.0" 6 | description = "Example usage of the AG-UI adapter for Pydantic AI" 7 | license = "MIT" 8 | 9 | readme = "README.md" 10 | requires-python = ">=3.9" 11 | dependencies = [ 12 | "fastapi>=0.104.0", 13 | "uvicorn[standard]>=0.24.0", 14 | "pydantic-ai-slim[openai,ag-ui]>=0.1.0", 15 | ] 16 | authors = [] 17 | 18 | [project.scripts] 19 | dev = "server:main" 20 | 21 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/pydantic-ai/examples/server/__init__.py: -------------------------------------------------------------------------------- 1 | """Example usage of the AG-UI adapter for Pydantic AI. 2 | 3 | This provides a FastAPI application that demonstrates how to use the 4 | Pydantic AI agent with the AG-UI protocol. It includes examples for 5 | each of the AG-UI dojo features: 6 | - Agentic Chat 7 | - Human in the Loop 8 | - Agentic Generative UI 9 | - Tool Based Generative UI 10 | - Shared State 11 | - Predictive State Updates 12 | """ 13 | 14 | from __future__ import annotations 15 | 16 | from fastapi import FastAPI 17 | import uvicorn 18 | import os 19 | 20 | 21 | from .api import ( 22 | agentic_chat_app, 23 | agentic_generative_ui_app, 24 | human_in_the_loop_app, 25 | predictive_state_updates_app, 26 | shared_state_app, 27 | tool_based_generative_ui_app, 28 | ) 29 | 30 | app = FastAPI(title='Pydantic AI AG-UI server') 31 | app.mount('/agentic_chat', agentic_chat_app, 'Agentic Chat') 32 | app.mount('/agentic_generative_ui', agentic_generative_ui_app, 'Agentic Generative UI') 33 | app.mount('/human_in_the_loop', human_in_the_loop_app, 'Human in the Loop') 34 | app.mount( 35 | '/predictive_state_updates', 36 | predictive_state_updates_app, 37 | 'Predictive State Updates', 38 | ) 39 | app.mount('/shared_state', shared_state_app, 'Shared State') 40 | app.mount( 41 | '/tool_based_generative_ui', 42 | tool_based_generative_ui_app, 43 | 'Tool Based Generative UI', 44 | ) 45 | 46 | 47 | def main(): 48 | """Main function to start the FastAPI server.""" 49 | port = int(os.getenv("PORT", "9000")) 50 | uvicorn.run(app, host="0.0.0.0", port=port) 51 | 52 | if __name__ == "__main__": 53 | main() 54 | 55 | __all__ = ["main"] 56 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/pydantic-ai/examples/server/api/__init__.py: -------------------------------------------------------------------------------- 1 | """Example API for a AG-UI compatible Pydantic AI Agent UI.""" 2 | 3 | from __future__ import annotations 4 | 5 | from .agentic_chat import app as agentic_chat_app 6 | from .agentic_generative_ui import app as agentic_generative_ui_app 7 | from .human_in_the_loop import app as human_in_the_loop_app 8 | from .predictive_state_updates import app as predictive_state_updates_app 9 | from .shared_state import app as shared_state_app 10 | from .tool_based_generative_ui import app as tool_based_generative_ui_app 11 | 12 | __all__ = [ 13 | 'agentic_chat_app', 14 | 'agentic_generative_ui_app', 15 | 'human_in_the_loop_app', 16 | 'predictive_state_updates_app', 17 | 'shared_state_app', 18 | 'tool_based_generative_ui_app', 19 | ] 20 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/pydantic-ai/examples/server/api/agentic_chat.py: -------------------------------------------------------------------------------- 1 | """Agentic Chat feature.""" 2 | 3 | from __future__ import annotations 4 | 5 | from datetime import datetime 6 | from zoneinfo import ZoneInfo 7 | 8 | from pydantic_ai import Agent 9 | 10 | agent = Agent('openai:gpt-4o-mini') 11 | app = agent.to_ag_ui() 12 | 13 | 14 | @agent.tool_plain 15 | async def current_time(timezone: str = 'UTC') -> str: 16 | """Get the current time in ISO format. 17 | 18 | Args: 19 | timezone: The timezone to use. 20 | 21 | Returns: 22 | The current time in ISO format string. 23 | """ 24 | tz: ZoneInfo = ZoneInfo(timezone) 25 | return datetime.now(tz=tz).isoformat() 26 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/pydantic-ai/examples/server/api/human_in_the_loop.py: -------------------------------------------------------------------------------- 1 | """Human in the Loop Feature. 2 | 3 | No special handling is required for this feature. 4 | """ 5 | 6 | from __future__ import annotations 7 | 8 | from textwrap import dedent 9 | 10 | from pydantic_ai import Agent 11 | 12 | agent = Agent( 13 | 'openai:gpt-4o-mini', 14 | instructions=dedent( 15 | """ 16 | When planning tasks use tools only, without any other messages. 17 | IMPORTANT: 18 | - Use the `generate_task_steps` tool to display the suggested steps to the user 19 | - Never repeat the plan, or send a message detailing steps 20 | - If accepted, confirm the creation of the plan and the number of selected (enabled) steps only 21 | - If not accepted, ask the user for more information, DO NOT use the `generate_task_steps` tool again 22 | """ 23 | ), 24 | ) 25 | 26 | app = agent.to_ag_ui() 27 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/pydantic-ai/examples/server/api/tool_based_generative_ui.py: -------------------------------------------------------------------------------- 1 | """Tool Based Generative UI feature. 2 | 3 | No special handling is required for this feature. 4 | """ 5 | 6 | from __future__ import annotations 7 | 8 | from pydantic_ai import Agent 9 | 10 | agent = Agent('openai:gpt-4o-mini') 11 | app = agent.to_ag_ui() 12 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/pydantic-ai/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | passWithNoTests: true, 7 | moduleNameMapper: { 8 | "^@/(.*)$": "/src/$1", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/pydantic-ai/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ag-ui/pydantic-ai", 3 | "author": "Steven Hartland ", 4 | "version": "0.0.1", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "sideEffects": false, 9 | "files": [ 10 | "dist/**" 11 | ], 12 | "scripts": { 13 | "build": "tsup", 14 | "dev": "tsup --watch", 15 | "clean": "rm -rf dist .turbo node_modules", 16 | "typecheck": "tsc --noEmit", 17 | "test": "jest", 18 | "link:global": "pnpm link --global", 19 | "unlink:global": "pnpm unlink --global" 20 | }, 21 | "dependencies": { 22 | "@ag-ui/client": "workspace:*" 23 | }, 24 | "peerDependencies": { 25 | "rxjs": "7.8.1" 26 | }, 27 | "devDependencies": { 28 | "@types/jest": "^29.5.14", 29 | "@types/node": "^20.11.19", 30 | "jest": "^29.7.0", 31 | "ts-jest": "^29.1.2", 32 | "tsup": "^8.0.2", 33 | "typescript": "^5.3.3" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/pydantic-ai/src/index.ts: -------------------------------------------------------------------------------- 1 | import { HttpAgent } from "@ag-ui/client"; 2 | 3 | export class PydanticAIAgent extends HttpAgent {} 4 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/pydantic-ai/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "moduleResolution": "node", 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "jsx": "react-jsx", 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | "stripInternal": true 21 | }, 22 | "include": ["src"], 23 | "exclude": ["node_modules", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/pydantic-ai/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | minify: true, 11 | }); 12 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter-all-features/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | server 14 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter-all-features/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | passWithNoTests: true, 7 | moduleNameMapper: { 8 | "^@/(.*)$": "/src/$1", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter-all-features/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ag-ui/server-starter-all-features", 3 | "author": "Markus Ecker ", 4 | "version": "0.0.1", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "sideEffects": false, 9 | "files": [ 10 | "dist/**" 11 | ], 12 | "scripts": { 13 | "build": "tsup", 14 | "dev": "tsup --watch", 15 | "clean": "rm -rf dist .turbo node_modules", 16 | "typecheck": "tsc --noEmit", 17 | "test": "jest", 18 | "link:global": "pnpm link --global", 19 | "unlink:global": "pnpm unlink --global" 20 | }, 21 | "dependencies": { 22 | "@ag-ui/client": "workspace:*" 23 | }, 24 | "peerDependencies": { 25 | "rxjs": "7.8.1" 26 | }, 27 | "devDependencies": { 28 | "@types/jest": "^29.5.14", 29 | "@types/node": "^20.11.19", 30 | "jest": "^29.7.0", 31 | "ts-jest": "^29.1.2", 32 | "tsup": "^8.0.2", 33 | "typescript": "^5.3.3" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter-all-features/server/python/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/server-starter-all-features/server/python/README.md -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter-all-features/server/python/example_server/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Example server for the AG-UI protocol. 3 | """ 4 | 5 | import os 6 | import uvicorn 7 | from fastapi import FastAPI 8 | from .agentic_chat import agentic_chat_endpoint 9 | from .human_in_the_loop import human_in_the_loop_endpoint 10 | from .agentic_generative_ui import agentic_generative_ui_endpoint 11 | from .tool_based_generative_ui import tool_based_generative_ui_endpoint 12 | from .shared_state import shared_state_endpoint 13 | from .predictive_state_updates import predictive_state_updates_endpoint 14 | 15 | app = FastAPI(title="AG-UI Endpoint") 16 | 17 | # Register the agentic chat endpoint 18 | app.post("/agentic_chat")(agentic_chat_endpoint) 19 | 20 | # Register the human in the loop endpoint 21 | app.post("/human_in_the_loop")(human_in_the_loop_endpoint) 22 | 23 | # Register the agentic generative UI endpoint 24 | app.post("/agentic_generative_ui")(agentic_generative_ui_endpoint) 25 | 26 | # Register the tool-based generative UI endpoint 27 | app.post("/tool_based_generative_ui")(tool_based_generative_ui_endpoint) 28 | 29 | # Register the shared state endpoint 30 | app.post("/shared_state")(shared_state_endpoint) 31 | 32 | # Register the predictive state updates endpoint 33 | app.post("/predictive_state_updates")(predictive_state_updates_endpoint) 34 | 35 | 36 | def main(): 37 | """Run the uvicorn server.""" 38 | port = int(os.getenv("PORT", "8000")) 39 | uvicorn.run( 40 | "example_server:app", 41 | host="0.0.0.0", 42 | port=port, 43 | reload=True 44 | ) 45 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter-all-features/server/python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "example_server" 3 | version = "0.1.0" 4 | description = "" 5 | authors = ["Markus Ecker "] 6 | readme = "README.md" 7 | 8 | [tool.poetry.dependencies] 9 | python = "^3.12" 10 | ag-ui-protocol = {path = "../../../../../python-sdk/"} 11 | fastapi = "^0.115.12" 12 | uvicorn = "^0.34.3" 13 | jsonpatch = "^1.33" 14 | 15 | [build-system] 16 | requires = ["poetry-core"] 17 | build-backend = "poetry.core.masonry.api" 18 | 19 | [tool.poetry.scripts] 20 | dev = "example_server:main" -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter-all-features/server/python/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/server-starter-all-features/server/python/tests/__init__.py -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter-all-features/src/index.ts: -------------------------------------------------------------------------------- 1 | import { HttpAgent } from "@ag-ui/client"; 2 | 3 | export class ServerStarterAllFeaturesAgent extends HttpAgent {} 4 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter-all-features/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "moduleResolution": "node", 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "jsx": "react-jsx", 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | "stripInternal": true 21 | }, 22 | "include": ["src"], 23 | "exclude": ["node_modules", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter-all-features/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | minify: true, 11 | }); 12 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | server 14 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter/README.md: -------------------------------------------------------------------------------- 1 | # Server Starter 2 | 3 | This starter kit demonstrates sending the minimal set of events that are needed to stream data from the agent to the frontend. 4 | 5 | ## Running the server 6 | 7 | To run the server: 8 | 9 | ```bash 10 | cd typescript-sdk/integrations/server-starter/server/python 11 | 12 | poetry install && poetry run dev 13 | ``` 14 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | passWithNoTests: true, 7 | moduleNameMapper: { 8 | "^@/(.*)$": "/src/$1", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ag-ui/server-starter", 3 | "author": "Markus Ecker ", 4 | "version": "0.0.1", 5 | "main": "./dist/index.js", 6 | "module": "./dist/index.mjs", 7 | "types": "./dist/index.d.ts", 8 | "sideEffects": false, 9 | "files": [ 10 | "dist/**" 11 | ], 12 | "scripts": { 13 | "build": "tsup", 14 | "dev": "tsup --watch", 15 | "clean": "rm -rf dist .turbo node_modules", 16 | "typecheck": "tsc --noEmit", 17 | "test": "jest", 18 | "link:global": "pnpm link --global", 19 | "unlink:global": "pnpm unlink --global" 20 | }, 21 | "dependencies": { 22 | "@ag-ui/client": "workspace:*" 23 | }, 24 | "peerDependencies": { 25 | "rxjs": "7.8.1" 26 | }, 27 | "devDependencies": { 28 | "@types/jest": "^29.5.14", 29 | "@types/node": "^20.11.19", 30 | "jest": "^29.7.0", 31 | "ts-jest": "^29.1.2", 32 | "tsup": "^8.0.2", 33 | "typescript": "^5.3.3" 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter/server/python/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/server-starter/server/python/README.md -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter/server/python/pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.poetry] 2 | name = "example_server" 3 | version = "0.1.0" 4 | description = "" 5 | authors = ["Markus Ecker "] 6 | readme = "README.md" 7 | 8 | [tool.poetry.dependencies] 9 | python = "^3.12" 10 | ag-ui-protocol = "^0.1.5" 11 | fastapi = "^0.115.12" 12 | uvicorn = "^0.34.3" 13 | 14 | [build-system] 15 | requires = ["poetry-core"] 16 | build-backend = "poetry.core.masonry.api" 17 | 18 | [tool.poetry.scripts] 19 | dev = "example_server:main" -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter/server/python/tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ag-ui-protocol/ag-ui/84425772ac707e944973f2864f5bca00bdbae95a/typescript-sdk/integrations/server-starter/server/python/tests/__init__.py -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter/src/index.ts: -------------------------------------------------------------------------------- 1 | import { HttpAgent } from "@ag-ui/client"; 2 | 3 | export class ServerStarterAgent extends HttpAgent {} 4 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "moduleResolution": "node", 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "jsx": "react-jsx", 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | "stripInternal": true 21 | }, 22 | "include": ["src"], 23 | "exclude": ["node_modules", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/server-starter/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | minify: true, 11 | }); 12 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/vercel-ai-sdk/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/vercel-ai-sdk/README.md: -------------------------------------------------------------------------------- 1 | # @ag-ui/vercel-ai-sdk 2 | 3 | Implementation of the AG-UI protocol for Vercel AI SDK. 4 | 5 | Connects Vercel AI SDK models and tools to frontend applications via the AG-UI protocol. Provides native TypeScript integration with streamText, tool execution, and multi-step workflows. 6 | 7 | ## Installation 8 | 9 | ```bash 10 | npm install @ag-ui/vercel-ai-sdk 11 | pnpm add @ag-ui/vercel-ai-sdk 12 | yarn add @ag-ui/vercel-ai-sdk 13 | ``` 14 | 15 | ## Usage 16 | 17 | ```ts 18 | import { VercelAISDKAgent } from "@ag-ui/vercel-ai-sdk"; 19 | import { openai } from "ai/openai"; 20 | 21 | // Create an AG-UI compatible agent 22 | const agent = new VercelAISDKAgent({ 23 | model: openai("gpt-4"), 24 | maxSteps: 3, 25 | toolChoice: "auto", 26 | }); 27 | 28 | // Run with streaming 29 | const result = await agent.runAgent({ 30 | messages: [{ role: "user", content: "Help me with a task" }], 31 | }); 32 | ``` 33 | 34 | ## Features 35 | 36 | - **Native TypeScript** – Direct integration with Vercel AI SDK models 37 | - **Streaming support** – Real-time text and tool call streaming 38 | - **Multi-step workflows** – Automatic tool execution chains 39 | - **Model flexibility** – Works with OpenAI, Anthropic, and other providers 40 | 41 | ## To run the example server in the dojo 42 | 43 | ```bash 44 | # Use directly in TypeScript applications 45 | # No separate server needed 46 | ``` 47 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/vercel-ai-sdk/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | passWithNoTests: true, 7 | moduleNameMapper: { 8 | "^@/(.*)$": "/src/$1", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/vercel-ai-sdk/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ag-ui/vercel-ai-sdk", 3 | "version": "0.0.2", 4 | "main": "./dist/index.js", 5 | "module": "./dist/index.mjs", 6 | "types": "./dist/index.d.ts", 7 | "sideEffects": false, 8 | "files": [ 9 | "dist/**", 10 | "README.md" 11 | ], 12 | "scripts": { 13 | "build": "tsup", 14 | "dev": "tsup --watch", 15 | "clean": "rm -rf dist .turbo node_modules", 16 | "typecheck": "tsc --noEmit", 17 | "test": "jest", 18 | "link:global": "pnpm link --global", 19 | "unlink:global": "pnpm unlink --global" 20 | }, 21 | "peerDependencies": { 22 | "rxjs": "7.8.1" 23 | }, 24 | "devDependencies": { 25 | "@types/jest": "^29.5.14", 26 | "@types/node": "^20.11.19", 27 | "jest": "^29.7.0", 28 | "ts-jest": "^29.1.2", 29 | "tsup": "^8.0.2", 30 | "typescript": "^5.3.3" 31 | }, 32 | "dependencies": { 33 | "@ag-ui/client": "workspace:*", 34 | "ai": "^4.3.16", 35 | "zod": "^3.22.4" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/vercel-ai-sdk/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "moduleResolution": "node", 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "jsx": "react-jsx", 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | "stripInternal": true 21 | }, 22 | "include": ["src"], 23 | "exclude": ["node_modules", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /typescript-sdk/integrations/vercel-ai-sdk/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | minify: true, 11 | }); 12 | -------------------------------------------------------------------------------- /typescript-sdk/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ag-ui", 3 | "author": "Markus Ecker ", 4 | "private": true, 5 | "scripts": { 6 | "build": "turbo run build", 7 | "clean": "rm -rf dist .turbo node_modules && pnpm -r clean", 8 | "build:clean": "rm -rf dist .turbo node_modules && pnpm -r clean && pnpm install && turbo run build", 9 | "dev": "turbo run dev", 10 | "lint": "turbo run lint", 11 | "format": "prettier --write \"**/*.{ts,tsx,md,mdx}\"", 12 | "check-types": "turbo run check-types", 13 | "test": "turbo run test", 14 | "bump": "pnpm --filter './packages/*' exec -- pnpm version", 15 | "bump:alpha": "pnpm --filter './packages/*' exec -- pnpm version --preid alpha", 16 | "publish": "pnpm -r clean && pnpm install && turbo run build && pnpm publish -r --filter='./packages/*'", 17 | "publish:alpha": "pnpm -r clean && pnpm install && turbo run build && pnpm publish -r --no-git-checks --filter='./packages/*' --tag alpha" 18 | }, 19 | "devDependencies": { 20 | "prettier": "^3.5.3", 21 | "turbo": "^2.4.4", 22 | "typescript": "5.8.2" 23 | }, 24 | "packageManager": "pnpm@10.13.1", 25 | "engines": { 26 | "node": ">=18" 27 | }, 28 | "version": "0.0.1" 29 | } 30 | -------------------------------------------------------------------------------- /typescript-sdk/packages/cli/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | -------------------------------------------------------------------------------- /typescript-sdk/packages/cli/README.md: -------------------------------------------------------------------------------- 1 | # create-ag-ui-app 2 | 3 | CLI tool for scaffolding **Agent-User Interaction (AG-UI) Protocol** applications. 4 | 5 | `create-ag-ui-app` provides an interactive setup wizard to quickly bootstrap AG-UI projects with your preferred client framework and agent backend. 6 | 7 | Choose from CopilotKit/Next.js for web apps or CLI clients for terminal-based interactions. 8 | 9 | ## Usage 10 | 11 | ```bash 12 | npx create-ag-ui-app@latest 13 | pnpx create-ag-ui-app@latest 14 | bunx create-ag-ui-app@latest 15 | ``` 16 | 17 | ## Features 18 | 19 | - 🎯 **Interactive setup** – Guided prompts for client and framework selection 20 | - 🌐 **Multiple clients** – CopilotKit/Next.js web apps and CLI clients 21 | - 🔧 **Framework integration** – Built-in support for LangGraph, CrewAI, Mastra, Agno, LlamaIndex, and more 22 | - 📦 **Zero config** – Automatically sets up dependencies and project structure 23 | - ⚡ **Quick start** – Get from idea to running app in minutes 24 | 25 | ## Quick example 26 | 27 | ```bash 28 | # Interactive setup 29 | npx create-ag-ui-app@latest 30 | 31 | # With framework flags 32 | npx create-ag-ui-app@latest --langgraph-py 33 | npx create-ag-ui-app@latest --mastra 34 | 35 | # See all options 36 | npx create-ag-ui-app@latest --help 37 | ``` 38 | 39 | ## Documentation 40 | 41 | - Concepts & architecture: [`docs/concepts`](https://docs.ag-ui.com/concepts/architecture) 42 | - Full API reference: [`docs/events`](https://docs.ag-ui.com/concepts/events) 43 | 44 | ## Contributing 45 | 46 | Bug reports and pull requests are welcome! Please read our [contributing guide](https://github.com/ag-ui-protocol/ag-ui/blob/main/CONTRIBUTING.md) first. 47 | 48 | ## License 49 | 50 | MIT © 2025 AG-UI Protocol Contributors 51 | -------------------------------------------------------------------------------- /typescript-sdk/packages/cli/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | passWithNoTests: true, 7 | moduleNameMapper: { 8 | "^@/(.*)$": "/src/$1", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /typescript-sdk/packages/cli/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "create-ag-ui-app", 3 | "author": "Markus Ecker ", 4 | "version": "0.0.38", 5 | "private": false, 6 | "publishConfig": { 7 | "access": "public" 8 | }, 9 | "main": "./dist/index.js", 10 | "module": "./dist/index.mjs", 11 | "types": "./dist/index.d.ts", 12 | "bin": "./dist/index.mjs", 13 | "sideEffects": false, 14 | "files": [ 15 | "dist/**", 16 | "README.md" 17 | ], 18 | "scripts": { 19 | "build": "tsup", 20 | "dev": "tsup --watch", 21 | "clean": "rm -rf dist .turbo node_modules", 22 | "typecheck": "tsc --noEmit", 23 | "test": "jest", 24 | "link:global": "pnpm link --global", 25 | "unlink:global": "pnpm unlink --global" 26 | }, 27 | "dependencies": { 28 | "@types/inquirer": "^9.0.8", 29 | "commander": "^12.1.0", 30 | "inquirer": "^12.6.3", 31 | "giget": "2.0.0" 32 | }, 33 | "devDependencies": { 34 | "@types/jest": "^29.5.14", 35 | "@types/node": "^20.11.19", 36 | "jest": "^29.7.0", 37 | "ts-jest": "^29.1.2", 38 | "tsup": "^8.0.2", 39 | "typescript": "^5.3.3" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /typescript-sdk/packages/cli/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "moduleResolution": "node", 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "jsx": "react-jsx", 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | "stripInternal": true 21 | }, 22 | "include": ["src"], 23 | "exclude": ["node_modules", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /typescript-sdk/packages/cli/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: true, 10 | minify: true, 11 | }); 12 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | passWithNoTests: true, 7 | moduleNameMapper: { 8 | "^@/(.*)$": "/src/$1", 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ag-ui/client", 3 | "author": "Markus Ecker ", 4 | "version": "0.0.36", 5 | "private": false, 6 | "publishConfig": { 7 | "access": "public" 8 | }, 9 | "main": "./dist/index.js", 10 | "module": "./dist/index.mjs", 11 | "types": "./dist/index.d.ts", 12 | "sideEffects": false, 13 | "files": [ 14 | "dist/**", 15 | "README.md" 16 | ], 17 | "scripts": { 18 | "build": "tsup", 19 | "dev": "tsup --watch", 20 | "clean": "rm -rf dist .turbo node_modules", 21 | "typecheck": "tsc --noEmit", 22 | "test": "jest", 23 | "link:global": "pnpm link --global", 24 | "unlink:global": "pnpm unlink --global" 25 | }, 26 | "dependencies": { 27 | "@ag-ui/core": "workspace:*", 28 | "@ag-ui/proto": "workspace:*", 29 | "@ag-ui/encoder": "workspace:*", 30 | "@types/uuid": "^10.0.0", 31 | "fast-json-patch": "^3.1.1", 32 | "rxjs": "7.8.1", 33 | "untruncate-json": "^0.0.1", 34 | "uuid": "^11.1.0", 35 | "zod": "^3.22.4" 36 | }, 37 | "devDependencies": { 38 | "@types/jest": "^29.5.14", 39 | "@types/node": "^20.11.19", 40 | "jest": "^29.7.0", 41 | "ts-jest": "^29.1.2", 42 | "tsup": "^8.0.2", 43 | "typescript": "^5.3.3" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/src/agent/index.ts: -------------------------------------------------------------------------------- 1 | export { AbstractAgent } from "./agent"; 2 | export { HttpAgent } from "./http"; 3 | export type { AgentConfig } from "./types"; 4 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/src/agent/types.ts: -------------------------------------------------------------------------------- 1 | import { Message, RunAgentInput, State } from "@ag-ui/core"; 2 | 3 | export interface AgentConfig { 4 | agentId?: string; 5 | description?: string; 6 | threadId?: string; 7 | initialMessages?: Message[]; 8 | initialState?: State; 9 | debug?: boolean; 10 | } 11 | 12 | export interface HttpAgentConfig extends AgentConfig { 13 | url: string; 14 | headers?: Record; 15 | } 16 | 17 | export type RunAgentParameters = Partial< 18 | Pick 19 | >; 20 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/src/apply/index.ts: -------------------------------------------------------------------------------- 1 | export { defaultApplyEvents } from "./default"; 2 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/src/chunks/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./transform"; 2 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./apply"; 2 | export * from "./verify"; 3 | export * from "./transform"; 4 | export * from "./run"; 5 | export * from "./legacy"; 6 | export * from "./agent"; 7 | export * from "@ag-ui/core"; 8 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/src/legacy/index.ts: -------------------------------------------------------------------------------- 1 | export { convertToLegacyEvents } from "./convert"; 2 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/src/run/index.ts: -------------------------------------------------------------------------------- 1 | export { runHttpRequest as runHttpRequest } from "./http-request"; 2 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/src/transform/index.ts: -------------------------------------------------------------------------------- 1 | export { transformHttpEventStream } from "./http"; 2 | export { parseSSEStream } from "./sse"; 3 | export { parseProtoStream } from "./proto"; 4 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/src/utils.ts: -------------------------------------------------------------------------------- 1 | export const structuredClone_ = (obj: T): T => { 2 | if (typeof structuredClone === "function") { 3 | return structuredClone(obj); 4 | } 5 | 6 | try { 7 | return JSON.parse(JSON.stringify(obj)); 8 | } catch (err) { 9 | return { ...obj } as T; 10 | } 11 | }; 12 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/src/verify/index.ts: -------------------------------------------------------------------------------- 1 | export { verifyEvents } from "./verify"; 2 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "moduleResolution": "node", 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "jsx": "react-jsx", 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | }, 20 | "stripInternal": true 21 | }, 22 | "include": ["src", "../core/src/subscriber.ts"], 23 | "exclude": ["node_modules", "dist"] 24 | } 25 | -------------------------------------------------------------------------------- /typescript-sdk/packages/client/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig((options) => ({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: !options.watch, // Don't clean in watch mode to prevent race conditions 10 | minify: !options.watch, // Don't minify in watch mode for faster builds 11 | })); 12 | -------------------------------------------------------------------------------- /typescript-sdk/packages/core/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | -------------------------------------------------------------------------------- /typescript-sdk/packages/core/README.md: -------------------------------------------------------------------------------- 1 | # @ag-ui/core 2 | 3 | TypeScript definitions & runtime schemas for the **Agent-User Interaction (AG-UI) Protocol**. 4 | 5 | `@ag-ui/core` delivers the strongly-typed building blocks that every other AG-UI package is built on: message & state models, run inputs and the full set of streaming event types. 6 | 7 | ## Installation 8 | 9 | ```bash 10 | npm install @ag-ui/core 11 | pnpm add @ag-ui/core 12 | yarn add @ag-ui/core 13 | ``` 14 | 15 | ## Features 16 | 17 | - 🧩 **Typed data models** – `Message`, `Tool`, `Context`, `RunAgentInput`, `State` … 18 | - 🔄 **Streaming events** – 16 core event kinds covering assistant messages, tool calls, state updates and run lifecycle. 19 | - ✅ **Runtime validation** – schemas catch malformed payloads early. 20 | - 🚀 **Framework-agnostic** – works in Node.js, browsers and any agent framework that can emit JSON. 21 | 22 | ## Quick example 23 | 24 | ```ts 25 | import { EventSchemas, EventType } from "@ag-ui/core"; 26 | 27 | // Validate an incoming event 28 | EventSchemas.parse({ 29 | type: EventType.TEXT_MESSAGE_CONTENT, 30 | messageId: "msg_123", 31 | delta: "Hello, world!", 32 | }); 33 | ``` 34 | 35 | ## Documentation 36 | 37 | - Concepts & architecture: [`docs/concepts`](https://docs.ag-ui.com/concepts/architecture) 38 | - Full API reference: [`docs/sdk/js/core`](https://docs.ag-ui.com/sdk/js/core/overview) 39 | 40 | ## Contributing 41 | 42 | Bug reports and pull requests are welcome! Please read our [contributing guide](https://docs.ag-ui.com/development/contributing) first. 43 | 44 | ## License 45 | 46 | MIT © 2025 AG-UI Protocol Contributors 47 | -------------------------------------------------------------------------------- /typescript-sdk/packages/core/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | passWithNoTests: true, 7 | }; 8 | -------------------------------------------------------------------------------- /typescript-sdk/packages/core/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ag-ui/core", 3 | "author": "Markus Ecker ", 4 | "version": "0.0.36", 5 | "private": false, 6 | "publishConfig": { 7 | "access": "public" 8 | }, 9 | "main": "./dist/index.js", 10 | "module": "./dist/index.mjs", 11 | "types": "./dist/index.d.ts", 12 | "scripts": { 13 | "build": "tsup", 14 | "dev": "tsup --watch", 15 | "lint": "eslint \"src/**/*.ts*\"", 16 | "clean": "rm -rf dist .turbo node_modules", 17 | "test": "jest", 18 | "link:global": "pnpm link --global", 19 | "unlink:global": "pnpm unlink --global" 20 | }, 21 | "dependencies": { 22 | "rxjs": "7.8.1", 23 | "zod": "^3.22.4" 24 | }, 25 | "devDependencies": { 26 | "@types/jest": "^29.5.12", 27 | "jest": "^29.7.0", 28 | "ts-jest": "^29.1.2", 29 | "tsup": "^8.0.2", 30 | "typescript": "^5.8.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /typescript-sdk/packages/core/src/__tests__/index.test.ts: -------------------------------------------------------------------------------- 1 | describe("Core package", () => { 2 | it("should pass a simple test", () => { 3 | expect(true).toBe(true); 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /typescript-sdk/packages/core/src/index.ts: -------------------------------------------------------------------------------- 1 | // Export all base types and schemas 2 | export * from "./types"; 3 | 4 | // Export all event-related types and schemas 5 | export * from "./events"; 6 | -------------------------------------------------------------------------------- /typescript-sdk/packages/core/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "moduleResolution": "node", 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "jsx": "react-jsx", 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | } 20 | }, 21 | "include": ["src"], 22 | "exclude": ["node_modules", "dist"] 23 | } 24 | -------------------------------------------------------------------------------- /typescript-sdk/packages/core/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig((options) => ({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: !options.watch, // Don't clean in watch mode to prevent race conditions 10 | })); 11 | -------------------------------------------------------------------------------- /typescript-sdk/packages/encoder/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | -------------------------------------------------------------------------------- /typescript-sdk/packages/encoder/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('ts-jest').JestConfigWithTsJest} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | testMatch: ["**/*.test.ts"], 6 | passWithNoTests: true, 7 | }; 8 | -------------------------------------------------------------------------------- /typescript-sdk/packages/encoder/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ag-ui/encoder", 3 | "author": "Markus Ecker ", 4 | "version": "0.0.36", 5 | "private": false, 6 | "publishConfig": { 7 | "access": "public" 8 | }, 9 | "main": "./dist/index.js", 10 | "module": "./dist/index.mjs", 11 | "types": "./dist/index.d.ts", 12 | "scripts": { 13 | "build": "tsup", 14 | "dev": "tsup --watch", 15 | "lint": "eslint \"src/**/*.ts*\"", 16 | "clean": "rm -rf dist .turbo node_modules", 17 | "test": "jest", 18 | "link:global": "pnpm link --global", 19 | "unlink:global": "pnpm unlink --global" 20 | }, 21 | "dependencies": { 22 | "@ag-ui/core": "workspace:*", 23 | "@ag-ui/proto": "workspace:*" 24 | }, 25 | "devDependencies": { 26 | "@types/jest": "^29.5.12", 27 | "jest": "^29.7.0", 28 | "ts-jest": "^29.1.2", 29 | "tsup": "^8.0.2", 30 | "typescript": "^5.8.2" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /typescript-sdk/packages/encoder/src/index.ts: -------------------------------------------------------------------------------- 1 | export * from "./encoder"; 2 | export { AGUI_MEDIA_TYPE } from "@ag-ui/proto"; 3 | -------------------------------------------------------------------------------- /typescript-sdk/packages/encoder/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2017", 4 | "module": "esnext", 5 | "lib": ["dom", "dom.iterable", "esnext"], 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true, 9 | "moduleResolution": "node", 10 | "skipLibCheck": true, 11 | "strict": true, 12 | "jsx": "react-jsx", 13 | "esModuleInterop": true, 14 | "resolveJsonModule": true, 15 | "isolatedModules": true, 16 | "baseUrl": ".", 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | } 20 | }, 21 | "include": ["src"], 22 | "exclude": ["node_modules", "dist"] 23 | } 24 | -------------------------------------------------------------------------------- /typescript-sdk/packages/encoder/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig((options) => ({ 4 | entry: ["src/index.ts"], 5 | format: ["cjs", "esm"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: !options.watch, // Don't clean in watch mode to prevent race conditions 10 | })); 11 | -------------------------------------------------------------------------------- /typescript-sdk/packages/proto/.npmignore: -------------------------------------------------------------------------------- 1 | .turbo 2 | .DS_Store 3 | .git 4 | .gitignore 5 | .idea 6 | .vscode 7 | .env 8 | __tests__ 9 | src 10 | tsup.config.ts 11 | tsconfig.json 12 | jest.config.js 13 | -------------------------------------------------------------------------------- /typescript-sdk/packages/proto/__tests__/test-utils.ts: -------------------------------------------------------------------------------- 1 | import { BaseEvent } from "@ag-ui/core"; 2 | import { encode, decode } from "../src/proto"; 3 | import { expect, describe, it } from "@jest/globals"; 4 | 5 | /** 6 | * Performs a round-trip encode-decode on an event and returns the decoded result 7 | */ 8 | export function roundTrip(event: T): T { 9 | const encoded = encode(event); 10 | return decode(encoded) as T; 11 | } 12 | 13 | /** 14 | * Verifies that an event is the same after round-trip encoding and decoding 15 | */ 16 | export function expectRoundTripEquality(event: T): void { 17 | const decoded = roundTrip(event); 18 | 19 | // Verify all properties match 20 | for (const key in event) { 21 | if (Object.prototype.hasOwnProperty.call(event, key)) { 22 | expect(decoded[key]).toEqual(event[key]); 23 | } 24 | } 25 | } 26 | 27 | // Add a simple test to prevent "Your test suite must contain at least one test" error 28 | describe("Test Utilities", () => { 29 | it("should exist as a module for other tests to import from", () => { 30 | expect(typeof roundTrip).toBe("function"); 31 | expect(typeof expectRoundTripEquality).toBe("function"); 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /typescript-sdk/packages/proto/jest.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('jest').Config} */ 2 | module.exports = { 3 | preset: "ts-jest", 4 | testEnvironment: "node", 5 | passWithNoTests: true, 6 | }; 7 | -------------------------------------------------------------------------------- /typescript-sdk/packages/proto/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@ag-ui/proto", 3 | "author": "Markus Ecker ", 4 | "version": "0.0.36", 5 | "private": false, 6 | "publishConfig": { 7 | "access": "public" 8 | }, 9 | "main": "./dist/index.js", 10 | "module": "./dist/index.mjs", 11 | "types": "./dist/index.d.ts", 12 | "scripts": { 13 | "build": "tsup", 14 | "dev": "tsup --watch", 15 | "lint": "eslint \"src/**/*.ts*\"", 16 | "clean": "rm -rf dist .turbo node_modules", 17 | "test": "jest", 18 | "generate": "mkdir -p ./src/generated && npx protoc --plugin=./node_modules/.bin/protoc-gen-ts_proto --ts_proto_out=./src/generated --ts_proto_opt=esModuleInterop=true,outputJsonMethods=false,outputClientImpl=false -I ./src/proto ./src/proto/*.proto", 19 | "link:global": "pnpm link --global", 20 | "unlink:global": "pnpm unlink --global" 21 | }, 22 | "dependencies": { 23 | "@ag-ui/core": "workspace:*", 24 | "@bufbuild/protobuf": "^2.2.5", 25 | "@protobuf-ts/protoc": "^2.11.1" 26 | }, 27 | "devDependencies": { 28 | "@jest/globals": "^29.7.0", 29 | "@types/jest": "^29.5.14", 30 | "jest": "^29.7.0", 31 | "ts-jest": "^29.1.2", 32 | "ts-proto": "^2.7.0", 33 | "tsup": "^8.0.2", 34 | "typescript": "^5.8.2" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /typescript-sdk/packages/proto/src/index.ts: -------------------------------------------------------------------------------- 1 | export { encode, decode } from "./proto"; 2 | 3 | export const AGUI_MEDIA_TYPE = "application/vnd.ag-ui.event+proto"; 4 | -------------------------------------------------------------------------------- /typescript-sdk/packages/proto/src/proto/patch.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | import "google/protobuf/struct.proto"; 4 | 5 | package ag_ui; 6 | 7 | enum JsonPatchOperationType { 8 | ADD = 0; 9 | REMOVE = 1; 10 | REPLACE = 2; 11 | MOVE = 3; 12 | COPY = 4; 13 | TEST = 5; 14 | } 15 | 16 | message JsonPatchOperation { 17 | JsonPatchOperationType op = 1; 18 | string path = 2; 19 | optional string from = 3; 20 | optional google.protobuf.Value value = 4; 21 | } 22 | -------------------------------------------------------------------------------- /typescript-sdk/packages/proto/src/proto/types.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | 3 | package ag_ui; 4 | 5 | message ToolCall { 6 | string id = 1; 7 | string type = 2; 8 | message Function { 9 | string name = 1; 10 | string arguments = 2; 11 | } 12 | Function function = 3; 13 | } 14 | 15 | message Message { 16 | string id = 1; 17 | string role = 2; 18 | optional string content = 3; 19 | optional string name = 4; 20 | repeated ToolCall tool_calls = 5; 21 | optional string tool_call_id = 6; 22 | optional string error = 7; 23 | } 24 | -------------------------------------------------------------------------------- /typescript-sdk/packages/proto/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "../../tsconfig.json", 3 | "compilerOptions": { 4 | "outDir": "./dist", 5 | "rootDir": "./src", 6 | "declaration": true, 7 | "declarationMap": true, 8 | "sourceMap": true 9 | }, 10 | "include": ["src/**/*"], 11 | "exclude": ["node_modules", "dist", "**/__tests__/**"] 12 | } 13 | -------------------------------------------------------------------------------- /typescript-sdk/packages/proto/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | 3 | export default defineConfig((options) => ({ 4 | entry: ["src/index.ts"], 5 | format: ["esm", "cjs"], 6 | dts: true, 7 | splitting: false, 8 | sourcemap: true, 9 | clean: !options.watch, // Don't clean in watch mode to prevent race conditions 10 | })); 11 | -------------------------------------------------------------------------------- /typescript-sdk/pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - "apps/*" 3 | - "packages/*" 4 | - "integrations/*" 5 | -------------------------------------------------------------------------------- /typescript-sdk/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ES2019", 4 | "module": "ESNext", 5 | "moduleResolution": "node", 6 | "declaration": true, 7 | "strict": true, 8 | "esModuleInterop": true, 9 | "skipLibCheck": true, 10 | "forceConsistentCasingInFileNames": true 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /typescript-sdk/turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "ui": "tui", 4 | "envMode": "loose", 5 | "concurrency": "20", 6 | "tasks": { 7 | "generate": { 8 | "outputs": ["src/generated/**"] 9 | }, 10 | "build": { 11 | "dependsOn": ["^build", "generate"], 12 | "inputs": ["$TURBO_DEFAULT$", ".env*"], 13 | "outputs": ["dist/**", ".next/**", "!.next/cache/**"] 14 | }, 15 | "demo-viewer#build": { 16 | "dependsOn": ["^build", "generate"], 17 | "inputs": ["$TURBO_DEFAULT$", ".env*"], 18 | "outputs": ["dist/**", ".next/**", "!.next/cache/**"] 19 | }, 20 | "lint": { 21 | "dependsOn": ["^lint"] 22 | }, 23 | "check-types": { 24 | "dependsOn": ["^check-types"] 25 | }, 26 | "dev": { 27 | "dependsOn": ["^build", "generate"], 28 | "cache": false, 29 | "persistent": true 30 | }, 31 | "demo-viewer#dev": { 32 | "dependsOn": ["^build", "generate"], 33 | "cache": false, 34 | "persistent": true 35 | }, 36 | "test": { 37 | "dependsOn": ["^build"], 38 | "outputs": [] 39 | }, 40 | "link:global": { 41 | "cache": false 42 | }, 43 | "unlink:global": { 44 | "cache": false 45 | } 46 | } 47 | } 48 | --------------------------------------------------------------------------------