Sakurasan
|
d911881499
|
feat: add reset-password CLI command for any user
|
2026-09-07 02:33:11 +08:00 |
|
Sakurasan
|
2e3bb22f81
|
fix: use weighted random pick for load balancing instead of sequential iteration
|
2026-09-02 17:32:12 +08:00 |
|
Sakurasan
|
923ac79039
|
删除请求超时
|
2026-09-02 13:08:32 +08:00 |
|
Sakurasan
|
6d951a0d61
|
fix: sync schemaVersion to 2 matching production
|
2026-08-31 18:16:19 +08:00 |
|
Sakurasan
|
1f5f60e905
|
fix: move timeout migration outside schema version check
|
2026-08-31 18:01:33 +08:00 |
|
Sakurasan
|
c6a4fcfbbc
|
fix: migrate existing channels timeout_ms to 300000
|
2026-08-31 17:47:52 +08:00 |
|
Sakurasan
|
5cb428bba9
|
feat: increase default timeout to 5 minutes
|
2026-08-31 16:56:18 +08:00 |
|
Sakurasan
|
658a9cb580
|
fix: SQLite 迁移加版本锁,消除每次启动全量重建表
GORM sqlite AutoMigrate 对已有表判定不收敛(实测已迁移库再跑
仍触发 12 次表重建),SQLite 无在线 ALTER,每次重建走
CREATE __temp + INSERT SELECT + DROP 全表拷贝;usage_logs 含
raw_request/raw_response 大文本,一轮 40~80s,生产每次重启
重演导致启动数分钟。
- 新增 schemaVersion 常量,PRAGMA user_version 记录已迁移版本
- 版本达标跳过 AutoMigrate 秒开;旧库首次升级迁移一次写版本
- postgres 不受影响(支持 ALTER,保持原行为)
- 维护约定:改表结构须递增 schemaVersion
|
2026-08-29 12:46:52 +08:00 |
|
Sakurasan
|
3a836bf0e9
|
fix: curl 示例复制按钮逃逸到页头叠加在退出按钮上
上轮移动端修复误删容器 relative,absolute 按钮向上冒泡定位到
页面顶端。加回 relative 使按钮回到代码块右上角。
|
2026-08-28 21:22:40 +08:00 |
|
Sakurasan
|
faf38e2fd3
|
fix: 修复移动端仪表盘横向溢出
375px 视口下页面被撑到 763px:快速开始卡片的 curl 示例 <pre>
固有宽度沿 flex/grid 链层层撑破祖先(子项默认 min-width:auto
不可收缩,overflow-x-auto 形同虚设)。
- ShellLayout:flex-1 容器与 main 加 min-w-0 切断宽度传播(所有页面受益)
- DashboardView:快速开始卡片各块加 min-w-0,pre 的边框/背景
移入 overflow-hidden 容器、自身横滚
Playwright 实测 375px 视口滚动宽度 763 → 375,与视口齐平
|
2026-08-28 20:12:08 +08:00 |
|
Sakurasan
|
d8257df100
|
fix: messages 流式缓存场景 token 记账错乱
qwen/dashscope 等上游 messages 流式的 usage 语义:
- message_start.usage.input_tokens = 总输入
- message_delta.usage.input_tokens = 非缓存输入(缓存部分单列
cache_read/cache_creation 字段),是最终计费口径
原 usageSink 字段级合并中 delta 的 input 覆盖 start 的 input,
总输入丢失(31790 → 8);缓存写也未参与计费。
- push:带 cache_* 字段的 usage 视为最终口径,整体替换 sink
- finishUsage:缓存写按 1.25× 输入价计费(Anthropic 5m 口径);
落库 input_tokens 存总量(含缓存读/写)便于对账
- 估算兜底条件排除已有缓存计数的请求
- 回归测试:缓存写/缓存命中/chat 末块合并不回归
|
2026-08-28 18:11:24 +08:00 |
|
Sakurasan
|
cd015d370c
|
fix: handle zero channel_id in admin usage logs
|
2026-08-28 16:55:08 +08:00 |
|
Sakurasan
|
939a98d389
|
feat: show channel name in admin usage logs
|
2026-08-28 16:40:23 +08:00 |
|
Sakurasan
|
0b31cc209e
|
fix: chat→responses 转换 input 始终输出数组
单条消息时原逻辑把 input 塌缩成单个对象,火山方舟等上游只接受
[]*InputItem 数组,直接 400(Mismatch type)。chat/messages 经
vole 渠道转换因此全挂。改为恒为数组,三种协议全矩阵实测恢复。
|
2026-08-27 09:57:48 +08:00 |
|
Sakurasan
|
305b3ed731
|
refactor: 删除无用的模型展示名(display_name)字段
该字段仅存取、从不展示:管理列表只渲染 name,/v1/models 与用户侧
均不返回它。与渠道绑定 upstream_model 的名字映射职责重叠且悬空。
- store.Model 结构体、admin CRUD、seed 数据移除 display_name
- 前端编辑弹窗输入框、表单状态、types.ts 同步移除
- 本地库已 ALTER TABLE DROP COLUMN;生产残留列无害
|
2026-08-27 09:57:30 +08:00 |
|
Sakurasan
|
79545aa48e
|
fix: 兼容上游 SSE data: 后无空格格式,流式记账不再 0 消耗
火山方舟等上游流式返回 data:{...}(data: 后无空格),原解析只认
'data: '(带空格),导致 content 文本与 usage 全部漏解析:
- sseContentText 抽成 sseDataPayload,统一处理 data: 前缀
(支持带/不带空格 + event:+data: 多行块)
- scanUsage 复用 sseDataPayload
- convert/stream.go parseLine 也支持 data:{ 无空格
- 新增回归测试覆盖无空格/带空格/多行块三种形态
|
2026-08-27 01:24:30 +08:00 |
|
Sakurasan
|
d818cf3b4c
|
refactor: 命令树移入 internal/cli,去掉 DefaultRun 注入
- cmd/server/cmd → internal/cli,与 internal/api、internal/proxy 平级
- serve() 移入 cli 包作为默认子命令,main.go 退化为纯入口
- 消除 cmd/cmd 冗余层级和 main → cmd 的回调注入
|
2026-08-26 18:14:08 +08:00 |
|
Sakurasan
|
98f296101e
|
refactor: 改用 Cobra 命令行框架,reset-admin-password 带交互提示
- root.go 作为 Cobra 入口,DefaultRun 由 main 注入 serve()
- reset_admin.go 改为 Cobra 子命令,支持 --user/--password 参数
- 交互式:多管理员时选择目标、密码支持手动输入或随机生成(term.ReadPassword 不回显)
- 帮助输出自动生成,无需手写 Usage
- 删除旧的 flag 实现
|
2026-08-26 18:03:03 +08:00 |
|
Sakurasan
|
2983c89b42
|
feat: 新增 reset-admin-password 命令行重置管理员密码
- cmd/server 子命令分发:reset-admin-password 不启动服务
- -password 留空随机生成 16 位(去除易混淆字符),打印一次
- -user 指定目标管理员,仅匹配 role=admin
- 密码长度校验 8-72 与 API 一致,argon2id 参数取自配置
- Makefile 增加 make reset-admin-password 入口
|
2026-08-26 15:57:04 +08:00 |
|
Sakurasan
|
a45a6e16bd
|
fix: API Key 前缀调整为 sk-ot-
|
2026-08-26 15:57:04 +08:00 |
|
Sakurasan
|
c78a473e59
|
feat: API Key 前缀改为 sk-ot
- apikey 包 prefix 常量 sk- → sk-ot(生成/校验/展示前缀统一驱动)
- 鉴权错误提示同步更新为 sk-ot 格式
- 测试断言改用常量,避免硬编码长度
- 前端 curl 示例与 README/PLANNING 文档同步
|
2026-08-25 00:34:50 +08:00 |
|
Sakurasan
|
f7a5741b33
|
fix: 模型列表仅显示已启用渠道中的模型
|
2026-08-22 14:19:45 +08:00 |
|
Sakurasan
|
daf6b8c66b
|
fix: 获取模型列表时过滤已禁用渠道的绑定
|
2026-08-22 13:26:17 +08:00 |
|
Sakurasan
|
8430ecc6c6
|
fix: use inline style for enabled channel highlight
|
2026-08-22 12:21:48 +08:00 |
|
Sakurasan
|
4aa8b79156
|
fix: use bg-accent-soft for enabled channel highlight
|
2026-08-22 12:17:45 +08:00 |
|
Sakurasan
|
94fd7fd40a
|
feat: add highlight for enabled channels
|
2026-08-22 12:09:33 +08:00 |
|
Sakurasan
|
048de4c9a8
|
feat: add enable/disable toggle for channels
|
2026-08-22 02:12:10 +08:00 |
|
Sakurasan
|
781f1b9f83
|
添加 OT_PROXY_LOG_RAW 到 .env.example
|
2026-08-21 11:21:19 +08:00 |
|
Sakurasan
|
42214d6f5e
|
管理后台用量统计支持按用户筛选:用户名输入 + datalist 自动补全,精确匹配解析为 user_id
- types: UsageLog 补 user_id 字段
- UsageView: 新增用户筛选输入框,防抖 300ms 拉取 admin/users 候选做下拉补全
- search 时将用户名经 admin/users 精确解析为 user_id 再过滤 admin/usage;未找到用户时 toast 报错
- 支持清除筛选一键还原
|
2026-08-20 01:58:02 +08:00 |
|
Sakurasan
|
10f51cbdae
|
请求明细支持查看原始请求/响应:OT_PROXY_LOG_RAW 开关控制,仅管理员记录与可见,流式全量捕获
- 配置: ProxyConfig.LogRaw (OT_PROXY_LOG_RAW, 默认 false)
- 存储: usage_logs 新增 raw_request/raw_response 文本列 (AutoMigrate)
- 网关: NewGateway 接收 logRaw 参数
- handlers: 三个协议入口按 开关+管理员 条件记录原始请求体
- passthrough: 非流式 copyAndCapture 捕获响应, 流式 streamCopy 累积全部原始 SSE 行, finishUsage 统一写入
- admin API: AdminUsage 返回 raw_request/raw_response (仅管理员)
- 前端: 用量页新增查看入口, 弹窗 tab 切换请求/响应
- gitignore: 修正 server/web/ 忽略规则(尾随空格导致未生效)
|
2026-08-20 00:37:48 +08:00 |
|
Sakurasan
|
0939f98fb5
|
修复流式请求记账为 0 消耗:支持 SSE 多行块 usage 提取 + 无上游 usage 时 tiktoken 估算
- sseContentText/scanUsage 兼容 event:+data: 多行块(转换器 eventLine 产出)
- usageFromMap 新增 delta.usage 支持(Anthropic message_delta 标准格式)
- finishUsage: 流式成功但上游不返回 usage(如火山方舟)时按内容 tiktoken 估算,in/out 独立估算
- .gitignore 忽略 server/web 本地静态托管软链
|
2026-08-19 20:59:04 +08:00 |
|
Sakurasan
|
30ab9e842c
|
claude code tools error
|
2026-08-19 03:46:39 +08:00 |
|
Sakurasan
|
3e7efb3c88
|
fix passkey
server/internal/passkey/passkey.go
的 takeSession,过期校验只在显式设置了 Expires 时才生效(与 go-webauthn 库内部 !IsZero() 的检查一致)
|
2026-08-19 00:00:51 +08:00 |
|
 SakurasanandClaude
|
8495694671
|
构建: 入口脚本 chown 数据目录后降权运行
绑定挂载/命名卷被 docker 以 root 自动创建时,容器非 root 用户
写不进 db(SQLITE_CANTOPEN)。改为 entrypoint 以 root 启动,
chown 数据目录到 OT_UID:OT_GID(默认 1000:1000)后 su-exec 降权,
compose 不再需要 user: 覆盖。
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-18 22:25:43 +08:00 |
|
 SakurasanandClaude
|
5aa0be13dc
|
部署: docker-compose 一键启动
- 密钥从仓库根 .env 读取(:? 缺失即报错)
- db 绑定挂载当前目录 ./data,按宿主用户运行(OT_UID/OT_GID 可覆盖)
- healthcheck 探测 /healthz,restart unless-stopped
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-18 21:57:16 +08:00 |
|
 SakurasanandClaude
|
b5fb947a5b
|
构建: --local 改用 docker build 绕开 docker-container 驱动
multiarch builder 嵌套创建构建容器在受限环境报 "can't mask dir
/proc/acpi";本地单架构无需 buildx,直接 docker build 更稳。
多架构 --push 路径保持不变(仍须 docker-container builder)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-18 20:49:45 +08:00 |
|
 SakurasanandClaude
|
ea7f023228
|
构建: 多架构 Dockerfile + 构建脚本
- Dockerfile 三阶段:前端固定在 BUILDPLATFORM 编译一次(平台无关产物),
Go 后端按 TARGETARCH 交叉编译,两种架构共用同一份 web/dist
- 前端用 pnpm --ignore-scripts(pnpm≥10 拦截 esbuild/vue-demi postinstall,
esbuild 走 optionalDependencies 自带二进制),运行镜像非 root + /app/data 卷
- scripts/build-image.sh:--local 本地单架构加载;默认多架构 amd64+arm64 推送
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-18 13:16:54 +08:00 |
|
 SakurasanandClaude
|
967c54ae32
|
代理: 鉴权支持 Anthropic x-api-key 头
Claude Code / Anthropic SDK 用 x-api-key 头而不是 Authorization:
Bearer,缺失 Authorization 时回退读取 x-api-key,错误文案同步提示两种方式
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-18 00:51:53 +08:00 |
|
 SakurasanandClaude
|
eac6938baa
|
服务: SPA 缓存策略修复重建后首页黑屏
- index.html 设 Cache-Control: no-cache,避免浏览器启发式缓存保留引用已删除 chunk 的旧 HTML
- /assets/*(文件名含内容 hash,不可变)设 immutable 长缓存,减少回源
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-17 20:30:17 +08:00 |
|
 SakurasanandClaude
|
fcaafdc807
|
前端: Base URL 输入限长 + 列表截断防撑破
- Input 组件支持 maxlength 透传
- 渠道表单 4 个 Base URL 输入框限 255 字符
- 渠道列表 Base URL 单元格截断显示(max-w-220px)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-17 20:30:09 +08:00 |
|
 SakurasanandClaude
|
74424d980c
|
前端: 仪表盘快速开始卡片 + 移动端适配 + 主页 curl 用浏览器 host
- 仪表盘底部新增「快速开始」:Base URL(浏览器 host)+ 协议徽标 + curl 示例(可复制)
- 最近请求改为响应式两行(模型+状态 / token·成本·时间),窄屏不再挤压
- 主页调用演示改用 window.location.origin,去掉写死的 api.openteam.dev
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-17 20:30:03 +08:00 |
|
 SakurasanandClaude
|
c84fea9ef0
|
记账: Recorder Close 幂等防重复关闭
- main 的 defer Shutdown 与显式 Close 双调用导致停机 panic close of closed channel
- 用 sync.Once 保证只关闭一次
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-16 18:55:15 +08:00 |
|
 SakurasanandClaude
|
c3dc28fb5b
|
前端: 仪表盘最近请求 canceled 显示灰色
- 控制台/管理后台仪表盘「最近请求」的 canceled 状态改为 neutral 灰色
- 与用量页保持一致的三态判断(success=ok / canceled=neutral / err)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-16 18:55:10 +08:00 |
|
 SakurasanandClaude
|
4137b6fe20
|
渠道: 远程候选按渠道过滤 + key 掩码 + 移除批量导入端点
- 远程模型候选只排除本渠道已允许的模型,同名模型可被多个渠道各自允许
- 渠道 key 掩码统一 xxxxxxx******Mq4Y(保留前 7 位与后 4 位)
- 移除已弃用的批量导入端点 POST /channels/:id/models/import
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-16 18:55:05 +08:00 |
|
 SakurasanandClaude
|
d0c879a2ed
|
模型定价: 悬空模型标记 + 一键清除 + 允许渠道只读
- 无渠道绑定的模型以「悬空」琥珀色徽标 + 卡片着色标记
- 新增「清除悬空」一键删除未绑定渠道的模型(DELETE /models/unused)
- 移除页面内「绑定渠道」弹窗与 chips 的解除按钮,渠道支持列表只在渠道抽屉管理
- 缺失提示带上渠道真实模型名(upstream_model)
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-16 18:54:59 +08:00 |
|
 SakurasanandClaude
|
8194edb63d
|
前端: 用量页移动端卡片优化 + canceled 灰色 + 接口类型短标识
- 移动端卡片重排: 成本/状态右置, 协议在模型下方, 元信息分隔行
- canceled 状态徽章由 warn 改为 neutral(与成功/失败区分)
- 接口类型列改用短标识 chat/completions | responses | messages
- 管理后台页头搜索框移动端纵向排列
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-16 09:04:26 +08:00 |
|
 SakurasanandClaude
|
6f895acf63
|
前端: API Keys 移动端卡片布局 + 复制兼容
- 移动端(md 以下)以卡片列表替代横向滚动表格, 展示配额/过期/最近使用
- 桌面表格补充配额/过期列, 移除创建时间列
- copyText 支持 Clipboard API + execCommand 回退(HTTP 环境可用)
- 删除文案由"吊销"改为"删除(不可恢复)"
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-16 09:04:26 +08:00 |
|
 SakurasanandClaude
|
fb7db00817
|
密钥: 删除改为硬删(立即失效不可恢复)
- DELETE /api/v1/keys/:id 由软吊销(置 revoked)改为物理删除
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-16 09:04:18 +08:00 |
|
 SakurasanandClaude
|
0ee92d78e7
|
代理: 流式中断按已生成部分计费
- 新增 tokenizer 包(tiktoken-go)按模型估算 token, 未知模型回退 cl100k_base
- passthrough 提取请求输入文本 + SSE 已生成内容, 客户端断开时记 canceled
- usage 计费范围扩展: canceled(流式中断)按已生成部分收费
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-16 09:04:18 +08:00 |
|
 SakurasanandClaude
|
4b507d8064
|
转换器: 图片内容块跨协议互转保留(base64/url)
- 支持 OpenAI image_url ↔ Anthropic image.source(base64/url) 双向转换
- messages→chat / responses→chat 不再丢弃图片块, 保留图文原始顺序
- chat→messages 的 data URL 拆成 base64 source(media_type+data)
- chat→responses 的 image_url 转 input_image
- responses↔messages 经 chat 中转, 六方向全覆盖
- 新增多图/顺序回归测试
Co-Authored-By: Claude <noreply@anthropic.com>
|
2026-08-16 09:04:09 +08:00 |
|