@datalayer/agent-runtimes 1.0.5 → 1.0.6
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 +157 -10
- package/lib/AgentNode.d.ts +3 -0
- package/lib/AgentNode.js +676 -0
- package/lib/agent-node/themeStore.d.ts +3 -0
- package/lib/agent-node/themeStore.js +156 -0
- package/lib/agent-node-main.d.ts +1 -0
- package/lib/agent-node-main.js +14 -0
- package/lib/chat/Chat.js +16 -10
- package/lib/chat/ChatFloating.js +1 -1
- package/lib/chat/ChatSidebar.js +81 -49
- package/lib/chat/base/ChatBase.js +388 -74
- package/lib/chat/display/FloatingBrandButton.js +8 -1
- package/lib/chat/header/ChatHeader.d.ts +3 -1
- package/lib/chat/header/ChatHeader.js +15 -12
- package/lib/chat/header/ChatHeaderBase.d.ts +29 -9
- package/lib/chat/header/ChatHeaderBase.js +26 -3
- package/lib/chat/indicators/SandboxStatusIndicator.js +82 -47
- package/lib/chat/messages/ChatMessageList.js +46 -1
- package/lib/chat/messages/ChatMessages.js +6 -2
- package/lib/chat/prompt/InputFooter.d.ts +3 -1
- package/lib/chat/prompt/InputFooter.js +8 -5
- package/lib/chat/prompt/InputPrompt.d.ts +3 -1
- package/lib/chat/prompt/InputPrompt.js +2 -2
- package/lib/chat/prompt/InputPromptFooter.d.ts +3 -1
- package/lib/chat/prompt/InputPromptFooter.js +3 -3
- package/lib/client/AgentsMixin.js +14 -0
- package/lib/config/AgentConfiguration.d.ts +22 -0
- package/lib/config/AgentConfiguration.js +319 -64
- package/lib/examples/AgUiSharedStateExample.js +2 -1
- package/lib/examples/AgentCheckpointsExample.js +3 -3
- package/lib/examples/AgentCodemodeExample.d.ts +3 -3
- package/lib/examples/AgentCodemodeExample.js +24 -12
- package/lib/examples/AgentEvalsExample.js +330 -40
- package/lib/examples/AgentGuardrailsExample.js +16 -5
- package/lib/examples/AgentHooksExample.js +27 -9
- package/lib/examples/AgentInferenceProviderExample.d.ts +3 -0
- package/lib/examples/AgentInferenceProviderExample.js +329 -0
- package/lib/examples/AgentMCPExample.js +6 -5
- package/lib/examples/AgentMemoryExample.d.ts +1 -2
- package/lib/examples/AgentMemoryExample.js +71 -22
- package/lib/examples/AgentMonitoringExample.js +5 -5
- package/lib/examples/AgentNotificationsExample.d.ts +1 -2
- package/lib/examples/AgentNotificationsExample.js +71 -22
- package/lib/examples/AgentOtelExample.js +31 -40
- package/lib/examples/AgentOutputsExample.d.ts +1 -1
- package/lib/examples/AgentOutputsExample.js +67 -16
- package/lib/examples/AgentParametersExample.js +10 -8
- package/lib/examples/AgentSandboxExample.d.ts +1 -1
- package/lib/examples/AgentSandboxExample.js +7 -6
- package/lib/examples/AgentSkillsExample.js +6 -6
- package/lib/examples/AgentSubagentsExample.d.ts +1 -1
- package/lib/examples/AgentSubagentsExample.js +6 -6
- package/lib/examples/AgentToolApprovalsExample.js +27 -11
- package/lib/examples/AgentTriggersExample.js +5 -5
- package/lib/examples/{AgentSpecsExample.d.ts → AgentspecsExample.d.ts} +2 -2
- package/lib/examples/AgentspecsExample.js +1096 -0
- package/lib/examples/ChatCustomExample.js +6 -5
- package/lib/examples/ChatExample.js +6 -5
- package/lib/examples/Lexical2Example.js +1 -1
- package/lib/examples/LexicalAgentExample.js +1 -1
- package/lib/examples/NotebookAgentExample.js +3 -3
- package/lib/examples/components/ExampleWrapper.d.ts +6 -7
- package/lib/examples/components/ExampleWrapper.js +27 -10
- package/lib/examples/example-selector.js +2 -1
- package/lib/examples/index.d.ts +2 -1
- package/lib/examples/index.js +2 -1
- package/lib/examples/lexical/initial-content.json +6 -6
- package/lib/examples/main.js +56 -16
- package/lib/examples/utils/agentId.d.ts +1 -1
- package/lib/examples/utils/agentId.js +1 -1
- package/lib/examples/utils/useExampleAgentRuntimesUrl.d.ts +5 -0
- package/lib/examples/utils/useExampleAgentRuntimesUrl.js +19 -0
- package/lib/hooks/useAIAgentsWebSocket.js +35 -0
- package/lib/hooks/useAgentRuntimes.d.ts +32 -3
- package/lib/hooks/useAgentRuntimes.js +114 -19
- package/lib/index.d.ts +1 -1
- package/lib/specs/agents/agents.d.ts +20 -13
- package/lib/specs/agents/agents.js +1267 -581
- package/lib/specs/benchmarks.d.ts +20 -0
- package/lib/specs/benchmarks.js +205 -0
- package/lib/specs/envvars.d.ts +0 -1
- package/lib/specs/envvars.js +0 -11
- package/lib/specs/evals.d.ts +10 -9
- package/lib/specs/evals.js +128 -88
- package/lib/specs/index.d.ts +0 -1
- package/lib/specs/index.js +0 -1
- package/lib/specs/models.d.ts +0 -2
- package/lib/specs/models.js +0 -15
- package/lib/specs/skills.d.ts +0 -1
- package/lib/specs/skills.js +0 -18
- package/lib/stores/agentRuntimeStore.d.ts +5 -1
- package/lib/stores/agentRuntimeStore.js +22 -8
- package/lib/stores/conversationStore.js +2 -2
- package/lib/types/agents-lifecycle.d.ts +18 -0
- package/lib/types/agents.d.ts +6 -0
- package/lib/types/agentspecs.d.ts +4 -0
- package/lib/types/benchmarks.d.ts +43 -0
- package/lib/types/benchmarks.js +5 -0
- package/lib/types/chat.d.ts +16 -0
- package/lib/types/evals.d.ts +26 -17
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.js +1 -0
- package/package.json +9 -5
- package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_benchmarks.cpython-313.pyc +0 -0
- package/scripts/codegen/__pycache__/generate_evals.cpython-313.pyc +0 -0
- package/scripts/codegen/generate_agents.py +89 -43
- package/scripts/codegen/generate_benchmarks.py +441 -0
- package/scripts/codegen/generate_evals.py +94 -16
- package/scripts/codegen/generate_events.py +0 -1
- package/lib/examples/AgentSpecsExample.js +0 -694
|
@@ -5,16 +5,18 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
5
5
|
*/
|
|
6
6
|
import { useEffect, useState } from 'react';
|
|
7
7
|
import { Text, Spinner } from '@primer/react';
|
|
8
|
+
import { SyncIcon } from '@primer/octicons-react';
|
|
8
9
|
import { Box, setupPrimerPortals } from '@datalayer/primer-addons';
|
|
9
10
|
import { ThemedProvider } from './utils/themedProvider';
|
|
10
11
|
import { uniqueAgentId } from './utils/agentId';
|
|
12
|
+
import { useExampleAgentRuntimesUrl } from './utils/useExampleAgentRuntimesUrl';
|
|
11
13
|
import { ErrorView } from './components';
|
|
12
14
|
import { Chat } from '../chat';
|
|
13
15
|
setupPrimerPortals();
|
|
14
|
-
const
|
|
15
|
-
const
|
|
16
|
-
const AGENT_NAME = 'hooks-demo';
|
|
16
|
+
const AGENT_SPEC_ID = 'example-hooks';
|
|
17
|
+
const AGENT_NAME = 'hooks-example-agent';
|
|
17
18
|
const AgentHooksExample = () => {
|
|
19
|
+
const baseUrl = useExampleAgentRuntimesUrl();
|
|
18
20
|
const [agentId, setAgentId] = useState(null);
|
|
19
21
|
const [error, setError] = useState(null);
|
|
20
22
|
const [isCreating, setIsCreating] = useState(true);
|
|
@@ -23,7 +25,7 @@ const AgentHooksExample = () => {
|
|
|
23
25
|
const name = uniqueAgentId(AGENT_NAME);
|
|
24
26
|
const createAgent = async () => {
|
|
25
27
|
try {
|
|
26
|
-
const response = await fetch(`${
|
|
28
|
+
const response = await fetch(`${baseUrl}/api/v1/agents`, {
|
|
27
29
|
method: 'POST',
|
|
28
30
|
headers: { 'Content-Type': 'application/json' },
|
|
29
31
|
body: JSON.stringify({
|
|
@@ -55,19 +57,19 @@ const AgentHooksExample = () => {
|
|
|
55
57
|
return () => {
|
|
56
58
|
cancelled = true;
|
|
57
59
|
};
|
|
58
|
-
}, []);
|
|
60
|
+
}, [baseUrl]);
|
|
59
61
|
useEffect(() => {
|
|
60
62
|
return () => {
|
|
61
63
|
if (!agentId) {
|
|
62
64
|
return;
|
|
63
65
|
}
|
|
64
|
-
void fetch(`${
|
|
66
|
+
void fetch(`${baseUrl}/api/v1/agents/${encodeURIComponent(agentId)}`, {
|
|
65
67
|
method: 'DELETE',
|
|
66
68
|
}).catch(() => {
|
|
67
69
|
// Ignore teardown failures in example mode.
|
|
68
70
|
});
|
|
69
71
|
};
|
|
70
|
-
}, [agentId]);
|
|
72
|
+
}, [agentId, baseUrl]);
|
|
71
73
|
if (isCreating) {
|
|
72
74
|
return (_jsx(ThemedProvider, { children: _jsxs(Box, { sx: {
|
|
73
75
|
display: 'flex',
|
|
@@ -82,14 +84,14 @@ const AgentHooksExample = () => {
|
|
|
82
84
|
if (error || !agentId) {
|
|
83
85
|
return (_jsx(ThemedProvider, { children: _jsx(ErrorView, { error: "Failed to start hooks agent", detail: error || 'No agent ID returned' }) }));
|
|
84
86
|
}
|
|
85
|
-
return (_jsx(Chat, { protocol: "vercel-ai", baseUrl:
|
|
87
|
+
return (_jsx(Chat, { protocol: "vercel-ai", baseUrl: baseUrl, agentId: agentId, title: "Hooks Agent", brandIcon: _jsx(SyncIcon, { size: 16 }), placeholder: "Ask about lifecycle hooks...", description: "Demonstrates lifecycle hooks and pydantic-style tool hooks: before_tool_execute, after_tool_execute, on_tool_execute_error, deferred_tool_calls", showHeader: true, showModelSelector: true, showToolsMenu: true, showSkillsMenu: true, showTokenUsage: true, showInformation: true, autoFocus: true, height: "100vh", runtimeId: agentId, historyEndpoint: `${baseUrl}/api/v1/history`, suggestions: [
|
|
86
88
|
{
|
|
87
89
|
title: 'Read the pre-hook marker file',
|
|
88
90
|
message: 'Use execute_code to read /tmp/agent_runtimes_pre_hook_demo.txt and show its contents.',
|
|
89
91
|
},
|
|
90
92
|
{
|
|
91
93
|
title: 'Verify hook variables',
|
|
92
|
-
message: 'Use execute_code to run this verification:\n```python\nassert isinstance(hook_name, str) and hook_name == "
|
|
94
|
+
message: 'Use execute_code to run this verification:\n```python\nassert isinstance(hook_name, str) and hook_name == "example-hooks:pre", f"❌ hook_name wrong: {hook_name!r}"\nassert isinstance(hook_ran_at, str) and len(hook_ran_at) > 0, f"❌ hook_ran_at wrong: {hook_ran_at!r}"\nassert isinstance(hook_env, dict) and len(hook_env) > 0, f"❌ hook_env wrong: {hook_env!r}"\nprint("✅ hook_name =", hook_name)\nprint("✅ hook_ran_at =", hook_ran_at)\nprint("✅ hook_env =", hook_env)\n```\nThrow an exception with a ❌ message if any variable is missing or has the wrong type, print ✅ lines if all pass.',
|
|
93
95
|
},
|
|
94
96
|
{
|
|
95
97
|
title: "Verify 'rich' was installed",
|
|
@@ -99,6 +101,22 @@ const AgentHooksExample = () => {
|
|
|
99
101
|
title: 'Explain the hook lifecycle',
|
|
100
102
|
message: 'What pre-hooks and post-hooks are configured for this agent, and when does each run?',
|
|
101
103
|
},
|
|
104
|
+
{
|
|
105
|
+
title: 'Trigger function + python tool hooks',
|
|
106
|
+
message: "Call runtime_sensitive_echo with text 'hello' and reason 'audit', then explain which before_tool_execute hooks ran (function and python).",
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
title: 'Trigger deny in python hook',
|
|
110
|
+
message: "Call runtime_sensitive_echo with text 'danger' and reason 'delete notebook', then explain why local Python policy denied it.",
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
title: 'Read tool approval audit log',
|
|
114
|
+
message: 'Use execute_code to show the latest entries from /tmp/agent_runtimes_tool_approvals_audit.jsonl and summarize decision and execution status.',
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
title: 'Explain deferred hook handling',
|
|
118
|
+
message: 'Explain how deferred_tool_calls works with approval-required tools and when inline resolution is used in this run.',
|
|
119
|
+
},
|
|
102
120
|
], submitOnSuggestionClick: true }));
|
|
103
121
|
};
|
|
104
122
|
export default AgentHooksExample;
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2025-2026 Datalayer, Inc.
|
|
4
|
+
* Distributed under the terms of the Modified BSD License.
|
|
5
|
+
*/
|
|
6
|
+
/// <reference types="vite/client" />
|
|
7
|
+
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
8
|
+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
9
|
+
import { Button, Box, Heading, SegmentedControl, Spinner, Text, } from '@primer/react';
|
|
10
|
+
import { ThemedProvider } from './utils/themedProvider';
|
|
11
|
+
import { uniqueAgentId } from './utils/agentId';
|
|
12
|
+
import { useSimpleAuthStore } from '@datalayer/core/lib/views/otel';
|
|
13
|
+
import { Chat } from '../chat';
|
|
14
|
+
import { useAIAgentsWebSocket } from '../hooks';
|
|
15
|
+
const AGENT_SPEC_ID = 'example-inference';
|
|
16
|
+
const AGENT_NAME = 'inference-provider-example-agent';
|
|
17
|
+
const DEFAULT_LOCAL_BASE_URL = import.meta.env.VITE_BASE_URL || 'http://localhost:8765';
|
|
18
|
+
const queryClient = new QueryClient();
|
|
19
|
+
const nowIso = () => new Date().toISOString();
|
|
20
|
+
const toErrorMessage = (error) => error instanceof Error ? error.message : String(error);
|
|
21
|
+
const stringifyPayload = (value) => {
|
|
22
|
+
if (typeof value === 'string') {
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
return JSON.stringify(value, null, 2);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return String(value);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
const ProviderBadge = ({ provider, }) => (_jsx(Box, { sx: {
|
|
33
|
+
px: 2,
|
|
34
|
+
py: '2px',
|
|
35
|
+
borderRadius: 999,
|
|
36
|
+
border: '1px solid',
|
|
37
|
+
borderColor: 'border.default',
|
|
38
|
+
fontSize: 0,
|
|
39
|
+
color: 'fg.muted',
|
|
40
|
+
bg: 'canvas.inset',
|
|
41
|
+
textTransform: 'uppercase',
|
|
42
|
+
letterSpacing: '0.03em',
|
|
43
|
+
}, children: provider }));
|
|
44
|
+
const AgentInferenceProviderExampleInner = () => {
|
|
45
|
+
const { token } = useSimpleAuthStore();
|
|
46
|
+
const [provider, setProvider] = useState('local');
|
|
47
|
+
const [agentId, setAgentId] = useState(null);
|
|
48
|
+
const [isLaunching, setIsLaunching] = useState(true);
|
|
49
|
+
const [error, setError] = useState(null);
|
|
50
|
+
const [providerEvents, setProviderEvents] = useState([]);
|
|
51
|
+
const [expandedEventIds, setExpandedEventIds] = useState(() => new Set());
|
|
52
|
+
const currentAgentRef = useRef(null);
|
|
53
|
+
const requestEpochRef = useRef(0);
|
|
54
|
+
const baseUrl = DEFAULT_LOCAL_BASE_URL;
|
|
55
|
+
const inferenceUrl = useMemo(() => {
|
|
56
|
+
if (provider === 'local') {
|
|
57
|
+
return 'local inference';
|
|
58
|
+
}
|
|
59
|
+
const env = import.meta.env ?? {};
|
|
60
|
+
return (env.VITE_DATALAYER_AI_INFERENCE_URL ||
|
|
61
|
+
env.VITE_DATALAYER_RUN_URL ||
|
|
62
|
+
'https://prod1.datalayer.run');
|
|
63
|
+
}, [provider]);
|
|
64
|
+
const authFetch = useCallback((url, init = {}) => {
|
|
65
|
+
return fetch(url, {
|
|
66
|
+
...init,
|
|
67
|
+
headers: {
|
|
68
|
+
'Content-Type': 'application/json',
|
|
69
|
+
...(token ? { Authorization: `Bearer ${token}` } : {}),
|
|
70
|
+
...(init.headers ?? {}),
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
}, [token]);
|
|
74
|
+
const appendProviderEvent = useCallback((type, summary, payload) => {
|
|
75
|
+
setProviderEvents(prev => [
|
|
76
|
+
{
|
|
77
|
+
id: `${Date.now()}-${Math.random().toString(36).slice(2)}`,
|
|
78
|
+
type,
|
|
79
|
+
summary,
|
|
80
|
+
payload: stringifyPayload(payload),
|
|
81
|
+
createdAt: nowIso(),
|
|
82
|
+
},
|
|
83
|
+
...prev,
|
|
84
|
+
]);
|
|
85
|
+
}, []);
|
|
86
|
+
const deleteAgent = useCallback(async (id) => {
|
|
87
|
+
await authFetch(`${baseUrl}/api/v1/agents/${encodeURIComponent(id)}`, {
|
|
88
|
+
method: 'DELETE',
|
|
89
|
+
}).catch(() => {
|
|
90
|
+
// Best-effort cleanup in example mode.
|
|
91
|
+
});
|
|
92
|
+
}, [authFetch, baseUrl]);
|
|
93
|
+
const launchAgentForProvider = useCallback(async (nextProvider) => {
|
|
94
|
+
requestEpochRef.current += 1;
|
|
95
|
+
const requestEpoch = requestEpochRef.current;
|
|
96
|
+
setIsLaunching(true);
|
|
97
|
+
setError(null);
|
|
98
|
+
const previousAgentId = currentAgentRef.current;
|
|
99
|
+
if (previousAgentId) {
|
|
100
|
+
await deleteAgent(previousAgentId);
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
const configureResponse = await authFetch(`${baseUrl}/api/v1/configure/inference/provider`, {
|
|
104
|
+
method: 'PUT',
|
|
105
|
+
body: JSON.stringify({ provider: nextProvider }),
|
|
106
|
+
});
|
|
107
|
+
appendProviderEvent('configure.provider', `Configured runtime inference provider to ${nextProvider}`, {
|
|
108
|
+
status: configureResponse.status,
|
|
109
|
+
provider: nextProvider,
|
|
110
|
+
});
|
|
111
|
+
const name = uniqueAgentId(`${AGENT_NAME}-${nextProvider}`);
|
|
112
|
+
const createResponse = await authFetch(`${baseUrl}/api/v1/agents`, {
|
|
113
|
+
method: 'POST',
|
|
114
|
+
body: JSON.stringify({
|
|
115
|
+
name,
|
|
116
|
+
transport: 'vercel-ai',
|
|
117
|
+
agent_spec_id: AGENT_SPEC_ID,
|
|
118
|
+
inferenceProvider: nextProvider,
|
|
119
|
+
}),
|
|
120
|
+
});
|
|
121
|
+
if (!createResponse.ok) {
|
|
122
|
+
const detail = await createResponse.text();
|
|
123
|
+
throw new Error(detail || `Failed to create agent (${createResponse.status})`);
|
|
124
|
+
}
|
|
125
|
+
const payload = (await createResponse.json());
|
|
126
|
+
const nextAgentId = payload.id || name;
|
|
127
|
+
if (requestEpoch !== requestEpochRef.current) {
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
currentAgentRef.current = nextAgentId;
|
|
131
|
+
setAgentId(nextAgentId);
|
|
132
|
+
appendProviderEvent('agent.created', 'Launched local agent runtime', {
|
|
133
|
+
agentId: nextAgentId,
|
|
134
|
+
agentSpecId: AGENT_SPEC_ID,
|
|
135
|
+
inferenceProvider: nextProvider,
|
|
136
|
+
baseUrl,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
catch (launchError) {
|
|
140
|
+
if (requestEpoch !== requestEpochRef.current) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
setAgentId(null);
|
|
144
|
+
currentAgentRef.current = null;
|
|
145
|
+
setError(toErrorMessage(launchError));
|
|
146
|
+
appendProviderEvent('agent.error', 'Failed to launch agent', {
|
|
147
|
+
provider: nextProvider,
|
|
148
|
+
error: toErrorMessage(launchError),
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
if (requestEpoch === requestEpochRef.current) {
|
|
153
|
+
setIsLaunching(false);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}, [appendProviderEvent, authFetch, baseUrl, deleteAgent]);
|
|
157
|
+
useEffect(() => {
|
|
158
|
+
void launchAgentForProvider(provider);
|
|
159
|
+
}, [launchAgentForProvider, provider]);
|
|
160
|
+
useEffect(() => {
|
|
161
|
+
return () => {
|
|
162
|
+
const existing = currentAgentRef.current;
|
|
163
|
+
if (existing) {
|
|
164
|
+
void deleteAgent(existing);
|
|
165
|
+
}
|
|
166
|
+
};
|
|
167
|
+
}, [deleteAgent]);
|
|
168
|
+
const onProviderChange = useCallback((next) => {
|
|
169
|
+
setProvider(next);
|
|
170
|
+
}, []);
|
|
171
|
+
useAIAgentsWebSocket({
|
|
172
|
+
enabled: Boolean(agentId) && !isLaunching,
|
|
173
|
+
baseUrl,
|
|
174
|
+
path: '/api/v1/tool-approvals/ws',
|
|
175
|
+
queryParams: agentId ? { agent_id: agentId } : undefined,
|
|
176
|
+
onMessage: message => {
|
|
177
|
+
const eventType = typeof message.type === 'string'
|
|
178
|
+
? message.type
|
|
179
|
+
: typeof message.event === 'string'
|
|
180
|
+
? message.event
|
|
181
|
+
: 'stream.message';
|
|
182
|
+
appendProviderEvent('provider.stream', `Received ${eventType}`, {
|
|
183
|
+
provider,
|
|
184
|
+
agentId,
|
|
185
|
+
message: message.raw ?? message,
|
|
186
|
+
});
|
|
187
|
+
},
|
|
188
|
+
reconnectDelayMs: attempt => Math.min(1000 * 2 ** Math.max(0, attempt - 1), 10000),
|
|
189
|
+
});
|
|
190
|
+
const orderedProviderEvents = useMemo(() => [...providerEvents].sort((a, b) => b.createdAt.localeCompare(a.createdAt)), [providerEvents]);
|
|
191
|
+
const toggleEventExpanded = useCallback((eventId) => {
|
|
192
|
+
setExpandedEventIds(prev => {
|
|
193
|
+
const next = new Set(prev);
|
|
194
|
+
if (next.has(eventId)) {
|
|
195
|
+
next.delete(eventId);
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
next.add(eventId);
|
|
199
|
+
}
|
|
200
|
+
return next;
|
|
201
|
+
});
|
|
202
|
+
}, []);
|
|
203
|
+
return (_jsx(ThemedProvider, { children: _jsxs(Box, { sx: {
|
|
204
|
+
height: '100%',
|
|
205
|
+
minHeight: 0,
|
|
206
|
+
width: '100%',
|
|
207
|
+
display: 'grid',
|
|
208
|
+
gridTemplateColumns: ['1fr', '1fr', 'minmax(680px, 1fr) 420px'],
|
|
209
|
+
gridTemplateRows: 'minmax(0, 1fr)',
|
|
210
|
+
overflow: 'hidden',
|
|
211
|
+
bg: 'canvas.default',
|
|
212
|
+
}, children: [_jsxs(Box, { sx: {
|
|
213
|
+
height: '100%',
|
|
214
|
+
borderRight: ['none', 'none', '1px solid'],
|
|
215
|
+
borderColor: 'border.default',
|
|
216
|
+
p: 3,
|
|
217
|
+
display: 'flex',
|
|
218
|
+
flexDirection: 'column',
|
|
219
|
+
gap: 3,
|
|
220
|
+
minHeight: 0,
|
|
221
|
+
overflow: 'hidden',
|
|
222
|
+
}, children: [_jsxs(Box, { sx: {
|
|
223
|
+
display: 'flex',
|
|
224
|
+
justifyContent: 'space-between',
|
|
225
|
+
alignItems: 'center',
|
|
226
|
+
flexWrap: 'wrap',
|
|
227
|
+
gap: 2,
|
|
228
|
+
}, children: [_jsxs(Box, { children: [_jsx(Heading, { as: "h2", sx: { fontSize: 4, mb: 1 }, children: "Agent Inference Provider Example" }), _jsxs(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: ["Launches a local agent runtime from ", AGENT_SPEC_ID, " and lets you switch between local and datalayer inference."] })] }), _jsx(ProviderBadge, { provider: provider })] }), _jsxs(SegmentedControl, { "aria-label": "Inference provider", fullWidth: true, children: [_jsx(SegmentedControl.Button, { selected: provider === 'local', onClick: () => onProviderChange('local'), children: "local" }), _jsx(SegmentedControl.Button, { selected: provider === 'datalayer', onClick: () => onProviderChange('datalayer'), children: "datalayer" })] }), _jsxs(Box, { sx: {
|
|
229
|
+
display: 'flex',
|
|
230
|
+
gap: 2,
|
|
231
|
+
alignItems: 'center',
|
|
232
|
+
flexWrap: 'wrap',
|
|
233
|
+
}, children: [isLaunching ? _jsx(Spinner, { size: "small" }) : null, _jsxs(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: ["Runtime URL: ", baseUrl] }), _jsxs(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: ["Inference URL: ", inferenceUrl] }), _jsxs(Text, { sx: { fontSize: 1, color: 'fg.muted' }, children: ["Agent ID: ", agentId || 'launching...'] })] }), error ? (_jsx(Box, { sx: {
|
|
234
|
+
p: 2,
|
|
235
|
+
borderRadius: 2,
|
|
236
|
+
border: '1px solid',
|
|
237
|
+
borderColor: 'danger.emphasis',
|
|
238
|
+
bg: 'danger.subtle',
|
|
239
|
+
color: 'danger.fg',
|
|
240
|
+
fontSize: 1,
|
|
241
|
+
}, children: error })) : null, _jsx(Box, { sx: {
|
|
242
|
+
flexGrow: 1,
|
|
243
|
+
flexShrink: 1,
|
|
244
|
+
flexBasis: 0,
|
|
245
|
+
minHeight: 0,
|
|
246
|
+
border: '1px solid',
|
|
247
|
+
borderColor: 'border.default',
|
|
248
|
+
borderRadius: 2,
|
|
249
|
+
overflow: 'hidden',
|
|
250
|
+
bg: 'canvas.default',
|
|
251
|
+
}, children: agentId && !isLaunching ? (_jsx(Chat, { protocol: "vercel-ai", baseUrl: baseUrl, agentId: agentId, authToken: token ?? undefined, title: "Agent Inference Provider Example", subtitle: `Spec: ${AGENT_SPEC_ID}`, placeholder: "Ask the inference provider something...", showHeader: true, showNewChatButton: true, showClearButton: false, showModelSelector: true, showToolsMenu: true, showSkillsMenu: true, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${baseUrl}/api/v1/history`, onMessageSent: content => {
|
|
252
|
+
appendProviderEvent('provider.request', `Sent message via ${provider}`, {
|
|
253
|
+
provider,
|
|
254
|
+
agentId,
|
|
255
|
+
content,
|
|
256
|
+
});
|
|
257
|
+
}, onMessageReceived: message => {
|
|
258
|
+
appendProviderEvent('provider.message', 'Received stream message', message);
|
|
259
|
+
}, suggestions: [
|
|
260
|
+
{
|
|
261
|
+
title: 'Compare providers',
|
|
262
|
+
message: 'Give me a short 3-point comparison between local and datalayer inference providers.',
|
|
263
|
+
},
|
|
264
|
+
], submitOnSuggestionClick: true })) : (_jsxs(Box, { sx: {
|
|
265
|
+
height: '100%',
|
|
266
|
+
display: 'flex',
|
|
267
|
+
alignItems: 'center',
|
|
268
|
+
justifyContent: 'center',
|
|
269
|
+
gap: 2,
|
|
270
|
+
color: 'fg.muted',
|
|
271
|
+
}, children: [_jsx(Spinner, { size: "small" }), _jsx(Text, { sx: { fontSize: 1 }, children: "Launching provider runtime\u2026" })] })) })] }), _jsxs(Box, { sx: {
|
|
272
|
+
p: 3,
|
|
273
|
+
display: ['none', 'none', 'flex'],
|
|
274
|
+
flexDirection: 'column',
|
|
275
|
+
gap: 2,
|
|
276
|
+
minHeight: 0,
|
|
277
|
+
overflow: 'hidden',
|
|
278
|
+
bg: 'canvas.inset',
|
|
279
|
+
}, children: [_jsx(Heading, { as: "h3", sx: { fontSize: 2 }, children: "Provider Event Stream" }), _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "Low-level request/response events exchanged with the inference provider (newest first)." }), _jsx(Box, { sx: {
|
|
280
|
+
flex: 1,
|
|
281
|
+
minHeight: 0,
|
|
282
|
+
overflowY: 'auto',
|
|
283
|
+
display: 'flex',
|
|
284
|
+
flexDirection: 'column',
|
|
285
|
+
gap: 2,
|
|
286
|
+
}, children: providerEvents.length === 0 ? (_jsx(Box, { sx: {
|
|
287
|
+
border: '1px dashed',
|
|
288
|
+
borderColor: 'border.default',
|
|
289
|
+
borderRadius: 2,
|
|
290
|
+
p: 3,
|
|
291
|
+
}, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: "No provider events yet." }) })) : (orderedProviderEvents.map(event => (_jsxs(Box, { sx: {
|
|
292
|
+
border: '1px solid',
|
|
293
|
+
borderColor: 'border.default',
|
|
294
|
+
borderRadius: 2,
|
|
295
|
+
p: 2,
|
|
296
|
+
bg: 'canvas.default',
|
|
297
|
+
}, children: [_jsx(Text, { sx: {
|
|
298
|
+
display: 'block',
|
|
299
|
+
fontSize: 0,
|
|
300
|
+
color: 'fg.muted',
|
|
301
|
+
textTransform: 'uppercase',
|
|
302
|
+
letterSpacing: '0.04em',
|
|
303
|
+
}, children: event.type }), _jsx(Text, { sx: {
|
|
304
|
+
display: 'block',
|
|
305
|
+
fontWeight: 600,
|
|
306
|
+
fontSize: 1,
|
|
307
|
+
mt: 1,
|
|
308
|
+
}, children: event.summary }), _jsx(Text, { sx: {
|
|
309
|
+
display: 'block',
|
|
310
|
+
color: 'fg.muted',
|
|
311
|
+
fontSize: 0,
|
|
312
|
+
mt: 1,
|
|
313
|
+
}, children: new Date(event.createdAt).toLocaleTimeString() }), _jsx(Box, { sx: { mt: 2 }, children: _jsx(Button, { size: "small", variant: "invisible", onClick: () => toggleEventExpanded(event.id), children: expandedEventIds.has(event.id)
|
|
314
|
+
? 'Hide details'
|
|
315
|
+
: 'Show details' }) }), expandedEventIds.has(event.id) ? (_jsx(Text, { as: "pre", sx: {
|
|
316
|
+
mt: 2,
|
|
317
|
+
mb: 0,
|
|
318
|
+
p: 2,
|
|
319
|
+
borderRadius: 2,
|
|
320
|
+
bg: 'canvas.subtle',
|
|
321
|
+
fontSize: 0,
|
|
322
|
+
whiteSpace: 'pre-wrap',
|
|
323
|
+
fontFamily: 'mono',
|
|
324
|
+
}, children: event.payload })) : null] }, event.id)))) })] })] }) }));
|
|
325
|
+
};
|
|
326
|
+
const AgentInferenceProviderExample = () => {
|
|
327
|
+
return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(AgentInferenceProviderExampleInner, {}) }));
|
|
328
|
+
};
|
|
329
|
+
export default AgentInferenceProviderExample;
|
|
@@ -19,8 +19,9 @@ import { parseAgentStreamMessage } from '../types/stream';
|
|
|
19
19
|
import { MCP_STATUS_COLORS, MCP_STATUS_LABELS } from '../types/mcp';
|
|
20
20
|
import { MCP_SERVER_LIBRARY } from '../specs/mcpServers';
|
|
21
21
|
const queryClient = new QueryClient();
|
|
22
|
-
const AGENT_NAME = 'mcp-
|
|
23
|
-
|
|
22
|
+
const AGENT_NAME = 'mcp-example-agent';
|
|
23
|
+
// Must match agentspecs/agentspecs/agents/example-mcp.yaml `id`.
|
|
24
|
+
const AGENT_SPEC_ID = 'example-mcp';
|
|
24
25
|
const DEFAULT_LOCAL_BASE_URL = import.meta.env.VITE_BASE_URL || 'http://localhost:8765';
|
|
25
26
|
/* ── Aggregate MCP status helpers ─────────────────────── */
|
|
26
27
|
function deriveAggregate(servers) {
|
|
@@ -149,7 +150,7 @@ const AgentMCPInner = ({ onLogout }) => {
|
|
|
149
150
|
method: 'POST',
|
|
150
151
|
body: JSON.stringify({
|
|
151
152
|
name: agentName,
|
|
152
|
-
description: 'MCP
|
|
153
|
+
description: 'MCP example agent – web crawling and research via Tavily',
|
|
153
154
|
agent_library: 'pydantic-ai',
|
|
154
155
|
transport: 'vercel-ai',
|
|
155
156
|
agent_spec_id: AGENT_SPEC_ID,
|
|
@@ -372,7 +373,7 @@ const AgentMCPInner = ({ onLogout }) => {
|
|
|
372
373
|
justifyContent: 'center',
|
|
373
374
|
height: '100vh',
|
|
374
375
|
gap: 3,
|
|
375
|
-
}, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Launching MCP
|
|
376
|
+
}, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Launching MCP example agent..." })] }));
|
|
376
377
|
}
|
|
377
378
|
if (runtimeStatus === 'error' || hookError) {
|
|
378
379
|
return _jsx(ErrorView, { error: hookError, onLogout: onLogout });
|
|
@@ -386,7 +387,7 @@ const AgentMCPInner = ({ onLogout }) => {
|
|
|
386
387
|
py: 1,
|
|
387
388
|
borderBottom: '1px solid',
|
|
388
389
|
borderColor: 'border.default',
|
|
389
|
-
}, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: "Agent already running - reconnected." }) })), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, authToken: chatAuthToken, title: "MCP Demo Agent", placeholder: "Ask the agent to search the web or explore GitHub...", showHeader: true, showNewChatButton: true, showClearButton: false, showToolsMenu: true, showSkillsMenu: true, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, mcpStatusData: mcpStatusData, showToolApprovalBanner: true, headerActions: _jsx(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: _jsxs(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: ["MCP Tools: ", totalTools] }) }), suggestions: [
|
|
390
|
+
}, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: "Agent already running - reconnected." }) })), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, authToken: chatAuthToken, title: "MCP Demo Agent", brandIcon: _jsx(GlobeIcon, { size: 16 }), placeholder: "Ask the agent to search the web or explore GitHub...", showHeader: true, showNewChatButton: true, showClearButton: false, showToolsMenu: true, showSkillsMenu: true, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, mcpStatusData: mcpStatusData, showToolApprovalBanner: true, headerActions: _jsx(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: _jsxs(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: ["MCP Tools: ", totalTools] }) }), suggestions: [
|
|
390
391
|
{
|
|
391
392
|
title: '🔍 Search the web',
|
|
392
393
|
message: 'Search the web for recent news about AI agents.',
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
* AgentMemoryExample
|
|
3
3
|
*
|
|
4
4
|
* Demonstrates the Mem0 memory backend for durable agents.
|
|
5
|
-
* Creates a
|
|
6
|
-
* Runtimes API, then deploys an agent with persistent memory on its sidecar.
|
|
5
|
+
* Creates a local agent-runtimes agent using the `example-memory` spec.
|
|
7
6
|
*
|
|
8
7
|
* The left panel shows a standard Chat. The right panel shows the
|
|
9
8
|
* agent's memory contents (fetched from the runtime sidecar) and lets
|
|
@@ -7,8 +7,7 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
7
7
|
* AgentMemoryExample
|
|
8
8
|
*
|
|
9
9
|
* Demonstrates the Mem0 memory backend for durable agents.
|
|
10
|
-
* Creates a
|
|
11
|
-
* Runtimes API, then deploys an agent with persistent memory on its sidecar.
|
|
10
|
+
* Creates a local agent-runtimes agent using the `example-memory` spec.
|
|
12
11
|
*
|
|
13
12
|
* The left panel shows a standard Chat. The right panel shows the
|
|
14
13
|
* agent's memory contents (fetched from the runtime sidecar) and lets
|
|
@@ -26,31 +25,24 @@ import { uniqueAgentId } from './utils/agentId';
|
|
|
26
25
|
const queryClient = new QueryClient();
|
|
27
26
|
import { useSimpleAuthStore } from '@datalayer/core/lib/views/otel';
|
|
28
27
|
import { Chat } from '../chat';
|
|
29
|
-
import {
|
|
28
|
+
import { useExampleAgentRuntimesUrl } from './utils/useExampleAgentRuntimesUrl';
|
|
30
29
|
// ─── Constants ─────────────────────────────────────────────────────────────
|
|
31
|
-
const AGENT_NAME = 'memory-
|
|
32
|
-
const AGENT_SPEC_ID = '
|
|
30
|
+
const AGENT_NAME = 'memory-example-agent';
|
|
31
|
+
const AGENT_SPEC_ID = 'example-memory';
|
|
33
32
|
// ─── Inner component (rendered after auth) ─────────────────────────────────
|
|
34
33
|
const AgentMemoryInner = ({ onLogout }) => {
|
|
35
34
|
const { token } = useSimpleAuthStore();
|
|
36
35
|
const agentName = useRef(uniqueAgentId(AGENT_NAME)).current;
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
model: 'bedrock:us.anthropic.claude-3-5-haiku-20241022-v1:0',
|
|
43
|
-
protocol: 'vercel-ai',
|
|
44
|
-
description: 'Agent with Mem0 persistent memory',
|
|
45
|
-
},
|
|
46
|
-
});
|
|
36
|
+
const agentBaseUrl = useExampleAgentRuntimesUrl();
|
|
37
|
+
const [runtimeStatus, setRuntimeStatus] = useState('launching');
|
|
38
|
+
const [isReady, setIsReady] = useState(false);
|
|
39
|
+
const [hookError, setHookError] = useState(null);
|
|
40
|
+
const [agentId, setAgentId] = useState(agentName);
|
|
47
41
|
const [memories, setMemories] = useState([]);
|
|
48
42
|
const [searchQuery, setSearchQuery] = useState('');
|
|
49
43
|
const [searchResults, setSearchResults] = useState([]);
|
|
50
44
|
const [searching, setSearching] = useState(false);
|
|
51
|
-
const
|
|
52
|
-
const agentId = runtime?.agentId || AGENT_NAME;
|
|
53
|
-
const podName = runtime?.podName || '(launching…)';
|
|
45
|
+
const podName = isReady ? `local:${agentId}` : '(launching…)';
|
|
54
46
|
// Authenticated fetch helper (for sidecar endpoints)
|
|
55
47
|
const authFetch = useCallback((url, opts = {}) => fetch(url, {
|
|
56
48
|
...opts,
|
|
@@ -60,6 +52,65 @@ const AgentMemoryInner = ({ onLogout }) => {
|
|
|
60
52
|
...(opts.headers ?? {}),
|
|
61
53
|
},
|
|
62
54
|
}), [token]);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
let isCancelled = false;
|
|
57
|
+
const createLocalAgent = async () => {
|
|
58
|
+
setRuntimeStatus('launching');
|
|
59
|
+
setIsReady(false);
|
|
60
|
+
setHookError(null);
|
|
61
|
+
try {
|
|
62
|
+
const response = await authFetch(`${agentBaseUrl}/api/v1/agents`, {
|
|
63
|
+
method: 'POST',
|
|
64
|
+
body: JSON.stringify({
|
|
65
|
+
name: agentName,
|
|
66
|
+
description: 'Agent with Mem0 persistent memory',
|
|
67
|
+
agent_library: 'pydantic-ai',
|
|
68
|
+
transport: 'vercel-ai',
|
|
69
|
+
agent_spec_id: AGENT_SPEC_ID,
|
|
70
|
+
enable_skills: true,
|
|
71
|
+
tools: [],
|
|
72
|
+
}),
|
|
73
|
+
});
|
|
74
|
+
let resolvedAgentId = agentName;
|
|
75
|
+
if (response.ok) {
|
|
76
|
+
const data = await response.json();
|
|
77
|
+
resolvedAgentId = data?.id || agentName;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
const contentType = response.headers.get('content-type') || '';
|
|
81
|
+
let detail = '';
|
|
82
|
+
if (contentType.includes('application/json')) {
|
|
83
|
+
const data = await response.json().catch(() => null);
|
|
84
|
+
detail =
|
|
85
|
+
(typeof data?.detail === 'string' && data.detail) ||
|
|
86
|
+
(typeof data?.message === 'string' && data.message) ||
|
|
87
|
+
'';
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
detail = await response.text();
|
|
91
|
+
}
|
|
92
|
+
if (!(response.status === 409 || /already exists/i.test(detail))) {
|
|
93
|
+
throw new Error(detail || `Failed to create local agent: ${response.status}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (!isCancelled) {
|
|
97
|
+
setAgentId(resolvedAgentId);
|
|
98
|
+
setIsReady(true);
|
|
99
|
+
setRuntimeStatus('ready');
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch (error) {
|
|
103
|
+
if (!isCancelled) {
|
|
104
|
+
setHookError(error instanceof Error ? error.message : 'Agent failed to start');
|
|
105
|
+
setRuntimeStatus('error');
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
void createLocalAgent();
|
|
110
|
+
return () => {
|
|
111
|
+
isCancelled = true;
|
|
112
|
+
};
|
|
113
|
+
}, [agentBaseUrl, agentName, authFetch]);
|
|
63
114
|
// ── Fetch memory list ────────────────────────────────────────────────────
|
|
64
115
|
const fetchMemories = useCallback(async () => {
|
|
65
116
|
if (!isReady || !agentBaseUrl)
|
|
@@ -113,9 +164,7 @@ const AgentMemoryInner = ({ onLogout }) => {
|
|
|
113
164
|
justifyContent: 'center',
|
|
114
165
|
height: '100vh',
|
|
115
166
|
gap: 3,
|
|
116
|
-
}, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children:
|
|
117
|
-
? 'Launching runtime for memory agent…'
|
|
118
|
-
: 'Creating memory-enabled agent…' })] }));
|
|
167
|
+
}, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Launching local memory-enabled agent\u2026" })] }));
|
|
119
168
|
}
|
|
120
169
|
if (runtimeStatus === 'error' || hookError) {
|
|
121
170
|
return _jsx(ErrorView, { error: hookError, onLogout: onLogout });
|
|
@@ -139,7 +188,7 @@ const AgentMemoryInner = ({ onLogout }) => {
|
|
|
139
188
|
minWidth: 0,
|
|
140
189
|
borderRight: '1px solid',
|
|
141
190
|
borderColor: 'border.default',
|
|
142
|
-
}, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, title: "Memory Agent", placeholder: "Chat \u2014 the agent remembers you across sessions\u2026", description: "Agent with Mem0 persistent memory", showHeader: true, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: podName, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
|
|
191
|
+
}, children: _jsx(Chat, { protocol: "vercel-ai", baseUrl: agentBaseUrl, agentId: agentId, title: "Memory Agent", brandIcon: _jsx(DatabaseIcon, { size: 16 }), placeholder: "Chat \u2014 the agent remembers you across sessions\u2026", description: "Agent with Mem0 persistent memory", showHeader: true, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: podName, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
|
|
143
192
|
{
|
|
144
193
|
title: 'Remember',
|
|
145
194
|
message: 'My favourite colour is midnight blue.',
|