syntaur 0.66.1 → 0.67.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/dist/index.js CHANGED
@@ -13368,7 +13368,7 @@ async function resolveAgentTargets() {
13368
13368
  });
13369
13369
  return { targets: [...AGENT_TARGETS, ...user], warnings };
13370
13370
  }
13371
- var detectDir, claudeSessions, codexSessions, AGENT_TARGETS, AGENT_TARGETS_BY_ID;
13371
+ var detectDir, claudeSessions, codexSessions, piSessions, AGENT_TARGETS, AGENT_TARGETS_BY_ID;
13372
13372
  var init_registry = __esm({
13373
13373
  "src/targets/registry.ts"() {
13374
13374
  "use strict";
@@ -13396,6 +13396,16 @@ var init_registry = __esm({
13396
13396
  }
13397
13397
  }
13398
13398
  };
13399
+ piSessions = {
13400
+ globs: (root) => [join10(root ?? resolvePiSessionsRoot(), "*", "*.jsonl")],
13401
+ parse: async (file) => toDiscovered(await extractPiSessionMeta(file)),
13402
+ walk: async function* (opts = {}) {
13403
+ for await (const meta of walkPiSessions({ root: opts.root, sinceMtimeMs: opts.sinceMtimeMs })) {
13404
+ const d = toDiscovered(meta);
13405
+ if (d) yield d;
13406
+ }
13407
+ }
13408
+ };
13399
13409
  AGENT_TARGETS = [
13400
13410
  {
13401
13411
  id: "cursor",
@@ -13452,6 +13462,7 @@ var init_registry = __esm({
13452
13462
  detect: detectDir(home(".pi")),
13453
13463
  skillsDir: { global: home(".pi", "agent", "skills") },
13454
13464
  instructions: { files: [{ path: "AGENTS.md", renderer: "codexAgents" }] },
13465
+ sessions: piSessions,
13455
13466
  tier3: {
13456
13467
  kind: "pi-extension",
13457
13468
  source: "platforms/pi/extensions/syntaur",
@@ -27776,6 +27787,41 @@ function runRollup() {
27776
27787
  return { daysComputed, rowsWritten };
27777
27788
  }
27778
27789
 
27790
+ // src/usage/pricing.ts
27791
+ var PER_MILLION = 1e6;
27792
+ var MODEL_PRICING = {
27793
+ // Moonshot Kimi K2.6 — the model pi emits today. Official Moonshot list price.
27794
+ // source: https://platform.moonshot.ai/ (official) — cross-checked
27795
+ // https://openrouter.ai/moonshotai/kimi-k2.6 (retrieved 2026-06-17)
27796
+ "moonshotai/kimi-k2.6": { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0.95 },
27797
+ // Moonshot Kimi K2.5 — prior Kimi model. Official Moonshot list price.
27798
+ // source: https://platform.moonshot.ai/ — cross-checked
27799
+ // https://openrouter.ai/moonshotai/kimi-k2.5 (retrieved 2026-06-17)
27800
+ "moonshotai/kimi-k2.5": { input: 0.6, output: 3, cacheRead: 0.1, cacheWrite: 0.6 },
27801
+ // Z.ai (Zhipu) GLM-5.2 — official z.ai platform list price.
27802
+ // source: https://docs.z.ai/guides/overview/pricing — cross-checked
27803
+ // https://openrouter.ai/z-ai/glm-5 (retrieved 2026-06-18)
27804
+ "zai-org/glm-5.2": { input: 1.4, output: 4.4, cacheRead: 0.26, cacheWrite: 1.4 },
27805
+ // MiniMax M2.5 — official MiniMax platform list price. No separately-pinned
27806
+ // cached-read rate is published, so cacheRead is set conservatively to the
27807
+ // input rate (upper bound); revise if MiniMax publishes a cache rate.
27808
+ // source: https://platform.minimax.io/docs/guides/pricing-token-plan
27809
+ // — cross-checked https://openrouter.ai/minimax/minimax-m2.5 (retrieved 2026-06-18)
27810
+ "minimaxai/minimax-m2.5": { input: 0.15, output: 0.9, cacheRead: 0.15, cacheWrite: 0.15 }
27811
+ // NOTE: opaque Synthetic tier aliases like `syn:large:text` have no public
27812
+ // per-token rate (they route to whatever Synthetic assigns), so they remain
27813
+ // unpriced (→ $0). Reseller discounts (e.g. DeepInfra K2.6 0.75/3.50/0.15) are
27814
+ // rejected by the canonical-source rule and are NOT used here.
27815
+ };
27816
+ function normalizeModelKey(model) {
27817
+ return model.replace(/^\s*\[[^\]]*\]\s*/, "").replace(/^hf:/i, "").trim().toLowerCase();
27818
+ }
27819
+ function priceForModel(model, tokens) {
27820
+ const rate = MODEL_PRICING[normalizeModelKey(model)];
27821
+ if (!rate) return null;
27822
+ return (tokens.inputTokens * rate.input + tokens.outputTokens * rate.output + tokens.cacheReadTokens * rate.cacheRead + tokens.cacheCreationTokens * rate.cacheWrite) / PER_MILLION;
27823
+ }
27824
+
27779
27825
  // src/usage/collect.ts
27780
27826
  var THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1e3;
27781
27827
  function formatDayFromCcusageDate(yyyymmdd) {
@@ -27809,6 +27855,12 @@ async function collectAndPersist() {
27809
27855
  cwd,
27810
27856
  eventTs: row.eventTs
27811
27857
  });
27858
+ const totalCost = row.totalCost > 0 ? row.totalCost : priceForModel(row.model, {
27859
+ inputTokens: row.inputTokens,
27860
+ outputTokens: row.outputTokens,
27861
+ cacheCreationTokens: row.cacheCreationTokens,
27862
+ cacheReadTokens: row.cacheReadTokens
27863
+ }) ?? 0;
27812
27864
  return {
27813
27865
  sessionId: row.sessionId,
27814
27866
  model: row.model,
@@ -27819,7 +27871,7 @@ async function collectAndPersist() {
27819
27871
  cacheCreationTokens: row.cacheCreationTokens,
27820
27872
  cacheReadTokens: row.cacheReadTokens,
27821
27873
  totalTokens: row.totalTokens,
27822
- totalCost: row.totalCost,
27874
+ totalCost,
27823
27875
  cwd,
27824
27876
  projectSlug: attr.projectSlug ?? "",
27825
27877
  assignmentSlug: attr.assignmentSlug ?? "",
@@ -27836,8 +27888,72 @@ async function collectAndPersist() {
27836
27888
  tx.immediate();
27837
27889
  return { isFirstRun, rowsIngested: enriched.length };
27838
27890
  }
27891
+ function backfillZeroCostEvents() {
27892
+ const db6 = getUsageDb();
27893
+ const select2 = db6.prepare(
27894
+ `SELECT session_id, model, input_tokens, output_tokens,
27895
+ cache_creation_tokens, cache_read_tokens
27896
+ FROM usage_events
27897
+ WHERE total_cost = 0`
27898
+ );
27899
+ const update = db6.prepare(
27900
+ `UPDATE usage_events SET total_cost = @cost, updated_at = @updatedAt
27901
+ WHERE session_id = @sessionId AND model = @model AND total_cost = 0`
27902
+ );
27903
+ let updated = 0;
27904
+ const tx = db6.transaction(() => {
27905
+ const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
27906
+ for (const r of select2.all()) {
27907
+ const cost = priceForModel(r.model, {
27908
+ inputTokens: r.input_tokens,
27909
+ outputTokens: r.output_tokens,
27910
+ cacheCreationTokens: r.cache_creation_tokens,
27911
+ cacheReadTokens: r.cache_read_tokens
27912
+ });
27913
+ if (cost !== null && cost > 0) {
27914
+ updated += update.run({ cost, updatedAt, sessionId: r.session_id, model: r.model }).changes;
27915
+ }
27916
+ }
27917
+ });
27918
+ tx.immediate();
27919
+ return updated;
27920
+ }
27921
+ function reattributeOrphanEvents() {
27922
+ const db6 = getUsageDb();
27923
+ const select2 = db6.prepare(
27924
+ `SELECT session_id, model, cwd, event_ts
27925
+ FROM usage_events
27926
+ WHERE project_slug = '' AND assignment_slug = ''`
27927
+ );
27928
+ const update = db6.prepare(
27929
+ `UPDATE usage_events
27930
+ SET project_slug = @projectSlug, assignment_slug = @assignmentSlug, updated_at = @updatedAt
27931
+ WHERE session_id = @sessionId AND model = @model
27932
+ AND project_slug = '' AND assignment_slug = ''`
27933
+ );
27934
+ let updated = 0;
27935
+ const tx = db6.transaction(() => {
27936
+ const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
27937
+ for (const r of select2.all()) {
27938
+ const attr = resolveAttribution({
27939
+ sessionId: r.session_id,
27940
+ cwd: r.cwd,
27941
+ eventTs: r.event_ts
27942
+ });
27943
+ const projectSlug = attr.projectSlug ?? "";
27944
+ const assignmentSlug = attr.assignmentSlug ?? "";
27945
+ if (projectSlug !== "" || assignmentSlug !== "") {
27946
+ updated += update.run({ projectSlug, assignmentSlug, updatedAt, sessionId: r.session_id, model: r.model }).changes;
27947
+ }
27948
+ }
27949
+ });
27950
+ tx.immediate();
27951
+ return updated;
27952
+ }
27839
27953
  async function collectUsage() {
27840
27954
  const info = await collectAndPersist();
27955
+ backfillZeroCostEvents();
27956
+ reattributeOrphanEvents();
27841
27957
  runRollup();
27842
27958
  advanceMetaIso("usage_collector_heartbeat", (/* @__PURE__ */ new Date()).toISOString());
27843
27959
  return info;