@datalayer/agent-runtimes 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/README.md +35 -119
  2. package/lib/App.js +1 -1
  3. package/lib/agents/AgentDetails.d.ts +22 -1
  4. package/lib/agents/AgentDetails.js +34 -47
  5. package/lib/api/index.d.ts +0 -1
  6. package/lib/api/index.js +4 -2
  7. package/lib/chat/Chat.d.ts +5 -104
  8. package/lib/chat/Chat.js +4 -4
  9. package/lib/chat/ChatFloating.d.ts +7 -140
  10. package/lib/chat/ChatFloating.js +2 -2
  11. package/lib/chat/ChatPopupStandalone.d.ts +8 -47
  12. package/lib/chat/ChatPopupStandalone.js +3 -3
  13. package/lib/chat/ChatSidebar.d.ts +4 -69
  14. package/lib/chat/ChatSidebar.js +2 -2
  15. package/lib/chat/ChatStandalone.d.ts +4 -54
  16. package/lib/chat/ChatStandalone.js +3 -3
  17. package/lib/chat/base/ChatBase.js +1118 -141
  18. package/lib/chat/header/ChatHeaderBase.d.ts +11 -6
  19. package/lib/chat/header/ChatHeaderBase.js +18 -16
  20. package/lib/chat/indicators/McpStatusIndicator.d.ts +7 -4
  21. package/lib/chat/indicators/McpStatusIndicator.js +7 -32
  22. package/lib/chat/indicators/SandboxStatusIndicator.d.ts +4 -1
  23. package/lib/chat/indicators/SandboxStatusIndicator.js +9 -9
  24. package/lib/chat/indicators/SkillsStatusIndicator.d.ts +7 -0
  25. package/lib/chat/indicators/SkillsStatusIndicator.js +88 -0
  26. package/lib/chat/indicators/index.d.ts +1 -0
  27. package/lib/chat/indicators/index.js +1 -0
  28. package/lib/chat/messages/ChatMessageList.d.ts +1 -1
  29. package/lib/chat/messages/ChatMessageList.js +110 -102
  30. package/lib/chat/prompt/InputFooter.d.ts +19 -6
  31. package/lib/chat/prompt/InputFooter.js +71 -18
  32. package/lib/chat/prompt/InputPrompt.d.ts +3 -1
  33. package/lib/chat/prompt/InputPrompt.js +4 -4
  34. package/lib/chat/prompt/InputPromptFooter.js +1 -1
  35. package/lib/chat/prompt/InputPromptLexical.d.ts +3 -1
  36. package/lib/chat/prompt/InputPromptLexical.js +12 -5
  37. package/lib/chat/prompt/InputPromptText.d.ts +3 -1
  38. package/lib/chat/prompt/InputPromptText.js +2 -2
  39. package/lib/chat/tools/ToolApprovalBanner.js +1 -1
  40. package/lib/chat/tools/ToolCallDisplay.d.ts +3 -1
  41. package/lib/chat/tools/ToolCallDisplay.js +2 -2
  42. package/lib/chat/usage/TokenUsageBar.js +20 -2
  43. package/lib/client/AgentRuntimesClientContext.d.ts +53 -0
  44. package/lib/client/AgentRuntimesClientContext.js +55 -0
  45. package/lib/client/AgentsMixin.d.ts +48 -19
  46. package/lib/client/AgentsMixin.js +115 -30
  47. package/lib/client/IAgentRuntimesClient.d.ts +215 -0
  48. package/lib/client/IAgentRuntimesClient.js +5 -0
  49. package/lib/client/SdkAgentRuntimesClient.d.ts +151 -0
  50. package/lib/client/SdkAgentRuntimesClient.js +134 -0
  51. package/lib/client/index.d.ts +4 -1
  52. package/lib/client/index.js +3 -1
  53. package/lib/components/NotificationEventCard.js +55 -26
  54. package/lib/components/OutputCard.js +21 -7
  55. package/lib/components/ToolApprovalCard.js +20 -2
  56. package/lib/config/AgentConfiguration.js +3 -3
  57. package/lib/context/ContextDistribution.d.ts +3 -1
  58. package/lib/context/ContextDistribution.js +8 -27
  59. package/lib/context/ContextInspector.d.ts +3 -1
  60. package/lib/context/ContextInspector.js +19 -67
  61. package/lib/context/ContextPanel.d.ts +3 -1
  62. package/lib/context/ContextPanel.js +104 -64
  63. package/lib/context/ContextUsage.d.ts +3 -1
  64. package/lib/context/ContextUsage.js +3 -3
  65. package/lib/context/CostTracker.d.ts +9 -3
  66. package/lib/context/CostTracker.js +26 -47
  67. package/lib/context/CostUsageChart.d.ts +12 -0
  68. package/lib/context/CostUsageChart.js +378 -0
  69. package/lib/context/GraphFlowChart.d.ts +16 -0
  70. package/lib/context/GraphFlowChart.js +182 -0
  71. package/lib/context/TokenUsageChart.d.ts +8 -1
  72. package/lib/context/TokenUsageChart.js +349 -211
  73. package/lib/context/TurnGraphChart.d.ts +39 -0
  74. package/lib/context/TurnGraphChart.js +538 -0
  75. package/lib/context/otelWsPool.d.ts +20 -0
  76. package/lib/context/otelWsPool.js +69 -0
  77. package/lib/examples/A2UiComponentGalleryExample.d.ts +0 -17
  78. package/lib/examples/A2UiComponentGalleryExample.js +315 -522
  79. package/lib/examples/A2UiContactCardExample.d.ts +0 -18
  80. package/lib/examples/A2UiContactCardExample.js +154 -411
  81. package/lib/examples/A2UiRestaurantExample.d.ts +0 -30
  82. package/lib/examples/A2UiRestaurantExample.js +114 -212
  83. package/lib/examples/A2UiViewerExample.d.ts +0 -18
  84. package/lib/examples/A2UiViewerExample.js +283 -532
  85. package/lib/examples/AgUiBackendToolRenderingExample.js +1 -1
  86. package/lib/examples/AgUiHaikuGenUiExample.d.ts +1 -1
  87. package/lib/examples/AgUiHaikuGenUiExample.js +1 -1
  88. package/lib/examples/AgentCheckpointsExample.js +14 -34
  89. package/lib/examples/AgentCodemodeExample.d.ts +4 -6
  90. package/lib/examples/AgentCodemodeExample.js +591 -175
  91. package/lib/examples/AgentEvalsExample.js +13 -23
  92. package/lib/examples/AgentGuardrailsExample.js +371 -71
  93. package/lib/examples/AgentHooksExample.d.ts +3 -0
  94. package/lib/examples/AgentHooksExample.js +104 -0
  95. package/lib/examples/AgentMCPExample.d.ts +3 -0
  96. package/lib/examples/AgentMCPExample.js +480 -0
  97. package/lib/examples/AgentMemoryExample.js +14 -24
  98. package/lib/examples/AgentMonitoringExample.js +261 -206
  99. package/lib/examples/AgentNotificationsExample.js +50 -24
  100. package/lib/examples/AgentOtelExample.js +2 -3
  101. package/lib/examples/AgentOutputsExample.d.ts +11 -6
  102. package/lib/examples/AgentOutputsExample.js +383 -88
  103. package/lib/examples/AgentParametersExample.d.ts +3 -0
  104. package/lib/examples/AgentParametersExample.js +246 -0
  105. package/lib/examples/AgentSandboxExample.d.ts +2 -2
  106. package/lib/examples/AgentSandboxExample.js +69 -47
  107. package/lib/examples/AgentSkillsExample.js +92 -106
  108. package/lib/examples/{AgentspecExample.js → AgentSpecsExample.js} +10 -21
  109. package/lib/examples/AgentSubagentsExample.d.ts +14 -0
  110. package/lib/examples/AgentSubagentsExample.js +228 -0
  111. package/lib/examples/AgentToolApprovalsExample.js +30 -493
  112. package/lib/examples/AgentTriggersExample.js +1067 -246
  113. package/lib/examples/ChatCustomExample.js +11 -24
  114. package/lib/examples/ChatExample.js +9 -34
  115. package/lib/examples/CopilotKitLexicalExample.js +2 -1
  116. package/lib/examples/CopilotKitNotebookExample.js +2 -1
  117. package/lib/examples/HomeExample.d.ts +15 -0
  118. package/lib/examples/HomeExample.js +77 -0
  119. package/lib/examples/Lexical2Example.js +4 -2
  120. package/lib/examples/{LexicalExample.d.ts → LexicalAgentExample.d.ts} +4 -4
  121. package/lib/examples/{LexicalExample.js → LexicalAgentExample.js} +65 -16
  122. package/lib/examples/{LexicalSidebarExample.d.ts → LexicalAgentSidebarExample.d.ts} +5 -5
  123. package/lib/examples/LexicalAgentSidebarExample.js +261 -0
  124. package/lib/examples/NotebookAgentExample.d.ts +9 -0
  125. package/lib/examples/NotebookAgentExample.js +192 -0
  126. package/lib/examples/{NotebookSidebarExample.d.ts → NotebookAgentSidebarExample.d.ts} +2 -2
  127. package/lib/examples/NotebookAgentSidebarExample.js +221 -0
  128. package/lib/examples/{DatalayerNotebookExample.d.ts → NotebookCollaborationExample.d.ts} +4 -4
  129. package/lib/examples/{DatalayerNotebookExample.js → NotebookCollaborationExample.js} +3 -3
  130. package/lib/examples/NotebookExample.d.ts +4 -7
  131. package/lib/examples/NotebookExample.js +14 -146
  132. package/lib/examples/components/AuthRequiredView.d.ts +6 -0
  133. package/lib/examples/components/AuthRequiredView.js +33 -0
  134. package/lib/examples/components/ErrorView.d.ts +14 -0
  135. package/lib/examples/components/ErrorView.js +20 -0
  136. package/lib/examples/components/ExampleWrapper.d.ts +7 -0
  137. package/lib/examples/components/ExampleWrapper.js +25 -6
  138. package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.js +1 -1
  139. package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.js +1 -1
  140. package/lib/examples/{ag-ui → components}/haiku/index.d.ts +1 -1
  141. package/lib/examples/{ag-ui → components}/haiku/index.js +1 -1
  142. package/lib/examples/components/index.d.ts +5 -0
  143. package/lib/examples/components/index.js +5 -0
  144. package/lib/examples/{ag-ui → components}/weather/index.d.ts +1 -1
  145. package/lib/examples/{ag-ui → components}/weather/index.js +1 -1
  146. package/lib/examples/example-selector.d.ts +17 -4
  147. package/lib/examples/example-selector.js +107 -41
  148. package/lib/examples/index.d.ts +9 -6
  149. package/lib/examples/index.js +9 -6
  150. package/lib/examples/main.d.ts +1 -0
  151. package/lib/examples/main.js +218 -27
  152. package/lib/examples/utils/a2ui.d.ts +18 -0
  153. package/lib/examples/utils/a2ui.js +69 -0
  154. package/lib/examples/utils/a2uiMarkdownProvider.d.ts +7 -0
  155. package/lib/examples/utils/a2uiMarkdownProvider.js +9 -0
  156. package/lib/examples/utils/agentId.d.ts +18 -0
  157. package/lib/examples/utils/agentId.js +54 -0
  158. package/lib/examples/utils/agents/earthquake-detector.json +11 -11
  159. package/lib/examples/utils/agents/sales-forecaster.json +11 -11
  160. package/lib/examples/utils/agents/social-post-generator.json +11 -11
  161. package/lib/examples/utils/agents/stock-market.json +11 -11
  162. package/lib/examples/utils/examplesStore.js +82 -27
  163. package/lib/hooks/index.d.ts +8 -8
  164. package/lib/hooks/index.js +7 -7
  165. package/lib/hooks/useA2A.d.ts +2 -3
  166. package/lib/hooks/useAIAgentsWebSocket.d.ts +43 -4
  167. package/lib/hooks/useAIAgentsWebSocket.js +118 -12
  168. package/lib/hooks/useAcp.d.ts +1 -2
  169. package/lib/hooks/useAgUi.d.ts +1 -1
  170. package/lib/hooks/{useAgents.d.ts → useAgentRuntimes.d.ts} +39 -2
  171. package/lib/hooks/{useAgents.js → useAgentRuntimes.js} +125 -15
  172. package/lib/hooks/useAgentsCatalog.js +1 -1
  173. package/lib/hooks/useAgentsService.d.ts +2 -2
  174. package/lib/hooks/useAgentsService.js +7 -7
  175. package/lib/hooks/useCheckpoints.js +1 -1
  176. package/lib/hooks/useConfig.d.ts +4 -1
  177. package/lib/hooks/useConfig.js +10 -3
  178. package/lib/hooks/useContextSnapshot.d.ts +9 -4
  179. package/lib/hooks/useContextSnapshot.js +9 -37
  180. package/lib/hooks/useMonitoring.js +3 -0
  181. package/lib/hooks/useSandbox.d.ts +20 -8
  182. package/lib/hooks/useSandbox.js +105 -40
  183. package/lib/hooks/useSkills.d.ts +23 -5
  184. package/lib/hooks/useSkills.js +94 -39
  185. package/lib/hooks/useToolApprovals.d.ts +60 -36
  186. package/lib/hooks/useToolApprovals.js +318 -69
  187. package/lib/hooks/useVercelAI.d.ts +1 -1
  188. package/lib/index.d.ts +2 -1
  189. package/lib/index.js +1 -0
  190. package/lib/inference/index.d.ts +0 -1
  191. package/lib/middleware/index.d.ts +0 -1
  192. package/lib/protocols/AGUIAdapter.js +6 -0
  193. package/lib/protocols/VercelAIAdapter.d.ts +9 -0
  194. package/lib/protocols/VercelAIAdapter.js +144 -26
  195. package/lib/shims/json5.d.ts +4 -0
  196. package/lib/shims/json5.js +8 -0
  197. package/lib/specs/agents/agents.d.ts +10 -0
  198. package/lib/specs/agents/agents.js +752 -24
  199. package/lib/specs/envvars.d.ts +1 -0
  200. package/lib/specs/envvars.js +11 -0
  201. package/lib/specs/events.d.ts +1 -0
  202. package/lib/specs/events.js +1 -0
  203. package/lib/specs/index.d.ts +1 -0
  204. package/lib/specs/index.js +1 -0
  205. package/lib/specs/personas.d.ts +41 -0
  206. package/lib/specs/personas.js +168 -0
  207. package/lib/specs/skills.d.ts +2 -1
  208. package/lib/specs/skills.js +23 -5
  209. package/lib/specs/tools.js +3 -0
  210. package/lib/stores/agentRuntimeStore.d.ts +204 -0
  211. package/lib/stores/agentRuntimeStore.js +636 -0
  212. package/lib/stores/index.d.ts +1 -1
  213. package/lib/stores/index.js +1 -1
  214. package/lib/tools/adapters/copilotkit/lexicalHooks.d.ts +1 -2
  215. package/lib/tools/adapters/copilotkit/lexicalHooks.js +1 -3
  216. package/lib/tools/adapters/copilotkit/notebookHooks.d.ts +1 -2
  217. package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -3
  218. package/lib/tools/index.d.ts +0 -2
  219. package/lib/tools/index.js +0 -1
  220. package/lib/types/agentspecs.d.ts +50 -1
  221. package/lib/types/chat.d.ts +309 -8
  222. package/lib/types/context.d.ts +27 -0
  223. package/lib/types/cost.d.ts +2 -2
  224. package/lib/types/index.d.ts +2 -0
  225. package/lib/types/index.js +2 -0
  226. package/lib/types/mcp.d.ts +8 -0
  227. package/lib/types/models.d.ts +2 -2
  228. package/lib/types/personas.d.ts +25 -0
  229. package/lib/types/personas.js +5 -0
  230. package/lib/types/skills.d.ts +43 -1
  231. package/lib/types/stream.d.ts +110 -0
  232. package/lib/types/stream.js +36 -0
  233. package/lib/types/tools.d.ts +2 -0
  234. package/lib/utils/utils.d.ts +9 -5
  235. package/lib/utils/utils.js +9 -5
  236. package/package.json +13 -9
  237. package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
  238. package/scripts/codegen/__pycache__/generate_events.cpython-313.pyc +0 -0
  239. package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
  240. package/scripts/codegen/generate_agents.py +106 -7
  241. package/scripts/codegen/generate_events.py +47 -17
  242. package/scripts/codegen/generate_personas.py +319 -0
  243. package/scripts/codegen/generate_skills.py +9 -9
  244. package/scripts/codegen/generate_tools.py +20 -0
  245. package/scripts/sync-jupyter.sh +26 -7
  246. package/style/primer-primitives.css +1 -6
  247. package/lib/api/tool-approvals.d.ts +0 -62
  248. package/lib/api/tool-approvals.js +0 -145
  249. package/lib/examples/LexicalSidebarExample.js +0 -163
  250. package/lib/examples/NotebookSidebarExample.js +0 -119
  251. package/lib/examples/NotebookSimpleExample.d.ts +0 -6
  252. package/lib/examples/NotebookSimpleExample.js +0 -22
  253. package/lib/examples/ag-ui/index.d.ts +0 -10
  254. package/lib/examples/ag-ui/index.js +0 -16
  255. package/lib/hooks/useAgentsRegistry.d.ts +0 -10
  256. package/lib/hooks/useAgentsRegistry.js +0 -20
  257. package/lib/stores/agentsStore.d.ts +0 -123
  258. package/lib/stores/agentsStore.js +0 -270
  259. package/scripts/codegen/__pycache__/generate_envvars.cpython-313.pyc +0 -0
  260. package/scripts/codegen/__pycache__/generate_evals.cpython-313.pyc +0 -0
  261. package/scripts/codegen/__pycache__/generate_guardrails.cpython-313.pyc +0 -0
  262. package/scripts/codegen/__pycache__/generate_mcp_servers.cpython-313.pyc +0 -0
  263. package/scripts/codegen/__pycache__/generate_memory.cpython-313.pyc +0 -0
  264. package/scripts/codegen/__pycache__/generate_models.cpython-313.pyc +0 -0
  265. package/scripts/codegen/__pycache__/generate_notifications.cpython-313.pyc +0 -0
  266. package/scripts/codegen/__pycache__/generate_outputs.cpython-313.pyc +0 -0
  267. package/scripts/codegen/__pycache__/generate_skills.cpython-313.pyc +0 -0
  268. package/scripts/codegen/__pycache__/generate_teams.cpython-313.pyc +0 -0
  269. package/scripts/codegen/__pycache__/generate_tools.cpython-313.pyc +0 -0
  270. package/scripts/codegen/__pycache__/generate_triggers.cpython-313.pyc +0 -0
  271. /package/lib/examples/{AgentspecExample.d.ts → AgentSpecsExample.d.ts} +0 -0
  272. /package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.d.ts +0 -0
  273. /package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.d.ts +0 -0
  274. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.d.ts +0 -0
  275. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.js +0 -0
