@linxin666/dsh-client-ui-task-board 0.4.1 → 0.4.3
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 +28 -3
- package/README.zh.md +28 -3
- package/lib/client.js +1142 -467
- package/lib/client.js.map +1 -1
- package/lib/index.js +2066 -1475
- package/lib/types/client/TaskBoardSettingsCard.d.ts +4 -0
- package/lib/types/client/board/LinkSubtaskModal.d.ts +11 -0
- package/lib/types/client/board/NewTaskModal.d.ts +7 -1
- package/lib/types/client/board/TaskCard.d.ts +11 -1
- package/lib/types/client/index.d.ts +15 -1
- package/lib/types/client/locales.d.ts +33 -0
- package/lib/types/client/native-panel.d.ts +62 -0
- package/lib/types/client/settings-entry-form.d.ts +49 -0
- package/lib/types/core/controller.d.ts +71 -3
- package/lib/types/core/subtask.d.ts +122 -0
- package/lib/types/core/tasks.d.ts +46 -3
- package/lib/types/core/use-cases/task-archive.d.ts +10 -13
- package/lib/types/core/use-cases/task-create.d.ts +13 -4
- package/lib/types/core/use-cases/task-delete.d.ts +7 -1
- package/lib/types/core/use-cases/task-parent.d.ts +21 -0
- package/lib/types/core/use-cases/task-update.d.ts +1 -1
- package/lib/types/host/agent-tools.d.ts +27 -0
- package/lib/types/host-ledger.d.ts +97 -4
- package/lib/types/host-runner.d.ts +39 -1
- package/lib/types/host-service.d.ts +98 -5
- package/lib/types/index.d.ts +93 -5
- package/lib/types/mount-once.d.ts +38 -7
- package/lib/types/protocol.d.ts +14 -0
- package/package.json +26 -21
- package/src/client/TaskBoardSettingsCard.tsx +48 -3
- package/src/client/board/LinkSubtaskModal.tsx +82 -0
- package/src/client/board/NewTaskModal.tsx +40 -6
- package/src/client/board/TaskBoard.tsx +88 -8
- package/src/client/board/TaskCard.tsx +52 -2
- package/src/client/board/TaskDetail.tsx +124 -1
- package/src/client/board.module.css +112 -131
- package/src/client/host-api.ts +14 -4
- package/src/client/index.ts +56 -18
- package/src/client/locales.ts +70 -2
- package/src/client/native-panel.tsx +124 -0
- package/src/client/settings-entry-form.ts +142 -0
- package/src/core/controller.ts +128 -10
- package/src/core/store.ts +15 -0
- package/src/core/subtask.ts +286 -0
- package/src/core/tasks.ts +50 -2
- package/src/core/use-cases/task-archive.ts +46 -12
- package/src/core/use-cases/task-create.ts +42 -7
- package/src/core/use-cases/task-delete.ts +11 -1
- package/src/core/use-cases/task-parent.ts +64 -0
- package/src/core/use-cases/task-update.ts +3 -1
- package/src/host/agent-tools.ts +643 -0
- package/src/host-ledger.ts +343 -45
- package/src/host-routes.ts +37 -1
- package/src/host-runner.ts +141 -12
- package/src/host-service.ts +265 -32
- package/src/index.ts +203 -9
- package/src/mount-once.ts +107 -13
- package/src/protocol.ts +26 -2
- package/lib/types/client/board-mount.d.ts +0 -23
- package/lib/types/client/body-mutations.d.ts +0 -45
- package/lib/types/client/panel-mount-core.d.ts +0 -56
- package/lib/types/client/sidebar-entry-core.d.ts +0 -55
- package/lib/types/client/sidebar-entry.d.ts +0 -29
- package/src/client/board-mount.tsx +0 -43
- package/src/client/body-mutations.ts +0 -133
- package/src/client/panel-mount-core.ts +0 -155
- package/src/client/sidebar-entry-core.ts +0 -237
- package/src/client/sidebar-entry.ts +0 -53
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
import { type NewTaskInput, type TaskRecord } from '../tasks.ts';
|
|
2
2
|
/** Result of a create transition: the new task (when accepted) + the next ledger. */
|
|
3
3
|
export interface CreateTaskResult {
|
|
4
|
-
/** The minted task, or undefined when the input was rejected
|
|
4
|
+
/** The minted task, or undefined when the input was rejected. */
|
|
5
5
|
task: TaskRecord | undefined;
|
|
6
6
|
/** The next ledger; identical reference when rejected. */
|
|
7
7
|
tasks: readonly TaskRecord[];
|
|
8
|
+
/** Why the input was rejected; absent when a task was minted. */
|
|
9
|
+
error?: string;
|
|
8
10
|
}
|
|
9
11
|
/**
|
|
10
12
|
* Apply a create against the current ledger. Returns the new task and the
|
|
11
|
-
* appended ledger, or the unchanged ledger when the title is blank
|
|
13
|
+
* appended ledger, or the unchanged ledger when the title is blank or the
|
|
14
|
+
* requested parent link is refused.
|
|
15
|
+
*
|
|
16
|
+
* A subtask inherits the execution targets its parent already pins (workspace,
|
|
17
|
+
* agent preset, permission, model) unless the form supplied its own; the
|
|
18
|
+
* parent human permission confirmation travels with an inherited permission,
|
|
19
|
+
* so a subtask of an already-confirmed elevated card is runnable at once.
|
|
12
20
|
* @param tasks - current ledger.
|
|
13
|
-
* @param input - raw user input (title/description/prompt + optional schedule).
|
|
21
|
+
* @param input - raw user input (title/description/prompt + optional schedule/parent).
|
|
14
22
|
* @param now - clock instant (ms epoch).
|
|
15
23
|
* @param id - minted task id.
|
|
24
|
+
* @param maxSubtaskDepth - deployment subtask depth limit.
|
|
16
25
|
*/
|
|
17
|
-
export declare function applyCreateTask(tasks: readonly TaskRecord[], input: NewTaskInput, now: number, id: string): CreateTaskResult;
|
|
26
|
+
export declare function applyCreateTask(tasks: readonly TaskRecord[], input: NewTaskInput, now: number, id: string, maxSubtaskDepth?: number): CreateTaskResult;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Delete-task use case: drop a task from the ledger and clear the selection
|
|
3
3
|
* when it pointed at the removed task. Pure ledger transition (no persistence
|
|
4
|
-
* or notify
|
|
4
|
+
* or notify - the controller orchestrates those).
|
|
5
|
+
*
|
|
6
|
+
* A task that still has subtasks is refused: deleting the parent would leave
|
|
7
|
+
* dangling child links, and silently detaching (or cascading) the children is
|
|
8
|
+
* a data-loss decision the user must make explicitly.
|
|
5
9
|
*/
|
|
6
10
|
import type { TaskRecord } from '../tasks.ts';
|
|
7
11
|
/** Result of a delete transition. */
|
|
@@ -10,6 +14,8 @@ export interface DeleteTaskResult {
|
|
|
10
14
|
tasks: readonly TaskRecord[];
|
|
11
15
|
/** Whether the previous selection referenced the removed task. */
|
|
12
16
|
selectionCleared: boolean;
|
|
17
|
+
/** True when the task still carries subtasks, so nothing was removed. */
|
|
18
|
+
blocked: boolean;
|
|
13
19
|
}
|
|
14
20
|
/**
|
|
15
21
|
* Apply a delete across the ledger. The selection (a task id) is cleared when
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { TaskRecord } from '../tasks.ts';
|
|
2
|
+
/** Result of a parent-link transition. */
|
|
3
|
+
export interface SetParentResult {
|
|
4
|
+
/** The next ledger; the input reference when refused. */
|
|
5
|
+
tasks: readonly TaskRecord[];
|
|
6
|
+
/** Whether the link (or the detachment) was stored. */
|
|
7
|
+
applied: boolean;
|
|
8
|
+
/** User-facing refusal reason; absent when applied. */
|
|
9
|
+
error?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Attach or detach one task. A null (or blank) parent detaches, which is always
|
|
13
|
+
* allowed for a known on-board task; attaching validates the whole chain so a
|
|
14
|
+
* cyclic or too-deep ledger can never be stored.
|
|
15
|
+
* @param tasks - current ledger.
|
|
16
|
+
* @param id - the task being moved.
|
|
17
|
+
* @param parentId - the new parent, or null to detach.
|
|
18
|
+
* @param now - clock instant (ms epoch).
|
|
19
|
+
* @param maxSubtaskDepth - deployment subtask depth limit.
|
|
20
|
+
*/
|
|
21
|
+
export declare function applySetParent(tasks: readonly TaskRecord[], id: string, parentId: string | null, now: number, maxSubtaskDepth?: number): SetParentResult;
|
|
@@ -15,7 +15,7 @@ import type { TaskHandoverInput } from '../handover.ts';
|
|
|
15
15
|
* Editable fields on a task (the update patch surface). `freeze` replaces the
|
|
16
16
|
* continuation-card snapshot (restamping frozenAt); an explicit null clears it.
|
|
17
17
|
*/
|
|
18
|
-
export type TaskUpdatePatch = Partial<Pick<TaskRecord, 'title' | 'description' | 'prompt' | 'workspaceId' | 'mode' | 'permission' | 'model' | 'reuseSession'>> & {
|
|
18
|
+
export type TaskUpdatePatch = Partial<Pick<TaskRecord, 'title' | 'description' | 'prompt' | 'workspaceId' | 'mode' | 'permission' | 'model' | 'reuseSession' | 'teamRun'>> & {
|
|
19
19
|
freeze?: FreezeSnapshot & {
|
|
20
20
|
redacted?: boolean;
|
|
21
21
|
} | null;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ToolDefinition } from '@deepseek-ai/dsh-tools';
|
|
2
|
+
import type { TaskBoardAction, TaskBoardSnapshot } from '../protocol.ts';
|
|
3
|
+
/**
|
|
4
|
+
* The narrow Host face the tools need. TaskBoardHostService satisfies it
|
|
5
|
+
* structurally, so tests and a future host can drive the same surface.
|
|
6
|
+
*/
|
|
7
|
+
export interface TaskBoardToolHost {
|
|
8
|
+
/** Current board snapshot (tasks + scheduler + power + deployment constants). */
|
|
9
|
+
snapshot(): TaskBoardSnapshot;
|
|
10
|
+
/** Submit one confirmed Host action; returns the resulting snapshot. */
|
|
11
|
+
apply(requestId: string, action: TaskBoardAction, initiator?: string): TaskBoardSnapshot;
|
|
12
|
+
}
|
|
13
|
+
/** Registered tool names, in registration order. */
|
|
14
|
+
export declare const TASK_BOARD_TOOL_NAMES: readonly ["task_board_list", "task_board_get", "task_board_create", "task_board_update", "task_board_set_parent", "task_board_run", "task_board_manage", "task_board_schedule"];
|
|
15
|
+
/**
|
|
16
|
+
* The calling session id, for the execution audit trail (the same stamp the
|
|
17
|
+
* browser asserts). Absent when a call has no agent behind it.
|
|
18
|
+
*/
|
|
19
|
+
export declare function callingSessionId(exec: {
|
|
20
|
+
agent?: unknown;
|
|
21
|
+
}): string | undefined;
|
|
22
|
+
/**
|
|
23
|
+
* Build every task-board tool bound to one Host service.
|
|
24
|
+
* @param host - the Host ledger/service face (TaskBoardHostService).
|
|
25
|
+
* @returns the tool definitions, in TASK_BOARD_TOOL_NAMES order.
|
|
26
|
+
*/
|
|
27
|
+
export declare function buildTaskBoardTools(host: TaskBoardToolHost): ToolDefinition[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ExecutionRecord, type TaskRecord } from './core/tasks.ts';
|
|
1
|
+
import { type ExecutionOutcome, type ExecutionRecord, type TaskRecord } from './core/tasks.ts';
|
|
2
2
|
import { type TaskBoardAction, type TaskBoardSchedulerSnapshot } from './protocol.ts';
|
|
3
3
|
import { type TaskPermission } from './core/handover.ts';
|
|
4
4
|
export interface LedgerState {
|
|
@@ -9,6 +9,13 @@ export interface LedgerState {
|
|
|
9
9
|
export interface OpenedRun {
|
|
10
10
|
task: TaskRecord;
|
|
11
11
|
execution: ExecutionRecord;
|
|
12
|
+
/**
|
|
13
|
+
* How the Host obtains this run's session. Absent or `session` launches a
|
|
14
|
+
* fresh (or reused) execution session; `teammate` means the run belongs to a
|
|
15
|
+
* team-mode cascade, where the Host asks the root's Lead session to spawn a
|
|
16
|
+
* teammate instead of launching a session of its own.
|
|
17
|
+
*/
|
|
18
|
+
dispatch?: 'session' | 'teammate';
|
|
12
19
|
}
|
|
13
20
|
/** Minimal value copy used by the Host session monitor. */
|
|
14
21
|
export interface OpenExecutionReference {
|
|
@@ -52,6 +59,16 @@ export type PowerShellProbe = (script: string, timeoutMs: number) => string | un
|
|
|
52
59
|
* probe is injectable so the fallback chain is testable off Windows.
|
|
53
60
|
*/
|
|
54
61
|
export declare function win32StartTimeMs(pid: number, probe?: PowerShellProbe): number | undefined;
|
|
62
|
+
/**
|
|
63
|
+
* Repair parent links after a load or an import: a link whose parent row is
|
|
64
|
+
* missing, cyclic, or names an archived parent while the child is on board is
|
|
65
|
+
* dropped (the task becomes a root) instead of dropping the task. A chain
|
|
66
|
+
* deeper than the current `maxSubtaskDepth` is deliberately KEPT: the limit
|
|
67
|
+
* gates new links, it never deletes a stored one, and every cascade walk is
|
|
68
|
+
* bounded by the limit anyway. The Host is the only writer of these links, so
|
|
69
|
+
* this is a last-resort guard against a hand-edited or imported document.
|
|
70
|
+
*/
|
|
71
|
+
export declare function repairParentLinks(tasks: readonly TaskRecord[]): TaskRecord[];
|
|
55
72
|
export declare class HostTaskLedger {
|
|
56
73
|
private readonly now;
|
|
57
74
|
private document;
|
|
@@ -65,9 +82,24 @@ export declare class HostTaskLedger {
|
|
|
65
82
|
readonly schedulerFile: string;
|
|
66
83
|
/** Session-default permission the confirmation gate compares against. */
|
|
67
84
|
readonly sessionDefaultPermission: TaskPermission;
|
|
85
|
+
/**
|
|
86
|
+
* Deployment subtask depth limit (1..3): the lineage gate every write obeys.
|
|
87
|
+
* The settings card edits it live, so {@link setMaxSubtaskDepth} mutates it
|
|
88
|
+
* instead of remounting the row.
|
|
89
|
+
*/
|
|
90
|
+
private depthLimit;
|
|
68
91
|
constructor(dir?: string, now?: () => number, options?: {
|
|
69
92
|
sessionDefaultPermission?: TaskPermission;
|
|
93
|
+
maxSubtaskDepth?: number;
|
|
70
94
|
});
|
|
95
|
+
/** Current subtask depth limit (1..3). */
|
|
96
|
+
get maxSubtaskDepth(): number;
|
|
97
|
+
/**
|
|
98
|
+
* Apply a live settings edit of the subtask depth limit. A no-op when the
|
|
99
|
+
* normalized limit is unchanged, so a coarse volatile invalidation that
|
|
100
|
+
* changed nothing emits nothing.
|
|
101
|
+
*/
|
|
102
|
+
setMaxSubtaskDepth(depth: number): void;
|
|
71
103
|
/** Remove leftover *.tmp-* files from previous crashes or interrupted writes. */
|
|
72
104
|
private cleanStaleTemporaryFiles;
|
|
73
105
|
/** Revision + scheduler without any task cloning; feeds the SSE event frame. */
|
|
@@ -84,20 +116,81 @@ export declare class HostTaskLedger {
|
|
|
84
116
|
runtimeView(): LedgerRuntimeView;
|
|
85
117
|
/** Count armed, non-archived schedules without cloning task histories. */
|
|
86
118
|
armedScheduleCount(): number;
|
|
119
|
+
/**
|
|
120
|
+
* The earliest armed `nextRunAt` strictly after the supplied Host time, or
|
|
121
|
+
* undefined when no schedule is armed in the future. This is the instant the
|
|
122
|
+
* Host arms its native timer at, so the board wakes exactly when work is due
|
|
123
|
+
* instead of polling a fixed heartbeat.
|
|
124
|
+
* @param now - current Host time in ms epoch.
|
|
125
|
+
* @returns the nearest future trigger, or undefined when none is armed.
|
|
126
|
+
*/
|
|
127
|
+
nextArmedRunAt(now: number): number | undefined;
|
|
87
128
|
/** Return value-only references for schedules due at the supplied Host time. */
|
|
88
129
|
dueSchedules(now: number): DueScheduleReference[];
|
|
89
130
|
subscribe(listener: () => void): () => void;
|
|
90
131
|
dispose(): void;
|
|
91
132
|
applyRequest(requestId: string, action: TaskBoardAction, initiator?: string): {
|
|
92
133
|
state: LedgerState;
|
|
93
|
-
|
|
134
|
+
runs?: OpenedRun[];
|
|
94
135
|
};
|
|
95
|
-
|
|
136
|
+
/**
|
|
137
|
+
* Open the cascade one due schedule triggers: an empty array means nothing
|
|
138
|
+
* ran (already running, or a participant whose elevated permission is still
|
|
139
|
+
* unconfirmed), and the rule rolls to its next occurrence either way.
|
|
140
|
+
*/
|
|
141
|
+
openScheduled(taskId: string, nextRunAt: number | undefined, triggeredAt: number): OpenedRun[];
|
|
96
142
|
skipMissed(now: number): void;
|
|
97
143
|
setScheduler(patch: Partial<TaskBoardSchedulerSnapshot>): void;
|
|
144
|
+
/**
|
|
145
|
+
* Settle one execution. A cascade participant first records its OWN outcome
|
|
146
|
+
* and only finalizes once every child execution in its run group has
|
|
147
|
+
* settled, so a parent card leaves 'running' with the whole tree's verdict
|
|
148
|
+
* rather than its own turn alone.
|
|
149
|
+
*/
|
|
150
|
+
settle(taskId: string, executionId: string, outcome: ExecutionOutcome, error?: string): void;
|
|
98
151
|
attachSession(taskId: string, executionId: string, sessionId: string): void;
|
|
99
|
-
settle(taskId: string, executionId: string, outcome: 'succeeded' | 'failed' | 'cancelled', error?: string): void;
|
|
100
152
|
private apply;
|
|
153
|
+
/**
|
|
154
|
+
* The binding that makes a run illegal, if any.
|
|
155
|
+
*
|
|
156
|
+
* A plain cascade launches one session per participant, so every participant
|
|
157
|
+
* carries its own resolved binding and each one gates the run. A team run
|
|
158
|
+
* launches only the Lead session: the Lead's binding gates it, while a
|
|
159
|
+
* subtask's OWN above-default pin cannot be applied to a teammate and is
|
|
160
|
+
* refused instead of being silently dropped (an inherited binding is the
|
|
161
|
+
* Lead's own and stays allowed once the Lead is confirmed).
|
|
162
|
+
* @param root - the task being run.
|
|
163
|
+
* @returns the first refusal, or undefined when the run may start.
|
|
164
|
+
*/
|
|
165
|
+
private bindingRefusal;
|
|
166
|
+
/**
|
|
167
|
+
* The tasks a cascade from `rootId` would actually open executions for, with
|
|
168
|
+
* their effective execution targets resolved. Archived members never run, and
|
|
169
|
+
* a member that already has an open execution is skipped (a task cannot run
|
|
170
|
+
* twice), so the result is the participant set the launch will use.
|
|
171
|
+
*/
|
|
172
|
+
private cascadeParticipants;
|
|
173
|
+
/** Whether a task or any of its subtasks still has an open execution. */
|
|
174
|
+
private subtreeHasOpenExecution;
|
|
175
|
+
/**
|
|
176
|
+
* Open one execution per cascade participant (the requested task and its
|
|
177
|
+
* on-board descendants, within the depth limit) under a single run group, and
|
|
178
|
+
* commit the ledger once. The returned runs are ordered root-first, so the
|
|
179
|
+
* Host launches the parent before its subtasks.
|
|
180
|
+
* @param root - the task the user ran.
|
|
181
|
+
* @param now - clock instant (ms epoch).
|
|
182
|
+
* @param initiator - the DSH session that asked for the run (audit only).
|
|
183
|
+
* @param rerun - true to reset the root to 'todo' before starting it.
|
|
184
|
+
* @param nextRunAt - when set, the root's schedule also rolls forward.
|
|
185
|
+
*/
|
|
186
|
+
private startCascade;
|
|
187
|
+
/**
|
|
188
|
+
* Finalize every cascade parent that is ready, walking from `taskId` up the
|
|
189
|
+
* lineage: a member settles once its own outcome is recorded and none of its
|
|
190
|
+
* group children is still open, and its verdict folds those children in
|
|
191
|
+
* (failure dominates, then cancellation).
|
|
192
|
+
*/
|
|
193
|
+
private settleCascade;
|
|
101
194
|
private repairSchedules;
|
|
102
195
|
private reconcileInterruptedStarts;
|
|
103
196
|
/**
|
|
@@ -49,7 +49,29 @@ export declare class SessionLaunchError extends Error {
|
|
|
49
49
|
* first, the provenance wrap then encloses the instruction. Plain tasks (no
|
|
50
50
|
* freeze) keep the bare handover preamble + prompt.
|
|
51
51
|
*/
|
|
52
|
-
|
|
52
|
+
/** One other execution member of a run, as named in the launched task's prompt. */
|
|
53
|
+
export interface PromptPeer {
|
|
54
|
+
/** Task id of the member. */
|
|
55
|
+
id: string;
|
|
56
|
+
/** Member title. */
|
|
57
|
+
title: string;
|
|
58
|
+
/** Teammate name when this member runs as a teammate. */
|
|
59
|
+
name?: string;
|
|
60
|
+
}
|
|
61
|
+
/** Execution-shape context appended to the launched task's prompt. */
|
|
62
|
+
export interface PromptContext {
|
|
63
|
+
/** The other members this run opens, excluding the launched task itself. */
|
|
64
|
+
peers?: readonly PromptPeer[];
|
|
65
|
+
/** True when those members run as teammates inside this session (Team Lead). */
|
|
66
|
+
team?: boolean;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Build the execution prompt for one task.
|
|
70
|
+
* @param task - the task being launched.
|
|
71
|
+
* @param context - the run's other members, for the execution-shape section.
|
|
72
|
+
* @returns the prompt text.
|
|
73
|
+
*/
|
|
74
|
+
export declare function promptText(task: TaskRecord, context?: PromptContext): string;
|
|
53
75
|
export declare class HostExecutionRunner {
|
|
54
76
|
private readonly gateway;
|
|
55
77
|
private readonly commands?;
|
|
@@ -77,7 +99,23 @@ export declare class HostExecutionRunner {
|
|
|
77
99
|
*/
|
|
78
100
|
launch(task: TaskRecord, options?: {
|
|
79
101
|
reuseSessionId?: string;
|
|
102
|
+
promptContext?: PromptContext;
|
|
80
103
|
}): Promise<string>;
|
|
104
|
+
/**
|
|
105
|
+
* Fail closed when a reused session records a different Agent preset than
|
|
106
|
+
* the one this task pins.
|
|
107
|
+
*
|
|
108
|
+
* The fresh branch asserts the pin by passing `agentPreset` to
|
|
109
|
+
* `session/create`; the reuse branch must not call that method (it would
|
|
110
|
+
* create or re-adopt the very session the board only meant to continue), so
|
|
111
|
+
* the recorded value is read through `session/projections` — the documented
|
|
112
|
+
* read that resolves no Agent — and compared here (issue #1708). A session
|
|
113
|
+
* whose preset cannot be read is not treated as a match: silently continuing
|
|
114
|
+
* under an unknown composition is the failure this guards.
|
|
115
|
+
* @param sessionId - the session this execution continues in.
|
|
116
|
+
* @param pinned - the preset id the task pins, when it pins one.
|
|
117
|
+
*/
|
|
118
|
+
private assertReusedPreset;
|
|
81
119
|
/**
|
|
82
120
|
* Re-assert the pinned execution contract on a session and queue the task
|
|
83
121
|
* prompt. Shared by the fresh-session and reuse paths so both apply exactly
|
|
@@ -4,16 +4,57 @@ import { HostExecutionRunner, type SessionCommandDispatcher, type TaskBoardWorks
|
|
|
4
4
|
import { PowerInhibitor } from './power-inhibitor.ts';
|
|
5
5
|
import { type TaskBoardAction, type TaskBoardEventPayload, type TaskBoardSnapshot } from './protocol.ts';
|
|
6
6
|
import type { TaskPermission } from './core/handover.ts';
|
|
7
|
+
/** One teammate the Host asks the Agent Teams service to spawn for a team run. */
|
|
8
|
+
export interface TeamSpawnInput {
|
|
9
|
+
/** Session id of the run's Team Lead (the root task's execution session). */
|
|
10
|
+
leadSessionId: string;
|
|
11
|
+
/** Immutable lower-kebab-case teammate name, unique inside the Team. */
|
|
12
|
+
name: string;
|
|
13
|
+
/** Short description of the delegated responsibility. */
|
|
14
|
+
description: string;
|
|
15
|
+
/** The subtask's execution prompt. */
|
|
16
|
+
prompt: string;
|
|
17
|
+
}
|
|
18
|
+
/** Result of one teammate spawn attempt. */
|
|
19
|
+
export interface TeamSpawnResult {
|
|
20
|
+
/** The teammate's session id when it reached the active edge. */
|
|
21
|
+
sessionId?: string;
|
|
22
|
+
/** Why the spawn failed: a thrown call, or a member that settled as failed. */
|
|
23
|
+
error?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The Agent Teams capability the Host needs for team-mode runs. The plugin
|
|
27
|
+
* builds it from the optional `agentTeams` service; it is absent when this
|
|
28
|
+
* deployment does not serve that service, in which case a team run is refused
|
|
29
|
+
* instead of silently degrading into a plain cascade.
|
|
30
|
+
*/
|
|
31
|
+
export interface TaskBoardTeamDispatcher {
|
|
32
|
+
spawn(input: TeamSpawnInput): Promise<TeamSpawnResult>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The native timer face the Host arms through. The cordis `timer` service
|
|
36
|
+
* (dsh-base's own `cordis-plugin-timer` row) provides it: its handles are
|
|
37
|
+
* registered on the owning fiber, so unloading the board clears every armed
|
|
38
|
+
* timer without this service tracking handles by hand. A composition that
|
|
39
|
+
* serves no timer service falls back to the process globals.
|
|
40
|
+
*/
|
|
41
|
+
export interface HostTimerFace {
|
|
42
|
+
timeout(callback: () => void, delay: number): () => void;
|
|
43
|
+
interval(callback: () => void, delay: number): () => void;
|
|
44
|
+
}
|
|
7
45
|
export declare class TaskBoardHostService {
|
|
8
46
|
readonly ledger: HostTaskLedger;
|
|
9
47
|
readonly runner: HostExecutionRunner;
|
|
10
48
|
readonly power: PowerInhibitor;
|
|
11
49
|
private readonly listeners;
|
|
12
|
-
|
|
13
|
-
private
|
|
50
|
+
/** The one recurring timer: the session-roster poll. */
|
|
51
|
+
private pollTimer;
|
|
52
|
+
/** The armed schedule timer, if a trigger is pending. */
|
|
53
|
+
private scheduleTimer;
|
|
54
|
+
/** The instant the armed schedule timer targets (ms epoch), for resume detection. */
|
|
55
|
+
private scheduleTarget;
|
|
14
56
|
private disposed;
|
|
15
57
|
private pollInFlight;
|
|
16
|
-
private tickInFlight;
|
|
17
58
|
private active;
|
|
18
59
|
/**
|
|
19
60
|
* Ids the last roster poll saw as present and idle; undefined while the
|
|
@@ -23,6 +64,8 @@ export declare class TaskBoardHostService {
|
|
|
23
64
|
*/
|
|
24
65
|
private idleSessionIds;
|
|
25
66
|
private preventIdleSleep;
|
|
67
|
+
private readonly team;
|
|
68
|
+
private readonly timers;
|
|
26
69
|
private lastPowerJson;
|
|
27
70
|
private readonly now;
|
|
28
71
|
constructor(gateway: TypertGateway, options?: {
|
|
@@ -32,6 +75,9 @@ export declare class TaskBoardHostService {
|
|
|
32
75
|
commandDispatcher?: SessionCommandDispatcher;
|
|
33
76
|
workspaceRegistry?: TaskBoardWorkspaceRegistry;
|
|
34
77
|
sessionDefaultPermission?: TaskPermission;
|
|
78
|
+
maxSubtaskDepth?: number;
|
|
79
|
+
team?: TaskBoardTeamDispatcher;
|
|
80
|
+
timers?: HostTimerFace;
|
|
35
81
|
});
|
|
36
82
|
start(): void;
|
|
37
83
|
setConfiguration(active: boolean, preventIdleSleep: boolean): void;
|
|
@@ -42,14 +88,61 @@ export declare class TaskBoardHostService {
|
|
|
42
88
|
apply(requestId: string, action: TaskBoardAction, initiator?: string): TaskBoardSnapshot;
|
|
43
89
|
dispose(): void;
|
|
44
90
|
private launch;
|
|
91
|
+
private scheduleTeammate;
|
|
92
|
+
/**
|
|
93
|
+
* Spawn one teammate inside the Lead session and attach the teammate's
|
|
94
|
+
* session to the subtask execution, so the existing session monitor settles
|
|
95
|
+
* it from the teammate's own turn like any other execution. A spawn that
|
|
96
|
+
* fails settles the subtask as failed immediately, which then folds into the
|
|
97
|
+
* Lead's cascade verdict.
|
|
98
|
+
*/
|
|
99
|
+
private spawnTeammate;
|
|
45
100
|
private pollSessions;
|
|
46
101
|
/** Reuse the session list this poll already fetched: one list RPC per tick, not 1 + E. */
|
|
47
102
|
private reconcileExecutions;
|
|
48
|
-
|
|
103
|
+
/** Drop the armed schedule timer and forget its target. */
|
|
104
|
+
private clearScheduleTimer;
|
|
105
|
+
/**
|
|
106
|
+
* Boot / resume recovery: skip every occurrence that came due while the
|
|
107
|
+
* board was not running and roll each schedule to its next future target,
|
|
108
|
+
* then arm the timer for the nearest one. Rendering the occurrence is
|
|
109
|
+
* deliberately not attempted: the ACL of a card that fired hours ago is
|
|
110
|
+
* stale, and the board's own recovery contract is "missed triggers are
|
|
111
|
+
* skipped, never replayed".
|
|
112
|
+
*/
|
|
113
|
+
private recoverSchedule;
|
|
114
|
+
/**
|
|
115
|
+
* Arm the native timer at the nearest armed future trigger. One timer serves
|
|
116
|
+
* every schedule: the ledger's next target is the only instant the Host has
|
|
117
|
+
* to wake for. A target beyond the platform's timer ceiling re-arms in
|
|
118
|
+
* segments, and a target already past (the wall clock jumped, or the process
|
|
119
|
+
* was suspended) is handled immediately as a recovery.
|
|
120
|
+
*/
|
|
121
|
+
private armSchedule;
|
|
122
|
+
/**
|
|
123
|
+
* One armed target became due. A fire landing well past its target is a
|
|
124
|
+
* resume (suspend, throttle, forward clock jump) rather than a normal
|
|
125
|
+
* occurrence, so it takes the recovery path instead of launching a run for a
|
|
126
|
+
* long-stale instant.
|
|
127
|
+
*/
|
|
128
|
+
private onScheduleFire;
|
|
49
129
|
private armedSchedules;
|
|
130
|
+
/**
|
|
131
|
+
* Launch one run set. The root goes first and receives the run shape in its
|
|
132
|
+
* prompt (which members this run opens, and how they run); every plain-cascade
|
|
133
|
+
* member then launches on its own so one refused participant cannot hold the
|
|
134
|
+
* others back. A team run's members are spawned inside the root's Lead
|
|
135
|
+
* session instead, once that session exists.
|
|
136
|
+
*/
|
|
137
|
+
private dispatchRuns;
|
|
50
138
|
private scheduleLaunch;
|
|
51
139
|
private schedulePoll;
|
|
52
|
-
|
|
140
|
+
/**
|
|
141
|
+
* Re-arm from the ledger's current targets. Callers that just changed a
|
|
142
|
+
* schedule (the host routes, the agent tools) invoke this after the write
|
|
143
|
+
* commits, so a new or edited trigger arms without waiting for the next fire.
|
|
144
|
+
*/
|
|
145
|
+
refreshSchedule(): void;
|
|
53
146
|
private syncPowerReasons;
|
|
54
147
|
private emit;
|
|
55
148
|
}
|
package/lib/types/index.d.ts
CHANGED
|
@@ -7,21 +7,25 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { Context, Volatile } from '@deepseek-ai/cordis';
|
|
9
9
|
import z from '@deepseek-ai/schemastery';
|
|
10
|
+
import type { ToolDefinition } from '@deepseek-ai/dsh-tools';
|
|
10
11
|
import type { LlmRuntime } from '@deepseek-ai/dsh-llm';
|
|
12
|
+
import { type HostTimerFace, type TaskBoardTeamDispatcher } from './host-service.ts';
|
|
11
13
|
import { type TaskPermission } from './core/tasks.ts';
|
|
12
14
|
/** Default environment variable holding the authenticated proxy token. */
|
|
13
15
|
export declare const DEFAULT_PROXY_TOKEN_ENV = "DSH_TASK_BOARD_PROXY_TOKEN";
|
|
14
16
|
export declare const inject: string[];
|
|
15
17
|
/** Model-facing announcement: plugin presence, capabilities, and limits. */
|
|
16
|
-
export declare const TASK_BOARD_GUIDANCE = "\u672C\u673A\u5DF2\u5B89\u88C5 dsh-task-board \u63D2\u4EF6\uFF08DSH Web GUI \u7684\u4EFB\u52A1\u770B\u677F\uFF09\uFF1A\u4FA7\u8FB9\u680F\u300C\u4EFB\u52A1\u770B\u677F\u300D\u5165\u53E3\uFF1B\u5728 dsh-web \u63D2\u4EF6\u5168\u5BB6\u6876\u4ED3\u5E93\uFF08packages/dsh-task-board\uFF09\u7EDF\u4E00\u7EF4\u62A4\uFF0C\u7ECF\u805A\u5408\u5305 web-ui-all \u4E00\u952E\u5B89\u88C5\u3002\u80FD\u529B\uFF1A\u591A\u5217\u770B\u677F\u7BA1\u7406\u4EFB\u52A1\uFF1BHost \u6743\u5A01\u8D26\u672C\uFF1B\u5173\u95ED\u6D4F\u89C8\u5668\u540E\u4ECD\u7531 Host \u6267\u884C\u548C\u7ED3\u7B97\uFF1B\u4EFB\u52A1\u53EF\u9489\u4F4F\u5DE5\u4F5C\u533A\u3001agent \u9884\u8BBE\u548C\u6743\u9650\uFF1B\u652F\u6301 Host \u672C\u5730\u65F6\u533A\u7684 5 \u6BB5 cron\uFF0C\u9519\u8FC7\u7684\u89E6\u53D1\u70B9\u4E0D\u8865\u8DD1\uFF1B\u53EF\u9009\u4E14\u9ED8\u8BA4\u5173\u95ED\u7684\u7A7A\u95F2\u7CFB\u7EDF\u7761\u7720\u4FDD\u62A4\u5141\u8BB8\u5C4F\u5E55\u7184\u706D\uFF0C\u4F46\u4E0D\u627F\u8BFA\u62E6\u622A\u5408\u76D6\u3001\u624B\u52A8\u7761\u7720\u3001\u4F11\u7720\u3001\u5173\u673A\u6216\u5524\u9192\u5DF2\u7761\u7720\u673A\u5668\u3002\u6267\u884C\u6D88\u8017 API \u989D\u5EA6\u3002\u7528\u6237\u63D0\u5230\u300C\u4EFB\u52A1\u770B\u677F / \u770B\u677F / \u5B9A\u65F6\u4EFB\u52A1\u300D\u65F6\u5373\u6307\u672C\u63D2\u4EF6\uFF0C\u8BF7\u636E\u6B64\u534F\u4F5C\u3002\u82E5\u4F60\u540C\u65F6\u7528 todo_write \u7EF4\u62A4\u4F1A\u8BDD\u9876\u90E8\u7684\u53EF\u89C1\u8BA1\u5212\u5217\u8868\uFF0C\u6700\u7EC8\u56DE\u590D\u524D\u5FC5\u987B\u518D\u6B21\u8C03\u7528 todo_write \u6536\u5C3E\uFF1A\u6CA1\u6709\u5269\u4F59\u5DE5\u4F5C\u65F6\u4E0D\u8981\u4FDD\u7559 in_progress\uFF0C\u5DF2\u5B8C\u6210\u7684\u6700\u540E\u4E00\u6B65\u8981\u6807\u4E3A completed\u3002";
|
|
18
|
+
export declare const TASK_BOARD_GUIDANCE = "\u672C\u673A\u5DF2\u5B89\u88C5 dsh-task-board \u63D2\u4EF6\uFF08DSH Web GUI \u7684\u4EFB\u52A1\u770B\u677F\uFF09\uFF1A\u4FA7\u8FB9\u680F\u300C\u4EFB\u52A1\u770B\u677F\u300D\u5165\u53E3\uFF1B\u5728 dsh-web \u63D2\u4EF6\u5168\u5BB6\u6876\u4ED3\u5E93\uFF08packages/dsh-task-board\uFF09\u7EDF\u4E00\u7EF4\u62A4\uFF0C\u7ECF\u805A\u5408\u5305 web-ui-all \u4E00\u952E\u5B89\u88C5\u3002\u80FD\u529B\uFF1A\u591A\u5217\u770B\u677F\u7BA1\u7406\u4EFB\u52A1\uFF1BHost \u6743\u5A01\u8D26\u672C\uFF1B\u5173\u95ED\u6D4F\u89C8\u5668\u540E\u4ECD\u7531 Host \u6267\u884C\u548C\u7ED3\u7B97\uFF1B\u4EFB\u52A1\u53EF\u9489\u4F4F\u5DE5\u4F5C\u533A\u3001agent \u9884\u8BBE\u548C\u6743\u9650\uFF1B\u4EFB\u52A1\u53EF\u5EFA\u5B50\u4EFB\u52A1\uFF08\u6DF1\u5EA6\u4E0A\u9650\u53EF\u914D 1..3\uFF0C\u9ED8\u8BA4 1 \u5C42\uFF0C\u5B50\u4EFB\u52A1\u4E0D\u80FD\u518D\u5E26\u5B50\u4EFB\u52A1\uFF09\uFF0C\u6267\u884C\u7236\u4EFB\u52A1\u4F1A\u5E76\u53D1\u6267\u884C\u5176\u5B50\u4EFB\u52A1\u6811\uFF0C\u5B50\u4EFB\u52A1\u53EF\u5355\u72EC\u8986\u76D6\u6743\u9650\u4E0E\u6A21\u578B\uFF1B\u53E6\u6CE8\u518C task_board_* agent \u5DE5\u5177\uFF08list/get/create/update/set_parent/run/manage/schedule\uFF09\uFF0C\u4EFB\u4F55\u4F1A\u8BDD\u90FD\u53EF\u76F4\u63A5\u8BFB\u5199\u770B\u677F\u3001\u5B50\u4EFB\u52A1\u4E0E\u5B9A\u65F6\u8BA1\u5212\uFF0C\u4F46\u8FD0\u884C\u4EFB\u52A1\u4F1A\u771F\u5B9E\u6267\u884C\u5E76\u6D88\u8017\u989D\u5EA6\uFF0C\u9AD8\u4E8E\u4F1A\u8BDD\u9ED8\u8BA4\u6743\u9650\u7684\u7ED1\u5B9A\u4ECD\u5FC5\u987B\u7531\u7528\u6237\u5728 GUI \u4EBA\u5DE5\u786E\u8BA4\uFF08\u5DE5\u5177\u523B\u610F\u4E0D\u63D0\u4F9B\u786E\u8BA4\u80FD\u529B\uFF09\uFF1B\u652F\u6301 Host \u672C\u5730\u65F6\u533A\u7684 5 \u6BB5 cron\uFF0C\u9519\u8FC7\u7684\u89E6\u53D1\u70B9\u4E0D\u8865\u8DD1\uFF1B\u53EF\u9009\u4E14\u9ED8\u8BA4\u5173\u95ED\u7684\u7A7A\u95F2\u7CFB\u7EDF\u7761\u7720\u4FDD\u62A4\u5141\u8BB8\u5C4F\u5E55\u7184\u706D\uFF0C\u4F46\u4E0D\u627F\u8BFA\u62E6\u622A\u5408\u76D6\u3001\u624B\u52A8\u7761\u7720\u3001\u4F11\u7720\u3001\u5173\u673A\u6216\u5524\u9192\u5DF2\u7761\u7720\u673A\u5668\u3002\u6267\u884C\u6D88\u8017 API \u989D\u5EA6\u3002\u7528\u6237\u63D0\u5230\u300C\u4EFB\u52A1\u770B\u677F / \u770B\u677F / \u5B9A\u65F6\u4EFB\u52A1\u300D\u65F6\u5373\u6307\u672C\u63D2\u4EF6\uFF0C\u8BF7\u636E\u6B64\u534F\u4F5C\u3002\u82E5\u4F60\u540C\u65F6\u7528 todo_write \u7EF4\u62A4\u4F1A\u8BDD\u9876\u90E8\u7684\u53EF\u89C1\u8BA1\u5212\u5217\u8868\uFF0C\u6700\u7EC8\u56DE\u590D\u524D\u5FC5\u987B\u518D\u6B21\u8C03\u7528 todo_write \u6536\u5C3E\uFF1A\u6CA1\u6709\u5269\u4F59\u5DE5\u4F5C\u65F6\u4E0D\u8981\u4FDD\u7559 in_progress\uFF0C\u5DF2\u5B8C\u6210\u7684\u6700\u540E\u4E00\u6B65\u8981\u6807\u4E3A completed\u3002";
|
|
17
19
|
/**
|
|
18
20
|
* Plugin config, validated by the same-named schemastery schema.
|
|
19
21
|
*
|
|
20
22
|
* This schema IS the board's settings page: the 0.1.7 Host serves one
|
|
21
23
|
* configuration form per profile entry from the entry's own Config, so the
|
|
22
|
-
*
|
|
24
|
+
* fields the browser card edits are marked volatile — the Loader commits
|
|
23
25
|
* an edit into the running fiber's references without remounting the row (no
|
|
24
|
-
* settings document of the plugin's own exists any more).
|
|
26
|
+
* settings document of the plugin's own exists any more). A field without the
|
|
27
|
+
* marker is refused by the settings write path, which fences writes on
|
|
28
|
+
* volatility.
|
|
25
29
|
*/
|
|
26
30
|
export interface Config {
|
|
27
31
|
/**
|
|
@@ -48,7 +52,25 @@ export interface Config {
|
|
|
48
52
|
* confirmation before it may run; cron refuses unconfirmed cards.
|
|
49
53
|
*/
|
|
50
54
|
sessionDefaultPermission?: TaskPermission;
|
|
55
|
+
/**
|
|
56
|
+
* Subtask depth limit, 1..3 (default 1). At 1 a task may carry one level of
|
|
57
|
+
* subtasks and a subtask cannot be given subtasks of its own; raising it
|
|
58
|
+
* allows deeper trees. Every extra level multiplies the sessions one run
|
|
59
|
+
* of the root task opens, so the ceiling is deliberately small.
|
|
60
|
+
*/
|
|
61
|
+
maxSubtaskDepth?: Volatile<number>;
|
|
62
|
+
/**
|
|
63
|
+
* Continuable-subagent provider the Agent Teams service uses to compose a
|
|
64
|
+
* teammate. Matches the Agent Teams tool plugin's `freshProvider` default;
|
|
65
|
+
* only team-mode runs use it.
|
|
66
|
+
*/
|
|
67
|
+
teamProvider?: string;
|
|
51
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Continuable-subagent provider for fresh teammates, matching the Agent Teams
|
|
71
|
+
* tool plugin's own `freshProvider` default.
|
|
72
|
+
*/
|
|
73
|
+
export declare const DEFAULT_TEAM_PROVIDER = "spawn";
|
|
52
74
|
/**
|
|
53
75
|
* The schema is left to inference rather than annotated with `z<Config>`: a
|
|
54
76
|
* volatile field's parsed output is a `Volatile` reference while its accepted
|
|
@@ -62,6 +84,8 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
62
84
|
trustedProxyHosts: z<string[], string[], "defined">;
|
|
63
85
|
proxyTokenEnv: z<string, string, "defined">;
|
|
64
86
|
sessionDefaultPermission: z<"read-only" | "workspace-write" | "danger-full-access", "read-only" | "workspace-write" | "danger-full-access", "defined">;
|
|
87
|
+
maxSubtaskDepth: z<number, number, "volatile-defined">;
|
|
88
|
+
teamProvider: z<string, string, "defined">;
|
|
65
89
|
}>>, Schemastery.ObjectT<NoInfer<{
|
|
66
90
|
announceToAgent: z<boolean, boolean, "volatile-defined">;
|
|
67
91
|
enabled: z<boolean, boolean, "volatile-defined">;
|
|
@@ -69,6 +93,8 @@ export declare const Config: z<Schemastery.ObjectS<NoInfer<{
|
|
|
69
93
|
trustedProxyHosts: z<string[], string[], "defined">;
|
|
70
94
|
proxyTokenEnv: z<string, string, "defined">;
|
|
71
95
|
sessionDefaultPermission: z<"read-only" | "workspace-write" | "danger-full-access", "read-only" | "workspace-write" | "danger-full-access", "defined">;
|
|
96
|
+
maxSubtaskDepth: z<number, number, "volatile-defined">;
|
|
97
|
+
teamProvider: z<string, string, "defined">;
|
|
72
98
|
}>>, "plain">;
|
|
73
99
|
declare module '@deepseek-ai/cordis' {
|
|
74
100
|
interface Events {
|
|
@@ -100,6 +126,68 @@ export declare function resolveProxyAccess(config: Config | undefined, env?: Nod
|
|
|
100
126
|
trustedProxyHosts: string[];
|
|
101
127
|
proxyToken?: string;
|
|
102
128
|
};
|
|
129
|
+
/** The registry face the agent tools register into. */
|
|
130
|
+
interface AgentToolRegistry {
|
|
131
|
+
register(definition: ToolDefinition): () => void;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Resolve the optional agent-tool registry. The board deliberately does not
|
|
135
|
+
* inject it: a deployment whose runtime serves no registry must still mount the
|
|
136
|
+
* whole board and lose only the agent-tool surface, the same tolerance the
|
|
137
|
+
* optional llm service gets.
|
|
138
|
+
* @param ctx - the plugin context.
|
|
139
|
+
* @returns the registry, or undefined when this deployment serves none.
|
|
140
|
+
*/
|
|
141
|
+
export declare function resolveToolRegistry(ctx: Context): AgentToolRegistry | undefined;
|
|
142
|
+
/**
|
|
143
|
+
* Resolve the native cordis timer service (dsh-base's own `cordis-plugin-timer`
|
|
144
|
+
* row). The board arms its schedule through it so unloading the row clears
|
|
145
|
+
* every pending timer with the owning fiber, instead of the row tracking raw
|
|
146
|
+
* process handles by hand. A composition that serves no timer service keeps
|
|
147
|
+
* working on the process globals.
|
|
148
|
+
* @param ctx - the plugin context.
|
|
149
|
+
* @returns the timer face, or undefined when this deployment serves none.
|
|
150
|
+
*/
|
|
151
|
+
export declare function resolveHostTimers(ctx: Context): HostTimerFace | undefined;
|
|
152
|
+
/** The subset of the Agent Teams service this plugin drives. */
|
|
153
|
+
interface AgentTeamsFace {
|
|
154
|
+
spawnTeammate(caller: unknown, request: {
|
|
155
|
+
name: string;
|
|
156
|
+
description: string;
|
|
157
|
+
prompt: Array<{
|
|
158
|
+
type: 'text';
|
|
159
|
+
text: string;
|
|
160
|
+
}>;
|
|
161
|
+
context: 'fresh' | 'fork';
|
|
162
|
+
provider: string;
|
|
163
|
+
signal: AbortSignal;
|
|
164
|
+
}): Promise<{
|
|
165
|
+
member?: {
|
|
166
|
+
id?: string;
|
|
167
|
+
phase?: string;
|
|
168
|
+
error?: string;
|
|
169
|
+
};
|
|
170
|
+
}>;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Resolve the optional Agent Teams service. Like the tool registry and the llm
|
|
174
|
+
* runtime, it is deliberately not injected: a deployment without Agent Teams
|
|
175
|
+
* must still mount the whole board and only lose team-mode runs.
|
|
176
|
+
* @param ctx - the plugin context.
|
|
177
|
+
* @returns the service, or undefined when this deployment serves none.
|
|
178
|
+
*/
|
|
179
|
+
export declare function resolveAgentTeams(ctx: Context): AgentTeamsFace | undefined;
|
|
180
|
+
/**
|
|
181
|
+
* Build the team dispatcher: the run's Lead session spawns one teammate per
|
|
182
|
+
* subtask through the Agent Teams service, and the teammate's session id is
|
|
183
|
+
* attached to that subtask's execution so the ordinary session monitor settles
|
|
184
|
+
* it. Returns undefined when the deployment serves no Agent Teams service or
|
|
185
|
+
* no live-agent registry, which makes a team run fail closed.
|
|
186
|
+
* @param ctx - the plugin context.
|
|
187
|
+
* @param provider - the continuable-subagent provider for fresh teammates.
|
|
188
|
+
* @returns the dispatcher, or undefined when team runs cannot be served.
|
|
189
|
+
*/
|
|
190
|
+
export declare function buildTeamDispatcher(ctx: Context, provider: string): TaskBoardTeamDispatcher | undefined;
|
|
103
191
|
/**
|
|
104
192
|
* Read the optional `llm` service. The board deliberately does not inject it:
|
|
105
193
|
* a deployment without a model must still mount the board, and the parse route
|
|
@@ -112,8 +200,8 @@ export declare function resolveLlmRuntime(ctx: Context): LlmRuntime | undefined;
|
|
|
112
200
|
* Activate the board's host half: ledger, routes, cron scheduler, power
|
|
113
201
|
* inhibitor, and the model-facing announcement.
|
|
114
202
|
*
|
|
115
|
-
* The effective settings are the config the Host hands this row. The
|
|
116
|
-
*
|
|
203
|
+
* The effective settings are the config the Host hands this row. The fields
|
|
204
|
+
* the browser card edits are schema-volatile, so the Loader commits an
|
|
117
205
|
* edit into the running fiber's references instead of remounting the row —
|
|
118
206
|
* `sync` therefore reads them at use time and follows
|
|
119
207
|
* `loader/volatile-update`, the event the Loader emits once it has committed
|