@webless/agent 0.2.6 → 0.2.8
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/{chunk-GMG4WJNF.js → chunk-4SMLPH3B.js} +141 -20
- package/dist/chunk-4SMLPH3B.js.map +1 -0
- package/dist/embed.cjs +193 -21
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.d.cts +19 -5
- package/dist/embed.d.ts +19 -5
- package/dist/embed.js +52 -2
- package/dist/embed.js.map +1 -1
- package/dist/index.cjs +129 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -3
- package/dist/index.d.ts +10 -3
- package/dist/index.js +130 -14
- package/dist/index.js.map +1 -1
- package/dist/{placement-2d9GQGou.d.cts → placement-CXW_83AF.d.cts} +3 -1
- package/dist/{placement-2d9GQGou.d.ts → placement-CXW_83AF.d.ts} +3 -1
- package/dist/react.cjs +139 -18
- package/dist/react.cjs.map +1 -1
- package/dist/react.d.cts +6 -4
- package/dist/react.d.ts +6 -4
- package/dist/react.js +1 -1
- package/package.json +4 -4
- package/scripts/build-agent-manifest-bundle-impl.mjs +32 -32
- package/dist/chunk-GMG4WJNF.js.map +0 -1
package/dist/react.cjs
CHANGED
|
@@ -40,22 +40,110 @@ var import_react5 = require("react");
|
|
|
40
40
|
var import_react = require("react");
|
|
41
41
|
|
|
42
42
|
// src/runtime/client.ts
|
|
43
|
+
var import_client2 = require("eve/client");
|
|
44
|
+
|
|
45
|
+
// src/runtime/capability.ts
|
|
43
46
|
var import_client = require("eve/client");
|
|
47
|
+
var MAX_REFRESH_SKEW_MS = 3e4;
|
|
48
|
+
function isRecord(value) {
|
|
49
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
50
|
+
}
|
|
51
|
+
function parseBootstrapResponse(value, indexId, now) {
|
|
52
|
+
if (!isRecord(value) || value.apiVersion !== "webless.ai/agent-runtime-bootstrap/v1" || typeof value.accessToken !== "string" || !value.accessToken || typeof value.expiresAt !== "string" || !isRecord(value.identity) || value.identity.indexId !== indexId || typeof value.identity.revision !== "string" || !value.identity.revision || typeof value.identity.tenantId !== "string" || !value.identity.tenantId || typeof value.origin !== "string" || !value.origin || value.tokenType !== "Bearer" || typeof value.visitorSubject !== "string" || !value.visitorSubject) {
|
|
53
|
+
throw new Error("Agent Runtime returned an invalid access response.");
|
|
54
|
+
}
|
|
55
|
+
const expiresAt = Date.parse(value.expiresAt);
|
|
56
|
+
if (!Number.isFinite(expiresAt) || expiresAt <= now) {
|
|
57
|
+
throw new Error("Agent Runtime returned an expired access response.");
|
|
58
|
+
}
|
|
59
|
+
const refreshSkew = Math.min(MAX_REFRESH_SKEW_MS, Math.floor((expiresAt - now) / 10));
|
|
60
|
+
return {
|
|
61
|
+
accessToken: value.accessToken,
|
|
62
|
+
refreshAt: expiresAt - refreshSkew
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
async function readBootstrapError(response) {
|
|
66
|
+
const fallback = `Agent Runtime is unavailable (${response.status}).`;
|
|
67
|
+
try {
|
|
68
|
+
const value = await response.json();
|
|
69
|
+
return isRecord(value) && typeof value.error === "string" && value.error ? value.error : fallback;
|
|
70
|
+
} catch {
|
|
71
|
+
return fallback;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
function createAgentRuntimeCapability(options) {
|
|
75
|
+
const fetchImplementation = options.fetchImplementation ?? fetch;
|
|
76
|
+
const now = options.now ?? Date.now;
|
|
77
|
+
let capability;
|
|
78
|
+
let pendingBootstrap;
|
|
79
|
+
const bootstrap = async () => {
|
|
80
|
+
const response = await fetchImplementation(`${options.runtimeOrigin}/webless/v1/bootstrap`, {
|
|
81
|
+
body: JSON.stringify({
|
|
82
|
+
clientSessionId: options.visitorSessionId,
|
|
83
|
+
indexId: options.indexId
|
|
84
|
+
}),
|
|
85
|
+
headers: { "content-type": "application/json" },
|
|
86
|
+
method: "POST"
|
|
87
|
+
});
|
|
88
|
+
if (!response.ok) {
|
|
89
|
+
throw new Error(await readBootstrapError(response));
|
|
90
|
+
}
|
|
91
|
+
let value;
|
|
92
|
+
try {
|
|
93
|
+
value = await response.json();
|
|
94
|
+
} catch {
|
|
95
|
+
throw new Error("Agent Runtime returned an invalid access response.");
|
|
96
|
+
}
|
|
97
|
+
return parseBootstrapResponse(value, options.indexId, now());
|
|
98
|
+
};
|
|
99
|
+
return {
|
|
100
|
+
getAccessToken: async () => {
|
|
101
|
+
if (capability && capability.refreshAt > now()) {
|
|
102
|
+
return capability.accessToken;
|
|
103
|
+
}
|
|
104
|
+
pendingBootstrap ??= bootstrap().finally(() => {
|
|
105
|
+
pendingBootstrap = void 0;
|
|
106
|
+
});
|
|
107
|
+
capability = await pendingBootstrap;
|
|
108
|
+
return capability.accessToken;
|
|
109
|
+
},
|
|
110
|
+
invalidate: () => {
|
|
111
|
+
capability = void 0;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
async function withCapabilityRefresh(capability, request) {
|
|
116
|
+
try {
|
|
117
|
+
return await request();
|
|
118
|
+
} catch (error) {
|
|
119
|
+
if (!(error instanceof import_client.ClientError) || error.status !== 401) {
|
|
120
|
+
throw error;
|
|
121
|
+
}
|
|
122
|
+
capability.invalidate();
|
|
123
|
+
return await request();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
44
126
|
|
|
45
127
|
// src/runtime/config.ts
|
|
46
128
|
var DEFAULT_RUNTIME_ORIGIN = "https://runtime.staging.webless.ai";
|
|
47
129
|
var trimTrailingSlash = (value) => value.replace(/\/+$/, "");
|
|
48
|
-
function buildEveHost(origin, indexId) {
|
|
130
|
+
function buildEveHost(origin, indexId, version = "published") {
|
|
49
131
|
const base = trimTrailingSlash(origin);
|
|
50
|
-
|
|
132
|
+
const searchParams = new URLSearchParams({ indexId: indexId.trim() });
|
|
133
|
+
if (version === "unpublished") {
|
|
134
|
+
searchParams.set("version", version);
|
|
135
|
+
}
|
|
136
|
+
return `${base}?${searchParams.toString()}`;
|
|
51
137
|
}
|
|
52
138
|
function resolveAgentRuntimeConfig(input) {
|
|
53
139
|
const origin = trimTrailingSlash(input.runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN);
|
|
54
140
|
const resolvedIndexId = input.indexId.trim();
|
|
141
|
+
const version = input.version ?? "published";
|
|
55
142
|
return {
|
|
56
143
|
origin,
|
|
57
144
|
indexId: resolvedIndexId,
|
|
58
|
-
|
|
145
|
+
version,
|
|
146
|
+
host: resolvedIndexId ? buildEveHost(origin, resolvedIndexId, version) : origin
|
|
59
147
|
};
|
|
60
148
|
}
|
|
61
149
|
|
|
@@ -72,7 +160,8 @@ function buildAgentStorageKeyPrefix(input) {
|
|
|
72
160
|
if (!indexId) {
|
|
73
161
|
throw new Error("indexId is required to build agent storage keys.");
|
|
74
162
|
}
|
|
75
|
-
|
|
163
|
+
const versionSuffix = input.version === "unpublished" ? ":unpublished" : "";
|
|
164
|
+
return `${DEFAULT_STORAGE_KEY_PREFIX}:${customerId}:${indexId}${versionSuffix}:${normalizeRuntimeOrigin(input.runtimeOrigin)}`;
|
|
76
165
|
}
|
|
77
166
|
function createSessionId() {
|
|
78
167
|
if (typeof crypto !== "undefined" && typeof crypto.randomUUID === "function") {
|
|
@@ -141,13 +230,20 @@ function mapStepLabel(event) {
|
|
|
141
230
|
};
|
|
142
231
|
}
|
|
143
232
|
var AgentSession = class {
|
|
144
|
-
constructor(indexId, runtimeOrigin, visitorSessionId, storeOptions) {
|
|
233
|
+
constructor(indexId, version, runtimeOrigin, visitorSessionId, storeOptions) {
|
|
145
234
|
this.indexId = indexId;
|
|
235
|
+
this.version = version;
|
|
146
236
|
this.runtimeOrigin = runtimeOrigin;
|
|
147
237
|
this.visitorSessionId = visitorSessionId;
|
|
148
238
|
this.storeOptions = storeOptions;
|
|
239
|
+
this.capability = createAgentRuntimeCapability({
|
|
240
|
+
indexId,
|
|
241
|
+
runtimeOrigin,
|
|
242
|
+
visitorSessionId
|
|
243
|
+
});
|
|
149
244
|
}
|
|
150
245
|
indexId;
|
|
246
|
+
version;
|
|
151
247
|
runtimeOrigin;
|
|
152
248
|
visitorSessionId;
|
|
153
249
|
storeOptions;
|
|
@@ -156,6 +252,7 @@ var AgentSession = class {
|
|
|
156
252
|
session;
|
|
157
253
|
activeResponse;
|
|
158
254
|
renderedPrefix = "";
|
|
255
|
+
capability;
|
|
159
256
|
getActiveSessionId() {
|
|
160
257
|
return this.session?.state.sessionId ?? loadPersistedAgentSession(this.visitorSessionId, this.storeOptions)?.sessionId;
|
|
161
258
|
}
|
|
@@ -178,6 +275,7 @@ var AgentSession = class {
|
|
|
178
275
|
ensureClient() {
|
|
179
276
|
const config = resolveAgentRuntimeConfig({
|
|
180
277
|
indexId: this.indexId,
|
|
278
|
+
version: this.version,
|
|
181
279
|
runtimeOrigin: this.runtimeOrigin
|
|
182
280
|
});
|
|
183
281
|
if (!config.indexId) {
|
|
@@ -187,7 +285,11 @@ var AgentSession = class {
|
|
|
187
285
|
return this.client;
|
|
188
286
|
}
|
|
189
287
|
this.reset();
|
|
190
|
-
this.client = new
|
|
288
|
+
this.client = new import_client2.Client({
|
|
289
|
+
auth: { bearer: () => this.capability.getAccessToken() },
|
|
290
|
+
host: config.host,
|
|
291
|
+
redirect: "error"
|
|
292
|
+
});
|
|
191
293
|
this.clientHost = config.host;
|
|
192
294
|
return this.client;
|
|
193
295
|
}
|
|
@@ -206,9 +308,13 @@ var AgentSession = class {
|
|
|
206
308
|
if (session) {
|
|
207
309
|
this.session = session;
|
|
208
310
|
try {
|
|
209
|
-
|
|
311
|
+
const activeSession = session;
|
|
312
|
+
response = await withCapabilityRefresh(
|
|
313
|
+
this.capability,
|
|
314
|
+
() => activeSession.send(message, { signal })
|
|
315
|
+
);
|
|
210
316
|
} catch (error) {
|
|
211
|
-
if (error instanceof
|
|
317
|
+
if (error instanceof import_client2.ClientError && error.status === 409 && error.code === "session_not_active") {
|
|
212
318
|
clearPersistedAgentSession(this.visitorSessionId, this.storeOptions);
|
|
213
319
|
this.session = void 0;
|
|
214
320
|
session = void 0;
|
|
@@ -218,7 +324,10 @@ var AgentSession = class {
|
|
|
218
324
|
}
|
|
219
325
|
}
|
|
220
326
|
if (!response) {
|
|
221
|
-
const created = await
|
|
327
|
+
const created = await withCapabilityRefresh(
|
|
328
|
+
this.capability,
|
|
329
|
+
() => client.sessions.create({ message, signal })
|
|
330
|
+
);
|
|
222
331
|
response = created.response;
|
|
223
332
|
session = created.session;
|
|
224
333
|
this.session = session;
|
|
@@ -276,18 +385,25 @@ function createAgentClient(options) {
|
|
|
276
385
|
if (!indexId) {
|
|
277
386
|
throw new Error("indexId is required.");
|
|
278
387
|
}
|
|
279
|
-
const
|
|
388
|
+
const version = options.version ?? "published";
|
|
389
|
+
const runtimeOrigin = resolveAgentRuntimeConfig({
|
|
390
|
+
indexId,
|
|
391
|
+
runtimeOrigin: options.runtimeOrigin,
|
|
392
|
+
version
|
|
393
|
+
}).origin;
|
|
280
394
|
const storeOptions = {
|
|
281
395
|
storageKeyPrefix: options.storageKeyPrefix?.trim() || buildAgentStorageKeyPrefix({
|
|
282
396
|
customerId: options.customerId,
|
|
283
397
|
indexId,
|
|
398
|
+
version,
|
|
284
399
|
runtimeOrigin
|
|
285
400
|
})
|
|
286
401
|
};
|
|
287
402
|
const visitorSessionId = options.visitorSessionId?.trim() || getOrCreateVisitorSessionId(storeOptions);
|
|
288
|
-
const session = new AgentSession(indexId, runtimeOrigin, visitorSessionId, storeOptions);
|
|
403
|
+
const session = new AgentSession(indexId, version, runtimeOrigin, visitorSessionId, storeOptions);
|
|
289
404
|
return {
|
|
290
405
|
indexId,
|
|
406
|
+
version,
|
|
291
407
|
runtimeOrigin,
|
|
292
408
|
visitorSessionId,
|
|
293
409
|
sendTurn: (message, sendOptions) => session.sendTurn(
|
|
@@ -302,9 +418,9 @@ function createAgentClient(options) {
|
|
|
302
418
|
}
|
|
303
419
|
|
|
304
420
|
// src/runtime/errors.ts
|
|
305
|
-
var
|
|
421
|
+
var import_client3 = require("eve/client");
|
|
306
422
|
function formatAgentError(error) {
|
|
307
|
-
if (error instanceof
|
|
423
|
+
if (error instanceof import_client3.ClientError) {
|
|
308
424
|
if (error.status === 401 && error.code === "index_required") {
|
|
309
425
|
return "Missing indexId \u2014 pass a published index id to createAgentClient().";
|
|
310
426
|
}
|
|
@@ -370,6 +486,7 @@ async function runStatusSequence(signal, onStep) {
|
|
|
370
486
|
function useAgentChat({
|
|
371
487
|
customerId,
|
|
372
488
|
indexId,
|
|
489
|
+
version,
|
|
373
490
|
runtimeOrigin,
|
|
374
491
|
visitorSessionId,
|
|
375
492
|
storageKeyPrefix
|
|
@@ -377,8 +494,8 @@ function useAgentChat({
|
|
|
377
494
|
const [state, setState] = (0, import_react.useState)(INITIAL_STATE);
|
|
378
495
|
const runRef = (0, import_react.useRef)(null);
|
|
379
496
|
const resolvedStorageKeyPrefix = (0, import_react.useMemo)(
|
|
380
|
-
() => storageKeyPrefix?.trim() || buildAgentStorageKeyPrefix({ customerId, indexId, runtimeOrigin }),
|
|
381
|
-
[customerId, indexId, runtimeOrigin, storageKeyPrefix]
|
|
497
|
+
() => storageKeyPrefix?.trim() || buildAgentStorageKeyPrefix({ customerId, indexId, version, runtimeOrigin }),
|
|
498
|
+
[customerId, indexId, runtimeOrigin, storageKeyPrefix, version]
|
|
382
499
|
);
|
|
383
500
|
const visitorId = (0, import_react.useMemo)(
|
|
384
501
|
() => visitorSessionId?.trim() || getOrCreateVisitorSessionId({ storageKeyPrefix: resolvedStorageKeyPrefix }),
|
|
@@ -388,13 +505,14 @@ function useAgentChat({
|
|
|
388
505
|
createAgentClient({
|
|
389
506
|
customerId,
|
|
390
507
|
indexId,
|
|
508
|
+
version,
|
|
391
509
|
runtimeOrigin,
|
|
392
510
|
visitorSessionId: visitorId,
|
|
393
511
|
storageKeyPrefix: resolvedStorageKeyPrefix
|
|
394
512
|
})
|
|
395
513
|
);
|
|
396
514
|
const identityRef = (0, import_react.useRef)(null);
|
|
397
|
-
const identityKey = `${customerId ?? ""}|${indexId}|${runtimeOrigin ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}`;
|
|
515
|
+
const identityKey = `${customerId ?? ""}|${indexId}|${version ?? "published"}|${runtimeOrigin ?? ""}|${resolvedStorageKeyPrefix}|${visitorId}`;
|
|
398
516
|
(0, import_react.useEffect)(() => {
|
|
399
517
|
if (identityRef.current === null) {
|
|
400
518
|
identityRef.current = identityKey;
|
|
@@ -410,12 +528,13 @@ function useAgentChat({
|
|
|
410
528
|
clientRef.current = createAgentClient({
|
|
411
529
|
customerId,
|
|
412
530
|
indexId,
|
|
531
|
+
version,
|
|
413
532
|
runtimeOrigin,
|
|
414
533
|
visitorSessionId: visitorId,
|
|
415
534
|
storageKeyPrefix: resolvedStorageKeyPrefix
|
|
416
535
|
});
|
|
417
536
|
setState(INITIAL_STATE);
|
|
418
|
-
}, [customerId, identityKey, indexId, runtimeOrigin, resolvedStorageKeyPrefix, visitorId]);
|
|
537
|
+
}, [customerId, identityKey, indexId, runtimeOrigin, resolvedStorageKeyPrefix, version, visitorId]);
|
|
419
538
|
const reset = (0, import_react.useCallback)(() => {
|
|
420
539
|
runRef.current?.abort();
|
|
421
540
|
runRef.current = null;
|
|
@@ -518,7 +637,7 @@ function useAgentChat({
|
|
|
518
637
|
}));
|
|
519
638
|
}
|
|
520
639
|
},
|
|
521
|
-
[customerId, indexId, runtimeOrigin, resolvedStorageKeyPrefix, visitorId]
|
|
640
|
+
[customerId, indexId, runtimeOrigin, resolvedStorageKeyPrefix, version, visitorId]
|
|
522
641
|
);
|
|
523
642
|
(0, import_react.useEffect)(() => {
|
|
524
643
|
return () => {
|
|
@@ -1001,6 +1120,7 @@ var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
|
1001
1120
|
function AgentWidget({
|
|
1002
1121
|
indexId,
|
|
1003
1122
|
customerId,
|
|
1123
|
+
version,
|
|
1004
1124
|
runtimeOrigin,
|
|
1005
1125
|
placement: placementInput,
|
|
1006
1126
|
defaultCollapsed = true,
|
|
@@ -1013,6 +1133,7 @@ function AgentWidget({
|
|
|
1013
1133
|
const { state, submit } = useAgentChat({
|
|
1014
1134
|
customerId,
|
|
1015
1135
|
indexId,
|
|
1136
|
+
version,
|
|
1016
1137
|
runtimeOrigin
|
|
1017
1138
|
});
|
|
1018
1139
|
const idle = state.phase === "idle" && !hasVisitorMessages(state.messages);
|