package/README.md CHANGED
@@ -30,7 +30,9 @@ Agent Runtimes solves the complexity of deploying AI agents by providing:
30
30
 
31
31
  5. **Tool Ecosystem**: Seamless integration with MCP (Model Context Protocol) tools, custom tools, and built-in utilities for Jupyter notebooks and Lexical documents.
32
32
 
33
- ![Agent Runtimes](https://images.datalayer.io/product/agent-runtimes/agent-runtimes-example-1.gif)
33
+ ![Agent Runtimes Chat Web](https://images.datalayer.io/product/agent-runtimes/agent-runtimes-example-1.gif)
34
+
35
+ ![Agent Runtimes Chat CLI](https://images.datalayer.io/products/codeai/codeai_short_cut.gif)
34
36
 
35
37
  ## 🌟 Features
36
38
 
@@ -53,133 +55,47 @@ Agent Runtimes solves the complexity of deploying AI agents by providing:
53
55
  - 💾 **Persistence**: DBOS support for durable execution
54
56
  - 🔒 **Context Optimization**: LLM context management
55
57
 
56
- ## 🏗️ Architecture
57
-
58
- Agent Runtimes consists of three main components:
59
-
60
- ### 1. Python Server (`agent_runtimes/`)
61
- The backend server that hosts AI agents and handles protocol routing:
62
- - **Agent Adapters**: Unified interface for Pydantic AI, LangChain, and Jupyter AI
63
- - **Protocol Adapters**: Convert between different agent protocols (ACP, AG-UI, Vercel AI, etc.)
64
- - **FastAPI Server**: High-performance async server with automatic API documentation
65
- - **Tool Registry**: Manages and executes tools from various sources (MCP, custom, built-in)
66
-
67
- ### 2. React Components (`src/components/`)
68
- Pre-built UI components for interacting with agents:
69
- - **ChatBase**: Core chat interface with customizable styling
70
- - **ChatSidebar**: Collapsible sidebar for agent interactions
71
- - **ChatFloating**: Floating chat widget for non-intrusive agent access
72
- - **All components support**: Frontend tool execution, markdown rendering, code highlighting, and real-time streaming
73
-
74
- ### 3. Runtime Management (`src/runtime/`)
75
- Cloud runtime lifecycle management with Zustand store:
76
- - **Launch & Connect**: Create new cloud runtimes or connect to existing ones
77
- - **Agent Creation**: Automatically create and configure agents on runtimes
78
- - **State Management**: Track runtime status, agent connections, and errors
79
- - **Hooks**: React hooks for easy integration (`useAgentRuntime`, `useRuntimeStore`)
80
-
81
- ## 🚀 Use Cases
82
-
83
- ### Notebook AI Assistant
84
- Add an AI agent to Jupyter notebooks that can:
85
- - Execute cells, insert code, and modify notebook content
86
- - Explain code and data analysis
87
- - Debug errors and suggest improvements
88
-
89
- ```tsx
90
- import { NotebookAgentsRuntime } from '@datalayer/agent-runtimes';
91
-
92
- <NotebookAgentsRuntime
93
- notebookId={notebookId}
94
- environmentName="python-simple"
95
- runtimeName={runtimeName}
96
- serviceManager={serviceManager}
97
- />
98
- ```
58
+ ## Examples
59
+
60
+ The examples will demonstrate how to use the Agent Runtimes functionality in various scenarios and frameworks.
99
61
 
100
- ### Document Editor AI
101
- Integrate AI into Lexical-based document editors:
102
- - Insert headings, lists, code blocks, and formatted text
103
- - Summarize content and proofread text
104
- - Generate ideas and help with writing
105
-
106
- ```tsx
107
- import { DocumentAgentRuntime } from '@datalayer/agent-runtimes';
108
-
109
- <DocumentAgentRuntime
110
- documentId={documentId}
111
- environmentName="python-simple"
112
- runtimeName={runtimeName}
113
- serviceManager={serviceManager}
114
- />
62
+ ```bash
63
+ make examples
115
64
  ```
116
65
 
117
- ### Custom Agent Deployment
118
- Deploy your own Pydantic AI agent with custom tools:
66
+ On the main page, you’ll find an example gallery (cards) that break things down into practical building blocks:
119
67
 
120
- ```python
121
- from agent_runtimes import AgentRuntimesApp
122
- from pydantic_ai import Agent
68
+ • UX patterns (aka GenUI) with protocols like A2UI and AG-UI
69
+ Interactive or triggered workflows
70
+ Agent Identity and Controls with guardrails, monitoring, tool approvals
71
+ • Programmatic tooling with Sandbox and Codemode for MCP and Skills
72
+ • Outputs and Notifications
73
+ • Real-time collaboration with users, subagents, and multi-agent teams
74
+ • Custom agents built from Agentspecs
75
+ • ...
123
76
 
124
- # Create your agent
125
- agent = Agent(
126
- model='anthropic:claude-sonnet-4-5',
127
- system_prompt='You are a helpful assistant.',
128
- )
77
+ Each of these concerns deserves more than a one-off solution—they need deep, composable, and pluggable implementations.
129
78
 
130
- # Launch the server
131
- app = AgentRuntimesApp()
132
- app.add_agent(agent, name='my-agent', transport='ag-ui')
133
- app.run(port=8000)
134
- ```
79
+ ## Documentation
135
80
 
136
- ## 🧪 Run the examples
81
+ The detailed guides for architecture, use cases, interactive chat, key concepts, and runtime configuration are now in Docusaurus docs:
137
82
 
138
- Run the Codemode + MCP example UI:
83
+ - [Agent Runtimes Overview](https://agent-runtimes.datalayer.tech/)
84
+ - [Integrations](https://agent-runtimes.datalayer.tech/integrations)
85
+ - [Chat](https://agent-runtimes.datalayer.tech/chat)
86
+ - [Transports](https://agent-runtimes.datalayer.tech/transports)
87
+ - [Programmatic Tools](https://agent-runtimes.datalayer.tech/programmatic-tools)
88
+ - [CLI](https://agent-runtimes.datalayer.tech/cli)
89
+
90
+ ## Agentspecs
91
+
92
+ Generated catalogs are produced via:
139
93
 
140
94
  ```bash
141
- cd src/ai/agent-runtimes
142
- EXAMPLE=AgentCodemodeMcpExample npm run dev
95
+ make specs
143
96
  ```
144
97
 
145
- ## 🔧 Key Concepts
146
-
147
- ### Protocols
148
- Agent Runtimes supports multiple protocols for agent communication:
149
-
150
- - **AG-UI**: Lightweight protocol for web UIs (POST-based, Pydantic AI native)
151
- - **ACP**: WebSocket-based Agent Client Protocol for real-time interaction
152
- - **Vercel AI SDK**: Compatible with Vercel's AI SDK streaming
153
- - **MCP-UI**: Model Context Protocol with UI resources
154
- - **A2A**: Agent-to-agent communication protocol
155
-
156
- ### Tools
157
- Tools extend agent capabilities by allowing them to perform actions:
158
-
159
- - **Frontend Tools**: Execute in the browser (notebook editing, document manipulation)
160
- - **MCP Tools**: Tools from Model Context Protocol servers
161
- - **Custom Tools**: Your own Python functions decorated with tool metadata
162
- - **Built-in Tools**: File operations, web search, code execution
163
- - **Code Mode**: Tool discovery includes `output_schema` and `input_examples` for reliable calls; code execution returns `stdout`/`stderr` and a summarized `result`.
164
-
165
- ### Runtime Management
166
- Cloud runtimes provide compute resources for agents:
167
-
168
- ```typescript
169
- import { useAgentRuntime } from '@datalayer/agent-runtimes/lib/runtime';
170
-
171
- const { isReady, endpoint, tools, launchRuntime } = useAgentRuntime({
172
- autoCreateAgent: true,
173
- agentConfig: {
174
- model: 'anthropic:claude-sonnet-4-5',
175
- systemPrompt: 'You are a helpful AI assistant.',
176
- },
177
- });
178
-
179
- // Launch a new runtime
180
- await launchRuntime({
181
- environmentName: 'python-simple',
182
- creditsLimit: 100,
183
- type: 'notebook',
184
- });
185
- ```
98
+ Generation scripts are under [scripts/codegen](https://github.com/datalayer/agent-runtimes/tree/main/scripts/codegen), and outputs are written to:
99
+
100
+ - Python: [agent_runtimes/specs](https://github.com/datalayer/agent-runtimes/tree/main/agent_runtimes/specs)
101
+ - TypeScript: [src/specs](https://github.com/datalayer/agent-runtimes/tree/main/src/specs)
package/lib/App.js CHANGED
@@ -5,7 +5,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
5
5
  */
6
6
  import { useJupyter, JupyterReactTheme } from '@datalayer/jupyter-react';
7
7
  import { JupyterCellExample } from './examples/CellSimpleExample';
8
- import { JupyterNotebookExample } from './examples/NotebookSimpleExample';
8
+ import { JupyterNotebookExample } from './examples/NotebookExample';
9
9
  import './App.css';
10
10
  export function App() {
11
11
  const { serviceManager } = useJupyter({
@@ -3,7 +3,10 @@
3
3
  * including name, protocol, URL, message count, and context details.
4
4
  */
5
5
  import type { ReactNode } from 'react';
6
+ import { type FullContextResponse } from '../context/ContextInspector';
7
+ import type { ContextSnapshotResponse } from '../context/ContextPanel';
6
8
  import type { OAuthProvider, OAuthProviderConfig, Identity } from '../identity';
9
+ import type { CodemodeStatusData } from '../types/stream';
7
10
  export interface AgentDetailsProps {
8
11
  /** Agent name/title */
9
12
  name?: string;
@@ -39,9 +42,27 @@ export interface AgentDetailsProps {
39
42
  showBackHeader?: boolean;
40
43
  /** Whether to show context usage/history and context snapshot sections (default: true) */
41
44
  showUsage?: boolean;
45
+ /** Live MCP status from WS — bypasses REST polling when provided */
46
+ mcpStatusData?: MCPToolsetsStatus | null;
47
+ /** Live codemode status from WS — bypasses REST polling when provided */
48
+ codemodeStatusData?: CodemodeStatusData | null;
49
+ /** Live context usage snapshot from WS — bypasses REST polling when provided */
50
+ contextSnapshotData?: ContextSnapshotResponse | null;
51
+ /** Live full context from WS — bypasses REST polling when provided */
52
+ fullContextData?: FullContextResponse | null;
53
+ }
54
+ /**
55
+ * MCP toolsets status response
56
+ */
57
+ interface MCPToolsetsStatus {
58
+ initialized: boolean;
59
+ ready_count: number;
60
+ failed_count: number;
61
+ ready_servers: string[];
62
+ failed_servers: Record<string, string>;
42
63
  }
43
64
  /**
44
65
  * AgentDetails component displays comprehensive information about the agent.
45
66
  */
46
- export declare function AgentDetails({ name, icon, emoji, protocol, url, messageCount, agentId, apiBase, identityProviders, onIdentityConnect, onIdentityDisconnect, onBack, showBackHeader, showUsage, }: AgentDetailsProps): import("react/jsx-runtime").JSX.Element;
67
+ export declare function AgentDetails({ name, icon, emoji, protocol, url, messageCount, agentId, apiBase, identityProviders, onIdentityConnect, onIdentityDisconnect, onBack, showBackHeader, showUsage, mcpStatusData, codemodeStatusData, contextSnapshotData, fullContextData, }: AgentDetailsProps): import("react/jsx-runtime").JSX.Element;
47
68
  export default AgentDetails;
@@ -3,10 +3,11 @@ import { ArrowLeftIcon, CheckCircleIcon, XCircleIcon, CodeIcon, BriefcaseIcon, D
3
3
  import { Button, Heading, IconButton, Text, Label, Spinner, ToggleSwitch, } from '@primer/react';
4
4
  import { Box } from '@datalayer/primer-addons';
5
5
  import { AiAgentIcon } from '@datalayer/icons-react';
6
- import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
6
+ import { useQuery, useMutation } from '@tanstack/react-query';
7
7
  import { ContextPanel } from '../context/ContextPanel';
8
8
  import { ContextInspector, } from '../context/ContextInspector';
9
9
  import { AgentIdentity } from '../identity/AgentIdentity';
10
+ import { useAgentRuntimeCodemodeStatus, useAgentRuntimeContextSnapshot, useAgentRuntimeFullContext, useAgentRuntimeMcpStatus, useAgentRuntimeWsState, } from '../stores';
10
11
  /**
11
12
  * Get the API base URL for fetching data.
12
13
  * If apiBase prop is provided, use it.
@@ -27,13 +28,11 @@ function getApiBase(apiBase) {
27
28
  /**
28
29
  * Convert context snapshot data to CSV format and trigger download
29
30
  */
30
- async function downloadContextSnapshotAsCSV(agentId, apiBase) {
31
- const base = getApiBase(apiBase);
32
- const response = await fetch(`${base}/api/v1/configure/agents/${encodeURIComponent(agentId)}/full-context`);
33
- if (!response.ok) {
34
- throw new Error('Failed to fetch context snapshot');
31
+ async function downloadContextSnapshotAsCSV(agentId, _apiBase, preloadedData) {
32
+ if (!preloadedData) {
33
+ throw new Error('No context data available for CSV export. Data is delivered via WebSocket.');
35
34
  }
36
- const data = await response.json();
35
+ const data = preloadedData;
37
36
  const rows = [];
38
37
  // Header section
39
38
  rows.push(['Context Snapshot for Agent', data.agentId]);
@@ -165,34 +164,23 @@ async function downloadContextSnapshotAsCSV(agentId, apiBase) {
165
164
  /**
166
165
  * AgentDetails component displays comprehensive information about the agent.
167
166
  */
168
- export function AgentDetails({ name = 'AI Agent', icon, emoji, protocol, url, messageCount, agentId, apiBase, identityProviders, onIdentityConnect, onIdentityDisconnect, onBack, showBackHeader = true, showUsage = true, }) {
169
- const queryClient = useQueryClient();
170
- // Fetch MCP toolsets status
171
- const { data: mcpStatus, isLoading: mcpLoading } = useQuery({
172
- queryKey: ['mcp-toolsets-status', apiBase],
173
- queryFn: async () => {
174
- const base = getApiBase(apiBase);
175
- const response = await fetch(`${base}/api/v1/configure/mcp-toolsets-status`);
176
- if (!response.ok) {
177
- throw new Error('Failed to fetch MCP status');
178
- }
179
- return response.json();
180
- },
181
- refetchInterval: 5000, // Refresh every 5 seconds
182
- });
183
- // Fetch Codemode status
184
- const { data: codemodeStatus, isLoading: codemodeLoading } = useQuery({
185
- queryKey: ['codemode-status', apiBase],
186
- queryFn: async () => {
187
- const base = getApiBase(apiBase);
188
- const response = await fetch(`${base}/api/v1/configure/codemode-status`);
189
- if (!response.ok) {
190
- throw new Error('Failed to fetch Codemode status');
191
- }
192
- return response.json();
193
- },
194
- refetchInterval: 5000, // Refresh every 5 seconds
195
- });
167
+ export function AgentDetails({ name = 'AI Agent', icon, emoji, protocol, url, messageCount, agentId, apiBase, identityProviders, onIdentityConnect, onIdentityDisconnect, onBack, showBackHeader = true, showUsage = true, mcpStatusData, codemodeStatusData, contextSnapshotData, fullContextData, }) {
168
+ const wsMcpStatus = useAgentRuntimeMcpStatus();
169
+ const wsCodemodeStatus = useAgentRuntimeCodemodeStatus();
170
+ const wsContextSnapshot = useAgentRuntimeContextSnapshot();
171
+ const wsFullContext = useAgentRuntimeFullContext();
172
+ const wsState = useAgentRuntimeWsState();
173
+ const mcpStatus = mcpStatusData ?? wsMcpStatus;
174
+ const codemodeStatus = codemodeStatusData ??
175
+ wsCodemodeStatus;
176
+ const resolvedContextSnapshot = contextSnapshotData ??
177
+ wsContextSnapshot;
178
+ const resolvedFullContext = fullContextData ?? wsFullContext;
179
+ const hasMcpLiveData = mcpStatusData !== undefined || wsState !== 'closed';
180
+ const hasCodemodeLiveData = codemodeStatusData !== undefined || wsState !== 'closed';
181
+ // REST polling removed — data comes exclusively via WS `agent.snapshot`.
182
+ const mcpLoading = wsState === 'connecting' && !mcpStatus;
183
+ const codemodeLoading = wsState === 'connecting' && !codemodeStatus;
196
184
  // Mutation to toggle codemode
197
185
  const toggleCodemodeMutation = useMutation({
198
186
  mutationFn: async (enabled) => {
@@ -210,8 +198,7 @@ export function AgentDetails({ name = 'AI Agent', icon, emoji, protocol, url, me
210
198
  return response.json();
211
199
  },
212
200
  onSuccess: () => {
213
- // Invalidate the codemode status query to refetch
214
- queryClient.invalidateQueries({ queryKey: ['codemode-status'] });
201
+ // Status update will arrive via WS `agent.snapshot` push
215
202
  },
216
203
  });
217
204
  // Fetch agent spec (original creation request with separated system prompts)
@@ -330,7 +317,7 @@ export function AgentDetails({ name = 'AI Agent', icon, emoji, protocol, url, me
330
317
  borderRadius: 2,
331
318
  border: '1px solid',
332
319
  borderColor: 'border.default',
333
- }, children: _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(ServerIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', width: 100 }, children: "Variant:" }), _jsx(Label, { variant: agentSpec.sandbox.variant === 'local-jupyter'
320
+ }, children: _jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(ServerIcon, { size: 16 }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', width: 100 }, children: "Variant:" }), _jsx(Label, { variant: agentSpec.sandbox.variant === 'jupyter'
334
321
  ? 'accent'
335
322
  : 'secondary', size: "small", children: agentSpec.sandbox.variant })] }), _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', width: 100, pl: 4 }, children: "Running:" }), agentSpec.sandbox.sandbox_running ? (_jsxs(Box, { sx: {
336
323
  display: 'flex',
@@ -340,7 +327,7 @@ export function AgentDetails({ name = 'AI Agent', icon, emoji, protocol, url, me
340
327
  display: 'flex',
341
328
  alignItems: 'center',
342
329
  gap: 1,
343
- }, children: [_jsx(XCircleIcon, { size: 12, fill: "fg.muted" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No" })] }))] }), agentSpec.sandbox.variant === 'local-jupyter' && (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: {
330
+ }, children: [_jsx(XCircleIcon, { size: 12, fill: "fg.muted" }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No" })] }))] }), agentSpec.sandbox.variant === 'jupyter' && (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: {
344
331
  fontSize: 0,
345
332
  color: 'fg.muted',
346
333
  width: 100,
@@ -424,7 +411,7 @@ export function AgentDetails({ name = 'AI Agent', icon, emoji, protocol, url, me
424
411
  borderRadius: 2,
425
412
  border: '1px solid',
426
413
  borderColor: 'border.default',
427
- }, children: mcpLoading ? (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Loading MCP status..." })] })) : mcpStatus ? (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsx(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: _jsxs(Text, { sx: { fontSize: 1 }, children: [_jsx(Text, { as: "span", sx: { fontWeight: 'semibold' }, children: mcpStatus.ready_count }), ' ', "ready,", ' ', _jsx(Text, { as: "span", sx: { fontWeight: 'semibold' }, children: mcpStatus.failed_count }), ' ', "failed"] }) }), mcpStatus.ready_servers.length > 0 && (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsx(Text, { sx: {
414
+ }, children: !hasMcpLiveData && mcpLoading ? (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Loading MCP status..." })] })) : mcpStatus ? (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 2 }, children: [_jsx(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: _jsxs(Text, { sx: { fontSize: 1 }, children: [_jsx(Text, { as: "span", sx: { fontWeight: 'semibold' }, children: mcpStatus.ready_count }), ' ', "ready,", ' ', _jsx(Text, { as: "span", sx: { fontWeight: 'semibold' }, children: mcpStatus.failed_count }), ' ', "failed"] }) }), mcpStatus.ready_servers.length > 0 && (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 1 }, children: [_jsx(Text, { sx: {
428
415
  fontSize: 0,
429
416
  fontWeight: 'semibold',
430
417
  color: 'fg.muted',
@@ -453,7 +440,7 @@ export function AgentDetails({ name = 'AI Agent', icon, emoji, protocol, url, me
453
440
  pl: 4,
454
441
  whiteSpace: 'pre-wrap',
455
442
  wordBreak: 'break-word',
456
- }, children: error.split('\n')[0] })] }, server)))] }))] })) : (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Failed to load MCP status" })) })] }), _jsxs(Box, { children: [_jsx(Heading, { as: "h4", sx: {
443
+ }, children: error.split('\n')[0] })] }, server)))] }))] })) : hasMcpLiveData ? (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Waiting for MCP status from WebSocket stream..." })) : (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Failed to load MCP status" })) })] }), _jsxs(Box, { children: [_jsx(Heading, { as: "h4", sx: {
457
444
  fontSize: 1,
458
445
  fontWeight: 'semibold',
459
446
  mb: 2,
@@ -464,7 +451,7 @@ export function AgentDetails({ name = 'AI Agent', icon, emoji, protocol, url, me
464
451
  borderRadius: 2,
465
452
  border: '1px solid',
466
453
  borderColor: 'border.default',
467
- }, children: codemodeLoading ? (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Loading Codemode status..." })] })) : codemodeStatus ? (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 3 }, children: [_jsxs(Box, { sx: {
454
+ }, children: !hasCodemodeLiveData && codemodeLoading ? (_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Loading Codemode status..." })] })) : codemodeStatus ? (_jsxs(Box, { sx: { display: 'flex', flexDirection: 'column', gap: 3 }, children: [_jsxs(Box, { sx: {
468
455
  display: 'flex',
469
456
  alignItems: 'center',
470
457
  justifyContent: 'space-between',
@@ -486,9 +473,9 @@ export function AgentDetails({ name = 'AI Agent', icon, emoji, protocol, url, me
486
473
  flexDirection: 'column',
487
474
  gap: 1,
488
475
  pl: 4,
489
- }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', width: 80 }, children: "Variant:" }), _jsx(Label, { variant: codemodeStatus.sandbox.variant === 'local-jupyter'
476
+ }, children: [_jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', width: 80 }, children: "Variant:" }), _jsx(Label, { variant: codemodeStatus.sandbox.variant === 'jupyter'
490
477
  ? 'accent'
491
- : 'secondary', size: "small", children: codemodeStatus.sandbox.variant })] }), codemodeStatus.sandbox.variant === 'local-jupyter' && (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: {
478
+ : 'secondary', size: "small", children: codemodeStatus.sandbox.variant })] }), codemodeStatus.sandbox.variant === 'jupyter' && (_jsxs(_Fragment, { children: [_jsxs(Box, { sx: {
492
479
  display: 'flex',
493
480
  alignItems: 'center',
494
481
  gap: 2,
@@ -573,7 +560,7 @@ export function AgentDetails({ name = 'AI Agent', icon, emoji, protocol, url, me
573
560
  gap: 1,
574
561
  flexWrap: 'wrap',
575
562
  mt: 1,
576
- }, children: codemodeStatus.available_skills.map(skill => (_jsx(Label, { variant: "secondary", size: "small", children: skill.name }, skill.name))) })] })), codemodeStatus.available_skills.length === 0 && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No skills available. Add skills to the skills/ directory." }))] })) : (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Failed to load Codemode status" })) })] }), showUsage && agentId && (_jsx(ContextPanel, { agentId: agentId, apiBase: apiBase, messageCount: messageCount, chartHeight: "200px" })), showUsage && agentId && (_jsxs(Box, { sx: { mt: 3 }, children: [_jsxs(Box, { sx: {
563
+ }, children: codemodeStatus.available_skills.map(skill => (_jsx(Label, { variant: "secondary", size: "small", children: skill.name }, skill.name))) })] })), codemodeStatus.available_skills.length === 0 && (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No CodeMode skills are available for this agent. You can still use MCP tools by selecting MCP servers." }))] })) : hasCodemodeLiveData ? (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Waiting for Codemode status from WebSocket stream..." })) : (_jsx(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: "Failed to load Codemode status" })) })] }), showUsage && agentId && (_jsx(ContextPanel, { agentId: agentId, apiBase: apiBase, liveData: resolvedContextSnapshot, messageCount: messageCount, chartHeight: "200px" })), showUsage && agentId && (_jsxs(Box, { sx: { mt: 3 }, children: [_jsxs(Box, { sx: {
577
564
  display: 'flex',
578
565
  alignItems: 'center',
579
566
  justifyContent: 'space-between',
@@ -582,12 +569,12 @@ export function AgentDetails({ name = 'AI Agent', icon, emoji, protocol, url, me
582
569
  fontSize: 1,
583
570
  fontWeight: 'semibold',
584
571
  color: 'fg.muted',
585
- }, children: "Context Snapshot" }), _jsx(Button, { size: "small", variant: "invisible", leadingVisual: DownloadIcon, onClick: () => downloadContextSnapshotAsCSV(agentId, apiBase), children: "Download" })] }), _jsx(Box, { sx: {
572
+ }, children: "Context Snapshot" }), _jsx(Button, { size: "small", variant: "invisible", leadingVisual: DownloadIcon, onClick: () => downloadContextSnapshotAsCSV(agentId, apiBase, resolvedFullContext), children: "Download" })] }), _jsx(Box, { sx: {
586
573
  p: 3,
587
574
  bg: 'canvas.subtle',
588
575
  borderRadius: 2,
589
576
  border: '1px solid',
590
577
  borderColor: 'border.default',
591
- }, children: _jsx(ContextInspector, { agentId: agentId, apiBase: apiBase }) })] })), _jsx(AgentIdentity, { providers: identityProviders, title: "Connected Accounts", showHeader: true, showDescription: true, description: "OAuth identities connected to this agent. Agents can use these to access external services like GitHub repositories on your behalf.", showExpirationDetails: true, allowReconnect: Boolean(identityProviders), onConnect: onIdentityConnect, onDisconnect: onIdentityDisconnect }), showBackHeader && (_jsx(Box, { sx: { mt: 2 }, children: _jsx(Button, { variant: "primary", onClick: onBack, sx: { width: '100%' }, children: "Back to Chat" }) }))] })] }));
578
+ }, children: _jsx(ContextInspector, { agentId: agentId, apiBase: apiBase, liveData: resolvedFullContext }) })] })), _jsx(AgentIdentity, { providers: identityProviders, title: "Connected Accounts", showHeader: true, showDescription: true, description: "OAuth identities connected to this agent. Agents can use these to access external services like GitHub repositories on your behalf.", showExpirationDetails: true, allowReconnect: Boolean(identityProviders), onConnect: onIdentityConnect, onDisconnect: onIdentityDisconnect }), showBackHeader && (_jsx(Box, { sx: { mt: 2 }, children: _jsx(Button, { variant: "primary", onClick: onBack, sx: { width: '100%' }, children: "Back to Chat" }) }))] })] }));
592
579
  }
593
580
  export default AgentDetails;
@@ -12,4 +12,3 @@ export * as evals from './evals';
12
12
  export * as events from './events';
13
13
  export * as notifications from './notifications';
14
14
  export * as output from './output';
15
- export * as toolApprovals from './tool-approvals';
package/lib/api/index.js CHANGED
@@ -10,11 +10,13 @@
10
10
  *
11
11
  * @module api
12
12
  */
13
- // Agents Service API (agents, tool-approvals, notifications, etc.)
13
+ // Agents Service API (agents, notifications, etc.)
14
+ // Tool approvals are intentionally NOT exposed over REST here — all
15
+ // approval interactions flow over the websocket stream; see
16
+ // `hooks/useToolApprovals` and `components/ToolApprovalBanner`.
14
17
  export * as agents from './agents';
15
18
  export * as context from './context';
16
19
  export * as evals from './evals';
17
20
  export * as events from './events';
18
21
  export * as notifications from './notifications';
19
22
  export * as output from './output';
20
- export * as toolApprovals from './tool-approvals';
@@ -1,11 +1,10 @@
1
- import type { ReactNode } from 'react';
2
1
  import type { OAuthProvider, OAuthProviderConfig, Identity } from '../identity';
3
- import type { Extension, FrontendToolDefinition, McpServerSelection, Protocol, ChatViewMode, ModelConfig, RenderToolResult, Suggestion } from '../types';
2
+ import type { ChatCommonProps, Extension, Protocol } from '../types';
4
3
  /**
5
- * Chat props
4
+ * Chat props — extends ChatCommonProps with transport-specific configuration.
6
5
  */
7
- export interface ChatProps {
8
- /** Transport to use */
6
+ export interface ChatProps extends ChatCommonProps {
7
+ /** Transport to use — REQUIRED (narrows protocol to string enum) */
9
8
  protocol: Protocol;
10
9
  /** Extensions for chat features */
11
10
  extensions?: Extension[];
@@ -15,14 +14,6 @@ export interface ChatProps {
15
14
  wsUrl?: string;
16
15
  /** Agent ID */
17
16
  agentId?: string;
18
- /** Authentication token (JWT) to send as Authorization Bearer header */
19
- authToken?: string;
20
- /** Custom placeholder text */
21
- placeholder?: string;
22
- /** Custom title */
23
- title?: string;
24
- /** Brand icon shown in chat header/empty state and details title */
25
- brandIcon?: ReactNode;
26
17
  /** Whether to auto-connect on mount */
27
18
  autoConnect?: boolean;
28
19
  /** Whether to use streaming (for protocols that support it) */
@@ -37,55 +28,10 @@ export interface ChatProps {
37
28
  onLogout?: () => void;
38
29
  /** Callback when collapse panel is clicked */
39
30
  onCollapsePanel?: () => void;
40
- /** Custom styles */
41
- className?: string;
42
31
  /** Height of the chat container */
43
32
  height?: string | number;
44
- /** Show header with connection status */
45
- showHeader?: boolean;
46
- /** Show the new chat (+) button in the header */
47
- showNewChatButton?: boolean;
48
- /** Show the clear chat button in the header */
49
- showClearButton?: boolean;
50
- /** Show model selector (fetched from /configure endpoint) */
51
- showModelSelector?: boolean;
52
- /** Show tools menu (fetched from /configure endpoint) */
53
- showToolsMenu?: boolean;
54
- /** Show skills menu (fetched from /skills endpoint) */
55
- showSkillsMenu?: boolean;
56
- /** Indicate tools are accessed via Codemode meta-tools */
57
- codemodeEnabled?: boolean;
58
- /**
59
- * Show token usage bar between input and selectors.
60
- * @default true
61
- */
62
- showTokenUsage?: boolean;
63
- /** Initial model ID to select (e.g., 'openai:gpt-4o-mini') */
64
- initialModel?: string;
65
- /**
66
- * Override the list of available models.
67
- * When provided, this list replaces the models returned by the config endpoint.
68
- * Use this to restrict the model selector to a specific subset of models.
69
- */
70
- availableModels?: ModelConfig[];
71
- /** MCP server selections to enable (others will be disabled) */
72
- mcpServers?: McpServerSelection[];
73
- /** Initial skill IDs to enable */
74
- initialSkills?: string[];
75
33
  /** Clear messages when component mounts or agentId changes */
76
34
  clearOnMount?: boolean;
77
- /** Suggestions to show in empty state */
78
- suggestions?: Suggestion[];
79
- /** Whether to automatically submit the message when a suggestion is clicked */
80
- submitOnSuggestionClick?: boolean;
81
- /** Description shown in empty state */
82
- description?: string;
83
- /** Custom content to render in the chat header title row (left side). */
84
- headerContent?: ReactNode;
85
- /** Custom actions to render in the chat header title row (right side). */
86
- headerActions?: ReactNode;
87
- /** Auto-focus the input on mount */
88
- autoFocus?: boolean;
89
35
  /** Identity providers configuration for OAuth */
90
36
  identityProviders?: {
91
37
  [K in OAuthProvider]?: {
@@ -98,24 +44,6 @@ export interface ChatProps {
98
44
  onIdentityConnect?: (identity: Identity) => void;
99
45
  /** Callback when identity disconnects */
100
46
  onIdentityDisconnect?: (provider: OAuthProvider) => void;
101
- /**
102
- * Runtime ID for conversation persistence.
103
- * When provided, messages are fetched from the server API on page reload
104
- * and prevents message mixing between different agent runtimes.
105
- */
106
- runtimeId?: string;
107
- /**
108
- * Endpoint URL for fetching conversation history.
109
- * When runtimeId is provided, this endpoint is called to fetch
110
- * the conversation history on mount.
111
- * If not provided, defaults to `{protocol.endpoint}/api/v1/history`.
112
- */
113
- historyEndpoint?: string;
114
- /**
115
- * A prompt to append and send after the conversation history is loaded.
116
- * The message is shown in the chat and sent to the agent exactly once.
117
- */
118
- pendingPrompt?: string;
119
47
  /**
120
48
  * Error banner to display at the top of the chat.
121
49
  * Use this to show sandbox connection errors or other warnings.
@@ -124,33 +52,6 @@ export interface ChatProps {
124
52
  message: string;
125
53
  variant?: 'danger' | 'warning';
126
54
  };
127
- /**
128
- * Show the information icon in the header.
129
- * When clicked, it opens the agent details panel.
130
- * @default false
131
- */
132
- showInformation?: boolean;
133
- /**
134
- * Current chat view mode for the header segmented toggle.
135
- * When provided, a view-mode toggle is rendered in the header.
136
- */
137
- chatViewMode?: ChatViewMode;
138
- /**
139
- * Callback when the user switches chat view mode via the header toggle.
140
- */
141
- onChatViewModeChange?: (mode: ChatViewMode) => void;
142
- /**
143
- * Frontend tool definitions to register with the chat.
144
- * Pass an empty array to explicitly disable all frontend tools.
145
- */
146
- frontendTools?: FrontendToolDefinition[];
147
- /** Optional custom renderer for tool-call message cards. */
148
- renderToolResult?: RenderToolResult;
149
- /**
150
- * Hide assistant messages that follow a rendered tool call UI.
151
- * Useful to suppress raw tool-call/continuation text and show only tool cards.
152
- */
153
- hideMessagesAfterToolUI?: boolean;
154
55
  }
155
56
  /**
156
57
  * Chat Component
@@ -193,5 +94,5 @@ export interface ChatProps {
193
94
  * />
194
95
  * ```
195
96
  */
196
- export declare function Chat({ protocol: transport, extensions: _extensions, baseUrl, wsUrl, agentId, authToken: authTokenProp, placeholder, title, brandIcon, autoConnect: _autoConnect, streaming: _streaming, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height, showHeader, showNewChatButton, showClearButton, showModelSelector, showToolsMenu, showSkillsMenu, codemodeEnabled, showTokenUsage, initialModel, availableModels, mcpServers, initialSkills, clearOnMount: _clearOnMount, suggestions, submitOnSuggestionClick, description, headerContent, headerActions, autoFocus, identityProviders, onIdentityConnect, onIdentityDisconnect, runtimeId, historyEndpoint, pendingPrompt, errorBanner, showInformation, chatViewMode, onChatViewModeChange, frontendTools, renderToolResult, hideMessagesAfterToolUI, }: ChatProps): import("react/jsx-runtime").JSX.Element;
97
+ export declare function Chat({ protocol: transport, extensions: _extensions, baseUrl, wsUrl, agentId, authToken: authTokenProp, placeholder, title, subtitle, brandIcon, autoConnect: _autoConnect, streaming: _streaming, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height, showHeader, showNewChatButton, showClearButton, showModelSelector, showToolsMenu, showInput, disableInputPrompt, showSkillsMenu, codemodeEnabled, onToggleCodemode, showTokenUsage, initialModel, availableModels, mcpServers, initialSkills, clearOnMount: _clearOnMount, suggestions, submitOnSuggestionClick, description, headerContent, headerActions, autoFocus, identityProviders, onIdentityConnect, onIdentityDisconnect, runtimeId, historyEndpoint, pendingPrompt, errorBanner, showInformation, chatViewMode, onChatViewModeChange, frontendTools, onToolCallStart, onToolCallComplete, renderToolResult, hideMessagesAfterToolUI, contextSnapshot, mcpStatusData, codemodeStatusData, sandboxStatusData, showToolApprovalBanner, pendingApprovals, onApproveApproval, onRejectApproval, }: ChatProps): import("react/jsx-runtime").JSX.Element;
197
98
  export default Chat;
package/lib/chat/Chat.js CHANGED
@@ -133,7 +133,7 @@ function getProtocolType(protocol) {
133
133
  * />
134
134
  * ```
135
135
  */
136
- export function Chat({ protocol: transport, extensions: _extensions, baseUrl = 'http://localhost:8765', wsUrl, agentId, authToken: authTokenProp, placeholder = 'Type your message...', title, brandIcon, autoConnect: _autoConnect = true, streaming: _streaming = true, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height = '600px', showHeader = true, showNewChatButton = true, showClearButton = true, showModelSelector = true, showToolsMenu = true, showSkillsMenu = false, codemodeEnabled = false, showTokenUsage = true, initialModel, availableModels, mcpServers, initialSkills, clearOnMount: _clearOnMount = true, suggestions, submitOnSuggestionClick = true, description, headerContent, headerActions, autoFocus = false, identityProviders, onIdentityConnect, onIdentityDisconnect, runtimeId, historyEndpoint, pendingPrompt, errorBanner, showInformation = true, chatViewMode, onChatViewModeChange, frontendTools, renderToolResult, hideMessagesAfterToolUI = false, }) {
136
+ export function Chat({ protocol: transport, extensions: _extensions, baseUrl = 'http://localhost:8765', wsUrl, agentId, authToken: authTokenProp, placeholder = 'Type your message...', title, subtitle, brandIcon, autoConnect: _autoConnect = true, streaming: _streaming = true, onMessageSent: _onMessageSent, onMessageReceived: _onMessageReceived, onDisconnect, onLogout: _onLogout, onCollapsePanel: _onCollapsePanel, className, height = '600px', showHeader = true, showNewChatButton = true, showClearButton = true, showModelSelector = true, showToolsMenu = true, showInput = true, disableInputPrompt = false, showSkillsMenu = true, codemodeEnabled = false, onToggleCodemode, showTokenUsage = true, initialModel, availableModels, mcpServers, initialSkills, clearOnMount: _clearOnMount = true, suggestions, submitOnSuggestionClick = true, description, headerContent, headerActions, autoFocus = false, identityProviders, onIdentityConnect, onIdentityDisconnect, runtimeId, historyEndpoint, pendingPrompt, errorBanner, showInformation = true, chatViewMode, onChatViewModeChange, frontendTools, onToolCallStart, onToolCallComplete, renderToolResult, hideMessagesAfterToolUI = false, contextSnapshot, mcpStatusData, codemodeStatusData, sandboxStatusData, showToolApprovalBanner, pendingApprovals, onApproveApproval, onRejectApproval, }) {
137
137
  const [error, setError] = useState(null);
138
138
  const [isInitializing, setIsInitializing] = useState(true);
139
139
  const [showDetails, setShowDetails] = useState(false);
@@ -285,7 +285,7 @@ export function Chat({ protocol: transport, extensions: _extensions, baseUrl = '
285
285
  display: showDetails ? 'flex' : 'none',
286
286
  flexDirection: 'column',
287
287
  height: '100%',
288
- }, children: _jsx(AgentDetails, { name: title || 'AI Agent', icon: brandIcon, protocol: transport, url: protocolConfig?.endpoint || baseUrl, messageCount: messageCount, agentId: agentId, apiBase: baseUrl, identityProviders: identityProviders, onIdentityConnect: onIdentityConnect, onIdentityDisconnect: onIdentityDisconnect, onBack: () => setShowDetails(false) }) }), _jsxs(Box, { sx: {
288
+ }, children: _jsx(AgentDetails, { name: title || 'AI Agent', icon: brandIcon, protocol: transport, url: protocolConfig?.endpoint || baseUrl, messageCount: messageCount, agentId: agentId, apiBase: baseUrl, identityProviders: identityProviders, onIdentityConnect: onIdentityConnect, onIdentityDisconnect: onIdentityDisconnect, onBack: () => setShowDetails(false), mcpStatusData: mcpStatusData, codemodeStatusData: codemodeStatusData }) }), _jsxs(Box, { sx: {
289
289
  display: showDetails ? 'none' : 'flex',
290
290
  flexDirection: 'column',
291
291
  height: '100%',
@@ -310,12 +310,12 @@ export function Chat({ protocol: transport, extensions: _extensions, baseUrl = '
310
310
  ? 'attention.fg'
311
311
  : 'danger.fg',
312
312
  flex: 1,
313
- }, children: errorBanner.message })] })), _jsx(ChatBase, { title: title, brandIcon: brandIcon, showHeader: showHeader, protocol: protocolConfig, placeholder: placeholder, description: description, suggestions: suggestions, submitOnSuggestionClick: submitOnSuggestionClick, autoFocus: autoFocus, runtimeId: runtimeId, historyEndpoint: historyEndpoint, pendingPrompt: pendingPrompt, showInformation: showInformation, onInformationClick: () => setShowDetails(true), headerContent: headerContent, headerActions: headerActions, showModelSelector: showModelSelector, showToolsMenu: showToolsMenu, showSkillsMenu: showSkillsMenu, showTokenUsage: showTokenUsage, codemodeEnabled: codemodeEnabled, initialModel: initialModel, availableModels: availableModels, mcpServers: mcpServers, initialSkills: initialSkills, connectedIdentities: identitiesForChat, onNewChat: handleNewChat, onMessagesChange: messages => setMessageCount(messages.length), headerButtons: {
313
+ }, children: errorBanner.message })] })), _jsx(ChatBase, { title: title, subtitle: subtitle, brandIcon: brandIcon, showHeader: showHeader, protocol: protocolConfig, placeholder: placeholder, description: description, suggestions: suggestions, submitOnSuggestionClick: submitOnSuggestionClick, autoFocus: autoFocus, runtimeId: runtimeId, historyEndpoint: historyEndpoint, pendingPrompt: pendingPrompt, showInformation: showInformation, onInformationClick: () => setShowDetails(true), headerContent: headerContent, headerActions: headerActions, showModelSelector: showModelSelector, showToolsMenu: showToolsMenu, showInput: showInput, disableInputPrompt: disableInputPrompt, showSkillsMenu: showSkillsMenu, showTokenUsage: showTokenUsage, codemodeEnabled: codemodeEnabled, onToggleCodemode: onToggleCodemode, initialModel: initialModel, availableModels: availableModels, mcpServers: mcpServers, initialSkills: initialSkills, connectedIdentities: identitiesForChat, onNewChat: handleNewChat, onMessagesChange: messages => setMessageCount(messages.length), headerButtons: {
314
314
  showNewChat: showNewChatButton,
315
315
  showClear: showClearButton,
316
316
  onNewChat: handleNewChat,
317
317
  }, avatarConfig: {
318
318
  showAvatars: true,
319
- }, backgroundColor: "canvas.default", focusTrigger: focusTrigger, chatViewMode: chatViewMode, onChatViewModeChange: onChatViewModeChange, frontendTools: frontendTools, renderToolResult: renderToolResult, hideMessagesAfterToolUI: hideMessagesAfterToolUI })] })] }) }));
319
+ }, backgroundColor: "canvas.default", focusTrigger: focusTrigger, chatViewMode: chatViewMode, onChatViewModeChange: onChatViewModeChange, frontendTools: frontendTools, onToolCallStart: onToolCallStart, onToolCallComplete: onToolCallComplete, renderToolResult: renderToolResult, hideMessagesAfterToolUI: hideMessagesAfterToolUI, contextSnapshot: contextSnapshot, mcpStatusData: mcpStatusData, sandboxStatusData: sandboxStatusData, showToolApprovalBanner: showToolApprovalBanner, pendingApprovals: pendingApprovals, onApproveApproval: onApproveApproval, onRejectApproval: onRejectApproval })] })] }) }));
320
320
  }
321
321
  export default Chat;