@linxin666/dsh-client-ui-task-board 0.3.14 → 0.3.16
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/lib/client.js +92 -54
- package/lib/client.js.map +1 -1
- package/lib/index.js +40 -10
- package/lib/types/client/locales.d.ts +3 -0
- package/lib/types/core/controller.d.ts +8 -0
- package/lib/types/core/tasks.d.ts +7 -0
- package/lib/types/core/use-cases/task-update.d.ts +1 -1
- package/package.json +1 -1
- package/src/client/board/NewTaskModal.tsx +16 -0
- package/src/client/board/TaskDetail.tsx +17 -0
- package/src/client/index.ts +34 -2
- package/src/client/locales.ts +6 -0
- package/src/core/controller.ts +10 -1
- package/src/core/tasks.ts +8 -0
- package/src/core/use-cases/task-update.ts +3 -1
- package/src/host-runner.ts +15 -0
- package/src/index.ts +14 -4
- package/src/protocol.ts +4 -4
package/lib/client.js
CHANGED
|
@@ -94,6 +94,7 @@ window.__ModuleLoader__.load({
|
|
|
94
94
|
workspaceId: normalizeTargetId(input.workspaceId),
|
|
95
95
|
mode: normalizeTargetId(input.mode),
|
|
96
96
|
permission: isTaskPermission(input.permission) ? input.permission : void 0,
|
|
97
|
+
model: normalizeTargetId(input.model),
|
|
97
98
|
...input.freeze === void 0 ? {} : { freeze: freezeOf(input.freeze, now) },
|
|
98
99
|
...input.handover === void 0 ? {} : { handover: {
|
|
99
100
|
...input.handover,
|
|
@@ -515,6 +516,7 @@ window.__ModuleLoader__.load({
|
|
|
515
516
|
const workspaceId = "workspaceId" in patch ? normalizeTargetId(patch.workspaceId) : void 0;
|
|
516
517
|
const mode = "mode" in patch ? normalizeTargetId(patch.mode) : void 0;
|
|
517
518
|
const permission = "permission" in patch ? normalizePermission(task.permission, patch.permission) : void 0;
|
|
519
|
+
const model = "model" in patch ? normalizeTargetId(patch.model) : void 0;
|
|
518
520
|
const next = {
|
|
519
521
|
...task,
|
|
520
522
|
...rest,
|
|
@@ -534,6 +536,7 @@ window.__ModuleLoader__.load({
|
|
|
534
536
|
if (workspaceId !== void 0 || "workspaceId" in patch) next.workspaceId = workspaceId;
|
|
535
537
|
if (mode !== void 0 || "mode" in patch) next.mode = mode;
|
|
536
538
|
if (permission !== void 0 || "permission" in patch) next.permission = permission;
|
|
539
|
+
if (model !== void 0 || "model" in patch) next.model = model;
|
|
537
540
|
return next;
|
|
538
541
|
});
|
|
539
542
|
}
|
|
@@ -572,7 +575,8 @@ window.__ModuleLoader__.load({
|
|
|
572
575
|
selectedTaskId;
|
|
573
576
|
executionOptions = {
|
|
574
577
|
workspaces: [],
|
|
575
|
-
presets: []
|
|
578
|
+
presets: [],
|
|
579
|
+
models: []
|
|
576
580
|
};
|
|
577
581
|
listeners = /* @__PURE__ */ new Set();
|
|
578
582
|
disposers = [];
|
|
@@ -1581,6 +1585,7 @@ window.__ModuleLoader__.load({
|
|
|
1581
1585
|
"new.workspace": "工作区",
|
|
1582
1586
|
"new.mode": "模式",
|
|
1583
1587
|
"new.permission": "权限",
|
|
1588
|
+
"new.model": "模型",
|
|
1584
1589
|
"exec.workspace.recent": "最近使用(默认)",
|
|
1585
1590
|
"exec.mode.default": "部署默认",
|
|
1586
1591
|
"exec.mode.defaultSuffix": "(默认)",
|
|
@@ -1590,6 +1595,8 @@ window.__ModuleLoader__.load({
|
|
|
1590
1595
|
"exec.permission.read-only": "只读",
|
|
1591
1596
|
"exec.permission.workspace-write": "工作区可写",
|
|
1592
1597
|
"exec.permission.danger-full-access": "完全访问",
|
|
1598
|
+
"exec.model.default": "宿主默认(agent-default-model)",
|
|
1599
|
+
"exec.model.unknown": "(未知模型/回退默认)",
|
|
1593
1600
|
"detail.executionSettings": "执行设置",
|
|
1594
1601
|
"exec.hint": "执行时生效:工作区决定执行会话落在哪个工作区;模式决定会话的 agent 预设;权限经 /permission 命令应用到会话。留空则使用运行时默认。",
|
|
1595
1602
|
"settings.title": "任务看板",
|
|
@@ -1724,6 +1731,7 @@ window.__ModuleLoader__.load({
|
|
|
1724
1731
|
"new.workspace": "Workspace",
|
|
1725
1732
|
"new.mode": "Mode",
|
|
1726
1733
|
"new.permission": "Permission",
|
|
1734
|
+
"new.model": "Model",
|
|
1727
1735
|
"exec.workspace.recent": "Most recent (default)",
|
|
1728
1736
|
"exec.mode.default": "Deployment default",
|
|
1729
1737
|
"exec.mode.defaultSuffix": " (default)",
|
|
@@ -1733,6 +1741,8 @@ window.__ModuleLoader__.load({
|
|
|
1733
1741
|
"exec.permission.read-only": "Read-only",
|
|
1734
1742
|
"exec.permission.workspace-write": "Workspace Write",
|
|
1735
1743
|
"exec.permission.danger-full-access": "Full Access",
|
|
1744
|
+
"exec.model.default": "Host default (agent-default-model)",
|
|
1745
|
+
"exec.model.unknown": " (unknown / fallback to default)",
|
|
1736
1746
|
"detail.executionSettings": "Execution Settings",
|
|
1737
1747
|
"exec.hint": "Applied when the task runs: the workspace decides where the execution session lands; the mode composes the session's agent preset; the permission is applied through the /permission command. Blank = runtime default.",
|
|
1738
1748
|
"settings.title": "Task Board",
|
|
@@ -1988,6 +1998,7 @@ window.__ModuleLoader__.load({
|
|
|
1988
1998
|
const [workspaceId, setWorkspaceId] = (0, react.useState)("");
|
|
1989
1999
|
const [mode, setMode] = (0, react.useState)("");
|
|
1990
2000
|
const [permission, setPermission] = (0, react.useState)("");
|
|
2001
|
+
const [model, setModel] = (0, react.useState)("");
|
|
1991
2002
|
const [scheduleEnabled, setScheduleEnabled] = (0, react.useState)(false);
|
|
1992
2003
|
const [scheduleCron, setScheduleCron] = (0, react.useState)("");
|
|
1993
2004
|
const [scheduleError, setScheduleError] = (0, react.useState)(void 0);
|
|
@@ -2035,6 +2046,7 @@ window.__ModuleLoader__.load({
|
|
|
2035
2046
|
workspaceId: workspaceId === "" ? void 0 : workspaceId,
|
|
2036
2047
|
mode: mode === "" ? void 0 : mode,
|
|
2037
2048
|
permission: permission === "" ? void 0 : permission,
|
|
2049
|
+
model: model === "" ? void 0 : model,
|
|
2038
2050
|
schedule: scheduleEnabled ? {
|
|
2039
2051
|
enabled: true,
|
|
2040
2052
|
cron: scheduleCron.trim()
|
|
@@ -2172,6 +2184,26 @@ window.__ModuleLoader__.load({
|
|
|
2172
2184
|
}, id))]
|
|
2173
2185
|
})]
|
|
2174
2186
|
}),
|
|
2187
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
2188
|
+
className: board_module_css_default.field,
|
|
2189
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2190
|
+
className: board_module_css_default.fieldLabel,
|
|
2191
|
+
children: t("new.model")
|
|
2192
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
2193
|
+
className: board_module_css_default.select,
|
|
2194
|
+
value: model,
|
|
2195
|
+
onChange: (event) => {
|
|
2196
|
+
setModel(event.target.value);
|
|
2197
|
+
},
|
|
2198
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2199
|
+
value: "",
|
|
2200
|
+
children: t("exec.model.default")
|
|
2201
|
+
}), options.models?.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2202
|
+
value: item.id,
|
|
2203
|
+
children: item.name ?? item.id
|
|
2204
|
+
}, item.id))]
|
|
2205
|
+
})]
|
|
2206
|
+
}),
|
|
2175
2207
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2176
2208
|
className: board_module_css_default.detailSection,
|
|
2177
2209
|
children: [
|
|
@@ -2521,8 +2553,10 @@ window.__ModuleLoader__.load({
|
|
|
2521
2553
|
const workspaceId = task.workspaceId ?? "";
|
|
2522
2554
|
const mode = task.mode ?? "";
|
|
2523
2555
|
const permission = task.permission ?? "";
|
|
2556
|
+
const model = task.model ?? "";
|
|
2524
2557
|
const workspaceKnown = workspaceId === "" || options.workspaces.some((item) => item.workspaceId === workspaceId);
|
|
2525
2558
|
const modeKnown = mode === "" || options.presets.some((item) => item.id === mode);
|
|
2559
|
+
const modelKnown = model === "" || (options.models ?? []).some((item) => item.id === model);
|
|
2526
2560
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
2527
2561
|
className: board_module_css_default.detailSection,
|
|
2528
2562
|
children: [
|
|
@@ -2612,6 +2646,34 @@ window.__ModuleLoader__.load({
|
|
|
2612
2646
|
children: t(`exec.permission.${id}`)
|
|
2613
2647
|
}, id))]
|
|
2614
2648
|
})]
|
|
2649
|
+
}),
|
|
2650
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
2651
|
+
className: board_module_css_default.field,
|
|
2652
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2653
|
+
className: board_module_css_default.fieldLabel,
|
|
2654
|
+
children: t("new.model")
|
|
2655
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
2656
|
+
className: board_module_css_default.select,
|
|
2657
|
+
value: model,
|
|
2658
|
+
disabled: pending,
|
|
2659
|
+
onChange: (event) => {
|
|
2660
|
+
controller.updateTask(task.id, { model: event.target.value === "" ? void 0 : event.target.value });
|
|
2661
|
+
},
|
|
2662
|
+
children: [
|
|
2663
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2664
|
+
value: "",
|
|
2665
|
+
children: t("exec.model.default")
|
|
2666
|
+
}),
|
|
2667
|
+
!modelKnown && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("option", {
|
|
2668
|
+
value: model,
|
|
2669
|
+
children: [model, t("exec.model.unknown")]
|
|
2670
|
+
}),
|
|
2671
|
+
options.models?.map((item) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
2672
|
+
value: item.id,
|
|
2673
|
+
children: item.name ?? item.id
|
|
2674
|
+
}, item.id))
|
|
2675
|
+
]
|
|
2676
|
+
})]
|
|
2615
2677
|
})
|
|
2616
2678
|
]
|
|
2617
2679
|
});
|
|
@@ -4488,7 +4550,7 @@ window.__ModuleLoader__.load({
|
|
|
4488
4550
|
/** The building package's version, when the bundle carries it. */
|
|
4489
4551
|
function bakedVersion() {
|
|
4490
4552
|
try {
|
|
4491
|
-
return "0.3.
|
|
4553
|
+
return "0.3.16";
|
|
4492
4554
|
} catch {
|
|
4493
4555
|
return;
|
|
4494
4556
|
}
|
|
@@ -4574,44 +4636,6 @@ window.__ModuleLoader__.load({
|
|
|
4574
4636
|
"remote"
|
|
4575
4637
|
];
|
|
4576
4638
|
/**
|
|
4577
|
-
* Read the agent-preset roster through whichever face the running host
|
|
4578
|
-
* serves: the generated api-remotes face (`remote.agentPresets`,
|
|
4579
|
-
* 0.1.2-alpha.2) or the connection RPC face
|
|
4580
|
-
* (`connection.api.agentPresets`, hosts below that cohort). Answers
|
|
4581
|
-
* undefined when the host serves neither, so the caller leaves the picker
|
|
4582
|
-
* options untouched instead of erroring.
|
|
4583
|
-
*/
|
|
4584
|
-
async function readPresetRoster(ctx, remote) {
|
|
4585
|
-
let remotes;
|
|
4586
|
-
try {
|
|
4587
|
-
remotes = remote.agentPresets;
|
|
4588
|
-
} catch {
|
|
4589
|
-
remotes = void 0;
|
|
4590
|
-
}
|
|
4591
|
-
if (remotes !== void 0) {
|
|
4592
|
-
const response = await remotes.list();
|
|
4593
|
-
if (!response.ok) return {
|
|
4594
|
-
ok: false,
|
|
4595
|
-
presets: []
|
|
4596
|
-
};
|
|
4597
|
-
return {
|
|
4598
|
-
ok: true,
|
|
4599
|
-
presets: response.value.presets
|
|
4600
|
-
};
|
|
4601
|
-
}
|
|
4602
|
-
const legacy = ctx.get("connection").api?.agentPresets;
|
|
4603
|
-
if (legacy === void 0) return void 0;
|
|
4604
|
-
const response = await legacy.list({});
|
|
4605
|
-
if (!response.result.ok || response.result.value === void 0) return {
|
|
4606
|
-
ok: false,
|
|
4607
|
-
presets: []
|
|
4608
|
-
};
|
|
4609
|
-
return {
|
|
4610
|
-
ok: true,
|
|
4611
|
-
presets: response.result.value.presets ?? []
|
|
4612
|
-
};
|
|
4613
|
-
}
|
|
4614
|
-
/**
|
|
4615
4639
|
* Mount the task board.
|
|
4616
4640
|
* @param ctx - client root context (services: sessions, workspaces).
|
|
4617
4641
|
*/
|
|
@@ -4656,7 +4680,7 @@ window.__ModuleLoader__.load({
|
|
|
4656
4680
|
if (uiDisposer !== void 0) return;
|
|
4657
4681
|
const sessions = ctx.get("sessions");
|
|
4658
4682
|
const workspaces = ctx.get("workspaces");
|
|
4659
|
-
|
|
4683
|
+
ctx.get("remote");
|
|
4660
4684
|
const controller = new BoardController({
|
|
4661
4685
|
store: new LocalStorageTaskStore(),
|
|
4662
4686
|
transport: new HttpTaskBoardHostTransport(),
|
|
@@ -4676,24 +4700,38 @@ window.__ModuleLoader__.load({
|
|
|
4676
4700
|
};
|
|
4677
4701
|
pushWorkspaceOptions();
|
|
4678
4702
|
disposers.push(workspaces.list.subscribe(pushWorkspaceOptions));
|
|
4679
|
-
const
|
|
4703
|
+
const pushModelOptions = async () => {
|
|
4680
4704
|
try {
|
|
4681
|
-
const
|
|
4682
|
-
if (
|
|
4683
|
-
|
|
4684
|
-
|
|
4685
|
-
|
|
4686
|
-
|
|
4687
|
-
|
|
4688
|
-
|
|
4689
|
-
|
|
4705
|
+
const conn = ctx.get("connection");
|
|
4706
|
+
if (conn?.api) {
|
|
4707
|
+
let models = [];
|
|
4708
|
+
if (typeof conn.api.llm?.discoverModels === "function") {
|
|
4709
|
+
const list = (await conn.api.llm.discoverModels())?.result?.value?.models;
|
|
4710
|
+
if (Array.isArray(list)) models = list.map((m) => ({
|
|
4711
|
+
id: m.id,
|
|
4712
|
+
name: m.name
|
|
4713
|
+
}));
|
|
4714
|
+
}
|
|
4715
|
+
if (models.length === 0 && typeof conn.api.sessions?.modelCatalog === "function") {
|
|
4716
|
+
const groups = (await conn.api.sessions.modelCatalog())?.result?.value?.groups;
|
|
4717
|
+
if (Array.isArray(groups)) for (const g of groups) for (const m of g.models ?? []) {
|
|
4718
|
+
const qualifiedId = g.provider ? `${g.provider}/${m.id}` : m.id;
|
|
4719
|
+
models.push({
|
|
4720
|
+
id: qualifiedId,
|
|
4721
|
+
name: m.name ?? m.id,
|
|
4722
|
+
provider: g.provider
|
|
4723
|
+
});
|
|
4724
|
+
}
|
|
4725
|
+
}
|
|
4726
|
+
if (models.length > 0) controller.setExecutionOptions({ models });
|
|
4727
|
+
}
|
|
4690
4728
|
} catch (error) {
|
|
4691
|
-
console.error("[dsh-task-board]
|
|
4729
|
+
console.error("[dsh-task-board] model options read failed", error);
|
|
4692
4730
|
}
|
|
4693
4731
|
};
|
|
4694
|
-
|
|
4732
|
+
pushModelOptions();
|
|
4695
4733
|
disposers.push(ctx.on("connection/reset", () => {
|
|
4696
|
-
|
|
4734
|
+
pushModelOptions();
|
|
4697
4735
|
}));
|
|
4698
4736
|
try {
|
|
4699
4737
|
disposers.push(mountSidebarEntry(controller, ctx.locale));
|