ns-omp-provider-kiro 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +6 -1
  2. package/dist/index.js +99 -37
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -49,7 +49,12 @@ upstream shows up without a release here.
49
49
  - Reasoning effort maps onto Kiro's own ladder per model — `xhigh` and `max`
50
50
  exist only where the model advertises them, and a request for more thinking
51
51
  than a model offers is clamped rather than rejected.
52
- - Usage (`/settings`) reports the account's Kiro credit balance.
52
+ - Usage (`/settings`) reports the account's Kiro credit balance — the one the
53
+ host is signed in with, so run `/login kiro` after signing the machine into a
54
+ different account.
55
+ - Sessions come from the machine: the kiro-cli store first, the Kiro IDE's token
56
+ file as a fallback. They can be different IdC users of the same Kiro profile,
57
+ so `KIRO_AUTH_SOURCE=ide` switches a machine over to the IDE's login instead.
53
58
  - `KIRO_API_KEY` is read as a fallback when no session is stored.
54
59
  - `KIRO_DEBUG=1` writes a full request/response trace to
55
60
  `~/.ns-kiro-provider/logs/kiro-debug.log`, with credentials redacted.
package/dist/index.js CHANGED
@@ -307,14 +307,10 @@ import { homedir as homedir2, platform } from "node:os";
307
307
  import { join as join2 } from "node:path";
308
308
  function getKiroCliDbPath() {
309
309
  const p = platform();
310
- let dbPath;
311
- if (p === "win32")
312
- dbPath = join2(process.env.APPDATA || join2(homedir2(), "AppData", "Roaming"), "kiro-cli", "data.sqlite3");
313
- else if (p === "darwin")
314
- dbPath = join2(homedir2(), "Library", "Application Support", "kiro-cli", "data.sqlite3");
315
- else
316
- dbPath = join2(homedir2(), ".local", "share", "kiro-cli", "data.sqlite3");
317
- return existsSync(dbPath) ? dbPath : void 0;
310
+ const localAppData = process.env.LOCALAPPDATA || join2(homedir2(), "AppData", "Local");
311
+ const roamingAppData = process.env.APPDATA || join2(homedir2(), "AppData", "Roaming");
312
+ 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")];
313
+ return candidates.find((candidate) => existsSync(candidate));
318
314
  }
