@useago/sdk 1.0.0 → 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 +103 -74
- package/dist/AgoClient-_fig8FoN.cjs +6 -0
- package/dist/{AgoClient-BrYhSO5M.js → AgoClient-bQozE6-A.js} +174 -134
- package/dist/angular.cjs +1 -1
- package/dist/angular.d.cts +131 -1
- package/dist/angular.d.ts +131 -1
- package/dist/angular.js +1 -1
- package/dist/{createConversationSession-Dmqd80DX.js → createConversationSession-BbK3ou1k.js} +1 -1
- package/dist/{createConversationSession-CGRO0bs2.cjs → createConversationSession-DJUFgOXy.cjs} +1 -1
- package/dist/createFormCollector-CdQjGAl_.cjs +1 -0
- package/dist/createFormCollector-D-TpSd9x.js +257 -0
- package/dist/devtools.d.cts +131 -1
- package/dist/devtools.d.ts +131 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +126 -4
- package/dist/index.d.ts +126 -4
- package/dist/index.js +94 -92
- package/dist/react.cjs +20 -20
- package/dist/react.d.cts +125 -30
- package/dist/react.d.ts +125 -30
- package/dist/react.js +2207 -2135
- package/dist/testing.d.cts +131 -1
- package/dist/testing.d.ts +131 -1
- package/dist/vue.cjs +1 -1
- package/dist/vue.d.cts +131 -1
- package/dist/vue.d.ts +131 -1
- package/dist/vue.js +1 -1
- package/dist/widget.cjs +4 -4
- package/dist/widget.d.cts +115 -5
- package/dist/widget.d.ts +115 -5
- package/dist/widget.js +408 -322
- package/package.json +2 -2
- package/dist/AgoClient-CPqPT5s6.cjs +0 -6
- package/dist/createFormCollector-CPS2phYq.js +0 -245
- package/dist/createFormCollector-DaWZsBsI.cjs +0 -1
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
|
|
@@ -53,6 +67,13 @@ declare class AgoClient {
|
|
|
53
67
|
* Reject a tool call
|
|
54
68
|
*/
|
|
55
69
|
rejectToolCall(toolCallId: string): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Fetch a backend-stored form collector definition by name (the single source
|
|
72
|
+
* of truth for the form's description, schema, and submit target). Used by
|
|
73
|
+
* `loadFormCollector` / the name-only form of `useFormCollector` so the schema
|
|
74
|
+
* lives in the backend instead of being hardcoded in client code.
|
|
75
|
+
*/
|
|
76
|
+
getFormCollector(name: string): Promise<FormCollectorDefinition>;
|
|
56
77
|
/**
|
|
57
78
|
* Relay a completed form collector's values to a server-configured destination.
|
|
58
79
|
*
|
|
@@ -187,6 +208,11 @@ declare class AgoClient {
|
|
|
187
208
|
}): Promise<AgoClientEvents[K]>;
|
|
188
209
|
/**
|
|
189
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).
|
|
190
216
|
*/
|
|
191
217
|
updateConfig(config: Partial<AgoConfig>): void;
|
|
192
218
|
/**
|
|
@@ -222,8 +248,23 @@ declare interface AgoClientEvents {
|
|
|
222
248
|
*/
|
|
223
249
|
"message:answer-complete": AgoMessage;
|
|
224
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
|
+
};
|
|
225
264
|
"message:error": {
|
|
226
265
|
error: string;
|
|
266
|
+
/** Stable error code (see configuration.md#error-codes) when the failure was an AgoError. */
|
|
267
|
+
code?: string;
|
|
227
268
|
conversationId?: string;
|
|
228
269
|
messageId?: string;
|
|
229
270
|
};
|
|
@@ -252,7 +293,7 @@ declare interface AgoClientEvents {
|
|
|
252
293
|
declare interface AgoConfig {
|
|
253
294
|
/** API base URL (e.g., https://YOUR-DOMAIN.useago.com) */
|
|
254
295
|
baseUrl: string;
|
|
255
|
-
/**
|
|
296
|
+
/** Per-visitor anonymous ID (X-User-Anon-Id header). Auto-generated if not provided. */
|
|
256
297
|
widgetId?: string;
|
|
257
298
|
/** Default agent (id or slug) for new conversations. Shorthand for `defaultAgentId`. */
|
|
258
299
|
agent?: string;
|
|
@@ -266,6 +307,13 @@ declare interface AgoConfig {
|
|
|
266
307
|
userJwt?: string;
|
|
267
308
|
/** Enable debug logging */
|
|
268
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;
|
|
269
317
|
}
|
|
270
318
|
|
|
271
319
|
declare type AgoEventHandler<K extends AgoEventName> = (data: AgoClientEvents[K]) => void;
|
|
@@ -400,6 +448,30 @@ export declare function createMockClient(options?: MockAgoClientOptions): MockAg
|
|
|
400
448
|
*/
|
|
401
449
|
declare type DynamicContextProvider = () => ContextEntry | null | undefined;
|
|
402
450
|
|
|
451
|
+
/**
|
|
452
|
+
* The backend-stored shape returned by `GET /api/sdk/v1/forms/{name}` (see
|
|
453
|
+
* {@link AgoClient.getFormCollector}). Mirrors the persistable subset of
|
|
454
|
+
* {@link CreateFormCollectorOptions}: the `submit` here is never the client-only
|
|
455
|
+
* `handler` variant (a function can't be stored server-side).
|
|
456
|
+
*/
|
|
457
|
+
declare interface FormCollectorDefinition<V = Record<string, unknown>> {
|
|
458
|
+
name: string;
|
|
459
|
+
description: string;
|
|
460
|
+
schema: FormCollectorSchema;
|
|
461
|
+
/** Server-stored submit target, if any. Absent means collect-only. */
|
|
462
|
+
submit?: SubmitConfig<V>;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Shape of a form's fields. Mirrors a client function's `parameters` (so the same
|
|
467
|
+
* object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes before the schema reaches the LLM.
|
|
468
|
+
*/
|
|
469
|
+
declare interface FormCollectorSchema {
|
|
470
|
+
type: "object";
|
|
471
|
+
properties: Record<string, FormFieldSchema>;
|
|
472
|
+
required?: string[];
|
|
473
|
+
}
|
|
474
|
+
|
|
403
475
|
declare interface FormField {
|
|
404
476
|
type: "string" | "number" | "boolean" | "array";
|
|
405
477
|
title?: string;
|
|
@@ -408,6 +480,43 @@ declare interface FormField {
|
|
|
408
480
|
default?: unknown;
|
|
409
481
|
}
|
|
410
482
|
|
|
483
|
+
/**
|
|
484
|
+
* A field's conditional-requiredness rule. The field becomes required exactly
|
|
485
|
+
* when the controlling `property` matches `value` against the answers collected
|
|
486
|
+
* so far:
|
|
487
|
+
* - a single `value`, no `op` — equality (compared as strings);
|
|
488
|
+
* - a single `value` with `op` — numeric comparison (both sides coerced to numbers);
|
|
489
|
+
* - an array `value`, no `op` — "one of": matches when the property equals any
|
|
490
|
+
* listed value.
|
|
491
|
+
*
|
|
492
|
+
* SDK-only — it is stripped from the schema before it reaches the LLM tool
|
|
493
|
+
*/
|
|
494
|
+
declare interface FormFieldCondition {
|
|
495
|
+
/** The controlling field whose value the rule tests. */
|
|
496
|
+
property: string;
|
|
497
|
+
/** Comparison operator; omitted means equality. Ignored when `value` is an array. */
|
|
498
|
+
op?: ">=" | "<=" | ">" | "<";
|
|
499
|
+
/**
|
|
500
|
+
* The value(s) to test the controlling field against. A single value is an
|
|
501
|
+
* equality (or, with `op`, a numeric comparison); an array is an "is one of"
|
|
502
|
+
* membership test, e.g. `value: ["1", "2", "3"]`.
|
|
503
|
+
*/
|
|
504
|
+
value: string | number | Array<string | number>;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/** A single field's schema: the wire-legal keys plus the SDK-only `requiredWhen`. */
|
|
508
|
+
declare interface FormFieldSchema {
|
|
509
|
+
type: string;
|
|
510
|
+
description?: string;
|
|
511
|
+
enum?: string[];
|
|
512
|
+
default?: unknown;
|
|
513
|
+
/**
|
|
514
|
+
* Makes the field required only while this condition holds. Drives the dynamic
|
|
515
|
+
* `missing` list; stripped before the LLM tool — see {@link toWireParameters}.
|
|
516
|
+
*/
|
|
517
|
+
requiredWhen?: FormFieldCondition;
|
|
518
|
+
}
|
|
519
|
+
|
|
411
520
|
/**
|
|
412
521
|
* Form schema for tool calls requiring user input
|
|
413
522
|
*/
|
|
@@ -461,6 +570,27 @@ declare interface SendMessageOptions {
|
|
|
461
570
|
files?: File[];
|
|
462
571
|
}
|
|
463
572
|
|
|
573
|
+
/**
|
|
574
|
+
* Where a completed form is sent.
|
|
575
|
+
* - `"https://..."` (a bare string) — shorthand for `{ via: "client", url }`: the browser
|
|
576
|
+
* POSTs the values to that URL.
|
|
577
|
+
* - `{ via: "client", url }` — same, written out.
|
|
578
|
+
* - `{ via: "client", handler }` — the browser runs your own submit logic.
|
|
579
|
+
* - `{ via: "backend", destination }` — the browser relays the values to the backend,
|
|
580
|
+
* which forwards them to the server-configured destination (URL + secret stay server-side).
|
|
581
|
+
* - `false` — collect only, no submit function.
|
|
582
|
+
*/
|
|
583
|
+
declare type SubmitConfig<V = Record<string, unknown>> = string | {
|
|
584
|
+
via: "client";
|
|
585
|
+
url: string;
|
|
586
|
+
} | {
|
|
587
|
+
via: "client";
|
|
588
|
+
handler: (values: V) => Promise<unknown> | unknown;
|
|
589
|
+
} | {
|
|
590
|
+
via: "backend";
|
|
591
|
+
destination: string;
|
|
592
|
+
} | false;
|
|
593
|
+
|
|
464
594
|
/**
|
|
465
595
|
* Tool call data from SSE stream
|
|
466
596
|
*/
|
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
|
|
@@ -53,6 +67,13 @@ declare class AgoClient {
|
|
|
53
67
|
* Reject a tool call
|
|
54
68
|
*/
|
|
55
69
|
rejectToolCall(toolCallId: string): Promise<void>;
|
|
70
|
+
/**
|
|
71
|
+
* Fetch a backend-stored form collector definition by name (the single source
|
|
72
|
+
* of truth for the form's description, schema, and submit target). Used by
|
|
73
|
+
* `loadFormCollector` / the name-only form of `useFormCollector` so the schema
|
|
74
|
+
* lives in the backend instead of being hardcoded in client code.
|
|
75
|
+
*/
|
|
76
|
+
getFormCollector(name: string): Promise<FormCollectorDefinition>;
|
|
56
77
|
/**
|
|
57
78
|
* Relay a completed form collector's values to a server-configured destination.
|
|
58
79
|
*
|
|
@@ -187,6 +208,11 @@ declare class AgoClient {
|
|
|
187
208
|
}): Promise<AgoClientEvents[K]>;
|
|
188
209
|
/**
|
|
189
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).
|
|
190
216
|
*/
|
|
191
217
|
updateConfig(config: Partial<AgoConfig>): void;
|
|
192
218
|
/**
|
|
@@ -222,8 +248,23 @@ declare interface AgoClientEvents {
|
|
|
222
248
|
*/
|
|
223
249
|
"message:answer-complete": AgoMessage;
|
|
224
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
|
+
};
|
|
225
264
|
"message:error": {
|
|
226
265
|
error: string;
|
|
266
|
+
/** Stable error code (see configuration.md#error-codes) when the failure was an AgoError. */
|
|
267
|
+
code?: string;
|
|
227
268
|
conversationId?: string;
|
|
228
269
|
messageId?: string;
|
|
229
270
|
};
|
|
@@ -252,7 +293,7 @@ declare interface AgoClientEvents {
|
|
|
252
293
|
declare interface AgoConfig {
|
|
253
294
|
/** API base URL (e.g., https://YOUR-DOMAIN.useago.com) */
|
|
254
295
|
baseUrl: string;
|
|
255
|
-
/**
|
|
296
|
+
/** Per-visitor anonymous ID (X-User-Anon-Id header). Auto-generated if not provided. */
|
|
256
297
|
widgetId?: string;
|
|
257
298
|
/** Default agent (id or slug) for new conversations. Shorthand for `defaultAgentId`. */
|
|
258
299
|
agent?: string;
|
|
@@ -266,6 +307,13 @@ declare interface AgoConfig {
|
|
|
266
307
|
userJwt?: string;
|
|
267
308
|
/** Enable debug logging */
|
|
268
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;
|
|
269
317
|
}
|
|
270
318
|
|
|
271
319
|
declare type AgoEventHandler<K extends AgoEventName> = (data: AgoClientEvents[K]) => void;
|
|
@@ -400,6 +448,30 @@ export declare function createMockClient(options?: MockAgoClientOptions): MockAg
|
|
|
400
448
|
*/
|
|
401
449
|
declare type DynamicContextProvider = () => ContextEntry | null | undefined;
|
|
402
450
|
|
|
451
|
+
/**
|
|
452
|
+
* The backend-stored shape returned by `GET /api/sdk/v1/forms/{name}` (see
|
|
453
|
+
* {@link AgoClient.getFormCollector}). Mirrors the persistable subset of
|
|
454
|
+
* {@link CreateFormCollectorOptions}: the `submit` here is never the client-only
|
|
455
|
+
* `handler` variant (a function can't be stored server-side).
|
|
456
|
+
*/
|
|
457
|
+
declare interface FormCollectorDefinition<V = Record<string, unknown>> {
|
|
458
|
+
name: string;
|
|
459
|
+
description: string;
|
|
460
|
+
schema: FormCollectorSchema;
|
|
461
|
+
/** Server-stored submit target, if any. Absent means collect-only. */
|
|
462
|
+
submit?: SubmitConfig<V>;
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
/**
|
|
466
|
+
* Shape of a form's fields. Mirrors a client function's `parameters` (so the same
|
|
467
|
+
* object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes before the schema reaches the LLM.
|
|
468
|
+
*/
|
|
469
|
+
declare interface FormCollectorSchema {
|
|
470
|
+
type: "object";
|
|
471
|
+
properties: Record<string, FormFieldSchema>;
|
|
472
|
+
required?: string[];
|
|
473
|
+
}
|
|
474
|
+
|
|
403
475
|
declare interface FormField {
|
|
404
476
|
type: "string" | "number" | "boolean" | "array";
|
|
405
477
|
title?: string;
|
|
@@ -408,6 +480,43 @@ declare interface FormField {
|
|
|
408
480
|
default?: unknown;
|
|
409
481
|
}
|
|
410
482
|
|
|
483
|
+
/**
|
|
484
|
+
* A field's conditional-requiredness rule. The field becomes required exactly
|
|
485
|
+
* when the controlling `property` matches `value` against the answers collected
|
|
486
|
+
* so far:
|
|
487
|
+
* - a single `value`, no `op` — equality (compared as strings);
|
|
488
|
+
* - a single `value` with `op` — numeric comparison (both sides coerced to numbers);
|
|
489
|
+
* - an array `value`, no `op` — "one of": matches when the property equals any
|
|
490
|
+
* listed value.
|
|
491
|
+
*
|
|
492
|
+
* SDK-only — it is stripped from the schema before it reaches the LLM tool
|
|
493
|
+
*/
|
|
494
|
+
declare interface FormFieldCondition {
|
|
495
|
+
/** The controlling field whose value the rule tests. */
|
|
496
|
+
property: string;
|
|
497
|
+
/** Comparison operator; omitted means equality. Ignored when `value` is an array. */
|
|
498
|
+
op?: ">=" | "<=" | ">" | "<";
|
|
499
|
+
/**
|
|
500
|
+
* The value(s) to test the controlling field against. A single value is an
|
|
501
|
+
* equality (or, with `op`, a numeric comparison); an array is an "is one of"
|
|
502
|
+
* membership test, e.g. `value: ["1", "2", "3"]`.
|
|
503
|
+
*/
|
|
504
|
+
value: string | number | Array<string | number>;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
/** A single field's schema: the wire-legal keys plus the SDK-only `requiredWhen`. */
|
|
508
|
+
declare interface FormFieldSchema {
|
|
509
|
+
type: string;
|
|
510
|
+
description?: string;
|
|
511
|
+
enum?: string[];
|
|
512
|
+
default?: unknown;
|
|
513
|
+
/**
|
|
514
|
+
* Makes the field required only while this condition holds. Drives the dynamic
|
|
515
|
+
* `missing` list; stripped before the LLM tool — see {@link toWireParameters}.
|
|
516
|
+
*/
|
|
517
|
+
requiredWhen?: FormFieldCondition;
|
|
518
|
+
}
|
|
519
|
+
|
|
411
520
|
/**
|
|
412
521
|
* Form schema for tool calls requiring user input
|
|
413
522
|
*/
|
|
@@ -461,6 +570,27 @@ declare interface SendMessageOptions {
|
|
|
461
570
|
files?: File[];
|
|
462
571
|
}
|
|
463
572
|
|
|
573
|
+
/**
|
|
574
|
+
* Where a completed form is sent.
|
|
575
|
+
* - `"https://..."` (a bare string) — shorthand for `{ via: "client", url }`: the browser
|
|
576
|
+
* POSTs the values to that URL.
|
|
577
|
+
* - `{ via: "client", url }` — same, written out.
|
|
578
|
+
* - `{ via: "client", handler }` — the browser runs your own submit logic.
|
|
579
|
+
* - `{ via: "backend", destination }` — the browser relays the values to the backend,
|
|
580
|
+
* which forwards them to the server-configured destination (URL + secret stay server-side).
|
|
581
|
+
* - `false` — collect only, no submit function.
|
|
582
|
+
*/
|
|
583
|
+
declare type SubmitConfig<V = Record<string, unknown>> = string | {
|
|
584
|
+
via: "client";
|
|
585
|
+
url: string;
|
|
586
|
+
} | {
|
|
587
|
+
via: "client";
|
|
588
|
+
handler: (values: V) => Promise<unknown> | unknown;
|
|
589
|
+
} | {
|
|
590
|
+
via: "backend";
|
|
591
|
+
destination: string;
|
|
592
|
+
} | false;
|
|
593
|
+
|
|
464
594
|
/**
|
|
465
595
|
* Tool call data from SSE stream
|
|
466
596
|
*/
|
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
|
|
@@ -61,6 +75,13 @@ declare class AgoClient {
|
|
|
61
75
|
* Reject a tool call
|
|
62
76
|
*/
|
|
63
77
|
rejectToolCall(toolCallId: string): Promise<void>;
|
|
78
|
+
/**
|
|
79
|
+
* Fetch a backend-stored form collector definition by name (the single source
|
|
80
|
+
* of truth for the form's description, schema, and submit target). Used by
|
|
81
|
+
* `loadFormCollector` / the name-only form of `useFormCollector` so the schema
|
|
82
|
+
* lives in the backend instead of being hardcoded in client code.
|
|
83
|
+
*/
|
|
84
|
+
getFormCollector(name: string): Promise<FormCollectorDefinition>;
|
|
64
85
|
/**
|
|
65
86
|
* Relay a completed form collector's values to a server-configured destination.
|
|
66
87
|
*
|
|
@@ -195,6 +216,11 @@ declare class AgoClient {
|
|
|
195
216
|
}): Promise<AgoClientEvents[K]>;
|
|
196
217
|
/**
|
|
197
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).
|
|
198
224
|
*/
|
|
199
225
|
updateConfig(config: Partial<AgoConfig>): void;
|
|
200
226
|
/**
|
|
@@ -230,8 +256,23 @@ declare interface AgoClientEvents {
|
|
|
230
256
|
*/
|
|
231
257
|
"message:answer-complete": AgoMessage;
|
|
232
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
|
+
};
|
|
233
272
|
"message:error": {
|
|
234
273
|
error: string;
|
|
274
|
+
/** Stable error code (see configuration.md#error-codes) when the failure was an AgoError. */
|
|
275
|
+
code?: string;
|
|
235
276
|
conversationId?: string;
|
|
236
277
|
messageId?: string;
|
|
237
278
|
};
|
|
@@ -260,7 +301,7 @@ declare interface AgoClientEvents {
|
|
|
260
301
|
export declare interface AgoConfig {
|
|
261
302
|
/** API base URL (e.g., https://YOUR-DOMAIN.useago.com) */
|
|
262
303
|
baseUrl: string;
|
|
263
|
-
/**
|
|
304
|
+
/** Per-visitor anonymous ID (X-User-Anon-Id header). Auto-generated if not provided. */
|
|
264
305
|
widgetId?: string;
|
|
265
306
|
/** Default agent (id or slug) for new conversations. Shorthand for `defaultAgentId`. */
|
|
266
307
|
agent?: string;
|
|
@@ -274,6 +315,13 @@ export declare interface AgoConfig {
|
|
|
274
315
|
userJwt?: string;
|
|
275
316
|
/** Enable debug logging */
|
|
276
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;
|
|
277
325
|
}
|
|
278
326
|
|
|
279
327
|
declare type AgoEventHandler<K extends AgoEventName> = (data: AgoClientEvents[K]) => void;
|
|
@@ -417,6 +465,30 @@ export declare interface Conversation {
|
|
|
417
465
|
*/
|
|
418
466
|
declare type DynamicContextProvider = () => ContextEntry | null | undefined;
|
|
419
467
|
|
|
468
|
+
/**
|
|
469
|
+
* The backend-stored shape returned by `GET /api/sdk/v1/forms/{name}` (see
|
|
470
|
+
* {@link AgoClient.getFormCollector}). Mirrors the persistable subset of
|
|
471
|
+
* {@link CreateFormCollectorOptions}: the `submit` here is never the client-only
|
|
472
|
+
* `handler` variant (a function can't be stored server-side).
|
|
473
|
+
*/
|
|
474
|
+
declare interface FormCollectorDefinition<V = Record<string, unknown>> {
|
|
475
|
+
name: string;
|
|
476
|
+
description: string;
|
|
477
|
+
schema: FormCollectorSchema;
|
|
478
|
+
/** Server-stored submit target, if any. Absent means collect-only. */
|
|
479
|
+
submit?: SubmitConfig<V>;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Shape of a form's fields. Mirrors a client function's `parameters` (so the same
|
|
484
|
+
* object feeds the store, the update function, and the dynamic context). Additionally allows the SDK-only per-field `requiredWhen`, which {@link toWireParameters} removes before the schema reaches the LLM.
|
|
485
|
+
*/
|
|
486
|
+
declare interface FormCollectorSchema {
|
|
487
|
+
type: "object";
|
|
488
|
+
properties: Record<string, FormFieldSchema>;
|
|
489
|
+
required?: string[];
|
|
490
|
+
}
|
|
491
|
+
|
|
420
492
|
declare interface FormField {
|
|
421
493
|
type: "string" | "number" | "boolean" | "array";
|
|
422
494
|
title?: string;
|
|
@@ -433,6 +505,43 @@ declare interface FormField_2 {
|
|
|
433
505
|
default?: unknown;
|
|
434
506
|
}
|
|
435
507
|
|
|
508
|
+
/**
|
|
509
|
+
* A field's conditional-requiredness rule. The field becomes required exactly
|
|
510
|
+
* when the controlling `property` matches `value` against the answers collected
|
|
511
|
+
* so far:
|
|
512
|
+
* - a single `value`, no `op` — equality (compared as strings);
|
|
513
|
+
* - a single `value` with `op` — numeric comparison (both sides coerced to numbers);
|
|
514
|
+
* - an array `value`, no `op` — "one of": matches when the property equals any
|
|
515
|
+
* listed value.
|
|
516
|
+
*
|
|
517
|
+
* SDK-only — it is stripped from the schema before it reaches the LLM tool
|
|
518
|
+
*/
|
|
519
|
+
declare interface FormFieldCondition {
|
|
520
|
+
/** The controlling field whose value the rule tests. */
|
|
521
|
+
property: string;
|
|
522
|
+
/** Comparison operator; omitted means equality. Ignored when `value` is an array. */
|
|
523
|
+
op?: ">=" | "<=" | ">" | "<";
|
|
524
|
+
/**
|
|
525
|
+
* The value(s) to test the controlling field against. A single value is an
|
|
526
|
+
* equality (or, with `op`, a numeric comparison); an array is an "is one of"
|
|
527
|
+
* membership test, e.g. `value: ["1", "2", "3"]`.
|
|
528
|
+
*/
|
|
529
|
+
value: string | number | Array<string | number>;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/** A single field's schema: the wire-legal keys plus the SDK-only `requiredWhen`. */
|
|
533
|
+
declare interface FormFieldSchema {
|
|
534
|
+
type: string;
|
|
535
|
+
description?: string;
|
|
536
|
+
enum?: string[];
|
|
537
|
+
default?: unknown;
|
|
538
|
+
/**
|
|
539
|
+
* Makes the field required only while this condition holds. Drives the dynamic
|
|
540
|
+
* `missing` list; stripped before the LLM tool — see {@link toWireParameters}.
|
|
541
|
+
*/
|
|
542
|
+
requiredWhen?: FormFieldCondition;
|
|
543
|
+
}
|
|
544
|
+
|
|
436
545
|
/**
|
|
437
546
|
* Form schema for tool calls requiring user input
|
|
438
547
|
*/
|
|
@@ -479,6 +588,27 @@ declare interface Store<T> {
|
|
|
479
588
|
subscribe(listener: (state: T) => void): () => void;
|
|
480
589
|
}
|
|
481
590
|
|
|
591
|
+
/**
|
|
592
|
+
* Where a completed form is sent.
|
|
593
|
+
* - `"https://..."` (a bare string) — shorthand for `{ via: "client", url }`: the browser
|
|
594
|
+
* POSTs the values to that URL.
|
|
595
|
+
* - `{ via: "client", url }` — same, written out.
|
|
596
|
+
* - `{ via: "client", handler }` — the browser runs your own submit logic.
|
|
597
|
+
* - `{ via: "backend", destination }` — the browser relays the values to the backend,
|
|
598
|
+
* which forwards them to the server-configured destination (URL + secret stay server-side).
|
|
599
|
+
* - `false` — collect only, no submit function.
|
|
600
|
+
*/
|
|
601
|
+
declare type SubmitConfig<V = Record<string, unknown>> = string | {
|
|
602
|
+
via: "client";
|
|
603
|
+
url: string;
|
|
604
|
+
} | {
|
|
605
|
+
via: "client";
|
|
606
|
+
handler: (values: V) => Promise<unknown> | unknown;
|
|
607
|
+
} | {
|
|
608
|
+
via: "backend";
|
|
609
|
+
destination: string;
|
|
610
|
+
} | false;
|
|
611
|
+
|
|
482
612
|
/**
|
|
483
613
|
* Tool call data from SSE stream
|
|
484
614
|
*/
|