@linxin666/dsh-client-ui-task-board 0.3.13 → 0.3.15

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 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.13";
4553
+ return "0.3.15";
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
- const remote = ctx.get("remote");
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 pushPresetOptions = async () => {
4703
+ const pushModelOptions = async () => {
4680
4704
  try {
4681
- const roster = await readPresetRoster(ctx, remote);
4682
- if (roster === void 0 || !roster.ok) return;
4683
- controller.setExecutionOptions({ presets: roster.presets.map((preset) => ({
4684
- id: preset.id,
4685
- name: preset.name,
4686
- description: preset.description,
4687
- broken: preset.broken,
4688
- isDefault: preset.isDefault
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] agent preset roster read failed", error);
4729
+ console.error("[dsh-task-board] model options read failed", error);
4692
4730
  }
4693
4731
  };
4694
- pushPresetOptions();
4732
+ pushModelOptions();
4695
4733
  disposers.push(ctx.on("connection/reset", () => {
4696
- pushPresetOptions();
4734
+ pushModelOptions();
4697
4735
  }));
4698
4736
  try {
4699
4737
  disposers.push(mountSidebarEntry(controller, ctx.locale));