@solidxai/core-ui 0.1.20 → 0.1.21-beta.0
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/dist/components/common/FileReaderExt.d.ts.map +1 -1
- package/dist/components/common/FileReaderExt.js +22 -11
- package/dist/components/common/FileReaderExt.js.map +1 -1
- package/dist/components/common/FileReaderExt.tsx +27 -14
- package/dist/components/common/SocialMediaLogin.d.ts.map +1 -1
- package/dist/components/common/SocialMediaLogin.js +1 -1
- package/dist/components/common/SocialMediaLogin.js.map +1 -1
- package/dist/components/common/SocialMediaLogin.tsx +50 -19
- package/dist/components/common/solid-export.css +75 -0
- package/dist/components/core/common/SolidGenericImport/SolidImport.module.css +71 -0
- package/dist/components/core/form/SolidFormView.d.ts.map +1 -1
- package/dist/components/core/form/SolidFormView.js +14 -0
- package/dist/components/core/form/SolidFormView.js.map +1 -1
- package/dist/components/core/form/SolidFormView.tsx +13 -0
- package/dist/components/core/form/fields/SolidMediaMultipleField.js +3 -3
- package/dist/components/core/form/fields/SolidMediaMultipleField.js.map +1 -1
- package/dist/components/core/form/fields/SolidMediaMultipleField.tsx +3 -3
- package/dist/components/core/form/fields/SolidMediaSingleField.js +2 -2
- package/dist/components/core/form/fields/SolidMediaSingleField.js.map +1 -1
- package/dist/components/core/form/fields/SolidMediaSingleField.tsx +2 -2
- package/dist/components/core/list/columns/SolidMediaMultipleColumn.js +2 -2
- package/dist/components/core/list/columns/SolidMediaMultipleColumn.js.map +1 -1
- package/dist/components/core/list/columns/SolidMediaMultipleColumn.tsx +4 -4
- package/dist/components/core/list/columns/SolidMediaSingleColumn.js +1 -1
- package/dist/components/core/list/columns/SolidMediaSingleColumn.js.map +1 -1
- package/dist/components/core/list/columns/SolidMediaSingleColumn.tsx +3 -3
- package/dist/components/core/solid-agent/SolidAgentChat.d.ts +3 -1
- package/dist/components/core/solid-agent/SolidAgentChat.d.ts.map +1 -1
- package/dist/components/core/solid-agent/SolidAgentChat.js +150 -22
- package/dist/components/core/solid-agent/SolidAgentChat.js.map +1 -1
- package/dist/components/core/solid-agent/SolidAgentChat.tsx +76 -15
- package/dist/components/core/solid-agent/SolidAgentEmbedded.d.ts +2 -0
- package/dist/components/core/solid-agent/SolidAgentEmbedded.d.ts.map +1 -1
- package/dist/components/core/solid-agent/SolidAgentEmbedded.js +4 -4
- package/dist/components/core/solid-agent/SolidAgentEmbedded.js.map +1 -1
- package/dist/components/core/solid-agent/SolidAgentEmbedded.tsx +7 -1
- package/dist/components/core/solid-agent/SolidAgentHost.d.ts.map +1 -1
- package/dist/components/core/solid-agent/SolidAgentHost.js +79 -1
- package/dist/components/core/solid-agent/SolidAgentHost.js.map +1 -1
- package/dist/components/core/solid-agent/SolidAgentHost.tsx +69 -2
- package/dist/components/core/solid-agent/agentEvents.d.ts.map +1 -1
- package/dist/components/core/solid-agent/agentEvents.js +1 -3
- package/dist/components/core/solid-agent/agentEvents.js.map +1 -1
- package/dist/components/core/solid-agent/agentEvents.ts +5 -3
- package/dist/components/core/solid-agent/client/agentPublicEvents.d.ts +88 -0
- package/dist/components/core/solid-agent/client/agentPublicEvents.d.ts.map +1 -0
- package/dist/components/core/solid-agent/client/agentPublicEvents.js +26 -0
- package/dist/components/core/solid-agent/client/agentPublicEvents.js.map +1 -0
- package/dist/components/core/solid-agent/client/agentPublicEvents.ts +66 -0
- package/dist/components/core/solid-agent/client/agentRuntime.d.ts +18 -3
- package/dist/components/core/solid-agent/client/agentRuntime.d.ts.map +1 -1
- package/dist/components/core/solid-agent/client/agentRuntime.js +173 -31
- package/dist/components/core/solid-agent/client/agentRuntime.js.map +1 -1
- package/dist/components/core/solid-agent/client/agentRuntime.ts +126 -16
- package/dist/components/core/solid-agent/client/agentSocket.d.ts +3 -0
- package/dist/components/core/solid-agent/client/agentSocket.d.ts.map +1 -1
- package/dist/components/core/solid-agent/client/agentSocket.js +19 -1
- package/dist/components/core/solid-agent/client/agentSocket.js.map +1 -1
- package/dist/components/core/solid-agent/client/agentSocket.ts +11 -1
- package/dist/components/core/solid-agent/client/beforeUserMessageSend.d.ts +9 -0
- package/dist/components/core/solid-agent/client/beforeUserMessageSend.d.ts.map +1 -0
- package/dist/components/core/solid-agent/client/beforeUserMessageSend.js +53 -0
- package/dist/components/core/solid-agent/client/beforeUserMessageSend.js.map +1 -0
- package/dist/components/core/solid-agent/client/beforeUserMessageSend.ts +26 -0
- package/dist/components/core/solid-agent/embed/AgentEmbeddingPanel.d.ts.map +1 -1
- package/dist/components/core/solid-agent/embed/AgentEmbeddingPanel.js +4 -3
- package/dist/components/core/solid-agent/embed/AgentEmbeddingPanel.js.map +1 -1
- package/dist/components/core/solid-agent/embed/AgentEmbeddingPanel.tsx +4 -2
- package/dist/components/core/solid-agent/embed/agentEmbedProtocol.d.ts +29 -0
- package/dist/components/core/solid-agent/embed/agentEmbedProtocol.d.ts.map +1 -1
- package/dist/components/core/solid-agent/embed/agentEmbedProtocol.js +45 -2
- package/dist/components/core/solid-agent/embed/agentEmbedProtocol.js.map +1 -1
- package/dist/components/core/solid-agent/embed/agentEmbedProtocol.ts +49 -2
- package/dist/components/core/solid-agent/embed/agentEmbedSamples.d.ts +1 -0
- package/dist/components/core/solid-agent/embed/agentEmbedSamples.d.ts.map +1 -1
- package/dist/components/core/solid-agent/embed/agentEmbedSamples.js +2 -1
- package/dist/components/core/solid-agent/embed/agentEmbedSamples.js.map +1 -1
- package/dist/components/core/solid-agent/embed/agentEmbedSamples.ts +15 -1
- package/dist/components/core/solid-agent/types.d.ts +13 -0
- package/dist/components/core/solid-agent/types.d.ts.map +1 -1
- package/dist/components/core/solid-agent/types.js.map +1 -1
- package/dist/components/core/solid-agent/types.ts +8 -0
- package/dist/components/core/solid-agent/useAgentChat.d.ts +1 -1
- package/dist/components/core/solid-agent/useAgentChat.d.ts.map +1 -1
- package/dist/components/core/solid-agent/useAgentChat.js +7 -4
- package/dist/components/core/solid-agent/useAgentChat.js.map +1 -1
- package/dist/components/core/solid-agent/useAgentChat.ts +9 -5
- package/dist/components/core/solid-agent/widgets/DefaultUserMessageChatWidget.d.ts.map +1 -1
- package/dist/components/core/solid-agent/widgets/DefaultUserMessageChatWidget.js +12 -4
- package/dist/components/core/solid-agent/widgets/DefaultUserMessageChatWidget.js.map +1 -1
- package/dist/components/core/solid-agent/widgets/DefaultUserMessageChatWidget.tsx +18 -0
- package/dist/components/core/solid-agent/widgets/SolidNavigationIntentChatWidget.d.ts +4 -0
- package/dist/components/core/solid-agent/widgets/SolidNavigationIntentChatWidget.d.ts.map +1 -0
- package/dist/components/core/solid-agent/widgets/SolidNavigationIntentChatWidget.js +30 -0
- package/dist/components/core/solid-agent/widgets/SolidNavigationIntentChatWidget.js.map +1 -0
- package/dist/components/core/solid-agent/widgets/SolidNavigationIntentChatWidget.tsx +41 -0
- package/dist/components/core/solid-agent/widgets/solidChatWidgets.module.css +39 -0
- package/dist/components/shad-cn-ui/SolidCodeEditor.d.ts +2 -1
- package/dist/components/shad-cn-ui/SolidCodeEditor.d.ts.map +1 -1
- package/dist/components/shad-cn-ui/SolidCodeEditor.js +3 -2
- package/dist/components/shad-cn-ui/SolidCodeEditor.js.map +1 -1
- package/dist/components/shad-cn-ui/SolidCodeEditor.tsx +3 -0
- package/dist/helpers/adminViewRefresh.d.ts +13 -0
- package/dist/helpers/adminViewRefresh.d.ts.map +1 -0
- package/dist/helpers/adminViewRefresh.js +14 -0
- package/dist/helpers/adminViewRefresh.js.map +1 -0
- package/dist/helpers/adminViewRefresh.ts +26 -0
- package/dist/helpers/eventBus.d.ts +1 -0
- package/dist/helpers/eventBus.d.ts.map +1 -1
- package/dist/helpers/eventBus.js +1 -0
- package/dist/helpers/eventBus.js.map +1 -1
- package/dist/helpers/eventBus.ts +1 -0
- package/dist/helpers/fileTypeIcon.d.ts.map +1 -1
- package/dist/helpers/fileTypeIcon.js +4 -1
- package/dist/helpers/fileTypeIcon.js.map +1 -1
- package/dist/helpers/fileTypeIcon.tsx +15 -0
- package/dist/helpers/registry.d.ts.map +1 -1
- package/dist/helpers/registry.js +2 -0
- package/dist/helpers/registry.js.map +1 -1
- package/dist/helpers/registry.ts +2 -0
- package/dist/helpers/routePaths.d.ts +13 -0
- package/dist/helpers/routePaths.d.ts.map +1 -1
- package/dist/helpers/routePaths.js +39 -0
- package/dist/helpers/routePaths.js.map +1 -1
- package/dist/helpers/routePaths.ts +48 -0
- package/dist/redux/features/agentSlice.d.ts +2 -1
- package/dist/redux/features/agentSlice.d.ts.map +1 -1
- package/dist/redux/features/agentSlice.js +2 -2
- package/dist/redux/features/agentSlice.js.map +1 -1
- package/dist/redux/features/agentSlice.ts +8 -3
- package/dist/resources/solid-custom.css +42 -0
- package/dist/resources/solid-tailwind-generated.css +1 -1
- package/dist/routes/pages/admin/core/AgentHubModuleField.css +15 -0
- package/dist/routes/pages/admin/core/AgentHubModuleField.d.ts +22 -0
- package/dist/routes/pages/admin/core/AgentHubModuleField.d.ts.map +1 -0
- package/dist/routes/pages/admin/core/AgentHubModuleField.js +42 -0
- package/dist/routes/pages/admin/core/AgentHubModuleField.js.map +1 -0
- package/dist/routes/pages/admin/core/AgentHubModuleField.tsx +54 -0
- package/dist/routes/pages/admin/core/AgentHubTagsField.d.ts +3 -1
- package/dist/routes/pages/admin/core/AgentHubTagsField.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/AgentHubTagsField.js +3 -3
- package/dist/routes/pages/admin/core/AgentHubTagsField.js.map +1 -1
- package/dist/routes/pages/admin/core/AgentHubTagsField.tsx +7 -3
- package/dist/routes/pages/admin/core/AgentRegistryEditorPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/AgentRegistryEditorPage.js +37 -29
- package/dist/routes/pages/admin/core/AgentRegistryEditorPage.js.map +1 -1
- package/dist/routes/pages/admin/core/AgentRegistryEditorPage.tsx +12 -6
- package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.js +22 -15
- package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.js.map +1 -1
- package/dist/routes/pages/admin/core/AgentSkillRegistryEditorPage.tsx +17 -7
- package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.js +21 -15
- package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.js.map +1 -1
- package/dist/routes/pages/admin/core/AgentToolRegistryEditorPage.tsx +16 -9
- package/dist/routes/pages/admin/core/ArchivedChatterMessagesPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/ArchivedChatterMessagesPage.js +149 -37
- package/dist/routes/pages/admin/core/ArchivedChatterMessagesPage.js.map +1 -1
- package/dist/routes/pages/admin/core/ArchivedChatterMessagesPage.tsx +283 -73
- package/dist/routes/pages/admin/core/CardPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/CardPage.js +9 -1
- package/dist/routes/pages/admin/core/CardPage.js.map +1 -1
- package/dist/routes/pages/admin/core/CardPage.tsx +9 -1
- package/dist/routes/pages/admin/core/KanbanPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/KanbanPage.js +9 -1
- package/dist/routes/pages/admin/core/KanbanPage.js.map +1 -1
- package/dist/routes/pages/admin/core/KanbanPage.tsx +9 -1
- package/dist/routes/pages/admin/core/ListPage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/ListPage.js +10 -1
- package/dist/routes/pages/admin/core/ListPage.js.map +1 -1
- package/dist/routes/pages/admin/core/ListPage.tsx +10 -1
- package/dist/routes/pages/admin/core/TreePage.d.ts.map +1 -1
- package/dist/routes/pages/admin/core/TreePage.js +9 -1
- package/dist/routes/pages/admin/core/TreePage.js.map +1 -1
- package/dist/routes/pages/admin/core/TreePage.tsx +9 -1
- package/dist/routes/pages/embed/AgentEmbedPage.d.ts.map +1 -1
- package/dist/routes/pages/embed/AgentEmbedPage.js +67 -4
- package/dist/routes/pages/embed/AgentEmbedPage.js.map +1 -1
- package/dist/routes/pages/embed/AgentEmbedPage.tsx +61 -4
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentEmbeddingPanel.js","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/embed/AgentEmbeddingPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState } from \"react\";\nimport { Copy, Check } from \"lucide-react\";\nimport { env } from \"../../../../adapters/env\";\nimport { SolidButton, SolidCodeEditor, SolidTabGroup } from \"../../../shad-cn-ui\";\nimport type { AgentInputDefinition } from \"./agentEmbedProtocol\";\nimport { embedSamples } from \"./agentEmbedSamples\";\n\nexport function AgentEmbeddingPanel({ agentId, fields, hubUrl, active }: { agentId: number; fields: AgentInputDefinition[]; hubUrl: string; active: boolean }) {\n const [tab, setTab] = useState(\"javascript\");\n const [backend, setBackend] = useState(\"express\");\n const [copied, setCopied] = useState(\"\");\n const [copyError, setCopyError] = useState(\"\");\n const sdkUrl = `${env(\"NEXT_PUBLIC_BACKEND_API_URL\").replace(/\\/$/, \"\")}/api/agent-embed/sdk.js?v=2`;\n const samples = embedSamples(agentId, fields, sdkUrl, hubUrl || \"https://agenthub.example.com\");\n async function copy(key: string, code: string) {\n try { await navigator.clipboard.writeText(code); setCopied(key); setCopyError(\"\"); }\n catch { setCopyError(\"Clipboard access is unavailable. Select and copy the code below.\"); }\n }\n const code = (value: string, language: string) => <SolidCodeEditor readOnly value={value} language={language} fontSize={11} height=\"420px\" />;\n const copyButton = (key: string, value: string) => <SolidButton variant=\"secondary\" size=\"small\" onClick={() => void copy(key, value)}>\n {copied === key ? <Check size={14} /> : <Copy size={14} />} {copied === key ? \"Copied\" : \"Copy code\"}\n </SolidButton>;\n return <div className=\"agent-editor__stack\">\n {!active && <p role=\"status\" className=\"agent-editor__hint\">Activate this agent before embedding it. Samples use the saved agent definition.</p>}\n <section className=\"agent-editor__section\"><h2>1. Keep your API key on your server</h2>\n <p>Configure <code>AGENTHUB_API_KEY</code>, <code>AGENTHUB_AGENT_ID</code>, and <code>AGENTHUB_BACKEND_URL</code> on the server that hosts your app API. Never expose the API key or AgentHub runtime URL in browser code. The browser receives only the short-lived embed response through the SDK handshake.</p>\n </section>\n <section className=\"agent-editor__section\"><h2>2. Create your token endpoint</h2>\n <p>Your app API accepts the SDK's token request, ignores any client-selected backend or API key, and uses the configured agent ID to call <code>/api/agent/api-keys/embedded/me</code> on AgentHub Runtime. Return the successful JSON response unchanged with <code>Cache-Control: no-store</code>; never cache or log credentials or tokens.</p>\n <p>Anonymous embeds can expose this endpoint publicly, as in the demo. Add rate limiting at your API or gateway and use your app's authorization policy when chat access should require sign-in. <code>externalUserId</code> is optional: when the trusted auth layer supplies a stable user ID, send a namespaced value; omit it for anonymous visitors. The runtime manages chat sessions independently.</p>\n <SolidTabGroup tabs={[\n { value: \"python\", label: \"Python / FastAPI\", content: code(samples.python, \"python\") },\n { value: \"nestjs\", label: \"NestJS\", content: code(samples.nestjs, \"typescript\") },\n { value: \"express\", label: \"Express\", content: code(samples.express, \"javascript\") },\n { value: \"java\", label: \"Java / Spring Boot\", content: code(samples.java, \"java\") },\n { value: \"dotnet\", label: \".NET / ASP.NET Core\", content: code(samples.dotnet, \"csharp\") },\n ]} value={backend} onValueChange={setBackend} extra={copyButton(backend, samples[backend as keyof typeof samples])} />\n </section>\n <section className=\"agent-editor__section\"><h2>3. Embed the chat</h2>\n <p>Load the SDK from the public SDK URL shown below and mount it into a browser container. The SDK calls your app's <code>tokenEndpoint</code>, passes the response to the hosted chat in memory, and manages the iframe handshake and token renewal. No SolidX npm dependency is required.</p>\n <p>Use a same-origin path such as <code>/api/agent-chat/token</code> when possible. If your app API has another origin, give <code>tokenEndpoint</code> its absolute URL and configure that API's CORS policy for the browser app origin.</p>\n <p>The SDK-serving SolidX API selects the hosted chat UI from its server-side <code>AGENT_EMBED_UI_URL</code> setting. The consuming app does not supply an <code>embedUrl</code> or choose the iframe host. Keep the SDK script URL and the configured hosted UI origin aligned to the same SolidX deployment.</p>\n <p>Pass the current page's required input values in <code>inputs</code> using the names and types in this agent's schema. These values provide task context; they are not authorization to access records. Enforce access to protected data in your own API/tools. For a logged-in app, use <code>getTokenHeaders</code> to send the app's normal bearer or CSRF header to your app API; do not send the AgentHub API key from the browser.</p>\n <SolidTabGroup tabs={[\n { value: \"javascript\", label: \"JavaScript\", content: code(samples.javascript, \"html\") },\n { value: \"react\", label: \"React\", content: code(samples.react, \"javascript\") },\n ]} value={tab} onValueChange={setTab} extra={copyButton(tab, tab === \"javascript\" ? samples.javascript : samples.react)} />\n </section>\n <section className=\"agent-editor__section\"><h2>Inputs</h2>\n {fields.length ? <table style={{ width: \"100%\", textAlign: \"left\" }}><thead><tr><th>Variable</th><th>Data type</th><th>Description</th><th>Default value</th><th>Optional</th></tr></thead>\n <tbody>{fields.map((field) => <tr key={field.name}><td><code>{field.name}</code></td><td>{field.dataType}</td><td>{field.description}</td><td>{field.defaultValue == null ? \"—\" : typeof field.defaultValue === \"string\" ? field.defaultValue : JSON.stringify(field.defaultValue)}</td><td>{field.optional ? \"Yes\" : \"No\"}</td></tr>)}</tbody></table>\n : <p>This agent has no inputs.</p>}\n <p>Replace sample values with the current page's values and preserve each declared type. Default values are used when an input is omitted; optional inputs may be omitted without a default. Inputs are fixed after the first message; start a new chat to change them. They describe the task and do not grant access to data.</p>\n </section>\n <section className=\"agent-editor__section\"><h2>Hosting and deployment</h2><p>Make <code>/embed/agent/{agentId}</code> available on the hosted UI selected by <code>AGENT_EMBED_UI_URL</code>. Allow the consuming app origin in the hosted UI's frame-ancestors policy, the AgentHub Runtime origin in its CORS configuration, and the SDK/API/iframe origins in the consuming app's CSP. Use HTTPS for the consuming page, SDK, hosted UI, and runtime in production.</p></section>\n {copyError && <p role=\"alert\">{copyError}</p>}\n </div>;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"AgentEmbeddingPanel.js","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/embed/AgentEmbeddingPanel.tsx"],"names":[],"mappings":"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","sourcesContent":["import React, { useState } from \"react\";\nimport { Copy, Check } from \"lucide-react\";\nimport { env } from \"../../../../adapters/env\";\nimport { SolidButton, SolidCodeEditor, SolidTabGroup } from \"../../../shad-cn-ui\";\nimport type { AgentInputDefinition } from \"./agentEmbedProtocol\";\nimport { embedSamples } from \"./agentEmbedSamples\";\n\nexport function AgentEmbeddingPanel({ agentId, fields, hubUrl, active }: { agentId: number; fields: AgentInputDefinition[]; hubUrl: string; active: boolean }) {\n const [tab, setTab] = useState(\"javascript\");\n const [backend, setBackend] = useState(\"express\");\n const [copied, setCopied] = useState(\"\");\n const [copyError, setCopyError] = useState(\"\");\n const sdkUrl = `${env(\"NEXT_PUBLIC_BACKEND_API_URL\").replace(/\\/$/, \"\")}/api/agent-embed/sdk.js?v=4`;\n const samples = embedSamples(agentId, fields, sdkUrl, hubUrl || \"https://agenthub.example.com\");\n async function copy(key: string, code: string) {\n try { await navigator.clipboard.writeText(code); setCopied(key); setCopyError(\"\"); }\n catch { setCopyError(\"Clipboard access is unavailable. Select and copy the code below.\"); }\n }\n const code = (value: string, language: string) => <SolidCodeEditor readOnly value={value} language={language} fontSize={11} height=\"420px\" />;\n const copyButton = (key: string, value: string) => <SolidButton variant=\"secondary\" size=\"small\" onClick={() => void copy(key, value)}>\n {copied === key ? <Check size={14} /> : <Copy size={14} />} {copied === key ? \"Copied\" : \"Copy code\"}\n </SolidButton>;\n return <div className=\"agent-editor__stack\">\n {!active && <p role=\"status\" className=\"agent-editor__hint\">Activate this agent before embedding it. Samples use the saved agent definition.</p>}\n <section className=\"agent-editor__section\"><h2>1. Keep your API key on your server</h2>\n <p>Configure <code>AGENTHUB_API_KEY</code>, <code>AGENTHUB_AGENT_ID</code>, and <code>AGENTHUB_BACKEND_URL</code> on the server that hosts your app API. Never expose the API key or AgentHub runtime URL in browser code. The browser receives only the short-lived embed response through the SDK handshake.</p>\n </section>\n <section className=\"agent-editor__section\"><h2>2. Create your token endpoint</h2>\n <p>Your app API accepts the SDK's token request, ignores any client-selected backend or API key, and uses the configured agent ID to call <code>/api/agent/api-keys/embedded/me</code> on AgentHub Runtime. Return the successful JSON response unchanged with <code>Cache-Control: no-store</code>; never cache or log credentials or tokens.</p>\n <p>Anonymous embeds can expose this endpoint publicly, as in the demo. Add rate limiting at your API or gateway and use your app's authorization policy when chat access should require sign-in. <code>externalUserId</code> is optional: when the trusted auth layer supplies a stable user ID, send a namespaced value; omit it for anonymous visitors. The runtime manages chat sessions independently.</p>\n <SolidTabGroup tabs={[\n { value: \"python\", label: \"Python / FastAPI\", content: code(samples.python, \"python\") },\n { value: \"nestjs\", label: \"NestJS\", content: code(samples.nestjs, \"typescript\") },\n { value: \"express\", label: \"Express\", content: code(samples.express, \"javascript\") },\n { value: \"java\", label: \"Java / Spring Boot\", content: code(samples.java, \"java\") },\n { value: \"dotnet\", label: \".NET / ASP.NET Core\", content: code(samples.dotnet, \"csharp\") },\n ]} value={backend} onValueChange={setBackend} extra={copyButton(backend, samples[backend as keyof typeof samples])} />\n </section>\n <section className=\"agent-editor__section\"><h2>3. Embed the chat</h2>\n <p>Load the SDK from the public SDK URL shown below and mount it into a browser container. The SDK calls your app's <code>tokenEndpoint</code>, passes the response to the hosted chat in memory, and manages the iframe handshake and token renewal. No SolidX npm dependency is required.</p>\n <p><code>mode: \"popup\"</code> is the default and provides a floating launcher. <code>mode: \"inline\"</code> fills your container; your app controls its size and layout. Keep the instance mounted across client-side navigation to preserve the live chat.</p>\n <p>Use a same-origin path such as <code>/api/agent-chat/token</code> when possible. If your app API has another origin, give <code>tokenEndpoint</code> its absolute URL and configure that API's CORS policy for the browser app origin.</p>\n <p>The SDK-serving SolidX API selects the hosted chat UI from its server-side <code>AGENT_EMBED_UI_URL</code> setting. The consuming app does not supply an <code>embedUrl</code> or choose the iframe host. Keep the SDK script URL and the configured hosted UI origin aligned to the same SolidX deployment.</p>\n <p>Pass the current page's required input values in <code>inputs</code> using the names and types in this agent's schema. These values provide task context; they are not authorization to access records. Enforce access to protected data in your own API/tools. For a logged-in app, use <code>getTokenHeaders</code> to send the app's normal bearer or CSRF header to your app API; do not send the AgentHub API key from the browser.</p>\n <SolidTabGroup tabs={[\n { value: \"javascript\", label: \"JavaScript\", content: code(samples.javascript, \"html\") },\n { value: \"inline\", label: \"Inline\", content: code(samples.inline, \"html\") },\n { value: \"react\", label: \"React\", content: code(samples.react, \"javascript\") },\n ]} value={tab} onValueChange={setTab} extra={copyButton(tab, samples[tab as \"javascript\" | \"inline\" | \"react\"])} />\n </section>\n <section className=\"agent-editor__section\"><h2>Inputs</h2>\n {fields.length ? <table style={{ width: \"100%\", textAlign: \"left\" }}><thead><tr><th>Variable</th><th>Data type</th><th>Description</th><th>Default value</th><th>Optional</th></tr></thead>\n <tbody>{fields.map((field) => <tr key={field.name}><td><code>{field.name}</code></td><td>{field.dataType}</td><td>{field.description}</td><td>{field.defaultValue == null ? \"—\" : typeof field.defaultValue === \"string\" ? field.defaultValue : JSON.stringify(field.defaultValue)}</td><td>{field.optional ? \"Yes\" : \"No\"}</td></tr>)}</tbody></table>\n : <p>This agent has no inputs.</p>}\n <p>Replace sample values with the current page's values and preserve each declared type. Default values are used when an input is omitted; optional inputs may be omitted without a default. Inputs are fixed after the first message; start a new chat to change them. They describe the task and do not grant access to data.</p>\n </section>\n <section className=\"agent-editor__section\"><h2>Hosting and deployment</h2><p>Make <code>/embed/agent/{agentId}</code> available on the hosted UI selected by <code>AGENT_EMBED_UI_URL</code>. Allow the consuming app origin in the hosted UI's frame-ancestors policy, the AgentHub Runtime origin in its CORS configuration, and the SDK/API/iframe origins in the consuming app's CSP. Use HTTPS for the consuming page, SDK, hosted UI, and runtime in production.</p></section>\n {copyError && <p role=\"alert\">{copyError}</p>}\n </div>;\n}\n"]}
|
|
@@ -10,7 +10,7 @@ export function AgentEmbeddingPanel({ agentId, fields, hubUrl, active }: { agent
|
|
|
10
10
|
const [backend, setBackend] = useState("express");
|
|
11
11
|
const [copied, setCopied] = useState("");
|
|
12
12
|
const [copyError, setCopyError] = useState("");
|
|
13
|
-
const sdkUrl = `${env("NEXT_PUBLIC_BACKEND_API_URL").replace(/\/$/, "")}/api/agent-embed/sdk.js?v=
|
|
13
|
+
const sdkUrl = `${env("NEXT_PUBLIC_BACKEND_API_URL").replace(/\/$/, "")}/api/agent-embed/sdk.js?v=4`;
|
|
14
14
|
const samples = embedSamples(agentId, fields, sdkUrl, hubUrl || "https://agenthub.example.com");
|
|
15
15
|
async function copy(key: string, code: string) {
|
|
16
16
|
try { await navigator.clipboard.writeText(code); setCopied(key); setCopyError(""); }
|
|
@@ -38,13 +38,15 @@ export function AgentEmbeddingPanel({ agentId, fields, hubUrl, active }: { agent
|
|
|
38
38
|
</section>
|
|
39
39
|
<section className="agent-editor__section"><h2>3. Embed the chat</h2>
|
|
40
40
|
<p>Load the SDK from the public SDK URL shown below and mount it into a browser container. The SDK calls your app's <code>tokenEndpoint</code>, passes the response to the hosted chat in memory, and manages the iframe handshake and token renewal. No SolidX npm dependency is required.</p>
|
|
41
|
+
<p><code>mode: "popup"</code> is the default and provides a floating launcher. <code>mode: "inline"</code> fills your container; your app controls its size and layout. Keep the instance mounted across client-side navigation to preserve the live chat.</p>
|
|
41
42
|
<p>Use a same-origin path such as <code>/api/agent-chat/token</code> when possible. If your app API has another origin, give <code>tokenEndpoint</code> its absolute URL and configure that API's CORS policy for the browser app origin.</p>
|
|
42
43
|
<p>The SDK-serving SolidX API selects the hosted chat UI from its server-side <code>AGENT_EMBED_UI_URL</code> setting. The consuming app does not supply an <code>embedUrl</code> or choose the iframe host. Keep the SDK script URL and the configured hosted UI origin aligned to the same SolidX deployment.</p>
|
|
43
44
|
<p>Pass the current page's required input values in <code>inputs</code> using the names and types in this agent's schema. These values provide task context; they are not authorization to access records. Enforce access to protected data in your own API/tools. For a logged-in app, use <code>getTokenHeaders</code> to send the app's normal bearer or CSRF header to your app API; do not send the AgentHub API key from the browser.</p>
|
|
44
45
|
<SolidTabGroup tabs={[
|
|
45
46
|
{ value: "javascript", label: "JavaScript", content: code(samples.javascript, "html") },
|
|
47
|
+
{ value: "inline", label: "Inline", content: code(samples.inline, "html") },
|
|
46
48
|
{ value: "react", label: "React", content: code(samples.react, "javascript") },
|
|
47
|
-
]} value={tab} onValueChange={setTab} extra={copyButton(tab, tab
|
|
49
|
+
]} value={tab} onValueChange={setTab} extra={copyButton(tab, samples[tab as "javascript" | "inline" | "react"])} />
|
|
48
50
|
</section>
|
|
49
51
|
<section className="agent-editor__section"><h2>Inputs</h2>
|
|
50
52
|
{fields.length ? <table style={{ width: "100%", textAlign: "left" }}><thead><tr><th>Variable</th><th>Data type</th><th>Description</th><th>Default value</th><th>Optional</th></tr></thead>
|
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
import type { AgentBootstrap } from "../client/agentAuth";
|
|
2
2
|
export declare const EMBED_CHANNEL = "solidx-agent-embed";
|
|
3
|
+
export declare const EMBED_PUBLIC_PROTOCOL_VERSION = 2;
|
|
4
|
+
export declare const EMBED_MESSAGE_CONTEXT_MAX_BYTES: number;
|
|
5
|
+
export type EmbedJson = null | boolean | number | string | EmbedJson[] | {
|
|
6
|
+
[key: string]: EmbedJson;
|
|
7
|
+
};
|
|
8
|
+
export type EmbedContextContribution = {
|
|
9
|
+
context: EmbedJson;
|
|
10
|
+
revision: string;
|
|
11
|
+
displaySummary?: string;
|
|
12
|
+
};
|
|
13
|
+
export type EmbedMessageContext = {
|
|
14
|
+
schemaVersion: 1;
|
|
15
|
+
namespaces: Record<string, EmbedContextContribution>;
|
|
16
|
+
};
|
|
17
|
+
export type BeforeUserMessageSendRequest = {
|
|
18
|
+
text: string;
|
|
19
|
+
source: "composer" | "sdk" | "prefill" | "widget";
|
|
20
|
+
attachments: Array<{
|
|
21
|
+
name: string;
|
|
22
|
+
mimeType: string;
|
|
23
|
+
size: number;
|
|
24
|
+
}>;
|
|
25
|
+
contextRevision?: string;
|
|
26
|
+
};
|
|
27
|
+
export type BeforeUserMessageSendListener = (request: BeforeUserMessageSendRequest, signal: AbortSignal) => Promise<EmbedContextContribution | {
|
|
28
|
+
cancelled: true;
|
|
29
|
+
reason?: string;
|
|
30
|
+
}>;
|
|
3
31
|
export type AgentInputDefinition = {
|
|
4
32
|
name: string;
|
|
5
33
|
description: string;
|
|
@@ -17,6 +45,7 @@ export declare class MissingAgentInputsError extends Error {
|
|
|
17
45
|
readonly inputNames: string[];
|
|
18
46
|
constructor(inputNames: string[]);
|
|
19
47
|
}
|
|
48
|
+
export declare function validateMessageContext(value: unknown): EmbedMessageContext;
|
|
20
49
|
export declare function validateBootstrap(value: unknown, agentId: number): AgentEmbedBootstrap;
|
|
21
50
|
export declare function validateEmbedInputs(fields: AgentInputDefinition[], suppliedValues?: Record<string, unknown>): void;
|
|
22
51
|
//# sourceMappingURL=agentEmbedProtocol.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentEmbedProtocol.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/embed/agentEmbedProtocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,eAAO,MAAM,aAAa,uBAAuB,CAAC;AAClD,MAAM,MAAM,oBAAoB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AACvI,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG;IAC/C,KAAK,EAAE,IAAI,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,oBAAoB,EAAE,CAAC;CAC1C,CAAC;AAEF,qBAAa,uBAAwB,SAAQ,KAAK;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE;gBAApB,UAAU,EAAE,MAAM,EAAE;CAI5C;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAWtF;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,oBAAoB,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CA4BlH"}
|
|
1
|
+
{"version":3,"file":"agentEmbedProtocol.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/embed/agentEmbedProtocol.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,eAAO,MAAM,aAAa,uBAAuB,CAAC;AAClD,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAC/C,eAAO,MAAM,+BAA+B,QAAY,CAAC;AACzD,MAAM,MAAM,SAAS,GAAG,IAAI,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,EAAE,GAAG;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AACtG,MAAM,MAAM,wBAAwB,GAAG;IAAE,OAAO,EAAE,SAAS,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AACzG,MAAM,MAAM,mBAAmB,GAAG;IAAE,aAAa,EAAE,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,wBAAwB,CAAC,CAAA;CAAE,CAAC;AAC7G,MAAM,MAAM,4BAA4B,GAAG;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,GAAG,KAAK,GAAG,SAAS,GAAG,QAAQ,CAAC;IAClD,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACrE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC5B,CAAC;AACF,MAAM,MAAM,6BAA6B,GAAG,CACxC,OAAO,EAAE,4BAA4B,EACrC,MAAM,EAAE,WAAW,KAClB,OAAO,CAAC,wBAAwB,GAAG;IAAE,SAAS,EAAE,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAC9E,MAAM,MAAM,oBAAoB,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AACvI,MAAM,MAAM,mBAAmB,GAAG,cAAc,GAAG;IAC/C,KAAK,EAAE,IAAI,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,EAAE,oBAAoB,EAAE,CAAC;CAC1C,CAAC;AAEF,qBAAa,uBAAwB,SAAQ,KAAK;IAClC,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE;gBAApB,UAAU,EAAE,MAAM,EAAE;CAI5C;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CA8B1E;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAWtF;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,oBAAoB,EAAE,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CA4BlH"}
|
|
@@ -14,6 +14,8 @@ var __extends = (this && this.__extends) || (function () {
|
|
|
14
14
|
};
|
|
15
15
|
})();
|
|
16
16
|
export var EMBED_CHANNEL = "solidx-agent-embed";
|
|
17
|
+
export var EMBED_PUBLIC_PROTOCOL_VERSION = 2;
|
|
18
|
+
export var EMBED_MESSAGE_CONTEXT_MAX_BYTES = 32 * 1024;
|
|
17
19
|
var MissingAgentInputsError = /** @class */ (function (_super) {
|
|
18
20
|
__extends(MissingAgentInputsError, _super);
|
|
19
21
|
function MissingAgentInputsError(inputNames) {
|
|
@@ -30,6 +32,47 @@ var MissingAgentInputsError = /** @class */ (function (_super) {
|
|
|
30
32
|
return MissingAgentInputsError;
|
|
31
33
|
}(Error));
|
|
32
34
|
export { MissingAgentInputsError };
|
|
35
|
+
export function validateMessageContext(value) {
|
|
36
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
37
|
+
throw new Error("message_context must be an object.");
|
|
38
|
+
var context = value;
|
|
39
|
+
if (context.schemaVersion !== 1 || !context.namespaces || typeof context.namespaces !== "object"
|
|
40
|
+
|| Array.isArray(context.namespaces) || Object.keys(context.namespaces).length > 32)
|
|
41
|
+
throw new Error("message_context must use schemaVersion 1 and contain a namespaces object.");
|
|
42
|
+
for (var _i = 0, _a = Object.entries(context.namespaces); _i < _a.length; _i++) {
|
|
43
|
+
var _b = _a[_i], namespace = _b[0], contribution = _b[1];
|
|
44
|
+
if (!namespace || namespace.length > 80 || !contribution || typeof contribution !== "object"
|
|
45
|
+
|| typeof contribution.revision !== "string" || contribution.revision.length > 256 || !("context" in contribution)
|
|
46
|
+
|| (contribution.displaySummary !== undefined && (typeof contribution.displaySummary !== "string" || contribution.displaySummary.length > 1024)))
|
|
47
|
+
throw new Error("message_context contains an invalid namespace contribution.");
|
|
48
|
+
}
|
|
49
|
+
var isJson = function (item, depth) {
|
|
50
|
+
if (depth === void 0) { depth = 0; }
|
|
51
|
+
if (depth > 12)
|
|
52
|
+
return false;
|
|
53
|
+
if (item === null || typeof item === "string" || typeof item === "boolean")
|
|
54
|
+
return true;
|
|
55
|
+
if (typeof item === "number")
|
|
56
|
+
return Number.isFinite(item);
|
|
57
|
+
if (Array.isArray(item))
|
|
58
|
+
return item.length <= 1024 && item.every(function (child) { return isJson(child, depth + 1); });
|
|
59
|
+
if (typeof item !== "object" || Object.getPrototypeOf(item) !== Object.prototype)
|
|
60
|
+
return false;
|
|
61
|
+
return Object.values(item).every(function (child) { return isJson(child, depth + 1); });
|
|
62
|
+
};
|
|
63
|
+
var serialized;
|
|
64
|
+
try {
|
|
65
|
+
if (!isJson(value))
|
|
66
|
+
throw new Error("message_context contains unsupported JSON values.");
|
|
67
|
+
serialized = JSON.stringify(value);
|
|
68
|
+
}
|
|
69
|
+
catch (_c) {
|
|
70
|
+
throw new Error("message_context contains unsupported JSON values.");
|
|
71
|
+
}
|
|
72
|
+
if (new TextEncoder().encode(serialized).length > EMBED_MESSAGE_CONTEXT_MAX_BYTES)
|
|
73
|
+
throw new Error("message_context exceeds 32 KiB.");
|
|
74
|
+
return value;
|
|
75
|
+
}
|
|
33
76
|
export function validateBootstrap(value, agentId) {
|
|
34
77
|
var body = value;
|
|
35
78
|
if (!body || body.embed !== true || body.agentId !== agentId || typeof body.agentToken !== "string" || !body.agentToken
|
|
@@ -55,9 +98,9 @@ export function validateEmbedInputs(fields, suppliedValues) {
|
|
|
55
98
|
}
|
|
56
99
|
var missing = fields
|
|
57
100
|
.filter(function (_a) {
|
|
58
|
-
var name = _a.name, optional = _a.optional
|
|
101
|
+
var name = _a.name, optional = _a.optional;
|
|
59
102
|
var value = values[name];
|
|
60
|
-
return !optional &&
|
|
103
|
+
return !optional && (value === undefined || value === null || (typeof value === "string" && !value.trim()));
|
|
61
104
|
})
|
|
62
105
|
.map(function (_a) {
|
|
63
106
|
var name = _a.name;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentEmbedProtocol.js","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/embed/agentEmbedProtocol.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentBootstrap } from \"../client/agentAuth\";\n\nexport const EMBED_CHANNEL = \"solidx-agent-embed\";\nexport type AgentInputDefinition = { name: string; description: string; dataType: string; defaultValue?: unknown; optional?: boolean };\nexport type AgentEmbedBootstrap = AgentBootstrap & {\n embed: true;\n agentId: number;\n title?: string;\n requiredInputs: AgentInputDefinition[];\n};\n\nexport class MissingAgentInputsError extends Error {\n constructor(readonly inputNames: string[]) {\n super(`Required inputs are missing: ${inputNames.join(\", \")}`);\n this.name = \"MissingAgentInputsError\";\n }\n}\n\nexport function validateBootstrap(value: unknown, agentId: number): AgentEmbedBootstrap {\n const body = value as AgentEmbedBootstrap;\n if (!body || body.embed !== true || body.agentId !== agentId || typeof body.agentToken !== \"string\" || !body.agentToken\n || !Array.isArray(body.requiredInputs)) throw new Error(\"The token endpoint returned an invalid embed response.\");\n const ws = new URL(body.wsUrl), http = new URL(body.httpUrl);\n if (![\"ws:\", \"wss:\"].includes(ws.protocol) || ![\"http:\", \"https:\"].includes(http.protocol)\n || ws.username || ws.password || http.username || http.password || ws.search || http.search || ws.hash || http.hash)\n throw new Error(\"The token endpoint returned invalid connection URLs.\");\n if (window.location.protocol === \"https:\" && (ws.protocol !== \"wss:\" || http.protocol !== \"https:\"))\n throw new Error(\"HTTPS embeds require HTTPS and WSS AgentHub endpoints.\");\n return body;\n}\n\nexport function validateEmbedInputs(fields: AgentInputDefinition[], suppliedValues?: Record<string, unknown>): void {\n const values = suppliedValues ?? {};\n if (typeof values !== \"object\" || Array.isArray(values)) throw new Error(\"inputs must be an object.\");\n const names = new Set(fields.map((field) => field.name));\n for (const name of Object.keys(values)) if (!names.has(name)) throw new Error(`Unknown input: ${name}`);\n const missing = fields\n .filter(({ name, optional, defaultValue }) => {\n const value = values[name];\n return !optional && defaultValue == null && (value === undefined || value === null || (typeof value === \"string\" && !value.trim()));\n })\n .map(({ name }) => name);\n if (missing.length) throw new MissingAgentInputsError(missing);\n for (const field of fields) {\n const value = values[field.name];\n let valid = false;\n switch (field.dataType) {\n case \"string\": valid = typeof value === \"string\"; break;\n case \"number\": valid = typeof value === \"number\" && Number.isFinite(value); break;\n case \"integer\": valid = typeof value === \"number\" && Number.isSafeInteger(value); break;\n case \"boolean\": valid = typeof value === \"boolean\"; break;\n case \"array\": valid = Array.isArray(value); break;\n case \"object\": valid = typeof value === \"object\" && value !== null && !Array.isArray(value); break;\n case \"date\": valid = typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}$/.test(value)\n && !Number.isNaN(Date.parse(value)) && new Date(value).toISOString().slice(0, 10) === value; break;\n case \"datetime\": valid = typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}T/.test(value) && !Number.isNaN(Date.parse(value)); break;\n }\n if (!valid) throw new Error(`Input ${field.name} must have data type ${field.dataType}.`);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agentEmbedProtocol.js","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/embed/agentEmbedProtocol.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentBootstrap } from \"../client/agentAuth\";\n\nexport const EMBED_CHANNEL = \"solidx-agent-embed\";\nexport const EMBED_PUBLIC_PROTOCOL_VERSION = 2;\nexport const EMBED_MESSAGE_CONTEXT_MAX_BYTES = 32 * 1024;\nexport type EmbedJson = null | boolean | number | string | EmbedJson[] | { [key: string]: EmbedJson };\nexport type EmbedContextContribution = { context: EmbedJson; revision: string; displaySummary?: string };\nexport type EmbedMessageContext = { schemaVersion: 1; namespaces: Record<string, EmbedContextContribution> };\nexport type BeforeUserMessageSendRequest = {\n text: string;\n source: \"composer\" | \"sdk\" | \"prefill\" | \"widget\";\n attachments: Array<{ name: string; mimeType: string; size: number }>;\n contextRevision?: string;\n};\nexport type BeforeUserMessageSendListener = (\n request: BeforeUserMessageSendRequest,\n signal: AbortSignal,\n) => Promise<EmbedContextContribution | { cancelled: true; reason?: string }>;\nexport type AgentInputDefinition = { name: string; description: string; dataType: string; defaultValue?: unknown; optional?: boolean };\nexport type AgentEmbedBootstrap = AgentBootstrap & {\n embed: true;\n agentId: number;\n title?: string;\n requiredInputs: AgentInputDefinition[];\n};\n\nexport class MissingAgentInputsError extends Error {\n constructor(readonly inputNames: string[]) {\n super(`Required inputs are missing: ${inputNames.join(\", \")}`);\n this.name = \"MissingAgentInputsError\";\n }\n}\n\nexport function validateMessageContext(value: unknown): EmbedMessageContext {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) throw new Error(\"message_context must be an object.\");\n const context = value as Partial<EmbedMessageContext>;\n if (context.schemaVersion !== 1 || !context.namespaces || typeof context.namespaces !== \"object\"\n || Array.isArray(context.namespaces) || Object.keys(context.namespaces).length > 32)\n throw new Error(\"message_context must use schemaVersion 1 and contain a namespaces object.\");\n for (const [namespace, contribution] of Object.entries(context.namespaces)) {\n if (!namespace || namespace.length > 80 || !contribution || typeof contribution !== \"object\"\n || typeof contribution.revision !== \"string\" || contribution.revision.length > 256 || !(\"context\" in contribution)\n || (contribution.displaySummary !== undefined && (typeof contribution.displaySummary !== \"string\" || contribution.displaySummary.length > 1024)))\n throw new Error(\"message_context contains an invalid namespace contribution.\");\n }\n const isJson = (item: unknown, depth = 0): boolean => {\n if (depth > 12) return false;\n if (item === null || typeof item === \"string\" || typeof item === \"boolean\") return true;\n if (typeof item === \"number\") return Number.isFinite(item);\n if (Array.isArray(item)) return item.length <= 1024 && item.every((child) => isJson(child, depth + 1));\n if (typeof item !== \"object\" || Object.getPrototypeOf(item) !== Object.prototype) return false;\n return Object.values(item as Record<string, unknown>).every((child) => isJson(child, depth + 1));\n };\n let serialized: string;\n try {\n if (!isJson(value)) throw new Error(\"message_context contains unsupported JSON values.\");\n serialized = JSON.stringify(value);\n } catch {\n throw new Error(\"message_context contains unsupported JSON values.\");\n }\n if (new TextEncoder().encode(serialized).length > EMBED_MESSAGE_CONTEXT_MAX_BYTES)\n throw new Error(\"message_context exceeds 32 KiB.\");\n return value as EmbedMessageContext;\n}\n\nexport function validateBootstrap(value: unknown, agentId: number): AgentEmbedBootstrap {\n const body = value as AgentEmbedBootstrap;\n if (!body || body.embed !== true || body.agentId !== agentId || typeof body.agentToken !== \"string\" || !body.agentToken\n || !Array.isArray(body.requiredInputs)) throw new Error(\"The token endpoint returned an invalid embed response.\");\n const ws = new URL(body.wsUrl), http = new URL(body.httpUrl);\n if (![\"ws:\", \"wss:\"].includes(ws.protocol) || ![\"http:\", \"https:\"].includes(http.protocol)\n || ws.username || ws.password || http.username || http.password || ws.search || http.search || ws.hash || http.hash)\n throw new Error(\"The token endpoint returned invalid connection URLs.\");\n if (window.location.protocol === \"https:\" && (ws.protocol !== \"wss:\" || http.protocol !== \"https:\"))\n throw new Error(\"HTTPS embeds require HTTPS and WSS AgentHub endpoints.\");\n return body;\n}\n\nexport function validateEmbedInputs(fields: AgentInputDefinition[], suppliedValues?: Record<string, unknown>): void {\n const values = suppliedValues ?? {};\n if (typeof values !== \"object\" || Array.isArray(values)) throw new Error(\"inputs must be an object.\");\n const names = new Set(fields.map((field) => field.name));\n for (const name of Object.keys(values)) if (!names.has(name)) throw new Error(`Unknown input: ${name}`);\n const missing = fields\n .filter(({ name, optional }) => {\n const value = values[name];\n return !optional && (value === undefined || value === null || (typeof value === \"string\" && !value.trim()));\n })\n .map(({ name }) => name);\n if (missing.length) throw new MissingAgentInputsError(missing);\n for (const field of fields) {\n const value = values[field.name];\n let valid = false;\n switch (field.dataType) {\n case \"string\": valid = typeof value === \"string\"; break;\n case \"number\": valid = typeof value === \"number\" && Number.isFinite(value); break;\n case \"integer\": valid = typeof value === \"number\" && Number.isSafeInteger(value); break;\n case \"boolean\": valid = typeof value === \"boolean\"; break;\n case \"array\": valid = Array.isArray(value); break;\n case \"object\": valid = typeof value === \"object\" && value !== null && !Array.isArray(value); break;\n case \"date\": valid = typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}$/.test(value)\n && !Number.isNaN(Date.parse(value)) && new Date(value).toISOString().slice(0, 10) === value; break;\n case \"datetime\": valid = typeof value === \"string\" && /^\\d{4}-\\d{2}-\\d{2}T/.test(value) && !Number.isNaN(Date.parse(value)); break;\n }\n if (!valid) throw new Error(`Input ${field.name} must have data type ${field.dataType}.`);\n }\n}\n"]}
|
|
@@ -1,6 +1,21 @@
|
|
|
1
1
|
import type { AgentBootstrap } from "../client/agentAuth";
|
|
2
2
|
|
|
3
3
|
export const EMBED_CHANNEL = "solidx-agent-embed";
|
|
4
|
+
export const EMBED_PUBLIC_PROTOCOL_VERSION = 2;
|
|
5
|
+
export const EMBED_MESSAGE_CONTEXT_MAX_BYTES = 32 * 1024;
|
|
6
|
+
export type EmbedJson = null | boolean | number | string | EmbedJson[] | { [key: string]: EmbedJson };
|
|
7
|
+
export type EmbedContextContribution = { context: EmbedJson; revision: string; displaySummary?: string };
|
|
8
|
+
export type EmbedMessageContext = { schemaVersion: 1; namespaces: Record<string, EmbedContextContribution> };
|
|
9
|
+
export type BeforeUserMessageSendRequest = {
|
|
10
|
+
text: string;
|
|
11
|
+
source: "composer" | "sdk" | "prefill" | "widget";
|
|
12
|
+
attachments: Array<{ name: string; mimeType: string; size: number }>;
|
|
13
|
+
contextRevision?: string;
|
|
14
|
+
};
|
|
15
|
+
export type BeforeUserMessageSendListener = (
|
|
16
|
+
request: BeforeUserMessageSendRequest,
|
|
17
|
+
signal: AbortSignal,
|
|
18
|
+
) => Promise<EmbedContextContribution | { cancelled: true; reason?: string }>;
|
|
4
19
|
export type AgentInputDefinition = { name: string; description: string; dataType: string; defaultValue?: unknown; optional?: boolean };
|
|
5
20
|
export type AgentEmbedBootstrap = AgentBootstrap & {
|
|
6
21
|
embed: true;
|
|
@@ -16,6 +31,38 @@ export class MissingAgentInputsError extends Error {
|
|
|
16
31
|
}
|
|
17
32
|
}
|
|
18
33
|
|
|
34
|
+
export function validateMessageContext(value: unknown): EmbedMessageContext {
|
|
35
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new Error("message_context must be an object.");
|
|
36
|
+
const context = value as Partial<EmbedMessageContext>;
|
|
37
|
+
if (context.schemaVersion !== 1 || !context.namespaces || typeof context.namespaces !== "object"
|
|
38
|
+
|| Array.isArray(context.namespaces) || Object.keys(context.namespaces).length > 32)
|
|
39
|
+
throw new Error("message_context must use schemaVersion 1 and contain a namespaces object.");
|
|
40
|
+
for (const [namespace, contribution] of Object.entries(context.namespaces)) {
|
|
41
|
+
if (!namespace || namespace.length > 80 || !contribution || typeof contribution !== "object"
|
|
42
|
+
|| typeof contribution.revision !== "string" || contribution.revision.length > 256 || !("context" in contribution)
|
|
43
|
+
|| (contribution.displaySummary !== undefined && (typeof contribution.displaySummary !== "string" || contribution.displaySummary.length > 1024)))
|
|
44
|
+
throw new Error("message_context contains an invalid namespace contribution.");
|
|
45
|
+
}
|
|
46
|
+
const isJson = (item: unknown, depth = 0): boolean => {
|
|
47
|
+
if (depth > 12) return false;
|
|
48
|
+
if (item === null || typeof item === "string" || typeof item === "boolean") return true;
|
|
49
|
+
if (typeof item === "number") return Number.isFinite(item);
|
|
50
|
+
if (Array.isArray(item)) return item.length <= 1024 && item.every((child) => isJson(child, depth + 1));
|
|
51
|
+
if (typeof item !== "object" || Object.getPrototypeOf(item) !== Object.prototype) return false;
|
|
52
|
+
return Object.values(item as Record<string, unknown>).every((child) => isJson(child, depth + 1));
|
|
53
|
+
};
|
|
54
|
+
let serialized: string;
|
|
55
|
+
try {
|
|
56
|
+
if (!isJson(value)) throw new Error("message_context contains unsupported JSON values.");
|
|
57
|
+
serialized = JSON.stringify(value);
|
|
58
|
+
} catch {
|
|
59
|
+
throw new Error("message_context contains unsupported JSON values.");
|
|
60
|
+
}
|
|
61
|
+
if (new TextEncoder().encode(serialized).length > EMBED_MESSAGE_CONTEXT_MAX_BYTES)
|
|
62
|
+
throw new Error("message_context exceeds 32 KiB.");
|
|
63
|
+
return value as EmbedMessageContext;
|
|
64
|
+
}
|
|
65
|
+
|
|
19
66
|
export function validateBootstrap(value: unknown, agentId: number): AgentEmbedBootstrap {
|
|
20
67
|
const body = value as AgentEmbedBootstrap;
|
|
21
68
|
if (!body || body.embed !== true || body.agentId !== agentId || typeof body.agentToken !== "string" || !body.agentToken
|
|
@@ -35,9 +82,9 @@ export function validateEmbedInputs(fields: AgentInputDefinition[], suppliedValu
|
|
|
35
82
|
const names = new Set(fields.map((field) => field.name));
|
|
36
83
|
for (const name of Object.keys(values)) if (!names.has(name)) throw new Error(`Unknown input: ${name}`);
|
|
37
84
|
const missing = fields
|
|
38
|
-
.filter(({ name, optional
|
|
85
|
+
.filter(({ name, optional }) => {
|
|
39
86
|
const value = values[name];
|
|
40
|
-
return !optional &&
|
|
87
|
+
return !optional && (value === undefined || value === null || (typeof value === "string" && !value.trim()));
|
|
41
88
|
})
|
|
42
89
|
.map(({ name }) => name);
|
|
43
90
|
if (missing.length) throw new MissingAgentInputsError(missing);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AgentInputDefinition } from "./agentEmbedProtocol";
|
|
2
2
|
export declare function embedSamples(agentId: number, fields: AgentInputDefinition[], sdkUrl: string, hubBase: string): {
|
|
3
3
|
javascript: string;
|
|
4
|
+
inline: string;
|
|
4
5
|
react: string;
|
|
5
6
|
python: string;
|
|
6
7
|
nestjs: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentEmbedSamples.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/embed/agentEmbedSamples.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAMjE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM
|
|
1
|
+
{"version":3,"file":"agentEmbedSamples.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/embed/agentEmbedSamples.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAMjE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;;;;;;;;;EAiR5G"}
|
|
@@ -10,7 +10,8 @@ export function embedSamples(agentId, fields, sdkUrl, hubBase) {
|
|
|
10
10
|
var config = "agentId: ".concat(agentId, ",\n tokenEndpoint: \"/api/agent-chat/token\",\n inputs: ").concat(valuesJson);
|
|
11
11
|
return {
|
|
12
12
|
javascript: "<div id=\"agent-chat\"></div>\n<script src=".concat(JSON.stringify(sdkUrl).replace(/</g, "<"), "></script>\n<script>\n // Values should come from the current page or trusted app state.\n // The API key and AgentHub URL stay on your server.\n const chat = SolidAgentEmbed.mount({\n container: \"#agent-chat\",\n ").concat(config, "\n });\n // For app auth/CSRF, add getTokenHeaders: () => yourAppAuthHeaders().\n // Optional lifecycle methods: chat.open(), chat.close(), chat.destroy().\n // Update context before the first message or after starting a new chat:\n // await chat.setInputs({ ... });\n</script>"),
|
|
13
|
-
|
|
13
|
+
inline: "<div id=\"agent-chat\" style=\"width:420px;height:600px\"></div>\n<script src=".concat(JSON.stringify(sdkUrl).replace(/</g, "<"), "></script>\n<script>\n // Your app owns this container's size, position, and visibility.\n // Keep the same instance mounted when navigating within your app.\n const chat = SolidAgentEmbed.mount({\n mode: \"inline\",\n container: \"#agent-chat\",\n ").concat(config, "\n });\n chat.open();\n // chat.close() hides the iframe without ending the chat.\n // chat.destroy() removes the iframe when the user signs out.\n</script>"),
|
|
14
|
+
react: "\"use client\";\nimport { useEffect, useRef } from \"react\";\n\ntype AgentEmbed = { destroy: () => void };\ntype AgentEmbedSdk = { mount: (options: {\n container: HTMLElement; mode?: \"popup\" | \"inline\"; agentId: number; tokenEndpoint: string;\n inputs: Record<string, unknown>; label?: string; title?: string;\n getTokenHeaders?: () => Record<string, string>;\n}) => AgentEmbed };\ndeclare global { interface Window { SolidAgentEmbed?: AgentEmbedSdk } }\n\nconst SDK_URL = ".concat(js(sdkUrl), ";\nlet sdkPromise: Promise<AgentEmbedSdk> | undefined;\nfunction loadSdk() {\n if (window.SolidAgentEmbed) return Promise.resolve(window.SolidAgentEmbed);\n if (!sdkPromise) sdkPromise = new Promise((resolve, reject) => {\n const script = document.createElement(\"script\");\n script.src = SDK_URL;\n script.async = true;\n script.onload = () => window.SolidAgentEmbed\n ? resolve(window.SolidAgentEmbed)\n : reject(new Error(\"Agent embed SDK did not initialize\"));\n script.onerror = () => { script.remove(); sdkPromise = undefined; reject(new Error(\"Could not load Agent embed SDK\")); };\n document.head.appendChild(script);\n });\n return sdkPromise;\n}\n\nexport function AgentChat() {\n const containerRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n let disposed = false;\n let chat: AgentEmbed | undefined;\n void loadSdk().then((sdk) => {\n if (disposed || !containerRef.current) return;\n chat = sdk.mount({\n container: containerRef.current,\n ").concat(config.replace(/\n/g, "\n "), "\n });\n }).catch((error: unknown) => {\n if (!disposed) console.error(\"Could not initialize agent chat\", error);\n });\n return () => { disposed = true; chat?.destroy(); };\n }, []);\n return <div ref={containerRef} />;\n}"),
|
|
14
15
|
python: "# FastAPI. Install httpx; mount this router in your application.\n# Keep these server-only environment variables out of the browser bundle:\n# AGENTHUB_API_KEY, AGENTHUB_AGENT_ID, AGENTHUB_BACKEND_URL\n".concat(environmentNote, "\nimport os\nimport httpx\nfrom fastapi import APIRouter, HTTPException, Request, Response\nfrom pydantic import BaseModel\n\nrouter = APIRouter()\nAGENTHUB_URL = (os.getenv(\"AGENTHUB_BACKEND_URL\") or \"\").rstrip(\"/\")\n\nclass TokenRequest(BaseModel):\n agentId: int\n\n@router.post(\"/api/agent-chat/token\")\nasync def create_agent_token(body: TokenRequest, request: Request, response: Response):\n response.headers[\"Cache-Control\"] = \"no-store\"\n try:\n agent_id = int(os.environ.get(\"AGENTHUB_AGENT_ID\", \"0\"))\n except ValueError:\n agent_id = 0\n api_key = os.getenv(\"AGENTHUB_API_KEY\")\n if not api_key or not AGENTHUB_URL or agent_id <= 0:\n raise HTTPException(status_code=503, detail=\"Chat is temporarily unavailable\")\n if body.agentId != agent_id:\n raise HTTPException(status_code=400, detail=\"Agent is not configured for this application\")\n # If trusted optional-auth middleware populated request.state.user, pass its stable ID.\n user = getattr(request.state, \"user\", None)\n external_id = user.get(\"id\") if isinstance(user, dict) else getattr(user, \"id\", None)\n payload = {\"apiKey\": api_key, \"agentId\": agent_id}\n if external_id is not None:\n payload[\"externalUserId\"] = f\"my-app:{external_id}\"\n try:\n async with httpx.AsyncClient(timeout=15) as client:\n upstream = await client.post(f\"{AGENTHUB_URL}/api/agent/api-keys/embedded/me\", json=payload)\n if not upstream.is_success:\n raise HTTPException(status_code=502, detail=\"Chat is temporarily unavailable\")\n return upstream.json() # forward the token response; never cache or log it\n except httpx.HTTPError as exc:\n raise HTTPException(status_code=503, detail=\"Chat is temporarily unavailable\") from exc\n"),
|
|
15
16
|
nestjs: "// NestJS. Uses the app's existing ConfigService and optional auth middleware.\n// Add a distributed rate limit at the gateway or with your Nest throttler.\nimport { Body, Controller, HttpException, HttpStatus, Post, Req, Res } from \"@nestjs/common\";\nimport { ConfigService } from \"@nestjs/config\";\nimport { Public } from \"@solidxai/core\";\nimport { Request, Response } from \"express\";\n\n// Server environment: AGENTHUB_API_KEY=...; AGENTHUB_AGENT_ID=".concat(agentId, "\n").concat(environmentNoteSlash, "\ntype EmbedRequest = Request & { user?: { id?: string | number; sub?: string | number } };\n@Controller(\"agent-chat\")\nexport class AgentChatController {\n constructor(private readonly config: ConfigService) {}\n\n @Post(\"token\")\n @Public() // allow anonymous use; remove/replace with your app policy for login-only chat\n async createToken(@Body() body: { agentId: number }, @Req() req: EmbedRequest, @Res() res: Response) {\n res.setHeader(\"Cache-Control\", \"no-store\");\n const agentId = Number(this.config.get(\"AGENTHUB_AGENT_ID\")); // fixed; never trust browser selection\n const apiKey = this.config.get<string>(\"AGENTHUB_API_KEY\");\n const baseUrl = this.config.get<string>(\"AGENTHUB_BACKEND_URL\")?.replace(/\\/$/, \"\");\n if (!apiKey || !baseUrl || !Number.isSafeInteger(agentId) || agentId <= 0)\n throw new HttpException(\"Chat is temporarily unavailable\", HttpStatus.SERVICE_UNAVAILABLE);\n if (body.agentId !== agentId) throw new HttpException(\"Agent is not configured\", HttpStatus.BAD_REQUEST);\n const userId = req.user?.id ?? req.user?.sub; // set only by trusted auth middleware\n const payload = { apiKey, agentId, ...(userId != null ? { externalUserId: \"my-app:\" + userId } : {}) };\n try {\n const upstream = await fetch(baseUrl + \"/api/agent/api-keys/embedded/me\", {\n method: \"POST\", headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload), signal: AbortSignal.timeout(15_000),\n });\n if (!upstream.ok) throw new HttpException(\"Chat is temporarily unavailable\", HttpStatus.BAD_GATEWAY);\n res.status(200).type(\"application/json\").send(await upstream.text());\n } catch (error) {\n if (error instanceof HttpException) throw error;\n throw new HttpException(\"Chat is temporarily unavailable\", HttpStatus.SERVICE_UNAVAILABLE);\n }\n }\n}\n// Mount behind trusted proxy configuration and rate limiting. Apply the app's\n// authentication/authorization guard instead of @Public() when access is restricted."),
|
|
16
17
|
express: "// Express (Node.js 20+). Mount after any optional authentication middleware.\n// Protect this public endpoint with a distributed/IP-aware rate limiter in production.\n// Server environment: AGENTHUB_API_KEY=...; AGENTHUB_AGENT_ID=".concat(agentId, "\n").concat(environmentNoteSlash, "\nimport express from \"express\";\n\nconst router = express.Router();\nrouter.post(\"/api/agent-chat/token\", async (req, res) => {\n res.set(\"Cache-Control\", \"no-store\");\n const agentId = Number(process.env.AGENTHUB_AGENT_ID); // fixed server-side allowlist\n const apiKey = process.env.AGENTHUB_API_KEY;\n const baseUrl = process.env.AGENTHUB_BACKEND_URL?.replace(/\\/$/, \"\");\n if (!apiKey || !baseUrl || !Number.isSafeInteger(agentId) || agentId <= 0)\n return res.status(503).json({ error: \"Chat is temporarily unavailable\" });\n if (Number(req.body?.agentId) !== agentId)\n return res.status(400).json({ error: \"Agent is not configured for this application\" });\n const userId = req.user?.id ?? req.user?.sub; // optional identity from trusted middleware\n try {\n const upstream = await fetch(baseUrl + \"/api/agent/api-keys/embedded/me\", {\n method: \"POST\", headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ apiKey, agentId, ...(userId != null ? { externalUserId: \"my-app:\" + userId } : {}) }),\n signal: AbortSignal.timeout(15_000),\n });\n if (!upstream.ok) return res.status(502).json({ error: \"Chat is temporarily unavailable\" });\n return res.status(200).type(\"application/json\").send(await upstream.text());\n } catch {\n return res.status(503).json({ error: \"Chat is temporarily unavailable\" });\n }\n});\nexport default router;\n// Ensure express.json() is installed. Never accept API key/backend URL from req.body."),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentEmbedSamples.js","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/embed/agentEmbedSamples.ts"],"names":[],"mappings":"AAEA,IAAM,EAAE,GAAG,UAAC,KAAc,IAAK,OAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,EAAnH,CAAmH,CAAC;AACnJ,IAAM,QAAQ,GAA4B,EAAE,MAAM,EAAE,yBAAyB,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK;IAChH,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAElF,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,MAA8B,EAAE,MAAc,EAAE,OAAe;IACzG,IAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,UAAC,KAAK,YAAK,OAAA,CAAC,KAAK,CAAC,IAAI,EAAE,MAAA,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,mCAAI,yBAAyB,CAAC,CAAA,EAAA,CAAC,CAAC,CAAC;IAC9H,IAAM,UAAU,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACvD,IAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC9C,IAAM,eAAe,GAAG,iCAA0B,UAAU,CAAE,CAAC;IAC/D,IAAM,oBAAoB,GAAG,kCAA2B,UAAU,CAAE,CAAC;IACrE,IAAM,MAAM,GAAG,mBAAY,OAAO,2EAA+D,UAAU,CAAE,CAAC;IAC9G,OAAO;QACH,UAAU,EAAE,qDACN,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,6OAMpD,MAAM,+RAMF;QACF,KAAK,EAAE,4cAWG,EAAE,CAAC,MAAM,CAAC,uhCA0BlB,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,CAAC,2PAQ3C;QACM,MAAM,EAAE,oNAGd,eAAe,8zDAsChB;QACO,MAAM,EAAE,wdAOiD,OAAO,eACtE,oBAAoB,2hEAgCgE;QAC9E,OAAO,EAAE,iPAEgD,OAAO,eACtE,oBAAoB,6/CA2BiE;QAC/E,IAAI,EAAE,0OAEmD,OAAO,eACtE,oBAAoB,ojFAuC8D;QAC5E,MAAM,EAAE,mPAEiD,OAAO,eACtE,oBAAoB,g+DA6BoE;KACrF,CAAC;AACN,CAAC","sourcesContent":["import type { AgentInputDefinition } from \"./agentEmbedProtocol\";\n\nconst js = (value: unknown) => JSON.stringify(value, null, 2).replace(/</g, \"\\\\u003c\").replace(/\\u2028/g, \"\\\\u2028\").replace(/\\u2029/g, \"\\\\u2029\");\nconst examples: Record<string, unknown> = { string: \"Replace with your value\", number: 0, integer: 0, boolean: false,\n date: \"2026-01-01\", datetime: \"2026-01-01T09:00:00Z\", object: {}, array: [] };\n\nexport function embedSamples(agentId: number, fields: AgentInputDefinition[], sdkUrl: string, hubBase: string) {\n const values = Object.fromEntries(fields.map((field) => [field.name, examples[field.dataType] ?? \"Replace with your value\"]));\n const valuesJson = js(values).replace(/\\n/g, \"\\n \");\n const backendUrl = hubBase.replace(/\\/$/, \"\");\n const environmentNote = `# AGENTHUB_BACKEND_URL=${backendUrl}`;\n const environmentNoteSlash = `// AGENTHUB_BACKEND_URL=${backendUrl}`;\n const config = `agentId: ${agentId},\\n tokenEndpoint: \"/api/agent-chat/token\",\\n inputs: ${valuesJson}`;\n return {\n javascript: `<div id=\"agent-chat\"></div>\n<script src=${JSON.stringify(sdkUrl).replace(/</g, \"<\")}></script>\n<script>\n // Values should come from the current page or trusted app state.\n // The API key and AgentHub URL stay on your server.\n const chat = SolidAgentEmbed.mount({\n container: \"#agent-chat\",\n ${config}\n });\n // For app auth/CSRF, add getTokenHeaders: () => yourAppAuthHeaders().\n // Optional lifecycle methods: chat.open(), chat.close(), chat.destroy().\n // Update context before the first message or after starting a new chat:\n // await chat.setInputs({ ... });\n</script>`,\n react: `\"use client\";\nimport { useEffect, useRef } from \"react\";\n\ntype AgentEmbed = { destroy: () => void };\ntype AgentEmbedSdk = { mount: (options: {\n container: HTMLElement; agentId: number; tokenEndpoint: string;\n inputs: Record<string, unknown>; label?: string; title?: string;\n getTokenHeaders?: () => Record<string, string>;\n}) => AgentEmbed };\ndeclare global { interface Window { SolidAgentEmbed?: AgentEmbedSdk } }\n\nconst SDK_URL = ${js(sdkUrl)};\nlet sdkPromise: Promise<AgentEmbedSdk> | undefined;\nfunction loadSdk() {\n if (window.SolidAgentEmbed) return Promise.resolve(window.SolidAgentEmbed);\n if (!sdkPromise) sdkPromise = new Promise((resolve, reject) => {\n const script = document.createElement(\"script\");\n script.src = SDK_URL;\n script.async = true;\n script.onload = () => window.SolidAgentEmbed\n ? resolve(window.SolidAgentEmbed)\n : reject(new Error(\"Agent embed SDK did not initialize\"));\n script.onerror = () => { script.remove(); sdkPromise = undefined; reject(new Error(\"Could not load Agent embed SDK\")); };\n document.head.appendChild(script);\n });\n return sdkPromise;\n}\n\nexport function AgentChat() {\n const containerRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n let disposed = false;\n let chat: AgentEmbed | undefined;\n void loadSdk().then((sdk) => {\n if (disposed || !containerRef.current) return;\n chat = sdk.mount({\n container: containerRef.current,\n ${config.replace(/\\n/g, \"\\n \")}\n });\n }).catch((error: unknown) => {\n if (!disposed) console.error(\"Could not initialize agent chat\", error);\n });\n return () => { disposed = true; chat?.destroy(); };\n }, []);\n return <div ref={containerRef} />;\n}`,\n python: `# FastAPI. Install httpx; mount this router in your application.\n# Keep these server-only environment variables out of the browser bundle:\n# AGENTHUB_API_KEY, AGENTHUB_AGENT_ID, AGENTHUB_BACKEND_URL\n${environmentNote}\nimport os\nimport httpx\nfrom fastapi import APIRouter, HTTPException, Request, Response\nfrom pydantic import BaseModel\n\nrouter = APIRouter()\nAGENTHUB_URL = (os.getenv(\"AGENTHUB_BACKEND_URL\") or \"\").rstrip(\"/\")\n\nclass TokenRequest(BaseModel):\n agentId: int\n\n@router.post(\"/api/agent-chat/token\")\nasync def create_agent_token(body: TokenRequest, request: Request, response: Response):\n response.headers[\"Cache-Control\"] = \"no-store\"\n try:\n agent_id = int(os.environ.get(\"AGENTHUB_AGENT_ID\", \"0\"))\n except ValueError:\n agent_id = 0\n api_key = os.getenv(\"AGENTHUB_API_KEY\")\n if not api_key or not AGENTHUB_URL or agent_id <= 0:\n raise HTTPException(status_code=503, detail=\"Chat is temporarily unavailable\")\n if body.agentId != agent_id:\n raise HTTPException(status_code=400, detail=\"Agent is not configured for this application\")\n # If trusted optional-auth middleware populated request.state.user, pass its stable ID.\n user = getattr(request.state, \"user\", None)\n external_id = user.get(\"id\") if isinstance(user, dict) else getattr(user, \"id\", None)\n payload = {\"apiKey\": api_key, \"agentId\": agent_id}\n if external_id is not None:\n payload[\"externalUserId\"] = f\"my-app:{external_id}\"\n try:\n async with httpx.AsyncClient(timeout=15) as client:\n upstream = await client.post(f\"{AGENTHUB_URL}/api/agent/api-keys/embedded/me\", json=payload)\n if not upstream.is_success:\n raise HTTPException(status_code=502, detail=\"Chat is temporarily unavailable\")\n return upstream.json() # forward the token response; never cache or log it\n except httpx.HTTPError as exc:\n raise HTTPException(status_code=503, detail=\"Chat is temporarily unavailable\") from exc\n`,\n nestjs: `// NestJS. Uses the app's existing ConfigService and optional auth middleware.\n// Add a distributed rate limit at the gateway or with your Nest throttler.\nimport { Body, Controller, HttpException, HttpStatus, Post, Req, Res } from \"@nestjs/common\";\nimport { ConfigService } from \"@nestjs/config\";\nimport { Public } from \"@solidxai/core\";\nimport { Request, Response } from \"express\";\n\n// Server environment: AGENTHUB_API_KEY=...; AGENTHUB_AGENT_ID=${agentId}\n${environmentNoteSlash}\ntype EmbedRequest = Request & { user?: { id?: string | number; sub?: string | number } };\n@Controller(\"agent-chat\")\nexport class AgentChatController {\n constructor(private readonly config: ConfigService) {}\n\n @Post(\"token\")\n @Public() // allow anonymous use; remove/replace with your app policy for login-only chat\n async createToken(@Body() body: { agentId: number }, @Req() req: EmbedRequest, @Res() res: Response) {\n res.setHeader(\"Cache-Control\", \"no-store\");\n const agentId = Number(this.config.get(\"AGENTHUB_AGENT_ID\")); // fixed; never trust browser selection\n const apiKey = this.config.get<string>(\"AGENTHUB_API_KEY\");\n const baseUrl = this.config.get<string>(\"AGENTHUB_BACKEND_URL\")?.replace(/\\\\/$/, \"\");\n if (!apiKey || !baseUrl || !Number.isSafeInteger(agentId) || agentId <= 0)\n throw new HttpException(\"Chat is temporarily unavailable\", HttpStatus.SERVICE_UNAVAILABLE);\n if (body.agentId !== agentId) throw new HttpException(\"Agent is not configured\", HttpStatus.BAD_REQUEST);\n const userId = req.user?.id ?? req.user?.sub; // set only by trusted auth middleware\n const payload = { apiKey, agentId, ...(userId != null ? { externalUserId: \"my-app:\" + userId } : {}) };\n try {\n const upstream = await fetch(baseUrl + \"/api/agent/api-keys/embedded/me\", {\n method: \"POST\", headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload), signal: AbortSignal.timeout(15_000),\n });\n if (!upstream.ok) throw new HttpException(\"Chat is temporarily unavailable\", HttpStatus.BAD_GATEWAY);\n res.status(200).type(\"application/json\").send(await upstream.text());\n } catch (error) {\n if (error instanceof HttpException) throw error;\n throw new HttpException(\"Chat is temporarily unavailable\", HttpStatus.SERVICE_UNAVAILABLE);\n }\n }\n}\n// Mount behind trusted proxy configuration and rate limiting. Apply the app's\n// authentication/authorization guard instead of @Public() when access is restricted.`,\n express: `// Express (Node.js 20+). Mount after any optional authentication middleware.\n// Protect this public endpoint with a distributed/IP-aware rate limiter in production.\n// Server environment: AGENTHUB_API_KEY=...; AGENTHUB_AGENT_ID=${agentId}\n${environmentNoteSlash}\nimport express from \"express\";\n\nconst router = express.Router();\nrouter.post(\"/api/agent-chat/token\", async (req, res) => {\n res.set(\"Cache-Control\", \"no-store\");\n const agentId = Number(process.env.AGENTHUB_AGENT_ID); // fixed server-side allowlist\n const apiKey = process.env.AGENTHUB_API_KEY;\n const baseUrl = process.env.AGENTHUB_BACKEND_URL?.replace(/\\\\/$/, \"\");\n if (!apiKey || !baseUrl || !Number.isSafeInteger(agentId) || agentId <= 0)\n return res.status(503).json({ error: \"Chat is temporarily unavailable\" });\n if (Number(req.body?.agentId) !== agentId)\n return res.status(400).json({ error: \"Agent is not configured for this application\" });\n const userId = req.user?.id ?? req.user?.sub; // optional identity from trusted middleware\n try {\n const upstream = await fetch(baseUrl + \"/api/agent/api-keys/embedded/me\", {\n method: \"POST\", headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ apiKey, agentId, ...(userId != null ? { externalUserId: \"my-app:\" + userId } : {}) }),\n signal: AbortSignal.timeout(15_000),\n });\n if (!upstream.ok) return res.status(502).json({ error: \"Chat is temporarily unavailable\" });\n return res.status(200).type(\"application/json\").send(await upstream.text());\n } catch {\n return res.status(503).json({ error: \"Chat is temporarily unavailable\" });\n }\n});\nexport default router;\n// Ensure express.json() is installed. Never accept API key/backend URL from req.body.`,\n java: `// Spring Boot 3 / Java 17+. Keep this route public for anonymous embeds,\n// or apply your application's authorization policy. Add a distributed rate limiter.\n// Server environment: AGENTHUB_API_KEY=...; AGENTHUB_AGENT_ID=${agentId}\n${environmentNoteSlash}\n@RestController\npublic class AgentEmbedController {\n private final java.net.http.HttpClient client = java.net.http.HttpClient.newBuilder()\n .connectTimeout(java.time.Duration.ofSeconds(5)).build();\n private final com.fasterxml.jackson.databind.ObjectMapper json = new com.fasterxml.jackson.databind.ObjectMapper();\n\n @Value(\"\\${AGENTHUB_API_KEY}\") private String apiKey;\n @Value(\"\\${AGENTHUB_AGENT_ID}\") private int agentId;\n @Value(\"\\${AGENTHUB_BACKEND_URL}\") private String agentHubUrl;\n\n @PostMapping(\"/api/agent-chat/token\")\n public ResponseEntity<String> token(@RequestBody Map<String, Object> request,\n org.springframework.security.core.Authentication authentication) throws Exception {\n if (!Integer.valueOf(agentId).equals(request.get(\"agentId\")))\n return ResponseEntity.badRequest().cacheControl(CacheControl.noStore()).build();\n Map<String, Object> payload = new java.util.HashMap<>();\n payload.put(\"apiKey\", apiKey); payload.put(\"agentId\", agentId);\n // Omit externalUserId for anonymous access; ignore anonymous security principals.\n if (authentication != null && authentication.isAuthenticated() &&\n !(authentication instanceof org.springframework.security.authentication.AnonymousAuthenticationToken))\n payload.put(\"externalUserId\", \"my-app:\" + authentication.getName());\n var upstreamRequest = java.net.http.HttpRequest.newBuilder()\n .uri(java.net.URI.create(agentHubUrl.replaceAll(\"/+$\", \"\") + \"/api/agent/api-keys/embedded/me\"))\n .timeout(java.time.Duration.ofSeconds(15)).header(\"Content-Type\", \"application/json\")\n .POST(java.net.http.HttpRequest.BodyPublishers.ofString(json.writeValueAsString(payload))).build();\n try {\n var upstream = client.send(upstreamRequest, java.net.http.HttpResponse.BodyHandlers.ofString());\n if (upstream.statusCode() != 200)\n return ResponseEntity.status(502).cacheControl(CacheControl.noStore()).build();\n return ResponseEntity.ok().cacheControl(CacheControl.noStore())\n .contentType(MediaType.APPLICATION_JSON).body(upstream.body());\n } catch (java.io.IOException | InterruptedException error) {\n if (error instanceof InterruptedException) Thread.currentThread().interrupt();\n return ResponseEntity.status(503).cacheControl(CacheControl.noStore()).build();\n }\n }\n}\n// Imports: org.springframework.beans.factory.annotation.Value, web.bind.annotation.*,\n// org.springframework.http.*, java.util.Map. Do not log the key or token response.`,\n dotnet: `// ASP.NET Core Minimal API. Configure an IP/user rate-limit policy in production.\n// Authentication can be optional (anonymous demo) or required by your app's policy.\n// Server environment: AGENTHUB_API_KEY=...; AGENTHUB_AGENT_ID=${agentId}\n${environmentNoteSlash}\nusing System.Security.Claims;\nusing System.Collections.Generic;\nusing System.Net.Http.Json;\n\nbuilder.Services.AddHttpClient(\"AgentHub\", client => client.Timeout = TimeSpan.FromSeconds(15));\napp.MapPost(\"/api/agent-chat/token\", async (AgentTokenRequest body, HttpContext context, IHttpClientFactory clients, IConfiguration config) => {\n context.Response.Headers.CacheControl = \"no-store\";\n if (!int.TryParse(config[\"AGENTHUB_AGENT_ID\"], out var agentId) || agentId <= 0)\n return Results.StatusCode(503);\n var apiKey = config[\"AGENTHUB_API_KEY\"];\n var baseUrl = config[\"AGENTHUB_BACKEND_URL\"]?.TrimEnd('/');\n if (string.IsNullOrWhiteSpace(apiKey) || string.IsNullOrWhiteSpace(baseUrl))\n return Results.StatusCode(503);\n if (body.AgentId != agentId)\n return Results.BadRequest(new { error = \"Agent is not configured for this application\" });\n var subject = context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;\n var payload = new Dictionary<string, object?> { [\"apiKey\"] = apiKey, [\"agentId\"] = agentId };\n if (context.User.Identity?.IsAuthenticated == true && !string.IsNullOrEmpty(subject))\n payload[\"externalUserId\"] = \"my-app:\" + subject;\n try {\n var upstream = await clients.CreateClient(\"AgentHub\").PostAsJsonAsync(\n baseUrl + \"/api/agent/api-keys/embedded/me\", payload, context.RequestAborted);\n if (!upstream.IsSuccessStatusCode) return Results.StatusCode(502);\n return Results.Text(await upstream.Content.ReadAsStringAsync(context.RequestAborted), \"application/json\");\n } catch (HttpRequestException) { return Results.StatusCode(503); }\n}).AllowAnonymous(); // Replace with .RequireAuthorization() for login-only chat.\npublic sealed record AgentTokenRequest(int AgentId);\n// Imports: Microsoft.AspNetCore.Http, System.Net.Http.Json, System.Collections.Generic.\n// Add a distributed rate limiter and trusted-proxy configuration for public deployments.`,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agentEmbedSamples.js","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/embed/agentEmbedSamples.ts"],"names":[],"mappings":"AAEA,IAAM,EAAE,GAAG,UAAC,KAAc,IAAK,OAAA,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,EAAnH,CAAmH,CAAC;AACnJ,IAAM,QAAQ,GAA4B,EAAE,MAAM,EAAE,yBAAyB,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK;IAChH,IAAI,EAAE,YAAY,EAAE,QAAQ,EAAE,sBAAsB,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AAElF,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,MAA8B,EAAE,MAAc,EAAE,OAAe;IACzG,IAAM,MAAM,GAAG,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,UAAC,KAAK,YAAK,OAAA,CAAC,KAAK,CAAC,IAAI,EAAE,MAAA,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,mCAAI,yBAAyB,CAAC,CAAA,EAAA,CAAC,CAAC,CAAC;IAC9H,IAAM,UAAU,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACvD,IAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IAC9C,IAAM,eAAe,GAAG,iCAA0B,UAAU,CAAE,CAAC;IAC/D,IAAM,oBAAoB,GAAG,kCAA2B,UAAU,CAAE,CAAC;IACrE,IAAM,MAAM,GAAG,mBAAY,OAAO,2EAA+D,UAAU,CAAE,CAAC;IAC9G,OAAO;QACH,UAAU,EAAE,qDACN,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,6OAMpD,MAAM,+RAMF;QACF,MAAM,EAAE,wFACF,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,kRAOpD,MAAM,qKAKF;QACF,KAAK,EAAE,2eAWG,EAAE,CAAC,MAAM,CAAC,uhCA0BlB,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,YAAY,CAAC,2PAQ3C;QACM,MAAM,EAAE,oNAGd,eAAe,8zDAsChB;QACO,MAAM,EAAE,wdAOiD,OAAO,eACtE,oBAAoB,2hEAgCgE;QAC9E,OAAO,EAAE,iPAEgD,OAAO,eACtE,oBAAoB,6/CA2BiE;QAC/E,IAAI,EAAE,0OAEmD,OAAO,eACtE,oBAAoB,ojFAuC8D;QAC5E,MAAM,EAAE,mPAEiD,OAAO,eACtE,oBAAoB,g+DA6BoE;KACrF,CAAC;AACN,CAAC","sourcesContent":["import type { AgentInputDefinition } from \"./agentEmbedProtocol\";\n\nconst js = (value: unknown) => JSON.stringify(value, null, 2).replace(/</g, \"\\\\u003c\").replace(/\\u2028/g, \"\\\\u2028\").replace(/\\u2029/g, \"\\\\u2029\");\nconst examples: Record<string, unknown> = { string: \"Replace with your value\", number: 0, integer: 0, boolean: false,\n date: \"2026-01-01\", datetime: \"2026-01-01T09:00:00Z\", object: {}, array: [] };\n\nexport function embedSamples(agentId: number, fields: AgentInputDefinition[], sdkUrl: string, hubBase: string) {\n const values = Object.fromEntries(fields.map((field) => [field.name, examples[field.dataType] ?? \"Replace with your value\"]));\n const valuesJson = js(values).replace(/\\n/g, \"\\n \");\n const backendUrl = hubBase.replace(/\\/$/, \"\");\n const environmentNote = `# AGENTHUB_BACKEND_URL=${backendUrl}`;\n const environmentNoteSlash = `// AGENTHUB_BACKEND_URL=${backendUrl}`;\n const config = `agentId: ${agentId},\\n tokenEndpoint: \"/api/agent-chat/token\",\\n inputs: ${valuesJson}`;\n return {\n javascript: `<div id=\"agent-chat\"></div>\n<script src=${JSON.stringify(sdkUrl).replace(/</g, \"<\")}></script>\n<script>\n // Values should come from the current page or trusted app state.\n // The API key and AgentHub URL stay on your server.\n const chat = SolidAgentEmbed.mount({\n container: \"#agent-chat\",\n ${config}\n });\n // For app auth/CSRF, add getTokenHeaders: () => yourAppAuthHeaders().\n // Optional lifecycle methods: chat.open(), chat.close(), chat.destroy().\n // Update context before the first message or after starting a new chat:\n // await chat.setInputs({ ... });\n</script>`,\n inline: `<div id=\"agent-chat\" style=\"width:420px;height:600px\"></div>\n<script src=${JSON.stringify(sdkUrl).replace(/</g, \"<\")}></script>\n<script>\n // Your app owns this container's size, position, and visibility.\n // Keep the same instance mounted when navigating within your app.\n const chat = SolidAgentEmbed.mount({\n mode: \"inline\",\n container: \"#agent-chat\",\n ${config}\n });\n chat.open();\n // chat.close() hides the iframe without ending the chat.\n // chat.destroy() removes the iframe when the user signs out.\n</script>`,\n react: `\"use client\";\nimport { useEffect, useRef } from \"react\";\n\ntype AgentEmbed = { destroy: () => void };\ntype AgentEmbedSdk = { mount: (options: {\n container: HTMLElement; mode?: \"popup\" | \"inline\"; agentId: number; tokenEndpoint: string;\n inputs: Record<string, unknown>; label?: string; title?: string;\n getTokenHeaders?: () => Record<string, string>;\n}) => AgentEmbed };\ndeclare global { interface Window { SolidAgentEmbed?: AgentEmbedSdk } }\n\nconst SDK_URL = ${js(sdkUrl)};\nlet sdkPromise: Promise<AgentEmbedSdk> | undefined;\nfunction loadSdk() {\n if (window.SolidAgentEmbed) return Promise.resolve(window.SolidAgentEmbed);\n if (!sdkPromise) sdkPromise = new Promise((resolve, reject) => {\n const script = document.createElement(\"script\");\n script.src = SDK_URL;\n script.async = true;\n script.onload = () => window.SolidAgentEmbed\n ? resolve(window.SolidAgentEmbed)\n : reject(new Error(\"Agent embed SDK did not initialize\"));\n script.onerror = () => { script.remove(); sdkPromise = undefined; reject(new Error(\"Could not load Agent embed SDK\")); };\n document.head.appendChild(script);\n });\n return sdkPromise;\n}\n\nexport function AgentChat() {\n const containerRef = useRef<HTMLDivElement>(null);\n useEffect(() => {\n let disposed = false;\n let chat: AgentEmbed | undefined;\n void loadSdk().then((sdk) => {\n if (disposed || !containerRef.current) return;\n chat = sdk.mount({\n container: containerRef.current,\n ${config.replace(/\\n/g, \"\\n \")}\n });\n }).catch((error: unknown) => {\n if (!disposed) console.error(\"Could not initialize agent chat\", error);\n });\n return () => { disposed = true; chat?.destroy(); };\n }, []);\n return <div ref={containerRef} />;\n}`,\n python: `# FastAPI. Install httpx; mount this router in your application.\n# Keep these server-only environment variables out of the browser bundle:\n# AGENTHUB_API_KEY, AGENTHUB_AGENT_ID, AGENTHUB_BACKEND_URL\n${environmentNote}\nimport os\nimport httpx\nfrom fastapi import APIRouter, HTTPException, Request, Response\nfrom pydantic import BaseModel\n\nrouter = APIRouter()\nAGENTHUB_URL = (os.getenv(\"AGENTHUB_BACKEND_URL\") or \"\").rstrip(\"/\")\n\nclass TokenRequest(BaseModel):\n agentId: int\n\n@router.post(\"/api/agent-chat/token\")\nasync def create_agent_token(body: TokenRequest, request: Request, response: Response):\n response.headers[\"Cache-Control\"] = \"no-store\"\n try:\n agent_id = int(os.environ.get(\"AGENTHUB_AGENT_ID\", \"0\"))\n except ValueError:\n agent_id = 0\n api_key = os.getenv(\"AGENTHUB_API_KEY\")\n if not api_key or not AGENTHUB_URL or agent_id <= 0:\n raise HTTPException(status_code=503, detail=\"Chat is temporarily unavailable\")\n if body.agentId != agent_id:\n raise HTTPException(status_code=400, detail=\"Agent is not configured for this application\")\n # If trusted optional-auth middleware populated request.state.user, pass its stable ID.\n user = getattr(request.state, \"user\", None)\n external_id = user.get(\"id\") if isinstance(user, dict) else getattr(user, \"id\", None)\n payload = {\"apiKey\": api_key, \"agentId\": agent_id}\n if external_id is not None:\n payload[\"externalUserId\"] = f\"my-app:{external_id}\"\n try:\n async with httpx.AsyncClient(timeout=15) as client:\n upstream = await client.post(f\"{AGENTHUB_URL}/api/agent/api-keys/embedded/me\", json=payload)\n if not upstream.is_success:\n raise HTTPException(status_code=502, detail=\"Chat is temporarily unavailable\")\n return upstream.json() # forward the token response; never cache or log it\n except httpx.HTTPError as exc:\n raise HTTPException(status_code=503, detail=\"Chat is temporarily unavailable\") from exc\n`,\n nestjs: `// NestJS. Uses the app's existing ConfigService and optional auth middleware.\n// Add a distributed rate limit at the gateway or with your Nest throttler.\nimport { Body, Controller, HttpException, HttpStatus, Post, Req, Res } from \"@nestjs/common\";\nimport { ConfigService } from \"@nestjs/config\";\nimport { Public } from \"@solidxai/core\";\nimport { Request, Response } from \"express\";\n\n// Server environment: AGENTHUB_API_KEY=...; AGENTHUB_AGENT_ID=${agentId}\n${environmentNoteSlash}\ntype EmbedRequest = Request & { user?: { id?: string | number; sub?: string | number } };\n@Controller(\"agent-chat\")\nexport class AgentChatController {\n constructor(private readonly config: ConfigService) {}\n\n @Post(\"token\")\n @Public() // allow anonymous use; remove/replace with your app policy for login-only chat\n async createToken(@Body() body: { agentId: number }, @Req() req: EmbedRequest, @Res() res: Response) {\n res.setHeader(\"Cache-Control\", \"no-store\");\n const agentId = Number(this.config.get(\"AGENTHUB_AGENT_ID\")); // fixed; never trust browser selection\n const apiKey = this.config.get<string>(\"AGENTHUB_API_KEY\");\n const baseUrl = this.config.get<string>(\"AGENTHUB_BACKEND_URL\")?.replace(/\\\\/$/, \"\");\n if (!apiKey || !baseUrl || !Number.isSafeInteger(agentId) || agentId <= 0)\n throw new HttpException(\"Chat is temporarily unavailable\", HttpStatus.SERVICE_UNAVAILABLE);\n if (body.agentId !== agentId) throw new HttpException(\"Agent is not configured\", HttpStatus.BAD_REQUEST);\n const userId = req.user?.id ?? req.user?.sub; // set only by trusted auth middleware\n const payload = { apiKey, agentId, ...(userId != null ? { externalUserId: \"my-app:\" + userId } : {}) };\n try {\n const upstream = await fetch(baseUrl + \"/api/agent/api-keys/embedded/me\", {\n method: \"POST\", headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload), signal: AbortSignal.timeout(15_000),\n });\n if (!upstream.ok) throw new HttpException(\"Chat is temporarily unavailable\", HttpStatus.BAD_GATEWAY);\n res.status(200).type(\"application/json\").send(await upstream.text());\n } catch (error) {\n if (error instanceof HttpException) throw error;\n throw new HttpException(\"Chat is temporarily unavailable\", HttpStatus.SERVICE_UNAVAILABLE);\n }\n }\n}\n// Mount behind trusted proxy configuration and rate limiting. Apply the app's\n// authentication/authorization guard instead of @Public() when access is restricted.`,\n express: `// Express (Node.js 20+). Mount after any optional authentication middleware.\n// Protect this public endpoint with a distributed/IP-aware rate limiter in production.\n// Server environment: AGENTHUB_API_KEY=...; AGENTHUB_AGENT_ID=${agentId}\n${environmentNoteSlash}\nimport express from \"express\";\n\nconst router = express.Router();\nrouter.post(\"/api/agent-chat/token\", async (req, res) => {\n res.set(\"Cache-Control\", \"no-store\");\n const agentId = Number(process.env.AGENTHUB_AGENT_ID); // fixed server-side allowlist\n const apiKey = process.env.AGENTHUB_API_KEY;\n const baseUrl = process.env.AGENTHUB_BACKEND_URL?.replace(/\\\\/$/, \"\");\n if (!apiKey || !baseUrl || !Number.isSafeInteger(agentId) || agentId <= 0)\n return res.status(503).json({ error: \"Chat is temporarily unavailable\" });\n if (Number(req.body?.agentId) !== agentId)\n return res.status(400).json({ error: \"Agent is not configured for this application\" });\n const userId = req.user?.id ?? req.user?.sub; // optional identity from trusted middleware\n try {\n const upstream = await fetch(baseUrl + \"/api/agent/api-keys/embedded/me\", {\n method: \"POST\", headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ apiKey, agentId, ...(userId != null ? { externalUserId: \"my-app:\" + userId } : {}) }),\n signal: AbortSignal.timeout(15_000),\n });\n if (!upstream.ok) return res.status(502).json({ error: \"Chat is temporarily unavailable\" });\n return res.status(200).type(\"application/json\").send(await upstream.text());\n } catch {\n return res.status(503).json({ error: \"Chat is temporarily unavailable\" });\n }\n});\nexport default router;\n// Ensure express.json() is installed. Never accept API key/backend URL from req.body.`,\n java: `// Spring Boot 3 / Java 17+. Keep this route public for anonymous embeds,\n// or apply your application's authorization policy. Add a distributed rate limiter.\n// Server environment: AGENTHUB_API_KEY=...; AGENTHUB_AGENT_ID=${agentId}\n${environmentNoteSlash}\n@RestController\npublic class AgentEmbedController {\n private final java.net.http.HttpClient client = java.net.http.HttpClient.newBuilder()\n .connectTimeout(java.time.Duration.ofSeconds(5)).build();\n private final com.fasterxml.jackson.databind.ObjectMapper json = new com.fasterxml.jackson.databind.ObjectMapper();\n\n @Value(\"\\${AGENTHUB_API_KEY}\") private String apiKey;\n @Value(\"\\${AGENTHUB_AGENT_ID}\") private int agentId;\n @Value(\"\\${AGENTHUB_BACKEND_URL}\") private String agentHubUrl;\n\n @PostMapping(\"/api/agent-chat/token\")\n public ResponseEntity<String> token(@RequestBody Map<String, Object> request,\n org.springframework.security.core.Authentication authentication) throws Exception {\n if (!Integer.valueOf(agentId).equals(request.get(\"agentId\")))\n return ResponseEntity.badRequest().cacheControl(CacheControl.noStore()).build();\n Map<String, Object> payload = new java.util.HashMap<>();\n payload.put(\"apiKey\", apiKey); payload.put(\"agentId\", agentId);\n // Omit externalUserId for anonymous access; ignore anonymous security principals.\n if (authentication != null && authentication.isAuthenticated() &&\n !(authentication instanceof org.springframework.security.authentication.AnonymousAuthenticationToken))\n payload.put(\"externalUserId\", \"my-app:\" + authentication.getName());\n var upstreamRequest = java.net.http.HttpRequest.newBuilder()\n .uri(java.net.URI.create(agentHubUrl.replaceAll(\"/+$\", \"\") + \"/api/agent/api-keys/embedded/me\"))\n .timeout(java.time.Duration.ofSeconds(15)).header(\"Content-Type\", \"application/json\")\n .POST(java.net.http.HttpRequest.BodyPublishers.ofString(json.writeValueAsString(payload))).build();\n try {\n var upstream = client.send(upstreamRequest, java.net.http.HttpResponse.BodyHandlers.ofString());\n if (upstream.statusCode() != 200)\n return ResponseEntity.status(502).cacheControl(CacheControl.noStore()).build();\n return ResponseEntity.ok().cacheControl(CacheControl.noStore())\n .contentType(MediaType.APPLICATION_JSON).body(upstream.body());\n } catch (java.io.IOException | InterruptedException error) {\n if (error instanceof InterruptedException) Thread.currentThread().interrupt();\n return ResponseEntity.status(503).cacheControl(CacheControl.noStore()).build();\n }\n }\n}\n// Imports: org.springframework.beans.factory.annotation.Value, web.bind.annotation.*,\n// org.springframework.http.*, java.util.Map. Do not log the key or token response.`,\n dotnet: `// ASP.NET Core Minimal API. Configure an IP/user rate-limit policy in production.\n// Authentication can be optional (anonymous demo) or required by your app's policy.\n// Server environment: AGENTHUB_API_KEY=...; AGENTHUB_AGENT_ID=${agentId}\n${environmentNoteSlash}\nusing System.Security.Claims;\nusing System.Collections.Generic;\nusing System.Net.Http.Json;\n\nbuilder.Services.AddHttpClient(\"AgentHub\", client => client.Timeout = TimeSpan.FromSeconds(15));\napp.MapPost(\"/api/agent-chat/token\", async (AgentTokenRequest body, HttpContext context, IHttpClientFactory clients, IConfiguration config) => {\n context.Response.Headers.CacheControl = \"no-store\";\n if (!int.TryParse(config[\"AGENTHUB_AGENT_ID\"], out var agentId) || agentId <= 0)\n return Results.StatusCode(503);\n var apiKey = config[\"AGENTHUB_API_KEY\"];\n var baseUrl = config[\"AGENTHUB_BACKEND_URL\"]?.TrimEnd('/');\n if (string.IsNullOrWhiteSpace(apiKey) || string.IsNullOrWhiteSpace(baseUrl))\n return Results.StatusCode(503);\n if (body.AgentId != agentId)\n return Results.BadRequest(new { error = \"Agent is not configured for this application\" });\n var subject = context.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;\n var payload = new Dictionary<string, object?> { [\"apiKey\"] = apiKey, [\"agentId\"] = agentId };\n if (context.User.Identity?.IsAuthenticated == true && !string.IsNullOrEmpty(subject))\n payload[\"externalUserId\"] = \"my-app:\" + subject;\n try {\n var upstream = await clients.CreateClient(\"AgentHub\").PostAsJsonAsync(\n baseUrl + \"/api/agent/api-keys/embedded/me\", payload, context.RequestAborted);\n if (!upstream.IsSuccessStatusCode) return Results.StatusCode(502);\n return Results.Text(await upstream.Content.ReadAsStringAsync(context.RequestAborted), \"application/json\");\n } catch (HttpRequestException) { return Results.StatusCode(503); }\n}).AllowAnonymous(); // Replace with .RequireAuthorization() for login-only chat.\npublic sealed record AgentTokenRequest(int AgentId);\n// Imports: Microsoft.AspNetCore.Http, System.Net.Http.Json, System.Collections.Generic.\n// Add a distributed rate limiter and trusted-proxy configuration for public deployments.`,\n };\n}\n"]}
|
|
@@ -25,13 +25,27 @@ export function embedSamples(agentId: number, fields: AgentInputDefinition[], sd
|
|
|
25
25
|
// Optional lifecycle methods: chat.open(), chat.close(), chat.destroy().
|
|
26
26
|
// Update context before the first message or after starting a new chat:
|
|
27
27
|
// await chat.setInputs({ ... });
|
|
28
|
+
</script>`,
|
|
29
|
+
inline: `<div id="agent-chat" style="width:420px;height:600px"></div>
|
|
30
|
+
<script src=${JSON.stringify(sdkUrl).replace(/</g, "<")}></script>
|
|
31
|
+
<script>
|
|
32
|
+
// Your app owns this container's size, position, and visibility.
|
|
33
|
+
// Keep the same instance mounted when navigating within your app.
|
|
34
|
+
const chat = SolidAgentEmbed.mount({
|
|
35
|
+
mode: "inline",
|
|
36
|
+
container: "#agent-chat",
|
|
37
|
+
${config}
|
|
38
|
+
});
|
|
39
|
+
chat.open();
|
|
40
|
+
// chat.close() hides the iframe without ending the chat.
|
|
41
|
+
// chat.destroy() removes the iframe when the user signs out.
|
|
28
42
|
</script>`,
|
|
29
43
|
react: `"use client";
|
|
30
44
|
import { useEffect, useRef } from "react";
|
|
31
45
|
|
|
32
46
|
type AgentEmbed = { destroy: () => void };
|
|
33
47
|
type AgentEmbedSdk = { mount: (options: {
|
|
34
|
-
container: HTMLElement; agentId: number; tokenEndpoint: string;
|
|
48
|
+
container: HTMLElement; mode?: "popup" | "inline"; agentId: number; tokenEndpoint: string;
|
|
35
49
|
inputs: Record<string, unknown>; label?: string; title?: string;
|
|
36
50
|
getTokenHeaders?: () => Record<string, string>;
|
|
37
51
|
}) => AgentEmbed };
|
|
@@ -16,6 +16,17 @@ export type AgentContext = {
|
|
|
16
16
|
route?: string;
|
|
17
17
|
[key: string]: unknown;
|
|
18
18
|
};
|
|
19
|
+
export type AgentJson = null | boolean | number | string | AgentJson[] | {
|
|
20
|
+
[key: string]: AgentJson;
|
|
21
|
+
};
|
|
22
|
+
export type AgentMessageContext = {
|
|
23
|
+
schemaVersion: 1;
|
|
24
|
+
namespaces: Record<string, {
|
|
25
|
+
context: AgentJson;
|
|
26
|
+
revision: string;
|
|
27
|
+
displaySummary?: string;
|
|
28
|
+
}>;
|
|
29
|
+
};
|
|
19
30
|
export type AgentMode = "bubble" | "compact" | "docked" | "maximized";
|
|
20
31
|
/**
|
|
21
32
|
* Which agent backend a chat talks to: "solidx" (setting solidxAgentBackendUrl; the floating
|
|
@@ -121,7 +132,9 @@ export type AgentAction = {
|
|
|
121
132
|
action: "message";
|
|
122
133
|
session_id: string;
|
|
123
134
|
content: string;
|
|
135
|
+
source?: "composer" | "sdk" | "prefill" | "widget";
|
|
124
136
|
context?: AgentContext;
|
|
137
|
+
message_context?: AgentMessageContext;
|
|
125
138
|
inputs?: Record<string, unknown>;
|
|
126
139
|
widget_reply?: WidgetReply | null;
|
|
127
140
|
attachments?: AgentAttachmentPayload[] | AgentUploadedAttachment[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/core/solid-agent/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/components/core/solid-agent/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/components/core/solid-agent/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/components/core/solid-agent/types.ts"],"names":[],"mappings":"AAiEA,4GAA4G;AAC5G,MAAM,CAAC,IAAM,eAAe,GAAG;IAC3B,cAAc,EAAE,iBAAiB;IACjC,YAAY,EAAE,eAAe;IAC7B,WAAW,EAAE,aAAa;IAC1B,YAAY,EAAE,cAAc;IAC5B,WAAW,EAAE,aAAa;IAC1B,YAAY,EAAE,cAAc;IAC5B,QAAQ,EAAE,UAAU;IACpB,WAAW,EAAE,aAAa;IAC1B,WAAW,EAAE,aAAa;IAC1B,YAAY,EAAE,cAAc;IAC5B,UAAU,EAAE,YAAY;IACxB,YAAY,EAAE,mBAAmB;IACjC,kBAAkB,EAAE,eAAe;IACnC,aAAa,EAAE,eAAe;IAC9B,kBAAkB,EAAE,oBAAoB;IACxC,wBAAwB,EAAE,qBAAqB;IAC/C,UAAU,EAAE,YAAY;IACxB,KAAK,EAAE,OAAO;CACR,CAAC","sourcesContent":["import type { AgentChatWidgetMetadata } from \"../../../types/extension-registry\";\n\n/**\n * Shared types for the SolidX Agent chat (launcher, window, thread).\n *\n * Wire format: every agent payload carries `event_type` and `event_data`. When\n * `event_data.widget` names a registered chat widget, that widget renders the event;\n * otherwise the event is rendered by the default widget for its `event_type`.\n * (Legacy frames `{ type, data }` are normalised to the same shape.)\n * The widget contract itself (SolidChatWidgetProps) lives in types/solid-core.d.ts.\n */\n\n/** Page context passed with a prompt so the agent knows where the user is. */\nexport type AgentContext = {\n module?: string;\n model?: string;\n recordId?: string | number;\n route?: string;\n [key: string]: unknown;\n};\n\nexport type AgentJson = null | boolean | number | string | AgentJson[] | { [key: string]: AgentJson };\nexport type AgentMessageContext = {\n schemaVersion: 1;\n namespaces: Record<string, { context: AgentJson; revision: string; displaySummary?: string }>;\n};\n\nexport type AgentMode = \"bubble\" | \"compact\" | \"docked\" | \"maximized\";\n\n/**\n * Which agent backend a chat talks to: \"solidx\" (setting solidxAgentBackendUrl; the floating\n * launcher) or \"agentHub\" (setting solidxAgentHubBackendUrl).\n */\nexport type AgentRuntimeType = \"solidx\" | \"agentHub\";\nexport type AgentModelAssignment = { provider: string; model: string } | null;\nexport type AgentModelAssignments = { reasoning: AgentModelAssignment; fast: AgentModelAssignment };\n/** @deprecated Use AgentRuntimeType. */\nexport type AgentType = AgentRuntimeType;\n\nexport type AgentConnection = \"idle\" | \"connecting\" | \"open\" | \"reconnecting\" | \"offline\";\n\n/** A slash command advertised by the agent in `session_started`. */\nexport type AgentCommand = { name: string; description?: string };\n\n// ── Inbound ───────────────────────────────────────────────────────────────────\n\n/** A frame as it arrives on the socket or from session history (before normalisation). */\nexport type AgentWireFrame = {\n event_type?: string;\n event_data?: Record<string, any>;\n type?: string;\n data?: Record<string, any>;\n session_id?: string;\n history_session_id?: string;\n [key: string]: any;\n};\n\n/** The normalised event every reducer and widget works with. */\nexport type AgentChatEvent = {\n eventType: string;\n eventData: Record<string, any>;\n /** Top-level fields of the frame (session_id, history_session_id, commands, ...). */\n frame: AgentWireFrame;\n};\n\n/** Event types the chat knows by name. Anything else is still rendered (via its widget or the fallback). */\nexport const AgentEventTypes = {\n sessionStarted: \"session_started\",\n sessionEnded: \"session_ended\",\n userMessage: \"UserMessage\",\n agentStarted: \"AgentStarted\",\n stepStarted: \"StepStarted\",\n stepComplete: \"StepComplete\",\n llmToken: \"LlmToken\",\n llmComplete: \"LlmComplete\",\n toolCalling: \"ToolCalling\",\n toolProgress: \"ToolProgress\",\n toolResult: \"ToolResult\",\n turnComplete: \"TurnCompleteEvent\",\n turnCompleteLegacy: \"turn_complete\",\n agentComplete: \"AgentComplete\",\n executionCancelled: \"ExecutionCancelled\",\n executionCancelledLegacy: \"execution_cancelled\",\n agentError: \"AgentError\",\n error: \"error\",\n} as const;\n\n// ── Outbound ──────────────────────────────────────────────────────────────────\n\nexport type WidgetReply = { widgetId: string; value: unknown };\n\n/** A file sent inline with a message: text files as text, images base64-encoded (no data: prefix). */\nexport type AgentAttachmentPayload = {\n name: string;\n mimeType: string;\n size: number;\n encoding: \"text\" | \"base64\";\n content: string;\n};\n\n/** What the thread shows for an attachment (history only has name/type/size). */\nexport type AgentAttachmentMeta = {\n mediaId?: number;\n name: string;\n mimeType: string;\n size: number;\n /** data: URL for image thumbnails of files attached in this browser session. */\n previewUrl?: string;\n /** Stored copy in Solid media storage (resolved when a conversation is reopened). */\n url?: string;\n};\n\nexport type AgentAttachment = { payload: AgentAttachmentPayload; meta: AgentAttachmentMeta; file: File };\nexport type AgentUploadedAttachment = { id: number; name: string; mimeType: string; size: number };\n\nexport type AgentAction =\n | { action: \"start_session\"; widget_catalog?: AgentChatWidgetMetadata[] }\n | { action: \"resume_session\"; session_id: string; widget_catalog?: AgentChatWidgetMetadata[] }\n | {\n action: \"message\";\n session_id: string;\n content: string;\n source?: \"composer\" | \"sdk\" | \"prefill\" | \"widget\";\n context?: AgentContext;\n message_context?: AgentMessageContext;\n inputs?: Record<string, unknown>;\n widget_reply?: WidgetReply | null;\n attachments?: AgentAttachmentPayload[] | AgentUploadedAttachment[];\n }\n | { action: \"cancel\"; session_id: string }\n | { action: \"end_session\"; session_id: string };\n\n// ── Thread items ──────────────────────────────────────────────────────────────\n\n/**\n * One rendered entry in the thread. `eventData` is the (accumulated) event payload handed to\n * the widget; `widget` is set when the agent named one, otherwise the default for `eventType`.\n */\nexport type AgentChatItem = {\n id: string;\n at: number;\n eventType: string;\n eventData: Record<string, any>;\n widget?: string;\n widgetId?: string;\n /** Live items (a running tool, a streaming reply) are still updating. */\n live?: boolean;\n /** A final widget accepts no more updates or replies. */\n final?: boolean;\n};\n\n/** Options for `solidAgent.open`. */\nexport type SolidAgentOpenOptions = {\n prompt?: string;\n autoSend?: boolean;\n context?: AgentContext;\n mode?: Exclude<AgentMode, \"bubble\">;\n};\n"]}
|