dsh-connect-agnes-token-plan 0.5.0 → 0.6.0

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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,64 @@
2
2
 
3
3
  本文件只记**公开行为变化**(新增能力、破坏性改动、重要修复)。实现细节、重构与测试加固请直接看 `git log`。
4
4
 
5
+ ## [0.6.0] — 2026-10-01
6
+
7
+ **面板信息架构再收一刀**:顶栏从「页面标题栏」降格为「当前 tab 的状态与刷新出口」——撤销假的全局标题,「更新于」/令牌状态/刷新按 tab 归属;额度窗口卡片改以**百分比为主视**并按职责分池;三个 tab 补上常驻的官网入口。**AgnesCode 这条线修掉两个叠加的旧病**:GET 路由的 `lastHarvest` 落在暂时性死区,让「检测本机登录态」点了没反应;以及「开关先开、令牌后到」留下的 `not_configured` 被当作红色错误报警。推理侧把单次输出上限从兜底的 32768 提到实测平台上限 65536,契约基线 seed 一并退役、换真机全阶梯证据。
8
+
9
+ ### 修复:AgnesCode tab 开关提供方时闪现红色报错「not_configured」
10
+
11
+ - **自愈通道(Host)**:GET 路由原来只读不修——「开关先开、令牌后到」留下的 `not_configured` 会一直挂着,直到用户手动点击什么。现在 GET 发现「开关开 + 已关联 + providerError 为 not_configured」这一陈旧组合时,自动补一次发布(每 60s 至多一次,避免持续失败的发布被面板轮询反复重建适配器),下一拍轮询即可看到修复后的状态。手动采集保持手动——解锁桌面 App 的加密会话文件是隐私敏感操作,只在用户点击时执行;采集之后的一切(启动 seed、采集后发布、GET 自愈)全自动。
12
+ - **现象**:勾选「启用 AgnesCode 提供方」的瞬间,面板弹出一行红色 `not_configured`,检测到登录态后又自己消失——看起来像一次自愈的故障。
13
+ - **根因**:`not_configured` 是发布门的**预期中间态**(「开关已开、令牌还没有」),Host 语义无误;错在客户端把它当原始错误文本、以 alert 样式直渲染。检测/关联完成后发布门清掉错误,于是「又消失」。
14
+ - **修法(客户端)**:未关联时不再渲染它——「已启用——检测到本机登录态后即可注册模型」一行已经说了同一件事;已关联时降级为一句普通状态文字「凭据未就绪——点『检测本机登录态』重新采集后再试」,不再红色报警。其余 providerError 仍按错误渲染。
15
+
16
+ ### AgnesCode tab:凭据卡片一行式 + 「已注册」pill
17
+
18
+ - **AgnesCode tab 向小浣(商汤)参考件对齐排版**:凭据卡片改为**一行式**——「已关联:昵称」居左,「检测本机登录态」「解除关联」两个按钮居右(原先三行状态加两行按钮,声明一个「你已登录」要花五行);积分余额与时效/永久拆分合并为**一行**小字(`agnescode.balanceLine`,凭据有效期不并入——凭据卡里已经有一遍,重复的日期读起来像两个截止时间);「已注册」从一句普通文字改为模型清单头部的**绿色 pill**,与「模型(N)」同排——注册状态骑在它描述的清单上,而不是在清单上方独自成句。
19
+
20
+ ### 面板内常驻官网入口:「接入 API」tab 的额度管理链接与 AgnesCode tab 的客户端下载
21
+
22
+ - API Key 卡片原来只在**未配置** Key 时显示「前往官网免费获取 →」;现在配置了 Key 也会常驻一条「前往官网管理额度 →」,两条文案按状态切换、指向同一官网地址。与「积分额度」tab 有意重复——离开面板去找控制台不应要求记住网址。
23
+ - **AgnesCode tab 底部常驻客户端下载入口**:`agnes-ai.cn/agnescode`(产品页)以「下载 AgnesCode 桌面客户端,领取限时积分 →」一行小字钉在 tab 卡片底部,**未关联与已关联都显示**——已关联的账号同样要靠重开桌面 App 续期凭据(JWT 无刷新端点),且新用户安装可领限时积分。这是三个 tab 里唯一要求用户机器上装有额外软件的流程,此前面板里没有任何入口。
24
+
25
+ ### 额度窗口卡片改为百分比主视;移除静态套餐文案「1500 次模型请求 / 5 小时」
26
+
27
+ - **窗口卡片以百分比为主视**:平台在 `subscription.usage` 里报出某窗口的 `used` 时,卡片的大字是该窗口的消耗百分比(转写平台自己的 `used / limit`),`已用 X / Y` 的原始计数降为下方小字。原来的「上限作大字」在窗口耗尽时会读起来像还有量。
28
+ - **移除 `usageLimitText`**:套餐目录的 `usage_limit_text`(「1500 次模型请求 / 5 小时」)是**不随用量变化的静态文案**,额度用光时它照样显示 1500——误导来源,整条拔掉(解析 / 投影 / wire / 渲染)。5 小时窗口形态由 `concurrency_window_h` 字段本身给出,不依赖它。
29
+ - **窗口卡片按职责分池**:四个窗口不再平铺一行「模型请求 / 每周请求 / 生图 / 视频」,改为**两张池卡片**——「模型请求」池内含「5 小时」「每周」两张子卡(卡片头直接写窗口),「多媒体」池内含「生图」「视频」两张子卡(每日作小字角标)。池卡片共享一张 auto-fit 网格:宽屏下两池左右并排铺满一行,窄屏上下堆叠,消灭「每周请求 / 每周」这种名词与周期互相重复的卡片头,也消灭右侧留白。未知维度的窗口落进无标题的池,不会被分组吞掉。
30
+ - **卡片底部合并为一行**:`已用 X / Y` 与重置时间共用底部同一行(左计数、右重置),不再上下两行占两倍纵向空间。零上限窗口没有分数可画,也不显示「已用 0 / 0」。
31
+ - 没有报 `used` 的窗口(今天的 video)维持上限作主视、不画进度条,行为不变。
32
+
33
+ ### 面板顶栏降格为「按 tab 的 shell」:撤掉全局标题与全局刷新
34
+
35
+ - **撤掉假全局标题**:顶栏原来固定渲染「积分面板」,而它只是三个 tab 里第一个的名字;Plugins 页在这个卡片**上方**已经渲染了插件自己的名称与描述,所以那是第二遍、且口径更窄的标题。顶栏不再有标题(`panel.title` 随之从字典删除)。
36
+ - **状态与刷新按 tab 归属**(新决策函数 `barPlan`,纯函数、随 `panel` 测试面导出,由 Node 套件直接驱动):
37
+ - 「积分额度」tab:快照的「更新于」+ 令牌 chip + 陈旧数据告警 + 刷新快照;
38
+ - 「接入 API」tab:同一份快照(它渲染的就是快照里的 `llm` 块),因此同样的「更新于」与刷新,但**不再挂令牌 chip**——那枚令牌是控制台凭据,这个 tab 用的是已保存的 API Key;
39
+ - 「AgnesCode」tab:它读自己的路由、按 60s 自己的节奏轮询,所以由该 tab **自己发布**「更新于」与刷新。此前顶栏在这一 tab 上引用的是快照的时间戳,刷新按钮也只重载快照——两者都指向**另一个 tab** 的数据。
40
+ - **顺带修掉一个看不见的失败**:AgnesCode tab 的路由读取失败时 `error` 只被 set、从不渲染,于是「Host 没回话」显示成「未关联——请先在桌面端登录」,把原因甩给了用户的桌面 App。现在失败会明说,且这一刻不再声称「未关联」(面板没有这个证据);顶栏刷新按钮在该 tab 尚未发布 loader 时置灰,而不是静默重载另一个 tab。
41
+ - 契约:`barPlan` 的决策由 `test/render.test.mjs` H3 驱动,接线与「失败必须渲染」由 `test/panel.test.mjs` F6 钉住;`docs.test.mjs` 检查 9 依赖 `activeTab` 的字面联合类型,源码注释已写明不要改成类型别名。
42
+
43
+ ### 修复:AgnesCode tab 的「检测本机登录态」点了没反应(GET 路由每次都抛错)
44
+
45
+ - **现象**:桌面端已登录、点「检测本机登录态」也回「已读取本机登录态。」,但卡片仍然停在「未关联」——凭据其实早已写进 DSH 凭据服务,面板只是永远看不到它。
46
+ - **根因(Host 侧,`routes.ts`)**:AgnesCode 路由把「上一次探测记录」`lastHarvest` 声明在**处理函数内部、GET 分支之后**。GET 分支先 `return`,于是 `agnescodeState()` 读到的是处在**暂时性死区**的 `let` 绑定,整个 handler 抛 `ReferenceError: Cannot access 'lastHarvest' before initialization`,Host 把它变成**无 body 的 400**。POST(harvest/switch)在该声明之后执行,所以按钮全好——只有 tab 进场的 GET 是坏的。面板因此永远拿不到 `loggedIn`,5 分钟轮询也修不回来。
47
+ - **修法**:`lastHarvest` 与 `agnescodeHarvestInFlight` 上移到**路由注册作用域**(每次注册一份,跨请求共享)。这同时兑现了原注释里「GET 也带上次探测记录」「并发 harvest 合并成一次 walk」两句话——在此之前两者都只在单个请求内成立。
48
+ - **客户端加固**:`load()` 此前 `if (!response.ok) return;` 静默返回,`state === null` 且 `error === null`,于是渲染出「未关联——请先在桌面端登录」——把 Host 的故障说成用户的桌面 App 没登录。现在非 2xx 会把状态码写进 `error`,由「失败必须渲染」那条路径明说。
49
+ - 契约:`test/agnescode.test.mjs` 新增「route surface」段——用假 ctx 驱动真实 `registerRoutes` 并对 `/agnescode` 发 GET,钉住 200、`loggedIn` 与「payload 不带 token」。
50
+
51
+ ### 推理通道:单次输出上限从 32768 提到平台上限 65536
52
+
53
+ - Token Plan 推理线的每个请求此前实际携带 `max_tokens = 32768`。这不是平台限制,而是 `dsh-llm-pi-ai` 注册兜底(`DEFAULT_MAX_TOKENS = 32768`,其校验强制要求正整数)——descriptor「不声明值防截断」的旧决策因此失效:未声明≠无上限,而是被砍半,思考(默认 high 档)与回答挤在 32k 预算里,长回合先截思考。
54
+ - descriptor 现声明实测平台上限 `maxTokens: 65_536`(`PROBED_MAX_TOKENS`)。真机探针(2026-10-01,`api.agnes-ai.cn/v1`):32768 / 65536 / 缺省不发均 200(65536 在 agnes-2.5-flash 与 agnes-2.0-flash 复测通过),131072 → 400 平台原文「max_tokens 不能超过 65536」。每轮实际上限为 `min(65536, contextWindow − prompt − 4096)`。
55
+ - 契约钉点同步:`test/provider.test.mjs` / `test/contract.test.mjs` 翻正为钉 65536;`docs/AGNES-API.md` §7.3、`docs/ARCHITECTURE.md` §5.2 同步。
56
+
57
+ ### 契约基线 seed 退役:真机全阶梯回填(选择器档位面变化)
58
+
59
+ - `test/baselines/agnes-contract.json` 从单条 SenseNova 时代 seed(`deepseek-v4.1-flash`,全 pending)回填为 2026-10-01 真机实测:live 目录 7 条(`agnes-2.5-pro` / `-alpha` / `-beta` 当天内消失,已记入漂移),三个 chat 模型的 `reasoning_effort` 全阶梯 + thinking 字段拼写(统一 `message.reasoning_content`)逐项取证,全部附平台响应原文于 `driftLog`。
60
+ - `PROBED_EFFORT` 随之换血(Agnes id + 实测 cell),选择器档位面变化:**`max` 档在全部三个 Agnes chat 模型上开放**(SenseNova 时代 max 是 glm 独占),`xhigh` 仅 `agnes-3.0-flash` 开放(2.0/2.5 被平台校验器 400,其自报合法集 `'none', 'low', 'medium', 'high' or 'max'` 不含 xhigh);`off/low/medium/high` 面不变。
61
+ - `live-contract` 新增 §2c `max_tokens` 上限双向护栏(上限须仍 200、两倍须仍 400),基线 `meta.maxTokensCap` 固化该事实;`docs/AGNES-API.md` §7.1/§7.2 的 ⏳ 待实测注记了结。
62
+
5
63
  ## [0.5.0] — 2026-10-01
