@linxin666/dsh-client-ui-task-board 0.4.6 → 0.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +2 -2
- package/README.md +14 -6
- package/README.zh.md +14 -6
- package/lib/client.js +1502 -820
- package/lib/client.js.map +1 -1
- package/lib/index.js +674 -75
- package/lib/types/client/CardDefaultPresetField.d.ts +35 -0
- package/lib/types/client/TaskBoardSettingsCard.d.ts +49 -0
- package/lib/types/client/board/ReasoningEffortField.d.ts +25 -0
- package/lib/types/client/board/model-options.d.ts +67 -0
- package/lib/types/client/board/preset-label.d.ts +21 -0
- package/lib/types/client/board/preset-roster.d.ts +45 -0
- package/lib/types/client/board/team-run-promotion.d.ts +26 -0
- package/lib/types/client/locales.d.ts +16 -0
- package/lib/types/core/card-defaults.d.ts +78 -0
- package/lib/types/core/controller.d.ts +32 -7
- package/lib/types/core/launch-width.d.ts +31 -0
- package/lib/types/core/reasoning-effort.d.ts +57 -0
- package/lib/types/core/subtask.d.ts +30 -8
- package/lib/types/core/tasks.d.ts +19 -0
- package/lib/types/core/use-cases/task-create.d.ts +10 -5
- package/lib/types/core/use-cases/task-update.d.ts +1 -1
- package/lib/types/host/launch-admission.d.ts +72 -0
- package/lib/types/host-ledger.d.ts +9 -4
- package/lib/types/host-runner.d.ts +79 -4
- package/lib/types/host-service.d.ts +85 -2
- package/lib/types/index.d.ts +87 -0
- package/lib/types/protocol.d.ts +13 -0
- package/package.json +28 -28
- package/src/client/CardDefaultPresetField.tsx +101 -0
- package/src/client/TaskBoardSettingsCard.tsx +214 -16
- package/src/client/board/LinkSubtaskModal.tsx +8 -0
- package/src/client/board/NewTaskModal.tsx +86 -40
- package/src/client/board/ReasoningEffortField.tsx +50 -0
- package/src/client/board/TaskDetail.tsx +42 -6
- package/src/client/board/model-options.ts +178 -0
- package/src/client/board/preset-label.ts +32 -0
- package/src/client/board/preset-roster.ts +58 -0
- package/src/client/board/team-run-promotion.ts +39 -0
- package/src/client/index.ts +98 -94
- package/src/client/locales.ts +34 -2
- package/src/client/settings-entry-form.ts +0 -1
- package/src/core/card-defaults.ts +132 -0
- package/src/core/controller.ts +44 -9
- package/src/core/launch-width.ts +38 -0
- package/src/core/reasoning-effort.ts +92 -0
- package/src/core/store.ts +5 -0
- package/src/core/subtask.ts +48 -13
- package/src/core/tasks.ts +20 -0
- package/src/core/use-cases/task-create.ts +27 -16
- package/src/core/use-cases/task-update.ts +6 -1
- package/src/host/agent-tools.ts +21 -8
- package/src/host/launch-admission.ts +140 -0
- package/src/host-ledger.ts +18 -6
- package/src/host-runner.ts +184 -18
- package/src/host-service.ts +247 -23
- package/src/index.ts +149 -2
- package/src/protocol.ts +28 -4
package/README.i18n.yaml
CHANGED
|
@@ -2,5 +2,5 @@
|
|
|
2
2
|
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
|
3
3
|
# after editing either side, bring the other along and re-record with:
|
|
4
4
|
# node scripts/verify-docs.mjs --write <dir>
|
|
5
|
-
README.md:
|
|
6
|
-
README.zh.md:
|
|
5
|
+
README.md: dc528345f1bfd2b1dfce470545bcc73f9331e849
|
|
6
|
+
README.zh.md: 847ed5ce0acfb5091f9b9a8380fd3f701777c0c7
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ English | [中文](README.zh.md)
|
|
|
5
5
|
<p align="center">
|
|
6
6
|
<img src="https://img.shields.io/npm/v/@linxin666/dsh-task-board?style=flat-square" alt="Version">
|
|
7
7
|
|
|
8
|
-
<img src="https://img.shields.io/badge/DSH-%3E%3D0.2.
|
|
8
|
+
<img src="https://img.shields.io/badge/DSH-%3E%3D0.2.1--rc.2-4c6ef5?style=flat-square&labelColor=454a54" alt="DSH">
|
|
9
9
|
|
|
10
10
|
<img src="https://img.shields.io/badge/license-Apache--2.0-blue?style=flat-square" alt="License">
|
|
11
11
|
</p>
|
|
@@ -31,8 +31,8 @@ Cards keep multi-line title and description previews with visible metadata. Prev
|
|
|
31
31
|
- **Handover bundles and the permission confirmation gate**: a continuation card may attach a handover bundle — the pinned execution triplet (workspace / agent preset / permission) plus doc/script references. The bundle's triplet overrides the plain pin fields at execution, and the references ride the prompt as a handover preamble. A binding whose effective permission is above the deployment's permission baseline — the Host's own default permission preset unless the profile pins `sessionDefaultPermission` — is unconfirmed: manual run refuses, cron skips the card and rolls to the next occurrence, and the confirm button in the task detail resolves the binding; any later permission or bundle change re-arms the gate.
|
|
32
32
|
- **Claim provenance wrap and source audit**: executing a continuation card (a card with a frozen snapshot) mandatorily wraps the task instruction in a source-declaration template — freeze instant, source session, and an unreviewed-content warning — composed after the handover preamble so the picking-up agent stays wary of stored prompt injection in card text. The session issuing a create/update action is stamped into the snapshot (frozenBy, re-stamped when the snapshot is replaced), and the session issuing a run/rerun lands on the execution record (initiatedBy) together with a captured copy of the freeze provenance; both are visible in the task detail. The initiator is client-asserted audit metadata, not a trust boundary.
|
|
33
33
|
- **Task tags (issue #1521)**: a task may carry up to eight labels. A label renders as a colour-toned badge on the card — the tone is hashed from the name, so one label always paints the same way and no colour is stored — the board header gains a multi-select tag filter built from every label in use (including archived tasks), and search also matches label names. A label with an "execution hint" is injected ahead of the execution prompt on every run as a `标签提示` block; a label without one is display and filter only, so an untagged task's prompt is byte-for-byte what it was before the feature. Labels stay editable after the first run: they classify the task and shape the next run, they are not the record of what already ran. A **Manage labels** action on the filter row opens the label manager: every label in use with the number of tasks carrying it, a rename that rewrites the label on every card (merging into an existing label of that name and keeping that label's execution hint), and a delete that removes it from every task including archived ones. Both are ledger-wide Host transactions, so several windows looking at one board stay consistent.
|
|
34
|
-
- **Subtasks and cascade runs**: a task can be given subtasks, either by creating one from its detail view (the form starts from the parent's workspace, preset, permission, and model, and each stays overridable) or by linking an existing task that has no parent yet; a subtask can be detached again once it is not running. The lineage gate lives in the Host: the parent must exist and be on board, a task can never be attached under one of its own descendants, and a tree may not exceed the configured `maxSubtaskDepth` (1 by default, 3 maximum). Running a task also runs its
|
|
35
|
-
- **Agent Team runs (
|
|
34
|
+
- **Subtasks and cascade runs**: a task can be given subtasks, either by creating one from its detail view (the form starts from the parent's workspace, preset, permission, and model, and each stays overridable) or by linking an existing task that has no parent yet; a subtask can be detached again once it is not running. The lineage gate lives in the Host: the parent must exist and be on board, a task can never be attached under one of its own descendants, and a tree may not exceed the configured `maxSubtaskDepth` (1 by default, 3 maximum). Running a task also runs the members of its subtask tree that still have work, concurrently — one DSH session per member, all under one run group, with at most `runLaunchWidth` of them in flight at once — and a subtask already in the done column is not executed again (the same rule for a manual run, a re-run and a due occurrence; move it back to the todo column, or run it on its own, to run it again). The parent card stays in the running column until its own turn and every subtask this run opened have settled; its verdict fails if any member failed, and one failing subtask never stops the others. The board marks parent and subtask cards, the detail view lists the direct subtasks, and the header offers a one-click hide-subtasks filter.
|
|
35
|
+
- **Agent Team runs (per task)**: successfully creating or linking a subtask from the task detail automatically enables team execution on its parent when the deployment serves Agent Teams. Cancelled or failed actions and existing task trees leave the preference unchanged. The parent can be switched back to independent sessions in its detail view; another successful create/link enables Team again. A task may also enable it explicitly through `task_board_create`/`task_board_update`. Running such a task starts ONE session — the Team Lead — and the Host then asks the Agent Teams service to spawn one teammate per subtask inside it, attaching each teammate's session to that subtask's execution. The subtree is flattened into that one Team (only a Lead may spawn); the Lead's prompt lists every teammate by name and points at the team tools, and the Lead's verdict governs the run: a teammate's own completed turn settles its card even while the Team keeps that session alive, and once the Lead's own outcome lands, every member still open is settled with it. A plain cascade prompts the same way but names the independent sessions instead. The mode needs the optional `agentTeams` service: a deployment without it refuses the run by name instead of silently degrading, and a subtask pin the Lead session does not already carry is refused, because a teammate inherits that session's permission and cannot be narrowed below it — a pin the Lead already covers runs the member at the Lead's authority instead of failing the run. Team runs always mint a fresh Lead session (teammate names are immutable within a Team) and use `teamProvider`. An execution whose session history cannot be read at all is reported failed with the reason after two minutes of polling, so an unreadable session can never leave a card in the running column.
|
|
36
36
|
- **Project partition (issue #1536)**: the board header offers a project row built from the deployment's DSH workspaces — "all projects" plus one entry per registered project. Selecting a project narrows the columns to the tasks pinned to it, and tasks with no pinned workspace stay visible under "all projects". Opening the new-task form while a project is open preselects that project as the task's workspace, and "new project…" registers a host directory through the same runtime call the GUI's own add-project uses. A root task created without a project choice — from the form or through the board's agent tool — inherits the workspace of the session that created it, and a card that still pins nothing runs in the deployment's most recently used workspace instead of the Host's own working directory.
|
|
37
37
|
- **AI parse of pasted text (issue #1540)**: the new-task form takes text copied from anywhere and has a model turn it into the title, description, and run prompt. The model is one of the deployment's configured models (the same list the task's model pin uses, first entry preselected), and the call runs on the Host behind the board's usual loopback and same-origin fence, with a 45 s budget and a cancel affordance. The draft only fills the form: nothing is created until the task is submitted, and a failed parse leaves what you already typed untouched.
|
|
38
38
|
- **Collapsible task form**: the create/duplicate/subtask dialog groups its configuration into collapsible regions — task content open by default, then labels, execution settings, run mode, handover, and scheduled runs — and every collapsed region keeps a one-line summary of the values it holds, so the dialog fits without a scrollbar (its body keeps an overflow fallback for very short windows). The agent-preset field is named "Agent preset" and lists the deployment's built-in presets under localized names plus any user preset, with an inherit default that names the preset a run without a pin actually uses.
|
|
@@ -41,6 +41,7 @@ Cards keep multi-line title and description previews with visible metadata. Prev
|
|
|
41
41
|
- **Real execution**: manual and scheduled runs use the same Host runner, which by default creates a fresh session, renames it, applies the agent preset and `/permission <id>`, then queues the task prompt.
|
|
42
42
|
- **Goal-driven runs (opt-in per card, on top of the global switch)**: the GLOBAL native `/goal` switch (below, off by default) is the master control; with it on, and only when a card opts in through its detail-view checkbox (the new-task dialog starts unchecked), the runner queues the task prompt and then arms dsh's built-in `/goal` with that same composed prompt as the objective. dsh's goal-round driver keeps starting continuation rounds in the session until the agent marks the goal complete, and the board keeps the execution in `running` until the goal leaves its active phase: a completed goal settles the run as succeeded, a blocked one fails it with the goal's own reason. The option is per task (`goalRun`, absent means off, so a card that never touched it runs one plain turn) and is available to `task_board_create`/`task_board_update` too. The checkbox is always operable: the master switch decides whether the preference takes effect, never whether it can be stated, and it never rewrites the stored value.
|
|
43
43
|
- **Goal acceptance (on by default)**: a task executed in goal form must pass ONE acceptance before `update_goal(action: complete)` may take effect, because the board gates that call on the official tool pre-execute lifecycle instead of trusting the agent's own report. Acceptance runs the default final acceptance of the installed `dsh-llm-verifier` (MIT): the three coding criteria (Specification Adherence, Output Match, Error Signal Detection), a 0.65 threshold applied to the total AND to every criterion, two judge rounds per criterion with the A/B slots swapped and averaged, the task's real trajectory (tool calls, their output, assistant prose) judged against the empty-work baseline, the work must beat that baseline, and — when the deployment records workspace changes — the HOST's own record of what the run changed on disk (file list with added/deleted counts and bounded per-file comparisons) is attached as the prompt's reference context so a described-but-unapplied patch cannot pass. A veto is booked as a quality verdict only when it can be LOCATED: every criterion that makes the run fail must arrive with a structured finding naming the requirement it imposes, the observation that falls short, the difference, and a verbatim citation of the task, the work's own trajectory or the host's workspace record. A rejecting answer with no finding, a generic or empty finding, a citation that does not occur in the reviewed evidence, a citation of the empty-work baseline, and a criterion failed without its own evidence are recorded as an INVALID acceptance instead: they spend no quality budget, do not fail the card, and are bounded separately (two), after which the board stops calling the judge and holds the card for a human. A run whose only records are invalid ends for lack of a matching pass, but with its own terminal reason that states the acceptance was unusable and explicitly denies being an evidence-backed quality veto. A judge that could not see the output because the trace was truncated is treated the same way, because insufficient evidence is not a failure of the work. One execution may accept twice: the first failure returns the total, the per-criterion scores and the located findings to the fixing agent, the second failure ends that execution as failed. Once an execution PASSES and settles, the acceptance-only detail (its findings and structured citations) is removed automatically and only a lightweight audit credential remains — verdict, scores, time, judge route, evidence hash and a one-line problem summary. Nothing outside that execution's own acceptance record is touched, a failed or invalid execution keeps everything a repair or a review needs, the removal is idempotent, and a cleanup that fails is recorded and retried on the next Host start without ever revoking the pass. The budget lives on the execution record, so a repeated completion call, a new goal round, a plugin reload and a Host restart all reuse the same cycle, while a rerun or a scheduled occurrence is a new execution with its own budget. An anomaly (timeout, authentication failure, unparseable judge answer, unresolvable judge route) is recorded separately from a quality verdict and never consumes the quality budget. Exhausting the anomaly budget does NOT fail the card: a judge route that cannot answer is the environment failing, not the work, so the cycle is held open with no further judge call until a user clears the recorded anomalies through `task_board_manage(action: reset-verification)`. An attempt that the acceptance time budget ends before any verdict is recorded as its own stage, spends no budget at all and also fails nothing. Both ceilings are settings (`goalVerificationCallTimeoutSeconds`, `goalVerificationBudgetSeconds`), read live, and a judge call is never opened when the time left cannot hold it. The running column shows executing / verifying / fixing, and each execution's row carries its verdict, judge model and level, count, scores with thresholds, findings, evidence scope and token usage. Forced acceptance also keeps the old fallback paths honest: a paused goal, an unreadable projection, a completed turn and a manual settle can no longer settle a goal execution as succeeded without a matching pass record. A failure carrying acceptance records means the judge answered and the work did not pass, while a failure with no acceptance record at all is reported as its own reason: the gate never opened because the session never called `update_goal(action: complete)` — often a session that narrated completion in prose — so nothing was ever judged and the delivery was never rejected. **A single card can opt out of the gate**: the new-task form and the task detail both carry a Skip acceptance checkbox (off by default, a card-level option like Continue in the same conversation and Start with /goal), and a checked card no longer intercepts its completion claim in goal form. The execution records `applicability: skipped` and the report says the CARD skipped acceptance, which is a different fact from the board-wide switch being off and is reported as such. It applies only to executions started afterwards, so flipping it mid-run never rewrites the rule judging a run already in flight.
|
|
44
|
+
- **Task reasoning effort**: the task model picker exposes a reasoning-effort selector when the selected model declares supported levels in the Host model catalog. Leaving it blank inherits the model/Host default; only that model's declared levels are offered. The task stores its choice and applies it when selecting the execution model, including a reused session. This setting is separate from the acceptance judge's reasoning effort.
|
|
44
45
|
- **Optional session reuse**: a task can opt into continuing in its previous execution's session (issue #1419). Reuse happens only when that session is idle and still present in the runtime roster — the Host then re-applies the pinned permission and model on it and queues the prompt, keeping the conversation title and history; otherwise the run mints a fresh session as before, so an unknown roster or a busy session never blocks a scheduled run. The roster read is taken for the launch itself, so a board that has been idle reuses a session that has been idle all along instead of refusing it.
|
|
45
46
|
- **Idle-aware session polling (issue #1821)**: the Host reads the DSH session roster only while the board has something that roster can decide — an execution to inspect, or a card parked in the running column whose verdict may arrive from a settle this process never saw. An empty board with no running card, no open execution and no enabled schedule polls nothing at all, so an idle Host no longer rebuilds every persisted session row (string conversion, object allocation, one stat per record) on a fixed heartbeat. The cadence that governs a busy board is the `sessionPollSeconds` setting, and a roster read that fails or stays unknown backs off on a doubling delay up to one minute, so a session tree that is down is not hammered at the poll interval.
|
|
46
47
|
- **Fail-closed pins**: a missing workspace, missing or broken preset, or rejected permission command fails before the task prompt is sent.
|
|
@@ -75,7 +76,7 @@ The board is operable from a conversation, not only from the GUI. Each tool driv
|
|
|
75
76
|
- `task_board_create` creates a task or, with `parentId`, a subtask; execution targets left unset inherit the parent, and the deployment subtask-depth limit applies.
|
|
76
77
|
- `task_board_update` edits content, labels, and execution targets; an empty string clears a target and an empty label array clears the labels.
|
|
77
78
|
- `task_board_set_parent` links an existing card under a parent, or detaches it with an empty parent id.
|
|
78
|
-
- `task_board_run` runs a card now (optionally re-running a settled one), cascading over
|
|
79
|
+
- `task_board_run` runs a card now (optionally re-running a settled one), cascading over the subtask tree members that are not in the done column; it consumes real API quota and refuses an unconfirmed above-default permission with `confirmation-required`.
|
|
79
80
|
- `task_board_manage` moves a card to any column — the move writes the column and never an execution record, so backlog/todo plan, done/failed declare work that finished outside a tracked run and running parks work that is under way without a session, while a card with an open execution refuses the move until it settles — archives or restores it, deletes it, or settles a running card the board can no longer observe (recording a cancelled verdict with the caller as the reason and returning the card to todo), with the Host's running-task and subtask guards.
|
|
80
81
|
- `task_board_schedule` arms, changes, or disarms a card's schedule — a recurring cron rule (optionally capped by `maxRuns`; `0` clears the cap back to unlimited) or a one-shot at an epoch-millisecond `at` — including its IANA time zone (an empty `timeZone` clears it back to the Host zone).
|
|
81
82
|
|
|
@@ -101,7 +102,7 @@ dsh plugin --profile web add link:$(pwd)/packages/dsh-task-board
|
|
|
101
102
|
|
|
102
103
|
## Configuration
|
|
103
104
|
|
|
104
|
-
This plugin's settings card groups its options into collapsible sections — the board and its runtime behavior, task acceptance, and the section a provider extension contributes (the GitHub Issues integration). Every section starts collapsed, and one save writes them all.
|
|
105
|
+
This plugin's settings card groups its options into collapsible sections — the board and its runtime behavior, task acceptance, new-card defaults, and the section a provider extension contributes (the GitHub Issues integration). Every section starts collapsed, and one save writes them all.
|
|
105
106
|
|
|
106
107
|
| Key | Default | Behavior |
|
|
107
108
|
| --- | --- | --- |
|
|
@@ -113,6 +114,7 @@ This plugin's settings card groups its options into collapsible sections — the
|
|
|
113
114
|
| `sessionDefaultPermission` | follow the Host | Explicit baseline for the permission confirmation gate. Unset, the board follows the Host's own default permission preset (what new DSH sessions start at) and falls back to `read-only` when the deployment serves no permission catalog. A card whose effective permission (handover bundle or pin) is above the baseline requires a human confirmation before it may run; cron refuses unconfirmed cards. |
|
|
114
115
|
| `maxSubtaskDepth` | `1` | Subtask depth limit, 1 to 3. At 1 a task may carry one level of subtasks and a subtask cannot be given subtasks of its own; every extra level multiplies the sessions one run of the root opens. |
|
|
115
116
|
| `sessionPollSeconds` | `5` | How often, in seconds, the Host re-reads the DSH session roster while the board has something to reconcile: a running card or an open execution. An idle board with neither does not poll at all. Range 1 to 300; a shorter interval settles runs sooner and costs the Host more. |
|
|
117
|
+
| `runLaunchWidth` | `3` | How many run launches may be in flight at once, 1 to 16. One run opens its whole subtree, so this bounds the burst of sessions one run action creates; the waiting members still start, they just enter the running column in batches. The default follows this repository's measured guidance for heavy implementation subagents (at most three). Read at each admission, so a live edit bounds the launches that have not been admitted yet. |
|
|
116
118
|
| `goalRunEnabled` | `false` | GLOBAL native `/goal` switch. While off, every card runs one plain turn and the board never arms dsh's built-in `/goal`; a run uses native `/goal` only when this is on AND the card's own Start with /goal option is checked (that option is off by default). The value is frozen when an execution starts, so a live edit only affects executions that begin afterwards, and a card's stored `goalRun` preference is never rewritten. Such a run is recorded as `goal-disabled`: it is neither reported as accepted nor failed for lacking a completion call. Independent of `goalVerification`. |
|
|
117
119
|
| `goalVerification` | `true` | Goal acceptance for executions this board starts. When on, `update_goal(action: complete)` inside a task execution is refused until an acceptance pass is recorded for that execution. Only goal-form executions are affected: plain chat and a card that did not opt into `goalRun` are untouched. A single card can opt out of the gate on its own with the Skip acceptance checkbox (below). |
|
|
118
120
|
| `goalVerificationModel` | `''` (inherit) | Judge model route as `provider/model`. Blank inherits the HOST model catalog default — never the card's pinned execution model. |
|
|
@@ -120,6 +122,12 @@ This plugin's settings card groups its options into collapsible sections — the
|
|
|
120
122
|
| `goalVerificationCallTimeoutSeconds` | `150` | Ceiling of ONE judge request of an acceptance, in seconds (range 30 to 600). One acceptance issues six judge requests, so a ceiling too small for the judge model turns a slow but healthy route into a wall of timeouts. |
|
|
121
123
|
| `goalVerificationBudgetSeconds` | `1200` | Total ceiling of ONE acceptance attempt, in seconds (range 120 to 1800), covering evidence rendering and every judge call including retries. Keep it at or above the per-call ceiling times six or the acceptance can never finish; an attempt that runs out is recorded as a budget stop that judges nothing and spends no budget. |
|
|
122
124
|
| `teamProvider` | `spawn` | Continuable-subagent provider the Agent Teams service composes a teammate from. Only team-mode runs use it; it matches the Agent Teams tool plugin's `freshProvider` default. |
|
|
125
|
+
| `cardDefaultMode` | `''` (no default) | Agent preset a newly created card starts from. Blank pins nothing, so the card follows the deployment default as before. |
|
|
126
|
+
| `cardDefaultPermission` | `''` (no default) | Permission a newly created card starts from. It may sit above the session permission baseline: it is a prefill, so an above-baseline binding still needs a human confirmation before the card runs. |
|
|
127
|
+
| `cardDefaultModel` | `''` (no default) | Execution model (`provider/model`) a newly created card starts from. Blank pins nothing and makes `cardDefaultReasoningEffort` inert. |
|
|
128
|
+
| `cardDefaultReasoningEffort` | `''` (no default) | Reasoning level a newly created card starts from, applied only while the card's final model is the configured `cardDefaultModel`; a caller that picks a model of its own borrows no default level. |
|
|
129
|
+
|
|
130
|
+
All four new-card defaults are blank by default and volatile: an edit takes effect without a restart, for the cards created afterwards and on a page that is already open (no reload is needed for the new-task dialog to offer the saved values), and a blank value pins nothing, so a deployment that configures none of them creates cards exactly as it does today. A new card takes each of its execution targets in one order — the explicit choice made in the new-task dialog wins over the values carried over from the card it was created from (a duplicate keeps its source's pins, a subtask keeps its parent's), which win over the board defaults — and the parent's permission is never carried over. None of the four lifts the permission gate: a default permission above the session baseline is only a prefill, and the card still waits for a human confirmation before it may run.
|
|
123
131
|
|
|
124
132
|
Direct browser access remains limited to the DSH loopback origin. For a same-host authenticated reverse proxy, bind DSH Web to loopback, set `trustedProxyHosts`, place a high-entropy token in the environment variable selected by `proxyTokenEnv`, and configure the proxy to replace (not forward from the client) `X-Dsh-Task-Board-Proxy-Token` after it authenticates the request. The proxy Host must be allowlisted, and the browser `Origin` must have that same authority. Restart the Host after changing these composition-level proxy settings.
|
|
125
133
|
|
|
@@ -186,7 +194,7 @@ Set `DSH_POWER_SMOKE=1` to opt into the native helper smoke test on Windows, mac
|
|
|
186
194
|
- Linux requires systemd-logind and policy permission for the current user to acquire an idle block lock. Containers, WSL, hosts without a system bus, and non-systemd systems may report `unsupported` or `error`. Whether a desktop also associates a logind idle lock with display idleness is desktop policy; the plugin does not request a screensaver or display inhibitor.
|
|
187
195
|
- Keeping enabled schedules armed may increase battery consumption because protection starts before their future trigger time.
|
|
188
196
|
- Host execution consumes the same API quota as an ordinary DSH agent session.
|
|
189
|
-
- Running a task also runs its subtask tree: one DSH session
|
|
197
|
+
- Running a task also runs the unfinished members of its subtask tree: every one of them gets its own DSH session, started in batches of `runLaunchWidth` (three by default), so a deep tree opens several concurrent sessions and each consumes API quota. A subtask that is already done is skipped, so re-running a parent after its subtasks were finished one by one costs one session, not the whole tree.
|
|
190
198
|
- Agent tool calls are model-driven: a run or a scheduled cascade started from a conversation consumes the same API quota, and an agent can arm a schedule that keeps firing until it is disarmed or the board is switched off.
|
|
191
199
|
- A goal run keeps working for as many rounds as the objective needs: every round consumes API quota, and the session stays busy until the goal completes or dsh blocks it (round limit, a rejected round, or a failed queue), which the board reports as a failed execution.
|
|
192
200
|
- Goal mode needs the runtime's `/goal` command and a command dispatcher. A deployment that serves neither still runs every card as a single turn; the host log reports that the goal was unavailable instead of failing the run.
|
package/README.zh.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<p align="center">
|
|
6
6
|
<img src="https://img.shields.io/npm/v/@linxin666/dsh-task-board?style=flat-square" alt="Version">
|
|
7
7
|
|
|
8
|
-
<img src="https://img.shields.io/badge/DSH-%3E%3D0.2.
|
|
8
|
+
<img src="https://img.shields.io/badge/DSH-%3E%3D0.2.1--rc.2-4c6ef5?style=flat-square&labelColor=454a54" alt="DSH">
|
|
9
9
|
|
|
10
10
|
<img src="https://img.shields.io/badge/license-Apache--2.0-blue?style=flat-square" alt="License">
|
|
11
11
|
</p>
|
|
@@ -31,8 +31,8 @@
|
|
|
31
31
|
- **交接包与权限确认门**:续接卡片可附交接包——钉住三元组(工作区/agent 预设/权限)加文档与脚本引用。执行时交接包三元组覆盖普通钉住字段,引用以交接前言随 Prompt 下发。有效权限高于部署权限基线——未钉住 `sessionDefaultPermission` 时即宿主自己的默认权限预设——的绑定处于待确认状态:手动执行被拒绝、cron 跳过该卡并滚动到下一触发点,任务详情中的确认按钮完成人工确认;此后任何权限或交接包变更都会重新武装确认门。
|
|
32
32
|
- **领卡来源声明包裹与来源审计**:执行续接卡片(带冻结快照的卡片)时,任务指令被来源声明模板强制包裹——冻结时间、来源会话与未经人工审查提示,组合在交接前言之后,使接手 Agent 对卡片文本中的存储型提示注入保持警惕。create/update 动作的发起方会话织入快照(frozenBy,快照被替换时重新盖章),run/rerun 的发起方会话连同冻结来源的捕获副本一起落在执行记录(initiatedBy)上,两者均可在任务详情查看。发起方为客户端断言的审计元数据,不构成信任边界。
|
|
33
33
|
- **任务标签(issue #1521)**:每个任务可带最多八个标签。标签在卡片上渲染为带色调的徽章——色调由标签名哈希得到,因此同一标签永远同色,也不需要存储颜色;看板顶栏据此提供多选标签筛选,候选项来自全账本在用的标签(含已归档任务),搜索也会匹配标签名。填了「执行提示」的标签会在每次执行前以 `标签提示` 段注入到执行 Prompt 之前;没填的标签只作展示与筛选,因此无标签任务的 Prompt 与加入该功能前逐字节一致。标签在首次执行后仍可编辑:它们给任务分类、塑造下一次运行,而不是「已经跑过什么」的凭证。筛选行的**管理标签**入口会打开标签管理器:列出每个在用标签及其任务数,重命名会写到所有卡片上(与已有同名标签合并,并保留该标签的执行提示),删除会从全部任务(含已归档)上移除。两者都是 Host 的整账本事务,因此多个窗口看同一块看板时状态一致。
|
|
34
|
-
- **子任务与级联执行**:任务可以有子任务——在详情页新建子任务(表单以父任务的工作区、模式、权限和模型为起点,每一项都可覆盖),或把一个还没有父任务的现有任务关联为子任务;子任务不在运行中时也可以解除关联。父子关系的准入由 Host 判定:父任务必须存在且在看板上、任务不能挂到自己的后代之下、树的深度不得超过配置的 `maxSubtaskDepth`(默认 1 层,最大 3
|
|
35
|
-
- **Agent Team
|
|
34
|
+
- **子任务与级联执行**:任务可以有子任务——在详情页新建子任务(表单以父任务的工作区、模式、权限和模型为起点,每一项都可覆盖),或把一个还没有父任务的现有任务关联为子任务;子任务不在运行中时也可以解除关联。父子关系的准入由 Host 判定:父任务必须存在且在看板上、任务不能挂到自己的后代之下、树的深度不得超过配置的 `maxSubtaskDepth`(默认 1 层,最大 3 层)。执行一个任务会并发执行它这棵子任务树里尚未完成的成员——每个成员各开一个 DSH 会话,同属一个 run group,同一刻最多 `runLaunchWidth` 个在启动——已经在「完成」列的子任务不会被重复执行(手动执行、重新执行与定时到点都是同一条规则),需要重跑时把它移回「待办」列或单独执行它;父任务卡片会一直留在「进行中」列,直到它自己的回合与它本次开启的子任务都结算;任一成员失败则父任务判为失败,而单个子任务失败不会阻塞其它子任务。看板会标注父任务与子任务卡片,详情页列出直接子任务,顶栏提供一键隐藏子任务。
|
|
35
|
+
- **Agent Team 执行(任务级)**:部署提供 Agent Teams 服务时,在任务详情中成功创建或关联子任务会自动开启父任务的团队执行。取消、失败和已有任务树不改变该偏好。用户可在父任务详情中手动切回独立会话;再次成功创建或关联子任务会重新开启 Team。任务也可经 `task_board_create`/`task_board_update` 显式开启团队执行。执行这样的任务只启动一个会话——Team Lead——随后 Host 通过 Agent Teams 服务在它内部为每个子任务派生一个 teammate,并把 teammate 的会话挂到该子任务的 execution 上。整棵子树被压平成这一个 Team(只有 Lead 可以派生);Lead 的提示词按名字列出每个 teammate 并指向团队工具,团队执行由 Lead 判定统辖:teammate 自己已完成的回合即结算它的卡片(即使 Team 仍让该会话存活),Lead 自身结果落定后,仍未报结果的成员一并按该判定结算。普通级联的提示词结构相同,只是改为列出各独立会话。该模式依赖可选的 `agentTeams` 服务:未提供该服务的部署会明确拒绝执行而不是静默降级;子任务自己的权限钉住若高于 Lead 会话实际权限也会被拒绝,因为 teammate 继承 Lead 会话的权限且无法被收窄;Lead 已覆盖的钉住则让该成员按 Lead 的权限照常执行,而不是让整次运行失败。团队执行总是新建 Lead 会话(同一 Team 内 teammate 名字不可变),并使用 `teamProvider`。会话历史完全读不到的 execution 会在轮询满两分钟后带原因判为失败,因此读不到历史的会话不会把卡片永久留在运行列。
|
|
36
36
|
- **项目分区(issue #1536)**:看板头部新增项目下拉,选项来自当前部署的 DSH 工作区——「全部项目」加每个已注册项目。选定项目后各列只显示钉在该项目上的任务,未钉工作区的任务只在「全部项目」下可见;在某个项目下打开「新建任务」会把该项目预选为任务工作区,「新建项目…」则用与 GUI「添加项目」相同的运行时接口把宿主目录注册为项目。未选项目而创建的根任务——无论来自表单还是看板的 agent 工具——继承创建它的会话所在的工作区;仍未钉住工作区的卡片在部署最近使用的工作区里执行,而不是落到宿主自身的工作目录。
|
|
37
37
|
- **粘贴文本 AI 解析(issue #1540)**:新建任务表单可以把从别处复制的一段话交给模型,整理成标题、描述和执行 Prompt。模型取当前部署已配置的模型(与任务「模型」下拉同一份列表,默认选中第一项),调用在宿主侧完成,走看板既有的回环与同源校验,预算 45 秒并支持取消。解析结果只填进表单:不提交就不会创建任务,解析失败也不会改动你已经输入的内容。
|
|
38
38
|
- **可折叠的任务表单**:新建/复制/子任务对话框把配置分成可折叠区域——任务内容默认展开,其后依次是标签、执行设置、运行方式、交接与续跑、定时运行——每个折叠区域都保留一行当前值摘要,因此对话框不需要滚动条(正文仍保留极矮窗口下的溢出兜底)。Agent 预设字段更名为「Agent 预设」,把部署内置预设以本地化名称列出,并附上任何用户预设;默认的「继承」选项会写明未钉住时真正使用的预设。
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
- **真实执行**:手动运行和定时运行共用 Host runner,默认新建独立会话、重命名、应用 agent 预设和 `/permission <id>`,再以 queue 模式发送任务 Prompt。
|
|
42
42
|
- **目标驱动执行(卡片逐张选择加入,且需总开关开启)**:全局原生 `/goal` 开关(见下,默认关闭)是总开关;开启后,只有卡片在详情页勾选加入(新建任务对话框默认不勾选)时,runner 才会先入队任务 Prompt,再以同一份组合 Prompt 作为目标武装 dsh 内置的 `/goal`。dsh 的目标轮次驱动器会在同一会话中不断开启续跑轮次,直到 agent 标记目标完成;看板则让该执行一直保持 `running`,直到目标离开 active 阶段:目标正常完成判为成功,被阻塞则以目标自身的原因判为失败。该选项按任务设置(`goalRun`,缺席即关闭,因此从未动过该选项的卡片只执行一轮普通对话),`task_board_create`/`task_board_update` 同样可用。勾选框始终可操作:总开关只决定该偏好是否生效,从不决定它能否被表达,也绝不改写已保存的值。
|
|
43
43
|
- **任务验收(默认开启)**:以 goal 形式执行的任务必须先通过一次验收,`update_goal(action: complete)` 才会生效——看板在官方「工具执行前」生命周期上拦截这次调用,而不是相信 agent 的自述。验收沿用已安装 dsh-llm-verifier(MIT)的默认最终验收:三项 coding 判据(Specification Adherence、Output Match、Error Signal Detection)、总分与每项判据都必须达到 0.65 阈值、每项两轮并交换 A/B 位置后取平均、以任务真实轨迹(工具调用及其输出、assistant 文本)对比空工作基线,实际工作必须胜过该基线;部署记录工作区变更时,还会附上宿主自身对「本次运行改了磁盘上什么」的记录(文件清单与增删行数、有界的逐文件对比)作为提示词的参考上下文,使「只在自述里写过的补丁」无法通过。否决只有在**可定位**时才记为质量判定:任何导致不通过的判据都必须带有结构化问题反馈,写明它施加的任务要求、未达标的实际观测、差异,以及对任务、本次执行自己的轨迹或宿主工作区记录的逐字引用。没有反馈的否决、空泛或空的反馈、引用并不出现在所审证据中、引用空工作基线、以及「判据不通过却没有它自己的证据」,都记为**无效验收**:不消耗质量额度、不判卡片失败,并单独有界(两次);额度用尽后看板停止调用裁判、把卡片留给人工处理。若某次执行的记录只有无效验收,它同样因没有匹配的通过记录而结束,但使用独立终态原因,说明验收本身不可用,并明确否认这是有证据的质量判负。轨迹被截断导致裁判看不到输出时同样按无效验收处理,因为证据不足不等于工作没做。同一 execution 最多验收两次:第一次不通过把总分、逐项分数与可定位问题交回修复的 agent,第二次仍不通过即判该 execution 失败。执行**通过**并结算后,验收专用详细材料(问题反馈与结构化引用)会自动移除,只保留轻量审计凭据——判定、分数、时间、裁判路由、证据哈希与一行问题摘要。该 execution 记录之外的任何东西都不动;失败或无效的执行保留修复与复核所需的全部材料;移除是幂等的;清理失败会被记录并在宿主下次启动时重试,且绝不撤销通过记录。额度记录在 execution 记录上,因此重复完成调用、跨入下一 goal 轮次、插件重载与宿主重启都复用同一周期;重跑或一次定时触发则是新的 execution、重新计数。验收异常(超时、鉴权失败、裁判回答无法解析、裁判路由不可解析)与质量判定分开记录,不消耗质量额度。异常额度用尽并不把卡片判死:裁判路由答不上来是环境故障而不是工作不合格,此时执行周期保持打开、不再发起裁判调用,直到用户通过 `task_board_manage(action: reset-verification)` 清除已记录的异常。若一次验收在产生任何判定前就耗尽时间预算,会单独记为一类结果,不消耗任何额度,同样不判死卡片。两个上限都是配置项(`goalVerificationCallTimeoutSeconds`、`goalVerificationBudgetSeconds`),按需实时读取;剩余时间装不下一次调用时不会发起这次注定被中断的调用。运行列显示「执行中 / 验收中 / 验收未通过修复中」,每条 execution 记录展示判定、裁判模型与强度、次数、各项分数与阈值、问题反馈、证据范围与 token 用量。强制验收还堵住了旧回退路径:暂停的 goal、读取失败的 projection、已完成的回合与人工强制结算,都不能在没有匹配通过记录的情况下把 goal 执行结算为成功。带着验收记录失败意味着裁判给出了判定而工作没通过;一条验收记录都没有的失败则单独说明:验收门从未打开,因为执行会话没有调用 `update_goal(action= complete)`(常见于只在回复里宣告完成),交付从未被判定,更谈不上被判负。**单张卡片可以退出这道门**:新建任务与任务详情都有「跳过本任务的验收」勾选(默认不勾,语义与「同一对话继续」「以 /goal 开始执行任务」同级的卡片级选项),勾选后该卡以 goal 形式执行时不再拦截完成声明,执行记录标注 `applicability: skipped` 并在验收面板写明「该任务卡勾选了跳过验收」——它与总开关关闭是两回事,看板会分别说明。只对之后新开的执行生效,运行中改勾选不会改写已在飞的执行的判定规则。
|
|
44
|
+
- **任务思考强度**:所选模型在 Host 模型目录中声明支持的思考档位时,任务模型选择器提供思考强度下拉框。留空沿用模型/宿主默认值,只提供该模型声明的档位。任务保存该选择,并在选择执行模型时应用,包括复用已有会话的执行。此设置独立于验收裁判的思考强度。
|
|
44
45
|
- **可选会话复用**:任务可选择在上一执行会话中继续(issue #1419)。仅当该会话空闲且仍在运行时会话名册中才复用——Host 会重新应用钉住的权限与模型再以 queue 模式发送 Prompt,会话标题与历史保持不变;否则照旧新建会话,因此名册未知或会话正忙都不会阻塞定时运行。名册读取就发生在这次启动本身,所以长期空闲的看板会复用一个一直空闲的会话,而不是因为缓存过期而拒绝它。
|
|
45
46
|
- **空闲时停止会话轮询(issue #1821)**:只有当看板确实有需要名册裁决的事情时,Host 才读取 DSH 会话名册——存在待核对的执行,或运行列里有一张卡片(它的结果可能来自本进程没观测到的结算)。空看板、没有运行中卡片、没有未结算执行、也没有已启用计划时不轮询任何东西,因此空闲的 Host 不再按固定心跳重建每一条持久化会话行(字符串转换、对象分配、每条记录一次 stat)。有工作时按配置项 `sessionPollSeconds` 的节奏轮询;读取失败或名册仍未知时按翻倍延迟退避,上限一分钟,因此会话树故障时不会被按轮询间隔反复冲击。
|
|
46
47
|
- **钉子失败即关闭**:工作区缺失、预设缺失或损坏、权限命令被拒绝时,任务 Prompt 不会发送。
|
|
@@ -75,7 +76,7 @@
|
|
|
75
76
|
- `task_board_create`:创建任务;带 `parentId` 时创建子任务。未单独设置的执行目标继承父任务,并受部署的子任务深度上限约束。
|
|
76
77
|
- `task_board_update`:修改内容、标签与执行目标;空字符串清除某个目标,空标签数组清除全部标签。
|
|
77
78
|
- `task_board_set_parent`:把现有卡片挂到某个父任务下,或用空 parentId 解除关联。
|
|
78
|
-
- `task_board_run
|
|
79
|
+
- `task_board_run`:立即执行一张卡片(可选择重跑已结算的卡片),并级联执行它子任务树里不在「完成」列的成员;会消耗真实 API 额度,且未确认的高于默认权限的绑定会以 `confirmation-required` 被拒绝。
|
|
79
80
|
- `task_board_manage`:把卡片移到任意列——只写列、绝不伪造执行记录,因此待规划/待办用于规划、已完成/已失败用于声明工作在受追踪的执行之外结束、进行中用于表示工作正在进行但没有会话;真正有未结算执行的卡片会拒绝移动直到结算——归档或恢复、删除,或对看板已无法观察的运行中卡片强制结算(记为 cancelled 并记录调用者原因,卡片回到待办),同样受 Host 的运行中子任务与父子关系护栏约束。
|
|
80
81
|
- `task_board_schedule`:启用、修改或关闭卡片的计划——循环 cron(可选 `maxRuns` 上限,传 `0` 清空回不限次)或在 `at`(epoch 毫秒)指定时刻只执行一次的单次计划——包括其 IANA 时区(`timeZone` 传空字符串即清除,回退到 Host 时区)。
|
|
81
82
|
|
|
@@ -101,7 +102,7 @@ dsh plugin --profile web add link:$(pwd)/packages/dsh-task-board
|
|
|
101
102
|
|
|
102
103
|
## 配置
|
|
103
104
|
|
|
104
|
-
|
|
105
|
+
本插件的设置卡把选项组织成可折叠的分区——看板与运行行为、任务验收、新建卡片默认值,以及提供方扩展(GitHub Issues 集成)贡献的分区。每个分区默认折叠,整张卡共用一次保存。
|
|
105
106
|
|
|
106
107
|
| 键 | 默认值 | 行为 |
|
|
107
108
|
| --- | --- | --- |
|
|
@@ -113,6 +114,7 @@ dsh plugin --profile web add link:$(pwd)/packages/dsh-task-board
|
|
|
113
114
|
| `sessionDefaultPermission` | 跟随宿主 | 权限确认门的显式基线。未设置时跟随宿主自己的默认权限预设(DSH 新会话的起始权限),部署不提供权限目录时回退 `read-only`。卡片有效权限(交接包或钉住字段)高于该基线时,运行前必须经人工确认;cron 拒绝调度待确认卡片。 |
|
|
114
115
|
| `maxSubtaskDepth` | `1` | 子任务深度上限,1 到 3。取 1 时一个任务只能有一层子任务,子任务不能再创建或关联子任务;每多一层,执行根任务一次开启的会话数就会成倍增加。 |
|
|
115
116
|
| `sessionPollSeconds` | `5` | 看板有需要核对的事情(运行中的卡片或未结算执行)时,Host 重新读取 DSH 会话名册的间隔秒数。两者都没有的空闲看板完全不轮询。取值 1 到 300;间隔越短结算越快、Host 负载越高。 |
|
|
117
|
+
| `runLaunchWidth` | `3` | 同一刻允许在启动中的运行数,1 到 16。一次执行会开启整棵子任务树,因此该值限制一次运行动作创建的会话洪峰;等待中的成员仍会启动,只是分批进入运行列。默认值取自本仓「重型实施子代理并发 ≤ 3」的实测纪律。每次准入时读取,修改只影响尚未入列的启动。 |
|
|
116
118
|
| `goalRunEnabled` | `false` | 全局原生 `/goal` 执行开关。关闭时所有卡片都按普通单回合执行,看板不再武装 dsh 内置的 `/goal`;只有它开启、且卡片自身的「以 /goal 开始执行任务」被勾选时(该选项默认关闭),运行才使用原生 /goal。该值在执行启动时冻结,因此实时修改只影响之后新开的执行,卡片存储的 `goalRun` 偏好绝不被改写。这类运行记录为 `goal-disabled`:既不会被报告为已验收通过,也不会因缺少完成调用被判失败。与 `goalVerification` 相互独立。 |
|
|
117
119
|
| `goalVerification` | `true` | 本插件所开执行的 goal 验收。开启后,任务执行内的 `update_goal(action: complete)` 在该执行取得验收通过记录前一律被拒绝。只影响以 goal 形式执行的运行:普通聊天与未勾选 `goalRun` 的卡片不受影响。单张任务卡可以用「跳过本任务的验收」勾选退出本开关的约束(见下)。 |
|
|
118
120
|
| `goalVerificationModel` | `''`(继承) | 裁判模型路由,形如 `provider/model`。留空继承宿主模型目录的默认路由,绝不是任务卡钉住的执行模型。 |
|
|
@@ -120,6 +122,12 @@ dsh plugin --profile web add link:$(pwd)/packages/dsh-task-board
|
|
|
120
122
|
| `goalVerificationCallTimeoutSeconds` | `150` | 单次裁判调用的上限(秒,范围 30–600)。一次验收要发六次裁判调用,上限过小会把「慢但健康」的路由变成一整排超时。 |
|
|
121
123
|
| `goalVerificationBudgetSeconds` | `1200` | 单次验收的总时间上限(秒,范围 120–1800),覆盖证据渲染与全部裁判调用(含重试)。应不小于单次调用上限的六倍,否则一次验收永远跑不完;耗尽时记为一类「预算耗尽」结果,不产生任何判定,也不消耗任何额度。 |
|
|
122
124
|
| `teamProvider` | `spawn` | Agent Teams 服务用来组成 teammate 的 continuable-subagent provider。仅团队执行模式使用,与 Agent Teams 工具插件的 `freshProvider` 默认值一致。 |
|
|
125
|
+
| `cardDefaultMode` | `''`(无默认值) | 新建卡片起始的 agent 预设。留空不钉住任何值,卡片照旧跟随部署默认预设。 |
|
|
126
|
+
| `cardDefaultPermission` | `''`(无默认值) | 新建卡片起始的权限。它可以高于会话权限基线:它只是预填,高于基线的绑定仍需人工确认后才能运行。 |
|
|
127
|
+
| `cardDefaultModel` | `''`(无默认值) | 新建卡片起始的执行模型(`provider/model`)。留空不钉住任何值,并使 `cardDefaultReasoningEffort` 失效。 |
|
|
128
|
+
| `cardDefaultReasoningEffort` | `''`(无默认值) | 新建卡片起始的思考档位,仅在卡片最终模型就是配置的 `cardDefaultModel` 时生效;自己选了模型的调用方不借用任何默认档位。 |
|
|
129
|
+
|
|
130
|
+
四个新建卡片默认值都默认空,且都是 volatile:改动无需重启即生效,既作用于之后新建的卡片,也作用于已经打开的页面(无需刷新,新建对话框就会用上刚保存的值);留空不钉住任何值,因此完全不配置它们的部署创建卡片的行为与今天一致。新卡片的每个执行目标按同一顺序取值——新建对话框里的显式选择优先于从源卡带过来的值(复制卡片沿用源卡已钉住的值,新建子任务沿用父卡的),后者优先于看板默认值——而父卡的权限永不参与。这四个默认值都不会放松权限确认门:高于会话基线的默认权限只是预填,卡片仍要等人工确认后才能运行。
|
|
123
131
|
|
|
124
132
|
浏览器直接访问仍限制为 DSH loopback origin。若使用同机认证反向代理,应让 DSH Web 绑定 loopback,配置 `trustedProxyHosts`,在 `proxyTokenEnv` 指定的环境变量中放置高熵 token,并让代理在完成认证后替换(不能透传客户端提供的)`X-Dsh-Task-Board-Proxy-Token`。代理 Host 必须在白名单内,浏览器 `Origin` 必须与其 authority 相同。修改这些 composition 级代理设置后需重启 Host。
|
|
125
133
|
|
|
@@ -186,7 +194,7 @@ pnpm --filter @linxin666/dsh-client-ui-task-board build
|
|
|
186
194
|
- Linux 需要 systemd-logind 及允许当前用户取得 idle block lock 的策略;容器、WSL、无 system bus 或非 systemd 系统可能显示 `unsupported` 或 `error`。桌面环境是否把 logind idle lock 与显示器空闲联动属于其自身策略,插件不请求屏保或显示器 inhibitor。
|
|
187
195
|
- 已启用计划会从未来触发点之前持续持锁,因此可能增加电池消耗。
|
|
188
196
|
- Host 执行消耗与普通 DSH agent 会话相同的 API 额度。
|
|
189
|
-
-
|
|
197
|
+
- 执行一个任务会同时执行它子任务树里尚未完成的成员:每个成员都会开启自己的 DSH 会话,按 `runLaunchWidth`(默认 3)分批启动,树越深并发会话越多,每个会话都会消耗 API 额度。已在「完成」列的子任务会被跳过,因此把子任务逐个跑完再执行父任务只花一个会话,而不是整棵树。
|
|
190
198
|
- Agent 工具调用由模型驱动:从对话发起的执行或定时级联同样消耗 API 额度,且 agent 可以启用一个持续触发的计划,直到被关闭或看板被关掉。
|
|
191
199
|
- 目标执行会按目标需要不断续跑:每一轮都消耗 API 额度,会话会一直忙碌,直到目标完成或被 dsh 阻塞(轮次上限、回合被拒或入队失败),后者在看板上记为执行失败。
|
|
192
200
|
- 目标模式依赖运行时的 `/goal` 命令与命令派发器。两者都不提供的部署仍会把每张卡片当单回合执行,并在宿主日志中记录目标模式不可用,而不是让执行失败。
|