@useago/sdk 1.3.2 → 1.4.1
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/README.md +41 -0
- package/dist/{AgoClient-Cwx_eYSu.js → AgoClient-BdtuHX7k.js} +150 -85
- package/dist/AgoClient-CRAnT4qE.cjs +8 -0
- package/dist/angular.cjs +1 -1
- package/dist/angular.d.cts +99 -1
- package/dist/angular.d.ts +99 -1
- package/dist/angular.js +16 -7
- package/dist/{createConversationSession-DV0Xp_3O.cjs → createConversationSession-B8zfTL78.cjs} +1 -1
- package/dist/{createConversationSession-B3h567tt.js → createConversationSession-CWpf4u6I.js} +1 -1
- package/dist/{createFormCollector-CyWisAkI.js → createFormCollector-B4n0_diV.js} +1 -1
- package/dist/{createFormCollector-BB3Uscuo.cjs → createFormCollector-BB_l0Sia.cjs} +1 -1
- package/dist/{createMockClient-DwdxNwEn.js → createMockClient-d-arlmCq.js} +19 -17
- package/dist/createMockClient-ucPENDzz.cjs +1 -0
- package/dist/devtools.d.cts +93 -1
- package/dist/devtools.d.ts +93 -1
- package/dist/helpers.d.cts +5 -1
- package/dist/helpers.d.ts +5 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +93 -1
- package/dist/index.d.ts +93 -1
- package/dist/index.js +4 -4
- package/dist/react.cjs +3 -3
- package/dist/react.d.cts +158 -2
- package/dist/react.d.ts +158 -2
- package/dist/react.js +469 -391
- package/dist/testing.cjs +1 -1
- package/dist/testing.d.cts +93 -1
- package/dist/testing.d.ts +93 -1
- package/dist/testing.js +1 -1
- package/dist/vue.cjs +1 -1
- package/dist/vue.d.cts +125 -1
- package/dist/vue.d.ts +125 -1
- package/dist/vue.js +73 -64
- package/dist/widget.cjs +1 -1
- package/dist/widget.d.cts +93 -1
- package/dist/widget.d.ts +93 -1
- package/dist/widget.js +3 -3
- package/package.json +1 -1
- package/dist/AgoClient-CzSmJQxl.cjs +0 -6
- package/dist/createMockClient-zHQ0cjUH.cjs +0 -1
package/dist/widget.d.cts
CHANGED
|
@@ -146,6 +146,12 @@ declare class AgoClient {
|
|
|
146
146
|
getRegisteredFunctions(): ClientFunctionSchema[];
|
|
147
147
|
/**
|
|
148
148
|
* Register a navigation function that lets AGO navigate users to different pages.
|
|
149
|
+
*
|
|
150
|
+
* Also registers a dynamic context entry (`current-page`) that reports the page
|
|
151
|
+
* the user is currently on, by route name, on every message. This is what lets
|
|
152
|
+
* the agent know *where* it is after it navigates (e.g. so auto-continuation
|
|
153
|
+
* can apply page state on the destination), not just how to navigate away.
|
|
154
|
+
*
|
|
149
155
|
* @param navigate - A callback that performs the navigation (e.g. react-router's navigate)
|
|
150
156
|
* @param routes - Map of route names to paths, with descriptions for the LLM
|
|
151
157
|
*/
|
|
@@ -154,6 +160,41 @@ declare class AgoClient {
|
|
|
154
160
|
path: string;
|
|
155
161
|
description: string;
|
|
156
162
|
}>): void;
|
|
163
|
+
/**
|
|
164
|
+
* Unregister the navigation function and its `current-page` context provider.
|
|
165
|
+
*/
|
|
166
|
+
unregisterNavigationFunction(): void;
|
|
167
|
+
/**
|
|
168
|
+
* Register a "page state" function that lets AGO change the current page's
|
|
169
|
+
* state (filters, sort, view mode, selection…) and reads the current state
|
|
170
|
+
* back as dynamic context. This is the state-mutation mirror of
|
|
171
|
+
* {@link registerNavigationFunction}.
|
|
172
|
+
*
|
|
173
|
+
* It does two things:
|
|
174
|
+
* - Synthesizes ONE client function (default name `setPageState`) whose
|
|
175
|
+
* properties are the controls — all optional, so the agent sets only the
|
|
176
|
+
* ones the user asked for.
|
|
177
|
+
* - Registers a dynamic context provider (keyed `page-state:<fnName>`) that
|
|
178
|
+
* reports each control's current `get()` value on every message.
|
|
179
|
+
*
|
|
180
|
+
* ```ts
|
|
181
|
+
* client.registerPageStateFunction([
|
|
182
|
+
* {
|
|
183
|
+
* name: "statusFilter",
|
|
184
|
+
* description: "Filter the list by review status",
|
|
185
|
+
* schema: { type: "string", enum: ["all", "pending", "approved"] },
|
|
186
|
+
* get: () => filters.status,
|
|
187
|
+
* set: (v) => setFilters({ ...filters, status: v }),
|
|
188
|
+
* },
|
|
189
|
+
* ]);
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
registerPageStateFunction(controls: AgoStateControl[], opts?: AgoPageStateOptions): void;
|
|
193
|
+
/**
|
|
194
|
+
* Unregister a page state function and its dynamic context provider.
|
|
195
|
+
* Mirror of unregistering `navigateToPage`.
|
|
196
|
+
*/
|
|
197
|
+
unregisterPageStateFunction(functionName?: string): void;
|
|
157
198
|
/**
|
|
158
199
|
* Register or update a piece of client-side context.
|
|
159
200
|
* This context is sent with every message so the AI understands the user's situation.
|
|
@@ -386,9 +427,23 @@ declare interface AgoMessage {
|
|
|
386
427
|
followUpReplies?: string[];
|
|
387
428
|
/** Uploaded files on this message (usually the user's). */
|
|
388
429
|
attachments?: AgoAttachment[];
|
|
430
|
+
/**
|
|
431
|
+
* True when the backend flagged this message as hidden (e.g. an
|
|
432
|
+
* auto-continuation nudge). Kept in the model's context but not displayed;
|
|
433
|
+
* UI helpers like `useMessages`/`ChatWidget` filter these out.
|
|
434
|
+
*/
|
|
435
|
+
hidden?: boolean;
|
|
389
436
|
createdAt: Date;
|
|
390
437
|
}
|
|
391
438
|
|
|
439
|
+
/**
|
|
440
|
+
* Options for {@link AgoClient.registerPageStateFunction}.
|
|
441
|
+
*/
|
|
442
|
+
declare interface AgoPageStateOptions {
|
|
443
|
+
/** Name of the synthesized client function. Defaults to "setPageState". */
|
|
444
|
+
functionName?: string;
|
|
445
|
+
}
|
|
446
|
+
|
|
392
447
|
/**
|
|
393
448
|
* Knowledge source citation
|
|
394
449
|
*/
|
|
@@ -398,6 +453,32 @@ declare interface AgoSource {
|
|
|
398
453
|
url?: string;
|
|
399
454
|
}
|
|
400
455
|
|
|
456
|
+
/**
|
|
457
|
+
* A single editable control on the current page (a filter, a sort, a view mode,
|
|
458
|
+
* a selection…). It becomes one optional property of the synthesized
|
|
459
|
+
* `setPageState` function, and its current value is surfaced back to the agent
|
|
460
|
+
* as dynamic context. This is the state-mutation mirror of a navigation route.
|
|
461
|
+
*/
|
|
462
|
+
declare interface AgoStateControl<T = unknown> {
|
|
463
|
+
/** Machine name of the control, e.g. "statusFilter". Becomes a property of the tool. */
|
|
464
|
+
name: string;
|
|
465
|
+
/** Description for the LLM, e.g. "Filter the list by review status". */
|
|
466
|
+
description: string;
|
|
467
|
+
/** JSON schema for a SINGLE field (like one property of navigateToPage). */
|
|
468
|
+
schema: {
|
|
469
|
+
type: "string" | "number" | "boolean" | "array";
|
|
470
|
+
enum?: (string | number)[];
|
|
471
|
+
items?: {
|
|
472
|
+
type: string;
|
|
473
|
+
enum?: (string | number)[];
|
|
474
|
+
};
|
|
475
|
+
};
|
|
476
|
+
/** Current value → pushed as dynamic context so the agent knows what to change. */
|
|
477
|
+
get?: () => T;
|
|
478
|
+
/** Apply the state change on the page. May be async. */
|
|
479
|
+
set: (value: T) => void | Promise<void>;
|
|
480
|
+
}
|
|
481
|
+
|
|
401
482
|
export declare interface AgoWidgetColors {
|
|
402
483
|
button?: string;
|
|
403
484
|
header?: string;
|
|
@@ -507,7 +588,11 @@ declare interface ClientFunctionSchema {
|
|
|
507
588
|
properties: Record<string, {
|
|
508
589
|
type: string;
|
|
509
590
|
description?: string;
|
|
510
|
-
enum?: string[];
|
|
591
|
+
enum?: (string | number)[];
|
|
592
|
+
items?: {
|
|
593
|
+
type: string;
|
|
594
|
+
enum?: (string | number)[];
|
|
595
|
+
};
|
|
511
596
|
default?: unknown;
|
|
512
597
|
}>;
|
|
513
598
|
required?: string[];
|
|
@@ -992,6 +1077,13 @@ declare interface SendMessageOptions {
|
|
|
992
1077
|
agentId?: string;
|
|
993
1078
|
/** File attachments */
|
|
994
1079
|
files?: File[];
|
|
1080
|
+
/**
|
|
1081
|
+
* Mark this message as hidden. The backend keeps it in the model's context but
|
|
1082
|
+
* flags it so the UI never displays it. Used by auto-continuation to nudge the
|
|
1083
|
+
* agent after a navigation without polluting the visible transcript.
|
|
1084
|
+
* Requires backend support for the `hidden` flag; older backends ignore it.
|
|
1085
|
+
*/
|
|
1086
|
+
hidden?: boolean;
|
|
995
1087
|
}
|
|
996
1088
|
|
|
997
1089
|
/**
|
package/dist/widget.d.ts
CHANGED
|
@@ -146,6 +146,12 @@ declare class AgoClient {
|
|
|
146
146
|
getRegisteredFunctions(): ClientFunctionSchema[];
|
|
147
147
|
/**
|
|
148
148
|
* Register a navigation function that lets AGO navigate users to different pages.
|
|
149
|
+
*
|
|
150
|
+
* Also registers a dynamic context entry (`current-page`) that reports the page
|
|
151
|
+
* the user is currently on, by route name, on every message. This is what lets
|
|
152
|
+
* the agent know *where* it is after it navigates (e.g. so auto-continuation
|
|
153
|
+
* can apply page state on the destination), not just how to navigate away.
|
|
154
|
+
*
|
|
149
155
|
* @param navigate - A callback that performs the navigation (e.g. react-router's navigate)
|
|
150
156
|
* @param routes - Map of route names to paths, with descriptions for the LLM
|
|
151
157
|
*/
|
|
@@ -154,6 +160,41 @@ declare class AgoClient {
|
|
|
154
160
|
path: string;
|
|
155
161
|
description: string;
|
|
156
162
|
}>): void;
|
|
163
|
+
/**
|
|
164
|
+
* Unregister the navigation function and its `current-page` context provider.
|
|
165
|
+
*/
|
|
166
|
+
unregisterNavigationFunction(): void;
|
|
167
|
+
/**
|
|
168
|
+
* Register a "page state" function that lets AGO change the current page's
|
|
169
|
+
* state (filters, sort, view mode, selection…) and reads the current state
|
|
170
|
+
* back as dynamic context. This is the state-mutation mirror of
|
|
171
|
+
* {@link registerNavigationFunction}.
|
|
172
|
+
*
|
|
173
|
+
* It does two things:
|
|
174
|
+
* - Synthesizes ONE client function (default name `setPageState`) whose
|
|
175
|
+
* properties are the controls — all optional, so the agent sets only the
|
|
176
|
+
* ones the user asked for.
|
|
177
|
+
* - Registers a dynamic context provider (keyed `page-state:<fnName>`) that
|
|
178
|
+
* reports each control's current `get()` value on every message.
|
|
179
|
+
*
|
|
180
|
+
* ```ts
|
|
181
|
+
* client.registerPageStateFunction([
|
|
182
|
+
* {
|
|
183
|
+
* name: "statusFilter",
|
|
184
|
+
* description: "Filter the list by review status",
|
|
185
|
+
* schema: { type: "string", enum: ["all", "pending", "approved"] },
|
|
186
|
+
* get: () => filters.status,
|
|
187
|
+
* set: (v) => setFilters({ ...filters, status: v }),
|
|
188
|
+
* },
|
|
189
|
+
* ]);
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
registerPageStateFunction(controls: AgoStateControl[], opts?: AgoPageStateOptions): void;
|
|
193
|
+
/**
|
|
194
|
+
* Unregister a page state function and its dynamic context provider.
|
|
195
|
+
* Mirror of unregistering `navigateToPage`.
|
|
196
|
+
*/
|
|
197
|
+
unregisterPageStateFunction(functionName?: string): void;
|
|
157
198
|
/**
|
|
158
199
|
* Register or update a piece of client-side context.
|
|
159
200
|
* This context is sent with every message so the AI understands the user's situation.
|
|
@@ -386,9 +427,23 @@ declare interface AgoMessage {
|
|
|
386
427
|
followUpReplies?: string[];
|
|
387
428
|
/** Uploaded files on this message (usually the user's). */
|
|
388
429
|
attachments?: AgoAttachment[];
|
|
430
|
+
/**
|
|
431
|
+
* True when the backend flagged this message as hidden (e.g. an
|
|
432
|
+
* auto-continuation nudge). Kept in the model's context but not displayed;
|
|
433
|
+
* UI helpers like `useMessages`/`ChatWidget` filter these out.
|
|
434
|
+
*/
|
|
435
|
+
hidden?: boolean;
|
|
389
436
|
createdAt: Date;
|
|
390
437
|
}
|
|
391
438
|
|
|
439
|
+
/**
|
|
440
|
+
* Options for {@link AgoClient.registerPageStateFunction}.
|
|
441
|
+
*/
|
|
442
|
+
declare interface AgoPageStateOptions {
|
|
443
|
+
/** Name of the synthesized client function. Defaults to "setPageState". */
|
|
444
|
+
functionName?: string;
|
|
445
|
+
}
|
|
446
|
+
|
|
392
447
|
/**
|
|
393
448
|
* Knowledge source citation
|
|
394
449
|
*/
|
|
@@ -398,6 +453,32 @@ declare interface AgoSource {
|
|
|
398
453
|
url?: string;
|
|
399
454
|
}
|
|
400
455
|
|
|
456
|
+
/**
|
|
457
|
+
* A single editable control on the current page (a filter, a sort, a view mode,
|
|
458
|
+
* a selection…). It becomes one optional property of the synthesized
|
|
459
|
+
* `setPageState` function, and its current value is surfaced back to the agent
|
|
460
|
+
* as dynamic context. This is the state-mutation mirror of a navigation route.
|
|
461
|
+
*/
|
|
462
|
+
declare interface AgoStateControl<T = unknown> {
|
|
463
|
+
/** Machine name of the control, e.g. "statusFilter". Becomes a property of the tool. */
|
|
464
|
+
name: string;
|
|
465
|
+
/** Description for the LLM, e.g. "Filter the list by review status". */
|
|
466
|
+
description: string;
|
|
467
|
+
/** JSON schema for a SINGLE field (like one property of navigateToPage). */
|
|
468
|
+
schema: {
|
|
469
|
+
type: "string" | "number" | "boolean" | "array";
|
|
470
|
+
enum?: (string | number)[];
|
|
471
|
+
items?: {
|
|
472
|
+
type: string;
|
|
473
|
+
enum?: (string | number)[];
|
|
474
|
+
};
|
|
475
|
+
};
|
|
476
|
+
/** Current value → pushed as dynamic context so the agent knows what to change. */
|
|
477
|
+
get?: () => T;
|
|
478
|
+
/** Apply the state change on the page. May be async. */
|
|
479
|
+
set: (value: T) => void | Promise<void>;
|
|
480
|
+
}
|
|
481
|
+
|
|
401
482
|
export declare interface AgoWidgetColors {
|
|
402
483
|
button?: string;
|
|
403
484
|
header?: string;
|
|
@@ -507,7 +588,11 @@ declare interface ClientFunctionSchema {
|
|
|
507
588
|
properties: Record<string, {
|
|
508
589
|
type: string;
|
|
509
590
|
description?: string;
|
|
510
|
-
enum?: string[];
|
|
591
|
+
enum?: (string | number)[];
|
|
592
|
+
items?: {
|
|
593
|
+
type: string;
|
|
594
|
+
enum?: (string | number)[];
|
|
595
|
+
};
|
|
511
596
|
default?: unknown;
|
|
512
597
|
}>;
|
|
513
598
|
required?: string[];
|
|
@@ -992,6 +1077,13 @@ declare interface SendMessageOptions {
|
|
|
992
1077
|
agentId?: string;
|
|
993
1078
|
/** File attachments */
|
|
994
1079
|
files?: File[];
|
|
1080
|
+
/**
|
|
1081
|
+
* Mark this message as hidden. The backend keeps it in the model's context but
|
|
1082
|
+
* flags it so the UI never displays it. Used by auto-continuation to nudge the
|
|
1083
|
+
* agent after a navigation without polluting the visible transcript.
|
|
1084
|
+
* Requires backend support for the `hidden` flag; older backends ignore it.
|
|
1085
|
+
*/
|
|
1086
|
+
hidden?: boolean;
|
|
995
1087
|
}
|
|
996
1088
|
|
|
997
1089
|
/**
|
package/dist/widget.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as Ut, i as Wt, m as Gt, o as Vt, s as jt, t as qt } from "./AgoClient-
|
|
2
|
-
import { r as Kt, t as Xt } from "./createFormCollector-
|
|
3
|
-
import { t as Qt } from "./createConversationSession-
|
|
1
|
+
import { a as Ut, i as Wt, m as Gt, o as Vt, s as jt, t as qt } from "./AgoClient-BdtuHX7k.js";
|
|
2
|
+
import { r as Kt, t as Xt } from "./createFormCollector-B4n0_diV.js";
|
|
3
|
+
import { t as Qt } from "./createConversationSession-CWpf4u6I.js";
|
|
4
4
|
var Yt = '"IBM Plex Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif', Se = `var(--ago-font, ${Yt})`, dt = {
|
|
5
5
|
font: "--ago-font",
|
|
6
6
|
radius: "--ago-radius",
|
package/package.json
CHANGED
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
var h=class extends Error{constructor(e,t,n){super(e),this.code=t,this.statusCode=n,this.name="AgoError"}},u=class b extends h{constructor(t,n,r,s,i,a){super(t,n,r),this.type=s,this.param=i,this.docUrl=a,this.name="AgoApiError"}static fromResponse(t,n){const r=t.error;return new b(r.doc_url?`${r.message} See ${r.doc_url}`:r.message,r.code,n,r.type,r.param,r.doc_url)}},d=class extends h{constructor(e,t){super(e,"network_error"),this.originalError=t,this.name="AgoNetworkError"}},m=class extends h{constructor(e,t="stream_error"){super(e,t),this.name="AgoStreamError"}},f=class extends h{constructor(e,t,n){super(e,"function_error"),this.functionName=t,this.originalError=n,this.name="AgoFunctionError"}},R=class{constructor(e=!1){this.enabled=e}enable(){this.enabled=!0}disable(){this.enabled=!1}log(...e){this.enabled&&console.log("[AGO SDK]",...e)}warn(...e){this.enabled&&console.warn("[AGO SDK]",...e)}error(...e){console.error("[AGO SDK]",...e)}debug(...e){this.enabled&&console.debug("[AGO SDK]",...e)}},o=new R,y="ago_widget_id";function I(){if(typeof localStorage<"u"){const t=localStorage.getItem(y);if(t)return t}const e=typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`ago-${Date.now().toString(36)}-${Math.random().toString(36).slice(2,12)}`;if(typeof localStorage<"u")try{localStorage.setItem(y,e)}catch{}return e}var x=class{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.headers={"X-User-Anon-Id":e.widgetId||I()},e.userEmail&&(this.headers["X-User-Email"]=e.userEmail),e.userJwt&&(this.headers.Authorization=`Bearer ${e.userJwt}`),e.permission&&(this.headers["X-Widget-Permission"]=e.permission)}updateConfig(e){e.baseUrl&&(this.baseUrl=e.baseUrl.replace(/\/$/,"")),e.widgetId&&(this.headers["X-User-Anon-Id"]=e.widgetId),e.userEmail&&(this.headers["X-User-Email"]=e.userEmail),e.userJwt&&(this.headers.Authorization=`Bearer ${e.userJwt}`),e.permission!==void 0&&(e.permission?this.headers["X-Widget-Permission"]=e.permission:delete this.headers["X-Widget-Permission"])}async get(e){return this.request("GET",e)}async post(e,t){return this.request("POST",e,t)}async postStream(e,t){const n=`${this.baseUrl}${e}`;o.debug("POST (stream)",n,t);try{const r=await fetch(n,{method:"POST",headers:{...this.headers,"Content-Type":"application/json"},body:t?JSON.stringify(t):void 0});return r.ok||await this.handleErrorResponse(r),r}catch(r){throw r instanceof u?r:new d(`Network error: ${r instanceof Error?r.message:"Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`,r instanceof Error?r:void 0)}}async postFormData(e,t){const n=`${this.baseUrl}${e}`;o.debug("POST (formData)",n);const r={...this.headers};try{const s=await fetch(n,{method:"POST",headers:r,body:t});return s.ok||await this.handleErrorResponse(s),s}catch(s){throw s instanceof u?s:new d(`Network error: ${s instanceof Error?s.message:"Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`,s instanceof Error?s:void 0)}}async request(e,t,n){const r=`${this.baseUrl}${t}`;o.debug(e,r,n);try{const s=await fetch(r,{method:e,headers:{...this.headers,"Content-Type":"application/json"},body:n?JSON.stringify(n):void 0});return s.ok||await this.handleErrorResponse(s),s.status===204?void 0:s.json()}catch(s){throw s instanceof u?s:new d(`Network error: ${s instanceof Error?s.message:"Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`,s instanceof Error?s:void 0)}}async handleErrorResponse(e){let t;try{t=await e.json()}catch{}if(t?.error)throw u.fromResponse(t,e.status);let n="";throw e.status===401||e.status===403?n=" Check `userJwt` (and that it has not expired).":e.status===404&&(n=" Check that `baseUrl` points at your AGO API root."),new u(`HTTP ${e.status}: ${e.statusText}.${n}`,"http_error",e.status,"api_error")}},C=class{constructor(){this.functions=new Map}register(e,t,n){if(typeof e=="object"){const{name:s,handler:i,description:a,parameters:c}=e;return this.register(s,i,{description:a,parameters:c})}const r=e;if(!t||!n)throw new h(`registerFunction("${r}"): both a handler and a schema are required. Pass them as arguments or use the single-object form: registerFunction({ name, parameters, handler }).`,"function_invalid_registration");this.functions.has(r)&&o.warn(`Function "${r}" is being overwritten`),this.functions.set(r,{schema:{...n,name:r},handler:t}),o.log(`Registered function: ${r}`)}unregister(e){const t=this.functions.delete(e);return t&&o.log(`Unregistered function: ${e}`),t}get(e){return this.functions.get(e)}has(e){return this.functions.has(e)}getSchemas(){return Array.from(this.functions.values()).map(e=>e.schema)}async execute(e,t){const n=this.functions.get(e);if(!n)throw new f(`Function "${e}" is not registered`,e);o.log(`Executing function: ${e}`,t);try{const r=await n.handler(t);return o.log(`Function ${e} completed:`,r),r}catch(r){throw o.error(`Function ${e} failed:`,r),new f(`Function "${e}" execution failed: ${r instanceof Error?r.message:"Unknown error"}`,e,r instanceof Error?r:void 0)}}clear(){this.functions.clear(),o.log("Cleared all registered functions")}get size(){return this.functions.size}},E=class{constructor(){this.entries=new Map,this.dynamicProviders=new Map}set(e,t){this.entries.set(e,t),o.log(`ClientContext set: ${e}`)}remove(e){const t=this.entries.delete(e);return t&&o.log(`ClientContext removed: ${e}`),t}addDynamicProvider(e,t){this.dynamicProviders.set(e,t),o.log(`DynamicContext provider added: ${e}`)}removeDynamicProvider(e){const t=this.dynamicProviders.delete(e);return t&&o.log(`DynamicContext provider removed: ${e}`),t}getSnapshot(){if(this.entries.size===0&&this.dynamicProviders.size===0)return null;const e={};for(const[t,n]of this.entries)e[t]=n;for(const[t,n]of this.dynamicProviders)try{const r=n();r&&(e[t]=r)}catch(r){o.error(`DynamicContext provider "${t}" threw:`,r)}return Object.keys(e).length===0?null:{entries:e}}clear(){this.entries.clear(),this.dynamicProviders.clear(),o.log("ClientContext cleared")}};function g(e){return e===null||typeof e!="object"?JSON.stringify(e)??"null":Array.isArray(e)?`[${e.map(g).join(",")}]`:`{${Object.keys(e).sort().map(t=>`${JSON.stringify(t)}:${g(e[t])}`).join(",")}}`}var _=class{constructor(e){this.callbacks=e,this.buffer="",this.message={},this.toolCalls=[],this.sources=[],this.followUpReplies=[],this.isFirstChunk=!0,this.answerCompleteEmitted=!1,this.firedClientFunctions=new Set}async processStream(e){if(!e.body)throw new m("Response has no body. The endpoint did not return a stream: check that `baseUrl` points at an AGO API and nothing (proxy, mock) strips the SSE body.","stream_no_body");const t=e.body.getReader(),n=new TextDecoder;try{for(;;){const{done:r,value:s}=await t.read();if(r)break;const i=n.decode(s,{stream:!0});this.buffer+=i,this.processBuffer()}return this.buffer.trim()&&this.processBuffer(),this.buildFinalMessage()}catch(r){const s=r instanceof Error?r:new m("Stream processing failed mid-flight. The connection may have dropped; retry the message.");throw this.callbacks.onError?.(s),s}finally{t.releaseLock()}}processBuffer(){const e=this.buffer.split(`
|
|
2
|
-
|
|
3
|
-
`);this.buffer=e.pop()||"";for(const t of e){if(!t.trim())continue;const n=t.split(`
|
|
4
|
-
`);for(const r of n)if(!r.startsWith(": ")&&r.startsWith("data: ")){const s=r.slice(6);try{const i=JSON.parse(s);this.handleChunk(i)}catch(i){o.warn("Failed to parse SSE data:",s,i)}}}}handleChunk(e){if(this.callbacks.onRawChunk?.(e),e.message_id&&!this.message.id&&(this.message.id=e.message_id),e.thread?.id&&(this.message.conversationId=e.thread.id,this.isFirstChunk&&this.message.id&&(this.isFirstChunk=!1,this.callbacks.onStart?.({conversationId:this.message.conversationId,messageId:this.message.id}))),e.content!==void 0&&(this.message.content=(this.message.content||"")+e.content,this.message.conversationId&&this.message.id&&this.callbacks.onChunk?.({content:e.content,conversationId:this.message.conversationId,messageId:this.message.id})),e.full_content!==void 0&&(this.message.content=e.full_content),e.status&&(this.message.status=e.status),e.agent&&(this.message.agent={id:e.agent.id,name:e.agent.name,displayName:e.agent.display_name}),e.knowledge_sources&&(this.sources=e.knowledge_sources.map(t=>{const n=t.knowledge_document;return{id:n.id,title:n.title,url:n.use_external_link?n.external_link_url:n.internal_link_url}})),e.type==="client_function"&&e.function_name){const t=`${e.function_name}::${g(e.arguments??{})}`;this.firedClientFunctions.has(t)||(this.firedClientFunctions.add(t),this.callbacks.onClientFunction?.({invocationId:e.id||"",functionName:e.function_name,arguments:e.arguments||{},conversationId:this.message.conversationId||""}))}if(e.tool_call_data&&e.type&&e.type!=="client_function"){const t=this.parseToolCall(e);this.callbacks.onToolCall?.(t);const n=this.toolCalls.findIndex(r=>r.id===t.id);n>=0?this.toolCalls[n]=t:this.toolCalls.push(t)}e.follow_up_replies&&(this.followUpReplies=e.follow_up_replies),this.message.status==="DONE"&&!this.answerCompleteEmitted&&this.message.id&&(this.answerCompleteEmitted=!0,this.callbacks.onAnswerComplete?.(this.buildMessage()))}parseToolCall(e){return{id:e.id||"",type:e.type||"status_message",status:e.status||"unknown",toolName:e.tool_name||"",toolDisplayName:e.tool_display_name,message:e.message,formSchema:e.form_schema,data:e.data,functionName:e.function_name,arguments:e.arguments}}buildMessage(){return{id:this.message.id||"",conversationId:this.message.conversationId||"",content:this.message.content||"",role:"assistant",status:this.message.status||"DONE",agent:this.message.agent,sources:this.sources.length>0?this.sources:void 0,toolCalls:this.toolCalls.length>0?this.toolCalls:void 0,followUpReplies:this.followUpReplies.length>0?this.followUpReplies:void 0,createdAt:new Date}}buildFinalMessage(){const e=this.buildMessage();return this.callbacks.onComplete?.(e),e}};function F(e){const t=e.message.toLowerCase();return t.includes("load failed")||t.includes("failed to fetch")||t.includes("network")||t.includes("abort")}var U=new Set(["image/jpeg","image/png","image/gif","image/webp","image/bmp","image/tiff"]);function S(e){if(!e)return;const t=typeof window<"u"&&window.location?window.location.href:"https://ago.local/";try{const n=new URL(e,t);if(n.protocol==="http:"||n.protocol==="https:"||n.protocol==="blob:")return e}catch{}}function O(e){return e.isSafeImage===!0&&typeof e.contentType=="string"&&e.contentType.startsWith("image/")&&S(e.url)!==void 0}function P(e){if(e==null||e<0)return"";if(e<1024)return`${e} B`;const t=e/1024;return t<1024?`${t.toFixed(1)} KB`:`${(t/1024).toFixed(1)} MB`}function j(e){return{id:String(e.id??""),name:typeof e.name=="string"&&e.name?e.name:"file",contentType:typeof e.content_type=="string"?e.content_type:void 0,fileSize:typeof e.file_size=="number"?e.file_size:void 0,url:typeof e.file_url=="string"?e.file_url:void 0,isSafeImage:e.is_safe_image===!0}}function T(e){return e.map((t,n)=>({id:`local-${n}-${t.name}`,name:t.name,contentType:t.type||void 0,fileSize:t.size,url:typeof URL<"u"&&URL.createObjectURL?URL.createObjectURL(t):void 0,isSafeImage:U.has(t.type)}))}var A=class{constructor(){this.handlers=new Map}on(e,t){this.handlers.has(e)||this.handlers.set(e,new Set),this.handlers.get(e).add(t)}off(e,t){const n=this.handlers.get(e);n&&n.delete(t)}emit(e,t){const n=this.handlers.get(e);n&&n.forEach(r=>{try{r(t)}catch(s){console.error(`Error in event handler for ${String(e)}:`,s)}})}once(e,t){const n=(r=>{this.off(e,n),t(r)});this.on(e,n)}waitFor(e,t){return new Promise((n,r)=>{let s;const i=(a=>{s&&clearTimeout(s),n(a)});this.once(e,i),t?.timeout&&(s=setTimeout(()=>{this.off(e,i),r(new Error(`waitFor("${String(e)}") timed out after ${t.timeout}ms`))},t.timeout))})}removeAllListeners(e){e?this.handlers.delete(e):this.handlers.clear()}},w='`baseUrl` is required, e.g. new AgoClient({ baseUrl: "https://YOUR-DOMAIN.api.useago.com" }). Try the live demo endpoint https://playground.api.useago.com. See docs/general/configuration.md#error-codes (config_missing_base_url).',D=/^[a-z][a-z0-9+.-]*:\/\//i,v=!1;function p(e,t="AgoClient"){if(typeof e!="object"||e===null)throw new h(`${t}: ${w}`,"config_missing_base_url");const n=e.baseUrl;if(typeof n!="string"||n.trim()==="")throw new h(`${t}: ${w}`,"config_missing_base_url");!n.startsWith("/")&&!D.test(n)&&(v||(v=!0,console.warn(`[AGO] ${t}: \`baseUrl\` has no protocol and is not a relative path (config_suspect_base_url). Requests will fail: Node throws a URL parse error, browsers fetch it as a relative path. Use "https://..." (or a "/path" for a same-origin proxy).`)))}var N=class k{constructor(t){this.warnedEmptyConversations=new Set,p(t,"AgoClient"),this.config=t,this.httpClient=new x(t),this.functionRegistry=new C,this.contextRegistry=new E,this.eventEmitter=new A,t.debug&&o.enable(),o.log("AgoClient initialized")}async sendMessage(t,n){const r=this.functionRegistry.getSchemas(),s=this.contextRegistry.getSnapshot(),i=this.config.agent||this.config.defaultAgentId,a={content:t,conversation_id:n?.conversationId,agent_id:n?.agentId||i};r.length>0&&(a.client_functions=r),s&&(a.client_context=s);let c;if(n?.files&&n.files.length>0){const l=new FormData;l.append("content",t),n.conversationId&&l.append("conversation_id",n.conversationId),(n.agentId||i)&&l.append("agent_id",n.agentId||i||""),r.length>0&&l.append("client_functions",JSON.stringify(r)),s&&l.append("client_context",JSON.stringify(s));for(const $ of n.files)l.append("files",$);c=await this.httpClient.postFormData("/api/sdk/v1/messages",l)}else c=await this.httpClient.postStream("/api/sdk/v1/messages",a);return this.processSSEResponse(c)}async processSSEResponse(t){let n=!1;const r=await new _({onRawChunk:s=>{this.eventEmitter.emit("stream:message",s)},onStart:s=>{this.eventEmitter.emit("message:start",s)},onChunk:s=>{this.eventEmitter.emit("message:chunk",s)},onToolCall:s=>{this.eventEmitter.emit("toolCall:received",s),s.type==="form"&&this.eventEmitter.emit("toolCall:form",s)},onClientFunction:async s=>{n=!0,this.eventEmitter.emit("function:invoke",s),await this.handleClientFunctionInvocation(s)},onAnswerComplete:s=>{this.eventEmitter.emit("message:answer-complete",s)},onComplete:s=>{this.eventEmitter.emit("message:complete",s)},onError:s=>{this.eventEmitter.emit("message:error",{error:s.message,code:s instanceof h?s.code:void 0})}}).processStream(t);return this.maybeFlagEmptyReply(r,n),r}maybeFlagEmptyReply(t,n){t.status==="DONE"&&(t.content??"").trim()===""&&!n&&!(t.toolCalls&&t.toolCalls.length>0)&&!(t.followUpReplies&&t.followUpReplies.length>0)&&setTimeout(()=>{if(this.eventEmitter.emit("message:empty",{conversationId:t.conversationId??"",messageId:t.id??""}),this.config.warnOnEmptyReply===!1)return;const r=t.conversationId||"(no conversation)";if(this.warnedEmptyConversations.has(r))return;this.warnedEmptyConversations.add(r);const s=this.config.agent||this.config.defaultAgentId;t.id?console.warn("[AGO] Reply completed with empty content. Possible causes: "+(s?`the agent "${s}" may not exist for this tenant, `:"an unknown `agent` slug, ")+"or the agent replied with no text. Listen for the `message:empty` event to handle this in your app; silence this warning with `warnOnEmptyReply: false`."):console.warn("[AGO] The stream completed without any message data. Possible causes: "+(s?`the agent "${s}" may not exist for this tenant, or `:"")+"`baseUrl` does not point at an AGO endpoint that returns server-sent events. Listen for the `message:empty` event to handle this in your app; silence this warning with `warnOnEmptyReply: false`.")},0)}async handleClientFunctionInvocation(t){let n,r;try{n=await this.functionRegistry.execute(t.functionName,t.arguments)}catch(s){r=s instanceof Error?s.message:"Unknown error",o.error("Client function execution failed:",s)}if(t.invocationId)try{await this.submitToolCallForm(t.invocationId,{result:n,error:r,_type:"client_function_result"})}catch(s){o.error("Failed to submit function result:",s)}this.eventEmitter.emit("function:result",{invocationId:t.invocationId,result:n,error:r})}async getConversations(){return(await this.httpClient.get("/api/sdk/v1/conversations")).items.map(t=>({id:t.id,title:t.title,lastMessageDate:new Date(t.last_message_date)}))}async getConversation(t){const n=await this.httpClient.get(`/api/sdk/v1/conversations/${t}`),r={id:n.id,title:n.title,lastMessageDate:new Date(n.last_message_date),messages:n.messages.map(s=>({id:s.id,conversationId:n.id,content:s.content,role:s.role,status:s.status,createdAt:new Date(s.created_at),toolCalls:k.mapPersistedToolCalls(s.tool_call_data),attachments:s.attachments&&s.attachments.length>0?s.attachments.map(j):void 0}))};return this.eventEmitter.emit("conversation:loaded",r),r}static mapPersistedToolCalls(t){if(!(!t||t.length===0))return t.map(n=>({id:String(n.id??""),type:n.type??"status_message",status:String(n.status??"unknown"),toolName:n.tool_name??"",toolDisplayName:n.tool_display_name,message:n.message,formSchema:n.form_schema,data:n.data,functionName:n.function_name,arguments:n.arguments}))}async getMessages(t){return(await this.getConversation(t)).messages||[]}async submitToolCallForm(t,n){await this.httpClient.post(`/api/sdk/v1/tool-calls/${t}/submit`,{formData:n})}async confirmToolCall(t){await this.httpClient.post(`/api/tool-calls/${t}/confirm/`)}async rejectToolCall(t){await this.httpClient.post(`/api/tool-calls/${t}/reject/`)}async getFormCollector(t){const n=await this.httpClient.get(`/api/sdk/v1/forms/${encodeURIComponent(t)}`);return{name:n.name,description:n.description,schema:n.schema,submit:n.submit??void 0}}async submitFormCollector(t,n){return this.httpClient.post("/api/sdk/v1/forms/submit",{name:t,values:n})}async submitFeedback(t,n){await this.httpClient.post(`/api/sdk/v1/messages/${t}/feedback`,{rating:n})}registerFunction(t,n,r){typeof t=="object"?this.functionRegistry.register(t):this.functionRegistry.register(t,n,r)}register(t){if(Array.isArray(t))for(const n of t)this.functionRegistry.register(n);else this.functionRegistry.register(t)}unregisterFunction(t){return this.functionRegistry.unregister(t)}getRegisteredFunctions(){return this.functionRegistry.getSchemas()}registerNavigationFunction(t,n){const r=n.map(i=>i.name),s=n.map(i=>`- "${i.name}": ${i.description}`).join(`
|
|
5
|
-
`);this.registerFunction("navigateToPage",async i=>{const a=i.page,c=n.find(l=>l.name===a);return c?(t(c.path),{success:!0,navigatedTo:c.path}):{success:!1,error:`Unknown page: ${a}`}},{description:`Navigate the user to a page in the application. Available pages:
|
|
6
|
-
${s}`,parameters:{type:"object",properties:{page:{type:"string",description:"The page to navigate to",enum:r}},required:["page"]}})}setContext(t,n){this.contextRegistry.set(t,n),this.notifyContextChanged()}removeContext(t){const n=this.contextRegistry.remove(t);return n&&this.notifyContextChanged(),n}addDynamicContext(t,n){this.contextRegistry.addDynamicProvider(t,n),this.notifyContextChanged()}removeDynamicContext(t){const n=this.contextRegistry.removeDynamicProvider(t);return n&&this.notifyContextChanged(),n}notifyContextChanged(){this.eventEmitter.emit("context:changed",this.contextRegistry.getSnapshot())}emitFormEvent(t,n){this.eventEmitter.emit(t,n)}enableAutoPageContext(){this.addDynamicContext("browser-page",()=>{const t=typeof window<"u"?window.location.href:void 0,n=typeof document<"u"?document.title:void 0;return!t&&!n?null:{name:"Browser page",description:"Current page the user is viewing",data:{url:t,title:n}}})}getContextSnapshot(){return this.contextRegistry.getSnapshot()}on(t,n){this.eventEmitter.on(t,n)}off(t,n){this.eventEmitter.off(t,n)}once(t,n){this.eventEmitter.once(t,n)}waitFor(t,n){return this.eventEmitter.waitFor(t,n)}updateConfig(t){const n={};for(const[s,i]of Object.entries(t))i!==void 0&&(n[s]=i);const r={...this.config,...n};p(r,"AgoClient.updateConfig"),this.config=r,this.httpClient.updateConfig(n),n.debug!==void 0&&(n.debug?o.enable():o.disable())}destroy(){this.eventEmitter.removeAllListeners(),this.functionRegistry.clear(),this.contextRegistry.clear(),o.log("AgoClient destroyed")}};Object.defineProperty(exports,"AgoApiError",{enumerable:!0,get:function(){return u}});Object.defineProperty(exports,"AgoClient",{enumerable:!0,get:function(){return N}});Object.defineProperty(exports,"AgoError",{enumerable:!0,get:function(){return h}});Object.defineProperty(exports,"AgoFunctionError",{enumerable:!0,get:function(){return f}});Object.defineProperty(exports,"AgoNetworkError",{enumerable:!0,get:function(){return d}});Object.defineProperty(exports,"AgoStreamError",{enumerable:!0,get:function(){return m}});Object.defineProperty(exports,"ClientContextRegistry",{enumerable:!0,get:function(){return E}});Object.defineProperty(exports,"EventEmitter",{enumerable:!0,get:function(){return A}});Object.defineProperty(exports,"FunctionRegistry",{enumerable:!0,get:function(){return C}});Object.defineProperty(exports,"SSEHandler",{enumerable:!0,get:function(){return _}});Object.defineProperty(exports,"attachmentsFromFiles",{enumerable:!0,get:function(){return T}});Object.defineProperty(exports,"canInlineImage",{enumerable:!0,get:function(){return O}});Object.defineProperty(exports,"formatFileSize",{enumerable:!0,get:function(){return P}});Object.defineProperty(exports,"isStreamNetworkError",{enumerable:!0,get:function(){return F}});Object.defineProperty(exports,"logger",{enumerable:!0,get:function(){return o}});Object.defineProperty(exports,"safeAttachmentUrl",{enumerable:!0,get:function(){return S}});Object.defineProperty(exports,"validateConfig",{enumerable:!0,get:function(){return p}});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function C(g={}){const{overrides:u={}}=g,d={id:"mock-msg-1",conversationId:"mock-conv-1",content:"Mock response",role:"assistant",status:"DONE",createdAt:new Date},l={id:"mock-conv-1",title:"Mock Conversation",lastMessageDate:new Date},t=new Map,r=[],m={sendMessage:async()=>d,getConversations:async()=>[l],getConversation:async()=>l,getMessages:async()=>[d],submitToolCallForm:async()=>{},confirmToolCall:async()=>{},rejectToolCall:async()=>{},submitFeedback:async()=>{},registerFunction:()=>{},unregisterFunction:()=>!0,getRegisteredFunctions:()=>[],getContextSnapshot:()=>null,notifyContextChanged:()=>{},registerNavigationFunction:()=>{},on:(e,o)=>{t.has(e)||t.set(e,new Set),t.get(e).add(o)},off:(e,o)=>{t.get(e)?.delete(o)},once:(e,o)=>{const n=(...i)=>{t.get(e)?.delete(n),o(...i)};t.has(e)||t.set(e,new Set),t.get(e).add(n)},waitFor:(e,o)=>new Promise((n,i)=>{let a;const c=f=>{a&&clearTimeout(a),t.get(e)?.delete(c),n(f)};t.has(e)||t.set(e,new Set),t.get(e).add(c),o?.timeout&&(a=setTimeout(()=>{t.get(e)?.delete(c),i(new Error(`waitFor("${e}") timed out after ${o.timeout}ms`))},o.timeout))}),updateConfig:()=>{},destroy:()=>{t.clear()},...u},s={};for(const[e,o]of Object.entries(m))s[e]=(...n)=>(r.push({method:e,args:n}),o(...n));return s.__calls=r,s.__callsFor=e=>r.filter(o=>o.method===e),s.__emitEvent=(e,o)=>{const n=t.get(e);n&&[...n].forEach(i=>i(o))},s}Object.defineProperty(exports,"createMockClient",{enumerable:!0,get:function(){return C}});
|