ns-omp-provider 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.0
4
+
5
+ Bundles `@ngosangns/ns-pi-provider@0.2.0` (was 0.1.7).
6
+
7
+ - **Breaking (kiro):** the Kiro catalog now comes only from `ListAvailableModels`.
8
+ Without a Kiro credential or a saved catalog snapshot the `kiro` provider
9
+ registers with zero models, and derived `-1m` variants (e.g.
10
+ `claude-sonnet-4-6-1m`) are gone. Wire model ids are sent in Kiro's dot form
11
+ (`claude-sonnet-4.5`), fixing `INVALID_MODEL_ID` on discovered models. Users
12
+ with `NS_OMP_PROVIDER_DISABLE=kiro` are unaffected.
13
+ - fix(grok): `session_shutdown` disposes only that session's Grok ACP agent
14
+ (upstream pi-grok-sdk `45fde95`); switching or closing one session no longer
15
+ kills other sessions' agents, and one process-exit hook is installed per
16
+ process instead of per registration.
17
+ - No compat-shim changes needed: 0.2.0 adds no new `@earendil-works/pi-ai`
18
+ runtime imports.
19
+
3
20
  ## 0.1.0
4
21
 
5
22
  - Initial release: OMP wrapper around `@ngosangns/ns-pi-provider` 0.1.7.
package/README.md CHANGED
@@ -19,7 +19,7 @@ Shared command: `/ns-pi status | refresh [all\|kiro\|devin\|grok]`.
19
19
  ## Install
20
20
 
21
21
  ```bash
22
- # from npm (after first publish)
22
+ # from npm
23
23
  omp plugin install ns-omp-provider
24
24
 
25
25
  # from git
@@ -77,7 +77,11 @@ Or allow-list only what you want: `NS_OMP_PROVIDERS=devin,grok`.
77
77
  models from `omp models` even though the provider is registered. After
78
78
  `/login` (or with CLI creds present) the live catalog, including Devin
79
79
  `swe-2-*`, appears via `fetchDynamicModels`.
80
- - **Upstream pin** — this release bundles `@ngosangns/ns-pi-provider@0.1.7`.
80
+ - **Kiro catalog** — models come only from Kiro's `ListAvailableModels`
81
+ (since ns-pi-provider 0.2.0): with no Kiro credential and no saved catalog
82
+ snapshot, `kiro` registers zero models, and `-1m` long-context variants are
83
+ not offered.
84
+ - **Upstream pin** — this release bundles `@ngosangns/ns-pi-provider@0.2.0`.
81
85
  Bumping it is a deliberate change (rebuild + retest).
82
86
 
83
87
  ## Development
@@ -95,14 +99,14 @@ your real `~/.omp`.
95
99
 
96
100
  ## Publish
97
101
 
98
- Push a tag matching `package.json` (e.g. `v0.1.0`) to run
102
+ Push a tag matching `package.json` (e.g. `v0.2.0`) to run
99
103
  [`.github/workflows/publish.yml`](.github/workflows/publish.yml), which
100
104
  publishes with **provenance** from a GitHub-hosted runner:
101
105
 
102
106
  ```bash
103
107
  # bump "version" in package.json first, then
104
108
  npm run check
