@useago/sdk 0.1.6 → 0.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{createMockClient-BZKh_1em.cjs → AgoClient-BDO4avLq.cjs} +219 -124
- package/dist/AgoClient-BDO4avLq.cjs.map +1 -0
- package/dist/{createMockClient-uGlVyjbL.js → AgoClient-D-c91tx5.js} +221 -126
- package/dist/AgoClient-D-c91tx5.js.map +1 -0
- package/dist/angular/ago.service.d.ts +98 -0
- package/dist/angular/index.d.ts +4 -0
- package/dist/angular/provide.d.ts +27 -0
- package/dist/angular.cjs +105 -0
- package/dist/angular.cjs.map +1 -0
- package/dist/angular.d.ts +1 -0
- package/dist/angular.js +105 -0
- package/dist/angular.js.map +1 -0
- package/dist/auto/createAgo.d.ts +39 -0
- package/dist/auto/index.d.ts +1 -0
- package/dist/client/AgoClient.d.ts +56 -0
- package/dist/client/types.d.ts +4 -6
- package/dist/createMockClient-B1DcBiIK.js +94 -0
- package/dist/createMockClient-B1DcBiIK.js.map +1 -0
- package/dist/createMockClient-BqNSJUu4.cjs +93 -0
- package/dist/createMockClient-BqNSJUu4.cjs.map +1 -0
- package/dist/functions-B0Z0rNQW.cjs +306 -0
- package/dist/functions-B0Z0rNQW.cjs.map +1 -0
- package/dist/functions-C-wLEc8b.js +306 -0
- package/dist/functions-C-wLEc8b.js.map +1 -0
- package/dist/helpers/factory.d.ts +20 -0
- package/dist/helpers/functions.d.ts +62 -0
- package/dist/helpers/index.d.ts +1 -0
- package/dist/helpers.cjs +17 -0
- package/dist/helpers.cjs.map +1 -0
- package/dist/helpers.d.ts +1 -0
- package/dist/helpers.js +17 -0
- package/dist/helpers.js.map +1 -0
- package/dist/index.cjs +179 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +6 -0
- package/dist/index.js +173 -5
- package/dist/index.js.map +1 -1
- package/dist/react/context/AgoContext.d.ts +30 -4
- package/dist/react/context/index.d.ts +1 -1
- package/dist/react/hooks/index.d.ts +1 -0
- package/dist/react/hooks/useAgoContext.d.ts +40 -0
- package/dist/react/hooks/useAgoFunction.d.ts +14 -2
- package/dist/react/index.d.ts +2 -1
- package/dist/react.cjs +76 -11
- package/dist/react.cjs.map +1 -1
- package/dist/react.js +81 -17
- package/dist/react.js.map +1 -1
- package/dist/state/ClientContextRegistry.d.ts +64 -0
- package/dist/streaming/helpers.d.ts +67 -0
- package/dist/vue/composables/useAgo.d.ts +17 -0
- package/dist/vue/composables/useAgoEvents.d.ts +11 -0
- package/dist/vue/composables/useAgoFunction.d.ts +34 -0
- package/dist/vue/composables/useChat.d.ts +251 -0
- package/dist/vue/composables/useConversation.d.ts +178 -0
- package/dist/vue/composables/useMessages.d.ts +89 -0
- package/dist/vue/index.d.ts +10 -0
- package/dist/vue/plugin.d.ts +16 -0
- package/dist/vue/symbols.d.ts +3 -0
- package/dist/vue.cjs +232 -0
- package/dist/vue.cjs.map +1 -0
- package/dist/vue.d.ts +1 -0
- package/dist/vue.js +232 -0
- package/dist/vue.js.map +1 -0
- package/dist/widget/types.d.ts +1 -0
- package/package.json +23 -3
- package/dist/createMockClient-BZKh_1em.cjs.map +0 -1
- package/dist/createMockClient-uGlVyjbL.js.map +0 -1
|
@@ -77,14 +77,26 @@ class Logger {
|
|
|
77
77
|
}
|
|
78
78
|
}
|
|
79
79
|
const logger = new Logger();
|
|
80
|
-
const
|
|
80
|
+
const WIDGET_ID_KEY = "ago_widget_id";
|
|
81
|
+
function generateWidgetId() {
|
|
82
|
+
if (typeof localStorage !== "undefined") {
|
|
83
|
+
const stored = localStorage.getItem(WIDGET_ID_KEY);
|
|
84
|
+
if (stored) return stored;
|
|
85
|
+
}
|
|
86
|
+
const id = crypto.randomUUID();
|
|
87
|
+
if (typeof localStorage !== "undefined") {
|
|
88
|
+
try {
|
|
89
|
+
localStorage.setItem(WIDGET_ID_KEY, id);
|
|
90
|
+
} catch {
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return id;
|
|
94
|
+
}
|
|
81
95
|
class HttpClient {
|
|
82
96
|
constructor(config) {
|
|
83
|
-
|
|
84
|
-
this.baseUrl = ((_a = config.baseUrl) == null ? void 0 : _a.replace(/\/$/, "")) || DEFAULT_BASE_URL;
|
|
97
|
+
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
85
98
|
this.headers = {
|
|
86
|
-
"X-Widget-
|
|
87
|
-
"X-Widget-Id": config.widgetId
|
|
99
|
+
"X-Widget-Id": config.widgetId || generateWidgetId()
|
|
88
100
|
};
|
|
89
101
|
if (config.userEmail) {
|
|
90
102
|
this.headers["X-User-Email"] = config.userEmail;
|
|
@@ -100,9 +112,6 @@ class HttpClient {
|
|
|
100
112
|
if (config.baseUrl) {
|
|
101
113
|
this.baseUrl = config.baseUrl.replace(/\/$/, "");
|
|
102
114
|
}
|
|
103
|
-
if (config.apiKey) {
|
|
104
|
-
this.headers["X-Widget-Key"] = config.apiKey;
|
|
105
|
-
}
|
|
106
115
|
if (config.widgetId) {
|
|
107
116
|
this.headers["X-Widget-Id"] = config.widgetId;
|
|
108
117
|
}
|
|
@@ -316,6 +325,86 @@ class FunctionRegistry {
|
|
|
316
325
|
return this.functions.size;
|
|
317
326
|
}
|
|
318
327
|
}
|
|
328
|
+
class ClientContextRegistry {
|
|
329
|
+
constructor() {
|
|
330
|
+
this.entries = /* @__PURE__ */ new Map();
|
|
331
|
+
this.dynamicProviders = /* @__PURE__ */ new Map();
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Register or update a static context entry.
|
|
335
|
+
*/
|
|
336
|
+
set(key, entry) {
|
|
337
|
+
this.entries.set(key, entry);
|
|
338
|
+
logger.log(`ClientContext set: ${key}`);
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Remove a static context entry (typically on component unmount).
|
|
342
|
+
*/
|
|
343
|
+
remove(key) {
|
|
344
|
+
const deleted = this.entries.delete(key);
|
|
345
|
+
if (deleted) {
|
|
346
|
+
logger.log(`ClientContext removed: ${key}`);
|
|
347
|
+
}
|
|
348
|
+
return deleted;
|
|
349
|
+
}
|
|
350
|
+
/**
|
|
351
|
+
* Register a dynamic context provider. The function is called every time
|
|
352
|
+
* a message is sent, so it always returns the freshest data.
|
|
353
|
+
*
|
|
354
|
+
* Use this for context that lives outside React state — global stores,
|
|
355
|
+
* refs, or computed values that shouldn't trigger re-renders.
|
|
356
|
+
*/
|
|
357
|
+
addDynamicProvider(key, provider) {
|
|
358
|
+
this.dynamicProviders.set(key, provider);
|
|
359
|
+
logger.log(`DynamicContext provider added: ${key}`);
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Remove a dynamic context provider.
|
|
363
|
+
*/
|
|
364
|
+
removeDynamicProvider(key) {
|
|
365
|
+
const deleted = this.dynamicProviders.delete(key);
|
|
366
|
+
if (deleted) {
|
|
367
|
+
logger.log(`DynamicContext provider removed: ${key}`);
|
|
368
|
+
}
|
|
369
|
+
return deleted;
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* Build a snapshot of the current client context.
|
|
373
|
+
* Evaluates every registered dynamic provider. Returns `null` when there is
|
|
374
|
+
* nothing to report.
|
|
375
|
+
*/
|
|
376
|
+
getSnapshot() {
|
|
377
|
+
if (this.entries.size === 0 && this.dynamicProviders.size === 0) {
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
const entries = {};
|
|
381
|
+
for (const [key, entry] of this.entries) {
|
|
382
|
+
entries[key] = entry;
|
|
383
|
+
}
|
|
384
|
+
for (const [key, provider] of this.dynamicProviders) {
|
|
385
|
+
try {
|
|
386
|
+
const entry = provider();
|
|
387
|
+
if (entry) {
|
|
388
|
+
entries[key] = entry;
|
|
389
|
+
}
|
|
390
|
+
} catch (err) {
|
|
391
|
+
logger.error(`DynamicContext provider "${key}" threw:`, err);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
if (Object.keys(entries).length === 0) {
|
|
395
|
+
return null;
|
|
396
|
+
}
|
|
397
|
+
return { entries };
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Remove all entries and dynamic providers.
|
|
401
|
+
*/
|
|
402
|
+
clear() {
|
|
403
|
+
this.entries.clear();
|
|
404
|
+
this.dynamicProviders.clear();
|
|
405
|
+
logger.log("ClientContext cleared");
|
|
406
|
+
}
|
|
407
|
+
}
|
|
319
408
|
class SSEHandler {
|
|
320
409
|
constructor(callbacks) {
|
|
321
410
|
this.callbacks = callbacks;
|
|
@@ -428,18 +517,17 @@ class SSEHandler {
|
|
|
428
517
|
};
|
|
429
518
|
});
|
|
430
519
|
}
|
|
431
|
-
if (data.
|
|
520
|
+
if (data.type === "client_function" && data.function_name) {
|
|
521
|
+
(_g = (_f = this.callbacks).onClientFunction) == null ? void 0 : _g.call(_f, {
|
|
522
|
+
invocationId: data.id || "",
|
|
523
|
+
functionName: data.function_name,
|
|
524
|
+
arguments: data.arguments || {},
|
|
525
|
+
conversationId: this.message.conversationId || ""
|
|
526
|
+
});
|
|
527
|
+
}
|
|
528
|
+
if (data.tool_call_data && data.type && data.type !== "client_function") {
|
|
432
529
|
const toolCall = this.parseToolCall(data);
|
|
433
|
-
|
|
434
|
-
(_g = (_f = this.callbacks).onClientFunction) == null ? void 0 : _g.call(_f, {
|
|
435
|
-
invocationId: data.id,
|
|
436
|
-
functionName: data.function_name,
|
|
437
|
-
arguments: data.arguments || {},
|
|
438
|
-
conversationId: this.message.conversationId || ""
|
|
439
|
-
});
|
|
440
|
-
} else {
|
|
441
|
-
(_i = (_h = this.callbacks).onToolCall) == null ? void 0 : _i.call(_h, toolCall);
|
|
442
|
-
}
|
|
530
|
+
(_i = (_h = this.callbacks).onToolCall) == null ? void 0 : _i.call(_h, toolCall);
|
|
443
531
|
const existingIndex = this.toolCalls.findIndex((t) => t.id === toolCall.id);
|
|
444
532
|
if (existingIndex >= 0) {
|
|
445
533
|
this.toolCalls[existingIndex] = toolCall;
|
|
@@ -558,6 +646,7 @@ class AgoClient {
|
|
|
558
646
|
this.config = config;
|
|
559
647
|
this.httpClient = new HttpClient(config);
|
|
560
648
|
this.functionRegistry = new FunctionRegistry();
|
|
649
|
+
this.contextRegistry = new ClientContextRegistry();
|
|
561
650
|
this.eventEmitter = new EventEmitter();
|
|
562
651
|
if (config.debug) {
|
|
563
652
|
logger.enable();
|
|
@@ -572,6 +661,7 @@ class AgoClient {
|
|
|
572
661
|
*/
|
|
573
662
|
async sendMessage(content, options) {
|
|
574
663
|
const clientFunctions = this.functionRegistry.getSchemas();
|
|
664
|
+
const clientContext = this.contextRegistry.getSnapshot();
|
|
575
665
|
const body = {
|
|
576
666
|
content,
|
|
577
667
|
conversation_id: options == null ? void 0 : options.conversationId,
|
|
@@ -580,6 +670,9 @@ class AgoClient {
|
|
|
580
670
|
if (clientFunctions.length > 0) {
|
|
581
671
|
body.client_functions = clientFunctions;
|
|
582
672
|
}
|
|
673
|
+
if (clientContext) {
|
|
674
|
+
body.client_context = clientContext;
|
|
675
|
+
}
|
|
583
676
|
let response;
|
|
584
677
|
if ((options == null ? void 0 : options.files) && options.files.length > 0) {
|
|
585
678
|
const formData = new FormData();
|
|
@@ -593,6 +686,9 @@ class AgoClient {
|
|
|
593
686
|
if (clientFunctions.length > 0) {
|
|
594
687
|
formData.append("client_functions", JSON.stringify(clientFunctions));
|
|
595
688
|
}
|
|
689
|
+
if (clientContext) {
|
|
690
|
+
formData.append("client_context", JSON.stringify(clientContext));
|
|
691
|
+
}
|
|
596
692
|
for (const file of options.files) {
|
|
597
693
|
formData.append("files", file);
|
|
598
694
|
}
|
|
@@ -638,20 +734,22 @@ class AgoClient {
|
|
|
638
734
|
error = err instanceof Error ? err.message : "Unknown error";
|
|
639
735
|
logger.error("Client function execution failed:", err);
|
|
640
736
|
}
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
result,
|
|
650
|
-
|
|
651
|
-
});
|
|
652
|
-
} catch (submitError) {
|
|
653
|
-
logger.error("Failed to submit function result:", submitError);
|
|
737
|
+
if (data.invocationId) {
|
|
738
|
+
try {
|
|
739
|
+
await this.submitToolCallForm(data.invocationId, {
|
|
740
|
+
result,
|
|
741
|
+
error,
|
|
742
|
+
_type: "client_function_result"
|
|
743
|
+
});
|
|
744
|
+
} catch (submitError) {
|
|
745
|
+
logger.error("Failed to submit function result:", submitError);
|
|
746
|
+
}
|
|
654
747
|
}
|
|
748
|
+
this.eventEmitter.emit("function:result", {
|
|
749
|
+
invocationId: data.invocationId,
|
|
750
|
+
result,
|
|
751
|
+
error
|
|
752
|
+
});
|
|
655
753
|
}
|
|
656
754
|
// ─────────────────────────────────────────────────────────────────
|
|
657
755
|
// Conversations
|
|
@@ -734,6 +832,23 @@ class AgoClient {
|
|
|
734
832
|
this.functionRegistry.register(nameOrDef, handler, schema);
|
|
735
833
|
}
|
|
736
834
|
}
|
|
835
|
+
/**
|
|
836
|
+
* Short alias for `registerFunction`. Also accepts an array of definitions.
|
|
837
|
+
*
|
|
838
|
+
* ```ts
|
|
839
|
+
* client.register(lookupOrder);
|
|
840
|
+
* client.register([lookupOrder, cancelOrder]);
|
|
841
|
+
* ```
|
|
842
|
+
*/
|
|
843
|
+
register(definition) {
|
|
844
|
+
if (Array.isArray(definition)) {
|
|
845
|
+
for (const def of definition) {
|
|
846
|
+
this.functionRegistry.register(def);
|
|
847
|
+
}
|
|
848
|
+
} else {
|
|
849
|
+
this.functionRegistry.register(definition);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
737
852
|
/**
|
|
738
853
|
* Unregister a client-side function
|
|
739
854
|
*/
|
|
@@ -783,6 +898,75 @@ ${routeDescriptions}`,
|
|
|
783
898
|
);
|
|
784
899
|
}
|
|
785
900
|
// ─────────────────────────────────────────────────────────────────
|
|
901
|
+
// Client Context
|
|
902
|
+
// ─────────────────────────────────────────────────────────────────
|
|
903
|
+
/**
|
|
904
|
+
* Register or update a piece of client-side context.
|
|
905
|
+
* This context is sent with every message so the AI understands the user's situation.
|
|
906
|
+
*
|
|
907
|
+
* ```ts
|
|
908
|
+
* client.setContext("order-page", {
|
|
909
|
+
* name: "Order detail",
|
|
910
|
+
* description: "User is viewing order #123",
|
|
911
|
+
* data: { orderId: "123", status: "shipped" },
|
|
912
|
+
* });
|
|
913
|
+
* ```
|
|
914
|
+
*/
|
|
915
|
+
setContext(key, entry) {
|
|
916
|
+
this.contextRegistry.set(key, entry);
|
|
917
|
+
}
|
|
918
|
+
/**
|
|
919
|
+
* Remove a previously registered context entry.
|
|
920
|
+
*/
|
|
921
|
+
removeContext(key) {
|
|
922
|
+
return this.contextRegistry.remove(key);
|
|
923
|
+
}
|
|
924
|
+
/**
|
|
925
|
+
* Register a dynamic context provider. The callback is invoked every time
|
|
926
|
+
* a message is sent, so the AI always gets the freshest data.
|
|
927
|
+
*
|
|
928
|
+
* Use this for context that lives outside React state — global stores,
|
|
929
|
+
* refs, or computed values.
|
|
930
|
+
*
|
|
931
|
+
* ```ts
|
|
932
|
+
* client.addDynamicContext("cart", () => ({
|
|
933
|
+
* name: "Checkout",
|
|
934
|
+
* data: { itemCount: cart.items.length, total: cart.total },
|
|
935
|
+
* }));
|
|
936
|
+
* ```
|
|
937
|
+
*/
|
|
938
|
+
addDynamicContext(key, provider) {
|
|
939
|
+
this.contextRegistry.addDynamicProvider(key, provider);
|
|
940
|
+
}
|
|
941
|
+
/**
|
|
942
|
+
* Remove a dynamic context provider.
|
|
943
|
+
*/
|
|
944
|
+
removeDynamicContext(key) {
|
|
945
|
+
return this.contextRegistry.removeDynamicProvider(key);
|
|
946
|
+
}
|
|
947
|
+
/**
|
|
948
|
+
* Enable automatic capture of the current browser page (URL + title).
|
|
949
|
+
* Injected as a dynamic context entry named `browser-page`.
|
|
950
|
+
*/
|
|
951
|
+
enableAutoPageContext() {
|
|
952
|
+
this.contextRegistry.addDynamicProvider("browser-page", () => {
|
|
953
|
+
const url = typeof window !== "undefined" ? window.location.href : void 0;
|
|
954
|
+
const title = typeof document !== "undefined" ? document.title : void 0;
|
|
955
|
+
if (!url && !title) return null;
|
|
956
|
+
return {
|
|
957
|
+
name: "Browser page",
|
|
958
|
+
description: "Current page the user is viewing",
|
|
959
|
+
data: { url, title }
|
|
960
|
+
};
|
|
961
|
+
});
|
|
962
|
+
}
|
|
963
|
+
/**
|
|
964
|
+
* Get the current context snapshot.
|
|
965
|
+
*/
|
|
966
|
+
getContextSnapshot() {
|
|
967
|
+
return this.contextRegistry.getSnapshot();
|
|
968
|
+
}
|
|
969
|
+
// ─────────────────────────────────────────────────────────────────
|
|
786
970
|
// Events
|
|
787
971
|
// ─────────────────────────────────────────────────────────────────
|
|
788
972
|
/**
|
|
@@ -832,111 +1016,22 @@ ${routeDescriptions}`,
|
|
|
832
1016
|
destroy() {
|
|
833
1017
|
this.eventEmitter.removeAllListeners();
|
|
834
1018
|
this.functionRegistry.clear();
|
|
1019
|
+
this.contextRegistry.clear();
|
|
835
1020
|
logger.log("AgoClient destroyed");
|
|
836
1021
|
}
|
|
837
1022
|
}
|
|
838
|
-
function createMockClient(options = {}) {
|
|
839
|
-
const { overrides = {} } = options;
|
|
840
|
-
const noopMessage = {
|
|
841
|
-
id: "mock-msg-1",
|
|
842
|
-
conversationId: "mock-conv-1",
|
|
843
|
-
content: "Mock response",
|
|
844
|
-
role: "assistant",
|
|
845
|
-
status: "DONE",
|
|
846
|
-
createdAt: /* @__PURE__ */ new Date()
|
|
847
|
-
};
|
|
848
|
-
const noopConversation = {
|
|
849
|
-
id: "mock-conv-1",
|
|
850
|
-
title: "Mock Conversation",
|
|
851
|
-
lastMessageDate: /* @__PURE__ */ new Date()
|
|
852
|
-
};
|
|
853
|
-
const listeners = /* @__PURE__ */ new Map();
|
|
854
|
-
const calls = [];
|
|
855
|
-
const defaults = {
|
|
856
|
-
sendMessage: async () => noopMessage,
|
|
857
|
-
getConversations: async () => [noopConversation],
|
|
858
|
-
getConversation: async () => noopConversation,
|
|
859
|
-
getMessages: async () => [noopMessage],
|
|
860
|
-
submitToolCallForm: async () => void 0,
|
|
861
|
-
confirmToolCall: async () => void 0,
|
|
862
|
-
rejectToolCall: async () => void 0,
|
|
863
|
-
submitFeedback: async () => void 0,
|
|
864
|
-
registerFunction: () => void 0,
|
|
865
|
-
unregisterFunction: () => true,
|
|
866
|
-
getRegisteredFunctions: () => [],
|
|
867
|
-
registerNavigationFunction: () => void 0,
|
|
868
|
-
on: (event, handler) => {
|
|
869
|
-
if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
|
|
870
|
-
listeners.get(event).add(handler);
|
|
871
|
-
},
|
|
872
|
-
off: (event, handler) => {
|
|
873
|
-
var _a;
|
|
874
|
-
(_a = listeners.get(event)) == null ? void 0 : _a.delete(handler);
|
|
875
|
-
},
|
|
876
|
-
once: (event, handler) => {
|
|
877
|
-
const wrapper = (...args) => {
|
|
878
|
-
var _a;
|
|
879
|
-
(_a = listeners.get(event)) == null ? void 0 : _a.delete(wrapper);
|
|
880
|
-
handler(...args);
|
|
881
|
-
};
|
|
882
|
-
if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
|
|
883
|
-
listeners.get(event).add(wrapper);
|
|
884
|
-
},
|
|
885
|
-
waitFor: (event, options2) => {
|
|
886
|
-
return new Promise((resolve, reject) => {
|
|
887
|
-
let timer;
|
|
888
|
-
const handler = (data) => {
|
|
889
|
-
var _a;
|
|
890
|
-
if (timer) clearTimeout(timer);
|
|
891
|
-
(_a = listeners.get(event)) == null ? void 0 : _a.delete(handler);
|
|
892
|
-
resolve(data);
|
|
893
|
-
};
|
|
894
|
-
if (!listeners.has(event)) listeners.set(event, /* @__PURE__ */ new Set());
|
|
895
|
-
listeners.get(event).add(handler);
|
|
896
|
-
if (options2 == null ? void 0 : options2.timeout) {
|
|
897
|
-
timer = setTimeout(() => {
|
|
898
|
-
var _a;
|
|
899
|
-
(_a = listeners.get(event)) == null ? void 0 : _a.delete(handler);
|
|
900
|
-
reject(new Error(`waitFor("${event}") timed out after ${options2.timeout}ms`));
|
|
901
|
-
}, options2.timeout);
|
|
902
|
-
}
|
|
903
|
-
});
|
|
904
|
-
},
|
|
905
|
-
updateConfig: () => void 0,
|
|
906
|
-
destroy: () => {
|
|
907
|
-
listeners.clear();
|
|
908
|
-
}
|
|
909
|
-
};
|
|
910
|
-
const merged = { ...defaults, ...overrides };
|
|
911
|
-
const mock = {};
|
|
912
|
-
for (const [key, fn] of Object.entries(merged)) {
|
|
913
|
-
mock[key] = (...args) => {
|
|
914
|
-
calls.push({ method: key, args });
|
|
915
|
-
return fn(...args);
|
|
916
|
-
};
|
|
917
|
-
}
|
|
918
|
-
mock.__calls = calls;
|
|
919
|
-
mock.__callsFor = (method) => calls.filter((c) => c.method === method);
|
|
920
|
-
mock.__emitEvent = (event, data) => {
|
|
921
|
-
const handlers = listeners.get(event);
|
|
922
|
-
if (handlers) {
|
|
923
|
-
[...handlers].forEach((h) => h(data));
|
|
924
|
-
}
|
|
925
|
-
};
|
|
926
|
-
return mock;
|
|
927
|
-
}
|
|
928
1023
|
export {
|
|
929
|
-
|
|
1024
|
+
AgoClient as A,
|
|
1025
|
+
ClientContextRegistry as C,
|
|
930
1026
|
EventEmitter as E,
|
|
931
1027
|
FunctionRegistry as F,
|
|
932
1028
|
SSEHandler as S,
|
|
933
|
-
|
|
1029
|
+
AgoApiError as a,
|
|
934
1030
|
AgoError as b,
|
|
935
1031
|
AgoFunctionError as c,
|
|
936
1032
|
AgoNetworkError as d,
|
|
937
1033
|
AgoStreamError as e,
|
|
938
|
-
createMockClient as f,
|
|
939
1034
|
isStreamNetworkError as i,
|
|
940
1035
|
logger as l
|
|
941
1036
|
};
|
|
942
|
-
//# sourceMappingURL=
|
|
1037
|
+
//# sourceMappingURL=AgoClient-D-c91tx5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgoClient-D-c91tx5.js","sources":["../src/client/errors.ts","../src/utils/logger.ts","../src/api/HttpClient.ts","../src/functions/FunctionRegistry.ts","../src/state/ClientContextRegistry.ts","../src/streaming/SSEHandler.ts","../src/utils/eventEmitter.ts","../src/client/AgoClient.ts"],"sourcesContent":["/**\n * Base error class for AGO SDK\n */\nexport class AgoError extends Error {\n constructor(\n message: string,\n public code: string,\n public statusCode?: number\n ) {\n super(message);\n this.name = \"AgoError\";\n }\n}\n\n/**\n * Error from API response\n */\nexport class AgoApiError extends AgoError {\n constructor(\n message: string,\n code: string,\n statusCode: number,\n public type: string,\n public param?: string,\n public docUrl?: string\n ) {\n super(message, code, statusCode);\n this.name = \"AgoApiError\";\n }\n\n static fromResponse(data: ApiErrorResponse, statusCode: number): AgoApiError {\n const error = data.error;\n return new AgoApiError(\n error.message,\n error.code,\n statusCode,\n error.type,\n error.param,\n error.doc_url\n );\n }\n}\n\nexport interface ApiErrorResponse {\n error: {\n type: string;\n code: string;\n message: string;\n param?: string;\n doc_url?: string;\n };\n}\n\n/**\n * Network/connection error\n */\nexport class AgoNetworkError extends AgoError {\n constructor(message: string, public originalError?: Error) {\n super(message, \"network_error\");\n this.name = \"AgoNetworkError\";\n }\n}\n\n/**\n * SSE stream error\n */\nexport class AgoStreamError extends AgoError {\n constructor(message: string) {\n super(message, \"stream_error\");\n this.name = \"AgoStreamError\";\n }\n}\n\n/**\n * Function execution error\n */\nexport class AgoFunctionError extends AgoError {\n constructor(\n message: string,\n public functionName: string,\n public originalError?: Error\n ) {\n super(message, \"function_error\");\n this.name = \"AgoFunctionError\";\n }\n}\n","/**\n * Debug logger for SDK\n */\nexport class Logger {\n constructor(private enabled: boolean = false) {}\n\n enable(): void {\n this.enabled = true;\n }\n\n disable(): void {\n this.enabled = false;\n }\n\n log(...args: unknown[]): void {\n if (this.enabled) {\n console.log(\"[AGO SDK]\", ...args);\n }\n }\n\n warn(...args: unknown[]): void {\n if (this.enabled) {\n console.warn(\"[AGO SDK]\", ...args);\n }\n }\n\n error(...args: unknown[]): void {\n // Always log errors\n console.error(\"[AGO SDK]\", ...args);\n }\n\n debug(...args: unknown[]): void {\n if (this.enabled) {\n console.debug(\"[AGO SDK]\", ...args);\n }\n }\n}\n\nexport const logger = new Logger();\n","import { AgoApiError, AgoNetworkError, ApiErrorResponse } from \"../client/errors\";\nimport type { AgoConfig } from \"../client/types\";\nimport { logger } from \"../utils/logger\";\n\nconst WIDGET_ID_KEY = \"ago_widget_id\";\n\nfunction generateWidgetId(): string {\n // Try to reuse a previously generated ID from localStorage\n if (typeof localStorage !== \"undefined\") {\n const stored = localStorage.getItem(WIDGET_ID_KEY);\n if (stored) return stored;\n }\n\n const id = crypto.randomUUID();\n\n if (typeof localStorage !== \"undefined\") {\n try {\n localStorage.setItem(WIDGET_ID_KEY, id);\n } catch {\n // localStorage may be unavailable (e.g., private browsing)\n }\n }\n\n return id;\n}\n\n/**\n * HTTP client with authentication headers\n */\nexport class HttpClient {\n private baseUrl: string;\n private headers: Record<string, string>;\n\n constructor(config: AgoConfig) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, \"\");\n this.headers = {\n \"X-Widget-Id\": config.widgetId || generateWidgetId(),\n };\n\n if (config.userEmail) {\n this.headers[\"X-User-Email\"] = config.userEmail;\n }\n\n if (config.userJwt) {\n this.headers[\"Authorization\"] = `Bearer ${config.userJwt}`;\n }\n }\n\n /**\n * Update configuration (e.g., JWT token)\n */\n updateConfig(config: Partial<AgoConfig>): void {\n if (config.baseUrl) {\n this.baseUrl = config.baseUrl.replace(/\\/$/, \"\");\n }\n if (config.widgetId) {\n this.headers[\"X-Widget-Id\"] = config.widgetId;\n }\n if (config.userEmail) {\n this.headers[\"X-User-Email\"] = config.userEmail;\n }\n if (config.userJwt) {\n this.headers[\"Authorization\"] = `Bearer ${config.userJwt}`;\n }\n }\n\n /**\n * Make a GET request\n */\n async get<T>(path: string): Promise<T> {\n return this.request<T>(\"GET\", path);\n }\n\n /**\n * Make a POST request with JSON body\n */\n async post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(\"POST\", path, body);\n }\n\n /**\n * Make a POST request and return the raw Response (for streaming)\n */\n async postStream(path: string, body?: unknown): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n logger.debug(\"POST (stream)\", url, body);\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers: {\n ...this.headers,\n \"Content-Type\": \"application/json\",\n },\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n return response;\n } catch (error) {\n if (error instanceof AgoApiError) {\n throw error;\n }\n throw new AgoNetworkError(\n `Network error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Make a POST request with FormData (for file uploads)\n */\n async postFormData(path: string, formData: FormData): Promise<Response> {\n const url = `${this.baseUrl}${path}`;\n logger.debug(\"POST (formData)\", url);\n\n // Don't set Content-Type for FormData - browser sets it with boundary\n const headers = { ...this.headers };\n\n try {\n const response = await fetch(url, {\n method: \"POST\",\n headers,\n body: formData,\n });\n\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n return response;\n } catch (error) {\n if (error instanceof AgoApiError) {\n throw error;\n }\n throw new AgoNetworkError(\n `Network error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown\n ): Promise<T> {\n const url = `${this.baseUrl}${path}`;\n logger.debug(method, url, body);\n\n try {\n const response = await fetch(url, {\n method,\n headers: {\n ...this.headers,\n \"Content-Type\": \"application/json\",\n },\n body: body ? JSON.stringify(body) : undefined,\n });\n\n if (!response.ok) {\n await this.handleErrorResponse(response);\n }\n\n // Handle 204 No Content\n if (response.status === 204) {\n return undefined as T;\n }\n\n return response.json();\n } catch (error) {\n if (error instanceof AgoApiError) {\n throw error;\n }\n throw new AgoNetworkError(\n `Network error: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n error instanceof Error ? error : undefined\n );\n }\n }\n\n private async handleErrorResponse(response: Response): Promise<never> {\n let errorData: ApiErrorResponse | undefined;\n\n try {\n errorData = await response.json();\n } catch {\n // Response is not JSON\n }\n\n if (errorData?.error) {\n throw AgoApiError.fromResponse(errorData, response.status);\n }\n\n throw new AgoApiError(\n `HTTP ${response.status}: ${response.statusText}`,\n \"http_error\",\n response.status,\n \"api_error\"\n );\n }\n}\n","import { AgoFunctionError } from \"../client/errors\";\nimport { logger } from \"../utils/logger\";\nimport type {\n ClientFunctionDefinition,\n ClientFunctionHandler,\n ClientFunctionSchema,\n RegisteredFunction,\n} from \"./types\";\n\n/**\n * Registry for client-side functions that AGO can call\n */\nexport class FunctionRegistry {\n private functions: Map<string, RegisteredFunction> = new Map();\n\n /**\n * Register a function that AGO can call.\n * Accepts either a single definition object or (name, handler, schema) args.\n */\n register(definition: ClientFunctionDefinition): void;\n register(\n name: string,\n handler: ClientFunctionHandler,\n schema: Omit<ClientFunctionSchema, \"name\">\n ): void;\n register(\n nameOrDef: string | ClientFunctionDefinition,\n handler?: ClientFunctionHandler,\n schema?: Omit<ClientFunctionSchema, \"name\">\n ): void {\n if (typeof nameOrDef === \"object\") {\n const { name, handler: h, description, parameters } = nameOrDef;\n return this.register(name, h, { description, parameters });\n }\n\n const name = nameOrDef;\n if (!handler || !schema) {\n throw new Error(\"handler and schema are required\");\n }\n if (this.functions.has(name)) {\n logger.warn(`Function \"${name}\" is being overwritten`);\n }\n\n this.functions.set(name, {\n schema: { ...schema, name },\n handler,\n });\n\n logger.log(`Registered function: ${name}`);\n }\n\n /**\n * Unregister a function\n */\n unregister(name: string): boolean {\n const deleted = this.functions.delete(name);\n if (deleted) {\n logger.log(`Unregistered function: ${name}`);\n }\n return deleted;\n }\n\n /**\n * Get a registered function\n */\n get(name: string): RegisteredFunction | undefined {\n return this.functions.get(name);\n }\n\n /**\n * Check if a function is registered\n */\n has(name: string): boolean {\n return this.functions.has(name);\n }\n\n /**\n * Get all registered function schemas (for sending to backend)\n */\n getSchemas(): ClientFunctionSchema[] {\n return Array.from(this.functions.values()).map((f) => f.schema);\n }\n\n /**\n * Execute a registered function\n */\n async execute(\n name: string,\n args: Record<string, unknown>\n ): Promise<unknown> {\n const registration = this.functions.get(name);\n\n if (!registration) {\n throw new AgoFunctionError(\n `Function \"${name}\" is not registered`,\n name\n );\n }\n\n logger.log(`Executing function: ${name}`, args);\n\n try {\n const result = await registration.handler(args);\n logger.log(`Function ${name} completed:`, result);\n return result;\n } catch (error) {\n logger.error(`Function ${name} failed:`, error);\n throw new AgoFunctionError(\n `Function \"${name}\" execution failed: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n name,\n error instanceof Error ? error : undefined\n );\n }\n }\n\n /**\n * Clear all registered functions\n */\n clear(): void {\n this.functions.clear();\n logger.log(\"Cleared all registered functions\");\n }\n\n /**\n * Get the number of registered functions\n */\n get size(): number {\n return this.functions.size;\n }\n}\n","import { logger } from \"../utils/logger\";\n\n/**\n * A single piece of context the client wants the LLM to know about.\n */\nexport interface ContextEntry {\n /** Human-readable label (e.g. \"Order detail\", \"Current user\") */\n name?: string;\n /** Short description of what this context represents */\n description?: string;\n /** Arbitrary structured data the AI should know about */\n data?: Record<string, unknown>;\n}\n\n/**\n * Serialised client context sent with each message.\n */\nexport interface ContextSnapshot {\n /** All active context entries keyed by their registration key */\n entries: Record<string, ContextEntry>;\n}\n\n/**\n * A function that returns a fresh context entry on demand.\n * Evaluated every time a message is sent — use it to pull data from stores,\n * refs, or any source that isn't captured by React state.\n */\nexport type DynamicContextProvider = () => ContextEntry | null | undefined;\n\n/**\n * Registry that collects client-side context from across the component tree.\n *\n * Components register/unregister context slices via unique keys.\n * When a message is sent the registry produces a single snapshot.\n */\nexport class ClientContextRegistry {\n private entries: Map<string, ContextEntry> = new Map();\n private dynamicProviders: Map<string, DynamicContextProvider> = new Map();\n\n /**\n * Register or update a static context entry.\n */\n set(key: string, entry: ContextEntry): void {\n this.entries.set(key, entry);\n logger.log(`ClientContext set: ${key}`);\n }\n\n /**\n * Remove a static context entry (typically on component unmount).\n */\n remove(key: string): boolean {\n const deleted = this.entries.delete(key);\n if (deleted) {\n logger.log(`ClientContext removed: ${key}`);\n }\n return deleted;\n }\n\n /**\n * Register a dynamic context provider. The function is called every time\n * a message is sent, so it always returns the freshest data.\n *\n * Use this for context that lives outside React state — global stores,\n * refs, or computed values that shouldn't trigger re-renders.\n */\n addDynamicProvider(key: string, provider: DynamicContextProvider): void {\n this.dynamicProviders.set(key, provider);\n logger.log(`DynamicContext provider added: ${key}`);\n }\n\n /**\n * Remove a dynamic context provider.\n */\n removeDynamicProvider(key: string): boolean {\n const deleted = this.dynamicProviders.delete(key);\n if (deleted) {\n logger.log(`DynamicContext provider removed: ${key}`);\n }\n return deleted;\n }\n\n /**\n * Build a snapshot of the current client context.\n * Evaluates every registered dynamic provider. Returns `null` when there is\n * nothing to report.\n */\n getSnapshot(): ContextSnapshot | null {\n if (this.entries.size === 0 && this.dynamicProviders.size === 0) {\n return null;\n }\n\n const entries: Record<string, ContextEntry> = {};\n for (const [key, entry] of this.entries) {\n entries[key] = entry;\n }\n\n for (const [key, provider] of this.dynamicProviders) {\n try {\n const entry = provider();\n if (entry) {\n entries[key] = entry;\n }\n } catch (err) {\n logger.error(`DynamicContext provider \"${key}\" threw:`, err);\n }\n }\n\n if (Object.keys(entries).length === 0) {\n return null;\n }\n\n return { entries };\n }\n\n /**\n * Remove all entries and dynamic providers.\n */\n clear(): void {\n this.entries.clear();\n this.dynamicProviders.clear();\n logger.log(\"ClientContext cleared\");\n }\n}\n","import type {\n AgoMessage,\n AgoSource,\n ToolCallData,\n SSEChunkData,\n} from \"../client/types\";\nimport { AgoStreamError } from \"../client/errors\";\nimport { logger } from \"../utils/logger\";\n\nexport interface SSEHandlerCallbacks {\n onStart?: (data: { conversationId: string; messageId: string }) => void;\n onChunk?: (data: { content: string; conversationId: string; messageId: string }) => void;\n onToolCall?: (toolCall: ToolCallData) => void;\n onClientFunction?: (data: {\n invocationId: string;\n functionName: string;\n arguments: Record<string, unknown>;\n conversationId: string;\n }) => void;\n onComplete?: (message: AgoMessage) => void;\n onError?: (error: Error) => void;\n}\n\n/**\n * Handles SSE streaming responses from AGO backend\n */\nexport class SSEHandler {\n private buffer = \"\";\n private message: Partial<AgoMessage> = {};\n private toolCalls: ToolCallData[] = [];\n private sources: AgoSource[] = [];\n private followUpReplies: string[] = [];\n private isFirstChunk = true;\n\n constructor(private callbacks: SSEHandlerCallbacks) {}\n\n /**\n * Process a streaming response\n */\n async processStream(response: Response): Promise<AgoMessage> {\n if (!response.body) {\n throw new AgoStreamError(\"Response has no body\");\n }\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n\n if (done) {\n break;\n }\n\n const text = decoder.decode(value, { stream: true });\n this.buffer += text;\n this.processBuffer();\n }\n\n // Process any remaining data\n if (this.buffer.trim()) {\n this.processBuffer();\n }\n\n return this.buildFinalMessage();\n } catch (error) {\n const streamError =\n error instanceof Error ? error : new AgoStreamError(\"Stream processing failed\");\n this.callbacks.onError?.(streamError);\n throw streamError;\n } finally {\n reader.releaseLock();\n }\n }\n\n private processBuffer(): void {\n // SSE messages are separated by double newlines\n const parts = this.buffer.split(\"\\n\\n\");\n\n // Keep the last part (might be incomplete)\n this.buffer = parts.pop() || \"\";\n\n for (const part of parts) {\n if (!part.trim()) continue;\n\n // Handle SSE format: \"data: {...}\" or \": heartbeat\"\n const lines = part.split(\"\\n\");\n\n for (const line of lines) {\n if (line.startsWith(\": \")) {\n // Comment/heartbeat, ignore\n continue;\n }\n\n if (line.startsWith(\"data: \")) {\n const jsonStr = line.slice(6);\n try {\n const data = JSON.parse(jsonStr) as SSEChunkData;\n this.handleChunk(data);\n } catch (error) {\n logger.warn(\"Failed to parse SSE data:\", jsonStr, error);\n }\n }\n }\n }\n }\n\n private handleChunk(data: SSEChunkData): void {\n // Handle message ID and conversation ID\n if (data.message_id && !this.message.id) {\n this.message.id = data.message_id;\n }\n\n if (data.thread?.id) {\n this.message.conversationId = data.thread.id;\n\n // Emit start event on first chunk with IDs\n if (this.isFirstChunk && this.message.id) {\n this.isFirstChunk = false;\n this.callbacks.onStart?.({\n conversationId: this.message.conversationId,\n messageId: this.message.id,\n });\n }\n }\n\n // Handle content\n if (data.content !== undefined) {\n this.message.content = (this.message.content || \"\") + data.content;\n if (this.message.conversationId && this.message.id) {\n this.callbacks.onChunk?.({\n content: data.content,\n conversationId: this.message.conversationId,\n messageId: this.message.id,\n });\n }\n }\n\n // Handle full content replacement\n if (data.full_content !== undefined) {\n this.message.content = data.full_content;\n }\n\n // Handle status\n if (data.status) {\n this.message.status = data.status;\n }\n\n // Handle agent\n if (data.agent) {\n this.message.agent = {\n id: data.agent.id,\n name: data.agent.name,\n displayName: data.agent.display_name,\n };\n }\n\n // Handle knowledge sources\n if (data.knowledge_sources) {\n this.sources = data.knowledge_sources.map((s) => {\n const doc = s.knowledge_document;\n return {\n id: doc.id,\n title: doc.title,\n url: doc.use_external_link ? doc.external_link_url : doc.internal_link_url,\n };\n });\n }\n\n // Client-side function invocation — fires from either the tool_call_data UI\n // event or the raw state dict streamed by the backend (which has no\n // tool_call_data flag). Either form is enough to run the registered handler.\n if (data.type === \"client_function\" && data.function_name) {\n this.callbacks.onClientFunction?.({\n invocationId: data.id || \"\",\n functionName: data.function_name,\n arguments: data.arguments || {},\n conversationId: this.message.conversationId || \"\",\n });\n }\n\n // Handle standard tool call UI events\n if (data.tool_call_data && data.type && data.type !== \"client_function\") {\n const toolCall = this.parseToolCall(data);\n this.callbacks.onToolCall?.(toolCall);\n\n const existingIndex = this.toolCalls.findIndex((t) => t.id === toolCall.id);\n if (existingIndex >= 0) {\n this.toolCalls[existingIndex] = toolCall;\n } else {\n this.toolCalls.push(toolCall);\n }\n }\n\n // Handle follow-up replies\n if (data.follow_up_replies) {\n this.followUpReplies = data.follow_up_replies;\n }\n }\n\n private parseToolCall(data: SSEChunkData): ToolCallData {\n return {\n id: data.id || \"\",\n type: (data.type as ToolCallData[\"type\"]) || \"status_message\",\n status: data.status || \"unknown\",\n toolName: data.tool_name || \"\",\n toolDisplayName: data.tool_display_name,\n message: data.message,\n formSchema: data.form_schema,\n data: data.data,\n functionName: data.function_name,\n arguments: data.arguments,\n };\n }\n\n private buildFinalMessage(): AgoMessage {\n const message: AgoMessage = {\n id: this.message.id || \"\",\n conversationId: this.message.conversationId || \"\",\n content: this.message.content || \"\",\n role: \"assistant\",\n status: this.message.status || \"DONE\",\n agent: this.message.agent,\n sources: this.sources.length > 0 ? this.sources : undefined,\n toolCalls: this.toolCalls.length > 0 ? this.toolCalls : undefined,\n followUpReplies:\n this.followUpReplies.length > 0 ? this.followUpReplies : undefined,\n createdAt: new Date(),\n };\n\n this.callbacks.onComplete?.(message);\n return message;\n }\n}\n\n/**\n * Check if an error is a network error that should trigger polling fallback\n */\nexport function isStreamNetworkError(error: Error): boolean {\n const message = error.message.toLowerCase();\n return (\n message.includes(\"load failed\") ||\n message.includes(\"failed to fetch\") ||\n message.includes(\"network\") ||\n message.includes(\"abort\")\n );\n}\n","type EventHandler<T = unknown> = (data: T) => void;\n\n/**\n * Simple typed event emitter\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport class EventEmitter<Events extends Record<string, any> = Record<string, unknown>> {\n private handlers: Map<keyof Events, Set<EventHandler<unknown>>> = new Map();\n\n on<K extends keyof Events>(event: K, handler: EventHandler<Events[K]>): void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n this.handlers.get(event)!.add(handler as EventHandler<unknown>);\n }\n\n off<K extends keyof Events>(\n event: K,\n handler: EventHandler<Events[K]>\n ): void {\n const eventHandlers = this.handlers.get(event);\n if (eventHandlers) {\n eventHandlers.delete(handler as EventHandler<unknown>);\n }\n }\n\n emit<K extends keyof Events>(event: K, data: Events[K]): void {\n const eventHandlers = this.handlers.get(event);\n if (eventHandlers) {\n eventHandlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n console.error(`Error in event handler for ${String(event)}:`, error);\n }\n });\n }\n }\n\n /**\n * Subscribe to an event and auto-unsubscribe after the first call.\n */\n once<K extends keyof Events>(event: K, handler: EventHandler<Events[K]>): void {\n const wrapper = ((data: Events[K]) => {\n this.off(event, wrapper as EventHandler<Events[K]>);\n handler(data);\n }) as EventHandler<Events[K]>;\n this.on(event, wrapper);\n }\n\n /**\n * Returns a Promise that resolves the next time `event` fires.\n * Rejects if `timeout` (ms) is reached first.\n */\n waitFor<K extends keyof Events>(\n event: K,\n options?: { timeout?: number }\n ): Promise<Events[K]> {\n return new Promise((resolve, reject) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const handler = ((data: Events[K]) => {\n if (timer) clearTimeout(timer);\n resolve(data);\n }) as EventHandler<Events[K]>;\n\n this.once(event, handler);\n\n if (options?.timeout) {\n timer = setTimeout(() => {\n this.off(event, handler);\n reject(new Error(`waitFor(\"${String(event)}\") timed out after ${options.timeout}ms`));\n }, options.timeout);\n }\n });\n }\n\n removeAllListeners(event?: keyof Events): void {\n if (event) {\n this.handlers.delete(event);\n } else {\n this.handlers.clear();\n }\n }\n}\n","import { HttpClient } from \"../api/HttpClient\";\nimport { FunctionRegistry } from \"../functions/FunctionRegistry\";\nimport type { ClientFunctionDefinition, ClientFunctionHandler, ClientFunctionSchema } from \"../functions/types\";\nimport { ClientContextRegistry } from \"../state/ClientContextRegistry\";\nimport type {\n ContextEntry,\n ContextSnapshot,\n DynamicContextProvider,\n} from \"../state/ClientContextRegistry\";\nimport { SSEHandler } from \"../streaming/SSEHandler\";\nimport { EventEmitter } from \"../utils/eventEmitter\";\nimport { logger } from \"../utils/logger\";\nimport type {\n AgoConfig,\n AgoClientEvents,\n AgoEventName,\n AgoEventHandler,\n AgoMessage,\n Conversation,\n SendMessageOptions,\n} from \"./types\";\n\n/**\n * Main SDK client for AGO Chat integration\n */\nexport class AgoClient {\n private httpClient: HttpClient;\n private functionRegistry: FunctionRegistry;\n private contextRegistry: ClientContextRegistry;\n private eventEmitter: EventEmitter<AgoClientEvents>;\n private config: AgoConfig;\n\n constructor(config: AgoConfig) {\n this.config = config;\n this.httpClient = new HttpClient(config);\n this.functionRegistry = new FunctionRegistry();\n this.contextRegistry = new ClientContextRegistry();\n this.eventEmitter = new EventEmitter();\n\n if (config.debug) {\n logger.enable();\n }\n\n logger.log(\"AgoClient initialized\");\n }\n\n // ─────────────────────────────────────────────────────────────────\n // Messaging\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Send a message and receive a streaming response\n */\n async sendMessage(\n content: string,\n options?: SendMessageOptions\n ): Promise<AgoMessage> {\n const clientFunctions = this.functionRegistry.getSchemas();\n\n const clientContext = this.contextRegistry.getSnapshot();\n\n const body: Record<string, unknown> = {\n content,\n conversation_id: options?.conversationId,\n agent_id: options?.agentId || this.config.defaultAgentId,\n };\n\n // Include client functions if any are registered\n if (clientFunctions.length > 0) {\n body.client_functions = clientFunctions;\n }\n\n // Include client-supplied context if any is registered\n if (clientContext) {\n body.client_context = clientContext;\n }\n\n let response: Response;\n\n if (options?.files && options.files.length > 0) {\n // Use FormData for file uploads\n const formData = new FormData();\n formData.append(\"content\", content);\n\n if (options.conversationId) {\n formData.append(\"conversation_id\", options.conversationId);\n }\n\n if (options.agentId || this.config.defaultAgentId) {\n formData.append(\"agent_id\", options.agentId || this.config.defaultAgentId || \"\");\n }\n\n if (clientFunctions.length > 0) {\n formData.append(\"client_functions\", JSON.stringify(clientFunctions));\n }\n\n if (clientContext) {\n formData.append(\"client_context\", JSON.stringify(clientContext));\n }\n\n for (const file of options.files) {\n formData.append(\"files\", file);\n }\n\n response = await this.httpClient.postFormData(\"/api/sdk/v1/messages\", formData);\n } else {\n response = await this.httpClient.postStream(\"/api/sdk/v1/messages\", body);\n }\n\n return this.processSSEResponse(response);\n }\n\n private async processSSEResponse(response: Response): Promise<AgoMessage> {\n const handler = new SSEHandler({\n onStart: (data) => {\n this.eventEmitter.emit(\"message:start\", data);\n },\n onChunk: (data) => {\n this.eventEmitter.emit(\"message:chunk\", data);\n },\n onToolCall: (toolCall) => {\n this.eventEmitter.emit(\"toolCall:received\", toolCall);\n\n if (toolCall.type === \"form\") {\n this.eventEmitter.emit(\"toolCall:form\", toolCall);\n }\n },\n onClientFunction: async (data) => {\n this.eventEmitter.emit(\"function:invoke\", data);\n await this.handleClientFunctionInvocation(data);\n },\n onComplete: (message) => {\n this.eventEmitter.emit(\"message:complete\", message);\n },\n onError: (error) => {\n this.eventEmitter.emit(\"message:error\", { error: error.message });\n },\n });\n\n return handler.processStream(response);\n }\n\n private async handleClientFunctionInvocation(data: {\n invocationId: string;\n functionName: string;\n arguments: Record<string, unknown>;\n conversationId: string;\n }): Promise<void> {\n let result: unknown;\n let error: string | undefined;\n\n try {\n result = await this.functionRegistry.execute(data.functionName, data.arguments);\n } catch (err) {\n error = err instanceof Error ? err.message : \"Unknown error\";\n logger.error(\"Client function execution failed:\", err);\n }\n\n // Submit result back to backend using existing tool-call submit endpoint.\n // The raw state SSE event carries no invocationId — in that flow the backend\n // already continued with a placeholder, so we just emit the local event.\n if (data.invocationId) {\n try {\n await this.submitToolCallForm(data.invocationId, {\n result,\n error,\n _type: \"client_function_result\",\n });\n } catch (submitError) {\n logger.error(\"Failed to submit function result:\", submitError);\n }\n }\n\n this.eventEmitter.emit(\"function:result\", {\n invocationId: data.invocationId,\n result,\n error,\n });\n }\n\n // ─────────────────────────────────────────────────────────────────\n // Conversations\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Get list of conversations\n */\n async getConversations(): Promise<Conversation[]> {\n const response = await this.httpClient.get<{\n count: number;\n items: Array<{\n id: string;\n title: string;\n last_message_date: string;\n }>;\n }>(\"/api/sdk/v1/conversations\");\n\n return response.items.map((item) => ({\n id: item.id,\n title: item.title,\n lastMessageDate: new Date(item.last_message_date),\n }));\n }\n\n /**\n * Get a specific conversation with messages\n */\n async getConversation(conversationId: string): Promise<Conversation> {\n const response = await this.httpClient.get<{\n id: string;\n title: string;\n last_message_date: string;\n messages: Array<{\n id: string;\n content: string;\n role: \"user\" | \"assistant\";\n status: string;\n created_at: string;\n }>;\n }>(`/api/sdk/v1/conversations/${conversationId}`);\n\n return {\n id: response.id,\n title: response.title,\n lastMessageDate: new Date(response.last_message_date),\n messages: response.messages.map((m) => ({\n id: m.id,\n conversationId: response.id,\n content: m.content,\n role: m.role,\n status: m.status as AgoMessage[\"status\"],\n createdAt: new Date(m.created_at),\n })),\n };\n }\n\n /**\n * Get messages for a conversation\n */\n async getMessages(conversationId: string): Promise<AgoMessage[]> {\n const conversation = await this.getConversation(conversationId);\n return conversation.messages || [];\n }\n\n // ─────────────────────────────────────────────────────────────────\n // Tool Calls\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Submit form data for a tool call\n */\n async submitToolCallForm(\n toolCallId: string,\n formData: Record<string, unknown>\n ): Promise<void> {\n await this.httpClient.post(`/api/tool-calls/${toolCallId}/submit/`, {\n formData,\n });\n }\n\n /**\n * Confirm a tool call\n */\n async confirmToolCall(toolCallId: string): Promise<void> {\n await this.httpClient.post(`/api/tool-calls/${toolCallId}/confirm/`);\n }\n\n /**\n * Reject a tool call\n */\n async rejectToolCall(toolCallId: string): Promise<void> {\n await this.httpClient.post(`/api/tool-calls/${toolCallId}/reject/`);\n }\n\n // ─────────────────────────────────────────────────────────────────\n // Feedback\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Submit feedback for a message\n */\n async submitFeedback(\n messageId: string,\n rating: \"positive\" | \"negative\"\n ): Promise<void> {\n await this.httpClient.post(`/api/sdk/v1/messages/${messageId}/feedback`, {\n rating,\n });\n }\n\n // ─────────────────────────────────────────────────────────────────\n // Client-side Functions\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Register a client-side function that AGO can call.\n * Accepts either a definition object or (name, handler, schema) args.\n *\n * ```ts\n * // Single-object (preferred)\n * client.registerFunction({\n * name: \"lookupOrder\",\n * description: \"Look up an order\",\n * parameters: { type: \"object\", properties: { id: { type: \"string\" } } },\n * handler: async (args) => fetchOrder(args.id),\n * });\n *\n * // Classic 3-arg form\n * client.registerFunction(\"lookupOrder\", handler, schema);\n * ```\n */\n registerFunction(definition: ClientFunctionDefinition): void;\n registerFunction(\n name: string,\n handler: ClientFunctionHandler,\n schema: Omit<ClientFunctionSchema, \"name\">\n ): void;\n registerFunction(\n nameOrDef: string | ClientFunctionDefinition,\n handler?: ClientFunctionHandler,\n schema?: Omit<ClientFunctionSchema, \"name\">\n ): void {\n if (typeof nameOrDef === \"object\") {\n this.functionRegistry.register(nameOrDef);\n } else {\n this.functionRegistry.register(nameOrDef, handler!, schema!);\n }\n }\n\n /**\n * Short alias for `registerFunction`. Also accepts an array of definitions.\n *\n * ```ts\n * client.register(lookupOrder);\n * client.register([lookupOrder, cancelOrder]);\n * ```\n */\n register(\n definition: ClientFunctionDefinition | ClientFunctionDefinition[]\n ): void {\n if (Array.isArray(definition)) {\n for (const def of definition) {\n this.functionRegistry.register(def);\n }\n } else {\n this.functionRegistry.register(definition);\n }\n }\n\n /**\n * Unregister a client-side function\n */\n unregisterFunction(name: string): boolean {\n return this.functionRegistry.unregister(name);\n }\n\n /**\n * Get all registered function schemas\n */\n getRegisteredFunctions(): ClientFunctionSchema[] {\n return this.functionRegistry.getSchemas();\n }\n\n /**\n * Register a navigation function that lets AGO navigate users to different pages.\n * @param navigate - A callback that performs the navigation (e.g. react-router's navigate)\n * @param routes - Map of route names to paths, with descriptions for the LLM\n */\n registerNavigationFunction(\n navigate: (path: string) => void,\n routes: Array<{ name: string; path: string; description: string }>\n ): void {\n const routeNames = routes.map((r) => r.name);\n const routeDescriptions = routes\n .map((r) => `- \"${r.name}\": ${r.description}`)\n .join(\"\\n\");\n\n this.registerFunction(\n \"navigateToPage\",\n async (args) => {\n const pageName = args.page as string;\n const route = routes.find((r) => r.name === pageName);\n if (!route) {\n return { success: false, error: `Unknown page: ${pageName}` };\n }\n navigate(route.path);\n return { success: true, navigatedTo: route.path };\n },\n {\n description: `Navigate the user to a page in the application. Available pages:\\n${routeDescriptions}`,\n parameters: {\n type: \"object\",\n properties: {\n page: {\n type: \"string\",\n description: \"The page to navigate to\",\n enum: routeNames,\n },\n },\n required: [\"page\"],\n },\n }\n );\n }\n\n // ─────────────────────────────────────────────────────────────────\n // Client Context\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Register or update a piece of client-side context.\n * This context is sent with every message so the AI understands the user's situation.\n *\n * ```ts\n * client.setContext(\"order-page\", {\n * name: \"Order detail\",\n * description: \"User is viewing order #123\",\n * data: { orderId: \"123\", status: \"shipped\" },\n * });\n * ```\n */\n setContext(key: string, entry: ContextEntry): void {\n this.contextRegistry.set(key, entry);\n }\n\n /**\n * Remove a previously registered context entry.\n */\n removeContext(key: string): boolean {\n return this.contextRegistry.remove(key);\n }\n\n /**\n * Register a dynamic context provider. The callback is invoked every time\n * a message is sent, so the AI always gets the freshest data.\n *\n * Use this for context that lives outside React state — global stores,\n * refs, or computed values.\n *\n * ```ts\n * client.addDynamicContext(\"cart\", () => ({\n * name: \"Checkout\",\n * data: { itemCount: cart.items.length, total: cart.total },\n * }));\n * ```\n */\n addDynamicContext(key: string, provider: DynamicContextProvider): void {\n this.contextRegistry.addDynamicProvider(key, provider);\n }\n\n /**\n * Remove a dynamic context provider.\n */\n removeDynamicContext(key: string): boolean {\n return this.contextRegistry.removeDynamicProvider(key);\n }\n\n /**\n * Enable automatic capture of the current browser page (URL + title).\n * Injected as a dynamic context entry named `browser-page`.\n */\n enableAutoPageContext(): void {\n this.contextRegistry.addDynamicProvider(\"browser-page\", () => {\n const url = typeof window !== \"undefined\" ? window.location.href : undefined;\n const title = typeof document !== \"undefined\" ? document.title : undefined;\n if (!url && !title) return null;\n return {\n name: \"Browser page\",\n description: \"Current page the user is viewing\",\n data: { url, title },\n };\n });\n }\n\n /**\n * Get the current context snapshot.\n */\n getContextSnapshot(): ContextSnapshot | null {\n return this.contextRegistry.getSnapshot();\n }\n\n // ─────────────────────────────────────────────────────────────────\n // Events\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Subscribe to an event\n */\n on<K extends AgoEventName>(event: K, handler: AgoEventHandler<K>): void {\n this.eventEmitter.on(event, handler);\n }\n\n /**\n * Unsubscribe from an event\n */\n off<K extends AgoEventName>(event: K, handler: AgoEventHandler<K>): void {\n this.eventEmitter.off(event, handler);\n }\n\n /**\n * Subscribe to an event once — auto-unsubscribes after the first call.\n */\n once<K extends AgoEventName>(event: K, handler: AgoEventHandler<K>): void {\n this.eventEmitter.once(event, handler);\n }\n\n /**\n * Returns a Promise that resolves the next time `event` fires.\n *\n * ```ts\n * const msg = await client.waitFor(\"message:complete\", { timeout: 10000 });\n * ```\n */\n waitFor<K extends AgoEventName>(\n event: K,\n options?: { timeout?: number }\n ): Promise<AgoClientEvents[K]> {\n return this.eventEmitter.waitFor(event, options);\n }\n\n // ─────────────────────────────────────────────────────────────────\n // Configuration\n // ─────────────────────────────────────────────────────────────────\n\n /**\n * Update client configuration\n */\n updateConfig(config: Partial<AgoConfig>): void {\n this.config = { ...this.config, ...config };\n this.httpClient.updateConfig(config);\n\n if (config.debug !== undefined) {\n config.debug ? logger.enable() : logger.disable();\n }\n }\n\n /**\n * Clean up resources\n */\n destroy(): void {\n this.eventEmitter.removeAllListeners();\n this.functionRegistry.clear();\n this.contextRegistry.clear();\n logger.log(\"AgoClient destroyed\");\n }\n}\n"],"names":["name"],"mappings":"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"}
|