@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.
- package/README.md +13 -131
- package/lib/chat/Chat.d.ts +3 -1
- package/lib/chat/Chat.js +2 -2
- package/lib/chat/base/ChatBase.js +52 -1
- package/lib/chat/messages/ChatMessageList.js +17 -4
- package/lib/client/AgentsMixin.d.ts +48 -1
- package/lib/client/AgentsMixin.js +109 -0
- package/lib/components/NotificationEventCard.js +51 -26
- package/lib/components/OutputCard.js +21 -7
- package/lib/components/ToolApprovalCard.js +20 -2
- package/lib/examples/AgentCheckpointsExample.js +2 -8
- package/lib/examples/AgentCodemodeExample.js +3 -9
- package/lib/examples/AgentEvalsExample.js +3 -9
- package/lib/examples/AgentGuardrailsExample.js +3 -9
- package/lib/examples/AgentMemoryExample.js +3 -9
- package/lib/examples/AgentMonitoringExample.js +3 -9
- package/lib/examples/AgentNotificationsExample.js +2 -8
- package/lib/examples/AgentOutputsExample.js +3 -9
- package/lib/examples/AgentSandboxExample.js +3 -9
- package/lib/examples/AgentSkillsExample.js +3 -9
- package/lib/examples/AgentToolApprovalsExample.js +89 -24
- package/lib/examples/AgentTriggersExample.js +604 -37
- package/lib/examples/ChatExample.js +2 -10
- package/lib/examples/components/ErrorView.d.ts +14 -0
- package/lib/examples/components/ErrorView.js +20 -0
- package/lib/examples/components/index.d.ts +2 -0
- package/lib/examples/components/index.js +1 -0
- package/lib/examples/main.d.ts +1 -0
- package/lib/examples/main.js +1 -0
- package/lib/protocols/VercelAIAdapter.d.ts +2 -0
- package/lib/protocols/VercelAIAdapter.js +86 -20
- package/lib/shims/json5.d.ts +4 -0
- package/lib/shims/json5.js +8 -0
- package/lib/specs/agents/agents.js +241 -1390
- package/lib/specs/agents/index.js +1 -3
- package/lib/specs/envvars.js +20 -27
- package/lib/specs/evals.js +6 -6
- package/lib/specs/events.d.ts +10 -2
- package/lib/specs/events.js +84 -126
- package/lib/specs/frontendTools.js +2 -2
- package/lib/specs/guardrails.d.ts +7 -0
- package/lib/specs/guardrails.js +159 -240
- package/lib/specs/mcpServers.js +6 -35
- package/lib/specs/memory.d.ts +2 -0
- package/lib/specs/memory.js +17 -4
- package/lib/specs/models.js +5 -25
- package/lib/specs/notifications.js +18 -102
- package/lib/specs/outputs.js +9 -15
- package/lib/specs/skills.js +18 -18
- package/lib/specs/teams/index.js +1 -3
- package/lib/specs/teams/teams.js +348 -468
- package/lib/specs/tools.js +6 -3
- package/lib/specs/triggers.js +11 -61
- package/lib/types/tools.d.ts +2 -0
- package/package.json +1 -1
- package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
- package/scripts/codegen/generate_agents.py +4 -1
- package/scripts/codegen/generate_events.py +12 -4
- package/scripts/codegen/generate_tools.py +20 -0
- package/style/primer-primitives.css +1 -6
- package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_envvars.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_evals.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_guardrails.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_mcp_servers.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_memory.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_models.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_notifications.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_outputs.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_skills.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_teams.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_tools.cpython-313.pyc +0 -0
- 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
|
-

|
|
33
|
+

|
|
34
|
+
|
|
35
|
+

|
|
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
|
-
##
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
-
|
|
63
|
-
-
|
|
64
|
-
-
|
|
65
|
-
-
|
|
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)
|
package/lib/chat/Chat.d.ts
CHANGED
|
@@ -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 &&
|
|
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
|
-
}, [
|
|
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
|
}
|