@datalayer/agent-runtimes 1.0.3 → 1.0.4

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 (73) hide show
  1. package/README.md +13 -131
  2. package/lib/chat/Chat.d.ts +3 -1
  3. package/lib/chat/Chat.js +2 -2
  4. package/lib/chat/base/ChatBase.js +52 -1
  5. package/lib/chat/messages/ChatMessageList.js +17 -4
  6. package/lib/client/AgentsMixin.d.ts +48 -1
  7. package/lib/client/AgentsMixin.js +109 -0
  8. package/lib/components/NotificationEventCard.js +51 -26
  9. package/lib/components/OutputCard.js +21 -7
  10. package/lib/components/ToolApprovalCard.js +20 -2
  11. package/lib/examples/AgentCheckpointsExample.js +2 -8
  12. package/lib/examples/AgentCodemodeExample.js +3 -9
  13. package/lib/examples/AgentEvalsExample.js +3 -9
  14. package/lib/examples/AgentGuardrailsExample.js +3 -9
  15. package/lib/examples/AgentMemoryExample.js +3 -9
  16. package/lib/examples/AgentMonitoringExample.js +3 -9
  17. package/lib/examples/AgentNotificationsExample.js +2 -8
  18. package/lib/examples/AgentOutputsExample.js +3 -9
  19. package/lib/examples/AgentSandboxExample.js +3 -9
  20. package/lib/examples/AgentSkillsExample.js +3 -9
  21. package/lib/examples/AgentToolApprovalsExample.js +89 -24
  22. package/lib/examples/AgentTriggersExample.js +604 -37
  23. package/lib/examples/ChatExample.js +2 -10
  24. package/lib/examples/components/ErrorView.d.ts +14 -0
  25. package/lib/examples/components/ErrorView.js +20 -0
  26. package/lib/examples/components/index.d.ts +2 -0
  27. package/lib/examples/components/index.js +1 -0
  28. package/lib/examples/main.d.ts +1 -0
  29. package/lib/examples/main.js +1 -0
  30. package/lib/protocols/VercelAIAdapter.d.ts +2 -0
  31. package/lib/protocols/VercelAIAdapter.js +86 -20
  32. package/lib/shims/json5.d.ts +4 -0
  33. package/lib/shims/json5.js +8 -0
  34. package/lib/specs/agents/agents.js +241 -1390
  35. package/lib/specs/agents/index.js +1 -3
  36. package/lib/specs/envvars.js +20 -27
  37. package/lib/specs/evals.js +6 -6
  38. package/lib/specs/events.d.ts +10 -2
  39. package/lib/specs/events.js +84 -126
  40. package/lib/specs/frontendTools.js +2 -2
  41. package/lib/specs/guardrails.d.ts +7 -0
  42. package/lib/specs/guardrails.js +159 -240
  43. package/lib/specs/mcpServers.js +6 -35
  44. package/lib/specs/memory.d.ts +2 -0
  45. package/lib/specs/memory.js +17 -4
  46. package/lib/specs/models.js +5 -25
  47. package/lib/specs/notifications.js +18 -102
  48. package/lib/specs/outputs.js +9 -15
  49. package/lib/specs/skills.js +18 -18
  50. package/lib/specs/teams/index.js +1 -3
  51. package/lib/specs/teams/teams.js +348 -468
  52. package/lib/specs/tools.js +6 -3
  53. package/lib/specs/triggers.js +11 -61
  54. package/lib/types/tools.d.ts +2 -0
  55. package/package.json +1 -1
  56. package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
  57. package/scripts/codegen/generate_agents.py +4 -1
  58. package/scripts/codegen/generate_events.py +12 -4
  59. package/scripts/codegen/generate_tools.py +20 -0
  60. package/style/primer-primitives.css +1 -6
  61. package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
  62. package/scripts/codegen/__pycache__/generate_envvars.cpython-313.pyc +0 -0
  63. package/scripts/codegen/__pycache__/generate_evals.cpython-313.pyc +0 -0
  64. package/scripts/codegen/__pycache__/generate_guardrails.cpython-313.pyc +0 -0
  65. package/scripts/codegen/__pycache__/generate_mcp_servers.cpython-313.pyc +0 -0
  66. package/scripts/codegen/__pycache__/generate_memory.cpython-313.pyc +0 -0
  67. package/scripts/codegen/__pycache__/generate_models.cpython-313.pyc +0 -0
  68. package/scripts/codegen/__pycache__/generate_notifications.cpython-313.pyc +0 -0
  69. package/scripts/codegen/__pycache__/generate_outputs.cpython-313.pyc +0 -0
  70. package/scripts/codegen/__pycache__/generate_skills.cpython-313.pyc +0 -0
  71. package/scripts/codegen/__pycache__/generate_teams.cpython-313.pyc +0 -0
  72. package/scripts/codegen/__pycache__/generate_tools.cpython-313.pyc +0 -0
  73. package/scripts/codegen/__pycache__/generate_triggers.cpython-313.pyc +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,13 @@ 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
