eve 0.13.1 → 0.13.3

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