6
64
 
7
65
  **独立仓库首次发布**:新包名 `dsh-connect-agnes-token-plan` 首次上 npm。全面更名并切换登录线(Agnes 一跳登录),额度模型改为账号级四窗口,新增视频生成 agent 工具与第三上游 AgnesCode。
@@ -20,6 +78,13 @@
20
78
  - Agnes 不发布 per-pool 余额,只在滑动窗口上封顶四个维度(5h 请求 / 周请求 / 日图 / 日视频),控制台只给上限与**累计**用量——`limit − total` 无人能负责,所以面板头条从「剩余」换成「限额」,累计用量单独一行(宁少一个数,也不发明一个)。
21
79
  - 控制台未连接时不再整页只剩登录表单;额度正常显示时不再误挂「需要重新登录」。
22
80
 
81
+ ### 窗口内已用量(上线实测推翻旧结论)
82
+
83
+ - **结论更正**:原来认为「控制台不提供窗口内的已用量」,实测 `/api/cn/user/subscription` 的 `usage` 块**就是**控制台「当前用量」那一屏的数据源,每窗口带 `used` / `limit` / `time_range_start` / `time_range_end` / `reset_at` / `reset_in_seconds` / `usage_pct`。旧结论让面板只显示上限、进度条永远缺席——数据一直在已下载的订阅响应里,只是没人解析。
84
+ - **新增 `parseSubscriptionUsage`**(`parsers.ts`):把 `usage` 归一成面板的四个窗口 key(`text_generation.windowed`→`requests5h`、`.weekly`→`requestsWeekly`、`image_generation.daily`→`imagesDaily`、`video_generation.daily`→`videoDaily`),时间戳按平台声明的 Asia/Shanghai 解析(UTC+8),缺字段读作 `null` 而不是 0。
85
+ - **`quota.windows[]` 并入平台给的 `used` / 窗口起止 / 重置时间**;客户端 `QuotaWindowCard` 在 `used` 存在时画进度条并显示「已用 x / limit · y%」与「重置 时间」。**仍然不做减法**:窗口用量是平台逐字转写的,账号累计是另一段周期,`limit − total` 依旧被拒绝。
86
+ - **契约与文案同步**:`EXPECTED_SHAPES.subscription` 由空数组填成真实身份键(`usage` 故意不要求,避免把「从未消费」误报成形状漂移);`quota.windowNote` 中英文案、`docs/AGNES-API.md` §4 / §6 / 端点表、`docs/API.md` 相应更正。
87
+
23
88
  ### 视频生成 agent 工具(可选,默认关)
