@koreanhole/opencodex 2.95.10 → 2.96.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.
@@ -1,8 +1,7 @@
1
- import { execFileSync, spawn as nodeSpawn } from "node:child_process";
1
+ import { spawn as nodeSpawn } from "node:child_process";
2
2
  import { mkdtemp, rm, stat, writeFile } from "node:fs/promises";
3
3
  import { homedir, tmpdir } from "node:os";
4
4
  import { join, resolve } from "node:path";
5
- import { Readable, Writable } from "node:stream";
6
5
  import * as acp from "@agentclientprotocol/sdk";
7
6
  import type { AdapterEvent, IncomingMeta } from "../../../types";
8
7
  import { commandInvocation } from "../../../lib/win-exec";
@@ -10,17 +9,15 @@ import { baseScopedEnv } from "../env";
10
9
  import { resolveClineBinary } from "./binary";
11
10
  import type { CliAgentStreamState, CliAgentTurnDeps } from "../types";
12
11
  import { createClineStreamState, ClineStreamProtocolError, mapClineToolIntent } from "./stream";
12
+ import { AcpClient, AcpError, type AcpClientOptions } from "../acp-client";
13
13
 
14
14
  const DEFAULT_TIMEOUT_MS = 300_000;
15
- const DEFAULT_KILL_GRACE_MS = 2_000;
16
15
  const MAX_STDERR_BYTES = 8 * 1024;
17
16
  const MAX_MODEL_ID_CHARS = 512;
18
17
  const MAX_ACP_MODELS = 512;
19
18
  const MAX_ACP_CONFIG_OPTIONS = 128;
20
19
  const MAX_ACP_OPTION_VALUES = 512;
21
- const MAX_MCP_SERVERS = 32;
22
20
 
23
- const CLINE_ACP_ARGS = ["--acp"] as const;
24
21
  const OPENAI_CODEX_AUTH_IDS = new Set(["openai-codex", "openai-codex-oauth"]);
25
22
  const CLINE_AUTH_IDS = new Set(["cline", "cline-oauth"]);
26
23
 
@@ -65,7 +62,7 @@ export interface ClineAcpInitialize {
65
62
  agentVersion?: string;
66
63
  }
67
64
 
68
- export class ClineAcpError extends Error {
65
+ export class ClineAcpError extends AcpError {
69
66
  constructor(
70
67
  message: string,
71
68
  readonly status: number,
@@ -75,7 +72,7 @@ export class ClineAcpError extends Error {
75
72
  readonly fallbackAllowed: boolean,
76
73
  readonly authRequired = false,
77
74
  ) {
78
- super(message);
75
+ super(message, status, errorType, code, retryable, fallbackAllowed, authRequired);
79
76
  this.name = "ClineAcpError";
80
77
  }
81
78
  }
@@ -331,272 +328,9 @@ async function runClineHelp(
331
328
  });
332
329
  }
333
330
 