- ```
99
-
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
- />
115
- ```
116
-
117
- ### Custom Agent Deployment
118
- Deploy your own Pydantic AI agent with custom tools:
119
-
120
- ```python
121
- from agent_runtimes import AgentRuntimesApp
122
- from pydantic_ai import Agent
123
-
124
- # Create your agent
125
- agent = Agent(
126
- model='anthropic:claude-sonnet-4-5',
127
- system_prompt='You are a helpful assistant.',
128
- )
129
-
130
- # Launch the server
131
- app = AgentRuntimesApp()
132
- app.add_agent(agent, name='my-agent', transport='ag-ui')
133
- app.run(port=8000)
134
- ```
135
-
136
- ## 🧪 Run the examples
137
-
138
- Run the Codemode + MCP example UI:
139
-
140
- ```bash
141
- cd src/ai/agent-runtimes
142
- EXAMPLE=AgentCodemodeMcpExample npm run dev
143
- ```
144
-
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
- ```
58
+ ## Documentation
59
+
60
+ The detailed guides for architecture, use cases, interactive chat, key concepts, and runtime configuration are now in Docusaurus docs:
61
+
62
+ - [Agent Runtimes Overview](https://agent-runtimes.datalayer.tech/)
63
+ - [Integrations](https://agent-runtimes.datalayer.tech/integrations)
64
+ - [Chat](https://agent-runtimes.datalayer.tech/chat)
65
+ - [Transports](https://agent-runtimes.datalayer.tech/transports)
66
+ - [Programmatic Tools](https://agent-runtimes.datalayer.tech/programmatic-tools)
67
+ - [CLI](https://agent-runtimes.datalayer.tech/cli)
@@ -51,6 +51,8 @@ export interface ChatProps {
51
51
  showModelSelector?: boolean;
52
52
  /** Show tools menu (fetched from /configure endpoint) */
53
53
  showToolsMenu?: boolean;
54
+ /** Show input area */
55
+ showInput?: boolean;
54
56
  /** Show skills menu (fetched from /skills endpoint) */
55
57
  showSkillsMenu?: boolean;
56
58
  /** Indicate tools are accessed via Codemode meta-tools */
@@ -193,5 +195,5 @@ export interface ChatProps {
193
195
  * />
194
196
  * ```
