@rallycry/conveyor-agent 10.13.71 → 11.0.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,7 +1,9 @@
1
1
  import {
2
- loadPtySpawn,
2
+ loadPtySpawn
3
+ } from "./chunk-3F4ZZKCA.js";
4
+ import {
3
5
  terminateProcessGroup
4
- } from "./chunk-GJXAAPJ6.js";
6
+ } from "./chunk-W4LZ7R6Z.js";
5
7
  import {
6
8
  FrameReader,
7
9
  timingSafeTokenEqual,
@@ -1,75 +1,122 @@
1
- // src/harness/pty/pty-support.ts
2
- import { stat } from "fs/promises";
3
- import { tmpdir } from "os";
4
-
5
- // src/harness/pty/spawn-args.ts
6
- function resolveClaudeBinary() {
7
- return process.env.CONVEYOR_CLAUDE_BIN ?? "claude";
8
- }
9
- function buildSpawnArgs(input) {
10
- const args = [];
11
- if (input.resume) {
12
- args.push("--resume", input.resume);
13
- } else if (input.sessionId) {
14
- args.push("--session-id", input.sessionId);
15
- }
16
- args.push("--model", input.model);
17
- if (input.permissionMode === "bypassPermissions") {
18
- args.push("--dangerously-skip-permissions");
19
- } else {
20
- args.push("--permission-mode", "plan");
21
- }
22
- args.push("--settings", input.settingsPath);
23
- if (input.appendSystemPrompt) {
24
- args.push("--append-system-prompt", input.appendSystemPrompt);
25
- }
26
- if (input.mcpConfigPath) {
27
- args.push("--mcp-config", input.mcpConfigPath);
28
- if (input.strictMcpConfig) {
29
- args.push("--strict-mcp-config");
1
+ // src/setup/commands.ts
2
+ import { spawn, execSync } from "child_process";
3
+ var PROCESS_TERMINATION_GRACE_MS = 5e3;
4
+ function abortError() {
5
+ const error = new Error("Operation aborted");
6
+ error.name = "AbortError";
7
+ return error;
8
+ }
9
+ function signalProcessGroup(child, signal) {
10
+ try {
11
+ if (child.pid) process.kill(-child.pid, signal);
12
+ else child.kill(signal);
13
+ } catch {
14
+ try {
15
+ child.kill(signal);
16
+ } catch {
30
17
  }
31
18
  }
32
- return args;
33
- }
34
- function spawnOptionsFingerprint(input) {
35
- return JSON.stringify([
36
- input.model,
37
- input.permissionMode,
38
- input.appendSystemPrompt ?? "",
39
- input.cwd
40
- ]);
41
- }
42
- var ANSI_CSI = new RegExp(`${String.fromCharCode(27)}\\[[0-9;?]*[ -/]*[@-~]`, "g");
43
- function cleanTerminalOutput(raw, maxChars = 1200) {
44
- const noAnsi = raw.replace(ANSI_CSI, "");
45
- let out = "";
46
- for (const ch of noAnsi) {
47
- const code = ch.charCodeAt(0);
48
- if (ch === "\r" || ch === "\n") out += "\n";
49
- else if (ch === " ") out += ch;
50
- else if (code < 32 || code === 127) continue;
51
- else out += ch;
52
- }
53
- const lines = out.split("\n").map((line) => line.trimEnd()).filter((line) => line.trim().length > 0);
54
- const text = lines.join("\n").trim();
55
- return text.length > maxChars ? `\u2026${text.slice(-maxChars)}` : text;
56
- }
57
- function isMissingBinaryFailure(tail) {
58
- return /execvp\(\d+\) failed|no such file or directory|command not found/i.test(tail);
59
- }
60
- function buildExitErrors(exitCode, rawOutput, binary) {
61
- const errors = [`claude exited (code ${exitCode}) without a result`];
62
- const tail = cleanTerminalOutput(rawOutput);
63
- if (isMissingBinaryFailure(tail)) {
64
- errors.push(
65
- `The \`${binary}\` CLI could not be started \u2014 it is not installed or not on PATH. Install the Claude Code CLI in this environment (npm i -g @anthropic-ai/claude-code) or set CONVEYOR_CLAUDE_BIN to its absolute path.`
66
- );
67
- }
68
- if (tail) {
69
- errors.push(`Last terminal output before exit:
70
- ${tail}`);
19
+ }
20
+ function terminateProcessGroup(child, graceMs = PROCESS_TERMINATION_GRACE_MS) {
21
+ if (child.exitCode !== null) return Promise.resolve();
22
+ return new Promise((resolve) => {
23
+ let settled = false;
24
+ const finish = () => {
25
+ if (settled) return;
26
+ settled = true;
27
+ clearTimeout(timer);
28
+ child.removeListener("exit", finish);
29
+ resolve();
30
+ };
31
+ const timer = setTimeout(() => {
32
+ signalProcessGroup(child, "SIGKILL");
33
+ finish();
34
+ }, graceMs);
35
+ timer.unref();
36
+ child.once("exit", finish);
37
+ signalProcessGroup(child, "SIGTERM");
38
+ });
39
+ }
40
+ function runSetupCommand(cmd, cwd, onOutput, signal) {
41
+ if (signal?.aborted) return Promise.reject(abortError());
42
+ return new Promise((resolve, reject) => {
43
+ const child = spawn("sh", ["-c", cmd], {
44
+ cwd,
45
+ stdio: ["ignore", "pipe", "pipe"],
46
+ detached: true,
47
+ env: { ...process.env }
48
+ });
49
+ let settled = false;
50
+ let aborting = false;
51
+ const cleanup = () => signal?.removeEventListener("abort", onAbort);
52
+ const settle = (error) => {
53
+ if (settled) return;
54
+ settled = true;
55
+ cleanup();
56
+ if (error) reject(error);
57
+ else resolve();
58
+ };
59
+ const onAbort = () => {
60
+ if (settled || aborting) return;
61
+ aborting = true;
62
+ void terminateProcessGroup(child).then(() => settle(abortError()));
63
+ };
64
+ signal?.addEventListener("abort", onAbort, { once: true });
65
+ if (signal?.aborted) onAbort();
66
+ child.stdout.on("data", (chunk) => {
67
+ if (aborting || signal?.aborted) return;
68
+ onOutput("stdout", chunk.toString());
69
+ });
70
+ child.stderr.on("data", (chunk) => {
71
+ if (aborting || signal?.aborted) return;
72
+ onOutput("stderr", chunk.toString());
73
+ });
74
+ child.on("close", (code) => {
75
+ if (aborting) return;
76
+ settle(code === 0 ? void 0 : new Error(`Setup command exited with code ${code}`));
77
+ });
78
+ child.on("error", (err) => {
79
+ if (!aborting) settle(err);
80
+ });
81
+ });
82
+ }
83
+ var AUTH_TOKEN_TIMEOUT_MS = 3e4;
84
+ function runAuthTokenCommand(cmd, userEmail, cwd) {
85
+ try {
86
+ const output = execSync(`${cmd} ${JSON.stringify(userEmail)}`, {
87
+ cwd,
88
+ timeout: AUTH_TOKEN_TIMEOUT_MS,
89
+ stdio: ["ignore", "pipe", "ignore"],
90
+ env: { ...process.env }
91
+ });
92
+ const token = output.toString().trim();
93
+ return token || null;
94
+ } catch {
95
+ return null;
71
96
  }
72
- return errors;
97
+ }
98
+ function runStartCommand(cmd, cwd, onOutput) {
99
+ const child = spawn("sh", ["-c", cmd], {
100
+ cwd,
101
+ stdio: ["ignore", "pipe", "pipe"],
102
+ detached: true,
103
+ env: { ...process.env }
104
+ });
105
+ child.stdout.on("data", (chunk) => {
106
+ onOutput("stdout", chunk.toString());
107
+ });
108
+ child.stderr.on("data", (chunk) => {
109
+ onOutput("stderr", chunk.toString());
110
+ });
111
+ child.unref();
112
+ return child;
113
+ }
114
+
115
+ // src/utils/sleep.ts
116
+ function sleep(ms) {
117
+ return new Promise((resolve) => {
118
+ setTimeout(resolve, ms);
119
+ });
73
120
  }
74
121
 
75
122
  // src/boot/git-credential.ts
@@ -289,345 +336,15 @@ function classifyTokenShape(value) {
289
336
  return "unrecognized prefix";
290
337
  }
291
338
 
292
- // src/utils/sleep.ts
293
- function sleep(ms) {
294
- return new Promise((resolve) => {
295
- setTimeout(resolve, ms);
296
- });
297
- }
298
-
299
- // src/harness/pty/pty-support.ts
300
- var MAX_DIAGNOSTIC_OUTPUT = 4e3;
301
- var MAX_BETWEEN_TURN_BUFFER = 500;
302
- var SUBMIT_SETTLE_MS = 300;
303
- var SUBMIT_NUDGE_INTERVAL_MS = 2e3;
304
- var SUBMIT_NUDGE_MAX_PRESSES = 5;
305
- var SUBMIT_NUDGE_SLOW_INTERVAL_MS = 5e3;
306
- var SUBMIT_NUDGE_WINDOW_MS = 9e4;
307
- var SUBMIT_REDELIVERY_MAX_ATTEMPTS = 2;
308
- var PLAN_DIALOG_FIRST_PRESS_MS = 700;
309
- var PLAN_DIALOG_INTERVAL_MS = 1500;
310
- var PLAN_DIALOG_SLOW_INTERVAL_MS = 5e3;
311
- var PLAN_DIALOG_FAST_WINDOW_MS = 1e4;
312
- var PLAN_DIALOG_WINDOW_MS = 9e4;
313
- var RAW_TUI_PROBE_SENTINEL = "zqx";
314
- var RAW_TUI_PROBE_ACK_MS = 500;
315
- var RAW_TUI_PROBE_RETRY_MS = 250;
316
- var RAW_TUI_PROBE_POLL_MS = 20;
317
- var RAW_TUI_FIRST_OUTPUT_MAX_MS = 1e4;
318
- var RAW_TUI_INPUT_LIVE_MAX_MS = 2e4;
319
- function envMs(name, fallback) {
320
- const raw = Number(process.env[name]);
321
- return Number.isFinite(raw) && raw > 0 ? raw : fallback;
322
- }
323
- function resolveSubmitSettleMs() {
324
- return envMs("CONVEYOR_PTY_SUBMIT_SETTLE_MS", SUBMIT_SETTLE_MS);
325
- }
326
- function resolveRawTuiProbeTiming() {
327
- const sentinel = process.env.CONVEYOR_PTY_RAW_PROBE_SENTINEL;
328
- return {
329
- // A sentinel must be non-empty (it is what we search for) and must stay
330
- // free of digits and control chars — see the note on menu dialogs above.
331
- sentinel: sentinel && /^[a-z]{1,8}$/.test(sentinel) ? sentinel : RAW_TUI_PROBE_SENTINEL,
332
- ackMs: envMs("CONVEYOR_PTY_RAW_PROBE_ACK_MS", RAW_TUI_PROBE_ACK_MS),
333
- retryMs: envMs("CONVEYOR_PTY_RAW_PROBE_RETRY_MS", RAW_TUI_PROBE_RETRY_MS),
334
- pollMs: envMs("CONVEYOR_PTY_RAW_PROBE_POLL_MS", RAW_TUI_PROBE_POLL_MS),
335
- firstOutputMaxMs: envMs("CONVEYOR_PTY_RAW_FIRST_OUTPUT_MAX_MS", RAW_TUI_FIRST_OUTPUT_MAX_MS),
336
- maxMs: envMs("CONVEYOR_PTY_RAW_INPUT_LIVE_MAX_MS", RAW_TUI_INPUT_LIVE_MAX_MS)
337
- };
338
- }
339
- function sentinelEchoed(rawOutput, sentinel) {
340
- return cleanTerminalOutput(rawOutput, Number.MAX_SAFE_INTEGER).includes(sentinel);
341
- }
342
- var DEC_PRIVATE_MODE = new RegExp(`${String.fromCharCode(27)}\\[\\?[0-9;]+[hl]`);
343
- function sawTerminalSetup(rawOutput) {
344
- return DEC_PRIVATE_MODE.test(rawOutput);
345
- }
346
- function needsRawReadyGate(caps) {
347
- return caps.rawPromptGate;
348
- }
349
- function resolveSubmitNudgeTiming() {
350
- return {
351
- intervalMs: envMs("CONVEYOR_PTY_NUDGE_INTERVAL_MS", SUBMIT_NUDGE_INTERVAL_MS),
352
- slowIntervalMs: envMs("CONVEYOR_PTY_NUDGE_SLOW_INTERVAL_MS", SUBMIT_NUDGE_SLOW_INTERVAL_MS),
353
- maxPresses: SUBMIT_NUDGE_MAX_PRESSES,
354
- windowMs: envMs("CONVEYOR_PTY_NUDGE_WINDOW_MS", SUBMIT_NUDGE_WINDOW_MS)
355
- };
356
- }
357
- function resolveSubmitRedeliveryMaxAttempts() {
358
- const value = process.env.CONVEYOR_PTY_SUBMIT_REDELIVERY_MAX;
359
- if (!value) return SUBMIT_REDELIVERY_MAX_ATTEMPTS;
360
- const raw = Number(value);
361
- return Number.isFinite(raw) && raw >= 0 ? raw : SUBMIT_REDELIVERY_MAX_ATTEMPTS;
362
- }
363
- function resolvePlanDialogTiming() {
364
- return {
365
- firstPressMs: envMs("CONVEYOR_PTY_PLAN_DIALOG_FIRST_PRESS_MS", PLAN_DIALOG_FIRST_PRESS_MS),
366
- intervalMs: envMs("CONVEYOR_PTY_PLAN_DIALOG_INTERVAL_MS", PLAN_DIALOG_INTERVAL_MS),
367
- slowIntervalMs: envMs(
368
- "CONVEYOR_PTY_PLAN_DIALOG_SLOW_INTERVAL_MS",
369
- PLAN_DIALOG_SLOW_INTERVAL_MS
370
- ),
371
- fastWindowMs: envMs("CONVEYOR_PTY_PLAN_DIALOG_FAST_WINDOW_MS", PLAN_DIALOG_FAST_WINDOW_MS),
372
- windowMs: envMs("CONVEYOR_PTY_PLAN_DIALOG_WINDOW_MS", PLAN_DIALOG_WINDOW_MS)
373
- };
374
- }
375
- function turnOptionsFrom(options) {
376
- return {
377
- canUseTool: options.canUseTool,
378
- promptDelivery: options.promptDelivery,
379
- planDialogAutoAccept: options.planDialogAutoAccept,
380
- abortController: options.abortController
381
- };
382
- }
383
- var KILL_ESCALATION_MS = 5e3;
384
- function killPtyWithEscalation(pty, hasExited, escalationMs = KILL_ESCALATION_MS) {
385
- try {
386
- pty.kill();
387
- } catch {
388
- }
389
- const timer = setTimeout(() => {
390
- if (hasExited()) return;
391
- try {
392
- pty.kill("SIGKILL");
393
- } catch {
394
- }
395
- }, escalationMs);
396
- timer.unref?.();
397
- }
398
- function isRecord(value) {
399
- return typeof value === "object" && value !== null;
400
- }
401
- function extractSpawn(mod) {
402
- if (!isRecord(mod)) return null;
403
- if (typeof mod.spawn === "function") return mod.spawn;
404
- const def = mod.default;
405
- if (isRecord(def) && typeof def.spawn === "function") return def.spawn;
406
- return null;
407
- }
408
- async function loadPtySpawn() {
409
- const mod = await import("node-pty");
410
- const spawn2 = extractSpawn(mod);
411
- if (!spawn2) throw new Error("node-pty: spawn export not found");
412
- return spawn2;
413
- }
414
- async function resolvePtySpawn() {
415
- const { workbenchEnabled } = await import("./mode-ZJSOSLGU.js");
416
- if (!workbenchEnabled()) return loadPtySpawn();
417
- const { getWorkbenchClient } = await import("./client-IG6C5F2G.js");
418
- return (file, args, options) => getWorkbenchClient().spawnPty(file, args, options);
419
- }
420
- function sessionTempBase() {
421
- return process.env.CONVEYOR_SHARED_DIR ?? tmpdir();
422
- }
423
- function inheritedEnv(socketPath) {
424
- const env = {};
425
- for (const [key, value] of Object.entries(process.env)) {
426
- if (typeof value === "string") env[key] = value;
427
- }
428
- if (env.CLAUDE_CODE_OAUTH_TOKEN) {
429
- delete env.ANTHROPIC_API_KEY;
430
- }
431
- if (ghHostsManagedByConveyor() && env.CONVEYOR_KEEP_GH_TOKEN_ENV !== "1") {
432
- delete env.GH_TOKEN;
433
- delete env.GITHUB_TOKEN;
434
- delete env.CONVEYOR_GITHUB_TOKEN;
435
- env.CONVEYOR_GITHUB_TOKEN_FILE = githubTokenFilePath();
436
- }
437
- if (socketPath) {
438
- env.CONVEYOR_HOOK_SOCKET = socketPath;
439
- }
440
- env.MCP_TIMEOUT ??= "60000";
441
- env.MCP_TOOL_TIMEOUT ??= "180000";
442
- return env;
443
- }
444
- function buildPromptBytes(text) {
445
- return `\x1B[200~${text}\x1B[201~`;
446
- }
447
- function renderPromptContentText(content) {
448
- return content.map((block) => {
449
- const b = block;
450
- if (b?.type === "text" && typeof b.text === "string") return b.text;
451
- if (b?.type === "image") {
452
- return `[Image attachment \u2014 use list_task_files / get_attachment to view]`;
453
- }
454
- return JSON.stringify(block);
455
- }).join("\n\n");
456
- }
457
- async function transcriptSize(path) {
458
- try {
459
- return (await stat(path)).size;
460
- } catch {
461
- return 0;
462
- }
463
- }
464
- function parseUserQuestions(input) {
465
- if (!Array.isArray(input.questions)) return [];
466
- const questions = [];
467
- for (const entry of input.questions) {
468
- if (!isRecord(entry)) continue;
469
- if (typeof entry.question !== "string") continue;
470
- const options = Array.isArray(entry.options) ? entry.options.filter(isRecord).filter((o) => typeof o.label === "string").map((o) => ({
471
- label: o.label,
472
- description: typeof o.description === "string" ? o.description : ""
473
- })) : [];
474
- questions.push({
475
- question: entry.question,
476
- header: typeof entry.header === "string" ? entry.header : "",
477
- options,
478
- ...typeof entry.multiSelect === "boolean" ? { multiSelect: entry.multiSelect } : {}
479
- });
480
- }
481
- return questions;
482
- }
483
-
484
- // src/setup/commands.ts
485
- import { spawn, execSync } from "child_process";
486
- var PROCESS_TERMINATION_GRACE_MS = 5e3;
487
- function abortError() {
488
- const error = new Error("Operation aborted");
489
- error.name = "AbortError";
490
- return error;
491
- }
492
- function signalProcessGroup(child, signal) {
493
- try {
494
- if (child.pid) process.kill(-child.pid, signal);
495
- else child.kill(signal);
496
- } catch {
497
- try {
498
- child.kill(signal);
499
- } catch {
500
- }
501
- }
502
- }
503
- function terminateProcessGroup(child, graceMs = PROCESS_TERMINATION_GRACE_MS) {
504
- if (child.exitCode !== null) return Promise.resolve();
505
- return new Promise((resolve) => {
506
- let settled = false;
507
- const finish = () => {
508
- if (settled) return;
509
- settled = true;
510
- clearTimeout(timer);
511
- child.removeListener("exit", finish);
512
- resolve();
513
- };
514
- const timer = setTimeout(() => {
515
- signalProcessGroup(child, "SIGKILL");
516
- finish();
517
- }, graceMs);
518
- timer.unref();
519
- child.once("exit", finish);
520
- signalProcessGroup(child, "SIGTERM");
521
- });
522
- }
523
- function runSetupCommand(cmd, cwd, onOutput, signal) {
524
- if (signal?.aborted) return Promise.reject(abortError());
525
- return new Promise((resolve, reject) => {
526
- const child = spawn("sh", ["-c", cmd], {
527
- cwd,
528
- stdio: ["ignore", "pipe", "pipe"],
529
- detached: true,
530
- env: { ...process.env }
531
- });
532
- let settled = false;
533
- let aborting = false;
534
- const cleanup = () => signal?.removeEventListener("abort", onAbort);
535
- const settle = (error) => {
536
- if (settled) return;
537
- settled = true;
538
- cleanup();
539
- if (error) reject(error);
540
- else resolve();
541
- };
542
- const onAbort = () => {
543
- if (settled || aborting) return;
544
- aborting = true;
545
- void terminateProcessGroup(child).then(() => settle(abortError()));
546
- };
547
- signal?.addEventListener("abort", onAbort, { once: true });
548
- if (signal?.aborted) onAbort();
549
- child.stdout.on("data", (chunk) => {
550
- if (aborting || signal?.aborted) return;
551
- onOutput("stdout", chunk.toString());
552
- });
553
- child.stderr.on("data", (chunk) => {
554
- if (aborting || signal?.aborted) return;
555
- onOutput("stderr", chunk.toString());
556
- });
557
- child.on("close", (code) => {
558
- if (aborting) return;
559
- settle(code === 0 ? void 0 : new Error(`Setup command exited with code ${code}`));
560
- });
561
- child.on("error", (err) => {
562
- if (!aborting) settle(err);
563
- });
564
- });
565
- }
566
- var AUTH_TOKEN_TIMEOUT_MS = 3e4;
567
- function runAuthTokenCommand(cmd, userEmail, cwd) {
568
- try {
569
- const output = execSync(`${cmd} ${JSON.stringify(userEmail)}`, {
570
- cwd,
571
- timeout: AUTH_TOKEN_TIMEOUT_MS,
572
- stdio: ["ignore", "pipe", "ignore"],
573
- env: { ...process.env }
574
- });
575
- const token = output.toString().trim();
576
- return token || null;
577
- } catch {
578
- return null;
579
- }
580
- }
581
- function runStartCommand(cmd, cwd, onOutput) {
582
- const child = spawn("sh", ["-c", cmd], {
583
- cwd,
584
- stdio: ["ignore", "pipe", "pipe"],
585
- detached: true,
586
- env: { ...process.env }
587
- });
588
- child.stdout.on("data", (chunk) => {
589
- onOutput("stdout", chunk.toString());
590
- });
591
- child.stderr.on("data", (chunk) => {
592
- onOutput("stderr", chunk.toString());
593
- });
594
- child.unref();
595
- return child;
596
- }
597
-
598
339
  export {
599
340
  sleep,
600
341
  gitCredentialHelper,
601
342
  writeGitCredential,
602
343
  githubTokenFilePath,
344
+ ghHostsManagedByConveyor,
603
345
  ghHostsExternallyOwned,
604
346
  syncGithubTokenFiles,
605
347
  describeTokenFile,
606
- resolveClaudeBinary,
607
- buildSpawnArgs,
608
- spawnOptionsFingerprint,
609
- cleanTerminalOutput,
610
- buildExitErrors,
611
- MAX_DIAGNOSTIC_OUTPUT,
612
- MAX_BETWEEN_TURN_BUFFER,
613
- resolveSubmitSettleMs,
614
- resolveRawTuiProbeTiming,
615
- sentinelEchoed,
616
- sawTerminalSetup,
617
- needsRawReadyGate,
618
- resolveSubmitNudgeTiming,
619
- resolveSubmitRedeliveryMaxAttempts,
620
- resolvePlanDialogTiming,
621
- turnOptionsFrom,
622
- killPtyWithEscalation,
623
- loadPtySpawn,
624
- resolvePtySpawn,
625
- sessionTempBase,
626
- inheritedEnv,
627
- buildPromptBytes,
628
- renderPromptContentText,
629
- transcriptSize,
630
- parseUserQuestions,
631
348
  terminateProcessGroup,
632
349
  runSetupCommand,
633
350
  runAuthTokenCommand,
@@ -0,0 +1,46 @@
1
+ // src/runner/session-runner-helpers.ts
2
+ import { readFileSync } from "fs";
3
+ import { dirname, join } from "path";
4
+ import { fileURLToPath } from "url";
5
+ function mapChatHistory(messages) {
6
+ if (!messages) return [];
7
+ return messages.map((m) => ({
8
+ id: m.id,
9
+ role: m.role ?? "user",
10
+ content: m.content ?? "",
11
+ userId: m.userId,
12
+ userName: m.user?.name ?? void 0,
13
+ createdAt: m.createdAt,
14
+ ...m.source ? { source: m.source } : {},
15
+ ...m.files && m.files.length > 0 ? {
16
+ files: m.files.map((f) => ({
17
+ fileId: f.id,
18
+ fileName: f.fileName,
19
+ mimeType: f.mimeType,
20
+ fileSize: f.fileSize,
21
+ downloadUrl: f.downloadUrl ?? "",
22
+ content: f.content,
23
+ contentEncoding: f.contentEncoding
24
+ }))
25
+ } : {}
26
+ }));
27
+ }
28
+ function readAgentVersion() {
29
+ try {
30
+ const here = dirname(fileURLToPath(import.meta.url));
31
+ for (const rel of ["../package.json", "../../package.json"]) {
32
+ try {
33
+ const pkg = JSON.parse(readFileSync(join(here, rel), "utf-8"));
34
+ if (pkg.version) return pkg.version;
35
+ } catch {
36
+ }
37
+ }
38
+ } catch {
39
+ }
40
+ return null;
41
+ }
42
+
43
+ export {
44
+ mapChatHistory,
45
+ readAgentVersion
46
+ };