@aidotnet/nextcowork-device-service 2.7.2 → 2.7.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.
package/RUNTIME.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "entry": "bin.mjs",
3
3
  "node": ">=24",
4
- "version": "2.7.2",
4
+ "version": "2.7.3",
5
5
  "note": "Dependencies are external; install them with the repository package.json before running.",
6
6
  "files": [
7
7
  "BUNDLE_IMPORTS.json",
package/bin.mjs CHANGED
@@ -4517,6 +4517,52 @@ function removeUserModelCatalog(id) {
4517
4517
  setKv(USER_MODEL_CATALOG_KEY, next);
4518
4518
  });
4519
4519
  }
4520
+ function listSyncedPricing() {
4521
+ return stmt(
4522
+ `SELECT provider_id, model_id, display_name, currency, modality, tiers, windows,
4523
+ effective_from, effective_until, source, fetched_at
4524
+ FROM model_pricing WHERE is_seed = 0 ORDER BY model_id, COALESCE(effective_from, '')`
4525
+ ).all().map((row) => ({
4526
+ providerId: asNullableString(row["provider_id"]),
4527
+ modelId: String(row["model_id"]),
4528
+ displayName: String(row["display_name"]),
4529
+ currency: String(row["currency"]),
4530
+ modality: String(row["modality"]),
4531
+ tiers: parse$1(row["tiers"]) ?? [],
4532
+ ...row["windows"] === null ? {} : { windows: parse$1(row["windows"]) ?? [] },
4533
+ ...row["effective_from"] === null ? {} : { effectiveFrom: String(row["effective_from"]) },
4534
+ ...row["effective_until"] === null ? {} : { effectiveUntil: String(row["effective_until"]) },
4535
+ source: String(row["source"]),
4536
+ fetchedAt: String(row["fetched_at"])
4537
+ }));
4538
+ }
4539
+ function replaceSyncedPricing(rows) {
4540
+ tx(() => {
4541
+ for (const r of rows) {
4542
+ stmt("DELETE FROM model_pricing WHERE is_seed = 0 AND model_id = ? AND COALESCE(provider_id, '') = ?").run(r.modelId, r.providerId ?? "");
4543
+ stmt(
4544
+ `INSERT INTO model_pricing
4545
+ (provider_id, model_id, display_name, currency, modality, tiers, windows, effective_from, effective_until, source, fetched_at, is_seed)
4546
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 0)`
4547
+ ).run(
4548
+ r.providerId,
4549
+ r.modelId,
4550
+ r.displayName,
4551
+ r.currency,
4552
+ r.modality,
4553
+ JSON.stringify(r.tiers),
4554
+ r.windows === void 0 ? null : JSON.stringify(r.windows),
4555
+ r.effectiveFrom ?? null,
4556
+ r.effectiveUntil ?? null,
4557
+ r.source,
4558
+ r.fetchedAt
4559
+ );
4560
+ }
4561
+ });
4562
+ }
4563
+ function clearSyncedPricing() {
4564
+ stmt("DELETE FROM model_pricing WHERE is_seed = 0").run();
4565
+ }
4520
4566
  const asNullableString = (value) => value === null || value === void 0 ? null : String(value);