334
- function isAuthError(error: unknown): boolean {
335
- const message = safeMessage(error);
336
- return /auth(?:entication)?\s*(?:required|failed)|not\s+(?:logged|signed)\s+in|sign[ -]?in|login required|unauthorized/i.test(message);
337
- }
338
-
339
- function acpError(error: unknown, fallbackAllowed: boolean): ClineAcpError {
340
- const authRequired = isAuthError(error);
341
- return new ClineAcpError(
342
- safeMessage(error),
343
- authRequired ? 401 : 502,
344
- authRequired ? "authentication_error" : "upstream_error",
345
- authRequired ? "acp_auth_required" : "acp_transport_error",
346
- false,
347
- fallbackAllowed,
348
- authRequired,
349
- );
350
- }
351
-
352
- function killWindowsProcessTree(pid: number): void {
353
- const taskkill = `${process.env.SystemRoot ?? "C:\\Windows"}\\System32\\taskkill.exe`;
354
- execFileSync(taskkill, ["/PID", String(pid), "/T", "/F"], { stdio: "pipe", windowsHide: true });
355
- }
356
-
357
- export interface ClineAcpClientOptions {
358
- binary: string;
359
- env: Record<string, string>;
360
- cwd: string;
361
- args?: readonly string[];
362
- hooks?: ClineAcpHooks;
363
- }
364
-
365
- /** One request-scoped ACP child. Cleanup is idempotent and always reaps the process. */
366
- export class ClineAcpClient {
367
- private readonly child: ReturnType<typeof nodeSpawn>;
368
- private readonly connection: acp.ClientSideConnection;
369
- private readonly processLifecycle: Promise<void>;
370
- private readonly stderrChunks: string[] = [];
371
- private stderrBytes = 0;
372
- private readonly terminateOnce: () => Promise<void>;
373
- private terminated = false;
374
- private exited = false;
375
- sessionId?: string;
376
- initializeResult?: ClineAcpInitialize;
377
-
378
- private constructor(
379
- child: ReturnType<typeof nodeSpawn>,
380
- connection: acp.ClientSideConnection,
381
- processLifecycle: Promise<void>,
382
- private readonly hooks: ClineAcpHooks,
383
- private readonly deps: ClineAcpDeps,
384
- ) {
385
- this.child = child;
386
- this.connection = connection;
387
- this.processLifecycle = processLifecycle;
388
- this.terminateOnce = async () => {
389
- if (this.terminated) return;
390
- this.terminated = true;
391
- try { this.child.stdin?.end(); } catch { /* already closed */ }
392
- if (this.deps.platform === "win32" && this.child.pid !== undefined) {
393
- try { (this.deps.killWindowsProcessTree ?? killWindowsProcessTree)(this.child.pid); } catch { /* direct fallback */ }
394
- }
395
- try { this.child.kill("SIGTERM"); } catch { /* already gone */ }
396
- await Promise.race([
397
- this.processLifecycle,
398
- new Promise<void>(resolve => setTimeout(resolve, this.deps.killGraceMs ?? DEFAULT_KILL_GRACE_MS)),
399
- ]);
400
- if (this.child.exitCode === null) {
401
- try { this.child.kill("SIGKILL"); } catch { /* already gone */ }
402
- await Promise.race([
403
- this.processLifecycle,
404
- new Promise<void>(resolve => setTimeout(resolve, (this.deps.reapTimeoutMs ?? (this.deps.killGraceMs ?? DEFAULT_KILL_GRACE_MS) * 2 + 250))),
405
- ]);
406
- }
407
- };
408
- }
409
-
410
- static async connect(
411
- options: ClineAcpClientOptions,
412
- deps: ClineAcpDeps = {},
413
- ): Promise<ClineAcpClient> {
414
- const hooks = options.hooks ?? {};
415
- const spawnFn = deps.spawn ?? (nodeSpawn as unknown as NonNullable<CliAgentTurnDeps["spawn"]>);
416
- const invocation = commandInvocation(options.binary, [...(options.args ?? CLINE_ACP_ARGS)], deps.platform ?? process.platform, { env: options.env });
417
- let child: ReturnType<typeof nodeSpawn>;
418
- try {
419
- child = spawnFn(invocation.file, invocation.args, {
420
- ...invocation.options,
421
- cwd: options.cwd,
422
- env: options.env,
423
- stdio: ["pipe", "pipe", "pipe"],
424
- windowsHide: true,
425
- });
426
- } catch (error) {
427
- throw acpError(error, true);
428
- }
429
- if (!child.stdin || !child.stdout) {
430
- try { child.kill("SIGKILL"); } catch { /* ignore */ }
431
- throw new ClineAcpError("Cline ACP process did not expose stdio.", 500, "upstream_error", "acp_spawn_failed", false, true);
432
- }
433
- const processLifecycle = new Promise<void>(resolvePromise => {
434
- let settled = false;
435
- const settle = (): void => {
436
- if (settled) return;
437
- settled = true;
438
- resolvePromise();
439
- };
440
- child.once("error", settle);
441
- child.once("close", settle);
442
- if (child.exitCode !== null) settle();
443
- });
444
- let instance: ClineAcpClient;
445
- const client: acp.Client = {
446
- requestPermission: async params => {
447
- hooks.onPermission?.(params);
448
- if (instance?.sessionId) void instance.cancel(instance.sessionId).catch(() => undefined);
449
- return { outcome: { outcome: "cancelled" } };
450
- },
451
- sessionUpdate: async notification => {
452
- if (notification.sessionId === instance?.sessionId) hooks.onSessionUpdate?.(notification);
453
- },
454
- };
455
- const stream = acp.ndJsonStream(
456
- Writable.toWeb(child.stdin) as WritableStream<Uint8Array>,
457
- Readable.toWeb(child.stdout) as unknown as ReadableStream<Uint8Array>,
458
- );
459
- const connection = new acp.ClientSideConnection(() => client, stream);
460
- instance = new ClineAcpClient(child, connection, processLifecycle, hooks, deps);
461
- child.stderr?.setEncoding("utf8");
462
- child.stderr?.on("data", (chunk: string) => {
463
- if (instance.stderrBytes >= MAX_STDERR_BYTES) return;
464
- const remaining = MAX_STDERR_BYTES - instance.stderrBytes;
465
- const admitted = chunk.slice(0, remaining);
466
- instance.stderrChunks.push(admitted);
467
- instance.stderrBytes += admitted.length;
468
- hooks.onStderr?.(admitted);
469
- });
470
- child.once("close", () => { instance.exited = true; });
471
- try {
472
- const initialize = await deadline(
473
- connection.initialize({
474
- protocolVersion: acp.PROTOCOL_VERSION,
475
- clientCapabilities: {},
476
- clientInfo: { name: "opencodex", version: "1.0.0" },
477
- }),
478
- deps.timeoutMs ?? DEFAULT_TIMEOUT_MS,
479
- () => instance.terminate(),
480
- );
481
- instance.initializeResult = parseClineAcpInitialize(initialize);
482
- return instance;
483
- } catch (error) {
484
- await instance.terminate();
485
- if (error instanceof ClineAcpError) {
486
- if (error.code === "timeout") {
487
- throw new ClineAcpError(error.message, error.status, error.errorType, error.code, error.retryable, true);
488
- }
489
- throw error;
490
- }
491
- throw acpError(error, true);
492
- }
493
- }
494
-
495
- stderrText(): string {
496
- return this.stderrChunks.join("");
497
- }
498
-
499
- async newSession(params: {
500
- cwd: string;
501
- mcpServers: readonly Record<string, unknown>[];
502
- }): Promise<ClineAcpSessionInfo> {
503
- try {
504
- const response = await deadline(
505
- this.connection.request<unknown>(acp.AGENT_METHODS.session_new, {
506
- cwd: params.cwd,
507
- mcpServers: params.mcpServers.slice(0, MAX_MCP_SERVERS),
508
- }),
509
- this.deps.timeoutMs ?? DEFAULT_TIMEOUT_MS,
510
- () => this.terminate(),
511
- );
512
- const session = parseClineAcpSession(response);
513
- this.sessionId = session.sessionId;
514
- return session;
515
- } catch (error) {
516
- if (error instanceof ClineAcpError) {
517
- if (error.code === "timeout") {
518
- throw new ClineAcpError(error.message, error.status, error.errorType, error.code, error.retryable, true);
519
- }
520
- throw error;
521
- }
522
- throw acpError(error, true);
523
- }
524
- }
525
-
526
- async setModel(sessionId: string, modelId: string): Promise<void> {
527
- await deadline(
528
- this.connection.request("session/set_model", { sessionId, modelId }),
529
- this.deps.timeoutMs ?? DEFAULT_TIMEOUT_MS,
530
- () => this.terminate(),
531
- ).catch(error => {
532
- if (error instanceof ClineAcpError) throw error;
533
- throw new ClineAcpError("Cline ACP rejected session/set_model.", 502, "upstream_error", "acp_transport_error", false, false);
534
- });
535
- }
536
-
537
- async setConfigOption(sessionId: string, configId: string, value: string): Promise<void> {
538
- await deadline(
539
- this.connection.request(acp.AGENT_METHODS.session_set_config_option, {
540
- sessionId,
541
- configId,
542
- value,
543
- }),
544
- this.deps.timeoutMs ?? DEFAULT_TIMEOUT_MS,
545
- () => this.terminate(),
546
- ).catch(error => {
547
- if (error instanceof ClineAcpError) throw error;
548
- throw new ClineAcpError("Cline ACP rejected session/set_config_option.", 502, "upstream_error", "acp_transport_error", false, false);
549
- });
550
- }
551
-
552
- async authenticate(methodId: string): Promise<void> {
553
- await deadline(
554
- this.connection.authenticate({ methodId }),
555
- this.deps.timeoutMs ?? DEFAULT_TIMEOUT_MS,
556
- () => this.terminate(),
557
- ).catch(error => {
558
- if (error instanceof ClineAcpError) throw error;
559
- throw acpError(error, false);
560
- });
561
- }
562
-
563
- async prompt(sessionId: string, text: string, cancellationSignal?: AbortSignal): Promise<acp.PromptResponse> {
564
- return await deadline(
565
- this.connection.request(
566
- acp.AGENT_METHODS.session_prompt,
567
- { sessionId, prompt: [{ type: "text" as const, text }] },
568
- { ...(cancellationSignal ? { cancellationSignal } : {}) },
569
- ),
570
- this.deps.timeoutMs ?? DEFAULT_TIMEOUT_MS,
571
- () => this.terminate(),
572
- );
573
- }
574
-
575
- async cancel(sessionId: string): Promise<void> {
576
- if (this.exited) return;
577
- await this.connection.cancel({ sessionId });
578
- }
579
-
580
- async terminate(): Promise<void> {
581
- await this.terminateOnce();
582
- }
583
- }
584
-
585
- async function deadline<T>(promise: Promise<T>, ms: number, onTimeout: () => Promise<void>): Promise<T> {
586
- let timer: ReturnType<typeof setTimeout> | undefined;
587
- const timeout = new Promise<never>((_, reject) => {
588
- timer = setTimeout(() => {
589
- void onTimeout().catch(() => undefined);
590
- reject(new ClineAcpError("Cline ACP request timed out.", 504, "upstream_error", "timeout", true, false));
591
- }, ms);
592
- });
593
- try {
594
- return await Promise.race([promise, timeout]);
595
- } finally {
596
- if (timer) clearTimeout(timer);
597
- }
598
- }
331
+ export type ClineAcpClientOptions = AcpClientOptions;
599
332
 
