@datalayer/agent-runtimes 1.0.4 → 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 (267) hide show
  1. package/README.md +34 -0
  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 -106
  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 +1083 -157
  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 +108 -113
  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 +0 -18
  46. package/lib/client/AgentsMixin.js +6 -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 +5 -1
  54. package/lib/config/AgentConfiguration.js +3 -3
  55. package/lib/context/ContextDistribution.d.ts +3 -1
  56. package/lib/context/ContextDistribution.js +8 -27
  57. package/lib/context/ContextInspector.d.ts +3 -1
  58. package/lib/context/ContextInspector.js +19 -67
  59. package/lib/context/ContextPanel.d.ts +3 -1
  60. package/lib/context/ContextPanel.js +104 -64
  61. package/lib/context/ContextUsage.d.ts +3 -1
  62. package/lib/context/ContextUsage.js +3 -3
  63. package/lib/context/CostTracker.d.ts +9 -3
  64. package/lib/context/CostTracker.js +26 -47
  65. package/lib/context/CostUsageChart.d.ts +12 -0
  66. package/lib/context/CostUsageChart.js +378 -0
  67. package/lib/context/GraphFlowChart.d.ts +16 -0
  68. package/lib/context/GraphFlowChart.js +182 -0
  69. package/lib/context/TokenUsageChart.d.ts +8 -1
  70. package/lib/context/TokenUsageChart.js +349 -211
  71. package/lib/context/TurnGraphChart.d.ts +39 -0
  72. package/lib/context/TurnGraphChart.js +538 -0
  73. package/lib/context/otelWsPool.d.ts +20 -0
  74. package/lib/context/otelWsPool.js +69 -0
  75. package/lib/examples/A2UiComponentGalleryExample.d.ts +0 -17
  76. package/lib/examples/A2UiComponentGalleryExample.js +315 -522
  77. package/lib/examples/A2UiContactCardExample.d.ts +0 -18
  78. package/lib/examples/A2UiContactCardExample.js +154 -411
  79. package/lib/examples/A2UiRestaurantExample.d.ts +0 -30
  80. package/lib/examples/A2UiRestaurantExample.js +114 -212
  81. package/lib/examples/A2UiViewerExample.d.ts +0 -18
  82. package/lib/examples/A2UiViewerExample.js +283 -532
  83. package/lib/examples/AgUiBackendToolRenderingExample.js +1 -1
  84. package/lib/examples/AgUiHaikuGenUiExample.d.ts +1 -1
  85. package/lib/examples/AgUiHaikuGenUiExample.js +1 -1
  86. package/lib/examples/AgentCheckpointsExample.js +13 -27
  87. package/lib/examples/AgentCodemodeExample.d.ts +4 -6
  88. package/lib/examples/AgentCodemodeExample.js +591 -169
  89. package/lib/examples/AgentEvalsExample.js +12 -16
  90. package/lib/examples/AgentGuardrailsExample.js +370 -64
  91. package/lib/examples/AgentHooksExample.d.ts +3 -0
  92. package/lib/examples/AgentHooksExample.js +104 -0
  93. package/lib/examples/AgentMCPExample.d.ts +3 -0
  94. package/lib/examples/AgentMCPExample.js +480 -0
  95. package/lib/examples/AgentMemoryExample.js +13 -17
  96. package/lib/examples/AgentMonitoringExample.js +260 -199
  97. package/lib/examples/AgentNotificationsExample.js +49 -17
  98. package/lib/examples/AgentOtelExample.js +2 -3
  99. package/lib/examples/AgentOutputsExample.d.ts +11 -6
  100. package/lib/examples/AgentOutputsExample.js +382 -81
  101. package/lib/examples/AgentParametersExample.d.ts +3 -0
  102. package/lib/examples/AgentParametersExample.js +246 -0
  103. package/lib/examples/AgentSandboxExample.d.ts +2 -2
  104. package/lib/examples/AgentSandboxExample.js +68 -40
  105. package/lib/examples/AgentSkillsExample.js +91 -99
  106. package/lib/examples/{AgentspecExample.js → AgentSpecsExample.js} +10 -21
  107. package/lib/examples/AgentSubagentsExample.d.ts +14 -0
  108. package/lib/examples/AgentSubagentsExample.js +228 -0
  109. package/lib/examples/AgentToolApprovalsExample.js +29 -557
  110. package/lib/examples/AgentTriggersExample.js +819 -565
  111. package/lib/examples/ChatCustomExample.js +11 -24
  112. package/lib/examples/ChatExample.js +7 -24
  113. package/lib/examples/CopilotKitLexicalExample.js +2 -1
  114. package/lib/examples/CopilotKitNotebookExample.js +2 -1
  115. package/lib/examples/HomeExample.d.ts +15 -0
  116. package/lib/examples/HomeExample.js +77 -0
  117. package/lib/examples/Lexical2Example.js +4 -2
  118. package/lib/examples/{LexicalExample.d.ts → LexicalAgentExample.d.ts} +4 -4
  119. package/lib/examples/{LexicalExample.js → LexicalAgentExample.js} +65 -16
  120. package/lib/examples/{LexicalSidebarExample.d.ts → LexicalAgentSidebarExample.d.ts} +5 -5
  121. package/lib/examples/LexicalAgentSidebarExample.js +261 -0
  122. package/lib/examples/NotebookAgentExample.d.ts +9 -0
  123. package/lib/examples/NotebookAgentExample.js +192 -0
  124. package/lib/examples/{NotebookSidebarExample.d.ts → NotebookAgentSidebarExample.d.ts} +2 -2
  125. package/lib/examples/NotebookAgentSidebarExample.js +221 -0
  126. package/lib/examples/{DatalayerNotebookExample.d.ts → NotebookCollaborationExample.d.ts} +4 -4
  127. package/lib/examples/{DatalayerNotebookExample.js → NotebookCollaborationExample.js} +3 -3
  128. package/lib/examples/NotebookExample.d.ts +4 -7
  129. package/lib/examples/NotebookExample.js +14 -146
  130. package/lib/examples/components/AuthRequiredView.d.ts +6 -0
  131. package/lib/examples/components/AuthRequiredView.js +33 -0
  132. package/lib/examples/components/ExampleWrapper.d.ts +7 -0
  133. package/lib/examples/components/ExampleWrapper.js +25 -6
  134. package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.js +1 -1
  135. package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.js +1 -1
  136. package/lib/examples/{ag-ui → components}/haiku/index.d.ts +1 -1
  137. package/lib/examples/{ag-ui → components}/haiku/index.js +1 -1
  138. package/lib/examples/components/index.d.ts +3 -0
  139. package/lib/examples/components/index.js +4 -0
  140. package/lib/examples/{ag-ui → components}/weather/index.d.ts +1 -1
  141. package/lib/examples/{ag-ui → components}/weather/index.js +1 -1
  142. package/lib/examples/example-selector.d.ts +17 -4
  143. package/lib/examples/example-selector.js +107 -41
  144. package/lib/examples/index.d.ts +9 -6
  145. package/lib/examples/index.js +9 -6
  146. package/lib/examples/main.js +217 -27
  147. package/lib/examples/utils/a2ui.d.ts +18 -0
  148. package/lib/examples/utils/a2ui.js +69 -0
  149. package/lib/examples/utils/a2uiMarkdownProvider.d.ts +7 -0
  150. package/lib/examples/utils/a2uiMarkdownProvider.js +9 -0
  151. package/lib/examples/utils/agentId.d.ts +18 -0
  152. package/lib/examples/utils/agentId.js +54 -0
  153. package/lib/examples/utils/agents/earthquake-detector.json +11 -11
  154. package/lib/examples/utils/agents/sales-forecaster.json +11 -11
  155. package/lib/examples/utils/agents/social-post-generator.json +11 -11
  156. package/lib/examples/utils/agents/stock-market.json +11 -11
  157. package/lib/examples/utils/examplesStore.js +82 -27
  158. package/lib/hooks/index.d.ts +8 -8
  159. package/lib/hooks/index.js +7 -7
  160. package/lib/hooks/useA2A.d.ts +2 -3
  161. package/lib/hooks/useAIAgentsWebSocket.d.ts +43 -4
  162. package/lib/hooks/useAIAgentsWebSocket.js +118 -12
  163. package/lib/hooks/useAcp.d.ts +1 -2
  164. package/lib/hooks/useAgUi.d.ts +1 -1
  165. package/lib/hooks/{useAgents.d.ts → useAgentRuntimes.d.ts} +39 -2
  166. package/lib/hooks/{useAgents.js → useAgentRuntimes.js} +125 -15
  167. package/lib/hooks/useAgentsCatalog.js +1 -1
  168. package/lib/hooks/useAgentsService.d.ts +2 -2
  169. package/lib/hooks/useAgentsService.js +7 -7
  170. package/lib/hooks/useCheckpoints.js +1 -1
  171. package/lib/hooks/useConfig.d.ts +4 -1
  172. package/lib/hooks/useConfig.js +10 -3
  173. package/lib/hooks/useContextSnapshot.d.ts +9 -4
  174. package/lib/hooks/useContextSnapshot.js +9 -37
  175. package/lib/hooks/useMonitoring.js +3 -0
  176. package/lib/hooks/useSandbox.d.ts +20 -8
  177. package/lib/hooks/useSandbox.js +105 -40
  178. package/lib/hooks/useSkills.d.ts +23 -5
  179. package/lib/hooks/useSkills.js +94 -39
  180. package/lib/hooks/useToolApprovals.d.ts +60 -36
  181. package/lib/hooks/useToolApprovals.js +318 -69
  182. package/lib/hooks/useVercelAI.d.ts +1 -1
  183. package/lib/index.d.ts +2 -1
  184. package/lib/index.js +1 -0
  185. package/lib/inference/index.d.ts +0 -1
  186. package/lib/middleware/index.d.ts +0 -1
  187. package/lib/protocols/AGUIAdapter.js +6 -0
  188. package/lib/protocols/VercelAIAdapter.d.ts +7 -0
  189. package/lib/protocols/VercelAIAdapter.js +59 -7
  190. package/lib/specs/agents/agents.d.ts +10 -0
  191. package/lib/specs/agents/agents.js +2139 -262
  192. package/lib/specs/agents/index.js +3 -1
  193. package/lib/specs/envvars.d.ts +1 -0
  194. package/lib/specs/envvars.js +38 -20
  195. package/lib/specs/evals.js +6 -6
  196. package/lib/specs/events.d.ts +3 -10
  197. package/lib/specs/events.js +127 -84
  198. package/lib/specs/frontendTools.js +2 -2
  199. package/lib/specs/guardrails.d.ts +0 -7
  200. package/lib/specs/guardrails.js +240 -159
  201. package/lib/specs/index.d.ts +1 -0
  202. package/lib/specs/index.js +1 -0
  203. package/lib/specs/mcpServers.js +35 -6
  204. package/lib/specs/memory.d.ts +0 -2
  205. package/lib/specs/memory.js +4 -17
  206. package/lib/specs/models.js +25 -5
  207. package/lib/specs/notifications.js +102 -18
  208. package/lib/specs/outputs.js +15 -9
  209. package/lib/specs/personas.d.ts +41 -0
  210. package/lib/specs/personas.js +168 -0
  211. package/lib/specs/skills.d.ts +2 -1
  212. package/lib/specs/skills.js +41 -23
  213. package/lib/specs/teams/index.js +3 -1
  214. package/lib/specs/teams/teams.js +468 -348
  215. package/lib/specs/tools.js +4 -4
  216. package/lib/specs/triggers.js +61 -11
  217. package/lib/stores/agentRuntimeStore.d.ts +204 -0
  218. package/lib/stores/agentRuntimeStore.js +636 -0
  219. package/lib/stores/index.d.ts +1 -1
  220. package/lib/stores/index.js +1 -1
  221. package/lib/tools/adapters/copilotkit/lexicalHooks.d.ts +1 -2
  222. package/lib/tools/adapters/copilotkit/lexicalHooks.js +1 -3
  223. package/lib/tools/adapters/copilotkit/notebookHooks.d.ts +1 -2
  224. package/lib/tools/adapters/copilotkit/notebookHooks.js +1 -3
  225. package/lib/tools/index.d.ts +0 -2
  226. package/lib/tools/index.js +0 -1
  227. package/lib/types/agentspecs.d.ts +50 -1
  228. package/lib/types/chat.d.ts +309 -8
  229. package/lib/types/context.d.ts +27 -0
  230. package/lib/types/cost.d.ts +2 -2
  231. package/lib/types/index.d.ts +2 -0
  232. package/lib/types/index.js +2 -0
  233. package/lib/types/mcp.d.ts +8 -0
  234. package/lib/types/models.d.ts +2 -2
  235. package/lib/types/personas.d.ts +25 -0
  236. package/lib/types/personas.js +5 -0
  237. package/lib/types/skills.d.ts +43 -1
  238. package/lib/types/stream.d.ts +110 -0
  239. package/lib/types/stream.js +36 -0
  240. package/lib/utils/utils.d.ts +9 -5
  241. package/lib/utils/utils.js +9 -5
  242. package/package.json +13 -9
  243. package/scripts/codegen/__pycache__/generate_agents.cpython-313.pyc +0 -0
  244. package/scripts/codegen/__pycache__/generate_events.cpython-313.pyc +0 -0
  245. package/scripts/codegen/__pycache__/versioning.cpython-313.pyc +0 -0
  246. package/scripts/codegen/generate_agents.py +102 -6
  247. package/scripts/codegen/generate_events.py +35 -13
  248. package/scripts/codegen/generate_personas.py +319 -0
  249. package/scripts/codegen/generate_skills.py +9 -9
  250. package/scripts/sync-jupyter.sh +26 -7
  251. package/lib/api/tool-approvals.d.ts +0 -62
  252. package/lib/api/tool-approvals.js +0 -145
  253. package/lib/examples/LexicalSidebarExample.js +0 -163
  254. package/lib/examples/NotebookSidebarExample.js +0 -119
  255. package/lib/examples/NotebookSimpleExample.d.ts +0 -6
  256. package/lib/examples/NotebookSimpleExample.js +0 -22
  257. package/lib/examples/ag-ui/index.d.ts +0 -10
  258. package/lib/examples/ag-ui/index.js +0 -16
  259. package/lib/hooks/useAgentsRegistry.d.ts +0 -10
  260. package/lib/hooks/useAgentsRegistry.js +0 -20
  261. package/lib/stores/agentsStore.d.ts +0 -123
  262. package/lib/stores/agentsStore.js +0 -270
  263. /package/lib/examples/{AgentspecExample.d.ts → AgentSpecsExample.d.ts} +0 -0
  264. /package/lib/examples/{ag-ui → components}/haiku/HaikuDisplay.d.ts +0 -0
  265. /package/lib/examples/{ag-ui → components}/haiku/InlineHaikuCard.d.ts +0 -0
  266. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.d.ts +0 -0
  267. /package/lib/examples/{ag-ui → components}/weather/InlineWeatherCard.js +0 -0
