codebee 0.1.69 → 0.1.70

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.
Files changed (57) hide show
  1. package/CHANGELOG.md +37 -0
  2. package/README.md +4 -3
  3. package/app/browser-final-1440.png +0 -0
  4. package/app/browser-final-390.png +0 -0
  5. package/app/browser-google-fallback.png +0 -0
  6. package/app/browser-google-test.png +0 -0
  7. package/app/browser-workbench-1440.png +0 -0
  8. package/app/browser-workbench-390.png +0 -0
  9. package/app/browser-workspace-google.png +0 -0
  10. package/app/browser-workspace-smoke.png +0 -0
  11. package/app/browser-workspace.png +0 -0
  12. package/app/core/audit.py +30 -0
  13. package/app/core/automation.py +107 -12
  14. package/app/core/benchstore.py +95 -0
  15. package/app/core/bookmeta.py +9 -4
  16. package/app/core/builtin_agent.py +472 -33
  17. package/app/core/catalog.py +7 -1
  18. package/app/core/dispatch.py +20 -3
  19. package/app/core/error_codes.py +11 -2
  20. package/app/core/evalbench.py +720 -0
  21. package/app/core/flows.py +228 -3
  22. package/app/core/jobs.py +22 -1
  23. package/app/core/manager.py +21 -0
  24. package/app/core/market_remote.py +10 -0
  25. package/app/core/mcp_client.py +287 -0
  26. package/app/core/modelhub.py +185 -2
  27. package/app/core/notify.py +118 -23
  28. package/app/core/novel_quality.py +189 -0
  29. package/app/core/paths.py +4 -0
  30. package/app/core/pipeline.py +426 -28
  31. package/app/core/planner.py +243 -22
  32. package/app/core/plugins.py +525 -0
  33. package/app/core/publish/browser.py +129 -13
  34. package/app/core/publish/fanqie.py +6 -0
  35. package/app/core/publish/flow.py +154 -5
  36. package/app/core/publish/flows-fanqie-calibrated.json +11 -7
  37. package/app/core/publish/ledger.py +29 -3
  38. package/app/core/publish/manager.py +134 -2
  39. package/app/core/publish/qimao.py +5 -0
  40. package/app/core/remotesync.py +121 -0
  41. package/app/core/runner.py +80 -5
  42. package/app/core/settings.py +39 -2
  43. package/app/core/settings_schema.py +8 -0
  44. package/app/core/store.py +30 -8
  45. package/app/core/usage.py +187 -14
  46. package/app/core/zentao.py +153 -4
  47. package/app/current-browser.png +0 -0
  48. package/app/main.py +279 -15
  49. package/app/mcp_server.py +175 -0
  50. package/app/pet.py +82 -21
  51. package/app/plugins/code-review-helper/.codex-plugin/plugin.json +18 -0
  52. package/app/plugins/code-review-helper/skills/review.md +16 -0
  53. package/app/ui/app.js +1380 -73
  54. package/app/ui/i18n.js +248 -6
  55. package/app/ui/index.html +277 -13
  56. package/app/ui/style.css +786 -0
  57. package/package.json +2 -1
@@ -9,6 +9,7 @@ from __future__ import annotations
9
9
 
10
10
  import copy
11
11
  import json
12
+ import os
12
13
  import re
13
14
  import sys
14
15
  import threading
@@ -430,7 +431,12 @@ def load(force=False):
430
431
  entries = json.loads(paths.CATALOG_FILE.read_text(encoding="utf-8"))
431
432
  except Exception:
432
433
  entries = copy.deepcopy(DEFAULT_CATALOG)
433
- _merge_new_defaults(entries)
434
+ # TUTTI_TEST_NO_DEFAULT_CATALOG:e2e 测试隔离开关——种盘的 catalog.json
435
+ # 就是全部条目。默认合并会把真实 CLI 条目带进测试服务,一键升级这类
436
+ # 「遍历全 catalog」的接口会把真机的 npm/winget 升级真跑一遍(2026-09-26
437
+ # e2e_upgrade_all 实弹案:codex 被真升)。
438
+ if not os.environ.get("TUTTI_TEST_NO_DEFAULT_CATALOG"):
439
+ _merge_new_defaults(entries)
434
440
  _apply_resume_patch(entries)
435
441
  _apply_launch_patch(entries)
436
442
  _apply_config_patch(entries)
@@ -119,6 +119,20 @@ def _online_model_bonus(entry, task_type, role):
119
119
  return 0.0, ""
120
120
 
121
121
 
