@useago/sdk 1.0.3 → 1.0.5
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 +51 -3
- package/dist/AgoClient--y10UXUV.cjs +6 -0
- package/dist/{AgoClient-CBLJfu90.js → AgoClient-DYdIe_R4.js} +55 -44
- package/dist/angular.cjs +1 -1
- package/dist/angular.d.cts +49 -2
- package/dist/angular.d.ts +49 -2
- package/dist/angular.js +1 -1
- package/dist/{createConversationSession-D3aHSSir.js → createConversationSession-Boi0PjDU.js} +1 -1
- package/dist/{createConversationSession-CnIchjFa.cjs → createConversationSession-lJWANT6T.cjs} +1 -1
- package/dist/{createFormCollector-CyD7KnjG.js → createFormCollector-BUqSA2Qw.js} +1 -1
- package/dist/{createFormCollector-CQKfRjfj.cjs → createFormCollector-CSG5ioym.cjs} +1 -1
- package/dist/devtools.cjs +41 -27
- package/dist/devtools.d.cts +48 -0
- package/dist/devtools.d.ts +48 -0
- package/dist/devtools.js +98 -70
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +13 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +3 -3
- package/dist/react.cjs +1 -1
- package/dist/react.d.cts +49 -2
- package/dist/react.d.ts +49 -2
- package/dist/react.js +2 -2
- package/dist/testing.d.cts +48 -0
- package/dist/testing.d.ts +48 -0
- package/dist/vue.cjs +1 -1
- package/dist/vue.d.cts +49 -2
- package/dist/vue.d.ts +49 -2
- package/dist/vue.js +1 -1
- package/dist/widget.cjs +1 -1
- package/dist/widget.d.cts +48 -0
- package/dist/widget.d.ts +48 -0
- package/dist/widget.js +3 -3
- package/package.json +4 -4
- package/dist/AgoClient-nYVPdI5x.cjs +0 -6
package/dist/vue.d.cts
CHANGED
|
@@ -251,6 +251,13 @@ declare interface AgoClientEvents {
|
|
|
251
251
|
conversationId: string;
|
|
252
252
|
messageId: string;
|
|
253
253
|
};
|
|
254
|
+
/**
|
|
255
|
+
* Every raw SSE message parsed off the stream, before the handler interprets it
|
|
256
|
+
* into the higher-level `message:*` / `toolCall:*` / `function:*` events. Carries
|
|
257
|
+
* the chunk verbatim so debugging tools (notably the dev panel) can log the exact
|
|
258
|
+
* wire payload. Heartbeat comments are not messages and don't fire this.
|
|
259
|
+
*/
|
|
260
|
+
"stream:message": SSEChunkData;
|
|
254
261
|
/**
|
|
255
262
|
* The main answer text is done (backend emitted `status: "DONE"`), but follow-up
|
|
256
263
|
* replies may still be pending. Fires once, before `message:complete`.
|
|
@@ -358,8 +365,7 @@ export declare const AgoPlugin: {
|
|
|
358
365
|
install(app: App, options: AgoPluginOptions): void;
|
|
359
366
|
};
|
|
360
367
|
|
|
361
|
-
export declare
|
|
362
|
-
}
|
|
368
|
+
export declare type AgoPluginOptions = AgoConfig;
|
|
363
369
|
|
|
364
370
|
declare interface AgoRoute {
|
|
365
371
|
name: string;
|
|
@@ -568,6 +574,47 @@ declare interface SendMessageOptions {
|
|
|
568
574
|
files?: File[];
|
|
569
575
|
}
|
|
570
576
|
|
|
577
|
+
/**
|
|
578
|
+
* SSE stream chunk data
|
|
579
|
+
*/
|
|
580
|
+
declare interface SSEChunkData {
|
|
581
|
+
content?: string;
|
|
582
|
+
full_content?: string;
|
|
583
|
+
message_id?: string;
|
|
584
|
+
status?: MessageStatus;
|
|
585
|
+
thread?: {
|
|
586
|
+
id: string;
|
|
587
|
+
};
|
|
588
|
+
agent?: {
|
|
589
|
+
id: string;
|
|
590
|
+
name: string;
|
|
591
|
+
display_name?: string;
|
|
592
|
+
};
|
|
593
|
+
knowledge_sources?: Array<{
|
|
594
|
+
knowledge_document: {
|
|
595
|
+
id: string;
|
|
596
|
+
title: string;
|
|
597
|
+
use_external_link: boolean;
|
|
598
|
+
external_link_url?: string;
|
|
599
|
+
internal_link_url?: string;
|
|
600
|
+
};
|
|
601
|
+
position: number;
|
|
602
|
+
}>;
|
|
603
|
+
tool_call_data?: boolean;
|
|
604
|
+
type?: string;
|
|
605
|
+
id?: string;
|
|
606
|
+
tool_name?: string;
|
|
607
|
+
tool_display_name?: string;
|
|
608
|
+
function_name?: string;
|
|
609
|
+
arguments?: Record<string, unknown>;
|
|
610
|
+
form_schema?: FormSchema;
|
|
611
|
+
message?: string;
|
|
612
|
+
data?: Record<string, unknown>;
|
|
613
|
+
follow_up_replies?: string[];
|
|
614
|
+
satisfaction_feedback?: unknown;
|
|
615
|
+
ask_to_talk_to_human?: boolean;
|
|
616
|
+
}
|
|
617
|
+
|
|
571
618
|
/**
|
|
572
619
|
* A minimal observable store: one value, synchronous subscriptions, and
|
|
573
620
|
* optional persistence via {@link PersistOptions} (localStorage by default).
|
package/dist/vue.d.ts
CHANGED
|
@@ -251,6 +251,13 @@ declare interface AgoClientEvents {
|
|
|
251
251
|
conversationId: string;
|
|
252
252
|
messageId: string;
|
|
253
253
|
};
|
|
254
|
+
/**
|
|
255
|
+
* Every raw SSE message parsed off the stream, before the handler interprets it
|
|
256
|
+
* into the higher-level `message:*` / `toolCall:*` / `function:*` events. Carries
|
|
257
|
+
* the chunk verbatim so debugging tools (notably the dev panel) can log the exact
|
|
258
|
+
* wire payload. Heartbeat comments are not messages and don't fire this.
|
|
259
|
+
*/
|
|
260
|
+
"stream:message": SSEChunkData;
|
|
254
261
|
/**
|
|
255
262
|
* The main answer text is done (backend emitted `status: "DONE"`), but follow-up
|
|
256
263
|
* replies may still be pending. Fires once, before `message:complete`.
|
|
@@ -358,8 +365,7 @@ export declare const AgoPlugin: {
|
|
|
358
365
|
install(app: App, options: AgoPluginOptions): void;
|
|
359
366
|
};
|
|
360
367
|
|
|
361
|
-
export declare
|
|
362
|
-
}
|
|
368
|
+
export declare type AgoPluginOptions = AgoConfig;
|
|
363
369
|
|
|
364
370
|
declare interface AgoRoute {
|
|
365
371
|
name: string;
|
|
@@ -568,6 +574,47 @@ declare interface SendMessageOptions {
|
|
|
568
574
|
files?: File[];
|
|
569
575
|
}
|
|
570
576
|
|
|
577
|
+
/**
|
|
578
|
+
* SSE stream chunk data
|
|
579
|
+
*/
|
|
580
|
+
declare interface SSEChunkData {
|
|
581
|
+
content?: string;
|
|
582
|
+
full_content?: string;
|
|
583
|
+
message_id?: string;
|
|
584
|
+
status?: MessageStatus;
|
|
585
|
+
thread?: {
|
|
586
|
+
id: string;
|
|
587
|
+
};
|
|
588
|
+
agent?: {
|
|
589
|
+
id: string;
|
|
590
|
+
name: string;
|
|
591
|
+
display_name?: string;
|
|
592
|
+
};
|
|
593
|
+
knowledge_sources?: Array<{
|
|
594
|
+
knowledge_document: {
|
|
595
|
+
id: string;
|
|
596
|
+
title: string;
|
|
597
|
+
use_external_link: boolean;
|
|
598
|
+
external_link_url?: string;
|
|
599
|
+
internal_link_url?: string;
|
|
600
|
+
};
|
|
601
|
+
position: number;
|
|
602
|
+
}>;
|
|
603
|
+
tool_call_data?: boolean;
|
|
604
|
+
type?: string;
|
|
605
|
+
id?: string;
|
|
606
|
+
tool_name?: string;
|
|
607
|
+
tool_display_name?: string;
|
|
608
|
+
function_name?: string;
|
|
609
|
+
arguments?: Record<string, unknown>;
|
|
610
|
+
form_schema?: FormSchema;
|
|
611
|
+
message?: string;
|
|
612
|
+
data?: Record<string, unknown>;
|
|
613
|
+
follow_up_replies?: string[];
|
|
614
|
+
satisfaction_feedback?: unknown;
|
|
615
|
+
ask_to_talk_to_human?: boolean;
|
|
616
|
+
}
|
|
617
|
+
|
|
571
618
|
/**
|
|
572
619
|
* A minimal observable store: one value, synchronous subscriptions, and
|
|
573
620
|
* optional persistence via {@link PersistOptions} (localStorage by default).
|
package/dist/vue.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as A } from "./AgoClient-
|
|
1
|
+
import { t as A } from "./AgoClient-DYdIe_R4.js";
|
|
2
2
|
import { computed as y, inject as F, onMounted as g, onScopeDispose as N, onUnmounted as I, ref as c, shallowRef as D } from "vue";
|
|
3
3
|
var L = /* @__PURE__ */ Symbol("ago-client"), b = { install(t, n) {
|
|
4
4
|
const e = new A(n);
|
package/dist/widget.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ke=require("./AgoClient
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const ke=require("./AgoClient--y10UXUV.cjs"),$e=require("./createFormCollector-CSG5ioym.cjs"),Ke=require("./createConversationSession-lJWANT6T.cjs");var Ve={"&":"&","<":"<",">":">",'"':""","'":"'"};function U(o){return o.replace(/[&<>"']/g,n=>Ve[n])}function Ae(o){const n=o.trim();return/^(https?:|mailto:|tel:|#|\/|\.\/|\.\.\/)/i.test(n)||!/^[a-z][a-z0-9+.-]*:/i.test(n)?n:null}var Te='"IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace',Q="";function M(o){const n=[],r=u=>(n.push(u),`${Q}${n.length-1}${Q}`);let t=o;return t=t.replace(/`([^`]+)`/g,(u,i)=>r(`<code style="background:#f0f2f5;padding:2px 5px;border-radius:4px;font-size:13px;font-family:${Te}">${U(i)}</code>`)),t=t.replace(/!\[([^\]]*)\]\(([^)\s]+)\)/g,(u,i,f)=>{const s=Ae(f);return s?r(`<img alt="${U(i)}" src="${U(s)}" style="max-width:100%;border-radius:8px;margin:4px 0" />`):u}),t=t.replace(/\[([^\]]+)\]\(([^)\s]+)\)/g,(u,i,f)=>{const s=Ae(f);return s?r(`<a href="${U(s)}" target="_blank" rel="noopener noreferrer" style="color:#1b5fc4;text-decoration:underline">${M(i)}</a>`):u}),t=U(t),t=t.replace(/\*\*([^*]+?)\*\*/g,"<strong>$1</strong>").replace(/__([^_]+?)__/g,"<strong>$1</strong>").replace(/~~([^~]+?)~~/g,"<del>$1</del>").replace(/(^|[^*])\*(?!\s)([^*]+?)\*/g,"$1<em>$2</em>").replace(/(^|[^\w_])_(?!\s)([^_]+?)_/g,"$1<em>$2</em>"),t=t.replace(new RegExp(`${Q}(\\d+)${Q}`,"g"),(u,i)=>n[Number(i)]),t}function _(o,n,r){const t=document.createElement(o);return Object.assign(t.style,n),r!==void 0&&(t.innerHTML=r),t}var De=/^ {0,3}([-*_])( *\1){2,} *$/,Me=/^ {0,3}(#{1,6})\s+(.*?)\s*#*\s*$/,Be=/^ {0,3}(```+|~~~+)/,Z=/^ {0,3}>\s?/,P=/^(\s*)([-*+]|\d+[.)])\s+(.*)$/,Qe=["20px","18px","16px","15px","14px","13px"],fe=o=>o.match(/^\s*/)?.[0].length??0;function Ye(o){return o.trim()===""||De.test(o)||Me.test(o)||Be.test(o)||Z.test(o)||P.test(o)}function ze(o){const n=o[0].match(P),r=n[1].length,t=/\d/.test(n[2]),u=_(t?"ol":"ul",{margin:"0 0 8px 0",paddingLeft:"20px",listStyleType:t?"decimal":"disc",listStylePosition:"outside"});let i=0;for(;i<o.length;){const f=o[i].match(P),s=[];for(i++;i<o.length&&fe(o[i])>r;)s.push(o[i]),i++;const p=_("li",{display:"list-item",margin:"2px 0",lineHeight:"1.6"}),c=f[3].match(/^\[([ xX])\]\s+(.*)$/);c?(p.style.listStyleType="none",p.style.marginLeft="-20px",p.innerHTML=`<span style="margin-right:6px">${c[1].toLowerCase()==="x"?"☑":"☐"}</span>${M(c[2])}`):p.innerHTML=M(f[3]),s.filter(h=>P.test(h)).length>0&&p.appendChild(ze(s.filter(h=>h.trim()!==""))),u.appendChild(p)}return u}function Ze(o){const n=s=>s.replace(/^\s*\|?/,"").replace(/\|?\s*$/,"").split("|").map(p=>p.trim()),r=_("div",{overflowX:"auto",margin:"0 0 8px 0"}),t=_("table",{borderCollapse:"collapse",width:"100%",fontSize:"13px"}),u=document.createElement("thead"),i=document.createElement("tr");for(const s of n(o[0]))i.appendChild(_("th",{border:"1px solid #dee3e8",padding:"6px 10px",textAlign:"left",backgroundColor:"#f5f7fa",fontWeight:"600"},M(s)));u.appendChild(i),t.appendChild(u);const f=document.createElement("tbody");for(const s of o.slice(2)){const p=document.createElement("tr");for(const c of n(s))p.appendChild(_("td",{border:"1px solid #dee3e8",padding:"6px 10px"},M(c)));f.appendChild(p)}return t.appendChild(f),r.appendChild(t),r}var Je=o=>!!o&&/^\s*\|?\s*:?-{1,}:?\s*(\|\s*:?-{1,}:?\s*)*\|?\s*$/.test(o);function J(o){const n=document.createDocumentFragment(),r=o.replace(/\r\n?/g,`
|
|
2
2
|
`).split(`
|
|
3
3
|
`);let t=0;for(;t<r.length;){const i=r[t];if(i.trim()===""){t++;continue}const f=i.match(Be);if(f){const c=f[1][0],h=[];for(t++;t<r.length&&!new RegExp(`^ {0,3}${c==="`"?"`{3,}":"~{3,}"}\\s*$`).test(r[t]);)h.push(r[t]),t++;t++;const L=_("pre",{margin:"0 0 8px 0"});L.appendChild(_("code",{display:"block",background:"#f5f5f5",padding:"8px 12px",borderRadius:"6px",fontSize:"13px",overflowX:"auto",fontFamily:Te,whiteSpace:"pre"},U(h.join(`
|
|
4
4
|
`)))),n.appendChild(L);continue}if(De.test(i)){n.appendChild(_("hr",{border:"none",borderTop:"1px solid #dee3e8",margin:"12px 0"})),t++;continue}const s=i.match(Me);if(s){const c=s[1].length;n.appendChild(_(`h${c}`,{margin:"16px 0 8px 0",fontSize:Qe[c-1],fontWeight:"600",lineHeight:"1.3"},M(s[2]))),t++;continue}if(Z.test(i)){const c=[];for(;t<r.length&&Z.test(r[t]);)c.push(r[t].replace(Z,"")),t++;const h=_("blockquote",{borderLeft:"4px solid #dee3e8",paddingLeft:"12px",margin:"0 0 8px 0",fontStyle:"italic",color:"#6b6d6f"});h.appendChild(J(c.join(`
|
package/dist/widget.d.cts
CHANGED
|
@@ -243,6 +243,13 @@ declare interface AgoClientEvents {
|
|
|
243
243
|
conversationId: string;
|
|
244
244
|
messageId: string;
|
|
245
245
|
};
|
|
246
|
+
/**
|
|
247
|
+
* Every raw SSE message parsed off the stream, before the handler interprets it
|
|
248
|
+
* into the higher-level `message:*` / `toolCall:*` / `function:*` events. Carries
|
|
249
|
+
* the chunk verbatim so debugging tools (notably the dev panel) can log the exact
|
|
250
|
+
* wire payload. Heartbeat comments are not messages and don't fire this.
|
|
251
|
+
*/
|
|
252
|
+
"stream:message": SSEChunkData;
|
|
246
253
|
/**
|
|
247
254
|
* The main answer text is done (backend emitted `status: "DONE"`), but follow-up
|
|
248
255
|
* replies may still be pending. Fires once, before `message:complete`.
|
|
@@ -835,6 +842,47 @@ declare interface SendMessageOptions {
|
|
|
835
842
|
files?: File[];
|
|
836
843
|
}
|
|
837
844
|
|
|
845
|
+
/**
|
|
846
|
+
* SSE stream chunk data
|
|
847
|
+
*/
|
|
848
|
+
declare interface SSEChunkData {
|
|
849
|
+
content?: string;
|
|
850
|
+
full_content?: string;
|
|
851
|
+
message_id?: string;
|
|
852
|
+
status?: MessageStatus;
|
|
853
|
+
thread?: {
|
|
854
|
+
id: string;
|
|
855
|
+
};
|
|
856
|
+
agent?: {
|
|
857
|
+
id: string;
|
|
858
|
+
name: string;
|
|
859
|
+
display_name?: string;
|
|
860
|
+
};
|
|
861
|
+
knowledge_sources?: Array<{
|
|
862
|
+
knowledge_document: {
|
|
863
|
+
id: string;
|
|
864
|
+
title: string;
|
|
865
|
+
use_external_link: boolean;
|
|
866
|
+
external_link_url?: string;
|
|
867
|
+
internal_link_url?: string;
|
|
868
|
+
};
|
|
869
|
+
position: number;
|
|
870
|
+
}>;
|
|
871
|
+
tool_call_data?: boolean;
|
|
872
|
+
type?: string;
|
|
873
|
+
id?: string;
|
|
874
|
+
tool_name?: string;
|
|
875
|
+
tool_display_name?: string;
|
|
876
|
+
function_name?: string;
|
|
877
|
+
arguments?: Record<string, unknown>;
|
|
878
|
+
form_schema?: FormSchema;
|
|
879
|
+
message?: string;
|
|
880
|
+
data?: Record<string, unknown>;
|
|
881
|
+
follow_up_replies?: string[];
|
|
882
|
+
satisfaction_feedback?: unknown;
|
|
883
|
+
ask_to_talk_to_human?: boolean;
|
|
884
|
+
}
|
|
885
|
+
|
|
838
886
|
/** The slice of the Web Storage API that {@link createStore} relies on. */
|
|
839
887
|
declare type StorageLike = Pick<Storage, "getItem" | "setItem">;
|
|
840
888
|
|
package/dist/widget.d.ts
CHANGED
|
@@ -243,6 +243,13 @@ declare interface AgoClientEvents {
|
|
|
243
243
|
conversationId: string;
|
|
244
244
|
messageId: string;
|
|
245
245
|
};
|
|
246
|
+
/**
|
|
247
|
+
* Every raw SSE message parsed off the stream, before the handler interprets it
|
|
248
|
+
* into the higher-level `message:*` / `toolCall:*` / `function:*` events. Carries
|
|
249
|
+
* the chunk verbatim so debugging tools (notably the dev panel) can log the exact
|
|
250
|
+
* wire payload. Heartbeat comments are not messages and don't fire this.
|
|
251
|
+
*/
|
|
252
|
+
"stream:message": SSEChunkData;
|
|
246
253
|
/**
|
|
247
254
|
* The main answer text is done (backend emitted `status: "DONE"`), but follow-up
|
|
248
255
|
* replies may still be pending. Fires once, before `message:complete`.
|
|
@@ -835,6 +842,47 @@ declare interface SendMessageOptions {
|
|
|
835
842
|
files?: File[];
|
|
836
843
|
}
|
|
837
844
|
|
|
845
|
+
/**
|
|
846
|
+
* SSE stream chunk data
|
|
847
|
+
*/
|
|
848
|
+
declare interface SSEChunkData {
|
|
849
|
+
content?: string;
|
|
850
|
+
full_content?: string;
|
|
851
|
+
message_id?: string;
|
|
852
|
+
status?: MessageStatus;
|
|
853
|
+
thread?: {
|
|
854
|
+
id: string;
|
|
855
|
+
};
|
|
856
|
+
agent?: {
|
|
857
|
+
id: string;
|
|
858
|
+
name: string;
|
|
859
|
+
display_name?: string;
|
|
860
|
+
};
|
|
861
|
+
knowledge_sources?: Array<{
|
|
862
|
+
knowledge_document: {
|
|
863
|
+
id: string;
|
|
864
|
+
title: string;
|
|
865
|
+
use_external_link: boolean;
|
|
866
|
+
external_link_url?: string;
|
|
867
|
+
internal_link_url?: string;
|
|
868
|
+
};
|
|
869
|
+
position: number;
|
|
870
|
+
}>;
|
|
871
|
+
tool_call_data?: boolean;
|
|
872
|
+
type?: string;
|
|
873
|
+
id?: string;
|
|
874
|
+
tool_name?: string;
|
|
875
|
+
tool_display_name?: string;
|
|
876
|
+
function_name?: string;
|
|
877
|
+
arguments?: Record<string, unknown>;
|
|
878
|
+
form_schema?: FormSchema;
|
|
879
|
+
message?: string;
|
|
880
|
+
data?: Record<string, unknown>;
|
|
881
|
+
follow_up_replies?: string[];
|
|
882
|
+
satisfaction_feedback?: unknown;
|
|
883
|
+
ask_to_talk_to_human?: boolean;
|
|
884
|
+
}
|
|
885
|
+
|
|
838
886
|
/** The slice of the Web Storage API that {@link createStore} relies on. */
|
|
839
887
|
declare type StorageLike = Pick<Storage, "getItem" | "setItem">;
|
|
840
888
|
|
package/dist/widget.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as Xe, u as Ke } from "./AgoClient-
|
|
2
|
-
import { r as qe, t as Ve } from "./createFormCollector-
|
|
3
|
-
import { t as Qe } from "./createConversationSession-
|
|
1
|
+
import { t as Xe, u as Ke } from "./AgoClient-DYdIe_R4.js";
|
|
2
|
+
import { r as qe, t as Ve } from "./createFormCollector-BUqSA2Qw.js";
|
|
3
|
+
import { t as Qe } from "./createConversationSession-Boi0PjDU.js";
|
|
4
4
|
var Ye = {
|
|
5
5
|
"&": "&",
|
|
6
6
|
"<": "<",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@useago/sdk",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Create In-APP AI agents that answers question and performs actions. Works with React, Vue, Angular and vanilla JS/TS.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -146,8 +146,8 @@
|
|
|
146
146
|
"@types/node": "^20.0.0",
|
|
147
147
|
"@types/react": "^18.0.0",
|
|
148
148
|
"@types/react-dom": "^18.0.0",
|
|
149
|
-
"@typescript-eslint/eslint-plugin": "^
|
|
150
|
-
"@typescript-eslint/parser": "^
|
|
149
|
+
"@typescript-eslint/eslint-plugin": "^8.0.0",
|
|
150
|
+
"@typescript-eslint/parser": "^8.0.0",
|
|
151
151
|
"esbuild": "^0.28.0",
|
|
152
152
|
"eslint": "^8.0.0",
|
|
153
153
|
"eslint-plugin-react-hooks": "^4.6.2",
|
|
@@ -155,7 +155,7 @@
|
|
|
155
155
|
"publint": "^0.3.0",
|
|
156
156
|
"react": "^18.0.0",
|
|
157
157
|
"react-dom": "^18.0.0",
|
|
158
|
-
"typescript": "^
|
|
158
|
+
"typescript": "^6.0.3",
|
|
159
159
|
"vite": "^8.0.0",
|
|
160
160
|
"vite-plugin-dts": "^4.0.0",
|
|
161
161
|
"vitest": "^4.0.0",
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
var h=class extends Error{constructor(e,t,s){super(e),this.code=t,this.statusCode=s,this.name="AgoError"}},u=class v extends h{constructor(t,s,r,n,i,a){super(t,s,r),this.type=n,this.param=i,this.docUrl=a,this.name="AgoApiError"}static fromResponse(t,s){const r=t.error;return new v(r.doc_url?`${r.message} See ${r.doc_url}`:r.message,r.code,s,r.type,r.param,r.doc_url)}},d=class extends h{constructor(e,t){super(e,"network_error"),this.originalError=t,this.name="AgoNetworkError"}},g=class extends h{constructor(e,t="stream_error"){super(e,t),this.name="AgoStreamError"}},m=class extends h{constructor(e,t,s){super(e,"function_error"),this.functionName=t,this.originalError=s,this.name="AgoFunctionError"}},A=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 A,p="ago_widget_id";function x(){if(typeof localStorage<"u"){const t=localStorage.getItem(p);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(p,e)}catch{}return e}var $=class{constructor(e){this.baseUrl=e.baseUrl.replace(/\/$/,""),this.headers={"X-User-Anon-Id":e.widgetId||x()},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 s=`${this.baseUrl}${e}`;o.debug("POST (stream)",s,t);try{const r=await fetch(s,{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 s=`${this.baseUrl}${e}`;o.debug("POST (formData)",s);const r={...this.headers};try{const n=await fetch(s,{method:"POST",headers:r,body:t});return n.ok||await this.handleErrorResponse(n),n}catch(n){throw n instanceof u?n:new d(`Network error: ${n instanceof Error?n.message:"Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`,n instanceof Error?n:void 0)}}async request(e,t,s){const r=`${this.baseUrl}${t}`;o.debug(e,r,s);try{const n=await fetch(r,{method:e,headers:{...this.headers,"Content-Type":"application/json"},body:s?JSON.stringify(s):void 0});return n.ok||await this.handleErrorResponse(n),n.status===204?void 0:n.json()}catch(n){throw n instanceof u?n:new d(`Network error: ${n instanceof Error?n.message:"Unknown error"}. Check that \`baseUrl\` is reachable and includes the protocol (https://).`,n instanceof Error?n:void 0)}}async handleErrorResponse(e){let t;try{t=await e.json()}catch{}if(t?.error)throw u.fromResponse(t,e.status);let s="";throw e.status===401||e.status===403?s=" Check `userJwt` (and that it has not expired).":e.status===404&&(s=" Check that `baseUrl` points at your AGO API root."),new u(`HTTP ${e.status}: ${e.statusText}.${s}`,"http_error",e.status,"api_error")}},b=class{constructor(){this.functions=new Map}register(e,t,s){if(typeof e=="object"){const{name:n,handler:i,description:a,parameters:l}=e;return this.register(n,i,{description:a,parameters:l})}const r=e;if(!t||!s)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:{...s,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 s=this.functions.get(e);if(!s)throw new m(`Function "${e}" is not registered`,e);o.log(`Executing function: ${e}`,t);try{const r=await s.handler(t);return o.log(`Function ${e} completed:`,r),r}catch(r){throw o.error(`Function ${e} failed:`,r),new m(`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}},C=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,s]of this.entries)e[t]=s;for(const[t,s]of this.dynamicProviders)try{const r=s();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")}},E=class{constructor(e){this.callbacks=e,this.buffer="",this.message={},this.toolCalls=[],this.sources=[],this.followUpReplies=[],this.isFirstChunk=!0,this.answerCompleteEmitted=!1}async processStream(e){if(!e.body)throw new g("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(),s=new TextDecoder;try{for(;;){const{done:r,value:n}=await t.read();if(r)break;const i=s.decode(n,{stream:!0});this.buffer+=i,this.processBuffer()}return this.buffer.trim()&&this.processBuffer(),this.buildFinalMessage()}catch(r){const n=r instanceof Error?r:new g("Stream processing failed mid-flight. The connection may have dropped; retry the message.");throw this.callbacks.onError?.(n),n}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 s=t.split(`
|
|
4
|
-
`);for(const r of s)if(!r.startsWith(": ")&&r.startsWith("data: ")){const n=r.slice(6);try{const i=JSON.parse(n);this.handleChunk(i)}catch(i){o.warn("Failed to parse SSE data:",n,i)}}}}handleChunk(e){if(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 s=t.knowledge_document;return{id:s.id,title:s.title,url:s.use_external_link?s.external_link_url:s.internal_link_url}})),e.type==="client_function"&&e.function_name&&this.callbacks.onClientFunction?.({invocationId:e.id||"",functionName:e.function_name,arguments:e.arguments||{},conversationId:this.message.conversationId||""}),e.tool_call_data&&e.type&&e.type!=="client_function"){const t=this.parseToolCall(e);this.callbacks.onToolCall?.(t);const s=this.toolCalls.findIndex(r=>r.id===t.id);s>=0?this.toolCalls[s]=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 R(e){const t=e.message.toLowerCase();return t.includes("load failed")||t.includes("failed to fetch")||t.includes("network")||t.includes("abort")}var _=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 s=this.handlers.get(e);s&&s.delete(t)}emit(e,t){const s=this.handlers.get(e);s&&s.forEach(r=>{try{r(t)}catch(n){console.error(`Error in event handler for ${String(e)}:`,n)}})}once(e,t){const s=(r=>{this.off(e,s),t(r)});this.on(e,s)}waitFor(e,t){return new Promise((s,r)=>{let n;const i=(a=>{n&&clearTimeout(n),s(a)});this.once(e,i),t?.timeout&&(n=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()}},y='`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).',I=/^[a-z][a-z0-9+.-]*:\/\//i,w=!1;function f(e,t="AgoClient"){if(typeof e!="object"||e===null)throw new h(`${t}: ${y}`,"config_missing_base_url");const s=e.baseUrl;if(typeof s!="string"||s.trim()==="")throw new h(`${t}: ${y}`,"config_missing_base_url");!s.startsWith("/")&&!I.test(s)&&(w||(w=!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 U=class S{constructor(t){this.warnedEmptyConversations=new Set,f(t,"AgoClient"),this.config=t,this.httpClient=new $(t),this.functionRegistry=new b,this.contextRegistry=new C,this.eventEmitter=new _,t.debug&&o.enable(),o.log("AgoClient initialized")}async sendMessage(t,s){const r=this.functionRegistry.getSchemas(),n=this.contextRegistry.getSnapshot(),i=this.config.agent||this.config.defaultAgentId,a={content:t,conversation_id:s?.conversationId,agent_id:s?.agentId||i};r.length>0&&(a.client_functions=r),n&&(a.client_context=n);let l;if(s?.files&&s.files.length>0){const c=new FormData;c.append("content",t),s.conversationId&&c.append("conversation_id",s.conversationId),(s.agentId||i)&&c.append("agent_id",s.agentId||i||""),r.length>0&&c.append("client_functions",JSON.stringify(r)),n&&c.append("client_context",JSON.stringify(n));for(const k of s.files)c.append("files",k);l=await this.httpClient.postFormData("/api/sdk/v1/messages",c)}else l=await this.httpClient.postStream("/api/sdk/v1/messages",a);return this.processSSEResponse(l)}async processSSEResponse(t){let s=!1;const r=await new E({onStart:n=>{this.eventEmitter.emit("message:start",n)},onChunk:n=>{this.eventEmitter.emit("message:chunk",n)},onToolCall:n=>{this.eventEmitter.emit("toolCall:received",n),n.type==="form"&&this.eventEmitter.emit("toolCall:form",n)},onClientFunction:async n=>{s=!0,this.eventEmitter.emit("function:invoke",n),await this.handleClientFunctionInvocation(n)},onAnswerComplete:n=>{this.eventEmitter.emit("message:answer-complete",n)},onComplete:n=>{this.eventEmitter.emit("message:complete",n)},onError:n=>{this.eventEmitter.emit("message:error",{error:n.message,code:n instanceof h?n.code:void 0})}}).processStream(t);return this.maybeFlagEmptyReply(r,s),r}maybeFlagEmptyReply(t,s){t.status==="DONE"&&(t.content??"").trim()===""&&!s&&!(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 n=this.config.agent||this.config.defaultAgentId;t.id?console.warn("[AGO] Reply completed with empty content. Possible causes: "+(n?`the agent "${n}" 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: "+(n?`the agent "${n}" 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 s,r;try{s=await this.functionRegistry.execute(t.functionName,t.arguments)}catch(n){r=n instanceof Error?n.message:"Unknown error",o.error("Client function execution failed:",n)}if(t.invocationId)try{await this.submitToolCallForm(t.invocationId,{result:s,error:r,_type:"client_function_result"})}catch(n){o.error("Failed to submit function result:",n)}this.eventEmitter.emit("function:result",{invocationId:t.invocationId,result:s,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 s=await this.httpClient.get(`/api/sdk/v1/conversations/${t}`),r={id:s.id,title:s.title,lastMessageDate:new Date(s.last_message_date),messages:s.messages.map(n=>({id:n.id,conversationId:s.id,content:n.content,role:n.role,status:n.status,createdAt:new Date(n.created_at),toolCalls:S.mapPersistedToolCalls(n.tool_call_data)}))};return this.eventEmitter.emit("conversation:loaded",r),r}static mapPersistedToolCalls(t){if(!(!t||t.length===0))return t.map(s=>({id:String(s.id??""),type:s.type??"status_message",status:String(s.status??"unknown"),toolName:s.tool_name??"",toolDisplayName:s.tool_display_name,message:s.message,formSchema:s.form_schema,data:s.data,functionName:s.function_name,arguments:s.arguments}))}async getMessages(t){return(await this.getConversation(t)).messages||[]}async submitToolCallForm(t,s){await this.httpClient.post(`/api/sdk/v1/tool-calls/${t}/submit`,{formData:s})}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 s=await this.httpClient.get(`/api/sdk/v1/forms/${encodeURIComponent(t)}`);return{name:s.name,description:s.description,schema:s.schema,submit:s.submit??void 0}}async submitFormCollector(t,s){return this.httpClient.post("/api/sdk/v1/forms/submit",{name:t,values:s})}async submitFeedback(t,s){await this.httpClient.post(`/api/sdk/v1/messages/${t}/feedback`,{rating:s})}registerFunction(t,s,r){typeof t=="object"?this.functionRegistry.register(t):this.functionRegistry.register(t,s,r)}register(t){if(Array.isArray(t))for(const s of t)this.functionRegistry.register(s);else this.functionRegistry.register(t)}unregisterFunction(t){return this.functionRegistry.unregister(t)}getRegisteredFunctions(){return this.functionRegistry.getSchemas()}registerNavigationFunction(t,s){const r=s.map(i=>i.name),n=s.map(i=>`- "${i.name}": ${i.description}`).join(`
|
|
5
|
-
`);this.registerFunction("navigateToPage",async i=>{const a=i.page,l=s.find(c=>c.name===a);return l?(t(l.path),{success:!0,navigatedTo:l.path}):{success:!1,error:`Unknown page: ${a}`}},{description:`Navigate the user to a page in the application. Available pages:
|
|
6
|
-
${n}`,parameters:{type:"object",properties:{page:{type:"string",description:"The page to navigate to",enum:r}},required:["page"]}})}setContext(t,s){this.contextRegistry.set(t,s),this.notifyContextChanged()}removeContext(t){const s=this.contextRegistry.remove(t);return s&&this.notifyContextChanged(),s}addDynamicContext(t,s){this.contextRegistry.addDynamicProvider(t,s),this.notifyContextChanged()}removeDynamicContext(t){const s=this.contextRegistry.removeDynamicProvider(t);return s&&this.notifyContextChanged(),s}notifyContextChanged(){this.eventEmitter.emit("context:changed",this.contextRegistry.getSnapshot())}enableAutoPageContext(){this.addDynamicContext("browser-page",()=>{const t=typeof window<"u"?window.location.href:void 0,s=typeof document<"u"?document.title:void 0;return!t&&!s?null:{name:"Browser page",description:"Current page the user is viewing",data:{url:t,title:s}}})}getContextSnapshot(){return this.contextRegistry.getSnapshot()}on(t,s){this.eventEmitter.on(t,s)}off(t,s){this.eventEmitter.off(t,s)}once(t,s){this.eventEmitter.once(t,s)}waitFor(t,s){return this.eventEmitter.waitFor(t,s)}updateConfig(t){const s={};for(const[n,i]of Object.entries(t))i!==void 0&&(s[n]=i);const r={...this.config,...s};f(r,"AgoClient.updateConfig"),this.config=r,this.httpClient.updateConfig(s),s.debug!==void 0&&(s.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 U}});Object.defineProperty(exports,"AgoError",{enumerable:!0,get:function(){return h}});Object.defineProperty(exports,"AgoFunctionError",{enumerable:!0,get:function(){return m}});Object.defineProperty(exports,"AgoNetworkError",{enumerable:!0,get:function(){return d}});Object.defineProperty(exports,"AgoStreamError",{enumerable:!0,get:function(){return g}});Object.defineProperty(exports,"ClientContextRegistry",{enumerable:!0,get:function(){return C}});Object.defineProperty(exports,"EventEmitter",{enumerable:!0,get:function(){return _}});Object.defineProperty(exports,"FunctionRegistry",{enumerable:!0,get:function(){return b}});Object.defineProperty(exports,"SSEHandler",{enumerable:!0,get:function(){return E}});Object.defineProperty(exports,"isStreamNetworkError",{enumerable:!0,get:function(){return R}});Object.defineProperty(exports,"logger",{enumerable:!0,get:function(){return o}});Object.defineProperty(exports,"validateConfig",{enumerable:!0,get:function(){return f}});
|