@@ -1,4 +1,4 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  /*
3
3
  * Copyright (c) 2025-2026 Datalayer, Inc.
4
4
  * Distributed under the terms of the Modified BSD License.
@@ -6,49 +6,241 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
6
6
  /**
7
7
  * AgentOutputsExample
8
8
  *
9
- * Demonstrates rich output rendering for agent responses: structured data
10
- * tables, charts, downloadable artifacts, and multi-format output panels.
9
+ * Demonstrates rich output rendering for agent responses. The agent (spec
10
+ * `demo-outputs`) is prompted to return exactly one of four output types per
11
+ * response:
12
+ * - TABLE → GitHub-flavored Markdown table
13
+ * - JSON → ```json fenced block
14
+ * - CHART → ```json fenced block whose first line is `// chart` (ECharts)
15
+ * - FILE → fenced block whose info string is a file extension and
16
+ * whose first line is `# filename: <name.ext>`
11
17
  *
12
- * - Creates a cloud agent runtime (environment: 'ai-agents-env') via the Datalayer
13
- * Runtimes API and deploys an agent on its sidecar
14
- * - Shows an output gallery alongside the chat with tabs for different
15
- * output formats (table, JSON, chart, file)
18
+ * We subscribe to the chat store, detect the output type of the latest
19
+ * assistant message, auto-switch the sidebar tab, and render the payload
20
+ * inline in the sidebar.
16
21
  */