24
89
 
25
90
  与出图对称新增 `agnes_video_generate`:面板开关 + 「建任务→轮询→取 url」状态机(`VIDEO_MAX_POLLS` 防呆、无 30s 冷却门)。
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # dsh-connect-agnes-token-plan
2
2
 
3
- Agnes 接入的 DSH **Plugins 页**插件卡**全家桶**(四个 tab):① **积分额度** tab——登录一次 Agnes 控制台,实时查看四类额度窗口与账号累计用量,令牌失效自动重登,之后无需再管;② **接入 API** tab——把 Agnes 模型注册为 DSH provider,参与对话与出图;③ **小浣熊** tab(可选、默认关)——微信扫码接入第二个上游 `xiaohuanxiong.com`;④ **AgnesCode** tab(可选、默认关)——读取本机 AgnesCode 桌面端登录态接入第三个上游。三条上游凭据相互独立。此外 429 自愈在后台生效:限频被误判为"额度耗尽"时在 Host 侧纠正回退避重试,模型不会无端消失。
3
+ Agnes 接入的 DSH **Plugins 页**插件卡**全家桶**(三个 tab):① **积分额度** tab——登录一次 Agnes 控制台,实时查看四类额度窗口与账号累计用量,令牌失效自动重登,之后无需再管;② **接入 API** tab——把 Agnes 模型注册为 DSH provider,参与对话与出图;③ **AgnesCode** tab(可选、默认关)——读取本机 AgnesCode 桌面端登录态接入桌面端上游。两条上游凭据相互独立。此外 429 自愈在后台生效:限频被误判为"额度耗尽"时在 Host 侧纠正回退避重试,模型不会无端消失。
4
4
 
