@webless/agent 0.2.7 → 0.2.9
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-4QGS7UZY.js → chunk-7XB5OBTP.js} +125 -41
- package/dist/chunk-7XB5OBTP.js.map +1 -0
- package/dist/embed.cjs +125 -41
- package/dist/embed.cjs.map +1 -1
- package/dist/embed.css +2 -0
- package/dist/embed.css.map +1 -1
- package/dist/embed.js +1 -1
- package/dist/index.cjs +111 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +112 -14
- package/dist/index.js.map +1 -1
- package/dist/react.cjs +123 -39
- package/dist/react.cjs.map +1 -1
- package/dist/react.css +2 -0
- package/dist/react.css.map +1 -1
- package/dist/react.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-4QGS7UZY.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,9 +1,91 @@
|
|
|
1
1
|
// src/runtime/client.ts
|
|
2
2
|
import {
|
|
3
3
|
Client,
|
|
4
|
-
ClientError
|
|
4
|
+
ClientError as ClientError2
|
|
5
5
|
} from "eve/client";
|
|
6
6
|
|
|
7
|
+
// src/runtime/capability.ts
|
|
8
|
+
import { ClientError } from "eve/client";
|
|
9
|
+
var MAX_REFRESH_SKEW_MS = 3e4;
|
|
10
|
+
function isRecord(value) {
|
|
11
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
12
|
+
}
|
|
13
|
+
function parseBootstrapResponse(value, indexId, now) {
|
|
14
|
+
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) {
|
|
15
|
+
throw new Error("Agent Runtime returned an invalid access response.");
|
|
16
|
+
}
|
|
17
|
+
const expiresAt = Date.parse(value.expiresAt);
|
|
18
|
+
if (!Number.isFinite(expiresAt) || expiresAt <= now) {
|
|
19
|
+
throw new Error("Agent Runtime returned an expired access response.");
|
|
20
|
+
}
|
|
21
|
+
const refreshSkew = Math.min(MAX_REFRESH_SKEW_MS, Math.floor((expiresAt - now) / 10));
|
|
22
|
+
return {
|
|
23
|
+
accessToken: value.accessToken,
|
|
24
|
+
refreshAt: expiresAt - refreshSkew
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
async function readBootstrapError(response) {
|
|
28
|
+
const fallback = `Agent Runtime is unavailable (${response.status}).`;
|
|
29
|
+
try {
|
|
30
|
+
const value = await response.json();
|
|
31
|
+
return isRecord(value) && typeof value.error === "string" && value.error ? value.error : fallback;
|
|
32
|
+
} catch {
|
|
33
|
+
return fallback;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function createAgentRuntimeCapability(options) {
|
|
37
|
+
const fetchImplementation = options.fetchImplementation ?? fetch;
|
|
38
|
+
const now = options.now ?? Date.now;
|
|
39
|
+
let capability;
|
|
40
|
+
let pendingBootstrap;
|
|
41
|
+
const bootstrap = async () => {
|
|
42
|
+
const response = await fetchImplementation(`${options.runtimeOrigin}/webless/v1/bootstrap`, {
|
|
43
|
+
body: JSON.stringify({
|
|
44
|
+
clientSessionId: options.visitorSessionId,
|
|
45
|
+
indexId: options.indexId
|
|
46
|
+
}),
|
|
47
|
+
headers: { "content-type": "application/json" },
|
|
48
|
+
method: "POST"
|
|
49
|
+
});
|
|
50
|
+
if (!response.ok) {
|
|
51
|
+
throw new Error(await readBootstrapError(response));
|
|
52
|
+
}
|
|
53
|
+
let value;
|
|
54
|
+
try {
|
|
55
|
+
value = await response.json();
|
|
56
|
+
} catch {
|
|
57
|
+
throw new Error("Agent Runtime returned an invalid access response.");
|
|
58
|
+
}
|
|
59
|
+
return parseBootstrapResponse(value, options.indexId, now());
|
|
60
|
+
};
|
|
61
|
+
return {
|
|
62
|
+
getAccessToken: async () => {
|
|
63
|
+
if (capability && capability.refreshAt > now()) {
|
|
64
|
+
return capability.accessToken;
|
|
65
|
+
}
|
|
66
|
+
pendingBootstrap ??= bootstrap().finally(() => {
|
|
67
|
+
pendingBootstrap = void 0;
|
|
68
|
+
});
|
|
69
|
+
capability = await pendingBootstrap;
|
|
70
|
+
return capability.accessToken;
|
|
71
|
+
},
|
|
72
|
+
invalidate: () => {
|
|
73
|
+
capability = void 0;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
async function withCapabilityRefresh(capability, request) {
|
|
78
|
+
try {
|
|
79
|
+
return await request();
|
|
80
|
+
} catch (error) {
|
|
81
|
+
if (!(error instanceof ClientError) || error.status !== 401) {
|
|
82
|
+
throw error;
|
|
83
|
+
}
|
|
84
|
+
capability.invalidate();
|
|
85
|
+
return await request();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
7
89
|
// src/runtime/config.ts
|
|
8
90
|
var DEFAULT_RUNTIME_ORIGIN = "https://runtime.staging.webless.ai";
|
|
9
91
|
var trimTrailingSlash = (value) => value.replace(/\/+$/, "");
|
|
@@ -125,6 +207,11 @@ var AgentSession = class {
|
|
|
125
207
|
this.runtimeOrigin = runtimeOrigin;
|
|
126
208
|
this.visitorSessionId = visitorSessionId;
|
|
127
209
|
this.storeOptions = storeOptions;
|
|
210
|
+
this.capability = createAgentRuntimeCapability({
|
|
211
|
+
indexId,
|
|
212
|
+
runtimeOrigin,
|
|
213
|
+
visitorSessionId
|
|
214
|
+
});
|
|
128
215
|
}
|
|
129
216
|
indexId;
|
|
130
217
|
version;
|
|
@@ -135,7 +222,7 @@ var AgentSession = class {
|
|
|
135
222
|
clientHost;
|
|
136
223
|
session;
|
|
137
224
|
activeResponse;
|
|
138
|
-
|
|
225
|
+
capability;
|
|
139
226
|
getActiveSessionId() {
|
|
140
227
|
return this.session?.state.sessionId ?? loadPersistedAgentSession(this.visitorSessionId, this.storeOptions)?.sessionId;
|
|
141
228
|
}
|
|
@@ -144,7 +231,6 @@ var AgentSession = class {
|
|
|
144
231
|
});
|
|
145
232
|
this.activeResponse = void 0;
|
|
146
233
|
this.session = void 0;
|
|
147
|
-
this.renderedPrefix = "";
|
|
148
234
|
clearPersistedAgentSession(this.visitorSessionId, this.storeOptions);
|
|
149
235
|
}
|
|
150
236
|
persistSessionCursor(session) {
|
|
@@ -168,14 +254,17 @@ var AgentSession = class {
|
|
|
168
254
|
return this.client;
|
|
169
255
|
}
|
|
170
256
|
this.reset();
|
|
171
|
-
this.client = new Client({
|
|
257
|
+
this.client = new Client({
|
|
258
|
+
auth: { bearer: () => this.capability.getAccessToken() },
|
|
259
|
+
host: config.host,
|
|
260
|
+
redirect: "error"
|
|
261
|
+
});
|
|
172
262
|
this.clientHost = config.host;
|
|
173
263
|
return this.client;
|
|
174
264
|
}
|
|
175
265
|
attachPersistedSession(client) {
|
|
176
266
|
const persisted = loadPersistedAgentSession(this.visitorSessionId, this.storeOptions);
|
|
177
267
|
if (!persisted?.sessionId) return void 0;
|
|
178
|
-
this.renderedPrefix = "";
|
|
179
268
|
return client.sessions.attach(persisted.sessionId, {
|
|
180
269
|
streamIndex: persisted.streamIndex
|
|
181
270
|
});
|
|
@@ -187,9 +276,13 @@ var AgentSession = class {
|
|
|
187
276
|
if (session) {
|
|
188
277
|
this.session = session;
|
|
189
278
|
try {
|
|
190
|
-
|
|
279
|
+
const activeSession = session;
|
|
280
|
+
response = await withCapabilityRefresh(
|
|
281
|
+
this.capability,
|
|
282
|
+
() => activeSession.send(message, { signal })
|
|
283
|
+
);
|
|
191
284
|
} catch (error) {
|
|
192
|
-
if (error instanceof
|
|
285
|
+
if (error instanceof ClientError2 && error.status === 409 && error.code === "session_not_active") {
|
|
193
286
|
clearPersistedAgentSession(this.visitorSessionId, this.storeOptions);
|
|
194
287
|
this.session = void 0;
|
|
195
288
|
session = void 0;
|
|
@@ -199,15 +292,17 @@ var AgentSession = class {
|
|
|
199
292
|
}
|
|
200
293
|
}
|
|
201
294
|
if (!response) {
|
|
202
|
-
const created = await
|
|
295
|
+
const created = await withCapabilityRefresh(
|
|
296
|
+
this.capability,
|
|
297
|
+
() => client.sessions.create({ message, signal })
|
|
298
|
+
);
|
|
203
299
|
response = created.response;
|
|
204
300
|
session = created.session;
|
|
205
301
|
this.session = session;
|
|
206
|
-
this.renderedPrefix = "";
|
|
207
302
|
this.persistSessionCursor(session);
|
|
208
303
|
}
|
|
209
304
|
this.activeResponse = response;
|
|
210
|
-
let rendered =
|
|
305
|
+
let rendered = "";
|
|
211
306
|
try {
|
|
212
307
|
for await (const event of response) {
|
|
213
308
|
if (signal.aborted) break;
|
|
@@ -233,7 +328,6 @@ var AgentSession = class {
|
|
|
233
328
|
}
|
|
234
329
|
} finally {
|
|
235
330
|
this.activeResponse = void 0;
|
|
236
|
-
this.renderedPrefix = rendered;
|
|
237
331
|
if (session) {
|
|
238
332
|
this.persistSessionCursor(session);
|
|
239
333
|
}
|
|
@@ -257,8 +351,12 @@ function createAgentClient(options) {
|
|
|
257
351
|
if (!indexId) {
|
|
258
352
|
throw new Error("indexId is required.");
|
|
259
353
|
}
|
|
260
|
-
const runtimeOrigin = options.runtimeOrigin?.trim() || resolveAgentRuntimeConfig({ indexId }).origin;
|
|
261
354
|
const version = options.version ?? "published";
|
|
355
|
+
const runtimeOrigin = resolveAgentRuntimeConfig({
|
|
356
|
+
indexId,
|
|
357
|
+
runtimeOrigin: options.runtimeOrigin,
|
|
358
|
+
version
|
|
359
|
+
}).origin;
|
|
262
360
|
const storeOptions = {
|
|
263
361
|
storageKeyPrefix: options.storageKeyPrefix?.trim() || buildAgentStorageKeyPrefix({
|
|
264
362
|
customerId: options.customerId,
|
|
@@ -286,9 +384,9 @@ function createAgentClient(options) {
|
|
|
286
384
|
}
|
|
287
385
|
|
|
288
386
|
// src/runtime/errors.ts
|
|
289
|
-
import { ClientError as
|
|
387
|
+
import { ClientError as ClientError3 } from "eve/client";
|
|
290
388
|
function formatAgentError(error) {
|
|
291
|
-
if (error instanceof
|
|
389
|
+
if (error instanceof ClientError3) {
|
|
292
390
|
if (error.status === 401 && error.code === "index_required") {
|
|
293
391
|
return "Missing indexId \u2014 pass a published index id to createAgentClient().";
|
|
294
392
|
}
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/runtime/client.ts","../src/runtime/config.ts","../src/runtime/session-store.ts","../src/runtime/errors.ts","../src/runtime/health.ts"],"sourcesContent":["import {\n Client,\n ClientError,\n type ClientSession,\n type MessageResponse,\n type MessageStreamEvent,\n} from \"eve/client\";\nimport { resolveAgentRuntimeConfig } from \"./config\";\nimport {\n buildAgentStorageKeyPrefix,\n clearPersistedAgentSession,\n getOrCreateVisitorSessionId,\n loadPersistedAgentSession,\n savePersistedAgentSession,\n type SessionStoreOptions,\n} from \"./session-store\";\nimport type {\n AgentClient,\n AgentClientOptions,\n AgentIndexVersion,\n AgentSendTurnOptions,\n AgentStreamHandlers,\n} from \"./types\";\n\nfunction mapStepLabel(event: MessageStreamEvent): { label: string; detail?: string } | null {\n if (event.type !== \"step.started\") return null;\n const stepIndex = event.data.stepIndex;\n return {\n label: \"Model step running\",\n detail: typeof stepIndex === \"number\" ? `Step ${stepIndex + 1}` : undefined,\n };\n}\n\nclass AgentSession {\n private client: Client | undefined;\n private clientHost: string | undefined;\n private session: ClientSession | undefined;\n private activeResponse: MessageResponse | undefined;\n private renderedPrefix = \"\";\n\n constructor(\n private readonly indexId: string,\n private readonly version: AgentIndexVersion,\n private readonly runtimeOrigin: string,\n private readonly visitorSessionId: string,\n private readonly storeOptions: SessionStoreOptions,\n ) {}\n\n getActiveSessionId(): string | undefined {\n return (\n this.session?.state.sessionId ??\n loadPersistedAgentSession(this.visitorSessionId, this.storeOptions)?.sessionId\n );\n }\n\n reset() {\n void this.activeResponse?.cancel().catch(() => {});\n this.activeResponse = undefined;\n this.session = undefined;\n this.renderedPrefix = \"\";\n clearPersistedAgentSession(this.visitorSessionId, this.storeOptions);\n }\n\n private persistSessionCursor(session: ClientSession) {\n savePersistedAgentSession(\n this.visitorSessionId,\n session.state.sessionId,\n session.state.streamIndex,\n this.storeOptions,\n );\n }\n\n private ensureClient(): Client {\n const config = resolveAgentRuntimeConfig({\n indexId: this.indexId,\n version: this.version,\n runtimeOrigin: this.runtimeOrigin,\n });\n if (!config.indexId) {\n throw new Error(\"indexId is required.\");\n }\n\n if (this.client && this.clientHost === config.host) {\n return this.client;\n }\n\n this.reset();\n this.client = new Client({ host: config.host });\n this.clientHost = config.host;\n return this.client;\n }\n\n private attachPersistedSession(client: Client): ClientSession | undefined {\n const persisted = loadPersistedAgentSession(this.visitorSessionId, this.storeOptions);\n if (!persisted?.sessionId) return undefined;\n\n this.renderedPrefix = \"\";\n return client.sessions.attach(persisted.sessionId, {\n streamIndex: persisted.streamIndex,\n });\n }\n\n async sendTurn(\n message: string,\n signal: AbortSignal,\n handlers: AgentStreamHandlers,\n ): Promise<string> {\n const client = this.ensureClient();\n let response: MessageResponse | undefined;\n let session = this.session ?? this.attachPersistedSession(client);\n\n if (session) {\n this.session = session;\n try {\n response = await session.send(message, { signal });\n } catch (error) {\n if (\n error instanceof ClientError &&\n error.status === 409 &&\n error.code === \"session_not_active\"\n ) {\n clearPersistedAgentSession(this.visitorSessionId, this.storeOptions);\n this.session = undefined;\n session = undefined;\n } else {\n throw error;\n }\n }\n }\n\n if (!response) {\n const created = await client.sessions.create({ message, signal });\n response = created.response;\n session = created.session;\n this.session = session;\n this.renderedPrefix = \"\";\n this.persistSessionCursor(session);\n }\n\n this.activeResponse = response;\n let rendered = this.renderedPrefix;\n\n try {\n for await (const event of response) {\n if (signal.aborted) break;\n\n const step = mapStepLabel(event);\n if (step) handlers.onStep?.(step.label, step.detail);\n\n if (event.type === \"message.appended\") {\n const { messageDelta, messageSoFar } = event.data;\n let delta = messageDelta;\n if (messageSoFar.startsWith(rendered)) {\n delta = messageSoFar.slice(rendered.length);\n rendered = messageSoFar;\n } else if (messageDelta) {\n rendered += messageDelta;\n }\n if (delta) handlers.onDelta(delta);\n }\n\n if (event.type === \"message.completed\") {\n handlers.onComplete?.();\n }\n\n if (event.type === \"session.failed\") {\n throw new Error(event.data.message || event.data.code);\n }\n }\n } finally {\n this.activeResponse = undefined;\n this.renderedPrefix = rendered;\n if (session) {\n this.persistSessionCursor(session);\n }\n }\n\n if (!rendered.trim() && !signal.aborted) {\n throw new Error(\"Empty response from runtime\");\n }\n\n if (signal.aborted) {\n await response.cancel().catch(() => {});\n }\n\n return rendered.trim();\n }\n\n cancelActive() {\n this.activeResponse?.cancel().catch(() => {});\n }\n}\n\nexport function createAgentClient(options: AgentClientOptions): AgentClient {\n const indexId = options.indexId.trim();\n if (!indexId) {\n throw new Error(\"indexId is required.\");\n }\n\n const runtimeOrigin = options.runtimeOrigin?.trim() || resolveAgentRuntimeConfig({ indexId }).origin;\n const version = options.version ?? \"published\";\n const storeOptions: SessionStoreOptions = {\n storageKeyPrefix:\n options.storageKeyPrefix?.trim() ||\n buildAgentStorageKeyPrefix({\n customerId: options.customerId,\n indexId,\n version,\n runtimeOrigin,\n }),\n };\n const visitorSessionId =\n options.visitorSessionId?.trim() || getOrCreateVisitorSessionId(storeOptions);\n\n const session = new AgentSession(indexId, version, runtimeOrigin, visitorSessionId, storeOptions);\n\n return {\n indexId,\n version,\n runtimeOrigin,\n visitorSessionId,\n sendTurn: (message, sendOptions: AgentSendTurnOptions) =>\n session.sendTurn(\n message,\n sendOptions.signal ?? new AbortController().signal,\n sendOptions.handlers,\n ),\n reset: () => session.reset(),\n cancelActive: () => session.cancelActive(),\n getActiveSessionId: () => session.getActiveSessionId(),\n };\n}\n","import type { AgentIndexVersion, AgentRuntimeConfig } from \"./types\";\n\nexport const DEFAULT_RUNTIME_ORIGIN = \"https://runtime.staging.webless.ai\";\n\nconst trimTrailingSlash = (value: string) => value.replace(/\\/+$/, \"\");\n\nexport function buildEveHost(\n origin: string,\n indexId: string,\n version: AgentIndexVersion = \"published\",\n): string {\n const base = trimTrailingSlash(origin);\n const searchParams = new URLSearchParams({ indexId: indexId.trim() });\n if (version === \"unpublished\") {\n searchParams.set(\"version\", version);\n }\n return `${base}?${searchParams.toString()}`;\n}\n\nexport function resolveAgentRuntimeConfig(input: {\n indexId: string;\n runtimeOrigin?: string;\n version?: AgentIndexVersion;\n}): AgentRuntimeConfig {\n const origin = trimTrailingSlash(input.runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN);\n const resolvedIndexId = input.indexId.trim();\n const version = input.version ?? \"published\";\n\n return {\n origin,\n indexId: resolvedIndexId,\n version,\n host: resolvedIndexId ? buildEveHost(origin, resolvedIndexId, version) : origin,\n };\n}\n\nexport function agentHealthUrl(runtimeOrigin?: string): string {\n const origin = trimTrailingSlash(runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN);\n return `${origin}/eve/v1/health`;\n}\n","import type { AgentIndexVersion, PersistedAgentSession } from \"./types\";\n\nconst DEFAULT_STORAGE_KEY_PREFIX = \"webless:agent\";\n\nexport type SessionStoreOptions = {\n storageKeyPrefix?: string;\n};\n\nfunction normalizeRuntimeOrigin(runtimeOrigin?: string) {\n const trimmed = runtimeOrigin?.trim();\n if (!trimmed) return \"_\";\n return trimmed.replace(/\\/+$/, \"\");\n}\n\nexport function buildAgentStorageKeyPrefix(input: {\n customerId?: string;\n indexId: string;\n runtimeOrigin?: string;\n version?: AgentIndexVersion;\n}) {\n const customerId = input.customerId?.trim() || \"_\";\n const indexId = input.indexId.trim();\n if (!indexId) {\n throw new Error(\"indexId is required to build agent storage keys.\");\n }\n\n const versionSuffix = input.version === \"unpublished\" ? \":unpublished\" : \"\";\n return `${DEFAULT_STORAGE_KEY_PREFIX}:${customerId}:${indexId}${versionSuffix}:${normalizeRuntimeOrigin(input.runtimeOrigin)}`;\n}\n\nfunction createSessionId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `sess_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n}\n\nfunction resolvePrefix(options?: SessionStoreOptions) {\n return options?.storageKeyPrefix?.trim() || DEFAULT_STORAGE_KEY_PREFIX;\n}\n\nexport function getOrCreateVisitorSessionId(options?: SessionStoreOptions): string {\n const prefix = resolvePrefix(options);\n const visitorKey = `${prefix}:visitorSessionId`;\n\n if (typeof sessionStorage === \"undefined\") {\n return createSessionId();\n }\n\n const existing = sessionStorage.getItem(visitorKey)?.trim();\n if (existing) return existing;\n\n const next = createSessionId();\n sessionStorage.setItem(visitorKey, next);\n return next;\n}\n\nexport function clearVisitorSessionId(options?: SessionStoreOptions) {\n if (typeof sessionStorage === \"undefined\") return;\n\n const prefix = resolvePrefix(options);\n sessionStorage.removeItem(`${prefix}:visitorSessionId`);\n}\n\nfunction runtimeSessionIdKey(visitorSessionId: string, prefix: string) {\n return `${prefix}:eve:${visitorSessionId}:sessionId`;\n}\n\nfunction runtimeStreamIndexKey(visitorSessionId: string, prefix: string) {\n return `${prefix}:eve:${visitorSessionId}:streamIndex`;\n}\n\nexport function loadPersistedAgentSession(\n visitorSessionId: string,\n options?: SessionStoreOptions,\n): PersistedAgentSession | null {\n if (typeof sessionStorage === \"undefined\" || !visitorSessionId.trim()) return null;\n\n const prefix = resolvePrefix(options);\n const sessionId = sessionStorage.getItem(runtimeSessionIdKey(visitorSessionId, prefix))?.trim();\n if (!sessionId) return null;\n\n const rawIndex = sessionStorage.getItem(runtimeStreamIndexKey(visitorSessionId, prefix));\n const streamIndex = rawIndex ? Number.parseInt(rawIndex, 10) : 0;\n\n return {\n sessionId,\n streamIndex: Number.isFinite(streamIndex) && streamIndex >= 0 ? streamIndex : 0,\n };\n}\n\nexport function savePersistedAgentSession(\n visitorSessionId: string,\n sessionId: string,\n streamIndex: number,\n options?: SessionStoreOptions,\n) {\n if (typeof sessionStorage === \"undefined\" || !visitorSessionId.trim() || !sessionId.trim()) {\n return;\n }\n\n const prefix = resolvePrefix(options);\n sessionStorage.setItem(runtimeSessionIdKey(visitorSessionId, prefix), sessionId);\n sessionStorage.setItem(\n runtimeStreamIndexKey(visitorSessionId, prefix),\n String(Math.max(0, streamIndex)),\n );\n}\n\nexport function clearPersistedAgentSession(\n visitorSessionId: string,\n options?: SessionStoreOptions,\n) {\n if (typeof sessionStorage === \"undefined\" || !visitorSessionId.trim()) return;\n const prefix = resolvePrefix(options);\n sessionStorage.removeItem(runtimeSessionIdKey(visitorSessionId, prefix));\n sessionStorage.removeItem(runtimeStreamIndexKey(visitorSessionId, prefix));\n}\n","import { ClientError } from \"eve/client\";\n\nexport function formatAgentError(error: unknown): string {\n if (error instanceof ClientError) {\n if (error.status === 401 && error.code === \"index_required\") {\n return \"Missing indexId — pass a published index id to createAgentClient().\";\n }\n if (error.status === 403 && error.code === \"agent_unavailable\") {\n return \"Agent unavailable for this index (disabled or unpublished).\";\n }\n if (error.status === 409 && error.code === \"session_not_active\") {\n return \"Session expired — send a new message to start again.\";\n }\n return error.message || `Runtime error (${error.status})`;\n }\n if (error instanceof DOMException && error.name === \"AbortError\") {\n return \"\";\n }\n if (error instanceof Error) return error.message;\n return \"Runtime request failed\";\n}\n","import { formatAgentError } from \"./errors\";\nimport { agentHealthUrl } from \"./config\";\nimport type { AgentHealthResult } from \"./types\";\n\nexport async function pingAgentHealth(\n runtimeOrigin?: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<AgentHealthResult> {\n const healthUrl = agentHealthUrl(runtimeOrigin);\n\n try {\n const response = await fetchImpl(healthUrl, {\n headers: { Accept: \"application/json\" },\n cache: \"no-store\",\n });\n if (!response.ok) {\n return { ok: false, detail: `Health check failed (${response.status})` };\n }\n const payload = (await response.json()) as { status?: string; ok?: boolean };\n if (payload.ok === true) {\n return { ok: true, detail: payload.status ?? \"ready\" };\n }\n return { ok: false, detail: \"Runtime health response was not ok\" };\n } catch (error) {\n return { ok: false, detail: formatAgentError(error) || \"Health check failed\" };\n }\n}\n"],"mappings":"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","names":["ClientError"]}
|
|
1
|
+
{"version":3,"sources":["../src/runtime/client.ts","../src/runtime/capability.ts","../src/runtime/config.ts","../src/runtime/session-store.ts","../src/runtime/errors.ts","../src/runtime/health.ts"],"sourcesContent":["import {\n Client,\n ClientError,\n type ClientSession,\n type MessageResponse,\n type MessageStreamEvent,\n} from \"eve/client\";\nimport {\n createAgentRuntimeCapability,\n type AgentRuntimeCapability,\n withCapabilityRefresh,\n} from \"./capability\";\nimport { resolveAgentRuntimeConfig } from \"./config\";\nimport {\n buildAgentStorageKeyPrefix,\n clearPersistedAgentSession,\n getOrCreateVisitorSessionId,\n loadPersistedAgentSession,\n savePersistedAgentSession,\n type SessionStoreOptions,\n} from \"./session-store\";\nimport type {\n AgentClient,\n AgentClientOptions,\n AgentIndexVersion,\n AgentSendTurnOptions,\n AgentStreamHandlers,\n} from \"./types\";\n\nfunction mapStepLabel(event: MessageStreamEvent): { label: string; detail?: string } | null {\n if (event.type !== \"step.started\") return null;\n const stepIndex = event.data.stepIndex;\n return {\n label: \"Model step running\",\n detail: typeof stepIndex === \"number\" ? `Step ${stepIndex + 1}` : undefined,\n };\n}\n\nclass AgentSession {\n private client: Client | undefined;\n private clientHost: string | undefined;\n private session: ClientSession | undefined;\n private activeResponse: MessageResponse | undefined;\n private readonly capability: AgentRuntimeCapability;\n\n constructor(\n private readonly indexId: string,\n private readonly version: AgentIndexVersion,\n private readonly runtimeOrigin: string,\n private readonly visitorSessionId: string,\n private readonly storeOptions: SessionStoreOptions,\n ) {\n this.capability = createAgentRuntimeCapability({\n indexId,\n runtimeOrigin,\n visitorSessionId,\n });\n }\n\n getActiveSessionId(): string | undefined {\n return (\n this.session?.state.sessionId ??\n loadPersistedAgentSession(this.visitorSessionId, this.storeOptions)?.sessionId\n );\n }\n\n reset() {\n void this.activeResponse?.cancel().catch(() => {});\n this.activeResponse = undefined;\n this.session = undefined;\n clearPersistedAgentSession(this.visitorSessionId, this.storeOptions);\n }\n\n private persistSessionCursor(session: ClientSession) {\n savePersistedAgentSession(\n this.visitorSessionId,\n session.state.sessionId,\n session.state.streamIndex,\n this.storeOptions,\n );\n }\n\n private ensureClient(): Client {\n const config = resolveAgentRuntimeConfig({\n indexId: this.indexId,\n version: this.version,\n runtimeOrigin: this.runtimeOrigin,\n });\n if (!config.indexId) {\n throw new Error(\"indexId is required.\");\n }\n\n if (this.client && this.clientHost === config.host) {\n return this.client;\n }\n\n this.reset();\n this.client = new Client({\n auth: { bearer: () => this.capability.getAccessToken() },\n host: config.host,\n redirect: \"error\",\n });\n this.clientHost = config.host;\n return this.client;\n }\n\n private attachPersistedSession(client: Client): ClientSession | undefined {\n const persisted = loadPersistedAgentSession(this.visitorSessionId, this.storeOptions);\n if (!persisted?.sessionId) return undefined;\n\n return client.sessions.attach(persisted.sessionId, {\n streamIndex: persisted.streamIndex,\n });\n }\n\n async sendTurn(\n message: string,\n signal: AbortSignal,\n handlers: AgentStreamHandlers,\n ): Promise<string> {\n const client = this.ensureClient();\n let response: MessageResponse | undefined;\n let session = this.session ?? this.attachPersistedSession(client);\n\n if (session) {\n this.session = session;\n try {\n const activeSession = session;\n response = await withCapabilityRefresh(this.capability, () =>\n activeSession.send(message, { signal }),\n );\n } catch (error) {\n if (\n error instanceof ClientError &&\n error.status === 409 &&\n error.code === \"session_not_active\"\n ) {\n clearPersistedAgentSession(this.visitorSessionId, this.storeOptions);\n this.session = undefined;\n session = undefined;\n } else {\n throw error;\n }\n }\n }\n\n if (!response) {\n const created = await withCapabilityRefresh(this.capability, () =>\n client.sessions.create({ message, signal }),\n );\n response = created.response;\n session = created.session;\n this.session = session;\n this.persistSessionCursor(session);\n }\n\n this.activeResponse = response;\n let rendered = \"\";\n\n try {\n for await (const event of response) {\n if (signal.aborted) break;\n\n const step = mapStepLabel(event);\n if (step) handlers.onStep?.(step.label, step.detail);\n\n if (event.type === \"message.appended\") {\n const { messageDelta, messageSoFar } = event.data;\n let delta = messageDelta;\n if (messageSoFar.startsWith(rendered)) {\n delta = messageSoFar.slice(rendered.length);\n rendered = messageSoFar;\n } else if (messageDelta) {\n rendered += messageDelta;\n }\n if (delta) handlers.onDelta(delta);\n }\n\n if (event.type === \"message.completed\") {\n handlers.onComplete?.();\n }\n\n if (event.type === \"session.failed\") {\n throw new Error(event.data.message || event.data.code);\n }\n }\n } finally {\n this.activeResponse = undefined;\n if (session) {\n this.persistSessionCursor(session);\n }\n }\n\n if (!rendered.trim() && !signal.aborted) {\n throw new Error(\"Empty response from runtime\");\n }\n\n if (signal.aborted) {\n await response.cancel().catch(() => {});\n }\n\n return rendered.trim();\n }\n\n cancelActive() {\n this.activeResponse?.cancel().catch(() => {});\n }\n}\n\nexport function createAgentClient(options: AgentClientOptions): AgentClient {\n const indexId = options.indexId.trim();\n if (!indexId) {\n throw new Error(\"indexId is required.\");\n }\n\n const version = options.version ?? \"published\";\n const runtimeOrigin = resolveAgentRuntimeConfig({\n indexId,\n runtimeOrigin: options.runtimeOrigin,\n version,\n }).origin;\n const storeOptions: SessionStoreOptions = {\n storageKeyPrefix:\n options.storageKeyPrefix?.trim() ||\n buildAgentStorageKeyPrefix({\n customerId: options.customerId,\n indexId,\n version,\n runtimeOrigin,\n }),\n };\n const visitorSessionId =\n options.visitorSessionId?.trim() || getOrCreateVisitorSessionId(storeOptions);\n\n const session = new AgentSession(indexId, version, runtimeOrigin, visitorSessionId, storeOptions);\n\n return {\n indexId,\n version,\n runtimeOrigin,\n visitorSessionId,\n sendTurn: (message, sendOptions: AgentSendTurnOptions) =>\n session.sendTurn(\n message,\n sendOptions.signal ?? new AbortController().signal,\n sendOptions.handlers,\n ),\n reset: () => session.reset(),\n cancelActive: () => session.cancelActive(),\n getActiveSessionId: () => session.getActiveSessionId(),\n };\n}\n","import { ClientError } from \"eve/client\";\n\ntype RuntimeCapability = {\n accessToken: string;\n refreshAt: number;\n};\n\ntype AgentRuntimeCapabilityOptions = {\n indexId: string;\n runtimeOrigin: string;\n visitorSessionId: string;\n fetchImplementation?: typeof fetch;\n now?: () => number;\n};\n\nconst MAX_REFRESH_SKEW_MS = 30_000;\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction parseBootstrapResponse(value: unknown, indexId: string, now: number): RuntimeCapability {\n if (\n !isRecord(value) ||\n value.apiVersion !== \"webless.ai/agent-runtime-bootstrap/v1\" ||\n typeof value.accessToken !== \"string\" ||\n !value.accessToken ||\n typeof value.expiresAt !== \"string\" ||\n !isRecord(value.identity) ||\n value.identity.indexId !== indexId ||\n typeof value.identity.revision !== \"string\" ||\n !value.identity.revision ||\n typeof value.identity.tenantId !== \"string\" ||\n !value.identity.tenantId ||\n typeof value.origin !== \"string\" ||\n !value.origin ||\n value.tokenType !== \"Bearer\" ||\n typeof value.visitorSubject !== \"string\" ||\n !value.visitorSubject\n ) {\n throw new Error(\"Agent Runtime returned an invalid access response.\");\n }\n\n const expiresAt = Date.parse(value.expiresAt);\n if (!Number.isFinite(expiresAt) || expiresAt <= now) {\n throw new Error(\"Agent Runtime returned an expired access response.\");\n }\n\n const refreshSkew = Math.min(MAX_REFRESH_SKEW_MS, Math.floor((expiresAt - now) / 10));\n return {\n accessToken: value.accessToken,\n refreshAt: expiresAt - refreshSkew,\n };\n}\n\nasync function readBootstrapError(response: Response): Promise<string> {\n const fallback = `Agent Runtime is unavailable (${response.status}).`;\n try {\n const value: unknown = await response.json();\n return isRecord(value) && typeof value.error === \"string\" && value.error\n ? value.error\n : fallback;\n } catch {\n return fallback;\n }\n}\n\nexport function createAgentRuntimeCapability(options: AgentRuntimeCapabilityOptions) {\n const fetchImplementation = options.fetchImplementation ?? fetch;\n const now = options.now ?? Date.now;\n let capability: RuntimeCapability | undefined;\n let pendingBootstrap: Promise<RuntimeCapability> | undefined;\n\n const bootstrap = async (): Promise<RuntimeCapability> => {\n const response = await fetchImplementation(`${options.runtimeOrigin}/webless/v1/bootstrap`, {\n body: JSON.stringify({\n clientSessionId: options.visitorSessionId,\n indexId: options.indexId,\n }),\n headers: { \"content-type\": \"application/json\" },\n method: \"POST\",\n });\n if (!response.ok) {\n throw new Error(await readBootstrapError(response));\n }\n\n let value: unknown;\n try {\n value = await response.json();\n } catch {\n throw new Error(\"Agent Runtime returned an invalid access response.\");\n }\n return parseBootstrapResponse(value, options.indexId, now());\n };\n\n return {\n getAccessToken: async (): Promise<string> => {\n if (capability && capability.refreshAt > now()) {\n return capability.accessToken;\n }\n\n pendingBootstrap ??= bootstrap().finally(() => {\n pendingBootstrap = undefined;\n });\n capability = await pendingBootstrap;\n return capability.accessToken;\n },\n invalidate: () => {\n capability = undefined;\n },\n };\n}\n\nexport type AgentRuntimeCapability = ReturnType<typeof createAgentRuntimeCapability>;\n\nexport async function withCapabilityRefresh<T>(\n capability: AgentRuntimeCapability,\n request: () => Promise<T>,\n): Promise<T> {\n try {\n return await request();\n } catch (error) {\n if (!(error instanceof ClientError) || error.status !== 401) {\n throw error;\n }\n capability.invalidate();\n return await request();\n }\n}\n","import type { AgentIndexVersion, AgentRuntimeConfig } from \"./types\";\n\nexport const DEFAULT_RUNTIME_ORIGIN = \"https://runtime.staging.webless.ai\";\n\nconst trimTrailingSlash = (value: string) => value.replace(/\\/+$/, \"\");\n\nexport function buildEveHost(\n origin: string,\n indexId: string,\n version: AgentIndexVersion = \"published\",\n): string {\n const base = trimTrailingSlash(origin);\n const searchParams = new URLSearchParams({ indexId: indexId.trim() });\n if (version === \"unpublished\") {\n searchParams.set(\"version\", version);\n }\n return `${base}?${searchParams.toString()}`;\n}\n\nexport function resolveAgentRuntimeConfig(input: {\n indexId: string;\n runtimeOrigin?: string;\n version?: AgentIndexVersion;\n}): AgentRuntimeConfig {\n const origin = trimTrailingSlash(input.runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN);\n const resolvedIndexId = input.indexId.trim();\n const version = input.version ?? \"published\";\n\n return {\n origin,\n indexId: resolvedIndexId,\n version,\n host: resolvedIndexId ? buildEveHost(origin, resolvedIndexId, version) : origin,\n };\n}\n\nexport function agentHealthUrl(runtimeOrigin?: string): string {\n const origin = trimTrailingSlash(runtimeOrigin?.trim() || DEFAULT_RUNTIME_ORIGIN);\n return `${origin}/eve/v1/health`;\n}\n","import type { AgentIndexVersion, PersistedAgentSession } from \"./types\";\n\nconst DEFAULT_STORAGE_KEY_PREFIX = \"webless:agent\";\n\nexport type SessionStoreOptions = {\n storageKeyPrefix?: string;\n};\n\nfunction normalizeRuntimeOrigin(runtimeOrigin?: string) {\n const trimmed = runtimeOrigin?.trim();\n if (!trimmed) return \"_\";\n return trimmed.replace(/\\/+$/, \"\");\n}\n\nexport function buildAgentStorageKeyPrefix(input: {\n customerId?: string;\n indexId: string;\n runtimeOrigin?: string;\n version?: AgentIndexVersion;\n}) {\n const customerId = input.customerId?.trim() || \"_\";\n const indexId = input.indexId.trim();\n if (!indexId) {\n throw new Error(\"indexId is required to build agent storage keys.\");\n }\n\n const versionSuffix = input.version === \"unpublished\" ? \":unpublished\" : \"\";\n return `${DEFAULT_STORAGE_KEY_PREFIX}:${customerId}:${indexId}${versionSuffix}:${normalizeRuntimeOrigin(input.runtimeOrigin)}`;\n}\n\nfunction createSessionId(): string {\n if (typeof crypto !== \"undefined\" && typeof crypto.randomUUID === \"function\") {\n return crypto.randomUUID();\n }\n return `sess_${Math.random().toString(36).slice(2)}${Date.now().toString(36)}`;\n}\n\nfunction resolvePrefix(options?: SessionStoreOptions) {\n return options?.storageKeyPrefix?.trim() || DEFAULT_STORAGE_KEY_PREFIX;\n}\n\nexport function getOrCreateVisitorSessionId(options?: SessionStoreOptions): string {\n const prefix = resolvePrefix(options);\n const visitorKey = `${prefix}:visitorSessionId`;\n\n if (typeof sessionStorage === \"undefined\") {\n return createSessionId();\n }\n\n const existing = sessionStorage.getItem(visitorKey)?.trim();\n if (existing) return existing;\n\n const next = createSessionId();\n sessionStorage.setItem(visitorKey, next);\n return next;\n}\n\nexport function clearVisitorSessionId(options?: SessionStoreOptions) {\n if (typeof sessionStorage === \"undefined\") return;\n\n const prefix = resolvePrefix(options);\n sessionStorage.removeItem(`${prefix}:visitorSessionId`);\n}\n\nfunction runtimeSessionIdKey(visitorSessionId: string, prefix: string) {\n return `${prefix}:eve:${visitorSessionId}:sessionId`;\n}\n\nfunction runtimeStreamIndexKey(visitorSessionId: string, prefix: string) {\n return `${prefix}:eve:${visitorSessionId}:streamIndex`;\n}\n\nexport function loadPersistedAgentSession(\n visitorSessionId: string,\n options?: SessionStoreOptions,\n): PersistedAgentSession | null {\n if (typeof sessionStorage === \"undefined\" || !visitorSessionId.trim()) return null;\n\n const prefix = resolvePrefix(options);\n const sessionId = sessionStorage.getItem(runtimeSessionIdKey(visitorSessionId, prefix))?.trim();\n if (!sessionId) return null;\n\n const rawIndex = sessionStorage.getItem(runtimeStreamIndexKey(visitorSessionId, prefix));\n const streamIndex = rawIndex ? Number.parseInt(rawIndex, 10) : 0;\n\n return {\n sessionId,\n streamIndex: Number.isFinite(streamIndex) && streamIndex >= 0 ? streamIndex : 0,\n };\n}\n\nexport function savePersistedAgentSession(\n visitorSessionId: string,\n sessionId: string,\n streamIndex: number,\n options?: SessionStoreOptions,\n) {\n if (typeof sessionStorage === \"undefined\" || !visitorSessionId.trim() || !sessionId.trim()) {\n return;\n }\n\n const prefix = resolvePrefix(options);\n sessionStorage.setItem(runtimeSessionIdKey(visitorSessionId, prefix), sessionId);\n sessionStorage.setItem(\n runtimeStreamIndexKey(visitorSessionId, prefix),\n String(Math.max(0, streamIndex)),\n );\n}\n\nexport function clearPersistedAgentSession(\n visitorSessionId: string,\n options?: SessionStoreOptions,\n) {\n if (typeof sessionStorage === \"undefined\" || !visitorSessionId.trim()) return;\n const prefix = resolvePrefix(options);\n sessionStorage.removeItem(runtimeSessionIdKey(visitorSessionId, prefix));\n sessionStorage.removeItem(runtimeStreamIndexKey(visitorSessionId, prefix));\n}\n","import { ClientError } from \"eve/client\";\n\nexport function formatAgentError(error: unknown): string {\n if (error instanceof ClientError) {\n if (error.status === 401 && error.code === \"index_required\") {\n return \"Missing indexId — pass a published index id to createAgentClient().\";\n }\n if (error.status === 403 && error.code === \"agent_unavailable\") {\n return \"Agent unavailable for this index (disabled or unpublished).\";\n }\n if (error.status === 409 && error.code === \"session_not_active\") {\n return \"Session expired — send a new message to start again.\";\n }\n return error.message || `Runtime error (${error.status})`;\n }\n if (error instanceof DOMException && error.name === \"AbortError\") {\n return \"\";\n }\n if (error instanceof Error) return error.message;\n return \"Runtime request failed\";\n}\n","import { formatAgentError } from \"./errors\";\nimport { agentHealthUrl } from \"./config\";\nimport type { AgentHealthResult } from \"./types\";\n\nexport async function pingAgentHealth(\n runtimeOrigin?: string,\n fetchImpl: typeof fetch = fetch,\n): Promise<AgentHealthResult> {\n const healthUrl = agentHealthUrl(runtimeOrigin);\n\n try {\n const response = await fetchImpl(healthUrl, {\n headers: { Accept: \"application/json\" },\n cache: \"no-store\",\n });\n if (!response.ok) {\n return { ok: false, detail: `Health check failed (${response.status})` };\n }\n const payload = (await response.json()) as { status?: string; ok?: boolean };\n if (payload.ok === true) {\n return { ok: true, detail: payload.status ?? \"ready\" };\n }\n return { ok: false, detail: \"Runtime health response was not ok\" };\n } catch (error) {\n return { ok: false, detail: formatAgentError(error) || \"Health check failed\" };\n }\n}\n"],"mappings":"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","names":["ClientError","ClientError","ClientError"]}
|
package/dist/react.cjs
CHANGED
|
@@ -40,7 +40,89 @@ 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";
|
|
@@ -154,6 +236,11 @@ var AgentSession = class {
|
|
|
154
236
|
this.runtimeOrigin = runtimeOrigin;
|
|
155
237
|
this.visitorSessionId = visitorSessionId;
|
|
156
238
|
this.storeOptions = storeOptions;
|
|
239
|
+
this.capability = createAgentRuntimeCapability({
|
|
240
|
+
indexId,
|
|
241
|
+
runtimeOrigin,
|
|
242
|
+
visitorSessionId
|
|
243
|
+
});
|
|
157
244
|
}
|
|
158
245
|
indexId;
|
|
159
246
|
version;
|
|
@@ -164,7 +251,7 @@ var AgentSession = class {
|
|
|
164
251
|
clientHost;
|
|
165
252
|
session;
|
|
166
253
|
activeResponse;
|
|
167
|
-
|
|
254
|
+
capability;
|
|
168
255
|
getActiveSessionId() {
|
|
169
256
|
return this.session?.state.sessionId ?? loadPersistedAgentSession(this.visitorSessionId, this.storeOptions)?.sessionId;
|
|
170
257
|
}
|
|
@@ -173,7 +260,6 @@ var AgentSession = class {
|
|
|
173
260
|
});
|
|
174
261
|
this.activeResponse = void 0;
|
|
175
262
|
this.session = void 0;
|
|
176
|
-
this.renderedPrefix = "";
|
|
177
263
|
clearPersistedAgentSession(this.visitorSessionId, this.storeOptions);
|
|
178
264
|
}
|
|
179
265
|
persistSessionCursor(session) {
|
|
@@ -197,14 +283,17 @@ var AgentSession = class {
|
|
|
197
283
|
return this.client;
|
|
198
284
|
}
|
|
199
285
|
this.reset();
|
|
200
|
-
this.client = new
|
|
286
|
+
this.client = new import_client2.Client({
|
|
287
|
+
auth: { bearer: () => this.capability.getAccessToken() },
|
|
288
|
+
host: config.host,
|
|
289
|
+
redirect: "error"
|
|
290
|
+
});
|
|
201
291
|
this.clientHost = config.host;
|
|
202
292
|
return this.client;
|
|
203
293
|
}
|
|
204
294
|
attachPersistedSession(client) {
|
|
205
295
|
const persisted = loadPersistedAgentSession(this.visitorSessionId, this.storeOptions);
|
|
206
296
|
if (!persisted?.sessionId) return void 0;
|
|
207
|
-
this.renderedPrefix = "";
|
|
208
297
|
return client.sessions.attach(persisted.sessionId, {
|
|
209
298
|
streamIndex: persisted.streamIndex
|
|
210
299
|
});
|
|
@@ -216,9 +305,13 @@ var AgentSession = class {
|
|
|
216
305
|
if (session) {
|
|
217
306
|
this.session = session;
|
|
218
307
|
try {
|
|
219
|
-
|
|
308
|
+
const activeSession = session;
|
|
309
|
+
response = await withCapabilityRefresh(
|
|
310
|
+
this.capability,
|
|
311
|
+
() => activeSession.send(message, { signal })
|
|
312
|
+
);
|
|
220
313
|
} catch (error) {
|
|
221
|
-
if (error instanceof
|
|
314
|
+
if (error instanceof import_client2.ClientError && error.status === 409 && error.code === "session_not_active") {
|
|
222
315
|
clearPersistedAgentSession(this.visitorSessionId, this.storeOptions);
|
|
223
316
|
this.session = void 0;
|
|
224
317
|
session = void 0;
|
|
@@ -228,15 +321,17 @@ var AgentSession = class {
|
|
|
228
321
|
}
|
|
229
322
|
}
|
|
230
323
|
if (!response) {
|
|
231
|
-
const created = await
|
|
324
|
+
const created = await withCapabilityRefresh(
|
|
325
|
+
this.capability,
|
|
326
|
+
() => client.sessions.create({ message, signal })
|
|
327
|
+
);
|
|
232
328
|
response = created.response;
|
|
233
329
|
session = created.session;
|
|
234
330
|
this.session = session;
|
|
235
|
-
this.renderedPrefix = "";
|
|
236
331
|
this.persistSessionCursor(session);
|
|
237
332
|
}
|
|
238
333
|
this.activeResponse = response;
|
|
239
|
-
let rendered =
|
|
334
|
+
let rendered = "";
|
|
240
335
|
try {
|
|
241
336
|
for await (const event of response) {
|
|
242
337
|
if (signal.aborted) break;
|
|
@@ -262,7 +357,6 @@ var AgentSession = class {
|
|
|
262
357
|
}
|
|
263
358
|
} finally {
|
|
264
359
|
this.activeResponse = void 0;
|
|
265
|
-
this.renderedPrefix = rendered;
|
|
266
360
|
if (session) {
|
|
267
361
|
this.persistSessionCursor(session);
|
|
268
362
|
}
|
|
@@ -286,8 +380,12 @@ function createAgentClient(options) {
|
|
|
286
380
|
if (!indexId) {
|
|
287
381
|
throw new Error("indexId is required.");
|
|
288
382
|
}
|
|
289
|
-
const runtimeOrigin = options.runtimeOrigin?.trim() || resolveAgentRuntimeConfig({ indexId }).origin;
|
|
290
383
|
const version = options.version ?? "published";
|
|
384
|
+
const runtimeOrigin = resolveAgentRuntimeConfig({
|
|
385
|
+
indexId,
|
|
386
|
+
runtimeOrigin: options.runtimeOrigin,
|
|
387
|
+
version
|
|
388
|
+
}).origin;
|
|
291
389
|
const storeOptions = {
|
|
292
390
|
storageKeyPrefix: options.storageKeyPrefix?.trim() || buildAgentStorageKeyPrefix({
|
|
293
391
|
customerId: options.customerId,
|
|
@@ -315,9 +413,9 @@ function createAgentClient(options) {
|
|
|
315
413
|
}
|
|
316
414
|
|
|
317
415
|
// src/runtime/errors.ts
|
|
318
|
-
var
|
|
416
|
+
var import_client3 = require("eve/client");
|
|
319
417
|
function formatAgentError(error) {
|
|
320
|
-
if (error instanceof
|
|
418
|
+
if (error instanceof import_client3.ClientError) {
|
|
321
419
|
if (error.status === 401 && error.code === "index_required") {
|
|
322
420
|
return "Missing indexId \u2014 pass a published index id to createAgentClient().";
|
|
323
421
|
}
|
|
@@ -356,11 +454,6 @@ var STATUS_SEQUENCE = [
|
|
|
356
454
|
{ id: "s1", label: "Starting Eve session", ms: 400 },
|
|
357
455
|
{ id: "s2", label: "Connecting to runtime", ms: 500 }
|
|
358
456
|
];
|
|
359
|
-
var DEFAULT_FOLLOW_UPS = [
|
|
360
|
-
{ id: "fu-1", label: "What can you help me with?" },
|
|
361
|
-
{ id: "fu-2", label: "Summarize your capabilities" },
|
|
362
|
-
{ id: "fu-3", label: "What should I ask next?" }
|
|
363
|
-
];
|
|
364
457
|
function delay(ms, signal) {
|
|
365
458
|
return new Promise((resolve, reject) => {
|
|
366
459
|
const timer = window.setTimeout(resolve, ms);
|
|
@@ -517,7 +610,7 @@ function useAgentChat({
|
|
|
517
610
|
messages: [...prev.messages, agentMessage],
|
|
518
611
|
toolSteps: [],
|
|
519
612
|
streamingText: "",
|
|
520
|
-
followUps:
|
|
613
|
+
followUps: [],
|
|
521
614
|
journey: null
|
|
522
615
|
}));
|
|
523
616
|
} catch (error) {
|
|
@@ -833,12 +926,17 @@ function AgentRail({
|
|
|
833
926
|
const transcriptRef = (0, import_react4.useRef)(null);
|
|
834
927
|
const railStyle = theme?.railMaxWidth ? { ["--rail-width"]: theme.railMaxWidth, ["--as-rail-max-width"]: theme.railMaxWidth } : void 0;
|
|
835
928
|
const isBusy = state.phase === "thinking" || state.phase === "running-tools" || state.phase === "streaming";
|
|
836
|
-
const showActivity = state.toolSteps.length > 0 && (state.phase === "thinking" || state.phase === "running-tools"
|
|
837
|
-
const showStreamingInActivity = state.phase === "streaming" && Boolean(state.streamingText);
|
|
929
|
+
const showActivity = state.toolSteps.length > 0 && (state.phase === "thinking" || state.phase === "running-tools");
|
|
838
930
|
const hasVisitorMessages2 = state.messages.some((message) => message.role === "visitor");
|
|
839
931
|
const showIdleFollowUps = !hasVisitorMessages2 && state.followUps.length > 0;
|
|
840
|
-
const
|
|
841
|
-
const
|
|
932
|
+
const showDockFollowUps = expanded && showIdleFollowUps;
|
|
933
|
+
const streamingMessage = state.phase === "streaming" && state.streamingText ? {
|
|
934
|
+
createdAt: 0,
|
|
935
|
+
id: "streaming-response",
|
|
936
|
+
role: "agent",
|
|
937
|
+
streaming: true,
|
|
938
|
+
text: state.streamingText
|
|
939
|
+
} : null;
|
|
842
940
|
(0, import_react4.useEffect)(() => {
|
|
843
941
|
const node = transcriptRef.current;
|
|
844
942
|
if (!node) return;
|
|
@@ -876,14 +974,8 @@ function AgentRail({
|
|
|
876
974
|
] }) }),
|
|
877
975
|
/* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { ref: transcriptRef, className: "agent-rail__transcript", children: [
|
|
878
976
|
state.messages.map((message) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MessageBubble, { message }, message.id)),
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
{
|
|
882
|
-
steps: state.toolSteps,
|
|
883
|
-
streamingText: state.streamingText,
|
|
884
|
-
showStreaming: showStreamingInActivity
|
|
885
|
-
}
|
|
886
|
-
) : null,
|
|
977
|
+
streamingMessage ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(MessageBubble, { message: streamingMessage }) : null,
|
|
978
|
+
showActivity ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(AgentActivityBubble, { steps: state.toolSteps }) : null,
|
|
887
979
|
!expanded && showIdleFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
888
980
|
FollowUpChips,
|
|
889
981
|
{
|
|
@@ -893,14 +985,6 @@ function AgentRail({
|
|
|
893
985
|
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
894
986
|
}
|
|
895
987
|
) }) : null,
|
|
896
|
-
!expanded && showCompleteFollowUps ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "agent-rail__followups-slot", children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
|
|
897
|
-
FollowUpChips,
|
|
898
|
-
{
|
|
899
|
-
suggestions: state.followUps,
|
|
900
|
-
disabled: isBusy,
|
|
901
|
-
onSelect: (suggestion) => onFollowUpSelect?.(suggestion.label)
|
|
902
|
-
}
|
|
903
|
-
) }) : null,
|
|
904
988
|
state.error ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: "alert", style: { fontSize: 13, color: "var(--as-danger)", margin: 0 }, children: state.error }) : null
|
|
905
989
|
] }),
|
|
906
990
|
expanded ? /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "agent-rail__dock-wrap", children: [
|