17
22
  /// <reference types="vite/client" />
18
- import { useEffect, useState, useCallback, useRef } from 'react';
23
+ import { useEffect, useState, useCallback, useRef, useMemo, } from 'react';
19
24
  import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
20
25
  import { Text, Button, Spinner, Heading, Label } from '@primer/react';
21
- import { TableIcon, FileIcon, CodeIcon, GraphIcon, DownloadIcon, SignOutIcon, } from '@primer/octicons-react';
26
+ import { TableIcon, FileIcon, CodeIcon, GraphIcon, DownloadIcon, } from '@primer/octicons-react';
22
27
  import { Box } from '@datalayer/primer-addons';
23
- import { ErrorView } from './components';
28
+ import { AuthRequiredView, ErrorView } from './components';
24
29
  import { useSimpleAuthStore } from '@datalayer/core/lib/views/otel';
25
- import { SignInSimple } from '@datalayer/core/lib/views/iam';
26
- import { UserBadge } from '@datalayer/core/lib/views/profile';
27
30
  import { ThemedProvider } from './utils/themedProvider';
28
- import { useAgents } from '../hooks/useAgents';
31
+ import { uniqueAgentId } from './utils/agentId';
29
32
  import { Chat } from '../chat';
33
+ import { useChatStore } from '../stores/chatStore';
30
34
  const queryClient = new QueryClient();