5
5
  ## 功能
6
6
 
@@ -20,10 +20,9 @@ Agnes 的 Token Plan **按窗口限流**,不是积分余额——账号级四
20
20
  - **套餐对比**:平台**公开**的套餐目录(六档:入门版 / 专业版 / 高级版 × 月付 / 年付),无需登录即可读,用来回答"升级能买到什么"
21
21
  - **模型清单**:当前 Key 实际能调哪些模型,其中哪些能看图(按平台 `input_modalities` 判定,不靠名字猜)
22
22
  - **可选接入**:把 Agnes 模型接进 DSH 对话,思考强度可选;并可注册出图 / 视频工具
23
- - **第二个上游(默认关)**:面板「小浣熊」tab 微信扫码接入 `xiaohuanxiong.com`,独立凭据、独立 provider,与 Token Plan 互不干涉
24
- - **第三个上游(默认关)**:面板「AgnesCode」tab 读取本机 AgnesCode 桌面端的登录态,独立 provider 与独立积分池
23
+ - **桌面端上游(默认关)**:面板「AgnesCode」tab 读取本机 AgnesCode 桌面端的登录态,独立 provider 与独立积分池
25
24
 
26
- 面板**不代你操作账务**:不改套餐、不代扣额度、不碰 Key 明文;数据来自 Agnes 控制台自己的 API,与网页控制台口径一致。真正会「动」的四部分——注册 provider、挂出图工具、接第二个上游、接 AgnesCode——全部 opt-in 且**默认关闭**,不打开时插件退化为纯信息展示。
25
+ 面板**不代你操作账务**:不改套餐、不代扣额度、不碰 Key 明文;数据来自 Agnes 控制台自己的 API,与网页控制台口径一致。真正会「动」的四部分——注册 provider、挂出图工具、挂视频工具、接入 AgnesCode 桌面端上游——全部 opt-in 且**默认关闭**,不打开时插件退化为纯信息展示。
27
26
 
