eve 0.13.3 → 0.13.4

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/src/chunks/use-eve-agent-BLv-Mj5g.js +1512 -0
  3. package/dist/src/chunks/use-eve-agent-C8UVUMA4.js +1542 -0
  4. package/dist/src/client/agent-info-schema.d.ts +1 -1
  5. package/dist/src/client/agent-info-schema.js +1 -1
  6. package/dist/src/compiled/.vendor-stamp.json +3 -3
  7. package/dist/src/compiled/@ai-sdk/anthropic/index.js +2 -2
  8. package/dist/src/compiled/@ai-sdk/google/index.js +6 -6
  9. package/dist/src/compiled/@ai-sdk/mcp/index.js +1 -1
  10. package/dist/src/compiled/@ai-sdk/openai/index.js +2 -2
  11. package/dist/src/compiled/@workflow/core/create-hook.d.ts +3 -1
  12. package/dist/src/compiled/@workflow/core/events-consumer.d.ts +9 -0
  13. package/dist/src/compiled/@workflow/core/index.js +2 -2
  14. package/dist/src/compiled/@workflow/core/logger.d.ts +1 -0
  15. package/dist/src/compiled/@workflow/core/private.d.ts +35 -2
  16. package/dist/src/compiled/@workflow/core/runtime/constants.d.ts +73 -0
  17. package/dist/src/compiled/@workflow/core/runtime/get-port-lazy.d.ts +15 -0
  18. package/dist/src/compiled/@workflow/core/runtime/run-id-time.d.ts +10 -0
  19. package/dist/src/compiled/@workflow/core/runtime/step-executor.d.ts +61 -1
  20. package/dist/src/compiled/@workflow/core/runtime/suspension-handler.d.ts +38 -2
  21. package/dist/src/compiled/@workflow/core/runtime.d.ts +1 -0
  22. package/dist/src/compiled/@workflow/core/runtime.js +28 -28
  23. package/dist/src/compiled/@workflow/core/source-map.d.ts +5 -0
  24. package/dist/src/compiled/@workflow/core/step/context-storage.d.ts +27 -0
  25. package/dist/src/compiled/@workflow/core/step-hydration-cache.d.ts +148 -0
  26. package/dist/src/compiled/@workflow/core/telemetry/semantic-conventions.d.ts +28 -0
  27. package/dist/src/compiled/@workflow/core/telemetry.d.ts +9 -6
  28. package/dist/src/compiled/@workflow/core/version.d.ts +1 -1
  29. package/dist/src/compiled/@workflow/core/vm/script-cache.d.ts +28 -0
  30. package/dist/src/compiled/@workflow/core/workflow.js +1 -1
  31. package/dist/src/compiled/@workflow/world/events.d.ts +78 -3
  32. package/dist/src/compiled/@workflow/world/index.d.ts +1 -1
  33. package/dist/src/compiled/@workflow/world/spec-version.d.ts +11 -1
  34. package/dist/src/compiled/_chunks/{workflow/core-CXJbIkCL.js → client/core-Bm8azZA6.js} +5 -5
  35. package/dist/src/compiled/_chunks/workflow/{attribute-changes-Bi5DLT8S.js → attribute-changes-DUxG-Gic.js} +3 -3
  36. package/dist/src/compiled/_chunks/workflow/dist-C9PV_vnE.js +77 -0
  37. package/dist/src/compiled/_chunks/workflow/resume-hook-CUCPW67D.js +1 -0
  38. package/dist/src/compiled/_chunks/workflow/{run-XM8dTRAo.js → run-CVlF84yI.js} +1 -1
  39. package/dist/src/compiled/_chunks/workflow/sleep-Dxuzj5to.js +1 -0
  40. package/dist/src/compiled/zod/index.js +1 -1
  41. package/dist/src/compiled/zod-validation-error/index.js +1 -1
  42. package/dist/src/execution/workflow-steps.js +1 -1
  43. package/dist/src/harness/authorization.d.ts +1 -0
  44. package/dist/src/harness/authorization.js +1 -1
  45. package/dist/src/internal/application/optional-package-install.js +15 -1
  46. package/dist/src/internal/application/package.js +1 -1
  47. package/dist/src/setup/scaffold/create/project.js +1 -1
  48. package/dist/src/svelte/index.js +1 -1
  49. package/dist/src/svelte/use-eve-agent.js +1 -1
  50. package/dist/src/vue/index.js +1 -1
  51. package/dist/src/vue/use-eve-agent.js +1 -1
  52. package/package.json +4 -4
  53. package/dist/src/chunks/use-eve-agent-B18LYpfZ.js +0 -5765
  54. package/dist/src/chunks/use-eve-agent-BPI1nbo5.js +0 -5795
  55. package/dist/src/compiled/_chunks/workflow/coerce-B-Ro4Nfe.js +0 -1
  56. package/dist/src/compiled/_chunks/workflow/compat-DLpWymPP.js +0 -1
  57. package/dist/src/compiled/_chunks/workflow/dist-DTchiX0N.js +0 -14
  58. package/dist/src/compiled/_chunks/workflow/resume-hook-CKTw-lb5.js +0 -1
  59. package/dist/src/compiled/_chunks/workflow/schemas-iG9Z4s4o.js +0 -1
  60. package/dist/src/compiled/_chunks/workflow/sleep-DPjVkRY-.js +0 -1