31
35
  // ─── Constants ─────────────────────────────────────────────────────────────
32
- const AGENT_NAME = 'output-demo-agent';
33
- const AGENT_SPEC_ID = 'monitor-sales-kpis';
36
+ const AGENT_NAME = 'outputs-demo-agent';
37
+ const AGENT_SPEC_ID = 'demo-outputs';
38
+ const DEFAULT_LOCAL_BASE_URL = import.meta.env.VITE_BASE_URL || 'http://localhost:8765';
39
+ // ─── Output detection ──────────────────────────────────────────────────────
40
+ const FENCE_RE = /```([a-zA-Z0-9_+-]*)\n([\s\S]*?)```/g;
41
+ const MD_TABLE_RE = /(^|\n)\s*\|[^\n]+\|\s*\n\s*\|[\s:|-]+\|\s*\n(\s*\|[^\n]+\|\s*\n?)+/;
42
+ const EXT_LIKE_INFOS = new Set([
43
+ 'csv',
44
+ 'tsv',
45
+ 'txt',
46
+ 'md',
47
+ 'markdown',
48
+ 'yaml',
49
+ 'yml',
50
+ 'xml',
51
+ 'html',
52
+ 'log',
53
+ 'ini',
54
+ 'toml',
55
+ ]);
56
+ const messageText = (m) => {
57
+ if (typeof m.content === 'string')
58
+ return m.content;
59
+ return m.content
60
+ .filter(p => p.type === 'text')
61
+ .map(p => p.text)
62
+ .join('\n');
63
+ };
64
+ const detectOutput = (m) => {
65
+ const text = messageText(m);
66
+ if (!text)
67
+ return null;
68
+ // 1) Fenced code blocks (first one wins).
69
+ FENCE_RE.lastIndex = 0;
70
+ const match = FENCE_RE.exec(text);
71
+ if (match) {
72
+ const info = (match[1] || '').toLowerCase();
73
+ const body = match[2] ?? '';
74
+ const firstLine = body.split('\n', 1)[0]?.trim() ?? '';
75
+ // Chart: ```json with `// chart` marker on first line.
76
+ if (info === 'json' && /^\/\/\s*chart\b/i.test(firstLine)) {
77
+ return {
78
+ tab: 'chart',
79
+ payload: body.replace(/^\/\/\s*chart.*\n?/i, ''),
80
+ messageId: m.id,
81
+ };
82
+ }
83
+ // File: info string is a known extension OR first line declares a filename.
84
+ const filenameMatch = firstLine.match(/^#\s*filename:\s*([\w.-]+)/i);
85
+ if (filenameMatch || EXT_LIKE_INFOS.has(info)) {
86
+ const filename = filenameMatch?.[1] ?? (info ? `output.${info}` : 'output.txt');
87
+ return {
88
+ tab: 'files',
89
+ payload: filenameMatch
90
+ ? body.replace(/^#\s*filename:.*\n?/i, '')
91
+ : body,
92
+ filename,
93
+ extension: filename.split('.').pop(),
94
+ messageId: m.id,
95
+ };
96
+ }
97
+ // JSON (explicit language tag).
98
+ if (info === 'json' || info === 'json5') {
99
+ return { tab: 'json', payload: body, messageId: m.id };
100
+ }
101
+ // JSON fallback: bare ``` fence whose body parses as JSON.
102
+ if (!info || info === 'text' || info === 'plain') {
103
+ const trimmed = body.trim();
104
+ if (trimmed.startsWith('{') || trimmed.startsWith('[')) {
105
+ try {
106
+ JSON.parse(trimmed);
107
+ return { tab: 'json', payload: trimmed, messageId: m.id };
108
+ }
109
+ catch {
110
+ /* not JSON — ignore */
111
+ }
112
+ }
113
+ }
114
+ }
115
+ // 1b) No fences — try to detect a bare JSON object/array in the message.
116
+ {
117
+ const stripped = text.trim();
118
+ if (stripped.startsWith('{') || stripped.startsWith('[')) {
119
+ try {
120
+ JSON.parse(stripped);
121
+ return { tab: 'json', payload: stripped, messageId: m.id };
122
+ }
123
+ catch {
124
+ /* not JSON — ignore */
125
+ }
126
+ }
127
+ // Or: find the first {...} / [...] block and try parsing it.
128
+ const blockMatch = stripped.match(/(\{[\s\S]*\}|\[[\s\S]*\])/);
129
+ if (blockMatch) {
130
+ try {
131
+ JSON.parse(blockMatch[1]);
132
+ return { tab: 'json', payload: blockMatch[1], messageId: m.id };
133
+ }
134
+ catch {
135
+ /* not JSON — ignore */
136
+ }
137
+ }
138
+ }
139
+ // 2) Markdown table (no fences).
140
+ if (MD_TABLE_RE.test(text)) {
141
+ const tableMatch = text.match(MD_TABLE_RE);
142
+ return {
143
+ tab: 'table',
144
+ payload: tableMatch ? tableMatch[0].trim() : text,
145
+ messageId: m.id,
146
+ };
147
+ }
148
+ return null;
149
+ };
150
+ // ─── Table renderer (parses the Markdown pipe syntax) ──────────────────────
151
+ const MarkdownTable = ({ source }) => {
152
+ const { headers, rows } = useMemo(() => {
153
+ const lines = source
154
+ .split('\n')
155
+ .map(l => l.trim())
156
+ .filter(l => l.startsWith('|'));
157
+ if (lines.length < 2)
158
+ return { headers: [], rows: [] };
159
+ const split = (line) => line
160
+ .replace(/^\|/, '')
161
+ .replace(/\|$/, '')
162
+ .split('|')
163
+ .map(c => c.trim());
164
+ const headers = split(lines[0]);
165
+ const rows = lines.slice(2).map(split);
166
+ return { headers, rows };
167
+ }, [source]);
168
+ if (headers.length === 0) {
169
+ return (_jsx(Box, { as: "pre", sx: {
170
+ fontFamily: 'mono',
171
+ fontSize: 0,
172
+ whiteSpace: 'pre-wrap',
173
+ m: 0,
174
+ }, children: source }));
175
+ }
176
+ return (_jsx(Box, { sx: { overflowX: 'auto' }, children: _jsxs(Box, { as: "table", sx: {
177
+ width: '100%',
178
+ borderCollapse: 'collapse',
179
+ fontSize: 0,
180
+ 'th, td': {
181
+ border: '1px solid',
182
+ borderColor: 'border.muted',
183
+ px: 2,
184
+ py: 1,
185
+ textAlign: 'left',
186
+ verticalAlign: 'top',
187
+ },
188
+ th: { bg: 'canvas.subtle', fontWeight: 'bold' },
189
+ }, children: [_jsx("thead", { children: _jsx("tr", { children: headers.map((h, i) => (_jsx("th", { children: h }, i))) }) }), _jsx("tbody", { children: rows.map((r, i) => (_jsx("tr", { children: r.map((c, j) => (_jsx("td", { children: c }, j))) }, i))) })] }) }));
190
+ };
191
+ // ─── Chart renderer (lazy ECharts) ─────────────────────────────────────────
192
+ const ChartView = ({ source }) => {
193
+ const [ReactECharts, setReactECharts] = useState(null);
194
+ useEffect(() => {
195
+ let cancelled = false;
196
+ import('echarts-for-react')
197
+ .then(m => {
198
+ if (!cancelled) {
199
+ setReactECharts(() => m.default);
200
+ }
201
+ })
202
+ .catch(() => {
203
+ /* echarts-for-react not installed — fall back to raw JSON */
204
+ });
205
+ return () => {
206
+ cancelled = true;
207
+ };
208
+ }, []);
209
+ const option = useMemo(() => {
210
+ try {
211
+ return JSON.parse(source);
212
+ }
213
+ catch {
214
+ return null;
215
+ }
216
+ }, [source]);
217
+ if (!option) {
218
+ return (_jsx(Text, { sx: { color: 'danger.fg', fontSize: 0 }, children: "Could not parse chart spec as JSON." }));
219
+ }
220
+ if (!ReactECharts) {
221
+ return (_jsx(Box, { as: "pre", sx: {
222
+ fontFamily: 'mono',
223
+ fontSize: 0,
224
+ whiteSpace: 'pre-wrap',
225
+ bg: 'canvas.subtle',
226
+ p: 2,
227
+ borderRadius: 2,
228
+ m: 0,
229
+ }, children: source }));
230
+ }
231
+ return (_jsx(ReactECharts, { option: option, style: { height: 280, width: '100%' } }));
232
+ };
34
233
  // ─── Inner component (rendered after auth) ─────────────────────────────────
35
234
  const AgentOutputsInner = ({ onLogout, }) => {
36
235
  const { token } = useSimpleAuthStore();
37
- const { runtime, status: runtimeStatus, isReady, error: hookError, } = useAgents({
38
- agentSpecId: AGENT_SPEC_ID,
39
- autoStart: true,
40
- agentConfig: {
41
- name: AGENT_NAME,
42
- protocol: 'ag-ui',
43
- description: 'Agent with rich output rendering and artifact management',
44
- },
45
- });
46
- const [activeTab, setActiveTab] = useState('table');
47
- const [artifacts, setArtifacts] = useState([]);
48
- const agentBaseUrl = runtime?.agentBaseUrl || '';
49
- const agentId = runtime?.agentId || AGENT_NAME;
50
- const podName = runtime?.podName || '(launching…)';
51
- // Authenticated fetch helper
236
+ const agentName = useRef(uniqueAgentId(AGENT_NAME)).current;
237
+ const [runtimeStatus, setRuntimeStatus] = useState('launching');
238
+ const [isReady, setIsReady] = useState(false);
239
+ const [hookError, setHookError] = useState(null);
240
+ const [agentId, setAgentId] = useState(agentName);
241
+ const [isReconnectedAgent, setIsReconnectedAgent] = useState(false);
242
+ const agentBaseUrl = DEFAULT_LOCAL_BASE_URL;
243
+ const chatAuthToken = token === null ? undefined : token;
52
244
  const authFetch = useCallback((url, opts = {}) => fetch(url, {
53
245
  ...opts,
54
246
  headers: {
@@ -57,26 +249,98 @@ const AgentOutputsInner = ({ onLogout, }) => {
57
249
  ...(opts.headers ?? {}),
58
250
  },
59
251
  }), [token]);
60
- // ── Poll output artifacts ─────────────────────────────────────────────
61
252
  useEffect(() => {
62
- if (!isReady || !agentBaseUrl)
63
- return;
64
- const poll = async () => {
253
+ let isCancelled = false;
254
+ const createAgent = async () => {
255
+ setRuntimeStatus('launching');
256
+ setIsReady(false);
257
+ setHookError(null);
258
+ setIsReconnectedAgent(false);
65
259
  try {
66
- const res = await authFetch(`${agentBaseUrl}/api/v1/agents/${agentId}/outputs`);
67
- if (res.ok) {
68
- const d = await res.json();
69
- setArtifacts(Array.isArray(d) ? d : (d.artifacts ?? []));
260
+ const response = await authFetch(`${agentBaseUrl}/api/v1/agents`, {
261
+ method: 'POST',
262
+ body: JSON.stringify({
263
+ name: agentName,
264
+ description: 'Agent with rich output rendering (table/JSON/chart/file)',
265
+ agent_library: 'pydantic-ai',
266
+ transport: 'vercel-ai',
267
+ agent_spec_id: AGENT_SPEC_ID,
268
+ enable_skills: true,
269
+ tools: [],
270
+ }),
271
+ });
272
+ let resolvedAgentId = agentName;
273
+ let isAlreadyRunning = false;
274
+ if (response.ok) {
275
+ const data = await response.json();
276
+ resolvedAgentId = data?.id || agentName;
277
+ }
278
+ else {
279
+ const contentType = response.headers.get('content-type') || '';
280
+ let detail = '';
281
+ if (contentType.includes('application/json')) {
282
+ const data = await response.json().catch(() => null);
283
+ detail =
284
+ (typeof data?.detail === 'string' && data.detail) ||
285
+ (typeof data?.message === 'string' && data.message) ||
286
+ '';
287
+ }
288
+ else {
289
+ detail = await response.text();
290
+ }
291
+ if (response.status === 409 || /already exists/i.test(detail || '')) {
292
+ isAlreadyRunning = true;
293
+ }
294
+ else {
295
+ throw new Error(detail || `Failed to create agent: ${response.status}`);
296
+ }
297
+ }
298
+ if (!isCancelled) {
299
+ setAgentId(resolvedAgentId);
300
+ setIsReconnectedAgent(isAlreadyRunning);
301
+ setIsReady(true);
302
+ setRuntimeStatus('ready');
70
303
  }
71
304
  }
72
- catch {
73
- /* ok */
305
+ catch (error) {
306
+ if (!isCancelled) {
307
+ setHookError(error instanceof Error ? error.message : 'Agent failed to start');
308
+ setRuntimeStatus('error');
309
+ }
74
310
  }
75
311
  };
76
- poll();
77
- const interval = setInterval(poll, 10_000);
78
- return () => clearInterval(interval);
79
- }, [isReady, agentBaseUrl, agentId, authFetch]);
312
+ void createAgent();
313
+ return () => {
314
+ isCancelled = true;
315
+ };
316
+ }, [agentBaseUrl, agentName, authFetch]);
317
+ const [activeTab, setActiveTab] = useState('table');
318
+ const [detected, setDetected] = useState([]);
319
+ const lastProcessedIdRef = useRef(null);
320
+ // Subscribe to chat store messages and detect outputs in assistant replies.
321
+ useEffect(() => {
322
+ const process = (messages) => {
323
+ const assistants = messages.filter(m => m.role === 'assistant');
324
+ if (assistants.length === 0)
325
+ return;
326
+ const last = assistants[assistants.length - 1];
327
+ if (last.id === lastProcessedIdRef.current)
328
+ return;
329
+ const out = detectOutput(last);
330
+ if (!out)
331
+ return;
332
+ lastProcessedIdRef.current = last.id;
333
+ setDetected(prev => {
334
+ if (prev.some(d => d.messageId === out.messageId))
335
+ return prev;
336
+ return [out, ...prev].slice(0, 20);
337
+ });
338
+ setActiveTab(out.tab);
339
+ };
340
+ process(useChatStore.getState().messages);
341
+ const unsub = useChatStore.subscribe(state => state.messages, process);
342
+ return unsub;
343
+ }, []);
80
344
  // ── Loading / Error ───────────────────────────────────────────────────
81
345
  if (!isReady && runtimeStatus !== 'error') {
82
346
  return (_jsxs(Box, { sx: {
@@ -87,18 +351,35 @@ const AgentOutputsInner = ({ onLogout, }) => {
87
351
  height: '100vh',
88
352
  gap: 3,
89
353
  }, children: [_jsx(Spinner, { size: "large" }), _jsx(Text, { sx: { color: 'fg.muted' }, children: runtimeStatus === 'launching'
90
- ? 'Launching runtime for output agent'
91
- : 'Creating output demo agent' })] }));
354
+ ? 'Launching outputs demo agent...'
355
+ : 'Creating outputs demo agent...' })] }));
92
356
  }