28
27
  **注册 provider 时**(面板开关打开),插件把 Agnes 模型接进 DSH 的对话模型选择器,并在 Host 侧纠正 peer 对限频 429 的误判(Agnes 把速率上限错命名为 `quota_exceeded_error`,会被判成额度耗尽而不重试)——限频真正退避重试,模型不再无端 "消失"。
29
28
 
@@ -68,11 +67,7 @@ Agnes 的 Token Plan **按窗口限流**,不是积分余额——账号级四
68
67
 
69
68
  面板「视频工具」卡(在「出图工具」下方,默认展开)打开开关后,Host 给 agent 注册工具 `agnes_video_generate`(首选模型由 `videoModelId` 指定),鉴权同样走 `AGNES_TOKEN_PLAN_API_KEY`。与出图**不同**的是协议:图片一次请求同步返回,视频是**异步任务制**——建任务后轮询到完成。**V2.0 与 2.5 两个参数体系都覆盖**,工具按选中模型分派请求体:V2.0(`agnes-video-v2.0`)走 `width`/`height`/`num_frames`/`frame_rate`,2.5(`agnes-video-2.5` / `agnes-video-2.5-flash`)走 `mode`/`seconds`/`size`/`aspect_ratio`。两套字段互斥、永不同时发给同一模型,但处理是**不对称**的:V2.0 帧数字段发到 2.5 模型会被换算成最接近的整秒(`121 @ 24fps → 5s`),保留「不判断家族也能出片」的退路;反过来,2.5 专有字段发到 V2.0 模型会**当场报错并给出修法**——工具不会静默丢弃,丢弃等于让你以为拿到 10 秒 2K、实际拿到 5 秒 720P。自动选择优先 V2.0,目录里没有 V2.0 时回落第一个 2.5 模型;面板仍会把 2.5 家族单独点名。协议细节与校验规则见 [docs/AGNES-API.md](docs/AGNES-API.md) §7.5。
