Copy disabled (too large)
Download .txt
Showing preview only (11,810K chars total). Download the full file to get everything.
Repository: ag-ui-protocol/ag-ui
Branch: main
Commit: 0db03d09bcf2
Files: 1836
Total size: 20.9 MB
Directory structure:
gitextract_1usf67qd/
├── .claude/
│ └── settings.json
├── .gitattributes
├── .github/
│ ├── CODEOWNERS
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ ├── documentation.yml
│ │ └── feature_request.yml
│ ├── pull_request_template.md
│ └── workflows/
│ ├── auto-approve-community.yml
│ ├── build-python-preview.yml
│ ├── dojo-e2e.yml
│ ├── pr-check-binaries.yml
│ ├── publish-commit.yml
│ ├── publish-java-sdk.yml
│ ├── publish-kotlin-sdk.yml
│ ├── publish-python-package.yml
│ ├── publish-python-preview.yml
│ ├── rust-lint-test.yml
│ ├── unit-dart-sdk.yml
│ ├── unit-genkit-go.yml
│ ├── unit-go-sdk.yml
│ ├── unit-java-sdk.yml
│ ├── unit-kotlin-sdk.yml
│ ├── unit-python-sdk.yml
│ ├── unit-ruby-sdk.yml
│ └── unit-typescript-sdk.yml
├── .gitignore
├── .mcp.json
├── AGENTS.md
├── CLAUDE.md
├── CONTRIBUTING.md
├── 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
│ ├── components.json
│ ├── e2e/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── VIDEO_SETUP.md
│ │ ├── clean-reporter.cjs
│ │ ├── featurePages/
│ │ │ ├── AgenticChatPage.ts
│ │ │ ├── HumanInTheLoopPage.ts
│ │ │ ├── SharedStatePage.ts
│ │ │ ├── ToolBaseGenUIPage.ts
│ │ │ └── V1AgenticChatPage.ts
│ │ ├── fixtures/
│ │ │ └── openai/
│ │ │ ├── agentic-chat.json
│ │ │ ├── agentic-gen-ui.json
│ │ │ ├── backend-tool-rendering.json
│ │ │ ├── human-in-the-loop.json
│ │ │ ├── predictive-state.json
│ │ │ ├── shared-state.json
│ │ │ ├── subgraphs.json
│ │ │ ├── tool-based-gen-ui.json
│ │ │ └── v1-chat.json
│ │ ├── lib/
│ │ │ ├── constants.ts
│ │ │ ├── mock-agent.ts
│ │ │ └── upload-video.ts
│ │ ├── llmock-setup.ts
│ │ ├── package.json
│ │ ├── pages/
│ │ │ ├── a2aMiddlewarePages/
│ │ │ │ └── A2AChatPage.ts
│ │ │ ├── adkMiddlewarePages/
│ │ │ │ ├── HumanInLoopPage.ts
│ │ │ │ └── PredictiveStateUpdatesPage.ts
│ │ │ ├── agnoPages/
│ │ │ │ └── HumanInLoopPage.ts
│ │ │ ├── awsStrandsPages/
│ │ │ │ ├── AgenticUIGenPage.ts
│ │ │ │ └── HumanInLoopPage.ts
│ │ │ ├── crewAIPages/
│ │ │ │ ├── AgenticUIGenPage.ts
│ │ │ │ ├── HumanInLoopPage.ts
│ │ │ │ └── PredictiveStateUpdatesPage.ts
│ │ │ ├── langGraphFastAPIPages/
│ │ │ │ ├── AgenticUIGenPage.ts
│ │ │ │ ├── HumanInLoopPage.ts
│ │ │ │ ├── PredictiveStateUpdatesPage.ts
│ │ │ │ └── SubgraphsPage.ts
│ │ │ ├── langGraphPages/
│ │ │ │ ├── AgenticUIGenPage.ts
│ │ │ │ ├── HumanInLoopPage.ts
│ │ │ │ ├── PredictiveStateUpdatesPage.ts
│ │ │ │ └── SubgraphsPage.ts
│ │ │ ├── langroidPages/
│ │ │ │ └── AgenticUIGenPage.ts
│ │ │ ├── llamaIndexPages/
│ │ │ │ ├── AgenticUIGenPage.ts
│ │ │ │ └── HumanInLoopPage.ts
│ │ │ ├── pydanticAIPages/
│ │ │ │ ├── AgenticUIGenPage.ts
│ │ │ │ ├── HumanInLoopPage.ts
│ │ │ │ └── PredictiveStateUpdatesPage.ts
│ │ │ └── serverStarterAllFeaturesPages/
│ │ │ ├── AgenticUIGenPage.ts
│ │ │ ├── HumanInLoopPage.ts
│ │ │ └── PredictiveStateUpdatesPage.ts
│ │ ├── playwright.config.ts
│ │ ├── 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
│ │ ├── test-isolation-teardown.ts
│ │ ├── tests/
│ │ │ ├── a2aMiddlewareTests/
│ │ │ │ └── a2aChatPage.spec.ts
│ │ │ ├── adkMiddlewareTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── predictiveStateUpdatePage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── agnoTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── awsStrandsTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── claudeAgentSdkPythonTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ └── toolBasedGenUIPage.spec.ts
│ │ │ ├── claudeAgentSdkTypescriptTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ └── toolBasedGenUIPage.spec.ts
│ │ │ ├── crewAITests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── predictiveStateUpdatePage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── langchainTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ └── toolBasedGenUIPage.spec.ts
│ │ │ ├── langgraphFastAPITests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── predictiveStateUpdatePage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── subgraphsPage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── langgraphPythonTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── predictiveStateUpdatePage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── subgraphsPage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── langgraphTypescriptTests/
│ │ │ │ ├── agenticChatDeterministic.spec.ts
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── predictiveStateUpdatePage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── subgraphsPage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── langroidTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ └── sharedStatePage.spec.ts
│ │ │ ├── llamaIndexTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── mastraAgentLocalTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── mastraTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── middlewareStarterTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── pydanticAITests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── predictiveStateUpdatePage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── serverStarterAllFeaturesTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── predictiveStateUpdatePage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ └── serverStarterTests/
│ │ │ ├── agenticChatPage.spec.ts
│ │ │ └── v1AgenticChatPage.spec.ts
│ │ └── utils/
│ │ ├── aiWaitHelpers.ts
│ │ ├── copilot-actions.ts
│ │ └── copilot-selectors.ts
│ ├── eslint.config.mjs
│ ├── next.config.ts
│ ├── package.json
│ ├── postcss.config.mjs
│ ├── scripts/
│ │ ├── generate-content-json.ts
│ │ ├── link-cpk.js
│ │ ├── prep-dojo-everything.js
│ │ └── run-dojo-everything.js
│ ├── src/
│ │ ├── agents.ts
│ │ ├── app/
│ │ │ ├── [integrationId]/
│ │ │ │ ├── feature/
│ │ │ │ │ ├── (v1)/
│ │ │ │ │ │ └── v1_agentic_chat/
│ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── (v2)/
│ │ │ │ │ │ ├── a2a_chat/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── a2a_chat.tsx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ ├── a2ui_chat/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ ├── style.css
│ │ │ │ │ │ │ └── theme.ts
│ │ │ │ │ │ ├── agentic_chat/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── agentic_chat_reasoning/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ ├── agentic_generative_ui/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ ├── backend_tool_rendering/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ ├── human_in_the_loop/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── predictive_state_updates/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ ├── shared_state/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ ├── subgraphs/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ ├── tool_based_generative_ui/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ └── vnext_chat/
│ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── layout-client.tsx
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── not-found.tsx
│ │ │ │ ├── not-found.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── api/
│ │ │ │ ├── copilotkit/
│ │ │ │ │ ├── [integrationId]/
│ │ │ │ │ │ └── [[...slug]]/
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ └── route.ts
│ │ │ │ └── copilotkitnext/
│ │ │ │ └── [integrationId]/
│ │ │ │ └── [[...slug]]/
│ │ │ │ └── route.ts
│ │ │ ├── globals.css
│ │ │ ├── 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
│ │ │ ├── theme-wrapper.tsx
│ │ │ └── ui/
│ │ │ ├── badge.tsx
│ │ │ ├── button.tsx
│ │ │ ├── carousel.tsx
│ │ │ ├── dropdown-menu.tsx
│ │ │ ├── mdx-components.tsx
│ │ │ ├── tabs.tsx
│ │ │ └── theme-toggle.tsx
│ │ ├── config.ts
│ │ ├── contexts/
│ │ │ └── url-params-context.tsx
│ │ ├── env.ts
│ │ ├── files.json
│ │ ├── lib/
│ │ │ └── utils.ts
│ │ ├── mastra/
│ │ │ ├── agents/
│ │ │ │ ├── agentic-chat.ts
│ │ │ │ ├── backend-tool-rendering.ts
│ │ │ │ ├── human-in-the-loop.ts
│ │ │ │ ├── shared-state.ts
│ │ │ │ └── tool-based-generative-ui.ts
│ │ │ ├── index.ts
│ │ │ ├── storage.ts
│ │ │ └── tools.ts
│ │ ├── menu.ts
│ │ ├── proxy.ts
│ │ ├── styles/
│ │ │ └── typography.css
│ │ ├── types/
│ │ │ ├── agents.ts
│ │ │ ├── feature.ts
│ │ │ ├── integration.ts
│ │ │ └── interface.ts
│ │ └── utils/
│ │ ├── agents.ts
│ │ ├── domain-config.ts
│ │ ├── mdx-utils.tsx
│ │ ├── menu.ts
│ │ ├── use-is-inside-iframe.ts
│ │ ├── use-mobile-chat.ts
│ │ └── use-mobile-view.ts
│ ├── tailwind.config.ts
│ └── tsconfig.json
├── docs/
│ ├── .gitignore
│ ├── .prettierignore
│ ├── .prettierrc
│ ├── LICENSE
│ ├── README.md
│ ├── ag_ui.md
│ ├── agentic-protocols.mdx
│ ├── concepts/
│ │ ├── agents.mdx
│ │ ├── architecture.mdx
│ │ ├── capabilities.mdx
│ │ ├── events.mdx
│ │ ├── generative-ui-specs.mdx
│ │ ├── messages.mdx
│ │ ├── middleware.mdx
│ │ ├── reasoning.mdx
│ │ ├── serialization.mdx
│ │ ├── state.mdx
│ │ └── tools.mdx
│ ├── development/
│ │ ├── contributing.mdx
│ │ ├── roadmap.mdx
│ │ └── updates.mdx
│ ├── docs.json
│ ├── drafts/
│ │ ├── generative-ui.mdx
│ │ ├── interrupts.mdx
│ │ ├── meta-events.mdx
│ │ ├── multimodal-messages.mdx
│ │ └── overview.mdx
│ ├── icons/
│ │ ├── custom-icons.tsx
│ │ └── index.tsx
│ ├── images/
│ │ └── left-illustration.avif
│ ├── integrations.mdx
│ ├── introduction.mdx
│ ├── package.json
│ ├── quickstart/
│ │ ├── applications.mdx
│ │ ├── clients.mdx
│ │ ├── introduction.mdx
│ │ ├── middleware.mdx
│ │ └── server.mdx
│ ├── sdk/
│ │ ├── dart/
│ │ │ ├── client/
│ │ │ │ ├── client.mdx
│ │ │ │ └── overview.mdx
│ │ │ ├── core/
│ │ │ │ ├── events.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── types.mdx
│ │ │ ├── encoder/
│ │ │ │ └── overview.mdx
│ │ │ └── overview.mdx
│ │ ├── go/
│ │ │ ├── client/
│ │ │ │ ├── overview.mdx
│ │ │ │ └── sse-client.mdx
│ │ │ ├── core/
│ │ │ │ ├── events.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── types.mdx
│ │ │ ├── encoding/
│ │ │ │ └── overview.mdx
│ │ │ ├── errors/
│ │ │ │ └── overview.mdx
│ │ │ └── overview.mdx
│ │ ├── java/
│ │ │ ├── client/
│ │ │ │ ├── abstract-agent.mdx
│ │ │ │ ├── http-agent.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── subscriber.mdx
│ │ │ ├── core/
│ │ │ │ ├── events.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ ├── stream.mdx
│ │ │ │ ├── subscription.mdx
│ │ │ │ └── types.mdx
│ │ │ ├── overview.mdx
│ │ │ └── server/
│ │ │ ├── overview.mdx
│ │ │ └── spring.mdx
│ │ ├── js/
│ │ │ ├── client/
│ │ │ │ ├── abstract-agent.mdx
│ │ │ │ ├── compaction.mdx
│ │ │ │ ├── http-agent.mdx
│ │ │ │ ├── middleware.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── subscriber.mdx
│ │ │ ├── core/
│ │ │ │ ├── events.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── types.mdx
│ │ │ ├── encoder.mdx
│ │ │ ├── overview.mdx
│ │ │ └── proto.mdx
│ │ ├── kotlin/
│ │ │ ├── client/
│ │ │ │ ├── abstract-agent.mdx
│ │ │ │ ├── agui-agent.mdx
│ │ │ │ ├── http-agent.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── stateful-agui-agent.mdx
│ │ │ ├── core/
│ │ │ │ ├── events.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── types.mdx
│ │ │ ├── overview.mdx
│ │ │ └── tools/
│ │ │ ├── overview.mdx
│ │ │ ├── tool-executor.mdx
│ │ │ └── tool-registry.mdx
│ │ ├── python/
│ │ │ ├── core/
│ │ │ │ ├── events.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── types.mdx
│ │ │ └── encoder/
│ │ │ └── overview.mdx
│ │ ├── ruby/
│ │ │ ├── core/
│ │ │ │ ├── events.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── types.mdx
│ │ │ ├── encoder/
│ │ │ │ └── overview.mdx
│ │ │ └── overview.mdx
│ │ └── rust/
│ │ ├── client/
│ │ │ ├── agent-trait.mdx
│ │ │ ├── http-agent.mdx
│ │ │ ├── overview.mdx
│ │ │ └── subscriber.mdx
│ │ ├── core/
│ │ │ ├── events.mdx
│ │ │ ├── overview.mdx
│ │ │ └── types.mdx
│ │ └── overview.mdx
│ ├── snippets/
│ │ └── snippet-intro.mdx
│ └── tutorials/
│ ├── cursor.mdx
│ └── debugging.mdx
├── integrations/
│ ├── a2a/
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmrc
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── __tests__/
│ │ │ │ ├── agent.test.ts
│ │ │ │ └── utils.test.ts
│ │ │ ├── agent.ts
│ │ │ ├── index.ts
│ │ │ ├── types.ts
│ │ │ └── utils.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── adk-middleware/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ ├── ARCHITECTURE.md
│ │ │ ├── CHANGELOG.md
│ │ │ ├── CLAUDE.md
│ │ │ ├── CONFIGURATION.md
│ │ │ ├── LOGGING.md
│ │ │ ├── README.md
│ │ │ ├── STREAMING_FC_ARGS_RECONSTRUCTION.md
│ │ │ ├── TOOLS.md
│ │ │ ├── USAGE.md
│ │ │ ├── examples/
│ │ │ │ ├── README.md
│ │ │ │ ├── other/
│ │ │ │ │ ├── complete_setup.py
│ │ │ │ │ ├── configure_adk_agent.py
│ │ │ │ │ ├── context_usage.py
│ │ │ │ │ └── simple_agent.py
│ │ │ │ ├── pyproject.toml
│ │ │ │ └── server/
│ │ │ │ ├── __init__.py
│ │ │ │ └── api/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agentic_chat.py
│ │ │ │ ├── agentic_generative_ui.py
│ │ │ │ ├── backend_tool_rendering.py
│ │ │ │ ├── human_in_the_loop.py
│ │ │ │ ├── predictive_state_updates.py
│ │ │ │ ├── shared_state.py
│ │ │ │ └── tool_based_generative_ui.py
│ │ │ ├── pyproject.toml
│ │ │ ├── pytest.ini
│ │ │ ├── src/
│ │ │ │ └── ag_ui_adk/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── adk_agent.py
│ │ │ │ ├── agui_toolset.py
│ │ │ │ ├── client_proxy_tool.py
│ │ │ │ ├── client_proxy_toolset.py
│ │ │ │ ├── config.py
│ │ │ │ ├── endpoint.py
│ │ │ │ ├── event_translator.py
│ │ │ │ ├── execution_state.py
│ │ │ │ ├── session_manager.py
│ │ │ │ └── utils/
│ │ │ │ ├── __init__.py
│ │ │ │ └── converters.py
│ │ │ └── tests/
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── run_all_tests.sh
│ │ │ ├── server_setup.py
│ │ │ ├── test_adk_agent.py
│ │ │ ├── test_adk_agent_memory_integration.py
│ │ │ ├── test_adk_llm_flow_tool_override.py
│ │ │ ├── test_app_name_extractor.py
│ │ │ ├── test_chunk_event.py
│ │ │ ├── test_claude_streaming.py
│ │ │ ├── test_client_proxy_tool.py
│ │ │ ├── test_client_proxy_toolset.py
│ │ │ ├── test_concurrency.py
│ │ │ ├── test_concurrent_limits.py
│ │ │ ├── test_context_handling.py
│ │ │ ├── test_context_integration.py
│ │ │ ├── test_credential_service_defaults.py
│ │ │ ├── test_duplicate_function_response.py
│ │ │ ├── test_endpoint.py
│ │ │ ├── test_endpoint_error_handling.py
│ │ │ ├── test_event_bookending.py
│ │ │ ├── test_event_translator_comprehensive.py
│ │ │ ├── test_execution_state.py
│ │ │ ├── test_from_app_integration.py
│ │ │ ├── test_hitl_resumption_text_output.py
│ │ │ ├── test_integration.py
│ │ │ ├── test_integration_mixed_partials.py
│ │ │ ├── test_issue_437_skip_summarization_integration.py
│ │ │ ├── test_lro_filtering.py
│ │ │ ├── test_lro_sse_id_remap.py
│ │ │ ├── test_lro_sse_persistence.py
│ │ │ ├── test_lro_tool_response_persistence.py
│ │ │ ├── test_message_history.py
│ │ │ ├── test_multi_turn_conversation.py
│ │ │ ├── test_non_streaming_text_with_lro_tool.py
│ │ │ ├── test_predictive_state.py
│ │ │ ├── test_resumability_config.py
│ │ │ ├── test_sequential_agent_hitl_resumption.py
│ │ │ ├── test_session_cleanup.py
│ │ │ ├── test_session_creation.py
│ │ │ ├── test_session_deletion.py
│ │ │ ├── test_session_memory.py
│ │ │ ├── test_skip_summarization.py
│ │ │ ├── test_stale_session_invocation_id.py
│ │ │ ├── test_streaming.py
│ │ │ ├── test_streaming_fc_args.py
│ │ │ ├── test_text_events.py
│ │ │ ├── test_thought_to_thinking_integration.py
│ │ │ ├── test_tool_error_handling.py
│ │ │ ├── test_tool_result_flow.py
│ │ │ ├── test_tool_tracking_hitl.py
│ │ │ ├── test_use_thread_id_as_session_id.py
│ │ │ ├── test_user_id_extractor.py
│ │ │ ├── test_utils_converters.py
│ │ │ ├── test_utils_init.py
│ │ │ └── test_vertex_session_service.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ └── tsdown.config.ts
│ ├── ag2/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ └── examples/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── pyproject.toml
│ │ │ └── server/
│ │ │ ├── __init__.py
│ │ │ └── api/
│ │ │ ├── __init__.py
│ │ │ ├── agentic_chat.py
│ │ │ ├── agentic_generative_ui.py
│ │ │ ├── backend_tool_rendering.py
│ │ │ ├── human_in_the_loop.py
│ │ │ ├── shared_state.py
│ │ │ └── tool_based_generative_ui.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── agent-spec/
│ │ └── python/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── ag_ui_agentspec/
│ │ │ ├── __init__.py
│ │ │ ├── agent.py
│ │ │ ├── agentspec_tracing_exporter.py
│ │ │ ├── agentspecloader.py
│ │ │ ├── endpoint.py
│ │ │ └── runtimes/
│ │ │ ├── __init__.py
│ │ │ ├── langgraph_runner.py
│ │ │ └── wayflow_runner.py
│ │ ├── examples/
│ │ │ ├── README.md
│ │ │ ├── pyproject.toml
│ │ │ └── server/
│ │ │ ├── __init__.py
│ │ │ └── api/
│ │ │ ├── A2UI_PROMPT.txt
│ │ │ ├── __init__.py
│ │ │ ├── a2ui_chat.py
│ │ │ ├── agentic_chat.py
│ │ │ ├── backend_tool_rendering.py
│ │ │ ├── human_in_the_loop.py
│ │ │ ├── routes.py
│ │ │ └── tool_based_generative_ui.py
│ │ └── pyproject.toml
│ ├── agno/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ └── examples/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── pyproject.toml
│ │ │ ├── requirements.txt
│ │ │ └── server/
│ │ │ ├── __init__.py
│ │ │ └── api/
│ │ │ ├── __init__.py
│ │ │ ├── agentic_chat.py
│ │ │ ├── backend_tool_rendering.py
│ │ │ ├── human_in_the_loop.py
│ │ │ └── tool_based_generative_ui.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── aws-strands/
│ │ ├── ARCHITECTURE.md
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── examples/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── pyproject.toml
│ │ │ │ └── server/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __main__.py
│ │ │ │ └── api/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agentic_chat.py
│ │ │ │ ├── agentic_generative_ui.py
│ │ │ │ ├── backend_tool_rendering.py
│ │ │ │ ├── human_in_the_loop.py
│ │ │ │ └── shared_state.py
│ │ │ ├── pyproject.toml
│ │ │ ├── src/
│ │ │ │ └── ag_ui_strands/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agent.py
│ │ │ │ ├── client_proxy_tool.py
│ │ │ │ ├── config.py
│ │ │ │ ├── endpoint.py
│ │ │ │ ├── types.py
│ │ │ │ └── utils.py
│ │ │ └── tests/
│ │ │ ├── __init__.py
│ │ │ └── test_client_proxy_tool.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── claude-agent-sdk/
│ │ ├── .gitignore
│ │ ├── python/
│ │ │ ├── README.md
│ │ │ ├── ag_ui_claude_sdk/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── adapter.py
│ │ │ │ ├── config.py
│ │ │ │ ├── endpoint.py
│ │ │ │ ├── handlers.py
│ │ │ │ ├── session.py
│ │ │ │ ├── types.py
│ │ │ │ └── utils.py
│ │ │ ├── examples/
│ │ │ │ ├── README.md
│ │ │ │ ├── agents/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── agentic_chat.py
│ │ │ │ │ ├── backend_tool_rendering.py
│ │ │ │ │ ├── constants.py
│ │ │ │ │ ├── human_in_the_loop.py
│ │ │ │ │ ├── shared_state.py
│ │ │ │ │ └── tool_based_generative_ui.py
│ │ │ │ ├── pyproject.toml
│ │ │ │ └── server.py
│ │ │ └── pyproject.toml
│ │ └── typescript/
│ │ ├── README.md
│ │ ├── examples/
│ │ │ ├── agentic_chat.ts
│ │ │ ├── backend_tool_rendering.ts
│ │ │ ├── constants.ts
│ │ │ ├── human_in_the_loop.ts
│ │ │ ├── server.ts
│ │ │ ├── shared_state.ts
│ │ │ └── tool_based_generative_ui.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── adapter.ts
│ │ │ ├── config.ts
│ │ │ ├── handlers.ts
│ │ │ ├── index.ts
│ │ │ ├── types.ts
│ │ │ └── utils.ts
│ │ ├── tsconfig.json
│ │ ├── tsup.config.ts
│ │ └── vitest.config.ts
│ ├── community/
│ │ ├── genkit/
│ │ │ └── go/
│ │ │ ├── README.md
│ │ │ ├── examples/
│ │ │ │ ├── README.md
│ │ │ │ ├── cmd/
│ │ │ │ │ └── server/
│ │ │ │ │ └── main.go
│ │ │ │ ├── go.mod
│ │ │ │ ├── go.sum
│ │ │ │ ├── internal/
│ │ │ │ │ ├── agents/
│ │ │ │ │ │ ├── agentic_chat/
│ │ │ │ │ │ │ └── agent.go
│ │ │ │ │ │ └── registry.go
│ │ │ │ │ ├── config/
│ │ │ │ │ │ └── config.go
│ │ │ │ │ └── handlers/
│ │ │ │ │ └── agent.go
│ │ │ │ └── mock/
│ │ │ │ └── mock.go
│ │ │ └── genkit/
│ │ │ ├── genkit.go
│ │ │ ├── genkit_test.go
│ │ │ ├── go.mod
│ │ │ └── go.sum
│ │ └── spring-ai/
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── crew-ai/
│ │ ├── 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
│ │ │ ├── pyproject.toml
│ │ │ └── tests/
│ │ │ └── __init__.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── langchain/
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── agent.ts
│ │ │ ├── index.ts
│ │ │ ├── messages.ts
│ │ │ ├── streaming.ts
│ │ │ └── tools.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── langgraph/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── ag_ui_langgraph/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agent.py
│ │ │ │ ├── endpoint.py
│ │ │ │ ├── middlewares/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── state_streaming.py
│ │ │ │ ├── types.py
│ │ │ │ └── utils.py
│ │ │ ├── examples/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── agents/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── a2ui_chat/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── agent.py
│ │ │ │ │ │ └── prompt.py
│ │ │ │ │ ├── agentic_chat/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── agentic_chat_reasoning/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── agentic_generative_ui/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── backend_tool_rendering/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── dojo.py
│ │ │ │ │ ├── human_in_the_loop/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── multimodal_messages/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── predictive_state_updates/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── shared_state/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── subgraphs/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ └── tool_based_generative_ui/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── agent.py
│ │ │ │ ├── langgraph.json
│ │ │ │ └── pyproject.toml
│ │ │ ├── pyproject.toml
│ │ │ └── tests/
│ │ │ ├── __init__.py
│ │ │ ├── test_make_json_safe.py
│ │ │ ├── test_multimodal.py
│ │ │ └── test_state_streaming_middleware.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── examples/
│ │ │ ├── .env.example
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── langgraph.json
│ │ │ ├── package.json
│ │ │ ├── pnpm-workspace.yaml
│ │ │ ├── src/
│ │ │ │ └── agents/
│ │ │ │ ├── agentic_chat/
│ │ │ │ │ └── agent.ts
│ │ │ │ ├── agentic_generative_ui/
│ │ │ │ │ └── agent.ts
│ │ │ │ ├── backend_tool_rendering/
│ │ │ │ │ └── agent.ts
│ │ │ │ ├── human_in_the_loop/
│ │ │ │ │ └── agent.ts
│ │ │ │ ├── multimodal_messages/
│ │ │ │ │ └── agent.ts
│ │ │ │ ├── predictive_state_updates/
│ │ │ │ │ └── agent.ts
│ │ │ │ ├── shared_state/
│ │ │ │ │ └── agent.ts
│ │ │ │ ├── subgraphs/
│ │ │ │ │ └── agent.ts
│ │ │ │ └── tool_based_generative_ui/
│ │ │ │ └── agent.ts
│ │ │ └── tsconfig.json
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── agent.ts
│ │ │ ├── index.ts
│ │ │ ├── messages-tuple.test.ts
│ │ │ ├── middlewares/
│ │ │ │ ├── index.ts
│ │ │ │ ├── state-streaming.test.ts
│ │ │ │ └── state-streaming.ts
│ │ │ ├── types.ts
│ │ │ ├── utils.test.ts
│ │ │ └── utils.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── langroid/
│ │ ├── ARCHITECTURE.md
│ │ ├── README.md
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── examples/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── pyproject.toml
│ │ │ │ └── server/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __main__.py
│ │ │ │ └── api/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agentic_chat.py
│ │ │ │ ├── agentic_generative_ui.py
│ │ │ │ ├── backend_tool_rendering.py
│ │ │ │ └── shared_state.py
│ │ │ ├── pyproject.toml
│ │ │ ├── src/
│ │ │ │ └── ag_ui_langroid/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agent.py
│ │ │ │ ├── endpoint.py
│ │ │ │ ├── types.py
│ │ │ │ └── utils.py
│ │ │ └── tests/
│ │ │ ├── __init__.py
│ │ │ ├── test_agent.py
│ │ │ ├── test_endpoint.py
│ │ │ └── test_types.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── index.test.ts
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ └── tsup.config.ts
│ ├── llama-index/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ └── examples/
│ │ │ ├── README.md
│ │ │ ├── pyproject.toml
│ │ │ └── server/
│ │ │ ├── __init__.py
│ │ │ └── routers/
│ │ │ ├── agentic_chat.py
│ │ │ ├── agentic_generative_ui.py
│ │ │ ├── backend_tool_rendering.py
│ │ │ ├── human_in_the_loop.py
│ │ │ └── shared_state.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── mastra/
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── examples/
│ │ │ ├── .env.example
│ │ │ ├── .gitignore
│ │ │ ├── package.json
│ │ │ ├── src/
│ │ │ │ └── mastra/
│ │ │ │ ├── agents/
│ │ │ │ │ ├── agentic-chat.ts
│ │ │ │ │ ├── backend-tool-rendering.ts
│ │ │ │ │ ├── human-in-the-loop.ts
│ │ │ │ │ └── tool-based-generative-ui.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── tools/
│ │ │ │ └── weather-tool.ts
│ │ │ └── tsconfig.json
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── __tests__/
│ │ │ │ ├── edge-cases.test.ts
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── integration.test.ts
│ │ │ │ └── message-conversion.test.ts
│ │ │ ├── copilotkit.ts
│ │ │ ├── index.ts
│ │ │ ├── mastra.ts
│ │ │ └── utils.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── microsoft-agent-framework/
│ │ ├── dotnet/
│ │ │ └── examples/
│ │ │ ├── .gitignore
│ │ │ ├── AGUIDojoServer/
│ │ │ │ ├── .dockerignore
│ │ │ │ ├── AGUIDojoServer.csproj
│ │ │ │ ├── AGUIDojoServerSerializerContext.cs
│ │ │ │ ├── AgenticUI/
│ │ │ │ │ ├── AgenticPlanningTools.cs
│ │ │ │ │ ├── AgenticUIAgent.cs
│ │ │ │ │ ├── JsonPatchOperation.cs
│ │ │ │ │ ├── Plan.cs
│ │ │ │ │ ├── Step.cs
│ │ │ │ │ └── StepStatus.cs
│ │ │ │ ├── BackendToolRendering/
│ │ │ │ │ └── WeatherInfo.cs
│ │ │ │ ├── ChatClientAgentFactory.cs
│ │ │ │ ├── Dockerfile
│ │ │ │ ├── PredictiveStateUpdates/
│ │ │ │ │ ├── DocumentState.cs
│ │ │ │ │ └── PredictiveStateUpdatesAgent.cs
│ │ │ │ ├── Program.cs
│ │ │ │ ├── Properties/
│ │ │ │ │ └── launchSettings.json
│ │ │ │ └── SharedState/
│ │ │ │ ├── Ingredient.cs
│ │ │ │ ├── Recipe.cs
│ │ │ │ ├── RecipeResponse.cs
│ │ │ │ └── SharedStateAgent.cs
│ │ │ └── README.md
│ │ └── python/
│ │ └── examples/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── agents/
│ │ │ ├── __init__.py
│ │ │ └── dojo.py
│ │ └── pyproject.toml
│ ├── pydantic-ai/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ └── examples/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── pyproject.toml
│ │ │ └── server/
│ │ │ ├── __init__.py
│ │ │ └── api/
│ │ │ ├── __init__.py
│ │ │ ├── agentic_chat.py
│ │ │ ├── agentic_generative_ui.py
│ │ │ ├── backend_tool_rendering.py
│ │ │ ├── human_in_the_loop.py
│ │ │ ├── predictive_state_updates.py
│ │ │ ├── shared_state.py
│ │ │ └── tool_based_generative_ui.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── server-starter/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ └── examples/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── example_server/
│ │ │ │ └── __init__.py
│ │ │ ├── pyproject.toml
│ │ │ └── tests/
│ │ │ └── __init__.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── server-starter-all-features/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ └── examples/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── example_server/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agentic_chat.py
│ │ │ │ ├── agentic_generative_ui.py
│ │ │ │ ├── backend_tool_rendering.py
│ │ │ │ ├── human_in_the_loop.py
│ │ │ │ ├── predictive_state_updates.py
│ │ │ │ ├── shared_state.py
│ │ │ │ └── tool_based_generative_ui.py
│ │ │ ├── pyproject.toml
│ │ │ └── tests/
│ │ │ └── __init__.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ └── vercel-ai-sdk/
│ └── typescript/
│ ├── .gitignore
│ ├── .npmignore
│ ├── README.md
│ ├── package.json
│ ├── src/
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── tsdown.config.ts
│ └── vitest.config.ts
├── lefthook.yml
├── middlewares/
│ ├── a2a-middleware/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── examples/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── buildings_management.py
│ │ │ ├── finance.py
│ │ │ ├── it.py
│ │ │ ├── orchestrator.py
│ │ │ └── pyproject.toml
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── index.ts
│ │ │ └── utils.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── a2ui-middleware/
│ │ ├── .gitignore
│ │ ├── __tests__/
│ │ │ └── a2ui-middleware.test.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── index.ts
│ │ │ ├── schema.ts
│ │ │ ├── tools.ts
│ │ │ └── types.ts
│ │ ├── tsconfig.json
│ │ ├── tsup.config.ts
│ │ └── vitest.config.ts
│ ├── mcp-apps-middleware/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── mcp-apps-middleware.test.ts
│ │ │ └── test-utils.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ └── middleware-starter/
│ ├── .gitignore
│ ├── .npmignore
│ ├── README.md
│ ├── package.json
│ ├── src/
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── tsdown.config.ts
│ └── vitest.config.ts
├── nx.json
├── package.json
├── pnpm-workspace.yaml
├── render.yaml
├── scripts/
│ ├── check-codeowners-auth.ts
│ └── rewrite-python-preview-versions.py
└── sdks/
├── community/
│ ├── dart/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── TEST_GUIDE.md
│ │ ├── analysis_options.yaml
│ │ ├── example/
│ │ │ ├── README.md
│ │ │ ├── analysis_options.yaml
│ │ │ ├── dart_output_with_tools.json
│ │ │ ├── dart_output_with_tools_fixed.json
│ │ │ └── pubspec.yaml
│ │ ├── lib/
│ │ │ ├── ag_ui.dart
│ │ │ └── src/
│ │ │ ├── client/
│ │ │ │ ├── client.dart
│ │ │ │ ├── config.dart
│ │ │ │ ├── errors.dart
│ │ │ │ └── validators.dart
│ │ │ ├── encoder/
│ │ │ │ ├── client_codec.dart
│ │ │ │ ├── decoder.dart
│ │ │ │ ├── encoder.dart
│ │ │ │ ├── errors.dart
│ │ │ │ └── stream_adapter.dart
│ │ │ ├── events/
│ │ │ │ ├── event_type.dart
│ │ │ │ └── events.dart
│ │ │ ├── sse/
│ │ │ │ ├── backoff_strategy.dart
│ │ │ │ ├── sse_client.dart
│ │ │ │ ├── sse_message.dart
│ │ │ │ └── sse_parser.dart
│ │ │ └── types/
│ │ │ ├── base.dart
│ │ │ ├── context.dart
│ │ │ ├── message.dart
│ │ │ ├── tool.dart
│ │ │ └── types.dart
│ │ ├── pubspec.yaml
│ │ └── test/
│ │ ├── ag_ui_test.dart
│ │ ├── client/
│ │ │ ├── client_test.dart
│ │ │ ├── config_test.dart
│ │ │ ├── config_test.dill
│ │ │ ├── errors_test.dart
│ │ │ ├── http_endpoints_test.dart
│ │ │ └── validators_test.dart
│ │ ├── encoder/
│ │ │ ├── client_codec_test.dart
│ │ │ ├── decoder_test.dart
│ │ │ ├── encoder_test.dart
│ │ │ ├── errors_test.dart
│ │ │ └── stream_adapter_test.dart
│ │ ├── events/
│ │ │ ├── event_test.dart
│ │ │ └── event_type_test.dart
│ │ ├── fixtures/
│ │ │ ├── events.json
│ │ │ └── sse_streams.txt
│ │ ├── integration/
│ │ │ ├── event_decoding_integration_test.dart
│ │ │ ├── fixtures_integration_test.dart
│ │ │ └── helpers/
│ │ │ └── test_helpers.dart
│ │ ├── sse/
│ │ │ ├── backoff_strategy_test.dart
│ │ │ ├── sse_client_basic_test.dart
│ │ │ ├── sse_client_stream_test.dart
│ │ │ ├── sse_client_test.dart.skip
│ │ │ ├── sse_message_test.dart
│ │ │ └── sse_parser_test.dart
│ │ └── types/
│ │ ├── base_test.dart
│ │ ├── message_test.dart
│ │ └── tool_context_test.dart
│ ├── go/
│ │ ├── .gitignore
│ │ ├── example/
│ │ │ ├── client/
│ │ │ │ ├── cmd/
│ │ │ │ │ └── main.go
│ │ │ │ ├── go.mod
│ │ │ │ ├── go.sum
│ │ │ │ └── internal/
│ │ │ │ ├── agent/
│ │ │ │ │ └── chat.go
│ │ │ │ ├── event/
│ │ │ │ │ └── parse.go
│ │ │ │ ├── message/
│ │ │ │ │ └── message.go
│ │ │ │ └── ui/
│ │ │ │ ├── model.go
│ │ │ │ ├── splash.go
│ │ │ │ ├── theme.go
│ │ │ │ └── typing.go
│ │ │ └── server/
│ │ │ ├── cmd/
│ │ │ │ └── main.go
│ │ │ ├── go.mod
│ │ │ ├── go.sum
│ │ │ └── internal/
│ │ │ ├── agentic/
│ │ │ │ ├── agentic.go
│ │ │ │ ├── agentic_integration_test.go
│ │ │ │ ├── data/
│ │ │ │ │ ├── languages_prompt.md
│ │ │ │ │ └── reminder.md
│ │ │ │ └── handler.go
│ │ │ ├── config/
│ │ │ │ └── config.go
│ │ │ ├── mcp/
│ │ │ │ ├── adapter.go
│ │ │ │ └── server.go
│ │ │ └── routes/
│ │ │ └── routes.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── pkg/
│ │ ├── client/
│ │ │ └── sse/
│ │ │ ├── client.go
│ │ │ ├── client_stream_test.go
│ │ │ └── client_test.go
│ │ ├── core/
│ │ │ ├── events/
│ │ │ │ ├── activity_events.go
│ │ │ │ ├── activity_events_test.go
│ │ │ │ ├── additional_events_test.go
│ │ │ │ ├── custom_events.go
│ │ │ │ ├── decoder.go
│ │ │ │ ├── decoder_test.go
│ │ │ │ ├── events.go
│ │ │ │ ├── events_test.go
│ │ │ │ ├── id_utils.go
│ │ │ │ ├── id_utils_test.go
│ │ │ │ ├── message_events.go
│ │ │ │ ├── reasoning_events.go
│ │ │ │ ├── run_events.go
│ │ │ │ ├── state_events.go
│ │ │ │ ├── state_events_test.go
│ │ │ │ ├── thinking_events.go
│ │ │ │ ├── thinking_events_test.go
│ │ │ │ └── tool_events.go
│ │ │ └── types/
│ │ │ ├── message_helpers.go
│ │ │ ├── types.go
│ │ │ └── types_test.go
│ │ ├── encoding/
│ │ │ ├── buffer_sizing.go
│ │ │ ├── encoder/
│ │ │ │ └── encoder.go
│ │ │ ├── errors.go
│ │ │ ├── interface.go
│ │ │ ├── json/
│ │ │ │ ├── json.go
│ │ │ │ ├── json_codec.go
│ │ │ │ ├── json_decoder.go
│ │ │ │ └── json_encoder.go
│ │ │ ├── negotiation/
│ │ │ │ ├── negotiator.go
│ │ │ │ ├── negotiator_test.go
│ │ │ │ ├── parser.go
│ │ │ │ └── selector.go
│ │ │ ├── pool.go
│ │ │ └── sse/
│ │ │ ├── writer.go
│ │ │ └── writer_test.go
│ │ └── errors/
│ │ ├── error_types.go
│ │ └── error_utils.go
│ ├── java/
│ │ ├── .gitignore
│ │ ├── CLAUDE.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── clients/
│ │ │ ├── ok-http/
│ │ │ │ ├── README.md
│ │ │ │ ├── pom.xml
│ │ │ │ └── src/
│ │ │ │ ├── main/
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── okhttp/
│ │ │ │ │ └── HttpClient.java
│ │ │ │ └── test/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── okhttp/
│ │ │ │ └── HttpClientTest.java
│ │ │ └── spring-client/
│ │ │ ├── pom.xml
│ │ │ └── src/
│ │ │ └── main/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── spring/
│ │ │ └── HttpClient.java
│ │ ├── examples/
│ │ │ ├── copilot-app/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── eslint.config.mjs
│ │ │ │ ├── next.config.ts
│ │ │ │ ├── package.json
│ │ │ │ ├── postcss.config.mjs
│ │ │ │ ├── src/
│ │ │ │ │ └── app/
│ │ │ │ │ ├── api/
│ │ │ │ │ │ └── copilotkit/
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ ├── globals.css
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ └── tsconfig.json
│ │ │ └── spring-ai-example/
│ │ │ ├── .gitignore
│ │ │ ├── Dockerfile
│ │ │ ├── docker-compose.yml
│ │ │ ├── pom.xml
│ │ │ └── src/
│ │ │ └── main/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── example/
│ │ │ ├── AgUiController.java
│ │ │ ├── Application.java
│ │ │ ├── config/
│ │ │ │ ├── AgUiConfig.java
│ │ │ │ └── CorsConfig.java
│ │ │ └── tools/
│ │ │ ├── GeocodingResponse.java
│ │ │ ├── WeatherRequest.java
│ │ │ ├── WeatherResponse.java
│ │ │ ├── WeatherTool.java
│ │ │ └── WeatherToolResult.java
│ │ ├── integrations/
│ │ │ └── spring-ai/
│ │ │ ├── README.md
│ │ │ ├── pom.xml
│ │ │ └── src/
│ │ │ ├── main/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── spring/
│ │ │ │ └── ai/
│ │ │ │ ├── AgUiFunctionToolCallback.java
│ │ │ │ ├── AgUiToolCallbackParams.java
│ │ │ │ ├── SpringAIAgent.java
│ │ │ │ ├── StateTool.java
│ │ │ │ └── ToolMapper.java
│ │ │ └── test/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── spring/
│ │ │ └── ai/
│ │ │ └── ToolMapperTest.java
│ │ ├── packages/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ ├── README.md
│ │ │ │ ├── pom.xml
│ │ │ │ └── src/
│ │ │ │ ├── main/
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── client/
│ │ │ │ │ ├── agent/
│ │ │ │ │ │ └── AbstractAgent.java
│ │ │ │ │ ├── message/
│ │ │ │ │ │ └── MessageFactory.java
│ │ │ │ │ └── verifier/
│ │ │ │ │ └── EventVerifier.java
│ │ │ │ └── test/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── client/
│ │ │ │ ├── agent/
│ │ │ │ │ └── AbstractAgentTest.java
│ │ │ │ ├── message/
│ │ │ │ │ └── MessageFactoryTest.java
│ │ │ │ └── verifier/
│ │ │ │ └── EventVerifierTest.java
│ │ │ ├── core/
│ │ │ │ ├── README.md
│ │ │ │ ├── pom.xml
│ │ │ │ └── src/
│ │ │ │ ├── main/
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── core/
│ │ │ │ │ ├── agent/
│ │ │ │ │ │ ├── Agent.java
│ │ │ │ │ │ ├── AgentSubscriber.java
│ │ │ │ │ │ ├── AgentSubscriberParams.java
│ │ │ │ │ │ ├── RunAgentInput.java
│ │ │ │ │ │ └── RunAgentParameters.java
│ │ │ │ │ ├── context/
│ │ │ │ │ │ └── Context.java
│ │ │ │ │ ├── event/
│ │ │ │ │ │ ├── BaseEvent.java
│ │ │ │ │ │ ├── CustomEvent.java
│ │ │ │ │ │ ├── MessagesSnapshotEvent.java
│ │ │ │ │ │ ├── RawEvent.java
│ │ │ │ │ │ ├── RunErrorEvent.java
│ │ │ │ │ │ ├── RunFinishedEvent.java
│ │ │ │ │ │ ├── RunStartedEvent.java
│ │ │ │ │ │ ├── StateDeltaEvent.java
│ │ │ │ │ │ ├── StateSnapshotEvent.java
│ │ │ │ │ │ ├── StepFinishedEvent.java
│ │ │ │ │ │ ├── StepStartedEvent.java
│ │ │ │ │ │ ├── TextMessageChunkEvent.java
│ │ │ │ │ │ ├── TextMessageContentEvent.java
│ │ │ │ │ │ ├── TextMessageEndEvent.java
│ │ │ │ │ │ ├── TextMessageStartEvent.java
│ │ │ │ │ │ ├── ThinkingEndEvent.java
│ │ │ │ │ │ ├── ThinkingStartEvent.java
│ │ │ │ │ │ ├── ThinkingTextMessageContentEvent.java
│ │ │ │ │ │ ├── ThinkingTextMessageEndEvent.java
│ │ │ │ │ │ ├── ThinkingTextMessageStartEvent.java
│ │ │ │ │ │ ├── ToolCallArgsEvent.java
│ │ │ │ │ │ ├── ToolCallChunkEvent.java
│ │ │ │ │ │ ├── ToolCallEndEvent.java
│ │ │ │ │ │ ├── ToolCallResultEvent.java
│ │ │ │ │ │ └── ToolCallStartEvent.java
│ │ │ │ │ ├── exception/
│ │ │ │ │ │ └── AGUIException.java
│ │ │ │ │ ├── function/
│ │ │ │ │ │ └── FunctionCall.java
│ │ │ │ │ ├── message/
│ │ │ │ │ │ ├── AssistantMessage.java
│ │ │ │ │ │ ├── BaseMessage.java
│ │ │ │ │ │ ├── DeveloperMessage.java
│ │ │ │ │ │ ├── Role.java
│ │ │ │ │ │ ├── SystemMessage.java
│ │ │ │ │ │ ├── ToolMessage.java
│ │ │ │ │ │ └── UserMessage.java
│ │ │ │ │ ├── state/
│ │ │ │ │ │ └── State.java
│ │ │ │ │ ├── stream/
│ │ │ │ │ │ ├── EventStream.java
│ │ │ │ │ │ └── IEventStream.java
│ │ │ │ │ ├── subscription/
│ │ │ │ │ │ └── Subscription.java
│ │ │ │ │ ├── tool/
│ │ │ │ │ │ ├── Tool.java
│ │ │ │ │ │ └── ToolCall.java
│ │ │ │ │ └── type/
│ │ │ │ │ └── EventType.java
│ │ │ │ └── test/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── core/
│ │ │ │ ├── agent/
│ │ │ │ │ ├── AgentSubscriberParamsTest.java
│ │ │ │ │ ├── AgentSubscriberTest.java
│ │ │ │ │ ├── RunAgentInputTest.java
│ │ │ │ │ └── RunAgentParametersTest.java
│ │ │ │ ├── context/
│ │ │ │ │ └── ContextTest.java
│ │ │ │ ├── event/
│ │ │ │ │ ├── BaseEventTest.java
│ │ │ │ │ ├── CustomEventTest.java
│ │ │ │ │ ├── MessagesSnapshotEventTest.java
│ │ │ │ │ ├── RawEventTest.java
│ │ │ │ │ ├── RunErrorEventTest.java
│ │ │ │ │ ├── RunFinishedEventTest.java
│ │ │ │ │ ├── RunStartedEventTest.java
│ │ │ │ │ ├── StateDeltaEventTest.java
│ │ │ │ │ ├── StateSnapshotEventTest.java
│ │ │ │ │ ├── StepFinishedEventTest.java
│ │ │ │ │ ├── StepStartedEventTest.java
│ │ │ │ │ ├── TextMessageChunkEventTest.java
│ │ │ │ │ ├── TextMessageContentEventTest.java
│ │ │ │ │ ├── TextMessageEndEventTest.java
│ │ │ │ │ ├── TextMessageStartEventTest.java
│ │ │ │ │ ├── ThinkingEndEventTest.java
│ │ │ │ │ ├── ThinkingStartEventTest.java
│ │ │ │ │ ├── ThinkingTextMessageContentEventTest.java
│ │ │ │ │ ├── ThinkingTextMessageEndEventTest.java
│ │ │ │ │ ├── ThinkingTextMessageStartEventTest.java
│ │ │ │ │ ├── ToolCallArgsEventTest.java
│ │ │ │ │ ├── ToolCallChunkEventTest.java
│ │ │ │ │ ├── ToolCallEndEventTest.java
│ │ │ │ │ ├── ToolCallResultEventTest.java
│ │ │ │ │ └── ToolCallStartEventTest.java
│ │ │ │ ├── exception/
│ │ │ │ │ └── AGUIExceptionTest.java
│ │ │ │ ├── function/
│ │ │ │ │ └── FunctionCallTest.java
│ │ │ │ ├── message/
│ │ │ │ │ ├── AssistantMessageTest.java
│ │ │ │ │ ├── DeveloperMessageTest.java
│ │ │ │ │ ├── SystemMessageTest.java
│ │ │ │ │ ├── ToolMessageTest.java
│ │ │ │ │ └── UserMessageTest.java
│ │ │ │ ├── state/
│ │ │ │ │ └── StateTest.java
│ │ │ │ ├── stream/
│ │ │ │ │ ├── EventStreamTest.java
│ │ │ │ │ └── IEventStreamTest.java
│ │ │ │ ├── subscription/
│ │ │ │ │ └── SubscriptionTest.java
│ │ │ │ ├── tool/
│ │ │ │ │ ├── ToolCallTest.java
│ │ │ │ │ └── ToolTest.java
│ │ │ │ └── type/
│ │ │ │ └── EventTypeTest.java
│ │ │ ├── http/
│ │ │ │ ├── README.md
│ │ │ │ ├── pom.xml
│ │ │ │ └── src/
│ │ │ │ ├── main/
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── http/
│ │ │ │ │ ├── BaseHttpClient.java
│ │ │ │ │ └── HttpAgent.java
│ │ │ │ └── test/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── http/
│ │ │ │ ├── BaseHttpClientTest.java
│ │ │ │ └── HttpAgentTest.java
│ │ │ └── server/
│ │ │ ├── README.md
│ │ │ ├── pom.xml
│ │ │ └── src/
│ │ │ ├── main/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── server/
│ │ │ │ ├── EventFactory.java
│ │ │ │ ├── LocalAgent.java
│ │ │ │ └── streamer/
│ │ │ │ └── AgentStreamer.java
│ │ │ └── test/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── server/
│ │ │ ├── EventFactoryTest.java
│ │ │ ├── LocalAgentTest.java
│ │ │ └── streamer/
│ │ │ └── AgentStreamerTest.java
│ │ ├── pom.xml
│ │ ├── servers/
│ │ │ └── spring/
│ │ │ ├── README.md
│ │ │ ├── pom.xml
│ │ │ └── src/
│ │ │ ├── main/
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── server/
│ │ │ │ │ └── spring/
│ │ │ │ │ ├── AgUiAutoConfiguration.java
│ │ │ │ │ ├── AgUiParameters.java
│ │ │ │ │ └── AgUiService.java
│ │ │ │ └── resources/
│ │ │ │ └── META-INF/
│ │ │ │ ├── spring/
│ │ │ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
│ │ │ │ └── spring.factories
│ │ │ └── test/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── server/
│ │ │ └── spring/
│ │ │ └── AgUiParametersTest.java
│ │ └── utils/
│ │ └── json/
│ │ ├── README.md
│ │ ├── pom.xml
│ │ └── src/
│ │ ├── main/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── json/
│ │ │ ├── ObjectMapperFactory.java
│ │ │ └── mixins/
│ │ │ ├── EventMixin.java
│ │ │ ├── MessageMixin.java
│ │ │ └── StateMixin.java
│ │ └── test/
│ │ └── java/
│ │ └── com/
│ │ └── agui/
│ │ └── json/
│ │ └── ObjectMapperFactoryTest.java
│ ├── kotlin/
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── OVERVIEW.md
│ │ ├── PERFORMANCE.md
│ │ ├── README.md
│ │ ├── build.bat
│ │ ├── build.gradle.kts
│ │ ├── build.sh
│ │ ├── detekt-config.yml
│ │ ├── examples/
│ │ │ ├── chatapp/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── CHANGELOG.md
│ │ │ │ ├── README.md
│ │ │ │ ├── androidApp/
│ │ │ │ │ ├── build.gradle.kts
│ │ │ │ │ └── src/
│ │ │ │ │ └── main/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ ├── assets/
│ │ │ │ │ │ └── logback.xml
│ │ │ │ │ └── res/
│ │ │ │ │ ├── drawable/
│ │ │ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ │ │ ├── mipmap-anydpi/
│ │ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ │ └── values/
│ │ │ │ │ └── strings.xml
│ │ │ │ ├── build.gradle.kts
│ │ │ │ ├── desktopApp/
│ │ │ │ │ └── build.gradle.kts
│ │ │ │ ├── gradle/
│ │ │ │ │ ├── libs.versions.toml
│ │ │ │ │ └── wrapper/
│ │ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ │ └── gradle-wrapper.properties
│ │ │ │ ├── gradle.properties
│ │ │ │ ├── gradlew
│ │ │ │ ├── gradlew.bat
│ │ │ │ ├── iosApp/
│ │ │ │ │ ├── README.md
│ │ │ │ │ ├── iosApp/
│ │ │ │ │ │ ├── Assets.xcassets/
│ │ │ │ │ │ │ ├── AccentColor.colorset/
│ │ │ │ │ │ │ │ └── Contents.json
│ │ │ │ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ │ │ │ └── Contents.json
│ │ │ │ │ │ │ └── Contents.json
│ │ │ │ │ │ ├── ContentView.swift
│ │ │ │ │ │ ├── Info.plist
│ │ │ │ │ │ └── iOSApp.swift
│ │ │ │ │ └── iosApp.xcodeproj/
│ │ │ │ │ ├── project.pbxproj
│ │ │ │ │ └── project.xcworkspace/
│ │ │ │ │ └── contents.xcworkspacedata
│ │ │ │ ├── settings.gradle.kts
│ │ │ │ ├── shared/
│ │ │ │ │ ├── build.gradle.kts
│ │ │ │ │ └── src/
│ │ │ │ │ ├── androidInstrumentedTest/
│ │ │ │ │ │ └── kotlin/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ ├── AndroidIntegrationTest.kt
│ │ │ │ │ │ ├── AndroidSettingsTest.kt
│ │ │ │ │ │ ├── MinimalAndroidTest.kt
│ │ │ │ │ │ └── ui/
│ │ │ │ │ │ ├── MessageBubbleTest.kt
│ │ │ │ │ │ └── components/
│ │ │ │ │ │ └── MessageBubbleComponentTest.kt
│ │ │ │ │ ├── androidMain/
│ │ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ │ └── kotlin/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ └── MainActivity.kt
│ │ │ │ │ ├── commonMain/
│ │ │ │ │ │ ├── composeResources/
│ │ │ │ │ │ │ └── values/
│ │ │ │ │ │ │ └── strings.xml
│ │ │ │ │ │ └── kotlin/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ ├── App.kt
│ │ │ │ │ │ ├── ui/
│ │ │ │ │ │ │ ├── screens/
│ │ │ │ │ │ │ │ ├── chat/
│ │ │ │ │ │ │ │ │ ├── ChatScreen.kt
│ │ │ │ │ │ │ │ │ ├── ChatViewModel.kt
│ │ │ │ │ │ │ │ │ └── components/
│ │ │ │ │ │ │ │ │ ├── ChatHeader.kt
│ │ │ │ │ │ │ │ │ ├── ChatInput.kt
│ │ │ │ │ │ │ │ │ ├── ClawgUiPairingDialog.kt
│ │ │ │ │ │ │ │ │ ├── MessageBubble.kt
│ │ │ │ │ │ │ │ │ └── MessageList.kt
│ │ │ │ │ │ │ │ └── settings/
│ │ │ │ │ │ │ │ ├── SettingsScreen.kt
│ │ │ │ │ │ │ │ ├── SettingsViewModel.kt
│ │ │ │ │ │ │ │ └── components/
│ │ │ │ │ │ │ │ ├── AddAgentDialog.kt
│ │ │ │ │ │ │ │ └── AgentCard.kt
│ │ │ │ │ │ │ └── theme/
│ │ │ │ │ │ │ ├── Color.kt
│ │ │ │ │ │ │ └── Theme.kt
│ │ │ │ │ │ └── util/
│ │ │ │ │ │ └── Extensions.kt
│ │ │ │ │ ├── commonTest/
│ │ │ │ │ │ └── kotlin/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ ├── auth/
│ │ │ │ │ │ │ └── AuthProviderTest.kt
│ │ │ │ │ │ ├── test/
│ │ │ │ │ │ │ └── TestSettings.kt
│ │ │ │ │ │ └── viewmodel/
│ │ │ │ │ │ └── ChatViewModelBehaviorTest.kt
│ │ │ │ │ ├── desktopMain/
│ │ │ │ │ │ └── kotlin/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ └── Main.kt
│ │ │ │ │ ├── desktopTest/
│ │ │ │ │ │ └── kotlin/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ ├── auth/
│ │ │ │ │ │ │ └── AuthManagerIntegrationTest.kt
│ │ │ │ │ │ └── repository/
│ │ │ │ │ │ └── AgentRepositoryPersistenceTest.kt
│ │ │ │ │ ├── iosMain/
│ │ │ │ │ │ └── kotlin/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ └── MainViewController.kt
│ │ │ │ │ └── iosTest/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── example/
│ │ │ │ │ └── chatapp/
│ │ │ │ │ ├── IosPlatformTest.kt
│ │ │ │ │ ├── IosSettingsTest.kt
│ │ │ │ │ └── IosUserIdManagerTest.kt
│ │ │ │ └── verify-ios-implementation.sh
│ │ │ ├── chatapp-java/
│ │ │ │ ├── README.md
│ │ │ │ ├── app/
│ │ │ │ │ ├── build.gradle
│ │ │ │ │ ├── proguard-rules.pro
│ │ │ │ │ └── src/
│ │ │ │ │ ├── androidTest/
│ │ │ │ │ │ └── java/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ └── java/
│ │ │ │ │ │ ├── MultiAgentInstrumentedTest.java
│ │ │ │ │ │ └── ui/
│ │ │ │ │ │ ├── ChatActivityTest.java
│ │ │ │ │ │ ├── SettingsActivityTest.java
│ │ │ │ │ │ └── SettingsActivityTest.java.old
│ │ │ │ │ └── main/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ ├── java/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ └── java/
│ │ │ │ │ │ ├── ChatJavaApplication.java
│ │ │ │ │ │ ├── model/
│ │ │ │ │ │ │ └── ChatMessage.java
│ │ │ │ │ │ ├── repository/
│ │ │ │ │ │ │ └── MultiAgentRepository.kt
│ │ │ │ │ │ ├── ui/
│ │ │ │ │ │ │ ├── ChatActivity.java
│ │ │ │ │ │ │ ├── SettingsActivity.java
│ │ │ │ │ │ │ └── adapter/
│ │ │ │ │ │ │ ├── AgentListAdapter.java
│ │ │ │ │ │ │ └── MessageAdapter.java
│ │ │ │ │ │ └── viewmodel/
│ │ │ │ │ │ └── ChatViewModel.kt
│ │ │ │ │ └── res/
│ │ │ │ │ ├── drawable/
│ │ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ │ │ ├── layout/
│ │ │ │ │ │ ├── activity_chat.xml
│ │ │ │ │ │ ├── activity_settings.xml
│ │ │ │ │ │ ├── dialog_agent_form.xml
│ │ │ │ │ │ ├── item_agent_card.xml
│ │ │ │ │ │ ├── item_message_assistant.xml
│ │ │ │ │ │ ├── item_message_system.xml
│ │ │ │ │ │ └── item_message_user.xml
│ │ │ │ │ ├── menu/
│ │ │ │ │ │ └── chat_menu.xml
│ │ │ │ │ ├── mipmap-anydpi-v26/
│ │ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ │ ├── values/
│ │ │ │ │ │ ├── colors.xml
│ │ │ │ │ │ ├── strings.xml
│ │ │ │ │ │ └── themes.xml
│ │ │ │ │ ├── values-night/
│ │ │ │ │ │ └── themes.xml
│ │ │ │ │ └── xml/
│ │ │ │ │ ├── backup_rules.xml
│ │ │ │ │ └── data_extraction_rules.xml
│ │ │ │ ├── build.gradle
│ │ │ │ ├── gradle/
│ │ │ │ │ ├── libs.versions.toml
│ │ │ │ │ └── wrapper/
│ │ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ │ └── gradle-wrapper.properties
│ │ │ │ ├── gradle.properties
│ │ │ │ ├── gradlew
│ │ │ │ ├── gradlew.bat
│ │ │ │ └── settings.gradle
│ │ │ ├── chatapp-shared/
│ │ │ │ ├── README.md
│ │ │ │ ├── build.gradle.kts
│ │ │ │ ├── gradle.properties
│ │ │ │ ├── settings.gradle.kts
│ │ │ │ └── src/
│ │ │ │ ├── androidMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── example/
│ │ │ │ │ └── chatapp/
│ │ │ │ │ ├── data/
│ │ │ │ │ │ └── pairing/
│ │ │ │ │ │ └── PairingHttpClientFactory.kt
│ │ │ │ │ └── util/
│ │ │ │ │ └── AndroidPlatform.kt
│ │ │ │ ├── commonMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── example/
│ │ │ │ │ ├── chatapp/
│ │ │ │ │ │ ├── chat/
│ │ │ │ │ │ │ ├── ChatAgent.kt
│ │ │ │ │ │ │ └── ChatController.kt
│ │ │ │ │ │ ├── data/
│ │ │ │ │ │ │ ├── auth/
│ │ │ │ │ │ │ │ ├── ApiKeyAuthProvider.kt
│ │ │ │ │ │ │ │ ├── AuthManager.kt
│ │ │ │ │ │ │ │ ├── AuthProvider.kt
│ │ │ │ │ │ │ │ ├── BasicAuthProvider.kt
│ │ │ │ │ │ │ │ └── BearerTokenAuthProvider.kt
│ │ │ │ │ │ │ ├── model/
│ │ │ │ │ │ │ │ ├── AgentConfig.kt
│ │ │ │ │ │ │ │ ├── AuthMethod.kt
│ │ │ │ │ │ │ │ └── ClawgUiPairingResponse.kt
│ │ │ │ │ │ │ ├── pairing/
│ │ │ │ │ │ │ │ ├── ClawgUiPairingService.kt
│ │ │ │ │ │ │ │ └── PairingHttpClientFactory.kt
│ │ │ │ │ │ │ └── repository/
│ │ │ │ │ │ │ └── AgentRepository.kt
│ │ │ │ │ │ └── util/
│ │ │ │ │ │ ├── Platform.kt
│ │ │ │ │ │ ├── StringResourceProvider.kt
│ │ │ │ │ │ └── UserIdManager.kt
│ │ │ │ │ └── tools/
│ │ │ │ │ └── ChangeBackgroundToolExecutor.kt
│ │ │ │ ├── commonTest/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── example/
│ │ │ │ │ └── chatapp/
│ │ │ │ │ ├── chat/
│ │ │ │ │ │ └── ChatControllerTest.kt
│ │ │ │ │ ├── data/
│ │ │ │ │ │ ├── AgentRepositoryTest.kt
│ │ │ │ │ │ ├── AuthManagerTest.kt
│ │ │ │ │ │ └── pairing/
│ │ │ │ │ │ └── ClawgUiPairingServiceTest.kt
│ │ │ │ │ └── testutil/
│ │ │ │ │ └── FakeSettings.kt
│ │ │ │ ├── desktopMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── example/
│ │ │ │ │ └── chatapp/
│ │ │ │ │ ├── data/
│ │ │ │ │ │ └── pairing/
│ │ │ │ │ │ └── PairingHttpClientFactory.kt
│ │ │ │ │ └── util/
│ │ │ │ │ └── DesktopPlatform.kt
│ │ │ │ └── iosMain/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── example/
│ │ │ │ └── chatapp/
│ │ │ │ ├── data/
│ │ │ │ │ └── pairing/
│ │ │ │ │ └── PairingHttpClientFactory.kt
│ │ │ │ └── util/
│ │ │ │ └── IosPlatform.kt
│ │ │ ├── chatapp-swiftui/
│ │ │ │ ├── README.md
│ │ │ │ ├── build.gradle.kts
│ │ │ │ ├── gradle/
│ │ │ │ │ ├── libs.versions.toml
│ │ │ │ │ └── wrapper/
│ │ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ │ └── gradle-wrapper.properties
│ │ │ │ ├── gradle.properties
│ │ │ │ ├── gradlew
│ │ │ │ ├── gradlew.bat
│ │ │ │ ├── iosApp/
│ │ │ │ │ ├── ChatAppSwiftUI.xcodeproj/
│ │ │ │ │ │ ├── project.pbxproj
│ │ │ │ │ │ └── project.xcworkspace/
│ │ │ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ │ │ └── xcshareddata/
│ │ │ │ │ │ └── swiftpm/
│ │ │ │ │ │ └── Package.resolved
│ │ │ │ │ ├── Resources/
│ │ │ │ │ │ ├── Assets.xcassets/
│ │ │ │ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ │ │ │ └── Contents.json
│ │ │ │ │ │ │ └── Contents.json
│ │ │ │ │ │ ├── Info.plist
│ │ │ │ │ │ └── LaunchScreen.storyboard
│ │ │ │ │ ├── Sources/
│ │ │ │ │ │ ├── App/
│ │ │ │ │ │ │ └── ChatAppSwiftUIApp.swift
│ │ │ │ │ │ ├── Store/
│ │ │ │ │ │ │ └── ChatAppStore.swift
│ │ │ │ │ │ └── Views/
│ │ │ │ │ │ ├── AgentFormView.swift
│ │ │ │ │ │ ├── ChatView.swift
│ │ │ │ │ │ ├── Components/
│ │ │ │ │ │ │ └── AgentListView.swift
│ │ │ │ │ │ └── RootView.swift
│ │ │ │ │ └── project.yml
│ │ │ │ ├── settings.gradle.kts
│ │ │ │ └── shared/
│ │ │ │ ├── build.gradle.kts
│ │ │ │ └── src/
│ │ │ │ └── commonMain/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── example/
│ │ │ │ └── chatapp/
│ │ │ │ └── bridge/
│ │ │ │ └── SwiftBridge.kt
│ │ │ ├── chatapp-wearos/
│ │ │ │ ├── README.md
│ │ │ │ ├── build.gradle.kts
│ │ │ │ ├── gradle/
│ │ │ │ │ ├── libs.versions.toml
│ │ │ │ │ └── wrapper/
│ │ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ │ └── gradle-wrapper.properties
│ │ │ │ ├── gradle.properties
│ │ │ │ ├── gradlew
│ │ │ │ ├── gradlew.bat
│ │ │ │ ├── settings.gradle.kts
│ │ │ │ └── wearApp/
│ │ │ │ ├── build.gradle.kts
│ │ │ │ └── src/
│ │ │ │ └── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── example/
│ │ │ │ │ └── chatwear/
│ │ │ │ │ ├── MainActivity.kt
│ │ │ │ │ └── ui/
│ │ │ │ │ ├── ChatWearApp.kt
│ │ │ │ │ ├── WearChatViewModel.kt
│ │ │ │ │ └── theme/
│ │ │ │ │ └── ChatWearTheme.kt
│ │ │ │ └── res/
│ │ │ │ ├── drawable/
│ │ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ │ ├── mipmap-anydpi/
│ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ └── values/
│ │ │ │ ├── colors.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── themes.xml
│ │ │ └── tools/
│ │ │ ├── build.gradle.kts
│ │ │ ├── gradle/
│ │ │ │ ├── libs.versions.toml
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ ├── settings.gradle.kts
│ │ │ └── src/
│ │ │ ├── androidMain/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── example/
│ │ │ │ └── tools/
│ │ │ │ └── AndroidLocationProvider.kt
│ │ │ ├── commonMain/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── example/
│ │ │ │ └── tools/
│ │ │ │ ├── ChangeBackgroundToolExecutor.kt
│ │ │ │ └── CurrentLocationToolExecutor.kt
│ │ │ ├── commonTest/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── example/
│ │ │ │ └── tools/
│ │ │ │ ├── CurrentLocationToolTest.kt
│ │ │ │ └── ExampleToolsIntegrationTest.kt
│ │ │ ├── iosMain/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── example/
│ │ │ │ └── tools/
│ │ │ │ └── IosLocationProvider.kt
│ │ │ ├── iosTest/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── example/
│ │ │ │ └── tools/
│ │ │ │ ├── IosLocationIntegrationTest.kt
│ │ │ │ └── IosLocationProviderTest.kt
│ │ │ └── jvmMain/
│ │ │ └── kotlin/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── example/
│ │ │ └── tools/
│ │ │ └── JvmLocationProvider.kt
│ │ ├── gradle.properties
│ │ ├── library/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── build.gradle.kts
│ │ │ ├── client/
│ │ │ │ ├── build.gradle.kts
│ │ │ │ ├── consumer-rules.pro
│ │ │ │ └── src/
│ │ │ │ ├── androidMain/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── client/
│ │ │ │ │ └── agent/
│ │ │ │ │ └── HttpClientFactory.kt
│ │ │ │ ├── commonMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── client/
│ │ │ │ │ ├── AgUiAgent.kt
│ │ │ │ │ ├── ClientStateManager.kt
│ │ │ │ │ ├── StatefulAgUiAgent.kt
│ │ │ │ │ ├── agent/
│ │ │ │ │ │ ├── AbstractAgent.kt
│ │ │ │ │ │ ├── AgentSubscriber.kt
│ │ │ │ │ │ ├── HttpAgent.kt
│ │ │ │ │ │ └── HttpClientFactory.kt
│ │ │ │ │ ├── builders/
│ │ │ │ │ │ └── AgentBuilders.kt
│ │ │ │ │ ├── chunks/
│ │ │ │ │ │ └── ChunkTransform.kt
│ │ │ │ │ ├── sse/
│ │ │ │ │ │ └── SseParser.kt
│ │ │ │ │ ├── state/
│ │ │ │ │ │ ├── DefaultApplyEvents.kt
│ │ │ │ │ │ ├── JsonPointer.kt
│ │ │ │ │ │ ├── StateHandler.kt
│ │ │ │ │ │ └── StateManager.kt
│ │ │ │ │ ├── tools/
│ │ │ │ │ │ └── ClientToolResponseHandler.kt
│ │ │ │ │ └── verify/
│ │ │ │ │ └── EventVerifier.kt
│ │ │ │ ├── commonTest/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── client/
│ │ │ │ │ ├── AgUiAgentConfigTest.kt
│ │ │ │ │ ├── AgUiAgentToolsTest.kt
│ │ │ │ │ ├── IntegrationTest.kt
│ │ │ │ │ ├── StatefulAgUiAgentConfigTest.kt
│ │ │ │ │ ├── StatefulAgUiAgentTest.kt
│ │ │ │ │ ├── UserIdTest.kt
│ │ │ │ │ ├── agent/
│ │ │ │ │ │ └── AbstractAgentTest.kt
│ │ │ │ │ ├── chunks/
│ │ │ │ │ │ └── ChunkTransformTest.kt
│ │ │ │ │ ├── integration/
│ │ │ │ │ │ ├── AdvancedIntegrationTest.kt
│ │ │ │ │ │ ├── AgentToolIntegrationTest.kt
│ │ │ │ │ │ └── SimpleAgentToolIntegrationTest.kt
│ │ │ │ │ ├── sse/
│ │ │ │ │ │ └── SseParserTest.kt
│ │ │ │ │ ├── state/
│ │ │ │ │ │ ├── DefaultApplyEventsTest.kt
│ │ │ │ │ │ └── StateManagerTest.kt
│ │ │ │ │ └── verify/
│ │ │ │ │ └── EventVerifierTest.kt
│ │ │ │ ├── iosMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── client/
│ │ │ │ │ └── agent/
│ │ │ │ │ └── HttpClientFactory.kt
│ │ │ │ └── jvmMain/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── client/
│ │ │ │ └── agent/
│ │ │ │ └── HttpClientFactory.kt
│ │ │ ├── core/
│ │ │ │ ├── build.gradle.kts
│ │ │ │ └── src/
│ │ │ │ ├── androidMain/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── platform/
│ │ │ │ │ └── AndroidPlatform.kt
│ │ │ │ ├── commonMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ ├── core/
│ │ │ │ │ │ └── types/
│ │ │ │ │ │ ├── AgUiJson.kt
│ │ │ │ │ │ ├── AgUiSerializersModule.kt
│ │ │ │ │ │ ├── Events.kt
│ │ │ │ │ │ └── Types.kt
│ │ │ │ │ └── platform/
│ │ │ │ │ └── Platform.kt
│ │ │ │ ├── commonTest/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── tests/
│ │ │ │ │ ├── EventSerializationTest.kt
│ │ │ │ │ ├── MessageProtocolComplianceTest.kt
│ │ │ │ │ ├── MessageSerializationTest.kt
│ │ │ │ │ ├── RunAgentInputProtocolTest.kt
│ │ │ │ │ └── ToolSerializationDebugTest.kt
│ │ │ │ ├── iosMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── platform/
│ │ │ │ │ └── IosPlatform.kt
│ │ │ │ ├── jvmMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── platform/
│ │ │ │ │ └── JvmPlatform.kt
│ │ │ │ └── jvmTest/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── platform/
│ │ │ │ └── PlatformJvmTest.kt
│ │ │ ├── gradle/
│ │ │ │ ├── libs.versions.toml
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ ├── settings.gradle.kts
│ │ │ └── tools/
│ │ │ ├── build.gradle.kts
│ │ │ └── src/
│ │ │ ├── androidMain/
│ │ │ │ └── AndroidManifest.xml
│ │ │ ├── commonMain/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── tools/
│ │ │ │ ├── ToolErrorHandling.kt
│ │ │ │ ├── ToolExecutionManager.kt
│ │ │ │ ├── ToolExecutor.kt
│ │ │ │ └── ToolRegistry.kt
│ │ │ └── commonTest/
│ │ │ └── kotlin/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── tools/
│ │ │ ├── CircuitBreakerTest.kt
│ │ │ ├── ToolErrorHandlerTest.kt
│ │ │ ├── ToolExecutionManagerTest.kt
│ │ │ └── ToolsModuleTest.kt
│ │ ├── publish.sh
│ │ └── settings.gradle.kts
│ ├── ruby/
│ │ ├── .gitignore
│ │ ├── .yardopts
│ │ ├── CHANGELOG.md
│ │ ├── Gemfile
│ │ ├── README.md
│ │ ├── Rakefile
│ │ ├── ag-ui-protocol.gemspec
│ │ ├── example/
│ │ │ ├── rails/
│ │ │ │ ├── Gemfile
│ │ │ │ ├── README.md
│ │ │ │ ├── app/
│ │ │ │ │ └── controllers/
│ │ │ │ │ └── ag_ui_controller.rb
│ │ │ │ ├── config/
│ │ │ │ │ ├── application.rb
│ │ │ │ │ ├── boot.rb
│ │ │ │ │ ├── environment.rb
│ │ │ │ │ ├── environments/
│ │ │ │ │ │ └── development.rb
│ │ │ │ │ ├── puma.rb
│ │ │ │ │ └── routes.rb
│ │ │ │ └── config.ru
│ │ │ └── simple-use/
│ │ │ ├── Gemfile
│ │ │ ├── README.md
│ │ │ └── main.rb
│ │ ├── lib/
│ │ │ ├── ag-ui-protocol.rb
│ │ │ ├── ag_ui_protocol/
│ │ │ │ ├── core/
│ │ │ │ │ ├── events.rb
│ │ │ │ │ └── types.rb
│ │ │ │ ├── encoder/
│ │ │ │ │ └── event_encoder.rb
│ │ │ │ ├── util.rb
│ │ │ │ └── version.rb
│ │ │ └── ag_ui_protocol.rb
│ │ ├── sorbet/
│ │ │ └── config
│ │ ├── templates/
│ │ │ └── default/
│ │ │ └── fulldoc/
│ │ │ └── markdown/
│ │ │ └── setup.rb
│ │ ├── test/
│ │ │ ├── ag_ui_protocol/
│ │ │ │ ├── core/
│ │ │ │ │ ├── events_test.rb
│ │ │ │ │ └── types_test.rb
│ │ │ │ └── encoder/
│ │ │ │ └── event_encoder_test.rb
│ │ │ └── test_helper.rb
│ │ └── yard_extensions.rb
│ └── rust/
│ ├── Cargo.toml
│ ├── TODO
│ └── crates/
│ ├── ag-ui-client/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── examples/
│ │ │ ├── basic_agent.rs
│ │ │ ├── generative_ui.rs
│ │ │ ├── logging_subscriber.rs
│ │ │ ├── shared_state.rs
│ │ │ └── sse_example.rs
│ │ ├── scripts/
│ │ │ ├── basic_agent.py
│ │ │ ├── generative_ui.py
│ │ │ └── shared_state.py
│ │ ├── src/
│ │ │ ├── agent.rs
│ │ │ ├── error.rs
│ │ │ ├── event_handler.rs
│ │ │ ├── http.rs
│ │ │ ├── lib.rs
│ │ │ ├── sse.rs
│ │ │ ├── stream.rs
│ │ │ └── subscriber.rs
│ │ └── tests/
│ │ ├── http_agent_test.rs
│ │ └── sse_test.rs
│ └── ag-ui-core/
│ ├── Cargo.toml
│ ├── README.md
│ ├── src/
│ │ ├── error.rs
│ │ ├── event.rs
│ │ ├── lib.rs
│ │ ├── state.rs
│ │ └── types/
│ │ ├── context.rs
│ │ ├── ids.rs
│ │ ├── input.rs
│ │ ├── message.rs
│ │ ├── mod.rs
│ │ └── tool.rs
│ └── tests/
│ └── unit.rs
├── python/
│ ├── .gitignore
│ ├── LICENSE
│ ├── README.md
│ ├── ag_ui/
│ │ ├── __init__.py
│ │ ├── core/
│ │ │ ├── __init__.py
│ │ │ ├── events.py
│ │ │ └── types.py
│ │ ├── encoder/
│ │ │ ├── __init__.py
│ │ │ └── encoder.py
│ │ └── py.typed
│ ├── pyproject.toml
│ └── tests/
│ ├── __init__.py
│ ├── test_encoder.py
│ ├── test_events.py
│ ├── test_text_roles.py
│ └── test_types.py
└── typescript/
├── .cursor/
│ └── rules/
│ └── project-rules.mdc
├── .gitignore
├── .npmrc
├── .prettierrc
├── LICENSE
├── README.md
├── packages/
│ ├── cli/
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── client/
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── agent/
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── agent-clone.test.ts
│ │ │ │ │ ├── agent-concurrent.test.ts
│ │ │ │ │ ├── agent-multiple-runs.test.ts
│ │ │ │ │ ├── agent-mutations.test.ts
│ │ │ │ │ ├── agent-result.test.ts
│ │ │ │ │ ├── agent-text-roles.test.ts
│ │ │ │ │ ├── agent-version.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.activity.test.ts
│ │ │ │ │ ├── default.concurrent.test.ts
│ │ │ │ │ ├── default.reasoning.test.ts
│ │ │ │ │ ├── default.state.test.ts
│ │ │ │ │ ├── default.text-message.test.ts
│ │ │ │ │ ├── default.tool-calls.test.ts
│ │ │ │ │ └── run-started-input.test.ts
│ │ │ │ ├── default.ts
│ │ │ │ └── index.ts
│ │ │ ├── chunks/
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── transform-roles.test.ts
│ │ │ │ │ └── transform.test.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── transform.ts
│ │ │ ├── compact/
│ │ │ │ ├── __tests__/
│ │ │ │ │ └── compact.test.ts
│ │ │ │ ├── compact.ts
│ │ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ ├── legacy/
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── convert.concurrent.test.ts
│ │ │ │ │ ├── convert.predictive.test.ts
│ │ │ │ │ ├── convert.state.test.ts
│ │ │ │ │ └── convert.tool-calls.test.ts
│ │ │ │ ├── convert.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── types.ts
│ │ │ ├── middleware/
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── backward-compatibility-0-0-39.test.ts
│ │ │ │ │ ├── backward-compatibility-0-0-45.test.ts
│ │ │ │ │ ├── filter-tool-calls.test.ts
│ │ │ │ │ ├── function-middleware.test.ts
│ │ │ │ │ ├── middleware-chained-integration.test.ts
│ │ │ │ │ ├── middleware-chained-run-next-with-state.test.ts
│ │ │ │ │ ├── middleware-live-events.test.ts
│ │ │ │ │ ├── middleware-usage-example.ts
│ │ │ │ │ ├── middleware-with-state.test.ts
│ │ │ │ │ └── middleware.test.ts
│ │ │ │ ├── backward-compatibility-0-0-39.ts
│ │ │ │ ├── backward-compatibility-0-0-45.ts
│ │ │ │ ├── filter-tool-calls.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── middleware.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.concurrent.test.ts
│ │ │ │ ├── verify.events.test.ts
│ │ │ │ ├── verify.lifecycle.test.ts
│ │ │ │ ├── verify.multiple-runs.test.ts
│ │ │ │ ├── verify.steps.test.ts
│ │ │ │ ├── verify.text-messages.test.ts
│ │ │ │ └── verify.tool-calls.test.ts
│ │ │ ├── index.ts
│ │ │ └── verify.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── core/
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── __tests__/
│ │ │ │ ├── activity-events.test.ts
│ │ │ │ ├── backwards-compatibility.test.ts
│ │ │ │ ├── event-factories.test.ts
│ │ │ │ ├── events-role-defaults.test.ts
│ │ │ │ ├── index.test.ts
│ │ │ │ └── multimodal-messages.test.ts
│ │ │ ├── capabilities.ts
│ │ │ ├── event-factories.ts
│ │ │ ├── events.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── encoder/
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── __tests__/
│ │ │ │ └── encoder.test.ts
│ │ │ ├── encoder.ts
│ │ │ ├── index.ts
│ │ │ └── media-type.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.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
│ ├── package.json
│ ├── src/
│ │ ├── index.ts
│ │ ├── proto/
│ │ │ ├── events.proto
│ │ │ ├── patch.proto
│ │ │ └── types.proto
│ │ └── proto.ts
│ ├── tsconfig.json
│ ├── tsdown.config.ts
│ └── vitest.config.ts
├── scripts/
│ └── create-integration.ts
├── tsconfig.json
└── vitest.base.ts
================================================
FILE CONTENTS
================================================
================================================
FILE: .claude/settings.json
================================================
{
"permissions": {
"allow": [
"Bash(npx nx show projects)",
"Bash(pnpm nx run dojo:check-types)",
"Bash(pnpm nx show projects)",
"Bash(pnpm nx run demo-viewer:check-types)",
"Bash(pnpm nx show project demo-viewer)",
"Bash(pnpm nx run demo-viewer:lint)"
]
}
}
================================================
FILE: .gitattributes
================================================
* text=auto eol=lf
*.mdx text eol=lf
*.js text eol=lf
*.ts text eol=lf
*.jsx text eol=lf
*.tsx text eol=lf
*.py text eol=lf
================================================
FILE: .github/CODEOWNERS
================================================
* @ag-ui-protocol/copilotkit
sdks/community/java @pascalwilbrink
docs/sdk/java @pascalwilbrink
sdks/community/kotlin @contextablemark
docs/sdk/kotlin @contextablemark
sdks/community/go @mattsp1290
docs/sdk/go @mattsp1290
sdks/community/dart @mattsp1290
docs/sdk/dart @mattsp1290
integrations/adk-middleware @contextablemark
integrations/agent-spec @sonleoracle
================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: "🐛 Bug Report"
description: "Something isn't working as expected? Let us know so we can fix it."
title: "[Bug]: "
labels: ["bug", "triage"]
body:
- type: markdown
attributes:
value: |
Thanks for helping improve AG-UI! Please fill this out so we can reproduce and fix the issue quickly.
> **Before you file:** Search [existing issues](https://github.com/ag-ui-protocol/ag-ui/issues) to avoid duplicates.
- type: checkboxes
id: preflight
attributes:
label: Pre-flight Checklist
options:
- label: I have searched [existing issues](https://github.com/ag-ui-protocol/ag-ui/issues) and this hasn't been reported yet.
required: true
- label: I am using the **latest** version AG-UI.
required: true
- type: textarea
id: description
attributes:
label: Describe the Bug
description: A clear description of what went wrong.
placeholder: "When I do X, Y happens instead of Z."
validations:
required: true
- type: textarea
id: steps
attributes:
label: Steps to Reproduce
description: Walk us through exactly how to trigger this bug.
placeholder: |
1. Install `@ag-ui/client`
2. Create an HttpAgent pointing at `http://localhost:8000/agent`
3. Call `agent.run(...)` with ...
4. Observe the error
validations:
required: true
- type: textarea
id: expected
attributes:
label: Expected Behavior
description: What did you expect to happen instead?
placeholder: "I expected X to happen when..."
validations:
required: true
- type: textarea
id: environment
attributes:
label: Environment
description: Tell us what you're working with so we can reproduce your setup.
placeholder: |
AG-UI package(s) & version(s): e.g. @ag-ui/core@0.0.44
Runtime: e.g. Node 22 / Python 3.12
render: text
validations:
required: true
- type: textarea
attributes:
label: Screenshots
description: If applicable, add screenshots to help explain your problem.
- type: textarea
id: logs
attributes:
label: Logs & Errors
description: Paste any relevant stack traces or error output. Auto-formatted as code.
render: shell
validations:
required: false
- type: textarea
id: additional
attributes:
label: Additional Context
description: Anything else — workarounds, screenshots, related issues, etc.
validations:
required: false
================================================
FILE: .github/ISSUE_TEMPLATE/documentation.yml
================================================
name: 📚 Documentation Issue
description: Let us know how we can improve the AG-UI documentation.
title: "📚 Documentation: "
labels: ["documentation"]
assignees: []
body:
- type: markdown
attributes:
value: |
We appreciate you taking the time to help us make our documentation better!
- type: textarea
id: description
attributes:
label: 💬 Let us know how we can improve our documentation.
description: |
If you are referring to an existing page in the documentation, please provide a link.
placeholder: |
Type your idea here...
validations:
required: true
================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.yml
================================================
name: "✨ Feature Request"
description: "Suggest a new feature or improvement."
title: "[Feature]: "
labels: ["enhancement"]
body:
- type: markdown
attributes:
value: |
Thanks for taking the time to suggest a feature!
> **Before you file:** Search existing issues to avoid duplicates.
- type: checkboxes
id: preflight
attributes:
label: Pre-flight Checklist
options:
- label: I have searched existing issues and this hasn't been requested yet.
required: true
- type: textarea
id: problem
attributes:
label: Problem or Motivation
description: What problem does this feature solve? Why is it needed?
placeholder: "I'm always frustrated when..."
validations:
required: true
- type: textarea
id: solution
attributes:
label: Proposed Solution
description: Describe the solution you'd like. Be as specific as possible.
placeholder: "It would be great if..."
validations:
required: true
- type: textarea
id: alternatives
attributes:
label: Alternatives Considered
description: Have you considered any alternative solutions or workarounds?
validations:
required: false
- type: textarea
id: additional
attributes:
label: Additional Context
description: Anything else — mockups, code snippets, related issues, links, etc.
validations:
required: false
================================================
FILE: .github/pull_request_template.md
================================================
<!--
**Please PLEASE reach out to us first before starting any significant work on new or existing features.**
By the time you've gotten here, you're looking at creating a pull request so hopefully we're not too late.
We love community contributions! That said, we want to make sure we're all on the same page before you start.
Investing a lot of time and effort just to find out it doesn't align with the upstream project feels awful, and we don't want that to happen.
It also helps to make sure the work you're planning isn't already in progress.
As described in our contributing guide, please file an issue first: https://github.com/ag-ui-protocol/ag-ui/issues
Or, reach out to us on Discord: https://discord.gg/Jd3FzfdJa8
Take a look at the contributing guide:
https://github.com/ag-ui-protocol/ag-ui/blob/main/CONTRIBUTING.md
-->
================================================
FILE: .github/workflows/auto-approve-community.yml
================================================
name: Auto-approve community PRs
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
pull-requests: write
contents: read
jobs:
auto-approve:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Fetch PR head
run: |
git fetch origin pull/${{ github.event.pull_request.number }}/head:pr-head
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Auto-approve based on CODEOWNERS
env:
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
PR_NUMBER: ${{ github.event.pull_request.number }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
node << 'EOF'
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const prAuthor = process.env.PR_AUTHOR;
const prNumber = process.env.PR_NUMBER;
// Get changed files (use pr-head ref which works for both forks and same-repo PRs)
const changedFiles = execSync(
`git diff --name-only origin/${process.env.BASE_REF}...pr-head`,
{ encoding: 'utf-8' }
)
.trim()
.split('\n')
.filter(f => f.trim());
console.log(`Changed files (${changedFiles.length}):`);
changedFiles.forEach(f => console.log(` - ${f}`));
// Parse CODEOWNERS file
const codeownersPath = '.github/CODEOWNERS';
const codeownersContent = fs.readFileSync(codeownersPath, 'utf-8');
const lines = codeownersContent.split('\n');
// Map of path patterns to owners (excluding root * rule)
const codeownersRules = [];
for (const line of lines) {
const trimmed = line.trim();
// Skip empty lines and comments
if (!trimmed || trimmed.startsWith('#')) {
continue;
}
// Skip root * line
if (trimmed.startsWith('* ')) {
console.log('Skipping root * rule');
continue;
}
// Parse pattern and owners
const parts = trimmed.split(/\s+/);
if (parts.length < 2) {
continue;
}
const pattern = parts[0];
const owners = parts.slice(1).map(o => o.replace('@', ''));
codeownersRules.push({ pattern, owners });
}
console.log('\nCODEOWNERS rules (excluding root):');
codeownersRules.forEach(rule => {
console.log(` ${rule.pattern} -> ${rule.owners.join(', ')}`);
});
// Function to check if a file matches a CODEOWNERS pattern
// CODEOWNERS patterns match:
// - Exact file/directory path
// - pattern/ matches everything in that directory
// - pattern/** matches everything recursively in that directory
function matchesPattern(file, pattern) {
// Normalize paths (handle both / and \ separators)
const normalizePath = (p) => p.replace(/\\/g, '/');
const normalizedFile = normalizePath(file);
const normalizedPattern = normalizePath(pattern);
// Exact match
if (normalizedFile === normalizedPattern) {
return true;
}
// Pattern ends with /**: matches recursively in directory
if (normalizedPattern.endsWith('/**')) {
const dirPrefix = normalizedPattern.slice(0, -3);
return normalizedFile.startsWith(dirPrefix + '/');
}
// Pattern ends with /: matches everything in directory
if (normalizedPattern.endsWith('/')) {
const dirPrefix = normalizedPattern.slice(0, -1);
return normalizedFile.startsWith(dirPrefix + '/');
}
// Pattern is a directory prefix (matches subdirectories)
if (normalizedFile.startsWith(normalizedPattern + '/')) {
return true;
}
return false;
}
// Check each changed file
// CODEOWNERS rules are evaluated top-to-bottom, first match wins
const unapprovedFiles = [];
for (const file of changedFiles) {
let matched = false;
let owned = false;
// Find the first matching rule (CODEOWNERS uses first match semantics)
for (const rule of codeownersRules) {
if (matchesPattern(file, rule.pattern)) {
matched = true;
// First match wins in CODEOWNERS, so check ownership here
owned = rule.owners.includes(prAuthor);
break; // Stop at first match
}
}
// File must be matched by a non-root CODEOWNERS rule AND author must own it
if (!matched || !owned) {
unapprovedFiles.push(file);
}
}
// Decision
if (unapprovedFiles.length === 0) {
console.log(`\n✅ All changed files are owned by ${prAuthor} according to CODEOWNERS`);
// Check if already approved by this workflow
try {
const reviews = JSON.parse(
execSync(`gh pr view ${prNumber} --json reviews`, { encoding: 'utf-8' })
);
// Check if there's already an approval from GitHub Actions bot
// (look for approval with the auto-approve message)
const hasAutoApproval = reviews.reviews.some(
review => review.state === 'APPROVED' &&
review.body &&
review.body.includes('Auto-approved: PR author has CODEOWNERS access')
);
if (hasAutoApproval) {
console.log('PR already auto-approved by this workflow');
} else {
// Approve the PR using GitHub Actions bot account
execSync(
`gh pr review ${prNumber} --approve --body "Auto-approved: PR author ${prAuthor} has CODEOWNERS access to all changed files (excluding root rule)"`,
{ stdio: 'inherit' }
);
console.log(`PR approved automatically for ${prAuthor}`);
}
} catch (error) {
console.error('Error checking/approving PR:', error.message);
// Don't fail the workflow if approval fails (might already be approved, etc.)
console.log('Continuing despite approval error...');
}
} else {
console.log(`\n❌ Not auto-approved: Some files are not owned by ${prAuthor}`);
console.log('Unauthorized files:');
unapprovedFiles.forEach(f => console.log(` - ${f}`));
}
EOF
================================================
FILE: .github/workflows/build-python-preview.yml
================================================
name: Build Python Preview
on:
pull_request:
types: [opened, synchronize, reopened]
concurrency:
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: ">=0.8.0"
- name: Compute preview version
id: version
run: |
TIMESTAMP=$(git log -1 --format=%ct HEAD)
VERSION="0.0.0.dev${TIMESTAMP}"
echo "version=${VERSION}" >> "$GITHUB_OUTPUT"
echo "Preview version: ${VERSION}"
- name: Rewrite pyproject.toml versions
run: uv run python scripts/rewrite-python-preview-versions.py ${{ steps.version.outputs.version }}
- name: Build ag-ui-protocol
working-directory: sdks/python
run: uv build
- name: Build ag-ui-langgraph
working-directory: integrations/langgraph/python
run: uv build
- name: Build ag-ui-crewai
working-directory: integrations/crew-ai/python
run: uv build
- name: Build ag-ui-agent-spec
working-directory: integrations/agent-spec/python
run: uv build
- name: Build ag_ui_adk
working-directory: integrations/adk-middleware/python
run: uv build
- name: Build ag_ui_strands
working-directory: integrations/aws-strands/python
run: uv build
- name: Collect dist artifacts
run: |
mkdir -p dist-preview
cp sdks/python/dist/* dist-preview/
cp integrations/langgraph/python/dist/* dist-preview/
cp integrations/crew-ai/python/dist/* dist-preview/
cp integrations/agent-spec/python/dist/* dist-preview/
cp integrations/adk-middleware/python/dist/* dist-preview/
cp integrations/aws-strands/python/dist/* dist-preview/
echo "Artifacts to publish:"
ls -1 dist-preview/
# Save metadata so the publish workflow can find the PR and version.
- name: Save PR metadata
run: |
mkdir -p pr-metadata
echo "${{ github.event.pull_request.number }}" > pr-metadata/pr-number
echo "${{ steps.version.outputs.version }}" > pr-metadata/version
echo "${{ github.sha }}" > pr-metadata/sha
- name: Upload dist artifacts
uses: actions/upload-artifact@v4
with:
name: python-preview-dist
path: dist-preview/
- name: Upload PR metadata
uses: actions/upload-artifact@v4
with:
name: python-preview-metadata
path: pr-metadata/
================================================
FILE: .github/workflows/dojo-e2e.yml
================================================
name: e2e
on:
workflow_dispatch:
push:
branches: [main]
paths:
- "integrations/**"
- "apps/dojo/**"
- "middlewares/**"
- "pnpm-lock.yaml"
- "pnpm-workspace.yaml"
- ".github/workflows/dojo-e2e.yml"
- "sdks/python/**"
- "sdks/typescript/**"
pull_request:
branches: [main]
paths:
- "apps/dojo/**"
- "integrations/**"
- "middlewares/**"
- "pnpm-lock.yaml"
- "pnpm-workspace.yaml"
- ".github/workflows/dojo-e2e.yml"
- "sdks/python/**"
- "sdks/typescript/**"
jobs:
check-generated-files:
name: dojo / check-generated-files
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10.13.1
- name: Validate agentFilesMapper and regenerate files.json
working-directory: apps/dojo
run: pnpm generate-content-json
- name: Check files.json is up to date
working-directory: apps/dojo
run: |
if git diff --exit-code src/files.json > /dev/null; then
echo "✅ No changes detected in dojo/src/files.json. Everything is up to date."
else
echo "❌ Detected changes in dojo/src/files.json."
echo ""
echo "The committed files.json doesn't match what would be generated."
echo "Please run \`(p)npm run generate-content-json\` in the apps/dojo folder and commit the updated file."
echo ""
echo "The detected diff was as follows:"
echo "::group::Diff for dojo/src/files.json"
git diff src/files.json
echo "::endgroup::"
exit 1
fi
dojo:
name: dojo / ${{ matrix.suite }}
needs: check-generated-files
runs-on: depot-ubuntu-24.04
timeout-minutes: 20
strategy:
fail-fast: false
matrix:
include:
- suite: a2a-middleware
test_path: tests/a2aMiddlewareTests
services: ["dojo", "a2a-middleware"]
wait_on: http://localhost:9999,http-get://localhost:8011/.well-known/agent.json,http-get://localhost:8012/.well-known/agent.json,http-get://localhost:8013/.well-known/agent.json,http-get://localhost:8014/openapi.json
- suite: adk-middleware
test_path: tests/adkMiddlewareTests
services: ["dojo", "adk-middleware"]
wait_on: http://localhost:9999,tcp:localhost:8010
- suite: agno
test_path: tests/agnoTests
services: ["dojo", "agno"]
wait_on: http://localhost:9999,tcp:localhost:8002
- suite: crew-ai
test_path: tests/crewAITests
services: ["dojo", "crew-ai"]
wait_on: http://localhost:9999,tcp:localhost:8003
- suite: langroid
test_path: tests/langroidTests
services: ["dojo", "langroid"]
wait_on: http://localhost:9999,tcp:localhost:8021
- suite: langgraph-python
test_path: tests/langgraphPythonTests
services: ["dojo", "langgraph-platform-python"]
wait_on: http://localhost:9999,tcp:localhost:8005
- suite: langgraph-typescript
test_path: tests/langgraphTypescriptTests
services: ["dojo", "langgraph-platform-typescript"]
wait_on: http://localhost:9999,tcp:localhost:8006
- suite: langgraph-fastapi
test_path: tests/langgraphFastAPITests
services: ["dojo", "langgraph-fastapi"]
wait_on: http://localhost:9999,tcp:localhost:8004
- suite: llama-index
test_path: tests/llamaIndexTests
services: ["dojo", "llama-index"]
wait_on: http://localhost:9999,tcp:localhost:8007
- suite: mastra
test_path: tests/mastraTests
services: ["dojo", "mastra"]
wait_on: http://localhost:9999,tcp:localhost:8008
- suite: mastra-agent-local
test_path: tests/mastraAgentLocalTests
services: ["dojo"]
wait_on: http://localhost:9999
- suite: middleware-starter
test_path: tests/middlewareStarterTests
services: ["dojo"]
wait_on: http://localhost:9999
- suite: pydantic-ai
test_path: tests/pydanticAITests
services: ["dojo", "pydantic-ai"]
wait_on: http://localhost:9999,tcp:localhost:8009
- suite: server-starter
test_path: tests/serverStarterTests
services: ["dojo", "server-starter"]
wait_on: http://localhost:9999,tcp:localhost:8000
- suite: server-starter-all
test_path: tests/serverStarterAllFeaturesTests
services: ["dojo", "server-starter-all"]
wait_on: http://localhost:9999,tcp:localhost:8001
- suite: aws-strands
test_path: tests/awsStrandsTests
services: ["dojo", "aws-strands"]
wait_on: http://localhost:9999,tcp:localhost:8017
- suite: claude-agent-sdk-python
test_path: tests/claudeAgentSdkPythonTests
services: ["dojo", "claude-agent-sdk-python"]
wait_on: http://localhost:9999,tcp:localhost:8019
- suite: claude-agent-sdk-typescript
test_path: tests/claudeAgentSdkTypescriptTests
services: ["dojo", "claude-agent-sdk-typescript"]
wait_on: http://localhost:9999,tcp:localhost:8020
# - suite: vercel-ai-sdk
# test_path: tests/vercelAISdkTests
# services: ["dojo"]
# wait_on: http://localhost:9999
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10.13.1
# Now that pnpm is available, cache its store to speed installs
- name: Resolve pnpm store path
id: pnpm-store
run: echo "STORE_PATH=$(pnpm store path --silent)" >> $GITHUB_ENV
- name: Cache pnpm store
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Cache Python dependencies
uses: actions/cache@v4
with:
path: |
~/.cache/pip
~/.cache/pypoetry
~/.cache/uv
**/.venv
key: ${{ runner.os }}-pydeps-${{ matrix.suite }}-${{ hashFiles('**/poetry.lock', '**/pyproject.toml') }}
restore-keys: |
${{ runner.os }}-pydeps-${{ matrix.suite }}-
${{ runner.os }}-pydeps-
- name: Cache Next.js build
uses: actions/cache@v4
with:
path: ${{ github.workspace }}/apps/dojo/.next/cache
key: ${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-${{ hashFiles('apps/dojo/src/**/*.ts', 'apps/dojo/src/**/*.tsx', 'apps/dojo/src/**/*.js', 'apps/dojo/src/**/*.jsx') }}
restore-keys: |
${{ runner.os }}-nextjs-${{ hashFiles('**/pnpm-lock.yaml') }}-
- name: Install Poetry
uses: snok/install-poetry@v1
with:
version: latest
virtualenvs-create: true
virtualenvs-in-project: true
- name: Install uv
uses: astral-sh/setup-uv@v6
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Prepare dojo for e2e
working-directory: apps/dojo
if: ${{ join(matrix.services, ',') != '' }}
run: node ./scripts/prep-dojo-everything.js --only ${{ join(matrix.services, ',') }}
- name: Cache Playwright browsers
id: cache-playwright
uses: actions/cache@v4
with:
path: ~/.cache/ms-playwright
key: ${{ runner.os }}-playwright-${{ hashFiles('apps/dojo/e2e/package.json') }}
restore-keys: |
${{ runner.os }}-playwright-
- name: Install e2e dependencies
working-directory: apps/dojo/e2e
run: pnpm install --ignore-scripts
- name: Install Playwright browsers
working-directory: apps/dojo/e2e
if: steps.cache-playwright.outputs.cache-hit != 'true'
run: pnpm exec playwright install --with-deps chromium
- name: Install Playwright system dependencies
working-directory: apps/dojo/e2e
if: steps.cache-playwright.outputs.cache-hit == 'true'
run: pnpm exec playwright install-deps chromium
- name: Create langgraph stub .env files
if: ${{ contains(join(matrix.services, ','), 'langgraph-platform-python') || contains(join(matrix.services, ','), 'langgraph-platform-typescript') }}
run: |
# langgraph.json declares "env": ".env" — the CLI requires this file
# to exist on disk. Values don't matter since run-dojo-everything.js
# injects LLMock env vars into the process environment.
touch integrations/langgraph/python/examples/.env
touch integrations/langgraph/typescript/examples/.env
- name: write langroid env files
working-directory: integrations/langroid/python/examples
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
if: ${{ contains(join(matrix.services, ','), 'langroid') }}
run: |
echo "OPENAI_API_KEY=${OPENAI_API_KEY}" > .env
- name: Run dojo+agents
uses: JarvusInnovations/background-action@v1
if: ${{ join(matrix.services, ',') != '' && contains(join(matrix.services, ','), 'dojo') }}
with:
run: |
node ../scripts/run-dojo-everything.js --only ${{ join(matrix.services, ',') }}
working-directory: apps/dojo/e2e
wait-on: ${{ matrix.wait_on }}
wait-for: 300000
- name: Run tests – ${{ matrix.suite }}
working-directory: apps/dojo/e2e
env:
BASE_URL: http://localhost:9999
PLAYWRIGHT_SUITE: ${{ matrix.suite }}
run: |
pnpm test -- ${{ matrix.test_path }}
- name: Upload traces – ${{ matrix.suite }}
if: always() # Uploads artifacts even if tests fail
uses: actions/upload-artifact@v4
with:
name: ${{ matrix.suite }}-playwright-traces
path: |
apps/dojo/e2e/test-results/${{ matrix.suite }}/**/*
apps/dojo/e2e/playwright-report/**/*
retention-days: 7
================================================
FILE: .github/workflows/pr-check-binaries.yml
================================================
name: Check for binary artifacts
on:
pull_request:
types: [opened, synchronize, reopened]
permissions:
contents: read
jobs:
check-binaries:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Check for binary and build artifacts
env:
BASE_REF: ${{ github.event.pull_request.base.ref }}
run: |
VIOLATIONS=0
# Get list of added/modified files in the PR
CHANGED_FILES=$(git diff --name-only "origin/${BASE_REF}...HEAD")
if [ -z "$CHANGED_FILES" ]; then
echo "No changed files detected."
exit 0
fi
# Check for binary file extensions
BINARY_FILES=$(echo "$CHANGED_FILES" | grep -iE '\.(exe|dll|so|dylib|o|obj|a|lib|wasm)$' || true)
if [ -n "$BINARY_FILES" ]; then
echo "::error::Binary files detected in PR:"
echo "$BINARY_FILES"
VIOLATIONS=1
fi
# Check for build directories
BUILD_FILES=$(echo "$CHANGED_FILES" | grep -E '/build/' || true)
if [ -n "$BUILD_FILES" ]; then
echo "::error::Files in build directories detected in PR:"
echo "$BUILD_FILES"
VIOLATIONS=1
fi
# Check for dSYM directories
DSYM_FILES=$(echo "$CHANGED_FILES" | grep -E '\.dSYM/' || true)
if [ -n "$DSYM_FILES" ]; then
echo "::error::dSYM debug symbol directories detected in PR:"
echo "$DSYM_FILES"
VIOLATIONS=1
fi
# Check for large files (>1MB) among changed files
# Exclude known generated files that are committed intentionally
LARGE_FILE_EXCLUDES="apps/dojo/src/files.json"
LARGE_FILES=""
while IFS= read -r file; do
if [ -f "$file" ] && ! echo "$LARGE_FILE_EXCLUDES" | grep -qF "$file"; then
SIZE=$(wc -c < "$file" | tr -d ' ')
if [ "$SIZE" -gt 1048576 ]; then
LARGE_FILES="${LARGE_FILES}${file} ($(( SIZE / 1024 )) KB)\n"
fi
fi
done <<< "$CHANGED_FILES"
if [ -n "$LARGE_FILES" ]; then
echo "::error::Files over 1 MB detected in PR:"
echo -e "$LARGE_FILES"
VIOLATIONS=1
fi
if [ "$VIOLATIONS" -eq 1 ]; then
echo ""
echo "This PR contains binary artifacts, build outputs, or oversized files."
echo "Please remove them and update your .gitignore if needed."
exit 1
fi
echo "No binary artifacts or oversized files detected."
================================================
FILE: .github/workflows/publish-commit.yml
================================================
name: 🚀 pkg-pr-new
on: [push, pull_request]
concurrency:
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v2
- name: Install pnpm
uses: pnpm/action-setup@v4
- run: corepack enable
- uses: actions/setup-node@v4
with:
node-version-file: "package.json"
- name: Install dependencies
run: pnpm install
- name: Build
run: pnpm run build
- name: Publish via pkg-pr-new
run: |
npx pkg-pr-new publish --pnpm --packageManager pnpm ./sdks/typescript/packages/* ./middlewares/* ./integrations/*/typescript || \
(sleep 10 && npx pkg-pr-new publish --pnpm --packageManager pnpm ./sdks/typescript/packages/* ./middlewares/* ./integrations/*/typescript)
================================================
FILE: .github/workflows/publish-java-sdk.yml
================================================
name: Publish Java SDK to Maven Central
on:
# Manual trigger only - no automatic publishing
workflow_dispatch:
jobs:
publish:
runs-on: ubuntu-latest
defaults:
run:
working-directory: sdks/community/java
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: "21"
distribution: "temurin"
cache: 'maven'
server-id: ossrh
server-username: MAVEN_USERNAME
server-password: MAVEN_PASSWORD
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
gpg-passphrase: MAVEN_GPG_PASSPHRASE
- name: Publish to Maven Central
run: mvn --batch-mode deploy -P release
env:
MAVEN_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
MAVEN_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
================================================
FILE: .github/workflows/publish-kotlin-sdk.yml
================================================
name: Publish Kotlin SDK to Maven Central
on:
# Manual trigger only - no automatic publishing
workflow_dispatch:
inputs:
dry_run:
description: 'Run in dry-run mode (test without uploading)'
required: false
type: boolean
default: false
jobs:
publish:
runs-on: macos-latest
permissions:
contents: read
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: "21"
distribution: "temurin"
- name: Setup Gradle
uses: gradle/gradle-build-action@v3
- name: Install Android SDK
uses: android-actions/setup-android@v3
- name: Install Android SDK 36 components
run: |
echo "Installing Android SDK 36 components..."
sdkmanager --install "platforms;android-36"
sdkmanager --install "build-tools;36.0.0"
- name: Accept Android licenses
run: yes | sdkmanager --licenses || true
- name: Verify Android SDK installation
run: |
echo "Checking Android SDK installation..."
sdkmanager --list_installed | grep -E "(platforms;android-36|build-tools;36)"
- name: Run tests
working-directory: sdks/community/kotlin/library
run: ./gradlew allTests --no-daemon --stacktrace
- name: Parse test results
if: always()
working-directory: sdks/community/kotlin/library
run: |
echo "## Kotlin SDK Test Results Summary"
echo ""
total_tests=0
total_failures=0
total_errors=0
for module in core client tools; do
xml_dir="$module/build/test-results/jvmTest"
if [ -d "$xml_dir" ]; then
# Sum up test counts from all XML files in the directory
module_tests=$(find "$xml_dir" -name "*.xml" -exec grep -h '<testsuite' {} \; | grep -o 'tests="[0-9]*"' | sed 's/tests="\([0-9]*\)"/\1/' | awk '{sum += $1} END {print sum}')
module_failures=$(find "$xml_dir" -name "*.xml" -exec grep -h '<testsuite' {} \; | grep -o 'failures="[0-9]*"' | sed 's/failures="\([0-9]*\)"/\1/' | awk '{sum += $1} END {print sum}')
module_errors=$(find "$xml_dir" -name "*.xml" -exec grep -h '<testsuite' {} \; | grep -o 'errors="[0-9]*"' | sed 's/errors="\([0-9]*\)"/\1/' | awk '{sum += $1} END {print sum}')
# Default to 0 if empty
module_tests=${module_tests:-0}
module_failures=${module_failures:-0}
module_errors=${module_errors:-0}
if [ "$module_tests" -gt 0 ]; then
echo "✅ kotlin-$module: $module_tests tests, $module_failures failures, $module_errors errors"
total_tests=$((total_tests + module_tests))
total_failures=$((total_failures + module_failures))
total_errors=$((total_errors + module_errors))
fi
fi
done
echo ""
echo "---"
echo "### Overall Results: $total_tests tests, $total_failures failures, $total_errors errors"
if [ $total_failures -gt 0 ] || [ $total_errors -gt 0 ]; then
echo "❌ Some tests failed - aborting publish"
exit 1
elif [ $total_tests -eq 0 ]; then
echo "⚠️ No tests were found or executed - aborting publish"
exit 1
else
echo "✅ All $total_tests tests passed!"
fi
- name: Publish to Maven Central (dry-run)
if: inputs.dry_run == true
working-directory: sdks/community/kotlin
env:
JRELEASER_MAVENCENTRAL_SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
JRELEASER_MAVENCENTRAL_SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
JRELEASER_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
JRELEASER_GPG_PUBLIC_KEY: ${{ secrets.GPG_PUBLIC_KEY }}
JRELEASER_GPG_SECRET_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
run: |
echo "🔍 Running publish script in dry-run mode..."
./publish.sh --dry-run
- name: Publish to Maven Central
if: inputs.dry_run == false
working-directory: sdks/community/kotlin
env:
JRELEASER_MAVENCENTRAL_SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
JRELEASER_MAVENCENTRAL_SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
JRELEASER_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
JRELEASER_GPG_PUBLIC_KEY: ${{ secrets.GPG_PUBLIC_KEY }}
JRELEASER_GPG_SECRET_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
run: |
echo "🚀 Publishing to Maven Central..."
./publish.sh
- name: Upload JReleaser logs
if: always()
uses: actions/upload-artifact@v4
with:
name: jreleaser-logs
path: sdks/community/kotlin/library/build/jreleaser/
retention-days: 7
- name: Summary
if: success() && inputs.dry_run == false
working-directory: sdks/community/kotlin/library
run: |
# Extract version from build.gradle.kts
VERSION=$(grep "^version = " build.gradle.kts | sed 's/version = "\(.*\)"/\1/')
echo "## ✅ Publishing Complete!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "The Kotlin SDK has been published to Maven Central." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Published Artifacts" >> $GITHUB_STEP_SUMMARY
echo "- \`com.ag-ui.community:kotlin-core:${VERSION}\` (JVM, Android, iOS)" >> $GITHUB_STEP_SUMMARY
echo "- \`com.ag-ui.community:kotlin-client:${VERSION}\` (JVM, Android, iOS)" >> $GITHUB_STEP_SUMMARY
echo "- \`com.ag-ui.community:kotlin-tools:${VERSION}\` (JVM, Android, iOS)" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "**Note:** All platforms published including iOS artifacts in .klib format." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Next Steps" >> $GITHUB_STEP_SUMMARY
echo "1. Check deployment status: https://central.sonatype.com/publishing" >> $GITHUB_STEP_SUMMARY
echo "2. Artifacts will be validated automatically" >> $GITHUB_STEP_SUMMARY
echo "3. Publishing completes in ~10-30 minutes" >> $GITHUB_STEP_SUMMARY
- name: Dry-run Summary
if: success() && inputs.dry_run == true
run: |
echo "## ✅ Dry-run Complete!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "The dry-run completed successfully. No artifacts were uploaded." >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Run without the dry-run flag to publish to Maven Central." >> $GITHUB_STEP_SUMMARY
================================================
FILE: .github/workflows/publish-python-package.yml
================================================
name: Publish Python Package to PyPI
on:
# Manual trigger only - no automatic publishing
workflow_dispatch:
inputs:
package:
description: 'Package to publish'
required: true
type: choice
options:
- sdks/python
- integrations/adk-middleware/python
- integrations/agent-spec/python
- integrations/aws-strands/python
- integrations/crew-ai/python
- integrations/langgraph/python
dry_run:
description: 'Run in dry-run mode (build without uploading)'
required: false
type: boolean
default: false
jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write # Required for PyPI trusted publishing
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Authorize actor against CODEOWNERS
env:
ACTOR: ${{ github.actor }}
PACKAGE: ${{ inputs.package }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx tsx scripts/check-codeowners-auth.ts
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: ">=0.8.0"
- name: Install dependencies
working-directory: ${{ inputs.package }}
run: uv sync
- name: Run tests
working-directory: ${{ inputs.package }}
run: |
TEST_CMD=$(uv run python -c "
import tomllib, sys
cfg = tomllib.load(open('pyproject.toml', 'rb'))
try:
cmd = cfg['tool']['ag-ui']['scripts']['test']
except KeyError:
print('ERROR: No test script configured in [tool.ag-ui.scripts]', file=sys.stderr)
sys.exit(1)
print(cmd)
")
uv run $TEST_CMD
- name: Build package
working-directory: ${{ inputs.package }}
run: uv build
- name: Verify wheel permissions
working-directory: ${{ inputs.package }}
run: |
echo "## Wheel file permissions check"
uv run python -c "
import zipfile, glob, sys
whl = glob.glob('dist/*.whl')[0]
print(f'Checking {whl}')
bad = []
for info in zipfile.ZipFile(whl).infolist():
perms = (info.external_attr >> 16) & 0o777
readable = perms & 0o444
print(f' {oct(perms):>8s} {info.filename}')
if not readable:
bad.append(info.filename)
if bad:
print(f'ERROR: {len(bad)} file(s) missing read permissions:')
for f in bad:
print(f' - {f}')
sys.exit(1)
print('All files have correct permissions.')
"
- name: Publish to PyPI
if: inputs.dry_run == false
working-directory: ${{ inputs.package }}
run: uv publish
env:
UV_PUBLISH_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
- name: Summary
if: success()
working-directory: ${{ inputs.package }}
run: |
NAME=$(uv run python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['name'])")
VERSION=$(uv run python -c "import tomllib; print(tomllib.load(open('pyproject.toml','rb'))['project']['version'])")
if [ "${{ inputs.dry_run }}" = "true" ]; then
echo "## ✅ Dry-run Complete!" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Built **${NAME} ${VERSION}** successfully. No artifacts were uploaded." >> $GITHUB_STEP_SUMMARY
else
echo "## ✅ Published ${NAME} ${VERSION} to PyPI" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "Install with: \`pip install ${NAME}==${VERSION}\`" >> $GITHUB_STEP_SUMMARY
fi
================================================
FILE: .github/workflows/publish-python-preview.yml
================================================
name: Publish Python Preview to TestPyPI
# Triggered when the build workflow completes. Runs in the base repo context,
# so it has access to secrets even for fork PRs. The code executed here comes
# from the base branch, not the fork — only the built wheel artifacts come
# from the fork's workflow run.
on:
workflow_run:
workflows: ["Build Python Preview"]
types: [completed]
jobs:
publish:
runs-on: ubuntu-latest
if: github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event == 'pull_request'
permissions:
actions: read
pull-requests: write
steps:
- name: Download dist artifacts
uses: actions/download-artifact@v4
with:
name: python-preview-dist
path: dist-preview/
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Download PR metadata
uses: actions/download-artifact@v4
with:
name: python-preview-metadata
path: pr-metadata/
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ github.token }}
- name: Read PR metadata
id: meta
run: |
echo "pr-number=$(cat pr-metadata/pr-number)" >> "$GITHUB_OUTPUT"
echo "version=$(cat pr-metadata/version)" >> "$GITHUB_OUTPUT"
echo "sha=$(cat pr-metadata/sha)" >> "$GITHUB_OUTPUT"
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: ">=0.8.0"
- name: Publish all packages to TestPyPI
run: |
echo "Publishing artifacts:"
ls -1 dist-preview/
uv publish \
--publish-url https://test.pypi.org/legacy/ \
--check-url https://test.pypi.org/simple/ \
dist-preview/*
env:
UV_PUBLISH_TOKEN: ${{ secrets.TEST_PYPI_API_TOKEN }}
- name: Find existing preview comment
if: always()
id: find-comment
uses: peter-evans/find-comment@v4
with:
issue-number: ${{ steps.meta.outputs.pr-number }}
comment-author: 'github-actions[bot]'
body-includes: '<!-- ag-ui-python-preview -->'
- name: Post or update install instructions
if: success()
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.find-comment.outputs.comment-id }}
issue-number: ${{ steps.meta.outputs.pr-number }}
edit-mode: replace
body: |
<!-- ag-ui-python-preview -->
## Python Preview Packages
Version `${{ steps.meta.outputs.version }}` published to [TestPyPI](https://test.pypi.org).
> **Warning**: These packages are built from contributor code that may not yet have been vetted for correctness or security. Install at your own risk and do not use in production.
### Install with uv
Add the TestPyPI index to your `pyproject.toml`:
```toml
[[tool.uv.index]]
name = "testpypi"
url = "https://test.pypi.org/simple/"
explicit = true
```
Then install the packages you need:
```bash
# Core SDK
uv add 'ag-ui-protocol==${{ steps.meta.outputs.version }}' --index testpypi
# Integrations (each already depends on the matching ag-ui-protocol preview)
uv add 'ag-ui-langgraph==${{ steps.meta.outputs.version }}' --index testpypi
uv add 'ag-ui-crewai==${{ steps.meta.outputs.version }}' --index testpypi
# NOTE: ag-ui-agent-spec depends on pyagentspec (git-only, not on PyPI).
# You will need to install pyagentspec separately from its git repo.
uv add 'ag-ui-agent-spec==${{ steps.meta.outputs.version }}' --index testpypi
uv add 'ag_ui_adk==${{ steps.meta.outputs.version }}' --index testpypi
uv add 'ag_ui_strands==${{ steps.meta.outputs.version }}' --index testpypi
```
### Install with pip
```bash
pip install \
--index-url https://test.pypi.org/simple/ \
--extra-index-url https://pypi.org/simple/ \
ag-ui-protocol==${{ steps.meta.outputs.version }}
```
> Use `--extra-index-url https://pypi.org/simple/` so pip can resolve
> transitive dependencies (pydantic, fastapi, etc.) from real PyPI.
---
_Commit: ${{ steps.meta.outputs.sha }}_
- name: Post failure comment
if: failure()
uses: peter-evans/create-or-update-comment@v4
with:
comment-id: ${{ steps.find-comment.outputs.comment-id }}
issue-number: ${{ steps.meta.outputs.pr-number }}
edit-mode: replace
body: |
<!-- ag-ui-python-preview -->
## Python Preview Packages — Publish Failed
Preview publish failed for commit ${{ steps.meta.outputs.sha }}.
See the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.
================================================
FILE: .github/workflows/rust-lint-test.yml
================================================
name: test
on:
push:
branches: [ "main" ]
paths:
- "crates/**"
- ".github/workflows/rust.yml"
- "tests/**"
- "Cargo.toml"
- ".cargo/**"
pull_request:
branches: [ "main" ]
paths:
- "sdks/community/rust/crates/**"
- "sdks/community/rust/**/tests/**"
- "sdks/community/rust/Cargo.toml"
- "sdks/community/rust/.cargo/**"
- ".github/workflows/rust-lint-test.yml"
defaults:
run:
working-directory: ./rust
jobs:
rust:
strategy:
fail-fast: false
matrix:
os: [ ubuntu-latest, macos-latest, windows-latest ]
name: Rust SDK Tests [${{ matrix.os }}]
runs-on: ${{ matrix.os }}
env:
CARGO_TERM_COLOR: always
steps:
- uses: actions/checkout@v4
- uses: Swatinem/rust-cache@v2
- name: Build
run: cargo build --verbose
- name: Check formatting
run: cargo fmt -- --check
- name: Check clippy
run: cargo clippy -- -D warnings
- name: Publish ag-ui-core dry-run
run: cargo publish -p ag-ui-core --dry-run
- name: Publish ag-ui-client dry-run
run: cargo publish -p ag-ui-client --dry-run
- name: Run tests
run: cargo test --verbose
================================================
FILE: .github/workflows/unit-dart-sdk.yml
================================================
name: unit
on:
push:
branches: [main]
paths:
- "sdks/community/dart/**"
- ".github/workflows/unit-dart-sdk.yml"
pull_request:
branches: [main]
paths:
- "sdks/community/dart/**"
- ".github/workflows/unit-dart-sdk.yml"
jobs:
dart:
runs-on: ubuntu-latest
defaults:
run:
working-directory: sdks/community/dart
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Dart
uses: dart-lang/setup-dart@v1
with:
sdk: stable
- name: Install dependencies
run: dart pub get
- name: Run tests
run: dart test --exclude-tags requires-server
================================================
FILE: .github/workflows/unit-genkit-go.yml
================================================
name: unit
on:
push:
branches: [main]
paths:
- "integrations/community/genkit/go/**"
- ".github/workflows/unit-genkit-go.yml"
pull_request:
branches: [main]
paths:
- "integrations/community/genkit/go/**"
- ".github/workflows/unit-genkit-go.yml"
jobs:
go-genkit:
name: Go Genkit Integration Tests
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.25.0"
- name: Setup Go module cache
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-genkit-${{ hashFiles('integrations/community/genkit/go/genkit/go.sum') }}
restore-keys: |
${{ runner.os }}-go-genkit-
- name: Download dependencies
working-directory: integrations/community/genkit/go/genkit
run: go mod download
- name: Run tests
working-directory: integrations/community/genkit/go/genkit
run: go test ./... -v
================================================
FILE: .github/workflows/unit-go-sdk.yml
================================================
name: unit
on:
push:
branches: [main]
paths:
- "sdks/community/go/**"
- ".github/workflows/unit-go-sdk.yml"
pull_request:
branches: [main]
paths:
- "sdks/community/go/**"
- ".github/workflows/unit-go-sdk.yml"
jobs:
go:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: "1.24.4"
- name: Setup Go module cache
uses: actions/cache@v4
with:
path: |
~/go/pkg/mod
~/.cache/go-build
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
restore-keys: |
${{ runner.os }}-go-
- name: Download dependencies
working-directory: sdks/community/go
run: go mod download
- name: Run tests
working-directory: sdks/community/go
run: go test ./... -v
================================================
FILE: .github/workflows/unit-java-sdk.yml
================================================
name: unit
on:
push:
branches: [main]
paths:
- "sdks/community/java/**"
- ".github/workflows/unit-java-sdk.yml"
pull_request:
branches: [main]
paths:
- "sdks/community/java/**"
- ".github/workflows/unit-java-sdk.yml"
jobs:
java:
runs-on: ubuntu-latest
defaults:
run:
working-directory: sdks/community/java
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Java
uses: actions/setup-java@v4
with:
distribution: "temurin"
java-version: "17"
cache: "maven"
- name: Run tests
run: mvn -B -ntp test
================================================
FILE: .github/workflows/unit-kotlin-sdk.yml
================================================
name: unit
on:
push:
branches: [main]
paths:
- "sdks/community/kotlin/**"
- ".github/workflows/unit-kotlin-sdk.yml"
pull_request:
branches: [main]
paths:
- "sdks/community/kotlin/**"
- ".github/workflows/unit-kotlin-sdk.yml"
jobs:
kotlin:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up JDK 21
uses: actions/setup-java@v4
with:
java-version: "21"
distribution: "temurin"
- name: Setup Gradle
uses: gradle/gradle-build-action@v3
- name: Run JVM tests
working-directory: sdks/community/kotlin/library
run: ./gradlew jvmTest --no-daemon --stacktrace
- name: Parse test results
if: always()
working-directory: sdks/community/kotlin/library
run: |
echo "## Kotlin SDK Test Results Summary"
echo ""
total_tests=0
total_failures=0
total_errors=0
for module in core client tools; do
xml_dir="$module/build/test-results/jvmTest"
if [ -d "$xml_dir" ]; then
# Sum up test counts from all XML files in the directory
module_tests=$(find "$xml_dir" -name "*.xml" -exec grep -h '<testsuite' {} \; | grep -o 'tests="[0-9]*"' | sed 's/tests="\([0-9]*\)"/\1/' | awk '{sum += $1} END {print sum}')
module_failures=$(find "$xml_dir" -name "*.xml" -exec grep -h '<testsuite' {} \; | grep -o 'failures="[0-9]*"' | sed 's/failures="\([0-9]*\)"/\1/' | awk '{sum += $1} END {print sum}')
module_errors=$(find "$xml_dir" -name "*.xml" -exec grep -h '<testsuite' {} \; | grep -o 'errors="[0-9]*"' | sed 's/errors="\([0-9]*\)"/\1/' | awk '{sum += $1} END {print sum}')
# Default to 0 if empty
module_tests=${module_tests:-0}
module_failures=${module_failures:-0}
module_errors=${module_errors:-0}
if [ "$module_tests" -gt 0 ]; then
echo "✅ kotlin-$module: $module_tests tests, $module_failures failures, $module_errors errors"
total_tests=$((total_tests + module_tests))
total_failures=$((total_failures + module_failures))
total_errors=$((total_errors + module_errors))
fi
fi
done
echo ""
echo "---"
echo "### Overall Results: $total_tests tests, $total_failures failures, $total_errors errors"
if [ $total_failures -gt 0 ] || [ $total_errors -gt 0 ]; then
echo "❌ Some tests failed"
exit 1
elif [ $total_tests -eq 0 ]; then
echo "⚠️ No tests were found or executed"
exit 1
else
echo "✅ All $total_tests tests passed!"
fi
================================================
FILE: .github/workflows/unit-python-sdk.yml
================================================
name: unit
on:
push:
branches: [main]
paths:
- "sdks/python/**"
- ".github/workflows/unit-python-sdk.yml"
pull_request:
branches: [main]
paths:
- "sdks/python/**"
- ".github/workflows/unit-python-sdk.yml"
jobs:
python:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Install uv
uses: astral-sh/setup-uv@v4
with:
version: ">=0.8.0"
- name: Load cached venv
id: cached-uv-dependencies
uses: actions/cache@v4
with:
path: sdks/python/.venv
key: venv-${{ runner.os }}-${{ hashFiles('sdks/python/uv.lock') }}
- name: Install dependencies
working-directory: sdks/python
run: uv sync
- name: Run tests
working-directory: sdks/python
run: uv run python -m unittest discover tests -v
================================================
FILE: .github/workflows/unit-ruby-sdk.yml
================================================
name: unit
on:
push:
branches: [main]
paths:
- "sdks/community/ruby/**"
- ".github/workflows/unit-ruby-sdk.yml"
pull_request:
branches: [main]
paths:
- "sdks/community/ruby/**"
- ".github/workflows/unit-ruby-sdk.yml"
jobs:
ruby:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4'
bundler-cache: true
working-directory: sdks/community/ruby
- run: bundle exec rake
working-directory: sdks/community/ruby
================================================
FILE: .github/workflows/unit-typescript-sdk.yml
================================================
name: unit
on:
push:
branches: [main]
paths:
- "sdks/typescript/**"
- "typescript-sdk/**"
- "integrations/**"
- "pnpm-lock.yaml"
- "pnpm-workspace.yaml"
- "package.json"
- "nx.json"
- ".github/workflows/unit-typescript-sdk.yml"
pull_request:
branches: [main]
paths:
- "sdks/typescript/**"
- "typescript-sdk/**"
- "integrations/**"
- "pnpm-lock.yaml"
- "pnpm-workspace.yaml"
- "package.json"
- "nx.json"
- ".github/workflows/unit-typescript-sdk.yml"
jobs:
typescript:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: "22"
- name: Install protoc
uses: arduino/setup-protoc@v3
with:
version: "25.x"
repo-token: ${{ secrets.GITHUB_TOKEN }}
- name: Install pnpm
uses: pnpm/action-setup@v4
with:
version: 10.13.1
- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ~/.local/share/pnpm/store
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Test Build
run: pnpm run build
- name: Run tests
run: pnpm run test
================================================
FILE: .gitignore
================================================
**/.claude/settings.local.json
.claude/worktrees
# Test coverage
coverage/
mastra.db*
**/.DS_Store
test-results/
**/target
.nx/cache
.nx/workspace-data
node_modules
.vscode
**/mastra.db*
.pnpm-store
**/.poetry-cache
*.egg-info
**/python/**/__pycache__/
**/python/**/.venv/
**/typescript/**/node_modules/
**/typescript/**/dist/
# Turborepo
.turbo
**/.turbo
# Build artifacts and binaries
**/build/
*.dSYM/
*.exe
*.dll
*.so
*.dylib
*.o
*.obj
*.a
*.lib
*.wasm
================================================
FILE: .mcp.json
================================================
{
"mcpServers": {
"nx-mcp": {
"type": "stdio",
"command": "npx",
"args": [
"nx",
"mcp"
]
}
}
}
================================================
FILE: AGENTS.md
================================================
<!-- nx configuration start-->
<!-- Leave the start & end comments to automatically receive updates. -->
# General Guidelines for working with Nx
- When running tasks (for example build, lint, test, e2e, etc.), always prefer running the task through `nx` (i.e. `nx run`, `nx run-many`, `nx affected`) instead of using the underlying tooling directly
- You have access to the Nx MCP server and its tools, use them to help the user
- When answering questions about the repository, use the `nx_workspace` tool first to gain an understanding of the workspace architecture where applicable.
- When working in individual projects, use the `nx_project_details` mcp tool to analyze and understand the specific project structure and dependencies
- For questions around nx configuration, best practices or if you're unsure, use the `nx_docs` tool to get relevant, up-to-date docs. Always use this instead of assuming things about nx configuration
- If the user needs help with an Nx configuration or project graph error, use the `nx_workspace` tool to get any errors
- For Nx plugin best practices, check `node_modules/@nx/<plugin>/PLUGIN.md`. Not all plugins have this file - proceed without it if unavailable.
<!-- nx configuration end-->
================================================
FILE: CLAUDE.md
================================================
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Common Development Commands
### TypeScript SDK (Main Development)
```bash
# Install dependencies (using pnpm)
pnpm install
# Build all packages
pnpm build
# Run development mode
pnpm dev
# Run linting
pnpm lint
# Run type checking
pnpm check-types
# Run tests
pnpm test
# Format code
pnpm format
# Clean build artifacts
pnpm clean
# Full clean build
pnpm build:clean
```
### Python SDK
```bash
# Navigate to python-sdk directory
cd python-sdk
# Install dependencies (using poetry)
poetry install
# Run tests
python -m unittest discover tests
# Build distribution
poetry build
```
### Running Specific Integration Tests
```bash
# For TypeScript packages/integrations
cd packages/<package-name>
pnpm test
# For running a single test file
cd packages/<package-name>
pnpm test -- path/to/test.spec.ts
```
## High-Level Architecture
AG-UI is an event-based protocol that standardizes agent-user interactions. The codebase is organized as a monorepo with the following structure:
### Core Protocol Architecture
- **Event-Driven Communication**: All agent-UI communication happens through typed events (BaseEvent and its subtypes)
- **Transport Agnostic**: Protocol supports SSE, WebSockets, HTTP binary, and custom transports
- **Observable Pattern**: Uses RxJS Observables for streaming agent responses
### Key Abstractions
1. **AbstractAgent**: Base class that all agents must implement with a `run(input: RunAgentInput) -> Observable<BaseEvent>` method
2. **HttpAgent**: Standard HTTP client supporting SSE and binary protocols for connecting to agent endpoints
3. **Event Types**: Lifecycle events (RUN_STARTED/FINISHED), message events (TEXT_MESSAGE_*), tool events (TOOL_CALL_*), and state management events (STATE_SNAPSHOT/DELTA)
### Repository Structure
- `/sdks/typescript/`: Main TypeScript implementation
- `/packages/`: Core protocol packages (@ag-ui/core, @ag-ui/client, @ag-ui/encoder, @ag-ui/proto)
- `/integrations/`: Framework integrations (langgraph, mastra, crewai, etc.)
- `/apps/`: Example applications including the AG-UI Dojo demo viewer
- `/sdks/python/`: Python implementation of the protocol
- `/docs/`: Documentation site content
### Integration Pattern
Each framework integration follows a similar pattern:
1. Implements the AbstractAgent interface
2. Translates framework-specific events to AG-UI protocol events
3. Provides both TypeScript client and Python server implementations
4. Includes examples demonstrating key AG-UI features (agentic chat, generative UI, human-in-the-loop, etc.)
### State Management
- Uses STATE_SNAPSHOT for complete state representations
- Uses STATE_DELTA with JSON Patch (RFC 6902) for efficient incremental updates
- MESSAGES_SNAPSHOT provides conversation history
### Multiple Sequential Runs
- AG-UI supports multiple sequential runs in a single event stream
- Each run must complete (RUN_FINISHED) before a new run can start (RUN_STARTED)
- Messages accumulate across runs (e.g., messages from run1 + messages from run2)
- State continues to evolve across runs unless explicitly reset with STATE_SNAPSHOT
- Run-specific tracking (active messages, tool calls, steps) resets between runs
### Development Workflow
- Nx is used for monorepo build orchestration
- Each package has independent versioning
- Integration tests demonstrate protocol compliance
- The AG-UI Dojo app showcases all protocol features with live examples
<!-- nx configuration start-->
<!-- Leave the start & end comments to automatically receive updates. -->
# General Guidelines for working with Nx
- When running tasks (for example build, lint, test, e2e, etc.), always prefer running the task through `nx` (i.e. `nx run`, `nx run-many`, `nx affected`) instead of using the underlying tooling directly
- You have access to the Nx MCP server and its tools, use them to help the user
- When answering questions about the repository, use the `nx_workspace` tool first to gain an understanding of the workspace architecture where applicable.
- When working in individual projects, use the `nx_project_details` mcp tool to analyze and understand the specific project structure and dependencies
- For questions around nx configuration, best practices or if you're unsure, use the `nx_docs` tool to get relevant, up-to-date docs. Always use this instead of assuming things about nx configuration
- If the user needs help with an Nx configuration or project graph error, use the `nx_workspace` tool to get any errors
- For Nx plugin best practices, check `node_modules/@nx/<plugin>/PLUGIN.md`. Not all plugins have this file - proceed without it if unavailable.
<!-- nx configuration end-->
================================================
FILE: CONTRIBUTING.md
================================================
# Contributing to AG-UI
Thanks for checking out AG-UI! Whether you're here to fix a bug, ship a feature, improve the docs, or just figure out how things work—we're glad you're here.
Here's how to get involved:
---
## Have a Question or Ran Into Something?
Pick the right spot so we can help you faster:
- **I want to contribute [Fixes / Feature Requests]** → [GitHub Issues](https://github.com/ag-ui-protocol/ag-ui/issues)
- **"How do I...?** → [Discord](https://discord.gg/Jd3FzfdJa8) → `#-💎-contributing`
- **Introduce Yourself** → [Discord](https://discord.gg/Jd3FzfdJa8) → `🤝-intro`
---
## Want to Contribute Code?
First, an important plea:
**Please PLEASE reach out to us first before starting any significant work on new or existing features.**
We love community contributions! That said, we want to make sure we're all on the same page before you start.
Investing a lot of time and effort just to find out it doesn't align with the upstream project feels awful, and we don't want that to happen.
It also helps to make sure the work you're planning isn't already in progress.
If you'd confirmed that the **[x]** work hasn't been started yet, please file an issue first: https://github.com/ag-ui-protocol/ag-ui/issues
1. **Find Something to Work On**
Browse open issues on [GitHub](https://github.com/ag-ui-protocol/ag-ui/issues).
Got your own idea? Open an issue first so we can start the discussion.
2. **Ask to Be Assigned**
Comment on the issue and tag a code owner:
→ [Code Owners](https://github.com/ag-ui-protocol/ag-ui/blob/main/.github/CODEOWNERS)
3. **Get on the Roadmap**
Once approved, you'll be assigned the issue, and it'll get added to our [roadmap](https://github.com/orgs/ag-ui-protocol/projects/1).
4. **Coordinate With Others**
- If you're collaborating or need feedback, start a thread in `#-💎-contributing` on Discord
- Or just DM the assignee directly
5. **Open a Pull Request**
- When you're ready, submit your PR
- In the description, include: `Fixes #<issue-number>`
(This links your PR to the issue and closes it automatically)
6. **Review & Merge**
- A maintainer will review your code and leave comments if needed
- Once it's approved, we'll merge it and move the issue to "done."
**NOTE:** All community integrations (ie, .NET, Golang SDK, etc.) will need to be maintained by the community member who made the contribution.
---
## Step-by-Step Guide to Adding an Integration PR
This guide walks you through everything needed to submit an integration PR to AG-UI. It covers adding the integration code, examples, dojo configuration, end-to-end tests, and CI setup.
Use existing integrations in `integrations/` (e.g., `integrations/adk-middleware/` or `integrations/langgraph/`) as reference implementations throughout.
### Step 1: Add Your Integration Folder
Your integration code goes inside the `integrations/` folder, under a subfolder named after your integration (e.g., `integrations/my-framework/`).
- **Language subfolder** — Organize by language. For example, if your integration is in Python, place it under `integrations/my-framework/python/`. If it supports multiple languages (e.g., Python and Rust), use separate subfolders like `python/` and `rust/`.
- **Examples subfolder** — Include an `examples/` directory inside your language folder (e.g., `integrations/my-framework/python/examples/`). The dojo examples must live here, but you can include additional examples as well.
- **TypeScript client folder (required)** — No matter what language the integration is in, you must also include a `typescript/` folder. At minimum, this contains the TypeScript client code that re-exports the HTTP agent. You can copy this from an existing integration like `integrations/adk-middleware/typescript/` as a reference. It includes a `package.json`, TypeScript config, and the client code itself. If your framework natively supports TypeScript, the full TypeScript implementation should also live in this package.
**Example structure:**
```
integrations/my-framework/
├── python/
│ ├── examples/ # Dojo examples live here
│ │ ├── pyproject.toml
│ │ └── ...
│ ├── pyproject.toml # Integration package
│ └── ...
└── typescript/
├── package.json
├── tsconfig.json
└── src/
└── index.ts # Re-exports the HTTP agent
```
### Step 2: Register Your Integration in the Dojo
You need to update three files inside `apps/dojo/src/` to make the dojo aware of your integration:
- **`agents.ts`** — Add an entry for your integration. The **object key** you choose is important because it must match exactly in the other configuration files. If your framework supports multiple variants — different languages, runtimes, or transport modes — each variant gets its own separate entry. For example, LangGraph has entries for LangGraph Platform (Python), LangGraph FastAPI (Python), and LangGraph TypeScript.
- **`menu.ts`** — Add your integration to the sidebar menu. The **`id`** must match the object key you used in `agents.ts`. The **`name`** is the human-readable display label shown in the left sidebar and does not need to match the ID. Each entry also defines which features it supports (e.g., `agentic_chat`, `human_in_the_loop`, `agentic_generative_ui`). This file is the single source of truth for integration configuration.
- **`env.ts`** — Define the environment variable for your agent's hosted URL (one per agent). This is how the dojo knows where to reach your agent at runtime. The default should match whatever host/port your example code uses.
### Step 3: Configure the Agent Mapping
Each entry in `agents.ts` contains a mapping of feature keys. This is typically a one-to-one mapping where each key corresponds to one agent. For most integrations, this is simple — one feature maps to one agent name. If your framework handles multiple agents talking together, there may be multiple agents listed, but each still gets its own entry.
### Step 4: Set Up Environment Variables
Your example code must:
- **Bind to host `0.0.0.0`** (or be overridable via the `HOST` environment variable)
- **Respect the `PORT` environment variable** — when the dojo sets a specific port, your agent must bind to that exact port
The port values defined in `env.ts` must match the URLs configured in `agents.ts`. If they don't line up, the dojo won't be able to find your agent.
### Step 5: Add Dojo Scripts
Add entries for your integration in the dojo script configuration at `apps/dojo/scripts/`. There are two scripts to update:
- **`prep-dojo-everything.js`** — This is the "prepare" command. It installs dependencies and builds your module (e.g., `pnpm install`, `uv sync`, `poetry install`, `go build`). It does **not** start any servers.
- **`run-dojo-everything.js`** — This is the "run" command. It starts your integration's agent server.
In both scripts, you add an entry to the `ALL_TARGETS` object. The **object key must match** the key you used in `agents.ts`. Each entry includes:
- The **name** for logging
- The **command** to execute (e.g., `uv sync` for prep, `uv run ...` for run)
- The **working directory** (pointing into your `integrations/` examples folder)
- **Environment variables** (optional) — for example, `PORT`
**Important rules for `run-dojo-everything.js`:**
- The **ports must not collide** with any other integration. Pick the next highest available port number.
- The `dojo` and `dojo-dev` entries in the same file need environment variables that point to your service's port, so the dojo knows where to reach your agent.
- If your integration runs **multiple agents**, you can have multiple entries in run. See `a2a-middleware` for an example of this pattern.
At this point, you should be able to spin up the dojo locally and see your integration working.
### Step 6: Add End-to-End Tests
Every feature listed in your sidebar entry (in `menu.ts`) needs a corresponding end-to-end test. **Without tests, your PR will not be considered ready.**
- **Create a test folder** for your integration inside `apps/dojo/e2e/tests/` (e.g., `apps/dojo/e2e/tests/myFrameworkTests/`). Each feature you support gets its own spec file inside this folder.
- **Follow existing test patterns** — Look at how other integrations implement their tests. If other frameworks use shared helpers from `apps/dojo/e2e/featurePages/`, you should use `featurePages` too. However, some tests use framework-specific page objects in `apps/dojo/e2e/pages/<framework-name>/`. If the same test for other frameworks lives in `pages/some-framework`, you'll need to copy it to `pages/my-framework` and adapt it for your integration.
- **Run tests locally** before submitting your PR. From `apps/dojo/`, in one terminal:
```bash
./scripts/prep-dojo-everything.js --only dojo,my-framework
./scripts/run-dojo-everything.js --only dojo,my-framework
```
Then in a separate terminal, from `apps/dojo/e2e/`:
```bash
pnpm install
pnpm test tests/myFrameworkTests/
```
### Step 7: Add CI Configuration
The end-to-end tests need to run in CI as well. Update the GitHub Actions workflow file at `.github/workflows/dojo-e2e.yml`:
- **Add your integration to the test matrix** at the top of the workflow. The entry name must match the key you used in `agents.ts`. This tells CI which test path to use (e.g., `tests/myFrameworkTests`).
- **Add a services section** that defines which services to build and run. The service names map back to the `prep-dojo` and `run-dojo` scripts. The CI workflow uses a `wait-on` command to check that services are responsive (via TCP/HTTP) before running tests.
**Note:** Tests won't run by default on external PRs. The team will open a separate PR from within the repo to trigger CI, then merge the original contributor PR once tests pass.
### Step 8 (Optional): Update CODEOWNERS
This step is only needed if you want to be added as a co-owner who can merge changes to your integration without core team review. If this applies to you, update the `.github/CODEOWNERS` file to add yourself alongside the team:
```
integrations/my-framework @ag-ui-protocol/copilotkit @your-github-username
```
For most contributors, this is not required — the core team already owns all paths by default.
### Quick Reference Checklist
Use this checklist to verify your PR is complete before submitting:
- [ ] Integration folder added under `integrations/` with language subfolder + examples
- [ ] TypeScript client folder included (even for non-TS integrations)
- [ ] `agents.ts` updated with integration entry and feature mapping (object key is the source of truth)
- [ ] `menu.ts` updated with sidebar entry (`id` matches `agents.ts` key, `name` is human-readable)
- [ ] `env.ts` updated with agent URL environment variable
- [ ] Example code binds to `0.0.0.0` and respects `HOST`/`PORT` env vars
- [ ] `prep-dojo-everything.js` and `run-dojo-everything.js` entries added (object keys match `agents.ts`)
- [ ] Ports in `run-dojo-everything.js` do not collide with existing integrations
- [ ] `dojo`/`dojo-dev` entries updated with env vars pointing to your service's port
- [ ] End-to-end test spec files added for every supported feature
- [ ] Tests pass locally
- [ ] CI workflow matrix updated in `.github/workflows/dojo-e2e.yml` (entry name matches `agents.ts`)
---
## Contributing a Community SDK
If you're adding a new language SDK (e.g., Go, Java, Kotlin, Ruby, Rust) rather than a framework integration, place it in the `sdks/community/` folder. The team will add you as a code owner for that SDK so you can push changes without needing core team sign-off. Documentation for community SDKs also lives inside that SDK folder.
This is a separate process from adding an integration — see the steps above for framework integrations.
---
## Want to Contribute to the Docs?
Docs are part of the codebase and super valuable—thanks for helping improve them!
Here's how to contribute:
1. **Open an Issue First**
- Open a [GitHub issue](https://github.com/ag-ui-protocol/ag-ui/issues) describing what you'd like to update or add.
- Then comment and ask to be assigned.
2. **Submit a PR**
- Once assigned, make your edits and open a pull request.
- In the description, include: `Fixes #<issue-number>`
(This links your PR to the issue and closes it automatically)
- A maintainer will review it and merge if it looks good.
That's it! Simple and appreciated.
---
## That's It!
AG-UI is community-built, and every contribution helps shape where we go next.
Big thanks for being part of it!
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2025
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:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
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.
================================================
FILE: README.md
================================================
# <img src="https://github.com/user-attachments/assets/ebc0dd08-8732-4519-9b6c-452ce54d8058" alt="ag-ui Logo" width="22"/> AG-UI: The Agent-User Interaction Protocol
AG-UI is an open, lightweight, event-based protocol that standardizes how AI agents connect to user-facing applications.
Built for simplicity and flexibility, it enables seamless integration between AI agents, real time user context, and user interfaces.
---
<br>
[](https://www.npmjs.com/package/@ag-ui/core)


<a href="https://discord.gg/Jd3FzfdJa8" target="_blank"> Join our Discord → </a> <a href="https://ag-ui.com/" target="_blank"> Read the Docs → </a> <a href="https://dojo.ag-ui.com/" target="_blank"> Go to the AG-UI Dojo → </a> <a href="https://x.com/CopilotKit" target="_blank"> Follow us → </a>
<img width="1600" height="680" alt="1600x680" src="https://github.com/user-attachments/assets/cd0376f3-0a3d-4cc3-a931-2b166c4efe5e" />
## 🚀 Getting Started
Create a new AG-UI application in seconds:
```bash
npx create-ag-ui-app my-agent-app
```
<h3> Useful Links:</h3>
- [The AG-UI Dojo](https://dojo.ag-ui.com/)
- [Build AG-UI-powered applications(Quickstart)](https://docs.ag-ui.com/quickstart/applications)
- [Build new AG-UI framework integrations (Quickstart)](https://go.copilotkit.ai/agui-contribute)
- [Book a call to discuss an AG-UI integration with a new framework](https://calendly.com/markus-copilotkit/ag-ui)
- [Join the Discord Community](https://discord.gg/Jd3FzfdJa8)
## What is AG-UI?
AG-UI is an open, lightweight, event-based protocol for agent-human interaction, designed for simplicity & flexibility:
- During agent executions, agent backends **emit events _compatible_ with one of AG-UI's ~16 standard event types**
- Agent backends can **accept one of a few simple AG-UI compatible inputs** as arguments
**AG-UI includes a flexible middleware layer** that ensures compatibility across diverse environments:
- Works with **any event transport** (SSE, WebSockets, webhooks, etc.)
- Allows for **loose event format matching**, enabling broad agent and app interoperability
It also ships with a **reference HTTP implementation** and **default connector** to help teams get started fast.
[Learn more about the specs →](https://go.copilotkit.ai/ag-ui-introduction)
## Why AG-UI?
AG-UI was developed based on real-world requirements and practical experience building in-app agent interactions.
## Where does AGUI fit in the agentic protocol stack?
AG-UI is complementary to the other 2 top agentic protocols
- MCP gives agents tools
- A2A allows agents to communicate with other agents
- AG-UI brings agents into user-facing applications
<div align="center">
<img width="2048" height="1182" alt="The Agent Protocol Stack" src="https://github.com/user-attachments/assets/41138f71-50be-4812-98aa-20e0ad595716" />
</div>
## 🚀 Features
- 💬 Real-time agentic chat with streaming
- 🔄 Bi-directional state synchronization
- 🧩 Generative UI and structured messages
- 🧠 Real-time context enrichment
- 🛠️ Frontend tool integration
- 🧑💻 Human-in-the-loop collaboration
## 🛠 Supported Integrations
AG-UI was born from CopilotKit's initial **partnership** with LangGraph and CrewAI - and brings the incredibly popular agent-user-interactivity infrastructure to the wider agentic ecosystem.
**1st party** = the platforms that have AG‑UI built in and provide documentation for guidance.
## Frameworks
| Framework | Status | AG-UI Resources |
| ------------------------------------------------------------------ | ------------------------ | -------------------------------------------------------------------------------- |
| Built-in Agent | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/direct-to-llm) |
### 🤝 Partnerships
| Framework | Status | AG-UI Resources |
| ---------- | ------- | ---------------- |
| [LangGraph](https://www.langchain.com/langgraph) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/langgraph/) 🎮 [Demos](https://dojo.ag-ui.com/langgraph-fastapi/feature/shared_state) |
| [CrewAI](https://crewai.com/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/crewai-flows) 🎮 [Demos](https://dojo.ag-ui.com/crewai/feature/shared_state) |
### 🧩 1st Party
| Framework | Status | AG-UI Resources |
| ---------- | ------- | ---------------- |
| [Microsoft Agent Framework](https://azure.microsoft.com/en-us/blog/introducing-microsoft-agent-framework/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/microsoft-agent-framework) 🎮 [Demos](https://dojo.ag-ui.com/microsoft-agent-framework-dotnet/feature/shared_state) |
| [Google ADK](https://google.github.io/adk-docs/get-started/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/adk) 🎮 [Demos](https://dojo.ag-ui.com/adk-middleware/feature/shared_state?openCopilot=true) |
| [AWS Strands Agents](https://github.com/strands-agents/sdk-python) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/aws-strands) 🎮 [Demos](https://dojo.ag-ui.com/aws-strands/feature/shared_state) |
| [Mastra](https://mastra.ai/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/mastra/) 🎮 [Demos](https://dojo.ag-ui.com/mastra/feature/tool_based_generative_ui) |
| [Pydantic AI](https://github.com/pydantic/pydantic-ai) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/pydantic-ai/) 🎮 [Demos](https://dojo.ag-ui.com/pydantic-ai/feature/shared_state) |
| [Agno](https://github.com/agno-agi/agno) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/agno/) 🎮 [Demos](https://dojo.ag-ui.com/agno/feature/tool_based_generative_ui) |
| [LlamaIndex](https://github.com/run-llama/llama_index) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/llamaindex/) 🎮 [Demos](https://dojo.ag-ui.com/llamaindex/feature/shared_state) |
| [AG2](https://ag2.ai/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/ag2/) 🎮 [Demos](https://dojo.ag-ui.com/ag2/feature/shared_state) |
| [AWS Bedrock Agents](https://aws.amazon.com/bedrock/agents/) | 🛠️ In Progress | – |
### 🌐 Community
| Framework | Status | AG-UI Resources |
| ---------- | ------- | ---------------- |
| [Langroid](https://github.com/ag-ui-protocol/ag-ui/tree/main/integrations/langroid) | ✅ Supported | 🎮 [Demos](https://dojo.ag-ui.com/langroid/feature/shared_state) |
| [OpenAI Agent SDK](https://openai.github.io/openai-agents-python/) | 🛠️ In Progress | – |
| [Cloudflare Agents](https://developers.cloudflare.com/agents/) | 🛠️ In Progress | – |
## Agent Interaction Protocols
| Protocols | Status | AG-UI Resources | Integrations |
| ---------- | ------- | ---------------- | ------------- |
| [A2A]() | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/a2a-protocol) | Partnership |
## Infrastructure / Deployment
| Platform | Status | AG-UI Resources | Integrations |
| ---------- | ------- | ---------------- | ------------- |
| [Amazon Bedrock AgentCore](https://aws.amazon.com/bedrock/agentcore/) | ✅ Supported | ➡️ [Docs](https://docs.aws.amazon.com/bedrock-agentcore/latest/devguide/runtime-agui.html) | 1st Party |
## Specification (standard)
| Framework | Status | AG-UI Resources |
| ---------- | ------- | ---------------- |
| [Oracle Agent Spec](http://oracle.github.io/agent-spec/) | ✅ Supported | ➡️ [Docs](https://go.copilotkit.ai/copilotkit-oracle-docs) 🎮 [Demos](https://dojo.ag-ui.com/agent-spec-langgraph/feature/tool_based_generative_ui) |
## Generative UI
| Framework | Status | AG-UI Resources |
| ---------- | ------- | ---------------- |
| [MCP Apps](https://blog.modelcontextprotocol.io/posts/2025-11-21-mcp-apps/) | ✅ Supported | ➡️ [Docs](https://docs.copilotkit.ai/generative-ui-specs/mcp-apps) 🎮 [Demos]() |
## SDKs
| SDK | Status | AG-UI Resources | Integrations |
| --- | ------- | ---------------- | ------------- |
| [Kotlin]() | ✅ Supported | ➡️ [Getting Started](https://github.com/ag-ui-protocol/ag-ui/blob/main/docs/sdk/kotlin/overview.mdx) | Community |
| [Golang]() | ✅ Supported | ➡️ [Getting Started](https://github.com/ag-ui-protocol/ag-ui/blob/main/docs/sdk/go/overview.mdx) | Community |
| [Dart]() | ✅ Supported | ➡️ [Getting Started](https://github.com/ag-ui-protocol/ag-ui/tree/main/sdks/community/dart) | Community |
| [Java]() | ✅ Supported | ➡️ [Getting Started](https://github.com/ag-ui-protocol/ag-ui/blob/main/docs/sdk/java/overview.mdx) | Community |
| [Rust]() | ✅ Supported | ➡️ [Getting Started](https://github.com/ag-ui-protocol/ag-ui/tree/main/sdks/community/rust/crates/ag-ui-client) | Community |
| [Ruby]() | ✅ Supported | ➡️ [Getting Started](https://github.com/ag-ui-protocol/ag-ui/tree/main/sdks/community/ruby) | Community |
| [.NET]() | 🛠️ In Progress | ➡️ [PR](https://github.com/ag-ui-protocol/ag-ui/pull/38) | Community |
| [Nim]() | 🛠️ In Progress | ➡️ [PR](https://github.com/ag-ui-protocol/ag-ui/pull/29) | Community |
| [Flowise]() | 🛠️ In Progress | ➡️ [GitHub Source](https://github.com/ag-ui-protocol/ag-ui/issues/367) | Community |
| [Langflow]() | 🛠️ In Progress | ➡️ [GitHub Source](https://github.com/ag-ui-protocol/ag-ui/issues/366) | Community |
## Clients
| Client | Status | AG-UI Resources | Integrations |
| --- | ------- | ---------------- | ------------- |
| [CopilotKit](https://github.com/CopilotKit/CopilotKit) | ✅ Supported | ➡️ [Getting Started](https://docs.copilotkit.ai/direct-to-llm/guides/quickstart) | 1st Party |
| [Terminal + Agent]() | ✅ Supported | ➡️ [Getting Started](https://docs.ag-ui.com/quickstart/clients) | Community |
| [React Native]() | 🛠️ Help Wanted | ➡️ [GitHub Source](https://github.com/ag-ui-protocol/ag-ui/issues/510) | Community |
[View all supported integrations →](https://docs.ag-ui.com/introduction#supported-integrations)
## Examples
### Hello World App
Video:
https://github.com/user-attachments/assets/18c03330-1ebc-4863-b2b8-cc6c3a4c7bae
https://agui-demo.vercel.app/
## The AG-UI Dojo (Building-Blocks Viewer)
The AG-UI Dojo demonstrates AG-UI's core building blocks through simple, focused examples—each just 50-200 lines of code.
View the source code for the Dojo and all framework integrations [here](https://github.com/ag-ui-protocol/ag-ui/tree/main/apps/dojo).
https://github.com/user-attachments/assets/c298eea8-3f39-4a94-b968-7712429b0c49
## 🙋🏽♂️ Contributing to AG-UI
Check out the [Contributing guide](https://github.com/ag-ui-protocol/ag-ui/blob/main/CONTRIBUTING.md)
- **[Bi-Weekely AG-UI Working Group](https://lu.ma/CopilotKit?k=c)**
📅 Follow the CopilotKit Luma Events Calendar
## Roadmap
Check out the [AG-UI Roadmap](https://github.com/orgs/ag-ui-protocol/projects/1) to see what's being built and where you can jump in.
## 📄 License
AG-UI is open source software [licensed as MIT](https://opensource.org/licenses/MIT).
================================================
FILE: apps/client-cli-example/.gitignore
================================================
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.*
!.env.example
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
.output
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Sveltekit cache directory
.svelte-kit/
# vitepress build output
**/.vitepress/dist
# vitepress cache directory
**/.vitepress/cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# Firebase cache directory
.firebase/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v3
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# Vite files
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
.vite/
================================================
FILE: apps/client-cli-example/README.md
================================================
# AG-UI CLI Example
A command-line chat interface demonstrating the AG-UI client with a Mastra agent. This example shows how to build an interactive CLI application that streams agent responses and tool calls in real-time.
## Features
- Interactive chat loop with streaming responses
- Real-time tool call visualization (weather and browser tools)
- Message history persistence using LibSQL
- Built with `@ag-ui/client` and `@ag-ui/mastra`
## Prerequisites
- Node.js 22.13.0 or later
- OpenAI API key
## Setup
1. Install dependencies from the repository root:
```bash
pnpm install
```
2. Set your OpenAI API key:
```bash
export OPENAI_API_KEY=your_api_key_here
```
## Usage
Run the CLI:
```bash
pnpm start
```
Try these example prompts:
- "What's the weather in San Francisco?"
- "Browse https://example.com"
Press `Ctrl+D` to quit.
## How It Works
This example uses:
- **MastraAgent**: Wraps a Mastra agent with AG-UI protocol support
- **Event Handlers**: Streams text deltas, tool calls, and results to the console
- **Memory**: Persists conversation history in a local SQLite database
================================================
FILE: apps/client-cli-example/package.json
================================================
{
"name": "client-cli-example",
"version": "0.1.0",
"private": true,
"scripts": {
"start": "tsx src/index.ts",
"dev": "tsx --watch src/index.ts",
"build": "tsc",
"clean": "git clean -fdX --exclude=\"!.env\""
},
"dependencies": {
"@ag-ui/client": "workspace:*",
"@ag-ui/core": "workspace:*",
"@ag-ui/mastra": "workspace:*",
"@mastra/client-js": "^1.0.1",
"@mastra/core": "^1.0.4",
"@mastra/libsql": "^1.0.0",
"@mastra/loggers": "^1.0.0",
"@mastra/memory": "^1.0.0",
"open": "^10.1.2",
"zod": "^4.3.6"
},
"devDependencies": {
"@types/node": "^20",
"tsx": "^4.7.0",
"typescript": "^5"
}
}
================================================
FILE: apps/client-cli-example/src/agent.ts
================================================
import { Agent } from "@mastra/core/agent";
import { MastraAgent } from "@ag-ui/mastra";
import { Memory } from "@mastra/memory";
import { LibSQLStore } from "@mastra/libsql";
import { weatherTool } from "./tools/weather.tool";
import { browserTool } from "./tools/browser.tool";
export const agent = new MastraAgent({
resourceId: "cliExample",
agent: new Agent({
id: "ag-ui-agent",
name: "AG-UI Agent",
instructions: `
You are a helpful assistant that runs a CLI application.
When helping users get weather details for specific locations, respond:
- Always ask for a location if none is provided.
- If the location name isn’t in English, please translate it
- If giving a location with multiple parts (e.g. "New York, NY"), use the most relevant part (e.g. "New York")
- Include relevant details like humidity, wind conditions, and precipitation
- Keep responses concise but informative
Use the weatherTool to fetch current weather data.
When helping users browse the web, always use a full URL, for example: "https://www.google.com"
Use the browserTool to browse the web.
`,
model: "openai/gpt-4.1-mini",
tools: { weatherTool, browserTool },
memory: new Memory({
storage: new LibSQLStore({
id: "mastra-cli-example-db",
url: "file:./mastra.db",
}),
}),
}),
});
================================================
FILE: apps/client-cli-example/src/index.ts
================================================
import * as readline from "readline";
import { randomUUID } from "@ag-ui/client";
import { agent } from "./agent";
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
});
async function chatLoop() {
console.log("🤖 AG-UI chat started! Type your messages and press Enter. Press Ctrl+D to quit.\n");
return new Promise<void>((resolve) => {
const promptUser = () => {
rl.question("> ", async (input) => {
if (input.trim() === "") {
promptUser();
return;
}
console.log("");
rl.pause();
agent.messages.push({
id: randomUUID(),
role: "user",
content: input.trim(),
});
try {
await agent.runAgent(
{},
{
onTextMessageStartEvent() {
process.stdout.write("🤖 AG-UI assistant: ");
},
onTextMessageContentEvent({ event }) {
process.stdout.write(event.delta);
},
onTextMessageEndEvent() {
console.log("\n");
},
onToolCallStartEvent({ event }) {
console.log("🔧 Tool call:", event.toolCallName);
},
onToolCallArgsEvent({ event }) {
process.stdout.write(event.delta);
},
onToolCallEndEvent() {
console.log("");
},
onToolCallResultEvent({ event }) {
if (event.content) {
console.log("🔍 Tool call result:", event.content);
}
},
},
);
} catch (error) {
console.error("❌ Error running agent:", error);
}
rl.resume();
promptUser();
});
};
rl.on("close", () => {
console.log("\n👋 Goodbye!");
resolve();
});
promptUser();
});
}
async function main() {
await chatLoop();
}
main().catch(console.error);
================================================
FILE: apps/client-cli-example/src/tools/browser.tool.ts
================================================
import { createTool } from "@mastra/core/tools";
import { z } from "zod";
import open from "open";
export const browserTool = createTool({
id: "browser",
description: "Browse the web",
inputSchema: z.object({
url: z.string().describe("URL to browse"),
}),
outputSchema: z.string(),
execute: async (inputData) => {
open(inputData.url);
return `Browsed ${inputData.url}`;
},
});
================================================
FILE: apps/client-cli-example/src/tools/weather.tool.ts
================================================
import { createTool } from "@mastra/core/tools";
import { z } from "zod";
interface GeocodingResponse {
results: {
latitude: number;
longitude: number;
name: string;
}[];
}
interface WeatherResponse {
current: {
time: string;
temperature_2m: number;
apparent_temperature: number;
relative_humidity_2m: number;
wind_speed_10m: number;
wind_gusts_10m: number;
weather_code: number;
};
}
export const weatherTool = createTool({
id: "get-weather",
description: "Get current weather for a location",
inputSchema: z.object({
location: z.string().describe("City name"),
}),
outputSchema: z.object({
temperature: z.number(),
feelsLike: z.number(),
humidity: z.number(),
windSpeed: z.number(),
windGust: z.number(),
conditions: z.string(),
location: z.string(),
}),
execute: async (inputData) => {
return await getWeather(inputData.location);
},
});
const getWeather = async (location: string) => {
const geocodingUrl = `https://geocoding-api.open-meteo.com/v1/search?name=${encodeURIComponent(location)}&count=1`;
const geocodingResponse = await fetch(geocodingUrl);
const geocodingData = (await geocodingResponse.json()) as GeocodingResponse;
if (!geocodingData.results?.[0]) {
throw new Error(`Location '${location}' not found`);
}
const { latitude, longitude, name } = geocodingData.results[0];
const weatherUrl = `https://api.open-meteo.com/v1/forecast?latitude=${latitude}&longitude=${longitude}¤t=temperature_2m,apparent_temperature,relative_humidity_2m,wind_speed_10m,wind_gusts_10m,weather_code`;
const response = await fetch(weatherUrl);
const data = (await response.json()) as WeatherResponse;
return {
temperature: data.current.temperature_2m,
feelsLike: data.current.apparent_temperature,
humidity: data.current.relative_humidity_2m,
windSpeed: data.current.wind_speed_10m,
windGust: data.current.wind_gusts_10m,
conditions: getWeatherCondition(data.current.weather_code),
location: name,
};
};
function getWeatherCondition(code: number): string {
const conditions: Record<number, string> = {
0: "Clear sky",
1: "Mainly clear",
2: "Partly cloudy",
3: "Overcast",
45: "Foggy",
48: "Depositing rime fog",
51: "Light drizzle",
53: "Moderate drizzle",
55: "Dense drizzle",
56: "Light freezing drizzle",
57: "Dense freezing drizzle",
61: "Slight rain",
63: "Moderate rain",
65: "Heavy rain",
66: "Light freezing rain",
67: "Heavy freezing rain",
71: "Slight snow fall",
73: "Moderate snow fall",
75: "Heavy snow fall",
77: "Snow grains",
80: "Slight rain showers",
81: "Moderate rain showers",
82: "Violent rain showers",
85: "Slight snow showers",
86: "Heavy snow showers",
95: "Thunderstorm",
96: "Thunderstorm with slight hail",
99: "Thunderstorm with heavy hail",
};
return conditions[code] || "Unknown";
}
================================================
FILE: apps/client-cli-example/tsconfig.json
================================================
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"lib": ["ES2020", "dom"],
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"moduleResolution": "node"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}
================================================
FILE: apps/dojo/.gitignore
================================================
next-env.d.ts
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*
# Diagnostic reports (https://nodejs.org/api/report.html)
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
*.lcov
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Snowpack dependency directory (https://snowpack.dev/)
web_modules/
# TypeScript cache
*.tsbuildinfo
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional stylelint cache
.stylelintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variable files
.env
.env.*
!.env.example
# parcel-bundler cache (https://parceljs.org/)
.cache
.parcel-cache
# Next.js build output
.next
out
# Nuxt.js build / generate output
.nuxt
dist
.output
# Gatsby files
.cache/
# Comment in the public line in if your project uses Gatsby and not Next.js
# https://nextjs.org/blog/next-9-1#public-directory-support
# public
# vuepress build output
.vuepress/dist
# vuepress v2.x temp and cache directory
.temp
.cache
# Sveltekit cache directory
.svelte-kit/
# vitepress build output
**/.vitepress/dist
# vitepress cache directory
**/.vitepress/cache
# Docusaurus cache and generated files
.docusaurus
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
# Firebase cache directory
.firebase/
# TernJS port file
.tern-port
# Stores VSCode versions used for testing VSCode extensions
.vscode-test
# yarn v3
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# Vite files
vite.config.js.timestamp-*
vite.config.ts.timestamp-*
.vite/
# Mastra files
.mastra
================================================
FILE: apps/dojo/LICENSE
================================================
Copyright (c) 2025 Tawkit Inc.
Copyright (c) 2025 Markus Ecker
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:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
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.
================================================
FILE: apps/dojo/README.md
================================================
# AG-UI Protocol Dojo
A modern, interactive viewer for exploring CopilotKit agent demos with a clean, responsive UI and dark/light theme support.
## Overview
The Demo Viewer provides a centralized interface for browsing, viewing, and exploring the source code of various CopilotKit agent demos. It features:
- Clean, modern UI with dark/light theme support
- Interactive demo previews
- Source code exploration with syntax highlighting
- Organized demo listing with tags and descriptions
- LLM provider selection
## Development Setup
To run the Demo Viewer locally for development, follow these steps:
### Install dependencies
```bash
brew install protobuf
```
Note that running the dojo currently requires the use of `pnpm` (vs `yarn` or `npm`) do to how we handle workspace dependencies.
```bash
curl -fsSL https://get.pnpm.io/install.sh | sh -
```
The first time you want to run, you need to build all of the dojos dependencies throught the repository.
```
# from the ag-ui repository root
pnpm i
pnpm build --filter=demo-viewer
```
### Run the Demo Viewer
There are 3 ways to run the demo viewer
- Run just the demo viewer, and run the agent(s) separately
- Run the dev script for the entire repo, and run the agent(s) separately
- use the `dojo-everything` scripts
#### Run just the demo viewer, and run the agent(s) separately.
In one terminal, you can `cd` into the dojo directory and run `pnpm dev` to just run the dojo
This will not capture updates to dependencies of the dojo
In another terminal, you'll need to run any other agents you want to test separately, see "Run Agents" below.
The dojo will start on port 3000 by default
Note that some agents may run on colliding ports
#### Run the dev script for the entire repo, and run the agent(s) separately
In one terminal, you can run `pnpm dev` from the *repository root*
This WILL automatically rebuild dependencies, for example if you change the mastra integration, it will automatically rebuild and be bundled into the dojo with HMR.
In another terminal, you'll need to run any other agents you want to test separately, see "Run Agents" below.
The dojo will start on port 3000 by default
Note that some agents may run on colliding ports
#### Run Agents
Agent examples for the dojo are generally located in `integrations/{integrationName}/{language}/examples`. A readme there should explain what you need to do to run the example, but it's usually either `npm dev` for typescript packages, or `poetry install && poetry run dev` or `uv sync && uv run dev` for python servers.
Note that some agents may run on colliding ports
#### Use the `dojo-everything` scripts
These are the easiest ways to run everything. They will automatically configure all of your ports to not be colliding, provide that information to the dojo, and spin up the dojo.
```
# In the apps/dojo directory
./scripts/prep-dojo-everything.js
./scripts/run-dojo-everything.js
```
The demo viewer will now run on port 9999.
The one caveat here is that (for precompiled speed while running tests) this runs a production nextjs build, and that build has to be redone if you modify the dojo code at all (or any of the typescript integrations).
You can look in the `run-dojo-everything.js` script and see which ports it runs agents at, and export those as environment variables, which can be found in `apps/dojo/src/env.ts`. Then you can run the dojo via `pnpm dev` at the repo root, to get live updates to typescript integrations and the dojo. There is not HMR on most of the python framework agent examples.
To choose which agents or services the `run-dojo-everything.js` script runs you can use the `--only` flag, like this: `./scripts/run-dojo-everything.js --only adk-middleware,langgraph-fastapi`. The names for these IDs match what is in `src/agents.ts` as well as being findable in the run-dojo-everything script. .
### Adding a new integration
Integrations should go in `integrations/{integrationID}`. There should always be a typescript folder that at least contains the client, and possibly a python (or other language) folder.
To add it to the dojo, please make sure it gets added to
- src/agents.ts
- src/menu.ts
- scripts/prep-dojo-everything.js
- scripts/run-dojo-everything.js
- e2e.yml
- the `apps/dojo/e2e` folder, look in the tests folder of other frameworks, and you should be able to mostly dupiclate these.
================================================
FILE: apps/dojo/components.json
================================================
{
"$schema": "https://ui.shadcn.com/schema.json",
"style": "new-york",
"rsc": true,
"tsx": true,
"tailwind": {
"config": "tailwind.config.ts",
"css": "src/app/globals.css",
"baseColor": "neutral",
"cssVariables": true,
"prefix": ""
},
"iconLibrary": "lucide",
"aliases": {
"components": "@/components",
"utils": "@/lib/utils",
"ui": "@/components/ui",
"lib": "@/lib",
"hooks": "@/hooks"
},
"registries": {}
}
================================================
FILE: apps/dojo/e2e/.gitignore
================================================
playwright-report/
test-results/
================================================
FILE: apps/dojo/e2e/README.md
================================================
# CopilotKit Demo Smoke Tests
This repository houses Playwright-based smoke tests that run on a 6-hour schedule to make sure CopilotKit demo apps remain live and functional.
## 🔧 Local development
```bash
# Install deps
npm install
# Install browsers once
npx playwright install --with-deps
# Run the full suite
npm test
```
Playwright HTML reports are saved to `./playwright-report`.
## ➕ Adding a new smoke test
1. Duplicate an existing file in `tests/` or create `tests/<demo>.spec.ts`.
2. Use Playwright's `test` API—keep the test short (<30 s).
3. Commit and push—GitHub Actions will pick it up on the next scheduled run.
## 🚦 CI / CD
- `.github/workflows/scheduled-tests.yml` executes the suite every 6 hours and on manual trigger.
- Failing runs surface in the Actions tab; the HTML report is uploaded as an artifact.
- (Optional) Slack notifications can be wired by adding a step after the tests.
- Slack alert on failure is baked into the workflow. Just add `SLACK_WEBHOOK_URL` (Incoming Webhook) in repo secrets.
================================================
FILE: apps/dojo/e2e/VIDEO_SETUP.md
================================================
# 📹 S3 Video Upload System
This system automatically uploads videos of failed Playwright tests to S3 and embeds clickable links in Slack notifications.
## ✅ **Setup Complete Checklist**
- [x] AWS infrastructure created (`setup-aws.sh`)
- [x] Dependencies installed (`@aws-sdk/client-s3`, `json2md`)
- [x] S3 video uploader created (`lib/upload-video.ts`)
- [x] Custom reporter created (`reporters/s3-video-reporter.ts`)
- [x] Playwright config updated (video recording enabled)
- [x] Slack layout updated (video links embedded)
- [x] GitHub Actions updated (AWS credentials)
## 🔧 **Required GitHub Secrets**
Add these secrets to your repository:
```
AWS_ACCESS_KEY_ID=AKIA...
AWS_SECRET_ACCESS_KEY=...
AWS_S3_BUCKET_NAME=copilotkit-e2e-smoke-test-recordings-abc123
AWS_S3_REGION=us-east-1
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/...
```
## 🎯 **How It Works**
### **1. Video Recording**
- Videos recorded only for **failed tests** (`retain-on-failure`)
- 1280x720 resolution, WebM format
- Stored temporarily in `test-results/`
### **2. S3 Upload Process**
```
Failed Test → Video Recorded → S3 Upload → Slack Notification
```
### **3. S3 File Organization**
```
copilotkit-e2e-smoke-test-recordings-{random}/
└── github-runs/
└── {GITHUB_RUN_ID}/
└── cpk-demos-smoke-tests/
└── {SUITE_NAME}/
└── {TEST_NAME}/
└── video.webm
```
### **4. Slack Integration**
Videos appear as clickable links in categorized failure notifications:
```
🤖 AI Response Issues (2 failures)
• Human in the Loop Feature: Chat interaction steps
→ No AI response - Expected: /Travel Guide/i
📹 [Watch Video](https://bucket.s3.amazonaws.com/path/video.webm)
🔧 Action: Check API keys and AI service status
```
## 🛠 **Local Development**
### **Test Video Upload Locally**
```bash
# Set environment variables
export AWS_S3_BUCKET_NAME="your-bucket-name"
export AWS_S3_REGION="us-east-1"
export AWS_ACCESS_KEY_ID="your-key"
export AWS_SECRET_ACCESS_KEY="your-secret"
# Run tests with video upload enabled
CI=true pnpm exec playwright test --reporter=./reporters/s3-video-reporter.ts
```
### **Disable Video Upload Locally**
Videos are automatically disabled in local runs. To force enable:
```bash
# Edit playwright.config.ts
uploadVideos: true // In local reporter config
```
## 📊 **Monitoring & Debugging**
### **Check Upload Status**
- Videos upload logs appear in GitHub Actions output
- Failed uploads are logged but don't fail the workflow
- Video URLs written to `test-results/video-urls.json`
### **Common Issues**
**❌ No videos in Slack**
- Check AWS credentials in GitHub secrets
- Verify S3 bucket permissions
- Look for upload errors in Actions logs
**❌ Videos not accessible**
- Verify S3 bucket has public read access
- Check bucket policy and CORS settings
**❌ Upload timeouts**
- Large video files may timeout
- Check network connectivity to S3
- Consider video compression settings
## 🧹 **Maintenance**
### **Automatic Cleanup**
- Videos automatically deleted after **30 days**
- Lifecycle policy configured in S3 bucket
- No manual cleanup required
### **Cost Management**
- Only failed tests generate videos (~5-10 MB each)
- 30-day retention keeps costs low
- Monitor S3 usage in AWS console
## 🚀 **Next Steps**
1. **Run `setup-aws.sh`** to create infrastructure ✅
2. **Add GitHub secrets** from script output ⏳
3. **Test the system** by running a failing test ⏳
4. **Check Slack notifications** for video links ⏳
## 🔗 **File Structure**
```
cpk-demos-smoke-tests/
├── lib/
│ └── upload-video.ts # S3 upload functionality
├── reporters/
│ └── s3-video-reporter.ts # Playwright reporter
├── .github/workflows/
│ └── scheduled-tests.yml # AWS credentials setup
├── playwright.config.ts # Video recording config
├── slack-layout.ts # Video links in notifications
├── setup-aws.sh # AWS infrastructure script
└── VIDEO_SETUP.md # This file
```
## 📹 **Video URL Format**
```
https://{bucket}.s3.{region}.amazonaws.com/github-runs/{run-id}/{project}/{suite}/{test}/video-{timestamp}.webm
```
Example:
```
https://copilotkit-e2e-recordings.s3.us-east-1.amazonaws.com/github-runs/1234567890/cpk-demos-smoke-tests/Human-in-the-Loop-Feature/Chat-interaction-steps/video-20240115-143022.webm
```
**🎉 Your failed test videos are now automatically uploaded to S3 and linked in Slack!**
================================================
FILE: apps/dojo/e2e/clean-reporter.cjs
================================================
function getTimestamp() {
return (process.env.CI || process.env.VERBOSE)
? new Date().toLocaleTimeString('en-US', { hour12: false })
: '';
}
function logStamp(...args) {
console.log(getTimestamp(), ...args);
}
class CleanReporter {
onBegin(config, suite) {
console.log(`\n🎭 Running ${suite.allTests().length} tests...\n`);
}
onTestEnd(test, result) {
const suiteName = test.parent?.title || "Unknown";
const testName = test.title;
// Clean up suite name
const cleanSuite = suiteName
.replace(/Tests?$/i, "")
.replace(/Page$/i, "")
.replace(/([a-z])([A-Z])/g, "$1 $2")
.trim();
if (result.status === "passed") {
logStamp(`✅ PASS ${cleanSuite}: ${testName}`);
return;
}
if (result.status === "skipped") {
console.log(`⚠️ SKIP ${cleanSuite}: ${testName} (skipped)`);
return;
}
// Handle all failure modes: "failed", "timedOut", "interrupted"
const icon = result.status === "timedOut" ? "⏰ TIMEOUT" : "❌ FAIL";
logStamp(`${icon} ${cleanSuite}: ${testName}`);
// Extract the most relevant error info
const error = result.error || result.errors?.[0];
if (error) {
let errorMsg = error.message || "Unknown error";
// Clean up common error patterns to make them more readable
if (errorMsg.includes("None of the expected patterns matched")) {
const patterns = errorMsg.match(/patterns matched[^:]*: ([^`]+)/);
errorMsg = `AI response timeout - Expected: ${
patterns?.[1] || "AI response"
}`;
} else if (
errorMsg.includes("Timed out") &&
errorMsg.includes("toBeVisible")
) {
const element = errorMsg.match(/locator\('([^']+)'\)/);
errorMsg = `Element not found: ${element?.[1] || "UI element"}`;
} else if (errorMsg.includes("Test timeout of")) {
errorMsg = errorMsg.split("\n")[0];
} else if (errorMsg.includes("toBeGreaterThan")) {
errorMsg = "Expected content not generated (count was 0)";
}
// Show just the key error info
console.log(`💥 ERROR: ${errorMsg.split("\n")[0]}`);
// If it's an AI/API issue, make it clear
if (
errorMsg.includes("AI") ||
errorMsg.includes("patterns") ||
errorMsg.includes("timeout")
) {
console.log(` HINT: Likely cause: AI service down or API key issue`);
}
}
// Surface diagnostic output from test-isolation-helper on failure.
// This includes AI State Dump, NetworkError, PageError, and
// BrowserConsole lines that would otherwise be hidden by this reporter.
const diagnosticPrefixes = [
"[AI State Dump]",
"[NetworkError]",
"[PageError]",
"[BrowserConsole]",
"[Test Cleanup]",
"[User]",
"[Assistant]",
];
const stdout = (result.stdout || [])
.map((chunk) => (typeof chunk === "string" ? chunk : chunk.toString("utf-8")))
.join("");
const diagnosticLines = stdout
.split("\n")
.filter((line) => diagnosticPrefixes.some((p) => line.includes(p)));
if (diagnosticLines.length > 0) {
console.log(" --- Diagnostics ---");
for (const line of diagnosticLines) {
console.log(` ${line.trim()}`);
}
}
console.log(""); // Extra spacing after failures
}
onEnd(result) {
console.log("\n" + "=".repeat(60));
logStamp(`📊 TEST SUMMARY`);
console.log("=".repeat(60));
if (!process.env.CI) {
console.log(
`Run 'pnpm exec playwright show-report' for detailed HTML report`
);
}
console.log("=".repeat(60) + "\n");
}
}
module.exports = CleanReporter;
================================================
FILE: apps/dojo/e2e/featurePages/AgenticChatPage.ts
================================================
import { Page, Locator, expect } from "@playwright/test";
import { CopilotSelectors } from "../utils/copilot-selectors";
import { sendChatMessage, awaitLLMResponseDone } from "../utils/copilot-actions";
import { DEFAULT_WELCOME_MESSAGE } from "../lib/constants";
export class AgenticChatPage {
readonly page: Page;
readonly openChatButton: Locator;
readonly agentGreeting: Locator;
readonly chatInput: Locator;
readonly sendButton: Locator;
readonly agentMessage: Locator;
readonly userMessage: Locator;
constructor(page: Page) {
this.page = page;
this.openChatButton = CopilotSelectors.chatToggle(page);
this.agentGreeting = page
.getByText(DEFAULT_WELCOME_MESSAGE);
this.chatInput = CopilotSelectors.chatTextarea(page);
this.sendButton = CopilotSelectors.sendButton(page);
this.agentMessage = CopilotSelectors.assistantMessages(page);
this.userMessage = CopilotSelectors.userMessages(page);
}
async openChat() {
try {
await this.openChatButton.click({ timeout: 3000 });
} catch (error) {
// Chat might already be open
}
}
async sendMessage(message: string) {
await sendChatMessage(this.page, message);
await awaitLLMResponseDone(this.page);
}
async getGradientButtonByName(name: string | RegExp) {
return this.page.getByRole("button", { name });
}
async assertUserMessageVisible(text: string | RegExp) {
await expect(this.userMessage.getByText(text)).toBeVisible();
}
async assertAgentReplyVisible(expectedText: RegExp | RegExp[]) {
const expectedTexts = Array.isArray(expectedText) ? expectedText : [expectedText];
let lastError: unknown = null;
for (const pattern of expectedTexts) {
try {
const agentMessage = CopilotSelectors.assistantMessages(this.page).filter({
hasText: pattern
});
await expect(agentMessage.last()).toBeVisible();
return; // At least one pattern matched, succeed
} catch (error) {
lastError = error;
}
}
throw lastError; // No pattern matched
}
async assertAgentReplyContains(expectedText: string) {
const agentMessage = CopilotSelectors.assistantMessages(this.page).last();
await expect(agentMessage).toContainText(expectedText);
}
async getAssistantMessageText(index: number): Promise<string> {
const message = this.agentMessage.nth(index);
await expect(message).toBeVisible();
return (await message.textContent()) ?? "";
}
async regenerateResponse(index: number) {
const message = this.agentMessage.nth(index);
await expect(message).toBeVisible();
// Hover over the message to reveal the regenerate button
await message.hover();
const regenerateButton = message.getByTestId("copilot-regenerate-button");
try {
await regenerateButton.click({ timeout: 3000 });
} catch {
// If hover didn't reveal the button, force click
await regenerateButton.click({ force: true });
}
}
async assertWeatherResponseStructure() {
// The get_weather tool renders a deterministic component with data-testid="weather-info"
const weatherInfo = this.page.getByTestId("weather-info");
await expect(weatherInfo.last()).toBeVisible();
await expect(weatherInfo.last()).toContainText("Temperature:");
await expect(weatherInfo.last()).toContainText("Humidity:");
await expect(weatherInfo.last()).toContainText("Wind Speed:");
await expect(weatherInfo.last()).toContainText("Conditions:");
}
}
================================================
FILE: apps/dojo/e2e/featurePages/HumanInTheLoopPage.ts
================================================
import { Page, Locator, expect } from "@playwright/test";
import { CopilotSelectors } from "../utils/copilot-selectors";
import { sendAndAwaitResponse } from "../utils/copilot-actions";
import { DEFAULT_WELCOME_MESSAGE } from "../lib/constants";
export class HumanInTheLoopPage {
readonly page: Page;
readonly planTaskButton: Locator;
readonly chatInput: Locator;
readonly sendButton: Locator;
readonly agentGreeting: Locator;
readonly plan: Locator;
readonly performStepsButton: Locator;
readonly agentMessage: Locator;
readonly userMessage: Locator;
constructor(page: Page) {
this.page = page;
this.planTaskButton = page.getByRole("button", {
name: "Human in the loop Plan a task",
});
this.agentGreeting = page.getByText(DEFAULT_WELCOME_MESSAGE);
this.chatInput = CopilotSelectors.chatTextarea(page);
this.sendButton = CopilotSelectors.sendButton(page);
this.plan = page.getByTestId("select-steps");
this.performStepsButton = page.getByRole("button", { name: "Confirm" });
this.agentMessage = CopilotSelectors.assistantMessages(page);
this.userMessage = CopilotSelectors.userMessages(page);
}
async openChat() {
await expect(this.agentGreeting).toBeVisible();
}
async sendMessage(message: string) {
await sendAndAwaitResponse(this.page, message);
}
async selectItemsInPlanner() {
await expect(this.plan).toBeVisible();
await this.plan.click();
}
async getPlannerOnClick(name: string | RegExp) {
return this.page.getByRole("button", { name });
}
async uncheckItem(identifier: number | string): Promise<string> {
const plannerContainer = this.page.getByTestId("select-steps");
const items = plannerContainer.getByTestId("step-item");
let item;
if (typeof identifier === "number") {
item = items.nth(identifier);
} else {
item = items
.filter({
has: this.page
.getByTestId("step-text")
.filter({ hasText: identifier }),
})
.first();
}
const stepTextElement = item.getByTestId("step-text");
const text = await stepTextElement.innerText();
await item.click();
return text;
}
async isStepItemUnchecked(target: number | string): Promise<boolean> {
const plannerContainer = this.page.getByTestId("select-steps");
const items = plannerContainer.getByTestId("step-item");
let item;
if (typeof target === "number") {
item = items.nth(target);
} else {
item = items
.filter({
has: this.page.getByTestId("step-text").filter({ hasText: target }),
})
.first();
}
const checkbox = item.locator('input[type="checkbox"]');
return !(await checkbox.isChecked());
}
async performSteps() {
await this.performStepsButton.click();
await this.performStepsButton.waitFor({ state: "hidden" });
}
async performStepsAndAwait() {
const countBefore = await this.page
.locator('[data-testid="copilot-assistant-message"]')
.count();
await this.performStepsButton.click();
await this.performStepsButton.waitFor({ state: "hidden" });
await this.page.waitForFunction(
(before) =>
document.querySelectorAll('[data-testid="copilot-assistant-message"]')
.length > before,
countBefore,
{ timeout: 30000 },
);
await this.page.waitForFunction(
() => document.querySelector('[data-copilot-running="false"]') !== null,
null,
{ timeout: 60000 },
);
}
async assertAgentReplyVisible(expectedText: RegExp) {
await expect(
this.agentMessage.last().getByText(expectedText),
).toBeVisible();
}
async assertUserMessageVisible(message: string) {
await expect(this.page.getByText(message)).toBeVisible();
}
}
================================================
FILE: apps/dojo/e2e/featurePages/SharedStatePage.ts
================================================
import { Page, Locator, expect } from '@playwright/test';
import { CopilotSelectors } from '../utils/copilot-selectors';
import { sendChatMessage, awaitLLMResponseDone } from '../utils/copilot-actions';
import { DEFAULT_WELCOME_MESSAGE } from '../lib/constants';
export class SharedStatePage {
readonly page: Page;
readonly chatInput: Locator;
readonly sendButton: Locator;
readonly agentGreeting: Locator;
readonly agentMessage: Locator;
readonly userMessage: Locator;
readonly promptResponseLoader: Locator;
readonly ingredientCards: Locator;
readonly instructionsContainer: Locator;
readonly addIngredient: Locator;
constructor(page: Page) {
this.page = page;
this.agentGreeting = page.getByText(DEFAULT_WELCOME_MESSAGE);
this.chatInput = CopilotSelectors.chatTextarea(page);
this.sendButton = CopilotSelectors.sendButton(page);
this.promptResponseLoader = page.getByRole('button', { name: 'Please Wait...', disabled: true });
this.instructionsContainer = page.locator('.instructions-container');
this.addIngredient = page.getByRole('button', { name: '+ Add Ingredient' });
this.agentMessage = CopilotSelectors.assistantMessages(page);
this.userMessage = CopilotSelectors.userMessages(page);
this.ingredientCards = page.locator('.ingredient-card');
}
async openChat() {
await expect(this.agentGreeting).toBeVisible();
}
async sendMessage(message: string) {
await sendChatMessage(this.page, message);
await awaitLLMResponseDone(this.page);
}
async loader() {
// Wait for the LLM stream to finish using data-copilot-running
await awaitLLMResponseDone(this.page);
}
async awaitIngredientCard(name: string) {
// Use page.waitForFunction for case-insensitive matching on input values,
// since CSS attribute selectors are case-sensitive
await this.page.waitForFunction(
(ingredientName) => {
const inputs = document.querySelectorAll('.ingredient-card input.ingredient-name-input');
return Array.from(inputs).some(
(input: HTMLInputElement) => input.value.toLowerCase().includes(ingredientName.toLowerCase())
);
},
name,
{ timeout: 15000 }
);
}
async addNewIngredient(placeholderText: string) {
await this.addIngredient.click();
await expect(this.page.locator(`input[placeholder="${placeholderText}"]`)).toBeVisible();
}
async getInstructionItems(containerLocator: Locator ) {
const count = await containerLocator.locator('.instruction-item').count();
if (count <= 0) {
throw new Error('No instruction items found in the container.');
}
console.log(`✅ Found ${count} instruction items.`);
return count;
}
async assertAgentReplyVisible(expectedText: RegExp) {
await expect(this.agentMessage.getByText(expectedText)).toBeVisible();
}
async assertUserMessageVisible(message: string) {
await expect(this.page.getByText(message)).toBeVisible();
}
}
================================================
FILE: apps/dojo/e2e/featurePages/ToolBaseGenUIPage.ts
================================================
import { Page, Locator, expect } from "@playwright/test";
import { CopilotSelectors } from "../utils/copilot-selectors";
import { sendChatMessage, awaitLLMResponseDone } from "../utils/copilot-actions";
import { DEFAULT_WELCOME_MESSAGE } from "../lib/constants";
export class ToolBaseGenUIPage {
readonly page: Page;
readonly haikuAgentIntro: Locator;
readonly messageBox: Locator;
readonly sendButton: Locator;
readonly applyButton: Locator;
readonly haikuBlock: Locator;
readonly japaneseLines: Locator;
readonly mainHaikuDisplay: Locator;
constructor(page: Page) {
this.page = page;
this.haikuAgentIntro = page.getByText(DEFAULT_WELCOME_MESSAGE).first();
this.messageBox = CopilotSelectors.chatTextarea(page);
this.sendButton = CopilotSelectors.sendButton(page);
this.haikuBlock = page.locator('[data-testid="haiku-card"]');
this.applyButton = page.getByRole("button", { name: "Apply" });
this.japaneseLines = page.locator('[data-testid="haiku-japanese-line"]');
this.mainHaikuDisplay = page.locator('[data-testid="haiku-carousel"]');
}
async generateHaiku(message: string) {
await expect(this.messageBox).toBeVisible();
await sendChatMessage(this.page, message);
await awaitLLMResponseDone(this.page);
}
async checkGeneratedHaiku() {
const cards = this.page.locator('[data-testid="haiku-card"]');
await expect(cards.last()).toBeVisible();
const mostRecentCard = cards.last();
await expect(mostRecentCard
.locator('[data-testid="haiku-japanese-line"]')
.first()).toBeVisible();
}
async extractChatHaikuContent(page: Page): Promise<string> {
const allHaikuCards = page.locator('[data-testid="haiku-card"]');
await expect(allHaikuCards.first()).toBeVisible();
const cardCount = await allHaikuCards.count();
let chatHaikuContainer;
let chatHaikuLines;
for (let cardIndex = cardCount - 1; cardIndex >= 0; cardIndex--) {
chatHaikuContainer = allHaikuCards.nth(cardIndex);
chatHaikuLines = chatHaikuContainer.locator('[data-testid="haiku-japanese-line"]');
const linesCount = await chatHaikuLines.count();
if (linesCount > 0) {
try {
await expect(chatHaikuLines.first()).toBeVisible();
break;
} catch (error) {
continue;
}
}
}
if (!chatHaikuLines) {
throw new Error("No haiku cards with visible lines found");
}
const count = await chatHaikuLines.count();
const lines: string[] = [];
for (let i = 0; i < count; i++) {
const haikuLine = chatHaikuLines.nth(i);
const japaneseText = await haikuLine.innerText();
lines.push(japaneseText);
}
const chatHaikuContent = lines.join("").replace(/\s/g, "");
return chatHaikuContent;
}
async extractMainDisplayHaikuContent(page: Page): Promise<string> {
const carousel = page.locator('[data-testid="haiku-carousel"]');
await expect(carousel).toBeVisible();
// Find the visible carousel item (the active slide)
const carouselItems = carousel.locator('[data-testid^="carousel-item-"]');
const itemCount = await carouselItems.count();
let activeCard = null;
// Find the visible/active carousel item
for (let i = 0; i < itemCount; i++) {
const item = carouselItems.nth(i);
const isVisible = await item.isVisible();
if (isVisible) {
activeCard = item.locator('[data-testid="haiku-card"]');
break;
}
}
if (!activeCard) {
// Fallback to first card if none found visible
activeCard = carousel.locator('[data-testid="haiku-card"]').first();
}
const mainDisplayLines = activeCard.locator('[data-testid="haiku-japanese-line"]');
const mainCount = await mainDisplayLines.count();
const lines: string[] = [];
if (mainCount > 0) {
for (let i = 0; i < mainCount; i++) {
const haikuLine = mainDisplayLines.nth(i);
const japaneseText = await haikuLine.innerText();
lines.push(japaneseText);
}
}
const mainHaikuContent = lines.join("").replace(/\s/g, "");
return mainHaikuContent;
}
private async carouselIncludesHaiku(
page: Page,
chatHaikuContent: string,
): Promise<boolean> {
const carousel = page.locator('[data-testid="haiku-carousel"]');
if (!(await carousel.isVisible())) {
return false;
}
const allCarouselCards = carousel.locator('[data-testid="haiku-card"]');
const cardCount = await allCarouselCards.count();
for (let i = 0; i < cardCount; i++) {
const card = allCarouselCards.nth(i);
const lines = card.locator('[data-testid="haiku-japanese-line"]');
const lineCount = await lines.count();
const cardLines: string[] = [];
for (let j = 0; j < lineCount; j++) {
const text = await lines.nth(j).innerText();
cardLines.push(text);
}
const cardContent = cardLines.join("").replace(/\s/g, "");
if (cardContent === chatHaikuContent) {
return true;
}
}
return false;
}
async checkHaikuDisplay(page: Page): Promise<void> {
const chatHaikuContent = await this.extractChatHaikuContent(page);
await expect
.poll(
async () => this.carouselIncludesHaiku(page, chatHaikuContent),
{ timeout: 15000, intervals: [500, 1000, 2000] },
)
.toBe(true);
}
}
================================================
FILE: apps/dojo/e2e/featurePages/V1AgenticChatPage.ts
================================================
import { Page, Locator, expect } from "@playwright/test";
/**
* Page object for v1 CopilotKit chat UI.
*
* V1 uses CSS class selectors (copilotKitInput, copilotKitAssistantMessage, etc.)
* instead of the data-testid attributes used by v2.
*/
export class V1AgenticChatPage {
readonly page: Page;
readonly chatInput: Locator;
readonly sendButton: Locator;
readonly assistantMessages: Locator;
readonly userMessages: Locator;
constructor(page: Page) {
this.page = page;
this.chatInput = page.locator(".copilotKitInput textarea");
this.sendButton = page.locator(
'button[data-test-id="copilot-chat-ready"], button[data-test-id="copilot-chat-request-in-progress"]'
);
this.assistantMessages = page.locator(".copilotKitAssistantMessage");
this.userMessages = page.locator(".copilotKitUserMessage");
}
async waitForReady() {
await expect(this.chatInput).toBeVisible();
}
async sendMessage(message: string) {
await this.chatInput.click();
await this.chatInput.fill(message);
const sendBtn = this.page.locator(
'button[data-test-id="copilot-chat-ready"]'
);
await expect(sendBtn).toBeEnabled();
await sendBtn.click();
// Wait for LLM to finish: in-progress → done
await this.awaitLLMResponseDone();
}
async awaitLLMResponseDone(timeout = 30_000) {
// Wait for in-progress to start
try {
await this.page.waitForFunction(
() =>
document.querySelector(
'button[data-copilotkit-in-progress="true"]'
) !== null,
null,
{ timeout: 5000 }
);
} catch {
// May have already started and finished
}
// Wait for in-progress to end
await this.page.waitForFunction(
() =>
document.querySelector(
'button[data-copilotkit-in-progress="false"]'
) !== null ||
document.querySelector(
'button[data-test-id="copilot-chat-ready"]'
) !== null,
null,
{ timeout }
);
}
async assertUserMessageVisible(text: string) {
await expect(this.userMessages.getByText(text)).toBeVisible();
}
async assertAgentReplyVisible(pattern: RegExp) {
const message = this.assistantMessages.filter({ hasText: pattern });
await expect(message.last()).toBeVisible();
}
}
================================================
FILE: apps/dojo/e2e/fixtures/openai/agentic-chat.json
================================================
{
"fixtures": [
{
"match": { "userMessage": "I am duaa" },
"response": { "content": "Hello duaa! How can I assist you today?" }
},
{
"match": { "userMessage": "background color to blue" },
"response": {
"toolCalls": [
{
"name": "change_background",
"arguments": "{\"background\":\"blue\"}"
}
]
}
},
{
"match": { "userMessage": "background color to pink" },
"response": {
"toolCalls": [
{
"name": "change_background",
"arguments": "{\"background\":\"pink\"}"
}
]
}
},
{
"match": { "userMessage": "stock price of AAPL" },
"response": {
"content": "The current stock price of Apple Inc. (AAPL) is $150.25."
}
},
{
"match": { "userMessage": "capital of France" },
"response": { "content": "The capital of France is Paris." }
},
{
"match": { "userMessage": "What was my first question" },
"response": {
"content": "Your first question was about the capital of France."
}
},
{
"match": { "userMessage": "favorite fruit is Mango" },
"response": {
"content": "That's great! Mango is a wonderful tropical fruit known for its sweet, juicy flavor."
}
},
{
"match": { "userMessage": "listening to Kaavish" },
"response": {
"content": "Kaavish is a wonderful musical group known for their unique blend of Eastern and Western sounds!"
}
},
{
"match": { "userMessage": "fact about Moon" },
"response": {
"content": "The Moon is Earth's only natural satellite, orbiting at an average distance of about 384,400 km. It takes approximately 27.3 days to complete one orbit."
}
},
{
"match": { "userMessage": "remind me what my favorite fruit" },
"response": { "content": "Your favorite fruit is Mango!" }
},
{
"match": { "userMessage": "counting down" },
"response": {
"content": "counting down:\n10\n9\n8\n7\n6\n5\n4\n3\n2\n1\n\u2713"
}
},
{
"match": { "userMessage": "tell me a joke" },
"response": {
"content": "Why did the scarecrow win an award? Because he was outstanding in his field!"
}
},
{
"match": { "userMessage": "say hello" },
"response": { "content": "Hello there! Nice to chat with you." }
},
{
"match": { "userMessage": "Hey there" },
"response": { "content": "Hello! How can I assist you today?" }
},
{
"match": { "userMessage": "Hi" },
"response": { "content": "Hello! How can I assist you today?" }
},
{
"match": { "userMessage": "my name is Alex" },
"response": { "content": "Hello Alex! Nice to meet you. How can I help you today?" }
},
{
"match": { "userMessage": "What is my name" },
"response": { "content": "Your name is Alex!" }
}
]
}
================================================
FILE: apps/dojo/e2e/fixtures/openai/agentic-gen-ui.json
================================================
{
"fixtures": [
{
"match": { "userMessage": "plan to make brownies" },
"response": {
"toolCalls": [
{
"name": "generate_task_steps_generative_ui",
"arguments": "{\"steps\":[{\"description\":\"Gather ingredients: cocoa, butter, eggs, sugar, flour\",\"status\":\"pending\"},{\"description\":\"Melt butter and mix with cocoa and sugar\",\"status\":\"pending\"},{\"description\":\"Add eggs and flour, mix until smooth\",\"status\":\"pending\"},{\"description\":\"Pour into greased pan and bake at 350F for 25 minutes\",\"status\":\"pending\"}]}"
}
]
}
},
{
"match": { "userMessage": "Go to Mars" },
"response": {
"toolCalls": [
{
"name": "generate_task_steps_generative_ui",
"arguments": "{\"steps\":[{\"description\":\"Design and build a spacecraft capable of Mars transit\",\"status\":\"pending\"},{\"description\":\"Assemble crew and run mission simulations\",\"status\":\"pending\"},{\"description\":\"Launch from Earth and navigate to Mars\",\"status\":\"pending\"},{\"description\":\"Land on Mars surface and establish base camp\",\"status\":\"pending\"}]}"
}
]
}
},
{
"match": { "userMessage": "help" },
"response": {
"content": "Hello! I can help you with anything you need. Just tell me what you'd like to accomplish and I'll create a plan for you."
}
}
]
}
================================================
FILE: apps/dojo/e2e/fixtures/openai/backend-tool-rendering.json
================================================
{
"fixtures": [
{
"match": { "userMessage": "Weather in San Francisco" },
"response": {
"toolCalls": [
{
"name": "get_weather",
"arguments": "{\"location\":\"San Francisco\"}"
}
]
}
},
{
"match": { "userMessage": "Weather in New York" },
"response": {
"toolCalls": [
{
"name": "get_weather",
"arguments": "{\"location\":\"New York\"}"
}
]
}
},
{
"match": { "userMessage": "weather" },
"response": {
"toolCalls": [
{
"name": "get_weather",
"arguments": "{\"location\":\"San Francisco\"}"
}
]
}
}
]
}
================================================
FILE: apps/dojo/e2e/fixtures/openai/human-in-the-loop.json
================================================
{
"fixtures": [
{
"match": { "userMessage": "one step with eggs" },
"response": {
"toolCalls": [
{
"name": "generate_task_steps",
"arguments": "{\"steps\":[{\"description\":\"Crack eggs into bowl\",\"status\":\"enabled\"},{\"description\":\"Preheat oven to 350F\",\"status\":\"enabled\"},{\"description\":\"Mix and bake for 25 min\",\"status\":\"enabled\"}]}"
}
]
}
},
{
"match": { "userMessage": "Does the planner include" },
"response": { "content": "No" }
},
{
"match": { "userMessage": "Start The Planning" },
"response": {
"toolCalls": [
{
"name": "generate_task_steps",
"arguments": "{\"steps\":[{\"description\":\"Start The Planning\",\"status\":\"enabled\"},{\"description\":\"Design spacecraft\",\"status\":\"enabled\"},{\"description\":\"Launch mission\",\"status\":\"enabled\"}]}"
}
]
}
},
{
"match": { "userMessage": "trip to mars" },
"response": {
"toolCalls": [
{
"name": "generate_task_steps",
"arguments": "{\"steps\":[{\"description\":\"Research mission requirements\",\"status\":\"enabled\"},{\"description\":\"Assemble crew\",\"status\":\"enabled\"},{\"description\":\"Build spacecraft\",\"status\":\"enabled\"},{\"description\":\"Launch from Earth\",\"status\":\"enabled\"},{\"description\":\"Land on Mars\",\"status\":\"enabled\"}]}"
}
]
}
}
]
}
================================================
FILE: apps/dojo/e2e/fixtures/openai/predictive-state.json
================================================
{
"fixtures": [
{
"match": { "userMessage": "dragon called Atlantis" },
"response": {
"toolCalls": [
{
"name": "write_document_local",
"arguments": "{\"document\":\"Once upon a time, in a land far away, there lived a magnificent dragon named Atlantis. Atlantis was known throughout the realm for its shimmering scales that reflected the light of a thousand stars. The dragon Atlantis would soar above the mountains, breathing fire that lit up the night sky. Villagers would gather to watch Atlantis perform its aerial dances, marveling at the grace of this ancient creature.\"}"
}
]
}
},
{
"match": { "userMessage": "Change dragon name to Lola" },
"response": {
"toolCalls": [
{
"name": "write_document_local",
"arguments": "{\"document\":\"Once upon a time, in a land far away, there lived a magnificent dragon named Lola. Lola was known throughout the realm for its shimmering scales that reflected the light of a thousand stars. The dragon Lola would soar above the mountains, breathing fire that lit up the night sky. Villagers would gather to watch Lola perform its aerial dances, marveling at the grace of this ancient creature.\"}"
}
]
}
}
]
}
================================================
FILE: apps/dojo/e2e/fixtures/openai/shared-state.json
================================================
{
"fixtures": [
{
"match": { "userMessage": "pasta recipe" },
"response": {
"toolCalls": [
{
"name": "updateWorkingMemory",
"arguments": "{\"memory\":{\"recipe\":{\"skill_level\":\"Intermediate\",\"special_preferences\":[],\"cooking_time\":\"45 min\",\"ingredients\":[{\"icon\":\"🍝\",\"name\":\"Pasta\",\"amount\":\"400g\"},{\"icon\":\"🧂\",\"name\":\"Salt\",\"amount\":\"1 tsp\"},{\"icon\":\"🫒\",\"name\":\"Olive Oil\",\"amount\":\"4 tbsp\"},{\"icon\":\"🧄\",\"name\":\"Garlic\",\"amount\":\"6 cloves\"},{\"icon\":\"🍅\",\"name\":\"Tomatoes\",\"amount\":\"2 cups\"}],\"instructions\":[\"Boil water and cook pasta until al dente\",\"Slice garlic thinly and sauté in olive oil\",\"Dice tomatoes and add to the pan\",\"Season with salt to taste\",\"Toss pasta with the sauce and serve\"]}}}"
}
]
}
},
{
"match": { "userMessage": "the ingredients" },
"response": {
"content": "Here are the ingredients:\n- Pasta: 400g\n- Salt: 1 tsp\n- Olive Oil: 4 tbsp\n- Garlic: 6 cloves\n- Tomatoes: 2 cups\n- Potatoes: 12\n- Carrots: 3\n- All-Purpose Flour: 2 cups"
}
}
]
}
================================================
FILE: apps/dojo/e2e/fixtures/openai/subgraphs.json
================================================
{
"fixtures": []
}
================================================
FILE: apps/dojo/e2e/fixtures/openai/tool-based-gen-ui.json
================================================
{
"fixtures": [
{
"match": { "userMessage": "I will always win" },
"response": {
"toolCalls": [
{
"name": "generate_haiku",
"arguments": "{\"japanese\":[\"勝利の道を\",\"常に歩み続ける\",\"勝つ運命よ\"],\"english\":[\"On the path of victory\",\"I will always keep walking\",\"Destined to always win\"],\"image_name\":\"Mount_Fuji_Lake_Reflection_Cherry_Blossoms_Sakura_Spring.jpg\",\"gradient\":\"linear-gradient(135deg, #667eea 0%, #764ba2 100%)\"}"
}
]
}
},
{
"match": { "userMessage": "moon shines bright" },
"response": {
"toolCalls": [
{
"name": "generate_haiku",
"arguments": "{\"japanese\":[\"月が輝く\",\"夜空に静かに浮かぶ\",\"光の詩よ\"],\"english\":[\"The bright moon shining\",\"Floating quietly in night sky\",\"A poem of light\"],\"image_name\":\"Cherry_Blossoms_Sakura_Night_View_City_Lights_Japan.jpg\",\"gradient\":\"linear-gradient(135deg, #0c3547 0%, #204f64 50%, #2d6187 100%)\"}"
}
]
}
}
]
}
================================================
FILE: apps/dojo/e2e/fixtures/openai/v1-chat.json
================================================
{
"fixtures": [
{
"match": { "userMessage": "Hello" },
"response": { "content": "Hello! How can I help you today?" }
}
]
}
================================================
FILE: apps/dojo/e2e/lib/constants.ts
================================================
/**
* The default welcome message shown by CopilotChat/CopilotSidebar when no
* custom `welcomeMessageText` label is provided. Update this single constant
* if the default ever changes—all e2e page objects reference it.
*/
export const DEFAULT_WELCOME_MESSAGE =
"How can I help you today?";
================================================
FILE: apps/dojo/e2e/lib/mock-agent.ts
================================================
import { Page, Route } from "@playwright/test";
/**
* Deterministic mock agent for Playwright e2e tests.
*
* Intercepts CopilotKit API calls at the browser level and returns
* pre-defined SSE responses. This allows testing UI behavior (background
* color changes, regenerate, shared state) without depending on live LLM
* responses, eliminating the primary source of test flakiness.
*
* Usage:
* const mock = new MockAgent(page);
* mock.onMessage("background color to blue",
* mock.toolCall("change_background", { background: "blue" })
* );
* await mock.install();
* // ... run test ...
* await mock.uninstall();
*/
// AG-UI event types used in SSE responses
interface SSEEvent {
type: string;
[key: string]: unknown;
}
type ResponseSequence = SSEEvent[];
interface MessageHandler {
pattern: string | RegExp;
responses: ResponseSequence;
once: boolean;
used: boolean;
}
const ROUTE_PATTERN = /\/api\/copilotkit(next)?\/[^/]+/;
export class MockAgent {
private page: Page;
private handlers: MessageHandler[] = [];
private fallbackResponse: ResponseSequence | null = null;
private installed = false;
private routeHandler: ((route: Route) => Promise<void>) | null = null;
private runCounter = 0;
private messageCounter = 0;
private toolCallCounter = 0;
constructor(page: Page) {
this.page = page;
}
private nextRunId() {
return `mock-run-${++this.runCounter}`;
}
private nextMessageId() {
return `mock-msg-${++this.messageCounter}`;
}
private nextToolCallId() {
return `mock-tc-${++this.toolCallCounter}`;
}
/**
* Register a response for messages matching a pattern.
*/
onMessage(
pattern: string | RegExp,
responses: ResponseSequence,
options: { once?: boolean } = {}
): this {
this.handlers.push({
pattern,
responses,
once: options.once ?? false,
used: false,
});
return this;
}
/**
* Set a fallback response for unmatched messages.
*/
onAnyMessage(responses: ResponseSequence): this {
this.fallbackResponse = responses;
return this;
}
/**
* Install the route interceptor. Call before page.goto().
*/
async install(): Promise<void> {
if (this.installed) return;
this.routeHandler = async (route: Route) => {
const request = route.request();
// Only intercept POST requests (SSE streams)
if (request.method() !== "POST") {
await route.continue();
return;
}
try {
let body: string;
try {
body = request.postData() ?? "";
} catch (err) {
console.warn("[MockAgent] Failed to read postData():", err instanceof Error ? err.message : err);
body = "";
}
// Find the user's last message in the request body.
// If there's no user message (e.g. CopilotKit initialization request),
// pass through to the real backend so the app can boot normally.
const lastUserMessage = this.extractLastUserMessage(body);
if (lastUserMessage === null) {
await route.continue();
return;
}
const responses = this.findResponse(lastUserMessage);
const sseBody = responses
.map((event) => `data: ${JSON.stringify(event)}\n\n`)
.join("");
await route.fulfill({
status: 200,
headers: {
"Content-Type": "text/event-stream",
"Cache-Control": "no-cache",
Connection: "keep-alive",
},
body: sseBody,
});
} catch (err) {
console.error("[MockAgent] Route handler error:", err instanceof Error ? err.message : err);
await route.abort("failed").catch(() => {});
}
};
await this.page.route(ROUTE_PATTERN, this.routeHandler);
this.installed = true;
}
/**
* Remove the route interceptor.
*/
async uninstall(): Promise<void> {
if (!this.installed || !this.routeHandler) return;
await this.page.unroute(ROUTE_PATTERN, this.routeHandler);
this.routeHandler = null;
this.installed = false;
}
private extractLastUserMessage(body: string): string | null {
try {
const parsed = JSON.parse(body);
// CopilotKit v2 format: { body: { messages: [...] } }
const messages =
parsed?.body?.messages ?? parsed?.messages ?? [];
for (let i = messages.length - 1; i >= 0; i--) {
if (messages[i]?.role === "user") {
// Content can be a string or array of content parts
const content = messages[i].content;
if (typeof content === "string") return content;
if (Array.isArray(content)) {
const textPart = content.find(
(p: { type: string; text?: string }) => p.type === "text"
);
return textPart?.text ?? "";
}
return ""; // user message exists but content shape is unrecognized
}
}
} catch {
// Not JSON or unexpected format
}
return null; // no user message found — likely an init request
}
private findResponse(userMessage: string): ResponseSequence {
for (const handler of this.handlers) {
if (handler.once && handler.used) continue;
const matches =
typeof handler.pattern === "string"
? userMessage.toLowerCase().includes(handler.pattern.toLowerCase())
: handler.pattern.test(userMessage);
if (matches) {
if (handler.once) handler.used = true;
return handler.responses;
}
}
if (this.fallbackResponse) {
return this.fallbackResponse;
}
// Default: simple acknowledgment with stable IDs
return [
{ type: "RUN_STARTED", runId: "mock-run-default", threadId: "mock-thread" },
{ type: "TEXT_MESSAGE_START", messageId: "mock-msg-default", role: "assistant" },
{ type: "TEXT_MESSAGE_CONTENT", messageId: "mock-msg-default", delta: "I understand. How can I help?" },
{ type: "TEXT_MESSAGE_END", messageId: "mock-msg-default" },
{ type: "RUN_FINISHED", runId: "mock-run-default", threadId: "mock-thread" },
];
}
// ── Instance helpers for building response sequences ──
/**
* Build a text message response sequence.
*/
textMessage(
text: string,
options: { runId?: string; messageId?: string } = {}
): ResponseSequence {
const runId = options.runId ?? this.nextRunId();
const messageId = options.messageId ?? this.nextMessageId();
const threadId = "mock-thread";
return [
{ type: "RUN_STARTED", runId, threadId },
{ type: "TEXT_MESSAGE_START", messageId, role: "assistant" },
{ type: "TEXT_MESSAGE_CONTENT", messageId, delta: text },
{ type: "TEXT_MESSAGE_END", messageId },
{ type: "RUN_FINISHED", runId, threadId },
];
}
/**
* Build a frontend tool call response sequence.
*
* For frontend tools (registered via useFrontendTool), CopilotKit uses a
* multi-run pattern:
* Run 1: Server sends TOOL_CALL events (no TOOL_CALL_RESULT) + RUN_FINISHED
* Client: CopilotKit detects the unresolved tool call, executes the
* frontend handler locally, then makes a follow-up request.
* Run 2: Server responds with text (handled by fallback or another handler).
*
* IMPORTANT: Do NOT include TOOL_CALL_RESULT in the response — that tells
* CopilotKit the tool was already executed server-side and it will skip
* calling the frontend handler. Use { once: true } on the handler so the
* follow-up request falls through to the fallback.
*/
toolCall(
toolName: string,
args: Record<string, unknown>,
options: {
runId?: string;
} = {}
): ResponseSequence {
const runId = options.runId ?? this.nextRunId();
const toolParentMessageId = this.nextMessageId();
const toolCallId = this.nextToolCallId();
const threadId = "mock-thread";
return [
{ type: "RUN_STARTED", runId, threadId },
{
type: "TOOL_CALL_START",
toolCallId,
toolCallName: toolName,
parentMessageId: toolParentMessageId,
},
{
type: "TOOL_CALL_ARGS",
toolCallId,
delta: JSON.stringify(args),
},
{ type: "TOOL_CALL_END", toolCallId },
{ type: "RUN_FINISHED", runId, threadId },
];
}
/**
* Concatenate multiple response sequences into one.
*/
static combine(...sequences: ResponseSequence[]): ResponseSequence {
return sequences.flat();
}
}
================================================
FILE: apps/dojo/e2e/lib/upload-video.ts
================================================
import { S3Client, PutObjectCommand } from "@aws-sdk/client-s3";
import { readFileSync, existsSync } from "fs";
import { basename } from "path";
export interface VideoToUpload {
videoPath: string;
s3ObjectPath: string;
testName: string;
suiteName?: string;
}
export interface S3Config {
bucketName: string;
region: string;
accessKeyId?: string;
secretAccessKey?: string;
}
export class S3VideoUploader {
private s3Client: S3Client;
private config: S3Config;
constructor(config: S3Config) {
this.config = config;
// Initialize S3 client with credentials from environment or passed config
this.s3Client = new S3Client({
region: config.region,
credentials:
config.accessKeyId && config.secretAccessKey
? {
accessKeyId: config.accessKeyId,
secretAccessKey: config.secretAccessKey,
}
: undefined, // Use default credential chain if not provided
});
}
/**
* Generate S3 object path for a video file
*/
generateS3Path(
videoPath: string,
testName: string,
suiteName?: string
): string {
const filename = basename(videoPath);
const runId = process.env.GITHUB_RUN_ID || `local-${Date.now()}`;
const projectName =
process.env.GITHUB_REPOSITORY?.split("/")[1] || "cpk-demos-smoke-tests";
// Clean test names for file paths
const cleanSuite =
suiteName?.replace(/[^a-zA-Z0-9-_]/g, "-") || "unknown-suite";
const cleanTest = testName.replace(/[^a-zA-Z0-9-_]/g, "-");
return `github-runs/${runId}/${projectName}/${cleanSuite}/${cleanTest}/${filename}`;
}
/**
* Generate public S3 URL for a given object path
*/
generatePublicUrl(s3ObjectPath: string): string {
return `https://${this.config.bucketName}.s3.${this.config.region}.amazonaws.com/${s3ObjectPath}`;
}
/**
* Upload a single video file to S3
*/
async uploadVideo(video: VideoToUpload): Promise<string> {
try {
// Check if file exists
if (!existsSync(video.videoPath)) {
throw new Error(`Video file not found: ${video.videoPath}`);
}
console.log(
`📹 Uploading video: ${basename(video.videoPath)} for test: ${
video.testName
}`
);
// Read file content
const fileContent = readFileSync(video.videoPath);
// Upload to S3
const command = new PutObjectCommand({
Bucket: this.config.bucketName,
Key: video.s3ObjectPath,
Body: fileContent,
ContentType: "video/webm",
CacheControl: "public, max-age=86400", // Cache for 1 day
Metadata: {
"test-name": video.testName,
"suite-name": video.suiteName || "unknown",
"upload-time": new Date().toISOString(),
},
});
await this.s3Client.send(command);
const publicUrl = this.generatePublicUrl(video.s3ObjectPath);
console.log(`✅ Video uploaded successfully: ${publicUrl}`);
return publicUrl;
} catch (error) {
console.error(`❌ Failed to upload video ${video.videoPath}:`, error);
throw error;
}
}
/**
* Upload multiple videos concurrently
*/
async uploadVideos(
videos: VideoToUpload[]
): Promise<{ url: string; testName: string; suiteName?: string }[]> {
if (videos.length === 0) {
console.log("📹 No videos to upload");
return [];
}
console.log(`📹 Uploading ${videos.length} video(s) to S3...`);
const uploadPromises = videos.map(async (video) => {
try {
const url = await this.uploadVideo(video);
return {
url,
testName: video.testName,
suiteName: video.suiteName,
};
} catch (error) {
console.error(
`Failed to upload video for test ${video.testName}:`,
error
);
return null;
}
});
const results = await Promise.allSettled(uploadPromises);
// Filter out failed uploads
const successfulUploads = results
.filter(
(
result
): result is PromiseFulfilledResult<{
url: string;
testName: string;
suiteName?: string;
} | null> => result.status === "fulfilled" && result.value !== null
)
.map((result) => result.value!);
const failedUploads = results.filter(
(result) => result.status === "rejected"
).length;
console.log(`✅ Successfully uploaded ${successfulUploads.length} videos`);
if (failedUploads > 0) {
console.warn(`⚠️ ${failedUploads} videos failed to upload`);
}
return successfulUploads;
}
}
/**
* Factory function to create uploader with environment variables
*/
export function createS3Uploader(): S3VideoUploader | null {
const bucketName = process.env.AWS_S3_BUCKET_NAME;
const region = process.env.AWS_S3_REGION || "us-east-1";
if (!bucketName) {
console.warn("⚠️ AWS_S3_BUCKET_NAME not set, video upload disabled");
return null;
}
return new S3VideoUploader({
bucketName,
region,
accessKeyId: process.env.AWS_ACCESS_KEY_ID,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
});
}
================================================
FILE: apps/dojo/e2e/llmock-setup.ts
================================================
import { LLMock, type ChatMessage } from "@copilotkit/llmock";
import * as path from "node:path";
const MOCK_PORT = 5555;
const FIXTURES_DIR = path.join(import.meta.dirname, "fixtures", "openai");
let mockServer: LLMock | null = null;
export async function setupLLMock(): Promise<void> {
console.log("🔧 Starting LLMock server...");
// Small per-chunk latency prevents crew-ai's asyncio event loop from
// getting congested by zero-latency streaming (real OpenAI has natural
// network delays between chunks; LLMock needs to simulate this).
mockServer = new LLMock({ port: MOCK_PORT, latency: 5 });
// Extract text from message content — handles both string and array-of-parts
// (Strands SDK sends content as [{type: "text", text: "..."}])
const textOf = (content: ChatMessage["content"] | undefined): string => {
if (typeof content === "string") return content;
if (Array.isArray(content)) {
return content
.filter((p) => p.type === "text" && typeof p.text === "string")
.map((p) => p.text!)
.join("");
}
return "";
};
// LangGraph HITL: the LangGraph agent registers tool `plan_execution_steps`,
// not `generate_task_steps`. The JSON fixture returns `generate_task_steps`
// which CopilotKit's useHumanInTheLoop() handles (wrong UI: Confirm/Reject).
// LangGraph needs the correct tool name so chatNode routes to processStepsNode,
// which calls interrupt() and triggers useLangGraphInterrupt() (correct UI:
// Perform Steps). These predicate fixtures MUST come before loadFixtureFile.
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasLangGraphTool = req.tools?.some(
(t) => t.function.name === "plan_execution_steps",
);
return (
!!hasLangGraphTool &&
textOf(lastUser?.content).includes("one step with eggs")
);
},
},
response: {
toolCalls: [
{
name: "plan_execution_steps",
arguments: JSON.stringify({
steps: [
{ description: "Crack eggs into bowl", status: "enabled" },
{ description: "Preheat oven to 350F", status: "enabled" },
{ description: "Mix and bake for 25 min", status: "enabled" },
],
}),
},
],
},
});
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasLangGraphTool = req.tools?.some(
(t) => t.function.name === "plan_execution_steps",
);
return (
!!hasLangGraphTool &&
textOf(lastUser?.content).includes("Start The Planning")
);
},
},
response: {
toolCalls: [
{
name: "plan_execution_steps",
arguments: JSON.stringify({
steps: [
{ description: "Start The Planning", status: "enabled" },
{ description: "Design spacecraft", status: "enabled" },
{ description: "Launch mission", status: "enabled" },
],
}),
},
],
},
});
// Claude Agent SDK HITL: same pattern as LangGraph above. The CLI registers
// tools as mcp__ag_ui__generate_task_steps. The JSON fixture returns bare
// generate_task_steps which the TS CLI resolves, but the Python CLI needs the
// exact MCP-prefixed name. These predicate fixtures fire before the JSON ones.
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasClaudeSdkTool = req.tools?.some(
(t) => t.function.name.endsWith("__generate_task_steps"),
);
return (
!!hasClaudeSdkTool &&
textOf(lastUser?.content).includes("one step with eggs")
);
},
},
response: {
toolCalls: [
{
name: "mcp__ag_ui__generate_task_steps",
arguments: JSON.stringify({
steps: [
{ description: "Crack eggs into bowl", status: "enabled" },
{ description: "Preheat oven to 350F", status: "enabled" },
{ description: "Mix and bake for 25 min", status: "enabled" },
],
}),
},
],
},
});
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasClaudeSdkTool = req.tools?.some(
(t) => t.function.name.endsWith("__generate_task_steps"),
);
return (
!!hasClaudeSdkTool &&
textOf(lastUser?.content).includes("Start The Planning")
);
},
},
response: {
toolCalls: [
{
name: "mcp__ag_ui__generate_task_steps",
arguments: JSON.stringify({
steps: [
{ description: "Start The Planning", status: "enabled" },
{ description: "Design spacecraft", status: "enabled" },
{ description: "Launch mission", status: "enabled" },
],
}),
},
],
},
});
// Load HITL fixtures — they share a "plan to make brownies" substring
// with agentic-gen-ui fixtures, and first-match-wins. By loading HITL first,
// "one step with eggs" matches HITL tests before "plan to make brownies"
// matches the agenticGenUI fixture (which returns the wrong tool name).
// NOTE: LangGraph and Claude SDK predicate fixtures above take priority
// over these for requests containing their specific tool names.
mockServer.loadFixtureFile(path.join(FIXTURES_DIR, "human-in-the-loop.json"));
const sysContent = (msgs: ChatMessage[]) =>
msgs.find((m) => m.role === "system")?.content ?? "";
// Case-insensitive check for system prompt content — Python booleans are
// True/False (capitalized) while JavaScript uses true/false (lowercase).
const sysIncludes = (msgs: ChatMessage[], substr: string) => {
const sys =
typeof sysContent(msgs) === "string" ? (sysContent(msgs) as string) : "";
return sys.toLowerCase().includes(substr.toLowerCase());
};
const supervisorRoute = (nextAgent: string, answer: string) => ({
response: {
toolCalls: [
{
name: "supervisor_response",
arguments: JSON.stringify({ answer, next_agent: nextAgent }),
},
],
},
});
// Supervisor: no flights yet → route to flights_agent
mockServer.addFixture({
match: {
predicate: (req) =>
sysIncludes(req.messages, "Flights found: false"),
},
...supervisorRoute("flights_agent", "Let me find flights for you!"),
});
// Supervisor: flights found, no hotels → route to hotels_agent
mockServer.addFixture({
match: {
predicate: (req) =>
sysIncludes(req.messages, "Flights found: true") &&
sysIncludes(req.messages, "Hotels found: false"),
},
...supervisorRoute(
"hotels_agent",
"Great choice! Now let me find hotels for you.",
),
});
// Supervisor: flights + hotels done, experiences not yet → route to experiences_agent
// NOTE: state.experiences has no default (undefined), so hasExperiences is always "true"
// in the system prompt. We distinguish by checking if the experiences agent's
// response text is already in the messages.
mockServer.addFixture({
match: {
predicate: (req) => {
const experiencesDone = req.messages.some(
(m) =>
m.role === "assistant" &&
textOf(m.content).includes("wonderful experiences"),
);
return (
sysIncludes(req.messages, "Hotels found: true") && !experiencesDone
);
},
},
...supervisorRoute(
"experiences_agent",
"Excellent! Now let me find some experiences for you.",
),
});
// Supervisor: all agents completed → route to complete
mockServer.addFixture({
match: {
predicate: (req) => {
const experiencesDone = req.messages.some(
(m) =>
m.role === "assistant" &&
textOf(m.content).includes("wonderful experiences"),
);
return (
sysIncludes(req.messages, "Hotels found: true") && experiencesDone
);
},
},
...supervisorRoute("complete", "Your travel plan is all set!"),
});
// Experiences agent's own ChatOpenAI call — returns generic text
mockServer.addFixture({
match: {
predicate: (req) =>
sysIncludes(req.messages, "You are the experiences agent"),
},
response: {
content:
"I've found some wonderful experiences for your trip to San Francisco!",
},
});
// Strands agentic gen UI: the Strands agent registers plan_task_steps,
// not generate_task_steps_generative_ui. Predicate fixtures detect the
// Strands tool name in the request and return the correct tool call.
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasStrandsTool = req.tools?.some(
(t) => t.function.name === "plan_task_steps",
);
return (
!!hasStrandsTool &&
textOf(lastUser?.content).includes("plan to make brownies")
);
},
},
response: {
toolCalls: [
{
name: "plan_task_steps",
arguments: JSON.stringify({
task: "make brownies",
context: "",
steps: [
{ description: "Gather ingredients", status: "pending" },
{
description: "Melt butter and mix with cocoa",
status: "pending",
},
{ description: "Add eggs and flour", status: "pending" },
{ description: "Bake at 350F for 25 min", status: "pending" },
],
}),
},
],
},
});
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasStrandsTool = req.tools?.some(
(t) => t.function.name === "plan_task_steps",
);
return (
!!hasStrandsTool && textOf(lastUser?.content).includes("Go to Mars")
);
},
},
response: {
toolCalls: [
{
name: "plan_task_steps",
arguments: JSON.stringify({
task: "Go to Mars",
context: "",
steps: [
{ description: "Design spacecraft", status: "pending" },
{ description: "Assemble crew", status: "pending" },
{ description: "Launch from Earth", status: "pending" },
{ description: "Land on Mars", status: "pending" },
],
}),
},
],
},
});
// Shared state: ADK/Strands use generate_recipe (not updateWorkingMemory).
// The JSON fixture in shared-state.json returns updateWorkingMemory which
// only works for CopilotKit frameworks (Agno/LangGraph). These predicate
// fixtures fire first for ADK and Strands (which both register generate_recipe).
const recipeData = {
title: "Pasta Aglio e Olio",
skill_level: "Intermediate",
special_preferences: [] as string[],
cooking_time: "45 min",
ingredients: [
{ icon: "🍝", name: "Pasta", amount: "400g" },
{ icon: "🧂", name: "Salt", amount: "1 tsp" },
{ icon: "🫒", name: "Olive Oil", amount: "4 tbsp" },
{ icon: "🧄", name: "Garlic", amount: "6 cloves" },
{ icon: "🍅", name: "Tomatoes", amount: "2 cups" },
],
instructions: [
"Boil water and cook pasta until al dente",
"Slice garlic thinly and sauté in olive oil",
"Dice tomatoes and add to the pan",
"Season with salt to taste",
"Toss pasta with the sauce and serve",
],
changes: "",
};
// Strands/CrewAI/LangGraph: generate_recipe(recipe: Recipe) — nested {recipe: {...}} args.
// These frameworks wrap recipe data under a "recipe" key. Discriminate from ADK
// (flat args) via two signals: (1) tool schema has parameters.properties.recipe
// (available in OpenAI-format requests), or (2) system prompt contains
// "helpful recipe assistant" (Strands — whose Gemini SDK omits parameter
// schemas from functionDeclarations).
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const recipeTool = req.tools?.find(
(t) => t.function.name === "generate_recipe",
);
const hasNestedRecipeParam = !!(
(recipeTool?.function.parameters as Record<string, unknown>)
?.properties as Record<string, unknown>
)?.recipe;
return (
!!recipeTool &&
(hasNestedRecipeParam ||
sysIncludes(req.messages, "helpful recipe assistant")) &&
textOf(lastUser?.content).includes("pasta recipe")
);
},
},
response: {
toolCalls: [
{
name: "generate_recipe",
arguments: JSON.stringify({ recipe: recipeData }),
},
],
},
});
// ADK: generate_recipe(skill_level, title, ...) — flat argument format.
// Falls through when neither tool schema nor system prompt indicates nested args.
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const recipeTool = req.tools?.find(
(t) => t.function.name === "generate_recipe",
);
const hasNestedRecipeParam = !!(
(recipeTool?.function.parameters as Record<string, unknown>)
?.properties as Record<string, unknown>
)?.recipe;
return (
!!recipeTool &&
!hasNestedRecipeParam &&
!sysIncludes(req.messages, "helpful recipe assistant") &&
textOf(lastUser?.content).includes("pasta recipe")
);
},
},
response: {
toolCalls: [
{ name: "generate_recipe", arguments: JSON.stringify(recipeData) },
],
},
});
// Pydantic AI shared state: the agent registers display_recipe,
// not updateWorkingMemory. The Recipe model differs from ADK/Strands
// (no title/changes fields, StrEnum values for skill_level/cooking_time).
// IMPORTANT: pydantic-ai's single_arg_name optimization means a tool with
// one model-like parameter (e.g. display_recipe(recipe: Recipe)) uses the
// model's schema directly as the tool JSON schema — so the arguments must
// be the Recipe fields at the top level, NOT wrapped in {"recipe": {...}}.
const pydanticRecipeData = {
skill_level: "Intermediate",
special_preferences: [] as string[],
cooking_time: "45 min",
ingredients: [
{ icon: "🍝", name: "Pasta", amount: "400g" },
{ icon: "🧂", name: "Salt", amount: "1 tsp" },
{ icon: "🫒", name: "Olive Oil", amount: "4 tbsp" },
{ icon: "🧄", name: "Garlic", amount: "6 cloves" },
{ icon: "🍅", name: "Tomatoes", amount: "2 cups" },
],
instructions: [
"Boil water and cook pasta until al dente",
"Slice garlic thinly and sauté in olive oil",
"Dice tomatoes and add to the pan",
"Season with salt to taste",
"Toss pasta with the sauce and serve",
],
};
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasPydanticTool = req.tools?.some(
(t) => t.function.name === "display_recipe",
);
return (
!!hasPydanticTool &&
textOf(lastUser?.content).includes("pasta recipe")
);
},
},
response: {
toolCalls: [
{
name: "display_recipe",
arguments: JSON.stringify(pydanticRecipeData),
},
],
},
});
// Pydantic AI agentic gen UI: the agent registers create_plan,
// not generate_task_steps_generative_ui. Predicate fixtures detect the
// Pydantic AI tool name and return the correct tool call.
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasPydanticTool = req.tools?.some(
(t) => t.function.name === "create_plan",
);
return (
!!hasPydanticTool &&
textOf(lastUser?.content).includes("plan to make brownies")
);
},
},
response: {
toolCalls: [
{
name: "create_plan",
arguments: JSON.stringify({
steps: [
"Gather ingredients",
"Melt butter and mix with cocoa",
"Add eggs and flour",
"Bake at 350F for 25 min",
],
}),
},
],
},
});
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasPydanticTool = req.tools?.some(
(t) => t.function.name === "create_plan",
);
return (
!!hasPydanticTool && textOf(lastUser?.content).includes("Go to Mars")
);
},
},
response: {
toolCalls: [
{
name: "create_plan",
arguments: JSON.stringify({
steps: [
"Design spacecraft",
"Assemble crew",
"Launch from Earth",
"Land on Mars",
],
}),
},
],
},
});
// Langroid agentic gen UI: Langroid embeds tool definitions in the system
// message text (TOOL: create_plan) instead of using the OpenAI tools array.
// Detect via system message content since req.tools will be empty.
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasLangroidTool = sysIncludes(req.messages, "TOOL: create_plan");
return (
!!hasLangroidTool &&
textOf(lastUser?.content).includes("plan to make brownies")
);
},
},
response: {
toolCalls: [
{
name: "create_plan",
arguments: JSON.stringify({
request: "create_plan",
steps: [
"Gather ingredients",
"Melt butter and mix with cocoa",
"Add eggs and flour",
"Bake at 350F for 25 min",
],
}),
},
],
},
});
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasLangroidTool = sysIncludes(req.messages, "TOOL: create_plan");
return (
!!hasLangroidTool && textOf(lastUser?.content).includes("Go to Mars")
);
},
},
response: {
toolCalls: [
{
name: "create_plan",
arguments: JSON.stringify({
request: "create_plan",
steps: [
"Design spacecraft",
"Assemble crew",
"Launch from Earth",
"Land on Mars",
],
}),
},
],
},
});
// Langroid shared state: Langroid embeds generate_recipe in the system message.
// The recipe arg is nested under "recipe" key like Strands/CrewAI/LangGraph.
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasLangroidTool = sysIncludes(
req.messages,
"TOOL: generate_recipe",
);
return (
!!hasLangroidTool &&
textOf(lastUser?.content).includes("pasta recipe")
);
},
},
response: {
toolCalls: [
{
name: "generate_recipe",
arguments: JSON.stringify({
request: "generate_recipe",
recipe: recipeData,
}),
},
],
},
});
// LlamaIndex agentic gen UI: the agent registers run_task (a backend tool),
// not generate_task_steps_generative_ui. The run_task tool takes a Task
// model with steps: list[Step], where each Step has a description string.
// Arguments are wrapped in {"task": {...}} since llama-index exposes the
// function parameter name as the top-level key.
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasLlamaIndexTool = req.tools?.some(
(t) => t.function.name === "run_task",
);
return (
!!hasLlamaIndexTool &&
textOf(lastUser?.content).includes("plan to make brownies")
);
},
},
response: {
toolCalls: [
{
name: "run_task",
arguments: JSON.stringify({
task: {
steps: [
{ description: "Gather ingredients" },
{ description: "Melt butter and mix with cocoa" },
{ description: "Add eggs and flour" },
{ description: "Bake at 350F for 25 min" },
],
},
}),
},
],
},
});
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasLlamaIndexTool = req.tools?.some(
(t) => t.function.name === "run_task",
);
return (
!!hasLlamaIndexTool &&
textOf(lastUser?.content).includes("Go to Mars")
);
},
},
response: {
toolCalls: [
{
name: "run_task",
arguments: JSON.stringify({
task: {
steps: [
{ description: "Design spacecraft" },
{ description: "Assemble crew" },
{ description: "Launch from Earth" },
{ description: "Land on Mars" },
],
},
}),
},
],
},
});
// LlamaIndex shared state: the agent registers update_recipe (a frontend
// tool), not updateWorkingMemory. The Recipe model has skill_level,
// special_preferences, cooking_time, ingredients, instructions (no title
// or changes). Arguments are wrapped in {"recipe": {...}}.
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasLlamaIndexTool = req.tools?.some(
(t) => t.function.name === "update_recipe",
);
return (
!!hasLlamaIndexTool &&
textOf(lastUser?.content).includes("pasta recipe")
);
},
},
response: {
toolCalls: [
{
name: "update_recipe",
arguments: JSON.stringify({
recipe: pydanticRecipeData,
}),
},
],
},
});
// Claude Agent SDK shared state: the adapter registers ag_ui_update_state
// via an MCP server named "ag_ui", so the CLI sends the tool as
// mcp__ag_ui__ag_ui_update_state. Match both bare and MCP-prefixed names.
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const hasClaudeSdkTool = req.tools?.some(
(t) =>
t.function.name === "ag_ui_update_state" ||
t.function.name.endsWith("__ag_ui_update_state"),
);
return (
!!hasClaudeSdkTool &&
textOf(lastUser?.content).includes("pasta recipe")
);
},
},
response: {
toolCalls: [
{
// Use MCP-prefixed name so the CLI can route it to the right tool.
// The Python Claude SDK CLI requires exact name matching.
name: "mcp__ag_ui__ag_ui_update_state",
arguments: JSON.stringify({ state_updates: { recipe: recipeData } }),
},
],
},
});
// Load all fixture JSON files from the fixtures directory
// (HITL fixtures are duplicated but the earlier copies match first)
mockServer.loadFixtureDir(FIXTURES_DIR);
// Programmatic catch-all: when the last message is a tool result,
// return a generic text acknowledgment. This must be added AFTER
// fixture files so it appears last in the fixture list — but
// fixture-file entries only match on userMessage (substring), and
// a follow-up request after a tool call still has the same last
// user message, so we need this predicate to fire FIRST.
// Insert at position 0 so it's checked before file-based fixtures.
// Prepend so it matches before substring-based fixtures on follow-up requests
mockServer.prependFixture({
match: {
predicate: (req) => {
const last = req.messages[req.messages.length - 1];
return last?.role === "tool";
},
},
response: { content: "Done! I've completed that for you." },
});
// Universal catch-all: matches any request that wasn't handled above.
// Appended LAST so specific fixtures always take priority.
// Log unmatched requests for debugging fixture mismatches.
mockServer.addFixture({
match: {
predicate: (req) => {
const lastUser = req.messages.filter((m) => m.role === "user").pop();
const userText = lastUser ? textOf(lastUser.content) : "(no user msg)";
const toolNames =
req.tools?.map((t) => t.function.name).join(",") ||
"(no tools)";
const contentType = lastUser ? typeof lastUser.content : "N/A";
const contentSample = lastUser
? JSON.stringify(lastUser.content).slice(0, 120)
: "N/A";
console.error(
`[LLMock CATCH-ALL] model=${req.model} lastUser="${userText.slice(0, 80)}" tools=[${toolNames}] msgs=${req.messages.length} contentType=${contentType} content=${contentSample}`,
);
return true;
},
},
response: { content: "I understand. How can I help you with that?" },
});
// Log fixture counts for debugging
const allFixtures = mockServer.getFixtures();
const predicateCount = allFixtures.filter((f) => f.match.predicate).length;
const userMsgCount = allFixtures.filter((f) => f.match.userMessage).length;
console.log(
` Fixture stats: ${allFixtures.length} total, ${predicateCount} predicate, ${userMsgCount} userMessage`,
);
// Log the userMessage fixtures to verify they loaded
allFixtures.forEach((f, i) => {
if (f.match.userMessage) {
console.log(
` [${i}] userMessage: "${String(f.match.userMessage).slice(0, 50)}"`,
);
}
});
const url = await mockServer.start();
console.log(`✅ LLMock server running at ${url}`);
console.log(` Fixtures loaded from: ${FIXTURES_DIR}`);
// Export the URL for child processes to use
process.env.LLMOCK_URL = `${url}/v1`;
}
export async function teardownLLMock(): Promise<void> {
if (mockServer) {
console.log("🧹 Stopping LLMock server...");
await mockServer.stop();
mockServer = null;
console.log("✅ LLMock server stopped");
}
}
export function getMockServer(): LLMock | null {
return mockServer;
}
================================================
FILE: apps/dojo/e2e/package.json
================================================
{
"name": "copilotkit-e2e",
"version": "0.1.0",
"private": true,
"type": "module",
"description": "Scheduled Playwright smoke tests for CopilotKit demo apps",
"scripts": {
"postinstall": "playwright install --with-deps",
"test": "playwright test",
"test:ui": "playwright test --ui",
"report": "playwright show-report"
},
"devDependencies": {
"@playwright/test": "^1.43.1",
"@slack/types": "^2.14.0",
"@types/node": "^22.15.28",
"playwright-slack-report": "^1.1.93"
},
"dependencies": {
"@aws-sdk/client-s3": "^3.600.0",
"json2md": "^2.0.1"
}
}
================================================
FILE: apps/dojo/e2e/pages/a2aMiddlewarePages/A2AChatPage.ts
================================================
import { Page, Locator, expect } from '@playwright/test';
export class A2AChatPage {
readonly page: Page;
readonly mainChatTab: Locator;
constructor(page: Page) {
this.page = page;
this.mainChatTab = page.getByRole('tab', {name: 'Main Chat' });
}
async openChat() {
await expect(this.mainChatTab).toBeVisible();
}
}
================================================
FILE: apps/dojo/e2e/pages/adkMiddlewarePages/HumanInLoopPage.ts
================================================
import { Page, Locator, expect } from "@playwright/test";
import { CopilotSelectors } from "../../utils/copilot-selectors";
import { sendAndAwaitResponse } from "../../utils/copilot-actions";
import { DEFAULT_WELCOME_MESSAGE } from "../../lib/constants";
export class HumanInLoopPage {
readonly page: Page;
readonly planTaskButton: Locator;
readonly chatInput: Locator;
readonly sendButton: Locator;
readonly agentGreeting: Locator;
readonly plan: Locator;
readonly performStepsButton: Locator;
readonly agentMessage: Locator;
readonly userMessage: Locator;
constructor(page: Page) {
this.page = page;
this.planTaskButton = page.getByRole("button", {
name: "Human in the loop Plan a task",
});
this.agentGreeting = page.getByText(DEFAULT_WELCOME_MESSAGE);
this.chatInput = CopilotSelectors.chatTextarea(page);
this.sendButton = CopilotSelectors.sendButton(page);
this.plan = page.getByTestId("select-steps");
this.performStepsButton = page.getByRole("bu
gitextract_1usf67qd/
├── .claude/
│ └── settings.json
├── .gitattributes
├── .github/
│ ├── CODEOWNERS
│ ├── ISSUE_TEMPLATE/
│ │ ├── bug_report.yml
│ │ ├── documentation.yml
│ │ └── feature_request.yml
│ ├── pull_request_template.md
│ └── workflows/
│ ├── auto-approve-community.yml
│ ├── build-python-preview.yml
│ ├── dojo-e2e.yml
│ ├── pr-check-binaries.yml
│ ├── publish-commit.yml
│ ├── publish-java-sdk.yml
│ ├── publish-kotlin-sdk.yml
│ ├── publish-python-package.yml
│ ├── publish-python-preview.yml
│ ├── rust-lint-test.yml
│ ├── unit-dart-sdk.yml
│ ├── unit-genkit-go.yml
│ ├── unit-go-sdk.yml
│ ├── unit-java-sdk.yml
│ ├── unit-kotlin-sdk.yml
│ ├── unit-python-sdk.yml
│ ├── unit-ruby-sdk.yml
│ └── unit-typescript-sdk.yml
├── .gitignore
├── .mcp.json
├── AGENTS.md
├── CLAUDE.md
├── CONTRIBUTING.md
├── 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
│ ├── components.json
│ ├── e2e/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── VIDEO_SETUP.md
│ │ ├── clean-reporter.cjs
│ │ ├── featurePages/
│ │ │ ├── AgenticChatPage.ts
│ │ │ ├── HumanInTheLoopPage.ts
│ │ │ ├── SharedStatePage.ts
│ │ │ ├── ToolBaseGenUIPage.ts
│ │ │ └── V1AgenticChatPage.ts
│ │ ├── fixtures/
│ │ │ └── openai/
│ │ │ ├── agentic-chat.json
│ │ │ ├── agentic-gen-ui.json
│ │ │ ├── backend-tool-rendering.json
│ │ │ ├── human-in-the-loop.json
│ │ │ ├── predictive-state.json
│ │ │ ├── shared-state.json
│ │ │ ├── subgraphs.json
│ │ │ ├── tool-based-gen-ui.json
│ │ │ └── v1-chat.json
│ │ ├── lib/
│ │ │ ├── constants.ts
│ │ │ ├── mock-agent.ts
│ │ │ └── upload-video.ts
│ │ ├── llmock-setup.ts
│ │ ├── package.json
│ │ ├── pages/
│ │ │ ├── a2aMiddlewarePages/
│ │ │ │ └── A2AChatPage.ts
│ │ │ ├── adkMiddlewarePages/
│ │ │ │ ├── HumanInLoopPage.ts
│ │ │ │ └── PredictiveStateUpdatesPage.ts
│ │ │ ├── agnoPages/
│ │ │ │ └── HumanInLoopPage.ts
│ │ │ ├── awsStrandsPages/
│ │ │ │ ├── AgenticUIGenPage.ts
│ │ │ │ └── HumanInLoopPage.ts
│ │ │ ├── crewAIPages/
│ │ │ │ ├── AgenticUIGenPage.ts
│ │ │ │ ├── HumanInLoopPage.ts
│ │ │ │ └── PredictiveStateUpdatesPage.ts
│ │ │ ├── langGraphFastAPIPages/
│ │ │ │ ├── AgenticUIGenPage.ts
│ │ │ │ ├── HumanInLoopPage.ts
│ │ │ │ ├── PredictiveStateUpdatesPage.ts
│ │ │ │ └── SubgraphsPage.ts
│ │ │ ├── langGraphPages/
│ │ │ │ ├── AgenticUIGenPage.ts
│ │ │ │ ├── HumanInLoopPage.ts
│ │ │ │ ├── PredictiveStateUpdatesPage.ts
│ │ │ │ └── SubgraphsPage.ts
│ │ │ ├── langroidPages/
│ │ │ │ └── AgenticUIGenPage.ts
│ │ │ ├── llamaIndexPages/
│ │ │ │ ├── AgenticUIGenPage.ts
│ │ │ │ └── HumanInLoopPage.ts
│ │ │ ├── pydanticAIPages/
│ │ │ │ ├── AgenticUIGenPage.ts
│ │ │ │ ├── HumanInLoopPage.ts
│ │ │ │ └── PredictiveStateUpdatesPage.ts
│ │ │ └── serverStarterAllFeaturesPages/
│ │ │ ├── AgenticUIGenPage.ts
│ │ │ ├── HumanInLoopPage.ts
│ │ │ └── PredictiveStateUpdatesPage.ts
│ │ ├── playwright.config.ts
│ │ ├── 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
│ │ ├── test-isolation-teardown.ts
│ │ ├── tests/
│ │ │ ├── a2aMiddlewareTests/
│ │ │ │ └── a2aChatPage.spec.ts
│ │ │ ├── adkMiddlewareTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── predictiveStateUpdatePage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── agnoTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── awsStrandsTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── claudeAgentSdkPythonTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ └── toolBasedGenUIPage.spec.ts
│ │ │ ├── claudeAgentSdkTypescriptTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ └── toolBasedGenUIPage.spec.ts
│ │ │ ├── crewAITests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── predictiveStateUpdatePage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── langchainTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ └── toolBasedGenUIPage.spec.ts
│ │ │ ├── langgraphFastAPITests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── predictiveStateUpdatePage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── subgraphsPage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── langgraphPythonTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── predictiveStateUpdatePage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── subgraphsPage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── langgraphTypescriptTests/
│ │ │ │ ├── agenticChatDeterministic.spec.ts
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── predictiveStateUpdatePage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── subgraphsPage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── langroidTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ └── sharedStatePage.spec.ts
│ │ │ ├── llamaIndexTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── mastraAgentLocalTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── mastraTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── middlewareStarterTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── pydanticAITests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── predictiveStateUpdatePage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ ├── serverStarterAllFeaturesTests/
│ │ │ │ ├── agenticChatPage.spec.ts
│ │ │ │ ├── agenticGenUI.spec.ts
│ │ │ │ ├── backendToolRenderingPage.spec.ts
│ │ │ │ ├── humanInTheLoopPage.spec.ts
│ │ │ │ ├── predictiveStateUpdatePage.spec.ts
│ │ │ │ ├── sharedStatePage.spec.ts
│ │ │ │ ├── toolBasedGenUIPage.spec.ts
│ │ │ │ └── v1AgenticChatPage.spec.ts
│ │ │ └── serverStarterTests/
│ │ │ ├── agenticChatPage.spec.ts
│ │ │ └── v1AgenticChatPage.spec.ts
│ │ └── utils/
│ │ ├── aiWaitHelpers.ts
│ │ ├── copilot-actions.ts
│ │ └── copilot-selectors.ts
│ ├── eslint.config.mjs
│ ├── next.config.ts
│ ├── package.json
│ ├── postcss.config.mjs
│ ├── scripts/
│ │ ├── generate-content-json.ts
│ │ ├── link-cpk.js
│ │ ├── prep-dojo-everything.js
│ │ └── run-dojo-everything.js
│ ├── src/
│ │ ├── agents.ts
│ │ ├── app/
│ │ │ ├── [integrationId]/
│ │ │ │ ├── feature/
│ │ │ │ │ ├── (v1)/
│ │ │ │ │ │ └── v1_agentic_chat/
│ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── (v2)/
│ │ │ │ │ │ ├── a2a_chat/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── a2a_chat.tsx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ ├── a2ui_chat/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ ├── style.css
│ │ │ │ │ │ │ └── theme.ts
│ │ │ │ │ │ ├── agentic_chat/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── agentic_chat_reasoning/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ ├── agentic_generative_ui/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ ├── backend_tool_rendering/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ ├── human_in_the_loop/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ └── page.tsx
│ │ │ │ │ │ ├── predictive_state_updates/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ ├── shared_state/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ ├── subgraphs/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ ├── tool_based_generative_ui/
│ │ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ │ ├── page.tsx
│ │ │ │ │ │ │ └── style.css
│ │ │ │ │ │ └── vnext_chat/
│ │ │ │ │ │ ├── README.mdx
│ │ │ │ │ │ └── page.tsx
│ │ │ │ │ ├── layout-client.tsx
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── not-found.tsx
│ │ │ │ ├── not-found.tsx
│ │ │ │ └── page.tsx
│ │ │ ├── api/
│ │ │ │ ├── copilotkit/
│ │ │ │ │ ├── [integrationId]/
│ │ │ │ │ │ └── [[...slug]]/
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ └── route.ts
│ │ │ │ └── copilotkitnext/
│ │ │ │ └── [integrationId]/
│ │ │ │ └── [[...slug]]/
│ │ │ │ └── route.ts
│ │ │ ├── globals.css
│ │ │ ├── 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
│ │ │ ├── theme-wrapper.tsx
│ │ │ └── ui/
│ │ │ ├── badge.tsx
│ │ │ ├── button.tsx
│ │ │ ├── carousel.tsx
│ │ │ ├── dropdown-menu.tsx
│ │ │ ├── mdx-components.tsx
│ │ │ ├── tabs.tsx
│ │ │ └── theme-toggle.tsx
│ │ ├── config.ts
│ │ ├── contexts/
│ │ │ └── url-params-context.tsx
│ │ ├── env.ts
│ │ ├── files.json
│ │ ├── lib/
│ │ │ └── utils.ts
│ │ ├── mastra/
│ │ │ ├── agents/
│ │ │ │ ├── agentic-chat.ts
│ │ │ │ ├── backend-tool-rendering.ts
│ │ │ │ ├── human-in-the-loop.ts
│ │ │ │ ├── shared-state.ts
│ │ │ │ └── tool-based-generative-ui.ts
│ │ │ ├── index.ts
│ │ │ ├── storage.ts
│ │ │ └── tools.ts
│ │ ├── menu.ts
│ │ ├── proxy.ts
│ │ ├── styles/
│ │ │ └── typography.css
│ │ ├── types/
│ │ │ ├── agents.ts
│ │ │ ├── feature.ts
│ │ │ ├── integration.ts
│ │ │ └── interface.ts
│ │ └── utils/
│ │ ├── agents.ts
│ │ ├── domain-config.ts
│ │ ├── mdx-utils.tsx
│ │ ├── menu.ts
│ │ ├── use-is-inside-iframe.ts
│ │ ├── use-mobile-chat.ts
│ │ └── use-mobile-view.ts
│ ├── tailwind.config.ts
│ └── tsconfig.json
├── docs/
│ ├── .gitignore
│ ├── .prettierignore
│ ├── .prettierrc
│ ├── LICENSE
│ ├── README.md
│ ├── ag_ui.md
│ ├── agentic-protocols.mdx
│ ├── concepts/
│ │ ├── agents.mdx
│ │ ├── architecture.mdx
│ │ ├── capabilities.mdx
│ │ ├── events.mdx
│ │ ├── generative-ui-specs.mdx
│ │ ├── messages.mdx
│ │ ├── middleware.mdx
│ │ ├── reasoning.mdx
│ │ ├── serialization.mdx
│ │ ├── state.mdx
│ │ └── tools.mdx
│ ├── development/
│ │ ├── contributing.mdx
│ │ ├── roadmap.mdx
│ │ └── updates.mdx
│ ├── docs.json
│ ├── drafts/
│ │ ├── generative-ui.mdx
│ │ ├── interrupts.mdx
│ │ ├── meta-events.mdx
│ │ ├── multimodal-messages.mdx
│ │ └── overview.mdx
│ ├── icons/
│ │ ├── custom-icons.tsx
│ │ └── index.tsx
│ ├── images/
│ │ └── left-illustration.avif
│ ├── integrations.mdx
│ ├── introduction.mdx
│ ├── package.json
│ ├── quickstart/
│ │ ├── applications.mdx
│ │ ├── clients.mdx
│ │ ├── introduction.mdx
│ │ ├── middleware.mdx
│ │ └── server.mdx
│ ├── sdk/
│ │ ├── dart/
│ │ │ ├── client/
│ │ │ │ ├── client.mdx
│ │ │ │ └── overview.mdx
│ │ │ ├── core/
│ │ │ │ ├── events.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── types.mdx
│ │ │ ├── encoder/
│ │ │ │ └── overview.mdx
│ │ │ └── overview.mdx
│ │ ├── go/
│ │ │ ├── client/
│ │ │ │ ├── overview.mdx
│ │ │ │ └── sse-client.mdx
│ │ │ ├── core/
│ │ │ │ ├── events.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── types.mdx
│ │ │ ├── encoding/
│ │ │ │ └── overview.mdx
│ │ │ ├── errors/
│ │ │ │ └── overview.mdx
│ │ │ └── overview.mdx
│ │ ├── java/
│ │ │ ├── client/
│ │ │ │ ├── abstract-agent.mdx
│ │ │ │ ├── http-agent.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── subscriber.mdx
│ │ │ ├── core/
│ │ │ │ ├── events.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ ├── stream.mdx
│ │ │ │ ├── subscription.mdx
│ │ │ │ └── types.mdx
│ │ │ ├── overview.mdx
│ │ │ └── server/
│ │ │ ├── overview.mdx
│ │ │ └── spring.mdx
│ │ ├── js/
│ │ │ ├── client/
│ │ │ │ ├── abstract-agent.mdx
│ │ │ │ ├── compaction.mdx
│ │ │ │ ├── http-agent.mdx
│ │ │ │ ├── middleware.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── subscriber.mdx
│ │ │ ├── core/
│ │ │ │ ├── events.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── types.mdx
│ │ │ ├── encoder.mdx
│ │ │ ├── overview.mdx
│ │ │ └── proto.mdx
│ │ ├── kotlin/
│ │ │ ├── client/
│ │ │ │ ├── abstract-agent.mdx
│ │ │ │ ├── agui-agent.mdx
│ │ │ │ ├── http-agent.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── stateful-agui-agent.mdx
│ │ │ ├── core/
│ │ │ │ ├── events.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── types.mdx
│ │ │ ├── overview.mdx
│ │ │ └── tools/
│ │ │ ├── overview.mdx
│ │ │ ├── tool-executor.mdx
│ │ │ └── tool-registry.mdx
│ │ ├── python/
│ │ │ ├── core/
│ │ │ │ ├── events.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── types.mdx
│ │ │ └── encoder/
│ │ │ └── overview.mdx
│ │ ├── ruby/
│ │ │ ├── core/
│ │ │ │ ├── events.mdx
│ │ │ │ ├── overview.mdx
│ │ │ │ └── types.mdx
│ │ │ ├── encoder/
│ │ │ │ └── overview.mdx
│ │ │ └── overview.mdx
│ │ └── rust/
│ │ ├── client/
│ │ │ ├── agent-trait.mdx
│ │ │ ├── http-agent.mdx
│ │ │ ├── overview.mdx
│ │ │ └── subscriber.mdx
│ │ ├── core/
│ │ │ ├── events.mdx
│ │ │ ├── overview.mdx
│ │ │ └── types.mdx
│ │ └── overview.mdx
│ ├── snippets/
│ │ └── snippet-intro.mdx
│ └── tutorials/
│ ├── cursor.mdx
│ └── debugging.mdx
├── integrations/
│ ├── a2a/
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmrc
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── __tests__/
│ │ │ │ ├── agent.test.ts
│ │ │ │ └── utils.test.ts
│ │ │ ├── agent.ts
│ │ │ ├── index.ts
│ │ │ ├── types.ts
│ │ │ └── utils.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── adk-middleware/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ ├── ARCHITECTURE.md
│ │ │ ├── CHANGELOG.md
│ │ │ ├── CLAUDE.md
│ │ │ ├── CONFIGURATION.md
│ │ │ ├── LOGGING.md
│ │ │ ├── README.md
│ │ │ ├── STREAMING_FC_ARGS_RECONSTRUCTION.md
│ │ │ ├── TOOLS.md
│ │ │ ├── USAGE.md
│ │ │ ├── examples/
│ │ │ │ ├── README.md
│ │ │ │ ├── other/
│ │ │ │ │ ├── complete_setup.py
│ │ │ │ │ ├── configure_adk_agent.py
│ │ │ │ │ ├── context_usage.py
│ │ │ │ │ └── simple_agent.py
│ │ │ │ ├── pyproject.toml
│ │ │ │ └── server/
│ │ │ │ ├── __init__.py
│ │ │ │ └── api/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agentic_chat.py
│ │ │ │ ├── agentic_generative_ui.py
│ │ │ │ ├── backend_tool_rendering.py
│ │ │ │ ├── human_in_the_loop.py
│ │ │ │ ├── predictive_state_updates.py
│ │ │ │ ├── shared_state.py
│ │ │ │ └── tool_based_generative_ui.py
│ │ │ ├── pyproject.toml
│ │ │ ├── pytest.ini
│ │ │ ├── src/
│ │ │ │ └── ag_ui_adk/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── adk_agent.py
│ │ │ │ ├── agui_toolset.py
│ │ │ │ ├── client_proxy_tool.py
│ │ │ │ ├── client_proxy_toolset.py
│ │ │ │ ├── config.py
│ │ │ │ ├── endpoint.py
│ │ │ │ ├── event_translator.py
│ │ │ │ ├── execution_state.py
│ │ │ │ ├── session_manager.py
│ │ │ │ └── utils/
│ │ │ │ ├── __init__.py
│ │ │ │ └── converters.py
│ │ │ └── tests/
│ │ │ ├── __init__.py
│ │ │ ├── conftest.py
│ │ │ ├── run_all_tests.sh
│ │ │ ├── server_setup.py
│ │ │ ├── test_adk_agent.py
│ │ │ ├── test_adk_agent_memory_integration.py
│ │ │ ├── test_adk_llm_flow_tool_override.py
│ │ │ ├── test_app_name_extractor.py
│ │ │ ├── test_chunk_event.py
│ │ │ ├── test_claude_streaming.py
│ │ │ ├── test_client_proxy_tool.py
│ │ │ ├── test_client_proxy_toolset.py
│ │ │ ├── test_concurrency.py
│ │ │ ├── test_concurrent_limits.py
│ │ │ ├── test_context_handling.py
│ │ │ ├── test_context_integration.py
│ │ │ ├── test_credential_service_defaults.py
│ │ │ ├── test_duplicate_function_response.py
│ │ │ ├── test_endpoint.py
│ │ │ ├── test_endpoint_error_handling.py
│ │ │ ├── test_event_bookending.py
│ │ │ ├── test_event_translator_comprehensive.py
│ │ │ ├── test_execution_state.py
│ │ │ ├── test_from_app_integration.py
│ │ │ ├── test_hitl_resumption_text_output.py
│ │ │ ├── test_integration.py
│ │ │ ├── test_integration_mixed_partials.py
│ │ │ ├── test_issue_437_skip_summarization_integration.py
│ │ │ ├── test_lro_filtering.py
│ │ │ ├── test_lro_sse_id_remap.py
│ │ │ ├── test_lro_sse_persistence.py
│ │ │ ├── test_lro_tool_response_persistence.py
│ │ │ ├── test_message_history.py
│ │ │ ├── test_multi_turn_conversation.py
│ │ │ ├── test_non_streaming_text_with_lro_tool.py
│ │ │ ├── test_predictive_state.py
│ │ │ ├── test_resumability_config.py
│ │ │ ├── test_sequential_agent_hitl_resumption.py
│ │ │ ├── test_session_cleanup.py
│ │ │ ├── test_session_creation.py
│ │ │ ├── test_session_deletion.py
│ │ │ ├── test_session_memory.py
│ │ │ ├── test_skip_summarization.py
│ │ │ ├── test_stale_session_invocation_id.py
│ │ │ ├── test_streaming.py
│ │ │ ├── test_streaming_fc_args.py
│ │ │ ├── test_text_events.py
│ │ │ ├── test_thought_to_thinking_integration.py
│ │ │ ├── test_tool_error_handling.py
│ │ │ ├── test_tool_result_flow.py
│ │ │ ├── test_tool_tracking_hitl.py
│ │ │ ├── test_use_thread_id_as_session_id.py
│ │ │ ├── test_user_id_extractor.py
│ │ │ ├── test_utils_converters.py
│ │ │ ├── test_utils_init.py
│ │ │ └── test_vertex_session_service.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ └── tsdown.config.ts
│ ├── ag2/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ └── examples/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── pyproject.toml
│ │ │ └── server/
│ │ │ ├── __init__.py
│ │ │ └── api/
│ │ │ ├── __init__.py
│ │ │ ├── agentic_chat.py
│ │ │ ├── agentic_generative_ui.py
│ │ │ ├── backend_tool_rendering.py
│ │ │ ├── human_in_the_loop.py
│ │ │ ├── shared_state.py
│ │ │ └── tool_based_generative_ui.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── agent-spec/
│ │ └── python/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── ag_ui_agentspec/
│ │ │ ├── __init__.py
│ │ │ ├── agent.py
│ │ │ ├── agentspec_tracing_exporter.py
│ │ │ ├── agentspecloader.py
│ │ │ ├── endpoint.py
│ │ │ └── runtimes/
│ │ │ ├── __init__.py
│ │ │ ├── langgraph_runner.py
│ │ │ └── wayflow_runner.py
│ │ ├── examples/
│ │ │ ├── README.md
│ │ │ ├── pyproject.toml
│ │ │ └── server/
│ │ │ ├── __init__.py
│ │ │ └── api/
│ │ │ ├── A2UI_PROMPT.txt
│ │ │ ├── __init__.py
│ │ │ ├── a2ui_chat.py
│ │ │ ├── agentic_chat.py
│ │ │ ├── backend_tool_rendering.py
│ │ │ ├── human_in_the_loop.py
│ │ │ ├── routes.py
│ │ │ └── tool_based_generative_ui.py
│ │ └── pyproject.toml
│ ├── agno/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ └── examples/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── pyproject.toml
│ │ │ ├── requirements.txt
│ │ │ └── server/
│ │ │ ├── __init__.py
│ │ │ └── api/
│ │ │ ├── __init__.py
│ │ │ ├── agentic_chat.py
│ │ │ ├── backend_tool_rendering.py
│ │ │ ├── human_in_the_loop.py
│ │ │ └── tool_based_generative_ui.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── aws-strands/
│ │ ├── ARCHITECTURE.md
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── examples/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── pyproject.toml
│ │ │ │ └── server/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __main__.py
│ │ │ │ └── api/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agentic_chat.py
│ │ │ │ ├── agentic_generative_ui.py
│ │ │ │ ├── backend_tool_rendering.py
│ │ │ │ ├── human_in_the_loop.py
│ │ │ │ └── shared_state.py
│ │ │ ├── pyproject.toml
│ │ │ ├── src/
│ │ │ │ └── ag_ui_strands/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agent.py
│ │ │ │ ├── client_proxy_tool.py
│ │ │ │ ├── config.py
│ │ │ │ ├── endpoint.py
│ │ │ │ ├── types.py
│ │ │ │ └── utils.py
│ │ │ └── tests/
│ │ │ ├── __init__.py
│ │ │ └── test_client_proxy_tool.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── claude-agent-sdk/
│ │ ├── .gitignore
│ │ ├── python/
│ │ │ ├── README.md
│ │ │ ├── ag_ui_claude_sdk/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── adapter.py
│ │ │ │ ├── config.py
│ │ │ │ ├── endpoint.py
│ │ │ │ ├── handlers.py
│ │ │ │ ├── session.py
│ │ │ │ ├── types.py
│ │ │ │ └── utils.py
│ │ │ ├── examples/
│ │ │ │ ├── README.md
│ │ │ │ ├── agents/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── agentic_chat.py
│ │ │ │ │ ├── backend_tool_rendering.py
│ │ │ │ │ ├── constants.py
│ │ │ │ │ ├── human_in_the_loop.py
│ │ │ │ │ ├── shared_state.py
│ │ │ │ │ └── tool_based_generative_ui.py
│ │ │ │ ├── pyproject.toml
│ │ │ │ └── server.py
│ │ │ └── pyproject.toml
│ │ └── typescript/
│ │ ├── README.md
│ │ ├── examples/
│ │ │ ├── agentic_chat.ts
│ │ │ ├── backend_tool_rendering.ts
│ │ │ ├── constants.ts
│ │ │ ├── human_in_the_loop.ts
│ │ │ ├── server.ts
│ │ │ ├── shared_state.ts
│ │ │ └── tool_based_generative_ui.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── adapter.ts
│ │ │ ├── config.ts
│ │ │ ├── handlers.ts
│ │ │ ├── index.ts
│ │ │ ├── types.ts
│ │ │ └── utils.ts
│ │ ├── tsconfig.json
│ │ ├── tsup.config.ts
│ │ └── vitest.config.ts
│ ├── community/
│ │ ├── genkit/
│ │ │ └── go/
│ │ │ ├── README.md
│ │ │ ├── examples/
│ │ │ │ ├── README.md
│ │ │ │ ├── cmd/
│ │ │ │ │ └── server/
│ │ │ │ │ └── main.go
│ │ │ │ ├── go.mod
│ │ │ │ ├── go.sum
│ │ │ │ ├── internal/
│ │ │ │ │ ├── agents/
│ │ │ │ │ │ ├── agentic_chat/
│ │ │ │ │ │ │ └── agent.go
│ │ │ │ │ │ └── registry.go
│ │ │ │ │ ├── config/
│ │ │ │ │ │ └── config.go
│ │ │ │ │ └── handlers/
│ │ │ │ │ └── agent.go
│ │ │ │ └── mock/
│ │ │ │ └── mock.go
│ │ │ └── genkit/
│ │ │ ├── genkit.go
│ │ │ ├── genkit_test.go
│ │ │ ├── go.mod
│ │ │ └── go.sum
│ │ └── spring-ai/
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── crew-ai/
│ │ ├── 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
│ │ │ ├── pyproject.toml
│ │ │ └── tests/
│ │ │ └── __init__.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── langchain/
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── agent.ts
│ │ │ ├── index.ts
│ │ │ ├── messages.ts
│ │ │ ├── streaming.ts
│ │ │ └── tools.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── langgraph/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── ag_ui_langgraph/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agent.py
│ │ │ │ ├── endpoint.py
│ │ │ │ ├── middlewares/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── state_streaming.py
│ │ │ │ ├── types.py
│ │ │ │ └── utils.py
│ │ │ ├── examples/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── agents/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ ├── a2ui_chat/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ ├── agent.py
│ │ │ │ │ │ └── prompt.py
│ │ │ │ │ ├── agentic_chat/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── agentic_chat_reasoning/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── agentic_generative_ui/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── backend_tool_rendering/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── dojo.py
│ │ │ │ │ ├── human_in_the_loop/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── multimodal_messages/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── predictive_state_updates/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── shared_state/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ ├── subgraphs/
│ │ │ │ │ │ ├── __init__.py
│ │ │ │ │ │ └── agent.py
│ │ │ │ │ └── tool_based_generative_ui/
│ │ │ │ │ ├── __init__.py
│ │ │ │ │ └── agent.py
│ │ │ │ ├── langgraph.json
│ │ │ │ └── pyproject.toml
│ │ │ ├── pyproject.toml
│ │ │ └── tests/
│ │ │ ├── __init__.py
│ │ │ ├── test_make_json_safe.py
│ │ │ ├── test_multimodal.py
│ │ │ └── test_state_streaming_middleware.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── examples/
│ │ │ ├── .env.example
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── langgraph.json
│ │ │ ├── package.json
│ │ │ ├── pnpm-workspace.yaml
│ │ │ ├── src/
│ │ │ │ └── agents/
│ │ │ │ ├── agentic_chat/
│ │ │ │ │ └── agent.ts
│ │ │ │ ├── agentic_generative_ui/
│ │ │ │ │ └── agent.ts
│ │ │ │ ├── backend_tool_rendering/
│ │ │ │ │ └── agent.ts
│ │ │ │ ├── human_in_the_loop/
│ │ │ │ │ └── agent.ts
│ │ │ │ ├── multimodal_messages/
│ │ │ │ │ └── agent.ts
│ │ │ │ ├── predictive_state_updates/
│ │ │ │ │ └── agent.ts
│ │ │ │ ├── shared_state/
│ │ │ │ │ └── agent.ts
│ │ │ │ ├── subgraphs/
│ │ │ │ │ └── agent.ts
│ │ │ │ └── tool_based_generative_ui/
│ │ │ │ └── agent.ts
│ │ │ └── tsconfig.json
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── agent.ts
│ │ │ ├── index.ts
│ │ │ ├── messages-tuple.test.ts
│ │ │ ├── middlewares/
│ │ │ │ ├── index.ts
│ │ │ │ ├── state-streaming.test.ts
│ │ │ │ └── state-streaming.ts
│ │ │ ├── types.ts
│ │ │ ├── utils.test.ts
│ │ │ └── utils.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── langroid/
│ │ ├── ARCHITECTURE.md
│ │ ├── README.md
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── examples/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── pyproject.toml
│ │ │ │ └── server/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── __main__.py
│ │ │ │ └── api/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agentic_chat.py
│ │ │ │ ├── agentic_generative_ui.py
│ │ │ │ ├── backend_tool_rendering.py
│ │ │ │ └── shared_state.py
│ │ │ ├── pyproject.toml
│ │ │ ├── src/
│ │ │ │ └── ag_ui_langroid/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agent.py
│ │ │ │ ├── endpoint.py
│ │ │ │ ├── types.py
│ │ │ │ └── utils.py
│ │ │ └── tests/
│ │ │ ├── __init__.py
│ │ │ ├── test_agent.py
│ │ │ ├── test_endpoint.py
│ │ │ └── test_types.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── jest.config.js
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── index.test.ts
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ └── tsup.config.ts
│ ├── llama-index/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ └── examples/
│ │ │ ├── README.md
│ │ │ ├── pyproject.toml
│ │ │ └── server/
│ │ │ ├── __init__.py
│ │ │ └── routers/
│ │ │ ├── agentic_chat.py
│ │ │ ├── agentic_generative_ui.py
│ │ │ ├── backend_tool_rendering.py
│ │ │ ├── human_in_the_loop.py
│ │ │ └── shared_state.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── mastra/
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── examples/
│ │ │ ├── .env.example
│ │ │ ├── .gitignore
│ │ │ ├── package.json
│ │ │ ├── src/
│ │ │ │ └── mastra/
│ │ │ │ ├── agents/
│ │ │ │ │ ├── agentic-chat.ts
│ │ │ │ │ ├── backend-tool-rendering.ts
│ │ │ │ │ ├── human-in-the-loop.ts
│ │ │ │ │ └── tool-based-generative-ui.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── tools/
│ │ │ │ └── weather-tool.ts
│ │ │ └── tsconfig.json
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── __tests__/
│ │ │ │ ├── edge-cases.test.ts
│ │ │ │ ├── helpers.ts
│ │ │ │ ├── integration.test.ts
│ │ │ │ └── message-conversion.test.ts
│ │ │ ├── copilotkit.ts
│ │ │ ├── index.ts
│ │ │ ├── mastra.ts
│ │ │ └── utils.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── microsoft-agent-framework/
│ │ ├── dotnet/
│ │ │ └── examples/
│ │ │ ├── .gitignore
│ │ │ ├── AGUIDojoServer/
│ │ │ │ ├── .dockerignore
│ │ │ │ ├── AGUIDojoServer.csproj
│ │ │ │ ├── AGUIDojoServerSerializerContext.cs
│ │ │ │ ├── AgenticUI/
│ │ │ │ │ ├── AgenticPlanningTools.cs
│ │ │ │ │ ├── AgenticUIAgent.cs
│ │ │ │ │ ├── JsonPatchOperation.cs
│ │ │ │ │ ├── Plan.cs
│ │ │ │ │ ├── Step.cs
│ │ │ │ │ └── StepStatus.cs
│ │ │ │ ├── BackendToolRendering/
│ │ │ │ │ └── WeatherInfo.cs
│ │ │ │ ├── ChatClientAgentFactory.cs
│ │ │ │ ├── Dockerfile
│ │ │ │ ├── PredictiveStateUpdates/
│ │ │ │ │ ├── DocumentState.cs
│ │ │ │ │ └── PredictiveStateUpdatesAgent.cs
│ │ │ │ ├── Program.cs
│ │ │ │ ├── Properties/
│ │ │ │ │ └── launchSettings.json
│ │ │ │ └── SharedState/
│ │ │ │ ├── Ingredient.cs
│ │ │ │ ├── Recipe.cs
│ │ │ │ ├── RecipeResponse.cs
│ │ │ │ └── SharedStateAgent.cs
│ │ │ └── README.md
│ │ └── python/
│ │ └── examples/
│ │ ├── .gitignore
│ │ ├── README.md
│ │ ├── agents/
│ │ │ ├── __init__.py
│ │ │ └── dojo.py
│ │ └── pyproject.toml
│ ├── pydantic-ai/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ └── examples/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── pyproject.toml
│ │ │ └── server/
│ │ │ ├── __init__.py
│ │ │ └── api/
│ │ │ ├── __init__.py
│ │ │ ├── agentic_chat.py
│ │ │ ├── agentic_generative_ui.py
│ │ │ ├── backend_tool_rendering.py
│ │ │ ├── human_in_the_loop.py
│ │ │ ├── predictive_state_updates.py
│ │ │ ├── shared_state.py
│ │ │ └── tool_based_generative_ui.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── server-starter/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ └── examples/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── example_server/
│ │ │ │ └── __init__.py
│ │ │ ├── pyproject.toml
│ │ │ └── tests/
│ │ │ └── __init__.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── server-starter-all-features/
│ │ ├── python/
│ │ │ ├── .gitignore
│ │ │ └── examples/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── example_server/
│ │ │ │ ├── __init__.py
│ │ │ │ ├── agentic_chat.py
│ │ │ │ ├── agentic_generative_ui.py
│ │ │ │ ├── backend_tool_rendering.py
│ │ │ │ ├── human_in_the_loop.py
│ │ │ │ ├── predictive_state_updates.py
│ │ │ │ ├── shared_state.py
│ │ │ │ └── tool_based_generative_ui.py
│ │ │ ├── pyproject.toml
│ │ │ └── tests/
│ │ │ └── __init__.py
│ │ └── typescript/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ └── vercel-ai-sdk/
│ └── typescript/
│ ├── .gitignore
│ ├── .npmignore
│ ├── README.md
│ ├── package.json
│ ├── src/
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── tsdown.config.ts
│ └── vitest.config.ts
├── lefthook.yml
├── middlewares/
│ ├── a2a-middleware/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── examples/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── buildings_management.py
│ │ │ ├── finance.py
│ │ │ ├── it.py
│ │ │ ├── orchestrator.py
│ │ │ └── pyproject.toml
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── index.ts
│ │ │ └── utils.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── a2ui-middleware/
│ │ ├── .gitignore
│ │ ├── __tests__/
│ │ │ └── a2ui-middleware.test.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── index.ts
│ │ │ ├── schema.ts
│ │ │ ├── tools.ts
│ │ │ └── types.ts
│ │ ├── tsconfig.json
│ │ ├── tsup.config.ts
│ │ └── vitest.config.ts
│ ├── mcp-apps-middleware/
│ │ ├── .gitignore
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── __tests__/
│ │ │ ├── mcp-apps-middleware.test.ts
│ │ │ └── test-utils.ts
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ └── middleware-starter/
│ ├── .gitignore
│ ├── .npmignore
│ ├── README.md
│ ├── package.json
│ ├── src/
│ │ └── index.ts
│ ├── tsconfig.json
│ ├── tsdown.config.ts
│ └── vitest.config.ts
├── nx.json
├── package.json
├── pnpm-workspace.yaml
├── render.yaml
├── scripts/
│ ├── check-codeowners-auth.ts
│ └── rewrite-python-preview-versions.py
└── sdks/
├── community/
│ ├── dart/
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── TEST_GUIDE.md
│ │ ├── analysis_options.yaml
│ │ ├── example/
│ │ │ ├── README.md
│ │ │ ├── analysis_options.yaml
│ │ │ ├── dart_output_with_tools.json
│ │ │ ├── dart_output_with_tools_fixed.json
│ │ │ └── pubspec.yaml
│ │ ├── lib/
│ │ │ ├── ag_ui.dart
│ │ │ └── src/
│ │ │ ├── client/
│ │ │ │ ├── client.dart
│ │ │ │ ├── config.dart
│ │ │ │ ├── errors.dart
│ │ │ │ └── validators.dart
│ │ │ ├── encoder/
│ │ │ │ ├── client_codec.dart
│ │ │ │ ├── decoder.dart
│ │ │ │ ├── encoder.dart
│ │ │ │ ├── errors.dart
│ │ │ │ └── stream_adapter.dart
│ │ │ ├── events/
│ │ │ │ ├── event_type.dart
│ │ │ │ └── events.dart
│ │ │ ├── sse/
│ │ │ │ ├── backoff_strategy.dart
│ │ │ │ ├── sse_client.dart
│ │ │ │ ├── sse_message.dart
│ │ │ │ └── sse_parser.dart
│ │ │ └── types/
│ │ │ ├── base.dart
│ │ │ ├── context.dart
│ │ │ ├── message.dart
│ │ │ ├── tool.dart
│ │ │ └── types.dart
│ │ ├── pubspec.yaml
│ │ └── test/
│ │ ├── ag_ui_test.dart
│ │ ├── client/
│ │ │ ├── client_test.dart
│ │ │ ├── config_test.dart
│ │ │ ├── config_test.dill
│ │ │ ├── errors_test.dart
│ │ │ ├── http_endpoints_test.dart
│ │ │ └── validators_test.dart
│ │ ├── encoder/
│ │ │ ├── client_codec_test.dart
│ │ │ ├── decoder_test.dart
│ │ │ ├── encoder_test.dart
│ │ │ ├── errors_test.dart
│ │ │ └── stream_adapter_test.dart
│ │ ├── events/
│ │ │ ├── event_test.dart
│ │ │ └── event_type_test.dart
│ │ ├── fixtures/
│ │ │ ├── events.json
│ │ │ └── sse_streams.txt
│ │ ├── integration/
│ │ │ ├── event_decoding_integration_test.dart
│ │ │ ├── fixtures_integration_test.dart
│ │ │ └── helpers/
│ │ │ └── test_helpers.dart
│ │ ├── sse/
│ │ │ ├── backoff_strategy_test.dart
│ │ │ ├── sse_client_basic_test.dart
│ │ │ ├── sse_client_stream_test.dart
│ │ │ ├── sse_client_test.dart.skip
│ │ │ ├── sse_message_test.dart
│ │ │ └── sse_parser_test.dart
│ │ └── types/
│ │ ├── base_test.dart
│ │ ├── message_test.dart
│ │ └── tool_context_test.dart
│ ├── go/
│ │ ├── .gitignore
│ │ ├── example/
│ │ │ ├── client/
│ │ │ │ ├── cmd/
│ │ │ │ │ └── main.go
│ │ │ │ ├── go.mod
│ │ │ │ ├── go.sum
│ │ │ │ └── internal/
│ │ │ │ ├── agent/
│ │ │ │ │ └── chat.go
│ │ │ │ ├── event/
│ │ │ │ │ └── parse.go
│ │ │ │ ├── message/
│ │ │ │ │ └── message.go
│ │ │ │ └── ui/
│ │ │ │ ├── model.go
│ │ │ │ ├── splash.go
│ │ │ │ ├── theme.go
│ │ │ │ └── typing.go
│ │ │ └── server/
│ │ │ ├── cmd/
│ │ │ │ └── main.go
│ │ │ ├── go.mod
│ │ │ ├── go.sum
│ │ │ └── internal/
│ │ │ ├── agentic/
│ │ │ │ ├── agentic.go
│ │ │ │ ├── agentic_integration_test.go
│ │ │ │ ├── data/
│ │ │ │ │ ├── languages_prompt.md
│ │ │ │ │ └── reminder.md
│ │ │ │ └── handler.go
│ │ │ ├── config/
│ │ │ │ └── config.go
│ │ │ ├── mcp/
│ │ │ │ ├── adapter.go
│ │ │ │ └── server.go
│ │ │ └── routes/
│ │ │ └── routes.go
│ │ ├── go.mod
│ │ ├── go.sum
│ │ └── pkg/
│ │ ├── client/
│ │ │ └── sse/
│ │ │ ├── client.go
│ │ │ ├── client_stream_test.go
│ │ │ └── client_test.go
│ │ ├── core/
│ │ │ ├── events/
│ │ │ │ ├── activity_events.go
│ │ │ │ ├── activity_events_test.go
│ │ │ │ ├── additional_events_test.go
│ │ │ │ ├── custom_events.go
│ │ │ │ ├── decoder.go
│ │ │ │ ├── decoder_test.go
│ │ │ │ ├── events.go
│ │ │ │ ├── events_test.go
│ │ │ │ ├── id_utils.go
│ │ │ │ ├── id_utils_test.go
│ │ │ │ ├── message_events.go
│ │ │ │ ├── reasoning_events.go
│ │ │ │ ├── run_events.go
│ │ │ │ ├── state_events.go
│ │ │ │ ├── state_events_test.go
│ │ │ │ ├── thinking_events.go
│ │ │ │ ├── thinking_events_test.go
│ │ │ │ └── tool_events.go
│ │ │ └── types/
│ │ │ ├── message_helpers.go
│ │ │ ├── types.go
│ │ │ └── types_test.go
│ │ ├── encoding/
│ │ │ ├── buffer_sizing.go
│ │ │ ├── encoder/
│ │ │ │ └── encoder.go
│ │ │ ├── errors.go
│ │ │ ├── interface.go
│ │ │ ├── json/
│ │ │ │ ├── json.go
│ │ │ │ ├── json_codec.go
│ │ │ │ ├── json_decoder.go
│ │ │ │ └── json_encoder.go
│ │ │ ├── negotiation/
│ │ │ │ ├── negotiator.go
│ │ │ │ ├── negotiator_test.go
│ │ │ │ ├── parser.go
│ │ │ │ └── selector.go
│ │ │ ├── pool.go
│ │ │ └── sse/
│ │ │ ├── writer.go
│ │ │ └── writer_test.go
│ │ └── errors/
│ │ ├── error_types.go
│ │ └── error_utils.go
│ ├── java/
│ │ ├── .gitignore
│ │ ├── CLAUDE.md
│ │ ├── LICENSE
│ │ ├── README.md
│ │ ├── clients/
│ │ │ ├── ok-http/
│ │ │ │ ├── README.md
│ │ │ │ ├── pom.xml
│ │ │ │ └── src/
│ │ │ │ ├── main/
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── okhttp/
│ │ │ │ │ └── HttpClient.java
│ │ │ │ └── test/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── okhttp/
│ │ │ │ └── HttpClientTest.java
│ │ │ └── spring-client/
│ │ │ ├── pom.xml
│ │ │ └── src/
│ │ │ └── main/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── spring/
│ │ │ └── HttpClient.java
│ │ ├── examples/
│ │ │ ├── copilot-app/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── README.md
│ │ │ │ ├── eslint.config.mjs
│ │ │ │ ├── next.config.ts
│ │ │ │ ├── package.json
│ │ │ │ ├── postcss.config.mjs
│ │ │ │ ├── src/
│ │ │ │ │ └── app/
│ │ │ │ │ ├── api/
│ │ │ │ │ │ └── copilotkit/
│ │ │ │ │ │ └── route.ts
│ │ │ │ │ ├── globals.css
│ │ │ │ │ ├── layout.tsx
│ │ │ │ │ └── page.tsx
│ │ │ │ └── tsconfig.json
│ │ │ └── spring-ai-example/
│ │ │ ├── .gitignore
│ │ │ ├── Dockerfile
│ │ │ ├── docker-compose.yml
│ │ │ ├── pom.xml
│ │ │ └── src/
│ │ │ └── main/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── example/
│ │ │ ├── AgUiController.java
│ │ │ ├── Application.java
│ │ │ ├── config/
│ │ │ │ ├── AgUiConfig.java
│ │ │ │ └── CorsConfig.java
│ │ │ └── tools/
│ │ │ ├── GeocodingResponse.java
│ │ │ ├── WeatherRequest.java
│ │ │ ├── WeatherResponse.java
│ │ │ ├── WeatherTool.java
│ │ │ └── WeatherToolResult.java
│ │ ├── integrations/
│ │ │ └── spring-ai/
│ │ │ ├── README.md
│ │ │ ├── pom.xml
│ │ │ └── src/
│ │ │ ├── main/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── spring/
│ │ │ │ └── ai/
│ │ │ │ ├── AgUiFunctionToolCallback.java
│ │ │ │ ├── AgUiToolCallbackParams.java
│ │ │ │ ├── SpringAIAgent.java
│ │ │ │ ├── StateTool.java
│ │ │ │ └── ToolMapper.java
│ │ │ └── test/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── spring/
│ │ │ └── ai/
│ │ │ └── ToolMapperTest.java
│ │ ├── packages/
│ │ │ ├── README.md
│ │ │ ├── client/
│ │ │ │ ├── README.md
│ │ │ │ ├── pom.xml
│ │ │ │ └── src/
│ │ │ │ ├── main/
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── client/
│ │ │ │ │ ├── agent/
│ │ │ │ │ │ └── AbstractAgent.java
│ │ │ │ │ ├── message/
│ │ │ │ │ │ └── MessageFactory.java
│ │ │ │ │ └── verifier/
│ │ │ │ │ └── EventVerifier.java
│ │ │ │ └── test/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── client/
│ │ │ │ ├── agent/
│ │ │ │ │ └── AbstractAgentTest.java
│ │ │ │ ├── message/
│ │ │ │ │ └── MessageFactoryTest.java
│ │ │ │ └── verifier/
│ │ │ │ └── EventVerifierTest.java
│ │ │ ├── core/
│ │ │ │ ├── README.md
│ │ │ │ ├── pom.xml
│ │ │ │ └── src/
│ │ │ │ ├── main/
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── core/
│ │ │ │ │ ├── agent/
│ │ │ │ │ │ ├── Agent.java
│ │ │ │ │ │ ├── AgentSubscriber.java
│ │ │ │ │ │ ├── AgentSubscriberParams.java
│ │ │ │ │ │ ├── RunAgentInput.java
│ │ │ │ │ │ └── RunAgentParameters.java
│ │ │ │ │ ├── context/
│ │ │ │ │ │ └── Context.java
│ │ │ │ │ ├── event/
│ │ │ │ │ │ ├── BaseEvent.java
│ │ │ │ │ │ ├── CustomEvent.java
│ │ │ │ │ │ ├── MessagesSnapshotEvent.java
│ │ │ │ │ │ ├── RawEvent.java
│ │ │ │ │ │ ├── RunErrorEvent.java
│ │ │ │ │ │ ├── RunFinishedEvent.java
│ │ │ │ │ │ ├── RunStartedEvent.java
│ │ │ │ │ │ ├── StateDeltaEvent.java
│ │ │ │ │ │ ├── StateSnapshotEvent.java
│ │ │ │ │ │ ├── StepFinishedEvent.java
│ │ │ │ │ │ ├── StepStartedEvent.java
│ │ │ │ │ │ ├── TextMessageChunkEvent.java
│ │ │ │ │ │ ├── TextMessageContentEvent.java
│ │ │ │ │ │ ├── TextMessageEndEvent.java
│ │ │ │ │ │ ├── TextMessageStartEvent.java
│ │ │ │ │ │ ├── ThinkingEndEvent.java
│ │ │ │ │ │ ├── ThinkingStartEvent.java
│ │ │ │ │ │ ├── ThinkingTextMessageContentEvent.java
│ │ │ │ │ │ ├── ThinkingTextMessageEndEvent.java
│ │ │ │ │ │ ├── ThinkingTextMessageStartEvent.java
│ │ │ │ │ │ ├── ToolCallArgsEvent.java
│ │ │ │ │ │ ├── ToolCallChunkEvent.java
│ │ │ │ │ │ ├── ToolCallEndEvent.java
│ │ │ │ │ │ ├── ToolCallResultEvent.java
│ │ │ │ │ │ └── ToolCallStartEvent.java
│ │ │ │ │ ├── exception/
│ │ │ │ │ │ └── AGUIException.java
│ │ │ │ │ ├── function/
│ │ │ │ │ │ └── FunctionCall.java
│ │ │ │ │ ├── message/
│ │ │ │ │ │ ├── AssistantMessage.java
│ │ │ │ │ │ ├── BaseMessage.java
│ │ │ │ │ │ ├── DeveloperMessage.java
│ │ │ │ │ │ ├── Role.java
│ │ │ │ │ │ ├── SystemMessage.java
│ │ │ │ │ │ ├── ToolMessage.java
│ │ │ │ │ │ └── UserMessage.java
│ │ │ │ │ ├── state/
│ │ │ │ │ │ └── State.java
│ │ │ │ │ ├── stream/
│ │ │ │ │ │ ├── EventStream.java
│ │ │ │ │ │ └── IEventStream.java
│ │ │ │ │ ├── subscription/
│ │ │ │ │ │ └── Subscription.java
│ │ │ │ │ ├── tool/
│ │ │ │ │ │ ├── Tool.java
│ │ │ │ │ │ └── ToolCall.java
│ │ │ │ │ └── type/
│ │ │ │ │ └── EventType.java
│ │ │ │ └── test/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── core/
│ │ │ │ ├── agent/
│ │ │ │ │ ├── AgentSubscriberParamsTest.java
│ │ │ │ │ ├── AgentSubscriberTest.java
│ │ │ │ │ ├── RunAgentInputTest.java
│ │ │ │ │ └── RunAgentParametersTest.java
│ │ │ │ ├── context/
│ │ │ │ │ └── ContextTest.java
│ │ │ │ ├── event/
│ │ │ │ │ ├── BaseEventTest.java
│ │ │ │ │ ├── CustomEventTest.java
│ │ │ │ │ ├── MessagesSnapshotEventTest.java
│ │ │ │ │ ├── RawEventTest.java
│ │ │ │ │ ├── RunErrorEventTest.java
│ │ │ │ │ ├── RunFinishedEventTest.java
│ │ │ │ │ ├── RunStartedEventTest.java
│ │ │ │ │ ├── StateDeltaEventTest.java
│ │ │ │ │ ├── StateSnapshotEventTest.java
│ │ │ │ │ ├── StepFinishedEventTest.java
│ │ │ │ │ ├── StepStartedEventTest.java
│ │ │ │ │ ├── TextMessageChunkEventTest.java
│ │ │ │ │ ├── TextMessageContentEventTest.java
│ │ │ │ │ ├── TextMessageEndEventTest.java
│ │ │ │ │ ├── TextMessageStartEventTest.java
│ │ │ │ │ ├── ThinkingEndEventTest.java
│ │ │ │ │ ├── ThinkingStartEventTest.java
│ │ │ │ │ ├── ThinkingTextMessageContentEventTest.java
│ │ │ │ │ ├── ThinkingTextMessageEndEventTest.java
│ │ │ │ │ ├── ThinkingTextMessageStartEventTest.java
│ │ │ │ │ ├── ToolCallArgsEventTest.java
│ │ │ │ │ ├── ToolCallChunkEventTest.java
│ │ │ │ │ ├── ToolCallEndEventTest.java
│ │ │ │ │ ├── ToolCallResultEventTest.java
│ │ │ │ │ └── ToolCallStartEventTest.java
│ │ │ │ ├── exception/
│ │ │ │ │ └── AGUIExceptionTest.java
│ │ │ │ ├── function/
│ │ │ │ │ └── FunctionCallTest.java
│ │ │ │ ├── message/
│ │ │ │ │ ├── AssistantMessageTest.java
│ │ │ │ │ ├── DeveloperMessageTest.java
│ │ │ │ │ ├── SystemMessageTest.java
│ │ │ │ │ ├── ToolMessageTest.java
│ │ │ │ │ └── UserMessageTest.java
│ │ │ │ ├── state/
│ │ │ │ │ └── StateTest.java
│ │ │ │ ├── stream/
│ │ │ │ │ ├── EventStreamTest.java
│ │ │ │ │ └── IEventStreamTest.java
│ │ │ │ ├── subscription/
│ │ │ │ │ └── SubscriptionTest.java
│ │ │ │ ├── tool/
│ │ │ │ │ ├── ToolCallTest.java
│ │ │ │ │ └── ToolTest.java
│ │ │ │ └── type/
│ │ │ │ └── EventTypeTest.java
│ │ │ ├── http/
│ │ │ │ ├── README.md
│ │ │ │ ├── pom.xml
│ │ │ │ └── src/
│ │ │ │ ├── main/
│ │ │ │ │ └── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── http/
│ │ │ │ │ ├── BaseHttpClient.java
│ │ │ │ │ └── HttpAgent.java
│ │ │ │ └── test/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── http/
│ │ │ │ ├── BaseHttpClientTest.java
│ │ │ │ └── HttpAgentTest.java
│ │ │ └── server/
│ │ │ ├── README.md
│ │ │ ├── pom.xml
│ │ │ └── src/
│ │ │ ├── main/
│ │ │ │ └── java/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── server/
│ │ │ │ ├── EventFactory.java
│ │ │ │ ├── LocalAgent.java
│ │ │ │ └── streamer/
│ │ │ │ └── AgentStreamer.java
│ │ │ └── test/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── server/
│ │ │ ├── EventFactoryTest.java
│ │ │ ├── LocalAgentTest.java
│ │ │ └── streamer/
│ │ │ └── AgentStreamerTest.java
│ │ ├── pom.xml
│ │ ├── servers/
│ │ │ └── spring/
│ │ │ ├── README.md
│ │ │ ├── pom.xml
│ │ │ └── src/
│ │ │ ├── main/
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── server/
│ │ │ │ │ └── spring/
│ │ │ │ │ ├── AgUiAutoConfiguration.java
│ │ │ │ │ ├── AgUiParameters.java
│ │ │ │ │ └── AgUiService.java
│ │ │ │ └── resources/
│ │ │ │ └── META-INF/
│ │ │ │ ├── spring/
│ │ │ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports
│ │ │ │ └── spring.factories
│ │ │ └── test/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── server/
│ │ │ └── spring/
│ │ │ └── AgUiParametersTest.java
│ │ └── utils/
│ │ └── json/
│ │ ├── README.md
│ │ ├── pom.xml
│ │ └── src/
│ │ ├── main/
│ │ │ └── java/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── json/
│ │ │ ├── ObjectMapperFactory.java
│ │ │ └── mixins/
│ │ │ ├── EventMixin.java
│ │ │ ├── MessageMixin.java
│ │ │ └── StateMixin.java
│ │ └── test/
│ │ └── java/
│ │ └── com/
│ │ └── agui/
│ │ └── json/
│ │ └── ObjectMapperFactoryTest.java
│ ├── kotlin/
│ │ ├── .gitignore
│ │ ├── CHANGELOG.md
│ │ ├── LICENSE
│ │ ├── OVERVIEW.md
│ │ ├── PERFORMANCE.md
│ │ ├── README.md
│ │ ├── build.bat
│ │ ├── build.gradle.kts
│ │ ├── build.sh
│ │ ├── detekt-config.yml
│ │ ├── examples/
│ │ │ ├── chatapp/
│ │ │ │ ├── .gitignore
│ │ │ │ ├── CHANGELOG.md
│ │ │ │ ├── README.md
│ │ │ │ ├── androidApp/
│ │ │ │ │ ├── build.gradle.kts
│ │ │ │ │ └── src/
│ │ │ │ │ └── main/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ ├── assets/
│ │ │ │ │ │ └── logback.xml
│ │ │ │ │ └── res/
│ │ │ │ │ ├── drawable/
│ │ │ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ │ │ ├── mipmap-anydpi/
│ │ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ │ └── values/
│ │ │ │ │ └── strings.xml
│ │ │ │ ├── build.gradle.kts
│ │ │ │ ├── desktopApp/
│ │ │ │ │ └── build.gradle.kts
│ │ │ │ ├── gradle/
│ │ │ │ │ ├── libs.versions.toml
│ │ │ │ │ └── wrapper/
│ │ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ │ └── gradle-wrapper.properties
│ │ │ │ ├── gradle.properties
│ │ │ │ ├── gradlew
│ │ │ │ ├── gradlew.bat
│ │ │ │ ├── iosApp/
│ │ │ │ │ ├── README.md
│ │ │ │ │ ├── iosApp/
│ │ │ │ │ │ ├── Assets.xcassets/
│ │ │ │ │ │ │ ├── AccentColor.colorset/
│ │ │ │ │ │ │ │ └── Contents.json
│ │ │ │ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ │ │ │ └── Contents.json
│ │ │ │ │ │ │ └── Contents.json
│ │ │ │ │ │ ├── ContentView.swift
│ │ │ │ │ │ ├── Info.plist
│ │ │ │ │ │ └── iOSApp.swift
│ │ │ │ │ └── iosApp.xcodeproj/
│ │ │ │ │ ├── project.pbxproj
│ │ │ │ │ └── project.xcworkspace/
│ │ │ │ │ └── contents.xcworkspacedata
│ │ │ │ ├── settings.gradle.kts
│ │ │ │ ├── shared/
│ │ │ │ │ ├── build.gradle.kts
│ │ │ │ │ └── src/
│ │ │ │ │ ├── androidInstrumentedTest/
│ │ │ │ │ │ └── kotlin/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ ├── AndroidIntegrationTest.kt
│ │ │ │ │ │ ├── AndroidSettingsTest.kt
│ │ │ │ │ │ ├── MinimalAndroidTest.kt
│ │ │ │ │ │ └── ui/
│ │ │ │ │ │ ├── MessageBubbleTest.kt
│ │ │ │ │ │ └── components/
│ │ │ │ │ │ └── MessageBubbleComponentTest.kt
│ │ │ │ │ ├── androidMain/
│ │ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ │ └── kotlin/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ └── MainActivity.kt
│ │ │ │ │ ├── commonMain/
│ │ │ │ │ │ ├── composeResources/
│ │ │ │ │ │ │ └── values/
│ │ │ │ │ │ │ └── strings.xml
│ │ │ │ │ │ └── kotlin/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ ├── App.kt
│ │ │ │ │ │ ├── ui/
│ │ │ │ │ │ │ ├── screens/
│ │ │ │ │ │ │ │ ├── chat/
│ │ │ │ │ │ │ │ │ ├── ChatScreen.kt
│ │ │ │ │ │ │ │ │ ├── ChatViewModel.kt
│ │ │ │ │ │ │ │ │ └── components/
│ │ │ │ │ │ │ │ │ ├── ChatHeader.kt
│ │ │ │ │ │ │ │ │ ├── ChatInput.kt
│ │ │ │ │ │ │ │ │ ├── ClawgUiPairingDialog.kt
│ │ │ │ │ │ │ │ │ ├── MessageBubble.kt
│ │ │ │ │ │ │ │ │ └── MessageList.kt
│ │ │ │ │ │ │ │ └── settings/
│ │ │ │ │ │ │ │ ├── SettingsScreen.kt
│ │ │ │ │ │ │ │ ├── SettingsViewModel.kt
│ │ │ │ │ │ │ │ └── components/
│ │ │ │ │ │ │ │ ├── AddAgentDialog.kt
│ │ │ │ │ │ │ │ └── AgentCard.kt
│ │ │ │ │ │ │ └── theme/
│ │ │ │ │ │ │ ├── Color.kt
│ │ │ │ │ │ │ └── Theme.kt
│ │ │ │ │ │ └── util/
│ │ │ │ │ │ └── Extensions.kt
│ │ │ │ │ ├── commonTest/
│ │ │ │ │ │ └── kotlin/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ ├── auth/
│ │ │ │ │ │ │ └── AuthProviderTest.kt
│ │ │ │ │ │ ├── test/
│ │ │ │ │ │ │ └── TestSettings.kt
│ │ │ │ │ │ └── viewmodel/
│ │ │ │ │ │ └── ChatViewModelBehaviorTest.kt
│ │ │ │ │ ├── desktopMain/
│ │ │ │ │ │ └── kotlin/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ └── Main.kt
│ │ │ │ │ ├── desktopTest/
│ │ │ │ │ │ └── kotlin/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ ├── auth/
│ │ │ │ │ │ │ └── AuthManagerIntegrationTest.kt
│ │ │ │ │ │ └── repository/
│ │ │ │ │ │ └── AgentRepositoryPersistenceTest.kt
│ │ │ │ │ ├── iosMain/
│ │ │ │ │ │ └── kotlin/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── example/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ └── MainViewController.kt
│ │ │ │ │ └── iosTest/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── example/
│ │ │ │ │ └── chatapp/
│ │ │ │ │ ├── IosPlatformTest.kt
│ │ │ │ │ ├── IosSettingsTest.kt
│ │ │ │ │ └── IosUserIdManagerTest.kt
│ │ │ │ └── verify-ios-implementation.sh
│ │ │ ├── chatapp-java/
│ │ │ │ ├── README.md
│ │ │ │ ├── app/
│ │ │ │ │ ├── build.gradle
│ │ │ │ │ ├── proguard-rules.pro
│ │ │ │ │ └── src/
│ │ │ │ │ ├── androidTest/
│ │ │ │ │ │ └── java/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ └── java/
│ │ │ │ │ │ ├── MultiAgentInstrumentedTest.java
│ │ │ │ │ │ └── ui/
│ │ │ │ │ │ ├── ChatActivityTest.java
│ │ │ │ │ │ ├── SettingsActivityTest.java
│ │ │ │ │ │ └── SettingsActivityTest.java.old
│ │ │ │ │ └── main/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ ├── java/
│ │ │ │ │ │ └── com/
│ │ │ │ │ │ └── agui/
│ │ │ │ │ │ └── chatapp/
│ │ │ │ │ │ └── java/
│ │ │ │ │ │ ├── ChatJavaApplication.java
│ │ │ │ │ │ ├── model/
│ │ │ │ │ │ │ └── ChatMessage.java
│ │ │ │ │ │ ├── repository/
│ │ │ │ │ │ │ └── MultiAgentRepository.kt
│ │ │ │ │ │ ├── ui/
│ │ │ │ │ │ │ ├── ChatActivity.java
│ │ │ │ │ │ │ ├── SettingsActivity.java
│ │ │ │ │ │ │ └── adapter/
│ │ │ │ │ │ │ ├── AgentListAdapter.java
│ │ │ │ │ │ │ └── MessageAdapter.java
│ │ │ │ │ │ └── viewmodel/
│ │ │ │ │ │ └── ChatViewModel.kt
│ │ │ │ │ └── res/
│ │ │ │ │ ├── drawable/
│ │ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ │ │ ├── layout/
│ │ │ │ │ │ ├── activity_chat.xml
│ │ │ │ │ │ ├── activity_settings.xml
│ │ │ │ │ │ ├── dialog_agent_form.xml
│ │ │ │ │ │ ├── item_agent_card.xml
│ │ │ │ │ │ ├── item_message_assistant.xml
│ │ │ │ │ │ ├── item_message_system.xml
│ │ │ │ │ │ └── item_message_user.xml
│ │ │ │ │ ├── menu/
│ │ │ │ │ │ └── chat_menu.xml
│ │ │ │ │ ├── mipmap-anydpi-v26/
│ │ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ │ ├── values/
│ │ │ │ │ │ ├── colors.xml
│ │ │ │ │ │ ├── strings.xml
│ │ │ │ │ │ └── themes.xml
│ │ │ │ │ ├── values-night/
│ │ │ │ │ │ └── themes.xml
│ │ │ │ │ └── xml/
│ │ │ │ │ ├── backup_rules.xml
│ │ │ │ │ └── data_extraction_rules.xml
│ │ │ │ ├── build.gradle
│ │ │ │ ├── gradle/
│ │ │ │ │ ├── libs.versions.toml
│ │ │ │ │ └── wrapper/
│ │ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ │ └── gradle-wrapper.properties
│ │ │ │ ├── gradle.properties
│ │ │ │ ├── gradlew
│ │ │ │ ├── gradlew.bat
│ │ │ │ └── settings.gradle
│ │ │ ├── chatapp-shared/
│ │ │ │ ├── README.md
│ │ │ │ ├── build.gradle.kts
│ │ │ │ ├── gradle.properties
│ │ │ │ ├── settings.gradle.kts
│ │ │ │ └── src/
│ │ │ │ ├── androidMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── example/
│ │ │ │ │ └── chatapp/
│ │ │ │ │ ├── data/
│ │ │ │ │ │ └── pairing/
│ │ │ │ │ │ └── PairingHttpClientFactory.kt
│ │ │ │ │ └── util/
│ │ │ │ │ └── AndroidPlatform.kt
│ │ │ │ ├── commonMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── example/
│ │ │ │ │ ├── chatapp/
│ │ │ │ │ │ ├── chat/
│ │ │ │ │ │ │ ├── ChatAgent.kt
│ │ │ │ │ │ │ └── ChatController.kt
│ │ │ │ │ │ ├── data/
│ │ │ │ │ │ │ ├── auth/
│ │ │ │ │ │ │ │ ├── ApiKeyAuthProvider.kt
│ │ │ │ │ │ │ │ ├── AuthManager.kt
│ │ │ │ │ │ │ │ ├── AuthProvider.kt
│ │ │ │ │ │ │ │ ├── BasicAuthProvider.kt
│ │ │ │ │ │ │ │ └── BearerTokenAuthProvider.kt
│ │ │ │ │ │ │ ├── model/
│ │ │ │ │ │ │ │ ├── AgentConfig.kt
│ │ │ │ │ │ │ │ ├── AuthMethod.kt
│ │ │ │ │ │ │ │ └── ClawgUiPairingResponse.kt
│ │ │ │ │ │ │ ├── pairing/
│ │ │ │ │ │ │ │ ├── ClawgUiPairingService.kt
│ │ │ │ │ │ │ │ └── PairingHttpClientFactory.kt
│ │ │ │ │ │ │ └── repository/
│ │ │ │ │ │ │ └── AgentRepository.kt
│ │ │ │ │ │ └── util/
│ │ │ │ │ │ ├── Platform.kt
│ │ │ │ │ │ ├── StringResourceProvider.kt
│ │ │ │ │ │ └── UserIdManager.kt
│ │ │ │ │ └── tools/
│ │ │ │ │ └── ChangeBackgroundToolExecutor.kt
│ │ │ │ ├── commonTest/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── example/
│ │ │ │ │ └── chatapp/
│ │ │ │ │ ├── chat/
│ │ │ │ │ │ └── ChatControllerTest.kt
│ │ │ │ │ ├── data/
│ │ │ │ │ │ ├── AgentRepositoryTest.kt
│ │ │ │ │ │ ├── AuthManagerTest.kt
│ │ │ │ │ │ └── pairing/
│ │ │ │ │ │ └── ClawgUiPairingServiceTest.kt
│ │ │ │ │ └── testutil/
│ │ │ │ │ └── FakeSettings.kt
│ │ │ │ ├── desktopMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── example/
│ │ │ │ │ └── chatapp/
│ │ │ │ │ ├── data/
│ │ │ │ │ │ └── pairing/
│ │ │ │ │ │ └── PairingHttpClientFactory.kt
│ │ │ │ │ └── util/
│ │ │ │ │ └── DesktopPlatform.kt
│ │ │ │ └── iosMain/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── example/
│ │ │ │ └── chatapp/
│ │ │ │ ├── data/
│ │ │ │ │ └── pairing/
│ │ │ │ │ └── PairingHttpClientFactory.kt
│ │ │ │ └── util/
│ │ │ │ └── IosPlatform.kt
│ │ │ ├── chatapp-swiftui/
│ │ │ │ ├── README.md
│ │ │ │ ├── build.gradle.kts
│ │ │ │ ├── gradle/
│ │ │ │ │ ├── libs.versions.toml
│ │ │ │ │ └── wrapper/
│ │ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ │ └── gradle-wrapper.properties
│ │ │ │ ├── gradle.properties
│ │ │ │ ├── gradlew
│ │ │ │ ├── gradlew.bat
│ │ │ │ ├── iosApp/
│ │ │ │ │ ├── ChatAppSwiftUI.xcodeproj/
│ │ │ │ │ │ ├── project.pbxproj
│ │ │ │ │ │ └── project.xcworkspace/
│ │ │ │ │ │ ├── contents.xcworkspacedata
│ │ │ │ │ │ └── xcshareddata/
│ │ │ │ │ │ └── swiftpm/
│ │ │ │ │ │ └── Package.resolved
│ │ │ │ │ ├── Resources/
│ │ │ │ │ │ ├── Assets.xcassets/
│ │ │ │ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ │ │ │ └── Contents.json
│ │ │ │ │ │ │ └── Contents.json
│ │ │ │ │ │ ├── Info.plist
│ │ │ │ │ │ └── LaunchScreen.storyboard
│ │ │ │ │ ├── Sources/
│ │ │ │ │ │ ├── App/
│ │ │ │ │ │ │ └── ChatAppSwiftUIApp.swift
│ │ │ │ │ │ ├── Store/
│ │ │ │ │ │ │ └── ChatAppStore.swift
│ │ │ │ │ │ └── Views/
│ │ │ │ │ │ ├── AgentFormView.swift
│ │ │ │ │ │ ├── ChatView.swift
│ │ │ │ │ │ ├── Components/
│ │ │ │ │ │ │ └── AgentListView.swift
│ │ │ │ │ │ └── RootView.swift
│ │ │ │ │ └── project.yml
│ │ │ │ ├── settings.gradle.kts
│ │ │ │ └── shared/
│ │ │ │ ├── build.gradle.kts
│ │ │ │ └── src/
│ │ │ │ └── commonMain/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── example/
│ │ │ │ └── chatapp/
│ │ │ │ └── bridge/
│ │ │ │ └── SwiftBridge.kt
│ │ │ ├── chatapp-wearos/
│ │ │ │ ├── README.md
│ │ │ │ ├── build.gradle.kts
│ │ │ │ ├── gradle/
│ │ │ │ │ ├── libs.versions.toml
│ │ │ │ │ └── wrapper/
│ │ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ │ └── gradle-wrapper.properties
│ │ │ │ ├── gradle.properties
│ │ │ │ ├── gradlew
│ │ │ │ ├── gradlew.bat
│ │ │ │ ├── settings.gradle.kts
│ │ │ │ └── wearApp/
│ │ │ │ ├── build.gradle.kts
│ │ │ │ └── src/
│ │ │ │ └── main/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── java/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── example/
│ │ │ │ │ └── chatwear/
│ │ │ │ │ ├── MainActivity.kt
│ │ │ │ │ └── ui/
│ │ │ │ │ ├── ChatWearApp.kt
│ │ │ │ │ ├── WearChatViewModel.kt
│ │ │ │ │ └── theme/
│ │ │ │ │ └── ChatWearTheme.kt
│ │ │ │ └── res/
│ │ │ │ ├── drawable/
│ │ │ │ │ ├── ic_launcher_background.xml
│ │ │ │ │ └── ic_launcher_foreground.xml
│ │ │ │ ├── mipmap-anydpi/
│ │ │ │ │ ├── ic_launcher.xml
│ │ │ │ │ └── ic_launcher_round.xml
│ │ │ │ └── values/
│ │ │ │ ├── colors.xml
│ │ │ │ ├── strings.xml
│ │ │ │ └── themes.xml
│ │ │ └── tools/
│ │ │ ├── build.gradle.kts
│ │ │ ├── gradle/
│ │ │ │ ├── libs.versions.toml
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ ├── settings.gradle.kts
│ │ │ └── src/
│ │ │ ├── androidMain/
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── example/
│ │ │ │ └── tools/
│ │ │ │ └── AndroidLocationProvider.kt
│ │ │ ├── commonMain/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── example/
│ │ │ │ └── tools/
│ │ │ │ ├── ChangeBackgroundToolExecutor.kt
│ │ │ │ └── CurrentLocationToolExecutor.kt
│ │ │ ├── commonTest/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── example/
│ │ │ │ └── tools/
│ │ │ │ ├── CurrentLocationToolTest.kt
│ │ │ │ └── ExampleToolsIntegrationTest.kt
│ │ │ ├── iosMain/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── example/
│ │ │ │ └── tools/
│ │ │ │ └── IosLocationProvider.kt
│ │ │ ├── iosTest/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── example/
│ │ │ │ └── tools/
│ │ │ │ ├── IosLocationIntegrationTest.kt
│ │ │ │ └── IosLocationProviderTest.kt
│ │ │ └── jvmMain/
│ │ │ └── kotlin/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── example/
│ │ │ └── tools/
│ │ │ └── JvmLocationProvider.kt
│ │ ├── gradle.properties
│ │ ├── library/
│ │ │ ├── .gitignore
│ │ │ ├── README.md
│ │ │ ├── build.gradle.kts
│ │ │ ├── client/
│ │ │ │ ├── build.gradle.kts
│ │ │ │ ├── consumer-rules.pro
│ │ │ │ └── src/
│ │ │ │ ├── androidMain/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── client/
│ │ │ │ │ └── agent/
│ │ │ │ │ └── HttpClientFactory.kt
│ │ │ │ ├── commonMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── client/
│ │ │ │ │ ├── AgUiAgent.kt
│ │ │ │ │ ├── ClientStateManager.kt
│ │ │ │ │ ├── StatefulAgUiAgent.kt
│ │ │ │ │ ├── agent/
│ │ │ │ │ │ ├── AbstractAgent.kt
│ │ │ │ │ │ ├── AgentSubscriber.kt
│ │ │ │ │ │ ├── HttpAgent.kt
│ │ │ │ │ │ └── HttpClientFactory.kt
│ │ │ │ │ ├── builders/
│ │ │ │ │ │ └── AgentBuilders.kt
│ │ │ │ │ ├── chunks/
│ │ │ │ │ │ └── ChunkTransform.kt
│ │ │ │ │ ├── sse/
│ │ │ │ │ │ └── SseParser.kt
│ │ │ │ │ ├── state/
│ │ │ │ │ │ ├── DefaultApplyEvents.kt
│ │ │ │ │ │ ├── JsonPointer.kt
│ │ │ │ │ │ ├── StateHandler.kt
│ │ │ │ │ │ └── StateManager.kt
│ │ │ │ │ ├── tools/
│ │ │ │ │ │ └── ClientToolResponseHandler.kt
│ │ │ │ │ └── verify/
│ │ │ │ │ └── EventVerifier.kt
│ │ │ │ ├── commonTest/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── client/
│ │ │ │ │ ├── AgUiAgentConfigTest.kt
│ │ │ │ │ ├── AgUiAgentToolsTest.kt
│ │ │ │ │ ├── IntegrationTest.kt
│ │ │ │ │ ├── StatefulAgUiAgentConfigTest.kt
│ │ │ │ │ ├── StatefulAgUiAgentTest.kt
│ │ │ │ │ ├── UserIdTest.kt
│ │ │ │ │ ├── agent/
│ │ │ │ │ │ └── AbstractAgentTest.kt
│ │ │ │ │ ├── chunks/
│ │ │ │ │ │ └── ChunkTransformTest.kt
│ │ │ │ │ ├── integration/
│ │ │ │ │ │ ├── AdvancedIntegrationTest.kt
│ │ │ │ │ │ ├── AgentToolIntegrationTest.kt
│ │ │ │ │ │ └── SimpleAgentToolIntegrationTest.kt
│ │ │ │ │ ├── sse/
│ │ │ │ │ │ └── SseParserTest.kt
│ │ │ │ │ ├── state/
│ │ │ │ │ │ ├── DefaultApplyEventsTest.kt
│ │ │ │ │ │ └── StateManagerTest.kt
│ │ │ │ │ └── verify/
│ │ │ │ │ └── EventVerifierTest.kt
│ │ │ │ ├── iosMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── client/
│ │ │ │ │ └── agent/
│ │ │ │ │ └── HttpClientFactory.kt
│ │ │ │ └── jvmMain/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── client/
│ │ │ │ └── agent/
│ │ │ │ └── HttpClientFactory.kt
│ │ │ ├── core/
│ │ │ │ ├── build.gradle.kts
│ │ │ │ └── src/
│ │ │ │ ├── androidMain/
│ │ │ │ │ ├── AndroidManifest.xml
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── platform/
│ │ │ │ │ └── AndroidPlatform.kt
│ │ │ │ ├── commonMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ ├── core/
│ │ │ │ │ │ └── types/
│ │ │ │ │ │ ├── AgUiJson.kt
│ │ │ │ │ │ ├── AgUiSerializersModule.kt
│ │ │ │ │ │ ├── Events.kt
│ │ │ │ │ │ └── Types.kt
│ │ │ │ │ └── platform/
│ │ │ │ │ └── Platform.kt
│ │ │ │ ├── commonTest/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── tests/
│ │ │ │ │ ├── EventSerializationTest.kt
│ │ │ │ │ ├── MessageProtocolComplianceTest.kt
│ │ │ │ │ ├── MessageSerializationTest.kt
│ │ │ │ │ ├── RunAgentInputProtocolTest.kt
│ │ │ │ │ └── ToolSerializationDebugTest.kt
│ │ │ │ ├── iosMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── platform/
│ │ │ │ │ └── IosPlatform.kt
│ │ │ │ ├── jvmMain/
│ │ │ │ │ └── kotlin/
│ │ │ │ │ └── com/
│ │ │ │ │ └── agui/
│ │ │ │ │ └── platform/
│ │ │ │ │ └── JvmPlatform.kt
│ │ │ │ └── jvmTest/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── platform/
│ │ │ │ └── PlatformJvmTest.kt
│ │ │ ├── gradle/
│ │ │ │ ├── libs.versions.toml
│ │ │ │ └── wrapper/
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ │ ├── gradle.properties
│ │ │ ├── gradlew
│ │ │ ├── gradlew.bat
│ │ │ ├── settings.gradle.kts
│ │ │ └── tools/
│ │ │ ├── build.gradle.kts
│ │ │ └── src/
│ │ │ ├── androidMain/
│ │ │ │ └── AndroidManifest.xml
│ │ │ ├── commonMain/
│ │ │ │ └── kotlin/
│ │ │ │ └── com/
│ │ │ │ └── agui/
│ │ │ │ └── tools/
│ │ │ │ ├── ToolErrorHandling.kt
│ │ │ │ ├── ToolExecutionManager.kt
│ │ │ │ ├── ToolExecutor.kt
│ │ │ │ └── ToolRegistry.kt
│ │ │ └── commonTest/
│ │ │ └── kotlin/
│ │ │ └── com/
│ │ │ └── agui/
│ │ │ └── tools/
│ │ │ ├── CircuitBreakerTest.kt
│ │ │ ├── ToolErrorHandlerTest.kt
│ │ │ ├── ToolExecutionManagerTest.kt
│ │ │ └── ToolsModuleTest.kt
│ │ ├── publish.sh
│ │ └── settings.gradle.kts
│ ├── ruby/
│ │ ├── .gitignore
│ │ ├── .yardopts
│ │ ├── CHANGELOG.md
│ │ ├── Gemfile
│ │ ├── README.md
│ │ ├── Rakefile
│ │ ├── ag-ui-protocol.gemspec
│ │ ├── example/
│ │ │ ├── rails/
│ │ │ │ ├── Gemfile
│ │ │ │ ├── README.md
│ │ │ │ ├── app/
│ │ │ │ │ └── controllers/
│ │ │ │ │ └── ag_ui_controller.rb
│ │ │ │ ├── config/
│ │ │ │ │ ├── application.rb
│ │ │ │ │ ├── boot.rb
│ │ │ │ │ ├── environment.rb
│ │ │ │ │ ├── environments/
│ │ │ │ │ │ └── development.rb
│ │ │ │ │ ├── puma.rb
│ │ │ │ │ └── routes.rb
│ │ │ │ └── config.ru
│ │ │ └── simple-use/
│ │ │ ├── Gemfile
│ │ │ ├── README.md
│ │ │ └── main.rb
│ │ ├── lib/
│ │ │ ├── ag-ui-protocol.rb
│ │ │ ├── ag_ui_protocol/
│ │ │ │ ├── core/
│ │ │ │ │ ├── events.rb
│ │ │ │ │ └── types.rb
│ │ │ │ ├── encoder/
│ │ │ │ │ └── event_encoder.rb
│ │ │ │ ├── util.rb
│ │ │ │ └── version.rb
│ │ │ └── ag_ui_protocol.rb
│ │ ├── sorbet/
│ │ │ └── config
│ │ ├── templates/
│ │ │ └── default/
│ │ │ └── fulldoc/
│ │ │ └── markdown/
│ │ │ └── setup.rb
│ │ ├── test/
│ │ │ ├── ag_ui_protocol/
│ │ │ │ ├── core/
│ │ │ │ │ ├── events_test.rb
│ │ │ │ │ └── types_test.rb
│ │ │ │ └── encoder/
│ │ │ │ └── event_encoder_test.rb
│ │ │ └── test_helper.rb
│ │ └── yard_extensions.rb
│ └── rust/
│ ├── Cargo.toml
│ ├── TODO
│ └── crates/
│ ├── ag-ui-client/
│ │ ├── Cargo.toml
│ │ ├── README.md
│ │ ├── examples/
│ │ │ ├── basic_agent.rs
│ │ │ ├── generative_ui.rs
│ │ │ ├── logging_subscriber.rs
│ │ │ ├── shared_state.rs
│ │ │ └── sse_example.rs
│ │ ├── scripts/
│ │ │ ├── basic_agent.py
│ │ │ ├── generative_ui.py
│ │ │ └── shared_state.py
│ │ ├── src/
│ │ │ ├── agent.rs
│ │ │ ├── error.rs
│ │ │ ├── event_handler.rs
│ │ │ ├── http.rs
│ │ │ ├── lib.rs
│ │ │ ├── sse.rs
│ │ │ ├── stream.rs
│ │ │ └── subscriber.rs
│ │ └── tests/
│ │ ├── http_agent_test.rs
│ │ └── sse_test.rs
│ └── ag-ui-core/
│ ├── Cargo.toml
│ ├── README.md
│ ├── src/
│ │ ├── error.rs
│ │ ├── event.rs
│ │ ├── lib.rs
│ │ ├── state.rs
│ │ └── types/
│ │ ├── context.rs
│ │ ├── ids.rs
│ │ ├── input.rs
│ │ ├── message.rs
│ │ ├── mod.rs
│ │ └── tool.rs
│ └── tests/
│ └── unit.rs
├── python/
│ ├── .gitignore
│ ├── LICENSE
│ ├── README.md
│ ├── ag_ui/
│ │ ├── __init__.py
│ │ ├── core/
│ │ │ ├── __init__.py
│ │ │ ├── events.py
│ │ │ └── types.py
│ │ ├── encoder/
│ │ │ ├── __init__.py
│ │ │ └── encoder.py
│ │ └── py.typed
│ ├── pyproject.toml
│ └── tests/
│ ├── __init__.py
│ ├── test_encoder.py
│ ├── test_events.py
│ ├── test_text_roles.py
│ └── test_types.py
└── typescript/
├── .cursor/
│ └── rules/
│ └── project-rules.mdc
├── .gitignore
├── .npmrc
├── .prettierrc
├── LICENSE
├── README.md
├── packages/
│ ├── cli/
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ └── index.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── client/
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── agent/
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── agent-clone.test.ts
│ │ │ │ │ ├── agent-concurrent.test.ts
│ │ │ │ │ ├── agent-multiple-runs.test.ts
│ │ │ │ │ ├── agent-mutations.test.ts
│ │ │ │ │ ├── agent-result.test.ts
│ │ │ │ │ ├── agent-text-roles.test.ts
│ │ │ │ │ ├── agent-version.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.activity.test.ts
│ │ │ │ │ ├── default.concurrent.test.ts
│ │ │ │ │ ├── default.reasoning.test.ts
│ │ │ │ │ ├── default.state.test.ts
│ │ │ │ │ ├── default.text-message.test.ts
│ │ │ │ │ ├── default.tool-calls.test.ts
│ │ │ │ │ └── run-started-input.test.ts
│ │ │ │ ├── default.ts
│ │ │ │ └── index.ts
│ │ │ ├── chunks/
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── transform-roles.test.ts
│ │ │ │ │ └── transform.test.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── transform.ts
│ │ │ ├── compact/
│ │ │ │ ├── __tests__/
│ │ │ │ │ └── compact.test.ts
│ │ │ │ ├── compact.ts
│ │ │ │ └── index.ts
│ │ │ ├── index.ts
│ │ │ ├── legacy/
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── convert.concurrent.test.ts
│ │ │ │ │ ├── convert.predictive.test.ts
│ │ │ │ │ ├── convert.state.test.ts
│ │ │ │ │ └── convert.tool-calls.test.ts
│ │ │ │ ├── convert.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── types.ts
│ │ │ ├── middleware/
│ │ │ │ ├── __tests__/
│ │ │ │ │ ├── backward-compatibility-0-0-39.test.ts
│ │ │ │ │ ├── backward-compatibility-0-0-45.test.ts
│ │ │ │ │ ├── filter-tool-calls.test.ts
│ │ │ │ │ ├── function-middleware.test.ts
│ │ │ │ │ ├── middleware-chained-integration.test.ts
│ │ │ │ │ ├── middleware-chained-run-next-with-state.test.ts
│ │ │ │ │ ├── middleware-live-events.test.ts
│ │ │ │ │ ├── middleware-usage-example.ts
│ │ │ │ │ ├── middleware-with-state.test.ts
│ │ │ │ │ └── middleware.test.ts
│ │ │ │ ├── backward-compatibility-0-0-39.ts
│ │ │ │ ├── backward-compatibility-0-0-45.ts
│ │ │ │ ├── filter-tool-calls.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── middleware.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.concurrent.test.ts
│ │ │ │ ├── verify.events.test.ts
│ │ │ │ ├── verify.lifecycle.test.ts
│ │ │ │ ├── verify.multiple-runs.test.ts
│ │ │ │ ├── verify.steps.test.ts
│ │ │ │ ├── verify.text-messages.test.ts
│ │ │ │ └── verify.tool-calls.test.ts
│ │ │ ├── index.ts
│ │ │ └── verify.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── core/
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── __tests__/
│ │ │ │ ├── activity-events.test.ts
│ │ │ │ ├── backwards-compatibility.test.ts
│ │ │ │ ├── event-factories.test.ts
│ │ │ │ ├── events-role-defaults.test.ts
│ │ │ │ ├── index.test.ts
│ │ │ │ └── multimodal-messages.test.ts
│ │ │ ├── capabilities.ts
│ │ │ ├── event-factories.ts
│ │ │ ├── events.ts
│ │ │ ├── index.ts
│ │ │ └── types.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.config.ts
│ ├── encoder/
│ │ ├── .npmignore
│ │ ├── README.md
│ │ ├── package.json
│ │ ├── src/
│ │ │ ├── __tests__/
│ │ │ │ └── encoder.test.ts
│ │ │ ├── encoder.ts
│ │ │ ├── index.ts
│ │ │ └── media-type.ts
│ │ ├── tsconfig.json
│ │ ├── tsdown.config.ts
│ │ └── vitest.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
│ ├── package.json
│ ├── src/
│ │ ├── index.ts
│ │ ├── proto/
│ │ │ ├── events.proto
│ │ │ ├── patch.proto
│ │ │ └── types.proto
│ │ └── proto.ts
│ ├── tsconfig.json
│ ├── tsdown.config.ts
│ └── vitest.config.ts
├── scripts/
│ └── create-integration.ts
├── tsconfig.json
└── vitest.base.ts
Showing preview only (566K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (6032 symbols across 712 files)
FILE: apps/client-cli-example/src/index.ts
function chatLoop (line 10) | async function chatLoop() {
function main (line 77) | async function main() {
FILE: apps/client-cli-example/src/tools/weather.tool.ts
type GeocodingResponse (line 4) | interface GeocodingResponse {
type WeatherResponse (line 11) | interface WeatherResponse {
function getWeatherCondition (line 70) | function getWeatherCondition(code: number): string {
FILE: apps/dojo/e2e/clean-reporter.cjs
function getTimestamp (line 1) | function getTimestamp() {
function logStamp (line 7) | function logStamp(...args) {
class CleanReporter (line 11) | class CleanReporter {
method onBegin (line 12) | onBegin(config, suite) {
method onTestEnd (line 16) | onTestEnd(test, result) {
method onEnd (line 105) | onEnd(result) {
FILE: apps/dojo/e2e/featurePages/AgenticChatPage.ts
class AgenticChatPage (line 6) | class AgenticChatPage {
method constructor (line 15) | constructor(page: Page) {
method openChat (line 26) | async openChat() {
method sendMessage (line 34) | async sendMessage(message: string) {
method getGradientButtonByName (line 39) | async getGradientButtonByName(name: string | RegExp) {
method assertUserMessageVisible (line 43) | async assertUserMessageVisible(text: string | RegExp) {
method assertAgentReplyVisible (line 47) | async assertAgentReplyVisible(expectedText: RegExp | RegExp[]) {
method assertAgentReplyContains (line 64) | async assertAgentReplyContains(expectedText: string) {
method getAssistantMessageText (line 69) | async getAssistantMessageText(index: number): Promise<string> {
method regenerateResponse (line 75) | async regenerateResponse(index: number) {
method assertWeatherResponseStructure (line 92) | async assertWeatherResponseStructure() {
FILE: apps/dojo/e2e/featurePages/HumanInTheLoopPage.ts
class HumanInTheLoopPage (line 6) | class HumanInTheLoopPage {
method constructor (line 17) | constructor(page: Page) {
method openChat (line 31) | async openChat() {
method sendMessage (line 35) | async sendMessage(message: string) {
method selectItemsInPlanner (line 39) | async selectItemsInPlanner() {
method getPlannerOnClick (line 44) | async getPlannerOnClick(name: string | RegExp) {
method uncheckItem (line 48) | async uncheckItem(identifier: number | string): Promise<string> {
method isStepItemUnchecked (line 71) | async isStepItemUnchecked(target: number | string): Promise<boolean> {
method performSteps (line 89) | async performSteps() {
method performStepsAndAwait (line 94) | async performStepsAndAwait() {
method assertAgentReplyVisible (line 114) | async assertAgentReplyVisible(expectedText: RegExp) {
method assertUserMessageVisible (line 120) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/featurePages/SharedStatePage.ts
class SharedStatePage (line 6) | class SharedStatePage {
method constructor (line 18) | constructor(page: Page) {
method openChat (line 31) | async openChat() {
method sendMessage (line 35) | async sendMessage(message: string) {
method loader (line 40) | async loader() {
method awaitIngredientCard (line 45) | async awaitIngredientCard(name: string) {
method addNewIngredient (line 60) | async addNewIngredient(placeholderText: string) {
method getInstructionItems (line 65) | async getInstructionItems(containerLocator: Locator ) {
method assertAgentReplyVisible (line 74) | async assertAgentReplyVisible(expectedText: RegExp) {
method assertUserMessageVisible (line 78) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/featurePages/ToolBaseGenUIPage.ts
class ToolBaseGenUIPage (line 6) | class ToolBaseGenUIPage {
method constructor (line 16) | constructor(page: Page) {
method generateHaiku (line 27) | async generateHaiku(message: string) {
method checkGeneratedHaiku (line 33) | async checkGeneratedHaiku() {
method extractChatHaikuContent (line 42) | async extractChatHaikuContent(page: Page): Promise<string> {
method extractMainDisplayHaikuContent (line 81) | async extractMainDisplayHaikuContent(page: Page): Promise<string> {
method carouselIncludesHaiku (line 121) | private async carouselIncludesHaiku(
method checkHaikuDisplay (line 154) | async checkHaikuDisplay(page: Page): Promise<void> {
FILE: apps/dojo/e2e/featurePages/V1AgenticChatPage.ts
class V1AgenticChatPage (line 9) | class V1AgenticChatPage {
method constructor (line 16) | constructor(page: Page) {
method waitForReady (line 26) | async waitForReady() {
method sendMessage (line 30) | async sendMessage(message: string) {
method awaitLLMResponseDone (line 44) | async awaitLLMResponseDone(timeout = 30_000) {
method assertUserMessageVisible (line 73) | async assertUserMessageVisible(text: string) {
method assertAgentReplyVisible (line 77) | async assertAgentReplyVisible(pattern: RegExp) {
FILE: apps/dojo/e2e/lib/constants.ts
constant DEFAULT_WELCOME_MESSAGE (line 6) | const DEFAULT_WELCOME_MESSAGE =
FILE: apps/dojo/e2e/lib/mock-agent.ts
type SSEEvent (line 22) | interface SSEEvent {
type ResponseSequence (line 27) | type ResponseSequence = SSEEvent[];
type MessageHandler (line 29) | interface MessageHandler {
constant ROUTE_PATTERN (line 36) | const ROUTE_PATTERN = /\/api\/copilotkit(next)?\/[^/]+/;
class MockAgent (line 38) | class MockAgent {
method constructor (line 49) | constructor(page: Page) {
method nextRunId (line 53) | private nextRunId() {
method nextMessageId (line 57) | private nextMessageId() {
method nextToolCallId (line 61) | private nextToolCallId() {
method onMessage (line 68) | onMessage(
method onAnyMessage (line 85) | onAnyMessage(responses: ResponseSequence): this {
method install (line 93) | async install(): Promise<void> {
method uninstall (line 150) | async uninstall(): Promise<void> {
method extractLastUserMessage (line 157) | private extractLastUserMessage(body: string): string | null {
method findResponse (line 183) | private findResponse(userMessage: string): ResponseSequence {
method textMessage (line 217) | textMessage(
method toolCall (line 249) | toolCall(
method combine (line 282) | static combine(...sequences: ResponseSequence[]): ResponseSequence {
FILE: apps/dojo/e2e/lib/upload-video.ts
type VideoToUpload (line 5) | interface VideoToUpload {
type S3Config (line 12) | interface S3Config {
class S3VideoUploader (line 19) | class S3VideoUploader {
method constructor (line 23) | constructor(config: S3Config) {
method generateS3Path (line 42) | generateS3Path(
method generatePublicUrl (line 63) | generatePublicUrl(s3ObjectPath: string): string {
method uploadVideo (line 70) | async uploadVideo(video: VideoToUpload): Promise<string> {
method uploadVideos (line 115) | async uploadVideos(
function createS3Uploader (line 173) | function createS3Uploader(): S3VideoUploader | null {
FILE: apps/dojo/e2e/llmock-setup.ts
constant MOCK_PORT (line 4) | const MOCK_PORT = 5555;
constant FIXTURES_DIR (line 5) | const FIXTURES_DIR = path.join(import.meta.dirname, "fixtures", "openai");
function setupLLMock (line 9) | async function setupLLMock(): Promise<void> {
function teardownLLMock (line 803) | async function teardownLLMock(): Promise<void> {
function getMockServer (line 812) | function getMockServer(): LLMock | null {
FILE: apps/dojo/e2e/pages/a2aMiddlewarePages/A2AChatPage.ts
class A2AChatPage (line 3) | class A2AChatPage {
method constructor (line 7) | constructor(page: Page) {
method openChat (line 12) | async openChat() {
FILE: apps/dojo/e2e/pages/adkMiddlewarePages/HumanInLoopPage.ts
class HumanInLoopPage (line 6) | class HumanInLoopPage {
method constructor (line 17) | constructor(page: Page) {
method openChat (line 31) | async openChat() {
method sendMessage (line 35) | async sendMessage(message: string) {
method selectItemsInPlanner (line 39) | async selectItemsInPlanner() {
method getPlannerOnClick (line 44) | async getPlannerOnClick(name: string | RegExp) {
method uncheckItem (line 48) | async uncheckItem(identifier: number | string): Promise<string> {
method isStepItemUnchecked (line 71) | async isStepItemUnchecked(target: number | string): Promise<boolean> {
method performSteps (line 89) | async performSteps() {
method performStepsAndAwait (line 94) | async performStepsAndAwait() {
method assertAgentReplyVisible (line 114) | async assertAgentReplyVisible(expectedText: RegExp) {
method assertUserMessageVisible (line 120) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/adkMiddlewarePages/PredictiveStateUpdatesPage.ts
class PredictiveStateUpdatesPage (line 9) | class PredictiveStateUpdatesPage {
method constructor (line 24) | constructor(page: Page) {
method openChat (line 45) | async openChat() {
method sendMessage (line 49) | async sendMessage(message: string) {
method getPredictiveResponse (line 53) | async getPredictiveResponse() {
method getButton (line 58) | async getButton(page, buttonName) {
method getStatusLabelOfButton (line 62) | async getStatusLabelOfButton(page, statusText) {
method getUserApproval (line 66) | async getUserApproval() {
method getUserRejection (line 74) | async getUserRejection() {
method verifyAgentResponse (line 82) | async verifyAgentResponse(dragonName) {
method verifyHighlightedText (line 96) | async verifyHighlightedText() {
FILE: apps/dojo/e2e/pages/agnoPages/HumanInLoopPage.ts
class HumanInLoopPage (line 6) | class HumanInLoopPage {
method constructor (line 17) | constructor(page: Page) {
method openChat (line 31) | async openChat() {
method sendMessage (line 35) | async sendMessage(message: string) {
method selectItemsInPlanner (line 39) | async selectItemsInPlanner() {
method getPlannerOnClick (line 44) | async getPlannerOnClick(name: string | RegExp) {
method uncheckItem (line 48) | async uncheckItem(identifier: number | string): Promise<string> {
method isStepItemUnchecked (line 71) | async isStepItemUnchecked(target: number | string): Promise<boolean> {
method performSteps (line 89) | async performSteps() {
method performStepsAndAwait (line 94) | async performStepsAndAwait() {
method assertAgentReplyVisible (line 114) | async assertAgentReplyVisible(expectedText: RegExp) {
method assertUserMessageVisible (line 120) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/awsStrandsPages/AgenticUIGenPage.ts
class AgenticGenUIPage (line 5) | class AgenticGenUIPage {
method constructor (line 15) | constructor(page: Page) {
method plan (line 26) | async plan() {
method openChat (line 37) | async openChat() {
method sendMessage (line 41) | async sendMessage(message: string) {
method getPlannerButton (line 46) | getPlannerButton(name: string | RegExp) {
method assertAgentReplyVisible (line 50) | async assertAgentReplyVisible(expectedText: RegExp) {
method getUserText (line 54) | async getUserText(textOrRegex) {
method assertUserMessageVisible (line 58) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/awsStrandsPages/HumanInLoopPage.ts
class HumanInLoopPage (line 6) | class HumanInLoopPage {
method constructor (line 17) | constructor(page: Page) {
method openChat (line 31) | async openChat() {
method sendMessage (line 35) | async sendMessage(message: string) {
method selectItemsInPlanner (line 39) | async selectItemsInPlanner() {
method getPlannerOnClick (line 44) | async getPlannerOnClick(name: string | RegExp) {
method uncheckItem (line 48) | async uncheckItem(identifier: number | string): Promise<string> {
method isStepItemUnchecked (line 71) | async isStepItemUnchecked(target: number | string): Promise<boolean> {
method performSteps (line 89) | async performSteps() {
method performStepsAndAwait (line 94) | async performStepsAndAwait() {
method assertAgentReplyVisible (line 114) | async assertAgentReplyVisible(expectedText: RegExp) {
method assertUserMessageVisible (line 120) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/crewAIPages/AgenticUIGenPage.ts
class AgenticGenUIPage (line 5) | class AgenticGenUIPage {
method constructor (line 15) | constructor(page: Page) {
method plan (line 26) | async plan() {
method openChat (line 37) | async openChat() {
method sendMessage (line 41) | async sendMessage(message: string) {
method getPlannerButton (line 46) | getPlannerButton(name: string | RegExp) {
method assertAgentReplyVisible (line 50) | async assertAgentReplyVisible(expectedText: RegExp) {
method getUserText (line 54) | async getUserText(textOrRegex) {
method assertUserMessageVisible (line 58) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/crewAIPages/HumanInLoopPage.ts
class HumanInLoopPage (line 6) | class HumanInLoopPage {
method constructor (line 17) | constructor(page: Page) {
method openChat (line 31) | async openChat() {
method sendMessage (line 35) | async sendMessage(message: string) {
method selectItemsInPlanner (line 39) | async selectItemsInPlanner() {
method getPlannerOnClick (line 44) | async getPlannerOnClick(name: string | RegExp) {
method uncheckItem (line 48) | async uncheckItem(identifier: number | string): Promise<string> {
method isStepItemUnchecked (line 71) | async isStepItemUnchecked(target: number | string): Promise<boolean> {
method performSteps (line 89) | async performSteps() {
method performStepsAndAwait (line 94) | async performStepsAndAwait() {
method assertAgentReplyVisible (line 114) | async assertAgentReplyVisible(expectedText: RegExp) {
method assertUserMessageVisible (line 120) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/crewAIPages/PredictiveStateUpdatesPage.ts
class PredictiveStateUpdatesPage (line 6) | class PredictiveStateUpdatesPage {
method constructor (line 21) | constructor(page: Page) {
method openChat (line 36) | async openChat() {
method sendMessage (line 40) | async sendMessage(message: string) {
method getPredictiveResponse (line 44) | async getPredictiveResponse() {
method getButton (line 49) | async getButton(page, buttonName) {
method getStatusLabelOfButton (line 53) | async getStatusLabelOfButton(page, statusText) {
method getUserApproval (line 57) | async getUserApproval() {
method getUserRejection (line 64) | async getUserRejection() {
method verifyAgentResponse (line 71) | async verifyAgentResponse(dragonName) {
method verifyHighlightedText (line 84) | async verifyHighlightedText(){
FILE: apps/dojo/e2e/pages/langGraphFastAPIPages/AgenticUIGenPage.ts
class AgenticGenUIPage (line 5) | class AgenticGenUIPage {
method constructor (line 15) | constructor(page: Page) {
method plan (line 26) | async plan() {
method openChat (line 37) | async openChat() {
method sendMessage (line 41) | async sendMessage(message: string) {
method getPlannerButton (line 46) | getPlannerButton(name: string | RegExp) {
method assertAgentReplyVisible (line 50) | async assertAgentReplyVisible(expectedText: RegExp) {
method getUserText (line 54) | async getUserText(textOrRegex) {
method assertUserMessageVisible (line 58) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/langGraphFastAPIPages/HumanInLoopPage.ts
class HumanInLoopPage (line 5) | class HumanInLoopPage {
method constructor (line 16) | constructor(page: Page) {
method openChat (line 34) | async openChat() {
method sendMessage (line 38) | async sendMessage(message: string) {
method selectItemsInPlanner (line 42) | async selectItemsInPlanner() {
method getPlannerOnClick (line 47) | async getPlannerOnClick(name: string | RegExp) {
method uncheckItem (line 51) | async uncheckItem(identifier: number | string): Promise<string> {
method isStepItemUnchecked (line 73) | async isStepItemUnchecked(target: number | string): Promise<boolean> {
method performSteps (line 92) | async performSteps() {
method performStepsAndAwait (line 97) | async performStepsAndAwait() {
method assertAgentReplyVisible (line 117) | async assertAgentReplyVisible(expectedText: RegExp) {
method assertUserMessageVisible (line 123) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/langGraphFastAPIPages/PredictiveStateUpdatesPage.ts
class PredictiveStateUpdatesPage (line 6) | class PredictiveStateUpdatesPage {
method constructor (line 21) | constructor(page: Page) {
method openChat (line 37) | async openChat() {
method sendMessage (line 41) | async sendMessage(message: string) {
method getPredictiveResponse (line 45) | async getPredictiveResponse() {
method getButton (line 50) | async getButton(page, buttonName) {
method getStatusLabelOfButton (line 54) | async getStatusLabelOfButton(page, statusText) {
method getUserApproval (line 58) | async getUserApproval() {
method getUserRejection (line 65) | async getUserRejection() {
method verifyAgentResponse (line 72) | async verifyAgentResponse(dragonName) {
method verifyHighlightedText (line 85) | async verifyHighlightedText(){
FILE: apps/dojo/e2e/pages/langGraphPages/AgenticUIGenPage.ts
class AgenticGenUIPage (line 6) | class AgenticGenUIPage {
method constructor (line 15) | constructor(page: Page) {
method plan (line 25) | async plan() {
method openChat (line 36) | async openChat() {
method sendMessage (line 41) | async sendMessage(message: string) {
method getPlannerButton (line 46) | getPlannerButton(name: string | RegExp) {
method assertAgentReplyVisible (line 50) | async assertAgentReplyVisible(expectedText: RegExp) {
method getUserText (line 54) | async getUserText(textOrRegex) {
method assertUserMessageVisible (line 58) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/langGraphPages/HumanInLoopPage.ts
class HumanInLoopPage (line 6) | class HumanInLoopPage {
method constructor (line 16) | constructor(page: Page) {
method openChat (line 30) | async openChat() {
method sendMessage (line 35) | async sendMessage(message: string) {
method selectItemsInPlanner (line 39) | async selectItemsInPlanner() {
method getPlannerOnClick (line 44) | async getPlannerOnClick(name: string | RegExp) {
method uncheckItem (line 48) | async uncheckItem(identifier: number | string): Promise<string> {
method isStepItemUnchecked (line 70) | async isStepItemUnchecked(target: number | string): Promise<boolean> {
method performSteps (line 89) | async performSteps() {
method performStepsAndAwait (line 94) | async performStepsAndAwait() {
method assertAgentReplyVisible (line 114) | async assertAgentReplyVisible(expectedText: RegExp) {
method assertUserMessageVisible (line 120) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/langGraphPages/PredictiveStateUpdatesPage.ts
class PredictiveStateUpdatesPage (line 6) | class PredictiveStateUpdatesPage {
method constructor (line 21) | constructor(page: Page) {
method openChat (line 37) | async openChat() {
method sendMessage (line 41) | async sendMessage(message: string) {
method getPredictiveResponse (line 45) | async getPredictiveResponse() {
method getButton (line 50) | async getButton(page, buttonName) {
method getStatusLabelOfButton (line 54) | async getStatusLabelOfButton(page, statusText) {
method getUserApproval (line 58) | async getUserApproval() {
method getUserRejection (line 65) | async getUserRejection() {
method verifyAgentResponse (line 72) | async verifyAgentResponse(dragonName) {
method verifyHighlightedText (line 85) | async verifyHighlightedText(){
FILE: apps/dojo/e2e/pages/langGraphPages/SubgraphsPage.ts
class SubgraphsPage (line 6) | class SubgraphsPage {
method constructor (line 40) | constructor(page: Page) {
method openChat (line 75) | async openChat() {
method sendMessage (line 80) | async sendMessage(message: string) {
method selectFlight (line 85) | async selectFlight(airline: 'KLM' | 'United') {
method selectHotel (line 95) | async selectHotel(hotel: 'Zephyr' | 'Ritz-Carlton' | 'Zoe') {
method waitForFlightsAgent (line 117) | async waitForFlightsAgent() {
method waitForHotelsAgent (line 123) | async waitForHotelsAgent() {
method waitForExperiencesAgent (line 129) | async waitForExperiencesAgent() {
method verifyStaticFlightData (line 135) | async verifyStaticFlightData() {
method verifyStaticHotelData (line 140) | async verifyStaticHotelData() {
method verifyStaticExperienceData (line 146) | async verifyStaticExperienceData() {
method verifyItineraryContainsFlight (line 157) | async verifyItineraryContainsFlight(airline: 'KLM' | 'United') {
method verifyItineraryContainsHotel (line 161) | async verifyItineraryContainsHotel(hotel: 'Zephyr' | 'Ritz-Carlton' | ...
method assertAgentReplyVisible (line 166) | async assertAgentReplyVisible(expectedText: RegExp) {
method assertUserMessageVisible (line 170) | async assertUserMessageVisible(message: string) {
method waitForSupervisorCoordination (line 174) | async waitForSupervisorCoordination() {
method waitForAgentCompletion (line 180) | async waitForAgentCompletion() {
FILE: apps/dojo/e2e/pages/langroidPages/AgenticUIGenPage.ts
class AgenticGenUIPage (line 8) | class AgenticGenUIPage {
method constructor (line 18) | constructor(page: Page) {
method plan (line 31) | async plan() {
method openChat (line 42) | async openChat() {
method sendMessage (line 46) | async sendMessage(message: string) {
method getPlannerButton (line 51) | getPlannerButton(name: string | RegExp) {
method assertAgentReplyVisible (line 55) | async assertAgentReplyVisible(expectedText: RegExp) {
method getUserText (line 61) | async getUserText(textOrRegex) {
method assertUserMessageVisible (line 65) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/llamaIndexPages/AgenticUIGenPage.ts
class AgenticGenUIPage (line 5) | class AgenticGenUIPage {
method constructor (line 15) | constructor(page: Page) {
method plan (line 26) | async plan() {
method openChat (line 37) | async openChat() {
method sendMessage (line 41) | async sendMessage(message: string) {
method getPlannerButton (line 46) | getPlannerButton(name: string | RegExp) {
method assertAgentReplyVisible (line 50) | async assertAgentReplyVisible(expectedText: RegExp) {
method getUserText (line 54) | async getUserText(textOrRegex) {
method assertUserMessageVisible (line 58) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/llamaIndexPages/HumanInLoopPage.ts
class HumanInLoopPage (line 6) | class HumanInLoopPage {
method constructor (line 17) | constructor(page: Page) {
method openChat (line 31) | async openChat() {
method sendMessage (line 35) | async sendMessage(message: string) {
method selectItemsInPlanner (line 39) | async selectItemsInPlanner() {
method getPlannerOnClick (line 44) | async getPlannerOnClick(name: string | RegExp) {
method uncheckItem (line 48) | async uncheckItem(identifier: number | string): Promise<string> {
method isStepItemUnchecked (line 71) | async isStepItemUnchecked(target: number | string): Promise<boolean> {
method performSteps (line 89) | async performSteps() {
method performStepsAndAwait (line 94) | async performStepsAndAwait() {
method assertAgentReplyVisible (line 114) | async assertAgentReplyVisible(expectedText: RegExp) {
method assertUserMessageVisible (line 120) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/pydanticAIPages/AgenticUIGenPage.ts
class AgenticGenUIPage (line 5) | class AgenticGenUIPage {
method constructor (line 15) | constructor(page: Page) {
method plan (line 26) | async plan() {
method openChat (line 37) | async openChat() {
method sendMessage (line 41) | async sendMessage(message: string) {
method getPlannerButton (line 46) | getPlannerButton(name: string | RegExp) {
method assertAgentReplyVisible (line 50) | async assertAgentReplyVisible(expectedText: RegExp | RegExp[]) {
method getUserText (line 67) | async getUserText(textOrRegex) {
method assertUserMessageVisible (line 71) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/pydanticAIPages/HumanInLoopPage.ts
class HumanInLoopPage (line 6) | class HumanInLoopPage {
method constructor (line 17) | constructor(page: Page) {
method openChat (line 31) | async openChat() {
method sendMessage (line 35) | async sendMessage(message: string) {
method selectItemsInPlanner (line 39) | async selectItemsInPlanner() {
method getPlannerOnClick (line 44) | async getPlannerOnClick(name: string | RegExp) {
method uncheckItem (line 48) | async uncheckItem(identifier: number | string): Promise<string> {
method isStepItemUnchecked (line 71) | async isStepItemUnchecked(target: number | string): Promise<boolean> {
method performSteps (line 89) | async performSteps() {
method performStepsAndAwait (line 94) | async performStepsAndAwait() {
method assertAgentReplyVisible (line 114) | async assertAgentReplyVisible(expectedText: RegExp) {
method assertUserMessageVisible (line 120) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/pydanticAIPages/PredictiveStateUpdatesPage.ts
class PredictiveStateUpdatesPage (line 6) | class PredictiveStateUpdatesPage {
method constructor (line 21) | constructor(page: Page) {
method openChat (line 36) | async openChat() {
method sendMessage (line 40) | async sendMessage(message: string) {
method getPredictiveResponse (line 44) | async getPredictiveResponse() {
method getButton (line 49) | async getButton(page, buttonName) {
method getStatusLabelOfButton (line 53) | async getStatusLabelOfButton(page, statusText) {
method getUserApproval (line 57) | async getUserApproval() {
method getUserRejection (line 65) | async getUserRejection() {
method verifyAgentResponse (line 73) | async verifyAgentResponse(dragonName) {
method verifyHighlightedText (line 85) | async verifyHighlightedText(){
FILE: apps/dojo/e2e/pages/serverStarterAllFeaturesPages/AgenticUIGenPage.ts
class AgenticGenUIPage (line 5) | class AgenticGenUIPage {
method constructor (line 15) | constructor(page: Page) {
method plan (line 26) | async plan() {
method openChat (line 37) | async openChat() {
method sendMessage (line 41) | async sendMessage(message: string) {
method getPlannerButton (line 46) | getPlannerButton(name: string | RegExp) {
method assertAgentReplyVisible (line 50) | async assertAgentReplyVisible(expectedText: RegExp) {
method getUserText (line 54) | async getUserText(textOrRegex) {
method assertUserMessageVisible (line 58) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/serverStarterAllFeaturesPages/HumanInLoopPage.ts
class HumanInLoopPage (line 6) | class HumanInLoopPage {
method constructor (line 17) | constructor(page: Page) {
method openChat (line 31) | async openChat() {
method sendMessage (line 35) | async sendMessage(message: string) {
method selectItemsInPlanner (line 39) | async selectItemsInPlanner() {
method getPlannerOnClick (line 44) | async getPlannerOnClick(name: string | RegExp) {
method uncheckItem (line 48) | async uncheckItem(identifier: number | string): Promise<string> {
method isStepItemUnchecked (line 71) | async isStepItemUnchecked(target: number | string): Promise<boolean> {
method performSteps (line 89) | async performSteps() {
method performStepsAndAwait (line 94) | async performStepsAndAwait() {
method assertAgentReplyVisible (line 114) | async assertAgentReplyVisible(expectedText: RegExp) {
method assertUserMessageVisible (line 120) | async assertUserMessageVisible(message: string) {
FILE: apps/dojo/e2e/pages/serverStarterAllFeaturesPages/PredictiveStateUpdatesPage.ts
class PredictiveStateUpdatesPage (line 6) | class PredictiveStateUpdatesPage {
method constructor (line 21) | constructor(page: Page) {
method openChat (line 37) | async openChat() {
method sendMessage (line 41) | async sendMessage(message: string) {
method getPredictiveResponse (line 45) | async getPredictiveResponse() {
method getButton (line 50) | async getButton(page, buttonName) {
method getStatusLabelOfButton (line 54) | async getStatusLabelOfButton(page, statusText) {
method getUserApproval (line 58) | async getUserApproval() {
method getUserRejection (line 65) | async getUserRejection() {
method verifyAgentResponse (line 72) | async verifyAgentResponse(dragonName) {
method verifyHighlightedText (line 85) | async verifyHighlightedText(){
method getResponseContent (line 109) | async getResponseContent() {
FILE: apps/dojo/e2e/playwright.config.ts
function getReporters (line 4) | function getReporters(): ReporterDescription[] {
function getBaseUrl (line 37) | function getBaseUrl(): string {
FILE: apps/dojo/e2e/reporters/s3-video-reporter.ts
type S3VideoReporterOptions (line 15) | interface S3VideoReporterOptions {
type VideoInfo (line 20) | interface VideoInfo {
class S3VideoReporter (line 31) | class S3VideoReporter implements Reporter {
method constructor (line 35) | constructor(options: S3VideoReporterOptions = {}) {
method onBegin (line 47) | onBegin(config: FullConfig, suite: Suite) {
method onTestEnd (line 53) | onTestEnd(test: TestCase, result: TestResult) {
method onEnd (line 101) | async onEnd(result: FullResult) {
method writeVideoUrls (line 193) | private async writeVideoUrls() {
function getUploadedVideos (line 218) | function getUploadedVideos(): VideoInfo[] {
function getAllVideos (line 225) | function getAllVideos(): VideoInfo[] {
FILE: apps/dojo/e2e/slack-layout-simple.ts
type VideoInfo (line 5) | interface VideoInfo {
function getVideos (line 10) | function getVideos(): VideoInfo[] {
function generateSimpleLayout (line 25) | function generateSimpleLayout(
FILE: apps/dojo/e2e/slack-layout.ts
type VideoInfo (line 5) | interface VideoInfo {
function getVideosByCategory (line 12) | function getVideosByCategory(): Map<string, VideoInfo[]> {
function getTestDisplayName (line 42) | function getTestDisplayName(test: any): string {
function categorizeAndCleanError (line 60) | function categorizeAndCleanError(test: any): {
function generateCustomLayout (line 154) | function generateCustomLayout(
FILE: apps/dojo/e2e/test-isolation-helper.ts
function dumpPageAIState (line 9) | async function dumpPageAIState(page: Page) {
function dumpLLMockJournal (line 94) | async function dumpLLMockJournal() {
function waitForAIResponse (line 232) | async function waitForAIResponse(page: Page, timeout: number = 15000) {
function waitForAssistantMessage (line 240) | async function waitForAssistantMessage(
FILE: apps/dojo/e2e/test-isolation-setup.ts
function globalSetup (line 4) | async function globalSetup(config: FullConfig) {
FILE: apps/dojo/e2e/test-isolation-teardown.ts
function globalTeardown (line 3) | async function globalTeardown() {
FILE: apps/dojo/e2e/utils/aiWaitHelpers.ts
function waitForAIResponse (line 7) | async function waitForAIResponse(
function waitForAIContent (line 18) | async function waitForAIContent(
function waitForAIFormReady (line 28) | async function waitForAIFormReady(
function waitForAIDialog (line 40) | async function waitForAIDialog(
function waitForAIPatterns (line 51) | async function waitForAIPatterns(
FILE: apps/dojo/e2e/utils/copilot-actions.ts
constant LLM_RESPONSE_TIMEOUT (line 5) | const LLM_RESPONSE_TIMEOUT = 60_000;
constant ELEMENT_TIMEOUT (line 7) | const ELEMENT_TIMEOUT = 10_000;
function awaitLLMResponseDone (line 14) | async function awaitLLMResponseDone(
function sendChatMessage (line 40) | async function sendChatMessage(page: Page, message: string) {
function sendAndAwaitResponse (line 57) | async function sendAndAwaitResponse(
function assertAssistantReply (line 92) | async function assertAssistantReply(
function assertUserMessage (line 110) | async function assertUserMessage(
function openChat (line 123) | async function openChat(page: Page) {
function regenerateResponse (line 135) | async function regenerateResponse(page: Page, messageIndex: number) {
FILE: apps/dojo/scripts/generate-content-json.ts
function getFile (line 13) | async function getFile(_filePath: string | undefined, _fileName?: string) {
constant FEATURE_BASE (line 81) | const FEATURE_BASE = path.join(__dirname, "../src/app/[integrationId]/fe...
function resolveFeatureDir (line 83) | function resolveFeatureDir(featureId: string): string {
function getFeatureFrontendFiles (line 89) | async function getFeatureFrontendFiles(featureId: string) {
function runGenerateContent (line 471) | async function runGenerateContent() {
function validateAgentFilesMapper (line 518) | function validateAgentFilesMapper(): boolean {
function validateFeatureReadmes (line 546) | function validateFeatureReadmes(): boolean {
FILE: apps/dojo/scripts/link-cpk.js
function linkCopilotKit (line 34) | function linkCopilotKit() {
FILE: apps/dojo/scripts/prep-dojo-everything.js
function parseList (line 13) | function parseList(flag) {
constant ALL_TARGETS (line 51) | const ALL_TARGETS = {
function printDryRunServices (line 154) | function printDryRunServices(procs) {
function main (line 164) | async function main() {
FILE: apps/dojo/scripts/run-dojo-everything.js
constant LANGGRAPH_CLI_VERSION (line 9) | const LANGGRAPH_CLI_VERSION = '1.1.13';
function parseList (line 16) | function parseList(flag) {
constant ALL_SERVICES (line 56) | const ALL_SERVICES = {
function printDryRunServices (line 261) | function printDryRunServices(procs) {
function main (line 279) | async function main() {
FILE: apps/dojo/src/app/[integrationId]/feature/(v1)/v1_agentic_chat/page.tsx
type V1AgenticChatProps (line 7) | interface V1AgenticChatProps {
FILE: apps/dojo/src/app/[integrationId]/feature/(v2)/a2a_chat/a2a_chat.tsx
type A2AChatProps (line 17) | interface A2AChatProps {
type A2AChatState (line 37) | interface A2AChatState {
type Seat (line 41) | interface Seat {
type Table (line 47) | interface Table {
type MessageProps (line 74) | interface MessageProps {
method render (line 186) | render({ args, respond }: { args: { tables?: Table[] }; respond?: (resul...
FILE: apps/dojo/src/app/[integrationId]/feature/(v2)/a2a_chat/page.tsx
type PageProps (line 8) | interface PageProps {
function Page (line 14) | function Page({ params }: PageProps) {
FILE: apps/dojo/src/app/[integrationId]/feature/(v2)/a2ui_chat/page.tsx
type PageProps (line 18) | interface PageProps {
function Chat (line 24) | function Chat({ agentId }: { agentId: string }) {
function Page (line 42) | function Page({ params }: PageProps) {
FILE: apps/dojo/src/app/[integrationId]/feature/(v2)/agentic_chat/page.tsx
type AgenticChatProps (line 14) | interface AgenticChatProps {
FILE: apps/dojo/src/app/[integrationId]/feature/(v2)/agentic_chat_reasoning/page.tsx
type AgenticChatProps (line 25) | interface AgenticChatProps {
type AgentState (line 45) | interface AgentState {
FILE: apps/dojo/src/app/[integrationId]/feature/(v2)/agentic_generative_ui/page.tsx
type AgenticGenerativeUIProps (line 14) | interface AgenticGenerativeUIProps {
type AgentState (line 33) | interface AgentState {
function TaskProgress (line 90) | function TaskProgress({ steps, theme }: { steps: AgentState["steps"]; th...
function CheckIcon (line 260) | function CheckIcon() {
function SpinnerIcon (line 268) | function SpinnerIcon() {
function ClockIcon (line 286) | function ClockIcon({ theme }: { theme?: string }) {
FILE: apps/dojo/src/app/[integrationId]/feature/(v2)/backend_tool_rendering/page.tsx
type AgenticChatProps (line 13) | interface AgenticChatProps {
type WeatherToolResult (line 100) | interface WeatherToolResult {
function getThemeColor (line 108) | function getThemeColor(conditions: string): string {
function WeatherCard (line 125) | function WeatherCard({
function WeatherIcon (line 185) | function WeatherIcon({ conditions }: { conditions: string }) {
function SunIcon (line 213) | function SunIcon() {
function RainIcon (line 231) | function RainIcon() {
function CloudIcon (line 257) | function CloudIcon() {
FILE: apps/dojo/src/app/[integrationId]/feature/(v2)/human_in_the_loop/page.tsx
type HumanInTheLoopProps (line 15) | interface HumanInTheLoopProps {
type Step (line 35) | interface Step {
FILE: apps/dojo/src/app/[integrationId]/feature/(v2)/predictive_state_updates/page.tsx
type PredictiveStateUpdatesProps (line 28) | interface PredictiveStateUpdatesProps {
function PredictiveStateUpdates (line 34) | function PredictiveStateUpdates({ params }: PredictiveStateUpdatesProps) {
type AgentState (line 173) | interface AgentState {
method render (line 296) | render({ args, status, respond }: { args: { document?: string }; status:...
type ConfirmChangesProps (line 333) | interface ConfirmChangesProps {
function ConfirmChanges (line 341) | function ConfirmChanges({ args, respond, status, onReject, onConfirm }: ...
function fromMarkdown (line 400) | function fromMarkdown(text: string) {
function diffPartialText (line 409) | function diffPartialText(oldText: string, newText: string, isComplete: b...
function isAlpha (line 436) | function isAlpha(text: string) {
FILE: apps/dojo/src/app/[integrationId]/feature/(v2)/shared_state/page.tsx
type SharedStateProps (line 18) | interface SharedStateProps {
function SharedState (line 24) | function SharedState({ params }: SharedStateProps) {
type SkillLevel (line 156) | enum SkillLevel {
type CookingTime (line 162) | enum CookingTime {
type SpecialPreferences (line 178) | enum SpecialPreferences {
type Ingredient (line 188) | interface Ingredient {
type Recipe (line 194) | interface Recipe {
type RecipeAgentState (line 203) | interface RecipeAgentState {
constant INITIAL_STATE (line 207) | const INITIAL_STATE: RecipeAgentState = {
function Recipe (line 221) | function Recipe() {
function Ping (line 625) | function Ping() {
FILE: apps/dojo/src/app/[integrationId]/feature/(v2)/subgraphs/page.tsx
type SubgraphsProps (line 18) | interface SubgraphsProps {
type Flight (line 25) | interface Flight {
type Hotel (line 33) | interface Hotel {
type Experience (line 40) | interface Experience {
type Itinerary (line 47) | interface Itinerary {
type AvailableAgents (line 53) | type AvailableAgents = 'flights' | 'hotels' | 'experiences' | 'supervisor'
type TravelAgentState (line 55) | interface TravelAgentState {
constant INITIAL_STATE (line 64) | const INITIAL_STATE: TravelAgentState = {
type InterruptEvent (line 73) | interface InterruptEvent<TAgent extends AvailableAgents> {
function InterruptHumanInTheLoop (line 80) | function InterruptHumanInTheLoop<TAgent extends AvailableAgents>({
function Subgraphs (line 160) | function Subgraphs({ params }: SubgraphsProps) {
function TravelPlanner (line 284) | function TravelPlanner() {
FILE: apps/dojo/src/app/[integrationId]/feature/(v2)/tool_based_generative_ui/page.tsx
type ToolBasedGenerativeUIProps (line 20) | interface ToolBasedGenerativeUIProps {
type Haiku (line 26) | interface Haiku {
function ToolBasedGenerativeUI (line 33) | function ToolBasedGenerativeUI({ params }: ToolBasedGenerativeUIProps) {
function SidebarWithSuggestions (line 49) | function SidebarWithSuggestions({ defaultOpen }: { defaultOpen: boolean ...
constant VALID_IMAGE_NAMES (line 70) | const VALID_IMAGE_NAMES = [
function HaikuDisplay (line 83) | function HaikuDisplay() {
function HaikuCard (line 152) | function HaikuCard({ haiku }: { haiku: Partial<Haiku> }) {
FILE: apps/dojo/src/app/[integrationId]/feature/(v2)/vnext_chat/page.tsx
type PageProps (line 10) | interface PageProps {
function Page (line 16) | function Page({ params }: PageProps) {
function Chat (line 35) | function Chat({ threadId }: { threadId: string }) {
FILE: apps/dojo/src/app/[integrationId]/feature/layout-client.tsx
type FileItem (line 12) | type FileItem = {
type FilesJsonType (line 19) | type FilesJsonType = Record<string, FileItem[]>;
type Props (line 21) | interface Props {
function FeatureLayoutClient (line 25) | function FeatureLayoutClient({ children }: Props) {
FILE: apps/dojo/src/app/[integrationId]/feature/layout.tsx
type Props (line 8) | interface Props {
function FeatureLayout (line 12) | async function FeatureLayout({ children }: Props) {
FILE: apps/dojo/src/app/[integrationId]/feature/not-found.tsx
function FeatureNotFound (line 3) | function FeatureNotFound() {
FILE: apps/dojo/src/app/[integrationId]/not-found.tsx
function NotFound (line 4) | function NotFound() {
FILE: apps/dojo/src/app/[integrationId]/page.tsx
function generateStaticParams (line 8) | async function generateStaticParams() {
type IntegrationPageProps (line 17) | interface IntegrationPageProps {
function IntegrationPage (line 23) | function IntegrationPage({ params }: IntegrationPageProps) {
FILE: apps/dojo/src/app/api/copilotkit/[integrationId]/[[...slug]]/route.ts
type RouteParams (line 13) | type RouteParams = {
function getHandler (line 22) | async function getHandler(integrationId: string) {
function POST (line 50) | async function POST(request: NextRequest, context: RouteParams) {
FILE: apps/dojo/src/app/api/copilotkit/route.ts
constant GET (line 22) | const GET = handler;
constant POST (line 23) | const POST = handler;
FILE: apps/dojo/src/app/api/copilotkitnext/[integrationId]/[[...slug]]/route.ts
type RouteParams (line 14) | type RouteParams = {
function getHandler (line 25) | function getHandler(integrationId: string): Promise<any> {
function createHandler (line 37) | async function createHandler(integrationId: string): Promise<any> {
function GET (line 71) | async function GET(request: NextRequest, context: RouteParams) {
function POST (line 77) | async function POST(request: NextRequest, context: RouteParams) {
FILE: apps/dojo/src/app/layout.tsx
function RootLayout (line 25) | function RootLayout({
FILE: apps/dojo/src/app/page.tsx
function Home (line 5) | function Home() {
FILE: apps/dojo/src/components/code-viewer/code-editor.tsx
type CodeEditorProps (line 5) | interface CodeEditorProps {
function CodeEditor (line 10) | function CodeEditor({ file, onFileChange }: CodeEditorProps) {
FILE: apps/dojo/src/components/code-viewer/code-viewer.tsx
function CodeViewer (line 10) | function CodeViewer({ codeFiles }: { codeFiles: FeatureFile[] }) {
FILE: apps/dojo/src/components/demo-list/demo-list.tsx
type DemoListProps (line 6) | interface DemoListProps {
function DemoList (line 13) | function DemoList({ demos, selectedDemo, onSelect, llmSelector }: DemoLi...
FILE: apps/dojo/src/components/file-tree/file-tree-nav.tsx
type FileTreeNavProps (line 7) | interface FileTreeNavProps {
function FileTreeNav (line 13) | function FileTreeNav({ path, rootPath, onNavigate }: FileTreeNavProps) {
FILE: apps/dojo/src/components/file-tree/file-tree.tsx
type FileTreeProps (line 7) | interface FileTreeProps {
function FileTreeNode (line 13) | function FileTreeNode({
function FileTree (line 71) | function FileTree({ files, onFileSelect, selectedFile }: FileTreeProps) {
FILE: apps/dojo/src/components/layout/main-layout.tsx
function MainLayout (line 12) | function MainLayout({ children }: { children: React.ReactNode }) {
type MaybeSidebarProps (line 88) | interface MaybeSidebarProps {
function MaybeSidebar (line 94) | function MaybeSidebar({ isMobile, isMobileSidebarOpen, onMobileClose }: ...
FILE: apps/dojo/src/components/layout/viewer-layout.tsx
type ViewerLayoutProps (line 7) | interface ViewerLayoutProps extends ViewerConfig {
function ViewerLayout (line 15) | function ViewerLayout({
FILE: apps/dojo/src/components/readme/readme.tsx
function Readme (line 5) | function Readme({ content }: { content: string }) {
FILE: apps/dojo/src/components/sidebar/sidebar.tsx
type SidebarProps (line 30) | interface SidebarProps {
function Sidebar (line 35) | function Sidebar({ isMobile, onMobileClose }: SidebarProps) {
function SectionTitle (line 197) | function SectionTitle({ title }: { title: string }) {
FILE: apps/dojo/src/components/theme-provider.tsx
function ThemeProvider (line 6) | function ThemeProvider({ children, ...props }: NextThemeProviderProps) {
FILE: apps/dojo/src/components/theme-wrapper.tsx
function ThemeWrapper (line 6) | function ThemeWrapper({ children }: { children: React.ReactNode }) {
FILE: apps/dojo/src/components/ui/badge.tsx
function Badge (line 26) | function Badge({
FILE: apps/dojo/src/components/ui/button.tsx
function Button (line 35) | function Button({
FILE: apps/dojo/src/components/ui/carousel.tsx
type CarouselApi (line 12) | type CarouselApi = UseEmblaCarouselType[1]
type UseCarouselParameters (line 13) | type UseCarouselParameters = Parameters<typeof useEmblaCarousel>
type CarouselOptions (line 14) | type CarouselOptions = UseCarouselParameters[0]
type CarouselPlugin (line 15) | type CarouselPlugin = UseCarouselParameters[1]
type CarouselProps (line 17) | type CarouselProps = {
type CarouselContextProps (line 24) | type CarouselContextProps = {
function useCarousel (line 35) | function useCarousel() {
FILE: apps/dojo/src/components/ui/dropdown-menu.tsx
function DropdownMenu (line 9) | function DropdownMenu({ ...props }: React.ComponentProps<typeof Dropdown...
function DropdownMenuPortal (line 13) | function DropdownMenuPortal({
function DropdownMenuTrigger (line 19) | function DropdownMenuTrigger({
function DropdownMenuContent (line 25) | function DropdownMenuContent({
function DropdownMenuGroup (line 45) | function DropdownMenuGroup({ ...props }: React.ComponentProps<typeof Dro...
function DropdownMenuItem (line 49) | function DropdownMenuItem({
function DropdownMenuCheckboxItem (line 72) | function DropdownMenuCheckboxItem({
function DropdownMenuRadioGroup (line 98) | function DropdownMenuRadioGroup({
function DropdownMenuRadioItem (line 104) | function DropdownMenuRadioItem({
function DropdownMenuLabel (line 128) | function DropdownMenuLabel({
function DropdownMenuSeparator (line 145) | function DropdownMenuSeparator({
function DropdownMenuShortcut (line 158) | function DropdownMenuShortcut({ className, ...props }: React.ComponentPr...
function DropdownMenuSub (line 168) | function DropdownMenuSub({ ...props }: React.ComponentProps<typeof Dropd...
function DropdownMenuSubTrigger (line 172) | function DropdownMenuSubTrigger({
function DropdownMenuSubContent (line 196) | function DropdownMenuSubContent({
FILE: apps/dojo/src/components/ui/mdx-components.tsx
type Components (line 5) | type Components = ComponentProps<typeof Streamdown>['components'];
type CustomMDXComponents (line 25) | type CustomMDXComponents = Components & {
FILE: apps/dojo/src/components/ui/tabs.tsx
function Tabs (line 8) | function Tabs({ className, ...props }: React.ComponentProps<typeof TabsP...
function TabsList (line 14) | function TabsList({ className, ...props }: React.ComponentProps<typeof T...
function TabsTrigger (line 27) | function TabsTrigger({ className, ...props }: React.ComponentProps<typeo...
function TabsContent (line 40) | function TabsContent({ className, ...props }: React.ComponentProps<typeo...
FILE: apps/dojo/src/components/ui/theme-toggle.tsx
function ThemeToggle (line 9) | function ThemeToggle() {
FILE: apps/dojo/src/config.ts
function createFeatureConfig (line 4) | function createFeatureConfig({
FILE: apps/dojo/src/contexts/url-params-context.tsx
type URLParamsState (line 7) | interface URLParamsState {
type URLParamsContextType (line 19) | interface URLParamsContextType extends URLParamsState {
type URLParamsProviderProps (line 33) | interface URLParamsProviderProps {
function generateURLParamsState (line 37) | function generateURLParamsState(searchParams: URLSearchParams): URLParam...
function URLParamsProvider (line 51) | function URLParamsProvider({ children }: URLParamsProviderProps) {
function useURLParams (line 221) | function useURLParams(): URLParamsContextType {
FILE: apps/dojo/src/env.ts
type envVars (line 1) | type envVars = {
function getEnvVars (line 30) | function getEnvVars(): envVars {
FILE: apps/dojo/src/lib/utils.ts
function cn (line 4) | function cn(...inputs: ClassValue[]) {
FILE: apps/dojo/src/mastra/storage.ts
function getStorage (line 4) | function getStorage(): LibSQLStore | DynamoDBStore {
FILE: apps/dojo/src/proxy.ts
function proxy (line 5) | function proxy(request: NextRequest) {
FILE: apps/dojo/src/types/agents.ts
type UIOnlyFeature (line 5) | type UIOnlyFeature = "v1_agentic_chat";
type MenuAgentsMap (line 12) | type MenuAgentsMap = {
type AgentsMap (line 25) | type AgentsMap = MenuAgentsMap & {
FILE: apps/dojo/src/types/feature.ts
type ViewerConfig (line 1) | interface ViewerConfig {
type FeatureFile (line 7) | interface FeatureFile {
type FeatureConfig (line 15) | interface FeatureConfig {
FILE: apps/dojo/src/types/integration.ts
type Feature (line 3) | type Feature =
type MenuIntegrationConfig (line 18) | interface MenuIntegrationConfig {
type IntegrationFeature (line 27) | type IntegrationFeature<
type IntegrationId (line 33) | type IntegrationId = (typeof menuIntegrations)[number]["id"];
type FeatureFor (line 36) | type FeatureFor<Id extends IntegrationId> = IntegrationFeature<
FILE: apps/dojo/src/types/interface.ts
type View (line 1) | type View = "preview" | "code" | "readme";
FILE: apps/dojo/src/utils/agents.ts
function mapAgents (line 12) | function mapAgents<const T extends Record<string, unknown>>(
FILE: apps/dojo/src/utils/domain-config.ts
function getTitleForCurrentDomain (line 4) | function getTitleForCurrentDomain(): string | undefined {
FILE: apps/dojo/src/utils/menu.ts
function isIntegrationValid (line 4) | function isIntegrationValid(integrationId: string): boolean {
function isFeatureAvailable (line 9) | function isFeatureAvailable(integrationId: string, featureId: string): b...
function getIntegration (line 15) | function getIntegration(integrationId: string): MenuIntegrationConfig | ...
FILE: apps/dojo/src/utils/use-is-inside-iframe.ts
function useIsInsideIframe (line 3) | function useIsInsideIframe() {
function useIsInsideCpkFrame (line 17) | function useIsInsideCpkFrame(): boolean {
FILE: apps/dojo/src/utils/use-mobile-chat.ts
function useMobileChat (line 4) | function useMobileChat(defaultChatHeight = 50) {
FILE: apps/dojo/src/utils/use-mobile-view.ts
function useMobileView (line 3) | function useMobileView() {
FILE: docs/icons/index.tsx
function icon (line 5) | function icon(icon: any) {
FILE: integrations/a2a/typescript/src/__tests__/agent.test.ts
type SendMessageResponseSuccess (line 7) | type SendMessageResponseSuccess = {
type SendMessageResponseError (line 13) | type SendMessageResponseError = {
class FakeA2AClient (line 19) | class FakeA2AClient {
method constructor (line 20) | constructor(
method sendMessageStream (line 28) | sendMessageStream(params: MessageSendParams) {
method sendMessage (line 35) | async sendMessage(params: MessageSendParams) {
method isErrorResponse (line 42) | isErrorResponse(response: SendMessageResponseSuccess | SendMessageResp...
method getAgentCard (line 46) | async getAgentCard() {
FILE: integrations/a2a/typescript/src/agent.ts
type A2AAgentConfig (line 28) | interface A2AAgentConfig extends AgentConfig {
constant EXTENSION_URI (line 32) | const EXTENSION_URI = "https://a2ui.org/a2a-extension/a2ui/v0.8";
constant A2A_UI_MIME_TYPE (line 33) | const A2A_UI_MIME_TYPE = "application/json+a2ui";
class A2AAgent (line 35) | class A2AAgent extends AbstractAgent {
method constructor (line 39) | constructor(config: A2AAgentConfig) {
method clone (line 51) | clone() {
method run (line 55) | run(input: RunAgentInput): Observable<BaseEvent> {
method prepareConversation (line 128) | private prepareConversation(input: RunAgentInput): ConvertedA2AMessages {
method createSendParams (line 138) | private async createSendParams(
method streamMessage (line 160) | private async streamMessage(
method fallbackToBlocking (line 196) | private async fallbackToBlocking(
method blockingMessage (line 220) | private async blockingMessage(
method initializeExtension (line 265) | private initializeExtension(client: A2AClient) {
method createSurfaceTracker (line 357) | private createSurfaceTracker(): SurfaceTracker {
method attachForwardedAction (line 367) | private attachForwardedAction(
FILE: integrations/a2a/typescript/src/types.ts
type SurfaceTracker (line 26) | interface SurfaceTracker {
type A2AStreamEvent (line 31) | type A2AStreamEvent =
type ConvertAGUIMessagesOptions (line 37) | interface ConvertAGUIMessagesOptions {
type ConvertedA2AMessages (line 42) | interface ConvertedA2AMessages {
type ConvertA2AEventOptions (line 48) | interface ConvertA2AEventOptions {
type A2AAgentRunResultSummary (line 57) | interface A2AAgentRunResultSummary {
FILE: integrations/a2a/typescript/src/utils.ts
constant ROLE_MAP (line 25) | const ROLE_MAP: Record<string, "user" | "agent" | undefined> = {
constant TOOL_RESULT_PART_TYPE (line 33) | const TOOL_RESULT_PART_TYPE = "tool-result";
constant TOOL_CALL_PART_TYPE (line 34) | const TOOL_CALL_PART_TYPE = "tool-call";
constant SURFACE_OPERATION_KEYS (line 35) | const SURFACE_OPERATION_KEYS = [
type SurfaceOperationKey (line 41) | type SurfaceOperationKey = (typeof SURFACE_OPERATION_KEYS)[number];
function convertAGUIMessagesToA2A (line 190) | function convertAGUIMessagesToA2A(
function resolveMappedMessageId (line 251) | function resolveMappedMessageId(
function convertMessageToEvents (line 280) | function convertMessageToEvents(
function convertA2AEventToAGUIEvents (line 428) | function convertA2AEventToAGUIEvents(
FILE: integrations/adk-middleware/python/examples/other/complete_setup.py
function setup_and_run (line 46) | async def setup_and_run():
FILE: integrations/adk-middleware/python/examples/other/configure_adk_agent.py
function create_simple_agent (line 16) | def create_simple_agent():
function create_configured_agent (line 28) | def create_configured_agent():
function create_agent_with_tools (line 48) | def create_agent_with_tools():
function create_domain_agent (line 91) | def create_domain_agent():
function setup_multi_agent_system (line 113) | def setup_multi_agent_system():
function create_agent_from_env (line 138) | def create_agent_from_env():
function setup_adk_agents (line 150) | def setup_adk_agents():
FILE: integrations/adk-middleware/python/examples/other/context_usage.py
function context_aware_instructions (line 41) | def context_aware_instructions(ctx: ReadonlyContext) -> str:
function get_user_preferences (line 69) | def get_user_preferences(tool_context: ToolContext) -> dict:
function personalized_greeting (line 97) | def personalized_greeting(tool_context: ToolContext) -> str:
function main (line 124) | async def main():
function handle_event (line 180) | def handle_event(event: BaseEvent):
FILE: integrations/adk-middleware/python/examples/other/simple_agent.py
function main (line 22) | async def main():
function handle_event (line 75) | def handle_event(event: BaseEvent):
function advanced_example (line 97) | async def advanced_example():
FILE: integrations/adk-middleware/python/examples/server/__init__.py
function root (line 43) | async def root():
function main (line 59) | def main():
FILE: integrations/adk-middleware/python/examples/server/api/agentic_generative_ui.py
class Step (line 18) | class Step(BaseModel):
class Plan (line 28) | class Plan(BaseModel):
class JSONPatchOp (line 34) | class JSONPatchOp(BaseModel):
function create_plan (line 52) | async def create_plan(steps: list[str]) -> StateSnapshotEvent:
function update_plan_step (line 70) | async def update_plan_step(
FILE: integrations/adk-middleware/python/examples/server/api/backend_tool_rendering.py
function get_weather_condition (line 19) | def get_weather_condition(code: int) -> str:
function get_weather (line 61) | async def get_weather(location: str) -> dict[str, str | float]:
FILE: integrations/adk-middleware/python/examples/server/api/predictive_state_updates.py
function write_document_local (line 42) | def write_document_local(
function on_before_agent (line 68) | def on_before_agent(callback_context: CallbackContext):
FILE: integrations/adk-middleware/python/examples/server/api/shared_state.py
class SkillLevel (line 28) | class SkillLevel(str, Enum):
class SpecialPreferences (line 34) | class SpecialPreferences(str, Enum):
class CookingTime (line 43) | class CookingTime(str, Enum):
class Ingredient (line 49) | class Ingredient(BaseModel):
class Recipe (line 54) | class Recipe(BaseModel):
function generate_recipe (line 71) | def generate_recipe(
function on_before_agent (line 165) | def on_before_agent(callback_context: CallbackContext):
function before_model_modifier (line 188) | def before_model_modifier(
function simple_after_model_modifier (line 224) | def simple_after_model_modifier(
FILE: integrations/adk-middleware/python/src/ag_ui_adk/__init__.py
function _configure_logging_from_env (line 37) | def _configure_logging_from_env() -> None:
FILE: integrations/adk-middleware/python/src/ag_ui_adk/adk_agent.py
class ADKAgent (line 60) | class ADKAgent:
method __init__ (line 67) | def __init__(
method _is_adk_resumable (line 241) | def _is_adk_resumable(self) -> bool:
method _root_agent_needs_invocation_id (line 259) | def _root_agent_needs_invocation_id(self) -> bool:
method from_app (line 283) | def from_app(
method _get_session_metadata (line 399) | def _get_session_metadata(self, thread_id: str) -> Optional[Tuple[str,...
method _get_backend_session_id (line 410) | def _get_backend_session_id(self, thread_id: str) -> Optional[str]:
method _get_app_name (line 422) | def _get_app_name(self, input: RunAgentInput) -> str:
method _default_app_extractor (line 431) | def _default_app_extractor(self, input: RunAgentInput) -> str:
method _get_user_id (line 440) | def _get_user_id(self, input: RunAgentInput) -> str:
method _default_user_extractor (line 449) | def _default_user_extractor(self, input: RunAgentInput) -> str:
method _add_pending_tool_call_with_context (line 454) | async def _add_pending_tool_call_with_context(self, thread_id: str, to...
method _remove_pending_tool_call (line 499) | async def _remove_pending_tool_call(self, thread_id: str, tool_call_id...
method _get_pending_tool_call_ids (line 540) | async def _get_pending_tool_call_ids(self, thread_id: str) -> Optional...
method _has_pending_tool_calls (line 564) | async def _has_pending_tool_calls(self, thread_id: str) -> bool:
method _extract_lro_id_remap (line 579) | def _extract_lro_id_remap(
method _store_lro_id_remap (line 618) | async def _store_lro_id_remap(
method _get_lro_id_remap (line 650) | async def _get_lro_id_remap(
method _consume_lro_id_remap (line 669) | async def _consume_lro_id_remap(
method _default_run_config (line 703) | def _default_run_config(self, input: RunAgentInput) -> ADKRunConfig:
method _run_config_supports_custom_metadata (line 730) | def _run_config_supports_custom_metadata(self) -> bool:
method _runner_supports_plugin_close_timeout (line 742) | def _runner_supports_plugin_close_timeout(self) -> bool:
method _adk_supports_streaming_fc_args (line 755) | def _adk_supports_streaming_fc_args() -> bool:
method _create_runner (line 773) | def _create_runner(self, adk_agent: BaseAgent, user_id: str, app_name:...
method run (line 812) | async def run(self, input: RunAgentInput) -> AsyncGenerator[BaseEvent,...
method _ensure_session_exists (line 1009) | async def _ensure_session_exists(self, app_name: str, user_id: str, th...
method _convert_latest_message (line 1071) | async def _convert_latest_message(
method _get_unseen_messages (line 1093) | async def _get_unseen_messages(self, input: RunAgentInput) -> List[Any]:
method _collect_message_ids (line 1122) | def _collect_message_ids(self, messages: List[Any]) -> List[str]:
method _is_tool_result_submission (line 1126) | async def _is_tool_result_submission(
method _handle_tool_result_submission (line 1148) | async def _handle_tool_result_submission(
method _extract_tool_results (line 1273) | async def _extract_tool_results(
method _stream_events (line 1334) | async def _stream_events(
method _start_new_execution (line 1405) | async def _start_new_execution(
method _shallow_copy_agent_tree (line 1534) | def _shallow_copy_agent_tree(agent: Any) -> Any:
method _start_background_execution (line 1561) | async def _start_background_execution(
method _run_adk_in_background (line 1704) | async def _run_adk_in_background(
method _cleanup_stale_executions (line 2362) | async def _cleanup_stale_executions(self):
method close (line 2375) | async def close(self):
FILE: integrations/adk-middleware/python/src/ag_ui_adk/agui_toolset.py
class AGUIToolset (line 7) | class AGUIToolset(BaseToolset):
method __init__ (line 13) | def __init__(
method get_tools (line 28) | async def get_tools(
FILE: integrations/adk-middleware/python/src/ag_ui_adk/client_proxy_tool.py
class ClientProxyTool (line 28) | class ClientProxyTool(BaseTool):
method __init__ (line 38) | def __init__(
method _get_declaration (line 118) | def _get_declaration(self) -> Optional[types.FunctionDeclaration]:
method run_async (line 146) | async def run_async(
method _execute_proxy_tool (line 168) | async def _execute_proxy_tool(self, args: Dict[str, Any], tool_context...
method __repr__ (line 267) | def __repr__(self) -> str:
FILE: integrations/adk-middleware/python/src/ag_ui_adk/client_proxy_toolset.py
class ClientProxyToolset (line 20) | class ClientProxyToolset(BaseToolset):
method __init__ (line 27) | def __init__(
method get_tools (line 65) | async def get_tools(
method get_accumulated_predict_state (line 123) | def get_accumulated_predict_state(self) -> dict:
method close (line 134) | async def close(self) -> None:
method __repr__ (line 138) | def __repr__(self) -> str:
FILE: integrations/adk-middleware/python/src/ag_ui_adk/config.py
class PredictStateMapping (line 12) | class PredictStateMapping:
method to_payload (line 34) | def to_payload(self) -> Dict[str, str]:
function normalize_predict_state (line 43) | def normalize_predict_state(value: Optional[Iterable[PredictStateMapping...
FILE: integrations/adk-middleware/python/src/ag_ui_adk/endpoint.py
class AgentStateRequest (line 22) | class AgentStateRequest(BaseModel):
class AgentStateResponse (line 34) | class AgentStateResponse(BaseModel):
function _header_to_key (line 42) | def _header_to_key(header_name: str) -> str:
function make_extract_headers (line 53) | def make_extract_headers(headers_to_extract: list[str]) -> Callable[[Req...
function add_adk_fastapi_endpoint (line 85) | def add_adk_fastapi_endpoint(
function create_adk_app (line 298) | def create_adk_app(
FILE: integrations/adk-middleware/python/src/ag_ui_adk/event_translator.py
function _check_thought_support (line 35) | def _check_thought_support() -> bool:
function _coerce_tool_response (line 62) | def _coerce_tool_response(value: Any, _visited: Optional[set[int]] = Non...
function _serialize_tool_response (line 146) | def _serialize_tool_response(response: Any) -> str:
class EventTranslator (line 160) | class EventTranslator:
method __init__ (line 167) | def __init__(
method get_and_clear_deferred_confirm_events (line 268) | def get_and_clear_deferred_confirm_events(self) -> List[BaseEvent]:
method has_deferred_confirm_events (line 281) | def has_deferred_confirm_events(self) -> bool:
method translate (line 289) | async def translate(
method translate_text_only (line 428) | async def translate_text_only(
method _translate_text_content (line 454) | async def _translate_text_content(
method _translate_thinking_content (line 660) | async def _translate_thinking_content(
method _close_thinking_stream (line 708) | async def _close_thinking_stream(self) -> AsyncGenerator[BaseEvent, No...
method translate_lro_function_calls (line 732) | async def translate_lro_function_calls(self,adk_event: ADKEvent)-> Asy...
method _translate_function_calls (line 782) | async def _translate_function_calls(
method _translate_streaming_function_call (line 898) | async def _translate_streaming_function_call(
method _translate_function_response (line 1034) | async def _translate_function_response(
method _create_state_delta_event (line 1076) | def _create_state_delta_event(
method _create_state_snapshot_event (line 1107) | def _create_state_snapshot_event(
method force_close_streaming_message (line 1125) | async def force_close_streaming_message(self) -> AsyncGenerator[BaseEv...
method reset (line 1148) | def reset(self):
function _translate_function_calls_to_tool_calls (line 1182) | def _translate_function_calls_to_tool_calls(function_calls: List[Any]) -...
function _is_thought_part (line 1205) | def _is_thought_part(part: Any) -> bool:
function adk_events_to_messages (line 1216) | def adk_events_to_messages(events: List[ADKEvent]) -> List[Message]:
FILE: integrations/adk-middleware/python/src/ag_ui_adk/execution_state.py
class ExecutionState (line 13) | class ExecutionState:
method __init__ (line 22) | def __init__(
method is_stale (line 44) | def is_stale(self, timeout_seconds: int) -> bool:
method cancel (line 55) | async def cancel(self):
method get_execution_time (line 69) | def get_execution_time(self) -> float:
method add_pending_tool_call (line 77) | def add_pending_tool_call(self, tool_call_id: str):
method remove_pending_tool_call (line 86) | def remove_pending_tool_call(self, tool_call_id: str):
method has_pending_tool_calls (line 95) | def has_pending_tool_calls(self) -> bool:
method get_status (line 103) | def get_status(self) -> str:
method __repr__ (line 119) | def __repr__(self) -> str:
FILE: integrations/adk-middleware/python/src/ag_ui_adk/session_manager.py
class SessionManager (line 20) | class SessionManager:
method __new__ (line 35) | def __new__(cls, session_service=None, **kwargs):
method __init__ (line 41) | def __init__(
method get_instance (line 103) | def get_instance(cls, **kwargs):
method reset_instance (line 108) | def reset_instance(cls):
method get_or_create_session (line 120) | async def get_or_create_session(
method _get_or_create_by_thread_id (line 171) | async def _get_or_create_by_thread_id(
method _get_or_create_by_scan (line 215) | async def _get_or_create_by_scan(
method _find_session_by_thread_id (line 245) | async def _find_session_by_thread_id(
method get_session (line 280) | async def get_session(
method update_session_state (line 308) | async def update_session_state(
method get_session_state (line 379) | async def get_session_state(
method get_state_value (line 417) | async def get_state_value(
method set_state_value (line 457) | async def set_state_value(
method remove_state_keys (line 484) | async def remove_state_keys(
method clear_session_state (line 529) | async def clear_session_state(
method initialize_session_state (line 575) | async def initialize_session_state(
method bulk_update_user_state (line 623) | async def bulk_update_user_state(
method _track_session (line 665) | def _track_session(self, session_key: str, user_id: str):
method _untrack_session (line 673) | def _untrack_session(self, session_key: str, user_id: str):
method _make_session_key (line 683) | def _make_session_key(self, app_name: str, session_id: str) -> str:
method get_processed_message_ids (line 686) | def get_processed_message_ids(self, app_name: str, session_id: str) ->...
method mark_messages_processed (line 690) | def mark_messages_processed(
method _remove_oldest_user_session (line 703) | async def _remove_oldest_user_session(self, user_id: str):
method _delete_session (line 733) | async def _delete_session(self, session):
method _start_cleanup_task (line 767) | def _start_cleanup_task(self):
method _cleanup_loop (line 776) | async def _cleanup_loop(self):
method _cleanup_expired_sessions (line 790) | async def _cleanup_expired_sessions(self):
method get_session_count (line 837) | def get_session_count(self) -> int:
method get_user_session_count (line 841) | def get_user_session_count(self, user_id: str) -> int:
method stop_cleanup_task (line 845) | async def stop_cleanup_task(self):
FILE: integrations/adk-middleware/python/src/ag_ui_adk/utils/converters.py
function _get_text_value (line 20) | def _get_text_value(item: Union[dict, TextInputContent]) -> Optional[str]:
function _get_binary_attributes (line 27) | def _get_binary_attributes(item: Union[dict, BinaryInputContent]) -> Tup...
function _to_binary_part (line 44) | def _to_binary_part(data: Optional[str], mime_type: Optional[str], url: ...
function _to_text_part (line 75) | def _to_text_part(text: Optional[str]) -> Optional[types.Part]:
function _is_text_content (line 81) | def _is_text_content(item: Union[dict, InputContent]) -> bool:
function _is_binary_content (line 86) | def _is_binary_content(item: Union[dict, InputContent]) -> bool:
function convert_message_content_to_parts (line 91) | def convert_message_content_to_parts(content: Optional[Union[str, List[A...
function convert_ag_ui_messages_to_adk (line 123) | def convert_ag_ui_messages_to_adk(messages: List[Message]) -> List[ADKEv...
function convert_adk_event_to_ag_ui_message (line 198) | def convert_adk_event_to_ag_ui_message(event: ADKEvent) -> Optional[Mess...
function convert_state_to_json_patch (line 254) | def convert_state_to_json_patch(state_delta: Dict[str, Any]) -> List[Dic...
function convert_json_patch_to_state (line 285) | def convert_json_patch_to_state(patches: List[Dict[str, Any]]) -> Dict[s...
function extract_text_from_content (line 312) | def extract_text_from_content(content: types.Content) -> str:
function flatten_message_content (line 325) | def flatten_message_content(content: Any) -> str:
function create_error_message (line 339) | def create_error_message(error: Exception, context: str = "") -> str:
FILE: integrations/adk-middleware/python/tests/conftest.py
function restore_system_message_class (line 13) | def restore_system_message_class():
FILE: integrations/adk-middleware/python/tests/server_setup.py
function root (line 54) | async def root():
function health (line 65) | async def health():
FILE: integrations/adk-middleware/python/tests/test_adk_agent.py
class TestADKAgent (line 25) | class TestADKAgent:
method mock_agent (line 29) | def mock_agent(self):
method reset_session_manager (line 37) | def reset_session_manager(self):
method adk_agent (line 53) | def adk_agent(self, mock_agent):
method sample_input (line 63) | def sample_input(self):
method test_agent_initialization (line 84) | async def test_agent_initialization(self, adk_agent):
method test_user_extraction (line 91) | async def test_user_extraction(self, adk_agent, sample_input):
method test_adk_agent_has_direct_reference (line 108) | async def test_adk_agent_has_direct_reference(self, adk_agent, sample_...
method test_run_basic_flow (line 115) | async def test_run_basic_flow(self, adk_agent, sample_input, mock_agent):
method test_runner_close_called_on_run_error (line 150) | async def test_runner_close_called_on_run_error(self, adk_agent, sampl...
method test_turn_complete_falls_back_to_streaming_translator (line 174) | async def test_turn_complete_falls_back_to_streaming_translator(
method test_partial_final_chunk_uses_streaming_translation (line 238) | async def test_partial_final_chunk_uses_streaming_translation(self, ad...
method test_streaming_finish_reason_fallback (line 288) | async def test_streaming_finish_reason_fallback(self, adk_agent, sampl...
method test_session_management (line 386) | async def test_session_management(self, adk_agent):
method test_error_handling (line 409) | async def test_error_handling(self, adk_agent, sample_input):
method test_cleanup (line 428) | async def test_cleanup(self, adk_agent):
method test_system_message_appended_to_instructions (line 444) | async def test_system_message_appended_to_instructions(self):
method test_system_message_appended_to_instruction_provider (line 491) | async def test_system_message_appended_to_instruction_provider(self):
method test_system_message_appended_to_instruction_provider_with_none (line 552) | async def test_system_message_appended_to_instruction_provider_with_no...
method test_system_message_appended_to_sync_instruction_provider (line 607) | async def test_system_message_appended_to_sync_instruction_provider(se...
method test_system_message_not_first_ignored (line 668) | async def test_system_message_not_first_ignored(self):
method test_system_message_with_no_existing_instruction (line 707) | async def test_system_message_with_no_existing_instruction(self):
method test_final_response_after_backend_tool_emits_text (line 740) | async def test_final_response_after_backend_tool_emits_text(self, adk_...
method test_skip_summarization_routes_through_translate_for_tool_result (line 809) | async def test_skip_summarization_routes_through_translate_for_tool_re...
method test_agui_tools_properly_converted_in_subagents (line 890) | async def test_agui_tools_properly_converted_in_subagents(self):
method test_non_deepcopyable_tool_does_not_crash (line 971) | async def test_non_deepcopyable_tool_does_not_crash(self):
method test_original_agent_not_mutated_after_run (line 1032) | async def test_original_agent_not_mutated_after_run(self):
class TestThreadIdSessionIdMapping (line 1081) | class TestThreadIdSessionIdMapping:
method reset_session_manager (line 1085) | def reset_session_manager(self):
method mock_agent (line 1098) | def mock_agent(self):
method adk_agent (line 1107) | def adk_agent(self, mock_agent):
method test_thread_id_becomes_session_id (line 1117) | async def test_thread_id_becomes_session_id(self, adk_agent):
method test_initial_state_passed_to_session (line 1176) | async def test_initial_state_passed_to_session(self, adk_agent):
method test_state_synced_via_update_session_state (line 1237) | async def test_state_synced_via_update_session_state(self, adk_agent):
method test_empty_initial_state (line 1299) | async def test_empty_initial_state(self, adk_agent):
FILE: integrations/adk-middleware/python/tests/test_adk_agent_memory_integration.py
class TestADKAgentMemoryIntegration (line 13) | class TestADKAgentMemoryIntegration:
method mock_agent (line 17) | def mock_agent(self):
method reset_session_manager (line 26) | def reset_session_manager(self):
method mock_memory_service (line 33) | def mock_memory_service(self):
method simple_input (line 40) | def simple_input(self):
method test_adk_agent_memory_service_initialization_explicit (line 52) | def test_adk_agent_memory_service_initialization_explicit(self, mock_m...
method test_adk_agent_memory_service_initialization_in_memory (line 65) | def test_adk_agent_memory_service_initialization_in_memory(self, mock_...
method test_adk_agent_memory_service_initialization_disabled (line 79) | def test_adk_agent_memory_service_initialization_disabled(self, mock_a...
method test_adk_agent_passes_memory_service_to_session_manager (line 92) | def test_adk_agent_passes_memory_service_to_session_manager(self, mock...
method test_adk_agent_memory_service_sharing_same_instance (line 111) | def test_adk_agent_memory_service_sharing_same_instance(self, mock_mem...
method test_adk_agent_creates_runner_with_memory_service (line 129) | def test_adk_agent_creates_runner_with_memory_service(self, mock_runne...
method test_adk_agent_memory_service_configuration_inheritance (line 173) | def test_adk_agent_memory_service_configuration_inheritance(self, mock...
method test_adk_agent_in_memory_memory_service_defaults (line 193) | def test_adk_agent_in_memory_memory_service_defaults(self, mock_agent):
FILE: integrations/adk-middleware/python/tests/test_adk_llm_flow_tool_override.py
class TestAdkLlmFlowToolOverride (line 12) | class TestAdkLlmFlowToolOverride:
method test_llm_flow_handles_tool_overrides (line 15) | async def test_llm_flow_handles_tool_overrides(self):
FILE: integrations/adk-middleware/python/tests/test_app_name_extractor.py
function test_static_app_name (line 9) | async def test_static_app_name():
function test_custom_extractor (line 46) | async def test_custom_extractor():
function test_default_extractor (line 106) | async def test_default_extractor():
function test_conflicting_config (line 144) | async def test_conflicting_config():
function test_combined_extractors (line 168) | async def test_combined_extractors():
function test_no_app_config (line 222) | async def test_no_app_config():
function main (line 258) | async def main():
FILE: integrations/adk-middleware/python/tests/test_chunk_event.py
function test_content_event (line 8) | def test_content_event():
function test_wrong_parameters (line 36) | def test_wrong_parameters():
FILE: integrations/adk-middleware/python/tests/test_claude_streaming.py
class MockClaudeADKEvent (line 25) | class MockClaudeADKEvent:
method __init__ (line 28) | def __init__(
method is_final_response (line 46) | def is_final_response(self) -> bool:
method get_function_calls (line 49) | def get_function_calls(self):
method get_function_responses (line 52) | def get_function_responses(self):
function test_claude_streaming_with_final_consolidated_message (line 57) | async def test_claude_streaming_with_final_consolidated_message():
function test_claude_streaming_closed_by_final_response (line 120) | async def test_claude_streaming_closed_by_final_response():
function test_claude_non_streaming_single_response (line 176) | async def test_claude_non_streaming_single_response():
function test_claude_repeated_runs_no_duplicate (line 210) | async def test_claude_repeated_runs_no_duplicate():
function test_claude_accumulated_text_in_chunks (line 264) | async def test_claude_accumulated_text_in_chunks():
function test_claude_accumulated_text_with_early_stream_end (line 317) | async def test_claude_accumulated_text_with_early_stream_end():
function test_claude_stream_ended_before_final (line 389) | async def test_claude_stream_ended_before_final():
FILE: integrations/adk-middleware/python/tests/test_client_proxy_tool.py
class TestClientProxyTool (line 17) | class TestClientProxyTool:
method sample_tool_definition (line 21) | def sample_tool_definition(self):
method mock_event_queue (line 48) | def mock_event_queue(self):
method proxy_tool (line 54) | def proxy_tool(self, sample_tool_definition, mock_event_queue):
method test_initialization (line 61) | def test_initialization(self, proxy_tool, sample_tool_definition, mock...
method test_get_declaration (line 68) | def test_get_declaration(self, proxy_tool):
method test_get_declaration_with_invalid_parameters (line 81) | def test_get_declaration_with_invalid_parameters(self, mock_event_queue):
method test_run_async_success (line 101) | async def test_run_async_success(self, proxy_tool, mock_event_queue):
method test_run_async_event_queue_error (line 140) | async def test_run_async_event_queue_error(self, proxy_tool):
method test_string_representation (line 158) | def test_string_representation(self, proxy_tool):
method test_multiple_concurrent_executions (line 169) | async def test_multiple_concurrent_executions(self, proxy_tool, mock_e...
method test_json_serialization_in_args (line 196) | async def test_json_serialization_in_args(self, proxy_tool, mock_event...
class TestClientProxyToolPredictState (line 226) | class TestClientProxyToolPredictState:
method tool_with_predict_state (line 230) | def tool_with_predict_state(self):
method predict_state_mappings (line 244) | def predict_state_mappings(self):
method test_predict_state_emitted_before_tool_call (line 255) | async def test_predict_state_emitted_before_tool_call(self, tool_with_...
method test_predict_state_only_emitted_once_with_shared_tracking (line 291) | async def test_predict_state_only_emitted_once_with_shared_tracking(se...
method test_predict_state_tracking_isolates_between_instances (line 333) | async def test_predict_state_tracking_isolates_between_instances(self,...
method test_no_predict_state_when_no_mapping (line 372) | async def test_no_predict_state_when_no_mapping(self):
method test_default_tracking_set_when_none_provided (line 410) | async def test_default_tracking_set_when_none_provided(self, tool_with...
FILE: integrations/adk-middleware/python/tests/test_client_proxy_toolset.py
class TestClientProxyToolset (line 15) | class TestClientProxyToolset:
method sample_tools (line 19) | def sample_tools(self):
method mock_event_queue (line 53) | def mock_event_queue(self):
method toolset (line 58) | def toolset(self, sample_tools, mock_event_queue):
method test_initialization (line 65) | def test_initialization(self, toolset, sample_tools, mock_event_queue):
method test_get_tools_first_call (line 71) | async def test_get_tools_first_call(self, toolset, sample_tools):
method test_get_tools_fresh_instances (line 89) | async def test_get_tools_fresh_instances(self, toolset):
method test_get_tools_with_readonly_context (line 108) | async def test_get_tools_with_readonly_context(self, toolset):
method test_get_tools_empty_list (line 118) | async def test_get_tools_empty_list(self, mock_event_queue):
method test_get_tools_with_invalid_tool (line 131) | async def test_get_tools_with_invalid_tool(self, mock_event_queue):
method test_close_no_pending_futures (line 158) | async def test_close_no_pending_futures(self, toolset):
method test_close_with_pending_futures (line 166) | async def test_close_with_pending_futures(self, toolset):
method test_close_idempotent (line 174) | async def test_close_idempotent(self, toolset):
method test_string_representation (line 182) | def test_string_representation(self, toolset):
method test_string_representation_empty (line 191) | def test_string_representation_empty(self, mock_event_queue):
method test_tool_properties_preserved (line 204) | async def test_tool_properties_preserved(self, toolset, sample_tools):
method test_shared_state_between_tools (line 216) | async def test_shared_state_between_tools(self, toolset, mock_event_qu...
method test_tool_timeout_configuration (line 225) | async def test_tool_timeout_configuration(self, sample_tools, mock_eve...
method test_lifecycle_get_tools_then_close (line 239) | async def test_lifecycle_get_tools_then_close(self, toolset):
method test_multiple_toolsets_isolation (line 253) | async def test_multiple_toolsets_isolation(self, sample_tools):
method test_filtered_toolset (line 276) | async def test_filtered_toolset(self, sample_tools, mock_event_queue):
method test_filtered_toolset_with_function (line 292) | async def test_filtered_toolset_with_function(self, sample_tools, mock...
method test_toolset_with_name_prefix (line 308) | async def test_toolset_with_name_prefix(self, sample_tools, mock_event...
method test_toolset_with_no_tools (line 326) | async def test_toolset_with_no_tools(self, mock_event_queue):
class TestClientProxyToolsetPredictStateTracking (line 340) | class TestClientProxyToolsetPredictStateTracking:
method tool_with_predict_state (line 344) | def tool_with_predict_state(self):
method predict_state_mappings (line 358) | def predict_state_mappings(self):
method test_toolset_creates_tracking_set (line 368) | def test_toolset_creates_tracking_set(self, tool_with_predict_state, p...
method test_tools_share_toolset_tracking_set (line 384) | async def test_tools_share_toolset_tracking_set(self, tool_with_predic...
method test_separate_toolsets_have_isolated_tracking (line 413) | async def test_separate_toolsets_have_isolated_tracking(self, tool_wit...
method test_toolset_tracking_persists_across_get_tools_calls (line 439) | async def test_toolset_tracking_persists_across_get_tools_calls(self, ...
method test_new_toolset_has_fresh_tracking (line 462) | async def test_new_toolset_has_fresh_tracking(self, tool_with_predict_...
FILE: integrations/adk-middleware/python/tests/test_concurrency.py
function simulate_concurrent_requests (line 12) | async def simulate_concurrent_requests():
function test_event_translator_isolation (line 133) | async def test_event_translator_isolation():
function main (line 162) | async def main():
FILE: integrations/adk-middleware/python/tests/test_concurrent_limits.py
class TestConcurrentLimits (line 16) | class TestConcurrentLimits:
method mock_adk_agent (line 21) | def mock_adk_agent(self):
method adk_middleware (line 31) | def adk_middleware(self, mock_adk_agent):
method sample_input (line 42) | def sample_input(self):
method test_concurrent_execution_limit_enforcement (line 57) | async def test_concurrent_execution_limit_enforcement(self, adk_middle...
method test_stale_execution_cleanup_frees_slots (line 145) | async def test_stale_execution_cleanup_frees_slots(self, adk_middleware):
method test_mixed_stale_and_active_executions (line 176) | async def test_mixed_stale_and_active_executions(self, adk_middleware):
method test_zero_concurrent_limit (line 203) | async def test_zero_concurrent_limit(self):
method test_execution_completion_frees_slot (line 233) | async def test_execution_completion_frees_slot(self, adk_middleware):
method test_execution_with_pending_tools_not_cleaned (line 264) | async def test_execution_with_pending_tools_not_cleaned(self, adk_midd...
method test_high_concurrent_limit (line 292) | async def test_high_concurrent_limit(self):
method test_cleanup_during_limit_check (line 317) | async def test_cleanup_during_limit_check(self, adk_middleware):
FILE: integrations/adk-middleware/python/tests/test_context_handling.py
class TestContextStateKey (line 26) | class TestContextStateKey:
method test_context_state_key_value (line 29) | def test_context_state_key_value(self):
method test_context_state_key_exported (line 33) | def test_context_state_key_exported(self):
class TestContextInSessionState (line 39) | class TestContextInSessionState:
method reset_session_manager (line 43) | def reset_session_manager(self):
method mock_agent (line 56) | def mock_agent(self):
method adk_agent (line 65) | def adk_agent(self, mock_agent):
method test_context_included_in_session_state (line 75) | async def test_context_included_in_session_state(self, adk_agent):
method test_empty_context_not_in_state (line 130) | async def test_empty_context_not_in_state(self, adk_agent):
class TestContextSerializationFormat (line 173) | class TestContextSerializationFormat:
method reset_session_manager (line 177) | def reset_session_manager(self):
method mock_agent (line 190) | def mock_agent(self):
method adk_agent (line 199) | def adk_agent(self, mock_agent):
method test_context_serialization_format (line 209) | async def test_context_serialization_format(self, adk_agent):
class TestCustomRunConfigFactory (line 263) | class TestCustomRunConfigFactory:
method reset_session_manager (line 267) | def reset_session_manager(self):
method mock_agent (line 280) | def mock_agent(self):
method test_custom_run_config_factory_receives_input (line 286) | def test_custom_run_config_factory_receives_input(self, mock_agent):
class TestDefaultRunConfigUnchanged (line 325) | class TestDefaultRunConfigUnchanged:
method reset_session_manager (line 329) | def reset_session_manager(self):
method mock_agent (line 342) | def mock_agent(self):
method adk_agent (line 349) | def adk_agent(self, mock_agent):
method test_default_run_config_returns_valid_config (line 358) | def test_default_run_config_returns_valid_config(self, adk_agent):
class TestVersionDetection (line 379) | class TestVersionDetection:
method reset_session_manager (line 383) | def reset_session_manager(self):
method mock_agent (line 396) | def mock_agent(self):
method adk_agent (line 403) | def adk_agent(self, mock_agent):
method test_run_config_supports_custom_metadata_returns_bool (line 412) | def test_run_config_supports_custom_metadata_returns_bool(self, adk_ag...
method test_custom_metadata_included_when_supported (line 417) | def test_custom_metadata_included_when_supported(self, adk_agent):
method test_empty_context_no_custom_metadata (line 452) | def test_empty_context_no_custom_metadata(self, adk_agent):
FILE: integrations/adk-middleware/python/tests/test_context_integration.py
function collect_events (line 32) | async def collect_events(agent: ADKAgent, run_input: RunAgentInput) -> L...
function get_event_types (line 40) | def get_event_types(events: List[BaseEvent]) -> List[str]:
class TestContextInInstructionProvider (line 45) | class TestContextInInstructionProvider:
method reset_session_manager (line 49) | def reset_session_manager(self):
method test_instruction_provider_receives_context (line 56) | async def test_instruction_provider_receives_context(self):
class TestContextInTools (line 120) | class TestContextInTools:
method reset_session_manager (line 124) | def reset_session_manager(self):
method test_tool_can_access_context_from_state (line 131) | async def test_tool_can_access_context_from_state(self):
class TestContextInStateSnapshot (line 202) | class TestContextInStateSnapshot:
method reset_session_manager (line 206) | def reset_session_manager(self):
method test_state_snapshot_includes_context (line 213) | async def test_state_snapshot_includes_context(self):
class TestContextPersistenceAcrossRuns (line 273) | class TestContextPersistenceAcrossRuns:
method reset_session_manager (line 277) | def reset_session_manager(self):
method test_context_updates_between_runs (line 284) | async def test_context_updates_between_runs(self):
FILE: integrations/adk-middleware/python/tests/test_credential_service_defaults.py
function test_credential_service_import (line 4) | def test_credential_service_import():
function test_adk_agent_defaults (line 24) | def test_adk_agent_defaults():
function test_adk_agent_explicit_none (line 60) | def test_adk_agent_explicit_none():
function test_all_service_defaults (line 90) | def test_all_service_defaults():
function main (line 143) | def main():
FILE: integrations/adk-middleware/python/tests/test_duplicate_function_response.py
class TestDuplicateFunctionResponseFix (line 36) | class TestDuplicateFunctionResponseFix:
method mock_adk_agent (line 40) | def mock_adk_agent(self):
method ag_ui_adk (line 50) | def ag_ui_adk(self, mock_adk_agent):
method _setup_session_with_tool_call (line 65) | async def _setup_session_with_tool_call(
method _count_function_responses_in_session (line 113) | def _count_function_responses_in_session(self, session, tool_call_id: ...
method test_no_duplicate_function_response_without_user_message (line 126) | async def test_no_duplicate_function_response_without_user_message(sel...
method test_function_response_persisted_with_user_message (line 248) | async def test_function_response_persisted_with_user_message(self, ag_...
method test_multiple_tool_results_without_user_message (line 365) | async def test_multiple_tool_results_without_user_message(self, ag_ui_...
FILE: integrations/adk-middleware/python/tests/test_endpoint.py
class TestAddADKFastAPIEndpoint (line 16) | class TestAddADKFastAPIEndpoint:
method mock_agent (line 20) | def mock_agent(self):
method app (line 28) | def app(self, request):
method get_test_app (line 32) | def get_test_app(self, app):
method sample_input (line 45) | def sample_input(self):
method test_add_endpoint_default_path (line 59) | def test_add_endpoint_default_path(self, app, mock_agent):
method test_add_endpoint_custom_path (line 67) | def test_add_endpoint_custom_path(self, app, mock_agent):
method test_endpoint_method_is_post (line 75) | def test_endpoint_method_is_post(self, app, mock_agent):
method test_endpoint_creates_event_encoder (line 84) | def test_endpoint_creates_event_encoder(self, mock_encoder_class, app,...
method test_endpoint_agent_id_extraction (line 113) | def test_endpoint_agent_id_extraction(self, mock_encoder_class, app, m...
method test_endpoint_root_path_agent_id (line 138) | def test_endpoint_root_path_agent_id(self, mock_encoder_class, app, mo...
method test_endpoint_successful_event_streaming (line 164) | def test_endpoint_successful_event_streaming(self, mock_logger, mock_e...
method test_endpoint_encoding_error_handling (line 203) | def test_endpoint_encoding_error_handling(self, mock_logger, mock_enco...
method test_endpoint_encoding_error_double_failure (line 247) | def test_endpoint_encoding_error_double_failure(self, mock_logger, moc...
method test_endpoint_agent_error_handling (line 284) | def test_endpoint_agent_error_handling(self, mock_logger, mock_encoder...
method test_endpoint_agent_error_encoding_failure (line 317) | def test_endpoint_agent_error_encoding_failure(self, mock_logger, mock...
method test_endpoint_returns_streaming_response (line 347) | def test_endpoint_returns_streaming_response(self, mock_encoder_class,...
method test_endpoint_input_validation (line 374) | def test_endpoint_input_validation(self, app, mock_agent):
method test_endpoint_no_accept_header (line 387) | def test_endpoint_no_accept_header(self, mock_encoder_class, app, mock...
class TestCreateADKApp (line 416) | class TestCreateADKApp:
method mock_agent (line 420) | def mock_agent(self):
method test_create_app_basic (line 424) | def test_create_app_basic(self, mock_agent):
method test_create_app_custom_path (line 435) | def test_create_app_custom_path(self, mock_agent):
method test_create_app_calls_add_endpoint (line 446) | def test_create_app_calls_add_endpoint(self, mock_add_endpoint, mock_a...
method test_create_app_passes_extract_headers (line 456) | def test_create_app_passes_extract_headers(self, mock_add_endpoint, mo...
method test_create_app_default_path (line 467) | def test_create_app_default_path(self, mock_agent):
method test_create_app_functional_test (line 475) | def test_create_app_functional_test(self, mock_encoder_class, mock_age...
class TestEndpointIntegration (line 513) | class TestEndpointIntegration:
method mock_agent (line 517) | def mock_agent(self):
method sample_input (line 522) | def sample_input(self):
method test_full_endpoint_flow (line 537) | def test_full_endpoint_flow(self, mock_encoder_class, mock_agent, samp...
method test_endpoint_with_different_http_methods (line 587) | def test_endpoint_with_different_http_methods(self, mock_agent):
method test_endpoint_with_long_running_stream (line 610) | def test_endpoint_with_long_running_stream(self, mock_encoder_class, m...
class TestExtractHeaders (line 639) | class TestExtractHeaders:
method mock_agent (line 643) | def mock_agent(self):
method sample_input (line 648) | def sample_input(self):
method test_extract_headers_into_nested_state (line 661) | def test_extract_headers_into_nested_state(self, mock_encoder_class, m...
method test_extract_headers_strips_x_prefix (line 700) | def test_extract_headers_strips_x_prefix(self, mock_encoder_class, moc...
method test_extract_headers_converts_hyphens_to_underscores (line 739) | def test_extract_headers_converts_hyphens_to_underscores(self, mock_en...
method test_extract_headers_missing_headers_skipped (line 777) | def test_extract_headers_missing_headers_skipped(self, mock_encoder_cl...
method test_extract_headers_client_state_preserved (line 816) | def test_extract_headers_client_state_preserved(self, mock_encoder_cla...
method test_extract_headers_client_headers_take_precedence (line 868) | def test_extract_headers_client_headers_take_precedence(self, mock_enc...
method test_no_extract_headers_backward_compatible (line 917) | def test_no_extract_headers_backward_compatible(self, mock_encoder_cla...
method test_extract_headers_with_non_dict_state (line 953) | def test_extract_headers_with_non_dict_state(self, mock_encoder_class,...
method test_extract_headers_case_insensitive (line 1002) | def test_extract_headers_case_insensitive(self, mock_encoder_class, mo...
method test_create_adk_app_with_extract_headers (line 1041) | def test_create_adk_app_with_extract_headers(self, mock_encoder_class,...
method test_extract_headers_non_x_prefix_header (line 1077) | def test_extract_headers_non_x_prefix_header(self, mock_encoder_class,...
method test_fail_with_both_extraction_options (line 1115) | def test_fail_with_both_extraction_options(self):
method test_legacy_extract_headers_parameter (line 1124) | def test_legacy_extract_headers_parameter(self, sample_input):
FILE: integrations/adk-middleware/python/tests/test_endpoint_error_handling.py
class TestEndpointErrorHandling (line 13) | class TestEndpointErrorHandling:
method app (line 19) | def app(self, request):
method get_test_app (line 23) | def get_test_app(self, app):
method test_encoding_error_handling (line 35) | async def test_encoding_error_handling(self, app):
method test_agent_error_handling (line 109) | async def test_agent_error_handling(self, app):
method test_successful_event_handling (line 170) | async def test_successful_event_handling(self, app):
method test_nested_encoding_error_handling (line 246) | async def test_nested_encoding_error_handling(self, app):
method test_encoding_error_handling_alternative (line 320) | async def test_encoding_error_handling_alternative(self, app):
FILE: integrations/adk-middleware/python/tests/test_event_bookending.py
function test_text_event_bookending (line 11) | async def test_text_event_bookending():
function test_multiple_messages (line 87) | async def test_multiple_messages():
function main (line 144) | async def main():
FILE: integrations/adk-middleware/python/tests/test_event_translator_comprehensive.py
class TestEventTranslatorComprehensive (line 22) | class TestEventTranslatorComprehensive:
method translator (line 26) | def translator(self):
method mock_adk_event (line 31) | def mock_adk_event(self):
method mock_adk_event_with_content (line 43) | def mock_adk_event_with_content(self):
method test_translate_user_event_skipped (line 63) | async def test_translate_user_event_skipped(self, translator, mock_adk...
method test_translate_event_without_content (line 74) | async def test_translate_event_without_content(self, translator, mock_...
method test_translate_event_with_empty_parts (line 85) | async def test_translate_event_with_empty_parts(self, translator, mock...
method test_translate_function_calls_detection (line 98) | async def test_translate_function_calls_detection(self, translator, mo...
method test_translate_function_responses_handling (line 116) | async def test_translate_function_responses_handling(self, translator,...
method test_translate_function_response_with_call_tool_result_payload (line 133) | async def test_translate_function_response_with_call_tool_result_paylo...
method test_translate_state_delta_event (line 183) | async def test_translate_state_delta_event(self, translator, mock_adk_...
method test_translate_state_snapshot_event_passthrough (line 206) | async def test_translate_state_snapshot_event_passthrough(self, transl...
method test_create_state_snapshot_event_passthrough (line 238) | def test_create_state_snapshot_event_passthrough(self, translator):
method test_translate_custom_event (line 255) | async def test_translate_custom_event(self, translator, mock_adk_event):
method test_translate_exception_handling (line 270) | async def test_translate_exception_handling(self, translator, mock_adk...
method test_translate_text_content_basic (line 289) | async def test_translate_text_content_basic(self, translator, mock_adk...
method test_translate_text_content_multiple_parts (line 308) | async def test_translate_text_content_multiple_parts(self, translator,...
method test_translate_text_content_partial_streaming (line 327) | async def test_translate_text_content_partial_streaming(self, translat...
method test_translate_text_content_final_response_callable (line 346) | async def test_translate_text_content_final_response_callable(self, tr...
method test_translate_text_content_final_response_property (line 367) | async def test_translate_text_content_final_response_property(self, tr...
method test_translate_text_content_final_response_no_streaming (line 383) | async def test_translate_text_content_final_response_no_streaming(self...
method test_translate_text_content_final_response_from_agent_callback (line 405) | async def test_translate_text_content_final_response_from_agent_callba...
method test_translate_text_content_final_response_after_stream_duplicate_suppressed (line 424) | async def test_translate_text_content_final_response_after_stream_dupl...
method test_translate_text_content_final_response_closes_stream_without_consolidated_text (line 485) | async def test_translate_text_content_final_response_closes_stream_wit...
method test_translate_text_content_final_response_after_stream_new_content (line 533) | async def test_translate_text_content_final_response_after_stream_new_...
method test_consolidated_text_skipped_during_streaming (line 589) | async def test_consolidated_text_skipped_during_streaming(self, transl...
method test_consolidated_text_with_different_content_still_skipped (line 649) | async def test_consolidated_text_with_different_content_still_skipped(...
method test_translate_text_content_empty_text (line 694) | async def test_translate_text_content_empty_text(self, translator, moc...
method test_translate_text_content_none_text_parts (line 710) | async def test_translate_text_content_none_text_parts(self, translator...
method test_translate_text_content_mixed_text_parts (line 727) | async def test_translate_text_content_mixed_text_parts(self, translato...
method test_translate_function_calls_basic (line 747) | async def test_translate_function_calls_basic(self, translator, mock_a...
method test_translate_function_calls_no_id (line 773) | async def test_translate_function_calls_no_id(self, translator, mock_a...
method test_translate_function_calls_no_args (line 796) | async def test_translate_function_calls_no_args(self, translator, mock...
method test_translate_function_calls_string_args (line 815) | async def test_translate_function_calls_string_args(self, translator, ...
method test_translate_function_calls_multiple (line 832) | async def test_translate_function_calls_multiple(self, translator, moc...
method test_create_state_delta_event_basic (line 864) | def test_create_state_delta_event_basic(self, translator):
method test_create_state_delta_event_empty (line 879) | def test_create_state_delta_event_empty(self, translator):
method test_create_state_delta_event_nested_objects (line 886) | def test_create_state_delta_event_nested_objects(self, translator):
method test_create_state_delta_event_array_values (line 903) | def test_create_state_delta_event_array_values(self, translator):
method test_create_state_delta_event_mixed_types (line 920) | def test_create_state_delta_event_mixed_types(self, translator):
method test_create_state_delta_event_special_characters_in_keys (line 951) | def test_create_state_delta_event_special_characters_in_keys(self, tra...
method test_force_close_streaming_message_with_open_stream (line 974) | async def test_force_close_streaming_message_with_open_stream(self, tr...
method test_force_close_streaming_message_no_open_stream (line 997) | async def test_force_close_streaming_message_no_open_stream(self, tran...
method test_reset_translator_state (line 1008) | def test_reset_translator_state(self, translator):
method test_streaming_state_management (line 1023) | async def test_streaming_state_management(self, translator, mock_adk_e...
method test_complex_event_with_multiple_features (line 1047) | async def test_complex_event_with_multiple_features(self, translator, ...
method test_event_logging_coverage (line 1081) | async def test_event_logging_coverage(self, translator, mock_adk_event...
method test_attribute_access_patterns (line 1095) | async def test_attribute_access_patterns(self, translator, mock_adk_ev...
method test_tool_call_tracking_cleanup (line 1112) | async def test_tool_call_tracking_cleanup(self, translator, mock_adk_e...
method test_partial_streaming_continuation (line 1132) | async def test_partial_streaming_continuation(self, translator):
method mock_adk_event_empty_text (line 1202) | def mock_adk_event_empty_text(self):
method test_empty_text_event_does_not_crash (line 1221) | async def test_empty_text_event_does_not_crash(self, translator, mock_...
method test_whitespace_only_text_event_does_not_crash (line 1237) | async def test_whitespace_only_text_event_does_not_crash(self, transla...
method test_multiple_empty_parts_filtered (line 1267) | async def test_multiple_empty_parts_filtered(self, translator, mock_ad...
method test_mixed_empty_and_valid_parts_filtering (line 1287) | async def test_mixed_empty_and_valid_parts_filtering(self, translator,...
method test_empty_combined_text_early_return (line 1309) | async def test_empty_combined_text_early_return(self, translator, mock...
class TestThoughtHandling (line 1340) | class TestThoughtHandling:
method translator (line 1344) | def translator(self):
method mock_adk_event (line 1349) | def mock_adk_event(self):
method test_thought_parts_emit_thinking_events (line 1361) | async def test_thought_parts_emit_thinking_events(self, translator, mo...
method test_mixed_thought_and_text_parts (line 1388) | async def test_mixed_thought_and_text_parts(self, translator, mock_adk...
method test_non_thought_parts_emit_text_events (line 1426) | async def test_non_thought_parts_emit_text_events(self, translator, mo...
method test_thought_false_emits_text_events (line 1448) | async def test_thought_false_emits_text_events(self, translator, mock_...
method test_thinking_stream_closed_on_final_response (line 1468) | async def test_thinking_stream_closed_on_final_response(self, translat...
method test_reset_clears_thinking_state (line 1513) | def test_reset_clears_thinking_state(self, translator):
method test_fallback_when_thought_support_unavailable (line 1529) | async def test_fallback_when_thought_support_unavailable(self, transla...
method test_thought_support_check_caching (line 1560) | async def test_thought_support_check_caching(self):
method test_thought_none_treated_as_non_thought (line 1580) | async def test_thought_none_treated_as_non_thought(self, translator, m...
FILE: integrations/adk-middleware/python/tests/test_execution_state.py
class TestExecutionState (line 12) | class TestExecutionState:
method mock_task (line 16) | def mock_task(self):
method mock_queue (line 24) | def mock_queue(self):
method execution_state (line 29) | def execution_state(self, mock_task, mock_queue):
method test_initialization (line 37) | def test_initialization(self, execution_state, mock_task, mock_queue):
method test_is_stale_fresh_execution (line 46) | def test_is_stale_fresh_execution(self, execution_state):
method test_is_stale_old_execution (line 52) | def test_is_stale_old_execution(self, execution_state):
method test_cancel_with_pending_task (line 61) | async def test_cancel_with_pending_task(self, mock_queue):
method test_cancel_with_completed_task (line 82) | async def test_cancel_with_completed_task(self, execution_state, mock_...
method test_get_execution_time (line 93) | def test_get_execution_time(self, execution_state):
method test_get_status_complete (line 101) | def test_get_status_complete(self, execution_state):
method test_get_status_task_done (line 107) | def test_get_status_task_done(self, execution_state, mock_task):
method test_get_status_running (line 113) | def test_get_status_running(self, execution_state):
method test_string_representation (line 118) | def test_string_representation(self, execution_state):
method test_execution_time_progression (line 127) | def test_execution_time_progression(self, execution_state):
FILE: integrations/adk-middleware/python/tests/test_from_app_integration.py
function sample_app (line 22) | def sample_app():
function reset_session_manager (line 33) | def reset_session_manager():
function test_from_app_basic_conversation (line 40) | async def test_from_app_basic_conversation(sample_app):
function test_from_app_preserves_app_name (line 65) | async def test_from_app_preserves_app_name(sample_app):
function test_from_app_preserves_cleanup_options (line 71) | async def test_from_app_preserves_cleanup_options(sample_app):
function test_from_app_stores_app_reference (line 114) | async def test_from_app_stores_app_reference(sample_app):
function test_from_app_with_custom_timeout (line 121) | async def test_from_app_with_custom_timeout():
function test_from_app_type_validation (line 140) | async def test_from_app_type_validation():
function test_from_app_extracts_root_agent (line 147) | async def test_from_app_extracts_root_agent(sample_app):
function test_from_app_multi_turn_conversation (line 154) | async def test_from_app_multi_turn_conversation(sample_app):
function test_from_app_with_valid_mime_type (line 198) | async def test_from_app_with_valid_mime_type(sample_app):
function test_from_app_with_unsupported_mime_type (line 232) | async def test_from_app_with_unsupported_mime_type(sample_app):
function test_runner_supports_plugin_close_timeout (line 269) | async def test_runner_supports_plugin_close_timeout():
FILE: integrations/adk-middleware/python/tests/test_hitl_resumption_text_output.py
function collect_events (line 52) | async def collect_events(agent: ADKAgent, run_input: RunAgentInput) -> L...
function find_tool_call_id (line 60) | def find_tool_call_id(events: List[BaseEvent]) -> Optional[str]:
function find_tool_call_name (line 68) | def find_tool_call_name(events: List[BaseEvent]) -> Optional[str]:
function collect_text_content (line 76) | def collect_text_content(events: List[BaseEvent]) -> str:
function get_event_types (line 87) | def get_event_types(events: List[BaseEvent]) -> List[str]:
class TestHITLResumptionTextOutput (line 92) | class TestHITLResumptionTextOutput:
method reset_session_manager (line 101) | def reset_session_manager(self):
method check_api_key (line 108) | def check_api_key(self):
method hitl_agent (line 114) | def hitl_agent(self):
method test_hitl_resumption_produces_text_after_tool_result (line 143) | async def test_hitl_resumption_produces_text_after_tool_result(
method test_hitl_resumption_no_duplicate_function_response (line 307) | async def test_hitl_resumption_no_duplicate_function_response(
FILE: integrations/adk-middleware/python/tests/test_integration.py
function test_session_creation_logic (line 10) | async def test_session_creation_logic():
function test_session_service_calls (line 85) | async def test_session_service_calls():
function main (line 125) | async def main():
FILE: integrations/adk-middleware/python/tests/test_integration_mixed_partials.py
function adk_agent_instance (line 22) | def adk_agent_instance():
function test_mixed_partials_non_lro_then_lro (line 30) | async def test_mixed_partials_non_lro_then_lro(adk_agent_instance):
FILE: integrations/adk-middleware/python/tests/test_issue_437_skip_summarization_integration.py
function get_weather_with_skip_summarization (line 60) | def get_weather_with_skip_summarization(
function get_temperature (line 73) | def get_temperature(
class TestSkipSummarizationIntegration (line 84) | class TestSkipSummarizationIntegration:
method reset_session_manager (line 88) | def reset_session_manager(self):
method weather_agent (line 101) | def weather_agent(self):
method normal_tool_agent (line 122) | def normal_tool_agent(self):
method _create_input (line 140) | def _create_input(self, message: str) -> RunAgentInput:
method _count_events (line 158) | def _count_events(self, events: List[BaseEvent]) -> Dict[str, int]:
method test_skip_summarization_no_infinite_loop (line 163) | async def test_skip_summarization_no_infinite_loop(self, weather_agent):
method test_skip_summarization_tool_result_emitted (line 208) | async def test_skip_summarization_tool_result_emitted(self, weather_ag...
method test_normal_tool_vs_skip_summarization_comparison (line 237) | async def test_normal_tool_vs_skip_summarization_comparison(
method test_skip_summarization_event_order (line 271) | async def test_skip_summarization_event_order(self, weather_agent):
method test_skip_summarization_with_ck_prefixed_tool_ids (line 325) | async def test_skip_summarization_with_ck_prefixed_tool_ids(self, weat...
class TestSkipSummarizationEdgeCases (line 380) | class TestSkipSummarizationEdgeCases:
method reset_session_manager (line 384) | def reset_session_manager(self):
method multi_tool_agent (line 397) | def multi_tool_agent(self):
method test_timeout_protection (line 428) | async def test_timeout_protection(self):
class TestSkipSummarizationReplayBug (line 486) | class TestSkipSummarizationReplayBug:
method reset_session_manager (line 505) | def reset_session_manager(self):
method skip_sum_agent (line 518) | def skip_sum_agent(self):
method test_skip_summarization_replay_scenario (line 545) | async def test_skip_summarization_replay_scenario(self, skip_sum_agent):
method test_document_skip_summarization_not_persisted (line 689) | async def test_document_skip_summarization_not_persisted(self, skip_su...
FILE: integrations/adk-middleware/python/tests/test_lro_filtering.py
function test_translate_skips_lro_function_calls (line 16) | async def test_translate_skips_lro_function_calls():
function test_translate_lro_function_calls_only_emits_lro (line 62) | async def test_translate_lro_function_calls_only_emits_lro():
function test_translate_skips_function_calls_from_partial_events_without_streaming_args (line 103) | async def test_translate_skips_function_calls_from_partial_events_withou...
function test_translate_emits_function_calls_from_confirmed_events (line 147) | async def test_translate_emits_function_calls_from_confirmed_events():
function test_translate_handles_missing_partial_attribute (line 187) | async def test_translate_handles_missing_partial_attribute():
function test_confirmed_event_skips_lro_already_emitted_via_translate_lro (line 221) | async def test_confirmed_event_skips_lro_already_emitted_via_translate_l...
function test_confirmed_event_still_emits_non_lro_after_lro_emitted (line 287) | async def test_confirmed_event_still_emits_non_lro_after_lro_emitted():
function test_confirmed_event_with_different_lro_id_not_suppressed (line 346) | async def test_confirmed_event_with_different_lro_id_not_suppressed():
function test_client_emitted_ids_suppress_confirmed_event (line 398) | async def test_client_emitted_ids_suppress_confirmed_event():
function test_client_emitted_ids_suppress_lro_translate (line 444) | async def test_client_emitted_ids_suppress_lro_translate():
function test_client_emitted_ids_suppress_partial_event (line 473) | async def test_client_emitted_ids_suppress_partial_event():
function test_client_emitted_ids_do_not_suppress_other_tools (line 506) | async def test_client_emitted_ids_do_not_suppress_other_tools():
function test_shared_set_mutation_visible_to_translator (line 536) | async def test_shared_set_mutation_visible_to_translator():
function test_client_tool_names_suppress_lro_path (line 573) | async def test_client_tool_names_suppress_lro_path():
function test_client_tool_names_suppress_confirmed_event (line 608) | async def test_client_tool_names_suppress_confirmed_event():
function test_client_tool_names_suppress_partial_event (line 639) | async def test_client_tool_names_suppress_partial_event():
function test_client_tool_names_do_not_suppress_other_tools (line 668) | async def test_client_tool_names_do_not_suppress_other_tools():
function test_client_tool_names_mixed_client_and_backend_calls (line 695) | async def test_client_tool_names_mixed_client_and_backend_calls():
function test_translator_records_emitted_tool_call_ids (line 729) | async def test_translator_records_emitted_tool_call_ids():
function test_full_resumable_hitl_flow_no_duplicates (line 758) | async def test_full_resumable_hitl_flow_no_duplicates():
function test_has_lro_function_call_sets_is_long_running_tool_even_when_translator_skips (line 828) | async def test_has_lro_function_call_sets_is_long_running_tool_even_when...
function test_non_resumable_agent_tool_round_trip (line 883) | async def test_non_resumable_agent_tool_round_trip():
function test_resumable_agent_no_duplicate_emission (line 958) | async def test_resumable_agent_no_duplicate_emission():
FILE: integrations/adk-middleware/python/tests/test_lro_sse_id_remap.py
class TestExtractLroIdRemap (line 53) | class TestExtractLroIdRemap:
method reset_session_manager (line 57) | def reset_session_manager(self):
method adk_agent (line 63) | def adk_agent(self):
method translator (line 71) | def translator(self):
method _make_event (line 74) | def _make_event(self, fc_name: str, fc_id: str):
method test_remap_detected_when_ids_differ (line 85) | def test_remap_detected_when_ids_differ(self, adk_agent, translator):
method test_no_remap_when_ids_match (line 94) | def test_no_remap_when_ids_match(self, adk_agent, translator):
method test_no_remap_for_unknown_tool (line 103) | def test_no_remap_for_unknown_tool(self, adk_agent, translator):
method test_no_remap_for_empty_event (line 111) | def test_no_remap_for_empty_event(self, adk_agent, translator):
method test_multiple_tools_remapped (line 121) | def test_multiple_tools_remapped(self, adk_agent, translator):
class TestLroIdRemapSessionState (line 139) | class TestLroIdRemapSessionState:
method reset_session_manager (line 143) | def reset_session_manager(self):
method adk_agent (line 149) | def adk_agent(self):
method test_store_and_retrieve_remap (line 157) | async def test_store_and_retrieve_remap(self, adk_agent):
method test_store_merges_existing (line 169) | async def test_store_merges_existing(self, adk_agent):
method test_consume_removes_entry (line 181) | async def test_consume_removes_entry(self, adk_agent):
method test_consume_returns_original_when_no_remap (line 199) | async def test_consume_returns_original_when_no_remap(self, adk_agent):
class TestEventTranslatorLroTracking (line 209) | class TestEventTranslatorLroTracking:
method translator (line 213) | def translator(self):
method _make_lro_event (line 216) | def _make_lro_event(self, fc_name: str, fc_id: str):
method test_lro_emitted_ids_by_name_populated (line 231) | async def test_lro_emitted_ids_by_name_populated(self, translator):
method test_lro_emitted_ids_cleared_on_reset (line 248) | async def test_lro_emitted_ids_cleared_on_reset(self, translator):
class TestDrainPathCapturesRemap (line 255) | class TestDrainPathCapturesRemap:
method reset_session_manager (line 259) | def reset_session_manager(self):
method adk_agent (line 265) | def adk_agent(self):
method test_drain_captures_remap_from_final_event (line 273) | async def test_drain_captures_remap_from_final_event(self, adk_agent):
class TestFunctionResponseRemapping (line 342) | class TestFunctionResponseRemapping:
method reset_session_manager (line 346) | def reset_session_manager(self):
method sample_tool (line 352) | def sample_tool(self):
method test_tool_result_uses_remapped_id (line 363) | async def test_tool_result_uses_remapped_id(self, sample_tool):
class TestMultiRoundLroStatePoisoning (line 516) | class TestMultiRoundLroStatePoisoning:
method reset_session_manager (line 528) | def reset_session_manager(self):
method sample_tool (line 534) | def sample_tool(self):
method _create_lro_event (line 545) | def _create_lro_event(partial, fc_id, fc_name="client_tool", invocatio...
method _create_text_event (line 567) | def _create_text_event(text="Done", invocation_id="inv"):
method test_second_hitl_tool_call_not_poisoned_by_stale_state (line 585) | async def test_second_hitl_tool_call_not_poisoned_by_stale_state(self,...
method test_internal_state_keys_stripped_from_input (line 754) | async def test_internal_state_keys_stripped_from_input(self, sample_to...
function _has_google_auth (line 816) | def _has_google_auth():
class TestLROSSEIdRemapIntegration (line 826) | class TestLROSSEIdRemapIntegration:
method reset_session_manager (line 841) | def reset_session_manager(self):
method lro_tool (line 847) | def lro_tool(self):
method test_hitl_round_trip_with_sse_streaming (line 864) | async def test_hitl_round_trip_with_sse_streaming(self, lro_tool):
method test_hitl_without_streaming_still_works (line 990) | async def test_hitl_without_streaming_still_works(self, lro_tool):
FILE: integrations/adk-middleware/python/tests/test_lro_sse_persistence.py
class TestLROSSEPersistenceUnit (line 44) | class TestLROSSEPersistenceUnit:
method reset_session_manager (line 48) | def reset_session_manager(self):
method adk_agent (line 55) | def adk_agent(self):
method test_lro_with_partial_true_drains_until_non_partial (line 68) | async def test_lro_with_partial_true_drains_until_non_partial(self, ad...
method test_lro_with_partial_false_returns_immediately (line 152) | async def test_lro_with_partial_false_returns_immediately(self, adk_ag...
method test_text_content_emitted_during_drain (line 223) | async def test_text_content_emitted_during_drain(self, adk_agent):
function _has_google_auth (line 301) | def _has_google_auth():
class TestLROSSEPersistenceIntegration (line 314) | class TestLROSSEPersistenceIntegration:
method reset_session_manager (line 328) | def reset_session_manager(self):
method lro_tool (line 335) | def lro_tool(self):
method test_agent_events_persisted_with_sse_streaming (line 353) | async def test_agent_events_persisted_with_sse_streaming(self, lro_tool):
method test_agent_events_persisted_without_streaming_baseline (line 437) | async def test_agent_events_persisted_without_streaming_baseline(self,...
FILE: integrations/adk-middleware/python/tests/test_lro_tool_response_persistence.py
function collect_events (line 50) | async def collect_events(agent: ADKAgent, run_input: RunAgentInput) -> L...
function get_event_types (line 58) | def get_event_types(events: List[BaseEvent]) -> List[str]:
function find_tool_call_id (line 63) | def find_tool_call_id(events: List[BaseEvent]) -> Optional[str]:
function count_function_responses (line 71) | def count_function_responses(session, tool_call_id: str) -> tuple[int, L...
class TestLROToolResponseIntegration (line 91) | class TestLROToolResponseIntegration:
method reset_session_manager (line 98) | def reset_session_manager(self):
method check_api_key (line 105) | def check_api_key(self):
method hitl_agent (line 111) | def hitl_agent(self):
method simple_agent (line 137) | def simple_agent(self):
method test_tool_result_persists_single_function_response (line 164) | async def test_tool_result_persists_single_function_response(
method test_function_response_has_correct_invocation_id (line 284) | async def test_function_response_has_correct_invocation_id(
method test_tool_result_with_trailing_user_message (line 377) | async def test_tool_result_with_trailing_user_message(
class TestHITLResumptionIntegration (line 467) | class TestHITLResumptionIntegration:
method reset_session_manager (line 471) | def reset_session_manager(self):
method check_api_key (line 478) | def check_api_key(self):
method hitl_agent (line 484) | def hitl_agent(self):
method test_hitl_resumption_preserves_invocation_context (line 507) | async def test_hitl_resumption_preserves_invocation_context(
FILE: integrations/adk-middleware/python/tests/test_message_history.py
function create_mock_adk_event (line 35) | def create_mock_adk_event(
function create_mock_adk_event_with_parts (line 70) | def create_mock_adk_event_with_parts(
function create_mock_function_call (line 107) | def create_mock_function_call(name: str, args: dict = None, fc_id: str =...
function create_mock_function_response (line 116) | def create_mock_function_response(response: Any, fr_id: str = None):
class TestAdkEventsToMessages (line 128) | class TestAdkEventsToMessages:
method test_empty_events_list (line 131) | def test_empty_events_list(self):
method test_user_message_conversion (line 136) | def test_user_message_conversion(self):
method test_assistant_message_conversion (line 152) | def test_assistant_message_conversion(self):
method test_assistant_message_with_tool_calls (line 168) | def test_assistant_message_with_tool_calls(self):
method test_tool_message_conversion (line 192) | def test_tool_message_conversion(self):
method test_partial_events_skipped (line 214) | def test_partial_events_skipped(self):
method test_events_without_content_skipped (line 232) | def test_events_without_content_skipped(self):
method test_conversation_order_preserved (line 248) | def test_conversation_order_preserved(self):
method test_none_author_treated_as_assistant (line 265) | def test_none_author_treated_as_assistant(self):
method test_custom_agent_name_treated_as_assistant (line 279) | def test_custom_agent_name_treated_as_assistant(self):
method test_model_author_treated_as_assistant (line 301) | def test_model_author_treated_as_assistant(self):
method test_empty_text_with_function_calls (line 315) | def test_empty_text_with_function_calls(self):
class TestThoughtPartSeparation (line 333) | class TestThoughtPartSeparation:
method test_thought_parts_emitted_as_reasoning_message (line 342) | def test_thought_parts_emitted_as_reasoning_message(self, mock_thought):
method test_multiple_thought_parts_concatenated (line 366) | def test_multiple_thought_parts_concatenated(self, mock_thought):
method test_thought_only_event_emits_reasoning_only (line 387) | def test_thought_only_event_emits_reasoning_only(self, mock_thought):
method test_user_message_thought_parts_excluded (line 404) | def test_user_message_thought_parts_excluded(self, mock_thought):
method test_user_message_with_only_thought_parts_skipped (line 422) | def test_user_message_with_only_thought_parts_skipped(self, mock_thoug...
method test_thought_parts_with_tool_calls (line 437) | def test_thought_parts_with_tool_calls(self, mock_thought):
method test_thought_only_with_tool_calls (line 461) | def test_thought_only_with_tool_calls(self, mock_thought):
method test_no_thought_support_treats_all_as_text (line 482) | def test_no_thought_support_treats_all_as_text(self, mock_thought):
method test_conversation_with_reasoning_preserves_order (line 501) | def test_conversation_with_reasoning_preserves_order(self, mock_thought):
method test_reasoning_message_serializes_correctly (line 541) | def test_reasoning_message_serializes_correctly(self, mock_thought):
class TestTranslateFunctionCallsToToolCalls (line 561) | class TestTranslateFunctionCallsToToolCalls:
method test_single_function_call (line 564) | def test_single_function_call(self):
method test_multiple_function_calls (line 580) | def test_multiple_function_calls(self):
method test_function_call_without_id (line 593) | def test_function_call_without_id(self):
method test_empty_function_calls (line 607) | def test_empty_function_calls(self):
class TestEmitMessagesSnapshot (line 617) | class TestEmitMessagesSnapshot:
method mock_adk_agent (line 621) | def mock_adk_agent(self):
method test_default_emit_messages_snapshot_is_false (line 627) | def test_default_emit_messages_snapshot_is_false(self, mock_adk_agent):
method test_emit_messages_snapshot_can_be_enabled (line 637) | def test_emit_messages_snapshot_can_be_enabled(self, mock_adk_agent):
method test_emit_messages_snapshot_stored_on_agent (line 648) | def test_emit_messages_snapshot_stored_on_agent(self, mock_adk_agent):
class TestAgentsStateEndpoint (line 673) | class TestAgentsStateEndpoint:
method mock_agent (line 677) | def mock_agent(self):
method app (line 696) | def app(self, request):
method get_test_app (line 700) | def get_test_app(self, app):
method test_agents_state_endpoint_exists (line 712) | def test_agents_state_endpoint_exists(self, app, mock_agent):
method test_agents_state_returns_thread_info (line 718) | def test_agents_state_returns_thread_info(self, app, mock_agent):
method test_agents_state_handles_missing_session (line 761) | def test_agents_state_handles_missing_session(self, app, mock_agent):
method test_agents_state_cache_miss_loads_events (line 781) | def test_agents_state_cache_miss_loads_events(self, app, mock_agent):
method test_agents_state_handles_empty_events (line 844) | def test_agents_state_handles_empty_events(self, app, mock_agent):
method test_agents_state_handles_error (line 876) | def test_agents_state_handles_error(self, app, mock_agent):
method test_agents_state_optional_fields (line 895) | def test_agents_state_optional_fields(self, app, mock_agent):
class TestMessageHistoryIntegration (line 933) | class TestMessageHistoryIntegration:
method real_agent (line 937) | def real_agent(self):
method app (line 952) | def app(self, request):
method get_test_app (line 956) | def get_test_app(self, app):
method test_agents_state_with_real_session_manager (line 969) | async def test_agents_state_with_real_session_manager(self, app, real_...
method test_agents_state_returns_json_stringified_response (line 996) | async def test_agents_state_returns_json_stringified_response(self, ap...
function find_free_port (line 1028) | def find_free_port():
class UvicornServer (line 1036) | class UvicornServer:
method __init__ (line 1039) | def __init__(self, app: FastAPI, host: str = "127.0.0.1", port: int = ...
method __enter__ (line 1046) | def __enter__(self):
method __exit__ (line 1072) | def __exit__(self, exc_type, exc_val, exc_tb):
method base_url (line 1079) | def base_url(self):
class TestLiveServerIntegration (line 1083) | class TestLiveServerIntegration:
method app (line 1093) | def app(self, request):
method live_agent (line 1098) | def live_agent(self):
method live_server (line 1111) | def live_server(self, app, live_agent):
method test_live_server_agents_state_endpoint (line 1126) | def test_live_server_agents_state_endpoint(self, live_server, live_age...
method test_live_server_agents_state_json_format (line 1152) | def test_live_server_agents_state_json_format(self, live_server):
method test_live_server_agents_state_with_optional_fields (line 1174) | def test_live_server_agents_state_with_optional_fields(self, live_serv...
method test_live_server_session_persistence (line 1190) | def test_live_server_session_persistence(self, live_server, live_agent):
method test_live_server_multiple_threads (line 1225) | def test_live_server_multiple_threads(self, live_server, live_agent):
method test_live_server_concurrent_requests (line 1257) | async def test_live_server_concurrent_requests(self, live_server):
method test_live_server_invalid_request (line 1279) | def test_live_server_invalid_request(self, live_server):
method test_live_server_main_endpoint_exists (line 1294) | def test_live_server_main_endpoint_exists(self, live_server):
FILE: integrations/adk-middleware/python/tests/test_multi_turn_conversation.py
function create_mock_adk_event (line 41) | def create_mock_adk_event(text: str, is_final: bool = False, partial: bo...
function collect_events (line 57) | async def collect_events(agent: ADKAgent, run_input: RunAgentInput) -> L...
function get_event_types (line 65) | def get_event_types(events: List[BaseEvent]) -> List[str]:
class TestMultiTurnConversation (line 70) | class TestMultiTurnConversation:
method reset_session_manager (line 74) | def reset_session_manager(self):
method llm_agent (line 81) | def llm_agent(self):
method adk_agent (line 90) | def adk_agent(self, llm_agent):
method test_first_message_succeeds (line 100) | async def test_first_message_succeeds(self, adk_agent):
method test_second_message_succeeds (line 132) | async def test_second_message_succeeds(self, adk_agent):
method test_third_and_fourth_messages_succeed (line 204) | async def test_third_and_fourth_messages_succeed(self, adk_agent):
class TestMultiTurnConversationMocked (line 258) | class TestMultiTurnConversationMocked:
method reset_session_manager (line 262) | def reset_session_manager(self):
method mock_agent (line 269) | def mock_agent(self):
method adk_agent (line 277) | def adk_agent(self, mock_agent):
method test_unseen_messages_filtering (line 287) | async def test_unseen_messages_filtering(self, adk_agent):
method test_convert_latest_message_with_empty_unseen (line 338) | async def test_convert_latest_message_with_empty_unseen(self, adk_agent):
method test_convert_latest_message_with_valid_unseen (line 374) | async def test_convert_latest_message_with_valid_unseen(self, adk_agent):
method test_message_batch_none_does_not_skip_user_message (line 399) | async def test_message_batch_none_does_not_skip_user_message(self, adk...
method test_processed_messages_accumulate_correctly (line 435) | async def test_processed_messages_accumulate_correctly(self, adk_agent):
method test_different_threads_have_separate_processed_ids (line 461) | async def test_different_threads_have_separate_processed_ids(self, adk...
class TestMultiTurnFallbackBehavior (line 487) | class TestMultiTurnFallbackBehavior:
method reset_session_manager (line 491) | def reset_session_manager(self):
method mock_agent (line 498) | def mock_agent(self):
method adk_agent (line 506) | def adk_agent(self, mock_agent):
method test_fallback_extracts_latest_user_message_when_all_processed (line 516) | async def test_fallback_extracts_latest_user_message_when_all_processed(
FILE: integrations/adk-middleware/python/tests/test_non_streaming_text_with_lro_tool.py
function adk_agent_instance (line 27) | def adk_agent_instance():
function test_non_streaming_text_with_lro_tool_call (line 35) | async def test_non_streaming_text_with_lro_tool_call(adk_agent_instance):
function test_non_streaming_lro_tool_without_text (line 125) | async def test_non_streaming_lro_tool_without_text(adk_agent_instance):
function test_non_streaming_text_only_no_lro (line 184) | async def test_non_streaming_text_only_no_lro(adk_agent_instance):
FILE: integrations/adk-middleware/python/tests/test_predictive_state.py
class TestPredictStateMapping (line 12) | class TestPredictStateMapping:
method test_predict_state_mapping_creation (line 15) | def test_predict_state_mapping_creation(self):
method test_predict_state_mapping_to_payload (line 26) | def test_predict_state_mapping_to_payload(self):
class TestNormalizePredictState (line 41) | class TestNormalizePredictState:
method test_normalize_none (line 44) | def test_normalize_none(self):
method test_normalize_single_mapping (line 49) | def test_normalize_single_mapping(self):
method test_normalize_list_of_mappings (line 60) | def test_normalize_list_of_mappings(self):
class TestEventTranslatorPredictState (line 71) | class TestEventTranslatorPredictState:
method translator_with_predict_state (line 75) | def translator_with_predict_state(self):
method translator_without_predict_state (line 88) | def translator_without_predict_state(self):
method test_predict_state_event_emitted_for_matching_tool (line 93) | async def test_predict_state_event_emitted_for_matching_tool(
method test_no_predict_state_event_for_non_matching_tool (line 132) | async def test_no_predict_state_event_for_non_matching_tool(
method test_no_predict_state_event_without_config (line 157) | async def test_no_predict_state_event_without_config(
method test_predict_state_event_only_emitted_once (line 182) | async def test_predict_state_event_only_emitted_once(
method test_predict_state_tracking_reset (line 228) | async def test_predict_state_tracking_reset(self, translator_with_pred...
method test_multiple_predict_state_mappings (line 271) | def test_multiple_predict_state_mappings(self):
class TestDeferredConfirmChangesEvents (line 305) | class TestDeferredConfirmChangesEvents:
method translator_with_emit_confirm (line 315) | def translator_with_emit_confirm(self):
method translator_without_emit_confirm (line 329) | def translator_without_emit_confirm(self):
method test_has_deferred_confirm_events_initially_false (line 342) | def test_has_deferred_confirm_events_initially_false(self, translator_...
method test_get_and_clear_deferred_confirm_events_initially_empty (line 346) | def test_get_and_clear_deferred_confirm_events_initially_empty(self, t...
method test_confirm_changes_events_are_deferred_not_yielded (line 352) | async def test_confirm_changes_events_are_deferred_not_yielded(
method test_deferred_events_contain_confirm_changes_trio (line 380) | async def test_deferred_events_contain_confirm_changes_trio(
method test_get_and_clear_actually_clears_events (line 416) | async def test_get_and_clear_actually_clears_events(
method test_no_confirm_changes_when_emit_confirm_tool_false (line 441) | async def test_no_confirm_changes_when_emit_confirm_tool_false(
method test_confirm_changes_only_emitted_once_per_tool (line 459) | async def test_confirm_changes_only_emitted_once_per_tool(
method test_reset_clears_deferred_confirm_events (line 492) | async def test_reset_clears_deferred_confirm_events(
method test_reset_allows_confirm_changes_to_be_emitted_again (line 516) | async def test_reset_allows_confirm_changes_to_be_emitted_again(
method test_emit_confirm_tool_default_is_true (line 548) | def test_emit_confirm_tool_default_is_true(self):
method test_emit_confirm_tool_can_be_set_to_false (line 557) | def test_emit_confirm_tool_can_be_set_to_false(self):
method test_multiple_tools_with_different_emit_confirm_settings (line 568) | async def test_multiple_tools_with_different_emit_confirm_settings(self):
class TestPredictiveStateToolCallResultSuppression (line 614) | class TestPredictiveStateToolCallResultSuppression:
method translator_with_predict_state (line 623) | def translator_with_predict_state(self):
method translator_without_predict_state (line 636) | def translator_without_predict_state(self):
method test_predictive_state_tool_call_ids_tracked (line 641) | async def test_predictive_state_tool_call_ids_tracked(
method test_non_predictive_state_tool_call_ids_not_tracked (line 660) | async def test_non_predictive_state_tool_call_ids_not_tracked(
method test_tool_call_result_suppressed_for_predictive_state_tools (line 679) | async def test_tool_call_result_suppressed_for_predictive_state_tools(
method test_tool_call_result_not_suppressed_for_regular_tools (line 712) | async def test_tool_call_result_not_suppressed_for_regular_tools(
method test_reset_clears_predictive_state_tool_call_ids (line 747) | async def test_reset_clears_predictive_state_tool_call_ids(
method test_reset_allows_tool_call_result_after_reset (line 771) | async def test_reset_allows_tool_call_result_after_reset(
method test_no_config_means_no_suppression (line 806) | async def test_no_config_means_no_suppression(
FILE: integrations/adk-middleware/python/tests/test_resumability_config.py
class TestIsAdkResumable (line 25) | class TestIsAdkResumable:
method reset_session_manager (line 29) | def reset_session_manager(self):
method simple_agent (line 36) | def simple_agent(self):
method test_is_adk_resumable_returns_false_without_app (line 44) | def test_is_adk_resumable_returns_false_without_app(self, simple_agent):
method test_is_adk_resumable_returns_false_without_resumability_config (line 55) | def test_is_adk_resumable_returns_false_without_resumability_config(se...
method test_is_adk_resumable_returns_false_when_not_resumable (line 62) | def test_is_adk_resumable_returns_false_when_not_resumable(self, simpl...
method test_is_adk_resumable_returns_true_when_resumable (line 73) | def test_is_adk_resumable_returns_true_when_resumable(self, simple_age...
method test_is_adk_resumable_handles_missing_attribute (line 84) | def test_is_adk_resumable_handles_missing_attribute(self, simple_agent):
class TestLROHandlingWithResumability (line 97) | class TestLROHandlingWithResumability:
method reset_session_manager (line 101) | def reset_session_manager(self):
method hitl_tool (line 108) | def hitl_tool(self):
method agent_with_agui_toolset (line 129) | def agent_with_agui_toolset(self):
method test_lro_early_return_without_resumability (line 139) | async def test_lro_early_return_without_resumability(self, agent_with_...
method test_lro_no_early_return_with_resumability (line 201) | async def test_lro_no_early_return_with_resumability(self, agent_with_...
class TestLROIntegration (line 220) | class TestLROIntegration:
method reset_session_manager (line 232) | def reset_session_manager(self):
method hitl_tool (line 239) | def hitl_tool(self):
method test_hitl_tool_call_emits_events_without_resumability (line 266) | async def test_hitl_tool_call_emits_events_without_resumability(self, ...
method test_hitl_tool_call_emits_events_with_resumability (line 318) | async def test_hitl_tool_call_emits_events_with_resumability(self, hit...
method test_hitl_tool_result_submission_with_resumability (line 360) | async def test_hitl_tool_result_submission_with_resumability(self, hit...
class TestNestedAgentsWithResumability (line 454) | class TestNestedAgentsWithResumability:
method reset_session_manager (line 467) | def reset_session_manager(self):
method nested_agent_hierarchy (line 474) | def nested_agent_hierarchy(self):
method hitl_tools (line 498) | def hitl_tools(self):
method test_nested_agents_with_resumability (line 541) | async def test_nested_agents_with_resumability(self, nested_agent_hier...
FILE: integrations/adk-middleware/python/tests/test_sequential_agent_hitl_resumption.py
function _make_mock_event (line 35) | def _make_mock_event(
class TestSequentialAgentHitlResumption (line 85) | class TestSequentialAgentHitlResumption:
method reset_session_manager (line 96) | def reset_session_manager(self):
method sequential_agent (line 103) | def sequential_agent(self):
method resumable_sequential_adk_agent (line 121) | def resumable_sequential_adk_agent(self, sequential_agent):
method hitl_tool (line 131) | def hitl_tool(self):
method test_sequential_agent_hitl_passes_invocation_id_to_run_async (line 151) | async def test_sequential_agent_hitl_passes_invocation_id_to_run_async(
method test_sequential_agent_stores_invocation_id_on_lro_pause (line 235) | async def test_sequential_agent_stores_invocation_id_on_lro_pause(
method test_invocation_id_not_cleared_when_lro_tool_active (line 306) | async def test_invocation_id_not_cleared_when_lro_tool_active(
method test_invocation_id_cleared_after_completed_run (line 384) | async def test_invocation_id_cleared_after_completed_run(
FILE: integrations/adk-middleware/python/tests/test_session_cleanup.py
function test_session_cleanup (line 11) | async def test_session_cleanup():
function main (line 78) | async def main():
FILE: integrations/adk-middleware/python/tests/test_session_creation.py
function test_session_creation (line 11) | async def test_session_creation():
function main (line 74) | async def main():
FILE: integrations/adk-middleware/python/tests/test_session_deletion.py
class TestSessionDeletion (line 11) | class TestSessionDeletion:
method save_session_to_memory_on_cleanup (line 16) | def save_session_to_memory_on_cleanup(self, request):
method mock_memory_service (line 22) | def mock_memory_service(self, request):
method test_session_deletion (line 31) | async def test_session_deletion(self, mock_memory_service, save_sessio...
method test_session_deletion_error_handling (line 110) | async def test_session_deletion_error_handling(self, mock_memory_servi...
method test_user_session_limits (line 173) | async def test_user_session_limits(self, mock_memory_service, save_ses...
FILE: integrations/adk-middleware/python/tests/test_session_memory.py
class TestSessionMemory (line 13) | class TestSessionMemory:
method delete_session_on_cleanup (line 19) | def delete_session_on_cleanup(self, request):
method reset_session_manager (line 23) | def reset_session_manager(self):
method mock_session_service (line 30) | def mock_session_service(self):
method mock_memory_service (line 40) | def mock_memory_service(self):
method mock_session (line 47) | def mock_session(self):
method test_memory_service_disabled_by_default (line 65) | async def test_memory_service_disabled_by_default(self, mock_session_s...
method test_memory_service_enabled_with_service (line 90) | async def test_memory_service_enabled_with_service(self, mock_session_...
method test_memory_service_error_handling (line 120) | async def test_memory_service_error_handling(self, mock_session_servic...
method test_memory_service_with_missing_session (line 145) | async def test_memory_service_with_missing_session(self, mock_session_...
method test_memory_service_during_cleanup (line 164) | async def test_memory_service_during_cleanup(self, mock_session_servic...
method test_memory_service_during_user_limit_enforcement (line 198) | async def test_memory_service_during_user_limit_enforcement(self, mock...
method test_memory_service_configuration (line 248) | async def test_memory_service_configuration(self, mock_session_service...
class TestSessionStateManagement (line 271) | class TestSessionStateManagement:
method reset_session_manager (line 275) | def reset_session_manager(self):
method mock_session_service (line 282) | def mock_session_service(self):
method mock_session (line 292) | def mock_session(self):
method manager (line 314) | def manager(self, mock_session_service):
method test_update_session_state_success (line 325) | async def test_update_session_state_success(self, manager, mock_sessio...
method test_update_session_state_session_not_found (line 351) | async def test_update_session_state_session_not_found(self, manager, m...
method test_update_session_state_empty_updates (line 366) | async def test_update_session_state_empty_updates(self, manager, mock_...
method test_update_session_state_exception_handling (line 381) | async def test_update_session_state_exception_handling(self, manager, ...
method test_get_session_state_success (line 397) | async def test_get_session_state_success(self, manager, mock_session_s...
method test_get_session_state_session_not_found (line 416) | async def test_get_session_state_session_not_found(self, manager, mock...
method test_get_session_state_exception_handling (line 429) | async def test_get_session_state_exception_handling(self, manager, moc...
method test_get_state_value_success (line 444) | async def test_get_state_value_success(self, manager, mock_session_ser...
method test_get_state_value_with_default (line 458) | async def test_get_state_value_with_default(self, manager, mock_sessio...
method test_get_state_value_session_not_found (line 473) | async def test_get_state_value_session_not_found(self, manager, mock_s...
method test_set_state_value_success (line 490) | async def test_set_state_value_success(self, manager, mock_session_ser...
method test_remove_state_keys_single_key (line 511) | async def test_remove_state_keys_single_key(self, manager, mock_sessio...
method test_remove_state_keys_multiple_keys (line 537) | async def test_remove_state_keys_multiple_keys(self, manager, mock_ses...
method test_remove_state_keys_nonexistent_keys (line 563) | async def test_remove_state_keys_nonexistent_keys(self, manager, mock_...
method test_clear_session_state_all_keys (line 586) | async def test_clear_session_state_all_keys(self, manager, mock_sessio...
method test_clear_session_state_preserve_prefixes (line 611) | async def test_clear_session_state_preserve_prefixes(self, manager, mo...
method test_initialize_session_state_new_keys_only (line 639) | async def test_initialize_session_state_new_keys_only(self, manager, m...
method test_initialize_session_state_overwrite_existing (line 668) | async def test_initialize_session_state_overwrite_existing(self, manag...
method test_bulk_update_user_state_success (line 696) | async def test_bulk_update_user_state_success(self, manager, mock_sess...
method test_bulk_update_user_state_with_app_filter (line 717) | async def test_bulk_update_user_state_with_app_filter(self, manager, m...
method test_bulk_update_user_state_no_sessions (line 745) | async def test_bulk_update_user_state_no_sessions(self, manager, mock_...
method test_bulk_update_user_state_mixed_results (line 755) | async def test_bulk_update_user_state_mixed_results(self, manager, moc...
FILE: integrations/adk-middleware/python/tests/test_skip_summarization.py
class TestSkipSummarizationScenarios (line 27) | class TestSkipSummarizationScenarios:
method translator (line 31) | def translator(self):
method _create_function_response (line 35) | def _create_function_response(self, tool_call_id: str, response: dict):
method _create_adk_event (line 39) | def _create_adk_event(
method test_skip_summarization_emits_tool_result_no_text (line 95) | async def test_skip_summarization_emits_tool_result_no_text(self, tran...
method test_skip_summarization_closes_active_stream_emits_tool_result (line 135) | async def test_skip_summarization_closes_active_stream_emits_tool_resu...
method test_event_with_both_text_and_function_responses (line 207) | async def test_event_with_both_text_and_function_responses(self, trans...
method test_multiple_function_responses_all_emitted (line 245) | async def test_multiple_function_responses_all_emitted(self, translator):
method test_skip_summarization_empty_function_responses_no_events (line 276) | async def test_skip_summarization_empty_function_responses_no_events(s...
method test_skip_summarization_does_not_emit_empty_text_content (line 297) | async def test_skip_summarization_does_not_emit_empty_text_content(sel...
method test_empty_final_response_no_function_responses_no_events (line 320) | async def test_empty_final_response_no_function_responses_no_events(se...
method test_whitespace_only_text_not_filtered (line 340) | async def test_whitespace_only_text_not_filtered(self, translator):
method test_mixed_empty_and_valid_text_parts (line 362) | async def test_mixed_empty_and_valid_text_parts(self, translator):
method test_function_response_parts_in_content_no_text_events (line 385) | async def test_function_response_parts_in_content_no_text_events(self,...
method test_non_final_response_with_function_responses (line 432) | async def test_non_final_response_with_function_responses(self, transl...
method test_lro_tool_responses_not_emitted (line 456) | async def test_lro_tool_responses_not_emitted(self, translator):
method test_early_return_at_line_380_still_emits_tool_result (line 482) | async def test_early_return_at_line_380_still_emits_tool_result(self, ...
FILE: integrations/adk-middleware/python/tests/test_stale_session_invocation_id.py
class TestInvocationIdNotPassedForStandaloneLlmAgent (line 28) | class TestInvocationIdNotPassedForStandaloneLlmAgent:
method reset_session_manager (line 32) | def reset_session_manager(self):
method simple_agent (line 39) | def simple_agent(self):
method resumable_adk_agent (line 47) | def resumable_adk_agent(self, simple_agent):
method non_resumable_adk_agent (line 57) | def non_resumable_adk_agent(self, simple_agent):
method _make_mock_event (line 62) | def _make_mock_event(
method test_no_invocation_id_in_run_kwargs_for_normal_run (line 112) | async def test_no_invocation_id_in_run_kwargs_for_normal_run(
method test_no_invocation_id_in_run_kwargs_for_lro_run (line 156) | async def test_no_invocation_id_in_run_kwargs_for_lro_run(
method test_no_invocation_id_in_run_kwargs_with_stored_id_and_tool_results (line 212) | async def test_no_invocation_id_in_run_kwargs_with_stored_id_and_tool_...
method test_stored_invocation_id_cleared_after_completed_run (line 274) | async def test_stored_invocation_id_cleared_after_completed_run(
method test_no_invocation_id_operations_without_resumability (line 334) | async def test_no_invocation_id_operations_without_resumability(
method test_no_mid_run_update_session_state_for_invocation_id (line 384) | async def test_no_mid_run_update_session_state_for_invocation_id(
class TestInvocationIdNotPassedForLlmAgentWithTransferTargets (line 456) | class TestInvocationIdNotPassedForLlmAgentWithTransferTargets:
method reset_session_manager (line 466) | def reset_session_manager(self):
method llm_agent_with_transfer_targets (line 473) | def llm_agent_with_transfer_targets(self):
method resumable_transfer_adk_agent (line 492) | def resumable_transfer_adk_agent(self, llm_agent_with_transfer_targets):
method _make_mock_event (line 501) | def _make_mock_event(
method test_no_invocation_id_for_llm_agent_with_transfer_targets (line 532) | async def test_no_invocation_id_for_llm_agent_with_transfer_targets(
FILE: integrations/adk-middleware/python/tests/test_streaming.py
class MockADKEvent (line 16) | class MockADKEvent:
method __init__ (line 18) | def __init__(self, text_content, finish_reason=None):
function test_streaming_behavior (line 36) | async def test_streaming_behavior():
function test_partial_with_finish_reason (line 103) | async def test_partial_with_finish_reason():
function test_non_streaming (line 169) | async def test_non_streaming():
function run_tests (line 202) | async def run_tests():
FILE: integrations/adk-middleware/python/tests/test_streaming_fc_args.py
function _event_types (line 16) | def _event_types(events):
function _make_adk_event (line 21) | def _make_adk_event(
function _make_func_call (line 43) | def _make_func_call(name=None, args=None, partial_args=None, will_contin...
function _make_partial_arg (line 54) | def _make_partial_arg(json_path, string_value):
function _collect_events (line 62) | async def _collect_events(translator, adk_event, thread_id="thread", run...
function test_streaming_fc_first_chunk_emits_start (line 76) | async def test_streaming_fc_first_chunk_emits_start():
function test_streaming_fc_disabled_by_default (line 93) | async def test_streaming_fc_disabled_by_default():
function test_streaming_fc_continuation_emits_args (line 112) | async def test_streaming_fc_continuation_emits_args():
function test_streaming_fc_multiple_continuations (line 136) | async def test_streaming_fc_multiple_continuations():
function test_streaming_fc_end_emits_end (line 174) | async def test_streaming_fc_end_emits_end():
function test_streaming_fc_full_sequence (line 209) | async def test_streaming_fc_full_sequence():
function test_streaming_fc_json_deltas_concatenate (line 237) | async def test_streaming_fc_json_deltas_concatenate():
function test_streaming_fc_suppresses_final_aggregated (line 273) | async def test_streaming_fc_suppresses_final_aggregated():
function test_streaming_fc_confirmed_id_remapped (line 298) | async def test_streaming_fc_confirmed_id_remapped():
function test_streaming_fc_uses_stable_id (line 327) | async def test_streaming_fc_uses_stable_id():
function test_streaming_fc_with_predict_state (line 361) | async def test_streaming_fc_with_predict_state():
function test_streaming_fc_resets_on_reset (line 396) | async def test_streaming_fc_resets_on_reset():
function test_adk_version_gate (line 422) | def test_adk_version_gate():
function test_streaming_fc_stray_chunk_ignored (line 433) | async def test_streaming_fc_stray_chunk_ignored():
function test_streaming_fc_special_chars_escaped (line 450) | async def test_streaming_fc_special_chars_escaped():
function test_streaming_fc_lro_skipped (line 476) | async def test_streaming_fc_lro_skipped():
function test_streaming_fc_deferred_end_for_stream_tool_call (line 490) | async def test_streaming_fc_deferred_end_for_stream_tool_call():
FILE: integrations/adk-middleware/python/tests/test_text_events.py
function test_message_events (line 16) | async def test_message_events():
function test_message_events_from_before_agent_callback (line 91) | async def test_message_events_from_before_agent_callback():
function validate_message_events (line 192) | def validate_message_events(events, expected_events):
function validate_message_event_pattern (line 227) | def validate_message_event_pattern(start_count, end_count, content_count...
function validate_event_sequence (line 265) | def validate_event_sequence(text_message_events):
function test_with_mock (line 291) | async def test_with_mock():
function test_edge_cases (line 405) | async def test_edge_cases():
function test_text_message_events (line 453) | async def test_text_message_events():
function test_text_message_events_from_before_agent_callback (line 460) | async def test_text_message_events_from_before_agent_callback():
function test_message_event_edge_cases (line 467) | async def test_message_event_edge_cases():
function main (line 474) | async def main():
FILE: integrations/adk-middleware/python/tests/test_thought_to_thinking_integration.py
class TestThoughtToThinkingIntegration (line 42) | class TestThoughtToThinkingIntegration:
method reset_session_manager (line 46) | def reset_session_manager(self):
method thinking_agent (line 59) | def thinking_agent(self):
method non_thinking_agent (line 87) | def non_thinking_agent(self):
method _create_input (line 102) | def _create_input(self, message: str) -> RunAgentInput:
method _count_events (line 120) | def _count_events(self, events: List[BaseEvent]) -> Dict[str, int]:
method _has_thinking_events (line 124) | def _has_thinking_events(self, events: List[BaseEvent]) -> bool:
method _get_thinking_content (line 135) | def _get_thinking_content(self, events: List[BaseEvent]) -> str:
method test_thinking_agent_emits_thinking_events (line 144) | async def test_thinking_agent_emits_thinking_events(self, thinking_age...
method test_non_thinking_agent_no_thinking_events (line 216) | async def test_non_thinking_agent_no_thinking_events(self, non_thinkin...
method test_thinking_events_structure (line 248) | async def test_thinking_events_structure(self, thinking_agent):
FILE: integrations/adk-middleware/python/tests/test_tool_error_handling.py
class TestToolErrorHandling (line 21) | class TestToolErrorHandling:
method mock_adk_agent (line 26) | def mock_adk_agent(self):
method adk_middleware (line 36) | def adk_middleware(self, mock_adk_agent):
method sample_tool (line 47) | def sample_tool(self):
method test_adk_execution_error_during_tool_run (line 63) | async def test_adk_execution_error_during_tool_run(self, adk_middlewar...
method test_tool_result_parsing_error (line 88) | async def test_tool_result_parsing_error(self, adk_middleware, sample_...
method test_tool_result_for_nonexistent_call (line 137) | async def test_tool_result_for_nonexistent_call(self, adk_middleware, ...
method test_toolset_creation_error (line 183) | async def test_toolset_creation_error(self, adk_middleware):
method test_tool_timeout_during_execution (line 212) | async def test_tool_timeout_during_execution(self, sample_tool):
method test_execution_state_error_handling (line 233) | async def test_execution_state_error_handling(self):
method test_multiple_tool_errors_handling (line 255) | async def test_multiple_tool_errors_handling(self, adk_middleware, sam...
method test_execution_cleanup_on_error (line 299) | async def test_execution_cleanup_on_error(self, adk_middleware, sample...
method test_toolset_close_error_handling (line 322) | async def test_toolset_close_error_handling(self):
method test_event_queue_error_during_tool_call_long_running (line 350) | async def test_event_queue_error_during_tool_call_long_running(self, s...
method test_event_queue_error_during_tool_call_blocking (line 372) | async def test_event_queue_error_during_tool_call_blocking(self, sampl...
method test_concurrent_tool_errors (line 394) | async def test_concurrent_tool_errors(self, adk_middleware, sample_tool):
method test_malformed_tool_message_handling (line 424) | async def test_malformed_tool_message_handling(self, adk_middleware, s...
method test_json_parsing_in_tool_result_submission (line 471) | async def test_json_parsing_in_tool_result_submission(self, adk_middle...
FILE: integrations/adk-middleware/python/tests/test_tool_result_flow.py
class TestToolResultFlow (line 19) | class TestToolResultFlow:
method sample_tool (line 24) | def sample_tool(self):
method mock_adk_agent (line 38) | def mock_adk_agent(self):
method ag_ui_adk (line 48) | def ag_ui_adk(self, mock_adk_agent):
method test_is_tool_result_submission_with_tool_message (line 63) | async def test_is_tool_result_submission_with_tool_message(self, ag_ui...
method test_is_tool_result_submission_with_user_message (line 82) | async def test_is_tool_result_submission_with_user_message(self, ag_ui...
method test_is_tool_result_submission_empty_messages (line 101) | async def test_is_tool_result_submission_empty_messages(self, ag_ui_adk):
method test_is_tool_result_submission_ignores_processed_history (line 116) | async def test_is_tool_result_submission_ignores_processed_history(sel...
method test_is_tool_result_submission_multiple_tool_messages (line 137) | async def test_is_tool_result_submission_multiple_tool_messages(self, ...
method test_is_tool_result_submission_new_user_after_tool (line 159) | async def test_is_tool_result_submission_new_user_after_tool(self, ag_...
method test_extract_tool_results_single_tool (line 181) | async def test_extract_tool_results_single_tool(self, ag_ui_adk):
method test_extract_tool_results_multiple_tools (line 205) | async def test_extract_tool_results_multiple_tools(self, ag_ui_adk):
method test_extract_tool_results_mixed_messages (line 228) | async def test_extract_tool_results_mixed_messages(self, ag_ui_adk):
method test_handle_tool_result_submission_no_active_execution (line 254) | async def test_handle_tool_result_submission_no_active_execution(self,...
method test_handle_tool_result_submission_no_active_execution_no_tools (line 278) | async def test_handle_tool_result_submission_no_active_execution_no_to...
method test_handle_tool_result_submission_with_active_execution (line 303) | async def test_handle_tool_result_submission_with_active_execution(sel...
method test_handle_tool_result_submission_streaming_error (line 341) | async def test_handle_tool_result_submission_streaming_error(self, ag_...
method test_handle_tool_result_submission_invalid_json (line 375) | async def test_handle_tool_result_submission_invalid_json(self, ag_ui_...
method test_handle_tool_result_submission_multiple_results (line 401) | async def test_handle_tool_result_submission_multiple_results(self, ag...
method test_tool_result_flow_integration (line 423) | async def test_tool_result_flow_integration(self, ag_ui_adk):
method test_run_processes_mixed_unseen_messages (line 467) | async def test_run_processes_mixed_unseen_messages(self, ag_ui_adk):
method test_run_skips_assistant_history_before_tool_result (line 545) | async def test_run_skips_assistant_history_before_tool_result(self, ag...
method test_run_preserves_order_for_user_then_tool (line 655) | async def test_run_preserves_order_for_user_then_tool(self, ag_ui_adk):
method test_new_execution_routing (line 727) | async def test_new_execution_routing(self, ag_ui_adk, sample_tool):
class TestConfirmChangesFiltering (line 761) | class TestConfirmChangesFiltering:
method mock_adk_agent (line 765) | def mock_adk_agent(self):
method ag_ui_adk (line 775) | def ag_ui_adk(self, mock_adk_agent):
method test_extract_tool_results_filters_confirm_changes (line 790) | async def test_extract_tool_results_filters_confirm_changes(self, ag_u...
method test_extract_tool_results_keeps_regular_tools (line 824) | async def test_extract_tool_results_keeps_regular_tools(self, ag_ui_adk):
method test_extract_tool_results_mixed_tools (line 860) | async def test_extract_tool_results_mixed_tools(self, ag_ui_adk):
method test_handle_tool_result_submission_only_confirm_changes (line 900) | async def test_handle_tool_result_submission_only_confirm_changes(self...
method test_handle_tool_result_submission_confirm_changes_with_trailing_messages (line 953) | async def test_handle_tool_result_submission_confirm_changes_with_trai...
class TestClientToolResultPersistence (line 1025) | class TestClientToolResultPersistence:
method mock_adk_agent (line 1029) | def mock_adk_agent(self):
method ag_ui_adk (line 1039) | def ag_ui_adk(self, mock_adk_agent):
method test_client_tool_result_persisted_to_session_db (line 1055) | async def test_client_tool_result_persisted_to_session_db(self, ag_ui_...
method test_backend_tool_results_not_double_persisted (line 1222) | async def test_backend_tool_results_not_double_persisted(self, ag_ui_a...
class TestDatabaseSessionServiceCompatibility (line 1400) | class TestDatabaseSessionServiceCompatibility:
method mock_adk_agent (line 1411) | def mock_adk_agent(self):
method ag_ui_adk (line 1421) | def ag_ui_adk(self, mock_adk_agent):
method _prepare_session_with_pending_tool_call (line 1436) | async def _prepare_session_with_pending_tool_call(
method _assert_function_response_invocation_id (line 1490) | def _assert_function_response_invocation_id(
method test_invocation_id_set_on_function_response_event (line 1513) | async def test_invocation_id_set_on_function_response_event(self, ag_u...
method test_explicit_persist_with_null_new_message_for_tool_results_only (line 1613) | async def test_explicit_persist_with_null_new_message_for_tool_results...
method test_session_refreshed_after_state_update (line 1729) | async def test_session_refreshed_after_state_update(self, ag_ui_adk):
FILE: integrations/adk-middleware/python/tests/test_tool_tracking_hitl.py
class TestHITLToolTracking (line 18) | class TestHITLToolTracking:
method reset_session_manager (line 22) | def reset_session_manager(self):
method mock_adk_agent (line 30) | def mock_adk_agent(self):
method adk_middleware (line 40) | def adk_middleware(self, mock_adk_agent):
method sample_tool (line 49) | def sample_tool(self):
method test_tool_call_tracking (line 63) | async def test_tool_call_tracking(self, adk_middleware, sample_tool):
method test_execution_not_cleaned_up_with_pending_tools (line 140) | async def test_execution_not_cleaned_up_with_pending_tools(self, adk_m...
method test_session_not_cleaned_up_with_pending_tools (line 187) | async def test_session_not_cleaned_up_with_pending_tools(self, mock_ad...
method test_session_cleaned_up_with_no_pending_tools (line 246) | async def test_session_cleaned_up_with_no_pending_tools(self, mock_adk...
method test_stale_pending_tool_calls_cleared_on_session_resumption (line 298) | async def test_stale_pending_tool_calls_cleared_on_session_resumption(
method test_new_session_has_no_pending_tool_calls_to_clear (line 365) | async def test_new_session_has_no_pending_tool_calls_to_clear(self, ad...
FILE: integrations/adk-middleware/python/tests/test_use_thread_id_as_session_id.py
class TestSessionManagerDirectLookup (line 16) | class TestSessionManagerDirectLookup:
method reset_session_manager (line 20) | def reset_session_manager(self):
method session_service (line 27) | def session_service(self):
method manager (line 31) | def manager(self, session_service):
method manager_scan (line 38) | def manager_scan(self, session_service):
method test_create_session_uses_thread_id (line 47) | async def test_create_session_uses_thread_id(self, manager, session_se...
method test_get_existing_session_direct_lookup (line 58) | async def test_get_existing_session_direct_lookup(self, manager, sessi...
method test_does_not_call_list_sessions (line 73) | async def test_does_not_call_list_sessions(self, manager, session_serv...
method test_stores_thread_id_in_state (line 90) | async def test_stores_thread_id_in_state(self, manager, session_service):
method test_initial_state_preserved (line 102) | async def test_initial_state_preserved(self, manager, session_service):
method test_multiple_threads_independent (line 114) | async def test_multiple_threads_independent(self, manager, session_ser...
method test_session_tracking (line 131) | async def test_session_tracking(self, manager):
method test_race_condition_retry (line 142) | async def test_race_condition_retry(self, manager, session_service):
class TestSessionManagerScanPath (line 183) | class TestSessionManagerScanPath:
method reset_session_manager (line 187) | def reset_session_manager(self):
method session_service (line 193) | def session_service(self):
method manager (line 197) | def manager(self, session_service):
method test_default_lets_backend_generate_id (line 204) | async def test_default_lets_backend_generate_id(self, manager, session...
method test_scan_finds_existing_session (line 216) | async def test_scan_finds_existing_session(self, manager, session_serv...
class TestADKAgentWithThreadIdAsSessionId (line 231) | class TestADKAgentWithThreadIdAsSessionId:
method reset_session_manager (line 235) | def reset_session_manager(self):
method mock_agent (line 241) | def mock_agent(self):
method adk_agent (line 249) | def adk_agent(self, mock_agent):
method sample_input (line 259) | def sample_input(self):
method test_ensure_session_uses_thread_id_as_session_id (line 273) | async def test_ensure_session_uses_thread_id_as_session_id(self, adk_a...
method test_cache_populated_after_session_creation (line 285) | async def test_cache_populated_after_session_creation(self, adk_agent,...
method test_second_call_uses_cache (line 298) | async def test_second_call_uses_cache(self, adk_agent):
method test_full_run_with_direct_lookup (line 316) | async def test_full_run_with_direct_lookup(self, adk_agent, sample_inp...
method test_parameter_defaults_to_false (line 347) | async def test_parameter_defaults_to_false(self):
FILE: integrations/adk-middleware/python/tests/test_user_id_extractor.py
function test_static_user_id (line 10) | def test_static_user_id():
function test_custom_extractor (line 38) | def test_custom_extractor():
function test_default_extractor (line 88) | def test_default_extractor():
function test_conflicting_config (line 117) | def test_conflicting_config():
function main (line 139) | def main():
FILE: integrations/adk-middleware/python/tests/test_utils_converters.py
class TestConvertAGUIMessagesToADK (line 32) | class TestConvertAGUIMessagesToADK:
method test_convert_user_message (line 35) | def test_convert_user_message(self):
method test_convert_user_message_multimodal_inline_data (line 53) | def test_convert_user_message_multimodal_inline_data(self):
method test_convert_user_message_multimodal_id_only_ignored (line 74) | def test_convert_user_message_multimodal_id_only_ignored(self):
method test_convert_user_message_multimodal_broken_base64_ignored (line 91) | def test_convert_user_message_multimodal_broken_base64_ignored(self):
method test_convert_user_message_multimodal_file_data_url_ignored (line 108) | def test_convert_user_message_multimodal_file_data_url_ignored(self):
method test_convert_system_message (line 126) | def test_convert_system_message(self):
method test_convert_assistant_message_with_text (line 143) | def test_convert_assistant_message_with_text(self):
method test_convert_assistant_message_with_tool_calls (line 160) | def test_convert_assistant_message_with_tool_calls(self):
method test_convert_assistant_message_with_dict_tool_args (line 195) | def test_convert_assistant_message_with_dict_tool_args(self):
method test_convert_tool_message (line 218) | def test_convert_tool_message(self):
method test_convert_tool_message_with_dict_content (line 240) | def test_convert_tool_message_with_dict_content(self):
method test_convert_empty_message_list (line 255) | def test_convert_empty_message_list(self):
method test_convert_message_without_content (line 260) | def test_convert_message_without_content(self):
method test_convert_assistant_message_without_content_or_tools (line 271) | def test_convert_assistant_message_without_content_or_tools(self):
method test_convert_multiple_messages (line 286) | def test_convert_multiple_messages(self):
method test_convert_with_exception_handling (line 302) | def test_convert_with_exception_handling(self, mock_logger):
class TestConvertADKEventToAGUIMessage (line 319) | class TestConvertADKEventToAGUIMessage:
method test_convert_user_event (line 322) | def test_convert_user_event(self):
method test_convert_user_event_multiple_text_parts (line 340) | def test_convert_user_event_multiple_text_parts(self):
method test_convert_assistant_event_with_text (line 357) | def test_convert_assistant_event_with_text(self):
method test_convert_assistant_event_with_function_call (line 377) | def test_convert_assistant_event_with_function_call(self):
method test_convert_assistant_event_with_text_and_function_call (line 404) | def test_convert_assistant_event_with_text_and_function_call(self):
method test_convert_function_call_without_args (line 430) | def test_convert_function_call_without_args(self):
method test_convert_function_call_without_id (line 452) | def test_convert_function_call_without_id(self):
method test_convert_event_without_content (line 474) | def test_convert_event_without_content(self):
method test_convert_event_without_parts (line 485) | def test_convert_event_without_parts(self):
method test_convert_user_event_without_text (line 497) | def test_convert_user_event_without_text(self):
method test_convert_with_exception_handling (line 513) | def test_convert_with_exception_handling(self, mock_logger):
class TestStateConversionFunctions (line 530) | class TestStateConversionFunctions:
method test_convert_state_to_json_patch_basic (line 533) | def test_convert_state_to_json_patch_basic(self):
method test_convert_state_to_json_patch_with_none_values (line 558) | def test_convert_state_to_json_patch_with_none_values(self):
method test_convert_state_to_json_patch_empty_dict (line 581) | def test_convert_state_to_json_patch_empty_dict(self):
method test_convert_json_patch_to_state_basic (line 586) | def test_convert_json_patch_to_state_basic(self):
method test_convert_json_patch_to_state_with_nested_paths (line 601) | def test_convert_json_patch_to_state_with_nested_paths(self):
method test_convert_json_patch_to_state_with_unsupported_ops (line 614) | def test_convert_json_patch_to_state_with_unsupported_ops(self):
method test_convert_json_patch_to_state_empty_list (line 629) | def test_convert_json_patch_to_state_empty_list(self):
method test_convert_json_patch_to_state_malformed_patches (line 634) | def test_convert_json_patch_to_state_malformed_patches(self):
method test_roundtrip_conversion (line 650) | def test_roundtrip_conversion(self):
class TestUtilityFunctions (line 665) | class TestUtilityFunctions:
method test_extract_text_from_content_basic (line 668) | def test_extract_text_from_content_basic(self):
method test_extract_text_from_content_with_none_text (line 682) | def test_extract_text_from_content_with_none_text(self):
method test_extract_text_from_content_no_text_parts (line 698) | def test_extract_text_from_content_no_text_parts(self):
method test_extract_text_from_content_no_parts (line 712) | def test_extract_text_from_content_no_parts(self):
method test_extract_text_from_content_none_content (line 721) | def test_extract_text_from_content_none_content(self):
method test_extract_text_from_content_no_parts_attribute (line 727) | def test_extract_text_from_content_no_parts_attribute(self):
method test_create_error_message_basic (line 736) | def test_create_error_message_basic(self):
method test_create_error_message_with_context (line 744) | def test_create_error_message_with_context(self):
method test_create_error_message_empty_context (line 753) | def test_create_error_message_empty_context(self):
method test_create_error_message_custom_exception (line 761) | def test_create_error_message_custom_exception(self):
method test_create_error_message_exception_without_message (line 772) | def test_create_error_message_exception_without_message(self):
FILE: integrations/adk-middleware/python/tests/test_utils_init.py
class TestUtilsInit (line 7) | class TestUtilsInit:
method test_imports_available (line 10) | def test_imports_available(self):
method test_module_has_all_attribute (line 25) | def test_module_has_all_attribute(self):
method test_direct_import_from_utils (line 39) | def test_direct_import_from_utils(self):
method test_utils_module_docstring (line 50) | def test_utils_module_docstring(self):
method test_re_export_functionality (line 57) | def test_re_export_functionality(self):
FILE: integrations/adk-middleware/python/tests/test_vertex_session_service.py
class _MockSession (line 36) | class _MockSession:
method __init__ (line 39) | def __init__(self, *, app_name: str, user_id: str, id: str, state: dict):
class _ListSessionsResponse (line 48) | class _ListSessionsResponse:
method __init__ (line 49) | def __init__(self, sessions: list):
class MockVertexAiSessionService (line 53) | class MockVertexAiSessionService:
method __init__ (line 62) | def __init__(self):
method _make_key (line 66) | def _make_key(self, app_name: str, user_id: str, session_id: str) -> str:
method _next_id (line 69) | def _next_id(self) -> str:
method create_session (line 73) | async def create_session(
method get_session (line 95) | async def get_session(
method list_sessions (line 106) | async def list_sessions(
method delete_session (line 118) | async def delete_session(
method append_event (line 124) | async def append_event(self, session: _MockSession, event: Any) -> Any:
class TestVertexSessionServiceMock (line 135) | class TestVertexSessionServiceMock:
method reset_session_manager (line 139) | def reset_session_manager(self):
method vertex_session_service (line 145) | def vertex_session_service(self):
method adk_agent (line 149) | def adk_agent(self, vertex_session_service):
method test_session_created_with_backend_generated_id (line 168) | async def test_session_created_with_backend_generated_id(
method test_thread_id_stored_in_state (line 184) | async def test_thread_id_stored_in_state(
method test_session_recovered_via_scan_after_cache_miss (line 197) | async def test_session_recovered_via_scan_after_cache_miss(
method test_multiple_threads_get_separate_sessions (line 222) | async def test_multiple_threads_get_separate_sessions(
method test_same_thread_reuses_session_from_cache (line 241) | async def test_same_thread_reuses_session_from_cache(
method test_initial_state_merged_with_metadata (line 260) | async def test_initial_state_merged_with_metadata(
class TestVertexSessionServiceRejectsCustomId (line 274) | class TestVertexSessionServiceRejectsCustomId:
method reset_session_manager (line 279) | def reset_session_manager(self):
method test_create_session_raises_on_custom_id (line 285) | async def test_create_session_raises_on_custom_id(self):
method test_use_thread_id_as_session_id_propagates_error (line 294) | async def test_use_thread_id_as_session_id_propagates_error(self):
class TestVertexSessionServiceFullRun (line 326) | class TestVertexSessionServiceFullRun:
method reset_session_manager (line 330) | def reset_session_manager(self):
method test_full_run_with_vertex_session_service (line 336) | async def test_full_run_with_vertex_session_service(self):
method test_multi_turn_with_vertex_session_service (line 398) | async def test_multi_turn_with_vertex_session_service(self):
function _has_vertex_session_auth (line 480) | def _has_vertex_session_auth():
class TestVertexSessionServiceLive (line 490) | class TestVertexSessionServiceLive:
method reset_session_manager (line 510) | def reset_session_manager(self):
method _clean_env_for_vertex (line 516) | def _clean_env_for_vertex(self, monkeypatch):
method vertex_service (line 532) | def vertex_service(self):
method app_name (line 546) | def app_name(self):
method test_create_and_get_session (line 551) | async def test_create_and_get_session(self, vertex_service, app_name):
method test_list_sessions_finds_created_session (line 582) | async def test_list_sessions_finds_created_session(
method test_custom_session_id_raises_value_error (line 608) | async def test_custom_session_id_raises_value_error(self, vertex_servi...
method test_adk_agent_default_path_works (line 618) | async def test_adk_agent_default_path_works(self, vertex_service, app_...
FILE: integrations/adk-middleware/typescript/src/index.ts
class ADKAgent (line 3) | class ADKAgent extends HttpAgent {}
FILE: integrations/ag2/python/examples/server/__init__.py
function main (line 56) | def main():
FILE: integrations/ag2/python/examples/server/api/agentic_generative_ui.py
class Step (line 17) | class Step(BaseModel):
class Plan (line 27) | class Plan(BaseModel):
function create_plan (line 34) | async def create_plan(
function update_plan_step (line 57) | async def update_plan_step(
FILE: integrations/ag2/python/examples/server/api/backend_tool_rendering.py
function get_weather_condition (line 16) | def get_weather_condition(code: int) -> str:
function get_weather (line 45) | async def get_weather(location: str) -> str:
FILE: integrations/ag2/python/examples/server/api/shared_state.py
class SkillLevel (line 18) | class SkillLevel(StrEnum):
class SpecialPreferences (line 26) | class SpecialPreferences(StrEnum):
class CookingTime (line 38) | class CookingTime(StrEnum):
class Ingredient (line 48) | class Ingredient(BaseModel):
class Recipe (line 59) | class Recipe(BaseModel):
class RecipeSnapshot (line 84) | class RecipeSnapshot(BaseModel):
function get_current_recipe (line 94) | async def get_current_recipe(context_variables: ContextVariables) -> str:
function display_recipe (line 108) | async def display_recipe(
FILE: integrations/ag2/typescript/src/index.ts
class Ag2Agent (line 9) | class Ag2Agent extends HttpAgent {
method maxVersion (line 10) | public override get maxVersion(): string {
FILE: integrations/agent-spec/python/ag_ui_agentspec/agent.py
function _inject_missing_contextvars (line 21) | def _inject_missing_contextvars(base_context: contextvars.Context):
function _apply_base_contextvars (line 42) | def _apply_base_contextvars(
class AgentSpecAgent (line 53) | class AgentSpecAgent:
method __init__ (line 54) | def __init__(
method run (line 91) | async def run(self, input_data: RunAgentInput) -> None:
FILE: integrations/agent-spec/python/ag_ui_agentspec/agentspec_tracing_exporter.py
function _safe_model_dump (line 62) | def _safe_model_dump(obj: Any) -> Any:
class AgUiSpanProcessor (line 72) | class AgUiSpanProcessor(SpanProcessor):
method __init__ (line 82) | def __init__(self, runtime: str) -> None:
method _emit (line 95) | def _emit(self, event_obj) -> None:
method _aemit (line 107) | async def _aemit(self, event_obj) -> None:
method _run_started_event (line 120) | def _run_started_event(self):
method _run_finished_event (line 124) | def _run_finished_event(self):
method startup (line 127) | def startup(self) -> None:
method shutdown (line 130) | def shutdown(self) -> None:
method startup_async (line 133) | async def startup_async(self) -> None:
method shutdown_async (line 136) | async def shutdown_async(self) -> None:
method on_start (line 139) | def on_start(self, span: Span) -> None:
method on_end (line 143) | def on_end(self, span: Span) -> None:
method on_start_async (line 147) | async def on_start_async(self, span: Span) -> None:
method on_end_async (line 151) | async def on_end_async(self, span: Span) -> None:
method on_event (line 156) | def on_event(self, event: Event, span: Span, *args: Any, **kwargs: Any...
method on_event_async (line 160) | async def on_event_async(self, event: Event, span: Span) -> None:
method _gather_start_events (line 165) | def _gather_start_events(self, span: Span) -> List[Any]:
method _gather_end_events (line 173) | def _gather_end_events(self, span: Span) -> List[Any]:
method _gather_events_for_event (line 181) | def _gather_events_for_event(self, event: Event, span: Span) -> List[A...
function repair_a2ui_json (line 297) | def repair_a2ui_json(a2ui_json: Any) -> str:
function _escape_html (line 312) | def _escape_html(text: str) -> str:
function _normalize_tool_output (line 318) | def _normalize_tool_output(outputs: Any) -> str:
function jsonable (line 353) | def jsonable(string):
FILE: integrations/agent-spec/python/ag_ui_agentspec/agentspecloader.py
function load_agent_spec (line 8) | def load_agent_spec(
function load_agent_spec (line 15) | def load_agent_spec(
function load_agent_spec (line 22) | def load_agent_spec(
FILE: integrations/agent-spec/python/ag_ui_agentspec/endpoint.py
function add_agentspec_fastapi_endpoint (line 17) | def add_agentspec_fastapi_endpoint(app: FastAPI, agentspec_agent: AgentS...
FILE: integrations/agent-spec/python/ag_ui_agentspec/runtimes/langgraph_runner.py
function run_langgraph_agent (line 13) | async def run_langgraph_agent(agent: CompiledStateGraph, input_data: Run...
function prepare_langgraph_agent_inputs (line 33) | def prepare_langgraph_agent_inputs(input_data: RunAgentInput) -> List[Di...
function filter_only_new_messages (line 50) | async def filter_only_new_messages(
FILE: integrations/agent-spec/python/ag_ui_agentspec/runtimes/wayflow_runner.py
function prepare_wayflow_agent_input (line 15) | def prepare_wayflow_agent_input(input_data: RunAgentInput) -> Dict[str, ...
function prepare_wayflow_flow_input (line 50) | def prepare_wayflow_flow_input(input_data: RunAgentInput) -> Dict[str, A...
function run_wayflow (line 55) | async def run_wayflow(agent: Any, input_data: RunAgentInput) -> None:
FILE: integrations/agent-spec/python/examples/server/__init__.py
function main (line 16) | def main():
FILE: integrations/agent-spec/python/examples/server/api/backend_tool_rendering.py
function get_weather (line 17) | def get_weather(location: str) -> Dict[str, Any]:
FILE: integrations/agent-spec/python/examples/server/api/routes.py
function _is_available (line 22) | def _is_available(module_name: str) -> bool:
function _mount (line 26) | def _mount(router: APIRouter):
FILE: integrations/agno/python/examples/server/__init__.py
function main (line 39) | def main():
FILE: integrations/agno/python/examples/server/api/agentic_chat.py
function change_background (line 15) | def change_background(background: str) -> str: # pylint: disable=unused...
FILE: integrations/agno/python/examples/server/api/backend_tool_rendering.py
function get_weather_condition (line 17) | def get_weather_condition(code: int) -> str:
function get_weather (line 60) | async def get_weather(location: str) -> str:
FILE: integrations/agno/python/examples/server/api/human_in_the_loop.py
class Step (line 17) | class Step(BaseModel):
function generate_task_steps (line 28) | def generate_task_steps(
FILE: integrations/agno/python/examples/server/api/tool_based_generative_ui.py
function generate_haiku (line 16) | def generate_haiku(english: List[str], japanese: List[str], image_names:...
FILE: integrations/agno/typescript/src/index.ts
class AgnoAgent (line 8) | class AgnoAgent extends HttpAgent {
method maxVersion (line 9) | public override get maxVersion(): string {
FILE: integrations/aws-strands/python/examples/server/__init__.py
function root (line 55) | def root():
function main (line 66) | def main():
FILE: integrations/aws-strands/python/examples/server/api/agentic_generative_ui.py
class TaskStep (line 58) | class TaskStep(BaseModel):
function plan_task_steps (line 66) | def plan_task_steps(
function _normalize_steps (line 93) | def _normalize_steps(raw_steps: Any) -> List[Dict[str, str]]:
function _fallback_steps (line 112) | def _fallback_steps(task: str, context: str) -> List[Dict[str, str]]:
function steps_state_from_result (line 143) | async def steps_state_from_result(context):
function simulate_progress (line 151) | async def simulate_progress(context):
function build_state_context (line 231) | def build_state_context(input_data, user_message: str) -> str:
FILE: integrations/aws-strands/python/examples/server/api/backend_tool_rendering.py
function render_chart (line 40) | def render_chart(chart_type: str, data: str) -> dict:
function get_weather (line 58) | def get_weather(location: str) -> dict:
FILE: integrations/aws-strands/python/examples/server/api/human_in_the_loop.py
class Step (line 39) | class Step(BaseModel):
function generate_task_steps (line 55) | def generate_task_steps(
FILE: integrations/aws-strands/python/examples/server/api/shared_state.py
class SkillLevel (line 13) | class SkillLevel(str, Enum):
class SpecialPreferences (line 20) | class SpecialPreferences(str, Enum):
class CookingTime (line 31) | class CookingTime(str, Enum):
class Ingredient (line 40) | class Ingredient(BaseModel):
class Recipe (line 47) | class Recipe(BaseModel):
function generate_recipe (line 66) | def generate_recipe(recipe: Recipe):
function build_recipe_prompt (line 92) | def build_recipe_prompt(input_data, user_message: str) -> str:
function recipe_state_from_args (line 105) | async def recipe_state_from_args(context):
function recipe_state_from_result (line 117) | async def recipe_state_from_result(context):
FILE: integrations/aws-strands/python/src/ag_ui_strands/agent.py
class StrandsAgent (line 45) | class StrandsAgent:
method __init__ (line 48) | def __init__(
method run (line 78) | async def run(self, input_data: RunAgentInput) -> AsyncIterator[Any]:
FILE: integrations/aws-strands/python/src/ag_ui_strands/client_proxy_tool.py
function create_proxy_tool (line 19) | def create_proxy_tool(ag_ui_tool: AgUiTool) -> PythonAgentTool:
function _is_proxy (line 71) | def _is_proxy(tool: Any) -> bool:
function sync_proxy_tools (line 76) | def sync_proxy_tools(
FILE: integrations/aws-strands/python/src/ag_ui_strands/config.py
class ToolCallContext (line 25) | class ToolCallContext:
class ToolResultContext (line 36) | class ToolResultContext(ToolCallContext):
class PredictStateMapping (line 51) | class PredictStateMapping:
method to_payload (line 58) | def to_payload(self) -> Dict[str, str]:
class ToolBehavior (line 67) | class ToolBehavior:
class StrandsAgentConfig (line 81) | class StrandsAgentConfig:
function maybe_await (line 88) | async def maybe_await(value: Any) -> Any:
function normalize_predict_state (line 96) | def normalize_predict_state(value: Optional[Iterable[PredictStateMapping...
FILE: integrations/aws-strands/python/src/ag_ui_strands/endpoint.py
function add_strands_fastapi_endpoint (line 9) | def add_strands_fastapi_endpoint(
function add_ping (line 42) | def add_ping(app: FastAPI, path: str) -> None:
FILE: integrations/aws-strands/python/src/ag_ui_strands/types.py
class StrandsEventTypes (line 7) | class StrandsEventTypes(str, Enum):
class StrandsMessage (line 16) | class StrandsMessage(BaseModel):
class StrandsToolCall (line 22) | class StrandsToolCall(BaseModel):
class StrandsState (line 29) | class StrandsState(BaseModel):
FILE: integrations/aws-strands/python/src/ag_ui_strands/utils.py
function create_strands_app (line 7) | def create_strands_app(
FILE: integrations/aws-strands/python/tests/test_client_proxy_tool.py
function _make_ag_ui_tool (line 24) | def _make_ag_ui_tool(name: str, description: str = "desc", parameters: d...
function _make_native_tool (line 29) | def _make_native_tool(name: str) -> PythonAgentTool:
class TestCreateProxyTool (line 44) | class TestCreateProxyTool:
method test_returns_python_agent_tool (line 45) | def test_returns_python_agent_tool(self):
method test_marked_dynamic (line 57) | def test_marked_dynamic(self):
method test_marked_as_proxy (line 61) | def test_marked_as_proxy(self):
method test_supports_hot_reload (line 66) | def test_supports_hot_reload(self):
class TestProxyToolResult (line 71) | class TestProxyToolResult:
method test_returns_success_with_placeholder (line 72) | def test_returns_success_with_placeholder(self):
class TestSyncProxyTools (line 86) | class TestSyncProxyTools:
method _fresh_registry (line 87) | def _fresh_registry(self) -> ToolRegistry:
method test_adds_new_tools (line 90) | def test_adds_new_tools(self):
method test_removes_stale_tools (line 102) | def test_removes_stale_tools(self):
method test_preserves_native_tools (line 117) | def test_preserves_native_tools(self):
method test_removes_all_when_empty_list (line 130) | def test_removes_all_when_empty_list(self):
method test_idempotent_re_registration (line 140) | def test_idempotent_re_registration(self):
FILE: integrations/aws-strands/typescript/src/index.ts
class AWSStrandsAgent (line 8) | class AWSStrandsAgent extends HttpAgent {}
FILE: integrations/claude-agent-sdk/python/ag_ui_claude_sdk/adapter.py
class ClaudeAgentAdapter (line 74) | class ClaudeAgentAdapter:
method __init__ (line 82) | def __init__(
method interrupt (line 102) | async def interrupt(self, thread_id: Optional[str] = None) -> None:
method shutdown (line 110) | async def shutdown(self) -> None:
method _evict_workers (line 117) | def _evict_workers(self) -> None:
method clear_session (line 144) | async def clear_session(self, thread_id: str) -> None:
method run (line 151) | async def run(self, input_data: RunAgentInput) -> AsyncIterator[BaseEv...
method build_options (line 265) | def build_options(self, input_data: Optional[RunAgentInput] = None, th...
method _stream_claude_sdk (line 395) | async def _stream_claude_sdk(
FILE: integrations/claude-agent-sdk/python/ag_ui_claude_sdk/endpoint.py
function add_claude_fastapi_endpoint (line 10) | def add_claude_fastapi_endpoint(app: FastAPI, adapter: ClaudeAgentAdapte...
FILE: integrations/claude-agent-sdk/python/ag_ui_claude_sdk/handlers.py
function handle_tool_use_block (line 28) | async def handle_tool_use_block(
function handle_tool_result_block (line 139) | async def handle_tool_result_block(
FILE: integrations/claude-agent-sdk/python/ag_ui_claude_sdk/session.py
class WorkerError (line 18) | class WorkerError:
method __init__ (line 20) | def __init__(self, exception: Exception):
class SessionWorker (line 24) | class SessionWorker:
method __init__ (line 32) | def __init__(self, thread_id: str, options: Any):
method start (line 40) | async def start(self) -> None:
method _run (line 48) | async def _run(self) -> None:
method _graceful_disconnect (line 93) | async def _graceful_disconnect(client: Any) -> None:
method query (line 99) | async def query(self, prompt: str, session_id: str = "default") -> Asy...
method interrupt (line 111) | async def interrupt(self) -> None:
method stop (line 119) | async def stop(self) -> None:
FILE: integrations/claude-agent-sdk/python/ag_ui_claude_sdk/utils.py
function fix_surrogates (line 17) | def fix_surrogates(s: str) -> str:
function fix_surrogates_deep (line 36) | def fix_surrogates_deep(obj: Any) -> Any:
function extract_tool_names (line 47) | def extract_tool_names(tools: List[Any]) -> List[str]:
function strip_mcp_prefix (line 67) | def strip_mcp_prefix(tool_name: str) -> str:
function process_messages (line 92) | def process_messages(input_data: RunAgentInput) -> Tuple[str, bool]:
function build_state_context_addendum (line 167) | def build_state_context_addendum(input_data: RunAgentInput) -> str:
function convert_agui_tool_to_claude_sdk (line 210) | def convert_agui_too
Copy disabled (too large)
Download .json
Condensed preview — 1836 files, each showing path, character count, and a content snippet. Download the .json file for the full structured content (12,137K chars).
[
{
"path": ".claude/settings.json",
"chars": 307,
"preview": "{\n \"permissions\": {\n \"allow\": [\n \"Bash(npx nx show projects)\",\n \"Bash(pnpm nx run dojo:check-types)\",\n "
},
{
"path": ".gitattributes",
"chars": 123,
"preview": "* text=auto eol=lf\n*.mdx text eol=lf\n*.js text eol=lf\n*.ts text eol=lf\n*.jsx text eol=lf\n*.tsx text eol=lf\n*.py text eol"
},
{
"path": ".github/CODEOWNERS",
"chars": 367,
"preview": "* @ag-ui-protocol/copilotkit\n\nsdks/community/java @pascalwilbrink\ndocs/sdk/java @pascalwilbrink\n\nsdks/community/kotlin @"
},
{
"path": ".github/ISSUE_TEMPLATE/bug_report.yml",
"chars": 2572,
"preview": "name: \"🐛 Bug Report\"\ndescription: \"Something isn't working as expected? Let us know so we can fix it.\"\ntitle: \"[Bug]: \"\n"
},
{
"path": ".github/ISSUE_TEMPLATE/documentation.yml",
"chars": 630,
"preview": "name: 📚 Documentation Issue\ndescription: Let us know how we can improve the AG-UI documentation.\ntitle: \"📚 Documentation"
},
{
"path": ".github/ISSUE_TEMPLATE/feature_request.yml",
"chars": 1454,
"preview": "name: \"✨ Feature Request\"\ndescription: \"Suggest a new feature or improvement.\"\ntitle: \"[Feature]: \"\nlabels: [\"enhancemen"
},
{
"path": ".github/pull_request_template.md",
"chars": 842,
"preview": "\n<!--\n\n**Please PLEASE reach out to us first before starting any significant work on new or existing features.**\n\nBy the"
},
{
"path": ".github/workflows/auto-approve-community.yml",
"chars": 7083,
"preview": "name: Auto-approve community PRs\n\non:\n pull_request:\n types: [opened, synchronize, reopened]\n\npermissions:\n pull-re"
},
{
"path": ".github/workflows/build-python-preview.yml",
"chars": 2811,
"preview": "name: Build Python Preview\n\non:\n pull_request:\n types: [opened, synchronize, reopened]\n\nconcurrency:\n group: ${{ gi"
},
{
"path": ".github/workflows/dojo-e2e.yml",
"chars": 10813,
"preview": "name: e2e\n\non:\n workflow_dispatch:\n push:\n branches: [main]\n paths:\n - \"integrations/**\"\n - \"apps/dojo"
},
{
"path": ".github/workflows/pr-check-binaries.yml",
"chars": 2721,
"preview": "name: Check for binary artifacts\n\non:\n pull_request:\n types: [opened, synchronize, reopened]\n\npermissions:\n content"
},
{
"path": ".github/workflows/publish-commit.yml",
"chars": 916,
"preview": "name: 🚀 pkg-pr-new\non: [push, pull_request]\n\nconcurrency:\n group: ${{ github.repository }}-${{ github.workflow }}-${{ g"
},
{
"path": ".github/workflows/publish-java-sdk.yml",
"chars": 1011,
"preview": "name: Publish Java SDK to Maven Central\n\non:\n # Manual trigger only - no automatic publishing\n workflow_dispatch:\n\njob"
},
{
"path": ".github/workflows/publish-kotlin-sdk.yml",
"chars": 6919,
"preview": "name: Publish Kotlin SDK to Maven Central\n\non:\n # Manual trigger only - no automatic publishing\n workflow_dispatch:\n "
},
{
"path": ".github/workflows/publish-python-package.yml",
"chars": 3868,
"preview": "name: Publish Python Package to PyPI\n\non:\n # Manual trigger only - no automatic publishing\n workflow_dispatch:\n inp"
},
{
"path": ".github/workflows/publish-python-preview.yml",
"chars": 5175,
"preview": "name: Publish Python Preview to TestPyPI\n\n# Triggered when the build workflow completes. Runs in the base repo context,\n"
},
{
"path": ".github/workflows/rust-lint-test.yml",
"chars": 1253,
"preview": "name: test\n\non:\n push:\n branches: [ \"main\" ]\n paths:\n - \"crates/**\"\n - \".github/workflows/rust.yml\"\n "
},
{
"path": ".github/workflows/unit-dart-sdk.yml",
"chars": 693,
"preview": "name: unit\n\non:\n push:\n branches: [main]\n paths:\n - \"sdks/community/dart/**\"\n - \".github/workflows/unit"
},
{
"path": ".github/workflows/unit-genkit-go.yml",
"chars": 1138,
"preview": "name: unit\n\non:\n push:\n branches: [main]\n paths:\n - \"integrations/community/genkit/go/**\"\n - \".github/w"
},
{
"path": ".github/workflows/unit-go-sdk.yml",
"chars": 962,
"preview": "name: unit\n\non:\n push:\n branches: [main]\n paths:\n - \"sdks/community/go/**\"\n - \".github/workflows/unit-g"
},
{
"path": ".github/workflows/unit-java-sdk.yml",
"chars": 671,
"preview": "name: unit\n\non:\n push:\n branches: [main]\n paths:\n - \"sdks/community/java/**\"\n - \".github/workflows/unit"
},
{
"path": ".github/workflows/unit-kotlin-sdk.yml",
"chars": 2870,
"preview": "name: unit\n\non:\n push:\n branches: [main]\n paths:\n - \"sdks/community/kotlin/**\"\n - \".github/workflows/un"
},
{
"path": ".github/workflows/unit-python-sdk.yml",
"chars": 913,
"preview": "name: unit\n\non:\n push:\n branches: [main]\n paths:\n - \"sdks/python/**\"\n - \".github/workflows/unit-python-"
},
{
"path": ".github/workflows/unit-ruby-sdk.yml",
"chars": 565,
"preview": "name: unit\n\non:\n push:\n branches: [main]\n paths:\n - \"sdks/community/ruby/**\"\n - \".github/workflows/unit"
},
{
"path": ".github/workflows/unit-typescript-sdk.yml",
"chars": 1512,
"preview": "name: unit\n\non:\n push:\n branches: [main]\n paths:\n - \"sdks/typescript/**\"\n - \"typescript-sdk/**\"\n -"
},
{
"path": ".gitignore",
"chars": 470,
"preview": "**/.claude/settings.local.json\n.claude/worktrees\n\n# Test coverage\ncoverage/\n\nmastra.db*\n\n**/.DS_Store\n\ntest-results/\n\n**"
},
{
"path": ".mcp.json",
"chars": 147,
"preview": "{\n \"mcpServers\": {\n \"nx-mcp\": {\n \"type\": \"stdio\",\n \"command\": \"npx\",\n \"args\": [\n \"nx\",\n "
},
{
"path": "AGENTS.md",
"chars": 1233,
"preview": "<!-- nx configuration start-->\n<!-- Leave the start & end comments to automatically receive updates. -->\n\n# General Guid"
},
{
"path": "CLAUDE.md",
"chars": 4766,
"preview": "# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\n## "
},
{
"path": "CONTRIBUTING.md",
"chars": 12600,
"preview": "# Contributing to AG-UI\n\nThanks for checking out AG-UI! Whether you're here to fix a bug, ship a feature, improve the do"
},
{
"path": "LICENSE",
"chars": 1056,
"preview": "MIT License\n\nCopyright (c) 2025\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this so"
},
{
"path": "README.md",
"chars": 11236,
"preview": "\n# <img src=\"https://github.com/user-attachments/assets/ebc0dd08-8732-4519-9b6c-452ce54d8058\" alt=\"ag-ui Logo\" width=\"22"
},
{
"path": "apps/client-cli-example/.gitignore",
"chars": 2162,
"preview": "# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports (https://nodejs."
},
{
"path": "apps/client-cli-example/README.md",
"chars": 1125,
"preview": "# AG-UI CLI Example\n\nA command-line chat interface demonstrating the AG-UI client with a Mastra agent. This example show"
},
{
"path": "apps/client-cli-example/package.json",
"chars": 672,
"preview": "{\n \"name\": \"client-cli-example\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"scripts\": {\n \"start\": \"tsx src/index.ts"
},
{
"path": "apps/client-cli-example/src/agent.ts",
"chars": 1411,
"preview": "import { Agent } from \"@mastra/core/agent\";\nimport { MastraAgent } from \"@ag-ui/mastra\";\nimport { Memory } from \"@mastra"
},
{
"path": "apps/client-cli-example/src/index.ts",
"chars": 2022,
"preview": "import * as readline from \"readline\";\nimport { randomUUID } from \"@ag-ui/client\";\nimport { agent } from \"./agent\";\n\ncons"
},
{
"path": "apps/client-cli-example/src/tools/browser.tool.ts",
"chars": 404,
"preview": "import { createTool } from \"@mastra/core/tools\";\nimport { z } from \"zod\";\nimport open from \"open\";\n\nexport const browser"
},
{
"path": "apps/client-cli-example/src/tools/weather.tool.ts",
"chars": 2997,
"preview": "import { createTool } from \"@mastra/core/tools\";\nimport { z } from \"zod\";\n\ninterface GeocodingResponse {\n results: {\n "
},
{
"path": "apps/client-cli-example/tsconfig.json",
"chars": 408,
"preview": "{\n \"compilerOptions\": {\n \"target\": \"ES2020\",\n \"module\": \"commonjs\",\n \"lib\": [\"ES2020\", \"dom\"],\n \"outDir\": \""
},
{
"path": "apps/dojo/.gitignore",
"chars": 2201,
"preview": "next-env.d.ts\n\n# Logs\nlogs\n*.log\nnpm-debug.log*\nyarn-debug.log*\nyarn-error.log*\nlerna-debug.log*\n\n# Diagnostic reports ("
},
{
"path": "apps/dojo/LICENSE",
"chars": 1087,
"preview": "Copyright (c) 2025 Tawkit Inc.\nCopyright (c) 2025 Markus Ecker\n\nPermission is hereby granted, free of charge, to any per"
},
{
"path": "apps/dojo/README.md",
"chars": 4383,
"preview": "# AG-UI Protocol Dojo\n\nA modern, interactive viewer for exploring CopilotKit agent demos with a clean, responsive UI and"
},
{
"path": "apps/dojo/components.json",
"chars": 469,
"preview": "{\n \"$schema\": \"https://ui.shadcn.com/schema.json\",\n \"style\": \"new-york\",\n \"rsc\": true,\n \"tsx\": true,\n \"tailwind\": {"
},
{
"path": "apps/dojo/e2e/.gitignore",
"chars": 32,
"preview": "playwright-report/\ntest-results/"
},
{
"path": "apps/dojo/e2e/README.md",
"chars": 1033,
"preview": "# CopilotKit Demo Smoke Tests\n\nThis repository houses Playwright-based smoke tests that run on a 6-hour schedule to make"
},
{
"path": "apps/dojo/e2e/VIDEO_SETUP.md",
"chars": 4454,
"preview": "# 📹 S3 Video Upload System\n\nThis system automatically uploads videos of failed Playwright tests to S3 and embeds clickab"
},
{
"path": "apps/dojo/e2e/clean-reporter.cjs",
"chars": 3692,
"preview": "function getTimestamp() {\n return (process.env.CI || process.env.VERBOSE)\n ? new Date().toLocaleTimeString('en-US', "
},
{
"path": "apps/dojo/e2e/featurePages/AgenticChatPage.ts",
"chars": 3521,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\nimport { CopilotSelectors } from \"../utils/copilot-selectors\";"
},
{
"path": "apps/dojo/e2e/featurePages/HumanInTheLoopPage.ts",
"chars": 3809,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\nimport { CopilotSelectors } from \"../utils/copilot-selectors\";"
},
{
"path": "apps/dojo/e2e/featurePages/SharedStatePage.ts",
"chars": 2987,
"preview": "import { Page, Locator, expect } from '@playwright/test';\nimport { CopilotSelectors } from '../utils/copilot-selectors';"
},
{
"path": "apps/dojo/e2e/featurePages/ToolBaseGenUIPage.ts",
"chars": 5403,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\nimport { CopilotSelectors } from \"../utils/copilot-selectors\";"
},
{
"path": "apps/dojo/e2e/featurePages/V1AgenticChatPage.ts",
"chars": 2319,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\n\n/**\n * Page object for v1 CopilotKit chat UI.\n *\n * V1 uses C"
},
{
"path": "apps/dojo/e2e/fixtures/openai/agentic-chat.json",
"chars": 3016,
"preview": "{\n \"fixtures\": [\n {\n \"match\": { \"userMessage\": \"I am duaa\" },\n \"response\": { \"content\": \"Hello duaa! How c"
},
{
"path": "apps/dojo/e2e/fixtures/openai/agentic-gen-ui.json",
"chars": 1473,
"preview": "{\n \"fixtures\": [\n {\n \"match\": { \"userMessage\": \"plan to make brownies\" },\n \"response\": {\n \"toolCall"
},
{
"path": "apps/dojo/e2e/fixtures/openai/backend-tool-rendering.json",
"chars": 761,
"preview": "{\n \"fixtures\": [\n {\n \"match\": { \"userMessage\": \"Weather in San Francisco\" },\n \"response\": {\n \"toolC"
},
{
"path": "apps/dojo/e2e/fixtures/openai/human-in-the-loop.json",
"chars": 1549,
"preview": "{\n \"fixtures\": [\n {\n \"match\": { \"userMessage\": \"one step with eggs\" },\n \"response\": {\n \"toolCalls\":"
},
{
"path": "apps/dojo/e2e/fixtures/openai/predictive-state.json",
"chars": 1327,
"preview": "{\n \"fixtures\": [\n {\n \"match\": { \"userMessage\": \"dragon called Atlantis\" },\n \"response\": {\n \"toolCal"
},
{
"path": "apps/dojo/e2e/fixtures/openai/shared-state.json",
"chars": 1180,
"preview": "{\n \"fixtures\": [\n {\n \"match\": { \"userMessage\": \"pasta recipe\" },\n \"response\": {\n \"toolCalls\": [\n "
},
{
"path": "apps/dojo/e2e/fixtures/openai/subgraphs.json",
"chars": 21,
"preview": "{\n \"fixtures\": []\n}\n"
},
{
"path": "apps/dojo/e2e/fixtures/openai/tool-based-gen-ui.json",
"chars": 1055,
"preview": "{\n \"fixtures\": [\n {\n \"match\": { \"userMessage\": \"I will always win\" },\n \"response\": {\n \"toolCalls\": "
},
{
"path": "apps/dojo/e2e/fixtures/openai/v1-chat.json",
"chars": 147,
"preview": "{\n \"fixtures\": [\n {\n \"match\": { \"userMessage\": \"Hello\" },\n \"response\": { \"content\": \"Hello! How can I help"
},
{
"path": "apps/dojo/e2e/lib/constants.ts",
"chars": 297,
"preview": "/**\n * The default welcome message shown by CopilotChat/CopilotSidebar when no\n * custom `welcomeMessageText` label is p"
},
{
"path": "apps/dojo/e2e/lib/mock-agent.ts",
"chars": 8537,
"preview": "import { Page, Route } from \"@playwright/test\";\n\n/**\n * Deterministic mock agent for Playwright e2e tests.\n *\n * Interce"
},
{
"path": "apps/dojo/e2e/lib/upload-video.ts",
"chars": 5177,
"preview": "import { S3Client, PutObjectCommand } from \"@aws-sdk/client-s3\";\nimport { readFileSync, existsSync } from \"fs\";\nimport {"
},
{
"path": "apps/dojo/e2e/llmock-setup.ts",
"chars": 27445,
"preview": "import { LLMock, type ChatMessage } from \"@copilotkit/llmock\";\nimport * as path from \"node:path\";\n\nconst MOCK_PORT = 555"
},
{
"path": "apps/dojo/e2e/package.json",
"chars": 606,
"preview": "{\n \"name\": \"copilotkit-e2e\",\n \"version\": \"0.1.0\",\n \"private\": true,\n \"type\": \"module\",\n \"description\": \"Scheduled P"
},
{
"path": "apps/dojo/e2e/pages/a2aMiddlewarePages/A2AChatPage.ts",
"chars": 343,
"preview": "import { Page, Locator, expect } from '@playwright/test';\n\nexport class A2AChatPage {\n readonly page: Page;\n readonly "
},
{
"path": "apps/dojo/e2e/pages/adkMiddlewarePages/HumanInLoopPage.ts",
"chars": 3815,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\nimport { CopilotSelectors } from \"../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/adkMiddlewarePages/PredictiveStateUpdatesPage.ts",
"chars": 3689,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\nimport { CopilotSelectors } from \"../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/agnoPages/HumanInLoopPage.ts",
"chars": 3815,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\nimport { CopilotSelectors } from \"../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/awsStrandsPages/AgenticUIGenPage.ts",
"chars": 2113,
"preview": "import { Page, Locator, expect } from '@playwright/test';\nimport { CopilotSelectors } from '../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/awsStrandsPages/HumanInLoopPage.ts",
"chars": 3815,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\nimport { CopilotSelectors } from \"../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/crewAIPages/AgenticUIGenPage.ts",
"chars": 2113,
"preview": "import { Page, Locator, expect } from '@playwright/test';\nimport { CopilotSelectors } from '../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/crewAIPages/HumanInLoopPage.ts",
"chars": 3815,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\nimport { CopilotSelectors } from \"../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/crewAIPages/PredictiveStateUpdatesPage.ts",
"chars": 3531,
"preview": "import { Page, Locator, expect } from '@playwright/test';\nimport { CopilotSelectors } from '../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/langGraphFastAPIPages/AgenticUIGenPage.ts",
"chars": 2113,
"preview": "import { Page, Locator, expect } from '@playwright/test';\nimport { CopilotSelectors } from '../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/langGraphFastAPIPages/HumanInLoopPage.ts",
"chars": 3790,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\nimport { CopilotSelectors } from \"../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/langGraphFastAPIPages/PredictiveStateUpdatesPage.ts",
"chars": 3586,
"preview": "import { Page, Locator, expect } from '@playwright/test';\nimport { CopilotSelectors } from '../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/langGraphFastAPIPages/SubgraphsPage.ts",
"chars": 63,
"preview": "export { SubgraphsPage } from '../langGraphPages/SubgraphsPage'"
},
{
"path": "apps/dojo/e2e/pages/langGraphPages/AgenticUIGenPage.ts",
"chars": 2139,
"preview": "import { Page, Locator, expect } from '@playwright/test';\nimport { CopilotSelectors } from '../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/langGraphPages/HumanInLoopPage.ts",
"chars": 3836,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\nimport { CopilotSelectors } from \"../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/langGraphPages/PredictiveStateUpdatesPage.ts",
"chars": 3586,
"preview": "import { Page, Locator, expect } from '@playwright/test';\nimport { CopilotSelectors } from '../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/langGraphPages/SubgraphsPage.ts",
"chars": 7094,
"preview": "import { Page, Locator, expect } from '@playwright/test';\nimport { CopilotSelectors } from '../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/langroidPages/AgenticUIGenPage.ts",
"chars": 2142,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\nimport { CopilotSelectors } from \"../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/llamaIndexPages/AgenticUIGenPage.ts",
"chars": 2113,
"preview": "import { Page, Locator, expect } from '@playwright/test';\nimport { CopilotSelectors } from '../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/llamaIndexPages/HumanInLoopPage.ts",
"chars": 3815,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\nimport { CopilotSelectors } from \"../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/pydanticAIPages/AgenticUIGenPage.ts",
"chars": 2564,
"preview": "import { Page, Locator, expect } from '@playwright/test';\nimport { CopilotSelectors } from '../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/pydanticAIPages/HumanInLoopPage.ts",
"chars": 3815,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\nimport { CopilotSelectors } from \"../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/pydanticAIPages/PredictiveStateUpdatesPage.ts",
"chars": 3552,
"preview": "import { Page, Locator, expect } from '@playwright/test';\nimport { CopilotSelectors } from '../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/serverStarterAllFeaturesPages/AgenticUIGenPage.ts",
"chars": 2113,
"preview": "import { Page, Locator, expect } from '@playwright/test';\nimport { CopilotSelectors } from '../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/serverStarterAllFeaturesPages/HumanInLoopPage.ts",
"chars": 3815,
"preview": "import { Page, Locator, expect } from \"@playwright/test\";\nimport { CopilotSelectors } from \"../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/pages/serverStarterAllFeaturesPages/PredictiveStateUpdatesPage.ts",
"chars": 3916,
"preview": "import { Page, Locator, expect } from '@playwright/test';\nimport { CopilotSelectors } from '../../utils/copilot-selector"
},
{
"path": "apps/dojo/e2e/playwright.config.ts",
"chars": 2785,
"preview": "import { defineConfig, devices, ReporterDescription } from \"@playwright/test\";\nimport { generateSimpleLayout } from \"./s"
},
{
"path": "apps/dojo/e2e/pnpm-workspace.yaml",
"chars": 17,
"preview": "packages:\n - '.'"
},
{
"path": "apps/dojo/e2e/reporters/s3-video-reporter.ts",
"chars": 6748,
"preview": "import {\n FullConfig,\n FullResult,\n Reporter,\n Suite,\n TestCase,\n TestResult,\n TestStep,\n} from \"@playwright/test"
},
{
"path": "apps/dojo/e2e/setup-aws.sh",
"chars": 5636,
"preview": "#!/bin/bash\n\n# AWS S3 Video Upload Setup Script\n# This script creates the necessary AWS infrastructure for Playwright vi"
},
{
"path": "apps/dojo/e2e/slack-layout-simple.ts",
"chars": 1730,
"preview": "import { Block, KnownBlock } from \"@slack/types\";\nimport { SummaryResults } from \"playwright-slack-report/dist/src\";\nimp"
},
{
"path": "apps/dojo/e2e/slack-layout.ts",
"chars": 7544,
"preview": "import { Block, KnownBlock } from \"@slack/types\";\nimport { SummaryResults } from \"playwright-slack-report/dist/src\";\nimp"
},
{
"path": "apps/dojo/e2e/test-isolation-helper.ts",
"chars": 9155,
"preview": "import { test as base, Page } from \"@playwright/test\";\nimport { awaitLLMResponseDone } from \"./utils/copilot-actions\";\n\n"
},
{
"path": "apps/dojo/e2e/test-isolation-setup.ts",
"chars": 1203,
"preview": "import { chromium, FullConfig } from \"@playwright/test\";\nimport { setupLLMock } from \"./llmock-setup\";\n\nasync function g"
},
{
"path": "apps/dojo/e2e/test-isolation-teardown.ts",
"chars": 144,
"preview": "import { teardownLLMock } from \"./llmock-setup\";\n\nasync function globalTeardown() {\n await teardownLLMock();\n}\n\nexport "
},
{
"path": "apps/dojo/e2e/tests/a2aMiddlewareTests/a2aChatPage.spec.ts",
"chars": 1066,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { A2AChatPage } from \"../../pages/a2aMiddlewarePages/"
},
{
"path": "apps/dojo/e2e/tests/adkMiddlewareTests/agenticChatPage.spec.ts",
"chars": 2991,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/adkMiddlewareTests/backendToolRenderingPage.spec.ts",
"chars": 1889,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { awaitLLMResponseDone } from \"../../utils/copilot-ac"
},
{
"path": "apps/dojo/e2e/tests/adkMiddlewareTests/humanInTheLoopPage.spec.ts",
"chars": 2011,
"preview": "import { awaitLLMResponseDone } from \"../../utils/copilot-actions\";\nimport { test, expect } from \"../../test-isolation-h"
},
{
"path": "apps/dojo/e2e/tests/adkMiddlewareTests/predictiveStateUpdatePage.spec.ts",
"chars": 2851,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { PredictiveStateUpdatesPage } from \"../../pages/adkM"
},
{
"path": "apps/dojo/e2e/tests/adkMiddlewareTests/sharedStatePage.spec.ts",
"chars": 2080,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { SharedStatePage } from \"../../featurePages/SharedSt"
},
{
"path": "apps/dojo/e2e/tests/adkMiddlewareTests/toolBasedGenUIPage.spec.ts",
"chars": 1425,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { ToolBaseGenUIPage } from \"../../featurePages/ToolBa"
},
{
"path": "apps/dojo/e2e/tests/adkMiddlewareTests/v1AgenticChatPage.spec.ts",
"chars": 468,
"preview": "import { test } from \"../../test-isolation-helper\";\nimport { V1AgenticChatPage } from \"../../featurePages/V1AgenticChatP"
},
{
"path": "apps/dojo/e2e/tests/agnoTests/agenticChatPage.spec.ts",
"chars": 3533,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/agnoTests/backendToolRenderingPage.spec.ts",
"chars": 1869,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { awaitLLMResponseDone } from \"../../utils/copilot-ac"
},
{
"path": "apps/dojo/e2e/tests/agnoTests/humanInTheLoopPage.spec.ts",
"chars": 1790,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { HumanInLoopPage } from \"../../pages/agnoPages/Human"
},
{
"path": "apps/dojo/e2e/tests/agnoTests/toolBasedGenUIPage.spec.ts",
"chars": 1280,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { ToolBaseGenUIPage } from \"../../featurePages/ToolBa"
},
{
"path": "apps/dojo/e2e/tests/agnoTests/v1AgenticChatPage.spec.ts",
"chars": 452,
"preview": "import { test } from \"../../test-isolation-helper\";\nimport { V1AgenticChatPage } from \"../../featurePages/V1AgenticChatP"
},
{
"path": "apps/dojo/e2e/tests/awsStrandsTests/agenticChatPage.spec.ts",
"chars": 3006,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/awsStrandsTests/agenticGenUI.spec.ts",
"chars": 1390,
"preview": "import { awaitLLMResponseDone } from \"../../utils/copilot-actions\";\nimport { test, expect } from \"../../test-isolation-h"
},
{
"path": "apps/dojo/e2e/tests/awsStrandsTests/backendToolRenderingPage.spec.ts",
"chars": 1904,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\n\ntest(\"[Strands] Backend Tool Rendering displays weather car"
},
{
"path": "apps/dojo/e2e/tests/awsStrandsTests/humanInTheLoopPage.spec.ts",
"chars": 1816,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { HumanInLoopPage } from \"../../pages/awsStrandsPages"
},
{
"path": "apps/dojo/e2e/tests/awsStrandsTests/sharedStatePage.spec.ts",
"chars": 2108,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { SharedStatePage } from \"../../featurePages/SharedSt"
},
{
"path": "apps/dojo/e2e/tests/awsStrandsTests/v1AgenticChatPage.spec.ts",
"chars": 466,
"preview": "import { test } from \"../../test-isolation-helper\";\nimport { V1AgenticChatPage } from \"../../featurePages/V1AgenticChatP"
},
{
"path": "apps/dojo/e2e/tests/claudeAgentSdkPythonTests/agenticChatPage.spec.ts",
"chars": 2296,
"preview": "import { test } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticChatPage\""
},
{
"path": "apps/dojo/e2e/tests/claudeAgentSdkPythonTests/backendToolRenderingPage.spec.ts",
"chars": 1796,
"preview": "import { test, expect } from \"@playwright/test\";\n\ntest(\"[Claude Agent SDK Python] Backend Tool Rendering displays weathe"
},
{
"path": "apps/dojo/e2e/tests/claudeAgentSdkPythonTests/humanInTheLoopPage.spec.ts",
"chars": 2021,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { awaitLLMResponseDone } from \"../../utils/copilot-ac"
},
{
"path": "apps/dojo/e2e/tests/claudeAgentSdkPythonTests/sharedStatePage.spec.ts",
"chars": 2440,
"preview": "import { test, expect } from \"@playwright/test\";\nimport { SharedStatePage } from \"../../featurePages/SharedStatePage\";\n\n"
},
{
"path": "apps/dojo/e2e/tests/claudeAgentSdkPythonTests/toolBasedGenUIPage.spec.ts",
"chars": 1368,
"preview": "import { test, expect } from \"@playwright/test\";\nimport { ToolBaseGenUIPage } from \"../../featurePages/ToolBaseGenUIPage"
},
{
"path": "apps/dojo/e2e/tests/claudeAgentSdkTypescriptTests/agenticChatPage.spec.ts",
"chars": 2320,
"preview": "import { test } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticChatPage\""
},
{
"path": "apps/dojo/e2e/tests/claudeAgentSdkTypescriptTests/backendToolRenderingPage.spec.ts",
"chars": 1812,
"preview": "import { test, expect } from \"@playwright/test\";\n\ntest(\"[Claude Agent SDK TypeScript] Backend Tool Rendering displays we"
},
{
"path": "apps/dojo/e2e/tests/claudeAgentSdkTypescriptTests/humanInTheLoopPage.spec.ts",
"chars": 2037,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { awaitLLMResponseDone } from \"../../utils/copilot-ac"
},
{
"path": "apps/dojo/e2e/tests/claudeAgentSdkTypescriptTests/sharedStatePage.spec.ts",
"chars": 2456,
"preview": "import { test, expect } from \"@playwright/test\";\nimport { SharedStatePage } from \"../../featurePages/SharedStatePage\";\n\n"
},
{
"path": "apps/dojo/e2e/tests/claudeAgentSdkTypescriptTests/toolBasedGenUIPage.spec.ts",
"chars": 1380,
"preview": "import { test, expect } from \"@playwright/test\";\nimport { ToolBaseGenUIPage } from \"../../featurePages/ToolBaseGenUIPage"
},
{
"path": "apps/dojo/e2e/tests/crewAITests/agenticChatPage.spec.ts",
"chars": 2874,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/crewAITests/agenticGenUI.spec.ts",
"chars": 1421,
"preview": "import { awaitLLMResponseDone } from \"../../utils/copilot-actions\";\nimport { test, expect } from \"../../test-isolation-h"
},
{
"path": "apps/dojo/e2e/tests/crewAITests/humanInTheLoopPage.spec.ts",
"chars": 1820,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { HumanInLoopPage } from \"../../pages/crewAIPages/Hum"
},
{
"path": "apps/dojo/e2e/tests/crewAITests/predictiveStateUpdatePage.spec.ts",
"chars": 2742,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { PredictiveStateUpdatesPage } from \"../../pages/crew"
},
{
"path": "apps/dojo/e2e/tests/crewAITests/sharedStatePage.spec.ts",
"chars": 2039,
"preview": "import { test, expect } from \"@playwright/test\";\nimport { SharedStatePage } from \"../../featurePages/SharedStatePage\";\n\n"
},
{
"path": "apps/dojo/e2e/tests/crewAITests/toolBasedGenUIPage.spec.ts",
"chars": 1279,
"preview": "import { test, expect } from \"@playwright/test\";\nimport { ToolBaseGenUIPage } from \"../../featurePages/ToolBaseGenUIPage"
},
{
"path": "apps/dojo/e2e/tests/crewAITests/v1AgenticChatPage.spec.ts",
"chars": 446,
"preview": "import { test } from \"../../test-isolation-helper\";\nimport { V1AgenticChatPage } from \"../../featurePages/V1AgenticChatP"
},
{
"path": "apps/dojo/e2e/tests/langchainTests/agenticChatPage.spec.ts",
"chars": 2895,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/langchainTests/toolBasedGenUIPage.spec.ts",
"chars": 1215,
"preview": "import { test, expect } from \"@playwright/test\";\nimport { ToolBaseGenUIPage } from \"../../featurePages/ToolBaseGenUIPage"
},
{
"path": "apps/dojo/e2e/tests/langgraphFastAPITests/agenticChatPage.spec.ts",
"chars": 4351,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/langgraphFastAPITests/agenticGenUI.spec.ts",
"chars": 1430,
"preview": "import { awaitLLMResponseDone } from \"../../utils/copilot-actions\";\nimport { test, expect } from \"../../test-isolation-h"
},
{
"path": "apps/dojo/e2e/tests/langgraphFastAPITests/backendToolRenderingPage.spec.ts",
"chars": 1894,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { awaitLLMResponseDone } from \"../../utils/copilot-ac"
},
{
"path": "apps/dojo/e2e/tests/langgraphFastAPITests/humanInTheLoopPage.spec.ts",
"chars": 1874,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { HumanInLoopPage } from \"../../pages/langGraphFastAP"
},
{
"path": "apps/dojo/e2e/tests/langgraphFastAPITests/predictiveStateUpdatePage.spec.ts",
"chars": 2634,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { PredictiveStateUpdatesPage } from \"../../pages/lang"
},
{
"path": "apps/dojo/e2e/tests/langgraphFastAPITests/sharedStatePage.spec.ts",
"chars": 2207,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { SharedStatePage } from \"../../featurePages/SharedSt"
},
{
"path": "apps/dojo/e2e/tests/langgraphFastAPITests/subgraphsPage.spec.ts",
"chars": 6521,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { SubgraphsPage } from \"../../pages/langGraphPages/Su"
},
{
"path": "apps/dojo/e2e/tests/langgraphFastAPITests/toolBasedGenUIPage.spec.ts",
"chars": 1249,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { ToolBaseGenUIPage } from \"../../featurePages/ToolBa"
},
{
"path": "apps/dojo/e2e/tests/langgraphFastAPITests/v1AgenticChatPage.spec.ts",
"chars": 471,
"preview": "import { test } from \"../../test-isolation-helper\";\nimport { V1AgenticChatPage } from \"../../featurePages/V1AgenticChatP"
},
{
"path": "apps/dojo/e2e/tests/langgraphPythonTests/agenticChatPage.spec.ts",
"chars": 4287,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/langgraphPythonTests/agenticGenUI.spec.ts",
"chars": 1391,
"preview": "import { awaitLLMResponseDone } from \"../../utils/copilot-actions\";\nimport { test, expect } from \"../../test-isolation-h"
},
{
"path": "apps/dojo/e2e/tests/langgraphPythonTests/backendToolRenderingPage.spec.ts",
"chars": 1877,
"preview": "import { test, expect } from \"@playwright/test\";\n\ntest(\"[LanggraphPython] Backend Tool Rendering displays weather cards\""
},
{
"path": "apps/dojo/e2e/tests/langgraphPythonTests/humanInTheLoopPage.spec.ts",
"chars": 1823,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { HumanInLoopPage } from \"../../pages/langGraphPages/"
},
{
"path": "apps/dojo/e2e/tests/langgraphPythonTests/predictiveStateUpdatePage.spec.ts",
"chars": 2595,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { PredictiveStateUpdatesPage } from \"../../pages/lang"
},
{
"path": "apps/dojo/e2e/tests/langgraphPythonTests/sharedStatePage.spec.ts",
"chars": 2130,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { SharedStatePage } from \"../../featurePages/SharedSt"
},
{
"path": "apps/dojo/e2e/tests/langgraphPythonTests/subgraphsPage.spec.ts",
"chars": 6397,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { SubgraphsPage } from \"../../pages/langGraphPages/Su"
},
{
"path": "apps/dojo/e2e/tests/langgraphPythonTests/toolBasedGenUIPage.spec.ts",
"chars": 1225,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { ToolBaseGenUIPage } from \"../../featurePages/ToolBa"
},
{
"path": "apps/dojo/e2e/tests/langgraphPythonTests/v1AgenticChatPage.spec.ts",
"chars": 459,
"preview": "import { test } from \"../../test-isolation-helper\";\nimport { V1AgenticChatPage } from \"../../featurePages/V1AgenticChatP"
},
{
"path": "apps/dojo/e2e/tests/langgraphTypescriptTests/agenticChatDeterministic.spec.ts",
"chars": 5994,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/langgraphTypescriptTests/agenticChatPage.spec.ts",
"chars": 4329,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/langgraphTypescriptTests/agenticGenUI.spec.ts",
"chars": 1499,
"preview": "import { awaitLLMResponseDone } from \"../../utils/copilot-actions\";\nimport { test, expect } from \"../../test-isolation-h"
},
{
"path": "apps/dojo/e2e/tests/langgraphTypescriptTests/humanInTheLoopPage.spec.ts",
"chars": 1825,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { HumanInLoopPage } from \"../../pages/langGraphPages/"
},
{
"path": "apps/dojo/e2e/tests/langgraphTypescriptTests/predictiveStateUpdatePage.spec.ts",
"chars": 2915,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { PredictiveStateUpdatesPage } from \"../../pages/lang"
},
{
"path": "apps/dojo/e2e/tests/langgraphTypescriptTests/sharedStatePage.spec.ts",
"chars": 2114,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { SharedStatePage } from \"../../featurePages/SharedSt"
},
{
"path": "apps/dojo/e2e/tests/langgraphTypescriptTests/subgraphsPage.spec.ts",
"chars": 6492,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { SubgraphsPage } from \"../../pages/langGraphPages/Su"
},
{
"path": "apps/dojo/e2e/tests/langgraphTypescriptTests/toolBasedGenUIPage.spec.ts",
"chars": 1236,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { ToolBaseGenUIPage } from \"../../featurePages/ToolBa"
},
{
"path": "apps/dojo/e2e/tests/langgraphTypescriptTests/v1AgenticChatPage.spec.ts",
"chars": 487,
"preview": "import { test } from \"../../test-isolation-helper\";\nimport { V1AgenticChatPage } from \"../../featurePages/V1AgenticChatP"
},
{
"path": "apps/dojo/e2e/tests/langroidTests/agenticChatPage.spec.ts",
"chars": 2894,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/langroidTests/agenticGenUI.spec.ts",
"chars": 1532,
"preview": "import { awaitLLMResponseDone } from \"../../utils/copilot-actions\";\nimport { test, expect } from \"../../test-isolation-h"
},
{
"path": "apps/dojo/e2e/tests/langroidTests/backendToolRenderingPage.spec.ts",
"chars": 1881,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\n\ntest(\"[Langroid] Backend Tool Rendering displays weather ca"
},
{
"path": "apps/dojo/e2e/tests/langroidTests/sharedStatePage.spec.ts",
"chars": 2088,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { SharedStatePage } from \"../../featurePages/SharedSt"
},
{
"path": "apps/dojo/e2e/tests/llamaIndexTests/agenticChatPage.spec.ts",
"chars": 2909,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/llamaIndexTests/agenticGenUI.spec.ts",
"chars": 1544,
"preview": "import { awaitLLMResponseDone } from \"../../utils/copilot-actions\";\nimport { test, expect } from \"../../test-isolation-h"
},
{
"path": "apps/dojo/e2e/tests/llamaIndexTests/backendToolRenderingPage.spec.ts",
"chars": 1874,
"preview": "import { test, expect } from \"@playwright/test\";\n\ntest(\"[LlamaIndex] Backend Tool Rendering displays weather cards\", asy"
},
{
"path": "apps/dojo/e2e/tests/llamaIndexTests/humanInTheLoopPage.spec.ts",
"chars": 1864,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { HumanInLoopPage } from \"../../pages/llamaIndexPages"
},
{
"path": "apps/dojo/e2e/tests/llamaIndexTests/sharedStatePage.spec.ts",
"chars": 2057,
"preview": "import { test, expect } from \"@playwright/test\";\nimport { SharedStatePage } from \"../../featurePages/SharedStatePage\";\n\n"
},
{
"path": "apps/dojo/e2e/tests/llamaIndexTests/v1AgenticChatPage.spec.ts",
"chars": 455,
"preview": "import { test } from \"../../test-isolation-helper\";\nimport { V1AgenticChatPage } from \"../../featurePages/V1AgenticChatP"
},
{
"path": "apps/dojo/e2e/tests/mastraAgentLocalTests/agenticChatPage.spec.ts",
"chars": 3246,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/mastraAgentLocalTests/backendToolRenderingPage.spec.ts",
"chars": 1920,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\n\ntest(\"[MastraAgentLocal] Backend Tool Rendering displays we"
},
{
"path": "apps/dojo/e2e/tests/mastraAgentLocalTests/humanInTheLoopPage.spec.ts",
"chars": 1855,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { HumanInTheLoopPage } from \"../../featurePages/Human"
},
{
"path": "apps/dojo/e2e/tests/mastraAgentLocalTests/sharedStatePage.spec.ts",
"chars": 2124,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { SharedStatePage } from \"../../featurePages/SharedSt"
},
{
"path": "apps/dojo/e2e/tests/mastraAgentLocalTests/toolBasedGenUIPage.spec.ts",
"chars": 1252,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { ToolBaseGenUIPage } from \"../../featurePages/ToolBa"
},
{
"path": "apps/dojo/e2e/tests/mastraAgentLocalTests/v1AgenticChatPage.spec.ts",
"chars": 491,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { V1AgenticChatPage } from \"../../featurePages/V1Agen"
},
{
"path": "apps/dojo/e2e/tests/mastraTests/agenticChatPage.spec.ts",
"chars": 3522,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/mastraTests/backendToolRenderingPage.spec.ts",
"chars": 1865,
"preview": "import { test, expect } from \"@playwright/test\";\n\ntest(\"[Mastra] Backend Tool Rendering displays weather cards\", async ("
},
{
"path": "apps/dojo/e2e/tests/mastraTests/humanInTheLoopPage.spec.ts",
"chars": 1827,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { HumanInTheLoopPage } from \"../../featurePages/Human"
},
{
"path": "apps/dojo/e2e/tests/mastraTests/toolBasedGenUIPage.spec.ts",
"chars": 1355,
"preview": "import { test, expect } from \"@playwright/test\";\nimport { ToolBaseGenUIPage } from \"../../featurePages/ToolBaseGenUIPage"
},
{
"path": "apps/dojo/e2e/tests/mastraTests/v1AgenticChatPage.spec.ts",
"chars": 446,
"preview": "import { test } from \"../../test-isolation-helper\";\nimport { V1AgenticChatPage } from \"../../featurePages/V1AgenticChatP"
},
{
"path": "apps/dojo/e2e/tests/middlewareStarterTests/agenticChatPage.spec.ts",
"chars": 534,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/middlewareStarterTests/v1AgenticChatPage.spec.ts",
"chars": 473,
"preview": "import { test } from \"../../test-isolation-helper\";\nimport { V1AgenticChatPage } from \"../../featurePages/V1AgenticChatP"
},
{
"path": "apps/dojo/e2e/tests/pydanticAITests/agenticChatPage.spec.ts",
"chars": 2904,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/pydanticAITests/agenticGenUI.spec.ts",
"chars": 1404,
"preview": "import { awaitLLMResponseDone } from \"../../utils/copilot-actions\";\nimport { test, expect } from \"../../test-isolation-h"
},
{
"path": "apps/dojo/e2e/tests/pydanticAITests/backendToolRenderingPage.spec.ts",
"chars": 1874,
"preview": "import { test, expect } from \"@playwright/test\";\n\ntest(\"[PydanticAI] Backend Tool Rendering displays weather cards\", asy"
},
{
"path": "apps/dojo/e2e/tests/pydanticAITests/humanInTheLoopPage.spec.ts",
"chars": 1822,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { HumanInLoopPage } from \"../../pages/pydanticAIPages"
},
{
"path": "apps/dojo/e2e/tests/pydanticAITests/predictiveStateUpdatePage.spec.ts",
"chars": 3098,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { PredictiveStateUpdatesPage } from \"../../pages/pyda"
},
{
"path": "apps/dojo/e2e/tests/pydanticAITests/sharedStatePage.spec.ts",
"chars": 1776,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { SharedStatePage } from \"../../featurePages/SharedSt"
},
{
"path": "apps/dojo/e2e/tests/pydanticAITests/toolBasedGenUIPage.spec.ts",
"chars": 1292,
"preview": "import { test, expect } from \"@playwright/test\";\nimport { ToolBaseGenUIPage } from \"../../featurePages/ToolBaseGenUIPage"
},
{
"path": "apps/dojo/e2e/tests/pydanticAITests/v1AgenticChatPage.spec.ts",
"chars": 456,
"preview": "import { test } from \"../../test-isolation-helper\";\nimport { V1AgenticChatPage } from \"../../featurePages/V1AgenticChatP"
},
{
"path": "apps/dojo/e2e/tests/serverStarterAllFeaturesTests/agenticChatPage.spec.ts",
"chars": 1395,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticChatPage } from \"../../featurePages/AgenticC"
},
{
"path": "apps/dojo/e2e/tests/serverStarterAllFeaturesTests/agenticGenUI.spec.ts",
"chars": 858,
"preview": "import { test, expect } from \"../../test-isolation-helper\";\nimport { AgenticGenUIPage } from \"../../pages/serverStarterA"
}
]
// ... and 1636 more files (download for full content)
About this extraction
This page contains the full source code of the ag-ui-protocol/ag-ui GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1836 files (20.9 MB), approximately 3.0M tokens, and a symbol index with 6032 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.