@linxin666/dsh-client-ui-task-board 0.4.5 → 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 +34 -18
- package/README.zh.md +34 -18
- package/lib/client.js +2804 -1024
- package/lib/client.js.map +1 -1
- package/lib/index.js +2576 -416
- package/lib/types/client/CardDefaultPresetField.d.ts +35 -0
- package/lib/types/client/TaskBoardSettingsCard.d.ts +61 -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/index.d.ts +4 -5
- package/lib/types/client/locales.d.ts +81 -0
- package/lib/types/client/plugin-card-seat.d.ts +5 -0
- package/lib/types/client/schedule-zone.d.ts +50 -0
- package/lib/types/core/card-defaults.d.ts +78 -0
- package/lib/types/core/controller.d.ts +41 -17
- package/lib/types/core/launch-width.d.ts +31 -0
- package/lib/types/core/poll-cadence.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 +163 -14
- package/lib/types/core/use-cases/task-create.d.ts +10 -5
- package/lib/types/core/use-cases/task-schedule.d.ts +68 -10
- package/lib/types/core/use-cases/task-update.d.ts +1 -1
- package/lib/types/core/verification-budget.d.ts +52 -0
- package/lib/types/core/verification.d.ts +376 -9
- package/lib/types/host/launch-admission.d.ts +72 -0
- package/lib/types/host/verification-gate.d.ts +24 -0
- package/lib/types/host/verification-runner.d.ts +38 -7
- package/lib/types/host-ledger.d.ts +91 -11
- package/lib/types/host-runner.d.ts +111 -13
- package/lib/types/host-service.d.ts +199 -8
- package/lib/types/index.d.ts +141 -0
- package/lib/types/protocol.d.ts +63 -12
- package/package.json +29 -33
- package/src/client/CardDefaultPresetField.tsx +101 -0
- package/src/client/TaskBoardSettingsCard.tsx +288 -17
- package/src/client/board/LinkSubtaskModal.tsx +8 -0
- package/src/client/board/NewTaskModal.tsx +237 -60
- package/src/client/board/ReasoningEffortField.tsx +50 -0
- package/src/client/board/TaskCard.tsx +3 -3
- package/src/client/board/TaskDetail.tsx +261 -24
- package/src/client/board/VerificationReport.tsx +132 -13
- 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/status-key.ts +3 -0
- package/src/client/board/team-run-promotion.ts +39 -0
- package/src/client/index.ts +105 -108
- package/src/client/locales.ts +171 -6
- package/src/client/plugin-card-seat.ts +7 -0
- package/src/client/schedule-zone.ts +100 -2
- package/src/client/settings-entry-form.ts +0 -1
- package/src/core/card-defaults.ts +132 -0
- package/src/core/controller.ts +55 -16
- package/src/core/launch-width.ts +38 -0
- package/src/core/poll-cadence.ts +41 -0
- package/src/core/reasoning-effort.ts +92 -0
- package/src/core/store.ts +69 -15
- package/src/core/subtask.ts +48 -13
- package/src/core/tasks.ts +213 -39
- package/src/core/use-cases/task-create.ts +57 -25
- package/src/core/use-cases/task-schedule.ts +190 -25
- package/src/core/use-cases/task-update.ts +9 -4
- package/src/core/verification-budget.ts +115 -0
- package/src/core/verification.ts +785 -17
- package/src/host/agent-tools.ts +127 -29
- package/src/host/launch-admission.ts +140 -0
- package/src/host/verification-gate.ts +172 -16
- package/src/host/verification-runner.ts +207 -40
- package/src/host-ledger.ts +346 -48
- package/src/host-runner.ts +234 -35
- package/src/host-service.ts +539 -52
- package/src/index.ts +250 -7
- package/src/protocol.ts +160 -32
- package/lib/invariant.js +0 -6
- package/lib/types/client/board-card-seat.d.ts +0 -34
- package/lib/types/invariant.d.ts +0 -3
- package/src/client/board-card-seat.ts +0 -102
- package/src/invariant.ts +0 -4
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { TypertGateway } from '@deepseek-ai/dsh-api-gateway';
|
|
2
2
|
import { HostTaskLedger } from './host-ledger.ts';
|
|
3
|
-
import { HostExecutionRunner, type SessionCommandDispatcher, type TaskBoardWorkspaceRegistry } from './host-runner.ts';
|
|
3
|
+
import { HostExecutionRunner, type GatewayPeer, type SessionCommandDispatcher, type TaskBoardWorkspaceRegistry } from './host-runner.ts';
|
|
4
4
|
import { PowerInhibitor } from './power-inhibitor.ts';
|
|
5
5
|
import { type TaskBoardAction, type TaskBoardEventPayload, type TaskBoardSnapshot } from './protocol.ts';
|
|
6
|
+
import type { CardDefaults } from './core/card-defaults.ts';
|
|
6
7
|
import { TaskBoardExtensionRegistry } from './host/extension-registry.ts';
|
|
7
8
|
import type { TaskBoardExtension } from './core/extension.ts';
|
|
9
|
+
import { type ScheduleMode } from './core/tasks.ts';
|
|
8
10
|
import { type ModelCatalogView, type VerificationContract, type VerificationSettings } from './core/verification.ts';
|
|
9
11
|
import type { TaskPermission } from './core/handover.ts';
|
|
10
12
|
/** One teammate the Host asks the Agent Teams service to spawn for a team run. */
|
|
@@ -34,6 +36,30 @@ export interface TeamSpawnResult {
|
|
|
34
36
|
export interface TaskBoardTeamDispatcher {
|
|
35
37
|
spawn(input: TeamSpawnInput): Promise<TeamSpawnResult>;
|
|
36
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Why an enforced goal execution settled failed while its acceptance DID run:
|
|
41
|
+
* attempts were recorded and none of them passed. The judge answered about the
|
|
42
|
+
* work and the work did not pass.
|
|
43
|
+
*/
|
|
44
|
+
export declare const NO_MATCHING_PASS_VERIFICATION_REASON = "goal \u9A8C\u6536\uFF1A\u672C\u6B21\u6267\u884C\u6CA1\u6709\u5339\u914D\u7684\u9A8C\u6536\u901A\u8FC7\u8BB0\u5F55\uFF08\u9A8C\u6536\u672A\u8FD0\u884C\u3001\u672A\u901A\u8FC7\u6216\u62A5\u544A\u6765\u81EA\u5176\u4ED6\u6267\u884C\uFF09\uFF0C\u6309\u672A\u9A8C\u6536\u5224\u5931\u8D25\u3002";
|
|
45
|
+
/**
|
|
46
|
+
* Why an enforced goal execution settled failed with ZERO acceptance records:
|
|
47
|
+
* the gate was never opened, so the judge never ran and nothing was ever judged
|
|
48
|
+
* (issue #1837). The root cause is a session that declared completion in prose
|
|
49
|
+
* instead of calling `update_goal(action: complete)` — a tool-adherence problem,
|
|
50
|
+
* NOT a quality verdict on the delivery — so this reason says so and keeps the
|
|
51
|
+
* two investigation directions apart.
|
|
52
|
+
*/
|
|
53
|
+
export declare const NEVER_INVOKED_VERIFICATION_REASON = "goal \u9A8C\u6536\u672A\u89E6\u53D1\uFF1A\u672C\u6B21\u6267\u884C\u6CA1\u6709\u4EFB\u4F55\u9A8C\u6536\u8BB0\u5F55\uFF0C\u9A8C\u6536\u95E8\u4ECE\u672A\u6253\u5F00\u2014\u2014\u6267\u884C\u4F1A\u8BDD\u6CA1\u6709\u8C03\u7528 update_goal(action: complete) \u6765\u5B8C\u6210\u76EE\u6807\uFF08\u5E38\u89C1\u4E8E\u53EA\u5728\u56DE\u590D\u91CC\u5BA3\u544A\u5B8C\u6210\uFF09\u3002\u8FD9\u4E0D\u662F\u8D28\u91CF\u5224\u8D1F\uFF1A\u4EA4\u4ED8\u4ECE\u672A\u88AB\u88C1\u5224\u8BC4\u4F30\u3002";
|
|
54
|
+
/**
|
|
55
|
+
* Why an enforced goal execution settled failed while its ONLY acceptance
|
|
56
|
+
* records are INVALID: the judge answered but could not locate its own
|
|
57
|
+
* rejection, so the board stopped calling it. This is NOT an evidence-backed
|
|
58
|
+
* quality veto — the requirement is explicit that such a run must not be
|
|
59
|
+
* described as one — but the execution still has no matching pass, so it ends
|
|
60
|
+
* for lack of one, and the reason names that precisely.
|
|
61
|
+
*/
|
|
62
|
+
export declare const INVALID_ONLY_VERIFICATION_REASON = "goal \u9A8C\u6536\u65E0\u6548\uFF1A\u672C\u6B21\u6267\u884C\u53EA\u8BB0\u5F55\u4E86\u65E0\u6548\u9A8C\u6536\uFF08\u88C1\u5224\u672A\u80FD\u7ED9\u51FA\u4E0E\u4EFB\u52A1\u8981\u6C42\u5BF9\u5E94\u3001\u4E14\u53EF\u5B9A\u4F4D\u5230\u672C\u6B21\u8BC1\u636E\u7684\u5426\u51B3\u4F9D\u636E\uFF09\uFF0C\u770B\u677F\u5DF2\u505C\u6B62\u8C03\u7528\u88C1\u5224\u3002\u8FD9**\u4E0D\u662F**\u6709\u8BC1\u636E\u7684\u8D28\u91CF\u5224\u8D1F\uFF1A\u9A8C\u6536\u672C\u8EAB\u4E0D\u53EF\u7528\uFF0C\u672C\u6B21\u8FD0\u884C\u56E0\u6CA1\u6709\u5339\u914D\u7684\u901A\u8FC7\u8BB0\u5F55\u800C\u7ED3\u675F\u3002\u8BF7\u68C0\u67E5\u9A8C\u6536\u73AF\u5883\u4E0E\u8BC1\u636E\u53EF\u89C1\u6027\uFF0C\u6216\u7528 task_board_manage(action=reset-verification) \u6E05\u9664\u8BB0\u5F55\u7684\u65E0\u6548\u9A8C\u6536\u540E\u91CD\u65B0\u5B8C\u6210\u76EE\u6807\u3002";
|
|
37
63
|
/**
|
|
38
64
|
* Provenance of one cron-triggered cascade: when the rule fired and the zone
|
|
39
65
|
* its wall clock was read in. Passed into every launched prompt of that run so
|
|
@@ -42,7 +68,10 @@ export interface TaskBoardTeamDispatcher {
|
|
|
42
68
|
export interface ScheduledRunContext {
|
|
43
69
|
triggeredAt: number;
|
|
44
70
|
timeZone: string;
|
|
45
|
-
|
|
71
|
+
/** Whether this fire came from a recurring rule or a single planned instant. */
|
|
72
|
+
mode: ScheduleMode;
|
|
73
|
+
/** Cron expression of a recurring rule; absent on a one-shot. */
|
|
74
|
+
cron?: string;
|
|
46
75
|
}
|
|
47
76
|
/**
|
|
48
77
|
* The native timer face the Host arms through. The cordis `timer` service
|
|
@@ -62,6 +91,12 @@ export declare class TaskBoardHostService {
|
|
|
62
91
|
private readonly listeners;
|
|
63
92
|
/** The one recurring timer: the session-roster poll. */
|
|
64
93
|
private pollTimer;
|
|
94
|
+
/** Cadence of the roster poll, in seconds (a settings field; see the config schema). */
|
|
95
|
+
private sessionPollSeconds;
|
|
96
|
+
/** Pending delay that follows a failed poll pass, if one is armed. */
|
|
97
|
+
private pollBackoffTimer;
|
|
98
|
+
/** Consecutive failed poll passes; doubles the next retry delay. */
|
|
99
|
+
private consecutivePollFailures;
|
|
65
100
|
/** The armed schedule timer, if a trigger is pending. */
|
|
66
101
|
private scheduleTimer;
|
|
67
102
|
/** The instant the armed schedule timer targets (ms epoch), for resume detection. */
|
|
@@ -70,12 +105,11 @@ export declare class TaskBoardHostService {
|
|
|
70
105
|
private pollInFlight;
|
|
71
106
|
private active;
|
|
72
107
|
/**
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* conversation instead of prompting into a session it cannot see.
|
|
108
|
+
* Admission control for the session-creating half of a run: one board action
|
|
109
|
+
* opens a whole subtree, and this is what keeps the Host from asking DSH for
|
|
110
|
+
* every member's session at once (see {@link LaunchAdmissionQueue}).
|
|
77
111
|
*/
|
|
78
|
-
private
|
|
112
|
+
private readonly launches;
|
|
79
113
|
/**
|
|
80
114
|
* Consecutive unreadable-history polls per open execution (see
|
|
81
115
|
* {@link noteUnreadableInspection}). Cleared as soon as an inspection
|
|
@@ -87,6 +121,16 @@ export declare class TaskBoardHostService {
|
|
|
87
121
|
private readonly verificationCatalog;
|
|
88
122
|
private readonly team;
|
|
89
123
|
private readonly timers;
|
|
124
|
+
/** Live reader of the global native-/goal switch; frozen per execution. */
|
|
125
|
+
private readonly goalRunEnabled;
|
|
126
|
+
/** Live reader of the deployment's new-card defaults (published and applied per create). */
|
|
127
|
+
private readonly cardDefaults;
|
|
128
|
+
/**
|
|
129
|
+
* Live reader of the run-launch admission width: how many launches may be in
|
|
130
|
+
* flight at once. Read at every admission, so a settings edit bounds the next
|
|
131
|
+
* launch without remounting the row. Absent means the default.
|
|
132
|
+
*/
|
|
133
|
+
private readonly runLaunchWidth;
|
|
90
134
|
private lastPowerJson;
|
|
91
135
|
private readonly now;
|
|
92
136
|
/** The deployment's workspaces, consulted to resolve a card that pins none. */
|
|
@@ -103,14 +147,36 @@ export declare class TaskBoardHostService {
|
|
|
103
147
|
now?: () => number;
|
|
104
148
|
commandDispatcher?: SessionCommandDispatcher;
|
|
105
149
|
workspaceRegistry?: TaskBoardWorkspaceRegistry;
|
|
150
|
+
/**
|
|
151
|
+
* The owner peer every gateway request the runner makes speaks for.
|
|
152
|
+
* Production passes the peer bound to the plugin fiber (see
|
|
153
|
+
* {@link createOwnerPeer}); absent is fine for tests and bare mounts,
|
|
154
|
+
* where the runner binds one to a fresh root context.
|
|
155
|
+
*/
|
|
156
|
+
ownerPeer?: GatewayPeer;
|
|
106
157
|
/**
|
|
107
158
|
* Permission baseline of the confirmation gate: a fixed value, or a live
|
|
108
159
|
* resolver the board re-reads so a Host Settings change needs no remount.
|
|
109
160
|
*/
|
|
110
161
|
sessionDefaultPermission?: TaskPermission | (() => TaskPermission);
|
|
111
162
|
maxSubtaskDepth?: number;
|
|
163
|
+
/**
|
|
164
|
+
* Live reader of the deployment's new-card defaults (volatile config reads).
|
|
165
|
+
* The board publishes them for the create dialog and re-reads them for every
|
|
166
|
+
* create that opts in, so a settings edit reaches the next created card
|
|
167
|
+
* without remounting the row. Absent means the deployment configures none.
|
|
168
|
+
*/
|
|
169
|
+
cardDefaults?: () => CardDefaults;
|
|
112
170
|
team?: TaskBoardTeamDispatcher;
|
|
113
171
|
timers?: HostTimerFace;
|
|
172
|
+
/**
|
|
173
|
+
* Live GLOBAL native /goal switch (a volatile config read). Read ONCE per
|
|
174
|
+
* execution, at launch, and carried by value from then on: a settings edit
|
|
175
|
+
* made while a run is in flight must not arm, disarm or otherwise change the
|
|
176
|
+
* goal/acceptance contract of that run. Absent means OFF, which is the
|
|
177
|
+
* default for every deployment that never configured it.
|
|
178
|
+
*/
|
|
179
|
+
goalRunEnabled?: () => boolean;
|
|
114
180
|
/**
|
|
115
181
|
* Live acceptance settings (volatile config reads). Absent keeps goal
|
|
116
182
|
* acceptance OFF for every execution this service opens, which is what a
|
|
@@ -119,9 +185,25 @@ export declare class TaskBoardHostService {
|
|
|
119
185
|
verificationSettings?: () => VerificationSettings;
|
|
120
186
|
/** The host model catalog the acceptance contract resolves its route from. */
|
|
121
187
|
verificationCatalog?: () => Promise<ModelCatalogView | undefined>;
|
|
188
|
+
/**
|
|
189
|
+
* Live admission width for run launches: the number of launches (one
|
|
190
|
+
* session creation and its prompt each) that may be in flight at once. Read
|
|
191
|
+
* per admission, so editing the setting bounds the next launch of a run that
|
|
192
|
+
* is still queueing. Absent means the default width.
|
|
193
|
+
*/
|
|
194
|
+
runLaunchWidth?: () => number;
|
|
122
195
|
});
|
|
123
196
|
start(): void;
|
|
124
|
-
|
|
197
|
+
/**
|
|
198
|
+
* Apply the live configuration. The roster cadence is re-read on every
|
|
199
|
+
* commit, so a settings edit takes effect without a restart; the poll is
|
|
200
|
+
* scheduled at the new cadence immediately rather than waiting out the old
|
|
201
|
+
* interval.
|
|
202
|
+
* @param active - the board's master switch.
|
|
203
|
+
* @param preventIdleSleep - whether the board holds an idle-sleep assertion.
|
|
204
|
+
* @param sessionPollSeconds - roster-poll cadence in seconds (clamped).
|
|
205
|
+
*/
|
|
206
|
+
setConfiguration(active: boolean, preventIdleSleep: boolean, sessionPollSeconds?: number): void;
|
|
125
207
|
snapshot(): TaskBoardSnapshot;
|
|
126
208
|
/**
|
|
127
209
|
* Admit one external provider. Idempotent by extension id; the returned
|
|
@@ -184,6 +266,26 @@ export declare class TaskBoardHostService {
|
|
|
184
266
|
private emitStatusChanges;
|
|
185
267
|
dispose(): void;
|
|
186
268
|
private launch;
|
|
269
|
+
/**
|
|
270
|
+
* Read the acceptance contract one run group freezes, in the order the board
|
|
271
|
+
* has always read it: the acceptance settings, then the global native-/goal
|
|
272
|
+
* switch, then the model catalog that both resolves the contract's route and
|
|
273
|
+
* decides the reasoning effort the session may be given.
|
|
274
|
+
*/
|
|
275
|
+
private freezeRunContract;
|
|
276
|
+
/**
|
|
277
|
+
* A {@link RunContractFreezer} that reads once and hands the SAME value to
|
|
278
|
+
* every later caller of one run group. A read that fails is not cached: the
|
|
279
|
+
* next member reads again, exactly as a per-execution read would have.
|
|
280
|
+
*/
|
|
281
|
+
private contractFreezerForRunGroup;
|
|
282
|
+
/**
|
|
283
|
+
* Give back the occurrence a launch consumed, for a launch that never reached
|
|
284
|
+
* a session: a failed launch, or one the Host abandoned while it was still
|
|
285
|
+
* waiting for an admission slot. A manual run, and a launch that DID reach a
|
|
286
|
+
* session, are never refunded.
|
|
287
|
+
*/
|
|
288
|
+
private refundUnstartedSchedule;
|
|
187
289
|
private scheduleTeammate;
|
|
188
290
|
/**
|
|
189
291
|
* Spawn one teammate inside the Lead session and attach the teammate's
|
|
@@ -193,7 +295,32 @@ export declare class TaskBoardHostService {
|
|
|
193
295
|
* Lead's cascade verdict.
|
|
194
296
|
*/
|
|
195
297
|
private spawnTeammate;
|
|
298
|
+
/**
|
|
299
|
+
* One roster pass, and whether it could read the session tree.
|
|
300
|
+
*
|
|
301
|
+
* The board reads the DSH session roster only while it has something the
|
|
302
|
+
* roster can decide: an execution to inspect, or a card parked in the running
|
|
303
|
+
* column whose verdict may arrive from a settle this process never saw. That
|
|
304
|
+
* gate is what removes the cost the reporter measured — `session/list`
|
|
305
|
+
* rebuilds every persisted session row (string conversion, object allocation,
|
|
306
|
+
* a stat per record), and an idle board with no tasks was paying it every few
|
|
307
|
+
* seconds forever.
|
|
308
|
+
* @returns whether the roster was readable (an idle pass counts as readable).
|
|
309
|
+
*/
|
|
196
310
|
private pollSessions;
|
|
311
|
+
/**
|
|
312
|
+
* The session a run may continue in, for a card that opted into reuse
|
|
313
|
+
* (issue #1419). Reuse requires positive evidence that the previous session
|
|
314
|
+
* is present and idle, and that evidence must be read for THIS launch: an
|
|
315
|
+
* idle board no longer polls, so a roster cached from an earlier pass could
|
|
316
|
+
* be hours old — either refusing a session that has been idle all along, or
|
|
317
|
+
* prompting into one that started running since. A card that did not opt in
|
|
318
|
+
* reads no roster at all, and a read that fails mints a fresh conversation
|
|
319
|
+
* exactly as an unknown roster always did.
|
|
320
|
+
* @param task - the task about to run.
|
|
321
|
+
* @returns the session id to continue in, or undefined for a fresh session.
|
|
322
|
+
*/
|
|
323
|
+
private reuseSessionFor;
|
|
197
324
|
/** Reuse the session list this poll already fetched: one list RPC per tick, not 1 + E. */
|
|
198
325
|
private reconcileExecutions;
|
|
199
326
|
/**
|
|
@@ -206,6 +333,30 @@ export declare class TaskBoardHostService {
|
|
|
206
333
|
* each streak is logged, so the Host log names the session.
|
|
207
334
|
*/
|
|
208
335
|
private settleAndNotify;
|
|
336
|
+
/**
|
|
337
|
+
* Remove one execution's acceptance-only detail after it PASSED and settled.
|
|
338
|
+
*
|
|
339
|
+
* Deliberately narrow: only the acceptance mechanism's own per-attempt
|
|
340
|
+
* material (findings, invalid diagnostics, the bulky judge side) is removed,
|
|
341
|
+
* and only for THIS execution, keyed by its own id in the ledger it belongs
|
|
342
|
+
* to. No user file, task artifact, raw session history or other execution's
|
|
343
|
+
* record is read or written. Idempotent by the record's own state, and it
|
|
344
|
+
* clearly never touches a run that did not pass (the caller's guard) — a
|
|
345
|
+
* failed or invalid execution keeps everything a repair or a review needs.
|
|
346
|
+
* @param taskId - the task whose execution settled.
|
|
347
|
+
* @param executionId - the settled execution.
|
|
348
|
+
*/
|
|
349
|
+
private cleanupAcceptanceDetail;
|
|
350
|
+
/**
|
|
351
|
+
* Catch-up pass: clean the acceptance detail of every execution that PASSED
|
|
352
|
+
* and settled but whose cleanup did not finish (a crash, a failed write, a
|
|
353
|
+
* Host killed mid-cleanup).
|
|
354
|
+
*
|
|
355
|
+
* The same bounds as any other cleanup apply — only a real pass record on a
|
|
356
|
+
* settled execution is touched — so this can never delete material belonging
|
|
357
|
+
* to an execution that did not pass, and never a user file.
|
|
358
|
+
*/
|
|
359
|
+
private cleanupPendingAcceptanceDetail;
|
|
209
360
|
private noteUnreadableInspection;
|
|
210
361
|
/** Drop the armed schedule timer and forget its target. */
|
|
211
362
|
private clearScheduleTimer;
|
|
@@ -240,6 +391,13 @@ export declare class TaskBoardHostService {
|
|
|
240
391
|
* member then launches on its own so one refused participant cannot hold the
|
|
241
392
|
* others back. A team run's members are spawned inside the root's Lead
|
|
242
393
|
* session instead, once that session exists.
|
|
394
|
+
*
|
|
395
|
+
* Every launch of one run set goes through the admission queue, which admits
|
|
396
|
+
* at most `runLaunchWidth` of them at a time — the whole subtree still opens,
|
|
397
|
+
* members just enter the running column in batches. Order inside the group is
|
|
398
|
+
* the order they are enqueued here, so the root's session always exists before
|
|
399
|
+
* any member's, and one member's launch settling (or failing) is what admits
|
|
400
|
+
* the next. All members share the one contract this group freezes.
|
|
243
401
|
*/
|
|
244
402
|
private dispatchRuns;
|
|
245
403
|
/**
|
|
@@ -248,7 +406,40 @@ export declare class TaskBoardHostService {
|
|
|
248
406
|
*/
|
|
249
407
|
private setApplicability;
|
|
250
408
|
private scheduleLaunch;
|
|
409
|
+
/**
|
|
410
|
+
* Hand one launch to the admission queue, or abandon it on the spot when the
|
|
411
|
+
* Host is already stopping: a queue entry created after {@link dispose} would
|
|
412
|
+
* otherwise never be drained, and its card would sit in the running column
|
|
413
|
+
* until the next Host start recovered it.
|
|
414
|
+
*/
|
|
415
|
+
private enqueueLaunch;
|
|
416
|
+
/** Whether one opened execution is still open in the ledger. */
|
|
417
|
+
private isExecutionOpen;
|
|
418
|
+
/**
|
|
419
|
+
* Take one launch that never started out of the running column.
|
|
420
|
+
*
|
|
421
|
+
* Settled as CANCELLED, not failed: nothing about the run's work went wrong —
|
|
422
|
+
* the Host stopped before the launch got a slot, which is exactly what the
|
|
423
|
+
* next start's interrupted-start recovery records for an execution that never
|
|
424
|
+
* reached a session. A scheduled occurrence that never reached a session is
|
|
425
|
+
* refunded on the same terms as any other pre-session failure, so a run the
|
|
426
|
+
* Host never started cannot silently spend the user's run budget.
|
|
427
|
+
*/
|
|
428
|
+
private abandonQueuedRun;
|
|
251
429
|
private schedulePoll;
|
|
430
|
+
/**
|
|
431
|
+
* Count one failed pass and arm the retry that follows it.
|
|
432
|
+
*
|
|
433
|
+
* A session tree that is down is retried on a doubling delay instead of
|
|
434
|
+
* hammering it on the fixed cadence: the heartbeat would otherwise repeat
|
|
435
|
+
* every failure — and every retry inside {@link HostExecutionRunner.listRunning}
|
|
436
|
+
* — at exactly the interval the reporter measured.
|
|
437
|
+
*/
|
|
438
|
+
private notePollFailure;
|
|
439
|
+
/** Arm the retry that follows a failed pass, doubling up to the ceiling. */
|
|
440
|
+
private armPollBackoff;
|
|
441
|
+
/** Drop a pending retry; the next regular tick takes over. */
|
|
442
|
+
private clearPollBackoff;
|
|
252
443
|
/**
|
|
253
444
|
* Re-arm from the ledger's current targets. Callers that just changed a
|
|
254
445
|
* schedule (the host routes, the agent tools) invoke this after the write
|
package/lib/types/index.d.ts
CHANGED
|
@@ -62,12 +62,73 @@ export interface Config {
|
|
|
62
62
|
* of the root task opens, so the ceiling is deliberately small.
|
|
63
63
|
*/
|
|
64
64
|
maxSubtaskDepth?: Volatile<number>;
|
|
65
|
+
/**
|
|
66
|
+
* How often, in seconds, the Host re-reads the DSH session roster while the
|
|
67
|
+
* board has something to reconcile: a running card, an open execution, or an
|
|
68
|
+
* active provider extension. An idle board with none of those does not poll
|
|
69
|
+
* at all, so this cadence only bounds how quickly a running card settles.
|
|
70
|
+
*/
|
|
71
|
+
sessionPollSeconds?: Volatile<number>;
|
|
72
|
+
/**
|
|
73
|
+
* How many run launches this board may have in flight at once (1..16,
|
|
74
|
+
* default 3). One run opens its whole subtree, so without a bound the Host
|
|
75
|
+
* asks DSH for every member's session in the same tick; this is the mechanism
|
|
76
|
+
* that enforces the repository's measured guidance for heavy implementation
|
|
77
|
+
* subagents. Members wait their turn instead of being dropped: the subtree
|
|
78
|
+
* still opens completely, they only enter the running column in batches. Read
|
|
79
|
+
* at each admission, so an edit bounds the next launch of a run that is still
|
|
80
|
+
* queueing.
|
|
81
|
+
*/
|
|
82
|
+
runLaunchWidth?: Volatile<number>;
|
|
65
83
|
/**
|
|
66
84
|
* Continuable-subagent provider the Agent Teams service uses to compose a
|
|
67
85
|
* teammate. Matches the Agent Teams tool plugin's `freshProvider` default;
|
|
68
86
|
* only team-mode runs use it.
|
|
69
87
|
*/
|
|
70
88
|
teamProvider?: string;
|
|
89
|
+
/**
|
|
90
|
+
* GLOBAL native /goal switch (default OFF), the master control over whether
|
|
91
|
+
* this board starts a run with dsh's built-in /goal at all. A run uses native
|
|
92
|
+
* /goal only when THIS is on AND the task's own `goalRun` is not off; while
|
|
93
|
+
* it is off every task runs one plain turn.
|
|
94
|
+
*
|
|
95
|
+
* The value is frozen when an execution starts, so toggling it only affects
|
|
96
|
+
* executions that begin afterwards and never re-writes a task's stored
|
|
97
|
+
* `goalRun` preference. A run that consequently does not execute native
|
|
98
|
+
* /goal is marked as such (its acceptance applicability is `goal-disabled`)
|
|
99
|
+
* and is never reported as a passed goal acceptance or failed for lacking a
|
|
100
|
+
* completion call. Independent of `goalVerification`; acceptance governs the
|
|
101
|
+
* completing call of a goal-form run, this switch governs whether the run
|
|
102
|
+
* becomes a goal run.
|
|
103
|
+
*/
|
|
104
|
+
goalRunEnabled?: Volatile<boolean>;
|
|
105
|
+
/**
|
|
106
|
+
* Agent preset a NEW card starts from (volatile, default blank = not set).
|
|
107
|
+
* A prefill, never a pin: the create dialog opens with it selected, the
|
|
108
|
+
* caller may override it, and the card stores what it was created with. It
|
|
109
|
+
* reaches the create path only when that caller opts in with
|
|
110
|
+
* `applyCardDefaults`, so the extension provider's own create and the legacy
|
|
111
|
+
* import are untouched.
|
|
112
|
+
*/
|
|
113
|
+
cardDefaultMode?: Volatile<string>;
|
|
114
|
+
/**
|
|
115
|
+
* Permission a NEW card starts from (volatile, default blank = not set), one
|
|
116
|
+
* of the three presets. A prefill like the rest: a value above
|
|
117
|
+
* `sessionDefaultPermission` still has to be confirmed by a human before the
|
|
118
|
+
* card may run, because the pre-execution gate is what decides that.
|
|
119
|
+
*/
|
|
120
|
+
cardDefaultPermission?: Volatile<TaskPermission | ''>;
|
|
121
|
+
/**
|
|
122
|
+
* Model a NEW card starts from (volatile, default blank = not set).
|
|
123
|
+
*/
|
|
124
|
+
cardDefaultModel?: Volatile<string>;
|
|
125
|
+
/**
|
|
126
|
+
* Reasoning level a NEW card starts from (volatile, default blank = not set).
|
|
127
|
+
* Bound to `cardDefaultModel` exactly as a card's own level is bound to its
|
|
128
|
+
* own model: it applies only while the card's final model IS that default
|
|
129
|
+
* model, and a blank `cardDefaultModel` makes it inert.
|
|
130
|
+
*/
|
|
131
|
+
cardDefaultReasoningEffort?: Volatile<string>;
|
|
71
132
|
/**
|
|
72
133
|
* Goal acceptance for executions this board starts (default ON). When on,
|
|
73
134
|
* update_goal(action: complete) inside a task execution is refused until an
|
|
@@ -93,6 +154,23 @@ export interface Config {
|
|
|
93
154
|
* sent, and the fallback to the model's own default is reported.
|
|
94
155
|
*/
|
|
95
156
|
goalVerificationReasoningEffort?: Volatile<string>;
|
|
157
|
+
/**
|
|
158
|
+
* Ceiling of ONE judge request of a goal acceptance, in seconds
|
|
159
|
+
* (30..600, default 150). One acceptance issues six judge requests (three
|
|
160
|
+
* criteria times two rounds), so a ceiling that is too small turns a slow but
|
|
161
|
+
* healthy judge route into a wall of timeouts, and every timeout was charged
|
|
162
|
+
* as an acceptance anomaly. Raise it for a reasoning model reading a long
|
|
163
|
+
* trace.
|
|
164
|
+
*/
|
|
165
|
+
goalVerificationCallTimeoutSeconds?: Volatile<number>;
|
|
166
|
+
/**
|
|
167
|
+
* Total ceiling of ONE goal acceptance attempt, in seconds (120..1800,
|
|
168
|
+
* default eight times the per-call default). Keep it at or above
|
|
169
|
+
* `goalVerificationCallTimeoutSeconds` times six or an acceptance can never
|
|
170
|
+
* finish: the attempt then ends early with a budget stop that judges nothing
|
|
171
|
+
* and spends no acceptance budget.
|
|
172
|
+
*/
|
|
173
|
+
goalVerificationBudgetSeconds?: Volatile<number>;
|
|
96
174
|
}
|
|
97
175
|
/**
|
|
98
176
|
* Continuable-subagent provider for fresh teammates, matching the Agent Teams
|
|
@@ -124,18 +202,42 @@ export interface ConfigInput {
|
|
|
124
202
|
sessionDefaultPermission?: TaskPermission;
|
|
125
203
|
/** Subtask depth limit, 1..3. */
|
|
126
204
|
maxSubtaskDepth?: number;
|
|
205
|
+
/** Roster-poll cadence in seconds while the board has work to reconcile. */
|
|
206
|
+
sessionPollSeconds?: number;
|
|
207
|
+
/** Concurrent run launches allowed at once, 1..16. */
|
|
208
|
+
runLaunchWidth?: number;
|
|
127
209
|
/** Continuable-subagent provider the Agent Teams service composes a teammate from. */
|
|
128
210
|
teamProvider?: string;
|
|
211
|
+
/** Global native /goal switch; default off, frozen per execution. */
|
|
212
|
+
goalRunEnabled?: boolean;
|
|
213
|
+
/** Agent preset a new card starts from; blank = not set. */
|
|
214
|
+
cardDefaultMode?: string;
|
|
215
|
+
/** Permission a new card starts from; blank = not set. */
|
|
216
|
+
cardDefaultPermission?: TaskPermission | '';
|
|
217
|
+
/** Model a new card starts from; blank = not set. */
|
|
218
|
+
cardDefaultModel?: string;
|
|
219
|
+
/** Reasoning level a new card starts from; blank = not set. */
|
|
220
|
+
cardDefaultReasoningEffort?: string;
|
|
129
221
|
/** Goal acceptance switch. */
|
|
130
222
|
goalVerification?: boolean;
|
|
131
223
|
/** Judge model route for goal acceptance; blank inherits the host default. */
|
|
132
224
|
goalVerificationModel?: string;
|
|
133
225
|
/** Judge reasoning effort; blank inherits the host default. */
|
|
134
226
|
goalVerificationReasoningEffort?: string;
|
|
227
|
+
/** Ceiling of one judge request of a goal acceptance, in seconds. */
|
|
228
|
+
goalVerificationCallTimeoutSeconds?: number;
|
|
229
|
+
/** Total ceiling of one goal acceptance attempt, in seconds. */
|
|
230
|
+
goalVerificationBudgetSeconds?: number;
|
|
135
231
|
}
|
|
136
232
|
export declare const Config: z<ConfigInput, Config>;
|
|
137
233
|
/** Schema default for the goal-acceptance switch, re-read for hand-built contexts. */
|
|
138
234
|
export declare const DEFAULT_GOAL_VERIFICATION = true;
|
|
235
|
+
/**
|
|
236
|
+
* Schema default for the GLOBAL native-/goal switch, re-read for hand-built
|
|
237
|
+
* contexts. Deliberately false: a deployment that never configured it (and
|
|
238
|
+
* every card written before the option existed) runs plain single turns.
|
|
239
|
+
*/
|
|
240
|
+
export declare const DEFAULT_GOAL_RUN = false;
|
|
139
241
|
declare module '@deepseek-ai/cordis' {
|
|
140
242
|
interface Events {
|
|
141
243
|
/**
|
|
@@ -250,6 +352,45 @@ export declare function buildTeamDispatcher(ctx: Context, provider: string): Tas
|
|
|
250
352
|
* @returns the llm service, or undefined when this deployment serves none.
|
|
251
353
|
*/
|
|
252
354
|
export declare function resolveLlmRuntime(ctx: Context): LlmRuntime | undefined;
|
|
355
|
+
/**
|
|
356
|
+
* The subset of `sessionController` the board uses to wake a cold persisted
|
|
357
|
+
* session before running a slash command on it (issue #1861).
|
|
358
|
+
*/
|
|
359
|
+
interface SessionControllerFace {
|
|
360
|
+
resolveAgent(sessionId: Parameters<Context['agents']['get']>[0]): Promise<{
|
|
361
|
+
readonly agent: Parameters<Context['commands']['execute']>[0];
|
|
362
|
+
} | {
|
|
363
|
+
readonly error: {
|
|
364
|
+
readonly message?: string;
|
|
365
|
+
};
|
|
366
|
+
}>;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Resolve the optional `sessionController` service. Like the tool registry and
|
|
370
|
+
* the llm runtime, it is read dynamically so capture-only test contexts that do
|
|
371
|
+
* not mount the full session controller still activate the board.
|
|
372
|
+
* @param ctx - the plugin context.
|
|
373
|
+
* @returns the session controller face, or undefined when unavailable.
|
|
374
|
+
*/
|
|
375
|
+
export declare function resolveSessionController(ctx: Context): SessionControllerFace | undefined;
|
|
376
|
+
/**
|
|
377
|
+
* Resolve the live Agent for an execution session, resuming a cold persisted
|
|
378
|
+
* session through `sessionController.resolveAgent` when it is not yet in
|
|
379
|
+
* `ctx.agents` (issue #1861).
|
|
380
|
+
*
|
|
381
|
+
* A fresh run (`session/create`) or a session the browser is currently
|
|
382
|
+
* following is already in `ctx.agents`, so the fast path returns immediately.
|
|
383
|
+
* A scheduled or manual reuse of a cold session — one that `session/list`
|
|
384
|
+
* reports as idle from disk without activating its Agent — is not in
|
|
385
|
+
* `ctx.agents` when `pinAndPrompt` runs `/permission` ahead of
|
|
386
|
+
* `session/selectModel` and `session/prompt`; delegating to
|
|
387
|
+
* `sessionController.resolveAgent` resumes it with its recorded preset and
|
|
388
|
+
* model-selection state, matching what those gateway endpoints do next.
|
|
389
|
+
* @param ctx - the plugin context.
|
|
390
|
+
* @param sessionId - the target execution session id.
|
|
391
|
+
* @returns the live Agent for `sessionId`.
|
|
392
|
+
*/
|
|
393
|
+
export declare function resolveExecutionAgent(ctx: Context, sessionId: Parameters<Context['agents']['get']>[0]): Promise<Parameters<Context['commands']['execute']>[0]>;
|
|
253
394
|
/**
|
|
254
395
|
* Activate the board's host half: ledger, routes, cron scheduler, power
|
|
255
396
|
* inhibitor, and the model-facing announcement.
|
package/lib/types/protocol.d.ts
CHANGED
|
@@ -1,22 +1,36 @@
|
|
|
1
1
|
import type { TaskUpdatePatch } from './core/use-cases/task-update.ts';
|
|
2
|
+
import type { SetSchedulePatch } from './core/use-cases/task-schedule.ts';
|
|
2
3
|
import { type NewTaskInput, type TaskPermission, type TaskRecord, type TaskStatus } from './core/tasks.ts';
|
|
3
4
|
import { type TaskBoardExtensionPayload } from './core/extension.ts';
|
|
4
5
|
import { type ModelCatalogView, type VerificationContract, type VerificationSettings } from './core/verification.ts';
|
|
5
|
-
export declare const TASK_BOARD_SCHEMA_VERSION:
|
|
6
|
-
/** Ledger documents written before
|
|
7
|
-
export declare const TASK_BOARD_LEGACY_SCHEMA_VERSION:
|
|
6
|
+
export declare const TASK_BOARD_SCHEMA_VERSION: 6;
|
|
7
|
+
/** Ledger documents written before v6; loaded once and migrated on startup. */
|
|
8
|
+
export declare const TASK_BOARD_LEGACY_SCHEMA_VERSION: 5;
|
|
9
|
+
/** Ledger documents written before v5; migrated through the v5 normalization too. */
|
|
10
|
+
export declare const TASK_BOARD_PRE_ACCEPTANCE_SCHEMA_VERSION: 4;
|
|
8
11
|
/** Ledger documents written before v4; migrated through the v4 normalization too. */
|
|
9
12
|
export declare const TASK_BOARD_OLDER_SCHEMA_VERSION: 3;
|
|
10
13
|
/** Ledger documents written before v3; migrated through every later normalization too. */
|
|
11
14
|
export declare const TASK_BOARD_OLDEST_SCHEMA_VERSION: 2;
|
|
12
15
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
16
|
+
* The last generation whose rules still need the Host zone stamped on them at
|
|
17
|
+
* migration: v4 introduced the stored zone but a rule written without one must
|
|
18
|
+
* stop following a later TZ change. A v5 rule already carries its zone (or
|
|
19
|
+
* deliberately follows the Host), so it is NOT stamped again.
|
|
20
|
+
*/
|
|
21
|
+
export declare const TASK_BOARD_ZONE_STAMP_SCHEMA_VERSION: 4;
|
|
22
|
+
/**
|
|
23
|
+
* Every older generation the loader migrates in place. v5 only added the
|
|
24
|
+
* per-execution acceptance block and v6 only added the scheduling mode and run
|
|
25
|
+
* budget, so the migration is the normalization pass that re-validates each
|
|
26
|
+
* row; a document from any listed generation upgrades losslessly.
|
|
17
27
|
*/
|
|
18
28
|
export declare const TASK_BOARD_MIGRATABLE_SCHEMA_VERSIONS: readonly number[];
|
|
19
29
|
export declare const TASK_BOARD_API_PREFIX = "/api/task-board";
|
|
30
|
+
/** Longest accepted caller identity on an external outcome record. */
|
|
31
|
+
export declare const EXTERNAL_INITIATOR_MAX_LENGTH = 200;
|
|
32
|
+
/** Longest accepted free-text summary on an external outcome record. */
|
|
33
|
+
export declare const EXTERNAL_SUMMARY_MAX_LENGTH = 1000;
|
|
20
34
|
export type PowerPhase = 'disabled' | 'idle' | 'acquiring' | 'active' | 'error' | 'unsupported';
|
|
21
35
|
export interface TaskBoardPowerSnapshot {
|
|
22
36
|
platform: string;
|
|
@@ -52,6 +66,27 @@ export interface TaskBoardSnapshot {
|
|
|
52
66
|
* into team execution (Team Lead session plus one teammate per subtask).
|
|
53
67
|
*/
|
|
54
68
|
teamRunAvailable?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Live GLOBAL native-/goal switch. The browser uses it to disable the
|
|
71
|
+
* task-level option (and explain that the global switch must be turned on
|
|
72
|
+
* first) WITHOUT rewriting anyone's stored per-task preference; the Host
|
|
73
|
+
* freezes its own read per execution, so this mirror never governs a run in
|
|
74
|
+
* flight.
|
|
75
|
+
*/
|
|
76
|
+
goalRunEnabled?: boolean;
|
|
77
|
+
/**
|
|
78
|
+
* New-card defaults this deployment configures: what the create dialog opens
|
|
79
|
+
* with, and what the create path fills an omitted target from when the caller
|
|
80
|
+
* opts in (`applyCardDefaults`). A target the board configures nothing for is
|
|
81
|
+
* omitted rather than published blank, so the browser can tell "no default
|
|
82
|
+
* model" from "a blank one".
|
|
83
|
+
*/
|
|
84
|
+
cardDefaults?: {
|
|
85
|
+
mode?: string;
|
|
86
|
+
permission?: TaskPermission;
|
|
87
|
+
model?: string;
|
|
88
|
+
reasoningEffort?: string;
|
|
89
|
+
};
|
|
55
90
|
/**
|
|
56
91
|
* Read-only summaries published by running extensions, keyed by extension id.
|
|
57
92
|
* The board forwards them verbatim; it never interprets their shape.
|
|
@@ -124,14 +159,30 @@ export type TaskBoardAction = {
|
|
|
124
159
|
} | {
|
|
125
160
|
kind: 'settle';
|
|
126
161
|
taskId: string;
|
|
162
|
+
}
|
|
163
|
+
/** Clear the acceptance anomalies recorded on a card's open execution (issue #1828). */
|
|
164
|
+
| {
|
|
165
|
+
kind: 'reset-verification';
|
|
166
|
+
taskId: string;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Record an outcome an agent OUTSIDE the Host produced (issue #1826).
|
|
170
|
+
*
|
|
171
|
+
* It writes a real execution record, so the terminal column and the run
|
|
172
|
+
* history both derive from that one record instead of a bare column edit.
|
|
173
|
+
* `cancelled` is deliberately absent: nothing outside a DSH session may
|
|
174
|
+
* claim the Host closed a run, and `running` must stay Host-only.
|
|
175
|
+
*/
|
|
176
|
+
| {
|
|
177
|
+
kind: 'record-external-outcome';
|
|
178
|
+
taskId: string;
|
|
179
|
+
result: 'succeeded' | 'failed';
|
|
180
|
+
initiatedBy: string;
|
|
181
|
+
summary?: string;
|
|
127
182
|
} | {
|
|
128
183
|
kind: 'set-schedule';
|
|
129
184
|
taskId: string;
|
|
130
|
-
patch:
|
|
131
|
-
enabled?: boolean;
|
|
132
|
-
cron?: string;
|
|
133
|
-
timeZone?: string | null;
|
|
134
|
-
};
|
|
185
|
+
patch: SetSchedulePatch;
|
|
135
186
|
} | {
|
|
136
187
|
kind: 'run';
|
|
137
188
|
taskId: string;
|