70
69
 
71
- ## 第二个上游:小浣熊(可选,默认关)
72
-
73
- 面板「小浣熊」tab 用微信扫码登录 `xiaohuanxiong.com`,并以 provider id `sensenova-raccoon`(显示名 SenseNova Raccoon)注册**独立** provider。登录后显示积分余额与模型清单,每个模型带**上下文窗口 / 最大输出**与积分倍率(`free` / `×0.75` 这类,由网关目录声明;目录没给就不显示,不猜)。它与 Token Plan 同属**商汤(SenseTime)旗下**的两条产品线,所以放在同一个插件里顺理成章;但两者的**认证域与额度口径互不相通**(那边是独立积分余额,这边是四个限流窗口),凭据也各走一套——它不是 Token Plan 的第二条登录路径,实测依据见 [docs/ROADMAP.md](docs/ROADMAP.md) §6.1.1。
74
-
75
- ## 第三个上游:AgnesCode(可选,默认关)
70
+ ## 桌面端上游:AgnesCode(可选,默认关)
76
71
 
77
72
  面板「AgnesCode」tab 接的是 **AgnesCode 桌面端**的登录态:微信扫码发生在桌面 App 里,本插件只**读取** App 留在本机的加密会话文件(Chromium os_crypt,密钥经系统 DPAPI 解封,全程内存使用、不落盘不显示;解出的凭据随后存入 DSH 凭据服务,与账号密码同一纪律),并以 provider id `sensenova-agnescode`(显示名 SenseNova AgnesCode)注册**独立** provider。它的接口地址写在会话文件里、**按账号跟随**(钉死在 Agnes 域名族内,地址不对就拒绝使用);显示的积分是**订阅池**口径(时效 + 永久),模型清单带「会员」标记(会员门槛是账号状态,不是模型不存在,所以标记而不隐藏)。检测不到登录态时,面板逐条列出**探测过哪些文件、各自为什么没成**——「没装 App」「解不开密」「会话里没有令牌」是三种不同的处理方式,不会笼统叫你重新登录。JWT 有效期约 28 天,过期后开一次桌面 App 再点「检测本机登录态」即可;协议探针记录见 [docs/ROADMAP.md](docs/ROADMAP.md) §6.3。
78
73
 
@@ -81,7 +76,7 @@ Agnes 的 Token Plan **按窗口限流**,不是积分余额——账号级四
81
76
  provider / 出图开关的生效值存在插件私有状态文件里(`$DSH_HOME/state/<name>/`),不在任何配置或路由上——查"到底开没开"用 doctor,它只读状态文件、不碰凭据,Host 没起也能跑:
82
77
 
83
78
  ```powershell
84
- npm run doctor # 人读:每个 profile 的 provider / draw / video / raccoon / agnescode 开关与模型清单
79
+ npm run doctor # 人读:每个 profile 的 provider / draw / video / agnescode 开关与模型清单
85
80
  npm run doctor:json # 机器读:JSON(可进你的巡检 / 工单脚本)
86
81
  ```
87
82