@lynn123411/dsh-subagent-judge-dispatch 0.1.1 → 0.3.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/DETAILS.md +15 -7
- package/README.md +3 -3
- package/lib/client.js +129 -129
- package/lib/client.js.map +2 -2
- package/lib/index.js +67 -26
- package/lib/index.js.map +2 -2
- package/package.json +17 -15
package/DETAILS.md
CHANGED
|
@@ -35,7 +35,11 @@ dsh plugin --profile web add @lynn123411/dsh-subagent-judge-dispatch
|
|
|
35
35
|
|
|
36
36
|
- **插手位置**:宿主的 `agent/request` 瀑布。注册在根层上下文,所以每个代理的每次请求都会经过;插件自己用 `subagentDepth`(会话头里的 `delegationDepth` 与运行时 `options.subagentDepth` 取较大者)筛出子代理。
|
|
37
37
|
- **判断次数**:按子代理 id 记住已判过的,一个跑十步的子代理只问一次。
|
|
38
|
-
-
|
|
38
|
+
- **判断模型读到的任务**:先是派出这次活的标签(`subagent/descriptor` 的 `label`,宿主用它当子会话标题),再是任务正文原文,两段之间空一行。标签只有三五个词,是派工方写的摘要;正文才是「这个活到底要做什么」。只发标签,判断只能看出个大概方向;只发正文,遇到开头是套话的任务就丢了派工方的意图。
|
|
39
|
+
- **任务正文怎么取**:取子代理自己那条 `source.kind === 'user'` 的消息。用户角色不等于任务——工作目录提示、工作区指令、运行时快照、技能清单、时间快照都写成用户消息,按来源筛才分得开。宿主的返回指引(「你的父代理 id 是……完事用 `send_message` 回报」)是那条消息末尾追加的一个文本块,讲的是怎么交作业,不算任务,取正文时整块去掉。
|
|
40
|
+
- **只读子代理自己的事件**:`ownEvents()`(或 `snapshotEvents(inheritedEventCount)`)是子代理自己产生的那一段。**不能从日志开头读**:叉出来的子代理,日志前缀是父代理已完成的回合,从开头读会把祖先的标签和父对话的第一条消息送给判断模型。
|
|
41
|
+
- **长任务按头尾截**:正文留开头 1400 字与结尾 400 字,中间省掉多少字写在省略号里(`… (N characters omitted) …`)。补充要求常写在末尾,所以留尾不留中;把省掉的字数写出来,读者看日志里那段请求才分得清「截断了」和「本来就这么短」。这句标记用英文,是判断协议本身的语言——中文写在英文任务里像任务的一部分,读者与判断模型都会读岔。
|
|
42
|
+
- **日志那一栏与判断输入分开算**:表格「子代理」一栏只放派工标签(没有标签时退回正文开头,截到 60 字),不把判断模型读过的那一整段塞回去——那一整段在同一行的弹窗里能看到。
|
|
39
43
|
- **判断协议**:`POST` 到页面填的地址,请求体 `{ model, state: { message }, questions }`;`questions` 只有一个 `task_type`,类型是 `choice`,`criteria` 就是你的类型清单(键是编号、值是你写的描述),答复取被选中选项的编号。
|
|
40
44
|
- **写入铁律**:模型、强度、提供方三项一起写。`resolveChildAgentOptions` 在「换了模型但没给强度」时会删掉继承来的强度,所以三项必须同进同出。
|
|
41
45
|
- **兜底**:任何失败都一个字段都不写,把宿主解析好的那个调用配置按身份原样退回——不是「把主代理的值再写一遍」,而是根本不碰它。这是 `decideRewrite` 返回 `none`、`applyDecision` 原样返回入参所保证的。
|
|
@@ -46,7 +50,10 @@ dsh plugin --profile web add @lynn123411/dsh-subagent-judge-dispatch
|
|
|
46
50
|
- **两节各存各的**:判断服务(含两个开关、端点、判断模型、密钥)与任务类型清单各有一个保存按钮,各写自己那几个字段。类型清单那一节的描述空着或两条重了时,只有它自己的保存会拒绝并弹窗说明;判断服务那一节照常能存。保存失败的提示也按节归位,不会跑到另一节下面去。
|
|
47
51
|
- **保存按下之后**:密钥先写,再写设置。密钥没写进去就不再动设置;设置被宿主拒绝(共享配置表单 resolve `false` 是拒绝,不是异常)时页面必须报没存上,不能显示成已保存。
|
|
48
52
|
- **草稿按字段保留**:宿主每次发布配置,只有读者改过、且改动与「本页上次看到的已提交值」不同的那一项才留在页面上,其余跟着宿主走。按整节保留会让一次保存把读者没碰过的字段写回去,等于撤掉别的页面刚做的改动。
|
|
49
|
-
-
|
|
53
|
+
- **放弃改动只丢草稿**:放弃判断服务那一节,只清掉还没交出去的文本与那几项设置;密钥已经存进凭据文件,页面因此不会改口说「还没有密钥」。
|
|
54
|
+
- **试通与预览跟着判断服务那一节走**:两个按钮放在这一节保存行的右端,左边写下去、右边查这一份。试通不落盘(它只是问一句),预览要求先把改动保存下来——两者都在标题栏下面,而不是标题那一行:那里是整节的标题,不是一套设置的出口。
|
|
55
|
+
- **最近判断是一张六列表**:结果(`类型 3` / `未判成`)、选择(`供应商 · 模型 · 强度`)、主代理、子代理、时间、耗时。结果在最左,读者扫一眼先看「判成了没有」;没判成的原因不在格子里展开,悬停才说——那一列宽度是给编号留的。放不下的格子截断,气泡用宿主的 `Tooltip`(原生 `title` 键盘够不到)。
|
|
56
|
+
- **点一行看的是这段提示词**:弹窗里只有这次真正发给判断模型的请求体,任务文字也在里面。结果、选择、主代理这几项行上已经有了,弹窗不再各列一遍。这条请求体由发出请求的那一处格式化后原样存进日志,页面没有第二次拼装的机会——`scripts/smoke-host.mjs` 断言日志里那一段与发出去的请求体同值。
|
|
50
57
|
- **密钥固定引用**:引用名是插件自己的常量 `SUBAGENT_JUDGE_API_KEY`,不是页面填的字段——读者只要把密钥贴进来,不必知道什么是凭据引用。密钥值交给凭据服务之后立刻从页面状态里清掉,`scripts/test-card.mjs` 有一条断言守着它不出现在状态里。密钥格与上面两格同宽;页面没有凭据通道(非回环地址)时,输入框与「删掉密钥」都禁用,并有一行字说明原因。
|
|
51
58
|
|
|
52
59
|
## 开发副本
|
|
@@ -58,7 +65,7 @@ cd ~/.dsh/profiles/web && pnpm add "link:<my-dsh 绝对路径>/plugins/dsh-subag
|
|
|
58
65
|
cd <my-dsh 绝对路径>/plugins/dsh-subagent-judge-dispatch && pnpm install && pnpm build
|
|
59
66
|
```
|
|
60
67
|
|
|
61
|
-
|
|
68
|
+
客户端半边改完刷新页面即生效,必要时强制刷新一次;宿主半边改完要触发一次 profile 重新组合——在插件页或 `plugin_manager` 里把本插件关一次再开一次,不必重启进程。
|
|
62
69
|
|
|
63
70
|
## 验证
|
|
64
71
|
|
|
@@ -68,13 +75,14 @@ cd <my-dsh 绝对路径>/plugins/dsh-subagent-judge-dispatch && pnpm install &&
|
|
|
68
75
|
cd plugins/dsh-subagent-judge-dispatch && pnpm check
|
|
69
76
|
```
|
|
70
77
|
|
|
71
|
-
`check` = `typecheck` + `build` +
|
|
78
|
+
`check` = `typecheck` + `build` + 五个自检 + `assert:lib-untracked`:
|
|
72
79
|
|
|
73
|
-
- **`scripts/test-decision.mjs`** 打的是 `src/`(Node 直接跑 `.ts`),守判断与改写这条纯逻辑:失败时**按身份**退回同一个对象(不是深比较——深比较会放过「复制一份再写回原值」这种仍然算覆盖的写法)、三项同写、残缺行不生效、答复读取的三种形状与七种空答复、四种失败原因各自的归类、超时不重试、日志留 20 条且读出来是副本、编号按位置从 1
|
|
74
|
-
- **`scripts/smoke-host.mjs`** 起真 cordis `Context`,把 `agent/request` 瀑布按宿主的方式跑一遍(`await next()`
|
|
80
|
+
- **`scripts/test-decision.mjs`** 打的是 `src/`(Node 直接跑 `.ts`),守判断与改写这条纯逻辑:失败时**按身份**退回同一个对象(不是深比较——深比较会放过「复制一份再写回原值」这种仍然算覆盖的写法)、三项同写、残缺行不生效、答复读取的三种形状与七种空答复、四种失败原因各自的归类、超时不重试、日志留 20 条且读出来是副本、编号按位置从 1 连着。它还守判断模型读到的输入:标签在前正文在后、没标签时只发正文、两样都没有时输入为空、短任务一字不动、长任务留头尾并写明省掉多少字、刚好到上限的不算截断。另有一条守「判断带回的提示词就是发出去的那一段」:成功、失败、没发出请求三种情形各一条。
|
|
81
|
+
- **`scripts/smoke-host.mjs`** 起真 cordis `Context`,把 `agent/request` 瀑布按宿主的方式跑一遍(`await next()` 拿到解析好的配置,再把返回值交给断言):主代理不被判断、同一子代理只判一次、两个开关各自的短路、发送出去的请求体形状、判断输入是标签加正文两段、正文按 `source.kind` 取(工作目录提示不算任务)、宿主追加的返回指引不送进去、长任务留头尾且写明省掉多少字、没有描述时取任务正文、叉出来的子代理只读自己的事件、日志的子代理一栏只写标签、判断过的记忆有上限。它的夹具照真实日志的形状搭:先是 `working-directory` 的通知,再是带返回指引的派工消息。它另起一个挂着 `connection` 的实例,从日志路由读回那一行,断言 `prompt` 与真正发出去的请求体同值——判断成功与判断失败各一条。
|
|
75
82
|
- **`scripts/smoke-client.mjs`** 按 Web shell 的方式装载 `lib/client.js`(`window.__ModuleLoader__.load` 桩件),喂假 cordis 服务:断言卡片注册进 `plugins.bundle.config`、key 是包名、走 `slots.inject`、读本插件自己的命名空间与宿主那份「子代理可选用哪些模型」设置、以宿主在服务本条目为挂载条件、样式表在 `apply()` 追加一次且没写死色值,以及 zh/en 键集一致。它的守卫带反例断言(「守卫拒绝未声明的服务读取」必须抛),否则那一串绿灯是假的。
|
|
76
83
|
|
|
77
|
-
- **`scripts/test-card.mjs`** 打的是 `src/`,守配置卡片这层状态机:两节各存各的、清单没填全不挡端点、宿主回 `false`
|
|
84
|
+
- **`scripts/test-card.mjs`** 打的是 `src/`,守配置卡片这层状态机:两节各存各的、清单没填全不挡端点、宿主回 `false` 算没存上、密钥跟着判断服务那次保存一起写且写的是固定引用名、密钥值从不进页面状态、草稿按字段保留(宿主改了一项而我在改另一项时,保存只写我改的那一项),以及「选择」一列把三项连成一段且不留悬空的分隔点。
|
|
85
|
+
- **`scripts/test-render.mjs`** 用真 react 把卡片画进 jsdom:试通与预览在判断服务那一节的保存行里、标题栏不再有按钮,日志表是六列且顺序固定,结果写「类型 3」/「未判成」,选择是连成的一段,没判成的原因挂在宿主的 `Tooltip` 上而不是原生 `title`,弹窗里只有那段提示词且不把行上的栏目再列一遍。`ui-primitives` 走替身(真组件是浏览器 ESM、带 `.css` 导入,Node 里跑不起来),所以它验的是本插件的视图结构,外观与浮层定位要在真浏览器里看。
|
|
78
86
|
|
|
79
87
|
`lib/` 是构建镜像,`assert:lib-untracked` 判它没被 git 跟踪。
|
|
80
88
|
|
package/README.md
CHANGED
|
@@ -4,13 +4,13 @@
|
|
|
4
4
|
|
|
5
5
|
## 功能
|
|
6
6
|
|
|
7
|
-
-
|
|
7
|
+
- **按任务类型指派**:每次派工把派出这次活的标签和任务正文交给判断服务,由它从你的类型清单里挑一个编号,插件按这个编号对应的设置改写子代理的模型与思考强度。
|
|
8
8
|
- **清单由你写**:任务类型是一张表格,每一行写一段判定依据、选一个模型、选一个思考强度;模型与强度两栏各是一个下拉。模型从宿主那份「子代理可选用哪些模型」设置里读,强度从该模型自己声明的档位里读。
|
|
9
9
|
- **预制词条**:研发流程常见的八类活各带一句判定依据和一句建议强度,点一下就把这句依据写进描述列,写进去之后就当是你自己写的。建议强度只是提示,模型与强度两栏不会自动填。
|
|
10
|
-
-
|
|
10
|
+
- **完整预览**:看一眼真正会发给判断服务的整段内容,派工标签与任务正文那两处标注「派工时才填」。
|
|
11
11
|
- **当场试通**:判断服务的地址填完就能试一下通不通,不用等第一次派工失败。
|
|
12
12
|
- **密钥直接填**:判断服务要用的密钥就填在配置卡片里,存进 DSH 的凭据文件,只写不读;页面不会把它显示回来。
|
|
13
|
-
-
|
|
13
|
+
- **结果日志**:每个判过的子代理记一行——结果、选择、主代理、子代理、时间、耗时。结果写「类型 3」或「未判成」;选择一栏把供应商、模型、强度连成一段。点开一行看这次真正发给判断模型的完整内容。只活在本次运行期间,重启即清空。
|
|
14
14
|
|
|
15
15
|
## 特性
|
|
16
16
|
|
package/lib/client.js
CHANGED
|
@@ -29,6 +29,7 @@ __export(index_exports, {
|
|
|
29
29
|
apply: () => apply2,
|
|
30
30
|
buildModelOptions: () => buildModelOptions,
|
|
31
31
|
createDispatchRemote: () => createDispatchRemote,
|
|
32
|
+
describeChoice: () => describeChoice,
|
|
32
33
|
dispatchCardStore: () => dispatchCardStore,
|
|
33
34
|
en: () => en,
|
|
34
35
|
inject: () => inject,
|
|
@@ -127,6 +128,9 @@ function readRow(value) {
|
|
|
127
128
|
effort: text("effort")
|
|
128
129
|
};
|
|
129
130
|
}
|
|
131
|
+
function describeChoice(row) {
|
|
132
|
+
return [row.provider, row.model, row.effort].map((part) => part.trim()).filter((part) => part !== "").join(" \xB7 ");
|
|
133
|
+
}
|
|
130
134
|
function routeKey(provider, model) {
|
|
131
135
|
return `${provider}\0${model}`;
|
|
132
136
|
}
|
|
@@ -614,7 +618,7 @@ var en = {
|
|
|
614
618
|
"switch.log.title": "Record the log",
|
|
615
619
|
"switch.log.desc": "Keep the most recent judgements in this running instance. Cleared on restart.",
|
|
616
620
|
"judge.title": "Judgement service",
|
|
617
|
-
"judge.desc": "The task type is decided by this endpoint. It receives the
|
|
621
|
+
"judge.desc": "The task type is decided by this endpoint. It receives the delegation label, the task text and the type list, and answers with one type number.",
|
|
618
622
|
"judge.endpoint": "Endpoint address",
|
|
619
623
|
"judge.endpointDesc": "The full address, including the protocol path. One System One example is prefilled.",
|
|
620
624
|
"judge.model": "Judgement model",
|
|
@@ -685,7 +689,7 @@ var en = {
|
|
|
685
689
|
"preset.effortMedium": "medium",
|
|
686
690
|
"preset.effortHigh": "high",
|
|
687
691
|
"preview.title": "View the full prompt",
|
|
688
|
-
"preview.desc": "Exactly what would be sent to the judgement service. The task text
|
|
692
|
+
"preview.desc": "Exactly what would be sent to the judgement service. The delegation label and the task text are filled in at delegation time.",
|
|
689
693
|
"preview.open": "View the full prompt",
|
|
690
694
|
"preview.copy": "Copy",
|
|
691
695
|
"preview.copied": "Copied",
|
|
@@ -703,26 +707,21 @@ var en = {
|
|
|
703
707
|
"save.invalid": "This cannot be saved yet.",
|
|
704
708
|
"save.refused": "The host did not accept this write.",
|
|
705
709
|
"log.title": "Recent judgements",
|
|
706
|
-
"log.desc": "The most recent 20 judgements in this running instance, newest first.",
|
|
710
|
+
"log.desc": "The most recent 20 judgements in this running instance, newest first. Click one to see the exact prompt that was sent.",
|
|
707
711
|
"log.empty": "No judgement has run yet.",
|
|
708
|
-
"log.
|
|
709
|
-
"log.
|
|
710
|
-
"log.
|
|
712
|
+
"log.colResult": "Result",
|
|
713
|
+
"log.colChoice": "Choice",
|
|
714
|
+
"log.colParent": "Main agent",
|
|
715
|
+
"log.colChild": "Subagent",
|
|
711
716
|
"log.colTime": "Time",
|
|
712
717
|
"log.colLatency": "Took",
|
|
713
|
-
"log.
|
|
714
|
-
"log.
|
|
718
|
+
"log.resultJudged": "Type {id}",
|
|
719
|
+
"log.resultInherited": "No match",
|
|
720
|
+
"log.promptTitle": "The prompt sent to the judge",
|
|
721
|
+
"log.promptDesc": "Exactly the request body this judgement sent.",
|
|
722
|
+
"log.promptClose": "Close",
|
|
723
|
+
"log.promptEmpty": "No request was sent for this judgement.",
|
|
715
724
|
"log.refresh": "Refresh",
|
|
716
|
-
"log.detailTitle": "Judgement detail",
|
|
717
|
-
"log.detailClose": "Close",
|
|
718
|
-
"log.detailSource": "Where it came from",
|
|
719
|
-
"log.detailProvider": "Provider",
|
|
720
|
-
"log.detailModel": "Model",
|
|
721
|
-
"log.detailEffort": "Effort",
|
|
722
|
-
"log.detailReason": "Reason",
|
|
723
|
-
"log.detailLatency": "Took",
|
|
724
|
-
"log.detailParent": "Conversation",
|
|
725
|
-
"log.detailChild": "Subagent description",
|
|
726
725
|
"log.loadFailed": "The log could not be read.",
|
|
727
726
|
"ms": "{value} ms"
|
|
728
727
|
};
|
|
@@ -734,7 +733,7 @@ var zh = {
|
|
|
734
733
|
"switch.log.title": "\u8BB0\u5F55\u65E5\u5FD7",
|
|
735
734
|
"switch.log.desc": "\u5728\u672C\u6B21\u8FD0\u884C\u671F\u95F4\u4FDD\u7559\u6700\u8FD1\u7684\u5224\u65AD\u8BB0\u5F55\u3002\u91CD\u542F\u5C31\u6E05\u7A7A\u3002",
|
|
736
735
|
"judge.title": "\u5224\u65AD\u670D\u52A1",
|
|
737
|
-
"judge.desc": "\u4EFB\u52A1\u7C7B\u578B\u7531\u8FD9\u4E2A\u5730\u5740\u51B3\u5B9A\uFF1A\u5B83\u6536\u5230\
|
|
736
|
+
"judge.desc": "\u4EFB\u52A1\u7C7B\u578B\u7531\u8FD9\u4E2A\u5730\u5740\u51B3\u5B9A\uFF1A\u5B83\u6536\u5230\u6D3E\u5DE5\u6807\u7B7E\u3001\u4EFB\u52A1\u6B63\u6587\u548C\u7C7B\u578B\u6E05\u5355\uFF0C\u56DE\u7B54\u4E00\u4E2A\u7C7B\u578B\u7F16\u53F7\u3002",
|
|
738
737
|
"judge.endpoint": "\u7AEF\u70B9\u5730\u5740",
|
|
739
738
|
"judge.endpointDesc": "\u5B8C\u6574\u5730\u5740\uFF0C\u8981\u5E26\u534F\u8BAE\u8DEF\u5F84\u3002\u5DF2\u7ECF\u9884\u586B\u4E00\u4E2A System One \u7684\u4F8B\u5B50\u3002",
|
|
740
739
|
"judge.model": "\u5224\u65AD\u6A21\u578B",
|
|
@@ -805,7 +804,7 @@ var zh = {
|
|
|
805
804
|
"preset.effortMedium": "\u4E2D",
|
|
806
805
|
"preset.effortHigh": "\u9AD8",
|
|
807
806
|
"preview.title": "\u67E5\u770B\u5B8C\u6574\u9884\u89C8",
|
|
808
|
-
"preview.desc": "\u771F\u6B63\u4F1A\u53D1\u7ED9\u5224\u65AD\u670D\u52A1\u7684\u90A3\u6BB5\u5185\u5BB9\u3002\u4EFB\u52A1\u6587\
|
|
807
|
+
"preview.desc": "\u771F\u6B63\u4F1A\u53D1\u7ED9\u5224\u65AD\u670D\u52A1\u7684\u90A3\u6BB5\u5185\u5BB9\u3002\u6D3E\u5DE5\u6807\u7B7E\u4E0E\u4EFB\u52A1\u6B63\u6587\u90FD\u5728\u6D3E\u5DE5\u90A3\u4E00\u523B\u624D\u586B\u8FDB\u53BB\u3002",
|
|
809
808
|
"preview.open": "\u67E5\u770B\u5B8C\u6574\u9884\u89C8",
|
|
810
809
|
"preview.copy": "\u590D\u5236",
|
|
811
810
|
"preview.copied": "\u5DF2\u590D\u5236",
|
|
@@ -823,26 +822,21 @@ var zh = {
|
|
|
823
822
|
"save.invalid": "\u73B0\u5728\u8FD8\u5B58\u4E0D\u4E86\u3002",
|
|
824
823
|
"save.refused": "\u5BBF\u4E3B\u6CA1\u6709\u63A5\u53D7\u8FD9\u6B21\u5199\u5165\u3002",
|
|
825
824
|
"log.title": "\u6700\u8FD1\u7684\u5224\u65AD",
|
|
826
|
-
"log.desc": "\u672C\u6B21\u8FD0\u884C\u671F\u95F4\u6700\u8FD1\u7684 20 \u6761\u5224\u65AD\uFF0C\u65B0\u7684\u5728\u6700\u524D\u9762\u3002",
|
|
825
|
+
"log.desc": "\u672C\u6B21\u8FD0\u884C\u671F\u95F4\u6700\u8FD1\u7684 20 \u6761\u5224\u65AD\uFF0C\u65B0\u7684\u5728\u6700\u524D\u9762\u3002\u70B9\u4E00\u884C\u770B\u8FD9\u6B21\u53D1\u7ED9\u5224\u65AD\u6A21\u578B\u7684\u90A3\u6BB5\u5185\u5BB9\u3002",
|
|
827
826
|
"log.empty": "\u8FD8\u6CA1\u6709\u5224\u65AD\u8FC7\u3002",
|
|
828
|
-
"log.
|
|
829
|
-
"log.
|
|
830
|
-
"log.
|
|
827
|
+
"log.colResult": "\u7ED3\u679C",
|
|
828
|
+
"log.colChoice": "\u9009\u62E9",
|
|
829
|
+
"log.colParent": "\u4E3B\u4EE3\u7406",
|
|
830
|
+
"log.colChild": "\u5B50\u4EE3\u7406",
|
|
831
831
|
"log.colTime": "\u65F6\u95F4",
|
|
832
832
|
"log.colLatency": "\u8017\u65F6",
|
|
833
|
-
"log.
|
|
834
|
-
"log.
|
|
833
|
+
"log.resultJudged": "\u7C7B\u578B {id}",
|
|
834
|
+
"log.resultInherited": "\u672A\u5224\u6210",
|
|
835
|
+
"log.promptTitle": "\u53D1\u7ED9\u5224\u65AD\u6A21\u578B\u7684\u5185\u5BB9",
|
|
836
|
+
"log.promptDesc": "\u8FD9\u6B21\u5224\u65AD\u771F\u6B63\u53D1\u51FA\u53BB\u7684\u8BF7\u6C42\u4F53\u3002",
|
|
837
|
+
"log.promptClose": "\u5173\u95ED",
|
|
838
|
+
"log.promptEmpty": "\u8FD9\u6B21\u5224\u65AD\u6CA1\u6709\u53D1\u51FA\u8BF7\u6C42\u3002",
|
|
835
839
|
"log.refresh": "\u5237\u65B0",
|
|
836
|
-
"log.detailTitle": "\u5224\u65AD\u8BE6\u60C5",
|
|
837
|
-
"log.detailClose": "\u5173\u95ED",
|
|
838
|
-
"log.detailSource": "\u7ED3\u679C\u6765\u6E90",
|
|
839
|
-
"log.detailProvider": "\u4F9B\u5E94\u5546",
|
|
840
|
-
"log.detailModel": "\u6A21\u578B",
|
|
841
|
-
"log.detailEffort": "\u5F3A\u5EA6",
|
|
842
|
-
"log.detailReason": "\u539F\u56E0",
|
|
843
|
-
"log.detailLatency": "\u8017\u65F6",
|
|
844
|
-
"log.detailParent": "\u4F1A\u8BDD",
|
|
845
|
-
"log.detailChild": "\u5B50\u4EE3\u7406\u63CF\u8FF0",
|
|
846
840
|
"log.loadFailed": "\u65E5\u5FD7\u8BFB\u4E0D\u51FA\u6765\u3002",
|
|
847
841
|
"ms": "{value} \u6BEB\u79D2"
|
|
848
842
|
};
|
|
@@ -870,6 +864,10 @@ function withSamples(text, samples) {
|
|
|
870
864
|
return sample === void 0 ? part : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { children: sample }, index);
|
|
871
865
|
});
|
|
872
866
|
}
|
|
867
|
+
function LogCell({ text, hint }) {
|
|
868
|
+
const label = hint === void 0 || hint === "" ? text : hint;
|
|
869
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Tooltip, { label, side: "top", portal: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-judge-cell-clip", children: text }) });
|
|
870
|
+
}
|
|
873
871
|
var CARD_CSS = `
|
|
874
872
|
.dsh-judge-card { display: flex; flex-direction: column; gap: 16px; box-sizing: border-box; width: 100%; max-width: 760px; color: var(--dsw-alias-label-primary); }
|
|
875
873
|
.dsh-judge-panel { display: flex; flex-direction: column; gap: 16px; }
|
|
@@ -898,8 +896,9 @@ var CARD_CSS = `
|
|
|
898
896
|
.dsh-judge-field input { box-sizing: border-box; width: 100%; min-width: 0; }
|
|
899
897
|
.dsh-judge-key-line { display: flex; align-items: center; gap: 8px; box-sizing: border-box; width: 100%; }
|
|
900
898
|
.dsh-judge-off { display: block; color: var(--dsw-alias-state-warn-label); font: var(--dsw-font-xxxs-11); white-space: nowrap; }
|
|
901
|
-
|
|
902
|
-
.dsh-judge-actions { display: flex; align-items: center; justify-content:
|
|
899
|
+
/* \u8FD9\u4E00\u8282\u7684\u51FA\u53E3\uFF1A\u5DE6\u8FB9\u5199\u4E0B\u53BB\uFF0C\u53F3\u8FB9\u67E5\u5DF2\u6709\u7684\u2014\u2014\u4E24\u4E2A\u65B9\u5411\u5206\u5F00\uFF0C\u6309\u9519\u4E00\u4E2A\u4E0D\u4F1A\u4E32\u5230\u53E6\u4E00\u4E2A\u3002 */
|
|
900
|
+
.dsh-judge-actions { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; padding-top: 12px; border-top: 0.5px solid var(--dsw-alias-border-l3); }
|
|
901
|
+
.dsh-judge-actions-group { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
|
|
903
902
|
.dsh-judge-hint { color: var(--dsw-alias-label-tertiary); font: var(--dsw-font-xxs-12); }
|
|
904
903
|
.dsh-judge-note-ok { color: var(--dsw-alias-state-success-primary); font: var(--dsw-font-xxs-12); }
|
|
905
904
|
.dsh-judge-note-bad { color: var(--dsw-alias-state-error-primary); font: var(--dsw-font-xxs-12); }
|
|
@@ -928,13 +927,14 @@ var CARD_CSS = `
|
|
|
928
927
|
.dsh-judge-preset-title { font: var(--dsw-font-xs-13); }
|
|
929
928
|
.dsh-judge-preset-hint { color: var(--dsw-alias-label-tertiary); font: var(--dsw-font-xxxs-11); }
|
|
930
929
|
.dsh-judge-log { display: flex; flex-direction: column; gap: 4px; font: var(--dsw-font-xxs-12); }
|
|
931
|
-
|
|
930
|
+
/* \u516D\u5217\u7684\u5BBD\u5EA6\u6309\u5185\u5BB9\u5B9A\uFF1A\u7ED3\u679C\u4E0E\u65F6\u95F4\u662F\u5B9A\u957F\u7684\uFF0C\u9009\u62E9\u6700\u957F\u3001\u4E3B\u4EE3\u7406\u4E0E\u5B50\u4EE3\u7406\u5404\u5360\u4E00\u4EFD\u4F59\u91CF\u3002
|
|
931
|
+
minmax(0, \u2026) \u662F\u622A\u65AD\u7684\u524D\u63D0\u2014\u2014\u4E0D\u7ED9\u4E0B\u9650\u5F52\u96F6\uFF0C\u957F\u5185\u5BB9\u4F1A\u628A\u6574\u5217\u6491\u51FA\u53BB\u3002 */
|
|
932
|
+
.dsh-judge-log-row { display: grid; grid-template-columns: 72px minmax(0, 2.2fr) minmax(0, 1.2fr) minmax(0, 1.2fr) 62px 74px; gap: 8px; align-items: center; text-align: left; border: 0; background: none; padding: 6px 4px; border-radius: var(--dsw-radius-sm); cursor: pointer; color: inherit; font: inherit; }
|
|
932
933
|
.dsh-judge-cell-clip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
933
934
|
.dsh-judge-log-row:hover { background: var(--dsw-alias-interactive-bg-hover); }
|
|
934
935
|
.dsh-judge-log-head { font-weight: 600; color: var(--dsw-alias-label-tertiary); cursor: default; }
|
|
935
936
|
.dsh-judge-log-head:hover { background: none; }
|
|
936
|
-
|
|
937
|
-
/* \u9884\u89C8\u91CC\u662F\u4E00\u6574\u6BB5 JSON\uFF0C\u9ED8\u8BA4\u7684\u5F39\u7A97\u5BBD\u5EA6\u4F1A\u628A\u5B83\u6298\u5F97\u5F88\u788E\u3002 */
|
|
937
|
+
/* \u5F39\u7A97\u91CC\u662F\u4E00\u6574\u6BB5 JSON\uFF0C\u9ED8\u8BA4\u7684\u5F39\u7A97\u5BBD\u5EA6\u4F1A\u628A\u5B83\u6298\u5F97\u5F88\u788E\u3002 */
|
|
938
938
|
.dsh-judge-modal { width: min(760px, 100%); max-height: min(85vh, 100%); }
|
|
939
939
|
`;
|
|
940
940
|
function injectCardStyles() {
|
|
@@ -983,29 +983,32 @@ function JudgeDispatchPanel(props) {
|
|
|
983
983
|
setPreview(text ?? t("preview.failed"));
|
|
984
984
|
setPreviewOpen(true);
|
|
985
985
|
};
|
|
986
|
-
const saveRow = (section, dirty, onSave) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-actions", children: [
|
|
987
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
986
|
+
const saveRow = (section, dirty, onSave, checks) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-actions", children: [
|
|
987
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-actions-group", children: [
|
|
988
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
989
|
+
import_dsh_client_ui_primitives.Button,
|
|
990
|
+
{
|
|
991
|
+
variant: "primary",
|
|
992
|
+
size: "sm",
|
|
993
|
+
disabled: state.saving !== "" || !dirty || !state.writable,
|
|
994
|
+
onClick: onSave,
|
|
995
|
+
children: state.saving === section ? t("save.saving") : t("save.button")
|
|
996
|
+
}
|
|
997
|
+
),
|
|
998
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
999
|
+
import_dsh_client_ui_primitives.Button,
|
|
1000
|
+
{
|
|
1001
|
+
variant: "outline",
|
|
1002
|
+
size: "sm",
|
|
1003
|
+
disabled: state.saving !== "" || !dirty,
|
|
1004
|
+
onClick: () => dispatchCardStore.revert(section),
|
|
1005
|
+
children: t("save.discard")
|
|
1006
|
+
}
|
|
1007
|
+
),
|
|
1008
|
+
dirty && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-judge-hint", children: t("save.unsaved") }),
|
|
1009
|
+
state.saveFailed === section && state.saveError !== "" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-judge-note-bad", role: "alert", children: t("save.failed").replace("{error}", state.saveError) })
|
|
1010
|
+
] }),
|
|
1011
|
+
checks !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-actions-group", children: checks })
|
|
1009
1012
|
] });
|
|
1010
1013
|
const row = (draft, index) => {
|
|
1011
1014
|
const efforts = dispatchCardStore.effortsFor(draft);
|
|
@@ -1134,31 +1137,7 @@ function JudgeDispatchPanel(props) {
|
|
|
1134
1137
|
};
|
|
1135
1138
|
const design = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-panel", children: [
|
|
1136
1139
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-section", children: [
|
|
1137
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
1138
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-judge-title", children: t("judge.title") }),
|
|
1139
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-head-actions", children: [
|
|
1140
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1141
|
-
import_dsh_client_ui_primitives.Button,
|
|
1142
|
-
{
|
|
1143
|
-
variant: "outline",
|
|
1144
|
-
size: "sm",
|
|
1145
|
-
disabled: probing || state.dirty,
|
|
1146
|
-
onClick: () => void runProbe(),
|
|
1147
|
-
children: probing ? t("judge.probing") : t("judge.probe")
|
|
1148
|
-
}
|
|
1149
|
-
),
|
|
1150
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1151
|
-
import_dsh_client_ui_primitives.Button,
|
|
1152
|
-
{
|
|
1153
|
-
variant: "outline",
|
|
1154
|
-
size: "sm",
|
|
1155
|
-
disabled: state.dirty,
|
|
1156
|
-
onClick: () => void openPreview(),
|
|
1157
|
-
children: t("preview.open")
|
|
1158
|
-
}
|
|
1159
|
-
)
|
|
1160
|
-
] })
|
|
1161
|
-
] }),
|
|
1140
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-head", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-judge-title", children: t("judge.title") }) }),
|
|
1162
1141
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-desc", children: t("judge.desc") }),
|
|
1163
1142
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-row", children: [
|
|
1164
1143
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-row-info", children: [
|
|
@@ -1264,7 +1243,28 @@ function JudgeDispatchPanel(props) {
|
|
|
1264
1243
|
] }),
|
|
1265
1244
|
probeResult !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: probeResult.ok ? "dsh-judge-note-ok" : "dsh-judge-note-bad", children: probeResult.ok ? t("judge.probeOk").replace("{latency}", String(probeResult.latencyMs)) : t("judge.probeFail").replace("{reason}", reasonText(probeResult.reason)) }),
|
|
1266
1245
|
state.dirty && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-hint", children: t("preview.blocked") }),
|
|
1267
|
-
saveRow("judge", state.judgeDirty, () => void dispatchCardStore.save("judge"))
|
|
1246
|
+
saveRow("judge", state.judgeDirty, () => void dispatchCardStore.save("judge"), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1247
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1248
|
+
import_dsh_client_ui_primitives.Button,
|
|
1249
|
+
{
|
|
1250
|
+
variant: "outline",
|
|
1251
|
+
size: "sm",
|
|
1252
|
+
disabled: probing || state.dirty,
|
|
1253
|
+
onClick: () => void runProbe(),
|
|
1254
|
+
children: probing ? t("judge.probing") : t("judge.probe")
|
|
1255
|
+
}
|
|
1256
|
+
),
|
|
1257
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1258
|
+
import_dsh_client_ui_primitives.Button,
|
|
1259
|
+
{
|
|
1260
|
+
variant: "outline",
|
|
1261
|
+
size: "sm",
|
|
1262
|
+
disabled: state.dirty,
|
|
1263
|
+
onClick: () => void openPreview(),
|
|
1264
|
+
children: t("preview.open")
|
|
1265
|
+
}
|
|
1266
|
+
)
|
|
1267
|
+
] }))
|
|
1268
1268
|
] }),
|
|
1269
1269
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-section", children: [
|
|
1270
1270
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-title", children: t("rows.title") }),
|
|
@@ -1313,28 +1313,36 @@ function JudgeDispatchPanel(props) {
|
|
|
1313
1313
|
state.logLoaded && state.log.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-desc", children: t("log.empty") }),
|
|
1314
1314
|
state.log.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-log", children: [
|
|
1315
1315
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-log-row dsh-judge-log-head", children: [
|
|
1316
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("log.
|
|
1317
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("log.
|
|
1318
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("log.
|
|
1316
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("log.colResult") }),
|
|
1317
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("log.colChoice") }),
|
|
1318
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("log.colParent") }),
|
|
1319
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("log.colChild") }),
|
|
1319
1320
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("log.colTime") }),
|
|
1320
1321
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("log.colLatency") })
|
|
1321
1322
|
] }),
|
|
1322
|
-
state.log.map((entry, index) =>
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1323
|
+
state.log.map((entry, index) => {
|
|
1324
|
+
const result = entry.typeId === null ? {
|
|
1325
|
+
text: t("log.resultInherited"),
|
|
1326
|
+
hint: entry.reason === void 0 ? "" : reasonText(entry.reason)
|
|
1327
|
+
} : { text: t("log.resultJudged").replace("{id}", String(entry.typeId)), hint: "" };
|
|
1328
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1329
|
+
"button",
|
|
1330
|
+
{
|
|
1331
|
+
type: "button",
|
|
1332
|
+
className: "dsh-judge-log-row",
|
|
1333
|
+
onClick: () => setDetail(entry),
|
|
1334
|
+
children: [
|
|
1335
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LogCell, { text: result.text, hint: result.hint }),
|
|
1336
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LogCell, { text: describeChoice(entry) || "\u2014" }),
|
|
1337
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LogCell, { text: entry.parentTitle || "\u2014" }),
|
|
1338
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LogCell, { text: entry.childLabel || "\u2014" }),
|
|
1339
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: new Date(entry.at).toLocaleTimeString() }),
|
|
1340
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("ms").replace("{value}", String(entry.latencyMs)) })
|
|
1341
|
+
]
|
|
1342
|
+
},
|
|
1343
|
+
index
|
|
1344
|
+
);
|
|
1345
|
+
})
|
|
1338
1346
|
] })
|
|
1339
1347
|
] }) });
|
|
1340
1348
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-card", children: [
|
|
@@ -1390,26 +1398,18 @@ function JudgeDispatchPanel(props) {
|
|
|
1390
1398
|
{
|
|
1391
1399
|
open: detail !== null,
|
|
1392
1400
|
onClose: () => setDetail(null),
|
|
1393
|
-
title: t("log.
|
|
1394
|
-
closeLabel: t("log.
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: detail.reason === void 0 ? "\u2014" : reasonText(detail.reason) }),
|
|
1406
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("log.detailLatency") }),
|
|
1407
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("ms").replace("{value}", String(detail.latencyMs)) }),
|
|
1408
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("log.detailParent") }),
|
|
1409
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: detail.parentTitle || "\u2014" }),
|
|
1410
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: t("log.detailChild") }),
|
|
1411
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { whiteSpace: "pre-wrap" }, children: detail.childLabel || "\u2014" })
|
|
1412
|
-
] })
|
|
1401
|
+
title: t("log.promptTitle"),
|
|
1402
|
+
closeLabel: t("log.promptClose"),
|
|
1403
|
+
description: t("log.promptDesc"),
|
|
1404
|
+
className: "dsh-judge-modal",
|
|
1405
|
+
children: detail !== null && (detail.prompt === "" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-desc", children: t("log.promptEmpty") }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1406
|
+
import_dsh_client_ui_primitives.CodeBlock,
|
|
1407
|
+
{
|
|
1408
|
+
code: detail.prompt,
|
|
1409
|
+
copyLabel: t("preview.copy"),
|
|
1410
|
+
copiedLabel: t("preview.copied")
|
|
1411
|
+
}
|
|
1412
|
+
))
|
|
1413
1413
|
}
|
|
1414
1414
|
)
|
|
1415
1415
|
] });
|