33 Commits
Author SHA1 Message Date
nyoung 5c0596e73e Revise README content and formatting
Updated the README to improve formatting and clarity.
2026-10-09 23:03:01 +08:00
nyoung f87a051d51 Update README with new section on service details
Added a section in Chinese discussing the service and its features.
2026-10-09 23:02:19 +08:00
nyoung 7f7ab190aa fix(openai): 解析/截断/续写兼容 DeepSeek DSML 工具调用方言;bump 0.6.5 2026-10-09 09:45:30 +08:00
nyoungo fed260559c feat(admin): 登录改用 bcrypt 并对失败登录限速;bump 0.6.4
- 管理台密码改为 bcrypt 校验(已配置的 bcrypt 值直接使用,明文先 SHA-256 再哈希,避开 72 字节上限并保持常数时间比较)
- 同一客户端 5 次失败登录锁定 5 分钟,429 响应带 Retry-After;成功登录清零
- 版本号提升到 0.6.4(Makefile / internal/admin.Version)
2026-10-09 00:50:36 +08:00
nyoungo c877c1bf8c fix(upstream): 额度耗尽立即轮换访客身份并识别 de/es/fr 额度文案
- 命中额度错误当场调用 RotateGuest(复用既有实现),不再等退避、也不再依赖 auto_refresh;后续路由与下一次请求直接用新访客身份
- quota_notice 信封(type=quota_notice / notice 对象)在通用 error 门之前判定,无 error 字段的额度通知不再被当成静默 delta
- 额度文案按站点语言识别:de guthaben/aufgebraucht、es agotado、fr épuisé/consomm、en quota/exhausted,并下钻 data/notice/quota_notice 嵌套字段
- cache message 失败与非 2xx 响应体也按同样规则归类,额度问题会走轮换与跨站 failover 而不是普通错误
2026-10-09 00:50:18 +08:00
nyoungo 86492460b0 feat: 工具调用解析、Responses 状态缓存、幂等重放与模型别名
- 重写工具调用解析:XML、DSML 未加引号键、fence 内跳过、参数外溢等形状,并按请求携带的 tools 过滤工具名
- 新增 GET /v1/responses/{id} 与 previous_response_id 有界状态缓存(进程内、TTL、store=false 不写入)
- /v1/chat/completions 支持 Idempotency-Key 幂等回放(1 MiB 上限、24h TTL、并发去重)
- 模型别名与 default_model 降级;错误体统一输出 param/code
- 补 e2e 修复场景与 docs/compat-audit.md 兼容性审计
2026-10-09 00:50:01 +08:00
nyoung e44e960fe9 chore: bump version to 0.6.3 2026-10-08 17:41:28 +08:00
nyoung 8ecece1572 fix(prompt): 工具指令显式禁止 DSML 标记输出
模型会退回 DeepSeek 原生 DSML 方言(<|DSML|> calls> / invoke /
parameter)代替 JSON 输出工具调用,而网关的流式(extractableToolJSON)、
解析(TryParseToolCalls)、续写(ToolCallTruncated)三层都只认 JSON:
DSML 回复既不会被转成 tool_calls,也不会触发续写,整段标记连同被截断
的正文一起当普通文本透传给客户端。

按既定决策不做 DSML 解析兼容,改为在注入的 TOOL INSTRUCTIONS 中显式
禁止该方言、声明只接受 JSON 格式。三接口共用 BuildPrompt 注入点,
一处改动同时生效。

新增红绿回归测试 TestToolsPromptForbidsDSML(先复现红,加文案后转绿)。
2026-10-08 17:41:28 +08:00
nyoung 68ba2aa431 chore: bump version to 0.6.2 2026-10-08 15:13:50 +08:00
nyoung edbf3623e1 feat(admin): 控制台 Turnstile 与代理线路页重组
Turnstile 页:
- 三种 Token 获取方式收进「Token 获取方式」一张卡,分段按钮切换字段区,
  Sitekey / Action 归入方式 1 字段区(全局兜底,浏览器求解共用)
- 「Cookie 池预热」与「Cookie 池」合并为一张卡;「求解参数」瘦身为
  「求解超时与重试」,只在方式 1/2 显示
