@tt-a1i/hive 1.4.4 → 1.6.0
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/CHANGELOG.md +47 -0
- package/README.en.md +21 -0
- package/README.md +16 -0
- package/assets/qq-group.jpg +0 -0
- package/dist/bin/team.cmd +1 -0
- package/dist/src/cli/hive-update.d.ts +45 -17
- package/dist/src/cli/hive-update.js +63 -25
- package/dist/src/cli/hive.d.ts +25 -0
- package/dist/src/cli/hive.js +41 -3
- package/dist/src/cli/team.d.ts +1 -0
- package/dist/src/cli/team.js +216 -3
- package/dist/src/server/agent-command-resolver.js +3 -19
- package/dist/src/server/agent-manager-support.d.ts +2 -2
- package/dist/src/server/agent-manager-support.js +98 -24
- package/dist/src/server/agent-run-starter.d.ts +6 -1
- package/dist/src/server/agent-run-starter.js +9 -2
- package/dist/src/server/agent-run-store.d.ts +1 -1
- package/dist/src/server/agent-runtime-close.d.ts +1 -0
- package/dist/src/server/agent-runtime-close.js +25 -1
- package/dist/src/server/agent-runtime-contract.d.ts +12 -1
- package/dist/src/server/agent-runtime-stop-run.d.ts +1 -1
- package/dist/src/server/agent-runtime-stop-run.js +4 -1
- package/dist/src/server/agent-runtime.d.ts +2 -1
- package/dist/src/server/agent-runtime.js +14 -3
- package/dist/src/server/agent-startup-instructions.d.ts +7 -1
- package/dist/src/server/agent-startup-instructions.js +17 -9
- package/dist/src/server/agent-stdin-dispatcher.d.ts +25 -5
- package/dist/src/server/agent-stdin-dispatcher.js +141 -40
- package/dist/src/server/cron-util.d.ts +7 -0
- package/dist/src/server/cron-util.js +19 -0
- package/dist/src/server/dispatch-ledger-store.d.ts +22 -0
- package/dist/src/server/dispatch-ledger-store.js +51 -3
- package/dist/src/server/env-sync-message.js +9 -9
- package/dist/src/server/feature-flags.d.ts +42 -0
- package/dist/src/server/feature-flags.js +24 -0
- package/dist/src/server/fs-pick-folder.js +4 -0
- package/dist/src/server/fs-sandbox.js +36 -7
- package/dist/src/server/hive-team-guidance.d.ts +12 -6
- package/dist/src/server/hive-team-guidance.js +253 -71
- package/dist/src/server/live-run-registry.d.ts +1 -0
- package/dist/src/server/live-run-registry.js +1 -1
- package/dist/src/server/open-target-commands.js +5 -6
- package/dist/src/server/orchestrator-autostart.d.ts +12 -0
- package/dist/src/server/orchestrator-autostart.js +15 -13
- package/dist/src/server/path-canonicalization.d.ts +3 -0
- package/dist/src/server/path-canonicalization.js +29 -0
- package/dist/src/server/platform-path.d.ts +3 -0
- package/dist/src/server/platform-path.js +13 -0
- package/dist/src/server/post-start-input-writer.d.ts +1 -1
- package/dist/src/server/post-start-input-writer.js +110 -13
- package/dist/src/server/preset-launch-support.d.ts +1 -1
- package/dist/src/server/preset-launch-support.js +33 -2
- package/dist/src/server/recovery-summary.d.ts +5 -1
- package/dist/src/server/recovery-summary.js +18 -17
- package/dist/src/server/report-outbox-store.d.ts +36 -0
- package/dist/src/server/report-outbox-store.js +33 -0
- package/dist/src/server/restart-policy-support.d.ts +5 -1
- package/dist/src/server/restart-policy-support.js +9 -1
- package/dist/src/server/restart-policy.d.ts +6 -2
- package/dist/src/server/restart-policy.js +51 -31
- package/dist/src/server/role-template-store.d.ts +1 -0
- package/dist/src/server/role-template-store.js +11 -1
- package/dist/src/server/route-types.d.ts +43 -0
- package/dist/src/server/routes-runtime.js +2 -1
- package/dist/src/server/routes-settings.js +76 -0
- package/dist/src/server/routes-tasks.js +23 -0
- package/dist/src/server/routes-team.js +211 -1
- package/dist/src/server/routes-workflow-schedules.d.ts +2 -0
- package/dist/src/server/routes-workflow-schedules.js +58 -0
- package/dist/src/server/routes-workflows.d.ts +2 -0
- package/dist/src/server/routes-workflows.js +83 -0
- package/dist/src/server/routes-workspaces.js +5 -0
- package/dist/src/server/routes.js +4 -0
- package/dist/src/server/runtime-restart-policy.d.ts +3 -1
- package/dist/src/server/runtime-restart-policy.js +2 -1
- package/dist/src/server/runtime-store-contract.d.ts +125 -0
- package/dist/src/server/runtime-store-contract.js +1 -0
- package/dist/src/server/runtime-store-helpers.d.ts +11 -0
- package/dist/src/server/runtime-store-helpers.js +106 -2
- package/dist/src/server/runtime-store-workflows.d.ts +6 -0
- package/dist/src/server/runtime-store-workflows.js +108 -0
- package/dist/src/server/runtime-store.d.ts +3 -72
- package/dist/src/server/runtime-store.js +71 -4
- package/dist/src/server/session-capture-codex.d.ts +3 -3
- package/dist/src/server/session-capture-codex.js +9 -7
- package/dist/src/server/session-capture-gemini.d.ts +1 -1
- package/dist/src/server/session-capture-gemini.js +6 -3
- package/dist/src/server/settings-store.d.ts +3 -0
- package/dist/src/server/settings-store.js +1 -0
- package/dist/src/server/sqlite-schema-v19.d.ts +2 -0
- package/dist/src/server/sqlite-schema-v19.js +17 -0
- package/dist/src/server/sqlite-schema-v20.d.ts +2 -0
- package/dist/src/server/sqlite-schema-v20.js +20 -0
- package/dist/src/server/sqlite-schema-v21.d.ts +2 -0
- package/dist/src/server/sqlite-schema-v21.js +20 -0
- package/dist/src/server/sqlite-schema.d.ts +1 -1
- package/dist/src/server/sqlite-schema.js +110 -1
- package/dist/src/server/system-message.d.ts +7 -0
- package/dist/src/server/system-message.js +8 -1
- package/dist/src/server/task-deps.d.ts +32 -0
- package/dist/src/server/task-deps.js +40 -0
- package/dist/src/server/tasks-file-watcher.d.ts +12 -1
- package/dist/src/server/tasks-file-watcher.js +128 -23
- package/dist/src/server/tasks-file.d.ts +3 -1
- package/dist/src/server/tasks-file.js +33 -9
- package/dist/src/server/tasks-websocket-server.js +13 -14
- package/dist/src/server/team-authz.d.ts +1 -1
- package/dist/src/server/team-authz.js +10 -1
- package/dist/src/server/team-autostaff.d.ts +16 -0
- package/dist/src/server/team-autostaff.js +16 -0
- package/dist/src/server/team-list-serializer.d.ts +1 -1
- package/dist/src/server/team-list-serializer.js +3 -1
- package/dist/src/server/team-operations.d.ts +21 -1
- package/dist/src/server/team-operations.js +183 -16
- package/dist/src/server/terminal-protocol.js +9 -3
- package/dist/src/server/terminal-stream-hub.js +16 -10
- package/dist/src/server/terminal-ws-server.js +10 -8
- package/dist/src/server/webhook-notifier.d.ts +34 -0
- package/dist/src/server/webhook-notifier.js +47 -0
- package/dist/src/server/websocket-upgrade-safety.d.ts +10 -0
- package/dist/src/server/websocket-upgrade-safety.js +35 -0
- package/dist/src/server/windows-command-line.d.ts +3 -0
- package/dist/src/server/windows-command-line.js +9 -0
- package/dist/src/server/windows-filename.d.ts +2 -0
- package/dist/src/server/windows-filename.js +33 -0
- package/dist/src/server/workflow-cli-policy.d.ts +60 -0
- package/dist/src/server/workflow-cli-policy.js +110 -0
- package/dist/src/server/workflow-dispatch-awaiter.d.ts +12 -0
- package/dist/src/server/workflow-dispatch-awaiter.js +80 -0
- package/dist/src/server/workflow-feature.d.ts +15 -0
- package/dist/src/server/workflow-feature.js +15 -0
- package/dist/src/server/workflow-http-serializers.d.ts +64 -0
- package/dist/src/server/workflow-http-serializers.js +58 -0
- package/dist/src/server/workflow-output-schema.d.ts +18 -0
- package/dist/src/server/workflow-output-schema.js +41 -0
- package/dist/src/server/workflow-run-log-store.d.ts +19 -0
- package/dist/src/server/workflow-run-log-store.js +45 -0
- package/dist/src/server/workflow-run-store.d.ts +50 -0
- package/dist/src/server/workflow-run-store.js +103 -0
- package/dist/src/server/workflow-runner.d.ts +147 -0
- package/dist/src/server/workflow-runner.js +411 -0
- package/dist/src/server/workflow-schedule-create.d.ts +14 -0
- package/dist/src/server/workflow-schedule-create.js +41 -0
- package/dist/src/server/workflow-schedule-store.d.ts +43 -0
- package/dist/src/server/workflow-schedule-store.js +112 -0
- package/dist/src/server/workflow-scheduler.d.ts +36 -0
- package/dist/src/server/workflow-scheduler.js +97 -0
- package/dist/src/server/workflow-script-loader.d.ts +34 -0
- package/dist/src/server/workflow-script-loader.js +106 -0
- package/dist/src/server/workspace-path-validation.js +16 -4
- package/dist/src/server/workspace-shell-runtime.d.ts +5 -0
- package/dist/src/server/workspace-shell-runtime.js +24 -2
- package/dist/src/server/workspace-store-contract.d.ts +4 -1
- package/dist/src/server/workspace-store-hydration.js +23 -7
- package/dist/src/server/workspace-store-mutations.js +2 -5
- package/dist/src/server/workspace-store-support.d.ts +4 -0
- package/dist/src/server/workspace-store-support.js +13 -1
- package/dist/src/server/workspace-store.js +38 -4
- package/dist/src/shared/types.d.ts +16 -1
- package/package.json +4 -2
- package/web/dist/assets/{AddWorkerDialog-DeZhTQLi.js → AddWorkerDialog-CGbaxu0T.js} +2 -2
- package/web/dist/assets/AddWorkspaceDialog-CNgExu6b.js +1 -0
- package/web/dist/assets/{FirstRunWizard-B5wLcat5.js → FirstRunWizard-DxGApUNc.js} +1 -1
- package/web/dist/assets/{MarketplaceDrawer-BC0eBOEW.js → MarketplaceDrawer-Bk6cpukn.js} +1 -1
- package/web/dist/assets/WhatsNewDialog-CSGzk-2U.js +1 -0
- package/web/dist/assets/WorkerModal-i2F3n3nZ.js +1 -0
- package/web/dist/assets/WorkspaceTaskDrawer-C_Ta_K13.js +1 -0
- package/web/dist/assets/WorkspaceTerminalPanels-VdDxtrQF.js +1 -0
- package/web/dist/assets/index-5zh61jMg.css +1 -0
- package/web/dist/assets/index-CAgGM6nb.js +75 -0
- package/web/dist/assets/path-join-7MR1s7b1.js +1 -0
- package/web/dist/index.html +2 -2
- package/web/dist/sw.js +1 -1
- package/web/dist/assets/AddWorkspaceDialog-DDpXNEKf.js +0 -1
- package/web/dist/assets/WorkerModal-BwMHq-Bi.js +0 -1
- package/web/dist/assets/WorkspaceTaskDrawer-CxvT4nqs.js +0 -1
- package/web/dist/assets/WorkspaceTerminalPanels-CvibsPSd.js +0 -1
- package/web/dist/assets/index-BEsTmfrO.css +0 -1
- package/web/dist/assets/index-Ddb7bDN5.js +0 -75
- package/web/dist/assets/path-join-S7qkXQtP.js +0 -1
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import type { AgentSummary, TeamListItem, WorkspaceSummary } from '../shared/types.js';
|
|
2
|
+
import type { AgentManager } from './agent-manager.js';
|
|
3
|
+
import type { AgentLaunchConfigInput, PersistedAgentRun } from './agent-run-store.js';
|
|
4
|
+
import type { LiveAgentRun } from './agent-runtime-types.js';
|
|
5
|
+
import type { DispatchRecord, ListDispatchesOptions } from './dispatch-ledger-store.js';
|
|
6
|
+
import type { RecoveryMessage } from './message-log-store.js';
|
|
7
|
+
import type { PtyOutputBus } from './pty-output-bus.js';
|
|
8
|
+
import type { SettingsStore } from './settings-store.js';
|
|
9
|
+
import type { CancelTaskInput, DispatchTaskInput, ReportTaskInput, ReportTaskResult, StatusTaskInput } from './team-operations.js';
|
|
10
|
+
import type { TerminalRunSummary } from './terminal-input-profile.js';
|
|
11
|
+
import type { WorkflowDispatchAwaiter } from './workflow-dispatch-awaiter.js';
|
|
12
|
+
import type { WorkflowRunRecord } from './workflow-run-store.js';
|
|
13
|
+
import type { RunInlineWorkflowInput, RunWorkflowInput, WorkflowRunner } from './workflow-runner.js';
|
|
14
|
+
import type { WorkflowScheduleRecord } from './workflow-schedule-store.js';
|
|
15
|
+
import type { WorkerInput, WorkspaceRecord } from './workspace-store.js';
|
|
16
|
+
export interface RuntimeStore {
|
|
17
|
+
close: () => Promise<void>;
|
|
18
|
+
createWorkspace: (path: string, name: string) => WorkspaceSummary;
|
|
19
|
+
deleteWorkspace: (workspaceId: string) => Promise<void>;
|
|
20
|
+
listWorkspaces: () => WorkspaceSummary[];
|
|
21
|
+
addWorker: (workspaceId: string, input: WorkerInput) => AgentSummary;
|
|
22
|
+
addWorkerWithLaunch: (workspaceId: string, input: WorkerInput, launchConfig: AgentLaunchConfigInput) => AgentSummary;
|
|
23
|
+
deleteWorker: (workspaceId: string, workerId: string) => void;
|
|
24
|
+
renameWorker: (workspaceId: string, workerId: string, name: string) => AgentSummary;
|
|
25
|
+
recordUserInput: (workspaceId: string, orchestratorId: string, text: string) => void;
|
|
26
|
+
dispatchTask: (workspaceId: string, workerId: string, text: string, input?: DispatchTaskInput) => Promise<DispatchRecord>;
|
|
27
|
+
dispatchTaskByWorkerName: (workspaceId: string, workerName: string, text: string, input?: DispatchTaskInput) => Promise<DispatchRecord & {
|
|
28
|
+
restartedWorker: boolean;
|
|
29
|
+
}>;
|
|
30
|
+
reportTask: (workspaceId: string, workerId: string, input?: ReportTaskInput) => ReportTaskResult;
|
|
31
|
+
/** Flush any reports stranded by a prior orchestrator outage. Safe no-op
|
|
32
|
+
* when the orchestrator is down or the outbox is empty. */
|
|
33
|
+
drainReportOutbox: (workspaceId: string) => void;
|
|
34
|
+
statusTask: (workspaceId: string, workerId: string, input?: StatusTaskInput) => ReportTaskResult;
|
|
35
|
+
cancelTask: (workspaceId: string, dispatchId: string, input: CancelTaskInput) => ReportTaskResult;
|
|
36
|
+
listDispatches: (workspaceId: string, options?: ListDispatchesOptions) => DispatchRecord[];
|
|
37
|
+
listWorkers: (workspaceId: string) => TeamListItem[];
|
|
38
|
+
getLastPtyLineForAgent: (workspaceId: string, agentId: string) => string | null;
|
|
39
|
+
getWorkspaceSnapshot: (workspaceId: string) => WorkspaceRecord;
|
|
40
|
+
getWorker: (workspaceId: string, workerId: string) => AgentSummary;
|
|
41
|
+
getAgent: (workspaceId: string, agentId: string) => AgentSummary;
|
|
42
|
+
getPtyOutputBus: () => PtyOutputBus;
|
|
43
|
+
listTerminalRuns: (workspaceId: string) => TerminalRunSummary[];
|
|
44
|
+
closeWorkspaceShell: (workspaceId: string, runId: string) => boolean;
|
|
45
|
+
startWorkspaceShell: (workspaceId: string) => Promise<LiveAgentRun>;
|
|
46
|
+
configureAgentLaunch: (workspaceId: string, agentId: string, input: AgentLaunchConfigInput) => void;
|
|
47
|
+
peekAgentLaunchConfig: (workspaceId: string, agentId: string) => AgentLaunchConfigInput | undefined;
|
|
48
|
+
startAgent: (workspaceId: string, agentId: string, input: StartAgentOptions) => Promise<LiveAgentRun>;
|
|
49
|
+
autostartConfiguredAgents: (input: StartAgentOptions) => Promise<Array<{
|
|
50
|
+
agent_id: string;
|
|
51
|
+
error: string | null;
|
|
52
|
+
ok: boolean;
|
|
53
|
+
run_id: string | null;
|
|
54
|
+
workspace_id: string;
|
|
55
|
+
}>>;
|
|
56
|
+
startWorkspaceWatch: (workspaceId: string) => Promise<void>;
|
|
57
|
+
getLiveRun: (runId: string) => LiveAgentRun;
|
|
58
|
+
getActiveRunByAgentId: (workspaceId: string, agentId: string) => LiveAgentRun | undefined;
|
|
59
|
+
registerTasksListener: (listener: (workspaceId: string, content: string) => void) => () => void;
|
|
60
|
+
listAgentRuns: (agentId: string) => PersistedAgentRun[];
|
|
61
|
+
listMessagesForRecovery: (workspaceId: string, sinceMs: number) => RecoveryMessage[];
|
|
62
|
+
peekAgentToken: (agentId: string) => string | undefined;
|
|
63
|
+
pauseTerminalRun: (runId: string) => void;
|
|
64
|
+
resizeAgentRun: (runId: string, cols: number, rows: number) => void;
|
|
65
|
+
resumeTerminalRun: (runId: string) => void;
|
|
66
|
+
settings: SettingsStore;
|
|
67
|
+
writeRunInput: (runId: string, input: Buffer | string) => void;
|
|
68
|
+
getUiToken: () => string;
|
|
69
|
+
stopAgentRun: (runId: string) => void;
|
|
70
|
+
validateAgentToken: (agentId: string, token: string | undefined) => boolean;
|
|
71
|
+
validateUiToken: (token: string | undefined) => boolean;
|
|
72
|
+
getWorkflowDispatchAwaiter: () => WorkflowDispatchAwaiter;
|
|
73
|
+
runWorkflow: (input: RunWorkflowInput) => Promise<WorkflowRunRecord>;
|
|
74
|
+
startWorkflow: (input: RunWorkflowInput) => Promise<WorkflowRunRecord>;
|
|
75
|
+
startWorkflowInline: (input: RunInlineWorkflowInput) => Promise<WorkflowRunRecord>;
|
|
76
|
+
stopWorkflowRun: (runId: string) => boolean;
|
|
77
|
+
getWorkflowRun: (runId: string) => WorkflowRunRecord | undefined;
|
|
78
|
+
listWorkspaceWorkflowRuns: (workspaceId: string) => WorkflowRunRecord[];
|
|
79
|
+
listWorkflowRunDispatches: (runId: string) => DispatchRecord[];
|
|
80
|
+
listWorkflowRunLogs: (runId: string) => Array<{
|
|
81
|
+
id: number;
|
|
82
|
+
ts: number;
|
|
83
|
+
message: string;
|
|
84
|
+
}>;
|
|
85
|
+
createWorkflowSchedule: (input: {
|
|
86
|
+
workspaceId: string;
|
|
87
|
+
scriptPath: string;
|
|
88
|
+
cron: string;
|
|
89
|
+
nextRunAt: number;
|
|
90
|
+
args?: unknown;
|
|
91
|
+
enabled?: boolean;
|
|
92
|
+
}) => WorkflowScheduleRecord;
|
|
93
|
+
scheduleWorkflowInline: (input: {
|
|
94
|
+
workspaceId: string;
|
|
95
|
+
source: string;
|
|
96
|
+
name: string;
|
|
97
|
+
cron: string;
|
|
98
|
+
nextRunAt: number;
|
|
99
|
+
args?: unknown;
|
|
100
|
+
}) => Promise<WorkflowScheduleRecord>;
|
|
101
|
+
updateWorkflowSchedule: (id: string, input: {
|
|
102
|
+
cron?: string;
|
|
103
|
+
args?: unknown;
|
|
104
|
+
enabled?: boolean;
|
|
105
|
+
lastRunAt?: number;
|
|
106
|
+
nextRunAt?: number;
|
|
107
|
+
}) => void;
|
|
108
|
+
getWorkflowSchedule: (id: string) => WorkflowScheduleRecord | undefined;
|
|
109
|
+
listWorkspaceWorkflowSchedules: (workspaceId: string) => WorkflowScheduleRecord[];
|
|
110
|
+
deleteWorkflowSchedule: (id: string) => void;
|
|
111
|
+
}
|
|
112
|
+
export interface RuntimeStoreOptions {
|
|
113
|
+
dataDir?: string;
|
|
114
|
+
agentManager?: AgentManager;
|
|
115
|
+
}
|
|
116
|
+
export interface StartAgentOptions {
|
|
117
|
+
hivePort: string;
|
|
118
|
+
}
|
|
119
|
+
export type RuntimeWorkflowRuntime = {
|
|
120
|
+
runner: WorkflowRunner;
|
|
121
|
+
scheduler: {
|
|
122
|
+
close: () => void;
|
|
123
|
+
start: () => void;
|
|
124
|
+
};
|
|
125
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -11,7 +11,12 @@ import { createTasksFileService } from './tasks-file.js';
|
|
|
11
11
|
import { createTasksFileWatcher } from './tasks-file-watcher.js';
|
|
12
12
|
import { createTeamOperations } from './team-operations.js';
|
|
13
13
|
import { createUiAuth } from './ui-auth.js';
|
|
14
|
+
import { createWebhookNotifier } from './webhook-notifier.js';
|
|
14
15
|
import { type WorkerOutputTracker } from './worker-output-tracker.js';
|
|
16
|
+
import { type WorkflowDispatchAwaiter } from './workflow-dispatch-awaiter.js';
|
|
17
|
+
import { createWorkflowRunLogStore } from './workflow-run-log-store.js';
|
|
18
|
+
import { createWorkflowRunStore } from './workflow-run-store.js';
|
|
19
|
+
import { createWorkflowScheduleStore } from './workflow-schedule-store.js';
|
|
15
20
|
import { createWorkspaceShellRuntime } from './workspace-shell-runtime.js';
|
|
16
21
|
import { createWorkspaceStore } from './workspace-store.js';
|
|
17
22
|
export interface RuntimeStoreServices {
|
|
@@ -27,7 +32,12 @@ export interface RuntimeStoreServices {
|
|
|
27
32
|
tasksFileService: ReturnType<typeof createTasksFileService>;
|
|
28
33
|
teamOps: ReturnType<typeof createTeamOperations>;
|
|
29
34
|
uiAuth: ReturnType<typeof createUiAuth>;
|
|
35
|
+
webhookNotifier: ReturnType<typeof createWebhookNotifier>;
|
|
30
36
|
workerOutputTracker: WorkerOutputTracker | null;
|
|
37
|
+
workflowDispatchAwaiter: WorkflowDispatchAwaiter;
|
|
38
|
+
workflowRunLogStore: ReturnType<typeof createWorkflowRunLogStore>;
|
|
39
|
+
workflowRunStore: ReturnType<typeof createWorkflowRunStore>;
|
|
40
|
+
workflowScheduleStore: ReturnType<typeof createWorkflowScheduleStore>;
|
|
31
41
|
workspaceStore: ReturnType<typeof createWorkspaceStore>;
|
|
32
42
|
}
|
|
33
43
|
interface CreateRuntimeStoreServicesOptions {
|
|
@@ -38,6 +48,7 @@ interface CreateRuntimeStoreLifecycleOptions {
|
|
|
38
48
|
agentManager?: AgentManager;
|
|
39
49
|
services: RuntimeStoreServices;
|
|
40
50
|
}
|
|
51
|
+
export declare const logTasksFileWatchStartError: (workspaceId: string, error: unknown) => void;
|
|
41
52
|
export declare const createRuntimeStoreServices: (options?: CreateRuntimeStoreServicesOptions) => RuntimeStoreServices;
|
|
42
53
|
export declare const createRuntimeStoreLifecycle: ({ agentManager, services, }: CreateRuntimeStoreLifecycleOptions) => {
|
|
43
54
|
close: () => Promise<void>;
|
|
@@ -2,8 +2,10 @@ import { createAgentRunStore } from './agent-run-store.js';
|
|
|
2
2
|
import { createAgentRuntime } from './agent-runtime.js';
|
|
3
3
|
import { createAgentSessionStore } from './agent-session-store.js';
|
|
4
4
|
import { createDispatchLedgerStore } from './dispatch-ledger-store.js';
|
|
5
|
+
import { readFeatureFlags } from './feature-flags.js';
|
|
5
6
|
import { createMessageLogStore } from './message-log-store.js';
|
|
6
7
|
import { seedOrchestratorLaunchConfig } from './orchestrator-launch.js';
|
|
8
|
+
import { createReportOutboxStore } from './report-outbox-store.js';
|
|
7
9
|
import { openRuntimeDatabase } from './runtime-database.js';
|
|
8
10
|
import { buildRuntimeRestartPolicy } from './runtime-restart-policy.js';
|
|
9
11
|
import { createSettingsStore } from './settings-store.js';
|
|
@@ -12,35 +14,59 @@ import { createTasksFileWatcher } from './tasks-file-watcher.js';
|
|
|
12
14
|
import { createTeamOperations } from './team-operations.js';
|
|
13
15
|
import { resolveTerminalInputProfile } from './terminal-input-profile.js';
|
|
14
16
|
import { createUiAuth } from './ui-auth.js';
|
|
17
|
+
import { createWebhookNotifier, WEBHOOK_URL_KEY } from './webhook-notifier.js';
|
|
15
18
|
import { createWorkerOutputTracker } from './worker-output-tracker.js';
|
|
19
|
+
import { readWorkflowCliPolicy, WORKFLOW_CLI_POLICY_KEY } from './workflow-cli-policy.js';
|
|
20
|
+
import { createWorkflowDispatchAwaiter, } from './workflow-dispatch-awaiter.js';
|
|
21
|
+
import { createWorkflowRunLogStore } from './workflow-run-log-store.js';
|
|
22
|
+
import { createWorkflowRunStore } from './workflow-run-store.js';
|
|
23
|
+
import { createWorkflowScheduleStore } from './workflow-schedule-store.js';
|
|
16
24
|
import { createWorkspaceShellRuntime } from './workspace-shell-runtime.js';
|
|
17
25
|
import { createWorkspaceStore } from './workspace-store.js';
|
|
26
|
+
import { getOrchestratorId } from './workspace-store-support.js';
|
|
18
27
|
const notifyTasksUpdated = (callbacks, workspaceId, content) => {
|
|
19
28
|
for (const callback of callbacks) {
|
|
20
29
|
callback(workspaceId, content);
|
|
21
30
|
}
|
|
22
31
|
};
|
|
32
|
+
export const logTasksFileWatchStartError = (workspaceId, error) => {
|
|
33
|
+
console.error(`[hive] failed to start tasks watcher for workspace ${workspaceId}`, error);
|
|
34
|
+
};
|
|
23
35
|
export const createRuntimeStoreServices = (options = {}) => {
|
|
24
36
|
const db = openRuntimeDatabase(options.dataDir);
|
|
25
37
|
const messageLogStore = createMessageLogStore(db);
|
|
26
38
|
const dispatchLedgerStore = createDispatchLedgerStore(db);
|
|
39
|
+
const reportOutbox = createReportOutboxStore(db);
|
|
40
|
+
const workflowDispatchAwaiter = createWorkflowDispatchAwaiter();
|
|
41
|
+
const workflowRunStore = createWorkflowRunStore(db);
|
|
42
|
+
const workflowRunLogStore = createWorkflowRunLogStore(db);
|
|
43
|
+
const workflowScheduleStore = createWorkflowScheduleStore(db);
|
|
27
44
|
const agentRunStore = createAgentRunStore(db);
|
|
28
45
|
const agentSessionStore = createAgentSessionStore(db);
|
|
29
46
|
const settings = createSettingsStore(db);
|
|
47
|
+
const getFlags = () => readFeatureFlags(settings);
|
|
48
|
+
const webhookNotifier = createWebhookNotifier({
|
|
49
|
+
getUrl: () => settings.getAppState(WEBHOOK_URL_KEY)?.value ?? null,
|
|
50
|
+
});
|
|
30
51
|
const tasksFileService = createTasksFileService();
|
|
31
52
|
const tasksFileWatchCallbacks = new Set();
|
|
32
53
|
const tasksFileWatcher = createTasksFileWatcher({
|
|
33
54
|
onTasksUpdated: (workspaceId, content) => {
|
|
34
55
|
notifyTasksUpdated(tasksFileWatchCallbacks, workspaceId, content);
|
|
35
56
|
},
|
|
57
|
+
getWorkflowCliPolicy: () => readWorkflowCliPolicy(settings.getAppState(WORKFLOW_CLI_POLICY_KEY)?.value ?? null),
|
|
58
|
+
getFlags,
|
|
36
59
|
});
|
|
37
60
|
const uiAuth = createUiAuth();
|
|
38
61
|
const shellRuntime = createWorkspaceShellRuntime(options.agentManager);
|
|
39
62
|
agentRunStore.markUnfinishedRunsStale();
|
|
63
|
+
workflowRunStore.markUnfinishedRunsInterrupted();
|
|
40
64
|
const workspaceStore = createWorkspaceStore(db, dispatchLedgerStore.listOpenDispatchKinds());
|
|
41
65
|
const startExistingWorkspaceWatches = () => {
|
|
42
66
|
for (const workspace of workspaceStore.listWorkspaces()) {
|
|
43
|
-
void tasksFileWatcher
|
|
67
|
+
void tasksFileWatcher
|
|
68
|
+
.start(workspace.id, workspace.path)
|
|
69
|
+
.catch((error) => logTasksFileWatchStartError(workspace.id, error));
|
|
44
70
|
}
|
|
45
71
|
};
|
|
46
72
|
const restartPolicy = buildRuntimeRestartPolicy({
|
|
@@ -48,6 +74,7 @@ export const createRuntimeStoreServices = (options = {}) => {
|
|
|
48
74
|
messageLogStore,
|
|
49
75
|
tasksFileService,
|
|
50
76
|
workspaceStore,
|
|
77
|
+
getFlags,
|
|
51
78
|
});
|
|
52
79
|
const workerOutputTracker = options.agentManager
|
|
53
80
|
? createWorkerOutputTracker(options.agentManager.getOutputBus())
|
|
@@ -57,7 +84,70 @@ export const createRuntimeStoreServices = (options = {}) => {
|
|
|
57
84
|
if (!workspaceStore.hasAgent(workspaceId, agentId))
|
|
58
85
|
return;
|
|
59
86
|
workspaceStore.markAgentStopped(workspaceId, agentId);
|
|
60
|
-
|
|
87
|
+
// TIER 1 #1 — if the exiting worker had any open workflow dispatches,
|
|
88
|
+
// tell the workflow awaiter so the runner's `awaitReport` rejects
|
|
89
|
+
// immediately instead of hanging until DEFAULT_TIMEOUT_MS (10 min).
|
|
90
|
+
// This is the only signal the runtime has that an ephemeral
|
|
91
|
+
// workflow worker died without calling `team report`.
|
|
92
|
+
const openWorkflowDispatches = dispatchLedgerStore.listOpenWorkflowDispatchesForWorker(workspaceId, agentId);
|
|
93
|
+
for (const { dispatchId } of openWorkflowDispatches) {
|
|
94
|
+
try {
|
|
95
|
+
const cancelled = dispatchLedgerStore.markCancelled({
|
|
96
|
+
dispatchId,
|
|
97
|
+
reason: 'worker PTY exited before report',
|
|
98
|
+
workspaceId,
|
|
99
|
+
});
|
|
100
|
+
if (!cancelled)
|
|
101
|
+
continue;
|
|
102
|
+
try {
|
|
103
|
+
workspaceStore.markTaskCancelled(workspaceId, agentId);
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
console.error('[hive] onAgentExit.markTaskCancelled failed', dispatchId, error);
|
|
107
|
+
}
|
|
108
|
+
workflowDispatchAwaiter.notifyCancel(dispatchId, 'worker PTY exited before report');
|
|
109
|
+
}
|
|
110
|
+
catch (error) {
|
|
111
|
+
console.error('[hive] onAgentExit.markCancelled failed', dispatchId, error);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
// Cascade: when the orchestrator's PTY exits, dismiss the ephemeral
|
|
115
|
+
// workers it spawned via `team spawn` (spec §6.3). Workflow-spawned
|
|
116
|
+
// workers are owned by the runner, not the orchestrator.
|
|
117
|
+
if (agentId === getOrchestratorId(workspaceId)) {
|
|
118
|
+
const children = workspaceStore
|
|
119
|
+
.getWorkspaceSnapshot(workspaceId)
|
|
120
|
+
.agents.filter((agent) => agent.ephemeral === true && agent.spawnedBy === 'orchestrator');
|
|
121
|
+
for (const child of children)
|
|
122
|
+
removeWorkerCompletely(workspaceId, child.id);
|
|
123
|
+
}
|
|
124
|
+
}, restartPolicy, (workspaceId, agentId) => workspaceStore.getAgent(workspaceId, agentId), getFlags);
|
|
125
|
+
// Mirrors runtime-store.deleteWorker (stop run → drop launch config → drop
|
|
126
|
+
// dispatches → drop worker row, transactionally). Hoisted `function` so the
|
|
127
|
+
// onAgentExit closure above can reference it; only invoked at runtime, after
|
|
128
|
+
// agentRuntime is assigned.
|
|
129
|
+
function removeWorkerCompletely(workspaceId, workerId) {
|
|
130
|
+
const activeRun = agentRuntime.getActiveRunByAgentId(workspaceId, workerId);
|
|
131
|
+
if (activeRun)
|
|
132
|
+
agentRuntime.stopAgentRun(activeRun.runId);
|
|
133
|
+
agentRuntime.deleteAgentLaunchConfig(workspaceId, workerId);
|
|
134
|
+
db.transaction(() => {
|
|
135
|
+
dispatchLedgerStore.deleteWorkerDispatches(workspaceId, workerId);
|
|
136
|
+
workspaceStore.deleteWorker(workspaceId, workerId);
|
|
137
|
+
})();
|
|
138
|
+
}
|
|
139
|
+
// Boot cleanup: after a runtime restart every ephemeral worker is an orphan
|
|
140
|
+
// (its spawner — a workflow run or an orchestrator PTY — is gone). Remove
|
|
141
|
+
// them so they don't accumulate (spec §6.3).
|
|
142
|
+
const cleanupOrphanEphemeralWorkers = () => {
|
|
143
|
+
for (const workspace of workspaceStore.listWorkspaces()) {
|
|
144
|
+
const ephemeral = workspaceStore
|
|
145
|
+
.getWorkspaceSnapshot(workspace.id)
|
|
146
|
+
.agents.filter((agent) => agent.ephemeral === true);
|
|
147
|
+
for (const agent of ephemeral)
|
|
148
|
+
removeWorkerCompletely(workspace.id, agent.id);
|
|
149
|
+
}
|
|
150
|
+
};
|
|
61
151
|
const teamOps = createTeamOperations({
|
|
62
152
|
agentRuntime,
|
|
63
153
|
createDispatch: dispatchLedgerStore.createDispatch,
|
|
@@ -69,8 +159,13 @@ export const createRuntimeStoreServices = (options = {}) => {
|
|
|
69
159
|
markDispatchCancelled: dispatchLedgerStore.markCancelled,
|
|
70
160
|
markDispatchReportedByWorker: dispatchLedgerStore.markReportedByWorker,
|
|
71
161
|
markDispatchSubmitted: dispatchLedgerStore.markSubmitted,
|
|
162
|
+
reportOutbox,
|
|
163
|
+
notifyWebhook: webhookNotifier.notify,
|
|
164
|
+
workflowDispatchAwaiter,
|
|
72
165
|
workspaceStore,
|
|
166
|
+
dismissEphemeralWorker: (workspaceId, workerId) => removeWorkerCompletely(workspaceId, workerId),
|
|
73
167
|
});
|
|
168
|
+
cleanupOrphanEphemeralWorkers();
|
|
74
169
|
startExistingWorkspaceWatches();
|
|
75
170
|
return {
|
|
76
171
|
agentRunStore,
|
|
@@ -85,7 +180,12 @@ export const createRuntimeStoreServices = (options = {}) => {
|
|
|
85
180
|
tasksFileService,
|
|
86
181
|
teamOps,
|
|
87
182
|
uiAuth,
|
|
183
|
+
webhookNotifier,
|
|
88
184
|
workerOutputTracker,
|
|
185
|
+
workflowDispatchAwaiter,
|
|
186
|
+
workflowRunLogStore,
|
|
187
|
+
workflowRunStore,
|
|
188
|
+
workflowScheduleStore,
|
|
89
189
|
workspaceStore,
|
|
90
190
|
};
|
|
91
191
|
};
|
|
@@ -143,6 +243,10 @@ export const createRuntimeStoreLifecycle = ({ agentManager, services, }) => {
|
|
|
143
243
|
};
|
|
144
244
|
return {
|
|
145
245
|
close: async () => {
|
|
246
|
+
// Fail in-flight workflow awaiters BEFORE their workers vanish, so the
|
|
247
|
+
// runner's `await agent(...)` rejects with a clear shutdown error
|
|
248
|
+
// instead of hanging on a Promise that can never resolve.
|
|
249
|
+
services.workflowDispatchAwaiter.cancelAll('runtime closing');
|
|
146
250
|
services.shellRuntime.close();
|
|
147
251
|
await services.agentRuntime.close();
|
|
148
252
|
await services.tasksFileWatcher.close();
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { RuntimeStore } from './runtime-store-contract.js';
|
|
2
|
+
import type { RuntimeStoreServices } from './runtime-store-helpers.js';
|
|
3
|
+
export declare const createRuntimeStoreWorkflowRuntime: (services: RuntimeStoreServices, store: RuntimeStore) => {
|
|
4
|
+
runner: import("./workflow-runner.js").WorkflowRunner;
|
|
5
|
+
scheduler: import("./workflow-scheduler.js").WorkflowScheduler;
|
|
6
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { readWorkflowCliPolicy, WORKFLOW_CLI_POLICY_KEY } from './workflow-cli-policy.js';
|
|
2
|
+
import { readWorkflowEnabled, WORKFLOW_ENABLED_KEY } from './workflow-feature.js';
|
|
3
|
+
import { createWorkflowRunner } from './workflow-runner.js';
|
|
4
|
+
import { createWorkflowScheduler } from './workflow-scheduler.js';
|
|
5
|
+
export const createRuntimeStoreWorkflowRuntime = (services, store) => {
|
|
6
|
+
const runner = createWorkflowRunner({
|
|
7
|
+
awaiter: services.workflowDispatchAwaiter,
|
|
8
|
+
workflowRunStore: services.workflowRunStore,
|
|
9
|
+
dispatchPort: {
|
|
10
|
+
listOpenDispatchIdsForRun: (runId) => services.dispatchLedgerStore.listOpenDispatchIdsForRun(runId),
|
|
11
|
+
},
|
|
12
|
+
resolveWorkspacePath: (workspaceId) => services.workspaceStore.getWorkspaceSnapshot(workspaceId).summary.path,
|
|
13
|
+
logStore: {
|
|
14
|
+
append: (runId, message, ts) => services.workflowRunLogStore.append(runId, message, ts),
|
|
15
|
+
},
|
|
16
|
+
getWorkflowCliPolicy: () => readWorkflowCliPolicy(services.settings.getAppState(WORKFLOW_CLI_POLICY_KEY)?.value ?? null),
|
|
17
|
+
roleTemplateResolver: {
|
|
18
|
+
findByName: (name) => {
|
|
19
|
+
const t = services.settings.findRoleTemplateByName(name);
|
|
20
|
+
if (!t)
|
|
21
|
+
return undefined;
|
|
22
|
+
return {
|
|
23
|
+
name: t.name,
|
|
24
|
+
roleType: t.roleType,
|
|
25
|
+
defaultCommand: t.defaultCommand,
|
|
26
|
+
defaultArgs: t.defaultArgs,
|
|
27
|
+
};
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
onRunFinished: ({ runId, triggeredByAgentId, finalRecord }) => {
|
|
31
|
+
const workspaceId = finalRecord.workspaceId;
|
|
32
|
+
const dispatches = services.dispatchLedgerStore.listWorkflowRunDispatches(runId);
|
|
33
|
+
const errorLine = finalRecord.error ? `\nerror: ${finalRecord.error}` : '';
|
|
34
|
+
const dispatchSummary = dispatches.length === 0
|
|
35
|
+
? '\n(no agent() calls in this run)'
|
|
36
|
+
: '\n' +
|
|
37
|
+
dispatches
|
|
38
|
+
.map((d) => {
|
|
39
|
+
const reply = d.reportText
|
|
40
|
+
? d.reportText.length > 200
|
|
41
|
+
? `${d.reportText.slice(0, 197).trim()}...`
|
|
42
|
+
: d.reportText.trim()
|
|
43
|
+
: `(no report; status=${d.status})`;
|
|
44
|
+
return ` #${d.stepIndex ?? '?'} -> ${reply}`;
|
|
45
|
+
})
|
|
46
|
+
.join('\n');
|
|
47
|
+
const resultBlock = (() => {
|
|
48
|
+
if (finalRecord.result === null || finalRecord.result === undefined)
|
|
49
|
+
return '';
|
|
50
|
+
const serialized = typeof finalRecord.result === 'string'
|
|
51
|
+
? finalRecord.result
|
|
52
|
+
: JSON.stringify(finalRecord.result, null, 2);
|
|
53
|
+
const truncated = serialized.length > 4000
|
|
54
|
+
? `${serialized.slice(0, 4000)}\n...(truncated; ${serialized.length - 4000} more chars)`
|
|
55
|
+
: serialized;
|
|
56
|
+
return `\nResult (workflow return value):\n${truncated}`;
|
|
57
|
+
})();
|
|
58
|
+
const logTail = services.workflowRunLogStore.tailForRun(runId, 8);
|
|
59
|
+
const logBlock = logTail.length === 0
|
|
60
|
+
? ''
|
|
61
|
+
: `\nNarrator (last ${logTail.length} log line${logTail.length === 1 ? '' : 's'}):\n` +
|
|
62
|
+
logTail.map((line) => ` - ${line}`).join('\n');
|
|
63
|
+
const payload = '<hive-system-reminder>\n' +
|
|
64
|
+
`Hive workflow \`${finalRecord.name}\` finished: status=${finalRecord.status}` +
|
|
65
|
+
` (run_id=${runId}, ${dispatches.length} agent call${dispatches.length === 1 ? '' : 's'}).` +
|
|
66
|
+
errorLine +
|
|
67
|
+
resultBlock +
|
|
68
|
+
logBlock +
|
|
69
|
+
dispatchSummary +
|
|
70
|
+
'\nThis result is what you should synthesize back to the user. ' +
|
|
71
|
+
'Per-agent transcripts are available via `team workflow show ' +
|
|
72
|
+
runId +
|
|
73
|
+
'` if needed.\n' +
|
|
74
|
+
'</hive-system-reminder>\n';
|
|
75
|
+
try {
|
|
76
|
+
services.agentRuntime.writeSystemMessageToAgent(workspaceId, triggeredByAgentId, payload);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error('[hive] workflow.notifyTrigger failed', error);
|
|
80
|
+
}
|
|
81
|
+
// Outbound completion webhook (best-effort) so the user is pinged when a
|
|
82
|
+
// long fan-out finishes without watching the drawer.
|
|
83
|
+
services.webhookNotifier.notify({
|
|
84
|
+
type: 'workflow_finished',
|
|
85
|
+
workspaceId,
|
|
86
|
+
summary: `${finalRecord.name}: ${finalRecord.status}${finalRecord.error ? ` — ${finalRecord.error}` : ''}`,
|
|
87
|
+
at: Date.now(),
|
|
88
|
+
});
|
|
89
|
+
},
|
|
90
|
+
store: {
|
|
91
|
+
addWorkerWithLaunch: (ws, input, launch) => store.addWorkerWithLaunch(ws, input, launch),
|
|
92
|
+
deleteWorker: (ws, workerId) => store.deleteWorker(ws, workerId),
|
|
93
|
+
dispatchTaskByWorkerName: async (ws, name, text, input) => {
|
|
94
|
+
const dispatch = await store.dispatchTaskByWorkerName(ws, name, text, input);
|
|
95
|
+
return { id: dispatch.id };
|
|
96
|
+
},
|
|
97
|
+
startAgent: (ws, agentId, input) => store.startAgent(ws, agentId, input),
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
const scheduler = createWorkflowScheduler({
|
|
101
|
+
schedules: services.workflowScheduleStore,
|
|
102
|
+
startWorkflow: (input) => store.startWorkflow(input),
|
|
103
|
+
workspaceExists: (workspaceId) => services.workspaceStore.hasWorkspace(workspaceId),
|
|
104
|
+
isWorkflowEnabled: () => readWorkflowEnabled(services.settings.getAppState(WORKFLOW_ENABLED_KEY)?.value ?? null),
|
|
105
|
+
});
|
|
106
|
+
scheduler.start();
|
|
107
|
+
return { runner, scheduler };
|
|
108
|
+
};
|
|
@@ -1,73 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
import type { LiveAgentRun } from './agent-runtime-types.js';
|
|
5
|
-
import type { DispatchRecord, ListDispatchesOptions } from './dispatch-ledger-store.js';
|
|
6
|
-
import type { RecoveryMessage } from './message-log-store.js';
|
|
7
|
-
import type { PtyOutputBus } from './pty-output-bus.js';
|
|
8
|
-
import type { SettingsStore } from './settings-store.js';
|
|
9
|
-
import type { CancelTaskInput, DispatchTaskInput, ReportTaskInput, ReportTaskResult, StatusTaskInput } from './team-operations.js';
|
|
10
|
-
import type { TerminalRunSummary } from './terminal-input-profile.js';
|
|
11
|
-
import type { WorkerInput, WorkspaceRecord } from './workspace-store.js';
|
|
12
|
-
interface RuntimeStore {
|
|
13
|
-
close: () => Promise<void>;
|
|
14
|
-
createWorkspace: (path: string, name: string) => WorkspaceSummary;
|
|
15
|
-
deleteWorkspace: (workspaceId: string) => Promise<void>;
|
|
16
|
-
listWorkspaces: () => WorkspaceSummary[];
|
|
17
|
-
addWorker: (workspaceId: string, input: WorkerInput) => AgentSummary;
|
|
18
|
-
deleteWorker: (workspaceId: string, workerId: string) => void;
|
|
19
|
-
renameWorker: (workspaceId: string, workerId: string, name: string) => AgentSummary;
|
|
20
|
-
recordUserInput: (workspaceId: string, orchestratorId: string, text: string) => void;
|
|
21
|
-
dispatchTask: (workspaceId: string, workerId: string, text: string, input?: DispatchTaskInput) => Promise<DispatchRecord>;
|
|
22
|
-
dispatchTaskByWorkerName: (workspaceId: string, workerName: string, text: string, input?: DispatchTaskInput) => Promise<DispatchRecord & {
|
|
23
|
-
restartedWorker: boolean;
|
|
24
|
-
}>;
|
|
25
|
-
reportTask: (workspaceId: string, workerId: string, input?: ReportTaskInput) => ReportTaskResult;
|
|
26
|
-
statusTask: (workspaceId: string, workerId: string, input?: StatusTaskInput) => ReportTaskResult;
|
|
27
|
-
cancelTask: (workspaceId: string, dispatchId: string, input: CancelTaskInput) => ReportTaskResult;
|
|
28
|
-
listDispatches: (workspaceId: string, options?: ListDispatchesOptions) => DispatchRecord[];
|
|
29
|
-
listWorkers: (workspaceId: string) => TeamListItem[];
|
|
30
|
-
getLastPtyLineForAgent: (workspaceId: string, agentId: string) => string | null;
|
|
31
|
-
getWorkspaceSnapshot: (workspaceId: string) => WorkspaceRecord;
|
|
32
|
-
getWorker: (workspaceId: string, workerId: string) => AgentSummary;
|
|
33
|
-
getAgent: (workspaceId: string, agentId: string) => AgentSummary;
|
|
34
|
-
getPtyOutputBus: () => PtyOutputBus;
|
|
35
|
-
listTerminalRuns: (workspaceId: string) => TerminalRunSummary[];
|
|
36
|
-
closeWorkspaceShell: (workspaceId: string, runId: string) => boolean;
|
|
37
|
-
startWorkspaceShell: (workspaceId: string) => Promise<LiveAgentRun>;
|
|
38
|
-
configureAgentLaunch: (workspaceId: string, agentId: string, input: AgentLaunchConfigInput) => void;
|
|
39
|
-
peekAgentLaunchConfig: (workspaceId: string, agentId: string) => AgentLaunchConfigInput | undefined;
|
|
40
|
-
startAgent: (workspaceId: string, agentId: string, input: StartAgentOptions) => Promise<LiveAgentRun>;
|
|
41
|
-
autostartConfiguredAgents: (input: StartAgentOptions) => Promise<Array<{
|
|
42
|
-
agent_id: string;
|
|
43
|
-
error: string | null;
|
|
44
|
-
ok: boolean;
|
|
45
|
-
run_id: string | null;
|
|
46
|
-
workspace_id: string;
|
|
47
|
-
}>>;
|
|
48
|
-
startWorkspaceWatch: (workspaceId: string) => Promise<void>;
|
|
49
|
-
getLiveRun: (runId: string) => LiveAgentRun;
|
|
50
|
-
getActiveRunByAgentId: (workspaceId: string, agentId: string) => LiveAgentRun | undefined;
|
|
51
|
-
registerTasksListener: (listener: (workspaceId: string, content: string) => void) => () => void;
|
|
52
|
-
listAgentRuns: (agentId: string) => PersistedAgentRun[];
|
|
53
|
-
listMessagesForRecovery: (workspaceId: string, sinceMs: number) => RecoveryMessage[];
|
|
54
|
-
peekAgentToken: (agentId: string) => string | undefined;
|
|
55
|
-
pauseTerminalRun: (runId: string) => void;
|
|
56
|
-
resizeAgentRun: (runId: string, cols: number, rows: number) => void;
|
|
57
|
-
resumeTerminalRun: (runId: string) => void;
|
|
58
|
-
settings: SettingsStore;
|
|
59
|
-
writeRunInput: (runId: string, input: Buffer | string) => void;
|
|
60
|
-
getUiToken: () => string;
|
|
61
|
-
stopAgentRun: (runId: string) => void;
|
|
62
|
-
validateAgentToken: (agentId: string, token: string | undefined) => boolean;
|
|
63
|
-
validateUiToken: (token: string | undefined) => boolean;
|
|
64
|
-
}
|
|
65
|
-
interface RuntimeStoreOptions {
|
|
66
|
-
dataDir?: string;
|
|
67
|
-
agentManager?: AgentManager;
|
|
68
|
-
}
|
|
69
|
-
interface StartAgentOptions {
|
|
70
|
-
hivePort: string;
|
|
71
|
-
}
|
|
72
|
-
export type { RuntimeStore };
|
|
1
|
+
import type { RuntimeStore, RuntimeStoreOptions } from './runtime-store-contract.js';
|
|
2
|
+
import type { WorkflowRunRecord } from './workflow-run-store.js';
|
|
3
|
+
export type { RuntimeStore, WorkflowRunRecord };
|
|
73
4
|
export declare const createRuntimeStore: (options?: RuntimeStoreOptions) => RuntimeStore;
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { createRuntimeStoreLifecycle, createRuntimeStoreServices } from './runtime-store-helpers.js';
|
|
1
|
+
import { createRuntimeStoreLifecycle, createRuntimeStoreServices, logTasksFileWatchStartError, } from './runtime-store-helpers.js';
|
|
2
|
+
import { createRuntimeStoreWorkflowRuntime } from './runtime-store-workflows.js';
|
|
3
|
+
import { persistWorkflowSchedule } from './workflow-schedule-create.js';
|
|
2
4
|
export const createRuntimeStore = (options = {}) => {
|
|
3
5
|
const services = createRuntimeStoreServices(options);
|
|
4
6
|
const lifecycle = createRuntimeStoreLifecycle(options.agentManager ? { agentManager: options.agentManager, services } : { services });
|
|
@@ -9,11 +11,22 @@ export const createRuntimeStore = (options = {}) => {
|
|
|
9
11
|
}
|
|
10
12
|
services.db.transaction(mutation)();
|
|
11
13
|
};
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
let workflowRuntime;
|
|
15
|
+
const getWorkflowRuntime = () => {
|
|
16
|
+
if (!workflowRuntime)
|
|
17
|
+
throw new Error('Workflow runtime not initialized');
|
|
18
|
+
return workflowRuntime;
|
|
19
|
+
};
|
|
20
|
+
const store = {
|
|
21
|
+
close: async () => {
|
|
22
|
+
workflowRuntime?.scheduler.close();
|
|
23
|
+
await lifecycle.close();
|
|
24
|
+
},
|
|
14
25
|
createWorkspace: (path, name) => {
|
|
15
26
|
const workspace = services.workspaceStore.createWorkspace(path, name);
|
|
16
|
-
void lifecycle
|
|
27
|
+
void lifecycle
|
|
28
|
+
.startWorkspaceWatch(workspace.id)
|
|
29
|
+
.catch((error) => logTasksFileWatchStartError(workspace.id, error));
|
|
17
30
|
return workspace;
|
|
18
31
|
},
|
|
19
32
|
listWorkspaces: () => services.workspaceStore.listWorkspaces(),
|
|
@@ -36,6 +49,34 @@ export const createRuntimeStore = (options = {}) => {
|
|
|
36
49
|
}
|
|
37
50
|
},
|
|
38
51
|
addWorker: (workspaceId, input) => services.workspaceStore.addWorker(workspaceId, input),
|
|
52
|
+
addWorkerWithLaunch: (workspaceId, input, launchConfig) => {
|
|
53
|
+
// Atomic spawn: create the worker AND its launch config together so a
|
|
54
|
+
// failure can never persist a worker with no way to start it. The DB
|
|
55
|
+
// transaction rolls back the row; the catch prunes the in-memory worker
|
|
56
|
+
// that addWorker already pushed into the workspace record.
|
|
57
|
+
let worker;
|
|
58
|
+
try {
|
|
59
|
+
runDataMutation(() => {
|
|
60
|
+
worker = store.addWorker(workspaceId, input);
|
|
61
|
+
store.configureAgentLaunch(workspaceId, worker.id, launchConfig);
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
catch (error) {
|
|
65
|
+
if (worker) {
|
|
66
|
+
try {
|
|
67
|
+
store.deleteWorker(workspaceId, worker.id);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// The transaction already removed the DB row; this only prunes the
|
|
71
|
+
// stale in-memory entry, which may already be gone.
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
throw error;
|
|
75
|
+
}
|
|
76
|
+
if (!worker)
|
|
77
|
+
throw new Error('addWorkerWithLaunch produced no worker');
|
|
78
|
+
return worker;
|
|
79
|
+
},
|
|
39
80
|
renameWorker: (workspaceId, workerId, name) => services.workspaceStore.renameWorker(workspaceId, workerId, name),
|
|
40
81
|
deleteWorker: (workspaceId, workerId) => {
|
|
41
82
|
const activeRun = services.agentRuntime.getActiveRunByAgentId(workspaceId, workerId);
|
|
@@ -52,6 +93,7 @@ export const createRuntimeStore = (options = {}) => {
|
|
|
52
93
|
dispatchTask: services.teamOps.dispatchTask,
|
|
53
94
|
dispatchTaskByWorkerName: services.teamOps.dispatchTaskByWorkerName,
|
|
54
95
|
reportTask: services.teamOps.reportTask,
|
|
96
|
+
drainReportOutbox: services.teamOps.drainReportOutbox,
|
|
55
97
|
statusTask: services.teamOps.statusTask,
|
|
56
98
|
listDispatches: services.dispatchLedgerStore.listWorkspaceDispatches,
|
|
57
99
|
listWorkers: (workspaceId) => services.workspaceStore.listWorkers(workspaceId),
|
|
@@ -83,5 +125,30 @@ export const createRuntimeStore = (options = {}) => {
|
|
|
83
125
|
stopAgentRun: lifecycle.stopTerminalRun,
|
|
84
126
|
validateAgentToken: (agentId, token) => services.agentRuntime.validateAgentToken(agentId, token),
|
|
85
127
|
validateUiToken: (token) => services.uiAuth.validate(token),
|
|
128
|
+
getWorkflowDispatchAwaiter: () => services.workflowDispatchAwaiter,
|
|
129
|
+
runWorkflow: (input) => getWorkflowRuntime().runner.runWorkflow(input),
|
|
130
|
+
startWorkflow: (input) => getWorkflowRuntime().runner.startWorkflow(input),
|
|
131
|
+
startWorkflowInline: (input) => getWorkflowRuntime().runner.startWorkflowInline(input),
|
|
132
|
+
stopWorkflowRun: (runId) => getWorkflowRuntime().runner.stopRun(runId),
|
|
133
|
+
getWorkflowRun: (runId) => services.workflowRunStore.getRun(runId),
|
|
134
|
+
listWorkspaceWorkflowRuns: (workspaceId) => services.workflowRunStore.listWorkspaceRuns(workspaceId),
|
|
135
|
+
listWorkflowRunDispatches: (runId) => services.dispatchLedgerStore.listWorkflowRunDispatches(runId),
|
|
136
|
+
listWorkflowRunLogs: (runId) => services.workflowRunLogStore.listForRun(runId).map((row) => ({
|
|
137
|
+
id: row.id,
|
|
138
|
+
ts: row.ts,
|
|
139
|
+
message: row.message,
|
|
140
|
+
})),
|
|
141
|
+
createWorkflowSchedule: (input) => services.workflowScheduleStore.create(input),
|
|
142
|
+
scheduleWorkflowInline: (input) => persistWorkflowSchedule({
|
|
143
|
+
workspacePath: services.workspaceStore.getWorkspaceSnapshot(input.workspaceId).summary.path,
|
|
144
|
+
scheduleStore: services.workflowScheduleStore,
|
|
145
|
+
...input,
|
|
146
|
+
}),
|
|
147
|
+
updateWorkflowSchedule: (id, input) => services.workflowScheduleStore.update(id, input),
|
|
148
|
+
getWorkflowSchedule: (id) => services.workflowScheduleStore.get(id),
|
|
149
|
+
listWorkspaceWorkflowSchedules: (workspaceId) => services.workflowScheduleStore.listForWorkspace(workspaceId),
|
|
150
|
+
deleteWorkflowSchedule: (id) => services.workflowScheduleStore.deleteSchedule(id),
|
|
86
151
|
};
|
|
152
|
+
workflowRuntime = createRuntimeStoreWorkflowRuntime(services, store);
|
|
153
|
+
return store;
|
|
87
154
|
};
|