@useago/sdk 1.4.4 → 1.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +63 -1
- package/dist/AgoClient-5VGybmvz.cjs +8 -0
- package/dist/AgoClient-DXrH2AMi.js +964 -0
- package/dist/angular.cjs +1 -1
- package/dist/angular.d.cts +124 -5
- package/dist/angular.d.ts +124 -5
- package/dist/angular.js +5 -1
- package/dist/autoContinue-CC8K9mBU.js +63 -0
- package/dist/autoContinue-CP9pJR-V.cjs +1 -0
- package/dist/{createConversationSession-CUkNp6mZ.cjs → createConversationSession-0WTqcCLK.cjs} +1 -1
- package/dist/{createConversationSession-QIBN0gLx.js → createConversationSession-DPrrr70o.js} +1 -1
- package/dist/createFormCollector-1GKKwQV_.cjs +1 -0
- package/dist/{createFormCollector-F3YJfsbg.js → createFormCollector-DYh90kiG.js} +97 -91
- package/dist/devtools.d.cts +82 -5
- package/dist/devtools.d.ts +82 -5
- package/dist/functions-CPs7omgM.cjs +1 -0
- package/dist/helpers.cjs +1 -1
- package/dist/helpers.d.cts +5 -0
- package/dist/helpers.d.ts +5 -0
- package/dist/helpers.js +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +147 -7
- package/dist/index.d.ts +147 -7
- package/dist/index.js +45 -43
- package/dist/react.cjs +3 -3
- package/dist/react.d.cts +191 -21
- package/dist/react.d.ts +191 -21
- package/dist/react.js +666 -529
- package/dist/testing.cjs +1 -1
- package/dist/testing.d.cts +82 -5
- package/dist/testing.d.ts +82 -5
- package/dist/testing.js +1 -1
- package/dist/vue.cjs +1 -1
- package/dist/vue.d.cts +82 -5
- package/dist/vue.d.ts +82 -5
- package/dist/vue.js +1 -1
- package/dist/widget.cjs +4 -4
- package/dist/widget.d.cts +82 -5
- package/dist/widget.d.ts +82 -5
- package/dist/widget.js +437 -423
- package/llms-full.txt +100 -6
- package/package.json +1 -1
- package/dist/AgoClient-CLmtYTJx.cjs +0 -8
- package/dist/AgoClient-Ozz2b1dQ.js +0 -912
- package/dist/createFormCollector-DHT1ObOb.cjs +0 -1
- package/dist/functions-Djnq-JAo.cjs +0 -1
- package/dist/rolldown-runtime-16Nf8qvH.cjs +0 -1
- /package/dist/{createMockClient-BSr-UV8R.cjs → createMockClient-C-wrjb2C.cjs} +0 -0
- /package/dist/{createMockClient-bAZ9KBHC.js → createMockClient-we-XoPom.js} +0 -0
- /package/dist/{functions-CApuQZ2b.js → functions-tzyOZNp6.js} +0 -0
|
@@ -1,72 +1,72 @@
|
|
|
1
|
-
import { f as
|
|
2
|
-
function
|
|
1
|
+
import { f as w } from "./AgoClient-DXrH2AMi.js";
|
|
2
|
+
function J(n, e) {
|
|
3
3
|
const a = e ? e.storage ?? (typeof localStorage < "u" ? localStorage : void 0) : void 0;
|
|
4
|
-
let
|
|
4
|
+
let s = n;
|
|
5
5
|
if (e && a) try {
|
|
6
6
|
const m = a.getItem(e.key);
|
|
7
|
-
m != null && (
|
|
7
|
+
m != null && (s = JSON.parse(m));
|
|
8
8
|
} catch {
|
|
9
9
|
}
|
|
10
|
-
const o = /* @__PURE__ */ new Set(), c = () => o.forEach((m) => m(
|
|
10
|
+
const o = /* @__PURE__ */ new Set(), c = () => o.forEach((m) => m(s));
|
|
11
11
|
function b() {
|
|
12
12
|
if (e && a) try {
|
|
13
|
-
a.setItem(e.key, JSON.stringify(
|
|
13
|
+
a.setItem(e.key, JSON.stringify(s));
|
|
14
14
|
} catch {
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
return {
|
|
18
|
-
get: () =>
|
|
18
|
+
get: () => s,
|
|
19
19
|
set: (m) => {
|
|
20
|
-
|
|
20
|
+
s = m, b(), c();
|
|
21
21
|
},
|
|
22
22
|
subscribe: (m) => (o.add(m), () => {
|
|
23
23
|
o.delete(m);
|
|
24
24
|
})
|
|
25
25
|
};
|
|
26
26
|
}
|
|
27
|
-
var
|
|
28
|
-
function
|
|
29
|
-
if ("anyOf" in
|
|
30
|
-
if ("allOf" in
|
|
31
|
-
const a = e[
|
|
32
|
-
if (
|
|
33
|
-
if (Array.isArray(
|
|
34
|
-
if (!
|
|
35
|
-
const
|
|
36
|
-
if (Number.isNaN(
|
|
37
|
-
switch (
|
|
27
|
+
var j = /^[a-zA-Z0-9_-]{1,40}$/, I = (n) => n == null || n === "";
|
|
28
|
+
function N(n, e) {
|
|
29
|
+
if ("anyOf" in n) return n.anyOf.some((c) => N(c, e));
|
|
30
|
+
if ("allOf" in n) return n.allOf.every((c) => N(c, e));
|
|
31
|
+
const a = e[n.property];
|
|
32
|
+
if (I(a)) return !1;
|
|
33
|
+
if (Array.isArray(n.value)) return n.value.some((c) => String(a) === String(c));
|
|
34
|
+
if (!n.op) return String(a) === String(n.value);
|
|
35
|
+
const s = Number(a), o = Number(n.value);
|
|
36
|
+
if (Number.isNaN(s) || Number.isNaN(o)) return !1;
|
|
37
|
+
switch (n.op) {
|
|
38
38
|
case ">=":
|
|
39
|
-
return
|
|
39
|
+
return s >= o;
|
|
40
40
|
case "<=":
|
|
41
|
-
return
|
|
41
|
+
return s <= o;
|
|
42
42
|
case ">":
|
|
43
|
-
return
|
|
43
|
+
return s > o;
|
|
44
44
|
case "<":
|
|
45
|
-
return
|
|
45
|
+
return s < o;
|
|
46
46
|
default:
|
|
47
|
-
return
|
|
47
|
+
return w.warn(`Unknown requiredWhen op "${n.op}"; treating as not required.`), !1;
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
|
-
function
|
|
51
|
-
const a =
|
|
52
|
-
for (const c of
|
|
50
|
+
function p(n, e) {
|
|
51
|
+
const a = n.properties ?? {}, s = /* @__PURE__ */ new Set();
|
|
52
|
+
for (const c of n.required ?? []) {
|
|
53
53
|
const b = a[c]?.requiredWhen;
|
|
54
|
-
(!b ||
|
|
54
|
+
(!b || N(b, e)) && s.add(c);
|
|
55
55
|
}
|
|
56
|
-
for (const [c, b] of Object.entries(a)) b.requiredWhen &&
|
|
57
|
-
const o = [...
|
|
56
|
+
for (const [c, b] of Object.entries(a)) b.requiredWhen && N(b.requiredWhen, e) && s.add(c);
|
|
57
|
+
const o = [...s].filter((c) => I(e[c]));
|
|
58
58
|
return {
|
|
59
59
|
missing: o,
|
|
60
60
|
complete: o.length === 0
|
|
61
61
|
};
|
|
62
62
|
}
|
|
63
|
-
function
|
|
63
|
+
function R(n) {
|
|
64
64
|
const e = {};
|
|
65
|
-
for (const [a,
|
|
66
|
-
type:
|
|
67
|
-
...
|
|
68
|
-
...
|
|
69
|
-
...
|
|
65
|
+
for (const [a, s] of Object.entries(n.properties ?? {})) e[a] = {
|
|
66
|
+
type: s.type,
|
|
67
|
+
...s.description != null && { description: s.description },
|
|
68
|
+
...s.enum && { enum: s.enum },
|
|
69
|
+
...s.default !== void 0 && { default: s.default }
|
|
70
70
|
};
|
|
71
71
|
return {
|
|
72
72
|
type: "object",
|
|
@@ -74,15 +74,15 @@ function J(s) {
|
|
|
74
74
|
required: []
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
|
-
function
|
|
78
|
-
const { name: e, description: a, schema:
|
|
79
|
-
if (!
|
|
80
|
-
const o = typeof
|
|
77
|
+
function B(n) {
|
|
78
|
+
const { name: e, description: a, schema: s } = n;
|
|
79
|
+
if (!j.test(e)) throw new Error(`Invalid form collector name "${e}": must match ${j} (it becomes the update_/submit_ function names).`);
|
|
80
|
+
const o = typeof n.submit == "string" ? n.submit ? {
|
|
81
81
|
via: "client",
|
|
82
|
-
url:
|
|
83
|
-
} : !1 :
|
|
84
|
-
|
|
85
|
-
const c = (
|
|
82
|
+
url: n.submit
|
|
83
|
+
} : !1 : n.submit ?? !1;
|
|
84
|
+
n.autoSubmit === !0 && !o && w.warn(`FormCollector "${e}": autoSubmit is ignored because no submit target is configured.`);
|
|
85
|
+
const c = (n.autoSubmit ?? !0) && !!o, b = s.properties ?? {}, m = (t) => {
|
|
86
86
|
const r = {};
|
|
87
87
|
for (const [u, i] of Object.entries(t)) {
|
|
88
88
|
const l = b[u];
|
|
@@ -94,10 +94,10 @@ function R(s) {
|
|
|
94
94
|
} else l.type === "boolean" ? r[u] = typeof i == "boolean" ? i : i === "true" ? !0 : i === "false" ? !1 : !!i : r[u] = i;
|
|
95
95
|
}
|
|
96
96
|
return r;
|
|
97
|
-
},
|
|
98
|
-
values:
|
|
97
|
+
}, $ = n.initialValues ?? {}, f = J({
|
|
98
|
+
values: $,
|
|
99
99
|
submitted: !1
|
|
100
|
-
}),
|
|
100
|
+
}), k = (t) => {
|
|
101
101
|
const r = f.get(), u = {
|
|
102
102
|
...r,
|
|
103
103
|
values: {
|
|
@@ -108,16 +108,16 @@ function R(s) {
|
|
|
108
108
|
return f.set(u), u;
|
|
109
109
|
};
|
|
110
110
|
let h = null;
|
|
111
|
-
const
|
|
111
|
+
const F = (t, r) => {
|
|
112
112
|
h?.emitFormEvent("form:error", {
|
|
113
113
|
name: e,
|
|
114
114
|
values: t,
|
|
115
115
|
error: r
|
|
116
116
|
});
|
|
117
117
|
};
|
|
118
|
-
let
|
|
119
|
-
const
|
|
120
|
-
const { values: t } = f.get(), { complete: r, missing: u } =
|
|
118
|
+
let y = null;
|
|
119
|
+
const V = async () => {
|
|
120
|
+
const { values: t } = f.get(), { complete: r, missing: u } = p(s, t);
|
|
121
121
|
if (!r) return {
|
|
122
122
|
ok: !1,
|
|
123
123
|
missing: u
|
|
@@ -138,10 +138,10 @@ function R(s) {
|
|
|
138
138
|
body: JSON.stringify(i)
|
|
139
139
|
});
|
|
140
140
|
if (!d.ok) {
|
|
141
|
-
const
|
|
142
|
-
return
|
|
141
|
+
const W = `Submit failed: HTTP ${d.status}`;
|
|
142
|
+
return F(i, W), {
|
|
143
143
|
ok: !1,
|
|
144
|
-
error:
|
|
144
|
+
error: W
|
|
145
145
|
};
|
|
146
146
|
}
|
|
147
147
|
l = await d.json().catch(() => {
|
|
@@ -168,27 +168,27 @@ function R(s) {
|
|
|
168
168
|
};
|
|
169
169
|
} catch (l) {
|
|
170
170
|
const d = l instanceof Error ? l.message : "Submit failed";
|
|
171
|
-
return
|
|
171
|
+
return w.error(`FormCollector "${e}" submit failed:`, l), F(i, d), {
|
|
172
172
|
ok: !1,
|
|
173
173
|
error: d
|
|
174
174
|
};
|
|
175
175
|
}
|
|
176
|
-
},
|
|
176
|
+
}, C = () => y || (y = (async () => {
|
|
177
177
|
try {
|
|
178
|
-
return await
|
|
178
|
+
return await V();
|
|
179
179
|
} finally {
|
|
180
|
-
|
|
180
|
+
y = null;
|
|
181
181
|
}
|
|
182
|
-
})(),
|
|
182
|
+
})(), y), q = async () => {
|
|
183
183
|
if (!c || !o) return null;
|
|
184
184
|
const { values: t, submitted: r } = f.get();
|
|
185
|
-
return r || !
|
|
186
|
-
},
|
|
185
|
+
return r || !p(s, t).complete ? null : C();
|
|
186
|
+
}, O = {
|
|
187
187
|
name: `update_${e}`,
|
|
188
188
|
description: `Fill or update fields of the "${e}" form. ${a} 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.`,
|
|
189
|
-
parameters:
|
|
189
|
+
parameters: R(s),
|
|
190
190
|
handler: async (t) => {
|
|
191
|
-
const r =
|
|
191
|
+
const r = k(m(t)), { missing: u } = p(s, r.values), i = await q();
|
|
192
192
|
return i ? i.ok ? {
|
|
193
193
|
ok: !0,
|
|
194
194
|
values: r.values,
|
|
@@ -206,7 +206,7 @@ function R(s) {
|
|
|
206
206
|
missing: u
|
|
207
207
|
};
|
|
208
208
|
}
|
|
209
|
-
}, g = [
|
|
209
|
+
}, g = [O];
|
|
210
210
|
o && !c && g.push({
|
|
211
211
|
name: `submit_${e}`,
|
|
212
212
|
description: `Submit the completed "${e}" 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.`,
|
|
@@ -214,30 +214,34 @@ function R(s) {
|
|
|
214
214
|
type: "object",
|
|
215
215
|
properties: {}
|
|
216
216
|
},
|
|
217
|
-
handler: () =>
|
|
217
|
+
handler: () => C()
|
|
218
218
|
});
|
|
219
|
-
const
|
|
219
|
+
const A = "client__", x = o ? `submit_${e}` : null, D = (t) => {
|
|
220
220
|
const r = t.functionName ?? t.toolName;
|
|
221
221
|
if (r)
|
|
222
|
-
return r.startsWith(
|
|
222
|
+
return r.startsWith(A) ? r.slice(8) : r;
|
|
223
223
|
}, _ = (t) => {
|
|
224
|
-
let r = {
|
|
224
|
+
let r = { ...$ }, u = !1;
|
|
225
225
|
for (const i of t) {
|
|
226
|
-
const l =
|
|
227
|
-
l ===
|
|
226
|
+
const l = D(i);
|
|
227
|
+
l === O.name ? i.arguments && (r = {
|
|
228
228
|
...r,
|
|
229
229
|
...m(i.arguments)
|
|
230
|
-
}) :
|
|
230
|
+
}) : x && l === x && i.status?.toLowerCase() === "done" && (u = !0);
|
|
231
231
|
}
|
|
232
232
|
f.set({
|
|
233
233
|
values: r,
|
|
234
234
|
submitted: u
|
|
235
235
|
});
|
|
236
|
-
},
|
|
237
|
-
|
|
236
|
+
}, v = `form:${e}`, S = `${v}:definition`, E = () => ({
|
|
237
|
+
name: `Form definition: ${e}`,
|
|
238
|
+
description: `${a} Some fields are conditionally required; the requiredWhen field in the schema tells you when each becomes required. The form schema is the following: ${JSON.stringify(s)}.`,
|
|
239
|
+
stable: !0
|
|
240
|
+
}), T = () => {
|
|
241
|
+
const { values: t, submitted: r } = f.get(), { missing: u, complete: i } = p(s, t), l = o ? c ? " The form is submitted automatically as soon as every required field is filled, so there is no submit function to call." : ` When nothing is missing and the user confirms, call submit_${e}.` : "", d = r ? `The "${e}" form has been submitted.` : `You are currently collecting information from the user to fill the "${e}" form.`;
|
|
238
242
|
return {
|
|
239
243
|
name: `Form: ${e}`,
|
|
240
|
-
description: `${d}
|
|
244
|
+
description: `${d} The form's schema and field requirements are in the "${S}" client context. Call update_${e} with any fields the user provides; ask only for what is still missing.${l}`,
|
|
241
245
|
data: {
|
|
242
246
|
values: t,
|
|
243
247
|
missing: u,
|
|
@@ -245,44 +249,46 @@ function R(s) {
|
|
|
245
249
|
submitted: r
|
|
246
250
|
}
|
|
247
251
|
};
|
|
248
|
-
},
|
|
252
|
+
}, P = (t) => {
|
|
249
253
|
_((t.messages ?? []).flatMap((r) => r.toolCalls ?? []));
|
|
250
254
|
};
|
|
251
255
|
return {
|
|
252
256
|
name: e,
|
|
253
257
|
store: f,
|
|
254
258
|
functions: g,
|
|
255
|
-
contextKey:
|
|
256
|
-
contextProvider:
|
|
259
|
+
contextKey: v,
|
|
260
|
+
contextProvider: T,
|
|
261
|
+
definitionContextKey: S,
|
|
262
|
+
definitionContextProvider: E,
|
|
257
263
|
install: (t) => {
|
|
258
264
|
h = t;
|
|
259
265
|
for (const u of g) t.register(u);
|
|
260
|
-
t.addDynamicContext(
|
|
266
|
+
t.addDynamicContext(S, E), t.addDynamicContext(v, T);
|
|
261
267
|
const r = f.subscribe(() => t.notifyContextChanged());
|
|
262
|
-
return t.on("conversation:loaded",
|
|
268
|
+
return t.on("conversation:loaded", P), () => {
|
|
263
269
|
r();
|
|
264
270
|
for (const u of g) t.unregisterFunction(u.name);
|
|
265
|
-
t.removeDynamicContext(
|
|
271
|
+
t.removeDynamicContext(v), t.removeDynamicContext(S), t.off("conversation:loaded", P), h === t && (h = null);
|
|
266
272
|
};
|
|
267
273
|
},
|
|
268
274
|
hydrate: _,
|
|
269
|
-
submit:
|
|
275
|
+
submit: C,
|
|
270
276
|
getValues: () => f.get().values,
|
|
271
277
|
setValues: (t) => {
|
|
272
|
-
|
|
278
|
+
k(m(t)), q();
|
|
273
279
|
},
|
|
274
280
|
reset: () => {
|
|
275
281
|
f.set({
|
|
276
|
-
values:
|
|
282
|
+
values: $,
|
|
277
283
|
submitted: !1
|
|
278
284
|
});
|
|
279
285
|
},
|
|
280
|
-
getStatus: () =>
|
|
286
|
+
getStatus: () => p(s, f.get().values)
|
|
281
287
|
};
|
|
282
288
|
}
|
|
283
|
-
async function
|
|
284
|
-
const a = await
|
|
285
|
-
return
|
|
289
|
+
async function K(n, e) {
|
|
290
|
+
const a = await n.getFormCollector(e.name);
|
|
291
|
+
return B({
|
|
286
292
|
name: a.name,
|
|
287
293
|
description: e.description ?? a.description,
|
|
288
294
|
schema: e.schema ?? a.schema,
|
|
@@ -292,8 +298,8 @@ async function L(s, e) {
|
|
|
292
298
|
});
|
|
293
299
|
}
|
|
294
300
|
export {
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
301
|
+
J as i,
|
|
302
|
+
p as n,
|
|
303
|
+
K as r,
|
|
304
|
+
B as t
|
|
299
305
|
};
|
package/dist/devtools.d.cts
CHANGED
|
@@ -41,6 +41,12 @@ declare class AgoClient {
|
|
|
41
41
|
private warnedEmptyConversations;
|
|
42
42
|
/** Paused turns awaiting auto-resume, keyed by assistant message id. */
|
|
43
43
|
private pendingResumes;
|
|
44
|
+
/**
|
|
45
|
+
* Client function invocations held pending user approval, keyed by
|
|
46
|
+
* invocationId (the tool-call id). Populated when {@link requiresApproval}
|
|
47
|
+
* matches; drained by {@link approveFunction} / {@link rejectFunction}.
|
|
48
|
+
*/
|
|
49
|
+
private pendingApprovals;
|
|
44
50
|
/** App-provided gate deciding WHEN a paused turn resumes (see {@link registerResumeGate}). */
|
|
45
51
|
private resumeGate;
|
|
46
52
|
constructor(config: AgoConfig);
|
|
@@ -91,6 +97,24 @@ declare class AgoClient {
|
|
|
91
97
|
*/
|
|
92
98
|
private maybeFlagEmptyReply;
|
|
93
99
|
private handleClientFunctionInvocation;
|
|
100
|
+
/**
|
|
101
|
+
* Whether a client function invocation must wait for explicit user approval.
|
|
102
|
+
* True when the {@link AgoConfig.approvalPolicy} returns true OR the function
|
|
103
|
+
* was registered with `requiresApproval: true` — the two OR together.
|
|
104
|
+
*/
|
|
105
|
+
private requiresApproval;
|
|
106
|
+
/**
|
|
107
|
+
* Approve a client function call held by the approval gate: run it, submit its
|
|
108
|
+
* result, and let the paused turn resume. No-op if the invocation is unknown
|
|
109
|
+
* (already handled, or never gated).
|
|
110
|
+
*/
|
|
111
|
+
approveFunction(invocationId: string): Promise<void>;
|
|
112
|
+
/**
|
|
113
|
+
* Reject a client function call held by the approval gate: submit a rejection
|
|
114
|
+
* result so the agent sees the user declined, and let the paused turn resume
|
|
115
|
+
* (the agent decides what to do next). No-op if the invocation is unknown.
|
|
116
|
+
*/
|
|
117
|
+
rejectFunction(invocationId: string): Promise<void>;
|
|
94
118
|
/**
|
|
95
119
|
* Get list of conversations
|
|
96
120
|
*/
|
|
@@ -120,8 +144,10 @@ declare class AgoClient {
|
|
|
120
144
|
*
|
|
121
145
|
* Opt-in on purpose — re-running functions on reload can be surprising (e.g. a
|
|
122
146
|
* navigation function would navigate again), so the app decides. Returns the
|
|
123
|
-
* resumed turn's final message, or `null` when there was nothing to resume
|
|
124
|
-
* some waiting function is not registered on this page
|
|
147
|
+
* resumed turn's final message, or `null` when there was nothing to resume,
|
|
148
|
+
* some waiting function is not registered on this page, or a waiting call is
|
|
149
|
+
* gated by the approval policy (it is held for `approveFunction` /
|
|
150
|
+
* `rejectFunction` and the turn stays paused, exactly as on the live stream).
|
|
125
151
|
*/
|
|
126
152
|
resumePendingClientFunctions(conversation: Conversation): Promise<AgoMessage | null>;
|
|
127
153
|
/**
|
|
@@ -416,6 +442,15 @@ declare interface AgoClientEvents {
|
|
|
416
442
|
"toolCall:received": ToolCallData;
|
|
417
443
|
"toolCall:form": ToolCallData;
|
|
418
444
|
"function:invoke": ClientFunctionInvocation;
|
|
445
|
+
/**
|
|
446
|
+
* A client function call is held pending the user's approval (pause mode +
|
|
447
|
+
* an {@link AgoConfig.approvalPolicy}/`requiresApproval` match). The turn stays
|
|
448
|
+
* at `WAITING_CLIENT`; call `approveFunction(invocationId)` to run it and
|
|
449
|
+
* resume, or `rejectFunction(invocationId)` to decline. Fires after
|
|
450
|
+
* `function:invoke` (which still fires for every call) and instead of the
|
|
451
|
+
* call running immediately.
|
|
452
|
+
*/
|
|
453
|
+
"function:awaiting-approval": ClientFunctionInvocation;
|
|
419
454
|
"function:result": {
|
|
420
455
|
invocationId: string;
|
|
421
456
|
result: unknown;
|
|
@@ -476,14 +511,28 @@ declare interface AgoConfig {
|
|
|
476
511
|
warnOnEmptyReply?: boolean;
|
|
477
512
|
/**
|
|
478
513
|
* How the agent loop treats client function calls (requires backend support):
|
|
479
|
-
* - `"
|
|
480
|
-
* result; the real result is only visible to the agent on later turns.
|
|
481
|
-
* - `"pause"`: the turn stops on client function call(s) with status
|
|
514
|
+
* - `"pause"` (default): the turn stops on client function call(s) with status
|
|
482
515
|
* `WAITING_CLIENT`; once every result is submitted, the SDK resumes the SAME
|
|
483
516
|
* turn via `POST /messages/{id}/continue`, so the agent sees the real results.
|
|
517
|
+
* - `"placeholder"` (legacy): the turn continues immediately on a placeholder
|
|
518
|
+
* result; the real result is only visible to the agent on later turns.
|
|
484
519
|
* Older backends ignore the flag, so `"pause"` degrades to legacy behavior.
|
|
485
520
|
*/
|
|
486
521
|
clientFunctionsMode?: ClientFunctionsMode;
|
|
522
|
+
/**
|
|
523
|
+
* Gate client function calls behind explicit user approval. Return `true` for
|
|
524
|
+
* an invocation the user must approve/reject before it runs; return `false`
|
|
525
|
+
* (or omit the policy) to let it run immediately as before.
|
|
526
|
+
*
|
|
527
|
+
* Only effective in pause mode (`clientFunctionsMode: "pause"`) — a gated call
|
|
528
|
+
* holds at `WAITING_CLIENT`, the SDK emits `function:awaiting-approval`, and it
|
|
529
|
+
* runs (and the turn resumes) only after `approveFunction(invocationId)`; a
|
|
530
|
+
* `rejectFunction(invocationId)` submits a rejection so the agent sees the
|
|
531
|
+
* decline. In placeholder mode there is no pause to hold, so the policy is a
|
|
532
|
+
* no-op and the call runs normally. A per-function `requiresApproval: true`
|
|
533
|
+
* also gates a call; the policy and the flag OR together.
|
|
534
|
+
*/
|
|
535
|
+
approvalPolicy?: (invocation: ClientFunctionInvocation) => boolean;
|
|
487
536
|
/**
|
|
488
537
|
* Max serialized size (bytes) of a client function result before the SDK
|
|
489
538
|
* replaces it with a flagged, truncated preview. Everything a handler
|
|
@@ -528,6 +577,11 @@ declare interface AgoMessage {
|
|
|
528
577
|
declare interface AgoPageStateOptions {
|
|
529
578
|
/** Name of the synthesized client function. Defaults to "setPageState". */
|
|
530
579
|
functionName?: string;
|
|
580
|
+
/**
|
|
581
|
+
* Require explicit user approval before this state change runs. See
|
|
582
|
+
* {@link AgoConfig.approvalPolicy} — pause mode only. Defaults to `false`.
|
|
583
|
+
*/
|
|
584
|
+
requiresApproval?: boolean;
|
|
531
585
|
}
|
|
532
586
|
|
|
533
587
|
/**
|
|
@@ -589,6 +643,11 @@ declare interface ClientFunctionDefinition {
|
|
|
589
643
|
* `Infinity` disables the guard for this function.
|
|
590
644
|
*/
|
|
591
645
|
maxResultBytes?: number;
|
|
646
|
+
/**
|
|
647
|
+
* Require explicit user approval before this function runs. See
|
|
648
|
+
* {@link AgoConfig.approvalPolicy} — pause mode only. ORs with the policy.
|
|
649
|
+
*/
|
|
650
|
+
requiresApproval?: boolean;
|
|
592
651
|
}
|
|
593
652
|
|
|
594
653
|
/**
|
|
@@ -615,6 +674,11 @@ declare type ClientFunctionRegisterOptions = Omit<ClientFunctionSchema, "name">
|
|
|
615
674
|
* disables the guard for this function.
|
|
616
675
|
*/
|
|
617
676
|
maxResultBytes?: number;
|
|
677
|
+
/**
|
|
678
|
+
* Require explicit user approval before this function runs. See
|
|
679
|
+
* {@link AgoConfig.approvalPolicy} — pause mode only. ORs with the policy.
|
|
680
|
+
*/
|
|
681
|
+
requiresApproval?: boolean;
|
|
618
682
|
};
|
|
619
683
|
|
|
620
684
|
/**
|
|
@@ -655,6 +719,19 @@ declare interface ContextEntry {
|
|
|
655
719
|
description?: string;
|
|
656
720
|
/** Arbitrary structured data the AI should know about */
|
|
657
721
|
data?: Record<string, unknown>;
|
|
722
|
+
/**
|
|
723
|
+
* Marks the entry as constant for the whole conversation. The backend then
|
|
724
|
+
* pins it right after the system prompt, where LLM providers cache it across
|
|
725
|
+
* turns, instead of re-processing it next to every new user message.
|
|
726
|
+
*
|
|
727
|
+
* Only set this when the entry's content is byte-identical on every message
|
|
728
|
+
* of a conversation (a schema, a capability list, static instructions). A
|
|
729
|
+
* stable entry that changes between messages invalidates the provider's
|
|
730
|
+
* cache for the entire conversation history, which costs more than leaving
|
|
731
|
+
* the flag off. Default: `false` (re-sent near the newest user message).
|
|
732
|
+
* Backends that don't know the flag ignore it.
|
|
733
|
+
*/
|
|
734
|
+
stable?: boolean;
|
|
658
735
|
}
|
|
659
736
|
|
|
660
737
|
/**
|
package/dist/devtools.d.ts
CHANGED
|
@@ -41,6 +41,12 @@ declare class AgoClient {
|
|
|
41
41
|
private warnedEmptyConversations;
|
|
42
42
|
/** Paused turns awaiting auto-resume, keyed by assistant message id. */
|
|
43
43
|
private pendingResumes;
|
|
44
|
+
/**
|
|
45
|
+
* Client function invocations held pending user approval, keyed by
|
|
46
|
+
* invocationId (the tool-call id). Populated when {@link requiresApproval}
|
|
47
|
+
* matches; drained by {@link approveFunction} / {@link rejectFunction}.
|
|
48
|
+
*/
|
|
49
|
+
private pendingApprovals;
|
|
44
50
|
/** App-provided gate deciding WHEN a paused turn resumes (see {@link registerResumeGate}). */
|
|
45
51
|
private resumeGate;
|
|
46
52
|
constructor(config: AgoConfig);
|
|
@@ -91,6 +97,24 @@ declare class AgoClient {
|
|
|
91
97
|
*/
|
|
92
98
|
private maybeFlagEmptyReply;
|
|
93
99
|
private handleClientFunctionInvocation;
|
|
100
|
+
/**
|
|
101
|
+
* Whether a client function invocation must wait for explicit user approval.
|
|
102
|
+
* True when the {@link AgoConfig.approvalPolicy} returns true OR the function
|
|
103
|
+
* was registered with `requiresApproval: true` — the two OR together.
|
|
104
|
+
*/
|
|
105
|
+
private requiresApproval;
|
|
106
|
+
/**
|
|
107
|
+
* Approve a client function call held by the approval gate: run it, submit its
|
|
108
|
+
* result, and let the paused turn resume. No-op if the invocation is unknown
|
|
109
|
+
* (already handled, or never gated).
|
|
110
|
+
*/
|
|
111
|
+
approveFunction(invocationId: string): Promise<void>;
|
|
112
|
+
/**
|
|
113
|
+
* Reject a client function call held by the approval gate: submit a rejection
|
|
114
|
+
* result so the agent sees the user declined, and let the paused turn resume
|
|
115
|
+
* (the agent decides what to do next). No-op if the invocation is unknown.
|
|
116
|
+
*/
|
|
117
|
+
rejectFunction(invocationId: string): Promise<void>;
|
|
94
118
|
/**
|
|
95
119
|
* Get list of conversations
|
|
96
120
|
*/
|
|
@@ -120,8 +144,10 @@ declare class AgoClient {
|
|
|
120
144
|
*
|
|
121
145
|
* Opt-in on purpose — re-running functions on reload can be surprising (e.g. a
|
|
122
146
|
* navigation function would navigate again), so the app decides. Returns the
|
|
123
|
-
* resumed turn's final message, or `null` when there was nothing to resume
|
|
124
|
-
* some waiting function is not registered on this page
|
|
147
|
+
* resumed turn's final message, or `null` when there was nothing to resume,
|
|
148
|
+
* some waiting function is not registered on this page, or a waiting call is
|
|
149
|
+
* gated by the approval policy (it is held for `approveFunction` /
|
|
150
|
+
* `rejectFunction` and the turn stays paused, exactly as on the live stream).
|
|
125
151
|
*/
|
|
126
152
|
resumePendingClientFunctions(conversation: Conversation): Promise<AgoMessage | null>;
|
|
127
153
|
/**
|
|
@@ -416,6 +442,15 @@ declare interface AgoClientEvents {
|
|
|
416
442
|
"toolCall:received": ToolCallData;
|
|
417
443
|
"toolCall:form": ToolCallData;
|
|
418
444
|
"function:invoke": ClientFunctionInvocation;
|
|
445
|
+
/**
|
|
446
|
+
* A client function call is held pending the user's approval (pause mode +
|
|
447
|
+
* an {@link AgoConfig.approvalPolicy}/`requiresApproval` match). The turn stays
|
|
448
|
+
* at `WAITING_CLIENT`; call `approveFunction(invocationId)` to run it and
|
|
449
|
+
* resume, or `rejectFunction(invocationId)` to decline. Fires after
|
|
450
|
+
* `function:invoke` (which still fires for every call) and instead of the
|
|
451
|
+
* call running immediately.
|
|
452
|
+
*/
|
|
453
|
+
"function:awaiting-approval": ClientFunctionInvocation;
|
|
419
454
|
"function:result": {
|
|
420
455
|
invocationId: string;
|
|
421
456
|
result: unknown;
|
|
@@ -476,14 +511,28 @@ declare interface AgoConfig {
|
|
|
476
511
|
warnOnEmptyReply?: boolean;
|
|
477
512
|
/**
|
|
478
513
|
* How the agent loop treats client function calls (requires backend support):
|
|
479
|
-
* - `"
|
|
480
|
-
* result; the real result is only visible to the agent on later turns.
|
|
481
|
-
* - `"pause"`: the turn stops on client function call(s) with status
|
|
514
|
+
* - `"pause"` (default): the turn stops on client function call(s) with status
|
|
482
515
|
* `WAITING_CLIENT`; once every result is submitted, the SDK resumes the SAME
|
|
483
516
|
* turn via `POST /messages/{id}/continue`, so the agent sees the real results.
|
|
517
|
+
* - `"placeholder"` (legacy): the turn continues immediately on a placeholder
|
|
518
|
+
* result; the real result is only visible to the agent on later turns.
|
|
484
519
|
* Older backends ignore the flag, so `"pause"` degrades to legacy behavior.
|
|
485
520
|
*/
|
|
486
521
|
clientFunctionsMode?: ClientFunctionsMode;
|
|
522
|
+
/**
|
|
523
|
+
* Gate client function calls behind explicit user approval. Return `true` for
|
|
524
|
+
* an invocation the user must approve/reject before it runs; return `false`
|
|
525
|
+
* (or omit the policy) to let it run immediately as before.
|
|
526
|
+
*
|
|
527
|
+
* Only effective in pause mode (`clientFunctionsMode: "pause"`) — a gated call
|
|
528
|
+
* holds at `WAITING_CLIENT`, the SDK emits `function:awaiting-approval`, and it
|
|
529
|
+
* runs (and the turn resumes) only after `approveFunction(invocationId)`; a
|
|
530
|
+
* `rejectFunction(invocationId)` submits a rejection so the agent sees the
|
|
531
|
+
* decline. In placeholder mode there is no pause to hold, so the policy is a
|
|
532
|
+
* no-op and the call runs normally. A per-function `requiresApproval: true`
|
|
533
|
+
* also gates a call; the policy and the flag OR together.
|
|
534
|
+
*/
|
|
535
|
+
approvalPolicy?: (invocation: ClientFunctionInvocation) => boolean;
|
|
487
536
|
/**
|
|
488
537
|
* Max serialized size (bytes) of a client function result before the SDK
|
|
489
538
|
* replaces it with a flagged, truncated preview. Everything a handler
|
|
@@ -528,6 +577,11 @@ declare interface AgoMessage {
|
|
|
528
577
|
declare interface AgoPageStateOptions {
|
|
529
578
|
/** Name of the synthesized client function. Defaults to "setPageState". */
|
|
530
579
|
functionName?: string;
|
|
580
|
+
/**
|
|
581
|
+
* Require explicit user approval before this state change runs. See
|
|
582
|
+
* {@link AgoConfig.approvalPolicy} — pause mode only. Defaults to `false`.
|
|
583
|
+
*/
|
|
584
|
+
requiresApproval?: boolean;
|
|
531
585
|
}
|
|
532
586
|
|
|
533
587
|
/**
|
|
@@ -589,6 +643,11 @@ declare interface ClientFunctionDefinition {
|
|
|
589
643
|
* `Infinity` disables the guard for this function.
|
|
590
644
|
*/
|
|
591
645
|
maxResultBytes?: number;
|
|
646
|
+
/**
|
|
647
|
+
* Require explicit user approval before this function runs. See
|
|
648
|
+
* {@link AgoConfig.approvalPolicy} — pause mode only. ORs with the policy.
|
|
649
|
+
*/
|
|
650
|
+
requiresApproval?: boolean;
|
|
592
651
|
}
|
|
593
652
|
|
|
594
653
|
/**
|
|
@@ -615,6 +674,11 @@ declare type ClientFunctionRegisterOptions = Omit<ClientFunctionSchema, "name">
|
|
|
615
674
|
* disables the guard for this function.
|
|
616
675
|
*/
|
|
617
676
|
maxResultBytes?: number;
|
|
677
|
+
/**
|
|
678
|
+
* Require explicit user approval before this function runs. See
|
|
679
|
+
* {@link AgoConfig.approvalPolicy} — pause mode only. ORs with the policy.
|
|
680
|
+
*/
|
|
681
|
+
requiresApproval?: boolean;
|
|
618
682
|
};
|
|
619
683
|
|
|
620
684
|
/**
|
|
@@ -655,6 +719,19 @@ declare interface ContextEntry {
|
|
|
655
719
|
description?: string;
|
|
656
720
|
/** Arbitrary structured data the AI should know about */
|
|
657
721
|
data?: Record<string, unknown>;
|
|
722
|
+
/**
|
|
723
|
+
* Marks the entry as constant for the whole conversation. The backend then
|
|
724
|
+
* pins it right after the system prompt, where LLM providers cache it across
|
|
725
|
+
* turns, instead of re-processing it next to every new user message.
|
|
726
|
+
*
|
|
727
|
+
* Only set this when the entry's content is byte-identical on every message
|
|
728
|
+
* of a conversation (a schema, a capability list, static instructions). A
|
|
729
|
+
* stable entry that changes between messages invalidates the provider's
|
|
730
|
+
* cache for the entire conversation history, which costs more than leaving
|
|
731
|
+
* the flag off. Default: `false` (re-sent near the newest user message).
|
|
732
|
+
* Backends that don't know the flag ignore it.
|
|
733
|
+
*/
|
|
734
|
+
stable?: boolean;
|
|
658
735
|
}
|
|
659
736
|
|
|
660
737
|
/**
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const v=require("./react.cjs");var w=v.__exportAll({copyToClipboard:()=>c,getLocalStorage:()=>f,getUserLocation:()=>p,highlightElement:()=>h,openUrl:()=>a,scrollToElement:()=>d,setLocalStorage:()=>m,setTheme:()=>l,showConfirmDialog:()=>u,showNotification:()=>s,showToast:()=>i,submitForm:()=>y,trackEvent:()=>g}),i={name:"showToast",description:"Show a toast notification to the user. Use this to confirm actions or display brief messages.",parameters:{type:"object",properties:{message:{type:"string",description:"The message to display"},type:{type:"string",description:"Toast type",enum:["success","error","warning","info"]},duration:{type:"number",description:"Duration in milliseconds (default 3000)"}},required:["message"]},handler:async()=>({shown:!1,error:"No toast handler configured"})},s={name:"showNotification",description:"Show a browser notification to the user. Useful for important alerts even when the tab is not focused.",parameters:{type:"object",properties:{title:{type:"string",description:"Notification title"},body:{type:"string",description:"Notification body text"}},required:["title"]},handler:async e=>typeof Notification>"u"?{shown:!1,error:"Notifications not supported"}:Notification.permission==="denied"?{shown:!1,error:"Notification permission denied"}:(Notification.permission!=="granted"&&await Notification.requestPermission(),Notification.permission==="granted"?(new Notification(e.title,{body:e.body}),{shown:!0}):{shown:!1,error:"Permission not granted"})},a={name:"openUrl",description:"Open a URL in a new browser tab.",parameters:{type:"object",properties:{url:{type:"string",description:"The URL to open"}},required:["url"]},handler:async e=>(window.open(e.url,"_blank","noopener,noreferrer"),{opened:!0})},c={name:"copyToClipboard",description:"Copy text to the user's clipboard.",parameters:{type:"object",properties:{text:{type:"string",description:"The text to copy"}},required:["text"]},handler:async e=>(await navigator.clipboard.writeText(e.text),{copied:!0})},l={name:"setTheme",description:"Change the application's color theme. Sets a data-theme attribute on the document element.",parameters:{type:"object",properties:{theme:{type:"string",description:"Theme to apply",enum:["light","dark","system"]}},required:["theme"]},handler:async e=>{const t=e.theme;return document.documentElement.setAttribute("data-theme",t),t==="dark"?document.documentElement.classList.add("dark"):document.documentElement.classList.remove("dark"),{theme:t,applied:!0}}},u={name:"showConfirmDialog",description:"Show a confirmation dialog to the user and return their choice (true/false).",parameters:{type:"object",properties:{message:{type:"string",description:"The confirmation message to display"}},required:["message"]},handler:async e=>({confirmed:window.confirm(e.message)})},p={name:"getUserLocation",description:"Get the user's current geographic location (requires permission).",parameters:{type:"object",properties:{}},handler:async()=>navigator.geolocation?new Promise(e=>{navigator.geolocation.getCurrentPosition(t=>e({latitude:t.coords.latitude,longitude:t.coords.longitude,accuracy:t.coords.accuracy}),t=>e({error:t.message}))}):{error:"Geolocation not supported"}},d={name:"scrollToElement",description:"Scroll the page to a specific element identified by CSS selector.",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the element to scroll to (e.g. '#section-pricing')"},behavior:{type:"string",description:"Scroll behavior",enum:["smooth","instant"]}},required:["selector"]},handler:async e=>{const t=document.querySelector(e.selector);return t?(t.scrollIntoView({behavior:e.behavior||"smooth"}),{scrolled:!0}):{scrolled:!1,error:`Element not found: ${e.selector}`}}},m={name:"setLocalStorage",description:"Store a value in the browser's localStorage.",parameters:{type:"object",properties:{key:{type:"string",description:"Storage key"},value:{type:"string",description:"Value to store"}},required:["key","value"]},handler:async e=>(localStorage.setItem(e.key,e.value),{stored:!0})},f={name:"getLocalStorage",description:"Retrieve a value from the browser's localStorage.",parameters:{type:"object",properties:{key:{type:"string",description:"Storage key"}},required:["key"]},handler:async e=>{const t=localStorage.getItem(e.key);return{key:e.key,value:t,found:t!==null}}},h={name:"highlightElement",description:"Highlight a DOM element to draw the user's attention (e.g. for onboarding).",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the element to highlight"},color:{type:"string",description:"Highlight border color (default: #3b82f6)"}},required:["selector"]},handler:async e=>{const t=document.querySelector(e.selector);if(!t)return{highlighted:!1,error:`Element not found: ${e.selector}`};const r=t.style.outline,o=e.color||"#3b82f6";return t.style.outline=`3px solid ${o}`,t.style.outlineOffset="2px",t.scrollIntoView({behavior:"smooth",block:"center"}),setTimeout(()=>{t.style.outline=r,t.style.outlineOffset=""},3e3),{highlighted:!0}}},y={name:"submitForm",description:"Fill and submit an HTML form on the page. Pass field values as key-value pairs.",parameters:{type:"object",properties:{selector:{type:"string",description:"CSS selector of the form element"},values:{type:"string",description:"JSON string of field name → value pairs"}},required:["selector"]},handler:async e=>{const t=document.querySelector(e.selector);if(!t)return{submitted:!1,error:`Form not found: ${e.selector}`};if(e.values){const r=JSON.parse(e.values);for(const[o,b]of Object.entries(r)){const n=t.elements.namedItem(o);n&&(n.value=b)}}return t.requestSubmit(),{submitted:!0}}},g={name:"trackEvent",description:"Track a custom analytics event. Override the handler to wire up your analytics provider.",parameters:{type:"object",properties:{event:{type:"string",description:"Event name"},properties:{type:"string",description:"JSON string of event properties"}},required:["event"]},handler:async e=>{const t=e.properties?JSON.parse(e.properties):{};return console.log(`[AGO Analytics] ${e.event}`,t),{tracked:!0,event:e.event}}};Object.defineProperty(exports,"copyToClipboard",{enumerable:!0,get:function(){return c}});Object.defineProperty(exports,"functions_exports",{enumerable:!0,get:function(){return w}});Object.defineProperty(exports,"getLocalStorage",{enumerable:!0,get:function(){return f}});Object.defineProperty(exports,"getUserLocation",{enumerable:!0,get:function(){return p}});Object.defineProperty(exports,"highlightElement",{enumerable:!0,get:function(){return h}});Object.defineProperty(exports,"openUrl",{enumerable:!0,get:function(){return a}});Object.defineProperty(exports,"scrollToElement",{enumerable:!0,get:function(){return d}});Object.defineProperty(exports,"setLocalStorage",{enumerable:!0,get:function(){return m}});Object.defineProperty(exports,"setTheme",{enumerable:!0,get:function(){return l}});Object.defineProperty(exports,"showConfirmDialog",{enumerable:!0,get:function(){return u}});Object.defineProperty(exports,"showNotification",{enumerable:!0,get:function(){return s}});Object.defineProperty(exports,"showToast",{enumerable:!0,get:function(){return i}});Object.defineProperty(exports,"submitForm",{enumerable:!0,get:function(){return y}});Object.defineProperty(exports,"trackEvent",{enumerable:!0,get:function(){return g}});
|