ns-omp-provider 0.5.0 → 0.6.1

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 (2) hide show
  1. package/dist/index.js +1700 -2481
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // ns-omp-provider 0.5.0 — bundles @ngosangns/ns-pi-provider@0.4.0 (MIT). See NOTICE.
1
+ // ns-omp-provider 0.6.1 — bundles @ngosangns/ns-pi-provider@0.5.1 (MIT). See NOTICE.
2
2
  import { createRequire as __nsOmpCreateRequire } from 'node:module';
3
3
  const require = __nsOmpCreateRequire(import.meta.url);
4
4
  var __create = Object.create;
@@ -298,439 +298,6 @@ var init_endpoints = __esm({
298
298
  }
299
299
  });
300
300
 
301
- // ../bridge-core/dist/sidecar/binary.js
302
- import { createRequire } from "node:module";
303
- function findPackagedSidecarBinary() {
304
- let bin;
305
- try {
306
- bin = localRequire(SIDECAR_BIN_PACKAGE);
307
- } catch {
308
- return { error: `${SIDECAR_BIN_PACKAGE} is not installed` };
309
- }
310
- try {
311
- return { path: bin.binaryPath() };
312
- } catch (error2) {
313
- return { error: error2 instanceof Error ? error2.message : String(error2) };
314
- }
315
- }
316
- function resolveSidecarBinary(explicit, env = process.env, options = {}) {
317
- const fromEnv = env[NS_BRIDGE_BIN_ENV]?.trim();
318
- if (fromEnv)
319
- return fromEnv;
320
- if (explicit?.trim())
321
- return explicit.trim();
322
- const packaged = (options.packaged ?? findPackagedSidecarBinary)();
323
- if ("path" in packaged)
324
- return packaged.path;
325
- return DEFAULT_SIDECAR_COMMAND;
326
- }
327
- var NS_BRIDGE_BIN_ENV, DEFAULT_SIDECAR_COMMAND, SIDECAR_BIN_PACKAGE, localRequire;
328
- var init_binary = __esm({
329
- "../bridge-core/dist/sidecar/binary.js"() {
330
- "use strict";
331
- NS_BRIDGE_BIN_ENV = "NS_BRIDGE_BIN";
332
- DEFAULT_SIDECAR_COMMAND = "ns-bridge";
333
- SIDECAR_BIN_PACKAGE = "ns-bridge-bin";
334
- localRequire = createRequire(import.meta.url);
335
- }
336
- });
337
-
338
- // ../bridge-core/dist/sidecar/errors.js
339
- var SidecarError;
340
- var init_errors = __esm({
341
- "../bridge-core/dist/sidecar/errors.js"() {
342
- "use strict";
343
- SidecarError = class _SidecarError extends Error {
344
- name = "SidecarError";
345
- kind;
346
- vendor;
347
- status;
348
- retryAfterMs;
349
- reasonCode;
350
- vendorError;
351
- providerAttempts;
352
- exitCode;
353
- exitSignal;
354
- stderr;
355
- constructor(kind, message, details = {}) {
356
- super(message, details.cause === void 0 ? void 0 : { cause: details.cause });
357
- this.kind = kind;
358
- this.vendor = details.vendor;
359
- this.status = details.status;
360
- this.retryAfterMs = details.retryAfterMs;
361
- this.reasonCode = details.reasonCode;
362
- this.vendorError = details.vendorError;
363
- this.providerAttempts = details.providerAttempts;
364
- this.exitCode = details.exitCode;
365
- this.exitSignal = details.exitSignal;
366
- this.stderr = details.stderr;
367
- }
368
- /** Rebuild the error a binary reported on its terminal line. */
369
- static fromPayload(payload, details = {}) {
370
- const kind = typeof payload.kind === "string" ? payload.kind : "internal";
371
- const message = typeof payload.message === "string" && payload.message ? payload.message : `sidecar ${kind} error`;
372
- return new _SidecarError(kind, message, {
373
- ...details,
374
- vendor: payload.vendor ?? details.vendor,
375
- status: payload.status,
376
- retryAfterMs: payload.retryAfterMs,
377
- reasonCode: payload.reasonCode,
378
- vendorError: payload.vendorError,
379
- providerAttempts: payload.providerAttempts
380
- });
381
- }
382
- };
383
- }
384
- });
385
-
386
- // ../bridge-core/dist/sidecar/stream.js
387
- import { spawn } from "node:child_process";
388
- async function* sidecarStream(vendor, request, options = {}) {
389
- let sawDone = false;
390
- for await (const message of sidecarLines(vendor, ["stream", "--vendor", vendor], request, options, "done")) {
391
- if (!EVENT_TYPES.has(message.type))
392
- continue;
393
- if (sawDone)
394
- continue;
395
- if (message.type === "done")
396
- sawDone = true;
397
- yield message;
398
- }
399
- }
400
- async function sidecarCall(vendor, op, request, options = {}) {
401
- let result;
402
- for await (const message of sidecarLines(vendor, ["call", "--vendor", vendor, "--op", op], request, options, "result")) {
403
- if (message.type === "result")
404
- result = message.result;
405
- }
406
- return result;
407
- }
408
- async function* sidecarLines(vendor, args, request, options, terminal) {
409
- const { signal } = options;
410
- signal?.throwIfAborted();
411
- const env = options.env ?? process.env;
412
- const binary = resolveSidecarBinary(options.binary, env);
413
- const graceMs = options.killGraceMs ?? DEFAULT_KILL_GRACE_MS;
414
- let child;
415
- try {
416
- child = spawn(binary, args, { env, stdio: "pipe", windowsHide: true });
417
- } catch (cause) {
418
- throw unavailable(binary, vendor, cause);
419
- }
420
- const lines = [];
421
- let partial = "";
422
- let stderr = "";
423
- let spawnError;
424
- let exited = false;
425
- let closed = false;
426
- let exitCode = null;
427
- let exitSignal = null;
428
- let aborted = false;
429
- let wake;
430
- const notify = () => {
431
- const resolve = wake;
432
- wake = void 0;
433
- resolve?.();
434
- };
435
- child.stdout.setEncoding("utf8");
436
- child.stdout.on("data", (chunk) => {
437
- const parts = (partial + chunk).split("\n");
438
- partial = parts.pop() ?? "";
439
- for (const part of parts)
440
- if (part.trim())
441
- lines.push(part);
442
- notify();
443
- });
444
- child.stderr.setEncoding("utf8");
445
- const stderrSink = options.stderr === void 0 ? process.stderr : options.stderr;
446
- child.stderr.on("data", (chunk) => {
447
- if (stderrSink)
448
- stderrSink.write(chunk);
449
- stderr = (stderr + chunk).slice(-STDERR_TAIL_BYTES);
450
- });
451
- child.stdin.on("error", () => {
452
- });
453
- child.on("error", (error2) => {
454
- spawnError = error2;
455
- notify();
456
- });
457
- child.on("exit", (code, sig) => {
458
- exited = true;
459
- exitCode = code;
460
- exitSignal = sig;
461
- });
462
- child.on("close", (code, sig) => {
463
- exited = true;
464
- closed = true;
465
- exitCode ??= code;
466
- exitSignal ??= sig;
467
- if (partial.trim())
468
- lines.push(partial);
469
- partial = "";
470
- notify();
471
- });
472
- const timers = [];
473
- const cancel = () => {
474
- if (!child.stdin.destroyed)
475
- child.stdin.end();
476
- if (exited)
477
- return;
478
- const escalate = (delay, sig) => {
479
- const timer = setTimeout(() => {
480
- if (!exited)
481
- child.kill(sig);
482
- }, delay);
483
- timer.unref();
484
- timers.push(timer);
485
- };
486
- escalate(graceMs, "SIGTERM");
487
- escalate(graceMs * 2, "SIGKILL");
488
- };
489
- const onAbort = () => {
490
- aborted = true;
491
- cancel();
492
- notify();
493
- };
494
- signal?.addEventListener("abort", onAbort, { once: true });
495
- child.stdin.write(`${JSON.stringify({ protocol: SIDECAR_PROTOCOL_VERSION, request })}
496
- `);
497
- const details = () => ({ vendor, exitCode, exitSignal, stderr: stderr.trim() || void 0 });
498
- let sawTerminal = false;
499
- let finished = false;
500
- try {
501
- while (true) {
502
- if (aborted)
503
- throw abortReason(signal);
504
- if (spawnError !== void 0)
505
- throw unavailable(binary, vendor, spawnError);
506
- const line = lines.shift();
507
- if (line !== void 0) {
508
- const message = parseLine(line, details);
509
- if (message.type === "error") {
510
- throw SidecarError.fromPayload(message.error ?? { kind: "protocol", message: "ns-bridge wrote an error line without a payload" }, details());
511
- }
512
- if (message.type === terminal)
513
- sawTerminal = true;
514
- yield message;
515
- continue;
516
- }
517
- if (closed)
518
- break;
519
- await new Promise((resolve) => {
520
- wake = resolve;
521
- });
522
- }
523
- if (exitCode !== 0) {
524
- const how = exitSignal ? `was killed by ${exitSignal}` : `exited with code ${exitCode}`;
525
- throw new SidecarError("crashed", `ns-bridge (${vendor}) ${how} without reporting an error`, details());
526
- }
527
- if (!sawTerminal) {
528
- throw new SidecarError("protocol", `ns-bridge (${vendor}) exited without a ${terminal} ${terminal === "done" ? "event" : "line"}`, details());
529
- }
530
- finished = true;
531
- } finally {
532
- signal?.removeEventListener("abort", onAbort);
533
- if (finished) {
534
- for (const timer of timers)
535
- clearTimeout(timer);
536
- } else {
537
- cancel();
538
- }
539
- }
540
- }
541
- function parseLine(line, details) {
542
- let value;
543
- try {
544
- value = JSON.parse(line);
545
- } catch (cause) {
546
- throw new SidecarError("protocol", `ns-bridge wrote a line that is not JSON: ${line.slice(0, 200)}`, {
547
- ...details(),
548
- cause
549
- });
550
- }
551
- if (!value || typeof value !== "object" || typeof value.type !== "string") {
552
- throw new SidecarError("protocol", `ns-bridge wrote a line without a type: ${line.slice(0, 200)}`, details());
553
- }
554
- return value;
555
- }
556
- function unavailable(binary, vendor, cause) {
557
- const code = cause?.code;
558
- const reason = code === "ENOENT" ? "not found" : code === "EACCES" ? "not executable" : String(cause);
559
- const packaged = binary === DEFAULT_SIDECAR_COMMAND ? findPackagedSidecarBinary() : void 0;
560
- const why = packaged && "error" in packaged ? ` ${packaged.error}.` : "";
561
- return new SidecarError("unavailable", `Cannot start the ns-bridge binary "${binary}" (${reason}).${why} Install ns-bridge-bin or point NS_BRIDGE_BIN at a binary.`, { vendor, cause });
562
- }
563
- function abortReason(signal) {
564
- const reason = signal?.reason;
565
- if (reason instanceof Error)
566
- return reason;
567
- return new DOMException(typeof reason === "string" ? reason : "This operation was aborted", "AbortError");
568
- }
569
- var SIDECAR_PROTOCOL_VERSION, DEFAULT_KILL_GRACE_MS, STDERR_TAIL_BYTES, EVENT_TYPES;
570
- var init_stream = __esm({
571
- "../bridge-core/dist/sidecar/stream.js"() {
572
- "use strict";
573
- init_binary();
574
- init_errors();
575
- SIDECAR_PROTOCOL_VERSION = 1;
576
- DEFAULT_KILL_GRACE_MS = 2e3;
577
- STDERR_TAIL_BYTES = 8 * 1024;
578
- EVENT_TYPES = /* @__PURE__ */ new Set([
579
- "start",
580
- "text_start",
581
- "text_delta",
582
- "text_end",
583
- "thinking_start",
584
- "thinking_delta",
585
- "thinking_end",
586
- "tool_call_start",
587
- "tool_call_delta",
588
- "tool_call_end",
589
- "reset",
590
- "usage",
591
- "done"
592
- ]);
593
- }
594
- });
595
-
596
- // ../bridge-core/dist/sidecar/engine.js
597
- import { existsSync, statSync } from "node:fs";
598
- import { delimiter, isAbsolute, join as join2 } from "node:path";
599
- function parseSetting(value) {
600
- switch (value?.trim().toLowerCase()) {
601
- case "go":
602
- case "sidecar":
603
- case "native":
604
- return "go";
605
- case "ts":
606
- case "typescript":
607
- case "js":
608
- case "node":
609
- case "in-process":
610
- return "ts";
611
- case "auto":
612
- return "auto";
613
- default:
614
- return void 0;
615
- }
616
- }
617
- function bridgeEngineSetting(vendor, env = process.env) {
618
- const perVendor = vendor ? parseSetting(env[`${NS_BRIDGE_ENGINE_ENV}_${vendor.toUpperCase()}`]) : void 0;
619
- return perVendor ?? parseSetting(env[NS_BRIDGE_ENGINE_ENV]) ?? DEFAULT_BRIDGE_ENGINE;
620
- }
621
- function isFile(path) {
622
- try {
623
- return statSync(path).isFile();
624
- } catch {
625
- return false;
626
- }
627
- }
628
- function onPath(command, env) {
629
- if (isAbsolute(command))
630
- return isFile(command);
631
- const extensions = process.platform === "win32" ? (env.PATHEXT ?? ".EXE;.CMD;.BAT").split(";") : [""];
632
- for (const dir of (env.PATH ?? "").split(delimiter)) {
633
- if (!dir)
634
- continue;
635
- for (const ext of extensions)
636
- if (isFile(join2(dir, command + ext.toLowerCase())) || isFile(join2(dir, command + ext)))
637
- return true;
638
- }
639
- return false;
640
- }
641
- function sidecarBinaryAvailable(env = process.env) {
642
- const fromEnv = env[NS_BRIDGE_BIN_ENV]?.trim();
643
- if (fromEnv)
644
- return existsSync(fromEnv) || onPath(fromEnv, env);
645
- if ("path" in findPackagedSidecarBinary())
646
- return true;
647
- return onPath(DEFAULT_SIDECAR_COMMAND, env);
648
- }
649
- function selectBridgeEngine(vendor, env = process.env) {
650
- const setting = bridgeEngineSetting(vendor, env);
651
- if (setting !== "auto")
652
- return setting;
653
- return sidecarBinaryAvailable(env) ? "go" : "ts";
654
- }
655
- function isAutoFallback(error2) {
656
- return error2.kind === "unavailable" || error2.kind === "unsupported" || error2.kind === "crashed" && error2.exitCode === 2;
657
- }
658
- async function* engineStream(options) {
659
- const env = options.env ?? process.env;
660
- const engine = options.engine ?? selectBridgeEngine(options.vendor, env);
661
- if (engine === "ts") {
662
- yield* options.inProcess();
663
- return;
664
- }
665
- let delivered = false;
666
- try {
667
- const raw = sidecarStream(options.vendor, options.request(), {
668
- ...options.sidecar,
669
- ...options.signal ? { signal: options.signal } : {},
670
- env
671
- });
672
- for await (const event of options.transform ? options.transform(raw) : raw) {
673
- delivered = true;
674
- yield event;
675
- }
676
- } catch (error2) {
677
- if (error2 instanceof SidecarError && isAutoFallback(error2) && !delivered && options.engine === void 0 && bridgeEngineSetting(options.vendor, env) === "auto") {
678
- if (!warnedFallback) {
679
- warnedFallback = true;
680
- console.warn(`[ns-bridge] ${error2.message} Falling back to the in-process TypeScript core.`);
681
- }
682
- yield* options.inProcess();
683
- return;
684
- }
685
- throw error2 instanceof SidecarError && options.mapError ? options.mapError(error2) : error2;
686
- }
687
- }
688
- async function engineCall(options) {
689
- const env = options.env ?? process.env;
690
- const engine = options.engine ?? selectBridgeEngine(options.vendor, env);
691
- if (engine === "ts")
692
- return options.inProcess();
693
- try {
694
- return await sidecarCall(options.vendor, options.op, options.request(), {
695
- ...options.sidecar,
696
- ...options.signal ? { signal: options.signal } : {},
697
- env
698
- });
699
- } catch (error2) {
700
- if (error2 instanceof SidecarError && isAutoFallback(error2) && options.engine === void 0 && bridgeEngineSetting(options.vendor, env) === "auto") {
701
- if (!warnedFallback) {
702
- warnedFallback = true;
703
- console.warn(`[ns-bridge] ${error2.message} Falling back to the in-process TypeScript core.`);
704
- }
705
- return options.inProcess();
706
- }
707
- throw error2 instanceof SidecarError && options.mapError ? options.mapError(error2) : error2;
708
- }
709
- }
710
- var NS_BRIDGE_ENGINE_ENV, DEFAULT_BRIDGE_ENGINE, warnedFallback;
711
- var init_engine = __esm({
712
- "../bridge-core/dist/sidecar/engine.js"() {
713
- "use strict";
714
- init_binary();
715
- init_errors();
716
- init_stream();
717
- NS_BRIDGE_ENGINE_ENV = "NS_BRIDGE_ENGINE";
718
- DEFAULT_BRIDGE_ENGINE = "auto";
719
- warnedFallback = false;
720
- }
721
- });
722
-
723
- // ../bridge-core/dist/sidecar/index.js
724
- var init_sidecar = __esm({
725
- "../bridge-core/dist/sidecar/index.js"() {
726
- "use strict";
727
- init_binary();
728
- init_engine();
729
- init_errors();
730
- init_stream();
731
- }
732
- });
733
-
734
301
  // ../kiro-core/dist/kiro-cli.js
735
302
  var kiro_cli_exports = {};