- 求解恒开启,不再提供关闭开关(保存固定 enabled=true),manual 方式下
  停掉 Cookie 池 5s 轮询

代理线路页:
- 顶部加「基础线路 / 代理池」页签分组,页签状态跨重渲染保留
- 「降级策略」改名「限流与故障切换」;原「代理池 · Xray 核心」大杂烩卡
  拆为「代理池 · 基础」与「Xray 核心」两张,各带同一提交逻辑的保存按钮
2026-10-08 15:13:42 +08:00
nyoung ed51efd8bc fix: 网关与控制台代码审查修复批次(含回归测试)
- Chat 接口拒绝 n>1(此前静默丢弃多余 choice),返回 400 结构化错误
- Responses 接口透传 text.format(json_schema / json_object),三种接口协议对齐
- TLS 指纹统一升级到 Chrome_150(internal/httpx.DefaultProfile),与 UA 匹配
- metrics 落盘失败不再静默:Save() 返回错误并打日志,临时文件失败会清理
- GET /api/config 脱敏 admin.password 与 turnstile.api_key(控制台从不展示,
  不应随 5s 轮询下发);PUT 改走 ReplaceJSON,先校验后替换、失败回滚
- set_limits / set_turnstile 改指针部分更新:缺字段保持现状,不会把并发、
  限流或求解开关按零值清掉
- 读请求体统一 64MB 上限;配置写盘原子替换 + 0600 权限
- main.go 改为 run() 返回退出码:日志落盘、指标落盘、xray 子进程回收全部
  挂 defer,任何退出路径(含启动失败)都会执行,杜绝孤儿 xray
- proxypool / turnstile / upstream / openai / config / httpx / logbuf 等
  逐项补红绿回归测试,新增 14 个测试文件,race 下全绿
2026-10-08 15:13:23 +08:00
nyoung 454bb970b8 Merge pull request #1 from jinyiwei2012/feat/pools-and-sentinel
feat: 代理池 + Cookie 池预热 + 日志轮转 + 配额哨兵 + 求解器修复
2026-10-08 09:29:07 +08:00
nyoungo 3db73ded64 chore: bump version to 0.6.1 2026-10-08 01:07:10 +08:00
nyoungo d2c6f4787b chore: add env-gated SSE read timing diagnostics 2026-10-08 01:07:10 +08:00
nyoungo 18bf4ee723 feat: stream tool-call arguments progressively instead of buffering 2026-10-08 01:07:10 +08:00
nyoungo a9821d120e fix: accept prose-prefixed tool JSON and heal invalid escape sequences 2026-10-08 01:07:04 +08:00
luotianyi 63f228d2c7 docs: README 补全求解器风格、预热环境变量与架构清单
- Turnstile 说明补充 api_style = "ezsolver"(本地求解服务、直连旁路)
- 环境变量表补充 TURNSTILE_TIMEOUT_SECONDS 与 TURNSTILE_WARM_*
- 架构清单补充 internal/logfile / internal/quota,turnstile 行标注后台预热
- [sites.*] / [turnstile] 行与管理台 Turnstile 行同步补全
2026-10-08 00:41:03 +08:00
luotianyi 69743d53bd fix(turnstile): 浏览器 CDP 等待 / 关闭与 Windows 降权分裂修复
- --do-not-de-elevate:修复管理员父进程下 Chromium/Edge 自行降权导致的
  窗口残留 / CDP 连不上 / 进程孤儿
- DevTools 等待窗口不再把启动器退出当失败;关闭走 CDP Browser.close 兜底
2026-10-08 00:19:41 +08:00
luotianyi 97a59a2dfb feat(quota): 配额哨兵与配额耗尽留档
- 新增 internal/quota 哨兵:[quota] 定期用池内身份查询站点余额(访客态无需 nonce),
  quota low 告警、quota reset observed 留档,/api/overview 暴露 site × bot 余额
