@datalayer/agent-runtimes 1.0.3 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (275) hide show
  1. package/README.md +35 -119
  2. package/lib/App.js +1 -1
  3. package/lib/agents/AgentDetails.d.ts +22 -1
  4. package/lib/agents/AgentDetails.js +34 -47
  5. package/lib/api/index.d.ts +0 -1
  6. package/lib/api/index.js +4 -2
  7. package/lib/chat/Chat.d.ts +5 -104
  8. package/lib/chat/Chat.js +4 -4
  9. package/lib/chat/ChatFloating.d.ts +7 -140
  10. package/lib/chat/ChatFloating.js +2 -2
  11. package/lib/chat/ChatPopupStandalone.d.ts +8 -47
  12. package/lib/chat/ChatPopupStandalone.js +3 -3
  13. package/lib/chat/ChatSidebar.d.ts +4 -69
  14. package/lib/chat/ChatSidebar.js +2 -2
  15. package/lib/chat/ChatStandalone.d.ts +4 -54
  16. package/lib/chat/ChatStandalone.js +3 -3
  17. package/lib/chat/base/ChatBase.js +1118 -141
  18. package/lib/chat/header/ChatHeaderBase.d.ts +11 -6
  19. package/lib/chat/header/ChatHeaderBase.js +18 -16
  20. package/lib/chat/indicators/McpStatusIndicator.d.ts +7 -4
  21. package/lib/chat/indicators/McpStatusIndicator.js +7 -32
  22. package/lib/chat/indicators/SandboxStatusIndicator.d.ts +4 -1
  23. package/lib/chat/indicators/SandboxStatusIndicator.js +9 -9
  24. package/lib/chat/indicators/SkillsStatusIndicator.d.ts +7 -0
  25. package/lib/chat/indicators/SkillsStatusIndicator.js +88 -0
  26. package/lib/chat/indicators/index.d.ts +1 -0
  27. package/lib/chat/indicators/index.js +1 -0
  28. package/lib/chat/messages/ChatMessageList.d.ts +1 -1
  29. package/lib/chat/messages/ChatMessageList.js +110 -102
  30. package/lib/chat/prompt/InputFooter.d.ts +19 -6
  31. package/lib/chat/prompt/InputFooter.js +71 -18
  32. package/lib/chat/prompt/InputPrompt.d.ts +3 -1
  33. package/lib/chat/prompt/InputPrompt.js +4 -4
  34. package/lib/chat/prompt/InputPromptFooter.js +1 -1
  35. package/lib/chat/prompt/InputPromptLexical.d.ts +3 -1
  36. package/lib/chat/prompt/InputPromptLexical.js +12 -5
  37. package/lib/chat/prompt/InputPromptText.d.ts +3 -1
  38. package/lib/chat/prompt/InputPromptText.js +2 -2
  39. package/lib/chat/tools/ToolApprovalBanner.js +1 -1
  40. package/lib/chat/tools/ToolCallDisplay.d.ts +3 -1
  41. package/lib/chat/tools/ToolCallDisplay.js +2 -2
  42. package/lib/chat/usage/TokenUsageBar.js +20 -2
  43. package/lib/client/AgentRuntimesClientContext.d.ts +53 -0
  44. package/lib/client/AgentRuntimesClientContext.js +55 -0
  45. package/lib/client/AgentsMixin.d.ts +48 -19
  46. package/lib/client/AgentsMixin.js +115 -30
  47. package/lib/client/IAgentRuntimesClient.d.ts +215 -0
  48. package/lib/client/IAgentRuntimesClient.js +5 -0
  49. package/lib/client/SdkAgentRuntimesClient.d.ts +151 -0
  50. package/lib/client/SdkAgentRuntimesClient.js +134 -0
  51. package/lib/client/index.d.ts +4 -1
  52. package/lib/client/index.js +3 -1
  53. package/lib/components/NotificationEventCard.js +55 -26
  54. package/lib/components/OutputCard.js +21 -7
  55. package/lib/components/ToolApprovalCard.js +20 -2
  56. package/lib/config/AgentConfiguration.js +3 -3
  57. package/lib/context/ContextDistribution.d.ts +3 -1
  58. package/lib/context/ContextDistribution.js +8 -27
  59. package/lib/context/ContextInspector.d.ts +3 -1
  60. package/lib/context/ContextInspector.js +19 -67
  61. package/lib/context/ContextPanel.d.ts +3 -1
  62. package/lib/context/ContextPanel.js +104 -64
  63. package/lib/context/ContextUsage.d.ts +3 -1
  64. package/lib/context/ContextUsage.js +3 -3
  65. package/lib/context/CostTracker.d.ts +9 -3
  66. package/lib/context/CostTracker.js +26 -47
  67. package/lib/context/CostUsageChart.d.ts +12 -0
  68. package/lib/context/CostUsageChart.js +378 -0
  69. package/lib/context/GraphFlowChart.d.ts +16 -0
  70. package/lib/context/GraphFlowChart.js +182 -0
  71. package/lib/context/TokenUsageChart.d.ts +8 -1
  72. package/lib/context/TokenUsageChart.js +349 -211
  73. package/lib/context/TurnGraphChart.d.ts +39 -0
  74. package/lib/context/TurnGraphChart.js +538 -0
  75. package/lib/context/otelWsPool.d.ts +20 -0
  76. package/lib/context/otelWsPool.js +69 -0
  77. package/lib/examples/A2UiComponentGalleryExample.d.ts +0 -17
  78. package/lib/examples/A2UiComponentGalleryExample.js +315 -522
  79. package/lib/examples/A2UiContactCardExample.d.ts +0 -18
  80. package/lib/examples/A2UiContactCardExample.js +154 -411
  81. package/lib/examples/A2UiRestaurantExample.d.ts +0 -30
  82. package/lib/examples/A2UiRestaurantExample.js +114 -212
  83. package/lib/examples/A2UiViewerExample.d.ts +0 -18
  84. package/lib/examples/A2UiViewerExample.js +283 -532
  85. package/lib/examples/AgUiBackendToolRenderingExample.js +1 -1
  86. package/lib/examples/AgUiHaikuGenUiExample.d.ts +1 -1
  87. package/lib/examples/AgUiHaikuGenUiExample.js +1 -1
  88. package/lib/examples/AgentCheckpointsExample.js +14 -34
  89. package/lib/examples/AgentCodemodeExample.d.ts +4 -6
  90. package/lib/examples/AgentCodemodeExample.js +591 -175
  91. package/lib/examples/AgentEvalsExample.js +13 -23
  92. package/lib/examples/AgentGuardrailsExample.js +371 -71
  93. package/lib/examples/AgentHooksExample.d.ts +3 -0
  94. package/lib/examples/AgentHooksExample.js +104 -0
  95. package/lib/examples/AgentMCPExample.d.ts +3 -0
  96. package/lib/examples/AgentMCPExample.js +480 -0
  97. package/lib/examples/AgentMemoryExample.js +14 -24
  98. package/lib/examples/AgentMonitoringExample.js +261 -206
  99. package/lib/examples/AgentNotificationsExample.js +50 -24
  100. package/lib/examples/AgentOtelExample.js +2 -3
  101. package/lib/examples/AgentOutputsExample.d.ts +11 -6
  102. package/lib/examples/AgentOutputsExample.js +383 -88
  103. package/lib/examples/AgentParametersExample.d.ts +3 -0
  104. package/lib/examples/AgentParametersExample.js +246 -0
  105. package/lib/examples/AgentSandboxExample.d.ts +2 -2
  106. package/lib/examples/AgentSandboxExample.js +69 -47
  107. package/lib/examples/AgentSkillsExample.js +92 -106
  108. package/lib/examples/{AgentspecExample.js → AgentSpecsExample.js} +10 -21
  109. package/lib/examples/AgentSubagentsExample.d.ts +14 -0
  110. package/lib/examples/AgentSubagentsExample.js +228 -0
  111. package/lib/examples/AgentToolApprovalsExample.js +30 -493
  112. package/lib/examples/AgentTriggersExample.js +1067 -246
  113. package/lib/examples/ChatCustomExample.js +11 -24
  114. package/lib/examples/ChatExample.js +9 -34
  115. package/lib/examples/CopilotKitLexicalExample.js +2 -1
  116. package/lib/examples/CopilotKitNotebookExample.js +2 -1
  117. package/lib/examples/HomeExample.d.ts +15 -0
  118. package/lib/examples/HomeExample.js +77 -0
  119. package/lib/examples/Lexical2Example.js +4 -2
  120. package/lib/examples/{LexicalExample.d.ts → LexicalAgentExample.d.ts} +4 -4
  121. package/lib/examples/{LexicalExample.js → LexicalAgentExample.js} +65 -16
  122. package/lib/examples/{LexicalSidebarExample.d.ts → LexicalAgentSidebarExample.d.ts} +5 -5
  123. package/lib/examples/LexicalAgentSidebarExample.js +261 -0
  124. package/lib/examples/NotebookAgentExample.d.ts +9 -0
  125. package/lib/examples/NotebookAgentExample.js +192 -0
  126. package/lib/examples/{NotebookSidebarExample.d.ts → NotebookAgentSidebarExample.d.ts} +2 -2
  127. package/lib/examples/NotebookAgentSidebarExample.js +221 -0
  128. package/lib/examples/{DatalayerNotebookExample.d.ts → NotebookCollaborationExample.d.ts} +4 -4
  129. package/lib/examples/{DatalayerNotebookExample.js → NotebookCollaborationExample.js} +3 -3
  130. package/lib/examples/NotebookExample.d.ts +4 -7
  131. package/lib/examples/NotebookExample.js +14 -146
  132. package/lib/examples/components/AuthRequiredView.d.ts +6 -0
  133. package/lib/examples/components/AuthRequiredView.js +33 -0
  134. package/lib/examples/components/ErrorView.d.ts +14 -0
  135. package/lib/examples/components/ErrorView.js +20 -0
  136. package/lib/examples/components/ExampleWrapper.d.ts +7 -0
  137. package/lib/examples/components/ExampleWrapper.js +25 -6
  138. package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.js +1 -1
  139. package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.js +1 -1
  140. package/lib/examples/{ag-ui → components}/haiku/index.d.ts +1 -1
  141. package/lib/examples/{ag-ui → components}/haiku/index.js +1 -1
  142. package/lib/examples/components/index.d.ts +5 -0
  143. package/lib/examples/components/index.js +5 -0
  144. package/lib/examples/{ag-ui → components}/weather/index.d.ts +1 -1
  145. package/lib/examples/{ag-ui → components}/weather/index.js +1 -1
  146. package/lib/examples/example-selector.d.ts +17 -4
  147. package/lib/examples/example-selector.js +107 -41
  148. package/lib/examples/index.d.ts +9 -6
  149. package/lib/examples/index.js +9 -6
  150. package/lib/examples/main.d.ts +1 -0
  151. package/lib/examples/main.js +218 -27
  152. package/lib/examples/utils/a2ui.d.ts +18 -0
  153. package/lib/examples/utils/a2ui.js +69 -0
  154. package/lib/examples/utils/a2uiMarkdownProvider.d.ts +7 -0
  155. package/lib/examples/utils/a2uiMarkdownProvider.js +9 -0
  156. package/lib/examples/utils/agentId.d.ts +18 -0
  157. package/lib/examples/utils/agentId.js +54 -0
  158. package/lib/examples/utils/agents/earthquake-detector.json +11 -11
  159. package/lib/examples/utils/agents/sales-forecaster.json +11 -11
  160. package/lib/examples/utils/agents/social-post-generator.json +11 -11
  161. package/lib/examples/utils/agents/stock-market.json +11 -11
  162. package/lib/examples/utils/examplesStore.js +82 -27
  163. package/lib/hooks/index.d.ts +8 -8
  164. package/lib/hooks/index.js +7 -7
  165. package/lib/hooks/useA2A.d.ts +2 -3
  166. package/lib/hooks/useAIAgentsWebSocket.d.ts +43 -4
  167. package/lib/hooks/useAIAgentsWebSocket.js +118 -12
  168. package/lib/hooks/useAcp.d.ts +1 -2
  169. package/lib/hooks/useAgUi.d.ts +1 -1
  170. package/lib/hooks/{useAgents.d.ts → useAgentRuntimes.d.ts} +39 -2
  171. package/lib/hooks/{useAgents.js → useAgentRuntimes.js} +125 -15
  172. package/lib/hooks/useAgentsCatalog.js +1 -1
  173. package/lib/hooks/useAgentsService.d.ts +2 -2
  174. package/lib/hooks/useAgentsService.js +7 -7
  175. package/lib/hooks/useCheckpoints.js +1 -1
  176. package/lib/hooks/useConfig.d.ts +4 -1
  177. package/lib/hooks/useConfig.js +10 -3
  178. package/lib/hooks/useContextSnapshot.d.ts +9 -4
  179. package/lib/hooks/useContextSnapshot.js +9 -37
  180. package/lib/hooks/useMonitoring.js +3 -0
  181. package/lib/hooks/useSandbox.d.ts +20 -8
  182. package/lib/hooks/useSandbox.js +105 -40
  183. package/lib/hooks/useSkills.d.ts +23 -5
  184. package/lib/hooks/useSkills.js +94 -39
  185. package/lib/hooks/useToolApprovals.d.ts +60 -36
  186. package/lib/hooks/useToolApprovals.js +318 -69
  187. package/lib/hooks/useVercelAI.d.ts +1 -1
  188. package/lib/index.d.ts +2 -1
  189. package/lib/index.js +1 -0
  190. package/lib/inference/index.d.ts +0 -1
  191. package/lib/middleware/index.d.ts +0 -1
  192. package/lib/protocols/AGUIAdapter.js +6 -0
  193. package/lib/protocols/VercelAIAdapter.d.ts +9 -0
  194. package/lib/protocols/VercelAIAdapter.js +144 -26
  195. package/lib/shims/json5.d.ts +4 -0
  196. package/lib/shims/json5.js +8 -0
  197. package/lib/specs/agents/agents.d.ts +10 -0
  198. package/lib/specs/agents/agents.js +752 -24
  199. package/lib/specs/envvars.d.ts +1 -0
  200. package/lib/specs/envvars.js +11 -0
  201. package/lib/specs/events.d.ts +1 -0
  202. package/lib/specs/events.js +1 -0
  203. package/lib/specs/index.d.ts +1 -0
  204. package/lib/specs/index.js +1 -0
  205. package/lib/specs/personas.d.ts +41 -0
  206. package/lib/specs/personas.js +168 -0
  207. package/lib/specs/skills.d.ts +2 -1
  208. package/lib/specs/skills.js +23 -5
  209. package/lib/specs/tools.js +3 -0
  210. package/lib/stores/agentRuntimeStore.d.ts +204 -0
  211. package/lib/stores/agentRuntimeStore.js +636 -0
  212. package/lib/stores/index.d.ts +1 -1
  213. package/lib/stores/index.js +1 -1
  214. package/lib/tools/adapters/copilotkit/lexicalHooks.d.ts +1 -2
  215. package/lib/tools/adapters/copilotkit/lexicalHooks.js +1 -3
  216. package/lib/tools/adapters/copilotkit/notebookHooks.d.ts +1 -2
  217. package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -3
  218. package/lib/tools/index.d.ts +0 -2
  219. package/lib/tools/index.js +0 -1
  220. package/lib/types/agentspecs.d.ts +50 -1
  221. package/lib/types/chat.d.ts +309 -8
  222. package/lib/types/context.d.ts +27 -0
  223. package/lib/types/cost.d.ts +2 -2
  224. package/lib/types/index.d.ts +2 -0
  225. package/lib/types/index.js +2 -0
  226. package/lib/types/mcp.d.ts +8 -0
  227. package/lib/types/models.d.ts +2 -2
  228. package/lib/types/personas.d.ts +25 -0
  229. package/lib/types/personas.js +5 -0
  230. package/lib/types/skills.d.ts +43 -1
  231. package/lib/types/stream.d.ts +110 -0
  232. package/lib/types/stream.js +36 -0
  233. package/lib/types/tools.d.ts +2 -0
  234. package/lib/utils/utils.d.ts +9 -5
  235. package/lib/utils/utils.js +9 -5
  236. package/package.json +13 -9
  237. package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
  238. package/scripts/codegen/__pycache__/generate_events.cpython-313.pyc +0 -0
  239. package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
  240. package/scripts/codegen/generate_agents.py +106 -7
  241. package/scripts/codegen/generate_events.py +47 -17
  242. package/scripts/codegen/generate_personas.py +319 -0
  243. package/scripts/codegen/generate_skills.py +9 -9
  244. package/scripts/codegen/generate_tools.py +20 -0
  245. package/scripts/sync-jupyter.sh +26 -7
  246. package/style/primer-primitives.css +1 -6
  247. package/lib/api/tool-approvals.d.ts +0 -62
  248. package/lib/api/tool-approvals.js +0 -145
  249. package/lib/examples/LexicalSidebarExample.js +0 -163
  250. package/lib/examples/NotebookSidebarExample.js +0 -119
  251. package/lib/examples/NotebookSimpleExample.d.ts +0 -6
  252. package/lib/examples/NotebookSimpleExample.js +0 -22
  253. package/lib/examples/ag-ui/index.d.ts +0 -10
  254. package/lib/examples/ag-ui/index.js +0 -16
  255. package/lib/hooks/useAgentsRegistry.d.ts +0 -10
  256. package/lib/hooks/useAgentsRegistry.js +0 -20
  257. package/lib/stores/agentsStore.d.ts +0 -123
  258. package/lib/stores/agentsStore.js +0 -270
  259. package/scripts/codegen/__pycache__/generate_envvars.cpython-313.pyc +0 -0
  260. package/scripts/codegen/__pycache__/generate_evals.cpython-313.pyc +0 -0
  261. package/scripts/codegen/__pycache__/generate_guardrails.cpython-313.pyc +0 -0
  262. package/scripts/codegen/__pycache__/generate_mcp_servers.cpython-313.pyc +0 -0
  263. package/scripts/codegen/__pycache__/generate_memory.cpython-313.pyc +0 -0
  264. package/scripts/codegen/__pycache__/generate_models.cpython-313.pyc +0 -0
  265. package/scripts/codegen/__pycache__/generate_notifications.cpython-313.pyc +0 -0
  266. package/scripts/codegen/__pycache__/generate_outputs.cpython-313.pyc +0 -0
  267. package/scripts/codegen/__pycache__/generate_skills.cpython-313.pyc +0 -0
  268. package/scripts/codegen/__pycache__/generate_teams.cpython-313.pyc +0 -0
  269. package/scripts/codegen/__pycache__/generate_tools.cpython-313.pyc +0 -0
  270. package/scripts/codegen/__pycache__/generate_triggers.cpython-313.pyc +0 -0
  271. /package/lib/examples/{AgentspecExample.d.ts → AgentSpecsExample.d.ts} +0 -0
  272. /package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.d.ts +0 -0
  273. /package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.d.ts +0 -0
  274. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.d.ts +0 -0
  275. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.js +0 -0