736
303
  __export(kiro_cli_exports, {
@@ -746,16 +313,16 @@ __export(kiro_cli_exports, {
746
313
  tryKiroCliToken: () => tryKiroCliToken
747
314
  });
748
315
  import { execFileSync, execSync } from "node:child_process";
749
- import { existsSync as existsSync2 } from "node:fs";
750
- import { createRequire as createRequire2 } from "node:module";
316
+ import { existsSync } from "node:fs";
317
+ import { createRequire } from "node:module";
751
318
  import { homedir as homedir2, platform } from "node:os";
752
- import { join as join3 } from "node:path";
319
+ import { join as join2 } from "node:path";
753
320
  function getKiroCliDbPath() {
754
321
  const p = platform();
755
- const localAppData = process.env.LOCALAPPDATA || join3(homedir2(), "AppData", "Local");
756
- const roamingAppData = process.env.APPDATA || join3(homedir2(), "AppData", "Roaming");
757
- const candidates = p === "win32" ? [join3(localAppData, "Kiro-Cli", "data.sqlite3"), join3(roamingAppData, "kiro-cli", "data.sqlite3")] : p === "darwin" ? [join3(homedir2(), "Library", "Application Support", "kiro-cli", "data.sqlite3")] : [join3(homedir2(), ".local", "share", "kiro-cli", "data.sqlite3")];
758
- return candidates.find((candidate) => existsSync2(candidate));
322
+ const localAppData = process.env.LOCALAPPDATA || join2(homedir2(), "AppData", "Local");
323
+ const roamingAppData = process.env.APPDATA || join2(homedir2(), "AppData", "Roaming");
324
+ const candidates = p === "win32" ? [join2(localAppData, "Kiro-Cli", "data.sqlite3"), join2(roamingAppData, "kiro-cli", "data.sqlite3")] : p === "darwin" ? [join2(homedir2(), "Library", "Application Support", "kiro-cli", "data.sqlite3")] : [join2(homedir2(), ".local", "share", "kiro-cli", "data.sqlite3")];
325
+ return candidates.find((candidate) => existsSync(candidate));
759
326
  }
760
327
  function getKiroCliExternalIdpCredentials() {
761
328
  const dbPath = getKiroCliDbPath();
@@ -1035,7 +602,7 @@ var init_kiro_cli = __esm({
1035
602
  "../kiro-core/dist/kiro-cli.js"() {
1036
603
  "use strict";
1037
604
  init_debug();
1038
- require2 = createRequire2(import.meta.url);
605
+ require2 = createRequire(import.meta.url);
1039
606
  EXTERNAL_IDP_TOKEN_KEY = "kirocli:external-idp:token";
1040
607
  TOKEN_KEY_BY_AUTH_METHOD = {
1041
608
  idc: ["kirocli:odic:token", "codewhisperer:odic:token"],
@@ -1047,12 +614,12 @@ var init_kiro_cli = __esm({
1047
614
  });
1048
615
 
1049
616
  // ../kiro-core/dist/kiro-ide.js
1050
- import { existsSync as existsSync3, readFileSync } from "node:fs";
617
+ import { existsSync as existsSync2, readFileSync } from "node:fs";
1051
618
  import { homedir as homedir3 } from "node:os";
1052
- import { join as join4 } from "node:path";
619
+ import { join as join3 } from "node:path";
1053
620
  function readKiroIdeToken(allowExpired) {
1054
621
  try {
1055
- if (!existsSync3(KIRO_IDE_TOKEN_PATH))
622
+ if (!existsSync2(KIRO_IDE_TOKEN_PATH))
1056
623
  return void 0;
1057
624
  const tokenData = JSON.parse(readFileSync(KIRO_IDE_TOKEN_PATH, "utf-8"));
1058
625
  if (!tokenData.accessToken || !tokenData.refreshToken)
@@ -1064,8 +631,8 @@ function readKiroIdeToken(allowExpired) {
1064
631
  let clientId = "";
1065
632
  let clientSecret = "";
1066
633
  if (tokenData.clientIdHash) {
1067
- const regPath = join4(SSO_CACHE_DIR, `${tokenData.clientIdHash}.json`);
1068
- if (existsSync3(regPath)) {
634
+ const regPath = join3(SSO_CACHE_DIR, `${tokenData.clientIdHash}.json`);
635
+ if (existsSync2(regPath)) {
1069
636
  try {
1070
637
  const reg = JSON.parse(readFileSync(regPath, "utf-8"));
1071
638
  clientId = reg.clientId ?? "";
@@ -1099,8 +666,8 @@ var SSO_CACHE_DIR, KIRO_IDE_TOKEN_PATH;
1099
666
  var init_kiro_ide = __esm({
1100
667
  "../kiro-core/dist/kiro-ide.js"() {
1101
668
  "use strict";
1102
- SSO_CACHE_DIR = join4(homedir3(), ".aws", "sso", "cache");
1103
- KIRO_IDE_TOKEN_PATH = join4(SSO_CACHE_DIR, "kiro-auth-token.json");
669
+ SSO_CACHE_DIR = join3(homedir3(), ".aws", "sso", "cache");
670
+ KIRO_IDE_TOKEN_PATH = join3(SSO_CACHE_DIR, "kiro-auth-token.json");
1104
671
  }
1105
672
  });
1106
673
 
@@ -1130,23 +697,28 @@ function kiroAuthHeaders(token) {
1130
697
  function isApiKey(token) {
1131
698
  return token.startsWith("ksk_");
1132
699
  }
700
+ async function fetchApiKeyGetProfile(accessToken) {
701
+ try {
702
+ return await fetch(getKiroEndpoints(API_KEY_REGION).management, {
703
+ method: "POST",
704
+ headers: {
705
+ "Content-Type": "application/x-amz-json-1.0",
706
+ "X-Amz-Target": "AmazonCodeWhispererService.GetProfile",
707
+ ...kiroAuthHeaders(accessToken),
708
+ ...kiroUserAgent("codewhispererruntime", "F,C")
709
+ },
710
+ body: "{}"
711
+ });
712
+ } catch (error2) {
713
+ throw new Error(`Kiro management GetProfile request failed in ${API_KEY_REGION}`, { cause: error2 });
714
+ }
715
+ }
1133
716
  async function loginKiroWithApiKey(apiKey, onProgress) {
1134
717
  if (!apiKey.startsWith("ksk_")) {
1135
718
  throw new Error("Invalid API key format. Kiro API keys start with 'ksk_'.");
1136
719
  }
1137
720
  onProgress?.("Validating API key...");
1138
- const region = "us-east-1";
1139
- const managementUrl = `https://management.${resolveApiRegion(region)}.kiro.dev/`;
1140
- const response = await fetch(managementUrl, {
1141
- method: "POST",
1142
- headers: {
1143
- "Content-Type": "application/x-amz-json-1.0",
1144
- "X-Amz-Target": "AmazonCodeWhispererService.GetProfile",
1145
- ...kiroAuthHeaders(apiKey),
1146
- ...kiroUserAgent("codewhispererruntime", "F,C")
1147
- },
1148
- body: "{}"
1149
- });
721
+ const response = await fetchApiKeyGetProfile(apiKey);
1150
722
  if (!response.ok) {
1151
723
  let detail = "";
1152
724
  try {
@@ -1167,7 +739,7 @@ async function loginKiroWithApiKey(apiKey, onProgress) {
1167
739
  expires: Date.now() + 365 * 24 * 60 * 60 * 1e3,
1168
740
  clientId: "",
1169
741
  clientSecret: "",
1170
- region,
742
+ region: API_KEY_REGION,
1171
743
  authMethod: "apikey",
1172
744
  ...profileArn ? { profileArn } : {}
1173
745
  };
@@ -1238,8 +810,7 @@ async function refreshKiroTokenInternal(credentials) {
1238
810
  }
1239
811
  }
1240
812
  async function refreshKiroTokenDirect(credentials) {
1241
- const { runKiroOp: runKiroOp2 } = await Promise.resolve().then(() => (init_engine_ops(), engine_ops_exports));
1242
- return runKiroOp2("refreshToken", () => ({ credentials }), () => refreshKiroTokenDirectInProcess(credentials));
813
+ return refreshKiroTokenDirectInProcess(credentials);
1243
814
  }
1244
815
  function endpointFromEnv(name, fallback, region) {
1245
816
  return (process.env[name]?.trim() || fallback).replaceAll("{region}", region);
@@ -1360,7 +931,7 @@ async function resolveKiroCredentials() {
1360
931
  throw lastFailure;
1361
932
  return void 0;
1362
933
  }
1363
- var KIRO_DESKTOP_REFRESH_URL, EXPIRES_BUFFER_MS, KIRO_DESKTOP_USER_AGENT, AUTH_SOURCE_ENV, KIRO_DESKTOP_REFRESH_ENDPOINT_ENV, KIRO_OIDC_ENDPOINT_ENV;
934
+ var KIRO_DESKTOP_REFRESH_URL, EXPIRES_BUFFER_MS, KIRO_DESKTOP_USER_AGENT, AUTH_SOURCE_ENV, API_KEY_REGION, KIRO_DESKTOP_REFRESH_ENDPOINT_ENV, KIRO_OIDC_ENDPOINT_ENV;
1364
935
  var init_oauth = __esm({
1365
936
  "../kiro-core/dist/oauth.js"() {
1366
937
  "use strict";
@@ -1371,6 +942,7 @@ var init_oauth = __esm({
1371
942
  EXPIRES_BUFFER_MS = 5 * 60 * 1e3;
1372
943
  KIRO_DESKTOP_USER_AGENT = "Kiro-Desktop/0.2.13 (darwin; arm64)";
1373
944
  AUTH_SOURCE_ENV = "KIRO_AUTH_SOURCE";
945
+ API_KEY_REGION = "us-east-1";
1374
946
  KIRO_DESKTOP_REFRESH_ENDPOINT_ENV = "KIRO_DESKTOP_REFRESH_ENDPOINT";
1375
947
  KIRO_OIDC_ENDPOINT_ENV = "KIRO_OIDC_ENDPOINT";
1376
948
  }
@@ -1455,25 +1027,11 @@ function profileCacheKey(auth) {
1455
1027
  }
1456
1028
  async function getApiKeyProfileArn(accessToken) {
1457
1029
  const operation = "GetProfile";
1458
- let response;
1459
- try {
1460
- response = await fetch(getKiroEndpoints(API_KEY_REGION).management, {
1461
- method: "POST",
1462
- headers: {
1463
- "Content-Type": "application/x-amz-json-1.0",
1464
- "X-Amz-Target": GET_PROFILE_TARGET,
1465
- ...kiroAuthHeaders(accessToken),
1466
- ...kiroUserAgent("codewhispererruntime", "F,C")
1467
- },
1468
- body: "{}"
1469
- });
1470
- } catch (error2) {
1471
- throw new Error(`Kiro management ${operation} request failed in ${API_KEY_REGION}`, { cause: error2 });
1472
- }
1473
- const parsed = await parseManagementResponse(response, operation, API_KEY_REGION);
1030
+ const response = await fetchApiKeyGetProfile(accessToken);
1031
+ const parsed = await parseManagementResponse(response, operation, API_KEY_REGION2);
1474
1032
  const arn = parsed.profile?.arn;
1475
1033
  if (!arn) {
1476
- throw new Error(`Kiro management ${operation} returned no profile in ${API_KEY_REGION}`);
1034
+ throw new Error(`Kiro management ${operation} returned no profile in ${API_KEY_REGION2}`);
1477
1035
  }
1478
1036
  return arn;
1479
1037
  }
@@ -1488,32 +1046,6 @@ async function parseManagementResponse(response, operation, region) {
1488
1046
  throw new Error(`Kiro management ${operation} returned invalid JSON in ${region}`, { cause: error2 });
1489
1047
  }
1490
1048
  }
1491
- function snapshotKiroProfileArnCache() {
1492
- return Object.fromEntries(profileArnCache);
1493
- }
1494
- function snapshotKiroProfileRegionCache() {
1495
- return Object.fromEntries(profileRegionCache);
1496
- }
1497
- function applyKiroProfileRegionChanges(regions) {
1498
- if (!regions)
1499
- return;
1500
- for (const [key, region] of Object.entries(regions))
1501
- if (typeof region === "string" && region)
1502
- profileRegionCache.set(key, region);
1503
- }
1504
- function applyKiroProfileArnCacheChanges(changes) {
1505
- if (!changes)
1506
- return;
1507
- for (const [key, arn] of Object.entries(changes)) {
1508
- if (typeof arn === "string" && arn) {
1509
- profileArnCache.set(key, arn);
1510
- } else {
1511
- profileArnCache.delete(key);
1512
- profileRegionCache.delete(key);
1513
- pendingProfileRequests.delete(key);
1514
- }
1515
- }
1516
- }
1517
1049
  function invalidateKiroProfileArn(auth) {
1518
1050
  const key = profileCacheKey(auth);
1519
1051
  profileArnCache.delete(key);
@@ -1541,8 +1073,8 @@ async function resolveKiroProfileArn(auth, providedArn) {
1541
1073
  if (isApiKey(auth.accessToken)) {
1542
1074
  const arn = await getApiKeyProfileArn(auth.accessToken);
1543
1075
  profileArnCache.set(key, arn);
1544
- profileRegionCache.set(key, API_KEY_REGION);
1545
- debugLog("profile.resolve", { source: "api-key", region: API_KEY_REGION, arn });
1076
+ profileRegionCache.set(key, API_KEY_REGION2);
1077
+ debugLog("profile.resolve", { source: "api-key", region: API_KEY_REGION2, arn });
1546
1078
  return arn;
1547
1079
  }
1548
1080
  let lastResponse;
@@ -1595,13 +1127,13 @@ async function listAvailableModels(auth, profileArn) {
1595
1127
  }
1596
1128
  async function fetchKiroModelCatalog(auth, providedProfileArn) {
1597
1129
  const profileArn = await resolveKiroProfileArn(auth, providedProfileArn);
1598
- const region = isApiKey(auth.accessToken) ? API_KEY_REGION : profileRegionCache.get(profileCacheKey(auth)) ?? auth.region;
1130
+ const region = isApiKey(auth.accessToken) ? API_KEY_REGION2 : profileRegionCache.get(profileCacheKey(auth)) ?? auth.region;
1599
1131
  if (region !== auth.region) {
1600
1132
  return listAvailableModels({ ...auth, region }, profileArn);
1601
1133
  }
1602
1134
  return listAvailableModels(auth, profileArn);
1603
1135
  }
1604
- var LIST_PROFILES_PATH, LIST_MODELS_PATH, GET_PROFILE_TARGET, API_KEY_REGION, profileArnCache, pendingProfileRequests, profileRegionCache, CANONICAL_MANAGEMENT_REGIONS, ENV_PROFILE_ARN, KiroManagementHttpError;
1136
+ var LIST_PROFILES_PATH, LIST_MODELS_PATH, API_KEY_REGION2, profileArnCache, pendingProfileRequests, profileRegionCache, CANONICAL_MANAGEMENT_REGIONS, ENV_PROFILE_ARN, KiroManagementHttpError;
1605
1137
  var init_management = __esm({
1606
1138
  "../kiro-core/dist/management.js"() {
1607
1139
  "use strict";
@@ -1611,8 +1143,7 @@ var init_management = __esm({
1611
1143
  init_token_type();
1612
1144
  LIST_PROFILES_PATH = "List-Available-Profiles";
1613
1145
  LIST_MODELS_PATH = "List-Available-Models";
1614
- GET_PROFILE_TARGET = "AmazonCodeWhispererService.GetProfile";
1615
- API_KEY_REGION = "us-east-1";
1146
+ API_KEY_REGION2 = "us-east-1";
1616
1147
  profileArnCache = /* @__PURE__ */ new Map();
1617
1148
  pendingProfileRequests = /* @__PURE__ */ new Map();
1618
1149
  profileRegionCache = /* @__PURE__ */ new Map();
@@ -1648,9 +1179,9 @@ __export(models_exports, {
1648
1179
  updateKiroModelsCacheInProcess: () => updateKiroModelsCacheInProcess
1649
1180
  });
1650
1181
  import { randomUUID } from "node:crypto";
1651
- import { existsSync as existsSync4, readFileSync as readFileSync2, renameSync, rmSync, writeFileSync } from "node:fs";
1182
+ import { existsSync as existsSync3, readFileSync as readFileSync2, renameSync, rmSync, writeFileSync } from "node:fs";
1652
1183
  import { homedir as homedir4 } from "node:os";
1653
- import { join as join5 } from "node:path";
1184
+ import { join as join4 } from "node:path";
1654
1185
  function isRecord2(value) {
1655
1186
  return typeof value === "object" && value !== null && !Array.isArray(value);
1656
1187
  }
@@ -1702,7 +1233,7 @@ function parseManagementCache(raw) {
1702
1233
  };
1703
1234
  }
1704
1235
  function readManagementCache() {
1705
- if (!existsSync4(KIRO_MANAGEMENT_CACHE_PATH))
1236
+ if (!existsSync3(KIRO_MANAGEMENT_CACHE_PATH))
1706
1237
  return void 0;
1707
1238
  try {
1708
1239
  return parseManagementCache(readFileSync2(KIRO_MANAGEMENT_CACHE_PATH, "utf-8"));
@@ -1837,22 +1368,7 @@ function isCacheStale(region) {
1837
1368
  return !entry || Date.now() - entry.fetchedAt > CACHE_MAX_AGE_MS;
1838
1369
  }
1839
1370
  async function updateKiroModelsCache(accessToken, region, profileArn) {
1840
- const { runKiroOp: runKiroOp2 } = await Promise.resolve().then(() => (init_engine_ops(), engine_ops_exports));
1841
- await runKiroOp2("refreshModels", () => ({
1842
- accessToken,
1843
- region,
1844
- ...profileArn ? { profileArn } : {},
1845
- known: kiroModels.map((model) => ({
1846
- id: model.id,
1847
- name: model.name,
1848
- input: model.input,
1849
- ...model.firstTokenTimeout ? { firstTokenTimeout: model.firstTokenTimeout } : {}
1850
- })),
1851
- cachePath: KIRO_MANAGEMENT_CACHE_PATH
1852
- }), async () => {
1853
- await updateKiroModelsCacheInProcess(accessToken, region, profileArn);
1854
- return {};
1855
- });
1371
+ await updateKiroModelsCacheInProcess(accessToken, region, profileArn);
1856
1372
  refreshKnownModelIds(readManagementCache());
1857
1373
  }
1858
1374
  async function updateKiroModelsCacheInProcess(accessToken, region, profileArn) {
@@ -1896,7 +1412,7 @@ var init_models = __esm({
1896
1412
  init_endpoints();
1897
1413
  KIRO_MANAGEMENT_CACHE_VERSION = 1;
1898
1414
  KIRO_MANAGEMENT_CACHE_SOURCE = "ns-kiro-provider-management";
1899
- KIRO_MANAGEMENT_CACHE_PATH = join5(homedir4(), ".ns-kiro-provider-models-cache.json");
1415
+ KIRO_MANAGEMENT_CACHE_PATH = join4(homedir4(), ".ns-kiro-provider-models-cache.json");
1900
1416
  CACHE_MAX_AGE_MS = 36e5;
1901
1417
  DEFAULT_CONTEXT_WINDOW = 2e5;
1902
1418
  DEFAULT_MAX_TOKENS = 8192;
@@ -2118,254 +1634,34 @@ var init_models = __esm({
2118
1634
  }
2119
1635
  });
2120
1636
 
2121
- // ../kiro-core/dist/retry.js
2122
- function firstTokenTimeoutForModel(modelId) {
2123
- if (retryConfig.firstTokenTimeoutMs !== FIRST_TOKEN_TIMEOUT) {
2124
- return retryConfig.firstTokenTimeoutMs;
2125
- }
2126
- const model = kiroModels.find((m) => m.id === modelId);
2127
- return model?.firstTokenTimeout ?? FIRST_TOKEN_TIMEOUT;
2128
- }
2129
- function exponentialBackoff(attempt, baseMs, maxMs) {
2130
- return Math.min(baseMs * 2 ** attempt, maxMs);
2131
- }
2132
- function extractKiroReason(errorText) {
2133
- if (!errorText)
2134
- return void 0;
2135
- try {
2136
- const parsed = JSON.parse(errorText);
2137
- if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
2138
- return void 0;
2139
- const reason = parsed.reason;
2140
- return typeof reason === "string" && reason.length > 0 ? reason : void 0;
2141
- } catch {
2142
- return void 0;
2143
- }
2144
- }
2145
- function parseRetryAfterMs(headers, nowMs = Date.now()) {
2146
- const get = headers?.get?.bind(headers);
2147
- if (!get)
2148
- return void 0;
2149
- const milliseconds = nonNegativeNumber(get("retry-after-ms"));
2150
- if (milliseconds !== void 0)
2151
- return Math.round(milliseconds);
2152
- const retryAfter = get("retry-after");
2153
- if (retryAfter !== null && retryAfter.trim() !== "") {
2154
- const seconds = Number(retryAfter);
2155
- if (Number.isFinite(seconds)) {
2156
- if (seconds >= 0) {
2157
- const delayMs = seconds * 1e3;
2158
- if (Number.isFinite(delayMs))
2159
- return Math.round(delayMs);
1637
+ // ../../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
1638
+ var require_base64_js = __commonJS({
1639
+ "../../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js"(exports) {
1640
+ "use strict";
1641
+ exports.byteLength = byteLength;
1642
+ exports.toByteArray = toByteArray;
1643
+ exports.fromByteArray = fromByteArray;
1644
+ var lookup = [];
1645
+ var revLookup = [];
1646
+ var Arr = typeof Uint8Array !== "undefined" ? Uint8Array : Array;
1647
+ var code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1648
+ for (i = 0, len = code.length; i < len; ++i) {
1649
+ lookup[i] = code[i];
1650
+ revLookup[code.charCodeAt(i)] = i;
1651
+ }
1652
+ var i;
1653
+ var len;
1654
+ revLookup["-".charCodeAt(0)] = 62;
1655
+ revLookup["_".charCodeAt(0)] = 63;
1656
+ function getLens(b64) {
1657
+ var len2 = b64.length;
1658
+ if (len2 % 4 > 0) {
1659
+ throw new Error("Invalid string. Length must be a multiple of 4");
2160
1660
  }
2161
- } else {
2162
- const dateMs = Date.parse(retryAfter);
2163
- if (!Number.isNaN(dateMs))
2164
- return Math.max(0, dateMs - nowMs);
2165
- }
2166
- }
2167
- const resetAfterSeconds = nonNegativeNumber(get("x-ratelimit-reset-after"));
2168
- if (resetAfterSeconds !== void 0) {
2169
- const delayMs = resetAfterSeconds * 1e3;
2170
- if (Number.isFinite(delayMs))
2171
- return Math.round(delayMs);
2172
- }
2173
- return void 0;
2174
- }
2175
- function resolveRequestRateRetryDelay(headers, nowMs = Date.now()) {
2176
- const advertisedDelayMs = parseRetryAfterMs(headers, nowMs);
2177
- const requestedDelayMs = advertisedDelayMs ?? REQUEST_RATE_FALLBACK_DELAY_MS;
2178
- return {
2179
- delayMs: Math.min(requestedDelayMs, MAX_RETRY_DELAY),
2180
- ...advertisedDelayMs !== void 0 ? { advertisedDelayMs } : {},
2181
- capped: requestedDelayMs > MAX_RETRY_DELAY
2182
- };
2183
- }
2184
- function nonNegativeNumber(value) {
2185
- if (value === null || value.trim() === "")
2186
- return void 0;
2187
- const parsed = Number(value);
2188
- return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
2189
- }
2190
- function isTooBigError(status, errorText) {
2191
- return status === 413 || status === 400 && TOO_BIG_PATTERNS.some((p) => errorText.includes(p));
2192
- }
2193
- function isNonRetryableBodyError(errorText) {
2194
- return NON_RETRYABLE_BODY_PATTERNS.some((p) => errorText.includes(p));
2195
- }
2196
- function isCapacityError(errorText) {
2197
- return errorText.includes(CAPACITY_PATTERN);
2198
- }
2199
- var FIRST_TOKEN_TIMEOUT, REQUEST_HEADER_TIMEOUT, retryConfig, MAX_RETRY_DELAY, REQUEST_RATE_FALLBACK_DELAY_MS, KIRO_REASON_CODES, TOO_BIG_PATTERNS, NON_RETRYABLE_BODY_PATTERNS, CAPACITY_PATTERN, CAPACITY_MAX_RETRIES, CAPACITY_BASE_DELAY_MS, capacityRetryConfig;
2200
- var init_retry = __esm({
2201
- "../kiro-core/dist/retry.js"() {
2202
- "use strict";
2203
- init_models();
2204
- FIRST_TOKEN_TIMEOUT = 9e4;
2205
- REQUEST_HEADER_TIMEOUT = 9e4;
2206
- retryConfig = {
2207
- firstTokenTimeoutMs: FIRST_TOKEN_TIMEOUT,
2208
- requestHeaderTimeoutMs: REQUEST_HEADER_TIMEOUT
2209
- };
2210
- MAX_RETRY_DELAY = 1e4;
2211
- REQUEST_RATE_FALLBACK_DELAY_MS = 1e4;
2212
- KIRO_REASON_CODES = Object.freeze({
2213
- /** Request body exceeded the service's size threshold. */
2214
- CONTENT_LENGTH_EXCEEDS_THRESHOLD: "CONTENT_LENGTH_EXCEEDS_THRESHOLD",
2215
- /** Prose-only size rejection; the service sends no reason code for this one. */
2216
- INPUT_TOO_LONG: "Input is too long",
2217
- /** Monthly request quota exhausted — hard limit, not transient. */
2218
- MONTHLY_REQUEST_COUNT: "MONTHLY_REQUEST_COUNT",
2219
- /** Model capacity temporarily unavailable — transient, worth retrying. */
2220
- INSUFFICIENT_MODEL_CAPACITY: "INSUFFICIENT_MODEL_CAPACITY",
2221
- /** Short-window request throttle — retry only within the provider budget. */
2222
- USER_REQUEST_RATE_EXCEEDED: "USER_REQUEST_RATE_EXCEEDED",
2223
- /**
2224
- * Generic request-validation rejection, returned for a malformed body of any
2225
- * size (empty `content`, history referencing tools absent from the catalog).
2226
- * Not a size signal: classifying it as "too big" makes the caller compact a
2227
- * history that was never the problem, a loop it can never satisfy.
2228
- */
2229
- REQUEST_BODY_INVALID: "REQUEST_BODY_INVALID"
2230
- });
2231
- TOO_BIG_PATTERNS = Object.freeze([
2232
- KIRO_REASON_CODES.CONTENT_LENGTH_EXCEEDS_THRESHOLD,
2233
- KIRO_REASON_CODES.INPUT_TOO_LONG
2234
- ]);
2235
- NON_RETRYABLE_BODY_PATTERNS = Object.freeze([KIRO_REASON_CODES.MONTHLY_REQUEST_COUNT]);
2236
- CAPACITY_PATTERN = KIRO_REASON_CODES.INSUFFICIENT_MODEL_CAPACITY;
2237
- CAPACITY_MAX_RETRIES = 3;
2238
- CAPACITY_BASE_DELAY_MS = 5e3;
2239
- capacityRetryConfig = {
2240
- maxRetries: CAPACITY_MAX_RETRIES,
2241
- baseDelayMs: CAPACITY_BASE_DELAY_MS
2242
- };
2243
- }
2244
- });
2245
-
2246
- // ../kiro-core/dist/errors.js
2247
- function extractKiroReasonCode(errorText) {
2248
- if (!errorText)
2249
- return void 0;
2250
- const trimmed = errorText.trim();
2251
- if (trimmed.startsWith("{")) {
2252
- try {
2253
- const parsed = JSON.parse(trimmed);
2254
- const reason = parsed.reason ?? parsed.reasonCode;
2255
- if (typeof reason === "string" && reason.length > 0)
2256
- return reason;
2257
- } catch {
2258
- }
2259
- }
2260
- return REASON_CODE_MARKERS.find((code) => errorText.includes(code));
2261
- }
2262
- var REASON_CODE_MARKERS, KiroApiError;
2263
- var init_errors2 = __esm({
2264
- "../kiro-core/dist/errors.js"() {
2265
- "use strict";
2266
- init_retry();
2267
- init_retry();
2268
- REASON_CODE_MARKERS = [
2269
- KIRO_REASON_CODES.CONTENT_LENGTH_EXCEEDS_THRESHOLD,
2270
- KIRO_REASON_CODES.MONTHLY_REQUEST_COUNT,
2271
- KIRO_REASON_CODES.INSUFFICIENT_MODEL_CAPACITY,
2272
- KIRO_REASON_CODES.REQUEST_BODY_INVALID
2273
- ];
2274
- KiroApiError = class extends Error {
2275
- status;
2276
- reasonCode;
2277
- retryAfterMs;
2278
- providerAttempts;
2279
- constructor(message, status, reasonCode, retryAfterMs, providerAttempts) {
2280
- super(message);
2281
- this.status = status;
2282
- this.reasonCode = reasonCode;
2283
- this.retryAfterMs = retryAfterMs;
2284
- this.providerAttempts = providerAttempts;
2285
- this.name = "KiroApiError";
2286
- }
2287
- };
2288
- }
2289
- });
2290
-
2291
- // ../kiro-core/dist/engine-ops.js
2292
- var engine_ops_exports = {};
2293
- __export(engine_ops_exports, {
2294
- kiroErrorFromSidecar: () => kiroErrorFromSidecar,
2295
- runKiroOp: () => runKiroOp
2296
- });
2297
- function kiroErrorFromSidecar(error2) {
2298
- switch (error2.vendorError) {
2299
- case "KiroApiError":
2300
- return new KiroApiError(error2.message, error2.status ?? 0, error2.reasonCode, error2.retryAfterMs, error2.providerAttempts);
2301
- case "KiroManagementHttpError":
2302
- return new KiroManagementHttpError(error2.message, error2.status ?? 0);
2303
- case "Error":
2304
- return new Error(error2.message);
2305
- default:
2306
- return error2;
2307
- }
2308
- }
2309
- async function runKiroOp(op, request, inProcess) {
2310
- let ranInProcess = false;
2311
- const result = await engineCall({
2312
- vendor: "kiro",
2313
- op,
2314
- request: () => ({
2315
- ...request(),
2316
- profileArnCache: snapshotKiroProfileArnCache(),
2317
- profileRegions: snapshotKiroProfileRegionCache()
2318
- }),
2319
- inProcess: async () => {
2320
- ranInProcess = true;
2321
- return await inProcess();
2322
- },
2323
- mapError: kiroErrorFromSidecar
2324
- });
2325
- if (ranInProcess || !result || typeof result !== "object")
2326
- return result;
2327
- const { kiroProfileArns, kiroProfileRegions, ...rest } = result;
2328
- applyKiroProfileArnCacheChanges(kiroProfileArns);
2329
- applyKiroProfileRegionChanges(kiroProfileRegions);
2330
- return rest;
2331
- }
2332
- var init_engine_ops = __esm({
2333
- "../kiro-core/dist/engine-ops.js"() {
2334
- "use strict";
2335
- init_sidecar();
2336
- init_errors2();
2337
- init_management();
2338
- }
2339
- });
2340
-
2341
- // ../../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js
2342
- var require_base64_js = __commonJS({
2343
- "../../node_modules/.pnpm/base64-js@1.5.1/node_modules/base64-js/index.js"(exports) {
2344
- "use strict";
2345
- exports.byteLength = byteLength;
2346
- exports.toByteArray = toByteArray;
2347
- exports.fromByteArray = fromByteArray;
2348
- var lookup = [];
2349
- var revLookup = [];
2350
- var Arr = typeof Uint8Array !== "undefined" ? Uint8Array : Array;
2351
- var code = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2352
- for (i = 0, len = code.length; i < len; ++i) {
2353
- lookup[i] = code[i];
2354
- revLookup[code.charCodeAt(i)] = i;
2355
- }
2356
- var i;
2357
- var len;
2358
- revLookup["-".charCodeAt(0)] = 62;
2359
- revLookup["_".charCodeAt(0)] = 63;
2360
- function getLens(b64) {
2361
- var len2 = b64.length;
2362
- if (len2 % 4 > 0) {
2363
- throw new Error("Invalid string. Length must be a multiple of 4");
2364
- }
2365
- var validLen = b64.indexOf("=");
2366
- if (validLen === -1) validLen = len2;
2367
- var placeHoldersLen = validLen === len2 ? 0 : 4 - validLen % 4;
2368
- return [validLen, placeHoldersLen];
1661
+ var validLen = b64.indexOf("=");
1662
+ if (validLen === -1) validLen = len2;
1663
+ var placeHoldersLen = validLen === len2 ? 0 : 4 - validLen % 4;
1664
+ return [validLen, placeHoldersLen];
2369
1665
  }
2370
1666
  function byteLength(b64) {
2371
1667
  var lens = getLens(b64);
@@ -2439,393 +1735,83 @@ var require_base64_js = __commonJS({
2439
1735
  }
2440
1736
  });
2441
1737
 
2442
- // ../devin-core/dist/util.js
2443
- import { createHash as createHash4 } from "node:crypto";
2444
- function isRecord3(value) {
2445
- return typeof value === "object" && value !== null && !Array.isArray(value);
2446
- }
2447
- function sanitizeText(text) {
2448
- const wellFormed = text.toWellFormed();
2449
- const clean = wellFormed === text ? text : wellFormed.replaceAll(REPLACEMENT_CHAR, "");
2450
- return clean.replace(ANSI_PATTERN, "").replace(CONTROL_PATTERN, "");
2451
- }
2452
- function deterministicUuid(seed) {
2453
- const hex = createHash4("sha256").update(seed).digest("hex");
2454
- return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
2455
- }
2456
- function devinDebugEnabled() {
2457
- const value = process.env.NS_DEVIN_DEBUG ?? process.env.DEVIN_DEBUG;
2458
- return value !== void 0 && value !== "" && value !== "0" && value !== "false";
2459
- }
2460
- function emit(method, message, data) {
2461
- const line = data === void 0 ? `[devin] ${message}` : `[devin] ${message} ${safeJson(data)}`;
2462
- console[method === "debug" ? "error" : method](line);
1738
+ // src/compat/pi-ai.ts
1739
+ import { createAssistantMessageEventStream } from "@oh-my-pi/pi-ai";
1740
+
1741
+ // ../bridge-core/dist/pi/transcript.js
1742
+ function isSystemMessage(message) {
1743
+ return message?.role === "system";
2463
1744
  }
2464
- function safeJson(data) {
2465
- try {
2466
- return JSON.stringify(data, (_key, value) => typeof value === "bigint" ? Number(value) : value);
2467
- } catch {
1745
+ function contentText(content) {
1746
+ if (typeof content === "string")
1747
+ return content;
1748
+ if (!Array.isArray(content))
2468
1749
  return "";
2469
- }
1750
+ return content.map((part) => part && typeof part === "object" && part.type === "text" ? String(part.text ?? "") : "").filter((text) => text.length > 0).join("\n");
2470
1751
  }
2471
- function redactSensitiveCredentials(text) {
2472
- let out = text;
2473
- for (const pattern of SENSITIVE_PATTERNS) {
2474
- out = out.replace(pattern, (match) => {
2475
- const separator = match.match(/[:=\s]/)?.index ?? 0;
2476
- return `${match.slice(0, separator + 1)}[REDACTED]`;
2477
- });
1752
+ function getCurrentTools(messages) {
1753
+ const tools = /* @__PURE__ */ new Map();
1754
+ for (const message of messages) {
1755
+ if (!isSystemMessage(message))
1756
+ continue;
1757
+ for (const tool of message.toolsRemoved ?? [])
1758
+ tools.delete(tool.name);
1759
+ for (const tool of message.toolsAdded ?? [])
1760
+ tools.set(tool.name, tool);
2478
1761
  }
2479
- return out;
2480
- }
2481
- function normalizeSystemPrompts(systemPrompt) {
2482
- const prompts = systemPrompt === void 0 || systemPrompt === null ? [] : Array.isArray(systemPrompt) ? systemPrompt : typeof systemPrompt === "string" ? [systemPrompt] : [];
2483
- return prompts.map((prompt) => redactSensitiveCredentials(prompt.toWellFormed())).filter((prompt) => prompt.trim().length > 0);
1762
+ return [...tools.values()];
2484
1763
  }
2485
- var ANSI_PATTERN, CONTROL_PATTERN, REPLACEMENT_CHAR, logger, SENSITIVE_PATTERNS;
2486
- var init_util = __esm({
2487
- "../devin-core/dist/util.js"() {
2488
- "use strict";
2489
- ANSI_PATTERN = /\x1b(?:\[[0-9;?]*[ -/]*[@-~]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[@-Z\\-_])/g;
2490
- CONTROL_PATTERN = /[\x00-\x08\x0B-\x1F\x7F-\x9F]/g;
2491
- REPLACEMENT_CHAR = "\uFFFD";
2492
- logger = {
2493
- debug(message, data) {
2494
- if (devinDebugEnabled())
2495
- emit("debug", message, data);
2496
- },
2497
- warn(message, data) {
2498
- emit("warn", message, data);
2499
- },
2500
- error(message, data) {
2501
- emit("error", message, data);
2502
- }
2503
- };
2504
- SENSITIVE_PATTERNS = [
2505
- /\b(sk|pk|key|token|secret|password|bearer|api[_-]?key|credential|authorization)\s*[:=]\s*["']?[\w.$~+-]{6,}["']?/gi,
2506
- /\b(cog_|devin-session-token\$)[\w.$~+-]+/g,
2507
- /\bBearer\s+[\w.$~+-]{6,}/gi
2508
- ];
1764
+ function getCurrentSystemPrompt(messages) {
1765
+ const content = [];
1766
+ const sections = /* @__PURE__ */ new Map();
1767
+ for (const message of messages) {
1768
+ if (!isSystemMessage(message))
1769
+ continue;
1770
+ const text = contentText(message.content);
1771
+ if (text.length > 0)
1772
+ content.push(text);
1773
+ for (const [name, value] of Object.entries(message.sections ?? {})) {
1774
+ if (value === null)
1775
+ sections.delete(name);
1776
+ else
1777
+ sections.set(name, value);
1778
+ }
2509
1779
  }
2510
- });
1780
+ return [content.join("\n\n"), ...sections.values()].filter((part) => part.length > 0).join("\n\n");
1781
+ }
2511
1782
 
2512
- // ../devin-core/dist/errors.js
2513
- function devinErrorDetail(response, payload) {
2514
- let text;
2515
- try {
2516
- text = new TextDecoder("utf-8", { fatal: true }).decode(payload).trim();
2517
- } catch {
2518
- return void 0;
2519
- }
2520
- if (response.headers.get("content-type")?.toLowerCase().includes("text/html"))
2521
- return void 0;
2522
- try {
2523
- const decoded = JSON.parse(text);
2524
- if (isRecord3(decoded)) {
2525
- const error2 = decoded.error;
2526
- if (isRecord3(error2) && typeof error2.message === "string")
2527
- text = error2.message.trim();
2528
- else if (typeof error2 === "string")
2529
- text = error2.trim();
2530
- else if (typeof decoded.message === "string")
2531
- text = decoded.message.trim();
1783
+ // ../bridge-core/dist/pi/context.js
1784
+ function userContent(content) {
1785
+ if (typeof content === "string")
1786
+ return content ? [{ type: "text", text: content }] : [];
1787
+ if (!Array.isArray(content))
1788
+ return [];
1789
+ const out = [];
1790
+ for (const block of content) {
1791
+ if (block?.type === "text" && typeof block.text === "string")
1792
+ out.push({ type: "text", text: block.text });
1793
+ else if (block?.type === "image" && typeof block.data === "string") {
1794
+ out.push({ type: "image", data: block.data, mimeType: String(block.mimeType ?? "image/png") });
2532
1795
  }
2533
- } catch {
2534
- }
2535
- const normalized = text.replace(/\s+/g, " ").trim();
2536
- if (normalized.length === 0 || HTML_ERROR_BODY_PATTERN.test(normalized) || sanitizeText(normalized) !== normalized) {
2537
- return void 0;
2538
1796
  }
2539
- if (normalized.length <= MAX_DEVIN_ERROR_DETAIL_CHARS)
2540
- return normalized;
2541
- const boundaryUnit = normalized.charCodeAt(MAX_DEVIN_ERROR_DETAIL_CHARS - 1);
2542
- const cut = boundaryUnit >= 55296 && boundaryUnit <= 56319 ? MAX_DEVIN_ERROR_DETAIL_CHARS - 1 : MAX_DEVIN_ERROR_DETAIL_CHARS;
2543
- return normalized.slice(0, cut);
2544
- }
2545
- function createDevinHttpError(operation, response, payload) {
2546
- const status = `${response.status}${response.statusText ? ` ${response.statusText}` : ""}`;
2547
- const detail = devinErrorDetail(response, payload);
2548
- const headers = {};
2549
- response.headers.forEach((value, key) => {
2550
- headers[key] = value;
2551
- });
2552
- return new DevinApiError(`Devin ${operation} error ${status}${detail ? `: ${detail}` : ""}`, operation, response.status, headers);
1797
+ return out;
2553
1798
  }
2554
- function truncateTrailerEvidence(text) {
2555
- return text.length > MAX_TRAILER_EVIDENCE_CHARS ? `${text.slice(0, MAX_TRAILER_EVIDENCE_CHARS)}\u2026` : text;
1799
+ var STOP_REASONS = /* @__PURE__ */ new Set(["stop", "length", "toolUse", "error", "aborted"]);
1800
+ function parseArguments(value) {
1801
+ if (typeof value === "string") {
1802
+ try {
1803
+ const parsed = JSON.parse(value || "{}");
1804
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
1805
+ } catch {
1806
+ return {};
1807
+ }
1808
+ }
1809
+ return value && typeof value === "object" ? value : {};
2556
1810
  }
2557
- function summarizeTrailerDetails(details) {
2558
- if (!Array.isArray(details) || details.length === 0)
2559
- return void 0;
2560
- let summary = "";
2561
- for (const entry of details) {
2562
- if (!isRecord3(entry))
2563
- continue;
2564
- const type = typeof entry.type === "string" && entry.type ? entry.type : void 0;
2565
- const value = typeof entry.value === "string" && entry.value ? entry.value : void 0;
2566
- let debug;
2567
- if (entry.debug !== void 0) {
2568
- try {
2569
- debug = typeof entry.debug === "string" ? entry.debug : JSON.stringify(entry.debug);
2570
- } catch {
2571
- debug = void 0;
2572
- }
2573
- }
2574
- const boundedType = type ? truncateTrailerEvidence(type) : void 0;
2575
- const evidence = debug ?? value;
2576
- const boundedEvidence = evidence ? truncateTrailerEvidence(evidence) : void 0;
2577
- let part;
2578
- if (boundedType && boundedEvidence)
2579
- part = `${boundedType}: ${boundedEvidence}`;
2580
- else
2581
- part = boundedType ?? boundedEvidence;
2582
- if (!part)
2583
- continue;
2584
- const next = summary ? `${summary}; ${part}` : part;
2585
- if (next.length > MAX_TRAILER_EVIDENCE_CHARS)
2586
- return truncateTrailerEvidence(next);
2587
- summary = next;
2588
- }
2589
- return summary || void 0;
2590
- }
2591
- function readConnectTrailerError(text) {
2592
- if (text.length === 0)
2593
- return null;
2594
- let parsed;
2595
- try {
2596
- parsed = JSON.parse(text);
2597
- } catch {
2598
- return null;
2599
- }
2600
- if (!isRecord3(parsed) || !("error" in parsed))
2601
- return null;
2602
- const err = parsed.error;
2603
- if (!isRecord3(err))
2604
- return null;
2605
- const code = typeof err.code === "string" ? err.code : "";
2606
- const message = typeof err.message === "string" ? err.message : "";
2607
- if (!code && !message)
2608
- return null;
2609
- const trailer = {
2610
- code,
2611
- message,
2612
- formatted: `Devin stream error${code ? ` ${code}` : ""}: ${message}`,
2613
- raw: truncateTrailerEvidence(text)
2614
- };
2615
- const detail = summarizeTrailerDetails(err.details);
2616
- if (detail) {
2617
- trailer.detail = detail;
2618
- trailer.formatted += ` [details: ${detail}]`;
2619
- }
2620
- return trailer;
2621
- }
2622
- function isDevinCapacityError(error2) {
2623
- if (error2 instanceof DevinApiError)
2624
- return error2.status === 502 || error2.status === 503 || error2.status === 529;
2625
- if (error2 instanceof DevinStreamError) {
2626
- return error2.code === "unavailable" || error2.code === "deadline_exceeded" || /capacity|overload/i.test(error2.message);
2627
- }
2628
- return false;
2629
- }
2630
- var DevinApiError, DevinProtocolError, DevinStreamError, MAX_DEVIN_ERROR_DETAIL_CHARS, HTML_ERROR_BODY_PATTERN, MAX_TRAILER_EVIDENCE_CHARS;
2631
- var init_errors3 = __esm({
2632
- "../devin-core/dist/errors.js"() {
2633
- "use strict";
2634
- init_util();
2635
- DevinApiError = class extends Error {
2636
- status;
2637
- operation;
2638
- headers;
2639
- constructor(message, operation, status, headers) {
2640
- super(message);
2641
- this.name = "DevinApiError";
2642
- this.operation = operation;
2643
- this.status = status;
2644
- this.headers = headers ?? {};
2645
- }
2646
- };
2647
- DevinProtocolError = class extends Error {
2648
- kind;
2649
- constructor(message, kind = "runtime") {
2650
- super(message);
2651
- this.name = "DevinProtocolError";
2652
- this.kind = kind;
2653
- }
2654
- };
2655
- DevinStreamError = class extends Error {
2656
- code;
2657
- contextOverflow;
2658
- constructor(message, code = "", contextOverflow = false) {
2659
- super(message);
2660
- this.name = "DevinStreamError";
2661
- this.code = code;
2662
- this.contextOverflow = contextOverflow;
2663
- }
2664
- };
2665
- MAX_DEVIN_ERROR_DETAIL_CHARS = 4096;
2666
- HTML_ERROR_BODY_PATTERN = /^\s*(?:<!doctype\s+html\b|<html\b)/i;
2667
- MAX_TRAILER_EVIDENCE_CHARS = 2e3;
2668
- }
2669
- });
2670
-
2671
- // ../devin-core/dist/engine.js
2672
- function selectDevinEngine(request) {
2673
- return request.fetch ? "ts" : selectBridgeEngine(DEVIN_SIDECAR_VENDOR);
2674
- }
2675
- function toDevinSidecarRequest(request, capacityRetry) {
2676
- const { signal: _signal, fetch: _fetch, ...wire } = request;
2677
- return capacityRetry ? { ...wire, capacityRetry } : wire;
2678
- }
2679
- function devinErrorFromSidecar(error2) {
2680
- if (error2.status !== void 0) {
2681
- const headers = error2.retryAfterMs !== void 0 ? { "retry-after": String(error2.retryAfterMs / 1e3) } : {};
2682
- return new DevinApiError(error2.message, "API", error2.status, headers);
2683
- }
2684
- if (error2.kind === "protocol" && error2.reasonCode && PROTOCOL_KINDS.has(error2.reasonCode)) {
2685
- return new DevinProtocolError(error2.message, error2.reasonCode);
2686
- }
2687
- if (error2.kind === "context_overflow" || error2.kind === "capacity" || error2.kind === "rate_limit" || error2.kind === "auth" || error2.kind === "vendor") {
2688
- return new DevinStreamError(error2.message, error2.reasonCode ?? "", error2.kind === "context_overflow");
2689
- }
2690
- return error2;
2691
- }
2692
- function streamDevinOnEngine(request, capacityRetry, inProcess) {
2693
- if (request.fetch)
2694
- return inProcess(request);
2695
- return engineStream({
2696
- vendor: DEVIN_SIDECAR_VENDOR,
2697
- request: () => toDevinSidecarRequest(request, capacityRetry),
2698
- inProcess: () => inProcess(request),
2699
- mapError: devinErrorFromSidecar,
2700
- ...request.signal ? { signal: request.signal } : {}
2701
- });
2702
- }
2703
- var DEVIN_SIDECAR_VENDOR, PROTOCOL_KINDS;
2704
- var init_engine2 = __esm({
2705
- "../devin-core/dist/engine.js"() {
2706
- "use strict";
2707
- init_sidecar();
2708
- init_errors3();
2709
- DEVIN_SIDECAR_VENDOR = "devin";
2710
- PROTOCOL_KINDS = /* @__PURE__ */ new Set(["empty-body", "envelope", "runtime"]);
2711
- }
2712
- });
2713
-
2714
- // ../devin-core/dist/engine-ops.js
2715
- var engine_ops_exports2 = {};
2716
- __export(engine_ops_exports2, {
2717
- runDevinOp: () => runDevinOp
2718
- });
2719
- async function runDevinOp(options) {
2720
- let ranInProcess = false;
2721
- try {
2722
- const result = await engineCall({
2723
- vendor: DEVIN_SIDECAR_VENDOR,
2724
- op: options.op,
2725
- request: options.request,
2726
- inProcess: async () => {
2727
- ranInProcess = true;
2728
- return options.inProcess();
2729
- },
2730
- mapError: devinErrorFromSidecar,
2731
- ...options.signal ? { signal: options.signal } : {}
2732
- });
2733
- return ranInProcess ? result : options.fromWire(result);
2734
- } catch (error2) {
2735
- if (ranInProcess)
2736
- throw error2;
2737
- logger.warn(`Devin ${options.op} sidecar call failed`, {
2738
- error: error2 instanceof Error ? error2.name : "unknown"
2739
- });
2740
- return options.fallback;
2741
- }
2742
- }
2743
- var init_engine_ops2 = __esm({
2744
- "../devin-core/dist/engine-ops.js"() {
2745
- "use strict";
2746
- init_sidecar();
2747
- init_engine2();
2748
- init_util();
2749
- }
2750
- });
2751
-
2752
- // src/compat/pi-ai.ts
2753
- import { createAssistantMessageEventStream } from "@oh-my-pi/pi-ai";
2754
-
2755
- // ../bridge-core/dist/pi/transcript.js
2756
- function isSystemMessage(message) {
2757
- return message?.role === "system";
2758
- }
2759
- function contentText(content) {
2760
- if (typeof content === "string")
2761
- return content;
2762
- if (!Array.isArray(content))
2763
- return "";
2764
- return content.map((part) => part && typeof part === "object" && part.type === "text" ? String(part.text ?? "") : "").filter((text) => text.length > 0).join("\n");
2765
- }
2766
- function getCurrentTools(messages) {
2767
- const tools = /* @__PURE__ */ new Map();
2768
- for (const message of messages) {
2769
- if (!isSystemMessage(message))
2770
- continue;
2771
- for (const tool of message.toolsRemoved ?? [])
2772
- tools.delete(tool.name);
2773
- for (const tool of message.toolsAdded ?? [])
2774
- tools.set(tool.name, tool);
2775
- }
2776
- return [...tools.values()];
2777
- }
2778
- function getCurrentSystemPrompt(messages) {
2779
- const content = [];
2780
- const sections = /* @__PURE__ */ new Map();
2781
- for (const message of messages) {
2782
- if (!isSystemMessage(message))
2783
- continue;
2784
- const text = contentText(message.content);
2785
- if (text.length > 0)
2786
- content.push(text);
2787
- for (const [name, value] of Object.entries(message.sections ?? {})) {
2788
- if (value === null)
2789
- sections.delete(name);
2790
- else
2791
- sections.set(name, value);
2792
- }
2793
- }
2794
- return [content.join("\n\n"), ...sections.values()].filter((part) => part.length > 0).join("\n\n");
2795
- }
2796
-
2797
- // ../bridge-core/dist/pi/context.js
2798
- function userContent(content) {
2799
- if (typeof content === "string")
2800
- return content ? [{ type: "text", text: content }] : [];
2801
- if (!Array.isArray(content))
2802
- return [];
2803
- const out = [];
2804
- for (const block of content) {
2805
- if (block?.type === "text" && typeof block.text === "string")
2806
- out.push({ type: "text", text: block.text });
2807
- else if (block?.type === "image" && typeof block.data === "string") {
2808
- out.push({ type: "image", data: block.data, mimeType: String(block.mimeType ?? "image/png") });
2809
- }
2810
- }
2811
- return out;
2812
- }
2813
- var STOP_REASONS = /* @__PURE__ */ new Set(["stop", "length", "toolUse", "error", "aborted"]);
2814
- function parseArguments(value) {
2815
- if (typeof value === "string") {
2816
- try {
2817
- const parsed = JSON.parse(value || "{}");
2818
- return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
2819
- } catch {
2820
- return {};
2821
- }
2822
- }
2823
- return value && typeof value === "object" ? value : {};
2824
- }
2825
- function toBridgeMessages(messages) {
2826
- const out = [];
2827
- for (const message of messages) {
2828
- if (message.role === "system")
1811
+ function toBridgeMessages(messages) {
1812
+ const out = [];
1813
+ for (const message of messages) {
1814
+ if (message.role === "system")
2829
1815
  continue;
2830
1816
  if (message.role === "user" || message.role === "developer") {
2831
1817
  out.push({ role: "user", content: userContent(message.content) });
@@ -3327,245 +2313,471 @@ init_debug();
3327
2313
  init_effort();
3328
2314
  init_endpoints();
3329
2315
 
3330
- // ../kiro-core/dist/engine.js
3331
- init_sidecar();
3332
- init_debug();
3333
- init_endpoints();
3334
- init_engine_ops();
3335
- init_management();
3336
- init_models();
3337
- init_retry();
3338
-
3339
- // ../kiro-core/dist/stream.js
3340
- import { createHash as createHash3 } from "node:crypto";
3341
- init_debug();
3342
- init_effort();
3343
- init_endpoints();
3344
- init_errors2();
3345
- init_kiro_cli();
3346
- init_management();
2316
+ // ../kiro-core/dist/retry.js
3347
2317
  init_models();
3348
- init_oauth();
3349
-
3350
- // ../kiro-core/dist/request-builder.js
3351
- init_debug();
3352
-
3353
- // ../kiro-core/dist/history.js
3354
- var HISTORY_LIMIT = 85e4;
3355
- var HISTORY_LIMIT_CONTEXT_WINDOW = 2e5;
3356
- var HISTORY_IMAGE_BASE64_LIMIT = 512 * 1024;
3357
- function stripHistoryImages(history, keepNewestBounded = true) {
3358
- let newestImageIndex = -1;
3359
- for (let index = history.length - 1; index >= 0; index--) {
3360
- if ((history[index]?.userInputMessage?.images?.length ?? 0) > 0) {
3361
- newestImageIndex = index;
3362
- break;
3363
- }
2318
+ var FIRST_TOKEN_TIMEOUT = 9e4;
2319
+ var REQUEST_HEADER_TIMEOUT = 9e4;
2320
+ function firstTokenTimeoutForModel(modelId) {
2321
+ if (retryConfig.firstTokenTimeoutMs !== FIRST_TOKEN_TIMEOUT) {
2322
+ return retryConfig.firstTokenTimeoutMs;
3364
2323
  }
3365
- const newestImages = newestImageIndex >= 0 ? history[newestImageIndex]?.userInputMessage?.images : void 0;
3366
- const keepNewest = keepNewestBounded && newestImages !== void 0 && newestImages.reduce((size, image) => size + image.source.bytes.length, 0) <= HISTORY_IMAGE_BASE64_LIMIT;
3367
- return history.map((entry, index) => {
3368
- if (!entry.userInputMessage?.images || index === newestImageIndex && keepNewest)
3369
- return entry;
3370
- const { images: _images, ...rest } = entry.userInputMessage;
3371
- return { ...entry, userInputMessage: { ...rest } };
3372
- });
2324
+ const model = kiroModels.find((m) => m.id === modelId);
2325
+ return model?.firstTokenTimeout ?? FIRST_TOKEN_TIMEOUT;
3373
2326
  }
3374
- function sanitizeHistory(history) {
3375
- while (history.length > 0 && (!history[0]?.userInputMessage || history[0].userInputMessage.userInputMessageContext?.toolResults))
3376
- history = history.slice(1);
3377
- const result = [];
3378
- for (let i = 0; i < history.length; i++) {
3379
- const m = history[i];
3380
- if (!m)
3381
- continue;
3382
- if (m.assistantResponseMessage && !m.assistantResponseMessage.toolUses && !m.assistantResponseMessage.content)
3383
- continue;
3384
- if (m.assistantResponseMessage?.toolUses) {
3385
- const next = history[i + 1];
3386
- if (next?.userInputMessage?.userInputMessageContext?.toolResults)
3387
- result.push(m);
3388
- } else if (m.userInputMessage?.userInputMessageContext?.toolResults) {
3389
- const prev = result[result.length - 1];
3390
- if (prev?.assistantResponseMessage?.toolUses)
3391
- result.push(m);
3392
- } else {
3393
- result.push(m);
3394
- }
2327
+ var retryConfig = {
2328
+ firstTokenTimeoutMs: FIRST_TOKEN_TIMEOUT,
2329
+ requestHeaderTimeoutMs: REQUEST_HEADER_TIMEOUT
2330
+ };
2331
+ function exponentialBackoff(attempt, baseMs, maxMs) {
2332
+ return Math.min(baseMs * 2 ** attempt, maxMs);
2333
+ }
2334
+ var MAX_RETRY_DELAY = 1e4;
2335
+ var REQUEST_RATE_FALLBACK_DELAY_MS = 1e4;
2336
+ function extractKiroReason(errorText) {
2337
+ if (!errorText)
2338
+ return void 0;
2339
+ try {
2340
+ const parsed = JSON.parse(errorText);
2341
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
2342
+ return void 0;
2343
+ const reason = parsed.reason;
2344
+ return typeof reason === "string" && reason.length > 0 ? reason : void 0;
2345
+ } catch {
2346
+ return void 0;
3395
2347
  }
3396
- return result;
3397
2348
  }
3398
- function injectSyntheticToolCalls(history) {
3399
- const validIds = /* @__PURE__ */ new Set();
3400
- for (const entry of history) {
3401
- for (const tu of entry.assistantResponseMessage?.toolUses ?? []) {
3402
- if (tu.toolUseId)
3403
- validIds.add(tu.toolUseId);
3404
- }
3405
- }
3406
- const result = [];
3407
- for (const entry of history) {
3408
- const toolResults = entry.userInputMessage?.userInputMessageContext?.toolResults;
3409
- if (toolResults) {
3410
- const orphaned = toolResults.filter((tr) => !validIds.has(tr.toolUseId));
3411
- if (orphaned.length > 0) {
3412
- result.push({
3413
- assistantResponseMessage: {
3414
- content: "Tool calls were made.",
3415
- toolUses: orphaned.map((tr) => ({ name: "unknown_tool", toolUseId: tr.toolUseId, input: {} }))
3416
- }
3417
- });
3418
- for (const tr of orphaned)
3419
- validIds.add(tr.toolUseId);
2349
+ function parseRetryAfterMs(headers, nowMs = Date.now()) {
2350
+ const get = headers?.get?.bind(headers);
2351
+ if (!get)
2352
+ return void 0;
2353
+ const milliseconds = nonNegativeNumber(get("retry-after-ms"));
2354
+ if (milliseconds !== void 0)
2355
+ return Math.round(milliseconds);
2356
+ const retryAfter = get("retry-after");
2357
+ if (retryAfter !== null && retryAfter.trim() !== "") {
2358
+ const seconds = Number(retryAfter);
2359
+ if (Number.isFinite(seconds)) {
2360
+ if (seconds >= 0) {
2361
+ const delayMs = seconds * 1e3;
2362
+ if (Number.isFinite(delayMs))
2363
+ return Math.round(delayMs);
3420
2364
  }
2365
+ } else {
2366
+ const dateMs = Date.parse(retryAfter);
2367
+ if (!Number.isNaN(dateMs))
2368
+ return Math.max(0, dateMs - nowMs);
3421
2369
  }
3422
- result.push(entry);
3423
- }
3424
- return result;
3425
- }
3426
- function prepareHistory(history, keepNewestBoundedImage = true) {
3427
- return injectSyntheticToolCalls(sanitizeHistory(stripHistoryImages(history, keepNewestBoundedImage)));
3428
- }
3429
- function assertHistoryWithinLimit(history, limit) {
3430
- const size = JSON.stringify(history).length;
3431
- if (size > limit) {
3432
- throw new Error(`Kiro API error: context_length_exceeded (local history ${size} chars / ${history.length} entries exceeds ${limit}-char limit)`);
3433
2370
  }
3434
- }
3435
- function extractToolNamesFromHistory(history) {
3436
- const names = /* @__PURE__ */ new Set();
3437
- for (const entry of history) {
3438
- for (const tu of entry.assistantResponseMessage?.toolUses ?? []) {
3439
- if (tu.name)
3440
- names.add(tu.name);
3441
- }
2371
+ const resetAfterSeconds = nonNegativeNumber(get("x-ratelimit-reset-after"));
2372
+ if (resetAfterSeconds !== void 0) {
2373
+ const delayMs = resetAfterSeconds * 1e3;
2374
+ if (Number.isFinite(delayMs))
2375
+ return Math.round(delayMs);
3442
2376
  }
3443
- return names;
2377
+ return void 0;
3444
2378
  }
3445
- function addPlaceholderTools(tools, history) {
3446
- const historyNames = extractToolNamesFromHistory(history);
3447
- if (historyNames.size === 0)
3448
- return tools;
3449
- const existing = new Set(tools.map((t) => t.toolSpecification?.name).filter(Boolean));
3450
- const missing = Array.from(historyNames).filter((n) => !existing.has(n));
3451
- if (missing.length === 0)
3452
- return tools;
3453
- return [
3454
- ...tools,
3455
- ...missing.map((name) => ({
3456
- toolSpecification: {
3457
- name,
3458
- description: "Tool",
3459
- inputSchema: { json: { type: "object", properties: {} } }
3460
- }
3461
- }))
3462
- ];
2379
+ function resolveRequestRateRetryDelay(headers, nowMs = Date.now()) {
2380
+ const advertisedDelayMs = parseRetryAfterMs(headers, nowMs);
2381
+ const requestedDelayMs = advertisedDelayMs ?? REQUEST_RATE_FALLBACK_DELAY_MS;
2382
+ return {
2383
+ delayMs: Math.min(requestedDelayMs, MAX_RETRY_DELAY),
2384
+ ...advertisedDelayMs !== void 0 ? { advertisedDelayMs } : {},
2385
+ capped: requestedDelayMs > MAX_RETRY_DELAY
2386
+ };
3463
2387
  }
3464
-
3465
- // ../kiro-core/dist/transform.js
3466
- import { createHash as createHash2 } from "node:crypto";
3467
- var TOOL_RESULT_LIMIT = 25e4;
3468
- var EMPTY_CONTENT_PLACEHOLDER = "Please proceed with the task.";
3469
- function sanitizeSurrogates(text) {
3470
- return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
2388
+ function nonNegativeNumber(value) {
2389
+ if (value === null || value.trim() === "")
2390
+ return void 0;
2391
+ const parsed = Number(value);
2392
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : void 0;
3471
2393
  }
3472
- function truncate(text, limit) {
3473
- if (text.length <= limit)
3474
- return text;
3475
- const half = Math.floor(limit / 2);
3476
- return `${text.substring(0, half)}
3477
- ... [TRUNCATED] ...
3478
- ${text.substring(text.length - half)}`;
2394
+ var KIRO_REASON_CODES = Object.freeze({
2395
+ /** Request body exceeded the service's size threshold. */
2396
+ CONTENT_LENGTH_EXCEEDS_THRESHOLD: "CONTENT_LENGTH_EXCEEDS_THRESHOLD",
2397
+ /** Prose-only size rejection; the service sends no reason code for this one. */
2398
+ INPUT_TOO_LONG: "Input is too long",
2399
+ /** Monthly request quota exhausted — hard limit, not transient. */
2400
+ MONTHLY_REQUEST_COUNT: "MONTHLY_REQUEST_COUNT",
2401
+ /** Model capacity temporarily unavailable — transient, worth retrying. */
2402
+ INSUFFICIENT_MODEL_CAPACITY: "INSUFFICIENT_MODEL_CAPACITY",
2403
+ /** Short-window request throttle — retry only within the provider budget. */
2404
+ USER_REQUEST_RATE_EXCEEDED: "USER_REQUEST_RATE_EXCEEDED",
2405
+ /**
2406
+ * Generic request-validation rejection, returned for a malformed body of any
2407
+ * size (empty `content`, history referencing tools absent from the catalog).
2408
+ * Not a size signal: classifying it as "too big" makes the caller compact a
2409
+ * history that was never the problem, a loop it can never satisfy.
2410
+ */
2411
+ REQUEST_BODY_INVALID: "REQUEST_BODY_INVALID"
2412
+ });
2413
+ var TOO_BIG_PATTERNS = Object.freeze([
2414
+ KIRO_REASON_CODES.CONTENT_LENGTH_EXCEEDS_THRESHOLD,
2415
+ KIRO_REASON_CODES.INPUT_TOO_LONG
2416
+ ]);
2417
+ var NON_RETRYABLE_BODY_PATTERNS = Object.freeze([KIRO_REASON_CODES.MONTHLY_REQUEST_COUNT]);
2418
+ var CAPACITY_PATTERN = KIRO_REASON_CODES.INSUFFICIENT_MODEL_CAPACITY;
2419
+ var CAPACITY_MAX_RETRIES = 3;
2420
+ var CAPACITY_BASE_DELAY_MS = 5e3;
2421
+ var capacityRetryConfig = {
2422
+ maxRetries: CAPACITY_MAX_RETRIES,
2423
+ baseDelayMs: CAPACITY_BASE_DELAY_MS
2424
+ };
2425
+ function isTooBigError(status, errorText) {
2426
+ return status === 413 || status === 400 && TOO_BIG_PATTERNS.some((p) => errorText.includes(p));
3479
2427
  }
3480
- var KIRO_TOOL_USE_ID_PATTERN = /^[a-zA-Z0-9_.:-]{1,64}$/;
3481
- function toKiroToolUseId(toolUseId) {
3482
- const id = typeof toolUseId === "string" ? toolUseId : String(toolUseId);
3483
- if (KIRO_TOOL_USE_ID_PATTERN.test(id))
3484
- return id;
3485
- const digest = createHash2("sha256").update(id).digest("base64url").slice(0, 32);
3486
- return `pi_${digest}`;
2428
+ function isNonRetryableBodyError(errorText) {
2429
+ return NON_RETRYABLE_BODY_PATTERNS.some((p) => errorText.includes(p));
3487
2430
  }
3488
- var KIRO_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]{1,64}$/;
3489
- function toKiroToolName(name) {
3490
- const str2 = typeof name === "string" ? name : String(name);
3491
- if (KIRO_TOOL_NAME_PATTERN.test(str2))
3492
- return str2;
3493
- const clean = str2.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 55);
3494
- const digest = createHash2("sha256").update(str2).digest("base64url").slice(0, 8);
3495
- return `${clean || "tool"}_${digest}`;
2431
+ function isCapacityError(errorText) {
2432
+ return errorText.includes(CAPACITY_PATTERN);
3496
2433
  }
3497
- function kiroToolNameAliases(tools) {
3498
- const aliases = /* @__PURE__ */ new Map();
3499
- for (const tool of tools ?? []) {
3500
- const wire = toKiroToolName(tool.name);
3501
- if (wire !== tool.name)
3502
- aliases.set(wire, tool.name);
2434
+
2435
+ // ../kiro-core/dist/errors.js
2436
+ var REASON_CODE_MARKERS = [
2437
+ KIRO_REASON_CODES.CONTENT_LENGTH_EXCEEDS_THRESHOLD,
2438
+ KIRO_REASON_CODES.MONTHLY_REQUEST_COUNT,
2439
+ KIRO_REASON_CODES.INSUFFICIENT_MODEL_CAPACITY,
2440
+ KIRO_REASON_CODES.REQUEST_BODY_INVALID
2441
+ ];
2442
+ var KiroApiError = class extends Error {
2443
+ status;
2444
+ reasonCode;
2445
+ retryAfterMs;
2446
+ providerAttempts;
2447
+ constructor(message, status, reasonCode, retryAfterMs, providerAttempts) {
2448
+ super(message);
2449
+ this.status = status;
2450
+ this.reasonCode = reasonCode;
2451
+ this.retryAfterMs = retryAfterMs;
2452
+ this.providerAttempts = providerAttempts;
2453
+ this.name = "KiroApiError";
3503
2454
  }
3504
- return aliases;
3505
- }
3506
- function normalizeMessages(messages) {
3507
- return messages.filter((msg) => {
3508
- if (msg.role !== "assistant")
3509
- return true;
3510
- return msg.stopReason !== "error" && msg.stopReason !== "aborted";
3511
- });
3512
- }
3513
- function relocateDisplacedToolResults(messages) {
3514
- const out = [];
3515
- const pending = [...messages];
3516
- while (pending.length > 0) {
3517
- const msg = pending.shift();
3518
- if (!msg)
3519
- break;
3520
- out.push(msg);
3521
- if (msg.role !== "assistant")
3522
- continue;
3523
- for (const block of msg.content) {
3524
- if (block.type !== "toolCall")
3525
- continue;
3526
- const id = block.id;
3527
- const at = pending.findIndex((p) => p.role === "toolResult" && p.toolCallId === id);
3528
- if (at >= 0)
3529
- out.push(...pending.splice(at, 1));
2455
+ };
2456
+ function extractKiroReasonCode(errorText) {
2457
+ if (!errorText)
2458
+ return void 0;
2459
+ const trimmed = errorText.trim();
2460
+ if (trimmed.startsWith("{")) {
2461
+ try {
2462
+ const parsed = JSON.parse(trimmed);
2463
+ const reason = parsed.reason ?? parsed.reasonCode;
2464
+ if (typeof reason === "string" && reason.length > 0)
2465
+ return reason;
2466
+ } catch {
3530
2467
  }
3531
2468
  }
3532
- return out;
2469
+ return REASON_CODE_MARKERS.find((code) => errorText.includes(code));
3533
2470
  }
3534
- function extractImages(msg) {
3535
- return msg.content.filter((c) => c.type === "image");
2471
+
2472
+ // ../kiro-core/dist/event-parser.js
2473
+ var KIRO_EVENT_KEYS = [
2474
+ "assistantResponseEvent",
2475
+ "codeReferenceEvent",
2476
+ "contextUsageEvent",
2477
+ "documentCitationEvent",
2478
+ "error",
2479
+ "metadataEvent",
2480
+ "meteringEvent",
2481
+ "reasoningContentEvent",
2482
+ "serviceUnavailableError",
2483
+ "throttlingError",
2484
+ "toolResultEvent",
2485
+ "toolUseEvent",
2486
+ "validationError"
2487
+ ];
2488
+ var KIRO_EVENT_KEY_SET = new Set(KIRO_EVENT_KEYS);
2489
+ var KIRO_ERROR_MEMBERS = {
2490
+ error: { kind: "internalServer", exception: "InternalServerException" },
2491
+ throttlingError: { kind: "throttling", exception: "ThrottlingException" },
2492
+ validationError: { kind: "validation", exception: "ValidationException" },
2493
+ serviceUnavailableError: { kind: "serviceUnavailable", exception: "ServiceUnavailableException" }
2494
+ };
2495
+ var KIRO_ERROR_TOKENS = {
2496
+ ...KIRO_ERROR_MEMBERS,
2497
+ InternalServerException: KIRO_ERROR_MEMBERS.error,
2498
+ ThrottlingException: KIRO_ERROR_MEMBERS.throttlingError,
2499
+ ValidationException: KIRO_ERROR_MEMBERS.validationError,
2500
+ ServiceUnavailableException: KIRO_ERROR_MEMBERS.serviceUnavailableError
2501
+ };
2502
+ function lookupKiroErrorMember(key) {
2503
+ return Object.hasOwn(KIRO_ERROR_TOKENS, key) ? KIRO_ERROR_TOKENS[key] : void 0;
3536
2504
  }
3537
- function getContentText(msg) {
3538
- return msg.content.map((c) => {
3539
- if (c.type === "text")
3540
- return c.text;
3541
- if (c.type === "thinking")
3542
- return c.thinking;
3543
- return "";
3544
- }).join("");
2505
+ var num = (v) => typeof v === "number" ? v : void 0;
2506
+ var str = (v) => typeof v === "string" ? v : void 0;
2507
+ function tokenCount(value) {
2508
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
3545
2509
  }
3546
- function toKiroInputSchema(parameters) {
3547
- if (parameters && typeof parameters === "object" && !Array.isArray(parameters)) {
3548
- return parameters.type === void 0 ? { type: "object", ...parameters } : parameters;
2510
+ function firstTokenCount(source, keys) {
2511
+ for (const key of keys) {
2512
+ const count = tokenCount(source[key]);
2513
+ if (count !== void 0)
2514
+ return count;
3549
2515
  }
3550
- return { type: "object", properties: {} };
3551
- }
3552
- function toKiroToolDescription(description) {
3553
- if (typeof description === "string")
3554
- return description === "" ? {} : { description };
3555
- return description == null ? {} : { description: String(description) };
3556
- }
3557
- function convertToolsToKiro(tools) {
3558
- return tools.map((tool) => ({
3559
- toolSpecification: {
3560
- name: toKiroToolName(tool.name),
3561
- ...toKiroToolDescription(tool.description),
3562
- inputSchema: { json: toKiroInputSchema(tool.parameters) }
3563
- }
3564
- }));
2516
+ return void 0;
3565
2517
  }
3566
- var KIRO_IMAGE_FORMAT_ALIASES = {
3567
- png: "png",
3568
- "x-png": "png",
2518
+ var CACHE_READ_KEYS = ["cacheReadInputTokens", "cache_read_input_tokens", "cacheReadTokens"];
2519
+ var CACHE_WRITE_KEYS = [
2520
+ "cacheWriteInputTokens",
2521
+ "cache_creation_input_tokens",
2522
+ "cacheCreationInputTokens",
2523
+ "cacheWriteTokens"
2524
+ ];
2525
+ function toolInput(raw) {
2526
+ if (typeof raw === "string")
2527
+ return raw;
2528
+ if (raw && typeof raw === "object" && Object.keys(raw).length > 0) {
2529
+ return JSON.stringify(raw);
2530
+ }
2531
+ return "";
2532
+ }
2533
+ function parseToolUse(parsed) {
2534
+ if (parsed.name && parsed.toolUseId) {
2535
+ return {
2536
+ type: "toolUse",
2537
+ data: {
2538
+ name: parsed.name,
2539
+ toolUseId: parsed.toolUseId,
2540
+ input: toolInput(parsed.input),
2541
+ stop: parsed.stop
2542
+ }
2543
+ };
2544
+ }
2545
+ if (parsed.input !== void 0) {
2546
+ return { type: "toolUseInput", data: { input: toolInput(parsed.input) } };
2547
+ }
2548
+ if (parsed.stop !== void 0)
2549
+ return { type: "toolUseStop", data: { stop: parsed.stop } };
2550
+ return null;
2551
+ }
2552
+ function parseMetadata(parsed) {
2553
+ const tu = parsed.tokenUsage ?? {};
2554
+ const data = {
2555
+ inputTokens: tokenCount(tu.uncachedInputTokens) ?? tokenCount(tu.inputTokens),
2556
+ outputTokens: tokenCount(tu.outputTokens),
2557
+ totalTokens: tokenCount(tu.totalTokens),
2558
+ cacheReadInputTokens: firstTokenCount(tu, CACHE_READ_KEYS),
2559
+ cacheWriteInputTokens: firstTokenCount(tu, CACHE_WRITE_KEYS),
2560
+ contextUsagePercentage: num(tu.contextUsagePercentage),
2561
+ normalizedTokenUsage: num(tu.normalizedTokenUsage),
2562
+ rawStopReason: str(parsed.stopReason),
2563
+ stopDetails: parsed.stopDetails && typeof parsed.stopDetails === "object" ? parsed.stopDetails : void 0
2564
+ };
2565
+ for (const k of Object.keys(data)) {
2566
+ if (data[k] === void 0)
2567
+ delete data[k];
2568
+ }
2569
+ return Object.keys(data).length > 0 ? { type: "usage", data } : null;
2570
+ }
2571
+ function parseError(parsed, kind, fallbackName) {
2572
+ const rawError = parsed.error ?? parsed.Error;
2573
+ const error2 = typeof rawError === "string" ? rawError : rawError !== void 0 ? JSON.stringify(rawError) : str(parsed.name) ?? fallbackName;
2574
+ const message = parsed.message ?? parsed.Message ?? parsed.reason;
2575
+ const data = { error: error2, kind };
2576
+ if (typeof message === "string")
2577
+ data.message = message;
2578
+ const reason = str(parsed.reason);
2579
+ if (reason !== void 0)
2580
+ data.reason = reason;
2581
+ const retryAfterMilliseconds = num(parsed.retryAfterMilliseconds);
2582
+ if (retryAfterMilliseconds !== void 0)
2583
+ data.retryAfterMilliseconds = retryAfterMilliseconds;
2584
+ return { type: "error", data };
2585
+ }
2586
+ function parseKiroEvent(key, parsed) {
2587
+ switch (key) {
2588
+ case "assistantResponseEvent": {
2589
+ const content = str(parsed.content);
2590
+ return content !== void 0 ? { type: "content", data: content } : null;
2591
+ }
2592
+ case "reasoningContentEvent": {
2593
+ const text = str(parsed.text);
2594
+ if (text !== void 0)
2595
+ return { type: "thinkingText", data: text };
2596
+ const signature = str(parsed.signature);
2597
+ if (signature !== void 0)
2598
+ return { type: "thinkingSignature", data: signature };
2599
+ return { type: "ignored", data: { key } };
2600
+ }
2601
+ case "toolUseEvent":
2602
+ return parseToolUse(parsed);
2603
+ case "contextUsageEvent": {
2604
+ const pct = num(parsed.contextUsagePercentage);
2605
+ return pct !== void 0 ? { type: "contextUsage", data: { contextUsagePercentage: pct } } : null;
2606
+ }
2607
+ case "metadataEvent":
2608
+ return parseMetadata(parsed);
2609
+ case "meteringEvent":
2610
+ return {
2611
+ type: "metering",
2612
+ data: { credits: tokenCount(parsed.usage), unit: str(parsed.unit), unitPlural: str(parsed.unitPlural) }
2613
+ };
2614
+ // Reachable when a member that models an exception is delivered as an
2615
+ // ordinary event frame. The real wire uses exception framing, handled by
2616
+ // parseKiroExceptionFrame, but both routes must agree.
2617
+ case "error":
2618
+ case "throttlingError":
2619
+ case "validationError":
2620
+ case "serviceUnavailableError": {
2621
+ const member = lookupKiroErrorMember(key);
2622
+ return parseError(parsed, member.kind, member.exception);
2623
+ }
2624
+ // Known members with no consumer yet: explicitly ignored, not unparseable.
2625
+ case "codeReferenceEvent":
2626
+ case "documentCitationEvent":
2627
+ case "toolResultEvent":
2628
+ return { type: "ignored", data: { key } };
2629
+ default: {
2630
+ const member = lookupKiroErrorMember(key);
2631
+ if (member)
2632
+ return parseError(parsed, member.kind, member.exception);
2633
+ return parseKiroEventByShape(parsed);
2634
+ }
2635
+ }
2636
+ }
2637
+ function parseKiroExceptionFrame(key, parsed) {
2638
+ const member = lookupKiroErrorMember(key);
2639
+ if (!member)
2640
+ return null;
2641
+ const event = parseError(parsed, member.kind, member.exception);
2642
+ return event.data;
2643
+ }
2644
+ function parseKiroEventByShape(parsed) {
2645
+ if (parsed.content !== void 0)
2646
+ return { type: "content", data: parsed.content };
2647
+ if (typeof parsed.text === "string")
2648
+ return { type: "thinkingText", data: parsed.text };
2649
+ if (typeof parsed.signature === "string")
2650
+ return { type: "thinkingSignature", data: parsed.signature };
2651
+ if (parsed.name && parsed.toolUseId)
2652
+ return parseToolUse(parsed);
2653
+ if (parsed.input !== void 0 && !parsed.name) {
2654
+ return { type: "toolUseInput", data: { input: toolInput(parsed.input) } };
2655
+ }
2656
+ if (parsed.stop !== void 0 && parsed.contextUsagePercentage === void 0)
2657
+ return { type: "toolUseStop", data: { stop: parsed.stop } };
2658
+ if (parsed.contextUsagePercentage !== void 0)
2659
+ return { type: "contextUsage", data: { contextUsagePercentage: parsed.contextUsagePercentage } };
2660
+ if (parsed.followupPrompt !== void 0)
2661
+ return { type: "followupPrompt", data: parsed.followupPrompt };
2662
+ if (parsed.tokenUsage !== void 0 || parsed.stopReason !== void 0 || parsed.stopDetails !== void 0) {
2663
+ return parseMetadata(parsed);
2664
+ }
2665
+ if (parsed.error !== void 0 || parsed.Error !== void 0) {
2666
+ return parseError(parsed, "unknown", "unknown");
2667
+ }
2668
+ if (typeof parsed.usage === "number") {
2669
+ return {
2670
+ type: "metering",
2671
+ data: { credits: tokenCount(parsed.usage), unit: str(parsed.unit), unitPlural: str(parsed.unitPlural) }
2672
+ };
2673
+ }
2674
+ return null;
2675
+ }
2676
+
2677
+ // ../kiro-core/dist/transform.js
2678
+ import { createHash as createHash2 } from "node:crypto";
2679
+ var TOOL_RESULT_LIMIT = 25e4;
2680
+ var EMPTY_CONTENT_PLACEHOLDER = "Please proceed with the task.";
2681
+ function sanitizeSurrogates(text) {
2682
+ return text.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g, "");
2683
+ }
2684
+ function truncate(text, limit) {
2685
+ if (text.length <= limit)
2686
+ return text;
2687
+ const half = Math.floor(limit / 2);
2688
+ return `${text.substring(0, half)}
2689
+ ... [TRUNCATED] ...
2690
+ ${text.substring(text.length - half)}`;
2691
+ }
2692
+ var KIRO_TOOL_USE_ID_PATTERN = /^[a-zA-Z0-9_.:-]{1,64}$/;
2693
+ function toKiroToolUseId(toolUseId) {
2694
+ const id = typeof toolUseId === "string" ? toolUseId : String(toolUseId);
2695
+ if (KIRO_TOOL_USE_ID_PATTERN.test(id))
2696
+ return id;
2697
+ const digest = createHash2("sha256").update(id).digest("base64url").slice(0, 32);
2698
+ return `pi_${digest}`;
2699
+ }
2700
+ var KIRO_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]{1,64}$/;
2701
+ function toKiroToolName(name) {
2702
+ const str2 = typeof name === "string" ? name : String(name);
2703
+ if (KIRO_TOOL_NAME_PATTERN.test(str2))
2704
+ return str2;
2705
+ const clean = str2.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 55);
2706
+ const digest = createHash2("sha256").update(str2).digest("base64url").slice(0, 8);
2707
+ return `${clean || "tool"}_${digest}`;
2708
+ }
2709
+ function kiroToolNameAliases(tools) {
2710
+ const aliases = /* @__PURE__ */ new Map();
2711
+ for (const tool of tools ?? []) {
2712
+ const wire = toKiroToolName(tool.name);
2713
+ if (wire !== tool.name)
2714
+ aliases.set(wire, tool.name);
2715
+ }
2716
+ return aliases;
2717
+ }
2718
+ function normalizeMessages(messages) {
2719
+ return messages.filter((msg) => {
2720
+ if (msg.role !== "assistant")
2721
+ return true;
2722
+ return msg.stopReason !== "error" && msg.stopReason !== "aborted";
2723
+ });
2724
+ }
2725
+ function relocateDisplacedToolResults(messages) {
2726
+ const out = [];
2727
+ const pending = [...messages];
2728
+ while (pending.length > 0) {
2729
+ const msg = pending.shift();
2730
+ if (!msg)
2731
+ break;
2732
+ out.push(msg);
2733
+ if (msg.role !== "assistant")
2734
+ continue;
2735
+ for (const block of msg.content) {
2736
+ if (block.type !== "toolCall")
2737
+ continue;
2738
+ const id = block.id;
2739
+ const at = pending.findIndex((p) => p.role === "toolResult" && p.toolCallId === id);
2740
+ if (at >= 0)
2741
+ out.push(...pending.splice(at, 1));
2742
+ }
2743
+ }
2744
+ return out;
2745
+ }
2746
+ function extractImages(msg) {
2747
+ return msg.content.filter((c) => c.type === "image");
2748
+ }
2749
+ function getContentText(msg) {
2750
+ return msg.content.map((c) => {
2751
+ if (c.type === "text")
2752
+ return c.text;
2753
+ if (c.type === "thinking")
2754
+ return c.thinking;
2755
+ return "";
2756
+ }).join("");
2757
+ }
2758
+ function toKiroInputSchema(parameters) {
2759
+ if (parameters && typeof parameters === "object" && !Array.isArray(parameters)) {
2760
+ return parameters.type === void 0 ? { type: "object", ...parameters } : parameters;
2761
+ }
2762
+ return { type: "object", properties: {} };
2763
+ }
2764
+ function toKiroToolDescription(description) {
2765
+ if (typeof description === "string")
2766
+ return description === "" ? {} : { description };
2767
+ return description == null ? {} : { description: String(description) };
2768
+ }
2769
+ function convertToolsToKiro(tools) {
2770
+ return tools.map((tool) => ({
2771
+ toolSpecification: {
2772
+ name: toKiroToolName(tool.name),
2773
+ ...toKiroToolDescription(tool.description),
2774
+ inputSchema: { json: toKiroInputSchema(tool.parameters) }
2775
+ }
2776
+ }));
2777
+ }
2778
+ var KIRO_IMAGE_FORMAT_ALIASES = {
2779
+ png: "png",
2780
+ "x-png": "png",
3569
2781
  jpeg: "jpeg",
3570
2782
  jpg: "jpeg",
3571
2783
  pjpeg: "jpeg",
@@ -3676,333 +2888,621 @@ ${uim.content}` : prevUim.content || uim.content;
3676
2888
  armHadBlocks = true;
3677
2889
  }
3678
2890
  }
3679
- if (!armContent && armToolUses.length === 0 && !armHadBlocks)
3680
- continue;
3681
- history.push({
3682
- assistantResponseMessage: { content: armContent, ...armToolUses.length > 0 ? { toolUses: armToolUses } : {} }
3683
- });
2891
+ if (!armContent && armToolUses.length === 0 && !armHadBlocks)
2892
+ continue;
2893
+ history.push({
2894
+ assistantResponseMessage: { content: armContent, ...armToolUses.length > 0 ? { toolUses: armToolUses } : {} }
2895
+ });
2896
+ } else {
2897
+ const toolResults = [toolResultOf(msg)];
2898
+ const trImages = [...extractImages(msg)];
2899
+ let j = i + 1;
2900
+ while (j < historyMessages.length) {
2901
+ const next = historyMessages[j];
2902
+ if (next?.role !== "toolResult")
2903
+ break;
2904
+ toolResults.push(toolResultOf(next));
2905
+ trImages.push(...extractImages(next));
2906
+ j++;
2907
+ }
2908
+ i = j - 1;
2909
+ const prevTr = history[history.length - 1]?.userInputMessage;
2910
+ if (prevTr) {
2911
+ const images = convertImagesToKiro(trImages);
2912
+ if (images.length > 0)
2913
+ prevTr.images = [...prevTr.images || [], ...images];
2914
+ if (!prevTr.userInputMessageContext)
2915
+ prevTr.userInputMessageContext = {};
2916
+ prevTr.userInputMessageContext.toolResults = [
2917
+ ...prevTr.userInputMessageContext.toolResults || [],
2918
+ ...toolResults
2919
+ ];
2920
+ } else {
2921
+ const images = convertImagesToKiro(trImages);
2922
+ history.push({
2923
+ userInputMessage: {
2924
+ // Empty by design: `toolResults` is this turn's payload. See
2925
+ // EMPTY_CONTENT_PLACEHOLDER for the content-or-toolResults rule.
2926
+ content: "",
2927
+ modelId,
2928
+ origin: "KIRO_CLI",
2929
+ ...images.length > 0 ? { images } : {},
2930
+ userInputMessageContext: { toolResults }
2931
+ }
2932
+ });
2933
+ }
2934
+ }
2935
+ }
2936
+ return { history, systemPrepended, currentMsgStartIdx };
2937
+ }
2938
+
2939
+ // ../kiro-core/dist/history-validator.js
2940
+ var KiroValidationRule;
2941
+ (function(KiroValidationRule2) {
2942
+ KiroValidationRule2["STARTS_WITH_USER_MESSAGE"] = "STARTS_WITH_USER_MESSAGE";
2943
+ KiroValidationRule2["ENDS_WITH_USER_MESSAGE"] = "ENDS_WITH_USER_MESSAGE";
2944
+ KiroValidationRule2["ALTERNATING_MESSAGES"] = "ALTERNATING_MESSAGES";
2945
+ KiroValidationRule2["TOOL_USES_AND_RESULTS"] = "TOOL_USES_AND_RESULTS";
2946
+ KiroValidationRule2["TOOL_RESULTS_AND_NO_USES"] = "TOOL_RESULTS_AND_NO_USES";
2947
+ KiroValidationRule2["TOOL_RESULTS_ORPHAN_IDS"] = "TOOL_RESULTS_ORPHAN_IDS";
2948
+ KiroValidationRule2["NON_EMPTY_USER_MESSAGE"] = "NON_EMPTY_USER_MESSAGE";
2949
+ })(KiroValidationRule || (KiroValidationRule = {}));
2950
+ var KIRO_VALIDATION_MESSAGES = {
2951
+ [KiroValidationRule.STARTS_WITH_USER_MESSAGE]: "Conversation must start with a user message",
2952
+ [KiroValidationRule.ENDS_WITH_USER_MESSAGE]: "Conversation must end with a user message",
2953
+ [KiroValidationRule.ALTERNATING_MESSAGES]: "Between every two user messages there must be an assistant message",
2954
+ [KiroValidationRule.TOOL_USES_AND_RESULTS]: "If an assistant message has tool uses, the next message must be a user message with corresponding tool results",
2955
+ [KiroValidationRule.TOOL_RESULTS_AND_NO_USES]: "If there is a message with tool result, there has to be a corresponding message with tool use.",
2956
+ [KiroValidationRule.NON_EMPTY_USER_MESSAGE]: "User messages must have either content or tool results",
2957
+ [KiroValidationRule.TOOL_RESULTS_ORPHAN_IDS]: "User message has toolResults whose toolUseIds do not match any toolUse in the preceding assistant message."
2958
+ };
2959
+ var KIRO_TOOL_STRUCTURE_RULES = [
2960
+ KiroValidationRule.TOOL_USES_AND_RESULTS,
2961
+ KiroValidationRule.TOOL_RESULTS_AND_NO_USES,
2962
+ KiroValidationRule.TOOL_RESULTS_ORPHAN_IDS
2963
+ ];
2964
+ function isKiroToolStructureRule(rule) {
2965
+ return KIRO_TOOL_STRUCTURE_RULES.includes(rule);
2966
+ }
2967
+ var SYNTHETIC_FAILED_TOOL_RESULT_TEXT = "Tool use was interrupted and did not produce a result.";
2968
+ function error(rule, index, message) {
2969
+ return { rule, message: message ?? KIRO_VALIDATION_MESSAGES[rule], index };
2970
+ }
2971
+ function isUserEntry(entry) {
2972
+ return !!entry?.userInputMessage;
2973
+ }
2974
+ function isAssistantEntry(entry) {
2975
+ return !!entry?.assistantResponseMessage;
2976
+ }
2977
+ function toolResultsOf(entry) {
2978
+ return entry?.userInputMessage?.userInputMessageContext?.toolResults ?? [];
2979
+ }
2980
+ function hasToolResults(entry) {
2981
+ return toolResultsOf(entry).length > 0;
2982
+ }
2983
+ function toolUseIdsOf(entry) {
2984
+ return (entry?.assistantResponseMessage?.toolUses ?? []).map((tu) => tu.toolUseId).filter(Boolean);
2985
+ }
2986
+ function hasToolUses(entry) {
2987
+ return toolUseIdsOf(entry).length > 0;
2988
+ }
2989
+ function hasText(entry) {
2990
+ return (entry?.userInputMessage?.content ?? "").trim() !== "";
2991
+ }
2992
+ function toolResultsMatch(toolUseIds, toolResults) {
2993
+ if (toolUseIds.length === 0)
2994
+ return true;
2995
+ if (toolResults.length === 0)
2996
+ return false;
2997
+ const resultIds = new Set(toolResults.map((tr) => tr.toolUseId));
2998
+ const useIds = new Set(toolUseIds);
2999
+ return toolUseIds.every((id) => resultIds.has(id)) && toolResults.every((tr) => useIds.has(tr.toolUseId));
3000
+ }
3001
+ function validateStartsWithUserMessage(entries) {
3002
+ if (entries.length === 0 || !isUserEntry(entries[0])) {
3003
+ return error(KiroValidationRule.STARTS_WITH_USER_MESSAGE, 0);
3004
+ }
3005
+ return null;
3006
+ }
3007
+ function validateEndsWithUserMessage(entries) {
3008
+ if (entries.length === 0 || !isUserEntry(entries[entries.length - 1])) {
3009
+ return error(KiroValidationRule.ENDS_WITH_USER_MESSAGE, entries.length - 1);
3010
+ }
3011
+ return null;
3012
+ }
3013
+ function validateAlternatingMessages(entries) {
3014
+ for (let i = 1; i < entries.length; i++) {
3015
+ if (isUserEntry(entries[i - 1]) && isUserEntry(entries[i])) {
3016
+ return error(KiroValidationRule.ALTERNATING_MESSAGES, i, "Between every two user messages there must be an assistant message");
3017
+ }
3018
+ if (isAssistantEntry(entries[i - 1]) && isAssistantEntry(entries[i])) {
3019
+ return error(KiroValidationRule.ALTERNATING_MESSAGES, i, "Between every two assistant messages there must be a user message");
3020
+ }
3021
+ }
3022
+ return null;
3023
+ }
3024
+ function validateToolUsesAndResults(entries) {
3025
+ for (let i = 0; i < entries.length - 1; i++) {
3026
+ const current = entries[i];
3027
+ const next = entries[i + 1];
3028
+ if (isAssistantEntry(current) && hasToolUses(current) && (!isUserEntry(next) || !toolResultsMatch(toolUseIdsOf(current), toolResultsOf(next)))) {
3029
+ return error(KiroValidationRule.TOOL_USES_AND_RESULTS, i + 1);
3030
+ }
3031
+ if (isAssistantEntry(current) && !hasToolUses(current) && isUserEntry(next) && hasToolResults(next)) {
3032
+ return error(KiroValidationRule.TOOL_RESULTS_AND_NO_USES, i);
3033
+ }
3034
+ }
3035
+ for (let i = 0; i < entries.length; i++) {
3036
+ const entry = entries[i];
3037
+ if (!isUserEntry(entry) || !hasToolResults(entry))
3038
+ continue;
3039
+ const prev = i > 0 ? entries[i - 1] : void 0;
3040
+ if (!isAssistantEntry(prev))
3041
+ return error(KiroValidationRule.TOOL_RESULTS_AND_NO_USES, i);
3042
+ }
3043
+ return null;
3044
+ }
3045
+ function validateToolResultOrphanIds(entries) {
3046
+ for (let i = 1; i < entries.length; i++) {
3047
+ const prev = entries[i - 1];
3048
+ const current = entries[i];
3049
+ if (!isAssistantEntry(prev) || !hasToolUses(prev) || !isUserEntry(current) || !hasToolResults(current))
3050
+ continue;
3051
+ const validIds = new Set(toolUseIdsOf(prev));
3052
+ const toolResults = toolResultsOf(current);
3053
+ const hasOrphan = toolResults.some((tr) => !tr.toolUseId || !validIds.has(tr.toolUseId));
3054
+ const seen = /* @__PURE__ */ new Set();
3055
+ const hasDuplicate = toolResults.some((tr) => {
3056
+ if (!tr.toolUseId)
3057
+ return false;
3058
+ if (seen.has(tr.toolUseId))
3059
+ return true;
3060
+ seen.add(tr.toolUseId);
3061
+ return false;
3062
+ });
3063
+ if (hasOrphan || hasDuplicate)
3064
+ return error(KiroValidationRule.TOOL_RESULTS_ORPHAN_IDS, i);
3065
+ }
3066
+ return null;
3067
+ }
3068
+ function validateNonEmptyUserMessages(entries) {
3069
+ for (let i = 0; i < entries.length; i++) {
3070
+ const entry = entries[i];
3071
+ if (!isUserEntry(entry))
3072
+ continue;
3073
+ if (!hasText(entry) && !hasToolResults(entry)) {
3074
+ return error(KiroValidationRule.NON_EMPTY_USER_MESSAGE, i);
3075
+ }
3076
+ }
3077
+ return null;
3078
+ }
3079
+ function validateKiroToolStructure(entries) {
3080
+ const errors = [validateToolUsesAndResults(entries), validateToolResultOrphanIds(entries)].filter((e) => e !== null);
3081
+ return { valid: errors.length === 0, errors };
3082
+ }
3083
+ function validateKiroConversation(entries) {
3084
+ const errors = [
3085
+ validateStartsWithUserMessage(entries),
3086
+ validateEndsWithUserMessage(entries),
3087
+ validateAlternatingMessages(entries),
3088
+ ...validateKiroToolStructure(entries).errors,
3089
+ validateNonEmptyUserMessages(entries)
3090
+ ].filter((e) => e !== null);
3091
+ return { valid: errors.length === 0, errors };
3092
+ }
3093
+ function kiroConversationEntries(history, currentUserMessage) {
3094
+ return currentUserMessage ? [...history, { userInputMessage: currentUserMessage }] : [...history];
3095
+ }
3096
+ function repairKiroConversation(entries) {
3097
+ const diagnostics = validateKiroConversation(entries).errors;
3098
+ if (diagnostics.length === 0)
3099
+ return { entries, diagnostics, remaining: [] };
3100
+ const modelId = entries.find((e) => e.userInputMessage?.modelId)?.userInputMessage?.modelId ?? "";
3101
+ let working = [...entries];
3102
+ while (working.length > 0 && (!isUserEntry(working[0]) || hasToolResults(working[0])))
3103
+ working = working.slice(1);
3104
+ const consolidated = [];
3105
+ for (let i = 0; i < working.length; i++) {
3106
+ const entry = working[i];
3107
+ const isToolOnly = isUserEntry(entry) && hasToolResults(entry) && !hasText(entry);
3108
+ if (!isToolOnly) {
3109
+ consolidated.push(entry);
3110
+ continue;
3111
+ }
3112
+ let j = i;
3113
+ const merged = [];
3114
+ const seen = /* @__PURE__ */ new Set();
3115
+ while (j < working.length) {
3116
+ const candidate = working[j];
3117
+ if (!(isUserEntry(candidate) && hasToolResults(candidate) && !hasText(candidate)))
3118
+ break;
3119
+ for (const tr of toolResultsOf(candidate)) {
3120
+ if (tr.toolUseId && seen.has(tr.toolUseId))
3121
+ continue;
3122
+ if (tr.toolUseId)
3123
+ seen.add(tr.toolUseId);
3124
+ merged.push(tr);
3125
+ }
3126
+ j++;
3127
+ }
3128
+ if (j - i === 1) {
3129
+ consolidated.push(entry);
3684
3130
  } else {
3685
- const toolResults = [toolResultOf(msg)];
3686
- const trImages = [...extractImages(msg)];
3687
- let j = i + 1;
3688
- while (j < historyMessages.length) {
3689
- const next = historyMessages[j];
3690
- if (next?.role !== "toolResult")
3691
- break;
3692
- toolResults.push(toolResultOf(next));
3693
- trImages.push(...extractImages(next));
3694
- j++;
3695
- }
3696
- i = j - 1;
3697
- const prevTr = history[history.length - 1]?.userInputMessage;
3698
- if (prevTr) {
3699
- const images = convertImagesToKiro(trImages);
3700
- if (images.length > 0)
3701
- prevTr.images = [...prevTr.images || [], ...images];
3702
- if (!prevTr.userInputMessageContext)
3703
- prevTr.userInputMessageContext = {};
3704
- prevTr.userInputMessageContext.toolResults = [
3705
- ...prevTr.userInputMessageContext.toolResults || [],
3706
- ...toolResults
3707
- ];
3131
+ const uim = entry.userInputMessage;
3132
+ consolidated.push({
3133
+ userInputMessage: {
3134
+ ...uim,
3135
+ userInputMessageContext: { ...uim.userInputMessageContext, toolResults: merged }
3136
+ }
3137
+ });
3138
+ }
3139
+ i = j - 1;
3140
+ }
3141
+ working = consolidated;
3142
+ const repaired = [];
3143
+ for (let i = 0; i < working.length; i++) {
3144
+ const entry = working[i];
3145
+ if (isUserEntry(entry) && hasToolResults(entry)) {
3146
+ const prev = repaired[repaired.length - 1];
3147
+ const validIds = new Set(toolUseIdsOf(prev));
3148
+ const seen = /* @__PURE__ */ new Set();
3149
+ const kept = toolResultsOf(entry).filter((tr) => {
3150
+ if (!tr.toolUseId || !validIds.has(tr.toolUseId) || seen.has(tr.toolUseId))
3151
+ return false;
3152
+ seen.add(tr.toolUseId);
3153
+ return true;
3154
+ });
3155
+ const uim = { ...entry.userInputMessage };
3156
+ if (kept.length === 0) {
3157
+ const { userInputMessageContext, ...rest } = uim;
3158
+ const tools = userInputMessageContext?.tools;
3159
+ repaired.push({
3160
+ userInputMessage: { ...rest, ...tools ? { userInputMessageContext: { tools } } : {} }
3161
+ });
3708
3162
  } else {
3709
- const images = convertImagesToKiro(trImages);
3710
- history.push({
3163
+ repaired.push({
3711
3164
  userInputMessage: {
3712
- // Empty by design: `toolResults` is this turn's payload. See
3713
- // EMPTY_CONTENT_PLACEHOLDER for the content-or-toolResults rule.
3714
- content: "",
3715
- modelId,
3716
- origin: "KIRO_CLI",
3717
- ...images.length > 0 ? { images } : {},
3718
- userInputMessageContext: { toolResults }
3165
+ ...uim,
3166
+ userInputMessageContext: { ...uim.userInputMessageContext, toolResults: kept }
3719
3167
  }
3720
3168
  });
3721
3169
  }
3170
+ continue;
3171
+ }
3172
+ repaired.push(entry);
3173
+ if (isAssistantEntry(entry) && hasToolUses(entry)) {
3174
+ const next = working[i + 1];
3175
+ const answered = new Set(isUserEntry(next) ? toolResultsOf(next).map((tr) => tr.toolUseId) : (
3176
+ /* c8 ignore next */
3177
+ []
3178
+ ));
3179
+ const unanswered = toolUseIdsOf(entry).filter((id) => !answered.has(id));
3180
+ if (unanswered.length > 0 && !isUserEntry(next)) {
3181
+ repaired.push(syntheticToolResultEntry(unanswered, modelId));
3182
+ } else if (unanswered.length > 0 && isUserEntry(next)) {
3183
+ const uim = { ...next.userInputMessage };
3184
+ working[i + 1] = {
3185
+ userInputMessage: {
3186
+ ...uim,
3187
+ userInputMessageContext: {
3188
+ ...uim.userInputMessageContext,
3189
+ toolResults: [...toolResultsOf(next), ...unanswered.map(syntheticFailedToolResult)]
3190
+ }
3191
+ }
3192
+ };
3193
+ }
3722
3194
  }
3723
3195
  }
3724
- return { history, systemPrepended, currentMsgStartIdx };
3725
- }
3726
-
3727
- // ../kiro-core/dist/history-validator.js
3728
- var KiroValidationRule;
3729
- (function(KiroValidationRule2) {
3730
- KiroValidationRule2["STARTS_WITH_USER_MESSAGE"] = "STARTS_WITH_USER_MESSAGE";
3731
- KiroValidationRule2["ENDS_WITH_USER_MESSAGE"] = "ENDS_WITH_USER_MESSAGE";
3732
- KiroValidationRule2["ALTERNATING_MESSAGES"] = "ALTERNATING_MESSAGES";
3733
- KiroValidationRule2["TOOL_USES_AND_RESULTS"] = "TOOL_USES_AND_RESULTS";
3734
- KiroValidationRule2["TOOL_RESULTS_AND_NO_USES"] = "TOOL_RESULTS_AND_NO_USES";
3735
- KiroValidationRule2["TOOL_RESULTS_ORPHAN_IDS"] = "TOOL_RESULTS_ORPHAN_IDS";
3736
- KiroValidationRule2["NON_EMPTY_USER_MESSAGE"] = "NON_EMPTY_USER_MESSAGE";
3737
- })(KiroValidationRule || (KiroValidationRule = {}));
3738
- var KIRO_VALIDATION_MESSAGES = {
3739
- [KiroValidationRule.STARTS_WITH_USER_MESSAGE]: "Conversation must start with a user message",
3740
- [KiroValidationRule.ENDS_WITH_USER_MESSAGE]: "Conversation must end with a user message",
3741
- [KiroValidationRule.ALTERNATING_MESSAGES]: "Between every two user messages there must be an assistant message",
3742
- [KiroValidationRule.TOOL_USES_AND_RESULTS]: "If an assistant message has tool uses, the next message must be a user message with corresponding tool results",
3743
- [KiroValidationRule.TOOL_RESULTS_AND_NO_USES]: "If there is a message with tool result, there has to be a corresponding message with tool use.",
3744
- [KiroValidationRule.NON_EMPTY_USER_MESSAGE]: "User messages must have either content or tool results",
3745
- [KiroValidationRule.TOOL_RESULTS_ORPHAN_IDS]: "User message has toolResults whose toolUseIds do not match any toolUse in the preceding assistant message."
3746
- };
3747
- var KIRO_TOOL_STRUCTURE_RULES = [
3748
- KiroValidationRule.TOOL_USES_AND_RESULTS,
3749
- KiroValidationRule.TOOL_RESULTS_AND_NO_USES,
3750
- KiroValidationRule.TOOL_RESULTS_ORPHAN_IDS
3751
- ];
3752
- function isKiroToolStructureRule(rule) {
3753
- return KIRO_TOOL_STRUCTURE_RULES.includes(rule);
3754
- }
3755
- var SYNTHETIC_FAILED_TOOL_RESULT_TEXT = "Tool use was interrupted and did not produce a result.";
3756
- function error(rule, index, message) {
3757
- return { rule, message: message ?? KIRO_VALIDATION_MESSAGES[rule], index };
3758
- }
3759
- function isUserEntry(entry) {
3760
- return !!entry?.userInputMessage;
3761
- }
3762
- function isAssistantEntry(entry) {
3763
- return !!entry?.assistantResponseMessage;
3764
- }
3765
- function toolResultsOf(entry) {
3766
- return entry?.userInputMessage?.userInputMessageContext?.toolResults ?? [];
3767
- }
3768
- function hasToolResults(entry) {
3769
- return toolResultsOf(entry).length > 0;
3770
- }
3771
- function toolUseIdsOf(entry) {
3772
- return (entry?.assistantResponseMessage?.toolUses ?? []).map((tu) => tu.toolUseId).filter(Boolean);
3196
+ const final = repaired.map((entry) => {
3197
+ if (!isUserEntry(entry) || hasText(entry) || hasToolResults(entry))
3198
+ return entry;
3199
+ const uim = entry.userInputMessage;
3200
+ return { userInputMessage: { ...uim, content: EMPTY_CONTENT_PLACEHOLDER } };
3201
+ });
3202
+ return { entries: final, diagnostics, remaining: validateKiroConversation(final).errors };
3773
3203
  }
3774
- function hasToolUses(entry) {
3775
- return toolUseIdsOf(entry).length > 0;
3204
+ function syntheticFailedToolResult(toolUseId) {
3205
+ return { toolUseId, content: [{ text: SYNTHETIC_FAILED_TOOL_RESULT_TEXT }], status: "error" };
3776
3206
  }
3777
- function hasText(entry) {
3778
- return (entry?.userInputMessage?.content ?? "").trim() !== "";
3207
+ function syntheticToolResultEntry(toolUseIds, modelId) {
3208
+ return {
3209
+ userInputMessage: {
3210
+ // Empty by design: `toolResults` is the payload. Matches kiro-agent's
3211
+ // `FAILED_TOOL_USE_MESSAGE`, which also ships `content: ''`.
3212
+ content: "",
3213
+ modelId,
3214
+ origin: "KIRO_CLI",
3215
+ userInputMessageContext: { toolResults: toolUseIds.map(syntheticFailedToolResult) }
3216
+ }
3217
+ };
3779
3218
  }
3780
- function toolResultsMatch(toolUseIds, toolResults) {
3781
- if (toolUseIds.length === 0)
3782
- return true;
3783
- if (toolResults.length === 0)
3784
- return false;
3785
- const resultIds = new Set(toolResults.map((tr) => tr.toolUseId));
3786
- const useIds = new Set(toolUseIds);
3787
- return toolUseIds.every((id) => resultIds.has(id)) && toolResults.every((tr) => useIds.has(tr.toolUseId));
3219
+
3220
+ // ../kiro-core/dist/host-auth.js
3221
+ init_endpoints();
3222
+ init_oauth();
3223
+ var KIRO_NO_SESSION_MESSAGE = "No Kiro session found. Sign in with `kiro-cli login` (Builder ID, IAM Identity Center, Google, or GitHub), then run /login kiro again \u2014 or paste a Kiro API key below.";
3224
+ async function loginKiroFromSession(callbacks) {
3225
+ callbacks.onProgress?.("Looking for an existing Kiro session\u2026");
3226
+ const existing = await resolveKiroCredentials();
3227
+ if (existing) {
3228
+ callbacks.onProgress?.(`Using the ${existing.authMethod} session from kiro-cli.`);
3229
+ return existing;
3230
+ }
3231
+ if (!callbacks.onPrompt)
3232
+ throw new Error(KIRO_NO_SESSION_MESSAGE);
3233
+ const apiKey = (await callbacks.onPrompt({
3234
+ message: KIRO_NO_SESSION_MESSAGE,
3235
+ placeholder: "ksk_\u2026",
3236
+ allowEmpty: true,
3237
+ secret: true
3238
+ })).trim();
3239
+ if (!apiKey)
3240
+ throw new Error(KIRO_NO_SESSION_MESSAGE);
3241
+ return loginKiroWithApiKey(apiKey, callbacks.onProgress);
3788
3242
  }
3789
- function validateStartsWithUserMessage(entries) {
3790
- if (entries.length === 0 || !isUserEntry(entries[0])) {
3791
- return error(KiroValidationRule.STARTS_WITH_USER_MESSAGE, 0);
3243
+ async function resolveKiroRequestCredentials(hostKey) {
3244
+ const stored = await resolveKiroCredentials();
3245
+ const region = resolveApiRegion(stored?.region);
3246
+ if (hostKey && (isApiKey(hostKey) || hostKey === stored?.access)) {
3247
+ return { accessToken: hostKey, region, ...stored?.profileArn ? { profileArn: stored.profileArn } : {} };
3792
3248
  }
3793
- return null;
3249
+ if (stored) {
3250
+ return {
3251
+ accessToken: stored.access,
3252
+ region,
3253
+ ...stored.profileArn ? { profileArn: stored.profileArn } : {}
3254
+ };
3255
+ }
3256
+ if (hostKey)
3257
+ return { accessToken: hostKey, region };
3258
+ throw new Error("Kiro credentials not set. Run `kiro-cli login`, or set KIRO_API_KEY to a `ksk_` API key.");
3259
+ }
3260
+
3261
+ // ../kiro-core/dist/host-model.js
3262
+ init_models();
3263
+ function toKiroModelForHost(model, region) {
3264
+ const known = getCachedModels(region).find((candidate) => candidate.id === model.id);
3265
+ return {
3266
+ ...known ?? {
3267
+ id: model.id,
3268
+ // No fallback to `model.id`: that dash-spelled local id is not a valid
3269
+ // Kiro wire id. `""` is falsy, so `resolveKiroModel` runs its own
3270
+ // cache/bootstrap/dot-normalize resolution instead of being
3271
+ // short-circuited by a value that is really just `model.id` again.
3272
+ kiroModelId: model.kiroModelId ?? "",
3273
+ name: model.name,
3274
+ reasoning: model.reasoning,
3275
+ input: [...model.input],
3276
+ cost: { ...model.cost },
3277
+ contextWindow: model.contextWindow ?? 2e5,
3278
+ maxTokens: model.maxTokens ?? 8192
3279
+ },
3280
+ region,
3281
+ ...model.kiroProfileArn ? { profileArn: model.kiroProfileArn } : {},
3282
+ ...model.additionalModelRequestFieldsSchema ? { additionalModelRequestFieldsSchema: model.additionalModelRequestFieldsSchema } : {}
3283
+ };
3794
3284
  }
3795
- function validateEndsWithUserMessage(entries) {
3796
- if (entries.length === 0 || !isUserEntry(entries[entries.length - 1])) {
3797
- return error(KiroValidationRule.ENDS_WITH_USER_MESSAGE, entries.length - 1);
3285
+
3286
+ // ../kiro-core/dist/invoke-tool-parser.js
3287
+ var INVOKE_OPEN_ANCHORED = /^<invoke name="([\w-]+)">/;
3288
+ var INVOKE_OPEN_SEARCH = "<invoke name=";
3289
+ var INVOKE_OPEN_ANYWHERE = /<invoke name="[\w-]+">/;
3290
+ var PARAM_OPEN_ANCHORED = /^<parameter name="([^"]*)">/;
3291
+ var INVOKE_CLOSE = "</invoke>";
3292
+ var PARAM_CLOSE = "</parameter>";
3293
+ var FENCE = "```";
3294
+ function fencedRanges(text) {
3295
+ const ranges = [];
3296
+ let searchFrom = 0;
3297
+ while (true) {
3298
+ const open = text.indexOf(FENCE, searchFrom);
3299
+ if (open < 0)
3300
+ break;
3301
+ const close = text.indexOf(FENCE, open + FENCE.length);
3302
+ if (close < 0) {
3303
+ ranges.push({ start: open, end: text.length });
3304
+ break;
3305
+ }
3306
+ ranges.push({ start: open, end: close + FENCE.length });
3307
+ searchFrom = close + FENCE.length;
3798
3308
  }
3799
- return null;
3309
+ return ranges;
3800
3310
  }
3801
- function validateAlternatingMessages(entries) {
3802
- for (let i = 1; i < entries.length; i++) {
3803
- if (isUserEntry(entries[i - 1]) && isUserEntry(entries[i])) {
3804
- return error(KiroValidationRule.ALTERNATING_MESSAGES, i, "Between every two user messages there must be an assistant message");
3805
- }
3806
- if (isAssistantEntry(entries[i - 1]) && isAssistantEntry(entries[i])) {
3807
- return error(KiroValidationRule.ALTERNATING_MESSAGES, i, "Between every two assistant messages there must be a user message");
3311
+ var AmbiguousDialectError = class extends Error {
3312
+ };
3313
+ function parseBlockAt(text, start) {
3314
+ const openMatch = INVOKE_OPEN_ANCHORED.exec(text.substring(start));
3315
+ if (!openMatch)
3316
+ return null;
3317
+ const args = {};
3318
+ let cursor = start + openMatch[0].length;
3319
+ while (true) {
3320
+ const remainder = text.substring(cursor);
3321
+ const leadingWhitespace = remainder.length - remainder.trimStart().length;
3322
+ if (leadingWhitespace > 0)
3323
+ cursor += leadingWhitespace;
3324
+ if (text.startsWith(INVOKE_CLOSE, cursor)) {
3325
+ const end = cursor + INVOKE_CLOSE.length;
3326
+ if (end < text.length && !/\s/.test(text[end]))
3327
+ return null;
3328
+ return { name: openMatch[1], arguments: args, end };
3808
3329
  }
3330
+ const paramMatch = PARAM_OPEN_ANCHORED.exec(text.substring(cursor));
3331
+ if (!paramMatch)
3332
+ return null;
3333
+ const valueStart = cursor + paramMatch[0].length;
3334
+ const valueEnd = text.indexOf(PARAM_CLOSE, valueStart);
3335
+ if (valueEnd < 0)
3336
+ return null;
3337
+ const value = text.substring(valueStart, valueEnd);
3338
+ if (INVOKE_OPEN_ANYWHERE.test(value))
3339
+ throw new AmbiguousDialectError();
3340
+ args[paramMatch[1]] = value;
3341
+ cursor = valueEnd + PARAM_CLOSE.length;
3809
3342
  }
3810
- return null;
3811
3343
  }
3812
- function validateToolUsesAndResults(entries) {
3813
- for (let i = 0; i < entries.length - 1; i++) {
3814
- const current = entries[i];
3815
- const next = entries[i + 1];
3816
- if (isAssistantEntry(current) && hasToolUses(current) && (!isUserEntry(next) || !toolResultsMatch(toolUseIdsOf(current), toolResultsOf(next)))) {
3817
- return error(KiroValidationRule.TOOL_USES_AND_RESULTS, i + 1);
3344
+ function parseInvokeToolCalls(text) {
3345
+ const toolCalls = [];
3346
+ const removals = [];
3347
+ const fences = fencedRanges(text);
3348
+ const untouched = { toolCalls: [], cleanedText: text };
3349
+ let cursor = 0;
3350
+ while (cursor < text.length) {
3351
+ const openStart = text.indexOf(INVOKE_OPEN_SEARCH, cursor);
3352
+ if (openStart < 0)
3353
+ break;
3354
+ const containingFence = fences.find((range) => openStart >= range.start && openStart < range.end);
3355
+ if (containingFence) {
3356
+ cursor = containingFence.end;
3357
+ continue;
3818
3358
  }
3819
- if (isAssistantEntry(current) && !hasToolUses(current) && isUserEntry(next) && hasToolResults(next)) {
3820
- return error(KiroValidationRule.TOOL_RESULTS_AND_NO_USES, i);
3359
+ let block;
3360
+ try {
3361
+ block = parseBlockAt(text, openStart);
3362
+ } catch (e) {
3363
+ if (e instanceof AmbiguousDialectError)
3364
+ return untouched;
3365
+ throw e;
3821
3366
  }
3367
+ if (block === null)
3368
+ return untouched;
3369
+ const nextOpen = text.indexOf(INVOKE_OPEN_SEARCH, block.end);
3370
+ const interstitialEnd = nextOpen < 0 ? text.length : nextOpen;
3371
+ const interstitial = text.substring(block.end, interstitialEnd);
3372
+ if (interstitial.includes(PARAM_CLOSE) || interstitial.includes(INVOKE_CLOSE))
3373
+ return untouched;
3374
+ toolCalls.push({ toolUseId: crypto.randomUUID(), name: block.name, arguments: block.arguments });
3375
+ removals.push({ start: openStart, end: block.end });
3376
+ cursor = block.end;
3822
3377
  }
3823
- for (let i = 0; i < entries.length; i++) {
3824
- const entry = entries[i];
3825
- if (!isUserEntry(entry) || !hasToolResults(entry))
3826
- continue;
3827
- const prev = i > 0 ? entries[i - 1] : void 0;
3828
- if (!isAssistantEntry(prev))
3829
- return error(KiroValidationRule.TOOL_RESULTS_AND_NO_USES, i);
3830
- }
3831
- return null;
3832
- }
3833
- function validateToolResultOrphanIds(entries) {
3834
- for (let i = 1; i < entries.length; i++) {
3835
- const prev = entries[i - 1];
3836
- const current = entries[i];
3837
- if (!isAssistantEntry(prev) || !hasToolUses(prev) || !isUserEntry(current) || !hasToolResults(current))
3838
- continue;
3839
- const validIds = new Set(toolUseIdsOf(prev));
3840
- const toolResults = toolResultsOf(current);
3841
- const hasOrphan = toolResults.some((tr) => !tr.toolUseId || !validIds.has(tr.toolUseId));
3842
- const seen = /* @__PURE__ */ new Set();
3843
- const hasDuplicate = toolResults.some((tr) => {
3844
- if (!tr.toolUseId)
3845
- return false;
3846
- if (seen.has(tr.toolUseId))
3847
- return true;
3848
- seen.add(tr.toolUseId);
3849
- return false;
3850
- });
3851
- if (hasOrphan || hasDuplicate)
3852
- return error(KiroValidationRule.TOOL_RESULTS_ORPHAN_IDS, i);
3378
+ let cleanedText = text;
3379
+ for (let i = removals.length - 1; i >= 0; i--) {
3380
+ const { start, end } = removals[i];
3381
+ cleanedText = cleanedText.substring(0, start) + cleanedText.substring(end);
3853
3382
  }
3854
- return null;
3383
+ return { toolCalls, cleanedText };
3855
3384
  }
3856
- function validateNonEmptyUserMessages(entries) {
3857
- for (let i = 0; i < entries.length; i++) {
3858
- const entry = entries[i];
3859
- if (!isUserEntry(entry))
3860
- continue;
3861
- if (!hasText(entry) && !hasToolResults(entry)) {
3862
- return error(KiroValidationRule.NON_EMPTY_USER_MESSAGE, i);
3385
+
3386
+ // ../kiro-core/dist/index.js
3387
+ init_kiro_cli();
3388
+ init_kiro_ide();
3389
+ init_management();
3390
+ init_models();
3391
+ init_oauth();
3392
+
3393
+ // ../kiro-core/dist/request-builder.js
3394
+ init_debug();
3395
+
3396
+ // ../kiro-core/dist/history.js
3397
+ var HISTORY_LIMIT = 85e4;
3398
+ var HISTORY_LIMIT_CONTEXT_WINDOW = 2e5;
3399
+ var HISTORY_IMAGE_BASE64_LIMIT = 512 * 1024;
3400
+ function stripHistoryImages(history, keepNewestBounded = true) {
3401
+ let newestImageIndex = -1;
3402
+ for (let index = history.length - 1; index >= 0; index--) {
3403
+ if ((history[index]?.userInputMessage?.images?.length ?? 0) > 0) {
3404
+ newestImageIndex = index;
3405
+ break;
3863
3406
  }
3864
3407
  }
3865
- return null;
3866
- }
3867
- function validateKiroToolStructure(entries) {
3868
- const errors = [validateToolUsesAndResults(entries), validateToolResultOrphanIds(entries)].filter((e) => e !== null);
3869
- return { valid: errors.length === 0, errors };
3870
- }
3871
- function validateKiroConversation(entries) {
3872
- const errors = [
3873
- validateStartsWithUserMessage(entries),
3874
- validateEndsWithUserMessage(entries),
3875
- validateAlternatingMessages(entries),
3876
- ...validateKiroToolStructure(entries).errors,
3877
- validateNonEmptyUserMessages(entries)
3878
- ].filter((e) => e !== null);
3879
- return { valid: errors.length === 0, errors };
3880
- }
3881
- function kiroConversationEntries(history, currentUserMessage) {
3882
- return currentUserMessage ? [...history, { userInputMessage: currentUserMessage }] : [...history];
3408
+ const newestImages = newestImageIndex >= 0 ? history[newestImageIndex]?.userInputMessage?.images : void 0;
3409
+ const keepNewest = keepNewestBounded && newestImages !== void 0 && newestImages.reduce((size, image) => size + image.source.bytes.length, 0) <= HISTORY_IMAGE_BASE64_LIMIT;
3410
+ return history.map((entry, index) => {
3411
+ if (!entry.userInputMessage?.images || index === newestImageIndex && keepNewest)
3412
+ return entry;
3413
+ const { images: _images, ...rest } = entry.userInputMessage;
3414
+ return { ...entry, userInputMessage: { ...rest } };
3415
+ });
3883
3416
  }
3884
- function repairKiroConversation(entries) {
3885
- const diagnostics = validateKiroConversation(entries).errors;
3886
- if (diagnostics.length === 0)
3887
- return { entries, diagnostics, remaining: [] };
3888
- const modelId = entries.find((e) => e.userInputMessage?.modelId)?.userInputMessage?.modelId ?? "";
3889
- let working = [...entries];
3890
- while (working.length > 0 && (!isUserEntry(working[0]) || hasToolResults(working[0])))
3891
- working = working.slice(1);
3892
- const consolidated = [];
3893
- for (let i = 0; i < working.length; i++) {
3894
- const entry = working[i];
3895
- const isToolOnly = isUserEntry(entry) && hasToolResults(entry) && !hasText(entry);
3896
- if (!isToolOnly) {
3897
- consolidated.push(entry);
3417
+ function sanitizeHistory(history) {
3418
+ while (history.length > 0 && (!history[0]?.userInputMessage || history[0].userInputMessage.userInputMessageContext?.toolResults))
3419
+ history = history.slice(1);
3420
+ const result = [];
3421
+ for (let i = 0; i < history.length; i++) {
3422
+ const m = history[i];
3423
+ if (!m)
3898
3424
  continue;
3899
- }
3900
- let j = i;
3901
- const merged = [];
3902
- const seen = /* @__PURE__ */ new Set();
3903
- while (j < working.length) {
3904
- const candidate = working[j];
3905
- if (!(isUserEntry(candidate) && hasToolResults(candidate) && !hasText(candidate)))
3906
- break;
3907
- for (const tr of toolResultsOf(candidate)) {
3908
- if (tr.toolUseId && seen.has(tr.toolUseId))
3909
- continue;
3910
- if (tr.toolUseId)
3911
- seen.add(tr.toolUseId);
3912
- merged.push(tr);
3913
- }
3914
- j++;
3915
- }
3916
- if (j - i === 1) {
3917
- consolidated.push(entry);
3425
+ if (m.assistantResponseMessage && !m.assistantResponseMessage.toolUses && !m.assistantResponseMessage.content)
3426
+ continue;
3427
+ if (m.assistantResponseMessage?.toolUses) {
3428
+ const next = history[i + 1];
3429
+ if (next?.userInputMessage?.userInputMessageContext?.toolResults)
3430
+ result.push(m);
3431
+ } else if (m.userInputMessage?.userInputMessageContext?.toolResults) {
3432
+ const prev = result[result.length - 1];
3433
+ if (prev?.assistantResponseMessage?.toolUses)
3434
+ result.push(m);
3918
3435
  } else {
3919
- const uim = entry.userInputMessage;
3920
- consolidated.push({
3921
- userInputMessage: {
3922
- ...uim,
3923
- userInputMessageContext: { ...uim.userInputMessageContext, toolResults: merged }
3924
- }
3925
- });
3436
+ result.push(m);
3437
+ }
3438
+ }
3439
+ return result;
3440
+ }
3441
+ function injectSyntheticToolCalls(history) {
3442
+ const validIds = /* @__PURE__ */ new Set();
3443
+ for (const entry of history) {
3444
+ for (const tu of entry.assistantResponseMessage?.toolUses ?? []) {
3445
+ if (tu.toolUseId)
3446
+ validIds.add(tu.toolUseId);
3926
3447
  }
3927
- i = j - 1;
3928
3448
  }
3929
- working = consolidated;
3930
- const repaired = [];
3931
- for (let i = 0; i < working.length; i++) {
3932
- const entry = working[i];
3933
- if (isUserEntry(entry) && hasToolResults(entry)) {
3934
- const prev = repaired[repaired.length - 1];
3935
- const validIds = new Set(toolUseIdsOf(prev));
3936
- const seen = /* @__PURE__ */ new Set();
3937
- const kept = toolResultsOf(entry).filter((tr) => {
3938
- if (!tr.toolUseId || !validIds.has(tr.toolUseId) || seen.has(tr.toolUseId))
3939
- return false;
3940
- seen.add(tr.toolUseId);
3941
- return true;
3942
- });
3943
- const uim = { ...entry.userInputMessage };
3944
- if (kept.length === 0) {
3945
- const { userInputMessageContext, ...rest } = uim;
3946
- const tools = userInputMessageContext?.tools;
3947
- repaired.push({
3948
- userInputMessage: { ...rest, ...tools ? { userInputMessageContext: { tools } } : {} }
3949
- });
3950
- } else {
3951
- repaired.push({
3952
- userInputMessage: {
3953
- ...uim,
3954
- userInputMessageContext: { ...uim.userInputMessageContext, toolResults: kept }
3449
+ const result = [];
3450
+ for (const entry of history) {
3451
+ const toolResults = entry.userInputMessage?.userInputMessageContext?.toolResults;
3452
+ if (toolResults) {
3453
+ const orphaned = toolResults.filter((tr) => !validIds.has(tr.toolUseId));
3454
+ if (orphaned.length > 0) {
3455
+ result.push({
3456
+ assistantResponseMessage: {
3457
+ content: "Tool calls were made.",
3458
+ toolUses: orphaned.map((tr) => ({ name: "unknown_tool", toolUseId: tr.toolUseId, input: {} }))
3955
3459
  }
3956
3460
  });
3957
- }
3958
- continue;
3959
- }
3960
- repaired.push(entry);
3961
- if (isAssistantEntry(entry) && hasToolUses(entry)) {
3962
- const next = working[i + 1];
3963
- const answered = new Set(isUserEntry(next) ? toolResultsOf(next).map((tr) => tr.toolUseId) : (
3964
- /* c8 ignore next */
3965
- []
3966
- ));
3967
- const unanswered = toolUseIdsOf(entry).filter((id) => !answered.has(id));
3968
- if (unanswered.length > 0 && !isUserEntry(next)) {
3969
- repaired.push(syntheticToolResultEntry(unanswered, modelId));
3970
- } else if (unanswered.length > 0 && isUserEntry(next)) {
3971
- const uim = { ...next.userInputMessage };
3972
- working[i + 1] = {
3973
- userInputMessage: {
3974
- ...uim,
3975
- userInputMessageContext: {
3976
- ...uim.userInputMessageContext,
3977
- toolResults: [...toolResultsOf(next), ...unanswered.map(syntheticFailedToolResult)]
3978
- }
3979
- }
3980
- };
3461
+ for (const tr of orphaned)
3462
+ validIds.add(tr.toolUseId);
3981
3463
  }
3982
3464
  }
3465
+ result.push(entry);
3983
3466
  }
3984
- const final = repaired.map((entry) => {
3985
- if (!isUserEntry(entry) || hasText(entry) || hasToolResults(entry))
3986
- return entry;
3987
- const uim = entry.userInputMessage;
3988
- return { userInputMessage: { ...uim, content: EMPTY_CONTENT_PLACEHOLDER } };
3989
- });
3990
- return { entries: final, diagnostics, remaining: validateKiroConversation(final).errors };
3467
+ return result;
3991
3468
  }
3992
- function syntheticFailedToolResult(toolUseId) {
3993
- return { toolUseId, content: [{ text: SYNTHETIC_FAILED_TOOL_RESULT_TEXT }], status: "error" };
3469
+ function prepareHistory(history, keepNewestBoundedImage = true) {
3470
+ return injectSyntheticToolCalls(sanitizeHistory(stripHistoryImages(history, keepNewestBoundedImage)));
3994
3471
  }
3995
- function syntheticToolResultEntry(toolUseIds, modelId) {
3996
- return {
3997
- userInputMessage: {
3998
- // Empty by design: `toolResults` is the payload. Matches kiro-agent's
3999
- // `FAILED_TOOL_USE_MESSAGE`, which also ships `content: ''`.
4000
- content: "",
4001
- modelId,
4002
- origin: "KIRO_CLI",
4003
- userInputMessageContext: { toolResults: toolUseIds.map(syntheticFailedToolResult) }
3472
+ function assertHistoryWithinLimit(history, limit) {
3473
+ const size = JSON.stringify(history).length;
3474
+ if (size > limit) {
3475
+ throw new Error(`Kiro API error: context_length_exceeded (local history ${size} chars / ${history.length} entries exceeds ${limit}-char limit)`);
3476
+ }
3477
+ }
3478
+ function extractToolNamesFromHistory(history) {
3479
+ const names = /* @__PURE__ */ new Set();
3480
+ for (const entry of history) {
3481
+ for (const tu of entry.assistantResponseMessage?.toolUses ?? []) {
3482
+ if (tu.name)
3483
+ names.add(tu.name);
4004
3484
  }
4005
- };
3485
+ }
3486
+ return names;
3487
+ }
3488
+ function addPlaceholderTools(tools, history) {
3489
+ const historyNames = extractToolNamesFromHistory(history);
3490
+ if (historyNames.size === 0)
3491
+ return tools;
3492
+ const existing = new Set(tools.map((t) => t.toolSpecification?.name).filter(Boolean));
3493
+ const missing = Array.from(historyNames).filter((n) => !existing.has(n));
3494
+ if (missing.length === 0)
3495
+ return tools;
3496
+ return [
3497
+ ...tools,
3498
+ ...missing.map((name) => ({
3499
+ toolSpecification: {
3500
+ name,
3501
+ description: "Tool",
3502
+ inputSchema: { json: { type: "object", properties: {} } }
3503
+ }
3504
+ }))
3505
+ ];
4006
3506
  }
4007
3507
 
4008
3508
  // ../kiro-core/dist/truncation.js
@@ -4141,145 +3641,45 @@ ${currentContent}`;
4141
3641
  } else {
4142
3642
  wireHistory = [];
4143
3643
  wireContent = currentContent || EMPTY_CONTENT_PLACEHOLDER;
4144
- wireUimc = uimc?.tools?.length ? { tools: uimc.tools } : void 0;
4145
- }
4146
- if (repair.remaining.length > 0) {
4147
- const structural = repair.remaining.filter((e) => isKiroToolStructureRule(e.rule));
4148
- if (structural.length > 0) {
4149
- console.warn(`[kiro-core] outbound history still violates ${structural.map((e) => `${e.rule}@${e.index}`).join(", ")} after repair \u2014 Kiro may reject this request`);
4150
- }
4151
- }
4152
- return {
4153
- request: {
4154
- conversationState: {
4155
- chatTriggerType: "MANUAL",
4156
- agentTaskType: "vibe",
4157
- conversationId,
4158
- currentMessage: {
4159
- userInputMessage: {
4160
- content: sanitizeSurrogates(wireContent),
4161
- modelId: kiroModelId,
4162
- origin: "KIRO_CLI",
4163
- ...currentImages ? { images: currentImages } : {},
4164
- ...wireUimc ? { userInputMessageContext: wireUimc } : {}
4165
- }
4166
- },
4167
- ...wireHistory.length > 0 ? { history: wireHistory } : {}
4168
- },
4169
- ...params.additionalModelRequestFields ? { additionalModelRequestFields: params.additionalModelRequestFields } : {},
4170
- profileArn,
4171
- agentMode: "vibe"
4172
- },
4173
- wireHistoryLength: wireHistory.length,
4174
- wireContentLength: wireContent.length,
4175
- hasImages: !!currentImages,
4176
- toolResultCount: wireUimc?.toolResults?.length ?? 0
4177
- };
4178
- }
4179
-
4180
- // ../kiro-core/dist/response-assembler.js
4181
- init_debug();
4182
-
4183
- // ../kiro-core/dist/invoke-tool-parser.js
4184
- var INVOKE_OPEN_ANCHORED = /^<invoke name="([\w-]+)">/;
4185
- var INVOKE_OPEN_SEARCH = "<invoke name=";
4186
- var INVOKE_OPEN_ANYWHERE = /<invoke name="[\w-]+">/;
4187
- var PARAM_OPEN_ANCHORED = /^<parameter name="([^"]*)">/;
4188
- var INVOKE_CLOSE = "</invoke>";
4189
- var PARAM_CLOSE = "</parameter>";
4190
- var FENCE = "```";
4191
- function fencedRanges(text) {
4192
- const ranges = [];
4193
- let searchFrom = 0;
4194
- while (true) {
4195
- const open = text.indexOf(FENCE, searchFrom);
4196
- if (open < 0)
4197
- break;
4198
- const close = text.indexOf(FENCE, open + FENCE.length);
4199
- if (close < 0) {
4200
- ranges.push({ start: open, end: text.length });
4201
- break;
4202
- }
4203
- ranges.push({ start: open, end: close + FENCE.length });
4204
- searchFrom = close + FENCE.length;
4205
- }
4206
- return ranges;
4207
- }
4208
- var AmbiguousDialectError = class extends Error {
4209
- };
4210
- function parseBlockAt(text, start) {
4211
- const openMatch = INVOKE_OPEN_ANCHORED.exec(text.substring(start));
4212
- if (!openMatch)
4213
- return null;
4214
- const args = {};
4215
- let cursor = start + openMatch[0].length;
4216
- while (true) {
4217
- const remainder = text.substring(cursor);
4218
- const leadingWhitespace = remainder.length - remainder.trimStart().length;
4219
- if (leadingWhitespace > 0)
4220
- cursor += leadingWhitespace;
4221
- if (text.startsWith(INVOKE_CLOSE, cursor)) {
4222
- const end = cursor + INVOKE_CLOSE.length;
4223
- if (end < text.length && !/\s/.test(text[end]))
4224
- return null;
4225
- return { name: openMatch[1], arguments: args, end };
4226
- }
4227
- const paramMatch = PARAM_OPEN_ANCHORED.exec(text.substring(cursor));
4228
- if (!paramMatch)
4229
- return null;
4230
- const valueStart = cursor + paramMatch[0].length;
4231
- const valueEnd = text.indexOf(PARAM_CLOSE, valueStart);
4232
- if (valueEnd < 0)
4233
- return null;
4234
- const value = text.substring(valueStart, valueEnd);
4235
- if (INVOKE_OPEN_ANYWHERE.test(value))
4236
- throw new AmbiguousDialectError();
4237
- args[paramMatch[1]] = value;
4238
- cursor = valueEnd + PARAM_CLOSE.length;
4239
- }
4240
- }
4241
- function parseInvokeToolCalls(text) {
4242
- const toolCalls = [];
4243
- const removals = [];
4244
- const fences = fencedRanges(text);
4245
- const untouched = { toolCalls: [], cleanedText: text };
4246
- let cursor = 0;
4247
- while (cursor < text.length) {
4248
- const openStart = text.indexOf(INVOKE_OPEN_SEARCH, cursor);
4249
- if (openStart < 0)
4250
- break;
4251
- const containingFence = fences.find((range) => openStart >= range.start && openStart < range.end);
4252
- if (containingFence) {
4253
- cursor = containingFence.end;
4254
- continue;
4255
- }
4256
- let block;
4257
- try {
4258
- block = parseBlockAt(text, openStart);
4259
- } catch (e) {
4260
- if (e instanceof AmbiguousDialectError)
4261
- return untouched;
4262
- throw e;
4263
- }
4264
- if (block === null)
4265
- return untouched;
4266
- const nextOpen = text.indexOf(INVOKE_OPEN_SEARCH, block.end);
4267
- const interstitialEnd = nextOpen < 0 ? text.length : nextOpen;
4268
- const interstitial = text.substring(block.end, interstitialEnd);
4269
- if (interstitial.includes(PARAM_CLOSE) || interstitial.includes(INVOKE_CLOSE))
4270
- return untouched;
4271
- toolCalls.push({ toolUseId: crypto.randomUUID(), name: block.name, arguments: block.arguments });
4272
- removals.push({ start: openStart, end: block.end });
4273
- cursor = block.end;
3644
+ wireUimc = uimc?.tools?.length ? { tools: uimc.tools } : void 0;
4274
3645
  }
4275
- let cleanedText = text;
4276
- for (let i = removals.length - 1; i >= 0; i--) {
4277
- const { start, end } = removals[i];
4278
- cleanedText = cleanedText.substring(0, start) + cleanedText.substring(end);
3646
+ if (repair.remaining.length > 0) {
3647
+ const structural = repair.remaining.filter((e) => isKiroToolStructureRule(e.rule));
3648
+ if (structural.length > 0) {
3649
+ console.warn(`[kiro-core] outbound history still violates ${structural.map((e) => `${e.rule}@${e.index}`).join(", ")} after repair \u2014 Kiro may reject this request`);
3650
+ }
4279
3651
  }
4280
- return { toolCalls, cleanedText };
3652
+ return {
3653
+ request: {
3654
+ conversationState: {
3655
+ chatTriggerType: "MANUAL",
3656
+ agentTaskType: "vibe",
3657
+ conversationId,
3658
+ currentMessage: {
3659
+ userInputMessage: {
3660
+ content: sanitizeSurrogates(wireContent),
3661
+ modelId: kiroModelId,
3662
+ origin: "KIRO_CLI",
3663
+ ...currentImages ? { images: currentImages } : {},
3664
+ ...wireUimc ? { userInputMessageContext: wireUimc } : {}
3665
+ }
3666
+ },
3667
+ ...wireHistory.length > 0 ? { history: wireHistory } : {}
3668
+ },
3669
+ ...params.additionalModelRequestFields ? { additionalModelRequestFields: params.additionalModelRequestFields } : {},
3670
+ profileArn,
3671
+ agentMode: "vibe"
3672
+ },
3673
+ wireHistoryLength: wireHistory.length,
3674
+ wireContentLength: wireContent.length,
3675
+ hasImages: !!currentImages,
3676
+ toolResultCount: wireUimc?.toolResults?.length ?? 0
3677
+ };
4281
3678
  }
4282
3679
 
3680
+ // ../kiro-core/dist/response-assembler.js
3681
+ init_debug();
3682
+
4283
3683
  // ../kiro-core/dist/thinking-parser.js
4284
3684
  var THINKING_END_TAG = "</thinking>";
4285
3685
  var THINKING_TAG_VARIANTS = [
@@ -5756,294 +5156,87 @@ function getChunkedStream(source) {
5756
5156
  currentMessagePendingLength += numBytesForTotal;
5757
5157
  currentOffset += numBytesForTotal;
5758
5158
  if (currentMessagePendingLength < 4) {
5759
- break;
5760
- }
5761
- allocateMessage(new DataView(messageLengthBuffer.buffer).getUint32(0, false));
5762
- messageLengthBuffer = null;
5763
- }
5764
- const numBytesToWrite = Math.min(currentMessageTotalLength - currentMessagePendingLength, chunkLength - currentOffset);
5765
- currentMessage.set(value.slice(currentOffset, currentOffset + numBytesToWrite), currentMessagePendingLength);
5766
- currentMessagePendingLength += numBytesToWrite;
5767
- currentOffset += numBytesToWrite;
5768
- if (currentMessageTotalLength && currentMessageTotalLength === currentMessagePendingLength) {
5769
- yield currentMessage;
5770
- currentMessage = null;
5771
- currentMessageTotalLength = 0;
5772
- currentMessagePendingLength = 0;
5773
- }
5774
- }
5775
- }
5776
- };
5777
- return {
5778
- [Symbol.asyncIterator]: iterator
5779
- };
5780
- }
5781
-
5782
- // ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-serde-universal/getUnmarshalledStream.js
5783
- function getMessageUnmarshaller(deserializer, toUtf82) {
5784
- return async function(message) {
5785
- const { value: messageType } = message.headers[":message-type"];
5786
- if (messageType === "error") {
5787
- const unmodeledError = new Error(message.headers[":error-message"].value || "UnknownError");
5788
- unmodeledError.name = message.headers[":error-code"].value;
5789
- throw unmodeledError;
5790
- } else if (messageType === "exception") {
5791
- const code = message.headers[":exception-type"].value;
5792
- const exception = { [code]: message };
5793
- const deserializedException = await deserializer(exception);
5794
- if (deserializedException.$unknown) {
5795
- const error2 = new Error(toUtf82(message.body));
5796
- error2.name = code;
5797
- throw error2;
5798
- }
5799
- throw deserializedException[code];
5800
- } else if (messageType === "event") {
5801
- const event = {
5802
- [message.headers[":event-type"].value]: message
5803
- };
5804
- const deserialized = await deserializer(event);
5805
- if (deserialized.$unknown)
5806
- return;
5807
- return deserialized;
5808
- } else {
5809
- throw Error(`Unrecognizable event type: ${message.headers[":event-type"].value}`);
5810
- }
5811
- };
5812
- }
5813
-
5814
- // ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-serde-universal/EventStreamMarshaller.js
5815
- var EventStreamMarshaller = class {
5816
- eventStreamCodec;
5817
- utfEncoder;
5818
- constructor({ utf8Encoder, utf8Decoder }) {
5819
- this.eventStreamCodec = new EventStreamCodec(utf8Encoder, utf8Decoder);
5820
- this.utfEncoder = utf8Encoder;
5821
- }
5822
- deserialize(body, deserializer) {
5823
- const inputStream = getChunkedStream(body);
5824
- return new SmithyMessageDecoderStream({
5825
- messageStream: new MessageDecoderStream({ inputStream, decoder: this.eventStreamCodec }),
5826
- deserializer: getMessageUnmarshaller(deserializer, this.utfEncoder)
5827
- });
5828
- }
5829
- serialize(inputStream, serializer) {
5830
- return new MessageEncoderStream({
5831
- messageStream: new SmithyMessageEncoderStream({ inputStream, serializer }),
5832
- encoder: this.eventStreamCodec,
5833
- includeEndFrame: true
5834
- });
5835
- }
5836
- };
5837
-
5838
- // ../kiro-core/dist/response-stream.js
5839
- init_debug();
5840
-
5841
- // ../kiro-core/dist/event-parser.js
5842
- var KIRO_EVENT_KEYS = [
5843
- "assistantResponseEvent",
5844
- "codeReferenceEvent",
5845
- "contextUsageEvent",
5846
- "documentCitationEvent",
5847
- "error",
5848
- "metadataEvent",
5849
- "meteringEvent",
5850
- "reasoningContentEvent",
5851
- "serviceUnavailableError",
5852
- "throttlingError",
5853
- "toolResultEvent",
5854
- "toolUseEvent",
5855
- "validationError"
5856
- ];
5857
- var KIRO_EVENT_KEY_SET = new Set(KIRO_EVENT_KEYS);
5858
- var KIRO_ERROR_MEMBERS = {
5859
- error: { kind: "internalServer", exception: "InternalServerException" },
5860
- throttlingError: { kind: "throttling", exception: "ThrottlingException" },
5861
- validationError: { kind: "validation", exception: "ValidationException" },
5862
- serviceUnavailableError: { kind: "serviceUnavailable", exception: "ServiceUnavailableException" }
5863
- };
5864
- var KIRO_ERROR_TOKENS = {
5865
- ...KIRO_ERROR_MEMBERS,
5866
- InternalServerException: KIRO_ERROR_MEMBERS.error,
5867
- ThrottlingException: KIRO_ERROR_MEMBERS.throttlingError,
5868
- ValidationException: KIRO_ERROR_MEMBERS.validationError,
5869
- ServiceUnavailableException: KIRO_ERROR_MEMBERS.serviceUnavailableError
5870
- };
5871
- function lookupKiroErrorMember(key) {
5872
- return Object.hasOwn(KIRO_ERROR_TOKENS, key) ? KIRO_ERROR_TOKENS[key] : void 0;
5873
- }
5874
- var num = (v) => typeof v === "number" ? v : void 0;
5875
- var str = (v) => typeof v === "string" ? v : void 0;
5876
- function tokenCount(value) {
5877
- return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
5878
- }
5879
- function firstTokenCount(source, keys) {
5880
- for (const key of keys) {
5881
- const count = tokenCount(source[key]);
5882
- if (count !== void 0)
5883
- return count;
5884
- }
5885
- return void 0;
5886
- }
5887
- var CACHE_READ_KEYS = ["cacheReadInputTokens", "cache_read_input_tokens", "cacheReadTokens"];
5888
- var CACHE_WRITE_KEYS = [
5889
- "cacheWriteInputTokens",
5890
- "cache_creation_input_tokens",
5891
- "cacheCreationInputTokens",
5892
- "cacheWriteTokens"
5893
- ];
5894
- function toolInput(raw) {
5895
- if (typeof raw === "string")
5896
- return raw;
5897
- if (raw && typeof raw === "object" && Object.keys(raw).length > 0) {
5898
- return JSON.stringify(raw);
5899
- }
5900
- return "";
5901
- }
5902
- function parseToolUse(parsed) {
5903
- if (parsed.name && parsed.toolUseId) {
5904
- return {
5905
- type: "toolUse",
5906
- data: {
5907
- name: parsed.name,
5908
- toolUseId: parsed.toolUseId,
5909
- input: toolInput(parsed.input),
5910
- stop: parsed.stop
5911
- }
5912
- };
5913
- }
5914
- if (parsed.input !== void 0) {
5915
- return { type: "toolUseInput", data: { input: toolInput(parsed.input) } };
5916
- }
5917
- if (parsed.stop !== void 0)
5918
- return { type: "toolUseStop", data: { stop: parsed.stop } };
5919
- return null;
5920
- }
5921
- function parseMetadata(parsed) {
5922
- const tu = parsed.tokenUsage ?? {};
5923
- const data = {
5924
- inputTokens: tokenCount(tu.uncachedInputTokens) ?? tokenCount(tu.inputTokens),
5925
- outputTokens: tokenCount(tu.outputTokens),
5926
- totalTokens: tokenCount(tu.totalTokens),
5927
- cacheReadInputTokens: firstTokenCount(tu, CACHE_READ_KEYS),
5928
- cacheWriteInputTokens: firstTokenCount(tu, CACHE_WRITE_KEYS),
5929
- contextUsagePercentage: num(tu.contextUsagePercentage),
5930
- normalizedTokenUsage: num(tu.normalizedTokenUsage),
5931
- rawStopReason: str(parsed.stopReason),
5932
- stopDetails: parsed.stopDetails && typeof parsed.stopDetails === "object" ? parsed.stopDetails : void 0
5933
- };
5934
- for (const k of Object.keys(data)) {
5935
- if (data[k] === void 0)
5936
- delete data[k];
5937
- }
5938
- return Object.keys(data).length > 0 ? { type: "usage", data } : null;
5939
- }
5940
- function parseError(parsed, kind, fallbackName) {
5941
- const rawError = parsed.error ?? parsed.Error;
5942
- const error2 = typeof rawError === "string" ? rawError : rawError !== void 0 ? JSON.stringify(rawError) : str(parsed.name) ?? fallbackName;
5943
- const message = parsed.message ?? parsed.Message ?? parsed.reason;
5944
- const data = { error: error2, kind };
5945
- if (typeof message === "string")
5946
- data.message = message;
5947
- const reason = str(parsed.reason);
5948
- if (reason !== void 0)
5949
- data.reason = reason;
5950
- const retryAfterMilliseconds = num(parsed.retryAfterMilliseconds);
5951
- if (retryAfterMilliseconds !== void 0)
5952
- data.retryAfterMilliseconds = retryAfterMilliseconds;
5953
- return { type: "error", data };
5954
- }
5955
- function parseKiroEvent(key, parsed) {
5956
- switch (key) {
5957
- case "assistantResponseEvent": {
5958
- const content = str(parsed.content);
5959
- return content !== void 0 ? { type: "content", data: content } : null;
5960
- }
5961
- case "reasoningContentEvent": {
5962
- const text = str(parsed.text);
5963
- if (text !== void 0)
5964
- return { type: "thinkingText", data: text };
5965
- const signature = str(parsed.signature);
5966
- if (signature !== void 0)
5967
- return { type: "thinkingSignature", data: signature };
5968
- return { type: "ignored", data: { key } };
5969
- }
5970
- case "toolUseEvent":
5971
- return parseToolUse(parsed);
5972
- case "contextUsageEvent": {
5973
- const pct = num(parsed.contextUsagePercentage);
5974
- return pct !== void 0 ? { type: "contextUsage", data: { contextUsagePercentage: pct } } : null;
5159
+ break;
5160
+ }
5161
+ allocateMessage(new DataView(messageLengthBuffer.buffer).getUint32(0, false));
5162
+ messageLengthBuffer = null;
5163
+ }
5164
+ const numBytesToWrite = Math.min(currentMessageTotalLength - currentMessagePendingLength, chunkLength - currentOffset);
5165
+ currentMessage.set(value.slice(currentOffset, currentOffset + numBytesToWrite), currentMessagePendingLength);
5166
+ currentMessagePendingLength += numBytesToWrite;
5167
+ currentOffset += numBytesToWrite;
5168
+ if (currentMessageTotalLength && currentMessageTotalLength === currentMessagePendingLength) {
5169
+ yield currentMessage;
5170
+ currentMessage = null;
5171
+ currentMessageTotalLength = 0;
5172
+ currentMessagePendingLength = 0;
5173
+ }
5174
+ }
5975
5175
  }
5976
- case "metadataEvent":
5977
- return parseMetadata(parsed);
5978
- case "meteringEvent":
5979
- return {
5980
- type: "metering",
5981
- data: { credits: tokenCount(parsed.usage), unit: str(parsed.unit), unitPlural: str(parsed.unitPlural) }
5176
+ };
5177
+ return {
5178
+ [Symbol.asyncIterator]: iterator
5179
+ };
5180
+ }
5181
+
5182
+ // ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-serde-universal/getUnmarshalledStream.js
5183
+ function getMessageUnmarshaller(deserializer, toUtf82) {
5184
+ return async function(message) {
5185
+ const { value: messageType } = message.headers[":message-type"];
5186
+ if (messageType === "error") {
5187
+ const unmodeledError = new Error(message.headers[":error-message"].value || "UnknownError");
5188
+ unmodeledError.name = message.headers[":error-code"].value;
5189
+ throw unmodeledError;
5190
+ } else if (messageType === "exception") {
5191
+ const code = message.headers[":exception-type"].value;
5192
+ const exception = { [code]: message };
5193
+ const deserializedException = await deserializer(exception);
5194
+ if (deserializedException.$unknown) {
5195
+ const error2 = new Error(toUtf82(message.body));
5196
+ error2.name = code;
5197
+ throw error2;
5198
+ }
5199
+ throw deserializedException[code];
5200
+ } else if (messageType === "event") {
5201
+ const event = {
5202
+ [message.headers[":event-type"].value]: message
5982
5203
  };
5983
- // Reachable when a member that models an exception is delivered as an
5984
- // ordinary event frame. The real wire uses exception framing, handled by
5985
- // parseKiroExceptionFrame, but both routes must agree.
5986
- case "error":
5987
- case "throttlingError":
5988
- case "validationError":
5989
- case "serviceUnavailableError": {
5990
- const member = lookupKiroErrorMember(key);
5991
- return parseError(parsed, member.kind, member.exception);
5992
- }
5993
- // Known members with no consumer yet: explicitly ignored, not unparseable.
5994
- case "codeReferenceEvent":
5995
- case "documentCitationEvent":
5996
- case "toolResultEvent":
5997
- return { type: "ignored", data: { key } };
5998
- default: {
5999
- const member = lookupKiroErrorMember(key);
6000
- if (member)
6001
- return parseError(parsed, member.kind, member.exception);
6002
- return parseKiroEventByShape(parsed);
5204
+ const deserialized = await deserializer(event);
5205
+ if (deserialized.$unknown)
5206
+ return;
5207
+ return deserialized;
5208
+ } else {
5209
+ throw Error(`Unrecognizable event type: ${message.headers[":event-type"].value}`);
6003
5210
  }
6004
- }
6005
- }
6006
- function parseKiroExceptionFrame(key, parsed) {
6007
- const member = lookupKiroErrorMember(key);
6008
- if (!member)
6009
- return null;
6010
- const event = parseError(parsed, member.kind, member.exception);
6011
- return event.data;
5211
+ };
6012
5212
  }
6013
- function parseKiroEventByShape(parsed) {
6014
- if (parsed.content !== void 0)
6015
- return { type: "content", data: parsed.content };
6016
- if (typeof parsed.text === "string")
6017
- return { type: "thinkingText", data: parsed.text };
6018
- if (typeof parsed.signature === "string")
6019
- return { type: "thinkingSignature", data: parsed.signature };
6020
- if (parsed.name && parsed.toolUseId)
6021
- return parseToolUse(parsed);
6022
- if (parsed.input !== void 0 && !parsed.name) {
6023
- return { type: "toolUseInput", data: { input: toolInput(parsed.input) } };
6024
- }
6025
- if (parsed.stop !== void 0 && parsed.contextUsagePercentage === void 0)
6026
- return { type: "toolUseStop", data: { stop: parsed.stop } };
6027
- if (parsed.contextUsagePercentage !== void 0)
6028
- return { type: "contextUsage", data: { contextUsagePercentage: parsed.contextUsagePercentage } };
6029
- if (parsed.followupPrompt !== void 0)
6030
- return { type: "followupPrompt", data: parsed.followupPrompt };
6031
- if (parsed.tokenUsage !== void 0 || parsed.stopReason !== void 0 || parsed.stopDetails !== void 0) {
6032
- return parseMetadata(parsed);
5213
+
5214
+ // ../../node_modules/.pnpm/@smithy+core@3.34.1/node_modules/@smithy/core/dist-es/submodules/event-streams/eventstream-serde-universal/EventStreamMarshaller.js
5215
+ var EventStreamMarshaller = class {
5216
+ eventStreamCodec;
5217
+ utfEncoder;
5218
+ constructor({ utf8Encoder, utf8Decoder }) {
5219
+ this.eventStreamCodec = new EventStreamCodec(utf8Encoder, utf8Decoder);
5220
+ this.utfEncoder = utf8Encoder;
6033
5221
  }
6034
- if (parsed.error !== void 0 || parsed.Error !== void 0) {
6035
- return parseError(parsed, "unknown", "unknown");
5222
+ deserialize(body, deserializer) {
5223
+ const inputStream = getChunkedStream(body);
5224
+ return new SmithyMessageDecoderStream({
5225
+ messageStream: new MessageDecoderStream({ inputStream, decoder: this.eventStreamCodec }),
5226
+ deserializer: getMessageUnmarshaller(deserializer, this.utfEncoder)
5227
+ });
6036
5228
  }
6037
- if (typeof parsed.usage === "number") {
6038
- return {
6039
- type: "metering",
6040
- data: { credits: tokenCount(parsed.usage), unit: str(parsed.unit), unitPlural: str(parsed.unitPlural) }
6041
- };
5229
+ serialize(inputStream, serializer) {
5230
+ return new MessageEncoderStream({
5231
+ messageStream: new SmithyMessageEncoderStream({ inputStream, serializer }),
5232
+ encoder: this.eventStreamCodec,
5233
+ includeEndFrame: true
5234
+ });
6042
5235
  }
6043
- return null;
6044
- }
5236
+ };
6045
5237
 
6046
5238
  // ../kiro-core/dist/response-stream.js
5239
+ init_debug();
6047
5240
  var IDLE_TIMEOUT = 3e5;
6048
5241
  var eventStreamMarshaller = new EventStreamMarshaller({
6049
5242
  utf8Encoder: (input) => new TextDecoder().decode(input),
@@ -6155,12 +5348,17 @@ function readKiroEventStream(body, options) {
6155
5348
  iterResult = await iterator.next();
6156
5349
  }
6157
5350
  } catch (e) {
5351
+ if (callerSignal?.aborted)
5352
+ throw callerSignal.reason ?? e;
6158
5353
  const kiroError = e?.kiroError;
6159
5354
  if (kiroError)
6160
5355
  outcome.errorData = kiroError;
6161
5356
  outcome.error = e instanceof Error ? e.message : (typeof e === "object" && e !== null ? JSON.stringify(e) : String(e)) || "Unknown stream error";
6162
5357
  return;
6163
5358
  }
5359
+ if (callerSignal?.aborted) {
5360
+ throw callerSignal.reason ?? new Error("Request aborted");
5361
+ }
6164
5362
  const { done, value } = iterResult;
6165
5363
  if (done)
6166
5364
  return;
@@ -6198,15 +5396,22 @@ function readKiroEventStream(body, options) {
6198
5396
  }
6199
5397
 
6200
5398
  // ../kiro-core/dist/stream.js
6201
- init_retry();
5399
+ import { createHash as createHash3 } from "node:crypto";
5400
+ init_debug();
5401
+ init_effort();
5402
+ init_endpoints();
5403
+ init_kiro_cli();
5404
+ init_management();
5405
+ init_models();
5406
+ init_oauth();
6202
5407
  init_token_type();
6203
5408
 
6204
5409
  // ../kiro-core/dist/transport.js
6205
5410
  import { appendFile, mkdir } from "node:fs/promises";
6206
5411
  import { homedir as homedir5 } from "node:os";
6207
- import { join as join6 } from "node:path";
6208
- var CAPACITY_LOG_DIR = join6(homedir5(), ".ns-kiro-provider", "logs");
6209
- var CAPACITY_LOG_FILE = join6(CAPACITY_LOG_DIR, "capacity-retries.log");
5412
+ import { join as join5 } from "node:path";
5413
+ var CAPACITY_LOG_DIR = join5(homedir5(), ".ns-kiro-provider", "logs");
5414
+ var CAPACITY_LOG_FILE = join5(CAPACITY_LOG_DIR, "capacity-retries.log");
6210
5415
  var capacityLogDirCreated = false;
6211
5416
  function logCapacityEvent(message) {
6212
5417
  (async () => {
@@ -6324,9 +5529,6 @@ function describeReturnedContent(kinds) {
6324
5529
  }
6325
5530
  var skipProfileResolutionForTests = false;
6326
5531
  var TEST_PROFILE_ARN = "arn:aws:codewhisperer:us-east-1:000000000000:profile/test";
6327
- function testProfileArnOverride() {
6328
- return skipProfileResolutionForTests ? TEST_PROFILE_ARN : void 0;
6329
- }
6330
5532
  function throwOnTerminalWireStop(wireStopReason, stopDetails) {
6331
5533
  switch (wireStopReason) {
6332
5534
  case "MODEL_CONTEXT_WINDOW_EXCEEDED":
@@ -6338,7 +5540,7 @@ function throwOnTerminalWireStop(wireStopReason, stopDetails) {
6338
5540
  }
6339
5541
  }
6340
5542
  async function* streamKiro(request) {
6341
- yield* streamKiroOnEngine(request, streamKiroInProcess);
5543
+ yield* streamKiroInProcess(request);
6342
5544
  }
6343
5545
  async function* streamKiroInProcess(request) {
6344
5546
  const { model, signal } = request;
@@ -6621,185 +5823,25 @@ ${systemPrompt}` : ""}`;
6621
5823
  yield* assembler.takeEvents();
6622
5824
  if (!errorMessage) {
6623
5825
  const estimatedRead = applyCacheEstimate(conversationId, usage, wireUsage, usageTracking);
6624
- if (estimatedRead > 0) {
6625
- debugLog("usage.estimate", {
6626
- conversationId,
6627
- estimatedRead,
6628
- input: usage.input,
6629
- cacheRead: usage.cacheRead
6630
- });
6631
- }
6632
- const estimatedCost = estimateKiroCreditCost(usageTracking, metering);
6633
- if (estimatedCost !== void 0)
6634
- usage.cost.total = estimatedCost;
6635
- }
6636
- yield { type: "usage", usage };
6637
- yield { type: "done", stopReason, ...errorMessage ? { errorMessage } : {} };
6638
- return;
6639
- }
6640
- }
6641
-
6642
- // ../kiro-core/dist/engine.js
6643
- var KIRO_SIDECAR_VENDOR = "kiro";
6644
- function selectKiroEngine() {
6645
- return selectBridgeEngine(KIRO_SIDECAR_VENDOR);
6646
- }
6647
- function toKiroSidecarRequest(request, conversationId) {
6648
- const { signal: _signal, ...wire } = request;
6649
- const kiroModelId = resolveKiroModel(request.model.id, request.model.kiroModelId);
6650
- const testProfileArn = testProfileArnOverride();
6651
- return {
6652
- ...wire,
6653
- model: { ...request.model, kiroModelId },
6654
- conversationId,
6655
- profileArnCache: snapshotKiroProfileArnCache(),
6656
- timeouts: {
6657
- firstTokenMs: request.model.firstTokenTimeout ?? firstTokenTimeoutForModel(request.model.id),
6658
- requestHeaderMs: retryConfig.requestHeaderTimeoutMs
6659
- },
6660
- capacityRetry: { ...capacityRetryConfig },
6661
- ...testProfileArn ? { testProfileArn } : {}
6662
- };
6663
- }
6664
- async function* postProcess(events, request, conversationId) {
6665
- let pendingUsage;
6666
- for await (const event of events) {
6667
- if (event.type === "usage") {
6668
- pendingUsage = event;
6669
- continue;
6670
- }
6671
- if (event.type !== "done") {
6672
- yield event;
6673
- continue;
6674
- }
6675
- const { kiroProfileArns, kiroRuntimeRegion, kiroProfileArn, ...done } = event;
6676
- applyKiroProfileArnCacheChanges(kiroProfileArns);
6677
- const region = kiroRuntimeRegion ?? getKiroRegionFromProfileArn(kiroProfileArn) ?? request.model.region;
6678
- if (!process.env.VITEST && region && kiroProfileArn && isCacheStale(region)) {
6679
- updateKiroModelsCache(request.accessToken, region, kiroProfileArn).catch((error2) => {
6680
- console.warn(`[kiro-core] Failed to refresh Kiro model catalog in ${region}: ${formatSafeError(error2)}`);
6681
- });
6682
- }
6683
- if (pendingUsage) {
6684
- const { kiroWireCache, ...usageEvent } = pendingUsage;
6685
- if (!done.errorMessage) {
6686
- const estimatedRead = applyCacheEstimate(conversationId, usageEvent.usage, kiroWireCache ? { cacheReadInputTokens: 0 } : null, request.usageTracking ?? KIRO_USAGE_TRACKING_DISABLED);
6687
- if (estimatedRead > 0) {
6688
- debugLog("usage.estimate", {
6689
- conversationId,
6690
- estimatedRead,
6691
- input: usageEvent.usage.input,
6692
- cacheRead: usageEvent.usage.cacheRead
6693
- });
6694
- }
6695
- }
6696
- pendingUsage = void 0;
6697
- yield usageEvent;
6698
- }
6699
- yield done;
6700
- }
6701
- if (pendingUsage) {
6702
- const { kiroWireCache: _wire, ...usageEvent } = pendingUsage;
6703
- yield usageEvent;
6704
- }
6705
- }
6706
- function streamKiroOnEngine(request, inProcess) {
6707
- if (selectKiroEngine() === "ts" || !request.accessToken)
6708
- return inProcess(request);
6709
- const conversationId = request.sessionId ?? crypto.randomUUID();
6710
- let sidecarRequest;
6711
- try {
6712
- sidecarRequest = toKiroSidecarRequest(request, conversationId);
6713
- } catch {
6714
- return inProcess(request);
6715
- }
6716
- return engineStream({
6717
- vendor: KIRO_SIDECAR_VENDOR,
6718
- request: () => sidecarRequest,
6719
- inProcess: () => inProcess(request),
6720
- mapError: kiroErrorFromSidecar,
6721
- transform: (events) => postProcess(events, request, conversationId),
6722
- ...request.signal ? { signal: request.signal } : {}
6723
- });
6724
- }
6725
-
6726
- // ../kiro-core/dist/index.js
6727
- init_engine_ops();
6728
- init_errors2();
6729
-
6730
- // ../kiro-core/dist/host-auth.js
6731
- init_endpoints();
6732
- init_oauth();
6733
- var KIRO_NO_SESSION_MESSAGE = "No Kiro session found. Sign in with `kiro-cli login` (Builder ID, IAM Identity Center, Google, or GitHub), then run /login kiro again \u2014 or paste a Kiro API key below.";
6734
- async function loginKiroFromSession(callbacks) {
6735
- callbacks.onProgress?.("Looking for an existing Kiro session\u2026");
6736
- const existing = await resolveKiroCredentials();
6737
- if (existing) {
6738
- callbacks.onProgress?.(`Using the ${existing.authMethod} session from kiro-cli.`);
6739
- return existing;
6740
- }
6741
- if (!callbacks.onPrompt)
6742
- throw new Error(KIRO_NO_SESSION_MESSAGE);
6743
- const apiKey = (await callbacks.onPrompt({
6744
- message: KIRO_NO_SESSION_MESSAGE,
6745
- placeholder: "ksk_\u2026",
6746
- allowEmpty: true,
6747
- secret: true
6748
- })).trim();
6749
- if (!apiKey)
6750
- throw new Error(KIRO_NO_SESSION_MESSAGE);
6751
- return loginKiroWithApiKey(apiKey, callbacks.onProgress);
6752
- }
6753
- async function resolveKiroRequestCredentials(hostKey) {
6754
- const stored = await resolveKiroCredentials();
6755
- const region = resolveApiRegion(stored?.region);
6756
- if (hostKey && (isApiKey(hostKey) || hostKey === stored?.access)) {
6757
- return { accessToken: hostKey, region, ...stored?.profileArn ? { profileArn: stored.profileArn } : {} };
6758
- }
6759
- if (stored) {
6760
- return {
6761
- accessToken: stored.access,
6762
- region,
6763
- ...stored.profileArn ? { profileArn: stored.profileArn } : {}
6764
- };
6765
- }
6766
- if (hostKey)
6767
- return { accessToken: hostKey, region };
6768
- throw new Error("Kiro credentials not set. Run `kiro-cli login`, or set KIRO_API_KEY to a `ksk_` API key.");
6769
- }
6770
-
6771
- // ../kiro-core/dist/host-model.js
6772
- init_models();
6773
- function toKiroModelForHost(model, region) {
6774
- const known = getCachedModels(region).find((candidate) => candidate.id === model.id);
6775
- return {
6776
- ...known ?? {
6777
- id: model.id,
6778
- // No fallback to `model.id`: that dash-spelled local id is not a valid
6779
- // Kiro wire id. `""` is falsy, so `resolveKiroModel` runs its own
6780
- // cache/bootstrap/dot-normalize resolution instead of being
6781
- // short-circuited by a value that is really just `model.id` again.
6782
- kiroModelId: model.kiroModelId ?? "",
6783
- name: model.name,
6784
- reasoning: model.reasoning,
6785
- input: [...model.input],
6786
- cost: { ...model.cost },
6787
- contextWindow: model.contextWindow ?? 2e5,
6788
- maxTokens: model.maxTokens ?? 8192
6789
- },
6790
- region,
6791
- ...model.kiroProfileArn ? { profileArn: model.kiroProfileArn } : {},
6792
- ...model.additionalModelRequestFieldsSchema ? { additionalModelRequestFieldsSchema: model.additionalModelRequestFieldsSchema } : {}
6793
- };
5826
+ if (estimatedRead > 0) {
5827
+ debugLog("usage.estimate", {
5828
+ conversationId,
5829
+ estimatedRead,
5830
+ input: usage.input,
5831
+ cacheRead: usage.cacheRead
5832
+ });
5833
+ }
5834
+ const estimatedCost = estimateKiroCreditCost(usageTracking, metering);
5835
+ if (estimatedCost !== void 0)
5836
+ usage.cost.total = estimatedCost;
5837
+ }
5838
+ yield { type: "usage", usage };
5839
+ yield { type: "done", stopReason, ...errorMessage ? { errorMessage } : {} };
5840
+ return;
5841
+ }
6794
5842
  }
6795
5843
 
6796
5844
  // ../kiro-core/dist/index.js
6797
- init_kiro_cli();
6798
- init_kiro_ide();
6799
- init_management();
6800
- init_models();
6801
- init_oauth();
6802
- init_retry();
6803
5845
  init_types();
6804
5846
 
6805
5847
  // ../kiro-core/dist/usage.js
@@ -6935,17 +5977,225 @@ async function registerKiroProvider(pi) {
6935
5977
  }
6936
5978
 
6937
5979
  // ../pi-provider/src/devin/register.ts
6938
- import { existsSync as existsSync5, readFileSync as readFileSync5 } from "node:fs";
5980
+ import { existsSync as existsSync4, readFileSync as readFileSync5 } from "node:fs";
6939
5981
 
6940
- // ../devin-core/dist/capacity-retry.js
6941
- init_engine2();
6942
- init_errors3();
5982
+ // ../devin-core/dist/util.js
5983
+ import { createHash as createHash4 } from "node:crypto";
5984
+ function isRecord3(value) {
5985
+ return typeof value === "object" && value !== null && !Array.isArray(value);
5986
+ }
5987
+ var ANSI_PATTERN = /\x1b(?:\[[0-9;?]*[ -/]*[@-~]|\][^\x07\x1b]*(?:\x07|\x1b\\)|[@-Z\\-_])/g;
5988
+ var CONTROL_PATTERN = /[\x00-\x08\x0B-\x1F\x7F-\x9F]/g;
5989
+ var REPLACEMENT_CHAR = "\uFFFD";
5990
+ function sanitizeText(text) {
5991
+ const wellFormed = text.toWellFormed();
5992
+ const clean = wellFormed === text ? text : wellFormed.replaceAll(REPLACEMENT_CHAR, "");
5993
+ return clean.replace(ANSI_PATTERN, "").replace(CONTROL_PATTERN, "");
5994
+ }
5995
+ function deterministicUuid(seed) {
5996
+ const hex = createHash4("sha256").update(seed).digest("hex");
5997
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
5998
+ }
5999
+ function devinDebugEnabled() {
6000
+ const value = process.env.NS_DEVIN_DEBUG ?? process.env.DEVIN_DEBUG;
6001
+ return value !== void 0 && value !== "" && value !== "0" && value !== "false";
6002
+ }
6003
+ function emit(method, message, data) {
6004
+ const line = data === void 0 ? `[devin] ${message}` : `[devin] ${message} ${safeJson(data)}`;
6005
+ console[method === "debug" ? "error" : method](line);
6006
+ }
6007
+ function safeJson(data) {
6008
+ try {
6009
+ return JSON.stringify(data, (_key, value) => typeof value === "bigint" ? Number(value) : value);
6010
+ } catch {
6011
+ return "";
6012
+ }
6013
+ }
6014
+ var logger = {
6015
+ debug(message, data) {
6016
+ if (devinDebugEnabled())
6017
+ emit("debug", message, data);
6018
+ },
6019
+ warn(message, data) {
6020
+ emit("warn", message, data);
6021
+ },
6022
+ error(message, data) {
6023
+ emit("error", message, data);
6024
+ }
6025
+ };
6026
+ var SENSITIVE_PATTERNS = [
6027
+ /\b(sk|pk|key|token|secret|password|bearer|api[_-]?key|credential|authorization)\s*[:=]\s*["']?[\w.$~+-]{6,}["']?/gi,
6028
+ /\b(cog_|devin-session-token\$)[\w.$~+-]+/g,
6029
+ /\bBearer\s+[\w.$~+-]{6,}/gi
6030
+ ];
6031
+ function redactSensitiveCredentials(text) {
6032
+ let out = text;
6033
+ for (const pattern of SENSITIVE_PATTERNS) {
6034
+ out = out.replace(pattern, (match) => {
6035
+ const separator = match.match(/[:=\s]/)?.index ?? 0;
6036
+ return `${match.slice(0, separator + 1)}[REDACTED]`;
6037
+ });
6038
+ }
6039
+ return out;
6040
+ }
6041
+ function normalizeSystemPrompts(systemPrompt) {
6042
+ const prompts = systemPrompt === void 0 || systemPrompt === null ? [] : Array.isArray(systemPrompt) ? systemPrompt : typeof systemPrompt === "string" ? [systemPrompt] : [];
6043
+ return prompts.map((prompt) => redactSensitiveCredentials(prompt.toWellFormed())).filter((prompt) => prompt.trim().length > 0);
6044
+ }
6943
6045
 
6944
- // ../devin-core/dist/client.js
6945
- init_errors3();
6046
+ // ../devin-core/dist/errors.js
6047
+ var DevinApiError = class extends Error {
6048
+ status;
6049
+ operation;
6050
+ headers;
6051
+ constructor(message, operation, status, headers) {
6052
+ super(message);
6053
+ this.name = "DevinApiError";
6054
+ this.operation = operation;
6055
+ this.status = status;
6056
+ this.headers = headers ?? {};
6057
+ }
6058
+ };
6059
+ var DevinProtocolError = class extends Error {
6060
+ kind;
6061
+ constructor(message, kind = "runtime") {
6062
+ super(message);
6063
+ this.name = "DevinProtocolError";
6064
+ this.kind = kind;
6065
+ }
6066
+ };
6067
+ var DevinStreamError = class extends Error {
6068
+ code;
6069
+ contextOverflow;
6070
+ constructor(message, code = "", contextOverflow = false) {
6071
+ super(message);
6072
+ this.name = "DevinStreamError";
6073
+ this.code = code;
6074
+ this.contextOverflow = contextOverflow;
6075
+ }
6076
+ };
6077
+ var MAX_DEVIN_ERROR_DETAIL_CHARS = 4096;
6078
+ var HTML_ERROR_BODY_PATTERN = /^\s*(?:<!doctype\s+html\b|<html\b)/i;
6079
+ function devinErrorDetail(response, payload) {
6080
+ let text;
6081
+ try {
6082
+ text = new TextDecoder("utf-8", { fatal: true }).decode(payload).trim();
6083
+ } catch {
6084
+ return void 0;
6085
+ }
6086
+ if (response.headers.get("content-type")?.toLowerCase().includes("text/html"))
6087
+ return void 0;
6088
+ try {
6089
+ const decoded = JSON.parse(text);
6090
+ if (isRecord3(decoded)) {
6091
+ const error2 = decoded.error;
6092
+ if (isRecord3(error2) && typeof error2.message === "string")
6093
+ text = error2.message.trim();
6094
+ else if (typeof error2 === "string")
6095
+ text = error2.trim();
6096
+ else if (typeof decoded.message === "string")
6097
+ text = decoded.message.trim();
6098
+ }
6099
+ } catch {
6100
+ }
6101
+ const normalized = text.replace(/\s+/g, " ").trim();
6102
+ if (normalized.length === 0 || HTML_ERROR_BODY_PATTERN.test(normalized) || sanitizeText(normalized) !== normalized) {
6103
+ return void 0;
6104
+ }
6105
+ if (normalized.length <= MAX_DEVIN_ERROR_DETAIL_CHARS)
6106
+ return normalized;
6107
+ const boundaryUnit = normalized.charCodeAt(MAX_DEVIN_ERROR_DETAIL_CHARS - 1);
6108
+ const cut = boundaryUnit >= 55296 && boundaryUnit <= 56319 ? MAX_DEVIN_ERROR_DETAIL_CHARS - 1 : MAX_DEVIN_ERROR_DETAIL_CHARS;
6109
+ return normalized.slice(0, cut);
6110
+ }
6111
+ function createDevinHttpError(operation, response, payload) {
6112
+ const status = `${response.status}${response.statusText ? ` ${response.statusText}` : ""}`;
6113
+ const detail = devinErrorDetail(response, payload);
6114
+ const headers = {};
6115
+ response.headers.forEach((value, key) => {
6116
+ headers[key] = value;
6117
+ });
6118
+ return new DevinApiError(`Devin ${operation} error ${status}${detail ? `: ${detail}` : ""}`, operation, response.status, headers);
6119
+ }
6120
+ var MAX_TRAILER_EVIDENCE_CHARS = 2e3;
6121
+ function truncateTrailerEvidence(text) {
6122
+ return text.length > MAX_TRAILER_EVIDENCE_CHARS ? `${text.slice(0, MAX_TRAILER_EVIDENCE_CHARS)}\u2026` : text;
6123
+ }
6124
+ function summarizeTrailerDetails(details) {
6125
+ if (!Array.isArray(details) || details.length === 0)
6126
+ return void 0;
6127
+ let summary = "";
6128
+ for (const entry of details) {
6129
+ if (!isRecord3(entry))
6130
+ continue;
6131
+ const type = typeof entry.type === "string" && entry.type ? entry.type : void 0;
6132
+ const value = typeof entry.value === "string" && entry.value ? entry.value : void 0;
6133
+ let debug;
6134
+ if (entry.debug !== void 0) {
6135
+ try {
6136
+ debug = typeof entry.debug === "string" ? entry.debug : JSON.stringify(entry.debug);
6137
+ } catch {
6138
+ debug = void 0;
6139
+ }
6140
+ }
6141
+ const boundedType = type ? truncateTrailerEvidence(type) : void 0;
6142
+ const evidence = debug ?? value;
6143
+ const boundedEvidence = evidence ? truncateTrailerEvidence(evidence) : void 0;
6144
+ let part;
6145
+ if (boundedType && boundedEvidence)
6146
+ part = `${boundedType}: ${boundedEvidence}`;
6147
+ else
6148
+ part = boundedType ?? boundedEvidence;
6149
+ if (!part)
6150
+ continue;
6151
+ const next = summary ? `${summary}; ${part}` : part;
6152
+ if (next.length > MAX_TRAILER_EVIDENCE_CHARS)
6153
+ return truncateTrailerEvidence(next);
6154
+ summary = next;
6155
+ }
6156
+ return summary || void 0;
6157
+ }
6158
+ function readConnectTrailerError(text) {
6159
+ if (text.length === 0)
6160
+ return null;
6161
+ let parsed;
6162
+ try {
6163
+ parsed = JSON.parse(text);
6164
+ } catch {
6165
+ return null;
6166
+ }
6167
+ if (!isRecord3(parsed) || !("error" in parsed))
6168
+ return null;
6169
+ const err = parsed.error;
6170
+ if (!isRecord3(err))
6171
+ return null;
6172
+ const code = typeof err.code === "string" ? err.code : "";
6173
+ const message = typeof err.message === "string" ? err.message : "";
6174
+ if (!code && !message)
6175
+ return null;
6176
+ const trailer = {
6177
+ code,
6178
+ message,
6179
+ formatted: `Devin stream error${code ? ` ${code}` : ""}: ${message}`,
6180
+ raw: truncateTrailerEvidence(text)
6181
+ };
6182
+ const detail = summarizeTrailerDetails(err.details);
6183
+ if (detail) {
6184
+ trailer.detail = detail;
6185
+ trailer.formatted += ` [details: ${detail}]`;
6186
+ }
6187
+ return trailer;
6188
+ }
6189
+ function isDevinCapacityError(error2) {
6190
+ if (error2 instanceof DevinApiError)
6191
+ return error2.status === 502 || error2.status === 503 || error2.status === 529;
6192
+ if (error2 instanceof DevinStreamError) {
6193
+ return error2.code === "unavailable" || error2.code === "deadline_exceeded" || /capacity|overload/i.test(error2.message);
6194
+ }
6195
+ return false;
6196
+ }
6946
6197
 
6947
6198
  // ../devin-core/dist/proto/protobuf.js
6948
- init_util();
6949
6199
  var textEncoder = new TextEncoder();
6950
6200
  var textDecoder = new TextDecoder("utf-8", { fatal: true });
6951
6201
  function pb(typeName, fields = []) {
@@ -9478,7 +8728,6 @@ async function assignDevinModel(model, turn, routerPrompt, baseUrl, fetchImpl, s
9478
8728
  }
9479
8729
 
9480
8730
  // ../devin-core/dist/connect.js
9481
- init_errors3();
9482
8731
  import { gunzipSync as gunzipSync2, gzipSync } from "node:zlib";
9483
8732
  var CONNECT_COMPRESSED_FLAG = 1;
9484
8733
  var CONNECT_END_STREAM_FLAG = 2;
@@ -9524,10 +8773,6 @@ var ConnectFrameReader = class {
9524
8773
  }
9525
8774
  };
9526
8775
 
9527
- // ../devin-core/dist/stream.js
9528
- init_engine2();
9529
- init_errors3();
9530
-
9531
8776
  // ../devin-core/dist/json.js
9532
8777
  function parseStreamingJson(partialJson) {
9533
8778
  const trimmed = partialJson?.trimStart();
@@ -9620,7 +8865,6 @@ function parseToolCallArguments(json) {
9620
8865
  }
9621
8866
 
9622
8867
  // ../devin-core/dist/schema.js
9623
- init_util();
9624
8868
  var GOOGLE_UNSUPPORTED_FIELDS = /* @__PURE__ */ new Set([
9625
8869
  "$schema",
9626
8870
  "$id",
@@ -9715,7 +8959,6 @@ function isGeminiRoutedModel(...candidates) {
9715
8959
  }
9716
8960
 
9717
8961
  // ../devin-core/dist/request-builder.js
9718
- init_util();
9719
8962
  var DEVIN_DEFAULT_STOP_PATTERNS = [
9720
8963
  "<|user|>",
9721
8964
  "<|bot|>",
@@ -9855,7 +9098,6 @@ function buildDevinChatRequest(params) {
9855
9098
  }
9856
9099
 
9857
9100
  // ../devin-core/dist/stream.js
9858
- init_util();
9859
9101
  var LARGE_HISTORY_RECOVERY_BYTES = 512 * 1024;
9860
9102
  function calculateDevinCost(cost, usage) {
9861
9103
  const per = (tokens, rate) => tokens / 1e6 * rate;
@@ -9866,9 +9108,11 @@ function calculateDevinCost(cost, usage) {
9866
9108
  return { input, output, cacheRead, cacheWrite, total: input + output + cacheRead + cacheWrite };
9867
9109
  }
9868
9110
  function streamDevin(request) {
9869
- return streamDevinOnEngine(request, void 0, streamDevinInProcess);
9111
+ return streamDevinInProcess(request);
9870
9112
  }
9871
9113
  async function* streamDevinInProcess(request) {
9114
+ if (request.signal?.aborted)
9115
+ throw request.signal.reason ?? new Error("Request aborted");
9872
9116
  const model = request.model;
9873
9117
  const fetchImpl = request.fetch ?? fetch;
9874
9118
  const baseUrl = (model.baseUrl || DEVIN_DEFAULT_BASE_URL).replace(/\/+$/, "");
@@ -9947,143 +9191,169 @@ async function* streamDevinInProcess(request) {
9947
9191
  };
9948
9192
  const reader = new ConnectFrameReader();
9949
9193
  const body = response.body.getReader();
9950
- for (; ; ) {
9951
- const { done, value } = await body.read();
9952
- if (value && value.length > 0)
9953
- reader.push(value);
9194
+ const signal = request.signal;
9195
+ const onAbort = () => {
9196
+ void body.cancel(signal?.reason).catch(() => {
9197
+ });
9198
+ };
9199
+ if (signal?.aborted)
9200
+ onAbort();
9201
+ else
9202
+ signal?.addEventListener("abort", onAbort, { once: true });
9203
+ const abortReason = () => signal?.reason ?? new Error("Request aborted");
9204
+ try {
9954
9205
  for (; ; ) {
9955
- const envelope = reader.next();
9956
- if (envelope === null)
9957
- break;
9958
- if (envelope.endStream) {
9959
- const trailerError = readConnectTrailerError(new TextDecoder().decode(envelope.payload).trim());
9960
- if (trailerError === null)
9961
- continue;
9962
- logger.warn("stream rejected via Connect trailer", {
9963
- model: model.id,
9964
- code: trailerError.code,
9965
- message: trailerError.message,
9966
- ...trailerError.detail ? { detail: trailerError.detail } : {},
9967
- rawTrailer: trailerError.raw,
9968
- requestBytes: requestBytes.byteLength,
9969
- messages: request.messages.length,
9970
- hadOutput: sawAnyToken
9971
- });
9972
- let contextOverflow = false;
9973
- if (!sawAnyToken && trailerError.code.toLowerCase() === "invalid_argument" && /\binternal error\b/i.test(trailerError.message)) {
9974
- const historyBytes = toBinary(GetChatMessageRequestSchema, create(GetChatMessageRequestSchema, {
9975
- chatMessagePrompts: buildChatMessagePrompts(request.messages, turn.cascadeId)
9976
- })).byteLength;
9977
- contextOverflow = historyBytes >= LARGE_HISTORY_RECOVERY_BYTES;
9978
- if (contextOverflow) {
9979
- logger.warn("treating large-history invalid_argument as context overflow", {
9980
- model: model.id,
9981
- historyBytes
9982
- });
9206
+ if (signal?.aborted)
9207
+ throw abortReason();
9208
+ let read;
9209
+ try {
9210
+ read = await body.read();
9211
+ } catch (error2) {
9212
+ if (signal?.aborted)
9213
+ throw abortReason();
9214
+ throw error2;
9215
+ }
9216
+ if (signal?.aborted)
9217
+ throw abortReason();
9218
+ const { done, value } = read;
9219
+ if (value && value.length > 0)
9220
+ reader.push(value);
9221
+ for (; ; ) {
9222
+ const envelope = reader.next();
9223
+ if (envelope === null)
9224
+ break;
9225
+ if (envelope.endStream) {
9226
+ const trailerError = readConnectTrailerError(new TextDecoder().decode(envelope.payload).trim());
9227
+ if (trailerError === null)
9228
+ continue;
9229
+ logger.warn("stream rejected via Connect trailer", {
9230
+ model: model.id,
9231
+ code: trailerError.code,
9232
+ message: trailerError.message,
9233
+ ...trailerError.detail ? { detail: trailerError.detail } : {},
9234
+ rawTrailer: trailerError.raw,
9235
+ requestBytes: requestBytes.byteLength,
9236
+ messages: request.messages.length,
9237
+ hadOutput: sawAnyToken
9238
+ });
9239
+ let contextOverflow = false;
9240
+ if (!sawAnyToken && trailerError.code.toLowerCase() === "invalid_argument" && /\binternal error\b/i.test(trailerError.message)) {
9241
+ const historyBytes = toBinary(GetChatMessageRequestSchema, create(GetChatMessageRequestSchema, {
9242
+ chatMessagePrompts: buildChatMessagePrompts(request.messages, turn.cascadeId)
9243
+ })).byteLength;
9244
+ contextOverflow = historyBytes >= LARGE_HISTORY_RECOVERY_BYTES;
9245
+ if (contextOverflow) {
9246
+ logger.warn("treating large-history invalid_argument as context overflow", {
9247
+ model: model.id,
9248
+ historyBytes
9249
+ });
9250
+ }
9983
9251
  }
9252
+ throw new DevinStreamError(trailerError.formatted, trailerError.code, contextOverflow);
9984
9253
  }
9985
- throw new DevinStreamError(trailerError.formatted, trailerError.code, contextOverflow);
9986
- }
9987
- const msg = fromBinary(GetChatMessageResponseSchema, envelope.payload);
9988
- if (msg.messageId && !responseId)
9989
- responseId = msg.messageId;
9990
- if (msg.actualModelUid)
9991
- upstreamModel = msg.actualModelUid;
9992
- if (msg.deltaThinking) {
9993
- markToken();
9994
- if (openThinking === void 0) {
9995
- openThinking = { index: nextIndex++, text: "" };
9996
- yield { type: "thinking_start", index: openThinking.index };
9997
- }
9998
- openThinking.text += msg.deltaThinking;
9999
- yield { type: "thinking_delta", index: openThinking.index, delta: msg.deltaThinking };
10000
- }
10001
- if (msg.deltaSignature && openThinking !== void 0)
10002
- openThinking.signature = msg.deltaSignature;
10003
- if (msg.deltaText) {
10004
- markToken();
10005
- if (openThinking !== void 0) {
10006
- yield {
10007
- type: "thinking_end",
10008
- index: openThinking.index,
10009
- thinking: openThinking.text,
10010
- ...openThinking.signature ? { signature: openThinking.signature } : {}
10011
- };
10012
- openThinking = void 0;
9254
+ const msg = fromBinary(GetChatMessageResponseSchema, envelope.payload);
9255
+ if (msg.messageId && !responseId)
9256
+ responseId = msg.messageId;
9257
+ if (msg.actualModelUid)
9258
+ upstreamModel = msg.actualModelUid;
9259
+ if (msg.deltaThinking) {
9260
+ markToken();
9261
+ if (openThinking === void 0) {
9262
+ openThinking = { index: nextIndex++, text: "" };
9263
+ yield { type: "thinking_start", index: openThinking.index };
9264
+ }
9265
+ openThinking.text += msg.deltaThinking;
9266
+ yield { type: "thinking_delta", index: openThinking.index, delta: msg.deltaThinking };
10013
9267
  }
10014
- if (openText === void 0) {
10015
- openText = { index: nextIndex++, text: "" };
10016
- yield { type: "text_start", index: openText.index };
9268
+ if (msg.deltaSignature && openThinking !== void 0)
9269
+ openThinking.signature = msg.deltaSignature;
9270
+ if (msg.deltaText) {
9271
+ markToken();
9272
+ if (openThinking !== void 0) {
9273
+ yield {
9274
+ type: "thinking_end",
9275
+ index: openThinking.index,
9276
+ thinking: openThinking.text,
9277
+ ...openThinking.signature ? { signature: openThinking.signature } : {}
9278
+ };
9279
+ openThinking = void 0;
9280
+ }
9281
+ if (openText === void 0) {
9282
+ openText = { index: nextIndex++, text: "" };
9283
+ yield { type: "text_start", index: openText.index };
9284
+ }
9285
+ openText.text += msg.deltaText;
9286
+ yield { type: "text_delta", index: openText.index, delta: msg.deltaText };
10017
9287
  }
10018
- openText.text += msg.deltaText;
10019
- yield { type: "text_delta", index: openText.index, delta: msg.deltaText };
10020
- }
10021
- if (msg.deltaToolCalls.length > 0) {
10022
- markToken();
10023
- if (openText !== void 0) {
10024
- yield { type: "text_end", index: openText.index, text: openText.text };
10025
- openText = void 0;
9288
+ if (msg.deltaToolCalls.length > 0) {
9289
+ markToken();
9290
+ if (openText !== void 0) {
9291
+ yield { type: "text_end", index: openText.index, text: openText.text };
9292
+ openText = void 0;
9293
+ }
9294
+ if (openThinking !== void 0) {
9295
+ yield {
9296
+ type: "thinking_end",
9297
+ index: openThinking.index,
9298
+ thinking: openThinking.text,
9299
+ ...openThinking.signature ? { signature: openThinking.signature } : {}
9300
+ };
9301
+ openThinking = void 0;
9302
+ }
9303
+ for (const call of msg.deltaToolCalls) {
9304
+ const toolCallId = call.id || activeToolCallId;
9305
+ if (!toolCallId)
9306
+ continue;
9307
+ let block = toolBlocks.get(toolCallId);
9308
+ if (block === void 0) {
9309
+ block = { index: nextIndex++, name: call.name };
9310
+ toolBlocks.set(toolCallId, block);
9311
+ toolPartialJson.set(toolCallId, "");
9312
+ yield { type: "tool_call_start", index: block.index, id: toolCallId, name: call.name };
9313
+ }
9314
+ if (call.name)
9315
+ block.name = call.name;
9316
+ activeToolCallId = toolCallId;
9317
+ if (!call.argumentsJson)
9318
+ continue;
9319
+ const previousJson = toolPartialJson.get(toolCallId) ?? "";
9320
+ const accumulated = call.argumentsJson.startsWith(previousJson) ? call.argumentsJson : previousJson + call.argumentsJson;
9321
+ const delta = accumulated.slice(previousJson.length);
9322
+ toolPartialJson.set(toolCallId, accumulated);
9323
+ const throttled = parseStreamingJsonThrottled(accumulated, toolLastParseLen.get(toolCallId) ?? 0);
9324
+ if (throttled)
9325
+ toolLastParseLen.set(toolCallId, throttled.parsedLen);
9326
+ yield { type: "tool_call_delta", index: block.index, id: toolCallId, argumentsDelta: delta };
9327
+ }
10026
9328
  }
10027
- if (openThinking !== void 0) {
10028
- yield {
10029
- type: "thinking_end",
10030
- index: openThinking.index,
10031
- thinking: openThinking.text,
10032
- ...openThinking.signature ? { signature: openThinking.signature } : {}
9329
+ if (msg.stopReason !== StopReason.UNSPECIFIED)
9330
+ latestStopReason = msg.stopReason;
9331
+ if (msg.usage || msg.creditCost || msg.committedCreditCost || msg.committedAcuCost) {
9332
+ const usage = {
9333
+ input: Number(msg.usage?.inputTokens ?? 0n),
9334
+ output: Number(msg.usage?.outputTokens ?? 0n),
9335
+ cacheRead: Number(msg.usage?.cacheReadTokens ?? 0n),
9336
+ cacheWrite: Number(msg.usage?.cacheWriteTokens ?? 0n)
10033
9337
  };
10034
- openThinking = void 0;
10035
- }
10036
- for (const call of msg.deltaToolCalls) {
10037
- const toolCallId = call.id || activeToolCallId;
10038
- if (!toolCallId)
10039
- continue;
10040
- let block = toolBlocks.get(toolCallId);
10041
- if (block === void 0) {
10042
- block = { index: nextIndex++, name: call.name };
10043
- toolBlocks.set(toolCallId, block);
10044
- toolPartialJson.set(toolCallId, "");
10045
- yield { type: "tool_call_start", index: block.index, id: toolCallId, name: call.name };
10046
- }
10047
- if (call.name)
10048
- block.name = call.name;
10049
- activeToolCallId = toolCallId;
10050
- if (!call.argumentsJson)
9338
+ const totalTokens = usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
9339
+ const credits = msg.creditCost || msg.committedCreditCost || msg.committedAcuCost;
9340
+ const moved = responseUsage === void 0 ? totalTokens > 0 || credits !== 0 : totalTokens !== responseUsage.totalTokens || credits !== (responseUsage.credits ?? 0);
9341
+ if (!moved)
10051
9342
  continue;
10052
- const previousJson = toolPartialJson.get(toolCallId) ?? "";
10053
- const accumulated = call.argumentsJson.startsWith(previousJson) ? call.argumentsJson : previousJson + call.argumentsJson;
10054
- const delta = accumulated.slice(previousJson.length);
10055
- toolPartialJson.set(toolCallId, accumulated);
10056
- const throttled = parseStreamingJsonThrottled(accumulated, toolLastParseLen.get(toolCallId) ?? 0);
10057
- if (throttled)
10058
- toolLastParseLen.set(toolCallId, throttled.parsedLen);
10059
- yield { type: "tool_call_delta", index: block.index, id: toolCallId, argumentsDelta: delta };
9343
+ responseUsage = {
9344
+ ...usage,
9345
+ totalTokens,
9346
+ ...credits ? { credits } : {},
9347
+ cost: calculateDevinCost(model.cost, usage)
9348
+ };
9349
+ yield { type: "usage", usage: responseUsage };
10060
9350
  }
10061
9351
  }
10062
- if (msg.stopReason !== StopReason.UNSPECIFIED)
10063
- latestStopReason = msg.stopReason;
10064
- if (msg.usage || msg.creditCost || msg.committedCreditCost || msg.committedAcuCost) {
10065
- const usage = {
10066
- input: Number(msg.usage?.inputTokens ?? 0n),
10067
- output: Number(msg.usage?.outputTokens ?? 0n),
10068
- cacheRead: Number(msg.usage?.cacheReadTokens ?? 0n),
10069
- cacheWrite: Number(msg.usage?.cacheWriteTokens ?? 0n)
10070
- };
10071
- const totalTokens = usage.input + usage.output + usage.cacheRead + usage.cacheWrite;
10072
- const credits = msg.creditCost || msg.committedCreditCost || msg.committedAcuCost;
10073
- const moved = responseUsage === void 0 ? totalTokens > 0 || credits !== 0 : totalTokens !== responseUsage.totalTokens || credits !== (responseUsage.credits ?? 0);
10074
- if (!moved)
10075
- continue;
10076
- responseUsage = {
10077
- ...usage,
10078
- totalTokens,
10079
- ...credits ? { credits } : {},
10080
- cost: calculateDevinCost(model.cost, usage)
10081
- };
10082
- yield { type: "usage", usage: responseUsage };
10083
- }
9352
+ if (done)
9353
+ break;
10084
9354
  }
10085
- if (done)
10086
- break;
9355
+ } finally {
9356
+ signal?.removeEventListener("abort", onAbort);
10087
9357
  }
10088
9358
  if (openText !== void 0) {
10089
9359
  yield { type: "text_end", index: openText.index, text: openText.text };
@@ -10134,10 +9404,6 @@ function abortableDelay2(ms, signal) {
10134
9404
  });
10135
9405
  }
10136
9406
  async function* streamDevinWithCapacityRetry(request, policy = DEFAULT_DEVIN_CAPACITY_RETRY, stream = streamDevin) {
10137
- if (stream === streamDevin && selectDevinEngine(request) === "go") {
10138
- yield* streamDevinOnEngine(request, policy, streamDevin);
10139
- return;
10140
- }
10141
9407
  for (let attempt = 0; ; attempt++) {
10142
9408
  let heldStart;
10143
9409
  let committed = false;
@@ -10168,7 +9434,7 @@ async function* streamDevinWithCapacityRetry(request, policy = DEFAULT_DEVIN_CAP
10168
9434
  // ../devin-core/dist/credentials.js
10169
9435
  import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2 } from "node:fs";
10170
9436
  import { homedir as homedir6 } from "node:os";
10171
- import { dirname as dirname2, join as join7 } from "node:path";
9437
+ import { dirname as dirname2, join as join6 } from "node:path";
10172
9438
 
10173
9439
  // ../devin-core/dist/oauth.js
10174
9440
  import { createHash as createHash5, randomBytes } from "node:crypto";
@@ -10290,8 +9556,8 @@ function devinCredentialsPath() {
10290
9556
  const override = process.env.DEVIN_CREDENTIALS_PATH;
10291
9557
  if (override)
10292
9558
  return override;
10293
- const dataHome = process.env.XDG_DATA_HOME ?? join7(homedir6(), ".local", "share");
10294
- return join7(dataHome, "devin", "credentials.toml");
9559
+ const dataHome = process.env.XDG_DATA_HOME ?? join6(homedir6(), ".local", "share");
9560
+ return join6(dataHome, "devin", "credentials.toml");
10295
9561
  }
10296
9562
  function parseCredentialsToml(text) {
10297
9563
  const out = {};
@@ -10333,7 +9599,6 @@ function resolveDevinCredentials() {
10333
9599
  var DEVIN_EFFORT_ORDER = ["minimal", "low", "medium", "high", "xhigh", "max"];
10334
9600
 
10335
9601
  // ../devin-core/dist/discovery.js
10336
- init_util();
10337
9602
  var DEFAULT_CONTEXT_WINDOW2 = 2e5;
10338
9603
  var DEFAULT_MAX_TOKENS2 = 64e3;
10339
9604
  var DEVIN_DISPLAY_OPTION_INTERNAL_DEFAULT = 6;
@@ -10480,21 +9745,7 @@ function collectDevinFamilyLane(lanes, config, uid) {
10480
9745
  }
10481
9746
  }
10482
9747
  async function fetchDevinModels(options) {
10483
- if (options.fetch)
10484
- return fetchDevinModelsInProcess(options);
10485
- const { runDevinOp: runDevinOp2 } = await Promise.resolve().then(() => (init_engine_ops2(), engine_ops_exports2));
10486
- return runDevinOp2({
10487
- op: "models",
10488
- request: () => ({
10489
- ...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
10490
- ...options.baseUrl !== void 0 ? { baseUrl: options.baseUrl } : {},
10491
- ...options.timeoutMs !== void 0 ? { timeoutMs: options.timeoutMs } : {}
10492
- }),
10493
- inProcess: () => fetchDevinModelsInProcess(options),
10494
- fromWire: (models) => Array.isArray(models) && models.length > 0 ? models : null,
10495
- fallback: null,
10496
- ...options.signal ? { signal: options.signal } : {}
10497
- });
9748
+ return fetchDevinModelsInProcess(options);
10498
9749
  }
10499
9750
  async function fetchDevinModelsInProcess(options) {
10500
9751
  const timeoutMs = options.timeoutMs ?? 5e3;
@@ -10685,14 +9936,10 @@ function normalizeDevinModels(configs, baseUrlOverride) {
10685
9936
  return collapseDevinLanes(specs, lanes.values()).sort((a, b) => a.id.localeCompare(b.id));
10686
9937
  }
10687
9938
 
10688
- // ../devin-core/dist/index.js
10689
- init_engine2();
10690
- init_errors3();
10691
-
10692
9939
  // ../devin-core/dist/models.js
10693
- import { mkdirSync as mkdirSync3, readFileSync as readFileSync4, statSync as statSync2, writeFileSync as writeFileSync3 } from "node:fs";
9940
+ import { mkdirSync as mkdirSync3, readFileSync as readFileSync4, statSync, writeFileSync as writeFileSync3 } from "node:fs";
10694
9941
  import { homedir as homedir7 } from "node:os";
10695
- import { dirname as dirname3, join as join8 } from "node:path";
9942
+ import { dirname as dirname3, join as join7 } from "node:path";
10696
9943
  var devinModels = [
10697
9944
  {
10698
9945
  id: "swe-1-6",
@@ -10724,15 +9971,15 @@ function devinModelCachePath() {
10724
9971
  const override = process.env.NS_DEVIN_MODEL_CACHE;
10725
9972
  if (override)
10726
9973
  return override;
10727
- const dataHome = process.env.XDG_DATA_HOME ?? join8(homedir7(), ".local", "share");
10728
- return join8(dataHome, "ns-devin-provider", "models.json");
9974
+ const dataHome = process.env.XDG_DATA_HOME ?? join7(homedir7(), ".local", "share");
9975
+ return join7(dataHome, "ns-devin-provider", "models.json");
10729
9976
  }
10730
9977
  var CACHE_TTL_MS = 24 * 60 * 60 * 1e3;
10731
9978
  var cacheFile;
10732
9979
  var cacheMtimeMs = -1;
10733
9980
  function loadCacheFile() {
10734
9981
  try {
10735
- const mtimeMs = statSync2(devinModelCachePath()).mtimeMs;
9982
+ const mtimeMs = statSync(devinModelCachePath()).mtimeMs;
10736
9983
  if (mtimeMs !== cacheMtimeMs) {
10737
9984
  cacheMtimeMs = mtimeMs;
10738
9985
  const parsed = JSON.parse(readFileSync4(devinModelCachePath(), "utf8"));
@@ -10756,15 +10003,13 @@ function updateDevinModelsCache(models, now = Date.now()) {
10756
10003
  try {
10757
10004
  mkdirSync3(dirname3(devinModelCachePath()), { recursive: true });
10758
10005
  writeFileSync3(devinModelCachePath(), JSON.stringify(cacheFile), "utf8");
10759
- cacheMtimeMs = statSync2(devinModelCachePath()).mtimeMs;
10006
+ cacheMtimeMs = statSync(devinModelCachePath()).mtimeMs;
10760
10007
  } catch {
10761
10008
  }
10762
10009
  return models;
10763
10010
  }
10764
10011
 
10765
10012
  // ../devin-core/dist/usage.js
10766
- init_errors3();
10767
- init_util();
10768
10013
  var MICROS_PER_USD = 1e6;
10769
10014
  function timestampMs(timestamp) {
10770
10015
  return Number(timestamp.seconds) * 1e3 + timestamp.nanos / 1e6;
@@ -10895,30 +10140,7 @@ function buildDevinUsageReport(response) {
10895
10140
  };
10896
10141
  }
10897
10142
  async function fetchDevinUsage(options) {
10898
- if (options.fetch)
10899
- return fetchDevinUsageInProcess(options);
10900
- if (!options.apiKey?.trim())
10901
- return null;
10902
- const { runDevinOp: runDevinOp2 } = await Promise.resolve().then(() => (init_engine_ops2(), engine_ops_exports2));
10903
- return runDevinOp2({
10904
- op: "usage",
10905
- request: () => ({
10906
- ...options.apiKey !== void 0 ? { apiKey: options.apiKey } : {},
10907
- ...options.baseUrl !== void 0 ? { baseUrl: options.baseUrl } : {}
10908
- }),
10909
- inProcess: () => fetchDevinUsageInProcess(options),
10910
- fromWire: devinUsageFromWire,
10911
- fallback: null,
10912
- ...options.signal ? { signal: options.signal } : {}
10913
- });
10914
- }
10915
- function devinUsageFromWire(wire) {
10916
- if (!wire || typeof wire.raw !== "string")
10917
- return null;
10918
- const raw = decodeDevinUnaryMessage(GetUserStatusResponseSchema, Buffer.from(wire.raw, "base64"));
10919
- if (!raw)
10920
- return null;
10921
- return { ...wire.report, raw };
10143
+ return fetchDevinUsageInProcess(options);
10922
10144
  }
10923
10145
  async function fetchDevinUsageInProcess(options) {
10924
10146
  const token = options.apiKey?.trim();
@@ -10948,9 +10170,6 @@ async function fetchDevinUsageInProcess(options) {
10948
10170
  }
10949
10171
  }
10950
10172
 
10951
- // ../devin-core/dist/index.js
10952
- init_util();
10953
-
10954
10173
  // ../pi-provider/src/devin/register.ts
10955
10174
  var DEVIN_PROVIDER_ID = "devin";
10956
10175
  var DEVIN_API = "devin-cloud";
@@ -10981,7 +10200,7 @@ function resolveDevinToken(env = process.env, options = {}) {
10981
10200
  if (options.readFiles === false) return void 0;
10982
10201
  if (!options.paths) return resolveDevinCredentials()?.apiKey;
10983
10202
  for (const path of options.paths) {
10984
- if (!existsSync5(path)) continue;
10203
+ if (!existsSync4(path)) continue;
10985
10204
  try {
10986
10205
  const token = parseDevinCredentialsToml(readFileSync5(path, "utf8"));
10987
10206
  if (token) return token;
@@ -11149,9 +10368,9 @@ async function registerDevinProvider(pi) {
11149
10368
  }
11150
10369
 
11151
10370
  // ../pi-provider/src/grok/register.ts
11152
- import { existsSync as existsSync7 } from "node:fs";
10371
+ import { existsSync as existsSync6 } from "node:fs";
11153
10372
  import { homedir as homedir10 } from "node:os";
11154
- import { join as join11 } from "node:path";
10373
+ import { join as join10 } from "node:path";
11155
10374
 
11156
10375
  // ../pi-provider/src/shared/types.ts
11157
10376
  function ensureCacheCost(cost) {
@@ -11164,12 +10383,12 @@ function ensureCacheCost(cost) {
11164
10383
  }
11165
10384
 
11166
10385
  // ../pi-provider/src/shared/catalog-cache.ts
11167
- import { mkdirSync as mkdirSync4, readFileSync as readFileSync6, renameSync as renameSync2, writeFileSync as writeFileSync4, existsSync as existsSync6 } from "node:fs";
11168
- import { join as join9 } from "node:path";
10386
+ import { mkdirSync as mkdirSync4, readFileSync as readFileSync6, renameSync as renameSync2, writeFileSync as writeFileSync4, existsSync as existsSync5 } from "node:fs";
10387
+ import { join as join8 } from "node:path";
11169
10388
  import { homedir as homedir8 } from "node:os";
11170
10389
  var DEFAULT_TTL_MS = 15 * 60 * 1e3;
11171
10390
  function defaultCacheDir() {
11172
- return join9(homedir8(), ".pi", "agent", "cache", "ns-pi-provider");
10391
+ return join8(homedir8(), ".pi", "agent", "cache", "ns-pi-provider");
11173
10392
  }
11174
10393
  var CatalogCache = class {
11175
10394
  cacheDir;
@@ -11189,11 +10408,11 @@ var CatalogCache = class {
11189
10408
  mkdirSync4(path, opts);
11190
10409
  }),
11191
10410
  renameSync: options.fs?.renameSync ?? renameSync2,
11192
- existsSync: options.fs?.existsSync ?? existsSync6
10411
+ existsSync: options.fs?.existsSync ?? existsSync5
11193
10412
  };
11194
10413
  }
11195
10414
  pathFor(providerId) {
11196
- return join9(this.cacheDir, `${providerId}.models.json`);
10415
+ return join8(this.cacheDir, `${providerId}.models.json`);
11197
10416
  }
11198
10417
  lookup(providerId, expectedVersion) {
11199
10418
  const mem = this.memory.get(providerId);
@@ -11308,7 +10527,7 @@ function getDefaultCatalogCache(options) {
11308
10527
  import { accessSync, constants } from "node:fs";
11309
10528
  import { execFileSync as execFileSync2 } from "node:child_process";
11310
10529
  import { homedir as homedir9 } from "node:os";
11311
- import { join as join10 } from "node:path";
10530
+ import { join as join9 } from "node:path";
11312
10531
  var CANDIDATE_NAMES = ["agent", "grok"];
11313
10532
  function isExecutable(path) {
11314
10533
  try {
@@ -11345,9 +10564,9 @@ function resolveGrokBinary(env = process.env) {
11345
10564
  const found = which(name);
11346
10565
  if (found) return found;
11347
10566
  }
11348
- const homeBin = join10(homedir9(), ".grok", "bin");
10567
+ const homeBin = join9(homedir9(), ".grok", "bin");
11349
10568
  for (const name of CANDIDATE_NAMES) {
11350
- const candidate = join10(homeBin, name);
10569
+ const candidate = join9(homeBin, name);
11351
10570
  if (isExecutable(candidate)) return candidate;
11352
10571
  }
11353
10572
  throw new Error(
@@ -11967,7 +11186,7 @@ function registerSessionScope(pi) {
11967
11186
  }
11968
11187
 
11969
11188
  // ../pi-provider/src/grok/acp-client.ts
11970
- import { spawn as spawn2 } from "node:child_process";
11189
+ import { spawn } from "node:child_process";
11971
11190
  import { createInterface } from "node:readline";
11972
11191
  function buildAcpArgs(options) {
11973
11192
  const args = ["agent", "--no-leader"];
@@ -12149,7 +11368,7 @@ async function createLiveAcpSession(options) {
12149
11368
  reasoningEffort: options.reasoningEffort,
12150
11369
  alwaysApprove: options.alwaysApprove
12151
11370
  });
12152
- const proc = spawn2(options.binary, args, {
11371
+ const proc = spawn(options.binary, args, {
12153
11372
  stdio: ["pipe", "pipe", "pipe"],
12154
11373
  cwd: options.cwd ?? process.cwd(),
12155
11374
  env: options.env ?? process.env
@@ -12539,7 +11758,7 @@ function streamViaAcp(model, context, options) {
12539
11758
  }
12540
11759
 
12541
11760
  // ../pi-provider/src/grok/jsonl-mode.ts
12542
- import { spawn as spawn3 } from "node:child_process";
11761
+ import { spawn as spawn2 } from "node:child_process";
12543
11762
  import { createInterface as createInterface2 } from "node:readline";
12544
11763
  function buildJsonlArgs(prompt, options) {
12545
11764
  const args = [
@@ -12606,7 +11825,7 @@ function streamViaJsonl(model, context, options) {
12606
11825
  reasoningEffort: reasoning,
12607
11826
  cwd
12608
11827
  });
12609
- proc = spawn3(binary, args, {
11828
+ proc = spawn2(binary, args, {
12610
11829
  stdio: ["ignore", "pipe", "pipe"],
12611
11830
  cwd,
12612
11831
  env: process.env
@@ -12745,10 +11964,10 @@ function catalogToProviderModels(models) {
12745
11964
  function grokAuthPresent() {
12746
11965
  if (process.env.XAI_API_KEY?.trim() || process.env.GROK_API_KEY?.trim()) return true;
12747
11966
  const paths = [
12748
- join11(homedir10(), ".grok", "auth.json"),
12749
- join11("/workspace/.provider-creds/grok", "auth.json")
11967
+ join10(homedir10(), ".grok", "auth.json"),
11968
+ join10("/workspace/.provider-creds/grok", "auth.json")
12750
11969
  ];
12751
- return paths.some((p) => existsSync7(p));
11970
+ return paths.some((p) => existsSync6(p));
12752
11971
  }
12753
11972
  function refreshGrokModels(options = {}) {
12754
11973
  const cache = options.cache ?? getDefaultCatalogCache();