dsh-llm-verifier 0.6.2 → 0.6.4
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/README.md +8 -3
- package/lib/client.js +49 -23
- package/lib/client.js.map +1 -1
- package/lib/index.js +334 -10
- package/lib/index.js.map +1 -1
- package/lib/types/client-fields.d.ts +4 -0
- package/lib/types/client-fields.d.ts.map +1 -1
- package/lib/types/client-fields.js +21 -4
- package/lib/types/client-fields.js.map +1 -1
- package/lib/types/client-i18n.d.ts +24 -0
- package/lib/types/client-i18n.d.ts.map +1 -1
- package/lib/types/client-i18n.js +16 -0
- package/lib/types/client-i18n.js.map +1 -1
- package/lib/types/client.d.ts.map +1 -1
- package/lib/types/client.js +9 -8
- package/lib/types/client.js.map +1 -1
- package/lib/types/config.d.ts +12 -0
- package/lib/types/config.d.ts.map +1 -1
- package/lib/types/config.js +13 -1
- package/lib/types/config.js.map +1 -1
- package/lib/types/engine.d.ts +3 -0
- package/lib/types/engine.d.ts.map +1 -1
- package/lib/types/engine.js +7 -1
- package/lib/types/engine.js.map +1 -1
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/index.js +45 -6
- package/lib/types/index.js.map +1 -1
- package/lib/types/pricing.d.ts +132 -0
- package/lib/types/pricing.d.ts.map +1 -0
- package/lib/types/pricing.js +279 -0
- package/lib/types/pricing.js.map +1 -0
- package/package.json +1 -1
- package/scripts/sync-installed-profiles.mjs +226 -21
- package/src/client-fields.test.ts +2 -0
- package/src/client-fields.ts +27 -4
- package/src/client-i18n.ts +16 -0
- package/src/client.test.ts +59 -0
- package/src/client.tsx +11 -12
- package/src/config.ts +25 -1
- package/src/engine.ts +8 -2
- package/src/index.ts +45 -6
- package/src/pricing.test.ts +174 -0
- package/src/pricing.ts +324 -0
package/README.md
CHANGED
|
@@ -294,7 +294,11 @@ flowchart LR
|
|
|
294
294
|
| **缓存条目上限** | 成功评分持久化缓存的最大容量条目数 |
|
|
295
295
|
| **重试基础延迟 (ms)** | 重试时指数退避的基数,默认 500 |
|
|
296
296
|
| **缓存目录 (Cache directory)** | 评分缓存 / 能力记忆 / 统计文件在话题目录下的相对子目录,默认 `verifier`;留空保存时保留原值 |
|
|
297
|
-
|
|
|
297
|
+
| **输入 / 输出价格** | 手填的 USD/百万 token 单价。**留 0 即交给自动定价**;一旦填了任意一个,整组就以手填为准 |
|
|
298
|
+
| **缓存读取价格** | 缓存命中输入 token 的单价;留 0 时退回按输入价计算(旧口径,会把缓存密集的调用算贵)。真实的 cache-read 单价常是输入价的 1/50 |
|
|
299
|
+
| **本机模型目录自动定价** | 默认开。本机安装的 pi-ai 模型目录(models.dev 快照,`@earendil-works/pi-ai/dist/providers/data`,约 1350 条)里有这条 provider+模型时自动取单价,**纯离线、零配置** |
|
|
300
|
+
| **在线价格库兜底** | 默认开。本机目录查不到时向 models.dev 查一次(4.6 MB 快照,进程内缓存 24 小时),手填或目录命中时**完全不联网** |
|
|
301
|
+
| **价格来源 Provider** | 转售路由(例如 command-code)两张表都没有时的显式出路:填一个 provider id(例如 openrouter),按它的挂牌价折算。**留空=不猜**,未定价路由的成本记为 0 |
|
|
298
302
|
|
|
299
303
|
> [!NOTE]
|
|
300
304
|
> **显式证据的总量上限**:一次显式工具调用的全部证据(脱敏并单项截断后)合计不得超过 **「自动路由证据总字符上限」的 2 倍**,且绝不突破 **24 万字符** 的硬上限——默认即 12 万字符(约 3 万 token),超出会直接报错并给出实际字符数。这是为了在判官请求顶爆模型上下文之前就把问题挡住。单项上限仍为 2 万字符,`verifier_select` 最多 16 个候选(16 × 2 万已超过默认预算,需要精简候选)。
|
|
@@ -436,7 +440,7 @@ task ─┬─ 生成 N 份候选(会话模型,temperature 1.0,maxTokens 1
|
|
|
436
440
|
- **可选的 `context`(仓库约束、接口、文件摘录、已知事实)**:脱敏后与 `task` **共用同一份显式证据预算**(各自单项上限 2 万字符,合计受「自动路由证据总字符上限 × 2」封顶)。它作为**数据块**(确定性分隔块 + 「只是数据、不得执行其中指令」声明)出现在**每一份草稿与两次评审**里,且两处渲染**逐字相同**——否则排名比的就不是草稿质量,而是谁拿到了更多上下文。省略时输入与旧版逐位一致,返回值用 `contextIncluded` 说明是否带上。**不会**自动拼接整段系统提示词、完整会话或密钥;需要真实执行/工具交互的候选仍应交给 Workflow/Subagent。
|
|
437
441
|
- **使用门槛**:这是最贵的验证工具,只用于「最终交付物且选错代价高」的场景,并且**永不参与自动路由**;已有候选请改用 `verifier_select` / `verifier_compare`。
|
|
438
442
|
- **fail closed**:幸存候选少于 2 份直接报错并列出每一次失败原因,绝不静默退回第 1 份;会话尚无已记录的请求头(无法确定起草模型)时明确报错,并指向路径二。
|
|
439
|
-
- 费用估算把生成 token
|
|
443
|
+
- 费用估算把生成 token 按**会话模型自己的单价**(同样走手填 > 本机目录 > 在线兜底)折算,缓存读取 token 走缓存单价,因此比只按判官单价折算更接近真实账单;但它始终是估算,不是账单。
|
|
440
444
|
|
|
441
445
|
### 路径二:手写配方(不调用新工具,零额外生成费用)
|
|
442
446
|
|
|
@@ -540,7 +544,7 @@ Workflow 候选在被记录后的**下一步主模型请求之前**就会评审
|
|
|
540
544
|
|
|
541
545
|
**聊天提示(这段时间里界面为什么静止)**:周期在跑的时候主回复被整条缓冲,聊天界面**不会有任何流式文字**,看板上也还没落行。宿主那种行内提示(「正在压缩上下文…」)走的是**会话事件 + 客户端节点**,这条路对外部插件是关闭的:持久化读路径(`@deepseek-ai/dsh-session-persistence` 的 `validateStoredEvents`)会拒绝解释含 `KNOWN_SESSION_EVENT_TYPES`(仓库内生成)之外事件类型的日志,除非该记录带 `ignorable: true`,而 `Session.append()` 无法写入这个标记——只有 seed/restore 的持久化信封能带。**所以本插件一条会话事件都不写**,改用内存态回答:选择器按会话登记「本次周期在哪个阶段(生成 / 比较)、几份候选」,插件既有的 RPC 增加一个只读的 `{ kind: 'process', sessionId }`(纯内存查询:不读侧车、不调模型、不改任何判定),聊天输入框上方的 dock 只在**回合运行中、或刚结束的 20 秒内**轮询它,依次显示「正在过程选优:生成 N 份候选…」→「裁判比较 N 份候选…」→「已改用更优的回复 / 保留原回复 / 备选与原回复相同 / 未完成」。它**不进模型历史、不写会话日志、不参与任何判定**;重载后什么都不显示(那个周期确实已经不存在)。长期记录仍然只有统计看板。
|
|
542
546
|
|
|
543
|
-
同一块指示器也覆盖**自动路由与最终验收**:它们跑在 `agent/turn-stopping` 里,回复已经在屏幕上,但回合会一直开着等裁判(`compare` / `select` / `track` 各 6 次调用起,`select` 随候选数与对数上升;最终验收是判据数 × 轮次 × 裁判数)。发布点是**路由器的预约状态机**——那是唯一知道「一个周期被批准了、什么时候结算」的地方(`RouterCycleObserver`,可选且异常安全:一个坏掉的观察者绝不能改变预约、预算或判决),P06 自己的周期则由选择器发布更细的相位。于是这些窗口会显示「正在识别需要独立复核的对象…」→「正在比较候选方案 / 为多个候选排名 / 复核任务进度(约 N 次调用)…」,最终验收结束时给一次「最终验收通过 / 未通过」——**通过时宿主本来一句话都不说,这一行是唯一能看见它的地方**。这一行是**输入框上方的 dock 卡片**,几何与颜色都跟宿主同层的 Todo / Goal / Queue 卡片同族(同一条内容宽度轴:聊天内容列减去左右留白与四个 dock 内缩,高 36px、圆角 12px、底色 `--dsw-specific-tip`),状态点用宿主的 `StateDot`(进行中 / 完成 / 失败),容器带 `role="status"
|
|
547
|
+
同一块指示器也覆盖**自动路由与最终验收**:它们跑在 `agent/turn-stopping` 里,回复已经在屏幕上,但回合会一直开着等裁判(`compare` / `select` / `track` 各 6 次调用起,`select` 随候选数与对数上升;最终验收是判据数 × 轮次 × 裁判数)。发布点是**路由器的预约状态机**——那是唯一知道「一个周期被批准了、什么时候结算」的地方(`RouterCycleObserver`,可选且异常安全:一个坏掉的观察者绝不能改变预约、预算或判决),P06 自己的周期则由选择器发布更细的相位。于是这些窗口会显示「正在识别需要独立复核的对象…」→「正在比较候选方案 / 为多个候选排名 / 复核任务进度(约 N 次调用)…」,最终验收结束时给一次「最终验收通过 / 未通过」——**通过时宿主本来一句话都不说,这一行是唯一能看见它的地方**。这一行是**输入框上方的 dock 卡片**,几何与颜色都跟宿主同层的 Todo / Goal / Queue 卡片同族(同一条内容宽度轴:聊天内容列减去左右留白与四个 dock 内缩,高 36px、圆角 12px、底色 `--dsw-specific-tip`),状态点用宿主的 `StateDot`(进行中 / 完成 / 失败),容器带 `role="status"`,所以「通过」对读屏同样可达;它不是一条横贯窗口的状态行。**这张卡片只有一个元素**:宽度轴与表面(描边、圆角、底色)声明在同一个盒子上——composer stack 是宿主区域,宿主或皮肤样式表可以给 dock 行刷底,多一层「宽而无底」的 wrapper 会让那层底在卡片两侧露出一条遮罩(见 `.agents/notes/implemented/bug-fix/2026-09-15-single-element-activity-card.md`),`client.test.ts` 的 `client activity card structure` 锁死了这一点。计划预审与 Team 任务闸**不进**这块指示器:前者本来就有宿主的挂起工具行,后者窗口极短,加进去只是噪音。
|
|
544
548
|
|
|
545
549
|
### 定位诊断(Findings)与 smart 调度(P04)
|
|
546
550
|
|
|
@@ -569,6 +573,7 @@ Workflow 候选在被记录后的**下一步主模型请求之前**就会评审
|
|
|
569
573
|
- **两种"缓存命中率"要分清**:看板的「评分缓存命中率」是**本地评分缓存**命中(命中即不发模型请求),「前缀缓存命中率」是**模型服务端**按 token 计费口径统计的前缀命中(`cachedInputTokens / (inputTokens + cachedInputTokens)`,DSH 报告的两者是**不相交**的计数)。前者衡量省了多少次调用,后者衡量省了多少输入 token;只优化后者不会改变任何判决,而把两者混为一谈会让人误以为省钱优化无效。
|
|
570
574
|
- **看板与设置页只用宿主真实存在的主题 token**:所有颜色都写成 `--dsw-alias-*` / `--dsw-specific-*` / `--dsw-static-*` 里的名字,浅色与深色由宿主 token 表解析,不读主题标记、不手写两套色。原因见 `.agents/notes/implemented/bug-fix/2026-09-14-client-theme-tokens-and-activity-chip-geometry.md`:CSS 对取不到值的 `var()` **静默丢弃声明**,所以写错 token 名既不会被构建、类型检查也不会被单测发现,历史上就因此让看板在浅色主题下画出一片深色卡片。`src/client.test.ts` 里的 `client design tokens` 用例现在会双向校验这份名单(用了未登记的名字、或登记了没用的名字,都会失败)。
|
|
571
575
|
- **能力记忆**:当某个 Provider/Model 明确拒绝 `logprobs` 参数后,插件会记住该能力探测结果,避免后续每次调用重复报错。探测结果按话题持久化到 verifier 目录的 `capabilities-v1.json`(24 小时 TTL 后自动重新探测),随话题一并删除;跨进程与会话恢复不再重复探测,首次降级并发窗口内的相同请求也会合并在途调用、不重复计费。
|
|
576
|
+
- **自动定价的三层来源**(`src/pricing.ts`):手填单价 > 本机 pi-ai 模型目录 > models.dev(可选)。宿主**不向插件暴露任何价格**——`@deepseek-ai/dsh-llm` 的 usage 与 `resolveModel` 没有价格字段,`llm-pi-ai` 还明确把 pi-ai 的 cost 元数据归零("no consumer reports spend")——所以价格只能由插件自己找。匹配**只认精确的 provider + model**:同一个 model id 在 models.dev 上有 21 家 provider 挂牌、价差 6.5 倍(0.10/0.40 ↔ 0.65/1.45),跨 provider 取价等于往成本列写一个编造的数字,插件因此**绝不猜**;转售路由要用 `priceProviderOverride` 明确指定跟随谁的挂牌价,否则老老实实记为未定价(0)。两层目录都是「读不到就退到下一层」,任何一种失败都不会影响判定。判官自检会回报当前判官实际生效的单价与来源。
|
|
572
577
|
|
|
573
578
|
## 隐私与数据安全边界
|
|
574
579
|
|
package/lib/client.js
CHANGED
|
@@ -124,6 +124,14 @@ window.__ModuleLoader__.load({
|
|
|
124
124
|
"field.estimatedInputUsdPerMillion.help": "每百万输入 Token 的美元价格,仅用于统计估算。",
|
|
125
125
|
"field.estimatedOutputUsdPerMillion.title": "输出价格",
|
|
126
126
|
"field.estimatedOutputUsdPerMillion.help": "每百万输出 Token 的美元价格,仅用于统计估算。",
|
|
127
|
+
"field.estimatedCachedInputUsdPerMillion.title": "缓存读取价格",
|
|
128
|
+
"field.estimatedCachedInputUsdPerMillion.help": "每百万缓存命中输入 Token 的美元价格;留 0 时退回按输入价格计算(旧口径,对缓存密集的调用会高估)。",
|
|
129
|
+
"field.autoPriceFromCatalog.title": "从本机模型目录自动定价",
|
|
130
|
+
"field.autoPriceFromCatalog.help": "本机安装的 pi-ai 模型目录(models.dev 快照)里有这条 provider/模型时自动取出单价。手填的价格永远优先;目录里没有就交给在线价格库。",
|
|
131
|
+
"field.autoPriceOnline.title": "在线价格库兜底",
|
|
132
|
+
"field.autoPriceOnline.help": "本机目录查不到时向 models.dev 查一次(结果缓存 24 小时)。只按 provider + 模型精确匹配,绝不跨 provider 猜价——同一个模型 id 在不同转售商手里能差 6 倍。",
|
|
133
|
+
"field.priceProviderOverride.title": "价格来源 Provider",
|
|
134
|
+
"field.priceProviderOverride.help": "转售路由(例如 command-code)两张价格表里都没有时,填一个 provider id(例如 openrouter),按它的挂牌价折算。留空表示不猜:未定价的路由成本记为 0。",
|
|
127
135
|
"settings.catalogFailures": "部分模型目录读取失败",
|
|
128
136
|
"settings.saved": "设置已保存。",
|
|
129
137
|
"settings.reload": "重新载入",
|
|
@@ -433,6 +441,14 @@ window.__ModuleLoader__.load({
|
|
|
433
441
|
"field.estimatedInputUsdPerMillion.help": "USD price per million input tokens, for statistical estimation only.",
|
|
434
442
|
"field.estimatedOutputUsdPerMillion.title": "Output Price",
|
|
435
443
|
"field.estimatedOutputUsdPerMillion.help": "USD price per million output tokens, for statistical estimation only.",
|
|
444
|
+
"field.estimatedCachedInputUsdPerMillion.title": "Cached Input Price",
|
|
445
|
+
"field.estimatedCachedInputUsdPerMillion.help": "USD per million cached prompt tokens. Left at 0 it falls back to the input price, which is the old estimate and over-reports cache-heavy calls.",
|
|
446
|
+
"field.autoPriceFromCatalog.title": "Auto Price From Catalog",
|
|
447
|
+
"field.autoPriceFromCatalog.help": "Price this judge route from the installed pi-ai model catalog (a models.dev snapshot). Typed prices always win; a route the catalog does not describe moves on to the online lookup.",
|
|
448
|
+
"field.autoPriceOnline.title": "Online Price Lookup",
|
|
449
|
+
"field.autoPriceOnline.help": "When the installed catalog has no entry, query models.dev once (cached for 24 hours). Matching is exact provider + model only — prices are never guessed across providers, where the same model id can differ sixfold.",
|
|
450
|
+
"field.priceProviderOverride.title": "Price Source Provider",
|
|
451
|
+
"field.priceProviderOverride.help": "For a reseller route neither price table knows (for example command-code), name the provider whose list price to follow (for example openrouter). Empty means never guess and leave the route unpriced.",
|
|
436
452
|
"settings.catalogFailures": "Some model catalogs failed to load",
|
|
437
453
|
"settings.saved": "Settings saved.",
|
|
438
454
|
"settings.reload": "Reload",
|
|
@@ -1311,6 +1327,10 @@ window.__ModuleLoader__.load({
|
|
|
1311
1327
|
cacheMaxEntries: 1e4,
|
|
1312
1328
|
estimatedInputUsdPerMillion: 0,
|
|
1313
1329
|
estimatedOutputUsdPerMillion: 0,
|
|
1330
|
+
estimatedCachedInputUsdPerMillion: 0,
|
|
1331
|
+
autoPriceFromCatalog: true,
|
|
1332
|
+
autoPriceOnline: true,
|
|
1333
|
+
priceProviderOverride: "",
|
|
1314
1334
|
autoVerifySubagents: false,
|
|
1315
1335
|
extraJudges: []
|
|
1316
1336
|
};
|
|
@@ -1536,8 +1556,12 @@ window.__ModuleLoader__.load({
|
|
|
1536
1556
|
integer: true,
|
|
1537
1557
|
unitKey: "settings.unit.ms"
|
|
1538
1558
|
}),
|
|
1559
|
+
toggle("autoPriceFromCatalog", "cost"),
|
|
1560
|
+
toggle("autoPriceOnline", "cost"),
|
|
1561
|
+
text("priceProviderOverride", "cost", true),
|
|
1539
1562
|
number("estimatedInputUsdPerMillion", "cost", { min: 0 }),
|
|
1540
|
-
number("estimatedOutputUsdPerMillion", "cost", { min: 0 })
|
|
1563
|
+
number("estimatedOutputUsdPerMillion", "cost", { min: 0 }),
|
|
1564
|
+
number("estimatedCachedInputUsdPerMillion", "cost", { min: 0 })
|
|
1541
1565
|
];
|
|
1542
1566
|
function fieldsOfSection(section) {
|
|
1543
1567
|
return FIELDS.filter((field) => field.section === section);
|
|
@@ -1619,6 +1643,10 @@ window.__ModuleLoader__.load({
|
|
|
1619
1643
|
cacheMaxEntries: numberOr("cacheMaxEntries"),
|
|
1620
1644
|
estimatedInputUsdPerMillion: numberOr("estimatedInputUsdPerMillion"),
|
|
1621
1645
|
estimatedOutputUsdPerMillion: numberOr("estimatedOutputUsdPerMillion"),
|
|
1646
|
+
estimatedCachedInputUsdPerMillion: numberOr("estimatedCachedInputUsdPerMillion"),
|
|
1647
|
+
autoPriceFromCatalog: v.autoPriceFromCatalog !== false,
|
|
1648
|
+
autoPriceOnline: v.autoPriceOnline !== false,
|
|
1649
|
+
priceProviderOverride: typeof v.priceProviderOverride === "string" ? v.priceProviderOverride.trim() : "",
|
|
1622
1650
|
autoVerifySubagents: v.autoVerifySubagents === true,
|
|
1623
1651
|
extraJudges: normalizeExtraJudges(v.extraJudges)
|
|
1624
1652
|
};
|
|
@@ -1725,7 +1753,7 @@ window.__ModuleLoader__.load({
|
|
|
1725
1753
|
});
|
|
1726
1754
|
continue;
|
|
1727
1755
|
}
|
|
1728
|
-
if (field.kind === "text" && field.key !== "criteriaFile" && field.key !== "label" && field.key !== "autoProcessAlternativeModel") {
|
|
1756
|
+
if (field.kind === "text" && field.key !== "criteriaFile" && field.key !== "label" && field.key !== "autoProcessAlternativeModel" && field.key !== "priceProviderOverride") {
|
|
1729
1757
|
const value = typeof raw === "string" ? raw.trim() : "";
|
|
1730
1758
|
if (!value) {
|
|
1731
1759
|
issues.push({
|
|
@@ -4468,18 +4496,19 @@ window.__ModuleLoader__.load({
|
|
|
4468
4496
|
* four dock insets — and the fallbacks below only matter on a host that does not publish the three
|
|
4469
4497
|
* custom properties. Without this clamp the status line stretches to the window edge and its text
|
|
4470
4498
|
* sits far left of the composer it belongs to, which is exactly the misplacement it is here to fix.
|
|
4499
|
+
*
|
|
4500
|
+
* ONE element owns BOTH the dock-column width and the card surface. The composer stack is a host
|
|
4501
|
+
* region a host or skin stylesheet may paint (the dock row, for instance with the tip surface), and
|
|
4502
|
+
* a wider wrapper that paints no background of its own would show that paint as a mask reaching
|
|
4503
|
+
* well past the card on both sides. The surface here is declared inline, so it is itself the card:
|
|
4504
|
+
* a background can never be painted outside the border box it is declared on.
|
|
4471
4505
|
*/
|
|
4472
|
-
const
|
|
4473
|
-
boxSizing: "border-box",
|
|
4474
|
-
width: "calc(100% - var(--dsh-composer-side-clearance, 16px) - var(--dsh-composer-side-clearance, 16px) - var(--dsh-composer-dock-inset, 8px) - var(--dsh-composer-dock-inset, 8px) - var(--dsh-composer-dock-inset, 8px) - var(--dsh-composer-dock-inset, 8px))",
|
|
4475
|
-
margin: "0 auto"
|
|
4476
|
-
};
|
|
4477
|
-
const activityBar = {
|
|
4506
|
+
const activityCard = {
|
|
4478
4507
|
boxSizing: "border-box",
|
|
4479
4508
|
display: "flex",
|
|
4480
4509
|
alignItems: "center",
|
|
4481
4510
|
gap: 10,
|
|
4482
|
-
width: "100%",
|
|
4511
|
+
width: "calc(100% - var(--dsh-composer-side-clearance, 16px) - var(--dsh-composer-side-clearance, 16px) - var(--dsh-composer-dock-inset, 8px) - var(--dsh-composer-dock-inset, 8px) - var(--dsh-composer-dock-inset, 8px) - var(--dsh-composer-dock-inset, 8px))",
|
|
4483
4512
|
maxWidth: "calc(var(--dsh-composer-card-max-width, 952px) - 4 * var(--dsh-composer-dock-inset, 8px))",
|
|
4484
4513
|
height: 36,
|
|
4485
4514
|
margin: "0 auto",
|
|
@@ -4546,20 +4575,17 @@ window.__ModuleLoader__.load({
|
|
|
4546
4575
|
]);
|
|
4547
4576
|
if (rendered === null) return null;
|
|
4548
4577
|
const dotState = rendered.tone === "busy" ? "ongoing" : rendered.tone === "ok" ? "done" : "error";
|
|
4549
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.
|
|
4550
|
-
style:
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
|
|
4554
|
-
|
|
4555
|
-
|
|
4556
|
-
|
|
4557
|
-
|
|
4558
|
-
|
|
4559
|
-
|
|
4560
|
-
children: rendered.text
|
|
4561
|
-
})]
|
|
4562
|
-
})
|
|
4578
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4579
|
+
style: activityCard,
|
|
4580
|
+
role: "status",
|
|
4581
|
+
"aria-live": "polite",
|
|
4582
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, {
|
|
4583
|
+
state: dotState,
|
|
4584
|
+
size: 8
|
|
4585
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4586
|
+
style: activityTextStyle,
|
|
4587
|
+
children: rendered.text
|
|
4588
|
+
})]
|
|
4563
4589
|
});
|
|
4564
4590
|
}
|
|
4565
4591
|
/**
|