4521
4567
  function usageRecordFromRow(row) {
4522
4568
  return {
@@ -8260,6 +8306,16 @@ const store = {
8260
8306
  removeUserModelCatalog(id) {
8261
8307
  removeUserModelCatalog(id);
8262
8308
  },
8309
+ // ── synced pricing (models.dev) ──
8310
+ listSyncedPricing() {
8311
+ return listSyncedPricing();
8312
+ },
8313
+ replaceSyncedPricing(rows) {
8314
+ replaceSyncedPricing(rows);
8315
+ },
8316
+ clearSyncedPricing() {
8317
+ clearSyncedPricing();
8318
+ },
8263
8319
  // ── MCP 服务器(设置 › 连接 › MCP) ──
8264
8320
  /**
8265
8321
  * 顺序按 id,没有语义 —— 但要稳定。理由在 `repo.listMcpServers`。
@@ -11848,7 +11904,7 @@ async function scopedPath(root, scope) {
11848
11904
  function localSettingsPath(workspaceRoot2) {
11849
11905
  return join(workspaceRoot2, LOCAL_SETTINGS_DIRNAME, LOCAL_SETTINGS_FILENAME);
11850
11906
  }
11851
- const cache = /* @__PURE__ */ new Map();
11907
+ const cache$1 = /* @__PURE__ */ new Map();
11852
11908
  const writes = /* @__PURE__ */ new Map();
11853
11909
  const MISSING = "missing";
11854
11910
  function globalSettingsPath(userDataDir) {
@@ -11866,7 +11922,7 @@ async function fileKey(fs, path, strict = false) {
11866
11922
  }
11867
11923
  async function readSettingsAt(fs, path, cacheKey, strict, logger) {
11868
11924
  const key = await fileKey(fs, path, strict);
11869
- const hit = cacheKey === void 0 ? void 0 : cache.get(cacheKey);
11925
+ const hit = cacheKey === void 0 ? void 0 : cache$1.get(cacheKey);
11870
11926
  if (hit !== void 0 && hit.key === key) return hit.settings;
11871
11927
  let settings = emptyLocalSettings();
11872
11928
  if (key !== MISSING) {
@@ -11877,7 +11933,7 @@ async function readSettingsAt(fs, path, cacheKey, strict, logger) {
11877
11933
  logger?.warn(`[settings] ${path} 不是有效的 JSON,本次按「没有配置」处理`);
11878
11934
  }
11879
11935
  }
11880
- if (cacheKey !== void 0) cache.set(cacheKey, { key, settings });
11936
+ if (cacheKey !== void 0) cache$1.set(cacheKey, { key, settings });
11881
11937
  return settings;
11882
11938
  }
11883
11939
  async function readLocalSettings(fs, workspaceRoot2, logger, scope = {}) {
@@ -11914,7 +11970,7 @@ async function updateSettingsFile(fs, path, mutate, logger) {
11914
11970
  logger?.error(`[settings] 写入 ${path} 失败`, error);
11915
11971
  return { ok: false, reason: "io" };
11916
11972
  }
11917
- cache.delete(path);
11973
+ cache$1.delete(path);
11918
11974
  return { ok: true, path, changed: true };
11919
11975
  }
11920
11976
  function queued(key, run2) {
@@ -28431,6 +28487,15 @@ const geminiStandardCapabilities = (fileInput = true) => visionCapabilities({
28431
28487
  batch: true
28432
28488
  });
28433
28489
  const GOOGLE = [
28490
+ model("google", "gemini-4-argon", "Gemini 4 Argon", {
28491
+ capabilities: geminiStandardCapabilities(),
28492
+ contextWindow: 1048576,
28493
+ maxOutputTokens: 65536,
28494
+ thinkingConfig: effortThinking("reasoning_effort", "medium"),
28495
+ reasoningEfforts: ["low", "medium", "high"],
28496
+ source: source$1("https://ai.google.dev/gemini-api/docs/models/gemini-4-argon"),
28497
+ verificationStatus: "official-api"
28498
+ }),
28434
28499
  model("google", "gemini-3.8-flash", "Gemini 3.8 Flash", {
28435
28500
  capabilities: geminiStandardCapabilities(),
28436
28501
  contextWindow: 1048576,
@@ -31356,6 +31421,123 @@ function listResolvedModels() {
31356
31421
  (a, b) => (rank.get(a.providerId) ?? 1e9) - (rank.get(b.providerId) ?? 1e9) || (a.priority ?? Number.MAX_SAFE_INTEGER) - (b.priority ?? Number.MAX_SAFE_INTEGER) || a.alias.localeCompare(b.alias)
31357
31422
  );
31358
31423
  }
31424
+ function priceOf(p, usage, at) {
31425
+ const tierIndex = selectTier(p.tiers, billableInputTokens(usage));
31426
+ const tier = p.tiers[tierIndex];
31427
+ if (tier === void 0) return null;
31428
+ const window = activeWindow(p.windows, at);
31429
+ const micros = costMicros(effectiveRate(tier.rate, window), usage);
31430
+ if (micros === null) return null;
31431
+ return {
31432
+ micros,
31433
+ currency: p.currency,
31434
+ tier: tierIndex,
31435
+ ...window === null ? {} : { window: window.label }
31436
+ };
31437
+ }
31438
+ function billableInputTokens(u) {
31439
+ return u.inputTokens + (u.cacheReadInputTokens ?? 0) + (u.cacheCreationInputTokens ?? 0);
31440
+ }
31441
+ function selectTier(tiers, inputTokens) {
31442
+ for (let i = 0; i < tiers.length; i++) {
31443
+ const up = tiers[i]?.upToInputTokens;
31444
+ if (up === void 0) continue;
31445
+ if (up === null || inputTokens <= up) return i;
31446
+ }
31447
+ return tiers.length - 1;
31448
+ }
31449
+ function effectiveRate(base2, w) {
31450
+ if (w === null) return base2;
31451
+ if (w.rates !== void 0) return w.rates;
31452
+ if (w.multiplier === void 0) return base2;
31453
+ const m = w.multiplier;
31454
+ return {
31455
+ input: base2.input * m,
31456
+ output: base2.output * m,
31457
+ ...base2.cacheRead === void 0 ? {} : { cacheRead: base2.cacheRead * m },
31458
+ ...base2.cacheWrite === void 0 ? {} : { cacheWrite: base2.cacheWrite * m },
31459
+ ...base2.cacheWrite1h === void 0 ? {} : { cacheWrite1h: base2.cacheWrite1h * m },
31460
+ ...base2.perCall === void 0 ? {} : { perCall: base2.perCall * m }
31461
+ };
31462
+ }
31463
+ function costMicros(r, u) {
31464
+ const write1h = u.cacheCreation1hInputTokens ?? 0;
31465
+ const write5m = Math.max(0, (u.cacheCreationInputTokens ?? 0) - write1h);
31466
+ const read = u.cacheReadInputTokens ?? 0;
31467
+ let total = u.inputTokens * r.input + u.outputTokens * r.output;
31468
+ if (read > 0) {
31469
+ if (r.cacheRead === void 0) return null;
31470
+ total += read * r.cacheRead;
31471
+ }
31472
+ if (write5m > 0) {
31473
+ if (r.cacheWrite === void 0) return null;
31474
+ total += write5m * r.cacheWrite;
31475
+ }
31476
+ if (write1h > 0) {
31477
+ if (r.cacheWrite1h === void 0) return null;
31478
+ total += write1h * r.cacheWrite1h;
31479
+ }
31480
+ if (r.perCall !== void 0) total += r.perCall * 1e6;
31481
+ return Math.round(total);
31482
+ }
31483
+ function zonedHourAndDay(timezone, at) {
31484
+ const parts = new Intl.DateTimeFormat("en-US", {
31485
+ timeZone: timezone,
31486
+ hourCycle: "h23",
31487
+ weekday: "short",
31488
+ hour: "2-digit",
31489
+ minute: "2-digit"
31490
+ }).formatToParts(new Date(at));
31491
+ const get = (t) => parts.find((p) => p.type === t)?.value ?? "";
31492
+ return {
31493
+ minutes: Number(get("hour")) * 60 + Number(get("minute")),
31494
+ day: WEEKDAY[get("weekday")] ?? -1
31495
+ };
31496
+ }
31497
+ const WEEKDAY = {
31498
+ Sun: 0,
31499
+ Mon: 1,
31500
+ Tue: 2,
31501
+ Wed: 3,
31502
+ Thu: 4,
31503
+ Fri: 5,
31504
+ Sat: 6
31505
+ };
31506
+ const toMinutes = (hhmm) => {
31507
+ const [h, m] = hhmm.split(":");
31508
+ return Number(h) * 60 + Number(m);
31509
+ };
31510
+ function inWindow(w, at) {
31511
+ const { minutes, day } = zonedHourAndDay(w.timezone, at);
31512
+ if (w.daysOfWeek !== void 0 && !w.daysOfWeek.includes(day)) return false;
31513
+ const start = toMinutes(w.start);
31514
+ const end = toMinutes(w.end);
31515
+ return start <= end ? minutes >= start && minutes < end : minutes >= start || minutes < end;
31516
+ }
31517
+ function activeWindow(windows2, at) {
31518
+ return windows2?.find((w) => inWindow(w, at)) ?? null;
31519
+ }
31520
+ const isoDate = (at) => new Date(at).toISOString().slice(0, 10);
31521
+ const effectiveAt = (p, at) => {
31522
+ const d = isoDate(at);
31523
+ if (p.effectiveFrom !== void 0 && d < p.effectiveFrom) return false;
31524
+ if (p.effectiveUntil !== void 0 && d > p.effectiveUntil) return false;
31525
+ return true;
31526
+ };
31527
+ function findPricing(table, providerId, modelId2, at) {
31528
+ const rows = table.filter((p) => p.modelId === modelId2 && effectiveAt(p, at));
31529
+ if (providerId !== null) {
31530
+ const override = rows.find((p) => p.providerId === providerId);
31531
+ if (override !== void 0) return override;
31532
+ }
31533
+ return rows.find((p) => p.providerId === null) ?? null;
31534
+ }
31535
+ function mergePricing(seed2, synced) {
31536
+ if (synced.length === 0) return [...seed2];
31537
+ const key = (p) => `${p.providerId ?? ""}\0${p.modelId}`;
31538
+ const overridden = new Set(synced.map(key));
31539
+ return [...seed2.filter((p) => !overridden.has(key(p))), ...synced];
31540
+ }
31359
31541
  const FETCHED_AT = "2026-09-05";
31360
31542
  const one = (rate) => [{ upToInputTokens: null, rate }];
31361
31543
  const two = (upTo, low, high) => [
@@ -31494,6 +31676,14 @@ const OPENAI = [
31494
31676
  ];
31495
31677
  const gem = maker(null, "USD", "https://ai.google.dev/gemini-api/docs/pricing");
31496
31678
  const GEMINI = [
31679
+ gem("gemini-4-argon", "Gemini 4 Argon", one({ input: 2, output: 10, cacheRead: 0.1 }), {
31680
+ effectiveUntil: "2026-11-30",
31681
+ source: "https://ai.google.dev/gemini-api/docs/pricing#gemini-4-argon"
31682
+ }),
31683
+ gem("gemini-4-argon", "Gemini 4 Argon", one({ input: 4, output: 20, cacheRead: 0.2 }), {
31684
+ effectiveFrom: "2026-12-01",
31685
+ source: "https://ai.google.dev/gemini-api/docs/pricing#gemini-4-argon"
31686
+ }),
31497
31687
  gem("gemini-3.8-flash", "Gemini 3.8 Flash", one({ input: 0.75, output: 3.75, cacheRead: 0.075 }), {
31498
31688
  effectiveUntil: "2026-12-31",
31499
31689
  source: "https://ai.google.dev/gemini-api/docs/pricing#gemini-3.8-flash"
@@ -31756,116 +31946,10 @@ const MICROSOFT = [
31756
31946
  microsoft("mai-code-1.1-flash", "MAI-Code 1.1 Flash", two(272e3, { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite: 0.25 }, { input: 0.4, output: 1.8, cacheRead: 0.04, cacheWrite: 0.5 }))
31757
31947
  ];
31758
31948
  const PRICING_SEED = [...ANTHROPIC, ...OPENAI, ...GEMINI, ...XAI, ...ZHIPU, ...DEEPSEEK, ...MOONSHOT, ...QWEN, ...MINIMAX, ...MIMO, ...DOUBAO, ...BAIDU, ...HUNYUAN, ...STEPFUN, ...BAICHUAN, ...SENSENOVA, ...SPARK, ...PANGU, ...LONGCAT, ...MUSE, ...MICROSOFT];
31759
- function priceOf(p, usage, at) {
31760
- const tierIndex = selectTier(p.tiers, billableInputTokens(usage));
31761
- const tier = p.tiers[tierIndex];
31762
- if (tier === void 0) return null;
31763
- const window = activeWindow(p.windows, at);
31764
- const micros = costMicros(effectiveRate(tier.rate, window), usage);
31765
- if (micros === null) return null;
31766
- return {
31767
- micros,
31768
- currency: p.currency,
31769
- tier: tierIndex,
31770
- ...window === null ? {} : { window: window.label }
31771
- };
31772
- }
31773
- function billableInputTokens(u) {
31774
- return u.inputTokens + (u.cacheReadInputTokens ?? 0) + (u.cacheCreationInputTokens ?? 0);
31775
- }
31776
- function selectTier(tiers, inputTokens) {
31777
- for (let i = 0; i < tiers.length; i++) {
31778
- const up = tiers[i]?.upToInputTokens;
31779
- if (up === void 0) continue;
31780
- if (up === null || inputTokens <= up) return i;
31781
- }
31782
- return tiers.length - 1;
31783
- }
31784
- function effectiveRate(base2, w) {
31785
- if (w === null) return base2;
31786
- if (w.rates !== void 0) return w.rates;
31787
- if (w.multiplier === void 0) return base2;
31788
- const m = w.multiplier;
31789
- return {
31790
- input: base2.input * m,
31791
- output: base2.output * m,
31792
- ...base2.cacheRead === void 0 ? {} : { cacheRead: base2.cacheRead * m },
31793
- ...base2.cacheWrite === void 0 ? {} : { cacheWrite: base2.cacheWrite * m },
31794
- ...base2.cacheWrite1h === void 0 ? {} : { cacheWrite1h: base2.cacheWrite1h * m },
31795
- ...base2.perCall === void 0 ? {} : { perCall: base2.perCall * m }
31796
- };
31797
- }
31798
- function costMicros(r, u) {
31799
- const write1h = u.cacheCreation1hInputTokens ?? 0;
31800
- const write5m = Math.max(0, (u.cacheCreationInputTokens ?? 0) - write1h);
31801
- const read = u.cacheReadInputTokens ?? 0;
31802
- let total = u.inputTokens * r.input + u.outputTokens * r.output;
31803
- if (read > 0) {
31804
- if (r.cacheRead === void 0) return null;
31805
- total += read * r.cacheRead;
31806
- }
31807
- if (write5m > 0) {
31808
- if (r.cacheWrite === void 0) return null;
31809
- total += write5m * r.cacheWrite;
31810
- }
31811
- if (write1h > 0) {
31812
- if (r.cacheWrite1h === void 0) return null;
31813
- total += write1h * r.cacheWrite1h;
31814
- }
31815
- if (r.perCall !== void 0) total += r.perCall * 1e6;
31816
- return Math.round(total);
31817
- }
31818
- function zonedHourAndDay(timezone, at) {
31819
- const parts = new Intl.DateTimeFormat("en-US", {
31820
- timeZone: timezone,
31821
- hourCycle: "h23",
31822
- weekday: "short",
31823
- hour: "2-digit",
31824
- minute: "2-digit"
31825
- }).formatToParts(new Date(at));
31826
- const get = (t) => parts.find((p) => p.type === t)?.value ?? "";
31827
- return {
31828
- minutes: Number(get("hour")) * 60 + Number(get("minute")),
31829
- day: WEEKDAY[get("weekday")] ?? -1
31830
- };
31831
- }
31832
- const WEEKDAY = {
31833
- Sun: 0,
31834
- Mon: 1,
31835
- Tue: 2,
31836
- Wed: 3,
31837
- Thu: 4,
31838
- Fri: 5,
31839
- Sat: 6
31840
- };
31841
- const toMinutes = (hhmm) => {
31842
- const [h, m] = hhmm.split(":");
31843
- return Number(h) * 60 + Number(m);
31844
- };
31845
- function inWindow(w, at) {
31846
- const { minutes, day } = zonedHourAndDay(w.timezone, at);
31847
- if (w.daysOfWeek !== void 0 && !w.daysOfWeek.includes(day)) return false;
31848
- const start = toMinutes(w.start);
31849
- const end = toMinutes(w.end);
31850
- return start <= end ? minutes >= start && minutes < end : minutes >= start || minutes < end;
31851
- }
31852
- function activeWindow(windows2, at) {
31853
- return windows2?.find((w) => inWindow(w, at)) ?? null;
31854
- }
31855
- const isoDate = (at) => new Date(at).toISOString().slice(0, 10);
31856
- const effectiveAt = (p, at) => {
31857
- const d = isoDate(at);
31858
- if (p.effectiveFrom !== void 0 && d < p.effectiveFrom) return false;
31859
- if (p.effectiveUntil !== void 0 && d > p.effectiveUntil) return false;
31860
- return true;
31861
- };
31862
- function findPricing(table, providerId, modelId2, at) {
31863
- const rows = table.filter((p) => p.modelId === modelId2 && effectiveAt(p, at));
31864
- if (providerId !== null) {
31865
- const override = rows.find((p) => p.providerId === providerId);
31866
- if (override !== void 0) return override;
31867
- }
31868
- return rows.find((p) => p.providerId === null) ?? null;
31949
+ let cache = null;
31950
+ function getEffectivePricing() {
31951
+ cache ??= mergePricing(PRICING_SEED, store.listSyncedPricing());
31952
+ return cache;
31869
31953
  }
31870
31954
  const INPUT_LIMIT = 4e3;
31871
31955
  const TITLE_LIMIT = 80;
@@ -33660,7 +33744,7 @@ function resolveUsagePricingModelId(upstreamModel) {
33660
33744
  return catalogModel?.pricingModelId ?? catalogModel?.id ?? upstreamModel;
33661
33745
  }
33662
33746
  function resolveUsagePricing(providerId, pricingModelId, at) {
33663
- return findPricing(PRICING_SEED, providerId, pricingModelId, at);
33747
+ return findPricing(getEffectivePricing(), providerId, pricingModelId, at);
33664
33748
  }
33665
33749
  function priceUsageAttempt(providerId, upstreamModel, usage, at) {
33666
33750
  const pricing = resolveUsagePricing(providerId, resolveUsagePricingModelId(upstreamModel), at);