- upstream: SetQuotaObserver 观测器(含被跨站接力吞没的配额事件)
- metrics: 按站点累计 prompt / completion tokens 与配额事件计数
2026-10-08 00:19:40 +08:00
luotianyi 9900695855 feat(logfile): 日志按日轮转与 gzip 压缩([server].log_file)
- 新增 internal/logfile:按日轮转 + gzip 归档,io.Writer 形态接在 slog 之后
- [server].log_file:留空写 <data_dir>/logs/dsfree2api.log,"-" 仅终端;LOG_FILE env
2026-10-08 00:19:40 +08:00
luotianyi c9886a81d2 feat(turnstile): Cookie 池预热、可配求解超时、ezsolver 求解风格与本地直连
- 求解超时统一走 SolveTimeoutValue(默认 90s,CLamp 5–600),TURNSTILE_TIMEOUT_SECONDS
- Cookie 池 warm_enabled:按站点 × 线路后台预热/续期,失败指数退避(上限 15 分钟);
  warm_pool_only 仅预热池绑定线路;CookiesReady 与 slow-start 协同
- api_style = "ezsolver":兼容 {sitekey,siteurl,timeout} → {token} 的本地求解服务,
  api_key 可留空;环回/内网求解地址直连(不随线路代理)
- admin: 求解器风格选择与 Cookie 池预热状态
2026-10-08 00:19:39 +08:00
luotianyi 6aae7b65ea feat(proxypool): 站点级出口代理池(Xray / 订阅 / 端点,粘性选路与健康探测)
- proxypool: 站点级出口绑定 proxies = [条目名, "sub:订阅名"],粘性选路、
  失败切换、后台健康探测;支持 Xray 分享链接 / 订阅 / 裸 ip:port 与 socks5 端点,
  托管 Xray 核心(可自动下载);站点未绑定时回退 [proxy] 主/备线路
- upstream: RouteSource 抽象 + routesFor/poolReport;求解与请求共用同一出口
- admin: 代理池面板与维护动作;overview 暴露池状态
2026-10-08 00:19:39 +08:00
nyoungo 4cc4504a18 chore: bump version to 0.6.0 2026-10-07 23:16:00 +08:00
nyoungo 753b495f8a feat: console actions to query and reset a site quota 2026-10-07 23:16:00 +08:00
nyoungo 08464a27d7 feat: rotate visitor identity to restore a quota-exhausted site without re-solving 2026-10-07 23:16:00 +08:00
nyoungo f30049b137 chore: document partial-call fallback and bump version to 0.5.0 2026-10-07 22:41:18 +08:00
nyoungo 403ab48a46 feat: cool quota-exhausted sites down and fail over fast on cache rejections 2026-10-07 22:41:18 +08:00
nyoungo 975882292c feat: force-close truncated tool-call JSON into partial tool calls 2026-10-07 22:41:18 +08:00
nyoungo 413be4ba9e feat: stitch truncated tool-call JSON via multi-round continuation 2026-10-07 20:37:27 +08:00
nyoungo 3a21c53c0a ci: attach binaries to a GitHub Release on tag push
- release job (contents: write, gh CLI) creates the release with generated notes and uploads both binaries + sha256, --clobber for re-runs
- on tag builds the ldflags version comes from the tag itself
2026-10-07 17:45:58 +08:00
nyoungo c3e6d9d513 ci: add windows/linux binary build workflow
- test job: go vet + go test on push/PR/tag
- build job: CGO_ENABLED=0 cross-build linux/amd64 + windows/amd64 with version injection, sha256 checksums, uploaded as artifacts
- fix Makefile -X ldflags path after module rename
- add .gitattributes (LF normalization), ignore CI build outputs
2026-10-07 16:21:45 +08:00
nyoungo 18b2c04006 initial import
- Go service bridging deepseek.de/es/fr V4 models behind an OpenAI-compatible API
- /v1/chat/completions, /v1/responses, /v1/messages (Anthropic) with tool calling
- web admin console: dashboard, models/sites, keys, proxies, Turnstile, playground, live logs
- Turnstile solvers: solver API / local browser via CDP / manual cookie import
- MIT license, README with screenshots, Dockerfile and Makefile
2026-10-07 15:46:45 +08:00
nyoung d259d15992 Initial commit 2026-10-07 14:34:09 +08:00