@seanyao/roll 2.603.1 → 2.604.2

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.
@@ -9,14 +9,8 @@
9
9
  "prices": {
10
10
  "claude-opus-4-7": {"in": 5.00, "out": 25.00, "cache_create": 6.25, "cache_read": 0.50},
11
11
  "claude-opus-4-6": {"in": 5.00, "out": 25.00, "cache_create": 6.25, "cache_read": 0.50},
12
- "claude-opus-4-5": {"in": 5.00, "out": 25.00, "cache_create": 6.25, "cache_read": 0.50},
13
- "claude-opus-4-1": {"in": 15.00, "out": 75.00, "cache_create": 18.75, "cache_read": 1.50},
14
- "claude-opus-4": {"in": 15.00, "out": 75.00, "cache_create": 18.75, "cache_read": 1.50},
15
12
  "claude-sonnet-4-6": {"in": 3.00, "out": 15.00, "cache_create": 3.75, "cache_read": 0.30},
16
13
  "claude-sonnet-4-5": {"in": 3.00, "out": 15.00, "cache_create": 3.75, "cache_read": 0.30},
17
- "claude-sonnet-4": {"in": 3.00, "out": 15.00, "cache_create": 3.75, "cache_read": 0.30},
18
- "claude-haiku-4-5": {"in": 1.00, "out": 5.00, "cache_create": 1.25, "cache_read": 0.10},
19
- "claude-haiku-3-5": {"in": 0.80, "out": 4.00, "cache_create": 1.00, "cache_read": 0.08},
20
- "claude-3-5-sonnet": {"in": 3.00, "out": 15.00, "cache_create": 3.75, "cache_read": 0.30}
14
+ "claude-haiku-4-5": {"in": 1.00, "out": 5.00, "cache_create": 1.25, "cache_read": 0.10}
21
15
  }
22
16
  }
@@ -7,8 +7,6 @@
7
7
  "default_model": "deepseek-chat",
8
8
  "notes": "Rates per million tokens in CNY (¥) — DeepSeek's native billing currency; we never convert to USD (the dashboard already shows the currency symbol). deepseek-chat and deepseek-reasoner are both deepseek-v4-flash with different thinking modes — same pricing. deepseek-v4-pro is priced at in 3 / out 6 — the earlier 2.5折 launch promo became permanent (confirmed 2026-06-02 against the official page), so these are the standing rates, not a temporary discount. cache_read is the official cache-hit input price (reduced to 1/10 of launch price since 2026-04-26). cache_create = cache-miss input rate: DeepSeek levies no separate cache-write surcharge, and pi reports cacheWrite cost as 0, so this rate only ever applies to (near-zero) cacheWrite tokens. pi's own per-message cost.total is computed in USD and is kept as cost_reported_usd for audit, NOT used for the authoritative cost.",
9
9
  "prices": {
10
- "deepseek-chat": {"in": 1, "out": 2, "cache_create": 1, "cache_read": 0.02},
11
- "deepseek-reasoner": {"in": 1, "out": 2, "cache_create": 1, "cache_read": 0.02},
12
10
  "deepseek-v4-flash": {"in": 1, "out": 2, "cache_create": 1, "cache_read": 0.02},
13
11
  "deepseek-v4-pro": {"in": 3, "out": 6, "cache_create": 3, "cache_read": 0.025}
14
12
  }
@@ -7,7 +7,6 @@
7
7
  "default_model": "kimi-k2.6",
8
8
  "notes": "Rates per million tokens (CNY), verified 2026-06-02 against the official Kimi platform pricing pages (pricing/chat-k25 + pricing/chat-k26). Corrects the 2026-05-23 snapshot, which had copied the original-K2 rate (1/4) onto EVERY kimi model — real K2.5 is 4/21, K2.6 is 6.5/27, so the current models' cost was under-reported ~5-7x on output. Field convention: `in` = standard (cache-miss) input price; `cache_read` = cache-hit input price; `cache_create` = cache-miss input rate (Kimi documents no separate cache-write surcharge, mirroring DeepSeek). kimi-for-coding is the kimi-code CLI's model id; the CLI config pins it to K2.6 (display_name Kimi-k2.6, default_thinking=true, base_url api.kimi.com/coding/v1), so it is priced at K2.6 rates. NOTE: kimi-code is a coding *subscription*; these per-token rates are the published K2.6 API rates used as a usage-cost estimate, not the flat subscription fee. kimi-k2 is the prior-gen original K2, retained at its launch rate (1/4) for currency resolution of legacy name variants; it is no longer on the public pricing page and is not actually billed — only kimi-for-coding (K2.6) is.",
