@better-agent/client 0.1.0-canary.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,643 @@
1
+ import { a as toModelMessages, i as fromModelMessages, n as createAgentChatController, o as getEventErrorMessage, r as fromConversationItems, s as toAgentClientError } from "./controller-Cf_JhTdJ.mjs";
2
+ import { Events } from "@better-agent/core/events";
3
+ import { BetterAgentError } from "@better-agent/shared/errors";
4
+ import { pruneInputByCapabilities } from "@better-agent/core";
5
+
6
+ //#region src/core/sse.ts
7
+ const isEventType = (value) => Object.values(Events).includes(value);
8
+ const resetFrame = () => ({ data: "" });
9
+ const getSseErrorMessage = (data) => {
10
+ try {
11
+ const parsed = JSON.parse(data);
12
+ if (typeof parsed.message === "string" && parsed.message.trim().length > 0) return parsed.message;
13
+ } catch {}
14
+ return data.trim().length > 0 ? data.trim() : "Stream failed";
15
+ };
16
+ const parseFrame = (frame, options) => {
17
+ if (!frame.data) return null;
18
+ const data = frame.data.replace(/\n$/, "");
19
+ if (frame.eventName === "error") throw new Error(getSseErrorMessage(data));
20
+ try {
21
+ const parsed = JSON.parse(data);
22
+ if (!(parsed && typeof parsed === "object" && typeof parsed.type === "string")) return null;
23
+ if (!isEventType(parsed.type)) return null;
24
+ if (typeof frame.id === "number") {
25
+ parsed.seq = frame.id;
26
+ options.onId?.(frame.id);
27
+ }
28
+ return parsed;
29
+ } catch {
30
+ return null;
31
+ }
32
+ };
33
+ async function* parseSse(body, options = {}) {
34
+ const reader = body.getReader();
35
+ const decoder = new TextDecoder();
36
+ let buffer = "";
37
+ let frame = resetFrame();
38
+ while (true) {
39
+ const { done, value } = await reader.read();
40
+ if (done) break;
41
+ buffer += decoder.decode(value, { stream: true });
42
+ for (;;) {
43
+ const nl = buffer.indexOf("\n");
44
+ if (nl < 0) break;
45
+ const line = buffer.slice(0, nl).replace(/\r$/, "");
46
+ buffer = buffer.slice(nl + 1);
47
+ if (line === "") {
48
+ const event = parseFrame(frame, options);
49
+ frame = resetFrame();
50
+ if (event) yield event;
51
+ continue;
52
+ }
53
+ if (line.startsWith("event:")) {
54
+ frame.eventName = line.slice(6).trim();
55
+ continue;
56
+ }
57
+ if (line.startsWith("id:")) {
58
+ const idValue = Number(line.slice(3).trim());
59
+ frame.id = Number.isFinite(idValue) ? idValue : void 0;
60
+ continue;
61
+ }
62
+ if (line.startsWith("data:")) frame.data += `${line.slice(5).trim()}\n`;
63
+ }
64
+ }
65
+ const finalEvent = parseFrame(frame, options);
66
+ if (finalEvent) yield finalEvent;
67
+ }
68
+
69
+ //#endregion
70
+ //#region src/core/client/errors.ts
71
+ const tryParseJson = (bodyText) => {
72
+ try {
73
+ return JSON.parse(bodyText);
74
+ } catch {
75
+ return null;
76
+ }
77
+ };
78
+ const parseErrorBody = (bodyText) => {
79
+ let errorCodeFromBody;
80
+ let errorMessageFromBody;
81
+ let errorTitleFromBody;
82
+ let errorStatusFromBody;
83
+ let retryableFromBody;
84
+ let traceIdFromBody;
85
+ let issuesFromBody;
86
+ let contextFromBody;
87
+ let traceFromBody;
88
+ if (bodyText.length > 0) {
89
+ const parsed = tryParseJson(bodyText);
90
+ if (parsed) {
91
+ if (typeof parsed.code === "string") errorCodeFromBody = parsed.code;
92
+ else if (typeof parsed.error === "string") errorCodeFromBody = parsed.error;
93
+ if (typeof parsed.message === "string") errorMessageFromBody = parsed.message;
94
+ else if (typeof parsed.detail === "string") errorMessageFromBody = parsed.detail;
95
+ if (typeof parsed.title === "string") errorTitleFromBody = parsed.title;
96
+ if (typeof parsed.status === "number") errorStatusFromBody = parsed.status;
97
+ if (typeof parsed.retryable === "boolean") retryableFromBody = parsed.retryable;
98
+ if (typeof parsed.traceId === "string") traceIdFromBody = parsed.traceId;
99
+ if (Array.isArray(parsed.issues)) issuesFromBody = parsed.issues;
100
+ if (typeof parsed.context === "object" && parsed.context !== null) contextFromBody = parsed.context;
101
+ if (Array.isArray(parsed.trace)) traceFromBody = parsed.trace;
102
+ }
103
+ }
104
+ return {
105
+ errorCodeFromBody,
106
+ errorMessageFromBody,
107
+ errorTitleFromBody,
108
+ errorStatusFromBody,
109
+ retryableFromBody,
110
+ traceIdFromBody,
111
+ issuesFromBody,
112
+ contextFromBody,
113
+ traceFromBody
114
+ };
115
+ };
116
+ const getContentType = (response) => response.headers.get("content-type")?.toLowerCase() ?? "";
117
+ const isHtmlResponse = (response) => getContentType(response).includes("text/html");
118
+ const truncateForContext = (value, maxLength = 300) => value.length <= maxLength ? value : `${value.slice(0, maxLength)}...`;
119
+ const throwRequestError = async (params) => {
120
+ const bodyText = (await params.response.text().catch(() => "")).trim();
121
+ const { errorCodeFromBody, errorMessageFromBody, errorTitleFromBody, errorStatusFromBody, retryableFromBody, traceIdFromBody, issuesFromBody, contextFromBody, traceFromBody } = parseErrorBody(bodyText);
122
+ const fallbackDetail = isHtmlResponse(params.response) ? "Server returned an HTML error page. This usually means a framework or dev-server failure before the API handler ran." : params.response.statusText || "Unknown error";
123
+ const detail = errorMessageFromBody ?? (bodyText.length > 0 && !isHtmlResponse(params.response) ? bodyText : void 0) ?? fallbackDetail;
124
+ throw Object.assign(BetterAgentError.fromCode(errorCodeFromBody ?? (params.response.status >= 500 || params.response.status === 429 ? "UPSTREAM_FAILED" : "BAD_REQUEST"), detail, {
125
+ title: errorTitleFromBody,
126
+ status: errorStatusFromBody ?? params.response.status,
127
+ retryable: retryableFromBody,
128
+ traceId: traceIdFromBody,
129
+ context: {
130
+ ...params.context,
131
+ operation: params.operation,
132
+ status: params.response.status,
133
+ ...contextFromBody ?? {},
134
+ error: errorCodeFromBody,
135
+ issues: issuesFromBody,
136
+ ...isHtmlResponse(params.response) && bodyText.length > 0 ? {
137
+ responseContentType: getContentType(params.response),
138
+ responseBodySnippet: truncateForContext(bodyText)
139
+ } : {}
140
+ },
141
+ trace: [...traceFromBody ?? [], { at: params.at }]
142
+ }), issuesFromBody ? { issues: issuesFromBody } : {});
143
+ };
144
+
145
+ //#endregion
146
+ //#region src/core/client/request.ts
147
+ const mergeHeaders = (...parts) => {
148
+ const merged = new Headers();
149
+ for (const part of parts) {
150
+ if (!part) continue;
151
+ new Headers(part).forEach((value, key) => merged.set(key, value));
152
+ }
153
+ return merged;
154
+ };
155
+ const prepareRequest = async (advanced, context) => {
156
+ if (!advanced?.prepareRequest) return {
157
+ url: context.url,
158
+ method: context.method,
159
+ headers: context.headers,
160
+ body: context.body
161
+ };
162
+ const prepared = await advanced.prepareRequest(context);
163
+ if (!prepared) return {
164
+ url: context.url,
165
+ method: context.method,
166
+ headers: context.headers,
167
+ body: context.body
168
+ };
169
+ return {
170
+ url: prepared.url ?? context.url,
171
+ method: prepared.method ?? context.method,
172
+ headers: prepared.headers ?? context.headers,
173
+ ...prepared.body !== void 0 ? { body: prepared.body } : context.body !== void 0 ? { body: context.body } : {}
174
+ };
175
+ };
176
+
177
+ //#endregion
178
+ //#region src/core/client/tool-submission.ts
179
+ const sleep = async (ms) => {
180
+ await new Promise((resolve) => setTimeout(resolve, ms));
181
+ };
182
+ const createToolSubmissionHandlers = (deps) => {
183
+ const doFetch = deps.doFetch;
184
+ const authHeaders = deps.secret ? { authorization: `Bearer ${deps.secret}` } : void 0;
185
+ const submitToolResult = async (params) => {
186
+ const payload = JSON.stringify({
187
+ runId: params.runId,
188
+ toolCallId: params.toolCallId,
189
+ ...params.error !== void 0 ? {
190
+ status: "error",
191
+ error: params.error
192
+ } : {
193
+ status: "success",
194
+ result: params.result
195
+ }
196
+ });
197
+ for (let attempt = 1; attempt <= deps.toolSubmissionMaxAttempts; attempt++) try {
198
+ const prepared = await prepareRequest(deps.advanced, {
199
+ operation: "tool-result",
200
+ url: `${deps.baseURL}/${encodeURIComponent(params.agent)}/run/tool-result`,
201
+ method: "POST",
202
+ headers: mergeHeaders(authHeaders, { "content-type": "application/json" }, deps.defaultHeaders),
203
+ body: payload
204
+ });
205
+ const res = await doFetch(prepared.url, {
206
+ method: prepared.method,
207
+ headers: prepared.headers,
208
+ body: prepared.body
209
+ });
210
+ if (res.ok) return;
211
+ if (!(res.status >= 500 || res.status === 429) || attempt === deps.toolSubmissionMaxAttempts) await throwRequestError({
212
+ response: res,
213
+ operation: "tool-result",
214
+ at: "client.core.submitToolResult",
215
+ context: {
216
+ agentName: params.agent,
217
+ runId: params.runId,
218
+ toolCallId: params.toolCallId
219
+ }
220
+ });
221
+ await sleep(deps.toolSubmissionRetryDelayMs * attempt);
222
+ } catch (error) {
223
+ const wrapped = error instanceof Error ? error : new Error("Tool result submission failed.", { cause: error });
224
+ if (attempt === deps.toolSubmissionMaxAttempts) throw wrapped;
225
+ await sleep(deps.toolSubmissionRetryDelayMs * attempt);
226
+ }
227
+ };
228
+ const submitToolApproval = async (params) => {
229
+ const payload = JSON.stringify({
230
+ runId: params.runId,
231
+ toolCallId: params.toolCallId,
232
+ decision: params.decision,
233
+ ...params.note !== void 0 ? { note: params.note } : {},
234
+ ...params.actorId !== void 0 ? { actorId: params.actorId } : {}
235
+ });
236
+ for (let attempt = 1; attempt <= deps.toolSubmissionMaxAttempts; attempt++) try {
237
+ const prepared = await prepareRequest(deps.advanced, {
238
+ operation: "tool-approval",
239
+ url: `${deps.baseURL}/${encodeURIComponent(params.agent)}/run/tool-approval`,
240
+ method: "POST",
241
+ headers: mergeHeaders(authHeaders, { "content-type": "application/json" }, deps.defaultHeaders),
242
+ body: payload
243
+ });
244
+ const res = await doFetch(prepared.url, {
245
+ method: prepared.method,
246
+ headers: prepared.headers,
247
+ body: prepared.body
248
+ });
249
+ if (res.ok) return;
250
+ if (!(res.status >= 500 || res.status === 429) || attempt === deps.toolSubmissionMaxAttempts) await throwRequestError({
251
+ response: res,
252
+ operation: "tool-approval",
253
+ at: "client.core.submitToolApproval",
254
+ context: {
255
+ agentName: params.agent,
256
+ runId: params.runId,
257
+ toolCallId: params.toolCallId,
258
+ decision: params.decision
259
+ }
260
+ });
261
+ await sleep(deps.toolSubmissionRetryDelayMs * attempt);
262
+ } catch (error) {
263
+ const wrapped = error instanceof Error ? error : new Error("Tool approval submission failed.", { cause: error });
264
+ if (attempt === deps.toolSubmissionMaxAttempts) throw wrapped;
265
+ await sleep(deps.toolSubmissionRetryDelayMs * attempt);
266
+ }
267
+ };
268
+ return {
269
+ submitToolApproval,
270
+ submitToolResult
271
+ };
272
+ };
273
+
274
+ //#endregion
275
+ //#region src/core/client/index.ts
276
+ /**
277
+ * Creates a Better Agent client.
278
+ *
279
+ * @param config Client configuration.
280
+ * @returns A typed client.
281
+ *
282
+ * @example
283
+ * ```ts
284
+ * import { createClient } from "@better-agent/client";
285
+ *
286
+ * const client = createClient({
287
+ * baseURL: "http://localhost:3000/api",
288
+ * secret: "dev_secret",
289
+ * });
290
+ *
291
+ * const result = await client.run("helloAgent", {
292
+ * input: "Write one short sentence about TypeScript.",
293
+ * });
294
+ * ```
295
+ *
296
+ * @example
297
+ * ```ts
298
+ * import type ba from "./better-agent/server";
299
+ * import { createClient } from "@better-agent/client";
300
+ *
301
+ * const client = createClient<typeof ba>({
302
+ * baseURL: "http://localhost:3000/api",
303
+ * secret: "dev_secret",
304
+ * toolHandlers: {
305
+ * getClientTime: () => ({ now: new Date().toISOString() }),
306
+ * },
307
+ * });
308
+ *
309
+ * for await (const event of client.stream("helloAgent", {
310
+ * input: "Use tools if needed.",
311
+ * })) {
312
+ * console.log(event.type);
313
+ * }
314
+ * ```
315
+ */
316
+ const createClient = (config) => {
317
+ const baseURL = config.baseURL.replace(/\/$/, "");
318
+ const doFetch = config.fetch ?? fetch;
319
+ const advanced = config.advanced;
320
+ const authHeaders = config.secret ? { authorization: `Bearer ${config.secret}` } : void 0;
321
+ const toolSubmissionMaxAttempts = Math.max(1, Math.floor(advanced?.toolSubmissionMaxAttempts ?? 3));
322
+ const toolSubmissionRetryDelayMs = Math.max(0, advanced?.toolSubmissionRetryDelayMs ?? 150);
323
+ const { submitToolResult, submitToolApproval } = createToolSubmissionHandlers({
324
+ advanced,
325
+ baseURL,
326
+ defaultHeaders: config.headers,
327
+ doFetch,
328
+ secret: config.secret,
329
+ toolSubmissionMaxAttempts,
330
+ toolSubmissionRetryDelayMs
331
+ });
332
+ return {
333
+ async run(agent, input, options) {
334
+ const request = {
335
+ agent,
336
+ ...input
337
+ };
338
+ const prepared = await prepareRequest(advanced, {
339
+ operation: "run",
340
+ url: `${baseURL}/${encodeURIComponent(String(agent))}/run`,
341
+ method: "POST",
342
+ headers: mergeHeaders(authHeaders, { "content-type": "application/json" }, config.headers, options?.headers),
343
+ body: JSON.stringify(request)
344
+ });
345
+ const res = await doFetch(prepared.url, {
346
+ method: prepared.method,
347
+ headers: prepared.headers,
348
+ ...prepared.body !== void 0 ? { body: prepared.body } : {},
349
+ signal: options?.signal ?? null
350
+ });
351
+ options?.onResponse?.(res);
352
+ if (!res.ok) await throwRequestError({
353
+ response: res,
354
+ operation: "run",
355
+ at: "client.core.run",
356
+ context: { agentName: agent }
357
+ });
358
+ return await res.json();
359
+ },
360
+ stream(agent, input, options) {
361
+ const request = {
362
+ agent,
363
+ ...input
364
+ };
365
+ return (async function* () {
366
+ const pendingToolCalls = /* @__PURE__ */ new Map();
367
+ const toolCallController = new AbortController();
368
+ const abortToolCalls = () => {
369
+ if (!toolCallController.signal.aborted) toolCallController.abort();
370
+ };
371
+ const externalSignal = options?.signal;
372
+ const onExternalAbort = () => abortToolCalls();
373
+ if (externalSignal) if (externalSignal.aborted) abortToolCalls();
374
+ else externalSignal.addEventListener("abort", onExternalAbort, { once: true });
375
+ const processClientToolCall = async (toolCallKey, runId, toolCallId) => {
376
+ const pending = pendingToolCalls.get(toolCallKey);
377
+ if (!pending || pending.submitted || !pending.ended || pending.approvalState !== "waiting" && pending.approvalState !== "approved") return;
378
+ pending.submitted = true;
379
+ let parsedArgs = {};
380
+ try {
381
+ parsedArgs = pending.argsJson ? JSON.parse(pending.argsJson) : {};
382
+ } catch {
383
+ await submitToolResult({
384
+ agent: String(agent),
385
+ runId,
386
+ toolCallId,
387
+ error: `Invalid client tool arguments for '${pending.toolName}'.`
388
+ });
389
+ return;
390
+ }
391
+ const context = {
392
+ agent,
393
+ runId,
394
+ toolCallId,
395
+ signal: toolCallController.signal
396
+ };
397
+ const handler = resolveToolHandler(pending.toolName, options, config.toolHandlers);
398
+ if (!handler) {
399
+ await submitToolResult({
400
+ agent: String(agent),
401
+ runId,
402
+ toolCallId,
403
+ error: `Missing client tool handler for '${pending.toolName}'.`
404
+ });
405
+ return;
406
+ }
407
+ try {
408
+ const result = await Promise.resolve(handler({
409
+ toolName: pending.toolName,
410
+ input: parsedArgs,
411
+ context
412
+ }));
413
+ await submitToolResult({
414
+ agent: String(agent),
415
+ runId,
416
+ toolCallId,
417
+ result
418
+ });
419
+ } catch (error) {
420
+ await submitToolResult({
421
+ agent: String(agent),
422
+ runId,
423
+ toolCallId,
424
+ error: error instanceof Error ? error.message : "Client tool handler failed."
425
+ });
426
+ }
427
+ };
428
+ try {
429
+ const prepared = await prepareRequest(advanced, {
430
+ operation: "stream",
431
+ url: `${baseURL}/${encodeURIComponent(String(agent))}/run`,
432
+ method: "POST",
433
+ headers: mergeHeaders(authHeaders, {
434
+ "content-type": "application/json",
435
+ accept: "text/event-stream"
436
+ }, config.headers, options?.headers),
437
+ body: JSON.stringify({
438
+ ...request,
439
+ stream: true
440
+ })
441
+ });
442
+ const res = await doFetch(prepared.url, {
443
+ method: prepared.method,
444
+ headers: prepared.headers,
445
+ body: prepared.body,
446
+ signal: options?.signal ?? null
447
+ });
448
+ options?.onResponse?.(res);
449
+ if (!res.ok) await throwRequestError({
450
+ response: res,
451
+ operation: "stream",
452
+ at: "client.core.stream",
453
+ context: { agentName: agent }
454
+ });
455
+ if (!res.body) return;
456
+ for await (const ev of parseSse(res.body)) {
457
+ if (ev.type === "TOOL_CALL_START") {
458
+ if (ev.toolTarget !== "client") {
459
+ yield ev;
460
+ continue;
461
+ }
462
+ if (typeof ev.runId === "string") pendingToolCalls.set(getToolCallKey(ev.runId, ev.toolCallId), {
463
+ toolName: ev.toolCallName,
464
+ argsJson: "",
465
+ ended: false,
466
+ submitted: false,
467
+ approvalState: "waiting"
468
+ });
469
+ } else if (ev.type === "TOOL_CALL_ARGS") {
470
+ if (typeof ev.runId !== "string") {
471
+ yield ev;
472
+ continue;
473
+ }
474
+ const pending = pendingToolCalls.get(getToolCallKey(ev.runId, ev.toolCallId));
475
+ if (pending) pending.argsJson += ev.delta;
476
+ } else if (ev.type === "TOOL_CALL_END" && typeof ev.runId === "string") {
477
+ const toolCallKey = getToolCallKey(ev.runId, ev.toolCallId);
478
+ const pending = pendingToolCalls.get(toolCallKey);
479
+ if (pending) {
480
+ pending.ended = true;
481
+ await processClientToolCall(toolCallKey, ev.runId, ev.toolCallId);
482
+ }
483
+ } else if ((ev.type === "TOOL_APPROVAL_REQUIRED" || ev.type === "TOOL_APPROVAL_UPDATED") && ev.toolTarget === "client" && typeof ev.runId === "string") {
484
+ const toolCallKey = getToolCallKey(ev.runId, ev.toolCallId);
485
+ const pending = pendingToolCalls.get(toolCallKey);
486
+ if (pending) {
487
+ pending.approvalState = ev.state === "approved" ? "approved" : ev.state === "requested" ? "requested" : ev.state === "denied" ? "denied" : "expired";
488
+ if (pending.approvalState === "denied" || pending.approvalState === "expired") {
489
+ pending.submitted = true;
490
+ pendingToolCalls.delete(toolCallKey);
491
+ } else if (pending.approvalState === "approved") await processClientToolCall(toolCallKey, ev.runId, ev.toolCallId);
492
+ }
493
+ }
494
+ if (ev.type === "RUN_ABORTED" || ev.type === "RUN_ERROR" || ev.type === "RUN_FINISHED") {
495
+ for (const [toolCallKey, pending] of pendingToolCalls) if (pending.submitted) pendingToolCalls.delete(toolCallKey);
496
+ abortToolCalls();
497
+ }
498
+ yield ev;
499
+ }
500
+ } finally {
501
+ abortToolCalls();
502
+ if (externalSignal) externalSignal.removeEventListener("abort", onExternalAbort);
503
+ pendingToolCalls.clear();
504
+ }
505
+ })();
506
+ },
507
+ resumeStream(agent, input, options) {
508
+ return (async function* () {
509
+ const searchParams = new URLSearchParams();
510
+ searchParams.set("streamId", input.streamId);
511
+ const headers = mergeHeaders(authHeaders, { accept: "text/event-stream" }, config.headers, options?.headers);
512
+ if (typeof input.afterSeq === "number") headers.set("last-event-id", String(input.afterSeq));
513
+ const prepared = await prepareRequest(advanced, {
514
+ operation: "resume-stream",
515
+ url: `${baseURL}/${encodeURIComponent(String(agent))}/stream-events/resume?${searchParams.toString()}`,
516
+ method: "GET",
517
+ headers
518
+ });
519
+ const res = await doFetch(prepared.url, {
520
+ method: prepared.method,
521
+ headers: prepared.headers,
522
+ ...prepared.body !== void 0 ? { body: prepared.body } : {},
523
+ signal: options?.signal ?? null
524
+ });
525
+ options?.onResponse?.(res);
526
+ if (res.status === 204) return;
527
+ if (!res.ok) await throwRequestError({
528
+ response: res,
529
+ operation: "resume-stream",
530
+ at: "client.core.resumeStream",
531
+ context: { agentName: agent }
532
+ });
533
+ if (!res.body) return;
534
+ for await (const ev of parseSse(res.body)) yield ev;
535
+ })();
536
+ },
537
+ resumeConversation(agent, input, options) {
538
+ return (async function* () {
539
+ const headers = mergeHeaders(authHeaders, { accept: "text/event-stream" }, config.headers, options?.headers);
540
+ if (typeof input.afterSeq === "number") headers.set("last-event-id", String(input.afterSeq));
541
+ const prepared = await prepareRequest(advanced, {
542
+ operation: "resume-conversation",
543
+ url: `${baseURL}/${encodeURIComponent(String(agent))}/conversations/${encodeURIComponent(input.conversationId)}/resume`,
544
+ method: "GET",
545
+ headers
546
+ });
547
+ const res = await doFetch(prepared.url, {
548
+ method: prepared.method,
549
+ headers: prepared.headers,
550
+ ...prepared.body !== void 0 ? { body: prepared.body } : {},
551
+ signal: options?.signal ?? null
552
+ });
553
+ options?.onResponse?.(res);
554
+ if (res.status === 204) return;
555
+ if (!res.ok) await throwRequestError({
556
+ response: res,
557
+ operation: "resume-conversation",
558
+ at: "client.core.resumeConversation",
559
+ context: {
560
+ agentName: agent,
561
+ conversationId: input.conversationId
562
+ }
563
+ });
564
+ if (!res.body) return;
565
+ for await (const ev of parseSse(res.body)) yield ev;
566
+ })();
567
+ },
568
+ async loadConversation(agent, conversationId, options) {
569
+ const prepared = await prepareRequest(advanced, {
570
+ operation: "load-conversation",
571
+ url: `${baseURL}/${encodeURIComponent(String(agent))}/conversations/${encodeURIComponent(conversationId)}`,
572
+ method: "GET",
573
+ headers: mergeHeaders(authHeaders, config.headers, options?.headers)
574
+ });
575
+ const res = await doFetch(prepared.url, {
576
+ method: prepared.method,
577
+ headers: prepared.headers,
578
+ ...prepared.body !== void 0 ? { body: prepared.body } : {},
579
+ signal: options?.signal ?? null
580
+ });
581
+ options?.onResponse?.(res);
582
+ if (res.status === 204) return null;
583
+ if (!res.ok) await throwRequestError({
584
+ response: res,
585
+ operation: "load-conversation",
586
+ at: "client.core.loadConversation",
587
+ context: {
588
+ agentName: agent,
589
+ conversationId
590
+ }
591
+ });
592
+ return await res.json();
593
+ },
594
+ async abortRun(req, options) {
595
+ const prepared = await prepareRequest(advanced, {
596
+ operation: "abort-run",
597
+ url: `${baseURL}/${encodeURIComponent(String(req.agent))}/runs/${encodeURIComponent(req.runId)}/abort`,
598
+ method: "POST",
599
+ headers: mergeHeaders(authHeaders, config.headers, options?.headers)
600
+ });
601
+ const res = await doFetch(prepared.url, {
602
+ method: prepared.method,
603
+ headers: prepared.headers,
604
+ ...prepared.body !== void 0 ? { body: prepared.body } : {},
605
+ signal: options?.signal ?? null
606
+ });
607
+ options?.onResponse?.(res);
608
+ if (res.status === 204) return;
609
+ if (!res.ok) await throwRequestError({
610
+ response: res,
611
+ operation: "abort-run",
612
+ at: "client.core.abortRun",
613
+ context: {
614
+ agentName: req.agent,
615
+ runId: req.runId
616
+ }
617
+ });
618
+ },
619
+ async submitToolResult(req) {
620
+ await submitToolResult({
621
+ ...req,
622
+ agent: String(req.agent)
623
+ });
624
+ },
625
+ async submitToolApproval(req) {
626
+ await submitToolApproval({
627
+ ...req,
628
+ agent: String(req.agent)
629
+ });
630
+ }
631
+ };
632
+ };
633
+ const getToolCallKey = (runId, toolCallId) => `${runId}:${toolCallId}`;
634
+ const resolveToolHandler = (toolName, options, staticToolHandlers) => {
635
+ const requestHandler = options?.onToolCall;
636
+ const requestToolHandler = (options?.toolHandlers)?.[toolName];
637
+ const staticHandler = staticToolHandlers?.[toolName];
638
+ return requestHandler ?? (requestToolHandler ? (params) => requestToolHandler(params.input, params.context) : void 0) ?? (staticHandler ? (params) => staticHandler(params.input, params.context) : void 0);
639
+ };
640
+
641
+ //#endregion
642
+ export { createAgentChatController, createClient, fromConversationItems, fromModelMessages, getEventErrorMessage, pruneInputByCapabilities, toAgentClientError, toModelMessages };
643
+ //# sourceMappingURL=index.mjs.map