105
- git tag v0.1.0 && git push origin v0.1.0
109
+ git tag v0.2.0 && git push origin v0.2.0
106
110
  ```
107
111
 
108
112
  Auth, in the order npm tries it:
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- // ns-omp-provider 0.1.0 — bundles @ngosangns/ns-pi-provider@0.1.7 (MIT). See NOTICE.
1
+ // ns-omp-provider 0.2.0 — bundles @ngosangns/ns-pi-provider@0.2.0 (MIT). See NOTICE.
2
2
  import { createRequire as __nsOmpCreateRequire } from 'node:module';
3
3
  const require = __nsOmpCreateRequire(import.meta.url);
4
4
  var __defProp = Object.defineProperty;
@@ -696,9 +696,10 @@ function omitInternalKiroHeaders(headers) {
696
696
  return Object.keys(filtered).length > 0 ? filtered : void 0;
697
697
  }
698
698
  function buildRequest(model, context, config, options) {
699
- const { history, currentMessage } = convertMessages(context, model.id);
699
+ const wireModelId = model.id.replace(/(\d)-(\d)/g, "$1.$2");
700
+ const { history, currentMessage } = convertMessages(context, wireModelId);
700
701
  const firstContent = firstUserConversationContent(history, currentMessage);
701
- prependSystemInstructionHistory(history, buildSystemPrefix(context), model.id);
702
+ prependSystemInstructionHistory(history, buildSystemPrefix(context), wireModelId);
702
703
  const amazonQEndpoint = isAmazonQEndpoint(config);
703
704
  if (amazonQEndpoint) setUserMessageOrigin(history, currentMessage, "KIRO_CLI");
704
705
  const profileArn = getHeaderCaseInsensitive(options?.headers, KIRO_PROFILE_ARN_HEADER) ?? config.profileArn;
@@ -1368,9 +1369,6 @@ import { readFileSync as readFileSync2 } from "node:fs";
1368
1369
  import { join as join2 } from "node:path";
1369
1370
  var KIRO_API = "kiro";
1370
1371
  var KIRO_MAX_OUTPUT_TOKENS = 32e3;
1371
- var KIRO_PROMPT_CACHING_1024 = { supportsPromptCaching: true, maximumCacheCheckpointsPerRequest: 4, minimumTokensPerCacheCheckpoint: 1024 };
1372
- var KIRO_PROMPT_CACHING_4096 = { supportsPromptCaching: true, maximumCacheCheckpointsPerRequest: 4, minimumTokensPerCacheCheckpoint: 4096 };
1373
- var KIRO_PROMPT_CACHING_DISABLED = { supportsPromptCaching: false };
1374
1372
  var ANTHROPIC_REASONING_MAP = { off: "disabled", minimal: "low", low: "low", medium: "medium", high: "high", xhigh: null };
1375
1373
  var ANTHROPIC_OPUS_4_7_REASONING_MAP = { ...ANTHROPIC_REASONING_MAP, xhigh: "xhigh" };
1376
1374
  var ANTHROPIC_MAX_REASONING_MAP = { ...ANTHROPIC_REASONING_MAP, xhigh: "max" };
@@ -1380,21 +1378,6 @@ function defaultThinkingLevelMapForModel(id, name) {
1380
1378
  if (/claude[-\s_/]*(?:opus|sonnet)[-\s_/]*4[.-]?6\b/.test(identity)) return { ...ANTHROPIC_MAX_REASONING_MAP };
1381
1379
  return void 0;
1382
1380
  }
1383
- var DEFAULT_MODELS = [
1384
- { id: "auto", name: "Auto", reasoning: true, contextWindow: 1e6, maxTokens: KIRO_MAX_OUTPUT_TOKENS, rateMultiplier: 1, rateUnit: "Credit", promptCaching: KIRO_PROMPT_CACHING_1024, importOwnership: "model-discovery" },
1385
- { id: "claude-opus-4.7", name: "Claude Opus 4.7", reasoning: true, thinkingLevelMap: ANTHROPIC_OPUS_4_7_REASONING_MAP, contextWindow: 1e6, maxTokens: KIRO_MAX_OUTPUT_TOKENS, rateMultiplier: 2.2, rateUnit: "Credit", promptCaching: KIRO_PROMPT_CACHING_4096, importOwnership: "model-discovery" },
1386
- { id: "claude-opus-4.6", name: "Claude Opus 4.6", reasoning: true, thinkingLevelMap: ANTHROPIC_MAX_REASONING_MAP, contextWindow: 1e6, maxTokens: KIRO_MAX_OUTPUT_TOKENS, rateMultiplier: 2.2, rateUnit: "Credit", promptCaching: KIRO_PROMPT_CACHING_4096, importOwnership: "model-discovery" },
1387
- { id: "claude-sonnet-4.6", name: "Claude Sonnet 4.6", reasoning: true, thinkingLevelMap: ANTHROPIC_MAX_REASONING_MAP, contextWindow: 1e6, maxTokens: KIRO_MAX_OUTPUT_TOKENS, rateMultiplier: 1.3, rateUnit: "Credit", promptCaching: KIRO_PROMPT_CACHING_1024, importOwnership: "model-discovery" },
1388
- { id: "claude-opus-4.5", name: "Claude Opus 4.5", reasoning: true, contextWindow: 2e5, maxTokens: KIRO_MAX_OUTPUT_TOKENS, rateMultiplier: 2.2, rateUnit: "Credit", promptCaching: KIRO_PROMPT_CACHING_4096, importOwnership: "model-discovery" },
1389
- { id: "claude-sonnet-4.5", name: "Claude Sonnet 4.5", reasoning: true, contextWindow: 2e5, maxTokens: KIRO_MAX_OUTPUT_TOKENS, rateMultiplier: 1.3, rateUnit: "Credit", promptCaching: KIRO_PROMPT_CACHING_1024, importOwnership: "model-discovery" },
1390
- { id: "claude-sonnet-4", name: "Claude Sonnet 4", reasoning: true, contextWindow: 2e5, maxTokens: KIRO_MAX_OUTPUT_TOKENS, rateMultiplier: 1.3, rateUnit: "Credit", promptCaching: KIRO_PROMPT_CACHING_1024, importOwnership: "model-discovery" },
1391
- { id: "claude-haiku-4.5", name: "Claude Haiku 4.5", reasoning: true, contextWindow: 2e5, maxTokens: KIRO_MAX_OUTPUT_TOKENS, rateMultiplier: 0.4, rateUnit: "Credit", promptCaching: KIRO_PROMPT_CACHING_4096, importOwnership: "model-discovery" },
1392
- { id: "deepseek-3.2", name: "DeepSeek 3.2", reasoning: true, contextWindow: 164e3, maxTokens: KIRO_MAX_OUTPUT_TOKENS, rateMultiplier: 0.25, rateUnit: "Credit", promptCaching: KIRO_PROMPT_CACHING_DISABLED, importOwnership: "model-discovery" },
1393
- { id: "minimax-m2.5", name: "MiniMax M2.5", reasoning: true, contextWindow: 196e3, maxTokens: KIRO_MAX_OUTPUT_TOKENS, rateMultiplier: 0.25, rateUnit: "Credit", promptCaching: KIRO_PROMPT_CACHING_DISABLED, importOwnership: "model-discovery" },
1394
- { id: "minimax-m2.1", name: "MiniMax M2.1", reasoning: true, contextWindow: 196e3, maxTokens: KIRO_MAX_OUTPUT_TOKENS, rateMultiplier: 0.15, rateUnit: "Credit", promptCaching: KIRO_PROMPT_CACHING_DISABLED, importOwnership: "model-discovery" },
1395
- { id: "glm-5", name: "GLM-5", reasoning: true, contextWindow: 2e5, maxTokens: KIRO_MAX_OUTPUT_TOKENS, rateMultiplier: 0.5, rateUnit: "Credit", promptCaching: KIRO_PROMPT_CACHING_DISABLED, importOwnership: "model-discovery" },
1396
- { id: "qwen3-coder-next", name: "Qwen3 Coder Next", reasoning: true, contextWindow: 256e3, maxTokens: KIRO_MAX_OUTPUT_TOKENS, rateMultiplier: 0.05, rateUnit: "Credit", promptCaching: KIRO_PROMPT_CACHING_DISABLED, importOwnership: "model-discovery" }
1397
- ];
1398
1381
  var DEFAULT_MODEL_DEFAULTS = {
1399
1382
  reasoning: true,
1400
1383
  input: ["text"],
@@ -1602,11 +1585,7 @@ function loadConfig(extensionRoot) {
1602
1585
  const warnings = [];
1603
1586
  const raw = readRawConfig(extensionRoot, warnings);
1604
1587
  const defaults = modelDefaultsFrom(raw, warnings);
1605
- const models = normalizeModelList(Array.isArray(raw.models) ? raw.models : DEFAULT_MODELS, defaults, warnings);
1606
- if (models.length === 0) {
1607
- warnings.push("No valid models were configured; using the default Kiro model list.");
1608
- models.push(...normalizeModelList(DEFAULT_MODELS, defaults, warnings));
1609
- }
1588
+ const models = normalizeModelList(Array.isArray(raw.models) ? raw.models : [], defaults, warnings);
1610
1589
  const upstreamUrl = stringOr(raw.upstreamUrl, "https://codewhisperer.us-east-1.amazonaws.com/generateAssistantResponse");
1611
1590
  return {
1612
1591
  config: {
@@ -2273,244 +2252,20 @@ var log = {
2273
2252
  isDebug: () => enabled("debug")
2274
2253
  };
2275
2254
 
2276
- // node_modules/@ngosangns/ns-pi-provider/src/kiro/transform.ts
2277
- var KIRO_ORIGIN = "AI_EDITOR";
2278
-
2279
- // node_modules/@ngosangns/ns-pi-provider/src/kiro/models.ts
2280
- var discoveredModelIds = /* @__PURE__ */ new Set();
2281
- function setDiscoveredModelIds(kiroIds) {
2282
- discoveredModelIds.clear();
2283
- for (const id of kiroIds) discoveredModelIds.add(id);
2284
- }
2285
- var BASE_URL = "https://q.us-east-1.amazonaws.com/";
2286
- var ZERO_COST = Object.freeze({ input: 0, output: 0, cacheRead: 0, cacheWrite: 0 });
2287
- var KIRO_DEFAULTS = {
2288
- api: "kiro-api",
2289
- provider: "kiro",
2290
- baseUrl: BASE_URL,
2291
- cost: ZERO_COST
2292
- };
2293
- var MULTIMODAL = ["text", "image"];
2294
- var TEXT_ONLY = ["text"];
2295
- var kiroModels = [
2296
- {
2297
- ...KIRO_DEFAULTS,
2298
- id: "claude-opus-4-8",
2299
- name: "Claude Opus 4.8",
2300
- reasoning: true,
2301
- reasoningHidden: true,
2302
- input: MULTIMODAL,
2303
- contextWindow: 1e6,
2304
- maxTokens: 128e3,
2305
- firstTokenTimeout: 18e4
2306
- },
2307
- {
2308
- ...KIRO_DEFAULTS,
2309
- id: "claude-opus-4-7",
2310
- name: "Claude Opus 4.7",
2311
- reasoning: true,
2312
- reasoningHidden: true,
2313
- input: MULTIMODAL,
2314
- contextWindow: 1e6,
2315
- maxTokens: 128e3,
2316
- firstTokenTimeout: 18e4
2317
- },
2318
- {
2319
- ...KIRO_DEFAULTS,
2320
- id: "claude-opus-4-6",
2321
- name: "Claude Opus 4.6",
2322
- reasoning: true,
2323
- input: MULTIMODAL,
2324
- contextWindow: 2e5,
2325
- maxTokens: 32768
2326
- },
2327
- {
2328
- ...KIRO_DEFAULTS,
2329
- id: "claude-opus-4-6-1m",
2330
- name: "Claude Opus 4.6 (1M)",
2331
- reasoning: true,
2332
- input: MULTIMODAL,
2333
- contextWindow: 1e6,
2334
- maxTokens: 32768
2335
- },
2336
- {
2337
- ...KIRO_DEFAULTS,
2338
- id: "claude-sonnet-4-6",
2339
- name: "Claude Sonnet 4.6",
2340
- reasoning: true,
2341
- input: MULTIMODAL,
2342
- contextWindow: 2e5,
2343
- maxTokens: 65536
2344
- },
2345
- {
2346
- ...KIRO_DEFAULTS,
2347
- id: "claude-sonnet-4-6-1m",
2348
- name: "Claude Sonnet 4.6 (1M)",
2349
- reasoning: true,
2350
- input: MULTIMODAL,
2351
- contextWindow: 1e6,
2352
- maxTokens: 65536
2353
- },
2354
- {
2355
- ...KIRO_DEFAULTS,
2356
- id: "claude-opus-4-5",
2357
- name: "Claude Opus 4.5",
2358
- reasoning: true,
2359
- input: MULTIMODAL,
2360
- contextWindow: 2e5,
2361
- maxTokens: 32768
2362
- },
2363
- {
2364
- ...KIRO_DEFAULTS,
2365
- id: "claude-sonnet-4-5",
2366
- name: "Claude Sonnet 4.5",
2367
- reasoning: true,
2368
- input: MULTIMODAL,
2369
- contextWindow: 2e5,
2370
- maxTokens: 65536
2371
- },
2372
- {
2373
- ...KIRO_DEFAULTS,
2374
- id: "claude-sonnet-4-5-1m",
2375
- name: "Claude Sonnet 4.5 (1M)",
2376
- reasoning: true,
2377
- input: MULTIMODAL,
2378
- contextWindow: 1e6,
2379
- maxTokens: 65536
2380
- },
2381
- {
2382
- ...KIRO_DEFAULTS,
2383
- id: "claude-sonnet-4",
2384
- name: "Claude Sonnet 4",
2385
- reasoning: true,
2386
- input: MULTIMODAL,
2387
- contextWindow: 2e5,
2388
- maxTokens: 65536
2389
- },
2390
- {
2391
- ...KIRO_DEFAULTS,
2392
- id: "claude-haiku-4-5",
2393
- name: "Claude Haiku 4.5",
2394
- reasoning: false,
2395
- input: MULTIMODAL,
2396
- contextWindow: 2e5,
2397
- maxTokens: 65536
2398
- },
2399
- {
2400
- ...KIRO_DEFAULTS,
2401
- id: "deepseek-3-2",
2402
- name: "DeepSeek 3.2",
2403
- reasoning: true,
2404
- input: TEXT_ONLY,
2405
- contextWindow: 128e3,
2406
- maxTokens: 8192
2407
- },
2408
- {
2409
- ...KIRO_DEFAULTS,
2410
- id: "kimi-k2-5",
2411
- name: "Kimi K2.5",
2412
- reasoning: true,
2413
- input: TEXT_ONLY,
2414
- contextWindow: 2e5,
2415
- maxTokens: 8192
2416
- },
2417
- {
2418
- ...KIRO_DEFAULTS,
2419
- id: "minimax-m2-5",
2420
- name: "MiniMax M2.5",
2421
- reasoning: false,
2422
- input: TEXT_ONLY,
2423
- contextWindow: 2e5,
2424
- maxTokens: 8192
2425
- },
2426
- {
2427
- ...KIRO_DEFAULTS,
2428
- id: "minimax-m2-1",
2429
- name: "MiniMax M2.1",
2430
- reasoning: false,
2431
- input: TEXT_ONLY,
2432
- contextWindow: 2e5,
2433
- maxTokens: 8192
2434
- },
2435
- {
2436
- ...KIRO_DEFAULTS,
2437
- id: "glm-4-7",
2438
- name: "GLM 4.7",
2439
- reasoning: true,
2440
- input: TEXT_ONLY,
2441
- contextWindow: 128e3,
2442
- maxTokens: 8192
2443
- },
2444
- {
2445
- ...KIRO_DEFAULTS,
2446
- id: "glm-4-7-flash",
2447
- name: "GLM 4.7 Flash",
2448
- reasoning: false,
2449
- input: TEXT_ONLY,
2450
- contextWindow: 128e3,
2451
- maxTokens: 8192
2452
- },
2453
- {
2454
- ...KIRO_DEFAULTS,
2455
- id: "qwen3-coder-next",
2456
- name: "Qwen3 Coder Next",
2457
- reasoning: true,
2458
- input: TEXT_ONLY,
2459
- contextWindow: 256e3,
2460
- maxTokens: 8192
2461
- },
2462
- {
2463
- ...KIRO_DEFAULTS,
2464
- id: "qwen3-coder-480b",
2465
- name: "Qwen3 Coder 480B",
2466
- reasoning: true,
2467
- input: TEXT_ONLY,
2468
- contextWindow: 128e3,
2469
- maxTokens: 8192
2470
- },
2471
- {
2472
- ...KIRO_DEFAULTS,
2473
- id: "agi-nova-beta-1m",
2474
- name: "AGI Nova Beta (1M)",
2475
- reasoning: true,
2476
- input: MULTIMODAL,
2477
- contextWindow: 1e6,
2478
- maxTokens: 65536
2479
- },
2480
- {
2481
- ...KIRO_DEFAULTS,
2482
- id: "auto",
2483
- name: "Auto",
2484
- reasoning: true,
2485
- input: MULTIMODAL,
2486
- contextWindow: 2e5,
2487
- maxTokens: 65536
2488
- }
2489
- ];
2490
-
2491
2255
  // node_modules/@ngosangns/ns-pi-provider/src/kiro/discover.ts
2256
+ var KIRO_ORIGIN = "AI_EDITOR";
2492
2257
  var LIST_TARGET = "AmazonCodeWhispererService.ListAvailableModels";
2493
2258
  var LIST_TIMEOUT_MS = 15e3;
2494
2259
  function buildUserAgent() {
2495
2260
  const mid = crypto.randomUUID().replace(/-/g, "");
2496
2261
  return `aws-sdk-rust/1.0.0 ua/2.1 os/other lang/rust api/codewhispererstreaming#1.28.3 m/E app/AmazonQ-For-CLI md/appVersion-1.28.3-${mid}`;