9
9
  "prices": {
10
- "kimi-k2": {"in": 1.00, "out": 4.00, "cache_create": 1.00, "cache_read": 0.25},
11
10
  "kimi-k2.5": {"in": 4.00, "out": 21.00, "cache_create": 4.00, "cache_read": 0.70},
12
11
  "kimi-k2.6": {"in": 6.50, "out": 27.00, "cache_create": 6.50, "cache_read": 1.10},
13
12
  "kimi-for-coding": {"in": 6.50, "out": 27.00, "cache_create": 6.50, "cache_read": 1.10}
@@ -162,12 +162,6 @@ def _parse_deepseek_html(html: str) -> Dict[str, Dict[str, float]]:
162
162
  if not prices:
163
163
  raise ParseError('no price rows found in HTML; page layout may have changed')
164
164
 
165
- # Aliases: deepseek-chat and deepseek-reasoner both map to v4-flash.
166
- if 'deepseek-v4-flash' in prices:
167
- flash = prices['deepseek-v4-flash']
168
- prices['deepseek-chat'] = dict(flash)
169
- prices['deepseek-reasoner'] = dict(flash)
170
-
171
165
  return prices
172
166
 
173
167
 
@@ -212,13 +206,6 @@ def _parse_kimi_html(html: str) -> Dict[str, Dict[str, float]]:
212
206
  if prices:
213
207
  if "kimi-k2.6" in prices:
214
208
  prices["kimi-for-coding"] = dict(prices["kimi-k2.6"])
215
- if "kimi-k2" not in prices:
216
- prices["kimi-k2"] = {
217
- "in": 1.00,
218
- "out": 4.00,
219
- "cache_create": 1.00,
220
- "cache_read": 0.25,
221
- }
222
209
  return prices
223
210
 
224
211
  sub_urls = [
@@ -238,13 +225,7 @@ def _parse_kimi_html(html: str) -> Dict[str, Dict[str, float]]:
238
225
 
239
226
  if "kimi-k2.6" in prices:
240
227
  prices["kimi-for-coding"] = dict(prices["kimi-k2.6"])
241
- if "kimi-k2" not in prices:
242
- prices["kimi-k2"] = {
243
- "in": 1.00,
244
- "out": 4.00,
245
- "cache_create": 1.00,
246
- "cache_read": 0.25,
247
- }
228
+
248
229
  return prices
249
230
 
250
231
 
@@ -668,6 +668,12 @@ def load_runs(slug: str) -> Dict[str, Dict[str, Any]]:
668
668
  r = json.loads(line)
669
669
  except Exception:
670
670
  continue
671
+ # FIX-193: a stray line can parse as a bare JSON scalar (e.g. an
672
+ # agent pretty-printed a record across lines and `"FIX-181"` parses
673
+ # as a str) — r.get() then crashes the whole dashboard. Records
674
+ # must be objects; skip anything else.
675
+ if not isinstance(r, dict):
676
+ continue
671
677
  p = r.get("project", "")
672
678
  if p != slug and p != base and not p.startswith(f"{slug}-cycle-"):
673
679
  # String match failed — try path match for old-slug salvage.
@@ -737,7 +743,7 @@ def merge_runs_into_cycles(cycles: List[Dict[str, Any]], runs: Dict[str, Dict[st
737
743
  # Outcome: runs.jsonl wins when events stream was vacuous or
738
744
  # misleading (idle/failed emitted by _loop_event even though the
739
745
  # agent completed work and _runs_append recorded built).
740
- if cy.get("outcome") in ("unknown", "running", "idle", "failed") and r.get("status"):
746
+ if cy.get("outcome") in ("unknown", "running", "idle", "failed", "orphan") and r.get("status"):
741
747
  cy["outcome"] = {"built": "done", "interrupted": "fail"}.get(r["status"], r["status"])
742
748
  if not cy.get("story") and r["built"]:
743
749
  cy["story"] = r["built"][0]
@@ -1186,15 +1192,17 @@ def render(events, cron, state, backlog, *, days=3, lang="both", now=None,
1186
1192
  # would duplicate signal without adding info.
1187
1193
  print(eb_zh)
1188
1194
 
1189
- # US-LOOP-036: daily service (dream/brief) next-fire lines, read straight
1190
- # from the launchd plist so they reflect the latest `roll config <svc>-time`
1191
- # reload rather than a stale yaml-derived guess.
1192
- for _svc in ("dream", "brief"):
1195
+ # US-LOOP-036: daily service (dream) next-fire line, read straight from the
1196
+ # launchd plist so it reflects the latest `roll config dream-time` reload
1197
+ # rather than a stale yaml-derived guess.
1198
+ # FIX-194/FIX-195: brief loop retired — dream is the only daily service.
1199
+ for _svc in ("dream",):
1193
1200
  _sl = _daily_schedule_line(_svc, now=now)
1194
1201
  if _sl:
1195
1202
  print(" " + c("dim", _sl))
1196
- # FIX-151: dedicated loop (pr/ci/alert) last-tick age
1197
- for _loop in ("pr", "ci", "alert"):
1203
+ # FIX-151: dedicated loop last-tick age.
1204
+ # FIX-194: ci/alert loops retired — pr is the only dedicated loop tick.
1205
+ for _loop in ("pr",):
1198
1206
  _tl = _tick_age_line(_loop, now=now)
1199
1207
  if _tl:
1200
1208
  print(" " + c("dim", _tl))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@seanyao/roll",
3
- "version": "2.603.1",
3
+ "version": "2.604.2",
4
4
  "description": "Roll — Roll out features with AI agents",
5
5
  "scripts": {
6
6
  "test": "bash tests/run.sh"