93
357
  if (runtimeStatus === 'error' || hookError) {
94
358
  return _jsx(ErrorView, { error: hookError, onLogout: onLogout });
95
359
  }
96
- const filtered = artifacts.filter(a => a.type === activeTab);
360
+ const filtered = detected.filter(d => d.tab === activeTab);
361
+ const countByTab = (tab) => detected.filter(d => d.tab === tab).length;
362
+ const download = (d) => {
363
+ const blob = new Blob([d.payload], { type: 'text/plain;charset=utf-8' });
364
+ const url = URL.createObjectURL(blob);
365
+ const a = document.createElement('a');
366
+ a.href = url;
367
+ a.download = d.filename ?? `output.${d.extension ?? 'txt'}`;
368
+ document.body.appendChild(a);
369
+ a.click();
370
+ document.body.removeChild(a);
371
+ URL.revokeObjectURL(url);
372
+ };
97
373
  return (_jsxs(Box, { sx: {
98
374
  height: 'calc(100vh - 60px)',
99
375
  display: 'flex',
100
376
  flexDirection: 'column',
101
- }, children: [_jsxs(Box, { sx: {
377
+ }, children: [isReconnectedAgent && (_jsx(Box, { sx: {
378
+ px: 3,
379
+ py: 1,
380
+ borderBottom: '1px solid',
381
+ borderColor: 'border.default',
382
+ }, children: _jsx(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: "Agent already running - reconnected." }) })), _jsxs(Box, { sx: {
102
383
  display: 'flex',
103
384
  alignItems: 'center',
104
385
  gap: 2,
@@ -107,22 +388,30 @@ const AgentOutputsInner = ({ onLogout, }) => {
107
388
  borderBottom: '1px solid',
108
389
  borderColor: 'border.default',
109
390
  flexShrink: 0,
110
- }, children: [_jsx(TableIcon, { size: 16 }), _jsxs(Heading, { as: "h3", sx: { fontSize: 2, flex: 1 }, children: ["Agent Outputs \u2014 ", podName] }), token && _jsx(UserBadge, { token: token, variant: "small" }), _jsx(Button, { size: "small", variant: "invisible", onClick: onLogout, leadingVisual: SignOutIcon, sx: { color: 'fg.muted' }, children: "Sign out" })] }), _jsxs(Box, { sx: { flex: 1, minHeight: 0, display: 'flex' }, children: [_jsx(Box, { sx: { flex: 1, minWidth: 0 }, children: _jsx(Chat, { protocol: "ag-ui", baseUrl: agentBaseUrl, agentId: agentId, title: "Output Agent", placeholder: "Ask the agent to generate reports, data, or files\u2026", description: `${artifacts.length} artifact${artifacts.length !== 1 ? 's' : ''} produced`, showHeader: true, autoFocus: true, height: "100%", runtimeId: podName, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
391
+ }, children: [_jsx(TableIcon, { size: 16 }), _jsx(Heading, { as: "h3", sx: { fontSize: 2, flex: 1 }, children: "Agent Outputs \u2014 Local Runtime" })] }), _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: "Outputs Demo Agent", placeholder: "Ask for a Table, JSON, Chart, or File\u2026", description: `${detected.length} detected output${detected.length !== 1 ? 's' : ''}`, showHeader: true, showToolsMenu: true, showSkillsMenu: true, autoFocus: true, height: "100%", runtimeId: agentId, historyEndpoint: `${agentBaseUrl}/api/v1/history`, suggestions: [
111
392
  {
112
- title: 'Generate report',
113
- message: 'Generate a KPI summary report as a table',
393
+ title: 'Table',
394
+ message: 'Generate a Markdown table of the top 5 US cities by population, with columns City, State, Population.',
114
395
  },
115
396
  {
116
- title: 'Export JSON',
117
- message: 'Export the latest sales data as JSON',
397
+ title: 'JSON',
398
+ message: 'Return a JSON object describing a fictitious product catalog with 3 items (id, name, price, tags).',
399
+ },
400
+ {
401
+ title: 'Chart',
402
+ message: 'Produce a bar chart ECharts spec (valid JSON, with `// chart` on the first line of the fenced block) showing monthly sales for Jan–Jun.',
403
+ },
404
+ {
405
+ title: 'File',
406
+ message: 'Create a downloadable CSV file with sample sales data for the last 7 days. Output it inside a ```csv fenced block whose first line is `# filename: sales.csv`.',
118
407
  },
119
408
  ], submitOnSuggestionClick: true }) }), _jsxs(Box, { sx: {
120
- width: 380,
409
+ width: 420,
121
410
  borderLeft: '1px solid',
122
411
  borderColor: 'border.default',
123
412
  display: 'flex',
124
413
  flexDirection: 'column',
125
- overflow: 'auto',
414
+ overflow: 'hidden',
126
415
  }, children: [_jsx(Box, { sx: {
127
416
  display: 'flex',
128
417
  borderBottom: '1px solid',
@@ -133,13 +422,18 @@ const AgentOutputsInner = ({ onLogout, }) => {
133
422
  { key: 'json', icon: CodeIcon, label: 'JSON' },
134
423
  { key: 'chart', icon: GraphIcon, label: 'Chart' },
135
424
  { key: 'files', icon: FileIcon, label: 'Files' },
136
- ].map(t => (_jsx(Button, { size: "small", variant: "invisible", leadingVisual: t.icon, onClick: () => setActiveTab(t.key), sx: {
137
- flex: 1,
138
- borderRadius: 0,
139
- borderBottom: activeTab === t.key ? '2px solid' : '2px solid transparent',
140
- borderColor: activeTab === t.key ? 'accent.fg' : 'transparent',
141
- fontWeight: activeTab === t.key ? 'bold' : 'normal',
142
- }, children: t.label }, t.key))) }), _jsxs(Box, { sx: { p: 3, flex: 1, overflow: 'auto' }, children: [_jsxs(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: [activeTab.charAt(0).toUpperCase() + activeTab.slice(1), " Outputs"] }), filtered.length === 0 ? (_jsxs(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: ["No ", activeTab, " outputs yet. Ask the agent to generate some."] })) : (filtered.map(art => (_jsxs(Box, { sx: {
425
+ ].map(t => {
426
+ const n = countByTab(t.key);
427
+ return (_jsxs(Button, { size: "small", variant: "invisible", leadingVisual: t.icon, onClick: () => setActiveTab(t.key), sx: {
428
+ flex: 1,
429
+ borderRadius: 0,
430
+ borderBottom: activeTab === t.key
431
+ ? '2px solid'
432
+ : '2px solid transparent',
433
+ borderColor: activeTab === t.key ? 'accent.fg' : 'transparent',
434
+ fontWeight: activeTab === t.key ? 'bold' : 'normal',
435
+ }, children: [t.label, n > 0 ? ` (${n})` : ''] }, t.key));
436
+ }) }), _jsxs(Box, { sx: { p: 3, flex: 1, overflow: 'auto' }, children: [_jsxs(Heading, { as: "h4", sx: { fontSize: 1, mb: 2 }, children: [activeTab.charAt(0).toUpperCase() + activeTab.slice(1), " outputs"] }), filtered.length === 0 ? (_jsxs(Text, { sx: { color: 'fg.muted', fontSize: 0 }, children: ["No ", activeTab, " outputs yet. Use one of the suggestion buttons in the chat to produce one \u2014 the side panel will switch to the matching tab automatically."] })) : (filtered.map((d, idx) => (_jsxs(Box, { sx: {
143
437
  p: 2,
144
438
  mb: 2,
145
439
  border: '1px solid',
@@ -149,25 +443,37 @@ const AgentOutputsInner = ({ onLogout, }) => {
149
443
  display: 'flex',
150
444
  justifyContent: 'space-between',
151
445
  alignItems: 'center',
152
- mb: 1,
153
- }, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold' }, children: art.name }), _jsx(Label, { size: "small", variant: "secondary", children: art.size != null
154
- ? `${(art.size / 1024).toFixed(1)} KB`
155
- : activeTab })] }), art.preview && (_jsx(Box, { sx: {
446
+ mb: 2,
447
+ gap: 2,
448
+ }, children: [_jsx(Text, { sx: { fontSize: 1, fontWeight: 'bold' }, children: d.filename ?? `${d.tab} output` }), _jsx(Label, { size: "small", variant: "secondary", children: d.tab })] }), d.tab === 'table' && _jsx(MarkdownTable, { source: d.payload }), d.tab === 'json' && (_jsx(Box, { as: "pre", sx: {
156
449
  bg: 'canvas.subtle',
157
450
  p: 2,
158
451
  borderRadius: 2,
159
452
  fontFamily: 'mono',
160
453
  fontSize: 0,
161
- mb: 1,
162
- maxHeight: 120,
454
+ maxHeight: 320,
163
455
  overflow: 'auto',
164
456
  whiteSpace: 'pre-wrap',
165
- }, children: art.preview })), _jsxs(Box, { sx: {
166
- display: 'flex',
167
- justifyContent: 'space-between',
168
- fontSize: 0,
169
- color: 'fg.muted',
170
- }, children: [_jsx(Text, { children: new Date(art.timestamp).toLocaleString() }), _jsx(Button, { size: "small", variant: "invisible", leadingVisual: DownloadIcon, onClick: () => window.open(`${agentBaseUrl}/api/v1/agents/${agentId}/outputs/${art.id}/download`), children: "Download" })] })] }, art.id))))] })] })] })] }));
457
+ m: 0,
458
+ }, children: (() => {
459
+ try {
460
+ return JSON.stringify(JSON.parse(d.payload), null, 2);
461
+ }
462
+ catch {
463
+ return d.payload;
464
+ }
465
+ })() })), d.tab === 'chart' && _jsx(ChartView, { source: d.payload }), d.tab === 'files' && (_jsxs(_Fragment, { children: [_jsx(Box, { as: "pre", sx: {
466
+ bg: 'canvas.subtle',
467
+ p: 2,
468
+ borderRadius: 2,
469
+ fontFamily: 'mono',
470
+ fontSize: 0,
471
+ maxHeight: 200,
472
+ overflow: 'auto',
473
+ whiteSpace: 'pre-wrap',
474
+ m: 0,
475
+ mb: 2,
476
+ }, children: d.payload }), _jsxs(Button, { size: "small", leadingVisual: DownloadIcon, onClick: () => download(d), children: ["Download ", d.filename ?? 'file'] })] }))] }, d.messageId + ':' + idx))))] })] })] })] }));
171
477
  };
