sigrank 0.0.192 → 0.0.193

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/README.md CHANGED
@@ -339,7 +339,7 @@ All adapters are token-only (no message content, no cost fields, no credentials)
339
339
  | ------------------ | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
340
340
  | Claude Code | ✅ `~/.claude/projects` (recursive, incl. `subagents/`) | Native 4-pillar; dedup by `(session_id, message_id)` — final snapshot wins |
341
341
  | Codex | ✅ `~/.codex/sessions` (+ `archived_sessions`) | `input_tokens` incl. cached → `input` + `cacheCreate` split window-level via `io_ratio`; `cacheRead` native (`cached_input_tokens`); `reasoning_output`→output; verified vs ccusage (~1%) |
342
- | Devin CLI | ✅ `~/.local/share/devin/cli/sessions.db` | SQLite; same `io_ratio` split as Codex (Alpha 2.0 default); `cacheRead` native |
342
+ | Devin CLI | ✅ `~/.local/share/devin/cli/sessions.db` | SQLite; native 4-pillar from `metadata.metrics` (`input_tokens`, `output_tokens`, `cache_read_tokens`, `cache_creation_tokens`); `input_tokens` is fresh (excludes cache) |
343
343
  | Amp | ✅ `~/.local/share/amp/threads` | Native 4-pillar; per-message |
344
344
  | Kimi | ✅ `~/.kimi/sessions` | Native 4-pillar; `StatusUpdate` lines only |
345
345
  | pi-agent | ✅ `~/.pi/agent/sessions` | Native 4-pillar; per-message JSONL |
@@ -744,16 +744,15 @@ export const hermesAdapter = {
744
744
 
745
745
  // ── 14. Devin CLI ────────────────────────────────────────────────────────────
746
746
  // SQLite: ~/.local/share/devin/cli/sessions.db
747
- // Same combined-input problem as Codex: input_tokens INCLUDES cache write, so we
748
- // yield { ts, output, cacheRead, uncached } and let tokenpullCodex() do the
749
- // ioRatio split (input = output × ioRatio, cacheCreate = uncached − input).
750
- // ioRatio comes from Claude (Beta = operator's Claude input/output ratio) or
751
- // the Alpha 2.0 default (matches Codex; the "7:1:2 average → 0.5" note in a
752
- // prior revision was wrong — tokenpullAny defaults ioRatio to 2.0 for both).
747
+ // Native 4-pillar: metrics.input_tokens is FRESH input (does NOT include cache
748
+ // read or cache creation — verified against live data where input=3 alongside
749
+ // cache_creation_tokens=23500). cache_read_tokens and cache_creation_tokens are
750
+ // separate fields (nullable → treat null as 0). output_tokens includes any
751
+ // reasoning tokens (no separate reasoning field in metrics). No estimation needed.
753
752
  export const devinAdapter = {
754
753
  platform: "devin",
755
754
  defaultRoot: () => join(homedir(), ".local", "share", "devin", "cli"),
756
- async *records(root) {
755
+ async *messages(root) {
757
756
  for (const r of roots("DEVIN_HOME", root)) {
758
757
  const dbPath = join(r, "sessions.db");
759
758
  const rows = await sqliteJson(
@@ -762,6 +761,7 @@ export const devinAdapter = {
762
761
  json_extract(chat_message, '$.metadata.metrics.input_tokens') as input_tokens,
763
762
  json_extract(chat_message, '$.metadata.metrics.output_tokens') as output_tokens,
764
763
  json_extract(chat_message, '$.metadata.metrics.cache_read_tokens') as cache_read_tokens,
764
+ json_extract(chat_message, '$.metadata.metrics.cache_creation_tokens') as cache_creation_tokens,
765
765
  json_extract(chat_message, '$.metadata.created_at') as created_at
766
766
  FROM message_nodes
767
767
  WHERE json_extract(chat_message, '$.role') = 'assistant'
@@ -770,15 +770,19 @@ export const devinAdapter = {
770
770
  60_000,
771
771
  );
772
772
  for (const row of rows) {
773
- const inputIncl = Number(row.input_tokens || 0);
774
- const cached = Number(row.cache_read_tokens || 0);
773
+ const input = Number(row.input_tokens || 0);
775
774
  const output = Number(row.output_tokens || 0);
776
- if (inputIncl + output + cached === 0) continue;
775
+ const cacheRead = Number(row.cache_read_tokens || 0);
776
+ const cacheCreate = Number(row.cache_creation_tokens || 0);
777
+ if (input + output + cacheRead + cacheCreate === 0) continue;
777
778
  yield {
779
+ id: `devin:${row.row_id}`,
780
+ sid: row.session_id || null,
778
781
  ts: row.created_at || null,
782
+ input,
779
783
  output,
780
- cacheRead: cached,
781
- uncached: Math.max(0, inputIncl - cached),
784
+ cacheCreate,
785
+ cacheRead,
782
786
  file: dbPath,
783
787
  };
784
788
  }
@@ -359,9 +359,12 @@ export async function tokenpullCodex({
359
359
  export async function tokenpullAny(platform, opts = {}) {
360
360
  if (!platform || platform === "claude")
361
361
  return tokenpull({ adapter: claudeAdapter, ...opts });
362
- // Codex + Devin: both combine input + cache write in input_tokens, so both go
363
- // through tokenpullCodex() which splits via ioRatio (Beta from Claude, Alpha 2.0).
364
- if (platform === "codex" || platform === "devin") {
362
+ // Codex: input_tokens includes cache write, so it goes through tokenpullCodex()
363
+ // which splits via ioRatio (Beta from Claude, Alpha 2.0). Devin was previously
364
+ // routed here too, but its metrics object carries native cache_creation_tokens
365
+ // and cache_read_tokens as separate fields with input_tokens as fresh input —
366
+ // no estimation needed. Devin now goes through the standard tokenpull() path.
367
+ if (platform === "codex") {
365
368
  let ioRatio = opts.ioRatio || 2.0;
366
369
  if (!opts.ioRatio) {
367
370
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sigrank",
3
- "version": "0.0.192",
3
+ "version": "0.0.193",
4
4
  "author": "SunrisesIllNeverSee (https://github.com/SunrisesIllNeverSee)",
5
5
  "description": "SigRank MCP server — the yield cascade + live leaderboard as MCP tools any agent can call",
6
6
  "mcpName": "io.github.SunrisesIllNeverSee/sigrank-mcp",