@@ -7,59 +7,17 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
7
7
  import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
8
8
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
9
9
  import { Box } from '@datalayer/primer-addons';
10
- import { Button, Heading, SegmentedControl, Spinner, Text, } from '@primer/react';
11
- import { AlertIcon, SignOutIcon, ToolsIcon } from '@primer/octicons-react';
12
- import { useCoreStore } from '@datalayer/core';
13
- import { DEFAULT_SERVICE_URLS } from '@datalayer/core/lib/api/constants';
10
+ import { AuthRequiredView, ErrorView } from './components';
11
+ import { Spinner, Text } from '@primer/react';
14
12
  import { useSimpleAuthStore } from '@datalayer/core/lib/views/otel';
15
- import { SignInSimple } from '@datalayer/core/lib/views/iam';
16
- import { UserBadge } from '@datalayer/core/lib/views/profile';
17
13
  import { ThemedProvider } from './utils/themedProvider';
14
+ import { uniqueAgentId } from './utils/agentId';
18
15
  import { Chat } from '../chat';
19
- import { ToolCallDisplay, ToolApprovalBanner, ToolApprovalDialog, } from '../chat/tools';
20
- const normalizeToolName = (value) => value.replace(/[-_]/g, '').toLowerCase();
21
- const AI_AGENTS_API_PREFIX = '/api/ai-agents/v1';
22
- const stableStringify = (value) => {
23
- if (value === null || typeof value !== 'object') {
24
- return JSON.stringify(value);
25
- }
26
- if (Array.isArray(value)) {
27
- return `[${value.map(item => stableStringify(item)).join(',')}]`;
28
- }
29
- const entries = Object.entries(value)
30
- .sort(([a], [b]) => a.localeCompare(b))
31
- .map(([key, itemValue]) => `${JSON.stringify(key)}:${stableStringify(itemValue)}`);
32
- return `{${entries.join(',')}}`;
33
- };
34
- const toWsUrl = (baseUrl, path, token) => {
35
- try {
36
- const url = new URL(baseUrl);
37
- url.protocol = url.protocol === 'https:' ? 'wss:' : 'ws:';
38
- url.pathname = path;
39
- if (token) {
40
- url.searchParams.set('token', token);
41
- }
42
- else {
43
- url.search = '';
44
- }
45
- return url.toString();
46
- }
47
- catch {
48
- return null;
49
- }
50
- };
51
- const normalizeAiAgentsBaseUrl = (rawBaseUrl) => {
52
- const trimmed = rawBaseUrl.replace(/\/$/, '');
53
- if (trimmed.endsWith(AI_AGENTS_API_PREFIX)) {
54
- return trimmed.slice(0, -AI_AGENTS_API_PREFIX.length);
55
- }
56
- return trimmed;
57
- };
16
+ import { useAgentRuntimePendingCount } from '../stores/agentRuntimeStore';
58
17
  const queryClient = new QueryClient();