195
197
  */
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;
198
+ 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, showInput, 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;
197
199
  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, 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, 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, }) {
137
137
  const [error, setError] = useState(null);
138
138
  const [isInitializing, setIsInitializing] = useState(true);
139
139
  const [showDetails, setShowDetails] = useState(false);
@@ -310,7 +310,7 @@ 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, 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, showSkillsMenu: showSkillsMenu, showTokenUsage: showTokenUsage, codemodeEnabled: codemodeEnabled, 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,
@@ -1169,7 +1169,58 @@ pendingPrompt, }) {
1169
1169
  // ---- HITL respond handler (passed to MessageList) ----
1170
1170
  const handleRespond = useCallback(async (toolCallId, result) => {
1171
1171
  const existingToolCall = toolCallsRef.current.get(toolCallId);
1172
- if (existingToolCall && existingToolCall.status === 'executing') {
1172
+ if (existingToolCall &&
1173
+ (existingToolCall.status === 'executing' ||
1174
+ existingToolCall.status === 'inProgress')) {
1175
+ const isApprovalDecision = !!result &&
1176
+ typeof result === 'object' &&
1177
+ result.type === 'tool-approval-decision' &&
1178
+ typeof result.approved === 'boolean';
1179
+ if (isApprovalDecision && adapterRef.current) {
1180
+ const approved = Boolean(result.approved);
1181
+ const updatedToolCall = {
1182
+ ...existingToolCall,
1183
+ result,
1184
+ status: approved ? 'complete' : 'error',
1185
+ error: approved ? undefined : 'Tool approval rejected by user',
1186
+ };
1187
+ toolCallsRef.current.set(toolCallId, updatedToolCall);
1188
+ setDisplayItems(prev => prev.map(item => isToolCallMessage(item) && item.toolCallId === toolCallId
1189
+ ? updatedToolCall
1190
+ : item));
1191
+ setIsLoading(true);
1192
+ setIsStreaming(true);
1193
+ try {
1194
+ const approvalId = typeof result === 'object' &&
1195
+ result !== null &&
1196
+ typeof result.approvalId === 'string'
1197
+ ? result.approvalId
1198
+ : undefined;
1199
+ await adapterRef.current.sendToolResult(toolCallId, {
1200
+ toolCallId,
1201
+ success: approved,
1202
+ result: approved
1203
+ ? {
1204
+ approved: true,
1205
+ message: 'Tool call approved by user.',
1206
+ ...(approvalId ? { approvalId } : {}),
1207
+ }
1208
+ : {
1209
+ approved: false,
1210
+ message: 'Tool call rejected by user.',
1211
+ ...(approvalId ? { approvalId } : {}),
1212
+ },
1213
+ ...(approved
1214
+ ? {}
1215
+ : { error: 'Tool approval rejected by user' }),
1216
+ });
1217
+ }
1218
+ catch (err) {
1219
+ console.error('[ChatBase] Approval continuation error:', err);
1220
+ setError(err);
1221
+ }
1222
+ return;
1223
+ }
1173
1224
  const updatedToolCall = {
1174
1225
  ...existingToolCall,
1175
1226
  result,
@@ -19,7 +19,7 @@ import { isToolCallMessage, getMessageText } from '../../utils';
19
19
  // ---------------------------------------------------------------------------
20
20
  // DefaultToolCallRenderer — handles tool approval for a single tool call
21
21
  // ---------------------------------------------------------------------------
22
- function DefaultToolCallRenderer({ item, approvalConfig, }) {
22
+ function DefaultToolCallRenderer({ item, approvalConfig, onRespond, }) {
23
23
  const resultObject = item.result && typeof item.result === 'object'
24
24
  ? item.result
25
25
  : undefined;
@@ -110,6 +110,12 @@ function DefaultToolCallRenderer({ item, approvalConfig, }) {
110
110
  });
111
111
  if (res.ok) {
112
112
  setDecision(action === 'approve' ? 'approved' : 'denied');
113
+ onRespond({
114
+ type: 'tool-approval-decision',
115
+ approved: action === 'approve',
116
+ approvalId: matchedApprovalId,
117
+ toolName: item.toolName,
118
+ });
113
119
  }
114
120
  }
115
121
  catch {
@@ -118,7 +124,14 @@ function DefaultToolCallRenderer({ item, approvalConfig, }) {
118
124
  finally {
119
125
  setLoading(false);
120
126
  }
121
- }, [matchedApprovalId, approvalConfig?.apiBaseUrl, approvalConfig?.authToken]);
127
+ }, [
128
+ matchedApprovalId,
129
+ approvalConfig?.apiBaseUrl,
130
+ approvalConfig?.authToken,
131
+ onRespond,
132
+ item.toolCallId,
133
+ item.toolName,
134
+ ]);
122
135
  // Show approval UI when we have a confirmed pending approval (from result
123
136
  // or discovered via polling) or after a decision has been made.
124
137
  const hasApproval = isPendingFromResult || !!matchedApprovalId;
@@ -170,7 +183,7 @@ export function ChatMessageList({ displayItems, isLoading, isStreaming, showLoad
170
183
  return (_jsxs(_Fragment, { children: [displayItems.map((item, index) => {
171
184
  // ---- Tool call item ----
172
185
  if (isToolCallMessage(item)) {
173
- const respond = item.status === 'executing'
186
+ const respond = item.status === 'executing' || item.status === 'inProgress'
174
187
  ? createRespondCallback(item.toolCallId)
175
188
  : undefined;
176
189
  const toolUI = renderToolResult ? (renderToolResult({
@@ -182,7 +195,7 @@ export function ChatMessageList({ displayItems, isLoading, isStreaming, showLoad
182
195
  status: item.status,
183
196
  error: item.error,
184
197
  respond,
185
- })) : (_jsx(DefaultToolCallRenderer, { item: item, approvalConfig: approvalConfig }));
198
+ })) : (_jsx(DefaultToolCallRenderer, { item: item, approvalConfig: approvalConfig, onRespond: createRespondCallback(item.toolCallId) }));
186
199
  if (toolUI === null || toolUI === undefined)
187
200
  return null;
188
201
  return (_jsx(Box, { sx: {
@@ -11,7 +11,8 @@
11
11
  * @module client/AgentsMixin
12
12
  */
13
13
  import type { Constructor } from '@datalayer/core/lib/client/utils/mixins';
14
- import type { AgentEvent, CreateAgentEventRequest, GetAgentEventResponse, ListAgentEventsParams, ListAgentEventsResponse, UpdateAgentEventRequest, RunningAgent, AgentUsageSummary, ConversationCheckpoint, AgentNotification, NotificationFilters, OutputArtifact, EvalReport, RunEvalsRequest, ContextUsage, CostUsage } from '../types';
14
+ import type { AgentEvent, CreateAgentEventRequest, GetAgentEventResponse, ListAgentEventsParams, ListAgentEventsResponse, UpdateAgentEventRequest, RunningAgent, AgentUsageSummary, ConversationCheckpoint, AgentNotification, NotificationFilters, OutputArtifact, EvalReport, RunEvalsRequest, ContextUsage, CostUsage, AgentSpec } from '../types';
15
+ import type { CreateAgentRuntimeRequest, CreateRuntimeApiResponse } from '../types/agents-lifecycle';
15
16
  import type { ToolApproval, ToolApprovalFilters } from '../types/tool-approvals';
16
17
  /** Agents mixin providing durable agent management. */
17
18
  export declare function AgentsMixin<TBase extends Constructor>(Base: TBase): {
@@ -165,5 +166,51 @@ export declare function AgentsMixin<TBase extends Constructor>(Base: TBase): {
165
166
  * @returns Cost usage including per-model breakdown
166
167
  */
167
168
  getCostUsage(agentId: string): Promise<CostUsage>;
169
+ /**
170
+ * Get an agent specification by ID.
171
+ * @param agentSpecId - Agent spec identifier.
172
+ * @returns The agent spec, or undefined if not found.
173
+ */
174
+ getAgentSpec(agentSpecId: string): AgentSpec | undefined;
175
+ /**
176
+ * List all available agent specifications.
177
+ * @param prefix - If provided, only return specs whose ID starts with this prefix.
178
+ * @returns Array of agent specifications.
179
+ */
180
+ listAgentSpecs(prefix?: string): AgentSpec[];
181
+ /**
182
+ * Get required environment variables for an agent spec.
183
+ * @param spec - The agent specification.
184
+ * @returns Deduplicated array of required environment variable names.
185
+ */
186
+ getAgentSpecRequiredEnvVars(spec: AgentSpec): string[];
187
+ /**
188
+ * Assign an agent runtime to a project.
189
+ * @param projectUid - Project UID.
190
+ * @param agentPodName - Agent runtime pod name.
191
+ * @param agentSpecId - Agent spec ID.
192
+ * @param agentGivenName - Human-readable runtime name.
193
+ * @returns Updated project.
194
+ */
195
+ assignAgentToProject(projectUid: string, agentPodName: string, agentSpecId?: string, agentGivenName?: string): Promise<any>;
196
+ /**
197
+ * Remove the agent assignment from a project.
198
+ * @param projectUid - Project UID.
199
+ * @returns Updated project.
200
+ */
201
+ unassignAgentFromProject(projectUid: string): Promise<any>;
202
+ /**
203
+ * Create an agent runtime.
204
+ * @param data - Runtime creation parameters.
205
+ * @returns The created runtime response.
206
+ */
207
+ createAgentRuntime(data: CreateAgentRuntimeRequest): Promise<CreateRuntimeApiResponse>;
208
+ /**
209
+ * Create an agent runtime and assign it to a project.
210
+ * @param projectUid - The project UID to assign the agent to.
211
+ * @param data - Runtime creation parameters.
212
+ * @returns The created runtime response.
213
+ */
214
+ createAgentRuntimeForProject(projectUid: string, data: CreateAgentRuntimeRequest): Promise<CreateRuntimeApiResponse>;
168
215
  };
169
216
  } & TBase;
@@ -9,6 +9,8 @@ import * as events from '../api/events';
9
9
  import * as output from '../api/output';
10
10
  import * as evals from '../api/evals';
11
11
  import * as context from '../api/context';
12
+ import * as agentSpecs from '../specs/agents';
13
+ import { requestDatalayerAPI } from '@datalayer/core/lib/api/DatalayerApi';
12
14
  /** Agents mixin providing durable agent management. */
13
15
  export function AgentsMixin(Base) {
14
16
  return class extends Base {
@@ -275,5 +277,112 @@ export function AgentsMixin(Base) {
275
277
  const baseUrl = this.getIamRunUrl();
276
278
  return context.getCostUsage(token, agentId, baseUrl);
277
279
  }
280
+ // ========================================================================
281
+ // Agent Specs
282
+ // ========================================================================
283
+ /**
284
+ * Get an agent specification by ID.
285
+ * @param agentSpecId - Agent spec identifier.
286
+ * @returns The agent spec, or undefined if not found.
287
+ */
288
+ getAgentSpec(agentSpecId) {
289
+ return agentSpecs.getAgentSpecs(agentSpecId);
290
+ }
291
+ /**
292
+ * List all available agent specifications.
293
+ * @param prefix - If provided, only return specs whose ID starts with this prefix.
294
+ * @returns Array of agent specifications.
295
+ */
296
+ listAgentSpecs(prefix) {
297
+ return agentSpecs.listAgentSpecs(prefix);
298
+ }
299
+ /**
300
+ * Get required environment variables for an agent spec.
301
+ * @param spec - The agent specification.
302
+ * @returns Deduplicated array of required environment variable names.
303
+ */
304
+ getAgentSpecRequiredEnvVars(spec) {
305
+ return agentSpecs.getAgentSpecRequiredEnvVars(spec);
306
+ }
307
+ // ========================================================================
308
+ // Project Agent Assignment
309
+ // ========================================================================
310
+ /**
311
+ * Assign an agent runtime to a project.
312
+ * @param projectUid - Project UID.
313
+ * @param agentPodName - Agent runtime pod name.
314
+ * @param agentSpecId - Agent spec ID.
315
+ * @param agentGivenName - Human-readable runtime name.
316
+ * @returns Updated project.
317
+ */
318
+ async assignAgentToProject(projectUid, agentPodName, agentSpecId, agentGivenName) {
319
+ // Backend requires name and description on every update
320
+ const project = await this.getProject(projectUid);
321
+ return this.updateProject(projectUid, {
322
+ name: project.name,
323
+ description: project.description,
324
+ attached_agent_pod_name_s: agentPodName,
325
+ attached_agent_spec_id_s: agentSpecId || '',
326
+ attached_agent_given_name_s: agentGivenName || '',
327
+ });
328
+ }
329
+ /**
330
+ * Remove the agent assignment from a project.
331
+ * @param projectUid - Project UID.
332
+ * @returns Updated project.
333
+ */
334
+ async unassignAgentFromProject(projectUid) {
335
+ // Backend requires name and description on every update
336
+ const project = await this.getProject(projectUid);
337
+ return this.updateProject(projectUid, {
338
+ name: project.name,
339
+ description: project.description,
340
+ attached_agent_pod_name_s: '',
341
+ attached_agent_spec_id_s: '',
342
+ attached_agent_given_name_s: '',
343
+ });
344
+ }
345
+ // ========================================================================
346
+ // Agent Runtime Lifecycle
347
+ // ========================================================================
348
+ /**
349
+ * Create an agent runtime.
350
+ * @param data - Runtime creation parameters.
351
+ * @returns The created runtime response.
352
+ */
353
+ async createAgentRuntime(data) {
354
+ const token = this.getToken();
355
+ const runtimesRunUrl = this.getRuntimesRunUrl();
356
+ return requestDatalayerAPI({
357
+ url: `${runtimesRunUrl}/api/runtimes/v1/runtimes`,
358
+ method: 'POST',
359
+ token,
360
+ body: {
361
+ environment_name: data.environmentName || 'ai-agents-env',
362
+ given_name: data.givenName || 'Agent',
363
+ credits_limit: data.creditsLimit || 10,
364
+ type: data.type || 'notebook',
365
+ editor_variant: data.editorVariant || 'none',
366
+ enable_codemode: data.enableCodemode ?? false,
367
+ agent_spec_id: data.agentSpecId || undefined,
368
+ agent_spec: data.agentSpec || undefined,
369
+ },
370
+ });
371
+ }
372
+ /**
373
+ * Create an agent runtime and assign it to a project.
374
+ * @param projectUid - The project UID to assign the agent to.
375
+ * @param data - Runtime creation parameters.
376
+ * @returns The created runtime response.
377
+ */
378
+ async createAgentRuntimeForProject(projectUid, data) {
379
+ const response = await this.createAgentRuntime(data);
380
+ if (response.success && response.runtime) {
381
+ const podName = response.runtime.pod_name;
382
+ const givenName = response.runtime.given_name || data.givenName || data.agentSpecId;
383
+ await this.assignAgentToProject(projectUid, podName, data.agentSpecId, givenName);
384
+ }
385
+ return response;
386
+ }
278
387
  };
279
388
  }