@solidxai/core-ui 0.1.20-beta.1 → 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
|
@@ -9,8 +9,11 @@ import {
|
|
|
9
9
|
type AgentState,
|
|
10
10
|
} from "../../../../redux/features/agentSlice";
|
|
11
11
|
import { historyToItems, normalizeAgentFrame } from "../agentEvents";
|
|
12
|
+
import { parseWidgetContent } from "../thread/inlineWidget";
|
|
12
13
|
import { SOLID_AGENT_EVENTS } from "../sdk/solidAgent";
|
|
13
|
-
import {
|
|
14
|
+
import { emitBeforeUserMessageSend, type BeforeUserMessageSendContribution } from "./beforeUserMessageSend";
|
|
15
|
+
import { emitAgentPublicEvent, type AgentPublicEventName, type AgentPublicEventPayloads } from "./agentPublicEvents";
|
|
16
|
+
import { AgentEventTypes, type AgentRuntimeType, type AgentAttachment, type AgentChatEvent, type AgentContext, type AgentMessageContext, type AgentWireFrame } from "../types";
|
|
14
17
|
import { resolveAttachmentMedia } from "./agentAttachmentMedia";
|
|
15
18
|
import { clearAllAgentAuth } from "./agentAuth";
|
|
16
19
|
import { fetchSessionHistory, uploadAgentAttachments } from "./agentRest";
|
|
@@ -57,6 +60,9 @@ export class AgentRuntime {
|
|
|
57
60
|
private frame: number | null = null;
|
|
58
61
|
private unsubscribers: Array<() => void> = [];
|
|
59
62
|
private lastContext: AgentContext | undefined;
|
|
63
|
+
private responseStarted = false;
|
|
64
|
+
private hadPriorSession = false;
|
|
65
|
+
private preparationControllers = new Set<AbortController>();
|
|
60
66
|
private historySessionId: string | null = null;
|
|
61
67
|
private historyGeneration = 0;
|
|
62
68
|
private loadingHistoryPages = new Map<string, number>();
|
|
@@ -74,9 +80,14 @@ export class AgentRuntime {
|
|
|
74
80
|
this.sessionKey = sessionKey(agentRuntime, agentUrl);
|
|
75
81
|
this.socket = new AgentSocket(agentUrl, persistSession ? readSessionId(this.sessionKey) : null, agentRuntime === "agentHub",
|
|
76
82
|
agentRuntime === "agentHub" ? getAgentChatWidgetCatalog() : []);
|
|
83
|
+
this.hadPriorSession = !!this.socket.currentSessionId;
|
|
77
84
|
this.unsubscribers.push(
|
|
78
85
|
this.socket.onEvent((frame) => this.handleFrame(frame)),
|
|
79
86
|
this.socket.onStatus((status) => this.dispatch(agentConnectionChanged(status))),
|
|
87
|
+
this.socket.onStatus((status) => this.publish("onConnectionStateChanged", { state: status })),
|
|
88
|
+
this.socket.onSent((action) => {
|
|
89
|
+
if (action.action === "message") this.publish("onAfterUserMessageSend", { sessionId: action.session_id, source: action.source ?? "composer", deliveryStage: "sent" });
|
|
90
|
+
}),
|
|
80
91
|
);
|
|
81
92
|
this.socket.connect();
|
|
82
93
|
}
|
|
@@ -84,51 +95,102 @@ export class AgentRuntime {
|
|
|
84
95
|
/**
|
|
85
96
|
* Uploads files into SolidX media storage first, then sends their IDs with the socket message.
|
|
86
97
|
*/
|
|
87
|
-
async sendMessage(
|
|
88
|
-
|
|
89
|
-
|
|
98
|
+
async sendMessage(
|
|
99
|
+
text: string,
|
|
100
|
+
context?: AgentContext,
|
|
101
|
+
attachments: AgentAttachment[] = [],
|
|
102
|
+
inputs?: Record<string, unknown>,
|
|
103
|
+
beforeSend?: (request: { text: string; source: "composer" | "sdk" | "prefill" | "widget"; attachments: Array<{ name: string; mimeType: string; size: number }> }, signal: AbortSignal) => Promise<AgentMessageContext | AgentContext | undefined>,
|
|
104
|
+
source: "composer" | "sdk" | "prefill" | "widget" = "composer",
|
|
105
|
+
widgetReply?: { widgetId: string; value: unknown },
|
|
106
|
+
) {
|
|
107
|
+
const content = text;
|
|
108
|
+
if (!content.trim() && !attachments.length) return;
|
|
109
|
+
const controller = new AbortController();
|
|
110
|
+
this.preparationControllers.add(controller);
|
|
111
|
+
let messageContext: AgentMessageContext | undefined;
|
|
112
|
+
let contributedInputContext: AgentContext | undefined;
|
|
113
|
+
try {
|
|
114
|
+
const request = {
|
|
115
|
+
text: content,
|
|
116
|
+
source,
|
|
117
|
+
attachments: attachments.map(({ meta }) => ({ name: meta.name, mimeType: meta.mimeType, size: meta.size })),
|
|
118
|
+
};
|
|
119
|
+
const contributions: BeforeUserMessageSendContribution[] = this.agentRuntime === "solidx"
|
|
120
|
+
? await emitBeforeUserMessageSend(request, controller.signal)
|
|
121
|
+
: [];
|
|
122
|
+
if (beforeSend) contributions.push(await beforeSend(request, controller.signal));
|
|
123
|
+
for (const contribution of contributions) {
|
|
124
|
+
if (contribution && typeof contribution === "object" && "schemaVersion" in contribution
|
|
125
|
+
&& contribution.schemaVersion === 1 && "namespaces" in contribution) {
|
|
126
|
+
const incoming = contribution as AgentMessageContext;
|
|
127
|
+
messageContext = {
|
|
128
|
+
schemaVersion: 1,
|
|
129
|
+
namespaces: { ...(messageContext?.namespaces ?? {}), ...incoming.namespaces },
|
|
130
|
+
};
|
|
131
|
+
} else if (contribution && typeof contribution === "object") {
|
|
132
|
+
contributedInputContext = { ...(contributedInputContext ?? {}), ...contribution };
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
} catch (error) {
|
|
136
|
+
this.publish("onUserMessageFailed", { stage: "context", code: "context_preparation_failed", retryable: true });
|
|
137
|
+
throw error;
|
|
138
|
+
} finally {
|
|
139
|
+
this.preparationControllers.delete(controller);
|
|
140
|
+
}
|
|
141
|
+
if (controller.signal.aborted) throw new Error("Message preparation was cancelled.");
|
|
90
142
|
const uploaded = attachments.length
|
|
91
143
|
? await uploadAgentAttachments(this.agentUrl, attachments.map((item) => item.file))
|
|
92
144
|
: [];
|
|
93
145
|
if (uploaded.length !== attachments.length) {
|
|
146
|
+
this.publish("onUserMessageFailed", { stage: "upload", code: "attachment_upload_failed", retryable: true });
|
|
94
147
|
throw new Error("SolidX did not confirm every uploaded file. Please retry.");
|
|
95
148
|
}
|
|
149
|
+
this.publish("onUserMessageQueued", { source, hasAttachments: attachments.length > 0,
|
|
150
|
+
contextNamespaces: messageContext ? Object.keys(messageContext.namespaces) : [] });
|
|
151
|
+
this.responseStarted = false;
|
|
96
152
|
if (context) this.lastContext = context;
|
|
97
153
|
const displayAttachments = attachments.map((item, index) => ({
|
|
98
154
|
...item.meta,
|
|
99
155
|
...(uploaded[index] ? { mediaId: uploaded[index].id } : {}),
|
|
100
156
|
}));
|
|
101
|
-
this.dispatch(agentUserMessageAdded({ text: content, attachments: displayAttachments }));
|
|
157
|
+
this.dispatch(agentUserMessageAdded({ text: content, attachments: displayAttachments, messageContext }));
|
|
102
158
|
this.socket.send({
|
|
103
159
|
action: "message",
|
|
104
160
|
session_id: this.socket.currentSessionId ?? "",
|
|
105
161
|
content,
|
|
106
|
-
|
|
162
|
+
source,
|
|
163
|
+
context: contributedInputContext
|
|
164
|
+
? { ...(context ?? this.lastContext ?? {}), ...contributedInputContext }
|
|
165
|
+
: context ?? this.lastContext,
|
|
166
|
+
...(messageContext ? { message_context: messageContext } : {}),
|
|
107
167
|
...(this.agentRuntime === "agentHub" && inputs ? { inputs } : {}),
|
|
108
168
|
...(attachments.length ? { attachments: uploaded } : {}),
|
|
169
|
+
...(widgetReply ? { widget_reply: widgetReply } : {}),
|
|
109
170
|
});
|
|
110
171
|
}
|
|
111
172
|
|
|
112
173
|
/** Answers a widget. Sent as text too, so agents without widget_reply support still understand it. */
|
|
113
|
-
replyToWidget(widgetId: string, widget: string, value: unknown
|
|
174
|
+
async replyToWidget(widgetId: string, widget: string, value: unknown,
|
|
175
|
+
beforeSend?: Parameters<AgentRuntime["sendMessage"]>[4]) {
|
|
114
176
|
const text = typeof value === "string" ? value : Array.isArray(value) ? value.join(", ") : JSON.stringify(value);
|
|
115
|
-
this.
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
session_id: this.socket.currentSessionId ?? "",
|
|
119
|
-
content: text,
|
|
120
|
-
context: this.lastContext,
|
|
121
|
-
widget_reply: { widgetId, value },
|
|
122
|
-
});
|
|
177
|
+
await this.sendMessage(text, this.lastContext, [], undefined, beforeSend, "widget", { widgetId, value });
|
|
178
|
+
// The text message uses the shared preparation path. Keep the structured widget
|
|
179
|
+
// value as a separate event for consumers that handle widget replies.
|
|
123
180
|
eventBus.emit(SOLID_AGENT_EVENTS.widgetAction, { widgetId, widget, value, agentType: this.agentRuntime });
|
|
124
181
|
}
|
|
125
182
|
|
|
126
183
|
cancel() {
|
|
127
184
|
const sessionId = this.socket.currentSessionId;
|
|
128
|
-
if (sessionId)
|
|
185
|
+
if (sessionId) {
|
|
186
|
+
this.publish("onCancelRequested", { sessionId });
|
|
187
|
+
this.socket.send({ action: "cancel", session_id: sessionId });
|
|
188
|
+
}
|
|
129
189
|
}
|
|
130
190
|
|
|
131
191
|
newChat() {
|
|
192
|
+
this.publish("onNewChatRequested", { sessionId: this.socket.currentSessionId });
|
|
193
|
+
this.hadPriorSession = false;
|
|
132
194
|
this.resetHistoryLoads();
|
|
133
195
|
if (this.persistSession) writeSessionId(this.sessionKey, null);
|
|
134
196
|
this.lastContext = undefined;
|
|
@@ -137,6 +199,7 @@ export class AgentRuntime {
|
|
|
137
199
|
}
|
|
138
200
|
|
|
139
201
|
resume(sessionId: string) {
|
|
202
|
+
this.hadPriorSession = true;
|
|
140
203
|
this.resetHistoryLoads();
|
|
141
204
|
if (this.persistSession) writeSessionId(this.sessionKey, sessionId);
|
|
142
205
|
this.dispatch(agentThreadReset());
|
|
@@ -157,6 +220,8 @@ export class AgentRuntime {
|
|
|
157
220
|
}
|
|
158
221
|
|
|
159
222
|
dispose() {
|
|
223
|
+
this.preparationControllers.forEach((controller) => controller.abort());
|
|
224
|
+
this.preparationControllers.clear();
|
|
160
225
|
this.resetHistoryLoads();
|
|
161
226
|
this.unsubscribers.forEach((off) => off());
|
|
162
227
|
if (this.frame != null) cancelAnimationFrame(this.frame);
|
|
@@ -186,6 +251,47 @@ export class AgentRuntime {
|
|
|
186
251
|
|
|
187
252
|
private handleFrame(frame: AgentWireFrame) {
|
|
188
253
|
const event = normalizeAgentFrame(frame);
|
|
254
|
+
if (event.eventType === AgentEventTypes.sessionStarted) {
|
|
255
|
+
const sessionId = frame.session_id ?? event.eventData.session_id ?? null;
|
|
256
|
+
this.publish(this.hadPriorSession ? "onSessionResumed" : "onSessionStarted", { sessionId });
|
|
257
|
+
this.hadPriorSession = true;
|
|
258
|
+
}
|
|
259
|
+
else if (event.eventType === AgentEventTypes.sessionEnded) this.publish("onSessionEnded", { sessionId: this.socket.currentSessionId, reason: event.eventData.reason ?? "ended" });
|
|
260
|
+
else if (event.eventType === AgentEventTypes.agentStarted) this.publish("onAgentTurnStarted", { sessionId: this.socket.currentSessionId });
|
|
261
|
+
else if ((event.eventType === AgentEventTypes.llmToken || event.eventType === AgentEventTypes.llmComplete)
|
|
262
|
+
&& !event.eventData.widget && !this.responseStarted) {
|
|
263
|
+
this.responseStarted = true;
|
|
264
|
+
this.publish("onAgentResponseStarted", { sessionId: this.socket.currentSessionId });
|
|
265
|
+
}
|
|
266
|
+
else if (event.eventType === AgentEventTypes.turnComplete || event.eventType === AgentEventTypes.turnCompleteLegacy) {
|
|
267
|
+
this.publish("onAgentResponseCompleted", { sessionId: this.socket.currentSessionId });
|
|
268
|
+
const completedContent = event.eventData.content ?? event.frame.content;
|
|
269
|
+
const inline = parseWidgetContent(completedContent);
|
|
270
|
+
if (inline?.widget === "navigation-intent" && inline.data.schemaVersion === 1
|
|
271
|
+
&& inline.data.kind === "navigation" && typeof inline.data.domain === "string"
|
|
272
|
+
&& inline.data.payload && typeof inline.data.payload === "object" && !Array.isArray(inline.data.payload)) {
|
|
273
|
+
this.publish("onAgentNavigationRequested", {
|
|
274
|
+
schemaVersion: 1,
|
|
275
|
+
kind: "navigation",
|
|
276
|
+
domain: inline.data.domain,
|
|
277
|
+
payload: inline.data.payload as Record<string, unknown>,
|
|
278
|
+
...(typeof inline.data.message === "string" ? { message: inline.data.message } : {}),
|
|
279
|
+
sessionId: this.socket.currentSessionId,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
this.publish("onAgentTurnCompleted", { sessionId: this.socket.currentSessionId, outcome: "completed" });
|
|
283
|
+
} else if (event.eventType === AgentEventTypes.agentError || event.eventType === AgentEventTypes.error) {
|
|
284
|
+
this.publish("onError", { stage: "runtime", code: "agent_error", retryable: false });
|
|
285
|
+
} else if (event.eventType === "HumanRequestCreated") {
|
|
286
|
+
const approval = event.eventData.kind === "approval";
|
|
287
|
+
this.publish(approval ? "onApprovalRequested" : "onHumanInputRequested", {
|
|
288
|
+
sessionId: this.socket.currentSessionId,
|
|
289
|
+
requestId: event.eventData.request_id,
|
|
290
|
+
...(typeof event.eventData.question === "string" ? { displayPayload: event.eventData.question.slice(0, 1024) } : {}),
|
|
291
|
+
});
|
|
292
|
+
} else if (event.eventType === AgentEventTypes.executionCancelled || event.eventType === AgentEventTypes.executionCancelledLegacy) {
|
|
293
|
+
this.publish("onTurnCancelled", { sessionId: this.socket.currentSessionId });
|
|
294
|
+
}
|
|
189
295
|
|
|
190
296
|
// Stream text is batched per animation frame unless it carries a widget of its own.
|
|
191
297
|
if (event.eventType === AgentEventTypes.llmToken && !event.eventData.widget) {
|
|
@@ -199,6 +305,10 @@ export class AgentRuntime {
|
|
|
199
305
|
this.emitSdkEvents(event);
|
|
200
306
|
}
|
|
201
307
|
|
|
308
|
+
private publish<E extends AgentPublicEventName>(event: E, payload: AgentPublicEventPayloads[E]) {
|
|
309
|
+
emitAgentPublicEvent(event, payload, this.agentRuntime);
|
|
310
|
+
}
|
|
311
|
+
|
|
202
312
|
private emitSdkEvents(event: AgentChatEvent) {
|
|
203
313
|
if (event.eventType === AgentEventTypes.sessionStarted) {
|
|
204
314
|
const sessionId = event.frame.session_id ?? event.eventData.session_id ?? null;
|
|
@@ -2,6 +2,7 @@ import type { AgentAction, AgentConnection, AgentWireFrame } from "../types";
|
|
|
2
2
|
import type { AgentChatWidgetMetadata } from "../../../../types/extension-registry";
|
|
3
3
|
type EventListener = (frame: AgentWireFrame) => void;
|
|
4
4
|
type StatusListener = (status: AgentConnection) => void;
|
|
5
|
+
type SentListener = (action: AgentAction) => void;
|
|
5
6
|
export declare class AgentSocket {
|
|
6
7
|
private agentUrl;
|
|
7
8
|
private initialSessionId;
|
|
@@ -14,6 +15,7 @@ export declare class AgentSocket {
|
|
|
14
15
|
private queue;
|
|
15
16
|
private eventListeners;
|
|
16
17
|
private statusListeners;
|
|
18
|
+
private sentListeners;
|
|
17
19
|
private sessionId;
|
|
18
20
|
/** False until the agent confirms the session (session_started) on the current socket. */
|
|
19
21
|
private sessionReady;
|
|
@@ -28,6 +30,7 @@ export declare class AgentSocket {
|
|
|
28
30
|
get currentSessionId(): string | null;
|
|
29
31
|
onEvent(listener: EventListener): () => boolean;
|
|
30
32
|
onStatus(listener: StatusListener): () => boolean;
|
|
33
|
+
onSent(listener: SentListener): () => boolean;
|
|
31
34
|
connect(): void;
|
|
32
35
|
/** Sends an action, or queues it until the socket and session are ready. */
|
|
33
36
|
send(action: AgentAction): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentSocket.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/client/agentSocket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAepF,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;AACrD,KAAK,cAAc,GAAG,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"agentSocket.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/client/agentSocket.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC7E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAepF,KAAK,aAAa,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;AACrD,KAAK,cAAc,GAAG,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;AACxD,KAAK,YAAY,GAAG,CAAC,MAAM,EAAE,WAAW,KAAK,IAAI,CAAC;AAElD,qBAAa,WAAW;IAmBhB,OAAO,CAAC,QAAQ;IAChB,OAAO,CAAC,gBAAgB;IACxB,OAAO,CAAC,wBAAwB;IAChC,OAAO,CAAC,aAAa;IArBzB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,KAAK,CAA8C;IAC3D,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,cAAc,CAA4B;IAClD,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,aAAa,CAA2B;IAChD,OAAO,CAAC,SAAS,CAAuB;IACxC,0FAA0F;IAC1F,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,2BAA2B,CAAS;IAC5C,OAAO,CAAC,qBAAqB,CAA4B;IAEzD,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAU;gBAGzB,QAAQ,EAAE,MAAM,EAChB,gBAAgB,GAAE,MAAM,GAAG,IAAW,EACtC,wBAAwB,UAAQ,EAChC,aAAa,GAAE,uBAAuB,EAAO;IAazD,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,mBAAmB;IAK3B,IAAI,gBAAgB,kBAEnB;IAED,OAAO,CAAC,QAAQ,EAAE,aAAa;IAK/B,QAAQ,CAAC,QAAQ,EAAE,cAAc;IAKjC,MAAM,CAAC,QAAQ,EAAE,YAAY;IAK7B,OAAO;IAwFP,4EAA4E;IAC5E,IAAI,CAAC,MAAM,EAAE,WAAW;IAUxB,kEAAkE;IAClE,UAAU;IASV,4CAA4C;IAC5C,MAAM,CAAC,SAAS,EAAE,MAAM;IAOxB,uDAAuD;IACvD,KAAK;IASL,oEAAoE;IACpE,OAAO,CAAC,UAAU;IAalB,OAAO,CAAC,UAAU;YAUJ,OAAO;IAerB,OAAO,CAAC,iBAAiB;YAcX,iBAAiB;IAgB/B,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,YAAY;CAQvB"}
|
|
@@ -128,6 +128,12 @@ var AgentSocket = /** @class */ (function () {
|
|
|
128
128
|
writable: true,
|
|
129
129
|
value: new Set()
|
|
130
130
|
});
|
|
131
|
+
Object.defineProperty(this, "sentListeners", {
|
|
132
|
+
enumerable: true,
|
|
133
|
+
configurable: true,
|
|
134
|
+
writable: true,
|
|
135
|
+
value: new Set()
|
|
136
|
+
});
|
|
131
137
|
Object.defineProperty(this, "sessionId", {
|
|
132
138
|
enumerable: true,
|
|
133
139
|
configurable: true,
|
|
@@ -230,6 +236,16 @@ var AgentSocket = /** @class */ (function () {
|
|
|
230
236
|
return function () { return _this.statusListeners.delete(listener); };
|
|
231
237
|
}
|
|
232
238
|
});
|
|
239
|
+
Object.defineProperty(AgentSocket.prototype, "onSent", {
|
|
240
|
+
enumerable: false,
|
|
241
|
+
configurable: true,
|
|
242
|
+
writable: true,
|
|
243
|
+
value: function (listener) {
|
|
244
|
+
var _this = this;
|
|
245
|
+
this.sentListeners.add(listener);
|
|
246
|
+
return function () { return _this.sentListeners.delete(listener); };
|
|
247
|
+
}
|
|
248
|
+
});
|
|
233
249
|
Object.defineProperty(AgentSocket.prototype, "connect", {
|
|
234
250
|
enumerable: false,
|
|
235
251
|
configurable: true,
|
|
@@ -461,8 +477,10 @@ var AgentSocket = /** @class */ (function () {
|
|
|
461
477
|
if (this.debugEmbed)
|
|
462
478
|
console.info("[agent-embed][runtime] sending WebSocket action", { action: action.action });
|
|
463
479
|
this.ws.send(JSON.stringify(__assign(__assign({}, action), { agentToken: agentToken })));
|
|
464
|
-
if (action.action === "message")
|
|
480
|
+
if (action.action === "message") {
|
|
465
481
|
this.unacknowledgedMessage = action;
|
|
482
|
+
this.sentListeners.forEach(function (listener) { return listener(action); });
|
|
483
|
+
}
|
|
466
484
|
return [2 /*return*/];
|
|
467
485
|
}
|
|
468
486
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agentSocket.js","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/client/agentSocket.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentAction, AgentConnection, AgentWireFrame } from \"../types\";\nimport type { AgentChatWidgetMetadata } from \"../../../../types/extension-registry\";\nimport { agentWsUrl, clearAgentAuth, isAgentProcessAvailable, loadAgentAuth, onAgentAuthChange } from \"./agentAuth\";\n\n/**\n * WebSocket client for the agent, connecting to the full `wsUrl` named at sign-in (agentAuth.ts).\n *\n * Held outside Redux because sockets are not serializable; the host wires its listeners to\n * dispatch into agentSlice. Every outbound frame carries the `agentToken` from the agent login;\n * there is no socket until the user has signed in with an API key, and signing out closes it. Unexpected closes\n * reconnect with backoff (1s, 2s, 4s, then 15s) and re-send `resume_session`; frames sent\n * while disconnected are queued and flushed once the session is re-established.\n */\n\nconst BACKOFF_MS = [1000, 2000, 4000, 8000, 15000];\n\ntype EventListener = (frame: AgentWireFrame) => void;\ntype StatusListener = (status: AgentConnection) => void;\n\nexport class AgentSocket {\n private ws: WebSocket | null = null;\n private attempt = 0;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private closedByUser = false;\n private queue: AgentAction[] = [];\n private eventListeners = new Set<EventListener>();\n private statusListeners = new Set<StatusListener>();\n private sessionId: string | null = null;\n /** False until the agent confirms the session (session_started) on the current socket. */\n private sessionReady = false;\n private checkingProcessAvailability = false;\n private unacknowledgedMessage: AgentAction | null = null;\n\n private offAuthChange: () => void;\n private readonly debugEmbed: boolean;\n\n constructor(\n private agentUrl: string,\n private initialSessionId: string | null = null,\n private checkProcessAvailability = false,\n private widgetCatalog: AgentChatWidgetMetadata[] = [],\n ) {\n this.sessionId = initialSessionId;\n this.debugEmbed = !checkProcessAvailability;\n if (this.debugEmbed) console.info(\"[agent-embed][runtime] socket created\", { endpoint: this.safeEndpoint(), hasInitialSession: !!initialSessionId });\n // Signing in opens the socket on the wsUrl it named; signing out (or the token expiring) closes it.\n this.offAuthChange = onAgentAuthChange(agentUrl, () => {\n if (this.closedByUser) return;\n if (agentWsUrl(agentUrl)) this.connect();\n else this.disconnect();\n });\n }\n\n private openSession() {\n void this.sendRaw(this.sessionId ? this.resumeSessionAction(this.sessionId) : this.startSessionAction());\n }\n\n private startSessionAction(): AgentAction {\n return { action: \"start_session\", ...(this.widgetCatalog.length ? { widget_catalog: this.widgetCatalog } : {}) };\n }\n\n private resumeSessionAction(sessionId: string): AgentAction {\n return { action: \"resume_session\", session_id: sessionId,\n ...(this.widgetCatalog.length ? { widget_catalog: this.widgetCatalog } : {}) };\n }\n\n get currentSessionId() {\n return this.sessionId;\n }\n\n onEvent(listener: EventListener) {\n this.eventListeners.add(listener);\n return () => this.eventListeners.delete(listener);\n }\n\n onStatus(listener: StatusListener) {\n this.statusListeners.add(listener);\n return () => this.statusListeners.delete(listener);\n }\n\n connect() {\n if (this.closedByUser) return;\n const state = this.ws?.readyState;\n if (state === WebSocket.OPEN || state === WebSocket.CONNECTING) return;\n this.closedByUser = false;\n const url = agentWsUrl(this.agentUrl);\n if (!url) {\n if (this.debugEmbed) console.warn(\"[agent-embed][runtime] no WebSocket URL is available from auth yet\");\n // Not signed in: the auth listener connects once sign-in names the wsUrl.\n this.setStatus(\"idle\");\n return;\n }\n this.setStatus(this.attempt === 0 ? \"connecting\" : \"reconnecting\");\n if (this.debugEmbed) console.info(\"[agent-embed][runtime] opening WebSocket\", { endpoint: this.safeEndpoint(url), attempt: this.attempt + 1 });\n\n let ws: WebSocket;\n try {\n ws = new WebSocket(url);\n } catch (error) {\n if (this.debugEmbed) console.error(\"[agent-embed][runtime] WebSocket construction failed\", { name: error instanceof Error ? error.name : \"unknown\", message: error instanceof Error ? error.message : String(error) });\n this.scheduleReconnect();\n return;\n }\n this.ws = ws;\n\n ws.onopen = () => {\n if (this.ws !== ws) return;\n if (this.debugEmbed) console.info(\"[agent-embed][runtime] WebSocket open\");\n this.attempt = 0;\n this.sessionReady = false;\n this.setStatus(\"open\");\n this.openSession();\n };\n\n ws.onmessage = (message) => {\n if (this.ws !== ws) return;\n let frame: AgentWireFrame;\n try {\n frame = JSON.parse(message.data);\n } catch {\n return;\n }\n const eventType = frame.event_type ?? frame.type;\n const payload = frame.event_data ?? frame.data;\n if (this.debugEmbed) console.info(\"[agent-embed][runtime] WebSocket frame\", { eventType, hasSessionId: !!(frame.session_id ?? payload?.session_id), isError: eventType === \"error\" });\n if (eventType === \"session_started\") {\n // After an agent restart the old session is gone and resume returns a new id.\n this.sessionId = frame.session_id ?? payload?.session_id ?? null;\n this.sessionReady = true;\n this.flushQueue();\n } else if (eventType === \"error\" && /agent token/i.test(String(payload?.error ?? \"\"))) {\n // The agent forgot the token (idle 30 min or restarted): sign in again.\n this.sessionReady = false;\n if (this.unacknowledgedMessage) this.queue.push(this.unacknowledgedMessage);\n this.unacknowledgedMessage = null;\n clearAgentAuth(this.agentUrl);\n } else if (eventType === \"error\" && !this.sessionReady) {\n // Start/resume failed (e.g. auth); stop holding messages so their errors show.\n this.sessionReady = true;\n this.flushQueue();\n }\n if (eventType === \"UserMessage\" || eventType === \"turn_complete\" || eventType === \"error\") {\n this.unacknowledgedMessage = null;\n }\n // Drop frames for a different session (e.g. a late event after a switch).\n const frameSession = frame.session_id ?? payload?.session_id;\n if (eventType !== \"session_started\" && frameSession && this.sessionId && frameSession !== this.sessionId) return;\n this.eventListeners.forEach((listener) => listener(frame));\n };\n\n ws.onclose = (event) => {\n if (this.ws !== ws) return;\n if (this.debugEmbed) console.warn(\"[agent-embed][runtime] WebSocket closed\", { code: event.code, reason: event.reason, clean: event.wasClean });\n this.ws = null;\n this.sessionReady = false;\n if (this.closedByUser) {\n this.setStatus(\"idle\");\n return;\n }\n this.scheduleReconnect();\n };\n\n ws.onerror = () => {\n if (this.debugEmbed) console.error(\"[agent-embed][runtime] WebSocket error event\");\n // onclose follows and handles the reconnect.\n };\n }\n\n /** Sends an action, or queues it until the socket and session are ready. */\n send(action: AgentAction) {\n if (this.closedByUser) return;\n if (this.ws?.readyState === WebSocket.OPEN && this.sessionId && this.sessionReady) {\n void this.sendRaw(action);\n } else {\n this.queue.push(action);\n this.connect();\n }\n }\n\n /** Starts a fresh conversation (drops the current session id). */\n newSession() {\n this.unacknowledgedMessage = null;\n this.sessionId = null;\n this.sessionReady = false;\n this.queue = [];\n if (this.ws?.readyState === WebSocket.OPEN) void this.sendRaw(this.startSessionAction());\n else this.connect();\n }\n\n /** Switches to an existing conversation. */\n resume(sessionId: string) {\n this.sessionId = sessionId;\n this.sessionReady = false;\n if (this.ws?.readyState === WebSocket.OPEN) void this.sendRaw(this.resumeSessionAction(sessionId));\n else this.connect();\n }\n\n /** Closes for good (the runtime is being disposed). */\n close() {\n this.offAuthChange();\n this.closedByUser = true;\n if (this.timer) clearTimeout(this.timer);\n this.timer = null;\n this.ws?.close();\n this.ws = null;\n }\n\n /** Drops the socket after sign-out; the next sign-in reconnects. */\n private disconnect() {\n if (this.timer) clearTimeout(this.timer);\n this.timer = null;\n this.attempt = 0;\n this.sessionReady = false;\n if (this.ws) {\n this.ws.onclose = null; // No reconnect.\n this.ws.close();\n this.ws = null;\n }\n this.setStatus(\"idle\");\n }\n\n private flushQueue() {\n const pending = this.queue;\n this.queue = [];\n pending.forEach((action) => {\n // Queued messages were addressed before a session existed; point them at the current one.\n const addressed = \"session_id\" in action && this.sessionId ? { ...action, session_id: this.sessionId } : action;\n void this.sendRaw(addressed as AgentAction);\n });\n }\n\n private async sendRaw(action: AgentAction) {\n const agentToken = (await loadAgentAuth(this.agentUrl))?.agentToken;\n if (!agentToken || this.ws?.readyState !== WebSocket.OPEN) {\n if (this.debugEmbed) console.warn(\"[agent-embed][runtime] skipped outbound frame\", { action: action.action, hasAgentToken: !!agentToken, socketOpen: this.ws?.readyState === WebSocket.OPEN });\n if (action.action !== \"start_session\" && action.action !== \"resume_session\") this.queue.push(action);\n return;\n }\n if (this.debugEmbed) console.info(\"[agent-embed][runtime] sending WebSocket action\", { action: action.action });\n this.ws.send(JSON.stringify({ ...action, agentToken }));\n if (action.action === \"message\") this.unacknowledgedMessage = action;\n }\n\n private scheduleReconnect() {\n if (this.timer) return;\n const delay = BACKOFF_MS[Math.min(this.attempt, BACKOFF_MS.length - 1)];\n this.attempt += 1;\n this.setStatus(this.attempt > BACKOFF_MS.length ? \"offline\" : \"reconnecting\");\n if (this.checkProcessAvailability && this.attempt >= 2 && this.attempt % 3 === 2) {\n void this.checkAgentProcess(this.attempt);\n }\n this.timer = setTimeout(() => {\n this.timer = null;\n this.connect();\n }, delay);\n }\n\n private async checkAgentProcess(failedAttempt: number) {\n if (this.checkingProcessAvailability) return;\n this.checkingProcessAvailability = true;\n try {\n const auth = await loadAgentAuth(this.agentUrl);\n if (!auth || this.closedByUser || this.attempt !== failedAttempt) return;\n if (!(await isAgentProcessAvailable(auth)) && !this.closedByUser && this.attempt === failedAttempt) {\n // Repeated WebSocket failures plus a failed process health check mean the stored\n // endpoint is stale. Returning to sign-in lets the manager issue a fresh wsUrl.\n clearAgentAuth(this.agentUrl);\n }\n } finally {\n this.checkingProcessAvailability = false;\n }\n }\n\n private setStatus(status: AgentConnection) {\n if (this.debugEmbed) console.info(\"[agent-embed][runtime] connection status\", { status });\n this.statusListeners.forEach((listener) => listener(status));\n }\n\n private safeEndpoint(url = this.agentUrl) {\n try {\n const parsed = new URL(url);\n return `${parsed.origin}${parsed.pathname}`;\n } catch {\n return \"invalid-url\";\n }\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agentSocket.js","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/client/agentSocket.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AgentAction, AgentConnection, AgentWireFrame } from \"../types\";\nimport type { AgentChatWidgetMetadata } from \"../../../../types/extension-registry\";\nimport { agentWsUrl, clearAgentAuth, isAgentProcessAvailable, loadAgentAuth, onAgentAuthChange } from \"./agentAuth\";\n\n/**\n * WebSocket client for the agent, connecting to the full `wsUrl` named at sign-in (agentAuth.ts).\n *\n * Held outside Redux because sockets are not serializable; the host wires its listeners to\n * dispatch into agentSlice. Every outbound frame carries the `agentToken` from the agent login;\n * there is no socket until the user has signed in with an API key, and signing out closes it. Unexpected closes\n * reconnect with backoff (1s, 2s, 4s, then 15s) and re-send `resume_session`; frames sent\n * while disconnected are queued and flushed once the session is re-established.\n */\n\nconst BACKOFF_MS = [1000, 2000, 4000, 8000, 15000];\n\ntype EventListener = (frame: AgentWireFrame) => void;\ntype StatusListener = (status: AgentConnection) => void;\ntype SentListener = (action: AgentAction) => void;\n\nexport class AgentSocket {\n private ws: WebSocket | null = null;\n private attempt = 0;\n private timer: ReturnType<typeof setTimeout> | null = null;\n private closedByUser = false;\n private queue: AgentAction[] = [];\n private eventListeners = new Set<EventListener>();\n private statusListeners = new Set<StatusListener>();\n private sentListeners = new Set<SentListener>();\n private sessionId: string | null = null;\n /** False until the agent confirms the session (session_started) on the current socket. */\n private sessionReady = false;\n private checkingProcessAvailability = false;\n private unacknowledgedMessage: AgentAction | null = null;\n\n private offAuthChange: () => void;\n private readonly debugEmbed: boolean;\n\n constructor(\n private agentUrl: string,\n private initialSessionId: string | null = null,\n private checkProcessAvailability = false,\n private widgetCatalog: AgentChatWidgetMetadata[] = [],\n ) {\n this.sessionId = initialSessionId;\n this.debugEmbed = !checkProcessAvailability;\n if (this.debugEmbed) console.info(\"[agent-embed][runtime] socket created\", { endpoint: this.safeEndpoint(), hasInitialSession: !!initialSessionId });\n // Signing in opens the socket on the wsUrl it named; signing out (or the token expiring) closes it.\n this.offAuthChange = onAgentAuthChange(agentUrl, () => {\n if (this.closedByUser) return;\n if (agentWsUrl(agentUrl)) this.connect();\n else this.disconnect();\n });\n }\n\n private openSession() {\n void this.sendRaw(this.sessionId ? this.resumeSessionAction(this.sessionId) : this.startSessionAction());\n }\n\n private startSessionAction(): AgentAction {\n return { action: \"start_session\", ...(this.widgetCatalog.length ? { widget_catalog: this.widgetCatalog } : {}) };\n }\n\n private resumeSessionAction(sessionId: string): AgentAction {\n return { action: \"resume_session\", session_id: sessionId,\n ...(this.widgetCatalog.length ? { widget_catalog: this.widgetCatalog } : {}) };\n }\n\n get currentSessionId() {\n return this.sessionId;\n }\n\n onEvent(listener: EventListener) {\n this.eventListeners.add(listener);\n return () => this.eventListeners.delete(listener);\n }\n\n onStatus(listener: StatusListener) {\n this.statusListeners.add(listener);\n return () => this.statusListeners.delete(listener);\n }\n\n onSent(listener: SentListener) {\n this.sentListeners.add(listener);\n return () => this.sentListeners.delete(listener);\n }\n\n connect() {\n if (this.closedByUser) return;\n const state = this.ws?.readyState;\n if (state === WebSocket.OPEN || state === WebSocket.CONNECTING) return;\n this.closedByUser = false;\n const url = agentWsUrl(this.agentUrl);\n if (!url) {\n if (this.debugEmbed) console.warn(\"[agent-embed][runtime] no WebSocket URL is available from auth yet\");\n // Not signed in: the auth listener connects once sign-in names the wsUrl.\n this.setStatus(\"idle\");\n return;\n }\n this.setStatus(this.attempt === 0 ? \"connecting\" : \"reconnecting\");\n if (this.debugEmbed) console.info(\"[agent-embed][runtime] opening WebSocket\", { endpoint: this.safeEndpoint(url), attempt: this.attempt + 1 });\n\n let ws: WebSocket;\n try {\n ws = new WebSocket(url);\n } catch (error) {\n if (this.debugEmbed) console.error(\"[agent-embed][runtime] WebSocket construction failed\", { name: error instanceof Error ? error.name : \"unknown\", message: error instanceof Error ? error.message : String(error) });\n this.scheduleReconnect();\n return;\n }\n this.ws = ws;\n\n ws.onopen = () => {\n if (this.ws !== ws) return;\n if (this.debugEmbed) console.info(\"[agent-embed][runtime] WebSocket open\");\n this.attempt = 0;\n this.sessionReady = false;\n this.setStatus(\"open\");\n this.openSession();\n };\n\n ws.onmessage = (message) => {\n if (this.ws !== ws) return;\n let frame: AgentWireFrame;\n try {\n frame = JSON.parse(message.data);\n } catch {\n return;\n }\n const eventType = frame.event_type ?? frame.type;\n const payload = frame.event_data ?? frame.data;\n if (this.debugEmbed) console.info(\"[agent-embed][runtime] WebSocket frame\", { eventType, hasSessionId: !!(frame.session_id ?? payload?.session_id), isError: eventType === \"error\" });\n if (eventType === \"session_started\") {\n // After an agent restart the old session is gone and resume returns a new id.\n this.sessionId = frame.session_id ?? payload?.session_id ?? null;\n this.sessionReady = true;\n this.flushQueue();\n } else if (eventType === \"error\" && /agent token/i.test(String(payload?.error ?? \"\"))) {\n // The agent forgot the token (idle 30 min or restarted): sign in again.\n this.sessionReady = false;\n if (this.unacknowledgedMessage) this.queue.push(this.unacknowledgedMessage);\n this.unacknowledgedMessage = null;\n clearAgentAuth(this.agentUrl);\n } else if (eventType === \"error\" && !this.sessionReady) {\n // Start/resume failed (e.g. auth); stop holding messages so their errors show.\n this.sessionReady = true;\n this.flushQueue();\n }\n if (eventType === \"UserMessage\" || eventType === \"turn_complete\" || eventType === \"error\") {\n this.unacknowledgedMessage = null;\n }\n // Drop frames for a different session (e.g. a late event after a switch).\n const frameSession = frame.session_id ?? payload?.session_id;\n if (eventType !== \"session_started\" && frameSession && this.sessionId && frameSession !== this.sessionId) return;\n this.eventListeners.forEach((listener) => listener(frame));\n };\n\n ws.onclose = (event) => {\n if (this.ws !== ws) return;\n if (this.debugEmbed) console.warn(\"[agent-embed][runtime] WebSocket closed\", { code: event.code, reason: event.reason, clean: event.wasClean });\n this.ws = null;\n this.sessionReady = false;\n if (this.closedByUser) {\n this.setStatus(\"idle\");\n return;\n }\n this.scheduleReconnect();\n };\n\n ws.onerror = () => {\n if (this.debugEmbed) console.error(\"[agent-embed][runtime] WebSocket error event\");\n // onclose follows and handles the reconnect.\n };\n }\n\n /** Sends an action, or queues it until the socket and session are ready. */\n send(action: AgentAction) {\n if (this.closedByUser) return;\n if (this.ws?.readyState === WebSocket.OPEN && this.sessionId && this.sessionReady) {\n void this.sendRaw(action);\n } else {\n this.queue.push(action);\n this.connect();\n }\n }\n\n /** Starts a fresh conversation (drops the current session id). */\n newSession() {\n this.unacknowledgedMessage = null;\n this.sessionId = null;\n this.sessionReady = false;\n this.queue = [];\n if (this.ws?.readyState === WebSocket.OPEN) void this.sendRaw(this.startSessionAction());\n else this.connect();\n }\n\n /** Switches to an existing conversation. */\n resume(sessionId: string) {\n this.sessionId = sessionId;\n this.sessionReady = false;\n if (this.ws?.readyState === WebSocket.OPEN) void this.sendRaw(this.resumeSessionAction(sessionId));\n else this.connect();\n }\n\n /** Closes for good (the runtime is being disposed). */\n close() {\n this.offAuthChange();\n this.closedByUser = true;\n if (this.timer) clearTimeout(this.timer);\n this.timer = null;\n this.ws?.close();\n this.ws = null;\n }\n\n /** Drops the socket after sign-out; the next sign-in reconnects. */\n private disconnect() {\n if (this.timer) clearTimeout(this.timer);\n this.timer = null;\n this.attempt = 0;\n this.sessionReady = false;\n if (this.ws) {\n this.ws.onclose = null; // No reconnect.\n this.ws.close();\n this.ws = null;\n }\n this.setStatus(\"idle\");\n }\n\n private flushQueue() {\n const pending = this.queue;\n this.queue = [];\n pending.forEach((action) => {\n // Queued messages were addressed before a session existed; point them at the current one.\n const addressed = \"session_id\" in action && this.sessionId ? { ...action, session_id: this.sessionId } : action;\n void this.sendRaw(addressed as AgentAction);\n });\n }\n\n private async sendRaw(action: AgentAction) {\n const agentToken = (await loadAgentAuth(this.agentUrl))?.agentToken;\n if (!agentToken || this.ws?.readyState !== WebSocket.OPEN) {\n if (this.debugEmbed) console.warn(\"[agent-embed][runtime] skipped outbound frame\", { action: action.action, hasAgentToken: !!agentToken, socketOpen: this.ws?.readyState === WebSocket.OPEN });\n if (action.action !== \"start_session\" && action.action !== \"resume_session\") this.queue.push(action);\n return;\n }\n if (this.debugEmbed) console.info(\"[agent-embed][runtime] sending WebSocket action\", { action: action.action });\n this.ws.send(JSON.stringify({ ...action, agentToken }));\n if (action.action === \"message\") {\n this.unacknowledgedMessage = action;\n this.sentListeners.forEach((listener) => listener(action));\n }\n }\n\n private scheduleReconnect() {\n if (this.timer) return;\n const delay = BACKOFF_MS[Math.min(this.attempt, BACKOFF_MS.length - 1)];\n this.attempt += 1;\n this.setStatus(this.attempt > BACKOFF_MS.length ? \"offline\" : \"reconnecting\");\n if (this.checkProcessAvailability && this.attempt >= 2 && this.attempt % 3 === 2) {\n void this.checkAgentProcess(this.attempt);\n }\n this.timer = setTimeout(() => {\n this.timer = null;\n this.connect();\n }, delay);\n }\n\n private async checkAgentProcess(failedAttempt: number) {\n if (this.checkingProcessAvailability) return;\n this.checkingProcessAvailability = true;\n try {\n const auth = await loadAgentAuth(this.agentUrl);\n if (!auth || this.closedByUser || this.attempt !== failedAttempt) return;\n if (!(await isAgentProcessAvailable(auth)) && !this.closedByUser && this.attempt === failedAttempt) {\n // Repeated WebSocket failures plus a failed process health check mean the stored\n // endpoint is stale. Returning to sign-in lets the manager issue a fresh wsUrl.\n clearAgentAuth(this.agentUrl);\n }\n } finally {\n this.checkingProcessAvailability = false;\n }\n }\n\n private setStatus(status: AgentConnection) {\n if (this.debugEmbed) console.info(\"[agent-embed][runtime] connection status\", { status });\n this.statusListeners.forEach((listener) => listener(status));\n }\n\n private safeEndpoint(url = this.agentUrl) {\n try {\n const parsed = new URL(url);\n return `${parsed.origin}${parsed.pathname}`;\n } catch {\n return \"invalid-url\";\n }\n }\n}\n"]}
|
|
@@ -16,6 +16,7 @@ const BACKOFF_MS = [1000, 2000, 4000, 8000, 15000];
|
|
|
16
16
|
|
|
17
17
|
type EventListener = (frame: AgentWireFrame) => void;
|
|
18
18
|
type StatusListener = (status: AgentConnection) => void;
|
|
19
|
+
type SentListener = (action: AgentAction) => void;
|
|
19
20
|
|
|
20
21
|
export class AgentSocket {
|
|
21
22
|
private ws: WebSocket | null = null;
|
|
@@ -25,6 +26,7 @@ export class AgentSocket {
|
|
|
25
26
|
private queue: AgentAction[] = [];
|
|
26
27
|
private eventListeners = new Set<EventListener>();
|
|
27
28
|
private statusListeners = new Set<StatusListener>();
|
|
29
|
+
private sentListeners = new Set<SentListener>();
|
|
28
30
|
private sessionId: string | null = null;
|
|
29
31
|
/** False until the agent confirms the session (session_started) on the current socket. */
|
|
30
32
|
private sessionReady = false;
|
|
@@ -78,6 +80,11 @@ export class AgentSocket {
|
|
|
78
80
|
return () => this.statusListeners.delete(listener);
|
|
79
81
|
}
|
|
80
82
|
|
|
83
|
+
onSent(listener: SentListener) {
|
|
84
|
+
this.sentListeners.add(listener);
|
|
85
|
+
return () => this.sentListeners.delete(listener);
|
|
86
|
+
}
|
|
87
|
+
|
|
81
88
|
connect() {
|
|
82
89
|
if (this.closedByUser) return;
|
|
83
90
|
const state = this.ws?.readyState;
|
|
@@ -238,7 +245,10 @@ export class AgentSocket {
|
|
|
238
245
|
}
|
|
239
246
|
if (this.debugEmbed) console.info("[agent-embed][runtime] sending WebSocket action", { action: action.action });
|
|
240
247
|
this.ws.send(JSON.stringify({ ...action, agentToken }));
|
|
241
|
-
if (action.action === "message")
|
|
248
|
+
if (action.action === "message") {
|
|
249
|
+
this.unacknowledgedMessage = action;
|
|
250
|
+
this.sentListeners.forEach((listener) => listener(action));
|
|
251
|
+
}
|
|
242
252
|
}
|
|
243
253
|
|
|
244
254
|
private scheduleReconnect() {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { AgentContext, AgentMessageContext } from "../types";
|
|
2
|
+
import type { BeforeUserMessageSendRequest } from "../embed/agentEmbedProtocol";
|
|
3
|
+
export type BeforeUserMessageSendContribution = AgentContext | AgentMessageContext | undefined;
|
|
4
|
+
export type BeforeUserMessageSendListener = (request: BeforeUserMessageSendRequest, signal: AbortSignal) => BeforeUserMessageSendContribution | Promise<BeforeUserMessageSendContribution>;
|
|
5
|
+
/** Register an awaited in-app contributor that runs before each user message is sent. */
|
|
6
|
+
export declare function onBeforeUserMessageSend(listener: BeforeUserMessageSendListener): () => void;
|
|
7
|
+
/** Run a snapshot of current listeners so subscription changes cannot alter an in-flight send. */
|
|
8
|
+
export declare function emitBeforeUserMessageSend(request: BeforeUserMessageSendRequest, signal: AbortSignal): Promise<BeforeUserMessageSendContribution[]>;
|
|
9
|
+
//# sourceMappingURL=beforeUserMessageSend.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beforeUserMessageSend.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/client/beforeUserMessageSend.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAClE,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAEhF,MAAM,MAAM,iCAAiC,GAAG,YAAY,GAAG,mBAAmB,GAAG,SAAS,CAAC;AAC/F,MAAM,MAAM,6BAA6B,GAAG,CACxC,OAAO,EAAE,4BAA4B,EACrC,MAAM,EAAE,WAAW,KAClB,iCAAiC,GAAG,OAAO,CAAC,iCAAiC,CAAC,CAAC;AAIpF,yFAAyF;AACzF,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,6BAA6B,cAK9E;AAED,kGAAkG;AAClG,wBAAsB,yBAAyB,CAC3C,OAAO,EAAE,4BAA4B,EACrC,MAAM,EAAE,WAAW,GACpB,OAAO,CAAC,iCAAiC,EAAE,CAAC,CAE9C"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
12
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
+
function step(op) {
|
|
15
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
17
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
|
+
switch (op[0]) {
|
|
20
|
+
case 0: case 1: t = op; break;
|
|
21
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
+
default:
|
|
25
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
+
if (t[2]) _.ops.pop();
|
|
30
|
+
_.trys.pop(); continue;
|
|
31
|
+
}
|
|
32
|
+
op = body.call(thisArg, _);
|
|
33
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
var listeners = new Set();
|
|
38
|
+
/** Register an awaited in-app contributor that runs before each user message is sent. */
|
|
39
|
+
export function onBeforeUserMessageSend(listener) {
|
|
40
|
+
listeners.add(listener);
|
|
41
|
+
return function () {
|
|
42
|
+
listeners.delete(listener);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
/** Run a snapshot of current listeners so subscription changes cannot alter an in-flight send. */
|
|
46
|
+
export function emitBeforeUserMessageSend(request, signal) {
|
|
47
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
48
|
+
return __generator(this, function (_a) {
|
|
49
|
+
return [2 /*return*/, Promise.all(Array.from(listeners, function (listener) { return listener(request, signal); }))];
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=beforeUserMessageSend.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"beforeUserMessageSend.js","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/client/beforeUserMessageSend.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASA,IAAM,SAAS,GAAG,IAAI,GAAG,EAAiC,CAAC;AAE3D,yFAAyF;AACzF,MAAM,UAAU,uBAAuB,CAAC,QAAuC;IAC3E,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACxB,OAAO;QACH,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC,CAAC;AACN,CAAC;AAED,kGAAkG;AAClG,MAAM,UAAgB,yBAAyB,CAC3C,OAAqC,EACrC,MAAmB;;;YAEnB,sBAAO,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,UAAC,QAAQ,IAAK,OAAA,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC,EAAzB,CAAyB,CAAC,CAAC,EAAC;;;CACtF","sourcesContent":["import type { AgentContext, AgentMessageContext } from \"../types\";\nimport type { BeforeUserMessageSendRequest } from \"../embed/agentEmbedProtocol\";\n\nexport type BeforeUserMessageSendContribution = AgentContext | AgentMessageContext | undefined;\nexport type BeforeUserMessageSendListener = (\n request: BeforeUserMessageSendRequest,\n signal: AbortSignal,\n) => BeforeUserMessageSendContribution | Promise<BeforeUserMessageSendContribution>;\n\nconst listeners = new Set<BeforeUserMessageSendListener>();\n\n/** Register an awaited in-app contributor that runs before each user message is sent. */\nexport function onBeforeUserMessageSend(listener: BeforeUserMessageSendListener) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n}\n\n/** Run a snapshot of current listeners so subscription changes cannot alter an in-flight send. */\nexport async function emitBeforeUserMessageSend(\n request: BeforeUserMessageSendRequest,\n signal: AbortSignal,\n): Promise<BeforeUserMessageSendContribution[]> {\n return Promise.all(Array.from(listeners, (listener) => listener(request, signal)));\n}\n"]}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AgentContext, AgentMessageContext } from "../types";
|
|
2
|
+
import type { BeforeUserMessageSendRequest } from "../embed/agentEmbedProtocol";
|
|
3
|
+
|
|
4
|
+
export type BeforeUserMessageSendContribution = AgentContext | AgentMessageContext | undefined;
|
|
5
|
+
export type BeforeUserMessageSendListener = (
|
|
6
|
+
request: BeforeUserMessageSendRequest,
|
|
7
|
+
signal: AbortSignal,
|
|
8
|
+
) => BeforeUserMessageSendContribution | Promise<BeforeUserMessageSendContribution>;
|
|
9
|
+
|
|
10
|
+
const listeners = new Set<BeforeUserMessageSendListener>();
|
|
11
|
+
|
|
12
|
+
/** Register an awaited in-app contributor that runs before each user message is sent. */
|
|
13
|
+
export function onBeforeUserMessageSend(listener: BeforeUserMessageSendListener) {
|
|
14
|
+
listeners.add(listener);
|
|
15
|
+
return () => {
|
|
16
|
+
listeners.delete(listener);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/** Run a snapshot of current listeners so subscription changes cannot alter an in-flight send. */
|
|
21
|
+
export async function emitBeforeUserMessageSend(
|
|
22
|
+
request: BeforeUserMessageSendRequest,
|
|
23
|
+
signal: AbortSignal,
|
|
24
|
+
): Promise<BeforeUserMessageSendContribution[]> {
|
|
25
|
+
return Promise.all(Array.from(listeners, (listener) => listener(request, signal)));
|
|
26
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentEmbeddingPanel.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/embed/AgentEmbeddingPanel.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGjE,wBAAgB,mBAAmB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,
|
|
1
|
+
{"version":3,"file":"AgentEmbeddingPanel.d.ts","sourceRoot":"","sources":["../../../../../src/components/core/solid-agent/embed/AgentEmbeddingPanel.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAGjE,wBAAgB,mBAAmB,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,oBAAoB,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAA;CAAE,2CAoD5J"}
|
|
@@ -46,7 +46,7 @@ export function AgentEmbeddingPanel(_a) {
|
|
|
46
46
|
var _c = useState("express"), backend = _c[0], setBackend = _c[1];
|
|
47
47
|
var _d = useState(""), copied = _d[0], setCopied = _d[1];
|
|
48
48
|
var _e = useState(""), copyError = _e[0], setCopyError = _e[1];
|
|
49
|
-
var sdkUrl = "".concat(env("NEXT_PUBLIC_BACKEND_API_URL").replace(/\/$/, ""), "/api/agent-embed/sdk.js?v=
|
|
49
|
+
var sdkUrl = "".concat(env("NEXT_PUBLIC_BACKEND_API_URL").replace(/\/$/, ""), "/api/agent-embed/sdk.js?v=4");
|
|
50
50
|
var samples = embedSamples(agentId, fields, sdkUrl, hubUrl || "https://agenthub.example.com");
|
|
51
51
|
function copy(key, code) {
|
|
52
52
|
return __awaiter(this, void 0, void 0, function () {
|
|
@@ -78,10 +78,11 @@ export function AgentEmbeddingPanel(_a) {
|
|
|
78
78
|
{ value: "express", label: "Express", content: code(samples.express, "javascript") },
|
|
79
79
|
{ value: "java", label: "Java / Spring Boot", content: code(samples.java, "java") },
|
|
80
80
|
{ value: "dotnet", label: ".NET / ASP.NET Core", content: code(samples.dotnet, "csharp") },
|
|
81
|
-
], value: backend, onValueChange: setBackend, extra: copyButton(backend, samples[backend]) })] }), _jsxs("section", { className: "agent-editor__section", children: [_jsx("h2", { children: "3. Embed the chat" }), _jsxs("p", { children: ["Load the SDK from the public SDK URL shown below and mount it into a browser container. The SDK calls your app's ", _jsx("code", { children: "tokenEndpoint" }), ", passes the response to the hosted chat in memory, and manages the iframe handshake and token renewal. No SolidX npm dependency is required."] }), _jsxs("p", { children: ["Use a same-origin path such as ", _jsx("code", { children: "/api/agent-chat/token" }), " when possible. If your app API has another origin, give ", _jsx("code", { children: "tokenEndpoint" }), " its absolute URL and configure that API's CORS policy for the browser app origin."] }), _jsxs("p", { children: ["The SDK-serving SolidX API selects the hosted chat UI from its server-side ", _jsx("code", { children: "AGENT_EMBED_UI_URL" }), " setting. The consuming app does not supply an ", _jsx("code", { children: "embedUrl" }), " or choose the iframe host. Keep the SDK script URL and the configured hosted UI origin aligned to the same SolidX deployment."] }), _jsxs("p", { children: ["Pass the current page's required input values in ", _jsx("code", { children: "inputs" }), " 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 ", _jsx("code", { children: "getTokenHeaders" }), " to send the app's normal bearer or CSRF header to your app API; do not send the AgentHub API key from the browser."] }), _jsx(SolidTabGroup, { tabs: [
|
|
81
|
+
], value: backend, onValueChange: setBackend, extra: copyButton(backend, samples[backend]) })] }), _jsxs("section", { className: "agent-editor__section", children: [_jsx("h2", { children: "3. Embed the chat" }), _jsxs("p", { children: ["Load the SDK from the public SDK URL shown below and mount it into a browser container. The SDK calls your app's ", _jsx("code", { children: "tokenEndpoint" }), ", passes the response to the hosted chat in memory, and manages the iframe handshake and token renewal. No SolidX npm dependency is required."] }), _jsxs("p", { children: [_jsx("code", { children: "mode: \"popup\"" }), " is the default and provides a floating launcher. ", _jsx("code", { children: "mode: \"inline\"" }), " fills your container; your app controls its size and layout. Keep the instance mounted across client-side navigation to preserve the live chat."] }), _jsxs("p", { children: ["Use a same-origin path such as ", _jsx("code", { children: "/api/agent-chat/token" }), " when possible. If your app API has another origin, give ", _jsx("code", { children: "tokenEndpoint" }), " its absolute URL and configure that API's CORS policy for the browser app origin."] }), _jsxs("p", { children: ["The SDK-serving SolidX API selects the hosted chat UI from its server-side ", _jsx("code", { children: "AGENT_EMBED_UI_URL" }), " setting. The consuming app does not supply an ", _jsx("code", { children: "embedUrl" }), " or choose the iframe host. Keep the SDK script URL and the configured hosted UI origin aligned to the same SolidX deployment."] }), _jsxs("p", { children: ["Pass the current page's required input values in ", _jsx("code", { children: "inputs" }), " 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 ", _jsx("code", { children: "getTokenHeaders" }), " to send the app's normal bearer or CSRF header to your app API; do not send the AgentHub API key from the browser."] }), _jsx(SolidTabGroup, { tabs: [
|
|
82
82
|
{ value: "javascript", label: "JavaScript", content: code(samples.javascript, "html") },
|
|
83
|
+
{ value: "inline", label: "Inline", content: code(samples.inline, "html") },
|
|
83
84
|
{ value: "react", label: "React", content: code(samples.react, "javascript") },
|
|
84
|
-
], value: tab, onValueChange: setTab, extra: copyButton(tab, tab
|
|
85
|
+
], value: tab, onValueChange: setTab, extra: copyButton(tab, samples[tab]) })] }), _jsxs("section", { className: "agent-editor__section", children: [_jsx("h2", { children: "Inputs" }), fields.length ? _jsxs("table", { style: { width: "100%", textAlign: "left" }, children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "Variable" }), _jsx("th", { children: "Data type" }), _jsx("th", { children: "Description" }), _jsx("th", { children: "Default value" }), _jsx("th", { children: "Optional" })] }) }), _jsx("tbody", { children: fields.map(function (field) { return _jsxs("tr", { children: [_jsx("td", { children: _jsx("code", { children: field.name }) }), _jsx("td", { children: field.dataType }), _jsx("td", { children: field.description }), _jsx("td", { children: field.defaultValue == null ? "—" : typeof field.defaultValue === "string" ? field.defaultValue : JSON.stringify(field.defaultValue) }), _jsx("td", { children: field.optional ? "Yes" : "No" })] }, field.name); }) })] })
|
|
85
86
|
: _jsx("p", { children: "This agent has no inputs." }), _jsx("p", { children: "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." })] }), _jsxs("section", { className: "agent-editor__section", children: [_jsx("h2", { children: "Hosting and deployment" }), _jsxs("p", { children: ["Make ", _jsxs("code", { children: ["/embed/agent/", agentId] }), " available on the hosted UI selected by ", _jsx("code", { children: "AGENT_EMBED_UI_URL" }), ". 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."] })] }), copyError && _jsx("p", { role: "alert", children: copyError })] });
|
|
86
87
|
}
|
|
87
88
|
//# sourceMappingURL=AgentEmbeddingPanel.js.map
|