333
+ export const ClineAcpClient = AcpClient;
600
334
  export function selectClineAuthMethod(methods: readonly ClineAcpAuthMethod[]): ClineAcpAuthMethod | undefined {
601
335
  const byId = new Map(methods.map(method => [method.id.toLowerCase(), method]));
602
336
  for (const id of ["cline", "cline-oauth", "openai-codex", "openai-codex-oauth"]) {
@@ -635,13 +369,15 @@ export async function loginClineAcp(options: ClineAcpLoginOptions = {}): Promise
635
369
  }
636
370
  const workspace = await stageClineAcpWorkspace();
637
371
  let instructions = "";
638
- let client: ClineAcpClient | undefined;
372
+ let client: AcpClient | undefined;
639
373
  try {
640
- client = await ClineAcpClient.connect({
374
+ client = await AcpClient.connect({
641
375
  binary,
642
376
  env,
643
377
  cwd: workspace.cwd,
644
378
  args: mode.autoApproveFlag ? ["--acp", "--auto-approve", "false"] : ["--acp"],
379
+ label: "Cline ACP",
380
+ fallbackAllowed: true,
645
381
  hooks: {
646
382
  onStderr: text => {
647
383
  instructions = (instructions + text).slice(0, MAX_STDERR_BYTES);
@@ -751,7 +487,7 @@ function unsupportedModel(modelId: string): ClineAcpError {
751
487
  );
752
488
  }
753
489
 
754
- export async function applyClineAcpModel(client: ClineAcpClient, session: ClineAcpSessionInfo, modelId: string): Promise<void> {
490
+ export async function applyClineAcpModel(client: AcpClient, session: ClineAcpSessionInfo, modelId: string): Promise<void> {
755
491
  if (modelId === "default") return;
756
492
  if (session.availableModels.length > 0) {
757
493
  if (!session.availableModels.some(model => model.modelId === modelId)) throw unsupportedModel(modelId);
@@ -783,7 +519,7 @@ export async function runClineAcpTurn(
783
519
  ): Promise<void> {
784
520
  const deps = input.deps ?? {};
785
521
  const state = createClineStreamState();
786
- let client: ClineAcpClient | undefined;
522
+ let client: AcpClient | undefined;
787
523
  let session: ClineAcpSessionInfo | undefined;
788
524
  let terminalEmitted = false;
789
525
  let sawOutput = false;
@@ -857,7 +593,7 @@ export async function runClineAcpTurn(
857
593
  };
858
594
 
859
595
  try {
860
- client = await ClineAcpClient.connect({ binary: input.binary, env: input.env, cwd: input.cwd, hooks, ...(input.args ? { args: input.args } : {}) }, deps);
596
+ client = await AcpClient.connect({ binary: input.binary, env: input.env, cwd: input.cwd, hooks, label: "Cline ACP", fallbackAllowed: true, ...(input.args ? { args: input.args } : {}) }, deps);
861
597
  session = await client.newSession({ cwd: input.cwd, mcpServers: input.mcpServers });
862
598
  await applyClineAcpModel(client, session, input.modelId);
863
599
 
@@ -941,13 +677,13 @@ export async function runClineAcpTurn(
941
677
  });
942
678
  }
943
679
  } catch (error) {
944
- if (error instanceof ClineAcpError && error.fallbackAllowed && !sawOutput) throw error;
680
+ if (error instanceof AcpError && error.fallbackAllowed && !sawOutput) throw error;
945
681
  if (!terminalEmitted) {
946
682
  const failure = timedOut
947
683
  ? new ClineAcpError("Cline ACP turn timed out.", 504, "upstream_error", "timeout", true, false)
948
684
  : aborted
949
685
  ? new ClineAcpError("Cline ACP turn was cancelled.", 499, "invalid_request_error", "client_cancelled", false, false)
950
- : error instanceof ClineAcpError
686
+ : error instanceof AcpError
951
687
  ? error
952
688
  : new ClineAcpError(
953
689
  safeMessage(error),
@@ -21,7 +21,6 @@ import {
21
21
  import { resolveClineBinary } from "./binary";
22
22
  import {
23
23
  buildClineAcpEnv,
24
- ClineAcpError,
25
24
  probeClineAcpSupport,
26
25
  runClineAcpTurn,
27
26
  stageClineAcpWorkspace,
@@ -30,6 +29,7 @@ import {
30
29
  type ClineAcpTurnInput,
31
30
  } from "./acp";
32
31
  import { classifyClineFailure, createClineStreamState, mapClineMessage } from "./stream";
32
+ import { AcpError } from "../acp-client";
33
33
 
34
34
  export const CLINE_CLI_BASE_URL = "https://api.cline.bot";
35
35
  export const CLINE_CLI_MODEL_ID = "default";
@@ -140,7 +140,7 @@ function settingsError(error: unknown): Extract<AdapterEvent, { type: "error" }>
140
140
  }
141
141
 
142
142
  function acpFailure(error: unknown): Extract<AdapterEvent, { type: "error" }> {
143
- if (error instanceof ClineAcpError) {
143
+ if (error instanceof AcpError) {
144
144
  return {
145
145
  type: "error",
146
146
  message: error.message,
@@ -254,7 +254,7 @@ export async function runClineTurn(
254
254
  }, acpEmit, acpDeps);
255
255
  return;
256
256
  } catch (error) {
257
- if (!(error instanceof ClineAcpError && error.fallbackAllowed && !acpOutput && requestedModel === "default")) {
257
+ if (!(error instanceof AcpError && error.fallbackAllowed && !acpOutput && requestedModel === "default")) {
258
258
  emit(acpFailure(error));
259
259
  return;
260
260
  }
@@ -1,6 +1,4 @@
1
1
  import {
2
- ClineAcpClient,
3
- ClineAcpError,
4
2
  buildClineAcpEnv,
5
3
  clineAcpEnabled,
6
4
  clineModelSource,
@@ -9,6 +7,7 @@ import {
9
7
  type ClineAcpDeps,
10
8
  } from "./acp";
11
9
  import { clineBinaryFingerprintSync, resolveClineBinary } from "./binary";
10
+ import { AcpClient, AcpError } from "../acp-client";
12
11
 
13
12
  export type ClineLiveModelsFailure = "not_found" | "unsupported" | "auth_required" | "backoff" | "transport";
14
13
 
@@ -94,13 +93,15 @@ export async function discoverClineLiveModels(options: ClineLiveModelsOptions =
94
93
  ?? { ok: false, reason: "unsupported", detail: "Cline --help does not advertise --acp.", fingerprint };
95
94
  }
96
95
  const workspace = await stageClineAcpWorkspace();
97
- let client: ClineAcpClient | undefined;
96
+ let client: AcpClient | undefined;
98
97
  try {
99
- client = await ClineAcpClient.connect({
98
+ client = await AcpClient.connect({
100
99
  binary,
101
100
  env,
102
101
  cwd: workspace.cwd,
103
102
  args: mode.autoApproveFlag ? ["--acp", "--auto-approve", "false"] : ["--acp"],
103
+ label: "Cline ACP",
104
+ fallbackAllowed: true,
104
105
  }, options.deps);
105
106
  const session = await client.newSession({ cwd: workspace.cwd, mcpServers: [] });
106
107
  const discovered = clineModelSource(session);
@@ -111,7 +112,7 @@ export async function discoverClineLiveModels(options: ClineLiveModelsOptions =
111
112
  failureCache.set(fingerprint, timestamp);
112
113
  if (current) current.lastFailureAt = timestamp;
113
114
  const stale = staleResult(fingerprint, current);
114
- if (error instanceof ClineAcpError && error.authRequired) {
115
+ if (error instanceof AcpError && error.authRequired) {
115
116
  return stale ?? { ok: false, reason: "auth_required", detail: error.message, fingerprint };
116
117
  }
117
118
  return stale ?? {
@@ -1,8 +1,7 @@
1
- import { Buffer } from "node:buffer";
2
1
  import type { AdapterEvent, OcxUsage } from "../../../types";
3
2
  import type { CliAgentStreamState } from "../types";
3
+ import { mapToolIntent, ToolIntentError } from "../tool-intent";
4
4
 
5
- const MAX_TOOL_ARGUMENT_BYTES = 2 * 1024 * 1024;
6
5
  const MAX_ERROR_CHARS = 2_048;
7
6
 
8
7
  export class ClineStreamProtocolError extends Error {
@@ -86,24 +85,6 @@ function usageFrom(value: unknown): OcxUsage | undefined {
86
85
  };
87
86
  }
88
87
 
89
- function toolArguments(input: unknown): string {
90
- let value = input;
91
- if (typeof value === "string") {
92
- try {
93
- value = JSON.parse(value);
94
- } catch {
95
- throw new ClineStreamProtocolError("Cline returned a tool call with invalid JSON arguments.");
96
- }
97
- }
98
- const record = asRecord(value ?? {});
99
- if (!record) throw new ClineStreamProtocolError("Cline returned non-object tool arguments.");
100
- const serialized = JSON.stringify(record);
101
- if (Buffer.byteLength(serialized) > MAX_TOOL_ARGUMENT_BYTES) {
102
- throw new ClineStreamProtocolError("Cline returned tool arguments above the byte limit.");
103
- }
104
- return serialized;
105
- }
106
-
107
88
  /** Map a validated tool intent from either Cline's NDJSON or ACP event shape. */
108
89
  export function mapClineToolIntent(
109
90
  vendorName: string,
@@ -112,24 +93,12 @@ export function mapClineToolIntent(
112
93
  state: CliAgentStreamState,
113
94
  options: ClineStreamOptions,
114
95
  ): AdapterEvent[] {
115
- if (!vendorName) throw new ClineStreamProtocolError("Cline returned a tool call without a name.");
116
- const wireName = options.toolNames.get(vendorName);
117
- if (!wireName) {
118
- throw new ClineStreamProtocolError(`Cline returned an undeclared tool: ${vendorName.slice(0, 128)}`);
119
- }
120
- const maxToolCalls = options.maxToolCalls ?? 16;
121
- if (state.toolCalls >= maxToolCalls) {
122
- throw new ClineStreamProtocolError("Cline exceeded the per-turn tool-call limit.");
96
+ try {
97
+ return mapToolIntent("Cline", vendorName, toolCallId, input, state, options);
98
+ } catch (error) {
99
+ if (error instanceof ToolIntentError) throw new ClineStreamProtocolError(error.message);
100
+ throw error;
123
101
  }
124
- const ordinal = ++state.nextToolOrdinal;
125
- const id = toolCallId?.trim() || `cline-tool-${ordinal}`;
126
- const argumentsJson = toolArguments(input);
127
- state.toolCalls++;
128
- return [
129
- { type: "tool_call_start", id, name: wireName },
130
- { type: "tool_call_delta", arguments: argumentsJson },
131
- { type: "tool_call_end" },
132
- ];
133
102
  }
134
103
 
135
104
  function mapToolCall(