@useago/sdk 1.0.1 → 1.0.2
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/CHANGELOG.md +44 -0
- package/README.md +1 -1
- package/dist/AgoClient-_fig8FoN.cjs +6 -0
- package/dist/{AgoClient-CZYNL25R.js → AgoClient-bQozE6-A.js} +172 -141
- package/dist/angular.cjs +1 -1
- package/dist/angular.d.cts +42 -1
- package/dist/angular.d.ts +42 -1
- package/dist/angular.js +1 -1
- package/dist/{createConversationSession-Bmqj2rSS.js → createConversationSession-BbK3ou1k.js} +1 -1
- package/dist/{createConversationSession-BLZvXMmM.cjs → createConversationSession-DJUFgOXy.cjs} +1 -1
- package/dist/{createFormCollector-Ca8wRrxc.cjs → createFormCollector-CdQjGAl_.cjs} +1 -1
- package/dist/{createFormCollector-Bk0DRhUf.js → createFormCollector-D-TpSd9x.js} +1 -1
- package/dist/devtools.d.cts +42 -1
- package/dist/devtools.d.ts +42 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +79 -4
- package/dist/index.d.ts +79 -4
- package/dist/index.js +60 -59
- package/dist/react.cjs +19 -19
- package/dist/react.d.cts +51 -7
- package/dist/react.d.ts +51 -7
- package/dist/react.js +1268 -1275
- package/dist/testing.d.cts +42 -1
- package/dist/testing.d.ts +42 -1
- package/dist/vue.cjs +1 -1
- package/dist/vue.d.cts +42 -1
- package/dist/vue.d.ts +42 -1
- package/dist/vue.js +1 -1
- package/dist/widget.cjs +4 -4
- package/dist/widget.d.cts +42 -1
- package/dist/widget.d.ts +42 -1
- package/dist/widget.js +194 -201
- package/package.json +2 -2
- package/dist/AgoClient-0x2Du_62.cjs +0 -6
package/dist/testing.d.cts
CHANGED
|
@@ -16,12 +16,26 @@ declare class AgoClient {
|
|
|
16
16
|
private contextRegistry;
|
|
17
17
|
private eventEmitter;
|
|
18
18
|
private config;
|
|
19
|
+
/** Conversations already warned about an empty reply (one warning each). */
|
|
20
|
+
private warnedEmptyConversations;
|
|
19
21
|
constructor(config: AgoConfig);
|
|
20
22
|
/**
|
|
21
23
|
* Send a message and receive a streaming response
|
|
22
24
|
*/
|
|
23
25
|
sendMessage(content: string, options?: SendMessageOptions): Promise<AgoMessage>;
|
|
24
26
|
private processSSEResponse;
|
|
27
|
+
/**
|
|
28
|
+
* Detect a reply that completed as DONE with no content and no activity —
|
|
29
|
+
* today's backend answers an unknown `agent` slug with an empty 200, which
|
|
30
|
+
* otherwise fails silently. Emits `message:empty` (always) and warns on the
|
|
31
|
+
* console once per conversation (unless `warnOnEmptyReply: false`).
|
|
32
|
+
*
|
|
33
|
+
* Deferred with setTimeout(0) so both land AFTER `sendMessage` resolves:
|
|
34
|
+
* `await client.sendMessage(...)` followed by `client.waitFor("message:empty")`
|
|
35
|
+
* must not race. TEMPORARY heuristic: remove once the backend returns an
|
|
36
|
+
* explicit error for unknown agents (see TODOS.md, backend issue).
|
|
37
|
+
*/
|
|
38
|
+
private maybeFlagEmptyReply;
|
|
25
39
|
private handleClientFunctionInvocation;
|
|
26
40
|
/**
|
|
27
41
|
* Get list of conversations
|
|
@@ -194,6 +208,11 @@ declare class AgoClient {
|
|
|
194
208
|
}): Promise<AgoClientEvents[K]>;
|
|
195
209
|
/**
|
|
196
210
|
* Update client configuration
|
|
211
|
+
*
|
|
212
|
+
* Validates the MERGED config before committing: omitting a key (or passing
|
|
213
|
+
* it as `undefined`, common with spread-built partials) keeps the current
|
|
214
|
+
* value; an explicit empty/non-string `baseUrl` throws `config_missing_base_url`
|
|
215
|
+
* and leaves the client unchanged (no half-updated state).
|
|
197
216
|
*/
|
|
198
217
|
updateConfig(config: Partial<AgoConfig>): void;
|
|
199
218
|
/**
|
|
@@ -229,8 +248,23 @@ declare interface AgoClientEvents {
|
|
|
229
248
|
*/
|
|
230
249
|
"message:answer-complete": AgoMessage;
|
|
231
250
|
"message:complete": AgoMessage;
|
|
251
|
+
/**
|
|
252
|
+
* A reply finished as `DONE` with empty content and no tool calls, client
|
|
253
|
+
* functions, or follow-up replies — usually an unknown `agent` slug (the
|
|
254
|
+
* backend currently answers those with an empty 200). Fires after
|
|
255
|
+
* `message:complete` AND after `sendMessage` resolves, so subscribing right
|
|
256
|
+
* after `await sendMessage(...)` still catches it. `messageId` and
|
|
257
|
+
* `conversationId` are empty strings when the stream completed without any
|
|
258
|
+
* message data at all (e.g. a proxy stripped the SSE stream).
|
|
259
|
+
*/
|
|
260
|
+
"message:empty": {
|
|
261
|
+
conversationId: string;
|
|
262
|
+
messageId: string;
|
|
263
|
+
};
|
|
232
264
|
"message:error": {
|
|
233
265
|
error: string;
|
|
266
|
+
/** Stable error code (see configuration.md#error-codes) when the failure was an AgoError. */
|
|
267
|
+
code?: string;
|
|
234
268
|
conversationId?: string;
|
|
235
269
|
messageId?: string;
|
|
236
270
|
};
|
|
@@ -259,7 +293,7 @@ declare interface AgoClientEvents {
|
|
|
259
293
|
declare interface AgoConfig {
|
|
260
294
|
/** API base URL (e.g., https://YOUR-DOMAIN.useago.com) */
|
|
261
295
|
baseUrl: string;
|
|
262
|
-
/**
|
|
296
|
+
/** Per-visitor anonymous ID (X-User-Anon-Id header). Auto-generated if not provided. */
|
|
263
297
|
widgetId?: string;
|
|
264
298
|
/** Default agent (id or slug) for new conversations. Shorthand for `defaultAgentId`. */
|
|
265
299
|
agent?: string;
|
|
@@ -273,6 +307,13 @@ declare interface AgoConfig {
|
|
|
273
307
|
userJwt?: string;
|
|
274
308
|
/** Enable debug logging */
|
|
275
309
|
debug?: boolean;
|
|
310
|
+
/**
|
|
311
|
+
* Warn on the console when a reply completes with empty content and no tool
|
|
312
|
+
* calls (the usual cause is an unknown `agent` slug, which the backend
|
|
313
|
+
* currently answers with an empty 200). Default `true`. The `message:empty`
|
|
314
|
+
* event fires regardless of this setting.
|
|
315
|
+
*/
|
|
316
|
+
warnOnEmptyReply?: boolean;
|
|
276
317
|
}
|
|
277
318
|
|
|
278
319
|
declare type AgoEventHandler<K extends AgoEventName> = (data: AgoClientEvents[K]) => void;
|
package/dist/testing.d.ts
CHANGED
|
@@ -16,12 +16,26 @@ declare class AgoClient {
|
|
|
16
16
|
private contextRegistry;
|
|
17
17
|
private eventEmitter;
|
|
18
18
|
private config;
|
|
19
|
+
/** Conversations already warned about an empty reply (one warning each). */
|
|
20
|
+
private warnedEmptyConversations;
|
|
19
21
|
constructor(config: AgoConfig);
|
|
20
22
|
/**
|
|
21
23
|
* Send a message and receive a streaming response
|
|
22
24
|
*/
|
|
23
25
|
sendMessage(content: string, options?: SendMessageOptions): Promise<AgoMessage>;
|
|
24
26
|
private processSSEResponse;
|
|
27
|
+
/**
|
|
28
|
+
* Detect a reply that completed as DONE with no content and no activity —
|
|
29
|
+
* today's backend answers an unknown `agent` slug with an empty 200, which
|
|
30
|
+
* otherwise fails silently. Emits `message:empty` (always) and warns on the
|
|
31
|
+
* console once per conversation (unless `warnOnEmptyReply: false`).
|
|
32
|
+
*
|
|
33
|
+
* Deferred with setTimeout(0) so both land AFTER `sendMessage` resolves:
|
|
34
|
+
* `await client.sendMessage(...)` followed by `client.waitFor("message:empty")`
|
|
35
|
+
* must not race. TEMPORARY heuristic: remove once the backend returns an
|
|
36
|
+
* explicit error for unknown agents (see TODOS.md, backend issue).
|
|
37
|
+
*/
|
|
38
|
+
private maybeFlagEmptyReply;
|
|
25
39
|
private handleClientFunctionInvocation;
|
|
26
40
|
/**
|
|
27
41
|
* Get list of conversations
|
|
@@ -194,6 +208,11 @@ declare class AgoClient {
|
|
|
194
208
|
}): Promise<AgoClientEvents[K]>;
|
|
195
209
|
/**
|
|
196
210
|
* Update client configuration
|
|
211
|
+
*
|
|
212
|
+
* Validates the MERGED config before committing: omitting a key (or passing
|
|
213
|
+
* it as `undefined`, common with spread-built partials) keeps the current
|
|
214
|
+
* value; an explicit empty/non-string `baseUrl` throws `config_missing_base_url`
|
|
215
|
+
* and leaves the client unchanged (no half-updated state).
|
|
197
216
|
*/
|
|
198
217
|
updateConfig(config: Partial<AgoConfig>): void;
|
|
199
218
|
/**
|
|
@@ -229,8 +248,23 @@ declare interface AgoClientEvents {
|
|
|
229
248
|
*/
|
|
230
249
|
"message:answer-complete": AgoMessage;
|
|
231
250
|
"message:complete": AgoMessage;
|
|
251
|
+
/**
|
|
252
|
+
* A reply finished as `DONE` with empty content and no tool calls, client
|
|
253
|
+
* functions, or follow-up replies — usually an unknown `agent` slug (the
|
|
254
|
+
* backend currently answers those with an empty 200). Fires after
|
|
255
|
+
* `message:complete` AND after `sendMessage` resolves, so subscribing right
|
|
256
|
+
* after `await sendMessage(...)` still catches it. `messageId` and
|
|
257
|
+
* `conversationId` are empty strings when the stream completed without any
|
|
258
|
+
* message data at all (e.g. a proxy stripped the SSE stream).
|
|
259
|
+
*/
|
|
260
|
+
"message:empty": {
|
|
261
|
+
conversationId: string;
|
|
262
|
+
messageId: string;
|
|
263
|
+
};
|
|
232
264
|
"message:error": {
|
|
233
265
|
error: string;
|
|
266
|
+
/** Stable error code (see configuration.md#error-codes) when the failure was an AgoError. */
|
|
267
|
+
code?: string;
|
|
234
268
|
conversationId?: string;
|
|
235
269
|
messageId?: string;
|
|
236
270
|
};
|
|
@@ -259,7 +293,7 @@ declare interface AgoClientEvents {
|
|
|
259
293
|
declare interface AgoConfig {
|
|
260
294
|
/** API base URL (e.g., https://YOUR-DOMAIN.useago.com) */
|
|
261
295
|
baseUrl: string;
|
|
262
|
-
/**
|
|
296
|
+
/** Per-visitor anonymous ID (X-User-Anon-Id header). Auto-generated if not provided. */
|
|
263
297
|
widgetId?: string;
|
|
264
298
|
/** Default agent (id or slug) for new conversations. Shorthand for `defaultAgentId`. */
|
|
265
299
|
agent?: string;
|
|
@@ -273,6 +307,13 @@ declare interface AgoConfig {
|
|
|
273
307
|
userJwt?: string;
|
|
274
308
|
/** Enable debug logging */
|
|
275
309
|
debug?: boolean;
|
|
310
|
+
/**
|
|
311
|
+
* Warn on the console when a reply completes with empty content and no tool
|
|
312
|
+
* calls (the usual cause is an unknown `agent` slug, which the backend
|
|
313
|
+
* currently answers with an empty 200). Default `true`. The `message:empty`
|
|
314
|
+
* event fires regardless of this setting.
|
|
315
|
+
*/
|
|
316
|
+
warnOnEmptyReply?: boolean;
|
|
276
317
|
}
|
|
277
318
|
|
|
278
319
|
declare type AgoEventHandler<K extends AgoEventName> = (data: AgoClientEvents[K]) => void;
|
package/dist/vue.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const P=require("./rolldown-runtime-CaekUdDJ.cjs"),p=require("./AgoClient-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const P=require("./rolldown-runtime-CaekUdDJ.cjs"),p=require("./AgoClient-_fig8FoN.cjs");let t=require("vue");var I=Symbol("ago-client"),y={install(o,n){const e=new p.AgoClient(n);o.provide(I,e)}};function g(o){if(o)return new p.AgoClient(o);const n=(0,t.inject)(I);if(!n)throw new Error("useAgo(): no AgoClient found. Either pass config or install AgoPlugin.");return n}function E(o={}){const n=o.client??g(),e=(0,t.ref)([]),s=(0,t.ref)(o.conversationId),i=(0,t.ref)(!1),r=(0,t.ref)(null),c=a=>{s.value||(s.value=a.conversationId)},f=a=>{const u=e.value.findIndex(v=>v.id===a.messageId);u>=0&&(e.value[u]={...e.value[u],content:e.value[u].content+a.content})},m=a=>{const u=e.value.findIndex(v=>v.id===a.id);u>=0?e.value[u]=a:e.value.push(a),i.value=!1},C=a=>{r.value=new Error(a.error),i.value=!1};(0,t.onMounted)(()=>{n.on("message:start",c),n.on("message:chunk",f),n.on("message:complete",m),n.on("message:error",C)}),(0,t.onUnmounted)(()=>{n.off("message:start",c),n.off("message:chunk",f),n.off("message:complete",m),n.off("message:error",C)});async function d(a,u){i.value=!0,r.value=null;const v={id:`temp-${Date.now()}`,conversationId:s.value||"",content:a,role:"user",status:"DONE",createdAt:new Date},L={id:`temp-assistant-${Date.now()}`,conversationId:s.value||"",content:"",role:"assistant",status:"IN_PROGRESS",createdAt:new Date};e.value.push(v,L);try{const l=await n.sendMessage(a,{conversationId:s.value,files:u});l.conversationId&&!s.value&&(s.value=l.conversationId),e.value=e.value.filter(w=>!w.id.startsWith("temp-"));const A={...v,id:v.id.replace("temp-","user-"),conversationId:l.conversationId};return e.value.some(w=>w.id===l.id)?e.value.push(A):e.value.push(A,l),l}catch(l){return r.value=l instanceof Error?l:new Error("Failed to send"),i.value=!1,e.value=e.value.filter(A=>!A.id.startsWith("temp-")),null}}function h(){e.value=[],s.value=void 0,r.value=null}return{messages:e,isLoading:i,error:r,conversationId:s,sendMessage:d,clearMessages:h}}function M(o={}){const n=o.client??g(),e=o.autoLoad??!0,s=(0,t.ref)([]),i=(0,t.ref)(null),r=(0,t.ref)(!1),c=(0,t.ref)(null);async function f(){r.value=!0,c.value=null;try{s.value=await n.getConversations()}catch(d){c.value=d instanceof Error?d:new Error("Failed to load conversations")}finally{r.value=!1}}async function m(d){r.value=!0,c.value=null;try{i.value=await n.getConversation(d)}catch(h){c.value=h instanceof Error?h:new Error("Failed to load conversation")}finally{r.value=!1}}function C(){i.value=null}return(0,t.onMounted)(()=>{e&&f()}),{conversations:s,currentConversation:i,isLoading:r,error:c,selectConversation:m,startNewConversation:C,refreshConversations:f}}function N(o={}){const n=E({client:o.client,conversationId:o.conversationId}),e=M({client:o.client,autoLoad:o.autoLoad}),s=(0,t.computed)(()=>n.error.value||e.error.value);return{messages:n.messages,isLoading:n.isLoading,error:s,sendMessage:n.sendMessage,clearMessages:n.clearMessages,conversationId:n.conversationId,conversations:e.conversations,currentConversation:e.currentConversation,isConversationsLoading:e.isLoading,selectConversation:e.selectConversation,startNewConversation:e.startNewConversation,refreshConversations:e.refreshConversations}}function F(o,n){const e=g();(0,t.onMounted)(()=>{e.registerFunction(o,n.handler,{description:n.description,parameters:n.parameters})}),(0,t.onUnmounted)(()=>{e.unregisterFunction(o)})}function S(o,n){const e=g();(0,t.onMounted)(()=>{e.registerNavigationFunction(o,n)}),(0,t.onUnmounted)(()=>{e.unregisterFunction("navigateToPage")})}function _(o,n){const e=g();(0,t.onMounted)(()=>{e.on(o,n)}),(0,t.onUnmounted)(()=>{e.off(o,n)})}function D(o){const n=(0,t.shallowRef)(o.get());return(0,t.onScopeDispose)(o.subscribe(e=>{n.value=e})),n}exports.AGO_CLIENT_KEY=I;exports.AgoPlugin=y;exports.useAgo=g;exports.useAgoEvents=_;exports.useAgoFunction=F;exports.useAgoNavigation=S;exports.useAgoStore=D;exports.useChat=N;exports.useConversation=M;exports.useMessages=E;
|
package/dist/vue.d.cts
CHANGED
|
@@ -24,12 +24,26 @@ declare class AgoClient {
|
|
|
24
24
|
private contextRegistry;
|
|
25
25
|
private eventEmitter;
|
|
26
26
|
private config;
|
|
27
|
+
/** Conversations already warned about an empty reply (one warning each). */
|
|
28
|
+
private warnedEmptyConversations;
|
|
27
29
|
constructor(config: AgoConfig);
|
|
28
30
|
/**
|
|
29
31
|
* Send a message and receive a streaming response
|
|
30
32
|
*/
|
|
31
33
|
sendMessage(content: string, options?: SendMessageOptions): Promise<AgoMessage>;
|
|
32
34
|
private processSSEResponse;
|
|
35
|
+
/**
|
|
36
|
+
* Detect a reply that completed as DONE with no content and no activity —
|
|
37
|
+
* today's backend answers an unknown `agent` slug with an empty 200, which
|
|
38
|
+
* otherwise fails silently. Emits `message:empty` (always) and warns on the
|
|
39
|
+
* console once per conversation (unless `warnOnEmptyReply: false`).
|
|
40
|
+
*
|
|
41
|
+
* Deferred with setTimeout(0) so both land AFTER `sendMessage` resolves:
|
|
42
|
+
* `await client.sendMessage(...)` followed by `client.waitFor("message:empty")`
|
|
43
|
+
* must not race. TEMPORARY heuristic: remove once the backend returns an
|
|
44
|
+
* explicit error for unknown agents (see TODOS.md, backend issue).
|
|
45
|
+
*/
|
|
46
|
+
private maybeFlagEmptyReply;
|
|
33
47
|
private handleClientFunctionInvocation;
|
|
34
48
|
/**
|
|
35
49
|
* Get list of conversations
|
|
@@ -202,6 +216,11 @@ declare class AgoClient {
|
|
|
202
216
|
}): Promise<AgoClientEvents[K]>;
|
|
203
217
|
/**
|
|
204
218
|
* Update client configuration
|
|
219
|
+
*
|
|
220
|
+
* Validates the MERGED config before committing: omitting a key (or passing
|
|
221
|
+
* it as `undefined`, common with spread-built partials) keeps the current
|
|
222
|
+
* value; an explicit empty/non-string `baseUrl` throws `config_missing_base_url`
|
|
223
|
+
* and leaves the client unchanged (no half-updated state).
|
|
205
224
|
*/
|
|
206
225
|
updateConfig(config: Partial<AgoConfig>): void;
|
|
207
226
|
/**
|
|
@@ -237,8 +256,23 @@ declare interface AgoClientEvents {
|
|
|
237
256
|
*/
|
|
238
257
|
"message:answer-complete": AgoMessage;
|
|
239
258
|
"message:complete": AgoMessage;
|
|
259
|
+
/**
|
|
260
|
+
* A reply finished as `DONE` with empty content and no tool calls, client
|
|
261
|
+
* functions, or follow-up replies — usually an unknown `agent` slug (the
|
|
262
|
+
* backend currently answers those with an empty 200). Fires after
|
|
263
|
+
* `message:complete` AND after `sendMessage` resolves, so subscribing right
|
|
264
|
+
* after `await sendMessage(...)` still catches it. `messageId` and
|
|
265
|
+
* `conversationId` are empty strings when the stream completed without any
|
|
266
|
+
* message data at all (e.g. a proxy stripped the SSE stream).
|
|
267
|
+
*/
|
|
268
|
+
"message:empty": {
|
|
269
|
+
conversationId: string;
|
|
270
|
+
messageId: string;
|
|
271
|
+
};
|
|
240
272
|
"message:error": {
|
|
241
273
|
error: string;
|
|
274
|
+
/** Stable error code (see configuration.md#error-codes) when the failure was an AgoError. */
|
|
275
|
+
code?: string;
|
|
242
276
|
conversationId?: string;
|
|
243
277
|
messageId?: string;
|
|
244
278
|
};
|
|
@@ -267,7 +301,7 @@ declare interface AgoClientEvents {
|
|
|
267
301
|
export declare interface AgoConfig {
|
|
268
302
|
/** API base URL (e.g., https://YOUR-DOMAIN.useago.com) */
|
|
269
303
|
baseUrl: string;
|
|
270
|
-
/**
|
|
304
|
+
/** Per-visitor anonymous ID (X-User-Anon-Id header). Auto-generated if not provided. */
|
|
271
305
|
widgetId?: string;
|
|
272
306
|
/** Default agent (id or slug) for new conversations. Shorthand for `defaultAgentId`. */
|
|
273
307
|
agent?: string;
|
|
@@ -281,6 +315,13 @@ export declare interface AgoConfig {
|
|
|
281
315
|
userJwt?: string;
|
|
282
316
|
/** Enable debug logging */
|
|
283
317
|
debug?: boolean;
|
|
318
|
+
/**
|
|
319
|
+
* Warn on the console when a reply completes with empty content and no tool
|
|
320
|
+
* calls (the usual cause is an unknown `agent` slug, which the backend
|
|
321
|
+
* currently answers with an empty 200). Default `true`. The `message:empty`
|
|
322
|
+
* event fires regardless of this setting.
|
|
323
|
+
*/
|
|
324
|
+
warnOnEmptyReply?: boolean;
|
|
284
325
|
}
|
|
285
326
|
|
|
286
327
|
declare type AgoEventHandler<K extends AgoEventName> = (data: AgoClientEvents[K]) => void;
|
package/dist/vue.d.ts
CHANGED
|
@@ -24,12 +24,26 @@ declare class AgoClient {
|
|
|
24
24
|
private contextRegistry;
|
|
25
25
|
private eventEmitter;
|
|
26
26
|
private config;
|
|
27
|
+
/** Conversations already warned about an empty reply (one warning each). */
|
|
28
|
+
private warnedEmptyConversations;
|
|
27
29
|
constructor(config: AgoConfig);
|
|
28
30
|
/**
|
|
29
31
|
* Send a message and receive a streaming response
|
|
30
32
|
*/
|
|
31
33
|
sendMessage(content: string, options?: SendMessageOptions): Promise<AgoMessage>;
|
|
32
34
|
private processSSEResponse;
|
|
35
|
+
/**
|
|
36
|
+
* Detect a reply that completed as DONE with no content and no activity —
|
|
37
|
+
* today's backend answers an unknown `agent` slug with an empty 200, which
|
|
38
|
+
* otherwise fails silently. Emits `message:empty` (always) and warns on the
|
|
39
|
+
* console once per conversation (unless `warnOnEmptyReply: false`).
|
|
40
|
+
*
|
|
41
|
+
* Deferred with setTimeout(0) so both land AFTER `sendMessage` resolves:
|
|
42
|
+
* `await client.sendMessage(...)` followed by `client.waitFor("message:empty")`
|
|
43
|
+
* must not race. TEMPORARY heuristic: remove once the backend returns an
|
|
44
|
+
* explicit error for unknown agents (see TODOS.md, backend issue).
|
|
45
|
+
*/
|
|
46
|
+
private maybeFlagEmptyReply;
|
|
33
47
|
private handleClientFunctionInvocation;
|
|
34
48
|
/**
|
|
35
49
|
* Get list of conversations
|
|
@@ -202,6 +216,11 @@ declare class AgoClient {
|
|
|
202
216
|
}): Promise<AgoClientEvents[K]>;
|
|
203
217
|
/**
|
|
204
218
|
* Update client configuration
|
|
219
|
+
*
|
|
220
|
+
* Validates the MERGED config before committing: omitting a key (or passing
|
|
221
|
+
* it as `undefined`, common with spread-built partials) keeps the current
|
|
222
|
+
* value; an explicit empty/non-string `baseUrl` throws `config_missing_base_url`
|
|
223
|
+
* and leaves the client unchanged (no half-updated state).
|
|
205
224
|
*/
|
|
206
225
|
updateConfig(config: Partial<AgoConfig>): void;
|
|
207
226
|
/**
|
|
@@ -237,8 +256,23 @@ declare interface AgoClientEvents {
|
|
|
237
256
|
*/
|
|
238
257
|
"message:answer-complete": AgoMessage;
|
|
239
258
|
"message:complete": AgoMessage;
|
|
259
|
+
/**
|
|
260
|
+
* A reply finished as `DONE` with empty content and no tool calls, client
|
|
261
|
+
* functions, or follow-up replies — usually an unknown `agent` slug (the
|
|
262
|
+
* backend currently answers those with an empty 200). Fires after
|
|
263
|
+
* `message:complete` AND after `sendMessage` resolves, so subscribing right
|
|
264
|
+
* after `await sendMessage(...)` still catches it. `messageId` and
|
|
265
|
+
* `conversationId` are empty strings when the stream completed without any
|
|
266
|
+
* message data at all (e.g. a proxy stripped the SSE stream).
|
|
267
|
+
*/
|
|
268
|
+
"message:empty": {
|
|
269
|
+
conversationId: string;
|
|
270
|
+
messageId: string;
|
|
271
|
+
};
|
|
240
272
|
"message:error": {
|
|
241
273
|
error: string;
|
|
274
|
+
/** Stable error code (see configuration.md#error-codes) when the failure was an AgoError. */
|
|
275
|
+
code?: string;
|
|
242
276
|
conversationId?: string;
|
|
243
277
|
messageId?: string;
|
|
244
278
|
};
|
|
@@ -267,7 +301,7 @@ declare interface AgoClientEvents {
|
|
|
267
301
|
export declare interface AgoConfig {
|
|
268
302
|
/** API base URL (e.g., https://YOUR-DOMAIN.useago.com) */
|
|
269
303
|
baseUrl: string;
|
|
270
|
-
/**
|
|
304
|
+
/** Per-visitor anonymous ID (X-User-Anon-Id header). Auto-generated if not provided. */
|
|
271
305
|
widgetId?: string;
|
|
272
306
|
/** Default agent (id or slug) for new conversations. Shorthand for `defaultAgentId`. */
|
|
273
307
|
agent?: string;
|
|
@@ -281,6 +315,13 @@ export declare interface AgoConfig {
|
|
|
281
315
|
userJwt?: string;
|
|
282
316
|
/** Enable debug logging */
|
|
283
317
|
debug?: boolean;
|
|
318
|
+
/**
|
|
319
|
+
* Warn on the console when a reply completes with empty content and no tool
|
|
320
|
+
* calls (the usual cause is an unknown `agent` slug, which the backend
|
|
321
|
+
* currently answers with an empty 200). Default `true`. The `message:empty`
|
|
322
|
+
* event fires regardless of this setting.
|
|
323
|
+
*/
|
|
324
|
+
warnOnEmptyReply?: boolean;
|
|
284
325
|
}
|
|
285
326
|
|
|
286
327
|
declare type AgoEventHandler<K extends AgoEventName> = (data: AgoClientEvents[K]) => void;
|
package/dist/vue.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as A } from "./AgoClient-
|
|
1
|
+
import { t as A } from "./AgoClient-bQozE6-A.js";
|
|
2
2
|
import { computed as y, inject as F, onMounted as g, onScopeDispose as N, onUnmounted as I, ref as c, shallowRef as D } from "vue";
|
|
3
3
|
var L = /* @__PURE__ */ Symbol("ago-client"), b = { install(t, n) {
|
|
4
4
|
const e = new A(n);
|
package/dist/widget.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ke=require("./AgoClient-_fig8FoN.cjs"),$e=require("./createFormCollector-CdQjGAl_.cjs"),Ke=require("./createConversationSession-DJUFgOXy.cjs");var Ve={"&":"&","<":"<",">":">",'"':""","'":"'"};function U(o){return o.replace(/[&<>"']/g,n=>Ve[n])}function Ae(o){const n=o.trim();return/^(https?:|mailto:|tel:|#|\/|\.\/|\.\.\/)/i.test(n)||!/^[a-z][a-z0-9+.-]*:/i.test(n)?n:null}var Te='"IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace',Q="";function M(o){const n=[],r=u=>(n.push(u),`${Q}${n.length-1}${Q}`);let t=o;return t=t.replace(/`([^`]+)`/g,(u,i)=>r(`<code style="background:#f0f2f5;padding:2px 5px;border-radius:4px;font-size:13px;font-family:${Te}">${U(i)}</code>`)),t=t.replace(/!\[([^\]]*)\]\(([^)\s]+)\)/g,(u,i,f)=>{const s=Ae(f);return s?r(`<img alt="${U(i)}" src="${U(s)}" style="max-width:100%;border-radius:8px;margin:4px 0" />`):u}),t=t.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g,(u,i,f)=>{const s=Ae(f);return s?r(`<a href="${U(s)}" target="_blank" rel="noopener noreferrer" style="color:#1b5fc4;text-decoration:underline">${M(i)}</a>`):u}),t=U(t),t=t.replace(/\*\*([^*]+?)\*\*/g,"<strong>$1</strong>").replace(/__([^_]+?)__/g,"<strong>$1</strong>").replace(/~~([^~]+?)~~/g,"<del>$1</del>").replace(/(^|[^*])\*(?!\s)([^*]+?)\*/g,"$1<em>$2</em>").replace(/(^|[^\w_])_(?!\s)([^_]+?)_/g,"$1<em>$2</em>"),t=t.replace(new RegExp(`${Q}(\\d+)${Q}`,"g"),(u,i)=>n[Number(i)]),t}function _(o,n,r){const t=document.createElement(o);return Object.assign(t.style,n),r!==void 0&&(t.innerHTML=r),t}var De=/^ {0,3}([-*_])( *\1){2,} *$/,Me=/^ {0,3}(#{1,6})\s+(.*?)\s*#*\s*$/,Be=/^ {0,3}(```+|~~~+)/,Z=/^ {0,3}>\s?/,P=/^(\s*)([-*+]|\d+[.)])\s+(.*)$/,Qe=["20px","18px","16px","15px","14px","13px"],fe=o=>o.match(/^\s*/)?.[0].length??0;function Ye(o){return o.trim()===""||De.test(o)||Me.test(o)||Be.test(o)||Z.test(o)||P.test(o)}function ze(o){const n=o[0].match(P),r=n[1].length,t=/\d/.test(n[2]),u=_(t?"ol":"ul",{margin:"0 0 8px 0",paddingLeft:"20px",listStyleType:t?"decimal":"disc",listStylePosition:"outside"});let i=0;for(;i<o.length;){const f=o[i].match(P),s=[];for(i++;i<o.length&&fe(o[i])>r;)s.push(o[i]),i++;const p=_("li",{display:"list-item",margin:"2px 0",lineHeight:"1.6"}),c=f[3].match(/^\[([ xX])\]\s+(.*)$/);c?(p.style.listStyleType="none",p.style.marginLeft="-20px",p.innerHTML=`<span style="margin-right:6px">${c[1].toLowerCase()==="x"?"☑":"☐"}</span>${M(c[2])}`):p.innerHTML=M(f[3]),s.filter(h=>P.test(h)).length>0&&p.appendChild(ze(s.filter(h=>h.trim()!==""))),u.appendChild(p)}return u}function Ze(o){const n=s=>s.replace(/^\s*\|?/,"").replace(/\|?\s*$/,"").split("|").map(p=>p.trim()),r=_("div",{overflowX:"auto",margin:"0 0 8px 0"}),t=_("table",{borderCollapse:"collapse",width:"100%",fontSize:"13px"}),u=document.createElement("thead"),i=document.createElement("tr");for(const s of n(o[0]))i.appendChild(_("th",{border:"1px solid #dee3e8",padding:"6px 10px",textAlign:"left",backgroundColor:"#f5f7fa",fontWeight:"600"},M(s)));u.appendChild(i),t.appendChild(u);const f=document.createElement("tbody");for(const s of o.slice(2)){const p=document.createElement("tr");for(const c of n(s))p.appendChild(_("td",{border:"1px solid #dee3e8",padding:"6px 10px"},M(c)));f.appendChild(p)}return t.appendChild(f),r.appendChild(t),r}var Je=o=>!!o&&/^\s*\|?\s*:?-{1,}:?\s*(\|\s*:?-{1,}:?\s*)*\|?\s*$/.test(o);function J(o){const n=document.createDocumentFragment(),r=o.replace(/\r\n?/g,`
|
|
2
2
|
`).split(`
|
|
3
|
-
`);let t=0;for(;t<r.length;){const i=r[t];if(i.trim()===""){t++;continue}const f=i.match(Be);if(f){const c=f[1][0],
|
|
4
|
-
`)))),n.appendChild(L);continue}if(De.test(i)){n.appendChild(
|
|
5
|
-
`))),n.appendChild(m);continue}if(i.includes("|")&&Je(r[t+1])){const c=[i,r[t+1]];for(t+=2;t<r.length&&r[t].includes("|")&&r[t].trim();)c.push(r[t]),t++;n.appendChild(Ze(c));continue}if(P.test(i)){const c=[],m=ce(i);for(;t<r.length&&r[t].trim()!=="";)if(P.test(r[t])||ce(r[t])>m)c.push(r[t]),t++;else break;n.appendChild(ze(c));continue}const p=[i];for(t++;t<r.length&&!Ye(r[t]);)p.push(r[t]),t++;n.appendChild(R("p",{margin:"0 0 8px 0",lineHeight:"1.6"},p.map(c=>M(c)).join("<br>")))}const u=n.lastElementChild;return u&&(u.style.marginBottom="0"),n}var pe='var(--ago-font, "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif)',Ae={font:"--ago-font",radius:"--ago-radius",messageRadius:"--ago-message-radius",brand:"--ago-brand-color",brandText:"--ago-brand-text-color",headerBg:"--ago-header-background",headerText:"--ago-header-text-color",panelBg:"--ago-panel-background",messagesBg:"--ago-messages-background",text:"--ago-text-color",mutedText:"--ago-muted-text-color",border:"--ago-border-color",accent:"--ago-accent-color"},fe="var(--ago-brand-color, #03182f)",ue="var(--ago-brand-text-color, #fff)",et="var(--ago-header-background, var(--ago-brand-color, #03182f))",Ne="var(--ago-header-text-color, #e8f0fe)",j="var(--ago-panel-background, #fff)",tt="var(--ago-messages-background, #fbfbfb)",Y="var(--ago-text-color, #30373e)",nt="var(--ago-muted-text-color, #6b6d6f)",$="var(--ago-border-color, #dee3e8)",de="var(--ago-accent-color, #1b5fc4)",ot="var(--ago-radius, 16px)",Le="var(--ago-message-radius, 16px)";function rt(o,n){if(n)for(const r of Object.keys(Ae)){const t=n[r];t!=null&&o.style.setProperty(Ae[r],t)}}function y(o,n){Object.assign(o.style,n)}function b(o={}){const n=document.createElement("div");return y(n,o),n}var Oe="ago-chat-widget-keyframes";function at(){if(typeof document>"u"||document.getElementById(Oe))return;const o=document.createElement("style");o.id=Oe,o.textContent="@keyframes ago-pulse { 0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); } 40% { opacity: 1; transform: scale(1); } }",document.head.appendChild(o)}function it(o){const n=typeof o=="string"?document.querySelector(o):o;if(!n)throw new Error(`mountChatWidget: target "${String(o)}" not found.`);return n}function st(o,n){const{title:r="Chat",welcomeMessage:t="Hello! How can I help you today?",placeholder:u="Type a message...",allowFiles:i=!1,height:f=500,placement:s="inline",width:p=400,defaultOpen:c=!1,logoUrl:m,showAgentName:L=!1,theme:x,loadThreads:_=!1,forms:q,onFollowUpClick:B,onMessageSent:O,onMessageReceived:he}=n;if(!n.client&&!n.config?.baseUrl)throw new Error("mountChatWidget requires either `client` or `config` (with a baseUrl).");const h=n.client??new Xe.AgoClient(n.config),me=it(o),z=s==="left"||s==="right",He=z&&(n.launcher??!0);let H=z?c:!0;const J=n.persistConversation,X=J?Ke.createConversationSession(J===!0?{}:J):void 0;let k=n.conversationId??X?.getLastActiveThread()??void 0,d=[],A=!1,W=null;const K=[],U=b({display:"flex",flexDirection:"column",height:z?"100%":typeof f=="number"?`${f}px`:f,border:`1px solid ${$}`,borderRadius:ot,overflow:"hidden",backgroundColor:j,fontFamily:pe,textAlign:"left",boxShadow:"rgba(15, 15, 15, 0.08) 0px 2px 16px 0px"});U.className="ago-chat-widget",rt(U,x);const G=b({padding:"14px 16px",borderBottom:`1px solid ${$}`,backgroundColor:et,color:Ne,display:"flex",alignItems:"center",gap:"10px"});if(G.className="ago-chat-widget__header",m){const e=document.createElement("img");e.src=m,e.alt="Logo",y(e,{height:"24px",width:"auto"}),G.appendChild(e)}const ee=document.createElement("h3");if(ee.textContent=r,y(ee,{margin:"0",fontSize:"15px",fontWeight:"600"}),G.appendChild(ee),z){const e=document.createElement("button");e.type="button",e.className="ago-chat-widget__close",e.setAttribute("aria-label","Close"),e.textContent="×",y(e,{marginLeft:"auto",background:"transparent",border:"none",color:Ne,fontSize:"22px",lineHeight:"1",cursor:"pointer",padding:"0 2px"}),e.addEventListener("click",()=>se()),G.appendChild(e)}const N=b({flex:"1",overflow:"auto",padding:"16px",backgroundColor:tt});N.className="ago-chat-widget__messages";const{inputRow:Ue,setDisabled:Fe,focus:xe}=lt({placeholder:u,allowFiles:i,onSend:(e,a)=>{oe(e,a)}});at(),U.append(G,N,Ue);let V=U,T,E;const te=s==="left"?"left":"right";if(z&&(T=b({position:"fixed",top:"0",bottom:"0",[te]:"0",width:typeof p=="number"?`${p}px`:p,maxWidth:"100vw",display:"flex",zIndex:"2147483000",transition:"transform 0.3s ease",boxShadow:"rgba(15, 15, 15, 0.18) 0px 0px 24px 0px"}),T.className="ago-chat-widget-panel",y(U,{height:"100%",width:"100%",borderRadius:"0",border:"none",boxShadow:"none",[te==="left"?"borderRight":"borderLeft"]:`1px solid ${$}`}),T.appendChild(U),V=T),He){if(E=document.createElement("button"),E.type="button",E.className="ago-chat-widget-launcher",E.setAttribute("aria-label",`Open ${r}`),y(E,{position:"fixed",bottom:"20px",[te]:"20px",width:"56px",height:"56px",borderRadius:"50%",border:"none",backgroundColor:fe,color:ue,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",zIndex:"2147483000",boxShadow:"rgba(15, 15, 15, 0.2) 0px 4px 14px 0px",fontFamily:pe}),m){const e=document.createElement("img");e.src=m,e.alt="",y(e,{width:"26px",height:"26px",objectFit:"contain"}),E.appendChild(e)}else E.appendChild(qe());E.addEventListener("click",()=>ie())}me.appendChild(V),E&&me.appendChild(E),ae();const be=B!==!1,Ce=B===!1?void 0:B??(e=>{oe(e)});function Pe(e,a){const l=e.role==="user",S=b({display:"flex",flexDirection:"column",alignItems:l?"flex-end":"flex-start",marginBottom:"16px"});if(S.className=`ago-message ago-message--${e.role}`,!l&&L&&e.agent){const g=b({fontSize:"13px",fontWeight:"500",color:Y,marginBottom:"6px",padding:"0 4px"});g.className="ago-message__agent",g.textContent=e.agent.displayName||e.agent.name,S.appendChild(g)}if(!l&&e.sources&&e.sources.length>0){const g=b({display:"grid",gridTemplateColumns:"1fr 1fr",gap:"6px",marginBottom:"10px",width:"100%",maxWidth:"85%"});g.className="ago-message__sources",e.sources.forEach((C,w)=>{const D=C.url?document.createElement("a"):document.createElement("div");C.url&&D instanceof HTMLAnchorElement&&(D.href=C.url,D.target="_blank",D.rel="noopener noreferrer"),y(D,{display:"flex",alignItems:"center",gap:"8px",padding:"8px 10px",border:`1px solid ${$}`,borderRadius:"8px",backgroundColor:j,textDecoration:"none",color:Y,fontSize:"12px",overflow:"hidden"});const ke=b({flexShrink:"0",width:"18px",height:"18px",borderRadius:"3px",border:`1px solid ${de}`,color:de,fontSize:"11px",fontWeight:"500",display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"#f0f4ff"});ke.textContent=String(w+1);const le=b({overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});le.textContent=C.title,le.title=C.title,D.append(ke,le),g.appendChild(D)}),S.appendChild(g)}const v=b({maxWidth:l?"75%":"100%",padding:l?"10px 14px":"2px 8px",borderRadius:l?Le:"0",backgroundColor:l?fe:"transparent",color:l?ue:Y,wordBreak:"break-word",fontSize:"14px",lineHeight:"1.6"});if(v.className="ago-message__content",e.content?v.appendChild(ge(e.content)):e.status==="IN_PROGRESS"&&v.appendChild(_e()),S.appendChild(v),a&&A&&e.role==="assistant"&&e.status==="DONE"&&!(e.followUpReplies&&e.followUpReplies.length>0)){const g=b({marginTop:"10px",paddingLeft:"8px"});g.className="ago-message__followups-loading",g.appendChild(_e()),S.appendChild(g)}if(a&&e.followUpReplies&&e.followUpReplies.length>0){const g=b({display:"flex",flexWrap:"wrap",gap:"8px",marginTop:"10px"});g.className="ago-message__followups";for(const C of e.followUpReplies){const w=document.createElement("button");w.type="button",w.className="ago-message__followup-btn",w.textContent=C,w.disabled=!be,y(w,{padding:"6px 14px",fontSize:"13px",borderRadius:Le,border:`1px solid ${$}`,backgroundColor:j,color:Y,cursor:be?"pointer":"default",transition:"border-color 0.15s"}),Ce&&w.addEventListener("click",()=>Ce(C)),w.addEventListener("mouseenter",()=>{w.style.borderColor=de}),w.addEventListener("mouseleave",()=>{w.style.borderColor=$}),g.appendChild(w)}S.appendChild(g)}return S}function I(){if(N.replaceChildren(),d.length===0){const a=b({textAlign:"center",color:nt,padding:"24px 16px",fontSize:"14px",lineHeight:"1.5"});a.textContent=t,N.appendChild(a)}else d.forEach((a,l)=>{N.appendChild(Pe(a,l===d.length-1))});if(W){const a=b({padding:"10px 14px",backgroundColor:"#fef2f2",color:"#dc2626",borderRadius:"12px",marginTop:"8px",fontSize:"13px",border:"1px solid #fecaca"});a.textContent=W,N.appendChild(a)}N.scrollTop=N.scrollHeight;const e=d[d.length-1];Fe(A&&e?.role==="assistant"&&e.status==="IN_PROGRESS")}function We(){for(let e=d.length-1;e>=0;e--){const a=d[e];if(a.role==="assistant"&&a.status==="IN_PROGRESS")return a}}const ve=e=>{k||(k=e.conversationId)},we=e=>{const a=We();a&&(a.content+=e.content,I())},ye=e=>{const a=d.findIndex(l=>l.id===e.id||l.role==="assistant"&&l.status==="IN_PROGRESS");a>=0?d[a]=e:d.push(e),I()},Ee=e=>{const a=d.findIndex(l=>l.id===e.id||l.role==="assistant"&&l.status==="IN_PROGRESS");a>=0?d[a]=e:d.push(e),A=!1,I(),e.status==="DONE"&&he?.({id:e.id,content:e.content})},Se=e=>{W=e.error,A=!1,d=d.filter(a=>!a.id.startsWith("temp-")),I()};h.on("message:start",ve),h.on("message:chunk",we),h.on("message:answer-complete",ye),h.on("message:complete",Ee),h.on("message:error",Se);const ne=[];let Re=!1;for(const e of q??[])e.schema!=null?ne.push($e.createFormCollector(e).install(h)):$e.loadFormCollector(h,e).then(a=>{Re||ne.push(a.install(h))}).catch(()=>{});async function oe(e,a){const l=e.trim();if(!l&&!a?.length||A)return;O?.(l),A=!0,W=null;const S=Date.now();d.push({id:`temp-user-${S}`,conversationId:k||"",content:l,role:"user",status:"DONE",createdAt:new Date}),d.push({id:`temp-assistant-${S}`,conversationId:k||"",content:"",role:"assistant",status:"IN_PROGRESS",createdAt:new Date}),I();try{const v=await h.sendMessage(l,{conversationId:k,files:a});v.conversationId&&(k||(k=v.conversationId),X?.setActiveThread(v.conversationId,v.createdAt));const g=d.find(C=>C.id===`temp-user-${S}`);if(g&&(g.id=`user-${S}`,g.conversationId=v.conversationId),!d.some(C=>C.id===v.id)){const C=d.findIndex(w=>w.id===`temp-assistant-${S}`);C>=0?d[C]=v:d.push(v)}d=d.filter(C=>!C.id.startsWith("temp-")),A=!1,I(),_&&re()}catch(v){W=v instanceof Error?v.message:"Failed to send message",A=!1,d=d.filter(g=>!g.id.startsWith("temp-")),I()}}async function re(){try{const e=await h.getConversations();K.splice(0,K.length,...e)}catch{}return K}async function Ge(e){try{const a=(await h.getConversation(e))?.messages??[];a.length>0&&d.length===0&&(d=a,I())}catch{d.length===0&&(X?.clear(),k=void 0)}}return I(),xe(),k&&Ge(k),_&&re(),{client:h,element:V,sendMessage:oe,...z?{open:ie,close:se,toggle:je}:{},session:X,threads:K,refreshThreads:re,destroy(){h.off("message:start",ve),h.off("message:chunk",we),h.off("message:answer-complete",ye),h.off("message:complete",Ee),h.off("message:error",Se),Re=!0,ne.forEach(e=>e()),V.remove(),E?.remove(),n.client||h.destroy()}};function ae(){if(!T)return;const e=s==="left"?"translateX(-100%)":"translateX(100%)";T.style.transform=H?"translateX(0)":e,T.setAttribute("aria-hidden",H?"false":"true"),E&&(E.style.display=H?"none":"flex")}function ie(){H=!0,ae(),xe()}function se(){H=!1,ae()}function je(){H?se():ie()}function qe(){const e="http://www.w3.org/2000/svg",a=document.createElementNS(e,"svg");a.setAttribute("width","26"),a.setAttribute("height","26"),a.setAttribute("viewBox","0 0 24 24"),a.setAttribute("fill","none");const l=document.createElementNS(e,"path");return l.setAttribute("d","M21 11.5a8.38 8.38 0 0 1-8.5 8.5 8.5 8.5 0 0 1-3.8-.9L3 21l1.9-5.7a8.5 8.5 0 0 1-.9-3.8 8.38 8.38 0 0 1 8.5-8.5 8.38 8.38 0 0 1 8.5 8.5z"),l.setAttribute("stroke","currentColor"),l.setAttribute("stroke-width","2"),l.setAttribute("stroke-linecap","round"),l.setAttribute("stroke-linejoin","round"),a.appendChild(l),a}function _e(){const e=b({display:"flex",gap:"4px",padding:"4px 0"});for(let a=0;a<3;a++){const l=b({width:"6px",height:"6px",borderRadius:"50%",backgroundColor:"#b5bfc8",animation:"ago-pulse 1.2s ease-in-out infinite",animationDelay:`${a*.2}s`});e.appendChild(l)}return e}}function lt(o){let n=[];const r=document.createElement("form");y(r,{display:"flex",flexDirection:"column",gap:"8px",padding:"12px",borderTop:`1px solid ${$}`,backgroundColor:j}),r.className="ago-chat-input";const t=b({display:"flex",flexWrap:"wrap",gap:"6px"}),u=b({display:"flex",gap:"8px",alignItems:"flex-end"}),i=document.createElement("textarea");i.placeholder=o.placeholder,i.rows=1,y(i,{flex:"1",resize:"none",padding:"10px 12px",border:`1px solid ${$}`,borderRadius:"12px",fontSize:"14px",fontFamily:pe,lineHeight:"1.4",maxHeight:"120px",outline:"none"});const f=document.createElement("button");f.type="submit",f.textContent="Send",y(f,{padding:"10px 16px",border:"none",borderRadius:"12px",backgroundColor:fe,color:ue,fontSize:"14px",fontWeight:"500",cursor:"pointer"});let s=null,p=null;o.allowFiles&&(s=document.createElement("input"),s.type="file",s.multiple=!0,y(s,{display:"none"}),p=document.createElement("button"),p.type="button",p.textContent="📎",y(p,{padding:"10px 12px",border:`1px solid ${$}`,borderRadius:"12px",backgroundColor:j,cursor:"pointer",fontSize:"14px"}),p.addEventListener("click",()=>s?.click()),s.addEventListener("change",()=>{n=[...n,...Array.from(s?.files??[])],c()}));function c(){t.replaceChildren(),n.forEach((x,_)=>{const q=b({display:"flex",alignItems:"center",gap:"4px",padding:"4px 8px",backgroundColor:"#f0f4ff",border:`1px solid ${$}`,borderRadius:"8px",fontSize:"12px"}),B=document.createElement("span");B.textContent=x.name;const O=document.createElement("button");O.type="button",O.textContent="×",y(O,{border:"none",background:"transparent",cursor:"pointer",fontSize:"14px",lineHeight:"1"}),O.addEventListener("click",()=>{n=n.filter((he,h)=>h!==_),c()}),q.append(B,O),t.appendChild(q)})}const m=()=>{const x=i.value,_=n;return i.value="",n=[],c(),{content:x,files:_}},L=()=>{const{content:x,files:_}=m();(x.trim()||_.length>0)&&o.onSend(x.trim(),_.length>0?_:void 0)};return r.addEventListener("submit",x=>{x.preventDefault(),L()}),i.addEventListener("keydown",x=>{x.key==="Enter"&&!x.shiftKey&&(x.preventDefault(),L())}),p&&u.appendChild(p),u.append(i,f),s&&r.appendChild(s),r.append(t,u),{inputRow:r,getValueAndClear:m,setDisabled:x=>{i.disabled=x,f.disabled=x,f.style.opacity=x?"0.6":"1",f.style.cursor=x?"not-allowed":"pointer"},focus:()=>i.focus()}}exports.mountChatWidget=st;exports.renderMarkdown=ge;
|
|
3
|
+
`);let t=0;for(;t<r.length;){const i=r[t];if(i.trim()===""){t++;continue}const f=i.match(Be);if(f){const c=f[1][0],h=[];for(t++;t<r.length&&!new RegExp(`^ {0,3}${c==="`"?"`{3,}":"~{3,}"}\\s*$`).test(r[t]);)h.push(r[t]),t++;t++;const L=_("pre",{margin:"0 0 8px 0"});L.appendChild(_("code",{display:"block",background:"#f5f5f5",padding:"8px 12px",borderRadius:"6px",fontSize:"13px",overflowX:"auto",fontFamily:Te,whiteSpace:"pre"},U(h.join(`
|
|
4
|
+
`)))),n.appendChild(L);continue}if(De.test(i)){n.appendChild(_("hr",{border:"none",borderTop:"1px solid #dee3e8",margin:"12px 0"})),t++;continue}const s=i.match(Me);if(s){const c=s[1].length;n.appendChild(_(`h${c}`,{margin:"16px 0 8px 0",fontSize:Qe[c-1],fontWeight:"600",lineHeight:"1.3"},M(s[2]))),t++;continue}if(Z.test(i)){const c=[];for(;t<r.length&&Z.test(r[t]);)c.push(r[t].replace(Z,"")),t++;const h=_("blockquote",{borderLeft:"4px solid #dee3e8",paddingLeft:"12px",margin:"0 0 8px 0",fontStyle:"italic",color:"#6b6d6f"});h.appendChild(J(c.join(`
|
|
5
|
+
`))),n.appendChild(h);continue}if(i.includes("|")&&Je(r[t+1])){const c=[i,r[t+1]];for(t+=2;t<r.length&&r[t].includes("|")&&r[t].trim();)c.push(r[t]),t++;n.appendChild(Ze(c));continue}if(P.test(i)){const c=[],h=fe(i);for(;t<r.length&&r[t].trim()!=="";)if(P.test(r[t])||fe(r[t])>h)c.push(r[t]),t++;else break;n.appendChild(ze(c));continue}const p=[i];for(t++;t<r.length&&!Ye(r[t]);)p.push(r[t]),t++;n.appendChild(_("p",{margin:"0 0 8px 0",lineHeight:"1.6"},p.map(c=>M(c)).join("<br>")))}const u=n.lastElementChild;return u&&(u.style.marginBottom="0"),n}var ue='var(--ago-font, "IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif)',Ie={font:"--ago-font",radius:"--ago-radius",messageRadius:"--ago-message-radius",brand:"--ago-brand-color",brandText:"--ago-brand-text-color",headerBg:"--ago-header-background",headerText:"--ago-header-text-color",panelBg:"--ago-panel-background",messagesBg:"--ago-messages-background",text:"--ago-text-color",mutedText:"--ago-muted-text-color",border:"--ago-border-color",accent:"--ago-accent-color"},ge="var(--ago-brand-color, #03182f)",he="var(--ago-brand-text-color, #fff)",et="var(--ago-header-background, var(--ago-brand-color, #03182f))",Le="var(--ago-header-text-color, #e8f0fe)",j="var(--ago-panel-background, #fff)",tt="var(--ago-messages-background, #fbfbfb)",Y="var(--ago-text-color, #30373e)",nt="var(--ago-muted-text-color, #6b6d6f)",$="var(--ago-border-color, #dee3e8)",pe="var(--ago-accent-color, #1b5fc4)",ot="var(--ago-radius, 16px)",Ne="var(--ago-message-radius, 16px)";function rt(o,n){if(n)for(const r of Object.keys(Ie)){const t=n[r];t!=null&&o.style.setProperty(Ie[r],t)}}function y(o,n){Object.assign(o.style,n)}function x(o={}){const n=document.createElement("div");return y(n,o),n}var Oe="ago-chat-widget-keyframes";function at(){if(typeof document>"u"||document.getElementById(Oe))return;const o=document.createElement("style");o.id=Oe,o.textContent="@keyframes ago-pulse { 0%, 80%, 100% { opacity: 0.3; transform: scale(0.8); } 40% { opacity: 1; transform: scale(1); } }",document.head.appendChild(o)}function it(o){const n=typeof o=="string"?document.querySelector(o):o;if(!n)throw new Error(`mountChatWidget: target "${String(o)}" not found.`);return n}function st(o,n){const{title:r="Chat",welcomeMessage:t="Hello! How can I help you today?",placeholder:u="Type a message...",allowFiles:i=!1,height:f=500,placement:s="inline",width:p=400,defaultOpen:c=!1,logoUrl:h,showAgentName:L=!1,theme:m,loadThreads:R=!1,forms:q,onFollowUpClick:B,onMessageSent:N,onMessageReceived:me}=n;if(!n.client&&!n.config?.baseUrl)throw new ke.AgoError("mountChatWidget requires either `client` or `config` (with a baseUrl).","config_missing_base_url");const g=n.client??new ke.AgoClient(n.config),xe=it(o),z=s==="left"||s==="right",He=z&&(n.launcher??!0);let H=z?c:!0;const ee=n.persistConversation,X=ee?Ke.createConversationSession(ee===!0?{}:ee):void 0;let k=n.conversationId??X?.getLastActiveThread()??void 0,d=[],O=!1,W=null;const K=[],F=x({display:"flex",flexDirection:"column",height:z?"100%":typeof f=="number"?`${f}px`:f,border:`1px solid ${$}`,borderRadius:ot,overflow:"hidden",backgroundColor:j,fontFamily:ue,textAlign:"left",boxShadow:"rgba(15, 15, 15, 0.08) 0px 2px 16px 0px"});F.className="ago-chat-widget",rt(F,m);const G=x({padding:"14px 16px",borderBottom:`1px solid ${$}`,backgroundColor:et,color:Le,display:"flex",alignItems:"center",gap:"10px"});if(G.className="ago-chat-widget__header",h){const e=document.createElement("img");e.src=h,e.alt="Logo",y(e,{height:"24px",width:"auto"}),G.appendChild(e)}const te=document.createElement("h3");if(te.textContent=r,y(te,{margin:"0",fontSize:"15px",fontWeight:"600"}),G.appendChild(te),z){const e=document.createElement("button");e.type="button",e.className="ago-chat-widget__close",e.setAttribute("aria-label","Close"),e.textContent="×",y(e,{marginLeft:"auto",background:"transparent",border:"none",color:Le,fontSize:"22px",lineHeight:"1",cursor:"pointer",padding:"0 2px"}),e.addEventListener("click",()=>de()),G.appendChild(e)}const I=x({flex:"1",overflow:"auto",padding:"16px",backgroundColor:tt});I.className="ago-chat-widget__messages";const{inputRow:Fe,setDisabled:Ue,focus:ne}=lt({placeholder:u,allowFiles:i,onSend:(e,a)=>{ae(e,a)}});at(),F.append(G,I,Fe);let V=F,T,E;const oe=s==="left"?"left":"right";if(z&&(T=x({position:"fixed",top:"0",bottom:"0",[oe]:"0",width:typeof p=="number"?`${p}px`:p,maxWidth:"100vw",display:"flex",zIndex:"2147483000",transition:"transform 0.3s ease",boxShadow:"rgba(15, 15, 15, 0.18) 0px 0px 24px 0px"}),T.className="ago-chat-widget-panel",y(F,{height:"100%",width:"100%",borderRadius:"0",border:"none",boxShadow:"none",[oe==="left"?"borderRight":"borderLeft"]:`1px solid ${$}`}),T.appendChild(F),V=T),He){if(E=document.createElement("button"),E.type="button",E.className="ago-chat-widget-launcher",E.setAttribute("aria-label",`Open ${r}`),y(E,{position:"fixed",bottom:"20px",[oe]:"20px",width:"56px",height:"56px",borderRadius:"50%",border:"none",backgroundColor:ge,color:he,cursor:"pointer",display:"flex",alignItems:"center",justifyContent:"center",zIndex:"2147483000",boxShadow:"rgba(15, 15, 15, 0.2) 0px 4px 14px 0px",fontFamily:ue}),h){const e=document.createElement("img");e.src=h,e.alt="",y(e,{width:"26px",height:"26px",objectFit:"contain"}),E.appendChild(e)}else E.appendChild(qe());E.addEventListener("click",()=>le())}xe.appendChild(V),E&&xe.appendChild(E),se();const be=B!==!1,Ce=B===!1?void 0:B??(e=>{ae(e)});function Pe(e,a){const l=e.role==="user",S=x({display:"flex",flexDirection:"column",alignItems:l?"flex-end":"flex-start",marginBottom:"16px"});if(S.className=`ago-message ago-message--${e.role}`,!l&&L&&e.agent){const b=x({fontSize:"13px",fontWeight:"500",color:Y,marginBottom:"6px",padding:"0 4px"});b.className="ago-message__agent",b.textContent=e.agent.displayName||e.agent.name,S.appendChild(b)}if(!l&&e.sources&&e.sources.length>0){const b=x({display:"grid",gridTemplateColumns:"1fr 1fr",gap:"6px",marginBottom:"10px",width:"100%",maxWidth:"85%"});b.className="ago-message__sources",e.sources.forEach((C,w)=>{const D=C.url?document.createElement("a"):document.createElement("div");C.url&&D instanceof HTMLAnchorElement&&(D.href=C.url,D.target="_blank",D.rel="noopener noreferrer"),y(D,{display:"flex",alignItems:"center",gap:"8px",padding:"8px 10px",border:`1px solid ${$}`,borderRadius:"8px",backgroundColor:j,textDecoration:"none",color:Y,fontSize:"12px",overflow:"hidden"});const Re=x({flexShrink:"0",width:"18px",height:"18px",borderRadius:"3px",border:`1px solid ${pe}`,color:pe,fontSize:"11px",fontWeight:"500",display:"flex",alignItems:"center",justifyContent:"center",backgroundColor:"#f0f4ff"});Re.textContent=String(w+1);const ce=x({overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"});ce.textContent=C.title,ce.title=C.title,D.append(Re,ce),b.appendChild(D)}),S.appendChild(b)}const v=x({maxWidth:l?"75%":"100%",padding:l?"10px 14px":"2px 8px",borderRadius:l?Ne:"0",backgroundColor:l?ge:"transparent",color:l?he:Y,wordBreak:"break-word",fontSize:"14px",lineHeight:"1.6"});if(v.className="ago-message__content",e.content?v.appendChild(J(e.content)):e.status==="IN_PROGRESS"&&v.appendChild(Xe()),S.appendChild(v),a&&e.followUpReplies&&e.followUpReplies.length>0){const b=x({display:"flex",flexWrap:"wrap",gap:"8px",marginTop:"10px"});b.className="ago-message__followups";for(const C of e.followUpReplies){const w=document.createElement("button");w.type="button",w.className="ago-message__followup-btn",w.textContent=C,w.disabled=!be,y(w,{padding:"6px 14px",fontSize:"14px",borderRadius:Ne,border:`1px solid ${$}`,backgroundColor:j,color:Y,cursor:be?"pointer":"default",transition:"border-color 0.15s"}),Ce&&w.addEventListener("click",()=>Ce(C)),w.addEventListener("mouseenter",()=>{w.style.borderColor=pe}),w.addEventListener("mouseleave",()=>{w.style.borderColor=$}),b.appendChild(w)}S.appendChild(b)}return S}function A(){if(I.replaceChildren(),d.length===0){const a=x({textAlign:"center",color:nt,padding:"24px 16px",fontSize:"14px",lineHeight:"1.5"});a.appendChild(J(t)),I.appendChild(a)}else d.forEach((a,l)=>{I.appendChild(Pe(a,l===d.length-1))});if(W){const a=x({padding:"10px 14px",backgroundColor:"#fef2f2",color:"#dc2626",borderRadius:"12px",marginTop:"8px",fontSize:"13px",border:"1px solid #fecaca"});a.textContent=W,I.appendChild(a)}I.scrollTop=I.scrollHeight;const e=d[d.length-1];Ue(O&&e?.role==="assistant"&&e.status==="IN_PROGRESS")}function We(){for(let e=d.length-1;e>=0;e--){const a=d[e];if(a.role==="assistant"&&a.status==="IN_PROGRESS")return a}}const ve=e=>{k||(k=e.conversationId)},we=e=>{const a=We();a&&(a.content+=e.content,A())},ye=e=>{const a=d.findIndex(l=>l.id===e.id||l.role==="assistant"&&l.status==="IN_PROGRESS");a>=0?d[a]=e:d.push(e),A(),ne()},Ee=e=>{const a=d.findIndex(l=>l.id===e.id||l.role==="assistant"&&l.status==="IN_PROGRESS");a>=0?d[a]=e:d.push(e),O=!1,A(),e.status==="DONE"&&me?.({id:e.id,content:e.content})},Se=e=>{W=e.error,O=!1,d=d.filter(a=>!a.id.startsWith("temp-")),A()};g.on("message:start",ve),g.on("message:chunk",we),g.on("message:answer-complete",ye),g.on("message:complete",Ee),g.on("message:error",Se);const re=[];let _e=!1;for(const e of q??[])e.schema!=null?re.push($e.createFormCollector(e).install(g)):$e.loadFormCollector(g,e).then(a=>{_e||re.push(a.install(g))}).catch(()=>{});async function ae(e,a){const l=e.trim();if(!l&&!a?.length||O)return;N?.(l),O=!0,W=null;const S=Date.now();d.push({id:`temp-user-${S}`,conversationId:k||"",content:l,role:"user",status:"DONE",createdAt:new Date}),d.push({id:`temp-assistant-${S}`,conversationId:k||"",content:"",role:"assistant",status:"IN_PROGRESS",createdAt:new Date}),A();try{const v=await g.sendMessage(l,{conversationId:k,files:a});v.conversationId&&(k||(k=v.conversationId),X?.setActiveThread(v.conversationId,v.createdAt));const b=d.find(C=>C.id===`temp-user-${S}`);if(b&&(b.id=`user-${S}`,b.conversationId=v.conversationId),!d.some(C=>C.id===v.id)){const C=d.findIndex(w=>w.id===`temp-assistant-${S}`);C>=0?d[C]=v:d.push(v)}d=d.filter(C=>!C.id.startsWith("temp-")),O=!1,A(),R&&ie()}catch(v){W=v instanceof Error?v.message:"Failed to send message",O=!1,d=d.filter(b=>!b.id.startsWith("temp-")),A()}}async function ie(){try{const e=await g.getConversations();K.splice(0,K.length,...e)}catch{}return K}async function Ge(e){try{const a=(await g.getConversation(e))?.messages??[];a.length>0&&d.length===0&&(d=a,A())}catch{d.length===0&&(X?.clear(),k=void 0)}}return A(),ne(),k&&Ge(k),R&&ie(),{client:g,element:V,sendMessage:ae,...z?{open:le,close:de,toggle:je}:{},session:X,threads:K,refreshThreads:ie,destroy(){g.off("message:start",ve),g.off("message:chunk",we),g.off("message:answer-complete",ye),g.off("message:complete",Ee),g.off("message:error",Se),_e=!0,re.forEach(e=>e()),V.remove(),E?.remove(),n.client||g.destroy()}};function se(){if(!T)return;const e=s==="left"?"translateX(-100%)":"translateX(100%)";T.style.transform=H?"translateX(0)":e,T.setAttribute("aria-hidden",H?"false":"true"),E&&(E.style.display=H?"none":"flex")}function le(){H=!0,se(),ne()}function de(){H=!1,se()}function je(){H?de():le()}function qe(){const e="http://www.w3.org/2000/svg",a=document.createElementNS(e,"svg");a.setAttribute("width","26"),a.setAttribute("height","26"),a.setAttribute("viewBox","0 0 24 24"),a.setAttribute("fill","none");const l=document.createElementNS(e,"path");return l.setAttribute("d","M21 11.5a8.38 8.38 0 0 1-8.5 8.5 8.5 8.5 0 0 1-3.8-.9L3 21l1.9-5.7a8.5 8.5 0 0 1-.9-3.8 8.38 8.38 0 0 1 8.5-8.5 8.38 8.38 0 0 1 8.5 8.5z"),l.setAttribute("stroke","currentColor"),l.setAttribute("stroke-width","2"),l.setAttribute("stroke-linecap","round"),l.setAttribute("stroke-linejoin","round"),a.appendChild(l),a}function Xe(){const e=x({display:"flex",gap:"4px",padding:"4px 0"});for(let a=0;a<3;a++){const l=x({width:"6px",height:"6px",borderRadius:"50%",backgroundColor:"#b5bfc8",animation:"ago-pulse 1.2s ease-in-out infinite",animationDelay:`${a*.2}s`});e.appendChild(l)}return e}}function lt(o){let n=[];const r=document.createElement("form");y(r,{display:"flex",flexDirection:"column",gap:"8px",padding:"12px",borderTop:`1px solid ${$}`,backgroundColor:j}),r.className="ago-chat-input";const t=x({display:"flex",flexWrap:"wrap",gap:"6px"}),u=x({display:"flex",gap:"8px",alignItems:"flex-end"}),i=document.createElement("textarea");i.placeholder=o.placeholder,i.rows=1,y(i,{flex:"1",resize:"none",padding:"10px 12px",border:`1px solid ${$}`,borderRadius:"12px",fontSize:"14px",fontFamily:ue,lineHeight:"1.4",maxHeight:"120px",outline:"none"});const f=document.createElement("button");f.type="submit",f.textContent="Send",y(f,{padding:"10px 16px",border:"none",borderRadius:"12px",backgroundColor:ge,color:he,fontSize:"14px",fontWeight:"500",cursor:"pointer"});let s=null,p=null;o.allowFiles&&(s=document.createElement("input"),s.type="file",s.multiple=!0,y(s,{display:"none"}),p=document.createElement("button"),p.type="button",p.textContent="📎",y(p,{padding:"10px 12px",border:`1px solid ${$}`,borderRadius:"12px",backgroundColor:j,cursor:"pointer",fontSize:"14px"}),p.addEventListener("click",()=>s?.click()),s.addEventListener("change",()=>{n=[...n,...Array.from(s?.files??[])],c()}));function c(){t.replaceChildren(),n.forEach((m,R)=>{const q=x({display:"flex",alignItems:"center",gap:"4px",padding:"4px 8px",backgroundColor:"#f0f4ff",border:`1px solid ${$}`,borderRadius:"8px",fontSize:"12px"}),B=document.createElement("span");B.textContent=m.name;const N=document.createElement("button");N.type="button",N.textContent="×",y(N,{border:"none",background:"transparent",cursor:"pointer",fontSize:"14px",lineHeight:"1"}),N.addEventListener("click",()=>{n=n.filter((me,g)=>g!==R),c()}),q.append(B,N),t.appendChild(q)})}const h=()=>{const m=i.value,R=n;return i.value="",n=[],c(),{content:m,files:R}},L=()=>{const{content:m,files:R}=h();(m.trim()||R.length>0)&&o.onSend(m.trim(),R.length>0?R:void 0)};return r.addEventListener("submit",m=>{m.preventDefault(),L()}),i.addEventListener("keydown",m=>{m.key==="Enter"&&!m.shiftKey&&(m.preventDefault(),L())}),p&&u.appendChild(p),u.append(i,f),s&&r.appendChild(s),r.append(t,u),{inputRow:r,getValueAndClear:h,setDisabled:m=>{i.disabled=m,f.disabled=m,f.style.opacity=m?"0.6":"1",f.style.cursor=m?"not-allowed":"pointer"},focus:()=>i.focus()}}exports.mountChatWidget=st;exports.renderMarkdown=J;
|
package/dist/widget.d.cts
CHANGED
|
@@ -16,12 +16,26 @@ declare class AgoClient {
|
|
|
16
16
|
private contextRegistry;
|
|
17
17
|
private eventEmitter;
|
|
18
18
|
private config;
|
|
19
|
+
/** Conversations already warned about an empty reply (one warning each). */
|
|
20
|
+
private warnedEmptyConversations;
|
|
19
21
|
constructor(config: AgoConfig);
|
|
20
22
|
/**
|
|
21
23
|
* Send a message and receive a streaming response
|
|
22
24
|
*/
|
|
23
25
|
sendMessage(content: string, options?: SendMessageOptions): Promise<AgoMessage>;
|
|
24
26
|
private processSSEResponse;
|
|
27
|
+
/**
|
|
28
|
+
* Detect a reply that completed as DONE with no content and no activity —
|
|
29
|
+
* today's backend answers an unknown `agent` slug with an empty 200, which
|
|
30
|
+
* otherwise fails silently. Emits `message:empty` (always) and warns on the
|
|
31
|
+
* console once per conversation (unless `warnOnEmptyReply: false`).
|
|
32
|
+
*
|
|
33
|
+
* Deferred with setTimeout(0) so both land AFTER `sendMessage` resolves:
|
|
34
|
+
* `await client.sendMessage(...)` followed by `client.waitFor("message:empty")`
|
|
35
|
+
* must not race. TEMPORARY heuristic: remove once the backend returns an
|
|
36
|
+
* explicit error for unknown agents (see TODOS.md, backend issue).
|
|
37
|
+
*/
|
|
38
|
+
private maybeFlagEmptyReply;
|
|
25
39
|
private handleClientFunctionInvocation;
|
|
26
40
|
/**
|
|
27
41
|
* Get list of conversations
|
|
@@ -194,6 +208,11 @@ declare class AgoClient {
|
|
|
194
208
|
}): Promise<AgoClientEvents[K]>;
|
|
195
209
|
/**
|
|
196
210
|
* Update client configuration
|
|
211
|
+
*
|
|
212
|
+
* Validates the MERGED config before committing: omitting a key (or passing
|
|
213
|
+
* it as `undefined`, common with spread-built partials) keeps the current
|
|
214
|
+
* value; an explicit empty/non-string `baseUrl` throws `config_missing_base_url`
|
|
215
|
+
* and leaves the client unchanged (no half-updated state).
|
|
197
216
|
*/
|
|
198
217
|
updateConfig(config: Partial<AgoConfig>): void;
|
|
199
218
|
/**
|
|
@@ -229,8 +248,23 @@ declare interface AgoClientEvents {
|
|
|
229
248
|
*/
|
|
230
249
|
"message:answer-complete": AgoMessage;
|
|
231
250
|
"message:complete": AgoMessage;
|
|
251
|
+
/**
|
|
252
|
+
* A reply finished as `DONE` with empty content and no tool calls, client
|
|
253
|
+
* functions, or follow-up replies — usually an unknown `agent` slug (the
|
|
254
|
+
* backend currently answers those with an empty 200). Fires after
|
|
255
|
+
* `message:complete` AND after `sendMessage` resolves, so subscribing right
|
|
256
|
+
* after `await sendMessage(...)` still catches it. `messageId` and
|
|
257
|
+
* `conversationId` are empty strings when the stream completed without any
|
|
258
|
+
* message data at all (e.g. a proxy stripped the SSE stream).
|
|
259
|
+
*/
|
|
260
|
+
"message:empty": {
|
|
261
|
+
conversationId: string;
|
|
262
|
+
messageId: string;
|
|
263
|
+
};
|
|
232
264
|
"message:error": {
|
|
233
265
|
error: string;
|
|
266
|
+
/** Stable error code (see configuration.md#error-codes) when the failure was an AgoError. */
|
|
267
|
+
code?: string;
|
|
234
268
|
conversationId?: string;
|
|
235
269
|
messageId?: string;
|
|
236
270
|
};
|
|
@@ -259,7 +293,7 @@ declare interface AgoClientEvents {
|
|
|
259
293
|
declare interface AgoConfig {
|
|
260
294
|
/** API base URL (e.g., https://YOUR-DOMAIN.useago.com) */
|
|
261
295
|
baseUrl: string;
|
|
262
|
-
/**
|
|
296
|
+
/** Per-visitor anonymous ID (X-User-Anon-Id header). Auto-generated if not provided. */
|
|
263
297
|
widgetId?: string;
|
|
264
298
|
/** Default agent (id or slug) for new conversations. Shorthand for `defaultAgentId`. */
|
|
265
299
|
agent?: string;
|
|
@@ -273,6 +307,13 @@ declare interface AgoConfig {
|
|
|
273
307
|
userJwt?: string;
|
|
274
308
|
/** Enable debug logging */
|
|
275
309
|
debug?: boolean;
|
|
310
|
+
/**
|
|
311
|
+
* Warn on the console when a reply completes with empty content and no tool
|
|
312
|
+
* calls (the usual cause is an unknown `agent` slug, which the backend
|
|
313
|
+
* currently answers with an empty 200). Default `true`. The `message:empty`
|
|
314
|
+
* event fires regardless of this setting.
|
|
315
|
+
*/
|
|
316
|
+
warnOnEmptyReply?: boolean;
|
|
276
317
|
}
|
|
277
318
|
|
|
278
319
|
declare type AgoEventHandler<K extends AgoEventName> = (data: AgoClientEvents[K]) => void;
|