319
315
  function getKiroCliExternalIdpCredentials() {
320
316
  const dbPath = getKiroCliDbPath();
@@ -651,6 +647,9 @@ function readKiroIdeToken(allowExpired) {
651
647
  function getKiroIdeCredentials() {
652
648
  return readKiroIdeToken(false);
653
649
  }
650
+ function getKiroIdeCredentialsAllowExpired() {
651
+ return readKiroIdeToken(true);
652
+ }
654
653
  var SSO_CACHE_DIR, KIRO_IDE_TOKEN_PATH;
655
654
  var init_kiro_ide = __esm({
656
655
  "../kiro-core/dist/kiro-ide.js"() {
@@ -661,6 +660,15 @@ var init_kiro_ide = __esm({
661
660
  });
662
661
 
663
662
  // ../kiro-core/dist/oauth.js
663
+ function resolveKiroAuthSource() {
664
+ const configured = process.env[AUTH_SOURCE_ENV]?.trim().toLowerCase();
665
+ if (!configured)
666
+ return "cli";
667
+ if (configured === "cli" || configured === "ide")
668
+ return configured;
669
+ console.warn(`[kiro-core] Ignoring ${AUTH_SOURCE_ENV}=${configured}: expected "cli" or "ide".`);
670
+ return "cli";
671
+ }
664
672
  function kiroUserAgent(service, sdkVersion) {
665
673
  return {
666
674
  "User-Agent": `aws-sdk-js/3.714.0 os/macos/24.3.0 lang/js md/nodejs/22.14.0 api/${service}/3.714.0 exec-env/kiro-cli/2.7.0 m/E`,
@@ -751,26 +759,27 @@ async function refreshKiroTokenInternal(credentials) {
751
759
  };
752
760
  if (credentials.authMethod === "apikey" || isApiKey(credentials.access))
753
761
  return credentials;
754
- if (credentialAuthMethod === "idc") {
755
- const ideCreds = getKiroIdeCredentials();
756
- if (ideCreds)
757
- return ideCreds;
758
- }
759
- const preCheckCreds = getValidCliCredentials();
760
- if (preCheckCreds)
761
- return preCheckCreds;
762
+ const cliSession = getValidCliCredentials();
763
+ const cliStaleSession = getExpiredCliCredentials();
764
+ const ideSession = credentialAuthMethod === "idc" ? getKiroIdeCredentials() : void 0;
765
+ const ideStaleSession = credentialAuthMethod === "idc" ? getKiroIdeCredentialsAllowExpired() : void 0;
766
+ const cliIsThisLogin = (cliSession ?? cliStaleSession)?.refresh === credentials.refresh;
767
+ const ideIsThisLogin = (ideSession ?? ideStaleSession)?.refresh === credentials.refresh;
768
+ const replacement = cliIsThisLogin ? cliSession : ideIsThisLogin ? ideSession : resolveKiroAuthSource() === "ide" ? ideSession ?? cliSession : cliSession ?? ideSession;
769
+ if (replacement)
770
+ return replacement;
762
771
  try {
763
772
  const refreshed = await refreshKiroTokenDirect(credentials);
764
- saveKiroCliCredentials2(refreshed);
773
+ if (!ideIsThisLogin)
774
+ saveKiroCliCredentials2(refreshed);
765
775
  return refreshed;
766
776
  } catch (refreshError) {
767
777
  const retryCreds = getValidCliCredentials();
768
778
  if (retryCreds)
769
779
  return retryCreds;
770
- const expiredCliCreds = getExpiredCliCredentials();
771
- if (expiredCliCreds && expiredCliCreds.refresh !== credentials.refresh) {
780
+ if (cliStaleSession && cliStaleSession.refresh !== credentials.refresh) {
772
781
  try {
773
- const refreshedFromCli = await refreshKiroTokenDirect(expiredCliCreds);
782
+ const refreshedFromCli = await refreshKiroTokenDirect(cliStaleSession);
774
783
  saveKiroCliCredentials2(refreshedFromCli);
775
784
  return refreshedFromCli;
776
785
  } catch {
@@ -875,15 +884,31 @@ async function refreshKiroTokenDirect(credentials) {
875
884
  }
876
885
  async function resolveKiroCredentials() {
877
886
  const { getKiroCliCredentials: getKiroCliCredentials2, getKiroCliCredentialsAllowExpired: getKiroCliCredentialsAllowExpired2 } = await Promise.resolve().then(() => (init_kiro_cli(), kiro_cli_exports));
878
- const fresh = getKiroCliCredentials2() ?? getKiroIdeCredentials();
879
- if (fresh)
880
- return fresh;
881
- const stale = getKiroCliCredentialsAllowExpired2();
882
- if (!stale)
883
- return void 0;
884
- return refreshKiroToken(stale);
887
+ const stores = resolveKiroAuthSource() === "ide" ? [
888
+ { fresh: getKiroIdeCredentials(), stale: getKiroIdeCredentialsAllowExpired() },
889
+ { fresh: getKiroCliCredentials2(), stale: getKiroCliCredentialsAllowExpired2() }
890
+ ] : [
891
+ { fresh: getKiroCliCredentials2(), stale: getKiroCliCredentialsAllowExpired2() },
892
+ { fresh: getKiroIdeCredentials(), stale: getKiroIdeCredentialsAllowExpired() }
893
+ ];
894
+ let lastFailure;
895
+ for (const { fresh, stale } of stores) {
896
+ if (fresh)
897
+ return fresh;
898
+ if (!stale)
899
+ continue;
900
+ try {
901
+ return await refreshKiroToken(stale);
902
+ } catch (error2) {
903
+ lastFailure = error2;
904
+ console.warn(`[kiro-core] Kiro session refresh failed: ${formatSafeError(error2)}`);
905
+ }
906
+ }
907
+ if (lastFailure)
908
+ throw lastFailure;
909
+ return void 0;
885
910
  }
886
- var KIRO_DESKTOP_REFRESH_URL, EXPIRES_BUFFER_MS, KIRO_DESKTOP_USER_AGENT;
911
+ var KIRO_DESKTOP_REFRESH_URL, EXPIRES_BUFFER_MS, KIRO_DESKTOP_USER_AGENT, AUTH_SOURCE_ENV;
887
912
  var init_oauth = __esm({
888
913
  "../kiro-core/dist/oauth.js"() {
889
914
  "use strict";
@@ -893,6 +918,7 @@ var init_oauth = __esm({
893
918
  KIRO_DESKTOP_REFRESH_URL = "https://prod.{region}.auth.desktop.kiro.dev/refreshToken";
894
919
  EXPIRES_BUFFER_MS = 5 * 60 * 1e3;
895
920
  KIRO_DESKTOP_USER_AGENT = "Kiro-Desktop/0.2.13 (darwin; arm64)";
921
+ AUTH_SOURCE_ENV = "KIRO_AUTH_SOURCE";
896
922
  }
897
923
  });
898
924
 
@@ -2314,6 +2340,23 @@ function toKiroToolUseId(toolUseId) {
2314
2340
  const digest = createHash2("sha256").update(toolUseId).digest("base64url").slice(0, 32);
2315
2341
  return `pi_${digest}`;
2316
2342
  }
2343
+ var KIRO_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]{1,64}$/;
2344
+ function toKiroToolName(name) {
2345
+ if (KIRO_TOOL_NAME_PATTERN.test(name))
2346
+ return name;
2347
+ const clean = name.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 55);
2348
+ const digest = createHash2("sha256").update(name).digest("base64url").slice(0, 8);
2349
+ return `${clean || "tool"}_${digest}`;
2350
+ }
2351
+ function kiroToolNameAliases(tools) {
2352
+ const aliases = /* @__PURE__ */ new Map();
2353
+ for (const tool of tools ?? []) {
2354
+ const wire = toKiroToolName(tool.name);
2355
+ if (wire !== tool.name)
2356
+ aliases.set(wire, tool.name);
2357
+ }
2358
+ return aliases;
2359
+ }
2317
2360
  function normalizeMessages(messages) {
2318
2361
  return messages.filter((msg) => {
2319
2362
  if (msg.role !== "assistant")
@@ -2354,12 +2397,18 @@ function getContentText(msg) {
2354
2397
  return "";
2355
2398
  }).join("");
2356
2399
  }
2400
+ function toKiroInputSchema(parameters) {
2401
+ if (parameters && typeof parameters === "object" && !Array.isArray(parameters)) {
2402
+ return parameters.type === void 0 ? { type: "object", ...parameters } : parameters;
2403
+ }
2404
+ return { type: "object", properties: {} };
2405
+ }
2357
2406
  function convertToolsToKiro(tools) {
2358
2407
  return tools.map((tool) => ({
2359
2408
  toolSpecification: {
2360
- name: tool.name,
2409
+ name: toKiroToolName(tool.name),
2361
2410
  description: tool.description,
2362
- inputSchema: { json: tool.parameters }
2411
+ inputSchema: { json: toKiroInputSchema(tool.parameters) }
2363
2412
  }
2364
2413
  }));
2365
2414
  }
@@ -2425,7 +2474,7 @@ ${uim.content}` : prevUim.content || uim.content;
2425
2474
  armHadBlocks = true;
2426
2475
  } else if (block.type === "toolCall") {
2427
2476
  armToolUses.push({
2428
- name: block.name,
2477
+ name: toKiroToolName(block.name),
2429
2478
  toolUseId: toKiroToolUseId(block.id),
2430
2479
  input: block.arguments
2431
2480
  });
@@ -3018,7 +3067,11 @@ function buildKiroRequest(params) {
3018
3067
  if (block.type === "text")
3019
3068
  armContent += block.text;
3020
3069
  else if (block.type === "toolCall") {
3021
- armToolUses.push({ name: block.name, toolUseId: toKiroToolUseId(block.id), input: block.arguments });
3070
+ armToolUses.push({
3071
+ name: toKiroToolName(block.name),
3072
+ toolUseId: toKiroToolUseId(block.id),
3073
+ input: block.arguments
3074
+ });
3022
3075
  }
3023
3076
  }
3024
3077
  if (armContent || armToolUses.length > 0) {
@@ -3462,6 +3515,7 @@ var ECHO_NOISE_PATTERN = /^\s*(continue|\.+)\s*$/i;
3462
3515
  var KiroResponseAssembler = class {
3463
3516
  model;
3464
3517
  thinkingEnabled;
3518
+ toolNameAliases;
3465
3519
  pending = [];
3466
3520
  blocks = new KiroBlockBuffer((event) => this.pending.push(event));
3467
3521
  usage = {
@@ -3484,9 +3538,13 @@ var KiroResponseAssembler = class {
3484
3538
  droppedToolCalls = [];
3485
3539
  currentToolCall = null;
3486
3540
  stopReason = "stop";
3487
- constructor(model, thinkingEnabled) {
3541
+ constructor(model, thinkingEnabled, toolNameAliases) {
3488
3542
  this.model = model;
3489
3543
  this.thinkingEnabled = thinkingEnabled;
3544
+ this.toolNameAliases = toolNameAliases;
3545
+ }
3546
+ originalToolName(name) {
3547
+ return this.toolNameAliases?.get(name) ?? name;
3490
3548
  }
3491
3549
  /** Clear per-attempt state. Only block indexes are kept. */
3492
3550
  beginAttempt() {
@@ -3566,7 +3624,7 @@ var KiroResponseAssembler = class {
3566
3624
  this.sawAnyToolCalls = true;
3567
3625
  if (!this.currentToolCall || this.currentToolCall.toolUseId !== tc.toolUseId) {
3568
3626
  this.flushToolCall();
3569
- this.currentToolCall = { toolUseId: tc.toolUseId, name: tc.name, input: "" };
3627
+ this.currentToolCall = { toolUseId: tc.toolUseId, name: this.originalToolName(tc.name), input: "" };
3570
3628
  }
3571
3629
  this.currentToolCall.input += tc.input || "";
3572
3630
  if (tc.input)
@@ -3750,10 +3808,14 @@ var KiroResponseAssembler = class {
3750
3808
  this.blocks.setText(this.textBlockIndex, text);
3751
3809
  this.sawAnyToolCalls = true;
3752
3810
  for (const call of recovered) {
3753
- if (this.emitToolCall({ toolUseId: call.toolUseId, name: call.name, input: JSON.stringify(call.arguments) })) {
3811
+ if (this.emitToolCall({
3812
+ toolUseId: call.toolUseId,
3813
+ name: this.originalToolName(call.name),
3814
+ input: JSON.stringify(call.arguments)
3815
+ })) {
3754
3816
  this.emittedToolCalls++;
3755
3817
  } else {
3756
- this.droppedToolCalls.push(call.name);
3818
+ this.droppedToolCalls.push(this.originalToolName(call.name));
3757
3819
  }
3758
3820
  }
3759
3821
  }
@@ -4849,7 +4911,7 @@ async function* streamKiro(request) {
4849
4911
  systemPrompt = `<thinking_mode>enabled</thinking_mode><max_thinking_length>${budget}</max_thinking_length>${systemPrompt ? `
4850
4912
  ${systemPrompt}` : ""}`;
4851
4913
  }
4852
- const assembler = new KiroResponseAssembler(model, thinkingEnabled);
4914
+ const assembler = new KiroResponseAssembler(model, thinkingEnabled, kiroToolNameAliases(request.tools));
4853
4915
  const usageTracking = request.usageTracking ?? KIRO_USAGE_TRACKING_DISABLED;
4854
4916
  let retryCount = 0;
4855
4917
  const maxRetries = 3;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ns-omp-provider-kiro",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "description": "OMP (oh-my-pi) provider plugin: adds Kiro (AWS CodeWhisperer/Q) models via your kiro-cli login",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -37,7 +37,7 @@
37
37
  "README.md"
38
38
  ],
39
39
  "dependencies": {
40
- "ns-kiro-core": "0.3.1"
40
+ "ns-kiro-core": "0.3.3"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "@oh-my-pi/pi-ai": ">=18.2.0",