@lynn123411/dsh-subagent-judge-dispatch 0.3.0 → 0.4.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 +9 -7
- package/README.md +2 -2
- package/lib/client.js +177 -95
- package/lib/client.js.map +2 -2
- package/lib/index.js +153 -15
- package/lib/index.js.map +4 -4
- package/package.json +2 -1
package/DETAILS.md
CHANGED
|
@@ -36,9 +36,10 @@ dsh plugin --profile web add @lynn123411/dsh-subagent-judge-dispatch
|
|
|
36
36
|
- **插手位置**:宿主的 `agent/request` 瀑布。注册在根层上下文,所以每个代理的每次请求都会经过;插件自己用 `subagentDepth`(会话头里的 `delegationDepth` 与运行时 `options.subagentDepth` 取较大者)筛出子代理。
|
|
37
37
|
- **判断次数**:按子代理 id 记住已判过的,一个跑十步的子代理只问一次。
|
|
38
38
|
- **判断模型读到的任务**:先是派出这次活的标签(`subagent/descriptor` 的 `label`,宿主用它当子会话标题),再是任务正文原文,两段之间空一行。标签只有三五个词,是派工方写的摘要;正文才是「这个活到底要做什么」。只发标签,判断只能看出个大概方向;只发正文,遇到开头是套话的任务就丢了派工方的意图。
|
|
39
|
-
- **任务正文怎么取**:取子代理自己那条 `source.kind === 'user'`
|
|
39
|
+
- **任务正文怎么取**:取子代理自己那条 `source.kind === 'user'` 的消息。用户角色不等于任务——工作目录提示、工作区指令、运行时快照、技能清单、时间快照都写成用户消息,按来源筛才分得开。这条消息在子代理一生里以两种形状出现,两种都要认:派工那一刻它是收件箱里的待办(`agent/inbox/spliced` 事件里 `inserted` 的那条),宿主在步边界认领之后才写成 `user/message`。判断发生在步内的那次请求里,比写成 `user/message` 早,只认后者会在唯一要紧的那次请求上读空、只剩标签。宿主的返回指引(「你的父代理 id 是……完事用 `send_message` 回报」)是那条消息末尾追加的一个文本块,讲的是怎么交作业,不算任务,取正文时整块去掉。
|
|
40
40
|
- **只读子代理自己的事件**:`ownEvents()`(或 `snapshotEvents(inheritedEventCount)`)是子代理自己产生的那一段。**不能从日志开头读**:叉出来的子代理,日志前缀是父代理已完成的回合,从开头读会把祖先的标签和父对话的第一条消息送给判断模型。
|
|
41
41
|
- **长任务按头尾截**:正文留开头 1400 字与结尾 400 字,中间省掉多少字写在省略号里(`… (N characters omitted) …`)。补充要求常写在末尾,所以留尾不留中;把省掉的字数写出来,读者看日志里那段请求才分得清「截断了」和「本来就这么短」。这句标记用英文,是判断协议本身的语言——中文写在英文任务里像任务的一部分,读者与判断模型都会读岔。
|
|
42
|
+
- **日志落盘**:判断日志写在 `~/.dsh/dsh-subagent-judge-dispatch/judgements.json`(跟随 `DSH_HOME`),文件留最近 200 条,配置页只列最近 10 条——页面是看一眼刚发生什么的地方,不是日志查看器。连续追加合并成一次写入,先写临时文件再改名,进程崩了也不会留下半份文档;一条记录的字段缺了,留住它带着的那部分,不连累整份文件。
|
|
42
43
|
- **日志那一栏与判断输入分开算**:表格「子代理」一栏只放派工标签(没有标签时退回正文开头,截到 60 字),不把判断模型读过的那一整段塞回去——那一整段在同一行的弹窗里能看到。
|
|
43
44
|
- **判断协议**:`POST` 到页面填的地址,请求体 `{ model, state: { message }, questions }`;`questions` 只有一个 `task_type`,类型是 `choice`,`criteria` 就是你的类型清单(键是编号、值是你写的描述),答复取被选中选项的编号。
|
|
44
45
|
- **写入铁律**:模型、强度、提供方三项一起写。`resolveChildAgentOptions` 在「换了模型但没给强度」时会删掉继承来的强度,所以三项必须同进同出。
|
|
@@ -52,8 +53,9 @@ dsh plugin --profile web add @lynn123411/dsh-subagent-judge-dispatch
|
|
|
52
53
|
- **草稿按字段保留**:宿主每次发布配置,只有读者改过、且改动与「本页上次看到的已提交值」不同的那一项才留在页面上,其余跟着宿主走。按整节保留会让一次保存把读者没碰过的字段写回去,等于撤掉别的页面刚做的改动。
|
|
53
54
|
- **放弃改动只丢草稿**:放弃判断服务那一节,只清掉还没交出去的文本与那几项设置;密钥已经存进凭据文件,页面因此不会改口说「还没有密钥」。
|
|
54
55
|
- **试通与预览跟着判断服务那一节走**:两个按钮放在这一节保存行的右端,左边写下去、右边查这一份。试通不落盘(它只是问一句),预览要求先把改动保存下来——两者都在标题栏下面,而不是标题那一行:那里是整节的标题,不是一套设置的出口。
|
|
55
|
-
-
|
|
56
|
-
-
|
|
56
|
+
- **判断日志是一张六列表**:结果(`类型 3` / `未判成`)、选择(`模型 · 强度`,悬停补上供应商)、主代理、子代理、时间、耗时。结果在最左,读者扫一眼先看「判成了没有」;选择一栏只写各条之间真正不同的两样,供应商几乎每行都一样,悬停才把整段路 `供应商 · 模型 · 强度` 写出来。没判成的原因同样不在格子里展开,悬停才说——那一列宽度是给编号留的。放不下的格子截断,气泡用宿主的 `Tooltip`(原生 `title` 键盘够不到)。
|
|
57
|
+
- **点一行看的是这段提示词**:弹窗里只有这次真正发给判断模型的请求体,任务文字也在里面。正文按字符折行,不给长行留横向滚动;高度超出一屏就在框里竖向滚动,滚动条的深浅跟着弹窗这层表面走。结果、选择、主代理这几项行上已经有了,弹窗不再各列一遍。这条请求体由发出请求的那一处格式化后原样存进日志,页面没有第二次拼装的机会——`scripts/smoke-host.mjs` 断言日志里那一段与发出去的请求体同值。
|
|
58
|
+
- **导入导出走纯文本**:导出把清单按 `[{ description, provider, model, effort }]` 复制进剪贴板,不带编号——编号是按位置排的,写出去会让读者以为它是设置的一部分。导入是一个只收粘贴的弹窗:不读文件、不联网,粘进来的 JSON 先过形状检查(必须是数组、每条是对象、四个字段是文字、不能有整条全空的行),合格就整份换进草稿,按「保存」之前一个字都不写。三种坏输入(不是 JSON、形状不对、空清单)各自说一句不同的话,不合并成「格式有误」。
|
|
57
59
|
- **密钥固定引用**:引用名是插件自己的常量 `SUBAGENT_JUDGE_API_KEY`,不是页面填的字段——读者只要把密钥贴进来,不必知道什么是凭据引用。密钥值交给凭据服务之后立刻从页面状态里清掉,`scripts/test-card.mjs` 有一条断言守着它不出现在状态里。密钥格与上面两格同宽;页面没有凭据通道(非回环地址)时,输入框与「删掉密钥」都禁用,并有一行字说明原因。
|
|
58
60
|
|
|
59
61
|
## 开发副本
|
|
@@ -77,12 +79,12 @@ cd plugins/dsh-subagent-judge-dispatch && pnpm check
|
|
|
77
79
|
|
|
78
80
|
`check` = `typecheck` + `build` + 五个自检 + `assert:lib-untracked`:
|
|
79
81
|
|
|
80
|
-
- **`scripts/test-decision.mjs`** 打的是 `src/`(Node 直接跑 `.ts
|
|
81
|
-
- **`scripts/smoke-host.mjs`** 起真 cordis `Context`,把 `agent/request` 瀑布按宿主的方式跑一遍(`await next()` 拿到解析好的配置,再把返回值交给断言):主代理不被判断、同一子代理只判一次、两个开关各自的短路、发送出去的请求体形状、判断输入是标签加正文两段、正文按 `source.kind`
|
|
82
|
+
- **`scripts/test-decision.mjs`** 打的是 `src/`(Node 直接跑 `.ts`),守判断与改写这条纯逻辑:失败时**按身份**退回同一个对象(不是深比较——深比较会放过「复制一份再写回原值」这种仍然算覆盖的写法)、三项同写、残缺行不生效、答复读取的三种形状与七种空答复、四种失败原因各自的归类、超时不重试、日志文件留 200 条、页面只取最近 10 条、换一个 LogStore 实例也读得回来、文件缺失或残缺都不抛、读出来是副本,编号按位置从 1 连着。它还守判断模型读到的输入:标签在前正文在后、没标签时只发正文、两样都没有时输入为空、短任务一字不动、长任务留头尾并写明省掉多少字、刚好到上限的不算截断。另有一条守「判断带回的提示词就是发出去的那一段」:成功、失败、没发出请求三种情形各一条。
|
|
83
|
+
- **`scripts/smoke-host.mjs`** 起真 cordis `Context`,把 `agent/request` 瀑布按宿主的方式跑一遍(`await next()` 拿到解析好的配置,再把返回值交给断言):主代理不被判断、同一子代理只判一次、两个开关各自的短路、发送出去的请求体形状、判断输入是标签加正文两段、正文按 `source.kind` 取(工作目录提示不算任务)、派工消息还在收件箱里与已经落盘成 `user/message` 两种形状都读得到、宿主追加的返回指引不送进去、长任务留头尾且写明省掉多少字、没有描述时取任务正文、叉出来的子代理只读自己的事件、日志的子代理一栏只写标签、判断过的记忆有上限。它的夹具照真实日志的形状搭:先是 `working-directory` 的通知,再是收件箱里那份待办;两种形状各有一组用例,一组把消息留在收件箱,一组用落盘后的 `user/message`。它另起一个挂着 `connection` 的实例,从日志路由读回那一行,断言 `prompt` 与真正发出去的请求体同值——判断成功与判断失败各一条。
|
|
82
84
|
- **`scripts/smoke-client.mjs`** 按 Web shell 的方式装载 `lib/client.js`(`window.__ModuleLoader__.load` 桩件),喂假 cordis 服务:断言卡片注册进 `plugins.bundle.config`、key 是包名、走 `slots.inject`、读本插件自己的命名空间与宿主那份「子代理可选用哪些模型」设置、以宿主在服务本条目为挂载条件、样式表在 `apply()` 追加一次且没写死色值,以及 zh/en 键集一致。它的守卫带反例断言(「守卫拒绝未声明的服务读取」必须抛),否则那一串绿灯是假的。
|
|
83
85
|
|
|
84
|
-
- **`scripts/test-card.mjs`** 打的是 `src/`,守配置卡片这层状态机:两节各存各的、清单没填全不挡端点、宿主回 `false`
|
|
85
|
-
- **`scripts/test-render.mjs`** 用真 react 把卡片画进 jsdom:试通与预览在判断服务那一节的保存行里、标题栏不再有按钮,日志表是六列且顺序固定,结果写「类型 3
|
|
86
|
+
- **`scripts/test-card.mjs`** 打的是 `src/`,守配置卡片这层状态机:两节各存各的、清单没填全不挡端点、宿主回 `false` 算没存上、密钥跟着判断服务那次保存一起写且写的是固定引用名、密钥值从不进页面状态、草稿按字段保留(宿主改了一项而我在改另一项时,保存只写我改的那一项),「选择」一列只写模型与强度、悬停才带上供应商且两条路都不留悬空的分隔点,以及清单的 JSON 导出与导入各自认什么、拒什么。
|
|
87
|
+
- **`scripts/test-render.mjs`** 用真 react 把卡片画进 jsdom:试通与预览在判断服务那一节的保存行里、标题栏不再有按钮,日志表是六列且顺序固定,结果写「类型 3」/「未判成」,选择格只写模型与强度、供应商在悬停气泡里,导出把清单按纯 JSON 写进剪贴板、导入只填草稿且三种坏输入各报各的话,没判成的原因挂在宿主的 `Tooltip` 上而不是原生 `title`,弹窗里只有那段提示词且不把行上的栏目再列一遍。`ui-primitives` 走替身(真组件是浏览器 ESM、带 `.css` 导入,Node 里跑不起来),所以它验的是本插件的视图结构,外观与浮层定位要在真浏览器里看。
|
|
86
88
|
|
|
87
89
|
`lib/` 是构建镜像,`assert:lib-untracked` 判它没被 git 跟踪。
|
|
88
90
|
|
package/README.md
CHANGED
|
@@ -6,11 +6,11 @@
|
|
|
6
6
|
|
|
7
7
|
- **按任务类型指派**:每次派工把派出这次活的标签和任务正文交给判断服务,由它从你的类型清单里挑一个编号,插件按这个编号对应的设置改写子代理的模型与思考强度。
|
|
8
8
|
- **清单由你写**:任务类型是一张表格,每一行写一段判定依据、选一个模型、选一个思考强度;模型与强度两栏各是一个下拉。模型从宿主那份「子代理可选用哪些模型」设置里读,强度从该模型自己声明的档位里读。
|
|
9
|
-
-
|
|
9
|
+
- **导入导出**:任务类型清单能按纯 JSON 复制走,也能粘贴回来。导入只填表格,按「保存」才写进配置。
|
|
10
10
|
- **完整预览**:看一眼真正会发给判断服务的整段内容,派工标签与任务正文那两处标注「派工时才填」。
|
|
11
11
|
- **当场试通**:判断服务的地址填完就能试一下通不通,不用等第一次派工失败。
|
|
12
12
|
- **密钥直接填**:判断服务要用的密钥就填在配置卡片里,存进 DSH 的凭据文件,只写不读;页面不会把它显示回来。
|
|
13
|
-
- **结果日志**:每个判过的子代理记一行——结果、选择、主代理、子代理、时间、耗时。结果写「类型 3
|
|
13
|
+
- **结果日志**:每个判过的子代理记一行——结果、选择、主代理、子代理、时间、耗时。结果写「类型 3」或「未判成」;选择一栏写模型与强度,悬停再补上供应商。点开一行看这次真正发给判断模型的完整内容,长内容自己折行、框里滚动。日志写进 DSH 家目录,重启之后还在;配置页里只列最近 10 条。
|
|
14
14
|
|
|
15
15
|
## 特性
|
|
16
16
|
|
package/lib/client.js
CHANGED
|
@@ -30,6 +30,7 @@ __export(index_exports, {
|
|
|
30
30
|
buildModelOptions: () => buildModelOptions,
|
|
31
31
|
createDispatchRemote: () => createDispatchRemote,
|
|
32
32
|
describeChoice: () => describeChoice,
|
|
33
|
+
describeModel: () => describeModel,
|
|
33
34
|
dispatchCardStore: () => dispatchCardStore,
|
|
34
35
|
en: () => en,
|
|
35
36
|
inject: () => inject,
|
|
@@ -128,8 +129,14 @@ function readRow(value) {
|
|
|
128
129
|
effort: text("effort")
|
|
129
130
|
};
|
|
130
131
|
}
|
|
132
|
+
function describeModel(row) {
|
|
133
|
+
return joinRouteParts([row.model, row.effort]);
|
|
134
|
+
}
|
|
131
135
|
function describeChoice(row) {
|
|
132
|
-
return [row.provider, row.model, row.effort]
|
|
136
|
+
return joinRouteParts([row.provider, row.model, row.effort]);
|
|
137
|
+
}
|
|
138
|
+
function joinRouteParts(parts) {
|
|
139
|
+
return parts.map((part) => part.trim()).filter((part) => part !== "").join(" \xB7 ");
|
|
133
140
|
}
|
|
134
141
|
function routeKey(provider, model) {
|
|
135
142
|
return `${provider}\0${model}`;
|
|
@@ -178,6 +185,51 @@ function validateRows(rows, t) {
|
|
|
178
185
|
}
|
|
179
186
|
return "";
|
|
180
187
|
}
|
|
188
|
+
function exportRowsJson(rows) {
|
|
189
|
+
return JSON.stringify(
|
|
190
|
+
// 空白行(读者按了「加一行」还没填)不写进 JSON:它没有内容可带走,写出去
|
|
191
|
+
// 还会让这份文本自己读不回来。
|
|
192
|
+
rows.filter((row) => !isBlankRow(row)).map((row) => ({
|
|
193
|
+
description: row.description,
|
|
194
|
+
provider: row.provider,
|
|
195
|
+
model: row.model,
|
|
196
|
+
effort: row.effort
|
|
197
|
+
})),
|
|
198
|
+
null,
|
|
199
|
+
2
|
|
200
|
+
);
|
|
201
|
+
}
|
|
202
|
+
function isBlankRow(row) {
|
|
203
|
+
return [row.description, row.provider, row.model, row.effort].every((field) => field.trim() === "");
|
|
204
|
+
}
|
|
205
|
+
function parseRowsJson(text) {
|
|
206
|
+
let parsed;
|
|
207
|
+
try {
|
|
208
|
+
parsed = JSON.parse(text);
|
|
209
|
+
} catch {
|
|
210
|
+
return { ok: false, error: "json" };
|
|
211
|
+
}
|
|
212
|
+
if (!Array.isArray(parsed)) return { ok: false, error: "shape" };
|
|
213
|
+
if (parsed.length === 0) return { ok: false, error: "empty" };
|
|
214
|
+
const rows = [];
|
|
215
|
+
for (const value of parsed) {
|
|
216
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return { ok: false, error: "shape" };
|
|
217
|
+
const record = value;
|
|
218
|
+
const wrongType = ["description", "provider", "model", "effort"].some((key) => record[key] !== void 0 && typeof record[key] !== "string");
|
|
219
|
+
if (wrongType) return { ok: false, error: "shape" };
|
|
220
|
+
const field = (key) => typeof record[key] === "string" ? record[key] : "";
|
|
221
|
+
const row = {
|
|
222
|
+
description: field("description"),
|
|
223
|
+
provider: field("provider"),
|
|
224
|
+
model: field("model"),
|
|
225
|
+
effort: field("effort")
|
|
226
|
+
};
|
|
227
|
+
if (isBlankRow(row)) continue;
|
|
228
|
+
rows.push(row);
|
|
229
|
+
}
|
|
230
|
+
if (rows.length === 0) return { ok: false, error: "empty" };
|
|
231
|
+
return { ok: true, rows };
|
|
232
|
+
}
|
|
181
233
|
function emptyKey() {
|
|
182
234
|
return {
|
|
183
235
|
text: "",
|
|
@@ -393,9 +445,17 @@ var DispatchCardStore = class {
|
|
|
393
445
|
this.state = { ...this.state, rows: [...this.state.rows, { description: "", provider: "", model: "", effort: "" }], saveFailed: "" };
|
|
394
446
|
this.recompute();
|
|
395
447
|
}
|
|
396
|
-
/**
|
|
397
|
-
|
|
398
|
-
|
|
448
|
+
/**
|
|
449
|
+
* Stage a whole imported list, replacing what the page holds.
|
|
450
|
+
*
|
|
451
|
+
* Nothing is written: an import lands in the drafts exactly like typing does,
|
|
452
|
+
* so the section's own save button is still the only thing that reaches the
|
|
453
|
+
* document, and the reader can discard the import like any other edit.
|
|
454
|
+
*
|
|
455
|
+
* @param rows - the rows read from the pasted JSON.
|
|
456
|
+
*/
|
|
457
|
+
replaceRows(rows) {
|
|
458
|
+
this.state = { ...this.state, rows: rows.map((row) => ({ ...row })), saveFailed: "" };
|
|
399
459
|
this.recompute();
|
|
400
460
|
}
|
|
401
461
|
/** Delete one row; the remaining rows renumber themselves. */
|
|
@@ -616,7 +676,7 @@ var en = {
|
|
|
616
676
|
"switch.rewrite.title": "Rewrite subagent model and effort",
|
|
617
677
|
"switch.rewrite.desc": "Every subagent is judged once when it is delegated. While this is off, nothing is judged and nothing is logged.",
|
|
618
678
|
"switch.log.title": "Record the log",
|
|
619
|
-
"switch.log.desc": "
|
|
679
|
+
"switch.log.desc": "Write every judgement to a file under the DSH home, so it survives a restart.",
|
|
620
680
|
"judge.title": "Judgement service",
|
|
621
681
|
"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.",
|
|
622
682
|
"judge.endpoint": "Endpoint address",
|
|
@@ -650,7 +710,7 @@ var en = {
|
|
|
650
710
|
"reason.unknown": "unknown reason",
|
|
651
711
|
"rows.title": "Task types",
|
|
652
712
|
"rows.desc": "One row per task type: the number it answers with, the description it reads, the model it runs on, and the effort. Numbers are assigned for you, always 1, 2, 3\u2026",
|
|
653
|
-
"rows.empty": "No task type yet. Add one below
|
|
713
|
+
"rows.empty": "No task type yet. Add one below.",
|
|
654
714
|
"rows.colId": "No.",
|
|
655
715
|
"rows.colType": "Task type",
|
|
656
716
|
"rows.colDescription": "Description",
|
|
@@ -666,28 +726,18 @@ var en = {
|
|
|
666
726
|
"rows.incomplete": "Not used",
|
|
667
727
|
"rows.descriptionPlaceholder": "What kind of job is this? Write as much as you like.",
|
|
668
728
|
"rows.allowedEmpty": 'The host setting "models subagents may choose" is empty, so there is nothing to pick. Fill it in on the Subagent settings page first.',
|
|
669
|
-
"
|
|
670
|
-
"
|
|
671
|
-
"
|
|
672
|
-
"
|
|
673
|
-
"
|
|
674
|
-
"
|
|
675
|
-
"
|
|
676
|
-
"
|
|
677
|
-
"
|
|
678
|
-
"
|
|
679
|
-
"
|
|
680
|
-
"
|
|
681
|
-
"preset.review.desc": "Reading a change and reporting what is wrong or missing in it.",
|
|
682
|
-
"preset.debug": "Debugging a hard problem",
|
|
683
|
-
"preset.debug.desc": "Finding the cause of a failure that is not obvious from the symptom.",
|
|
684
|
-
"preset.design": "Technical plan",
|
|
685
|
-
"preset.design.desc": "Deciding how to build something and what the trade-offs are.",
|
|
686
|
-
"preset.test": "Running tests",
|
|
687
|
-
"preset.test.desc": "Running an existing check and reporting what it produced.",
|
|
688
|
-
"preset.effortLow": "low",
|
|
689
|
-
"preset.effortMedium": "medium",
|
|
690
|
-
"preset.effortHigh": "high",
|
|
729
|
+
"rows.importOpen": "Import",
|
|
730
|
+
"rows.export": "Export",
|
|
731
|
+
"rows.exported": "Copied the task-type list as JSON.",
|
|
732
|
+
"rows.exportFailed": "Could not copy to the clipboard.",
|
|
733
|
+
"rows.importTitle": "Import the task-type list",
|
|
734
|
+
"rows.importDesc": "Paste the JSON list here. It fills the table below; nothing is written until you press Save.",
|
|
735
|
+
"rows.importPlaceholder": '[\n { "description": "...", "provider": "...", "model": "...", "effort": "..." }\n]',
|
|
736
|
+
"rows.importApply": "Fill in",
|
|
737
|
+
"rows.importCancel": "Cancel",
|
|
738
|
+
"rows.importBadJson": "This is not valid JSON.",
|
|
739
|
+
"rows.importBadShape": "This is not a list of task types: every entry needs description, provider, model and effort as text.",
|
|
740
|
+
"rows.importEmpty": "There is no task type in this list.",
|
|
691
741
|
"preview.title": "View the full prompt",
|
|
692
742
|
"preview.desc": "Exactly what would be sent to the judgement service. The delegation label and the task text are filled in at delegation time.",
|
|
693
743
|
"preview.open": "View the full prompt",
|
|
@@ -706,8 +756,8 @@ var en = {
|
|
|
706
756
|
"save.emptyDescription": "Every row needs a description before it can be saved.",
|
|
707
757
|
"save.invalid": "This cannot be saved yet.",
|
|
708
758
|
"save.refused": "The host did not accept this write.",
|
|
709
|
-
"log.title": "
|
|
710
|
-
"log.desc": "The most recent
|
|
759
|
+
"log.title": "Judgement log",
|
|
760
|
+
"log.desc": "The most recent 10 judgements, newest first; the file keeps more. Click one to see the exact prompt that was sent.",
|
|
711
761
|
"log.empty": "No judgement has run yet.",
|
|
712
762
|
"log.colResult": "Result",
|
|
713
763
|
"log.colChoice": "Choice",
|
|
@@ -731,7 +781,7 @@ var zh = {
|
|
|
731
781
|
"switch.rewrite.title": "\u6539\u5199\u5B50\u4EE3\u7406\u7684\u6A21\u578B\u4E0E\u5F3A\u5EA6",
|
|
732
782
|
"switch.rewrite.desc": "\u6BCF\u4E2A\u5B50\u4EE3\u7406\u5728\u6D3E\u5DE5\u90A3\u4E00\u523B\u5224\u65AD\u4E00\u6B21\u3002\u8FD9\u4E2A\u5F00\u5173\u5173\u7740\u65F6\u4E0D\u5224\u65AD\uFF0C\u4E5F\u4E0D\u8BB0\u65E5\u5FD7\u3002",
|
|
733
783
|
"switch.log.title": "\u8BB0\u5F55\u65E5\u5FD7",
|
|
734
|
-
"switch.log.desc": "\
|
|
784
|
+
"switch.log.desc": "\u628A\u6BCF\u6B21\u5224\u65AD\u5199\u8FDB DSH \u5BB6\u76EE\u5F55\u91CC\u7684\u4E00\u4E2A\u6587\u4EF6\uFF0C\u91CD\u542F\u4E4B\u540E\u7167\u6837\u5728\u3002",
|
|
735
785
|
"judge.title": "\u5224\u65AD\u670D\u52A1",
|
|
736
786
|
"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",
|
|
737
787
|
"judge.endpoint": "\u7AEF\u70B9\u5730\u5740",
|
|
@@ -765,7 +815,7 @@ var zh = {
|
|
|
765
815
|
"reason.unknown": "\u539F\u56E0\u4E0D\u660E",
|
|
766
816
|
"rows.title": "\u4EFB\u52A1\u7C7B\u578B",
|
|
767
817
|
"rows.desc": "\u4E00\u884C\u4E00\u4E2A\u4EFB\u52A1\u7C7B\u578B\uFF1A\u5B83\u56DE\u7B54\u7684\u7F16\u53F7\u3001\u5B83\u8BFB\u7684\u63CF\u8FF0\u3001\u8BE5\u7528\u7684\u6A21\u578B\u4E0E\u5F3A\u5EA6\u3002\u7F16\u53F7\u7531\u63D2\u4EF6\u81EA\u52A8\u6392\uFF0C\u6C38\u8FDC\u4ECE 1 \u5F80\u540E\u8FDE\u7740\u3002",
|
|
768
|
-
"rows.empty": "\u8FD8\u6CA1\u6709\u4EFB\u52A1\u7C7B\u578B\u3002\u5728\u4E0B\u9762\u52A0\u4E00\u884C\
|
|
818
|
+
"rows.empty": "\u8FD8\u6CA1\u6709\u4EFB\u52A1\u7C7B\u578B\u3002\u5728\u4E0B\u9762\u52A0\u4E00\u884C\u3002",
|
|
769
819
|
"rows.colId": "\u7F16\u53F7",
|
|
770
820
|
"rows.colType": "\u4EFB\u52A1\u7C7B\u578B",
|
|
771
821
|
"rows.colDescription": "\u63CF\u8FF0",
|
|
@@ -781,28 +831,18 @@ var zh = {
|
|
|
781
831
|
"rows.incomplete": "\u4E0D\u751F\u6548",
|
|
782
832
|
"rows.descriptionPlaceholder": "\u8FD9\u662F\u54EA\u79CD\u6D3B\uFF1F\u5199\u591A\u5C11\u90FD\u884C\u3002",
|
|
783
833
|
"rows.allowedEmpty": "\u5BBF\u4E3B\u90A3\u4EFD\u300C\u5B50\u4EE3\u7406\u53EF\u9009\u7528\u54EA\u4E9B\u6A21\u578B\u300D\u8FD8\u662F\u7A7A\u7684\uFF0C\u6CA1\u6709\u53EF\u4EE5\u9009\u7684\u4E1C\u897F\u3002\u5148\u5230\u5B50\u4EE3\u7406\u8BBE\u7F6E\u9875\u628A\u5B83\u586B\u4E0A\u3002",
|
|
784
|
-
"
|
|
785
|
-
"
|
|
786
|
-
"
|
|
787
|
-
"
|
|
788
|
-
"
|
|
789
|
-
"
|
|
790
|
-
"
|
|
791
|
-
"
|
|
792
|
-
"
|
|
793
|
-
"
|
|
794
|
-
"
|
|
795
|
-
"
|
|
796
|
-
"preset.review.desc": "\u8BFB\u4E00\u5904\u6539\u52A8\uFF0C\u6307\u51FA\u54EA\u91CC\u4E0D\u5BF9\u3001\u54EA\u91CC\u7F3A\u4E86\u3002",
|
|
797
|
-
"preset.debug": "\u8C03\u8BD5\u7591\u96BE",
|
|
798
|
-
"preset.debug.desc": "\u627E\u51FA\u4E00\u4E2A\u4ECE\u73B0\u8C61\u770B\u4E0D\u51FA\u6765\u7684\u5931\u8D25\u7684\u8D77\u56E0\u3002",
|
|
799
|
-
"preset.design": "\u505A\u6280\u672F\u65B9\u6848",
|
|
800
|
-
"preset.design.desc": "\u51B3\u5B9A\u8FD9\u4EF6\u4E8B\u600E\u4E48\u505A\uFF0C\u4EE5\u53CA\u5404\u6761\u8DEF\u7684\u53D6\u820D\u3002",
|
|
801
|
-
"preset.test": "\u8DD1\u6D4B\u8BD5",
|
|
802
|
-
"preset.test.desc": "\u8DD1\u4E00\u6B21\u73B0\u6210\u7684\u68C0\u67E5\uFF0C\u628A\u7ED3\u679C\u62A5\u56DE\u6765\u3002",
|
|
803
|
-
"preset.effortLow": "\u4F4E",
|
|
804
|
-
"preset.effortMedium": "\u4E2D",
|
|
805
|
-
"preset.effortHigh": "\u9AD8",
|
|
834
|
+
"rows.importOpen": "\u5BFC\u5165",
|
|
835
|
+
"rows.export": "\u5BFC\u51FA",
|
|
836
|
+
"rows.exported": "\u5DF2\u7ECF\u628A\u4EFB\u52A1\u7C7B\u578B\u6E05\u5355\u6309 JSON \u590D\u5236\u8D70\u4E86\u3002",
|
|
837
|
+
"rows.exportFailed": "\u590D\u5236\u5230\u526A\u8D34\u677F\u6CA1\u6210\u529F\u3002",
|
|
838
|
+
"rows.importTitle": "\u5BFC\u5165\u4EFB\u52A1\u7C7B\u578B",
|
|
839
|
+
"rows.importDesc": "\u628A JSON \u6E05\u5355\u7C98\u8D34\u5230\u8FD9\u91CC\u3002\u5B83\u53EA\u586B\u4E0B\u9762\u90A3\u5F20\u8868\uFF0C\u6309\u300C\u4FDD\u5B58\u300D\u4E4B\u524D\u4E00\u4E2A\u5B57\u90FD\u4E0D\u5199\u3002",
|
|
840
|
+
"rows.importPlaceholder": '[\n { "description": "\u2026\u2026", "provider": "\u2026\u2026", "model": "\u2026\u2026", "effort": "\u2026\u2026" }\n]',
|
|
841
|
+
"rows.importApply": "\u586B\u8FDB\u53BB",
|
|
842
|
+
"rows.importCancel": "\u53D6\u6D88",
|
|
843
|
+
"rows.importBadJson": "\u8FD9\u4E0D\u662F\u5408\u6CD5\u7684 JSON\u3002",
|
|
844
|
+
"rows.importBadShape": "\u8FD9\u4E0D\u662F\u4E00\u4EFD\u4EFB\u52A1\u7C7B\u578B\u6E05\u5355\uFF1A\u6BCF\u4E00\u6761\u90FD\u8981\u6709 description\u3001provider\u3001model\u3001effort \u56DB\u4E2A\u6587\u5B57\u5B57\u6BB5\u3002",
|
|
845
|
+
"rows.importEmpty": "\u8FD9\u4EFD\u6E05\u5355\u91CC\u4E00\u6761\u4EFB\u52A1\u7C7B\u578B\u90FD\u6CA1\u6709\u3002",
|
|
806
846
|
"preview.title": "\u67E5\u770B\u5B8C\u6574\u9884\u89C8",
|
|
807
847
|
"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",
|
|
808
848
|
"preview.open": "\u67E5\u770B\u5B8C\u6574\u9884\u89C8",
|
|
@@ -821,8 +861,8 @@ var zh = {
|
|
|
821
861
|
"save.emptyDescription": "\u6BCF\u4E00\u884C\u90FD\u8981\u6709\u63CF\u8FF0\u624D\u80FD\u4FDD\u5B58\u3002",
|
|
822
862
|
"save.invalid": "\u73B0\u5728\u8FD8\u5B58\u4E0D\u4E86\u3002",
|
|
823
863
|
"save.refused": "\u5BBF\u4E3B\u6CA1\u6709\u63A5\u53D7\u8FD9\u6B21\u5199\u5165\u3002",
|
|
824
|
-
"log.title": "\
|
|
825
|
-
"log.desc": "\
|
|
864
|
+
"log.title": "\u5224\u65AD\u65E5\u5FD7",
|
|
865
|
+
"log.desc": "\u6700\u8FD1 10 \u6761\u5224\u65AD\uFF0C\u65B0\u7684\u5728\u6700\u524D\u9762\uFF1B\u6587\u4EF6\u91CC\u7559\u5F97\u66F4\u591A\u3002\u70B9\u4E00\u884C\u770B\u8FD9\u6B21\u53D1\u7ED9\u5224\u65AD\u6A21\u578B\u7684\u90A3\u6BB5\u5185\u5BB9\u3002",
|
|
826
866
|
"log.empty": "\u8FD8\u6CA1\u6709\u5224\u65AD\u8FC7\u3002",
|
|
827
867
|
"log.colResult": "\u7ED3\u679C",
|
|
828
868
|
"log.colChoice": "\u9009\u62E9",
|
|
@@ -846,16 +886,11 @@ function apply(ctx) {
|
|
|
846
886
|
|
|
847
887
|
// src/client/settings/ui.tsx
|
|
848
888
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
849
|
-
var
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
{ key: "review", effortHint: "preset.effortMedium" },
|
|
855
|
-
{ key: "debug", effortHint: "preset.effortHigh" },
|
|
856
|
-
{ key: "design", effortHint: "preset.effortHigh" },
|
|
857
|
-
{ key: "test", effortHint: "preset.effortLow" }
|
|
858
|
-
];
|
|
889
|
+
var IMPORT_ERROR_KEYS = {
|
|
890
|
+
json: "rows.importBadJson",
|
|
891
|
+
shape: "rows.importBadShape",
|
|
892
|
+
empty: "rows.importEmpty"
|
|
893
|
+
};
|
|
859
894
|
var CREDENTIALS_PATH = "~/.dsh/.credentials.yaml";
|
|
860
895
|
function withSamples(text, samples) {
|
|
861
896
|
return text.split(/(\{\w+\})/g).map((part, index) => {
|
|
@@ -921,11 +956,6 @@ var CARD_CSS = `
|
|
|
921
956
|
.dsh-judge-no { color: var(--dsw-alias-label-tertiary); font: var(--dsw-font-xxs-12); font-variant-numeric: tabular-nums; }
|
|
922
957
|
.dsh-judge-row-off .dsh-judge-field { opacity: 0.6; }
|
|
923
958
|
.dsh-judge-cell-actions { display: flex; gap: 6px; }
|
|
924
|
-
.dsh-judge-presets { display: flex; flex-wrap: wrap; gap: 6px; }
|
|
925
|
-
.dsh-judge-preset { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; padding: 6px 10px; border: 0.5px solid var(--dsw-alias-border-l3); border-radius: var(--dsw-radius-md); background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
|
|
926
|
-
.dsh-judge-preset:hover { background: var(--dsw-alias-interactive-bg-hover); }
|
|
927
|
-
.dsh-judge-preset-title { font: var(--dsw-font-xs-13); }
|
|
928
|
-
.dsh-judge-preset-hint { color: var(--dsw-alias-label-tertiary); font: var(--dsw-font-xxxs-11); }
|
|
929
959
|
.dsh-judge-log { display: flex; flex-direction: column; gap: 4px; font: var(--dsw-font-xxs-12); }
|
|
930
960
|
/* \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
961
|
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 */
|
|
@@ -934,18 +964,27 @@ var CARD_CSS = `
|
|
|
934
964
|
.dsh-judge-log-row:hover { background: var(--dsw-alias-interactive-bg-hover); }
|
|
935
965
|
.dsh-judge-log-head { font-weight: 600; color: var(--dsw-alias-label-tertiary); cursor: default; }
|
|
936
966
|
.dsh-judge-log-head:hover { background: none; }
|
|
937
|
-
/* \u5F39\u7A97\u91CC\u662F\u4E00\u6574\u6BB5
|
|
938
|
-
|
|
967
|
+
/* \u5F39\u7A97\u91CC\u662F\u4E00\u6574\u6BB5\u8BF7\u6C42\u4F53\uFF1A\u91CF\u5BBD\u653E\u5F00\uFF0C\u6B63\u6587\u81EA\u5DF1\u6362\u884C\uFF0C\u9AD8\u4E86\u5C31\u5728\u6846\u91CC\u6EDA\u52A8\u2014\u2014\u6491\u5230\u5F39\u7A97
|
|
968
|
+
\u5916\u9762\u7684\u5185\u5BB9\u65E2\u770B\u4E0D\u89C1\u4E5F\u6EDA\u4E0D\u5230\u3002\u6EDA\u52A8\u6761\u7684\u4E24\u79CD\u989C\u8272\u8DDF\u7740\u5F39\u7A97\u8FD9\u5C42\u8868\u9762\u8D70\u3002 */
|
|
969
|
+
.dsh-judge-modal { width: min(760px, 100%); max-height: min(85vh, 100%); --dsh-scrollbar-thumb: var(--dsw-alias-scrollbar-bg-l2); --dsh-scrollbar-thumb-hover: var(--dsw-alias-scrollbar-hover-l2); }
|
|
970
|
+
.dsh-judge-prompt { max-height: 58vh; overflow: auto; }
|
|
971
|
+
.dsh-judge-prompt pre { white-space: pre-wrap; overflow-wrap: anywhere; word-break: break-word; }
|
|
972
|
+
/* \u7C98\u8D34\u6846\uFF1A\u7B49\u5BBD\u663E\u793A\uFF0C\u597D\u8BA9\u8BFB\u8005\u770B\u51FA JSON \u7684\u5C42\u7EA7\uFF1B\u81EA\u5DF1\u6491\u9AD8\u5230\u4E00\u5C4F\u7684\u4E00\u534A\u518D\u6EDA\u52A8\u3002 */
|
|
973
|
+
.dsh-judge-paste { box-sizing: border-box; width: 100%; min-height: 220px; max-height: 45vh; resize: vertical; padding: 10px 12px; border: 0.5px solid var(--dsw-alias-border-l3); border-radius: var(--dsw-radius-md); background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); font: var(--dsw-font-markdown-code-block); }
|
|
974
|
+
.dsh-judge-paste:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--dsw-alias-state-business-primary); }
|
|
939
975
|
`;
|
|
940
976
|
function injectCardStyles() {
|
|
941
977
|
if (typeof document === "undefined") return;
|
|
942
978
|
if (document.getElementById(STYLE_ID) !== null) return;
|
|
943
979
|
const element = document.createElement("style");
|
|
944
980
|
element.id = STYLE_ID;
|
|
981
|
+
element.dataset.plugin = PLUGIN_NAME;
|
|
982
|
+
element.dataset.pluginCss = `${PLUGIN_NAME}/settings/ui`;
|
|
945
983
|
element.textContent = CARD_CSS;
|
|
946
984
|
document.head.appendChild(element);
|
|
947
985
|
}
|
|
948
986
|
var STYLE_ID = "dsh-subagent-judge-dispatch-styles";
|
|
987
|
+
var PLUGIN_NAME = "@lynn123411/dsh-subagent-judge-dispatch";
|
|
949
988
|
function JudgeDispatchPanel(props) {
|
|
950
989
|
const { t } = props;
|
|
951
990
|
const [state, setState] = (0, import_react.useState)(() => dispatchCardStore.getState());
|
|
@@ -958,6 +997,9 @@ function JudgeDispatchPanel(props) {
|
|
|
958
997
|
const [detail, setDetail] = (0, import_react.useState)(null);
|
|
959
998
|
const [openMenu, setOpenMenu] = (0, import_react.useState)(null);
|
|
960
999
|
const [refusal, setRefusal] = (0, import_react.useState)(null);
|
|
1000
|
+
const [importText, setImportText] = (0, import_react.useState)(null);
|
|
1001
|
+
const [importError, setImportError] = (0, import_react.useState)("");
|
|
1002
|
+
const [copyNote, setCopyNote] = (0, import_react.useState)(null);
|
|
961
1003
|
(0, import_react.useEffect)(() => {
|
|
962
1004
|
setState(dispatchCardStore.getState());
|
|
963
1005
|
return dispatchCardStore.subscribe(() => setState(dispatchCardStore.getState()));
|
|
@@ -983,6 +1025,25 @@ function JudgeDispatchPanel(props) {
|
|
|
983
1025
|
setPreview(text ?? t("preview.failed"));
|
|
984
1026
|
setPreviewOpen(true);
|
|
985
1027
|
};
|
|
1028
|
+
const exportRows = async () => {
|
|
1029
|
+
const copied = await (0, import_dsh_client_ui_primitives.writeClipboard)(exportRowsJson(state.rows));
|
|
1030
|
+
setCopyNote({ ok: copied, text: t(copied ? "rows.exported" : "rows.exportFailed") });
|
|
1031
|
+
};
|
|
1032
|
+
const openImport = () => {
|
|
1033
|
+
setImportText("");
|
|
1034
|
+
setImportError("");
|
|
1035
|
+
setCopyNote(null);
|
|
1036
|
+
};
|
|
1037
|
+
const applyImport = () => {
|
|
1038
|
+
const result = parseRowsJson(importText ?? "");
|
|
1039
|
+
if (!result.ok) {
|
|
1040
|
+
setImportError(t(IMPORT_ERROR_KEYS[result.error]));
|
|
1041
|
+
return;
|
|
1042
|
+
}
|
|
1043
|
+
dispatchCardStore.replaceRows(result.rows);
|
|
1044
|
+
setImportText(null);
|
|
1045
|
+
setImportError("");
|
|
1046
|
+
};
|
|
986
1047
|
const saveRow = (section, dirty, onSave, checks) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-actions", children: [
|
|
987
1048
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-actions-group", children: [
|
|
988
1049
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -1281,26 +1342,14 @@ function JudgeDispatchPanel(props) {
|
|
|
1281
1342
|
] }) }),
|
|
1282
1343
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("tbody", { children: state.rows.map((draft, index) => row(draft, index)) })
|
|
1283
1344
|
] }),
|
|
1284
|
-
/* @__PURE__ */ (0, import_jsx_runtime.
|
|
1345
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-actions-group", children: [
|
|
1346
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "outline", size: "sm", onClick: () => dispatchCardStore.addRow(), children: t("rows.add") }),
|
|
1347
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "outline", size: "sm", onClick: openImport, children: t("rows.importOpen") }),
|
|
1348
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "outline", size: "sm", onClick: () => void exportRows(), children: t("rows.export") }),
|
|
1349
|
+
copyNote !== null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: copyNote.ok ? "dsh-judge-note-ok" : "dsh-judge-note-bad", role: "status", children: copyNote.text })
|
|
1350
|
+
] }),
|
|
1285
1351
|
state.rowsInvalid !== "" && state.rowsDirty && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-note-bad", role: "alert", children: state.rowsInvalid }),
|
|
1286
1352
|
saveRow("rows", state.rowsDirty, saveRows)
|
|
1287
|
-
] }),
|
|
1288
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-section", children: [
|
|
1289
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-title", children: t("presets.title") }),
|
|
1290
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-desc", children: t("presets.desc") }),
|
|
1291
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-presets", children: PRESETS.map((preset) => /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1292
|
-
"button",
|
|
1293
|
-
{
|
|
1294
|
-
type: "button",
|
|
1295
|
-
className: "dsh-judge-preset",
|
|
1296
|
-
onClick: () => dispatchCardStore.addPreset(t(`preset.${preset.key}.desc`)),
|
|
1297
|
-
children: [
|
|
1298
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-judge-preset-title", children: t(`preset.${preset.key}`) }),
|
|
1299
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dsh-judge-preset-hint", children: t("presets.effortHint").replace("{effort}", t(preset.effortHint)) })
|
|
1300
|
-
]
|
|
1301
|
-
},
|
|
1302
|
-
preset.key
|
|
1303
|
-
)) })
|
|
1304
1353
|
] })
|
|
1305
1354
|
] });
|
|
1306
1355
|
const log = /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-panel", children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "dsh-judge-section", children: [
|
|
@@ -1333,7 +1382,7 @@ function JudgeDispatchPanel(props) {
|
|
|
1333
1382
|
onClick: () => setDetail(entry),
|
|
1334
1383
|
children: [
|
|
1335
1384
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LogCell, { text: result.text, hint: result.hint }),
|
|
1336
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LogCell, { text:
|
|
1385
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LogCell, { text: describeModel(entry) || "\u2014", hint: describeChoice(entry) }),
|
|
1337
1386
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LogCell, { text: entry.parentTitle || "\u2014" }),
|
|
1338
1387
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(LogCell, { text: entry.childLabel || "\u2014" }),
|
|
1339
1388
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: new Date(entry.at).toLocaleTimeString() }),
|
|
@@ -1379,7 +1428,40 @@ function JudgeDispatchPanel(props) {
|
|
|
1379
1428
|
className: "dsh-judge-modal",
|
|
1380
1429
|
children: [
|
|
1381
1430
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-desc", children: t("preview.desc") }),
|
|
1382
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.CodeBlock, { code: preview ?? "", copyLabel: t("preview.copy"), copiedLabel: t("preview.copied") })
|
|
1431
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-prompt", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.CodeBlock, { code: preview ?? "", copyLabel: t("preview.copy"), copiedLabel: t("preview.copied") }) })
|
|
1432
|
+
]
|
|
1433
|
+
}
|
|
1434
|
+
),
|
|
1435
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1436
|
+
import_dsh_client_ui_primitives.Modal,
|
|
1437
|
+
{
|
|
1438
|
+
open: importText !== null,
|
|
1439
|
+
onClose: () => setImportText(null),
|
|
1440
|
+
title: t("rows.importTitle"),
|
|
1441
|
+
closeLabel: t("rows.browseClose"),
|
|
1442
|
+
description: t("rows.importDesc"),
|
|
1443
|
+
className: "dsh-judge-modal",
|
|
1444
|
+
footer: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
1445
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "outline", size: "sm", onClick: () => setImportText(null), children: t("rows.importCancel") }),
|
|
1446
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dsh_client_ui_primitives.Button, { variant: "primary", size: "sm", onClick: applyImport, children: t("rows.importApply") })
|
|
1447
|
+
] }),
|
|
1448
|
+
children: [
|
|
1449
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1450
|
+
"textarea",
|
|
1451
|
+
{
|
|
1452
|
+
className: "dsh-judge-paste",
|
|
1453
|
+
value: importText ?? "",
|
|
1454
|
+
"aria-label": t("rows.importTitle"),
|
|
1455
|
+
placeholder: t("rows.importPlaceholder"),
|
|
1456
|
+
spellCheck: false,
|
|
1457
|
+
"data-modal-autofocus": true,
|
|
1458
|
+
onChange: (event) => {
|
|
1459
|
+
setImportText(event.target.value);
|
|
1460
|
+
setImportError("");
|
|
1461
|
+
}
|
|
1462
|
+
}
|
|
1463
|
+
),
|
|
1464
|
+
importError !== "" && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "dsh-judge-note-bad", role: "alert", children: importError })
|
|
1383
1465
|
]
|
|
1384
1466
|
}
|
|
1385
1467
|
),
|
|
@@ -1402,14 +1484,14 @@ function JudgeDispatchPanel(props) {
|
|
|
1402
1484
|
closeLabel: t("log.promptClose"),
|
|
1403
1485
|
description: t("log.promptDesc"),
|
|
1404
1486
|
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)(
|
|
1487
|
+
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)("div", { className: "dsh-judge-prompt", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1406
1488
|
import_dsh_client_ui_primitives.CodeBlock,
|
|
1407
1489
|
{
|
|
1408
1490
|
code: detail.prompt,
|
|
1409
1491
|
copyLabel: t("preview.copy"),
|
|
1410
1492
|
copiedLabel: t("preview.copied")
|
|
1411
1493
|
}
|
|
1412
|
-
))
|
|
1494
|
+
) }))
|
|
1413
1495
|
}
|
|
1414
1496
|
)
|
|
1415
1497
|
] });
|