ns-omp-provider-kiro 0.3.2 → 0.3.4

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 +100 -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
@@ -267,6 +267,7 @@ var init_endpoints = __esm({
267
267
  "../kiro-core/dist/endpoints.js"() {
268
268
  "use strict";
269
269
  API_REGION_MAP = {
270
+ "sa-east-1": "us-east-1",
270
271
  "us-west-1": "us-east-1",
271
272
  "us-west-2": "us-east-1",
272
273
  "us-east-2": "us-east-1",
@@ -307,14 +308,10 @@ import { homedir as homedir2, platform } from "node:os";
307
308
  import { join as join2 } from "node:path";
308
309
  function getKiroCliDbPath() {
309
310
  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;
311
+ const localAppData = process.env.LOCALAPPDATA || join2(homedir2(), "AppData", "Local");
312
+ const roamingAppData = process.env.APPDATA || join2(homedir2(), "AppData", "Roaming");
313
+ 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")];
314
+ return candidates.find((candidate) => existsSync(candidate));
318
315
  }
319
316
  function getKiroCliExternalIdpCredentials() {
320
317
  const dbPath = getKiroCliDbPath();
@@ -651,6 +648,9 @@ function readKiroIdeToken(allowExpired) {
651
648
  function getKiroIdeCredentials() {
652
649
  return readKiroIdeToken(false);
653
650
  }
651
+ function getKiroIdeCredentialsAllowExpired() {
652
+ return readKiroIdeToken(true);
653
+ }
654
654
  var SSO_CACHE_DIR, KIRO_IDE_TOKEN_PATH;
655
655
  var init_kiro_ide = __esm({
656
656
  "../kiro-core/dist/kiro-ide.js"() {
@@ -661,6 +661,15 @@ var init_kiro_ide = __esm({
661
661
  });
662
662
 
663
663
  // ../kiro-core/dist/oauth.js
664
+ function resolveKiroAuthSource() {
665
+ const configured = process.env[AUTH_SOURCE_ENV]?.trim().toLowerCase();
666
+ if (!configured)
667
+ return "cli";
668
+ if (configured === "cli" || configured === "ide")
669
+ return configured;
670
+ console.warn(`[kiro-core] Ignoring ${AUTH_SOURCE_ENV}=${configured}: expected "cli" or "ide".`);
671
+ return "cli";
672
+ }
664
673
  function kiroUserAgent(service, sdkVersion) {
665
674
  return {
666
675
  "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 +760,27 @@ async function refreshKiroTokenInternal(credentials) {
751
760
  };
752
761
  if (credentials.authMethod === "apikey" || isApiKey(credentials.access))
753
762
  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;
763
+ const cliSession = getValidCliCredentials();
764
+ const cliStaleSession = getExpiredCliCredentials();
765
+ const ideSession = credentialAuthMethod === "idc" ? getKiroIdeCredentials() : void 0;
766
+ const ideStaleSession = credentialAuthMethod === "idc" ? getKiroIdeCredentialsAllowExpired() : void 0;
767
+ const cliIsThisLogin = (cliSession ?? cliStaleSession)?.refresh === credentials.refresh;
768
+ const ideIsThisLogin = (ideSession ?? ideStaleSession)?.refresh === credentials.refresh;
769
+ const replacement = cliIsThisLogin ? cliSession : ideIsThisLogin ? ideSession : resolveKiroAuthSource() === "ide" ? ideSession ?? cliSession : cliSession ?? ideSession;
770
+ if (replacement)
771
+ return replacement;
762
772
  try {
763
773
  const refreshed = await refreshKiroTokenDirect(credentials);
764
- saveKiroCliCredentials2(refreshed);
774
+ if (!ideIsThisLogin)
775
+ saveKiroCliCredentials2(refreshed);
765
776
  return refreshed;
766
777
  } catch (refreshError) {
767
778
  const retryCreds = getValidCliCredentials();
768
779
  if (retryCreds)
769
780
  return retryCreds;
770
- const expiredCliCreds = getExpiredCliCredentials();
771
- if (expiredCliCreds && expiredCliCreds.refresh !== credentials.refresh) {
781
+ if (cliStaleSession && cliStaleSession.refresh !== credentials.refresh) {
772
782
  try {
773
- const refreshedFromCli = await refreshKiroTokenDirect(expiredCliCreds);
783
+ const refreshedFromCli = await refreshKiroTokenDirect(cliStaleSession);
774
784
  saveKiroCliCredentials2(refreshedFromCli);
775
785
  return refreshedFromCli;
776
786
  } catch {
@@ -875,15 +885,31 @@ async function refreshKiroTokenDirect(credentials) {
875
885
  }
876
886
  async function resolveKiroCredentials() {
877
887
  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);
888
+ const stores = resolveKiroAuthSource() === "ide" ? [
889
+ { fresh: getKiroIdeCredentials(), stale: getKiroIdeCredentialsAllowExpired() },
890
+ { fresh: getKiroCliCredentials2(), stale: getKiroCliCredentialsAllowExpired2() }
891
+ ] : [
892
+ { fresh: getKiroCliCredentials2(), stale: getKiroCliCredentialsAllowExpired2() },
893
+ { fresh: getKiroIdeCredentials(), stale: getKiroIdeCredentialsAllowExpired() }
894
+ ];
895
+ let lastFailure;
896
+ for (const { fresh, stale } of stores) {
897
+ if (fresh)
898
+ return fresh;
899
+ if (!stale)
900
+ continue;
901
+ try {
902
+ return await refreshKiroToken(stale);
903
+ } catch (error2) {
904
+ lastFailure = error2;
905
+ console.warn(`[kiro-core] Kiro session refresh failed: ${formatSafeError(error2)}`);
906
+ }
907
+ }
908
+ if (lastFailure)
909
+ throw lastFailure;
910
+ return void 0;
885
911
  }
886
- var KIRO_DESKTOP_REFRESH_URL, EXPIRES_BUFFER_MS, KIRO_DESKTOP_USER_AGENT;
912
+ var KIRO_DESKTOP_REFRESH_URL, EXPIRES_BUFFER_MS, KIRO_DESKTOP_USER_AGENT, AUTH_SOURCE_ENV;
887
913
  var init_oauth = __esm({
888
914
  "../kiro-core/dist/oauth.js"() {
889
915
  "use strict";
@@ -893,6 +919,7 @@ var init_oauth = __esm({
893
919
  KIRO_DESKTOP_REFRESH_URL = "https://prod.{region}.auth.desktop.kiro.dev/refreshToken";
894
920
  EXPIRES_BUFFER_MS = 5 * 60 * 1e3;
895
921
  KIRO_DESKTOP_USER_AGENT = "Kiro-Desktop/0.2.13 (darwin; arm64)";
922
+ AUTH_SOURCE_ENV = "KIRO_AUTH_SOURCE";
896
923
  }
897
924
  });
898
925
 
@@ -2314,6 +2341,23 @@ function toKiroToolUseId(toolUseId) {
2314
2341
  const digest = createHash2("sha256").update(toolUseId).digest("base64url").slice(0, 32);
2315
2342
  return `pi_${digest}`;
2316
2343
  }
2344
+ var KIRO_TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]{1,64}$/;
2345
+ function toKiroToolName(name) {
2346
+ if (KIRO_TOOL_NAME_PATTERN.test(name))
2347
+ return name;
2348
+ const clean = name.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 55);
2349
+ const digest = createHash2("sha256").update(name).digest("base64url").slice(0, 8);
2350
+ return `${clean || "tool"}_${digest}`;
2351
+ }
2352
+ function kiroToolNameAliases(tools) {
2353
+ const aliases = /* @__PURE__ */ new Map();
2354
+ for (const tool of tools ?? []) {
2355
+ const wire = toKiroToolName(tool.name);
2356
+ if (wire !== tool.name)
2357
+ aliases.set(wire, tool.name);
2358
+ }
2359
+ return aliases;
2360
+ }
2317
2361
  function normalizeMessages(messages) {
2318
2362
  return messages.filter((msg) => {
2319
2363
  if (msg.role !== "assistant")
@@ -2354,12 +2398,18 @@ function getContentText(msg) {
2354
2398
  return "";
2355
2399
  }).join("");
2356
2400
  }
2401
+ function toKiroInputSchema(parameters) {
2402
+ if (parameters && typeof parameters === "object" && !Array.isArray(parameters)) {
2403
+ return parameters.type === void 0 ? { type: "object", ...parameters } : parameters;
2404
+ }
2405
+ return { type: "object", properties: {} };
2406
+ }
2357
2407
  function convertToolsToKiro(tools) {
2358
2408
  return tools.map((tool) => ({
2359
2409
  toolSpecification: {
2360
- name: tool.name,
2410
+ name: toKiroToolName(tool.name),
2361
2411
  description: tool.description,
2362
- inputSchema: { json: tool.parameters }
2412
+ inputSchema: { json: toKiroInputSchema(tool.parameters) }
2363
2413
  }
2364
2414
  }));
2365
2415
  }
@@ -2425,7 +2475,7 @@ ${uim.content}` : prevUim.content || uim.content;
2425
2475
  armHadBlocks = true;
2426
2476
  } else if (block.type === "toolCall") {
2427
2477
  armToolUses.push({
2428
- name: block.name,
2478
+ name: toKiroToolName(block.name),
2429
2479
  toolUseId: toKiroToolUseId(block.id),
2430
2480
  input: block.arguments
2431
2481
  });
@@ -3018,7 +3068,11 @@ function buildKiroRequest(params) {
3018
3068
  if (block.type === "text")
3019
3069
  armContent += block.text;
3020
3070
  else if (block.type === "toolCall") {
3021
- armToolUses.push({ name: block.name, toolUseId: toKiroToolUseId(block.id), input: block.arguments });
3071
+ armToolUses.push({
3072
+ name: toKiroToolName(block.name),
3073
+ toolUseId: toKiroToolUseId(block.id),
3074
+ input: block.arguments
3075
+ });
3022
3076
  }
3023
3077
  }
3024
3078
  if (armContent || armToolUses.length > 0) {
@@ -3462,6 +3516,7 @@ var ECHO_NOISE_PATTERN = /^\s*(continue|\.+)\s*$/i;
3462
3516
  var KiroResponseAssembler = class {
3463
3517
  model;
3464
3518
  thinkingEnabled;
3519
+ toolNameAliases;
3465
3520
  pending = [];
3466
3521
  blocks = new KiroBlockBuffer((event) => this.pending.push(event));
3467
3522
  usage = {
@@ -3484,9 +3539,13 @@ var KiroResponseAssembler = class {
3484
3539
  droppedToolCalls = [];
3485
3540
  currentToolCall = null;
3486
3541
  stopReason = "stop";
3487
- constructor(model, thinkingEnabled) {
3542
+ constructor(model, thinkingEnabled, toolNameAliases) {
3488
3543
  this.model = model;
3489
3544
  this.thinkingEnabled = thinkingEnabled;
3545
+ this.toolNameAliases = toolNameAliases;
3546
+ }
3547
+ originalToolName(name) {
3548
+ return this.toolNameAliases?.get(name) ?? name;
3490
3549
  }
3491
3550
  /** Clear per-attempt state. Only block indexes are kept. */
3492
3551
  beginAttempt() {
@@ -3566,7 +3625,7 @@ var KiroResponseAssembler = class {
3566
3625
  this.sawAnyToolCalls = true;
3567
3626
  if (!this.currentToolCall || this.currentToolCall.toolUseId !== tc.toolUseId) {
3568
3627
  this.flushToolCall();
3569
- this.currentToolCall = { toolUseId: tc.toolUseId, name: tc.name, input: "" };
3628
+ this.currentToolCall = { toolUseId: tc.toolUseId, name: this.originalToolName(tc.name), input: "" };
3570
3629
  }
3571
3630
  this.currentToolCall.input += tc.input || "";
3572
3631
  if (tc.input)
@@ -3750,10 +3809,14 @@ var KiroResponseAssembler = class {
3750
3809
  this.blocks.setText(this.textBlockIndex, text);
3751
3810
  this.sawAnyToolCalls = true;
3752
3811
  for (const call of recovered) {
3753
- if (this.emitToolCall({ toolUseId: call.toolUseId, name: call.name, input: JSON.stringify(call.arguments) })) {
3812
+ if (this.emitToolCall({
3813
+ toolUseId: call.toolUseId,
3814
+ name: this.originalToolName(call.name),
3815
+ input: JSON.stringify(call.arguments)
3816
+ })) {
3754
3817
  this.emittedToolCalls++;
3755
3818
  } else {
3756
- this.droppedToolCalls.push(call.name);
3819
+ this.droppedToolCalls.push(this.originalToolName(call.name));
3757
3820
  }
3758
3821
  }
3759
3822
  }
@@ -4849,7 +4912,7 @@ async function* streamKiro(request) {
4849
4912
  systemPrompt = `<thinking_mode>enabled</thinking_mode><max_thinking_length>${budget}</max_thinking_length>${systemPrompt ? `
4850
4913
  ${systemPrompt}` : ""}`;
4851
4914
  }
4852
- const assembler = new KiroResponseAssembler(model, thinkingEnabled);
4915
+ const assembler = new KiroResponseAssembler(model, thinkingEnabled, kiroToolNameAliases(request.tools));
4853
4916
  const usageTracking = request.usageTracking ?? KIRO_USAGE_TRACKING_DISABLED;
4854
4917
  let retryCount = 0;
4855
4918
  const maxRetries = 3;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ns-omp-provider-kiro",
3
- "version": "0.3.2",
3
+ "version": "0.3.4",
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.2"
40
+ "ns-kiro-core": "0.3.4"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "@oh-my-pi/pi-ai": ">=18.2.0",