172
478
  // ─── Sync token to core IAM store ──────────────────────────────────────────
173
479
  const syncTokenToIamStore = (token) => {
@@ -177,7 +483,7 @@ const syncTokenToIamStore = (token) => {
177
483
  };
178
484
  // ─── Main component with auth gate ─────────────────────────────────────────
179
485
  const AgentOutputsExample = () => {
180
- const { token, setAuth, clearAuth } = useSimpleAuthStore();
486
+ const { token, clearAuth } = useSimpleAuthStore();
181
487
  const hasSynced = useRef(false);
182
488
  useEffect(() => {
183
489
  if (token && !hasSynced.current) {
@@ -185,11 +491,6 @@ const AgentOutputsExample = () => {
185
491
  syncTokenToIamStore(token);
186
492
  }
187
493
  }, [token]);
188
- const handleSignIn = useCallback((newToken, handle) => {
189
- setAuth(newToken, handle);
190
- hasSynced.current = true;
191
- syncTokenToIamStore(newToken);
192
- }, [setAuth]);
193
494
  const handleLogout = useCallback(() => {
194
495
  clearAuth();
195
496
  hasSynced.current = false;
@@ -198,7 +499,7 @@ const AgentOutputsExample = () => {
198
499
  });
199
500
  }, [clearAuth]);
200
501
  if (!token) {
201
- return (_jsx(ThemedProvider, { children: _jsx(SignInSimple, { onSignIn: handleSignIn, onApiKeySignIn: apiKey => handleSignIn(apiKey, 'api-key-user'), title: "Agent Outputs", description: "Sign in to view and manage agent output artifacts.", leadingIcon: _jsx(TableIcon, { size: 24 }) }) }));
502
+ return (_jsx(ThemedProvider, { children: _jsx(AuthRequiredView, {}) }));
202
503
  }
203
504
  return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(ThemedProvider, { children: _jsx(AgentOutputsInner, { onLogout: handleLogout }) }) }));
204
505
  };
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ declare const AgentParametersExample: React.FC;
3
+ export default AgentParametersExample;