2497
2262
  }
2498
- var BEHAVIOR_BY_KIRO_ID = Object.fromEntries(
2499
- kiroModels.map((m) => [
2500
- m.id.replace(/(\d)-(\d)/g, "$1.$2"),
2501
- {
2502
- ...m.reasoningHidden ? { reasoningHidden: true } : {},
2503
- ...m.firstTokenTimeout ? { firstTokenTimeout: m.firstTokenTimeout } : {}
2504
- }
2505
- ])
2506
- );
2507
- var ONE_M_SUFFIX = "-1m";
2508
- var ONE_M_CONTEXT = 1e6;
2509
2263
  function toPiId(kiroId) {
2510
2264
  return kiroId.replace(/(\d)\.(\d)/g, "$1-$2");
2511
2265
  }
2512
2266
  function toKiroModel(api, baseUrl) {
2513
2267
  const piId = toPiId(api.modelId);
2268
+ const thinkingLevelMap = defaultThinkingLevelMapForModel(piId, api.modelName ?? piId);
2514
2269
  const types = api.supportedInputTypes ?? ["TEXT"];
2515
2270
  const input = types.some((t) => t.toUpperCase() === "IMAGE") ? ["text", "image"] : ["text"];
2516
2271
  return {
@@ -2520,39 +2275,18 @@ function toKiroModel(api, baseUrl) {
2520
2275
  provider: "kiro",
2521
2276
  baseUrl,
2522
2277
  // The API reports no reasoning capability flag. Treat every model as
2523
- // reasoning-capable: stream.ts gates the `<thinking_mode>` directive on
2524
- // this, and an unnecessary directive is far cheaper than suppressing
2525
- // reasoning on a model that supports it.
2278
+ // reasoning-capable: an over-eager `reasoning` flag is far cheaper than
2279
+ // suppressing reasoning on a model that supports it.
2526
2280
  reasoning: true,
2527
2281
  input,
2528
2282
  // Kiro bills in credits via rateMultiplier, not per-token USD. There is
2529
- // no token price to report, so cost stays zero and the multiplier is
2530
- // surfaced in the model name instead.
2283
+ // no token price to report, so cost stays zero.
2531
2284
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
2532
2285
  contextWindow: api.tokenLimits?.maxInputTokens ?? 2e5,
2533
2286
  maxTokens: api.tokenLimits?.maxOutputTokens ?? 8192,
2534
- ...BEHAVIOR_BY_KIRO_ID[api.modelId]
2287
+ ...thinkingLevelMap ? { thinkingLevelMap } : {}
2535
2288
  };
2536
2289
  }
2537
- function deriveLongContextVariants(discovered, baseUrl) {
2538
- const present = new Set(discovered.map((m) => m.id));
2539
- const out = [];
2540
- for (const staticModel of kiroModels) {
2541
- if (!staticModel.id.endsWith(ONE_M_SUFFIX)) continue;
2542
- if (present.has(staticModel.id)) continue;
2543
- const baseId = staticModel.id.slice(0, -ONE_M_SUFFIX.length);
2544
- const base = discovered.find((m) => m.id === baseId);
2545
- if (!base) continue;
2546
- out.push({
2547
- ...base,
2548
- id: staticModel.id,
2549
- name: `${base.name} (1M)`,
2550
- contextWindow: ONE_M_CONTEXT,
2551
- ...BEHAVIOR_BY_KIRO_ID[staticModel.id.replace(/(\d)-(\d)/g, "$1.$2")]
2552
- });
2553
- }
2554
- return out;
2555
- }
2556
2290
  async function discoverKiroModels(apiKey, baseUrl, signal) {
2557
2291
  const ua = buildUserAgent();
2558
2292
  const timeout = AbortSignal.timeout(LIST_TIMEOUT_MS);
@@ -2606,13 +2340,10 @@ async function discoverKiroModels(apiKey, baseUrl, signal) {
2606
2340
  "Kiro model discovery returned no models for this API key. The key may lack model entitlements, or be scoped to another region."
2607
2341
  );
2608
2342
  }
2609
- const discovered = apiModels.filter((m) => typeof m.modelId === "string" && m.modelId.length > 0).map((m) => toKiroModel(m, baseUrl));
2610
- const models = [...discovered, ...deriveLongContextVariants(discovered, baseUrl)];
2611
- setDiscoveredModelIds(models.map((m) => m.id.replace(/(\d)-(\d)/g, "$1.$2")));
2343
+ const models = apiModels.filter((m) => typeof m.modelId === "string" && m.modelId.length > 0).map((m) => toKiroModel(m, baseUrl));
2612
2344
  log.info("discover.ok", {
2613
2345
  count: models.length,
2614
- discovered: discovered.map((m) => m.id),
2615
- derived: models.length - discovered.length,
2346
+ discovered: models.map((m) => m.id),
2616
2347
  defaultModel: payload.defaultModel?.modelId
2617
2348
  });
2618
2349
  return models;
@@ -2817,9 +2548,10 @@ async function refreshKiroModels(options = {}) {
2817
2548
  input: m.input,
2818
2549
  cost: ensureCacheCost(m.cost),
2819
2550
  contextWindow: m.contextWindow,
2820
- maxTokens: m.maxTokens
2551
+ maxTokens: m.maxTokens,
2552
+ ...m.thinkingLevelMap ? { thinkingLevelMap: m.thinkingLevelMap } : {}
2821
2553
  }));