@@ -0,0 +1,1512 @@
1
+ import { computed, onScopeDispose, shallowRef } from "vue";
2
+ import { z } from "#compiled/zod/index.js";
3
+
4
+ //#region src/protocol/routes.ts
5
+ const EVE_ROUTE_PREFIX = "/eve/v1";
6
+ const EVE_HEALTH_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/health`;
7
+ const EVE_INFO_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/info`;
8
+ const EVE_CREATE_SESSION_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/session`;
9
+ const EVE_CONTINUE_SESSION_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/session/:sessionId`;
10
+ const EVE_MESSAGE_STREAM_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/session/:sessionId/stream`;
11
+ const EVE_DEV_DISPATCH_SCHEDULE_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/dev/schedules/:scheduleId`;
12
+ const EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH = `${EVE_ROUTE_PREFIX}/dev/runtime-artifacts`;
13
+ const EVE_DEV_RUNTIME_ARTIFACTS_REBUILD_ROUTE_PATH = `${EVE_DEV_RUNTIME_ARTIFACTS_ROUTE_PATH}/rebuild`;
14
+ const EVE_CONNECTION_CALLBACK_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/connections/:name/callback/:token`;
15
+ const EVE_CALLBACK_ROUTE_PATTERN = `${EVE_ROUTE_PREFIX}/callback/:token`;
16
+ function createEveMessageStreamRoutePath(sessionId) {
17
+ return `${EVE_ROUTE_PREFIX}/session/${encodeURIComponent(sessionId)}/stream`;
18
+ }
19
+ function createEveContinueSessionRoutePath(sessionId) {
20
+ return `${EVE_ROUTE_PREFIX}/session/${encodeURIComponent(sessionId)}`;
21
+ }
22
+
23
+ //#endregion
24
+ //#region src/client/agent-info-schema.ts
25
+ const source = z.object({
26
+ exportName: z.string().optional(),
27
+ logicalPath: z.string(),
28
+ sourceId: z.string().optional(),
29
+ sourceKind: z.string()
30
+ });
31
+ const entry = source.extend({ name: z.string() });
32
+ const modelRouting = z.discriminatedUnion("kind", [z.object({
33
+ kind: z.literal("gateway"),
34
+ target: z.string(),
35
+ byok: z.string().optional()
36
+ }), z.object({
37
+ kind: z.literal("external"),
38
+ provider: z.string()
39
+ })]);
40
+ const modelEndpoint = z.union([
41
+ z.object({
42
+ kind: z.literal("external"),
43
+ provider: z.string()
44
+ }),
45
+ z.object({
46
+ kind: z.literal("gateway"),
47
+ connected: z.literal(true),
48
+ credential: z.enum(["api-key", "oidc"])
49
+ }),
50
+ z.object({
51
+ kind: z.literal("gateway"),
52
+ connected: z.literal(false)
53
+ })
54
+ ]);
55
+ const tool = entry.extend({
56
+ description: z.string(),
57
+ hasAuth: z.boolean(),
58
+ hasExecute: z.boolean(),
59
+ hasModelOutputProjection: z.boolean(),
60
+ hasOutputSchema: z.boolean(),
61
+ inputSchema: z.unknown(),
62
+ origin: z.enum(["authored", "framework"]),
63
+ outputSchema: z.unknown().optional(),
64
+ replacesFrameworkTool: z.boolean(),
65
+ requiresApproval: z.boolean()
66
+ });
67
+ const frameworkTool = tool.extend({
68
+ disabledByAuthor: z.boolean(),
69
+ replacedByAuthoredTool: z.boolean(),
70
+ status: z.enum([
71
+ "active",
72
+ "disabled",
73
+ "replaced"
74
+ ])
75
+ });
76
+ const dynamicResolver = source.extend({
77
+ eventNames: z.array(z.string()),
78
+ origin: z.enum(["authored", "framework"]),
79
+ slug: z.string()
80
+ });
81
+ const skill = entry.extend({
82
+ description: z.string(),
83
+ license: z.string().optional(),
84
+ markdown: z.string(),
85
+ metadata: z.record(z.string(), z.string()).optional()
86
+ });
87
+ const instructions = entry.extend({ markdown: z.string() });
88
+ const schedule = entry.extend({
89
+ cron: z.string(),
90
+ hasRun: z.boolean(),
91
+ markdown: z.string().optional()
92
+ });
93
+ const subagent = entry.extend({
94
+ description: z.string(),
95
+ entryPath: z.string(),
96
+ nodeId: z.string(),
97
+ rootPath: z.string(),
98
+ summary: z.object({
99
+ channels: z.number(),
100
+ connections: z.number(),
101
+ hooks: z.number(),
102
+ instructions: z.boolean(),
103
+ schedules: z.number(),
104
+ skills: z.number(),
105
+ tools: z.number()
106
+ })
107
+ });
108
+ const channel = entry.extend({
109
+ adapterKind: z.string().optional(),
110
+ method: z.string(),
111
+ origin: z.enum(["authored", "framework"]),
112
+ urlPath: z.string()
113
+ });
114
+ const frameworkChannel = channel.extend({
115
+ disabledByAuthor: z.boolean(),
116
+ replacedByAuthoredChannel: z.boolean(),
117
+ status: z.enum([
118
+ "active",
119
+ "disabled",
120
+ "replaced"
121
+ ])
122
+ });
123
+ const connection = source.extend({
124
+ connectionName: z.string(),
125
+ description: z.string(),
126
+ hasApproval: z.boolean(),
127
+ hasAuthorization: z.boolean(),
128
+ hasHeaders: z.boolean(),
129
+ protocol: z.string(),
130
+ toolFilter: z.unknown().optional(),
131
+ url: z.string()
132
+ });
133
+ const hook = source.extend({
134
+ eventNames: z.array(z.string()),
135
+ slug: z.string()
136
+ });
137
+ const sandbox = source.extend({
138
+ backendKind: z.string().optional(),
139
+ description: z.string().optional(),
140
+ hasBootstrap: z.boolean(),
141
+ hasOnSession: z.boolean(),
142
+ revalidationKey: z.string().optional(),
143
+ sourceHash: z.string().optional()
144
+ });
145
+ const AgentInfoResultSchema = z.object({
146
+ agent: z.object({
147
+ agentRoot: z.string(),
148
+ appRoot: z.string(),
149
+ configSource: source.optional(),
150
+ description: z.string().optional(),
151
+ model: z.object({
152
+ contextWindowTokens: z.number().optional(),
153
+ id: z.string(),
154
+ providerOptions: z.unknown().optional(),
155
+ source: source.optional(),
156
+ routing: modelRouting.optional(),
157
+ endpoint: modelEndpoint.optional()
158
+ }),
159
+ name: z.string(),
160
+ outputSchema: z.unknown().optional()
161
+ }),
162
+ capabilities: z.object({ devRoutes: z.boolean() }),
163
+ channels: z.object({
164
+ authored: z.array(channel),
165
+ available: z.array(channel),
166
+ disabledFramework: z.array(z.string()),
167
+ framework: z.array(frameworkChannel)
168
+ }),
169
+ connections: z.array(connection),
170
+ diagnostics: z.object({
171
+ discoveryErrors: z.number(),
172
+ discoveryWarnings: z.number()
173
+ }),
174
+ hooks: z.array(hook),
175
+ instructions: z.object({
176
+ dynamic: z.array(dynamicResolver),
177
+ static: instructions.nullable()
178
+ }),
179
+ kind: z.literal("eve-agent-info"),
180
+ mode: z.enum(["development", "production"]),
181
+ sandbox: sandbox.nullable(),
182
+ schedules: z.array(schedule),
183
+ skills: z.object({
184
+ dynamic: z.array(dynamicResolver),
185
+ static: z.array(skill)
186
+ }),
187
+ subagents: z.object({
188
+ local: z.array(subagent),
189
+ total: z.number()
190
+ }),
191
+ tools: z.object({
192
+ authored: z.array(tool),
193
+ available: z.array(tool),
194
+ disabledFramework: z.array(z.string()),
195
+ dynamic: z.array(dynamicResolver),
196
+ framework: z.array(frameworkTool),
197
+ reserved: z.array(z.string())
198
+ }),
199
+ version: z.literal(1),
200
+ workflow: z.object({
201
+ enabled: z.boolean(),
202
+ toolName: z.string()
203
+ }),
204
+ workspace: z.object({
205
+ resourceRoot: z.unknown(),
206
+ rootEntries: z.array(z.string())
207
+ })
208
+ });
209
+
210
+ //#endregion
211
+ //#region src/shared/guards.ts
212
+ function isObject(value) {
213
+ return typeof value === "object" && value !== null && !Array.isArray(value);
214
+ }
215
+
216
+ //#endregion
217
+ //#region src/client/client-error.ts
218
+ var ClientError = class extends Error {
219
+ status;
220
+ body;
221
+ constructor(status, body) {
222
+ let message = body || `Server returned ${status}.`;
223
+ try {
224
+ const parsed = JSON.parse(body);
225
+ if (isObject(parsed) && typeof parsed.error === "string") message = parsed.error;
226
+ } catch {}
227
+ super(message);
228
+ this.name = "ClientError";
229
+ this.status = status;
230
+ this.body = body;
231
+ }
232
+ };
233
+
234
+ //#endregion
235
+ //#region src/protocol/message.ts
236
+ const EVE_SESSION_ID_HEADER = "x-eve-session-id";
237
+ const textEncoder = new TextEncoder();
238
+ function isCurrentTurnBoundaryEvent(event) {
239
+ return event.type === "session.completed" || event.type === "session.failed" || event.type === "session.waiting";
240
+ }
241
+
242
+ //#endregion
243
+ //#region src/shared/json.ts
244
+ const INVALID_JSON_VALUE_CANDIDATE = Symbol("invalid-json-value-candidate");
245
+ const JSON_VALUE_ERROR_MESSAGE = "Expected a JSON-serializable value.";
246
+ const JSON_OBJECT_ERROR_MESSAGE = "Expected a JSON-serializable object.";
247
+ function parseJsonValue(value) {
248
+ const normalized = normalizeJsonValueCandidate(value);
249
+ if (normalized === INVALID_JSON_VALUE_CANDIDATE) throw new TypeError(JSON_VALUE_ERROR_MESSAGE);
250
+ return normalized;
251
+ }
252
+ function parseJsonObject(value) {
253
+ const normalized = parseJsonValue(value);
254
+ if (!isJsonObjectValue(normalized)) throw new TypeError(JSON_OBJECT_ERROR_MESSAGE);
255
+ return normalized;
256
+ }
257
+ function normalizeJsonValueCandidate(value, seen = /* @__PURE__ */ new WeakSet()) {
258
+ if (value === null || typeof value === "boolean" || typeof value === "string") return value;
259
+ if (typeof value === "number") return Number.isFinite(value) ? value : INVALID_JSON_VALUE_CANDIDATE;
260
+ if (Array.isArray(value)) {
261
+ const normalizedItems = [];
262
+ for (const item of value) {
263
+ const normalizedItem = normalizeJsonValueCandidate(item, seen);
264
+ if (normalizedItem === INVALID_JSON_VALUE_CANDIDATE) return INVALID_JSON_VALUE_CANDIDATE;
265
+ normalizedItems.push(normalizedItem);
266
+ }
267
+ return normalizedItems;
268
+ }
269
+ if (typeof value !== "object" || value === void 0) return INVALID_JSON_VALUE_CANDIDATE;
270
+ if (!isPlainObject(value)) return INVALID_JSON_VALUE_CANDIDATE;
271
+ if (seen.has(value)) return INVALID_JSON_VALUE_CANDIDATE;
272
+ seen.add(value);
273
+ const normalized = {};
274
+ for (const [key, entry] of Object.entries(value)) {
275
+ if (entry === void 0) continue;
276
+ const normalizedEntry = normalizeJsonValueCandidate(entry, seen);
277
+ if (normalizedEntry === INVALID_JSON_VALUE_CANDIDATE) return INVALID_JSON_VALUE_CANDIDATE;
278
+ normalized[key] = normalizedEntry;
279
+ }
280
+ seen.delete(value);
281
+ return normalized;
282
+ }
283
+ function isJsonObjectValue(value) {
284
+ return value !== null && !Array.isArray(value) && typeof value === "object";
285
+ }
286
+ function isPlainObject(value) {
287
+ const prototype = Object.getPrototypeOf(value);
288
+ return prototype === null || prototype === Object.prototype;
289
+ }
290
+
291
+ //#endregion
292
+ //#region src/shared/json-schema.ts
293
+ const STANDARD_JSON_SCHEMA_TARGET = "draft-07";
294
+ function normalizeJsonSchemaDefinition(value, direction = "input") {
295
+ if (isStandardSchema(value)) return parseJsonObject(value["~standard"].jsonSchema[direction]({ target: STANDARD_JSON_SCHEMA_TARGET }));
296
+ return parseJsonObject(value);
297
+ }
298
+ function isStandardSchema(value) {
299
+ return value !== null && typeof value === "object" && "~standard" in value;
300
+ }
301
+
302
+ //#endregion
303
+ //#region src/client/output-schema.ts
304
+ function normalizeOutputSchemaForRequest(schema) {
305
+ return schema === void 0 ? void 0 : normalizeJsonSchemaDefinition(schema, "output");
306
+ }
307
+ function extractCompletedResult(events) {
308
+ let result;
309
+ for (const event of events) if (isResultCompletedEvent(event)) result = event.data.result;
310
+ return result;
311
+ }
312
+ function isResultCompletedEvent(event) {
313
+ return event.type === "result.completed";
314
+ }
315
+
316
+ //#endregion
317
+ //#region src/client/session-utils.ts
318
+ function createInitialSessionState() {
319
+ return { streamIndex: 0 };
320
+ }
321
+ function advanceSession(input) {
322
+ const boundaryEvent = findBoundaryEvent(input.events);
323
+ const streamIndex = input.session.streamIndex + input.events.length;
324
+ if (boundaryEvent?.type === "session.waiting" || input.preserveCompletedSessions === true && boundaryEvent?.type === "session.completed") return {
325
+ continuationToken: input.continuationToken ?? input.session.continuationToken,
326
+ sessionId: input.sessionId,
327
+ streamIndex
328
+ };
329
+ return createInitialSessionState();
330
+ }
331
+ function extractCompletedMessage(events) {
332
+ let lastMessage;
333
+ for (const event of events) if (isFinalMessageCompleted(event)) lastMessage = event.data.message ?? void 0;
334
+ return lastMessage;
335
+ }
336
+ function deriveResultStatus(events) {
337
+ const boundary = findBoundaryEvent(events);
338
+ if (boundary?.type === "session.waiting") return "waiting";
339
+ if (boundary?.type === "session.failed") return "failed";
340
+ return "completed";
341
+ }
342
+ function extractInputRequests(events) {
343
+ const requests = [];
344
+ for (const event of events) if (event.type === "input.requested") requests.push(...event.data.requests);
345
+ return requests;
346
+ }
347
+ function findBoundaryEvent(events) {
348
+ for (let i = events.length - 1; i >= 0; i--) {
349
+ const event = events[i];
350
+ if (event !== void 0 && isCurrentTurnBoundaryEvent(event)) return event;
351
+ }
352
+ }
353
+ function isFinalMessageCompleted(event) {
354
+ return event.type === "message.completed" && event.data.finishReason !== "tool-calls";
355
+ }
356
+
357
+ //#endregion
358
+ //#region src/client/message-response.ts
359
+ var MessageResponse = class {
360
+ continuationToken;
361
+ sessionId;
362
+ #consumed = false;
363
+ #createStream;
364
+ constructor(input) {
365
+ this.continuationToken = input.continuationToken;
366
+ this.sessionId = input.sessionId;
367
+ this.#createStream = input.createStream;
368
+ }
369
+ async result() {
370
+ const events = [];
371
+ for await (const event of this) events.push(event);
372
+ return {
373
+ data: extractCompletedResult(events),
374
+ events,
375
+ inputRequests: extractInputRequests(events),
376
+ message: extractCompletedMessage(events),
377
+ sessionId: this.sessionId,
378
+ status: deriveResultStatus(events)
379
+ };
380
+ }
381
+ [Symbol.asyncIterator]() {
382
+ if (this.#consumed) throw new Error("MessageResponse has already been consumed.");
383
+ this.#consumed = true;
384
+ return this.#createStream();
385
+ }
386
+ };
387
+
388
+ //#endregion
389
+ //#region src/client/ndjson.ts
390
+ function isStreamDisconnectError(error) {
391
+ if (error instanceof DOMException) return error.name === "AbortError";
392
+ if (!(error instanceof Error)) return false;
393
+ const errorCode = "code" in error && typeof error.code === "string" ? error.code : void 0;
394
+ return error.name === "AbortError" || error.message === "terminated" || errorCode === "UND_ERR_SOCKET" || /abort|cancel|disconnect|premature close|socket|terminated/i.test(error.message);
395
+ }
396
+ async function* readNdjsonStream(body) {
397
+ const reader = body.getReader();
398
+ const decoder = new TextDecoder();
399
+ let buffer = "";
400
+ try {
401
+ while (true) {
402
+ const result = await reader.read();
403
+ if (result.done) {
404
+ buffer += decoder.decode();
405
+ break;
406
+ }
407
+ if (result.value) buffer += decoder.decode(result.value, { stream: true });
408
+ let newlineIndex = buffer.indexOf("\n");
409
+ while (newlineIndex !== -1) {
410
+ const line = buffer.slice(0, newlineIndex).trim();
411
+ buffer = buffer.slice(newlineIndex + 1);
412
+ if (line.length > 0) yield JSON.parse(line);
413
+ newlineIndex = buffer.indexOf("\n");
414
+ }
415
+ }
416
+ const trailing = buffer.trim();
417
+ if (trailing.length > 0) yield JSON.parse(trailing);
418
+ } finally {
419
+ reader.releaseLock();
420
+ }
421
+ }
422
+
423
+ //#endregion
424
+ //#region src/client/url.ts
425
+ function createClientUrl(host, routePath, searchParams) {
426
+ const normalizedRoute = routePath.startsWith("/") ? routePath : `/${routePath}`;
427
+ const search = formatSearch(searchParams);
428
+ if (isAbsoluteUrl(host)) {
429
+ const url = new URL(host);
430
+ url.pathname = `${trimTrailingSlash(url.pathname)}${normalizedRoute}`;
431
+ url.search = search;
432
+ url.hash = "";
433
+ return url.toString();
434
+ }
435
+ return `${trimTrailingSlash(host)}${normalizedRoute}${search}`;
436
+ }
437
+ function isAbsoluteUrl(value) {
438
+ return /^[a-z][a-z\d+\-.]*:/i.test(value);
439
+ }
440
+ function trimTrailingSlash(value) {
441
+ if (value === "/") return "";
442
+ return value.endsWith("/") ? value.slice(0, -1) : value;
443
+ }
444
+ function formatSearch(searchParams) {
445
+ if (!searchParams || Object.keys(searchParams).length === 0) return "";
446
+ return `?${new URLSearchParams(searchParams).toString()}`;
447
+ }
448
+
449
+ //#endregion
450
+ //#region src/client/open-stream.ts
451
+ const STREAM_OPEN_RETRY_ATTEMPTS = 12;
452
+ const STREAM_OPEN_RETRY_DELAY_MS = 250;
453
+ const STREAM_OPEN_RETRYABLE_STATUS = new Set([
454
+ 404,
455
+ 409,
456
+ 425,
457
+ 500,
458
+ 502,
459
+ 503,
460
+ 504
461
+ ]);
462
+ async function* openStreamIterable(input) {
463
+ let startIndex = input.startIndex;
464
+ let remainingReconnectAttempts = input.maxReconnectAttempts;
465
+ while (true) {
466
+ const body = await openStreamBody({
467
+ ...input,
468
+ startIndex
469
+ });
470
+ let disconnected = false;
471
+ try {
472
+ for await (const event of readNdjsonStream(body)) {
473
+ startIndex += 1;
474
+ yield event;
475
+ }
476
+ } catch (error) {
477
+ if (!isStreamDisconnectError(error)) throw error;
478
+ disconnected = true;
479
+ }
480
+ if (!disconnected || input.signal?.aborted || remainingReconnectAttempts <= 0) return;
481
+ remainingReconnectAttempts -= 1;
482
+ }
483
+ }
484
+ async function openStreamBody(input) {
485
+ let lastStatus;
486
+ let lastBody;
487
+ for (let attempt = 0; attempt < STREAM_OPEN_RETRY_ATTEMPTS; attempt += 1) {
488
+ const url = createClientUrl(input.host, createEveMessageStreamRoutePath(input.sessionId), input.startIndex > 0 ? { startIndex: String(input.startIndex) } : void 0);
489
+ const headers = await input.resolveHeaders();
490
+ const response = await fetch(url, {
491
+ headers,
492
+ redirect: input.redirect,
493
+ signal: input.signal ?? null
494
+ });
495
+ if (response.ok) {
496
+ if (!response.body) throw new ClientError(response.status, "Response body is null.");
497
+ return response.body;
498
+ }
499
+ lastStatus = response.status;
500
+ lastBody = await response.text();
501
+ if (!STREAM_OPEN_RETRYABLE_STATUS.has(response.status)) throw new ClientError(response.status, lastBody);
502
+ if (attempt < STREAM_OPEN_RETRY_ATTEMPTS - 1) await sleep$1(STREAM_OPEN_RETRY_DELAY_MS);
503
+ }
504
+ throw new ClientError(lastStatus ?? 0, lastBody ?? "Failed to open message stream.");
505
+ }
506
+ async function sleep$1(ms) {
507
+ await new Promise((resolve) => setTimeout(resolve, ms));
508
+ }
509
+
510
+ //#endregion
511
+ //#region src/client/session.ts
512
+ const DELIVER_RETRY_ATTEMPTS = 10;
513
+ const DELIVER_RETRY_DELAY_MS = 200;
514
+ var ClientSession = class {
515
+ #context;
516
+ #state;
517
+ constructor(context, state) {
518
+ this.#context = context;
519
+ this.#state = state;
520
+ }
521
+ get state() {
522
+ return this.#state;
523
+ }
524
+ async send(input) {
525
+ const payload = normalizeSendTurnInput(input);
526
+ const state = this.#state;
527
+ const { continuationToken, sessionId } = await this.#postTurn(payload, state);
528
+ return new MessageResponse({
529
+ continuationToken,
530
+ createStream: () => this.#createEventStream(sessionId, continuationToken, state, payload),
531
+ sessionId
532
+ });
533
+ }
534
+ stream(options) {
535
+ const sessionId = this.#state.sessionId;
536
+ if (!sessionId) throw new Error("Session has no session ID. Send a message first.");
537
+ return this.#streamAndAdvance(sessionId, options);
538
+ }
539
+ async #postTurn(input, session) {
540
+ const routePath = session.sessionId ? createEveContinueSessionRoutePath(session.sessionId) : EVE_CREATE_SESSION_ROUTE_PATH;
541
+ const url = createClientUrl(this.#context.host, routePath);
542
+ const headers = await this.#context.resolveHeaders(input.headers);
543
+ headers.set("content-type", "application/json");
544
+ const body = createHandleMessageBody({
545
+ input,
546
+ outputSchema: normalizeOutputSchemaForRequest(input.outputSchema),
547
+ session
548
+ });
549
+ if (body === null) throw new Error("Session.send requires a non-empty message, inputResponses, or both.");
550
+ const response = await postTurnWithRetry({
551
+ body: JSON.stringify(body),
552
+ headers,
553
+ mustDeliver: (input.inputResponses?.length ?? 0) > 0,
554
+ redirect: this.#context.redirect,
555
+ signal: input.signal,
556
+ url
557
+ });
558
+ const payload = await response.json();
559
+ const sessionId = (typeof payload.sessionId === "string" ? payload.sessionId : void 0) ?? response.headers.get("x-eve-session-id")?.trim() ?? session.sessionId;
560
+ if (!sessionId) throw new Error("Message route did not return a session id.");
561
+ return {
562
+ continuationToken: typeof payload.continuationToken === "string" ? payload.continuationToken : void 0,
563
+ sessionId
564
+ };
565
+ }
566
+ async *#createEventStream(sessionId, continuationToken, initialState, input) {
567
+ const events = [];
568
+ try {
569
+ let currentStreamIndex = initialState.sessionId === sessionId ? initialState.streamIndex : 0;
570
+ let remainingReconnectAttempts = this.#context.maxReconnectAttempts;
571
+ while (true) {
572
+ const body = await this.#openStreamBody(sessionId, currentStreamIndex, input.signal, input.headers);
573
+ let foundBoundary = false;
574
+ try {
575
+ for await (const event of readNdjsonStream(body)) {
576
+ events.push(event);
577
+ currentStreamIndex += 1;
578
+ yield event;
579
+ if (isCurrentTurnBoundaryEvent(event)) {
580
+ foundBoundary = true;
581
+ break;
582
+ }
583
+ }
584
+ } catch (error) {
585
+ if (!isStreamDisconnectError(error)) throw error;
586
+ }
587
+ if (foundBoundary) break;
588
+ if (input.signal?.aborted) break;
589
+ if (remainingReconnectAttempts <= 0) break;
590
+ remainingReconnectAttempts -= 1;
591
+ }
592
+ } finally {
593
+ this.#state = advanceSession({
594
+ continuationToken,
595
+ events,
596
+ preserveCompletedSessions: this.#context.preserveCompletedSessions,
597
+ sessionId,
598
+ session: initialState
599
+ });
600
+ }
601
+ }
602
+ async #openStreamBody(sessionId, startIndex, signal, headers) {
603
+ return await openStreamBody({
604
+ host: this.#context.host,
605
+ resolveHeaders: () => this.#context.resolveHeaders(headers),
606
+ redirect: this.#context.redirect,
607
+ sessionId,
608
+ signal,
609
+ startIndex
610
+ });
611
+ }
612
+ async *#streamAndAdvance(sessionId, options) {
613
+ const initialState = this.#state;
614
+ const streamIndex = options?.startIndex ?? initialState.streamIndex;
615
+ const events = [];
616
+ try {
617
+ for await (const event of openStreamIterable({
618
+ host: this.#context.host,
619
+ maxReconnectAttempts: this.#context.maxReconnectAttempts,
620
+ resolveHeaders: () => this.#context.resolveHeaders(),
621
+ redirect: this.#context.redirect,
622
+ sessionId,
623
+ signal: options?.signal,
624
+ startIndex: streamIndex
625
+ })) {
626
+ events.push(event);
627
+ yield event;
628
+ }
629
+ } finally {
630
+ this.#state = advanceSession({
631
+ continuationToken: initialState.continuationToken,
632
+ events,
633
+ preserveCompletedSessions: this.#context.preserveCompletedSessions,
634
+ session: {
635
+ ...initialState,
636
+ sessionId,
637
+ streamIndex
638
+ },
639
+ sessionId
640
+ });
641
+ }
642
+ }
643
+ };
644
+ async function postTurnWithRetry(input) {
645
+ const attempts = input.mustDeliver ? DELIVER_RETRY_ATTEMPTS : 1;
646
+ let lastStatus;
647
+ let lastBody;
648
+ for (let attempt = 0; attempt < attempts; attempt += 1) {
649
+ const response = await fetch(input.url, {
650
+ body: input.body,
651
+ headers: input.headers,
652
+ method: "POST",
653
+ redirect: input.redirect,
654
+ signal: input.signal ?? null
655
+ });
656
+ if (response.ok) return response;
657
+ lastStatus = response.status;
658
+ lastBody = await response.text();
659
+ if (!isRetryableDeliveryFailure(response.status, lastBody)) throw new ClientError(response.status, lastBody);
660
+ if (attempt < attempts - 1) await sleep(DELIVER_RETRY_DELAY_MS);
661
+ }
662
+ throw new ClientError(lastStatus ?? 0, lastBody ?? "Failed to deliver session turn.");
663
+ }
664
+ function isRetryableDeliveryFailure(status, body) {
665
+ return status === 500 && /target session was not found/i.test(body);
666
+ }
667
+ async function sleep(ms) {
668
+ await new Promise((resolve) => setTimeout(resolve, ms));
669
+ }
670
+ function normalizeSendTurnInput(input) {
671
+ return typeof input === "string" ? { message: input } : input;
672
+ }
673
+ function createHandleMessageBody(input) {
674
+ const body = {};
675
+ if (input.input.message !== void 0) body.message = input.input.message;
676
+ if (input.input.inputResponses !== void 0 && input.input.inputResponses.length > 0) body.inputResponses = input.input.inputResponses;
677
+ if (input.input.clientContext !== void 0) body.clientContext = input.input.clientContext;
678
+ if (input.outputSchema !== void 0) body.outputSchema = input.outputSchema;
679
+ if (input.session.continuationToken !== void 0) body.continuationToken = input.session.continuationToken;
680
+ if (Object.keys(body).length === 0) return null;
681
+ if (input.session.continuationToken === void 0 && body.message === void 0) return null;
682
+ if (input.session.continuationToken !== void 0 && body.message === void 0 && body.inputResponses === void 0) return null;
683
+ return body;
684
+ }
685
+
686
+ //#endregion
687
+ //#region src/client/types.ts
688
+ const VERCEL_TRUSTED_OIDC_IDP_TOKEN_HEADER = "x-vercel-trusted-oidc-idp-token";
689
+
690
+ //#endregion
691
+ //#region src/client/client.ts
692
+ var Client = class {
693
+ #auth;
694
+ #headers;
695
+ #host;
696
+ #maxReconnectAttempts;
697
+ #preserveCompletedSessions;
698
+ #redirect;
699
+ constructor(options) {
700
+ this.#host = options.host;
701
+ this.#auth = options.auth;
702
+ this.#headers = options.headers;
703
+ this.#maxReconnectAttempts = options.maxReconnectAttempts ?? 3;
704
+ this.#preserveCompletedSessions = options.preserveCompletedSessions ?? false;
705
+ this.#redirect = options.redirect;
706
+ }
707
+ async health() {
708
+ const url = createClientUrl(this.#host, EVE_HEALTH_ROUTE_PATH);
709
+ const headers = await this.#resolveHeaders();
710
+ const response = await fetch(url, withRedirectPolicy({ headers }, this.#redirect));
711
+ if (!response.ok) {
712
+ const body = await response.text();
713
+ throw new ClientError(response.status, body);
714
+ }
715
+ return await response.json();
716
+ }
717
+ async info() {
718
+ const response = await this.fetch(EVE_INFO_ROUTE_PATH);
719
+ if (!response.ok) {
720
+ const body = await response.text();
721
+ throw new ClientError(response.status, body);
722
+ }
723
+ const result = AgentInfoResultSchema.safeParse(await response.json());
724
+ if (!result.success) throw new SyntaxError("The server returned an unrecognized response from the Eve agent info route.");
725
+ return result.data;
726
+ }
727
+ async fetch(path, init = {}) {
728
+ const url = createClientUrl(this.#host, path);
729
+ const headers = await this.#resolveHeaders(headersInitToRecord(init.headers));
730
+ return await fetch(url, withRedirectPolicy({
731
+ ...init,
732
+ headers
733
+ }, this.#redirect));
734
+ }
735
+ session(state) {
736
+ let resolved;
737
+ if (typeof state === "string") resolved = {
738
+ continuationToken: state,
739
+ streamIndex: 0
740
+ };
741
+ else if (state) resolved = state;
742
+ else resolved = createInitialSessionState();
743
+ return new ClientSession({
744
+ host: this.#host,
745
+ maxReconnectAttempts: this.#maxReconnectAttempts,
746
+ preserveCompletedSessions: this.#preserveCompletedSessions,
747
+ redirect: this.#redirect,
748
+ resolveHeaders: (perRequest) => this.#resolveHeaders(perRequest)
749
+ }, resolved);
750
+ }
751
+ async #resolveHeaders(perRequest) {
752
+ const headers = new Headers();
753
+ const [baseHeaders, authHeaders] = await Promise.all([resolveHeadersValue(this.#headers), this.#resolveAuthHeaders()]);
754
+ for (const [key, value] of Object.entries(baseHeaders)) headers.set(key, value);
755
+ if (perRequest) for (const [key, value] of Object.entries(perRequest)) headers.set(key, value);
756
+ for (const [key, value] of Object.entries(authHeaders)) headers.set(key, value);
757
+ return headers;
758
+ }
759
+ async #resolveAuthHeaders() {
760
+ const auth = this.#auth;
761
+ if (!auth) return {};
762
+ if ("vercelOidc" in auth) {
763
+ const token = (await resolveTokenValue(auth.vercelOidc.token)).trim();
764
+ if (token.length === 0) return {};
765
+ return {
766
+ authorization: `Bearer ${token}`,
767
+ [VERCEL_TRUSTED_OIDC_IDP_TOKEN_HEADER]: token
768
+ };
769
+ }
770
+ if ("bearer" in auth) {
771
+ const token = (await resolveTokenValue(auth.bearer)).trim();
772
+ return token.length === 0 ? {} : { authorization: `Bearer ${token}` };
773
+ }
774
+ if ("basic" in auth) {
775
+ const password = await resolveTokenValue(auth.basic.password);
776
+ return { authorization: `Basic ${encodeBasicCredentials(auth.basic.username, password)}` };
777
+ }
778
+ return {};
779
+ }
780
+ };
781
+ async function resolveTokenValue(value) {
782
+ return typeof value === "function" ? value() : value;
783
+ }
784
+ async function resolveHeadersValue(value) {
785
+ if (value === void 0) return {};
786
+ return typeof value === "function" ? await value() : value;
787
+ }
788
+ function headersInitToRecord(headers) {
789
+ if (headers === void 0) return {};
790
+ return Object.fromEntries(new Headers(headers).entries());
791
+ }
792
+ function withRedirectPolicy(init, redirect) {
793
+ return redirect === void 0 ? init : {
794
+ ...init,
795
+ redirect
796
+ };
797
+ }
798
+ function encodeBasicCredentials(username, password) {
799
+ const bytes = new TextEncoder().encode(`${username}:${password}`);
800
+ const binaryString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join("");
801
+ return btoa(binaryString);
802
+ }
803
+
804
+ //#endregion
805
+ //#region src/shared/errors.ts
806
+ function toErrorMessage(error) {
807
+ if (error instanceof Error) return error.message;
808
+ if (typeof error === "string") return error;
809
+ if (error === null || error === void 0) return String(error);
810
+ if (isObject(error)) {
811
+ if (typeof error.message === "string" && error.message.length > 0) return error.message;
812
+ return safeJsonStringify(error);
813
+ }
814
+ return String(error);
815
+ }
816
+ function toError(raw) {
817
+ if (raw instanceof Error) return raw;
818
+ const error = new Error(toErrorMessage(raw));
819
+ if (!isObject(raw)) return error;
820
+ if (typeof raw.name === "string" && raw.name.length > 0) error.name = raw.name;
821
+ if (typeof raw.stack === "string" && raw.stack.length > 0) error.stack = raw.stack;
822
+ if ("cause" in raw && raw.cause !== void 0 && raw.cause !== raw) error.cause = raw.cause;
823
+ return error;
824
+ }
825
+ function safeJsonStringify(value) {
826
+ try {
827
+ return JSON.stringify(value) ?? String(value);
828
+ } catch {
829
+ return String(value);
830
+ }
831
+ }
832
+
833
+ //#endregion
834
+ //#region src/client/eve-agent-store.ts
835
+ var EveAgentStore = class {
836
+ #createSession;
837
+ #optimistic;
838
+ #reducer;
839
+ #subscribers = /* @__PURE__ */ new Set();
840
+ #abortController;
841
+ #callbacks = {};
842
+ #data;
843
+ #error;
844
+ #events;
845
+ #operationId = 0;
846
+ #pendingMessageSubmission;
847
+ #projectionEvents;
848
+ #session;
849
+ #snapshot;
850
+ #status = "ready";
851
+ constructor(init) {
852
+ this.#createSession = init.session ? void 0 : () => new Client({
853
+ auth: init.auth,
854
+ headers: init.headers,
855
+ host: init.host ?? "",
856
+ maxReconnectAttempts: init.maxReconnectAttempts
857
+ }).session(init.initialSession);
858
+ this.#events = [...init.initialEvents ?? []];
859
+ this.#projectionEvents = [...this.#events];
860
+ this.#optimistic = init.optimistic ?? true;
861
+ this.#reducer = init.reducer;
862
+ this.#session = init.session ?? this.#createOwnedSession();
863
+ this.#data = this.#reduceProjectionEvents(this.#projectionEvents);
864
+ this.#snapshot = this.#createSnapshot();
865
+ }
866
+ get snapshot() {
867
+ return this.#snapshot;
868
+ }
869
+ setCallbacks(callbacks) {
870
+ this.#callbacks = callbacks;
871
+ }
872
+ subscribe(callback) {
873
+ this.#subscribers.add(callback);
874
+ return () => {
875
+ this.#subscribers.delete(callback);
876
+ };
877
+ }
878
+ async send(input) {
879
+ if (this.#status === "streaming" || this.#status === "submitted") throw new Error("eve session is already processing a turn.");
880
+ const operationId = this.#startOperation();
881
+ const abortController = new AbortController();
882
+ this.#abortController = abortController;
883
+ this.#error = void 0;
884
+ this.#status = "submitted";
885
+ this.#publish();
886
+ try {
887
+ const preparedInput = await this.#callbacks.prepareSend?.(input) ?? input;
888
+ if (!this.#isCurrentOperation(operationId)) return;
889
+ this.#projectOptimisticMessage(preparedInput);
890
+ this.#projectInputResponses(preparedInput);
891
+ this.#publish();
892
+ const response = await this.#session.send({
893
+ ...preparedInput,
894
+ signal: createAbortSignal(preparedInput.signal, abortController.signal)
895
+ });
896
+ let sawEvent = false;
897
+ for await (const event of response) {
898
+ if (!this.#isCurrentOperation(operationId)) return;
899
+ if (!sawEvent) {
900
+ sawEvent = true;
901
+ this.#status = "streaming";
902
+ }
903
+ this.#events = [...this.#events, event];
904
+ this.#applyServerEvent(event);
905
+ this.#callbacks.onEvent?.(event);
906
+ this.#applyTerminalStreamFailure(event);
907
+ this.#publish();
908
+ }
909
+ if (!this.#isCurrentOperation(operationId)) return;
910
+ this.#status = this.#error === void 0 ? "ready" : "error";
911
+ } catch (error) {
912
+ if (!this.#isCurrentOperation(operationId)) return;
913
+ if (isAbortError(error)) {
914
+ this.#status = "ready";
915
+ this.#failPendingMessageSubmission(toError(error));
916
+ } else {
917
+ this.#error = toError(error);
918
+ this.#status = "error";
919
+ this.#failPendingMessageSubmission(this.#error);
920
+ this.#callbacks.onError?.(this.#error);
921
+ }
922
+ } finally {
923
+ if (this.#isCurrentOperation(operationId)) {
924
+ this.#abortController = void 0;
925
+ this.#callbacks.onSessionChange?.(this.#session.state);
926
+ this.#publish();
927
+ this.#callbacks.onFinish?.(this.#snapshot);
928
+ }
929
+ }
930
+ }
931
+ stop() {
932
+ this.#abortController?.abort();
933
+ }
934
+ reset() {
935
+ this.#invalidateOperation();
936
+ this.stop();
937
+ this.#abortController = void 0;
938
+ this.#session = this.#createSession?.() ?? this.#session;
939
+ this.#events = [];
940
+ this.#pendingMessageSubmission = void 0;
941
+ this.#projectionEvents = [];
942
+ this.#data = this.#reducer.initial();
943
+ this.#error = void 0;
944
+ this.#status = "ready";
945
+ this.#callbacks.onSessionChange?.(this.#session.state);
946
+ this.#publish();
947
+ }
948
+ #createOwnedSession() {
949
+ if (!this.#createSession) throw new Error("Cannot create an owned eve session from an external session.");
950
+ return this.#createSession();
951
+ }
952
+ #startOperation() {
953
+ this.#operationId += 1;
954
+ return this.#operationId;
955
+ }
956
+ #invalidateOperation() {
957
+ this.#operationId += 1;
958
+ }
959
+ #isCurrentOperation(operationId) {
960
+ return this.#operationId === operationId;
961
+ }
962
+ #projectOptimisticMessage(input) {
963
+ if (!this.#optimistic || input.message === void 0) return;
964
+ const id = createSubmissionId();
965
+ const pending = {
966
+ createdAt: Date.now(),
967
+ id,
968
+ message: summarizeUserContent(input.message)
969
+ };
970
+ this.#pendingMessageSubmission = pending;
971
+ this.#appendProjectionEvent({
972
+ data: {
973
+ createdAt: pending.createdAt,
974
+ message: pending.message,
975
+ submissionId: pending.id
976
+ },
977
+ type: "client.message.submitted"
978
+ });
979
+ }
980
+ #projectInputResponses(input) {
981
+ if (input.inputResponses === void 0 || input.inputResponses.length === 0) return;
982
+ this.#appendProjectionEvent({
983
+ data: {
984
+ createdAt: Date.now(),
985
+ responses: input.inputResponses
986
+ },
987
+ type: "client.input.responded"
988
+ });
989
+ }
990
+ #applyServerEvent(event) {
991
+ if (event.type === "message.received" && this.#pendingMessageSubmission !== void 0) {
992
+ const submissionId = this.#pendingMessageSubmission.id;
993
+ this.#pendingMessageSubmission = void 0;
994
+ this.#replaceProjectionEvent((candidate) => candidate.type === "client.message.submitted" && candidate.data.submissionId === submissionId, event);
995
+ return;
996
+ }
997
+ this.#appendProjectionEvent(event);
998
+ }
999
+ #applyTerminalStreamFailure(event) {
1000
+ const error = toTerminalStreamFailureError(event);
1001
+ if (error === void 0) return;
1002
+ this.#status = "error";
1003
+ this.#failPendingMessageSubmission(error);
1004
+ if (this.#error === void 0) {
1005
+ this.#error = error;
1006
+ this.#callbacks.onError?.(error);
1007
+ }
1008
+ }
1009
+ #failPendingMessageSubmission(error) {
1010
+ const pending = this.#pendingMessageSubmission;
1011
+ if (pending === void 0) return;
1012
+ this.#pendingMessageSubmission = void 0;
1013
+ this.#replaceProjectionEvent((event) => event.type === "client.message.submitted" && event.data.submissionId === pending.id, {
1014
+ data: {
1015
+ createdAt: pending.createdAt,
1016
+ error: { message: error.message },
1017
+ message: pending.message,
1018
+ submissionId: pending.id
1019
+ },
1020
+ type: "client.message.failed"
1021
+ });
1022
+ }
1023
+ #appendProjectionEvent(event) {
1024
+ this.#projectionEvents = [...this.#projectionEvents, event];
1025
+ this.#data = this.#reducer.reduce(this.#data, event);
1026
+ }
1027
+ #replaceProjectionEvent(predicate, replacement) {
1028
+ let replaced = false;
1029
+ this.#projectionEvents = this.#projectionEvents.map((event) => {
1030
+ if (!replaced && predicate(event)) {
1031
+ replaced = true;
1032
+ return replacement;
1033
+ }
1034
+ return event;
1035
+ });
1036
+ if (!replaced) this.#projectionEvents = [...this.#projectionEvents, replacement];
1037
+ this.#data = this.#reduceProjectionEvents(this.#projectionEvents);
1038
+ }
1039
+ #reduceProjectionEvents(events) {
1040
+ let data = this.#reducer.initial();
1041
+ for (const event of events) data = this.#reducer.reduce(data, event);
1042
+ return data;
1043
+ }
1044
+ #createSnapshot() {
1045
+ return {
1046
+ data: this.#data,
1047
+ error: this.#error,
1048
+ events: this.#events,
1049
+ session: this.#session.state,
1050
+ status: this.#status
1051
+ };
1052
+ }
1053
+ #publish() {
1054
+ this.#snapshot = this.#createSnapshot();
1055
+ for (const subscriber of this.#subscribers) subscriber();
1056
+ }
1057
+ };
1058
+ let submissionSequence = 0;
1059
+ function createSubmissionId() {
1060
+ const randomUUID = globalThis.crypto?.randomUUID;
1061
+ if (randomUUID !== void 0) return randomUUID.call(globalThis.crypto);
1062
+ submissionSequence += 1;
1063
+ return `submission_${submissionSequence.toString()}`;
1064
+ }
1065
+ function createAbortSignal(first, second) {
1066
+ return first ? AbortSignal.any([first, second]) : second;
1067
+ }
1068
+ function summarizeUserContent(message) {
1069
+ if (typeof message === "string") return message;
1070
+ const parts = [];
1071
+ for (const part of message) {
1072
+ if (part.type === "text") {
1073
+ parts.push(part.text);
1074
+ continue;
1075
+ }
1076
+ if (part.type === "file") parts.push(part.filename ? `[file: ${part.filename}]` : "[file]");
1077
+ }
1078
+ return parts.join("\n");
1079
+ }
1080
+ function isAbortError(error) {
1081
+ return error instanceof Error && error.name === "AbortError";
1082
+ }
1083
+ function toTerminalStreamFailureError(event) {
1084
+ if (event.type !== "session.failed") return;
1085
+ const error = new Error(event.data.message);
1086
+ error.name = event.data.code;
1087
+ return error;
1088
+ }
1089
+
1090
+ //#endregion
1091
+ //#region src/client/message-reducer.ts
1092
+ function defaultMessageReducer() {
1093
+ return {
1094
+ initial() {
1095
+ return { messages: [] };
1096
+ },
1097
+ reduce(data, event) {
1098
+ return reduceMessageData(data, event);
1099
+ }
1100
+ };
1101
+ }
1102
+ function reduceMessageData(data, event) {
1103
+ switch (event.type) {
1104
+ case "client.message.submitted": return upsertMessage(data, {
1105
+ id: optimisticUserMessageId(event.data.submissionId),
1106
+ metadata: {
1107
+ optimistic: true,
1108
+ status: "submitted"
1109
+ },
1110
+ parts: [{
1111
+ type: "text",
1112
+ text: event.data.message
1113
+ }],
1114
+ role: "user"
1115
+ });
1116
+ case "client.message.failed": return upsertMessage(data, {
1117
+ id: optimisticUserMessageId(event.data.submissionId),
1118
+ metadata: {
1119
+ optimistic: true,
1120
+ status: "failed"
1121
+ },
1122
+ parts: [{
1123
+ type: "text",
1124
+ text: event.data.message
1125
+ }],
1126
+ role: "user"
1127
+ });
1128
+ case "client.input.responded": {
1129
+ let next = data;
1130
+ for (const response of event.data.responses) next = respondToInputRequest(next, response);
1131
+ return next;
1132
+ }
1133
+ case "message.received": return upsertMessage(data, {
1134
+ id: `${event.data.turnId}:user`,
1135
+ metadata: {
1136
+ status: "complete",
1137
+ turnId: event.data.turnId
1138
+ },
1139
+ parts: [{
1140
+ type: "text",
1141
+ text: event.data.message,
1142
+ state: "done"
1143
+ }],
1144
+ role: "user"
1145
+ });
1146
+ case "step.started": return updateAssistantMessage(data, event.data.turnId, (message) => ensureStepStartPart(message, event.data.stepIndex));
1147
+ case "reasoning.appended": return updateAssistantMessage(data, event.data.turnId, (message) => upsertPart(ensureStepStartPart(message, event.data.stepIndex), {
1148
+ state: "streaming",
1149
+ stepIndex: event.data.stepIndex,
1150
+ text: event.data.reasoningSoFar,
1151
+ type: "reasoning"
1152
+ }));
1153
+ case "reasoning.completed": return updateAssistantMessage(data, event.data.turnId, (message) => upsertPart(ensureStepStartPart(message, event.data.stepIndex), {
1154
+ state: "done",
1155
+ stepIndex: event.data.stepIndex,
1156
+ text: event.data.reasoning,
1157
+ type: "reasoning"
1158
+ }));
1159
+ case "actions.requested": {
1160
+ let next = data;
1161
+ for (const action of event.data.actions) {
1162
+ const descriptor = normalizeActionRequest(action);
1163
+ next = updateAssistantMessage(next, event.data.turnId, (message) => upsertPart(ensureStepStartPart(message, event.data.stepIndex), {
1164
+ input: "input" in action ? action.input : void 0,
1165
+ state: "input-available",
1166
+ stepIndex: event.data.stepIndex,
1167
+ toolCallId: action.callId,
1168
+ toolMetadata: createToolMetadata(descriptor),
1169
+ toolName: descriptor.toolName,
1170
+ type: "dynamic-tool"
1171
+ }));
1172
+ }
1173
+ return next;
1174
+ }
1175
+ case "input.requested": {
1176
+ let next = data;
1177
+ for (const request of event.data.requests) {
1178
+ const descriptor = normalizeActionRequest(request.action);
1179
+ next = updateAssistantMessage(next, event.data.turnId, (message) => upsertPart(ensureStepStartPart(message, event.data.stepIndex), {
1180
+ approval: { id: request.requestId },
1181
+ input: request.action.input,
1182
+ state: "approval-requested",
1183
+ stepIndex: event.data.stepIndex,
1184
+ toolCallId: request.action.callId,
1185
+ toolMetadata: createToolMetadata(descriptor, { inputRequest: toMessageInputRequest(request) }),
1186
+ toolName: descriptor.toolName,
1187
+ type: "dynamic-tool"
1188
+ }));
1189
+ }
1190
+ return next;
1191
+ }
1192
+ case "action.result": {
1193
+ const descriptor = normalizeActionResult(event.data.result);
1194
+ const existing = findToolPart(data, event.data.result.callId);
1195
+ const denied = event.data.error?.code === "TOOL_EXECUTION_DENIED";
1196
+ const failed = event.data.status === "failed" && !denied;
1197
+ const approvalId = existing?.approval?.id ?? event.data.result.callId;
1198
+ const toolMetadata = mergeToolMetadata(existing?.toolMetadata, createToolMetadata(descriptor));
1199
+ const resultPartBase = {
1200
+ input: existing?.input,
1201
+ stepIndex: event.data.stepIndex,
1202
+ toolCallId: event.data.result.callId,
1203
+ toolMetadata,
1204
+ toolName: existing?.toolName ?? descriptor.toolName,
1205
+ type: "dynamic-tool"
1206
+ };
1207
+ let nextPart;
1208
+ if (denied) nextPart = {
1209
+ ...resultPartBase,
1210
+ approval: {
1211
+ approved: false,
1212
+ id: approvalId,
1213
+ reason: event.data.error?.message
1214
+ },
1215
+ state: "output-denied"
1216
+ };
1217
+ else if (failed) nextPart = {
1218
+ ...resultPartBase,
1219
+ approval: approvedApproval(existing),
1220
+ errorText: event.data.error?.message ?? stringifyUnknown(event.data.result.output),
1221
+ state: "output-error"
1222
+ };
1223
+ else nextPart = {
1224
+ ...resultPartBase,
1225
+ approval: approvedApproval(existing),
1226
+ output: event.data.result.output,
1227
+ state: "output-available"
1228
+ };
1229
+ if (existing !== void 0) return updateToolPart(data, event.data.result.callId, nextPart);
1230
+ return updateAssistantMessage(data, event.data.turnId, (message) => upsertPart(ensureStepStartPart(message, event.data.stepIndex), nextPart));
1231
+ }
1232
+ case "message.appended": return updateAssistantMessage(data, event.data.turnId, (message) => upsertPart(ensureStepStartPart(message, event.data.stepIndex), {
1233
+ state: "streaming",
1234
+ stepIndex: event.data.stepIndex,
1235
+ text: event.data.messageSoFar,
1236
+ type: "text"
1237
+ }));
1238
+ case "message.completed": return updateAssistantMessage(data, event.data.turnId, (message) => {
1239
+ if (event.data.message === null) return completeExistingTextPart(message);
1240
+ return upsertPart(ensureStepStartPart(message, event.data.stepIndex), {
1241
+ state: "done",
1242
+ stepIndex: event.data.stepIndex,
1243
+ text: event.data.message,
1244
+ type: "text"
1245
+ });
1246
+ });
1247
+ case "result.completed": return updateAssistantMetadata(data, event.data.turnId, { result: event.data.result });
1248
+ case "turn.completed": return updateAssistantMetadata(data, event.data.turnId, { status: "complete" });
1249
+ case "turn.failed":
1250
+ case "session.failed": return data;
1251
+ default: return data;
1252
+ }
1253
+ }
1254
+ function respondToInputRequest(data, response) {
1255
+ const existing = findToolPartByApprovalId(data, response.requestId);
1256
+ if (!existing) return data;
1257
+ const approval = { id: response.requestId };
1258
+ if (response.text !== void 0) approval.reason = response.text;
1259
+ return updateToolPart(data, existing.toolCallId, {
1260
+ approval,
1261
+ input: existing.input,
1262
+ state: "approval-responded",
1263
+ stepIndex: existing.stepIndex,
1264
+ toolCallId: existing.toolCallId,
1265
+ toolMetadata: mergeToolMetadata(existing.toolMetadata, { eve: {
1266
+ inputResponse: response,
1267
+ kind: existing.toolMetadata?.eve?.kind ?? "unknown",
1268
+ name: existing.toolMetadata?.eve?.name ?? existing.toolName
1269
+ } }),
1270
+ toolName: existing.toolName,
1271
+ type: "dynamic-tool"
1272
+ });
1273
+ }
1274
+ function updateAssistantMessage(data, turnId, update) {
1275
+ return upsertMessage(data, update(data.messages.find((message) => message.role === "assistant" && message.metadata?.turnId === turnId) ?? createAssistantMessage(turnId)));
1276
+ }
1277
+ function updateAssistantMetadata(data, turnId, metadata) {
1278
+ return updateAssistantMessage(data, turnId, (message) => ({
1279
+ ...message,
1280
+ metadata: {
1281
+ ...message.metadata,
1282
+ ...metadata
1283
+ }
1284
+ }));
1285
+ }
1286
+ function createAssistantMessage(turnId) {
1287
+ return {
1288
+ id: `${turnId}:assistant`,
1289
+ metadata: {
1290
+ status: "streaming",
1291
+ turnId
1292
+ },
1293
+ parts: [],
1294
+ role: "assistant"
1295
+ };
1296
+ }
1297
+ function ensureStepStartPart(message, stepIndex) {
1298
+ const stepStartCount = message.parts.filter((part) => part.type === "step-start").length;
1299
+ if (stepStartCount > stepIndex) return message;
1300
+ const missingCount = stepIndex - stepStartCount + 1;
1301
+ return {
1302
+ ...message,
1303
+ parts: [...message.parts, ...Array.from({ length: missingCount }, () => ({ type: "step-start" }))]
1304
+ };
1305
+ }
1306
+ function upsertPart(message, next) {
1307
+ const index = message.parts.findIndex((part) => partKey(part) === partKey(next));
1308
+ const parts = index === -1 ? [...message.parts, next] : [
1309
+ ...message.parts.slice(0, index),
1310
+ next,
1311
+ ...message.parts.slice(index + 1)
1312
+ ];
1313
+ return {
1314
+ ...message,
1315
+ metadata: {
1316
+ ...message.metadata,
1317
+ status: next.type === "text" && next.state === "done" ? "complete" : "streaming"
1318
+ },
1319
+ parts
1320
+ };
1321
+ }
1322
+ function completeExistingTextPart(message) {
1323
+ const index = findLastIndex(message.parts, (part) => part.type === "text");
1324
+ if (index === -1) return message;
1325
+ const existing = message.parts[index];
1326
+ if (existing?.type !== "text") return message;
1327
+ return {
1328
+ ...message,
1329
+ metadata: {
1330
+ ...message.metadata,
1331
+ status: "complete"
1332
+ },
1333
+ parts: [
1334
+ ...message.parts.slice(0, index),
1335
+ {
1336
+ ...existing,
1337
+ state: "done"
1338
+ },
1339
+ ...message.parts.slice(index + 1)
1340
+ ]
1341
+ };
1342
+ }
1343
+ function updateToolPart(data, toolCallId, next) {
1344
+ const message = data.messages.find((candidate) => candidate.role === "assistant" && candidate.parts.some((part) => part.type === "dynamic-tool" && part.toolCallId === toolCallId));
1345
+ if (!message) return data;
1346
+ return upsertMessage(data, upsertPart(message, next));
1347
+ }
1348
+ function findToolPart(data, toolCallId) {
1349
+ for (const message of data.messages) for (const part of message.parts) if (part.type === "dynamic-tool" && part.toolCallId === toolCallId) return part;
1350
+ }
1351
+ function findToolPartByApprovalId(data, approvalId) {
1352
+ for (const message of data.messages) for (const part of message.parts) if (part.type === "dynamic-tool" && part.approval?.id === approvalId) return part;
1353
+ }
1354
+ function partKey(part) {
1355
+ switch (part.type) {
1356
+ case "text": return `text:${part.stepIndex ?? 0}`;
1357
+ case "reasoning": return `reasoning:${part.stepIndex ?? 0}`;
1358
+ case "step-start": return "step-start";
1359
+ case "dynamic-tool": return `dynamic-tool:${part.toolCallId}`;
1360
+ }
1361
+ }
1362
+ function upsertMessage(data, next) {
1363
+ const index = data.messages.findIndex((message) => message.id === next.id);
1364
+ if (index === -1) return { messages: [...data.messages, next] };
1365
+ return { messages: [
1366
+ ...data.messages.slice(0, index),
1367
+ next,
1368
+ ...data.messages.slice(index + 1)
1369
+ ] };
1370
+ }
1371
+ function toMessageInputRequest(request) {
1372
+ return {
1373
+ allowFreeform: request.allowFreeform,
1374
+ display: request.display,
1375
+ options: request.options,
1376
+ prompt: request.prompt,
1377
+ requestId: request.requestId
1378
+ };
1379
+ }
1380
+ function createToolMetadata(descriptor, extra) {
1381
+ return { eve: {
1382
+ inputRequest: extra?.inputRequest,
1383
+ kind: descriptor.kind,
1384
+ name: descriptor.name
1385
+ } };
1386
+ }
1387
+ function mergeToolMetadata(current, next) {
1388
+ const kind = next.eve?.kind ?? current?.eve?.kind ?? "unknown";
1389
+ const name = next.eve?.name ?? current?.eve?.name ?? "unknown";
1390
+ return { eve: {
1391
+ ...current?.eve,
1392
+ ...next.eve,
1393
+ inputRequest: next.eve?.inputRequest ?? current?.eve?.inputRequest,
1394
+ inputResponse: next.eve?.inputResponse ?? current?.eve?.inputResponse,
1395
+ kind,
1396
+ name
1397
+ } };
1398
+ }
1399
+ function approvedApproval(part) {
1400
+ if (!part?.approval?.id) return;
1401
+ return {
1402
+ approved: true,
1403
+ id: part.approval.id,
1404
+ isAutomatic: part.approval.isAutomatic,
1405
+ reason: part.approval.reason
1406
+ };
1407
+ }
1408
+ function normalizeActionRequest(action) {
1409
+ switch (action.kind) {
1410
+ case "load-skill": return {
1411
+ kind: "load-skill",
1412
+ name: "load_skill",
1413
+ toolName: "eve:load-skill"
1414
+ };
1415
+ case "tool-call": return {
1416
+ kind: "tool-call",
1417
+ name: action.toolName,
1418
+ toolName: action.toolName
1419
+ };
1420
+ case "subagent-call": return {
1421
+ kind: "subagent-call",
1422
+ name: action.subagentName,
1423
+ toolName: `eve:subagent:${action.subagentName}`
1424
+ };
1425
+ case "remote-agent-call": return {
1426
+ kind: "subagent-call",
1427
+ name: action.remoteAgentName,
1428
+ toolName: `eve:subagent:${action.remoteAgentName}`
1429
+ };
1430
+ }
1431
+ }
1432
+ function normalizeActionResult(result) {
1433
+ switch (result.kind) {
1434
+ case "load-skill-result": return {
1435
+ kind: "load-skill",
1436
+ name: result.name ?? "load_skill",
1437
+ toolName: "eve:load-skill"
1438
+ };
1439
+ case "tool-result": return {
1440
+ kind: "tool-call",
1441
+ name: result.toolName,
1442
+ toolName: result.toolName
1443
+ };
1444
+ case "subagent-result": return {
1445
+ kind: "subagent-call",
1446
+ name: result.subagentName,
1447
+ toolName: `eve:subagent:${result.subagentName}`
1448
+ };
1449
+ }
1450
+ }
1451
+ function optimisticUserMessageId(submissionId) {
1452
+ return `optimistic:${submissionId}:user`;
1453
+ }
1454
+ function stringifyUnknown(value) {
1455
+ if (typeof value === "string") return value;
1456
+ try {
1457
+ return JSON.stringify(value);
1458
+ } catch {
1459
+ return "Action failed.";
1460
+ }
1461
+ }
1462
+ function findLastIndex(items, predicate) {
1463
+ for (let index = items.length - 1; index >= 0; index -= 1) if (predicate(items[index])) return index;
1464
+ return -1;
1465
+ }
1466
+
1467
+ //#endregion
1468
+ //#region src/vue/use-eve-agent.ts
1469
+ function useEveAgent(options = {}) {
1470
+ const reducer = options.reducer ?? defaultMessageReducer();
1471
+ const store = new EveAgentStore({
1472
+ auth: options.auth,
1473
+ headers: options.headers,
1474
+ host: options.host,
1475
+ initialEvents: options.initialEvents,
1476
+ initialSession: options.initialSession,
1477
+ maxReconnectAttempts: options.maxReconnectAttempts,
1478
+ optimistic: options.optimistic,
1479
+ reducer,
1480
+ session: options.session
1481
+ });
1482
+ store.setCallbacks({
1483
+ onError: options.onError,
1484
+ onEvent: options.onEvent,
1485
+ onFinish: options.onFinish,
1486
+ onSessionChange: options.onSessionChange,
1487
+ prepareSend: options.prepareSend
1488
+ });
1489
+ const snapshot = shallowRef(store.snapshot);
1490
+ if ("window" in globalThis) {
1491
+ const unsubscribe = store.subscribe(() => {
1492
+ snapshot.value = store.snapshot;
1493
+ });
1494
+ onScopeDispose(() => {
1495
+ unsubscribe();
1496
+ store.stop();
1497
+ });
1498
+ }
1499
+ return {
1500
+ data: computed(() => snapshot.value.data),
1501
+ error: computed(() => snapshot.value.error),
1502
+ events: computed(() => snapshot.value.events),
1503
+ reset: () => store.reset(),
1504
+ send: (input) => store.send(input),
1505
+ session: computed(() => snapshot.value.session),
1506
+ status: computed(() => snapshot.value.status),
1507
+ stop: () => store.stop()
1508
+ };
1509
+ }
1510
+
1511
+ //#endregion
1512
+ export { defaultMessageReducer as n, useEveAgent as t };