59
18
  const AGENT_NAME_PREFIX = 'tool-approval-demo-agent';
60
19
  const DEFAULT_AGENT_SPEC_ID = 'demo-full';
61
20
  const DEFAULT_LOCAL_BASE_URL = import.meta.env.VITE_BASE_URL || 'http://localhost:8765';
62
- const FALLBACK_AI_AGENTS_BASE_URL = import.meta.env.VITE_AI_AGENTS_URL || DEFAULT_SERVICE_URLS.AI_AGENTS;
63
21
  const getSelectedAgentSpecIdFromUi = () => {
64
22
  const params = new URLSearchParams(window.location.search);
65
23
  const directKeys = [
@@ -90,34 +48,23 @@ const buildAgentNameForSpec = (specId) => {
90
48
  .replace(/[^a-z0-9]+/g, '-')
91
49
  .replace(/^-+|-+$/g, '')
92
50
  .slice(0, 48);
93
- return slug ? `${AGENT_NAME_PREFIX}-${slug}` : AGENT_NAME_PREFIX;
51
+ const base = slug ? `${AGENT_NAME_PREFIX}-${slug}` : AGENT_NAME_PREFIX;
52
+ return uniqueAgentId(base);
94
53
  };
95
- const approvalSignature = (toolName, args) => `${normalizeToolName(toolName)}::${stableStringify(args ?? {})}`;
96
54
  const AgentToolApprovalsInner = ({ onLogout, }) => {
97
55
  const { token } = useSimpleAuthStore();
98
56
  const [selectedSpecId] = useState(() => getSelectedAgentSpecIdFromUi());
99
57
  const agentName = useMemo(() => buildAgentNameForSpec(selectedSpecId), [selectedSpecId]);
100
- const [mode, setMode] = useState('local');
101
58
  const [runtimeStatus, setRuntimeStatus] = useState('launching');
102
59
  const [isReady, setIsReady] = useState(false);
103
60
  const [hookError, setHookError] = useState(null);
104
61
  const [agentId, setAgentId] = useState(agentName);
105
62
  const [isReconnectedAgent, setIsReconnectedAgent] = useState(false);
106
- const [approvals, setApprovals] = useState([]);
107
- const [localApprovals, setLocalApprovals] = useState([]);
108
- const [activeApproval, setActiveApproval] = useState(null);
109
- const [approvalLoading, setApprovalLoading] = useState(null);
110
- const [approvalError, setApprovalError] = useState(null);
111
- const [toolApprovalState, setToolApprovalState] = useState({});
112
- const [wsState, setWsState] = useState('closed');
113
- const createdApprovalSignatures = useRef(new Set());
114
- const resolveLocalRef = useRef(async () => null);
115
- const authFetchRef = useRef((url, opts) => fetch(url, opts));
116
63
  const chatAuthToken = token === null ? undefined : token;
117
- const configuredAiAgentsBaseUrl = useCoreStore((s) => s.configuration?.aiagentsRunUrl);
118
64
  const agentBaseUrl = DEFAULT_LOCAL_BASE_URL;
119
- const aiAgentsBaseUrl = normalizeAiAgentsBaseUrl(configuredAiAgentsBaseUrl || FALLBACK_AI_AGENTS_BASE_URL);
120
65
  const podName = 'localhost';
66
+ const pendingApprovalCount = useAgentRuntimePendingCount();
67
+ const createAttemptedRef = useRef(false);
121
68
  const authFetch = useCallback((url, opts = {}) => fetch(url, {
122
69
  ...opts,
123
70
  headers: {
@@ -127,6 +74,10 @@ const AgentToolApprovalsInner = ({ onLogout, }) => {
127
74
  },
128
75
  }), [token]);
129
76
  useEffect(() => {
77
+ if (createAttemptedRef.current) {
78
+ return;
79
+ }
80
+ createAttemptedRef.current = true;
130
81
  let isCancelled = false;
131
82
  const createLocalAgent = async () => {
132
83
  setRuntimeStatus('launching');
@@ -192,366 +143,6 @@ const AgentToolApprovalsInner = ({ onLogout, }) => {
192
143
  isCancelled = true;
193
144
  };
194
145
  }, [agentBaseUrl, authFetch, agentName, selectedSpecId]);
195
- const pollApprovals = useCallback(async () => {
196
- if (!isReady) {
197
- return;
198
- }
199
- const fetchPendingApprovals = async (baseUrl, apiPrefix) => {
200
- const res = await authFetch(`${baseUrl}${apiPrefix}`);
201
- if (!res.ok) {
202
- return [];
203
- }
204
- const data = await res.json();
205
- const allApprovals = Array.isArray(data)
206
- ? data
207
- : (data.approvals ?? data.requests ?? []);
208
- return allApprovals
209
- .filter((approval) => approval.status === 'pending' &&
210
- (approval.agent_id === agentId || !approval.agent_id))
211
- .map((approval) => ({
212
- ...approval,
213
- backendBaseUrl: baseUrl,
214
- apiPrefix,
215
- }));
216
- };
217
- const source = mode === 'server'
218
- ? {
219
- baseUrl: aiAgentsBaseUrl,
220
- apiPrefix: `${AI_AGENTS_API_PREFIX}/tool-approvals`,
221
- }
222
- : { baseUrl: agentBaseUrl, apiPrefix: '/api/v1/tool-approvals' };
223
- try {
224
- const localPending = await fetchPendingApprovals(agentBaseUrl, '/api/v1/tool-approvals');
225
- setLocalApprovals(localPending);
226
- const pendingForAgent = await fetchPendingApprovals(source.baseUrl, source.apiPrefix);
227
- setApprovals(pendingForAgent);
228
- }
229
- catch (error) {
230
- if (mode === 'server') {
231
- setApprovalError(error instanceof Error
232
- ? error.message
233
- : 'Failed to fetch server approvals');
234
- }
235
- }
236
- }, [isReady, mode, aiAgentsBaseUrl, agentBaseUrl, agentId, authFetch]);
237
- const resolveLocalApprovalForTool = useCallback(async (toolName, toolArgs) => {
238
- const signature = approvalSignature(toolName, toolArgs);
239
- const matchFromState = localApprovals.find(approval => approvalSignature(approval.tool_name, approval.tool_args ?? {}) ===
240
- signature);
241
- if (matchFromState) {
242
- return matchFromState;
243
- }
244
- const res = await authFetch(`${agentBaseUrl}/api/v1/tool-approvals`);
245
- if (!res.ok) {
246
- return null;
247
- }
248
- const data = await res.json();
249
- const allApprovals = Array.isArray(data)
250
- ? data
251
- : (data.approvals ?? data.requests ?? []);
252
- const pendingLocal = allApprovals
253
- .filter((approval) => approval.status === 'pending' &&
254
- (approval.agent_id === agentId || !approval.agent_id))
255
- .map((approval) => ({
256
- ...approval,
257
- backendBaseUrl: agentBaseUrl,
258
- apiPrefix: '/api/v1/tool-approvals',
259
- }));
260
- setLocalApprovals(pendingLocal);
261
- return (pendingLocal.find(approval => approvalSignature(approval.tool_name, approval.tool_args ?? {}) ===
262
- signature) || null);
263
- }, [localApprovals, authFetch, agentBaseUrl, agentId]);
264
- useEffect(() => {
265
- void pollApprovals();
266
- const interval = setInterval(pollApprovals, 5000);
267
- return () => clearInterval(interval);
268
- }, [pollApprovals]);
269
- useEffect(() => {
270
- if (!isReady || mode !== 'server') {
271
- setWsState('closed');
272
- return;
273
- }
274
- const wsUrl = toWsUrl(aiAgentsBaseUrl, `${AI_AGENTS_API_PREFIX}/ws`, chatAuthToken);
275
- if (!wsUrl) {
276
- setWsState('closed');
277
- return;
278
- }
279
- let closedByCleanup = false;
280
- setWsState('connecting');
281
- const ws = new WebSocket(wsUrl);
282
- ws.onopen = () => {
283
- setWsState('connected');
284
- void pollApprovals();
285
- };
286
- ws.onmessage = event => {
287
- try {
288
- const payload = JSON.parse(String(event.data));
289
- const wsEvent = payload?.event;
290
- const approval = payload?.data;
291
- if (!wsEvent || !approval) {
292
- return;
293
- }
294
- if (wsEvent === 'tool_approval_created') {
295
- if (approval.status !== 'pending' ||
296
- (approval.agent_id && approval.agent_id !== agentId)) {
297
- return;
298
- }
299
- setApprovals(prev => {
300
- const next = prev.filter(item => item.id !== approval.id);
301
- next.unshift({
302
- ...approval,
303
- backendBaseUrl: aiAgentsBaseUrl,
304
- apiPrefix: `${AI_AGENTS_API_PREFIX}/tool-approvals`,
305
- });
306
- return next;
307
- });
308
- return;
309
- }
310
- if (wsEvent === 'tool_approval_approved' ||
311
- wsEvent === 'tool_approval_rejected') {
312
- // Remove from the server approval queue.
313
- setApprovals(prev => prev.filter(item => item.id !== approval.id));
314
- // Bridge the decision to the local agent-runtimes approval.
315
- const action = wsEvent === 'tool_approval_approved' ? 'approve' : 'reject';
316
- void (async () => {
317
- try {
318
- const localMatch = await resolveLocalRef.current(approval.tool_name, approval.tool_args ?? {});
319
- if (localMatch) {
320
- const localBaseUrl = `${agentBaseUrl}/api/v1/tool-approvals/${localMatch.id}/${action}`;
321
- await authFetchRef.current(localBaseUrl, {
322
- method: 'POST',
323
- body: JSON.stringify(approval.note ? { note: approval.note } : {}),
324
- });
325
- }
326
- }
327
- catch {
328
- // Local bridge errors are non-fatal; poll will reconcile.
329
- }
330
- })();
331
- return;
332
- }
333
- }
334
- catch {
335
- // Ignore malformed WS payloads.
336
- }
337
- };
338
- ws.onclose = () => {
339
- if (!closedByCleanup) {
340
- setWsState('closed');
341
- }
342
- };
343
- ws.onerror = () => {
344
- setWsState('closed');
345
- };
346
- return () => {
347
- closedByCleanup = true;
348
- ws.close();
349
- setWsState('closed');
350
- };
351
- }, [
352
- isReady,
353
- mode,
354
- aiAgentsBaseUrl,
355
- agentBaseUrl,
356
- chatAuthToken,
357
- agentId,
358
- pollApprovals,
359
- ]);
360
- // Keep refs in sync so the WS handler always has the latest functions.
361
- useEffect(() => {
362
- resolveLocalRef.current = resolveLocalApprovalForTool;
363
- }, [resolveLocalApprovalForTool]);
364
- useEffect(() => {
365
- authFetchRef.current = authFetch;
366
- }, [authFetch]);
367
- const approve = useCallback(async (requestId, note) => {
368
- setApprovalLoading(requestId);
369
- setApprovalError(null);
370
- try {
371
- const approval = approvals.find(item => item.id === requestId);
372
- const baseUrl = approval?.backendBaseUrl ||
373
- (mode === 'server' ? aiAgentsBaseUrl : agentBaseUrl);
374
- const apiPrefix = approval?.apiPrefix ||
375
- (mode === 'server'
376
- ? `${AI_AGENTS_API_PREFIX}/tool-approvals`
377
- : '/api/v1/tool-approvals');
378
- const response = await authFetch(`${baseUrl}${apiPrefix}/${requestId}/approve`, {
379
- method: 'POST',
380
- body: JSON.stringify(note ? { note } : {}),
381
- });
382
- if (!response.ok) {
383
- const errorText = await response.text().catch(() => '');
384
- throw new Error(errorText ||
385
- `Failed to approve request (${response.status} ${response.statusText})`);
386
- }
387
- // In server mode the WS event will remove from queue and bridge to
388
- // the local runtime — don't do it here to keep flow server-driven.
389
- if (mode !== 'server') {
390
- setApprovals(prev => prev.filter(a => a.id !== requestId));
391
- void pollApprovals();
392
- }
393
- return true;
394
- }
395
- catch (error) {
396
- const message = error instanceof Error
397
- ? error.message
398
- : 'Failed to approve tool request';
399
- setApprovalError(message);
400
- return false;
401
- }
402
- finally {
403
- setApprovalLoading(null);
404
- }
405
- }, [approvals, mode, aiAgentsBaseUrl, agentBaseUrl, authFetch, pollApprovals]);
406
- const reject = useCallback(async (requestId, note) => {
407
- setApprovalLoading(requestId);
408
- setApprovalError(null);
409
- try {
410
- const approval = approvals.find(item => item.id === requestId);
411
- const baseUrl = approval?.backendBaseUrl ||
412
- (mode === 'server' ? aiAgentsBaseUrl : agentBaseUrl);
413
- const apiPrefix = approval?.apiPrefix ||
414
- (mode === 'server'
415
- ? `${AI_AGENTS_API_PREFIX}/tool-approvals`
416
- : '/api/v1/tool-approvals');
417
- const response = await authFetch(`${baseUrl}${apiPrefix}/${requestId}/reject`, {
418
- method: 'POST',
419
- body: JSON.stringify(note ? { note } : {}),
420
- });
421
- if (!response.ok) {
422
- const errorText = await response.text().catch(() => '');
423
- throw new Error(errorText ||
424
- `Failed to reject request (${response.status} ${response.statusText})`);
425
- }
426
- // In server mode the WS event will remove from queue and bridge to
427
- // the local runtime — don't do it here to keep flow server-driven.
428
- if (mode !== 'server') {
429
- setApprovals(prev => prev.filter(a => a.id !== requestId));
430
- void pollApprovals();
431
- }
432
- return true;
433
- }
434
- catch (error) {
435
- const message = error instanceof Error
436
- ? error.message
437
- : 'Failed to reject tool request';
438
- setApprovalError(message);
439
- return false;
440
- }
441
- finally {
442
- setApprovalLoading(null);
443
- }
444
- }, [approvals, mode, aiAgentsBaseUrl, agentBaseUrl, authFetch, pollApprovals]);
445
- const ensureServerApproval = useCallback(async (toolName, args) => {
446
- if (mode !== 'server' || !aiAgentsBaseUrl || !isReady) {
447
- return;
448
- }
449
- const signature = approvalSignature(toolName, args);
450
- if (createdApprovalSignatures.current.has(signature)) {
451
- return;
452
- }
453
- const alreadyTracked = approvals.some(approval => approvalSignature(approval.tool_name, approval.tool_args ?? {}) ===
454
- signature);
455
- if (alreadyTracked) {
456
- createdApprovalSignatures.current.add(signature);
457
- return;
458
- }
459
- createdApprovalSignatures.current.add(signature);
460
- try {
461
- const response = await authFetch(`${aiAgentsBaseUrl}${AI_AGENTS_API_PREFIX}/tool-approvals`, {
462
- method: 'POST',
463
- body: JSON.stringify({
464
- agent_id: agentId,
465
- pod_name: podName,
466
- tool_name: toolName,
467
- tool_args: args,
468
- }),
469
- });
470
- if (!response.ok) {
471
- const text = await response.text().catch(() => '');
472
- throw new Error(text ||
473
- `Failed creating server approval (${response.status} ${response.statusText})`);
474
- }
475
- const created = (await response.json());
476
- setApprovals(prev => {
477
- const next = prev.filter(item => item.id !== created.id);
478
- next.unshift({
479
- ...created,
480
- backendBaseUrl: aiAgentsBaseUrl,
481
- apiPrefix: `${AI_AGENTS_API_PREFIX}/tool-approvals`,
482
- });
483
- return next;
484
- });
485
- }
486
- catch (error) {
487
- createdApprovalSignatures.current.delete(signature);
488
- setApprovalError(error instanceof Error
489
- ? error.message
490
- : 'Failed to create server approval request');
491
- }
492
- }, [mode, aiAgentsBaseUrl, isReady, approvals, authFetch, agentId, podName]);
493
- const pendingApprovals = useMemo(() => approvals.map(req => ({
494
- id: req.id,
495
- toolName: req.tool_name,
496
- toolDescription: req.note,
497
- args: req.tool_args ?? {},
498
- agentId,
499
- requestedAt: req.created_at ?? new Date().toISOString(),
500
- })), [approvals, agentId]);
501
- const findMatchingApproval = useCallback((toolName, args) => {
502
- const normalizedToolName = normalizeToolName(toolName);
503
- const argsSig = stableStringify(args ?? {});
504
- return (approvals.find(approval => {
505
- if (normalizeToolName(approval.tool_name) !== normalizedToolName) {
506
- return false;
507
- }
508
- return stableStringify(approval.tool_args ?? {}) === argsSig;
509
- }) || null);
510
- }, [approvals]);
511
- const handleToolLevelApprove = useCallback(async (toolCallId, requestId) => {
512
- const ok = await approve(requestId, 'Approved from tool message card');
513
- if (ok) {
514
- setToolApprovalState(prev => ({ ...prev, [toolCallId]: 'approved' }));
515
- }
516
- }, [approve]);
517
- const handleToolLevelDeny = useCallback(async (toolCallId, requestId) => {
518
- const ok = await reject(requestId, 'Rejected from tool message card');
519
- if (ok) {
520
- setToolApprovalState(prev => ({ ...prev, [toolCallId]: 'denied' }));
521
- }
522
- }, [reject]);
523
- const renderToolResult = useCallback(({ toolCallId, toolName, args, result, status, error }) => {
524
- const matchedApproval = findMatchingApproval(toolName, args);
525
- const resultObject = result && typeof result === 'object'
526
- ? result
527
- : undefined;
528
- const pendingByResult = status === 'inProgress' && resultObject?.pending_approval === true;
529
- const requiresServerApproval = mode === 'server' &&
530
- normalizeToolName(toolName) ===
531
- normalizeToolName('runtime_sensitive_echo');
532
- if (requiresServerApproval && !matchedApproval) {
533
- void ensureServerApproval(toolName, args);
534
- }
535
- const toolDecision = toolApprovalState[toolCallId];
536
- const loadingThisApproval = !!matchedApproval && approvalLoading === matchedApproval.id;
537
- const approvalState = toolDecision ||
538
- (pendingByResult || requiresServerApproval || !!matchedApproval
539
- ? 'pending'
540
- : undefined);
541
- return (_jsx(ToolCallDisplay, { toolCallId: toolCallId, toolName: toolName, args: args, result: result, status: status, error: error, approvalRequired: !!approvalState, approvalState: approvalState, approvalLoading: loadingThisApproval, onApprove: matchedApproval
542
- ? () => void handleToolLevelApprove(toolCallId, matchedApproval.id)
543
- : undefined, onDeny: matchedApproval
544
- ? () => void handleToolLevelDeny(toolCallId, matchedApproval.id)
545
- : undefined }));
546
- }, [
547
- mode,
548
- findMatchingApproval,
549
- ensureServerApproval,
550
- toolApprovalState,
551
- approvalLoading,
552
- handleToolLevelApprove,
553
- handleToolLevelDeny,
554
- ]);
555
146
  if (!isReady && runtimeStatus !== 'error') {
556
147
  return (_jsxs(Box, { sx: {
557
148
  display: 'flex',
@@ -560,39 +151,11 @@ const AgentToolApprovalsInner = ({ onLogout, }) => {
560
151
  justifyContent: 'center',
561
152
  height: '100vh',
562
153
  gap: 3,
563
- }, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Launching tool approval demo..." })] }));
154
+ }, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: "Launching tool approvals demo..." })] }));
564
155
  }
565
156
  if (runtimeStatus === 'error' || hookError) {
566
- return (_jsxs(Box, { sx: {
567
- display: 'flex',
568
- flexDirection: 'column',
569
- alignItems: 'center',
570
- justifyContent: 'center',
571
- height: '100vh',
572
- gap: 3,
573
- }, children: [_jsx(AlertIcon, { size: 48 }), _jsx(Text, { sx: { color: 'danger.fg' }, children: hookError || 'Agent failed to start' })] }));
157
+ return _jsx(ErrorView, { error: hookError, onLogout: onLogout });
574
158
  }
575
- const serverPanel = mode === 'server' ? (_jsxs(Box, { sx: {
576
- width: 320,
577
- minWidth: 280,
578
- borderLeft: '1px solid',
579
- borderColor: 'border.default',
580
- display: 'flex',
581
- flexDirection: 'column',
582
- minHeight: 0,
583
- bg: 'canvas.subtle',
584
- }, children: [_jsxs(Box, { sx: {
585
- p: 2,
586
- borderBottom: '1px solid',
587
- borderColor: 'border.default',
588
- }, children: [_jsx(Heading, { as: "h4", sx: { fontSize: 1, mb: 1 }, children: "Server Approval Queue" }), _jsxs(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: ["WebSocket: ", wsState, " \u2022 Pending: ", approvals.length] })] }), _jsx(Box, { sx: { p: 2, overflow: 'auto', flex: 1 }, children: approvals.length === 0 ? (_jsx(Text, { sx: { fontSize: 0, color: 'fg.muted' }, children: "No pending approvals." })) : (approvals.map(approval => (_jsxs(Box, { sx: {
589
- border: '1px solid',
590
- borderColor: 'border.default',
591
- borderRadius: 2,
592
- p: 2,
593
- mb: 2,
594
- bg: 'canvas.default',
595
- }, children: [_jsx(Text, { sx: { fontWeight: 600, fontSize: 1 }, children: approval.tool_name }), _jsx(Text, { sx: { fontSize: 0, color: 'fg.muted', mb: 2 }, children: approval.id }), _jsxs(Box, { sx: { display: 'flex', gap: 1 }, children: [_jsx(Button, { size: "small", variant: "primary", onClick: () => void approve(approval.id), children: "Approve" }), _jsx(Button, { size: "small", variant: "danger", onClick: () => void reject(approval.id, 'Rejected from queue'), children: "Reject" })] })] }, approval.id)))) })] })) : null;
596
159
  return (_jsxs(Box, { sx: {
597
160
  height: 'calc(100vh - 60px)',
598
161
  display: 'flex',
@@ -602,41 +165,20 @@ const AgentToolApprovalsInner = ({ onLogout, }) => {
602
165
  py: 1,
603
166
  borderBottom: '1px solid',
604
167
  borderColor: 'border.default',
605
- }, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: "Agent already running - reconnected." }) })), _jsx(ToolApprovalBanner, { pendingApprovals: pendingApprovals, onReview: approval => {
606
- const req = approvals.find(a => a.id === approval.id) || null;
607
- setActiveApproval(req);
608
- }, onApproveAll: async () => {
609
- for (const approval of approvals) {
610
- await approve(approval.id);
611
- }
612
- } }), _jsx(ToolApprovalDialog, { isOpen: !!activeApproval, toolName: activeApproval?.tool_name ?? '', toolDescription: activeApproval?.note, args: activeApproval?.tool_args ?? {}, onApprove: async () => {
613
- if (activeApproval) {
614
- const ok = await approve(activeApproval.id);
615
- if (ok) {
616
- setActiveApproval(null);
617
- }
618
- }
619
- }, onDeny: async () => {
620
- if (activeApproval) {
621
- const ok = await reject(activeApproval.id, 'Rejected from tool approval dialog');
622
- if (ok) {
623
- setActiveApproval(null);
624
- }
625
- }
626
- }, onClose: () => setActiveApproval(null) }), approvalError && (_jsx(Box, { sx: { px: 3, py: 1 }, children: _jsx(Text, { sx: { color: 'danger.fg', fontSize: 0 }, children: approvalError }) })), approvalLoading && (_jsx(Box, { sx: { px: 3, py: 1 }, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: "Processing approval request..." }) })), _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: `Tool Approval Agent - ${podName}`, placeholder: "Ask for actions that require approval...", showHeader: true, showNewChatButton: true, showClearButton: false, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, headerActions: _jsxs(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: [_jsxs(SegmentedControl, { "aria-label": "Approval mode", size: "small", onChange: index => setMode(index === 0 ? 'local' : 'server'), children: [_jsx(SegmentedControl.Button, { selected: mode === 'local', children: "Local" }), _jsx(SegmentedControl.Button, { selected: mode === 'server', children: "Server" })] }), _jsxs(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: ["Pending: ", pendingApprovals.length] }), token && _jsx(UserBadge, { token: token, variant: "small" }), _jsx(Button, { size: "small", variant: "invisible", onClick: onLogout, leadingVisual: SignOutIcon, sx: { color: 'fg.muted' }, children: "Sign out" })] }), suggestions: [
627
- {
628
- title: 'List your tools',
629
- message: 'list your tools',
630
- },
631
- {
632
- title: 'Run tool with approval',
633
- message: "Call the runtime_sensitive_echo tool with text 'hello' and reason 'audit', then reply with the tool result.",
634
- },
635
- {
636
- title: 'Run tool without approval',
637
- message: "Call the runtime_echo tool with text 'hello world', then reply with the tool result.",
638
- },
639
- ], renderToolResult: renderToolResult, submitOnSuggestionClick: true }) }), serverPanel] })] }));
168
+ }, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: "Agent already running - reconnected." }) })), _jsx(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: `Tool Approval Agent - ${podName}`, placeholder: "Ask for actions that require approval...", showHeader: true, showNewChatButton: true, showClearButton: false, showTokenUsage: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, headerActions: _jsx(Box, { sx: { display: 'flex', alignItems: 'center', gap: 2 }, children: _jsxs(Text, { sx: { color: 'fg.muted', fontSize: 1 }, children: ["Pending: ", pendingApprovalCount] }) }), suggestions: [
169
+ {
170
+ title: 'List your tools',
171
+ message: 'list your tools',
172
+ },
173
+ {
174
+ title: 'Run tool with approval',
175
+ message: "Call the runtime_sensitive_echo tool with text 'hello' and reason 'audit', then reply with the tool result.",
176
+ },
177
+ {
178
+ title: 'Run tool without approval',
179
+ message: "Call the runtime_echo tool with text 'hello world', then reply with the tool result.",
180
+ },
181
+ ], submitOnSuggestionClick: true }) }) })] }));
640
182
  };