122
+ def _bench_bonus(entry):
123
+ """评测基准台实测分软信号(promptfoo 式样题榜单;14 天新鲜度,过期记 0)。
124
+
125
+ 与在线信号同理念:软加减分,硬约束(健康/冷却/协议)仍由调用方负责;
126
+ 无数据不猜分——没上过评测台的候选保持原排序。
127
+ """
128
+ try:
129
+ from . import benchstore
130
+ return benchstore.bonus_for(entry.get("provider_id") or "",
131
+ entry.get("model") or "")
132
+ except Exception:
133
+ return 0.0, ""
134
+
135
+
122
136
  def score_model_entry(entry, providers, pricing, difficulty, task_type="", role=""):
123
137
  """给已通过硬约束的模型链条目评分,返回 (score, explanation)。"""
124
138
  provider = (providers or {}).get(entry.get("provider_id")) \
@@ -146,11 +160,14 @@ def score_model_entry(entry, providers, pricing, difficulty, task_type="", role=
146
160
  if dim == "vision":
147
161
  vision_score = 24.0 if meta.get("image_in") else -24.0
148
162
  online_score, online_reason = _online_model_bonus(entry, task_type, role)
149
- total = quality + tier_score + price_score + strength_score + vision_score + online_score
150
- reason = ("质量 %+.1f,档位 %s %+.1f,%s,能力 %s %+.1f%s%s"
163
+ bench_score, bench_reason = _bench_bonus(entry)
164
+ total = (quality + tier_score + price_score + strength_score + vision_score
165
+ + online_score + bench_score)
166
+ reason = ("质量 %+.1f,档位 %s %+.1f,%s,能力 %s %+.1f%s%s%s%s"
151
167
  % (quality, tier, tier_score, price_reason, dim,
152
168
  strength_score + vision_score,
153
- "," if online_reason else "", online_reason))
169
+ "," if online_reason else "", online_reason,
170
+ "," if bench_reason else "", bench_reason))
154
171
  return round(total, 2), reason
155
172
 
156
173
 
@@ -55,6 +55,9 @@ FATAL_CODES = frozenset({
55
55
  _MISSING_CREDENTIAL = (
56
56
  "no api key", "missing api key", "api key not found", "api key is required",
57
57
  "missing environment variable", "missing env var",
58
+ # claude CLI 登录闸门:无 OAuth/Key 时 -p 模式只吐一行提示即退出(exit 0/1
59
+ # 都见过),不产生 result 事件——绑定链 env 未注入或本机未登录时必现
60
+ "not logged in", "please run /login",
58
61
  )
59
62
  _AUTH = (
60
63
  "invalid api key", "invalid_api_key", "api key is invalid", "incorrect api key",
@@ -64,13 +67,19 @@ _AUTH = (
64
67
  "status code 401",
65
68
  )
66
69
  _FORBIDDEN = ("forbidden", "request not allowed", "permission denied", "access denied")
70
+ # 「request rejected」是智谱网关 429 的固定措辞(Request rejected (429)):
71
+ # 裸 (429) 不带 http/status-code 前缀,正则分支匹配不到,只能靠词面
72
+ # (2026-09-27 七天上限案:分类不出 → 换将闸门当终态收工,备用 KEY 永不上场)
67
73
  _RATE_LIMIT = ("rate limit", "rate_limit", "too many requests", "http 429", "status code 429",
74
+ "request rejected",
68
75
  "concurrent limit", "concurrency limit", "too many concurrent",
69
76
  "并发限制", "并发超限", "限流")
70
77
  _QUOTA = ("insufficient balance", "insufficient quota", "insufficient credit",
71
78
  "quota", "balance is insufficient", "credit balance", "billing", "arrears",
72
79
  "payment required", "http 402", "status code 402", "欠费", "余额", "额度",
73
- "usage limit", "limit exceeded", "quota exhausted")
80
+ "usage limit", "limit exceeded", "quota exhausted",
81
+ # 周期性用量上限(七天/五小时窗口):部分上游文案不带 429 字样
82
+ "使用上限", "用量上限")
74
83
  _SERVER = ("unexpected server error", "internal server error", "server error",
75
84
  "overloaded", "temporarily", "unavailable", "service unavailable",
76
85
  "internal error", "no available channel", "unknown model")
@@ -180,7 +189,7 @@ _SAFE_ERROR_SUMMARIES = {
180
189
  ErrorCode.EMPTY: "模型未返回内容",
181
190
  ErrorCode.NETWORK: "网络连接或数据流中断",
182
191
  ErrorCode.UPSTREAM_SERVER: "上游服务端异常",
183
- ErrorCode.MISSING_CREDENTIAL: "所选路由未找到可用 API 凭据",
192
+ ErrorCode.MISSING_CREDENTIAL: "未找到可用凭据(CLI 未登录或未配置 API Key)",
184
193
  ErrorCode.AUTH: "API 凭据认证失败",
185
194
  ErrorCode.FORBIDDEN: "上游拒绝账号、模型或请求权限",
186
195
  ErrorCode.QUOTA: "上游余额或调用额度不足",