@useago/sdk 0.3.3 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AgoClient-B6PsfMeg.cjs +6 -0
- package/dist/{AgoClient-DF7M2WAz.js → AgoClient-BerJvssl.js} +235 -219
- package/dist/angular.cjs +1 -1
- package/dist/angular.d.cts +12 -0
- package/dist/angular.d.ts +12 -0
- package/dist/angular.js +1 -1
- package/dist/createConversationSession-CLZvxyuu.js +58 -0
- package/dist/createConversationSession-D3K5Gf1k.cjs +1 -0
- package/dist/createFormCollector-CD1rqRG4.js +208 -0
- package/dist/createFormCollector-D1FfiSgA.cjs +1 -0
- package/dist/createMockClient-DMFGIOtc.cjs +1 -0
- package/dist/createMockClient-tVsApEAh.js +72 -0
- package/dist/devtools.cjs +26 -26
- package/dist/devtools.d.cts +16 -26
- package/dist/devtools.d.ts +16 -26
- package/dist/devtools.js +55 -55
- package/dist/helpers.cjs +1 -1
- package/dist/helpers.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +102 -1
- package/dist/index.d.ts +102 -1
- package/dist/index.js +46 -43
- package/dist/react.cjs +19 -19
- package/dist/react.d.cts +67 -8
- package/dist/react.d.ts +67 -8
- package/dist/react.js +1066 -1051
- package/dist/vue.cjs +1 -1
- package/dist/vue.d.cts +12 -0
- package/dist/vue.d.ts +12 -0
- package/dist/vue.js +1 -1
- package/dist/widget.cjs +1 -0
- package/dist/widget.d.cts +635 -0
- package/dist/widget.d.ts +635 -0
- package/dist/widget.js +418 -0
- package/package.json +58 -15
- package/dist/AgoClient-bjN-z2ZQ.cjs +0 -6
- package/dist/createMockClient-D6uVh-B9.js +0 -254
- package/dist/createMockClient-DecMEUcK.cjs +0 -1
- /package/dist/{functions-DdROP6Ui.js → functions-C1-5vadY.js} +0 -0
- /package/dist/{functions-Bz-1Bs3I.cjs → functions-DsmzgHjC.cjs} +0 -0
package/dist/angular.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./AgoClient-
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const o=require("./AgoClient-B6PsfMeg.cjs");var n=class{constructor(e){this.client=new o.AgoClient(e),this.messages$=this.fromEvent("message:complete"),this.chunks$=this.fromEvent("message:chunk"),this.errors$=this.fromEvent("message:error"),this.messageStart$=this.fromEvent("message:start")}fromEvent(e){const t=this.client;return{subscribe(i){const s=r=>{i.next?.(r)};return t.on(e,s),{unsubscribe:()=>t.off(e,s)}}}}sendMessage(e,t){return this.client.sendMessage(e,t)}getConversations(){return this.client.getConversations()}getConversation(e){return this.client.getConversation(e)}getMessages(e){return this.client.getMessages(e)}submitToolCallForm(e,t){return this.client.submitToolCallForm(e,t)}confirmToolCall(e){return this.client.confirmToolCall(e)}rejectToolCall(e){return this.client.rejectToolCall(e)}submitFeedback(e,t){return this.client.submitFeedback(e,t)}registerFunction(e,t,i){typeof e=="object"?this.client.registerFunction(e):this.client.registerFunction(e,t,i)}unregisterFunction(e){return this.client.unregisterFunction(e)}registerNavigationFunction(e,t){this.client.registerNavigationFunction(e,t)}on(e,t){this.client.on(e,t)}off(e,t){this.client.off(e,t)}updateConfig(e){this.client.updateConfig(e)}getClient(){return this.client}destroy(){this.client.destroy()}};function c(e){return{provide:n,useValue:new n(e)}}exports.AgoService=n;exports.provideAgo=c;
|
package/dist/angular.d.cts
CHANGED
|
@@ -31,6 +31,12 @@ declare class AgoClient {
|
|
|
31
31
|
* Get a specific conversation with messages
|
|
32
32
|
*/
|
|
33
33
|
getConversation(conversationId: string): Promise<Conversation>;
|
|
34
|
+
/**
|
|
35
|
+
* Map the backend's snake_case `tool_call_data` entries onto the camelCase
|
|
36
|
+
* {@link ToolCallData} shape used everywhere else in the SDK. Mirrors
|
|
37
|
+
* `SSEHandler.parseToolCall` so persisted and streamed tool calls match.
|
|
38
|
+
*/
|
|
39
|
+
private static mapPersistedToolCalls;
|
|
34
40
|
/**
|
|
35
41
|
* Get messages for a conversation
|
|
36
42
|
*/
|
|
@@ -201,6 +207,12 @@ export declare interface AgoClientEvents {
|
|
|
201
207
|
conversationId?: string;
|
|
202
208
|
messageId?: string;
|
|
203
209
|
};
|
|
210
|
+
/**
|
|
211
|
+
* A full conversation was loaded from the server (e.g. after a page reload).
|
|
212
|
+
* Carries the messages and their persisted tool calls so stateful helpers —
|
|
213
|
+
* notably `createFormCollector` — can replay them to restore their state.
|
|
214
|
+
*/
|
|
215
|
+
"conversation:loaded": Conversation;
|
|
204
216
|
"toolCall:received": ToolCallData;
|
|
205
217
|
"toolCall:form": ToolCallData;
|
|
206
218
|
"function:invoke": ClientFunctionInvocation;
|
package/dist/angular.d.ts
CHANGED
|
@@ -31,6 +31,12 @@ declare class AgoClient {
|
|
|
31
31
|
* Get a specific conversation with messages
|
|
32
32
|
*/
|
|
33
33
|
getConversation(conversationId: string): Promise<Conversation>;
|
|
34
|
+
/**
|
|
35
|
+
* Map the backend's snake_case `tool_call_data` entries onto the camelCase
|
|
36
|
+
* {@link ToolCallData} shape used everywhere else in the SDK. Mirrors
|
|
37
|
+
* `SSEHandler.parseToolCall` so persisted and streamed tool calls match.
|
|
38
|
+
*/
|
|
39
|
+
private static mapPersistedToolCalls;
|
|
34
40
|
/**
|
|
35
41
|
* Get messages for a conversation
|
|
36
42
|
*/
|
|
@@ -201,6 +207,12 @@ export declare interface AgoClientEvents {
|
|
|
201
207
|
conversationId?: string;
|
|
202
208
|
messageId?: string;
|
|
203
209
|
};
|
|
210
|
+
/**
|
|
211
|
+
* A full conversation was loaded from the server (e.g. after a page reload).
|
|
212
|
+
* Carries the messages and their persisted tool calls so stateful helpers —
|
|
213
|
+
* notably `createFormCollector` — can replay them to restore their state.
|
|
214
|
+
*/
|
|
215
|
+
"conversation:loaded": Conversation;
|
|
204
216
|
"toolCall:received": ToolCallData;
|
|
205
217
|
"toolCall:form": ToolCallData;
|
|
206
218
|
"function:invoke": ClientFunctionInvocation;
|
package/dist/angular.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as o } from "./AgoClient-
|
|
1
|
+
import { t as o } from "./AgoClient-BerJvssl.js";
|
|
2
2
|
var n = class {
|
|
3
3
|
constructor(t) {
|
|
4
4
|
this.client = new o(t), this.messages$ = this.fromEvent("message:complete"), this.chunks$ = this.fromEvent("message:chunk"), this.errors$ = this.fromEvent("message:error"), this.messageStart$ = this.fromEvent("message:start");
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { n as d } from "./createFormCollector-CD1rqRG4.js";
|
|
2
|
+
var f = "ago_widget_id", g = "ago_last_thread", y = 7200 * 1e3;
|
|
3
|
+
function v() {
|
|
4
|
+
return typeof crypto < "u" && typeof crypto.randomUUID == "function" ? crypto.randomUUID() : "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (e) => {
|
|
5
|
+
const r = Math.floor(Math.random() * 16);
|
|
6
|
+
return (e === "x" ? r : r & 3 | 8).toString(16);
|
|
7
|
+
});
|
|
8
|
+
}
|
|
9
|
+
function D(e = {}) {
|
|
10
|
+
const r = e.key ?? f, c = e.threadKey ?? g, u = e.ttlMs ?? y, l = e.storage ?? (typeof localStorage < "u" ? localStorage : void 0);
|
|
11
|
+
let n = e.widgetId ?? "";
|
|
12
|
+
if (!n && l) try {
|
|
13
|
+
n = l.getItem(r) ?? "";
|
|
14
|
+
} catch {
|
|
15
|
+
}
|
|
16
|
+
if (n || (n = v()), l) try {
|
|
17
|
+
l.setItem(r, n);
|
|
18
|
+
} catch {
|
|
19
|
+
}
|
|
20
|
+
const o = d({
|
|
21
|
+
value: null,
|
|
22
|
+
lastMessageAt: null
|
|
23
|
+
}, {
|
|
24
|
+
key: c,
|
|
25
|
+
storage: l
|
|
26
|
+
}), s = o.get();
|
|
27
|
+
s.value !== null && x(s.lastMessageAt) && o.set({
|
|
28
|
+
value: null,
|
|
29
|
+
lastMessageAt: null
|
|
30
|
+
});
|
|
31
|
+
function x(t) {
|
|
32
|
+
return t === null ? !0 : Number.isFinite(u) ? Date.now() - t > u : !1;
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
widgetId: n,
|
|
36
|
+
key: r,
|
|
37
|
+
getLastActiveThread() {
|
|
38
|
+
const { value: t, lastMessageAt: a } = o.get();
|
|
39
|
+
return t === null || x(a) ? null : t;
|
|
40
|
+
},
|
|
41
|
+
setActiveThread(t, a) {
|
|
42
|
+
const i = a == null ? null : a instanceof Date ? a.getTime() : a;
|
|
43
|
+
o.set({
|
|
44
|
+
value: t,
|
|
45
|
+
lastMessageAt: i
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
clear() {
|
|
49
|
+
o.set({
|
|
50
|
+
value: null,
|
|
51
|
+
lastMessageAt: null
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
export {
|
|
57
|
+
D as t
|
|
58
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const d=require("./createFormCollector-D1FfiSgA.cjs");var f="ago_widget_id",g="ago_last_thread",y=7200*1e3;function v(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const r=Math.floor(Math.random()*16);return(e==="x"?r:r&3|8).toString(16)})}function _(e={}){const r=e.key??f,i=e.threadKey??g,u=e.ttlMs??y,l=e.storage??(typeof localStorage<"u"?localStorage:void 0);let n=e.widgetId??"";if(!n&&l)try{n=l.getItem(r)??""}catch{}if(n||(n=v()),l)try{l.setItem(r,n)}catch{}const o=d.createStore({value:null,lastMessageAt:null},{key:i,storage:l}),c=o.get();c.value!==null&&s(c.lastMessageAt)&&o.set({value:null,lastMessageAt:null});function s(t){return t===null?!0:Number.isFinite(u)?Date.now()-t>u:!1}return{widgetId:n,key:r,getLastActiveThread(){const{value:t,lastMessageAt:a}=o.get();return t===null||s(a)?null:t},setActiveThread(t,a){const x=a==null?null:a instanceof Date?a.getTime():a;o.set({value:t,lastMessageAt:x})},clear(){o.set({value:null,lastMessageAt:null})}}}Object.defineProperty(exports,"createConversationSession",{enumerable:!0,get:function(){return _}});
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
import { s as I } from "./AgoClient-BerJvssl.js";
|
|
2
|
+
function O(u, o) {
|
|
3
|
+
const m = o ? o.storage ?? (typeof localStorage < "u" ? localStorage : void 0) : void 0;
|
|
4
|
+
let c = u;
|
|
5
|
+
if (o && m) try {
|
|
6
|
+
const a = m.getItem(o.key);
|
|
7
|
+
a != null && (c = JSON.parse(a));
|
|
8
|
+
} catch {
|
|
9
|
+
}
|
|
10
|
+
const r = /* @__PURE__ */ new Set(), h = () => r.forEach((a) => a(c));
|
|
11
|
+
function y() {
|
|
12
|
+
if (o && m) try {
|
|
13
|
+
m.setItem(o.key, JSON.stringify(c));
|
|
14
|
+
} catch {
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return {
|
|
18
|
+
get: () => c,
|
|
19
|
+
set: (a) => {
|
|
20
|
+
c = a, y(), h();
|
|
21
|
+
},
|
|
22
|
+
subscribe: (a) => (r.add(a), () => {
|
|
23
|
+
r.delete(a);
|
|
24
|
+
})
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
var T = /^[a-zA-Z0-9_-]{1,40}$/;
|
|
28
|
+
function M(u) {
|
|
29
|
+
const { name: o, description: m, schema: c } = u;
|
|
30
|
+
if (!T.test(o)) throw new Error(`Invalid form collector name "${o}": must match ${T} (it becomes the update_/submit_ function names).`);
|
|
31
|
+
const r = typeof u.submit == "string" ? u.submit ? {
|
|
32
|
+
via: "client",
|
|
33
|
+
url: u.submit
|
|
34
|
+
} : !1 : u.submit ?? !1, h = c.properties ?? {}, y = c.required ?? [], a = (e) => e == null || e === "", p = (e) => y.filter((t) => a(e[t])), v = (e) => {
|
|
35
|
+
const t = {};
|
|
36
|
+
for (const [n, s] of Object.entries(e)) {
|
|
37
|
+
const i = h[n];
|
|
38
|
+
if (i)
|
|
39
|
+
if (s == null) t[n] = s;
|
|
40
|
+
else if (i.type === "number" || i.type === "integer") {
|
|
41
|
+
const g = typeof s == "number" ? s : Number(s);
|
|
42
|
+
t[n] = Number.isNaN(g) ? s : g;
|
|
43
|
+
} else i.type === "boolean" ? t[n] = typeof s == "boolean" ? s : s === "true" ? !0 : s === "false" ? !1 : !!s : t[n] = s;
|
|
44
|
+
}
|
|
45
|
+
return t;
|
|
46
|
+
}, f = u.initialValues ?? {}, $ = p(f), l = O({
|
|
47
|
+
values: f,
|
|
48
|
+
missing: $,
|
|
49
|
+
complete: $.length === 0,
|
|
50
|
+
submitted: !1
|
|
51
|
+
}), C = (e) => {
|
|
52
|
+
const t = l.get(), n = {
|
|
53
|
+
...t.values,
|
|
54
|
+
...e
|
|
55
|
+
}, s = p(n), i = {
|
|
56
|
+
...t,
|
|
57
|
+
values: n,
|
|
58
|
+
missing: s,
|
|
59
|
+
complete: s.length === 0
|
|
60
|
+
};
|
|
61
|
+
return l.set(i), i;
|
|
62
|
+
};
|
|
63
|
+
let d = null;
|
|
64
|
+
const k = async () => {
|
|
65
|
+
const e = l.get();
|
|
66
|
+
if (!e.complete) return {
|
|
67
|
+
ok: !1,
|
|
68
|
+
missing: e.missing
|
|
69
|
+
};
|
|
70
|
+
if (!r) return {
|
|
71
|
+
ok: !1,
|
|
72
|
+
error: "No submit target configured for this form collector."
|
|
73
|
+
};
|
|
74
|
+
const t = e.values;
|
|
75
|
+
try {
|
|
76
|
+
let n;
|
|
77
|
+
if (r.via === "client") if ("handler" in r) n = await r.handler(t);
|
|
78
|
+
else {
|
|
79
|
+
const s = await fetch(r.url, {
|
|
80
|
+
method: "POST",
|
|
81
|
+
headers: { "Content-Type": "application/json" },
|
|
82
|
+
credentials: "include",
|
|
83
|
+
body: JSON.stringify(t)
|
|
84
|
+
});
|
|
85
|
+
if (!s.ok) return {
|
|
86
|
+
ok: !1,
|
|
87
|
+
error: `Submit failed: HTTP ${s.status}`
|
|
88
|
+
};
|
|
89
|
+
n = await s.json().catch(() => {
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
if (!d) return {
|
|
94
|
+
ok: !1,
|
|
95
|
+
error: "Backend submit requires install(client) (or useFormCollector) first."
|
|
96
|
+
};
|
|
97
|
+
n = await d.submitFormCollector(r.destination, t);
|
|
98
|
+
}
|
|
99
|
+
return l.set({
|
|
100
|
+
...l.get(),
|
|
101
|
+
submitted: !0
|
|
102
|
+
}), {
|
|
103
|
+
ok: !0,
|
|
104
|
+
result: n
|
|
105
|
+
};
|
|
106
|
+
} catch (n) {
|
|
107
|
+
const s = n instanceof Error ? n.message : "Submit failed";
|
|
108
|
+
return I.error(`FormCollector "${o}" submit failed:`, n), {
|
|
109
|
+
ok: !1,
|
|
110
|
+
error: s
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}, w = {
|
|
114
|
+
name: `update_${o}`,
|
|
115
|
+
description: `Fill or update fields of the "${o}" form. ${m} Pass any subset of fields; call it repeatedly to fill the form as the user provides information. Returns the current values and which required fields are still missing.`,
|
|
116
|
+
parameters: {
|
|
117
|
+
...c,
|
|
118
|
+
required: []
|
|
119
|
+
},
|
|
120
|
+
handler: (e) => {
|
|
121
|
+
const t = C(v(e));
|
|
122
|
+
return {
|
|
123
|
+
ok: !0,
|
|
124
|
+
values: t.values,
|
|
125
|
+
missing: t.missing,
|
|
126
|
+
complete: t.complete
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}, b = [w];
|
|
130
|
+
r && b.push({
|
|
131
|
+
name: `submit_${o}`,
|
|
132
|
+
description: `Submit the completed "${o}" form. Only call this once every required field is collected and the user has confirmed. If fields are missing it returns them instead of submitting.`,
|
|
133
|
+
parameters: {
|
|
134
|
+
type: "object",
|
|
135
|
+
properties: {}
|
|
136
|
+
},
|
|
137
|
+
handler: () => k()
|
|
138
|
+
});
|
|
139
|
+
const q = "client__", S = r ? `submit_${o}` : null, x = (e) => {
|
|
140
|
+
const t = e.functionName ?? e.toolName;
|
|
141
|
+
if (t)
|
|
142
|
+
return t.startsWith(q) ? t.slice(8) : t;
|
|
143
|
+
}, _ = (e) => {
|
|
144
|
+
let t = { ...f }, n = !1;
|
|
145
|
+
for (const i of e) {
|
|
146
|
+
const g = x(i);
|
|
147
|
+
g === w.name ? i.arguments && (t = {
|
|
148
|
+
...t,
|
|
149
|
+
...v(i.arguments)
|
|
150
|
+
}) : S && g === S && i.status?.toLowerCase() === "done" && (n = !0);
|
|
151
|
+
}
|
|
152
|
+
const s = p(t);
|
|
153
|
+
l.set({
|
|
154
|
+
values: t,
|
|
155
|
+
missing: s,
|
|
156
|
+
complete: s.length === 0,
|
|
157
|
+
submitted: n
|
|
158
|
+
});
|
|
159
|
+
}, N = `form:${o}`, F = () => {
|
|
160
|
+
const e = l.get(), t = r ? ` When all required fields are present and the user confirms, call submit_${o}.` : "";
|
|
161
|
+
return {
|
|
162
|
+
name: `Form: ${o}`,
|
|
163
|
+
description: `Conversational form the assistant is helping fill. ${m} Use update_${o} to record fields; ask the user only for what is still missing.${t}`,
|
|
164
|
+
data: {
|
|
165
|
+
values: e.values,
|
|
166
|
+
missing: e.missing,
|
|
167
|
+
complete: e.complete,
|
|
168
|
+
submitted: e.submitted
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
}, E = (e) => {
|
|
172
|
+
_((e.messages ?? []).flatMap((t) => t.toolCalls ?? []));
|
|
173
|
+
};
|
|
174
|
+
return {
|
|
175
|
+
name: o,
|
|
176
|
+
store: l,
|
|
177
|
+
functions: b,
|
|
178
|
+
contextKey: N,
|
|
179
|
+
contextProvider: F,
|
|
180
|
+
install: (e) => {
|
|
181
|
+
d = e;
|
|
182
|
+
for (const t of b) e.register(t);
|
|
183
|
+
return e.addDynamicContext(N, F), e.on("conversation:loaded", E), () => {
|
|
184
|
+
for (const t of b) e.unregisterFunction(t.name);
|
|
185
|
+
e.removeDynamicContext(N), e.off("conversation:loaded", E), d === e && (d = null);
|
|
186
|
+
};
|
|
187
|
+
},
|
|
188
|
+
hydrate: _,
|
|
189
|
+
submit: k,
|
|
190
|
+
getValues: () => l.get().values,
|
|
191
|
+
setValues: (e) => {
|
|
192
|
+
C(v(e));
|
|
193
|
+
},
|
|
194
|
+
reset: () => {
|
|
195
|
+
const e = p(f);
|
|
196
|
+
l.set({
|
|
197
|
+
values: f,
|
|
198
|
+
missing: e,
|
|
199
|
+
complete: e.length === 0,
|
|
200
|
+
submitted: !1
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
export {
|
|
206
|
+
O as n,
|
|
207
|
+
M as t
|
|
208
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const I=require("./AgoClient-B6PsfMeg.cjs");function P(u,r){const m=r?r.storage??(typeof localStorage<"u"?localStorage:void 0):void 0;let c=u;if(r&&m)try{const a=m.getItem(r.key);a!=null&&(c=JSON.parse(a))}catch{}const o=new Set,h=()=>o.forEach(a=>a(c));function y(){if(r&&m)try{m.setItem(r.key,JSON.stringify(c))}catch{}}return{get:()=>c,set:a=>{c=a,y(),h()},subscribe:a=>(o.add(a),()=>{o.delete(a)})}}var O=/^[a-zA-Z0-9_-]{1,40}$/;function j(u){const{name:r,description:m,schema:c}=u;if(!O.test(r))throw new Error(`Invalid form collector name "${r}": must match ${O} (it becomes the update_/submit_ function names).`);const o=typeof u.submit=="string"?u.submit?{via:"client",url:u.submit}:!1:u.submit??!1,h=c.properties??{},y=c.required??[],a=e=>e==null||e==="",b=e=>y.filter(t=>a(e[t])),v=e=>{const t={};for(const[n,s]of Object.entries(e)){const i=h[n];if(i)if(s==null)t[n]=s;else if(i.type==="number"||i.type==="integer"){const g=typeof s=="number"?s:Number(s);t[n]=Number.isNaN(g)?s:g}else i.type==="boolean"?t[n]=typeof s=="boolean"?s:s==="true"?!0:s==="false"?!1:!!s:t[n]=s}return t},f=u.initialValues??{},N=b(f),l=P({values:f,missing:N,complete:N.length===0,submitted:!1}),$=e=>{const t=l.get(),n={...t.values,...e},s=b(n),i={...t,values:n,missing:s,complete:s.length===0};return l.set(i),i};let d=null;const S=async()=>{const e=l.get();if(!e.complete)return{ok:!1,missing:e.missing};if(!o)return{ok:!1,error:"No submit target configured for this form collector."};const t=e.values;try{let n;if(o.via==="client")if("handler"in o)n=await o.handler(t);else{const s=await fetch(o.url,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(t)});if(!s.ok)return{ok:!1,error:`Submit failed: HTTP ${s.status}`};n=await s.json().catch(()=>{})}else{if(!d)return{ok:!1,error:"Backend submit requires install(client) (or useFormCollector) first."};n=await d.submitFormCollector(o.destination,t)}return l.set({...l.get(),submitted:!0}),{ok:!0,result:n}}catch(n){const s=n instanceof Error?n.message:"Submit failed";return I.logger.error(`FormCollector "${r}" submit failed:`,n),{ok:!1,error:s}}},_={name:`update_${r}`,description:`Fill or update fields of the "${r}" form. ${m} Pass any subset of fields; call it repeatedly to fill the form as the user provides information. Returns the current values and which required fields are still missing.`,parameters:{...c,required:[]},handler:e=>{const t=$(v(e));return{ok:!0,values:t.values,missing:t.missing,complete:t.complete}}},p=[_];o&&p.push({name:`submit_${r}`,description:`Submit the completed "${r}" form. Only call this once every required field is collected and the user has confirmed. If fields are missing it returns them instead of submitting.`,parameters:{type:"object",properties:{}},handler:()=>S()});const E="client__",k=o?`submit_${r}`:null,T=e=>{const t=e.functionName??e.toolName;if(t)return t.startsWith(E)?t.slice(8):t},w=e=>{let t={...f},n=!1;for(const i of e){const g=T(i);g===_.name?i.arguments&&(t={...t,...v(i.arguments)}):k&&g===k&&i.status?.toLowerCase()==="done"&&(n=!0)}const s=b(t);l.set({values:t,missing:s,complete:s.length===0,submitted:n})},C=`form:${r}`,F=()=>{const e=l.get(),t=o?` When all required fields are present and the user confirms, call submit_${r}.`:"";return{name:`Form: ${r}`,description:`Conversational form the assistant is helping fill. ${m} Use update_${r} to record fields; ask the user only for what is still missing.${t}`,data:{values:e.values,missing:e.missing,complete:e.complete,submitted:e.submitted}}},q=e=>{w((e.messages??[]).flatMap(t=>t.toolCalls??[]))};return{name:r,store:l,functions:p,contextKey:C,contextProvider:F,install:e=>{d=e;for(const t of p)e.register(t);return e.addDynamicContext(C,F),e.on("conversation:loaded",q),()=>{for(const t of p)e.unregisterFunction(t.name);e.removeDynamicContext(C),e.off("conversation:loaded",q),d===e&&(d=null)}},hydrate:w,submit:S,getValues:()=>l.get().values,setValues:e=>{$(v(e))},reset:()=>{const e=b(f);l.set({values:f,missing:e,complete:e.length===0,submitted:!1})}}}Object.defineProperty(exports,"createFormCollector",{enumerable:!0,get:function(){return j}});Object.defineProperty(exports,"createStore",{enumerable:!0,get:function(){return P}});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function w(u={}){const{overrides:g={}}=u,d={id:"mock-msg-1",conversationId:"mock-conv-1",content:"Mock response",role:"assistant",status:"DONE",createdAt:new Date},l={id:"mock-conv-1",title:"Mock Conversation",lastMessageDate:new Date},t=new Map,a=[],m={sendMessage:async()=>d,getConversations:async()=>[l],getConversation:async()=>l,getMessages:async()=>[d],submitToolCallForm:async()=>{},confirmToolCall:async()=>{},rejectToolCall:async()=>{},submitFeedback:async()=>{},registerFunction:()=>{},unregisterFunction:()=>!0,getRegisteredFunctions:()=>[],getContextSnapshot:()=>null,registerNavigationFunction:()=>{},on:(e,o)=>{t.has(e)||t.set(e,new Set),t.get(e).add(o)},off:(e,o)=>{t.get(e)?.delete(o)},once:(e,o)=>{const n=(...r)=>{t.get(e)?.delete(n),o(...r)};t.has(e)||t.set(e,new Set),t.get(e).add(n)},waitFor:(e,o)=>new Promise((n,r)=>{let i;const c=f=>{i&&clearTimeout(i),t.get(e)?.delete(c),n(f)};t.has(e)||t.set(e,new Set),t.get(e).add(c),o?.timeout&&(i=setTimeout(()=>{t.get(e)?.delete(c),r(new Error(`waitFor("${e}") timed out after ${o.timeout}ms`))},o.timeout))}),updateConfig:()=>{},destroy:()=>{t.clear()},...g},s={};for(const[e,o]of Object.entries(m))s[e]=(...n)=>(a.push({method:e,args:n}),o(...n));return s.__calls=a,s.__callsFor=e=>a.filter(o=>o.method===e),s.__emitEvent=(e,o)=>{const n=t.get(e);n&&[...n].forEach(r=>r(o))},s}Object.defineProperty(exports,"createMockClient",{enumerable:!0,get:function(){return w}});
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
function w(g = {}) {
|
|
2
|
+
const { overrides: m = {} } = g, d = {
|
|
3
|
+
id: "mock-msg-1",
|
|
4
|
+
conversationId: "mock-conv-1",
|
|
5
|
+
content: "Mock response",
|
|
6
|
+
role: "assistant",
|
|
7
|
+
status: "DONE",
|
|
8
|
+
createdAt: /* @__PURE__ */ new Date()
|
|
9
|
+
}, l = {
|
|
10
|
+
id: "mock-conv-1",
|
|
11
|
+
title: "Mock Conversation",
|
|
12
|
+
lastMessageDate: /* @__PURE__ */ new Date()
|
|
13
|
+
}, t = /* @__PURE__ */ new Map(), i = [], u = {
|
|
14
|
+
sendMessage: async () => d,
|
|
15
|
+
getConversations: async () => [l],
|
|
16
|
+
getConversation: async () => l,
|
|
17
|
+
getMessages: async () => [d],
|
|
18
|
+
submitToolCallForm: async () => {
|
|
19
|
+
},
|
|
20
|
+
confirmToolCall: async () => {
|
|
21
|
+
},
|
|
22
|
+
rejectToolCall: async () => {
|
|
23
|
+
},
|
|
24
|
+
submitFeedback: async () => {
|
|
25
|
+
},
|
|
26
|
+
registerFunction: () => {
|
|
27
|
+
},
|
|
28
|
+
unregisterFunction: () => !0,
|
|
29
|
+
getRegisteredFunctions: () => [],
|
|
30
|
+
getContextSnapshot: () => null,
|
|
31
|
+
registerNavigationFunction: () => {
|
|
32
|
+
},
|
|
33
|
+
on: (e, o) => {
|
|
34
|
+
t.has(e) || t.set(e, /* @__PURE__ */ new Set()), t.get(e).add(o);
|
|
35
|
+
},
|
|
36
|
+
off: (e, o) => {
|
|
37
|
+
t.get(e)?.delete(o);
|
|
38
|
+
},
|
|
39
|
+
once: (e, o) => {
|
|
40
|
+
const s = (...a) => {
|
|
41
|
+
t.get(e)?.delete(s), o(...a);
|
|
42
|
+
};
|
|
43
|
+
t.has(e) || t.set(e, /* @__PURE__ */ new Set()), t.get(e).add(s);
|
|
44
|
+
},
|
|
45
|
+
waitFor: (e, o) => new Promise((s, a) => {
|
|
46
|
+
let r;
|
|
47
|
+
const c = (f) => {
|
|
48
|
+
r && clearTimeout(r), t.get(e)?.delete(c), s(f);
|
|
49
|
+
};
|
|
50
|
+
t.has(e) || t.set(e, /* @__PURE__ */ new Set()), t.get(e).add(c), o?.timeout && (r = setTimeout(() => {
|
|
51
|
+
t.get(e)?.delete(c), a(/* @__PURE__ */ new Error(`waitFor("${e}") timed out after ${o.timeout}ms`));
|
|
52
|
+
}, o.timeout));
|
|
53
|
+
}),
|
|
54
|
+
updateConfig: () => {
|
|
55
|
+
},
|
|
56
|
+
destroy: () => {
|
|
57
|
+
t.clear();
|
|
58
|
+
},
|
|
59
|
+
...m
|
|
60
|
+
}, n = {};
|
|
61
|
+
for (const [e, o] of Object.entries(u)) n[e] = (...s) => (i.push({
|
|
62
|
+
method: e,
|
|
63
|
+
args: s
|
|
64
|
+
}), o(...s));
|
|
65
|
+
return n.__calls = i, n.__callsFor = (e) => i.filter((o) => o.method === e), n.__emitEvent = (e, o) => {
|
|
66
|
+
const s = t.get(e);
|
|
67
|
+
s && [...s].forEach((a) => a(o));
|
|
68
|
+
}, n;
|
|
69
|
+
}
|
|
70
|
+
export {
|
|
71
|
+
w as t
|
|
72
|
+
};
|
package/dist/devtools.cjs
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var r,d,v=()=>({});function c(){r&&(r.textContent=JSON.stringify(v(),null,2))}function p(a,o){if(!d)return;const e=document.createElement("div");e.className=`dev-log-line dev-log-${o}`,e.textContent=`${new Date().toLocaleTimeString()} ${a}`,d.appendChild(e),d.scrollTop=d.scrollHeight}var x="ago_dev_panel_collapsed";function i(a,o){a.classList.toggle("collapsed",o);const e=a.querySelector(".dev-toggle");e&&(e.textContent=o?"▢":"—",e.title=o?"Expand dev tools":"Collapse dev tools",e.setAttribute("aria-expanded",String(!o)));try{localStorage.setItem(x,o?"1":"0")}catch{}}function f(a){const{client:o,target:e}=a;v=()=>o.getContextSnapshot()?.entries??{},b();const u=typeof e=="string"?document.querySelector(e):e instanceof Element?e:document.body,t=document.createElement("aside");t.id="ago-dev-panel",(u??document.body).appendChild(t),t.innerHTML=`
|
|
2
2
|
<div class="dev-head">
|
|
3
3
|
<span class="dev-badge">DEV</span>
|
|
4
4
|
<span class="dev-title">DEV TOOLS · client-side function state — not for production</span>
|
|
5
5
|
<button type="button" class="dev-toggle" aria-label="Toggle dev tools">—</button>
|
|
6
6
|
</div>
|
|
7
7
|
<div class="dev-body">
|
|
8
|
-
<div class="dev-fns">Registered functions: <code>${(
|
|
8
|
+
<div class="dev-fns">Registered functions: <code>${(o.getRegisteredFunctions?.()??[]).map(n=>n.name).join(", ")||"—"}</code></div>
|
|
9
9
|
<div class="dev-section-label">JSON object (built by the agent)</div>
|
|
10
|
-
<pre class="dev-state" id="dev-state"></pre>
|
|
10
|
+
<pre class="dev-state" id="ago-dev-state"></pre>
|
|
11
11
|
<div class="dev-section-label">Function calls</div>
|
|
12
|
-
<div class="dev-log" id="dev-log"></div>
|
|
12
|
+
<div class="dev-log" id="ago-dev-log"></div>
|
|
13
13
|
</div>
|
|
14
|
-
`,
|
|
15
|
-
#dev-panel {
|
|
14
|
+
`,r=t.querySelector("#ago-dev-state"),d=t.querySelector("#ago-dev-log"),t.querySelector(".dev-toggle")?.addEventListener("click",n=>{n.stopPropagation(),i(t,!t.classList.contains("collapsed"))}),t.addEventListener("click",()=>{t.classList.contains("collapsed")&&i(t,!1)});let s=!1;try{s=localStorage.getItem(x)==="1"}catch{}i(t,s),o.on("function:invoke",({functionName:n,arguments:l})=>{p(`→ ${n}(${JSON.stringify(l??{})})`,"invoke")}),o.on("function:result",({result:n,error:l})=>{p(l?`✗ error: ${l}`:`← ${JSON.stringify(n)}`,l?"error":"result"),c()}),c()}var g="ago-dev-panel-styles";function b(){if(document.getElementById(g))return;const a=document.createElement("style");a.id=g,a.textContent=h,document.head.appendChild(a)}var h=`
|
|
15
|
+
#ago-dev-panel {
|
|
16
16
|
position: fixed;
|
|
17
17
|
top: 16px;
|
|
18
18
|
right: 16px;
|
|
@@ -33,8 +33,8 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var s,d,u=()=
|
|
|
33
33
|
font-size: 12px;
|
|
34
34
|
z-index: 1000;
|
|
35
35
|
}
|
|
36
|
-
#dev-panel .dev-head { display: flex; align-items: center; gap: 8px; }
|
|
37
|
-
#dev-panel .dev-toggle {
|
|
36
|
+
#ago-dev-panel .dev-head { display: flex; align-items: center; gap: 8px; }
|
|
37
|
+
#ago-dev-panel .dev-toggle {
|
|
38
38
|
margin-left: auto;
|
|
39
39
|
flex: none;
|
|
40
40
|
width: 22px;
|
|
@@ -50,19 +50,19 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var s,d,u=()=
|
|
|
50
50
|
line-height: 1;
|
|
51
51
|
cursor: pointer;
|
|
52
52
|
}
|
|
53
|
-
#dev-panel .dev-toggle:hover { color: #d7e0e8; border-color: #3a4655; }
|
|
54
|
-
#dev-panel .dev-body { display: flex; flex-direction: column; gap: 8px; }
|
|
53
|
+
#ago-dev-panel .dev-toggle:hover { color: #d7e0e8; border-color: #3a4655; }
|
|
54
|
+
#ago-dev-panel .dev-body { display: flex; flex-direction: column; gap: 8px; }
|
|
55
55
|
|
|
56
56
|
/* Collapsed: shrink to a small clickable widget showing only the DEV badge. */
|
|
57
|
-
#dev-panel.collapsed {
|
|
57
|
+
#ago-dev-panel.collapsed {
|
|
58
58
|
width: auto;
|
|
59
59
|
cursor: pointer;
|
|
60
60
|
padding: 8px 10px;
|
|
61
61
|
}
|
|
62
|
-
#dev-panel.collapsed .dev-title,
|
|
63
|
-
#dev-panel.collapsed .dev-body { display: none; }
|
|
64
|
-
#dev-panel.collapsed .dev-toggle { margin-left: 6px; }
|
|
65
|
-
#dev-panel .dev-badge {
|
|
62
|
+
#ago-dev-panel.collapsed .dev-title,
|
|
63
|
+
#ago-dev-panel.collapsed .dev-body { display: none; }
|
|
64
|
+
#ago-dev-panel.collapsed .dev-toggle { margin-left: 6px; }
|
|
65
|
+
#ago-dev-panel .dev-badge {
|
|
66
66
|
background: #f59e0b;
|
|
67
67
|
color: #1c1206;
|
|
68
68
|
font-weight: 700;
|
|
@@ -71,17 +71,17 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var s,d,u=()=
|
|
|
71
71
|
padding: 2px 6px;
|
|
72
72
|
border-radius: 5px;
|
|
73
73
|
}
|
|
74
|
-
#dev-panel .dev-title { color: #f59e0b; font-size: 11px; line-height: 1.3; }
|
|
75
|
-
#dev-panel .dev-fns { color: #7c8a99; font-size: 11px; }
|
|
76
|
-
#dev-panel .dev-fns code { color: #9ecbff; }
|
|
77
|
-
#dev-panel .dev-section-label {
|
|
74
|
+
#ago-dev-panel .dev-title { color: #f59e0b; font-size: 11px; line-height: 1.3; }
|
|
75
|
+
#ago-dev-panel .dev-fns { color: #7c8a99; font-size: 11px; }
|
|
76
|
+
#ago-dev-panel .dev-fns code { color: #9ecbff; }
|
|
77
|
+
#ago-dev-panel .dev-section-label {
|
|
78
78
|
color: #7c8a99;
|
|
79
79
|
text-transform: uppercase;
|
|
80
80
|
letter-spacing: .08em;
|
|
81
81
|
font-size: 10px;
|
|
82
82
|
margin-top: 4px;
|
|
83
83
|
}
|
|
84
|
-
#dev-panel .dev-state {
|
|
84
|
+
#ago-dev-panel .dev-state {
|
|
85
85
|
margin: 0;
|
|
86
86
|
padding: 8px;
|
|
87
87
|
background: #060a0e;
|
|
@@ -91,7 +91,7 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var s,d,u=()=
|
|
|
91
91
|
white-space: pre;
|
|
92
92
|
color: #c8e6c9;
|
|
93
93
|
}
|
|
94
|
-
#dev-panel .dev-log {
|
|
94
|
+
#ago-dev-panel .dev-log {
|
|
95
95
|
display: flex;
|
|
96
96
|
flex-direction: column;
|
|
97
97
|
gap: 2px;
|
|
@@ -101,8 +101,8 @@ Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});var s,d,u=()=
|
|
|
101
101
|
border-radius: 8px;
|
|
102
102
|
padding: 6px 8px;
|
|
103
103
|
}
|
|
104
|
-
#dev-panel .dev-log-line { white-space: pre-wrap; word-break: break-word; line-height: 1.4; }
|
|
105
|
-
#dev-panel .dev-log-invoke { color: #9ecbff; }
|
|
106
|
-
#dev-panel .dev-log-result { color: #86efac; }
|
|
107
|
-
#dev-panel .dev-log-error { color: #fca5a5; }
|
|
108
|
-
`;exports.initDevPanel=
|
|
104
|
+
#ago-dev-panel .dev-log-line { white-space: pre-wrap; word-break: break-word; line-height: 1.4; }
|
|
105
|
+
#ago-dev-panel .dev-log-invoke { color: #9ecbff; }
|
|
106
|
+
#ago-dev-panel .dev-log-result { color: #86efac; }
|
|
107
|
+
#ago-dev-panel .dev-log-error { color: #fca5a5; }
|
|
108
|
+
`;exports.initDevPanel=f;
|
package/dist/devtools.d.cts
CHANGED
|
@@ -31,6 +31,12 @@ declare class AgoClient {
|
|
|
31
31
|
* Get a specific conversation with messages
|
|
32
32
|
*/
|
|
33
33
|
getConversation(conversationId: string): Promise<Conversation>;
|
|
34
|
+
/**
|
|
35
|
+
* Map the backend's snake_case `tool_call_data` entries onto the camelCase
|
|
36
|
+
* {@link ToolCallData} shape used everywhere else in the SDK. Mirrors
|
|
37
|
+
* `SSEHandler.parseToolCall` so persisted and streamed tool calls match.
|
|
38
|
+
*/
|
|
39
|
+
private static mapPersistedToolCalls;
|
|
34
40
|
/**
|
|
35
41
|
* Get messages for a conversation
|
|
36
42
|
*/
|
|
@@ -201,6 +207,12 @@ declare interface AgoClientEvents {
|
|
|
201
207
|
conversationId?: string;
|
|
202
208
|
messageId?: string;
|
|
203
209
|
};
|
|
210
|
+
/**
|
|
211
|
+
* A full conversation was loaded from the server (e.g. after a page reload).
|
|
212
|
+
* Carries the messages and their persisted tool calls so stateful helpers —
|
|
213
|
+
* notably `createFormCollector` — can replay them to restore their state.
|
|
214
|
+
*/
|
|
215
|
+
"conversation:loaded": Conversation;
|
|
204
216
|
"toolCall:received": ToolCallData;
|
|
205
217
|
"toolCall:form": ToolCallData;
|
|
206
218
|
"function:invoke": ClientFunctionInvocation;
|
|
@@ -350,13 +362,12 @@ declare interface Conversation {
|
|
|
350
362
|
|
|
351
363
|
/** Options for {@link initDevPanel}. */
|
|
352
364
|
export declare interface DevPanelOptions {
|
|
353
|
-
/** The store whose state the panel renders live. */
|
|
354
|
-
store: Store<unknown>;
|
|
355
365
|
/**
|
|
356
|
-
*
|
|
357
|
-
*
|
|
366
|
+
* The AGO client to debug. The panel lists its registered functions, logs its
|
|
367
|
+
* function events, and renders its live context snapshot
|
|
368
|
+
* (`client.getContextSnapshot()`)
|
|
358
369
|
*/
|
|
359
|
-
client: Pick<AgoClient, "on" | "getRegisteredFunctions">;
|
|
370
|
+
client: Pick<AgoClient, "on" | "getRegisteredFunctions" | "getContextSnapshot">;
|
|
360
371
|
/** Where to mount: a CSS selector, an Element, or `document.body` (default). */
|
|
361
372
|
target?: string | Element;
|
|
362
373
|
}
|
|
@@ -401,27 +412,6 @@ declare interface SendMessageOptions {
|
|
|
401
412
|
files?: File[];
|
|
402
413
|
}
|
|
403
414
|
|
|
404
|
-
/**
|
|
405
|
-
* A minimal observable store: one value, synchronous subscriptions, and
|
|
406
|
-
* optional persistence via {@link PersistOptions} (localStorage by default).
|
|
407
|
-
*
|
|
408
|
-
* ```ts
|
|
409
|
-
* const store = createStore({ count: 0 });
|
|
410
|
-
* store.subscribe((state) => save(state));
|
|
411
|
-
* store.set({ count: 1 }); // listeners fire synchronously
|
|
412
|
-
*
|
|
413
|
-
* const cart = createStore({ items: [] }, { key: "cart" }); // persisted
|
|
414
|
-
* ```
|
|
415
|
-
*/
|
|
416
|
-
declare interface Store<T> {
|
|
417
|
-
/** Current state. */
|
|
418
|
-
get(): T;
|
|
419
|
-
/** Replace the state and notify subscribers synchronously. */
|
|
420
|
-
set(next: T): void;
|
|
421
|
-
/** Register a listener; returns a function that removes it. */
|
|
422
|
-
subscribe(listener: (state: T) => void): () => void;
|
|
423
|
-
}
|
|
424
|
-
|
|
425
415
|
/**
|
|
426
416
|
* Tool call data from SSE stream
|
|
427
417
|
*/
|