641
183
  const syncTokenToIamStore = (token) => {
642
184
  import('@datalayer/core/lib/state').then(({ iamStore }) => {
@@ -644,7 +186,7 @@ const syncTokenToIamStore = (token) => {
644
186
  });
645
187
  };
646
188
  const AgentToolApprovalsExample = () => {
647
- const { token, setAuth, clearAuth } = useSimpleAuthStore();
189
+ const { token, clearAuth } = useSimpleAuthStore();
648
190
  const hasSynced = useRef(false);
649
191
  useEffect(() => {
650
192
  if (token && !hasSynced.current) {
@@ -652,11 +194,6 @@ const AgentToolApprovalsExample = () => {
652
194
  syncTokenToIamStore(token);
653
195
  }
654
196
  }, [token]);
655
- const handleSignIn = useCallback((newToken, handle) => {
656
- setAuth(newToken, handle);
657
- hasSynced.current = true;
658
- syncTokenToIamStore(newToken);
659
- }, [setAuth]);
660
197
  const handleLogout = useCallback(() => {
661
198
  clearAuth();
662
199
  hasSynced.current = false;
@@ -665,7 +202,7 @@ const AgentToolApprovalsExample = () => {
665
202
  });
666
203
  }, [clearAuth]);
667
204
  if (!token) {
668
- return (_jsx(ThemedProvider, { children: _jsx(SignInSimple, { onSignIn: handleSignIn, onApiKeySignIn: apiKey => handleSignIn(apiKey, 'api-key-user'), title: "Tool Approval Agent", description: "Sign in to test local and server-backed tool approvals.", leadingIcon: _jsx(ToolsIcon, { size: 24 }) }) }));
205
+ return (_jsx(ThemedProvider, { children: _jsx(AuthRequiredView, {}) }));
669
206
  }
670
207
  return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(ThemedProvider, { children: _jsx(AgentToolApprovalsInner, { onLogout: handleLogout }) }) }));
671
208
  };