2822
- return { models, version: "kiro-list-v1" };
2554
+ return { models, version: "kiro-list-v2" };
2823
2555
  },
2824
2556
  { force: options.force }
2825
2557
  );
@@ -2830,7 +2562,7 @@ async function refreshKiroModels(options = {}) {
2830
2562
  return { models: fallback, fromCache: false };
2831
2563
  }
2832
2564
  }
2833
- function registerKiroProvider(pi) {
2565
+ async function registerKiroProvider(pi) {
2834
2566
  const { config, warnings } = loadConfig(EXTENSION_ROOT);
2835
2567
  const logger = new DebugLogger({ extensionRoot: EXTENSION_ROOT, debug: config.debug });
2836
2568
  for (const warning of warnings) logger.warn("config_warning", { warning });
@@ -2858,7 +2590,10 @@ function registerKiroProvider(pi) {
2858
2590
  const runtime = {};
2859
2591
  const streamSimple = createLazyKiroStream(config, runtime, logger);
2860
2592
  const providerHeaders = omitAuthorizationHeaders(config.headers);
2861
- let currentModels = toProviderModels(fallbackCatalogModels(config), config);
2593
+ let currentModels = toProviderModels(
2594
+ (await refreshKiroModels({ fallback: fallbackCatalogModels(config) })).models,
2595
+ config
2596
+ );
2862
2597
  const buildConfig = (models) => ({
2863
2598
  name: config.displayName || "Kiro",
2864
2599
  baseUrl: config.upstreamUrl,
@@ -3691,14 +3426,14 @@ function formatResetTime(epoch) {
3691
3426
  // node_modules/@ngosangns/ns-pi-provider/src/devin/register.ts
3692
3427
  var DEVIN_PROVIDER_ID = "devin";
3693
3428
  var API = "devin-cloud";
3694
- var BASE_URL2 = "https://server.codeium.com";
3429
+ var BASE_URL = "https://server.codeium.com";
3695
3430
  var FALLBACK_MODELS = [
3696
3431
  {
3697
3432
  id: "swe-1-7",
3698
3433
  name: "SWE-1.7",
3699
3434
  api: API,
3700
3435
  provider: DEVIN_PROVIDER_ID,
3701
- baseUrl: BASE_URL2,
3436
+ baseUrl: BASE_URL,
3702
3437
  reasoning: true,
3703
3438
  input: ["text"],
3704
3439
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
@@ -3710,7 +3445,7 @@ var FALLBACK_MODELS = [
3710
3445
  name: "SWE-1.6",
3711
3446
  api: API,
3712
3447
  provider: DEVIN_PROVIDER_ID,
3713
- baseUrl: BASE_URL2,
3448
+ baseUrl: BASE_URL,
3714
3449
  reasoning: true,
3715
3450
  input: ["text"],
3716
3451
  cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
@@ -3738,7 +3473,7 @@ function fromCatalog(models) {
3738
3473
  name: m.name,
3739
3474
  api: m.api || API,
3740
3475
  provider: DEVIN_PROVIDER_ID,
3741
- baseUrl: m.baseUrl ?? BASE_URL2,
3476
+ baseUrl: m.baseUrl ?? BASE_URL,
3742
3477
  reasoning: m.reasoning ?? true,
3743
3478
  input: m.input ?? ["text"],
3744
3479
  cost: ensureCacheCost(m.cost),
@@ -3813,7 +3548,7 @@ function providerConfig(currentModels, apiKey) {
3813
3548
  return {
3814
3549
  name: "Devin",
3815
3550
  api: API,
3816
- baseUrl: BASE_URL2,
3551
+ baseUrl: BASE_URL,
3817
3552
  models: currentModels,
3818
3553
  // When CLI credentials.toml (or env) already has a token, set apiKey so Pi
3819
3554
  // marks the provider configured for --list-models without auth.json /login.
@@ -4475,15 +4210,23 @@ var state = {
4475
4210
  };
4476
4211
  var nextGeneration = 1;
4477
4212
  var scopeGenerations = /* @__PURE__ */ new Map([[ANONYMOUS_SCOPE, 0]]);
4478
- var onScopeChange;
4479
4213
  function getSessionCwd() {
4480
4214
  return state.cwd;
4481
4215
  }
4482
4216
  function getSessionScopeKey() {
4483
- if (state.sessionFile) return state.sessionFile;
4484
- if (state.sessionId) return `${EPHEMERAL_PREFIX}${state.sessionId}`;
4217
+ return scopeKeyFrom(state.sessionFile, state.sessionId);
4218
+ }
4219
+ function scopeKeyFrom(sessionFile, sessionId) {
4220
+ if (sessionFile) return sessionFile;
4221
+ if (sessionId) return `${EPHEMERAL_PREFIX}${sessionId}`;
4485
4222
  return ANONYMOUS_SCOPE;
4486
4223
  }
4224
+ function scopeKeyFromCtx(ctx) {
4225
+ return scopeKeyFrom(
4226
+ ctx.sessionManager?.getSessionFile?.() ?? void 0,
4227
+ ctx.sessionManager?.getSessionId?.() ?? void 0
4228
+ );
4229
+ }
4487
4230
  function setScope(cwd, sessionFile, sessionId) {
4488
4231
  state.cwd = cwd;
4489
4232
  state.sessionFile = sessionFile;
@@ -4491,20 +4234,13 @@ function setScope(cwd, sessionFile, sessionId) {
4491
4234
  state.generation = nextGeneration++;
4492
4235
  scopeGenerations.set(getSessionScopeKey(), state.generation);
4493
4236
  }
4494
- function onSessionScopeKeyChange(handler) {
4495
- onScopeChange = handler;
4496
- }
4497
4237
  function registerSessionScope(pi) {
4498
4238
  pi.on("session_start", async (_event, ctx) => {
4499
- const previousScopeKey = getSessionScopeKey();
4500
4239
  setScope(
4501
4240
  ctx.cwd,
4502
4241
  ctx.sessionManager?.getSessionFile?.() ?? void 0,
4503
4242
  ctx.sessionManager?.getSessionId?.() ?? void 0
4504
4243
  );
4505
- if (previousScopeKey !== getSessionScopeKey()) {
4506
- await onScopeChange?.(previousScopeKey);
4507
- }
4508
4244
  });
4509
4245
  pi.on("session_info_changed", async () => {
4510
4246
  });
@@ -5116,6 +4852,7 @@ function streamGrokAgent(model, context, options) {
5116
4852
  }
5117
4853
 
5118
4854
  // node_modules/@ngosangns/ns-pi-provider/src/grok/register.ts
4855
+ var exitHookInstalled = false;
5119
4856
  var GROK_PROVIDER_ID = "grok";
5120
4857
  var GROK_SDK_PROVIDER_ID = "grok-sdk";
5121
4858
  var GROK_API = "grok-cli";
@@ -5199,19 +4936,18 @@ function createProviderConfig(models) {
5199
4936
  }
5200
4937
  function registerGrokProvider(pi) {
5201
4938
  registerSessionScope(pi);
5202
- onSessionScopeKeyChange((previousKey) => {
5203
- disposeSessionAgentsForScope(previousKey);
5204
- });
5205
- pi.on("session_shutdown", async () => {
5206
- disposeAllSessionAgents();
4939
+ pi.on("session_shutdown", async (_event, ctx) => {
4940
+ disposeSessionAgentsForScope(scopeKeyFromCtx(ctx));
5207
4941
  });
5208
- const cleanup = () => {
5209
- try {
5210
- disposeAllSessionAgents();
5211
- } catch {
5212
- }
5213
- };
5214
- process.once("exit", cleanup);
4942
+ if (!exitHookInstalled) {
4943
+ exitHookInstalled = true;
4944
+ process.once("exit", () => {
4945
+ try {
4946
+ disposeAllSessionAgents();
4947
+ } catch {
4948
+ }
4949
+ });
4950
+ }
5215
4951
  let binary;
5216
4952
  let binaryError;
5217
4953
  try {
@@ -5294,7 +5030,7 @@ async function registerAllProviders(pi, options = {}) {
5294
5030
  const enableGrok = options.grok !== false;
5295
5031
  if (enableKiro) {
5296
5032
  try {
5297
- registerKiroProvider(pi);
5033
+ await registerKiroProvider(pi);
5298
5034
  } catch (err) {
5299
5035
  console.warn(
5300
5036
  `[ns-pi-provider] kiro registration failed: ${err instanceof Error ? err.message : String(err)}`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ns-omp-provider",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "OMP (oh-my-pi) plugin: Kiro, Devin, and Grok providers from @ngosangns/ns-pi-provider, wrapped for OMP's provider/extension API.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -70,7 +70,7 @@
70
70
  }
71
71
  },
72
72
  "devDependencies": {
73
- "@ngosangns/ns-pi-provider": "0.1.7",
73
+ "@ngosangns/ns-pi-provider": "0.2.0",
74
74
  "@types/node": "^22.18.6",
75
75
  "esbuild": "^0.28.2",
76
76
  "typescript": "^5.9.2",