Commit History
-
fleet: per-space README (pp02) Running
6e50bb3 -
feat+fix: token 用量计数器(对账体系) + 修复重复 /health 装饰器
- TokenPool.usage_in/out: prompt/completion tokens 累计计数器 —— 空间是唯一 寿命 ≥ 流的观测者(2026-10-02 hub 长流 usage 被 Workers 掐死事故的教训), 这是 hub 侧抓取的完整兜底; 重启清零, hub 用快照差值取窗口量 - 流式路径: 原始块 O(1) 入 64KB 尾部窗, 流结束只解析结尾 usage 块(SSE 结尾 统计块, stream_options.include_usage 已开); 提取失败静默, 不影响转发 - 非流式路径: 聚合已有 usage 顺手累计 - stats()/stats_lite() 自报块新增 usage.prompt_tokens_total / completion_tokens_total(hub keeper 快照顺带落库) - 修复: 上次编辑事故残留的重复 @app.get('/health') 装饰器 —— FastAPI 按 注册顺序命中首个只有 docstring 的定义, /health 实际返回 null(线上已实证), hub 健康捷径静默失效回退全量拉取、ready 字段恒空; 已部署版本即带此 buga49e358
-
fix: /health 也自报 models(标准块), hub 保活快照捷径不再丢目录
8a9f39d -
feat: 标准自报块 — load.saturation(忙工人页占比) + models 目录自报(/api/stats); /health 带 load
085d867 -
feat: factory_mode 三模式(intercept/mock/real) — 空壳工厂页, 签发与目标站页面解耦
经 hf_reco/poc_mock_factory.py 三臂对照实验验证(真实页/host映射/route拦截 均签发+消费 200): - intercept(默认): route 拦截, 空壳页纯内存承载, 零基础设施, 不访问目标站 - mock: host-resolver-rules 域名映射 + 容器内本地 HTTPS 空壳页(自签证书), 不经 CDP 拦截层 - real: 真实工厂页(旧行为, 保底); 三模式均可在面板热切, mock<->其他自动回收浏览器重建 - 本地全链路冒烟: intercept/mock 两模式签发+消费 200 通过 - requirements: +cryptography==50.0.1(mock 模式自签证书用)8088875
-
deploy: update
27699df -
deploy: update
0231737
-
fix: 非流式聚合透传 tool_calls(function calling) 与真实 finish_reason
c8230e5 -
stats: /api/stats 增加 probe 可路由探测缓存信息与 denied_detail(带剩余TTL), 供 CF 集中面板展示; denied 原字段形状不变(兼容自身面板)
7cf850b
-
feat: admin console gated behind ?ui=1 (low-cost obscurity)
35222b8 -
fix(api): config PUT response no longer double-reports worker_pages/factory_page as skipped
fbf85cb -
feat: single-key console, hot-switchable worker/factory pages, neutral branding
46a8483
-
config: switch factory page Kimi-K3 -> gemma-4-26B-A4B-it
Tokens are universal across routable models, so the factory page only determines where Turnstile executions happen. gemma-4-26B-A4B-it is the smallest (4B active) and least-contended entry in the current routable set; this keeps signing pressure off hot models (Kimi-K3 got per-model rate-limited under dense signing).1481207 -
feat(security): no public info surface — data only behind /admin credentials
- root path now serves a data-free placeholder pointing at /admin - remove unauthenticated /api/public/status endpoint and admin_status.html - disable FastAPI /docs, /redoc, /openapi.json - Dockerfile: drop admin_status.html from COPY3ab7d3d -
fix(admin): serve /admin page skeleton without Bearer header
The console page carries no data itself; read/write APIs remain independently authenticated (check_key / check_admin), so the page-level header check only broke direct browser access. Route still 404s when the admin surface is disabled.7e2c6c8 -
config: restore deployed defaults WORKER_PAGES=3 SHELF_SIZE=30
These were the tuned production defaults in the previous deployed config.py; keep them as the in-repo defaults (with ADAPTIVE_SHELF on, SHELF_SIZE now acts as a peak cap, not a always-on stock level).5281872 -
feat(pool): self-healing hardening — adaptive shelf, worker health recycle, browser recycle, error visibility, rate limit
- fix: _wake() passed non-coroutine to create_task and called notify_all without the condition lock -> PUT /api/config 500 on token_max_age / idle_pause hot edits. Now wraps a proper coroutine holding the lock. - pool.last_error: most recent pool-level failure (worker start failure, sign-failure recycle, supervisor cycle, browser recycle) is exposed via /api/stats, /api/public/status and the read-only status page. - worker health: consecutive sign failures >= 5 recycles the page; keeper rebuilds it. Browser context missing -> keeper relaunches everything. - adaptive shelf: stock target = QPS(5min window) x avg sign latency + 1, capped by SHELF_SIZE; idles down instead of burning Turnstile at a fixed large level (ADAPTIVE_SHELF env, default on). - periodic browser recycle after BROWSER_MAX_AGE (default 12h) during idle windows; shelf tokens survive since they are plain strings. - probe results cached to probe_cache.json (PROBE_CACHE_TTL, default 6h). - ISSUE_TIMEOUT env …2d8e7b4 -
fix(pool): worker keeper auto-rescale + scale lock, defer probe until workers up
- keeper loop: retry scale-up every 30s when alive workers < desired (fixes 'ready=true but 0 workers' zombie state after a one-shot worker-page start failure at cold boot; previously only a manual /api/pool/scale call or restart could recover) - _apply_scale guarded by asyncio.Lock (keeper vs API race) - start background routable probe only after worker pages are up, avoiding the ~185-page scan racing the first factory page load802422f
-
Update config.py
Verified signaturea5ddd9d -
Update Dockerfile
Verified signature838c8b9 -
Upload README.md
Verified signatureb01af35 -
Delete .gitattributes
Verified signature380f3e9 -
Upload 8 files
Verified signaturef4541b6 -
Delete app.py
Verified signaturec06da0c -
Delete README.md
Verified signature340ba99
-
Update app.py
Verified signature79fc65b -
Create Dockerfile
Verified signature7921239 -
Update app.py
Verified signaturedeec013 -
Upload 2 files
Verified signature7ca7fc2 -
initial commit
Verified signaturee46b0e4