@tt-a1i/hive 2.1.6 → 2.1.8
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 +27 -0
- package/dist/src/server/agent-runtime-contract.d.ts +1 -9
- package/dist/src/server/agent-runtime.js +1 -7
- package/dist/src/server/agent-stdin-dispatcher.d.ts +2 -11
- package/dist/src/server/agent-stdin-dispatcher.js +14 -12
- package/dist/src/server/hive-team-guidance.js +12 -11
- package/dist/src/server/post-start-input-writer.js +1 -1
- package/dist/src/server/report-outbox-store.d.ts +10 -8
- package/dist/src/server/report-outbox-store.js +10 -1
- package/dist/src/server/role-templates.js +8 -4
- package/dist/src/server/routes-remote.js +46 -14
- package/dist/src/server/routes-team.js +1 -1
- package/dist/src/server/routes-workspaces.js +3 -6
- package/dist/src/server/runtime-store-contract.d.ts +2 -2
- package/dist/src/server/runtime-store-helpers.d.ts +4 -0
- package/dist/src/server/runtime-store-helpers.js +34 -11
- package/dist/src/server/runtime-store-worker-mutations.js +12 -6
- package/dist/src/server/runtime-store-workflows.js +7 -1
- package/dist/src/server/team-operations.d.ts +12 -5
- package/dist/src/server/team-operations.js +218 -159
- package/dist/src/shared/remote-bridge-routing.js +3 -1
- package/package.json +1 -1
- package/web/dist/assets/{AddWorkerDialog-DFNkbR_Q.js → AddWorkerDialog-Cd53ifv2.js} +2 -2
- package/web/dist/assets/{AddWorkspaceFlow-BjpjCuRe.js → AddWorkspaceFlow-3sR25gDy.js} +1 -1
- package/web/dist/assets/{FirstRunWizard-BuLgUAny.js → FirstRunWizard-DU8PipxA.js} +1 -1
- package/web/dist/assets/{MarketplaceDrawer-BALuhrnd.js → MarketplaceDrawer-BkNcknv0.js} +1 -1
- package/web/dist/assets/{TaskGraphDrawer-DQTS6JPI.js → TaskGraphDrawer-9mXNimSE.js} +1 -1
- package/web/dist/assets/{WhatsNewDialog-DpgjEIaA.js → WhatsNewDialog-C7awVYub.js} +1 -1
- package/web/dist/assets/WorkerModal-BzgrOKzF.js +1 -0
- package/web/dist/assets/{WorkflowsDrawer-DPWlZs4S.js → WorkflowsDrawer-C4yjTdY7.js} +1 -1
- package/web/dist/assets/{WorkspaceMemoryDrawer-C0vny4zK.js → WorkspaceMemoryDrawer-BlDznlGm.js} +1 -1
- package/web/dist/assets/{WorkspaceTaskDrawer-CJcFZh8C.js → WorkspaceTaskDrawer-CpGGZkp3.js} +1 -1
- package/web/dist/assets/index-BEyvsWk6.js +84 -0
- package/web/dist/assets/index-VHK8pAJq.css +1 -0
- package/web/dist/assets/{search-Bl5O-SfR.js → search-Cv0KnMjw.js} +1 -1
- package/web/dist/assets/{square-terminal-DCDaflg3.js → square-terminal-BZ7EavxU.js} +1 -1
- package/web/dist/index.html +2 -2
- package/web/dist/sw.js +1 -1
- package/web/dist/assets/WorkerModal-1y-Xdwv-.js +0 -1
- package/web/dist/assets/index-CEP_bvOg.css +0 -1
- package/web/dist/assets/index-CR1SPGBZ.js +0 -84
|
@@ -76,6 +76,7 @@ const createWorkspaceUploadStorage = (dataDir) => {
|
|
|
76
76
|
};
|
|
77
77
|
export const createRuntimeStoreServices = (options = {}) => {
|
|
78
78
|
const db = openRuntimeDatabase(options.dataDir);
|
|
79
|
+
let closing = false;
|
|
79
80
|
const uploadStorage = createWorkspaceUploadStorage(options.dataDir);
|
|
80
81
|
const messageLogStore = createMessageLogStore(db);
|
|
81
82
|
const dispatchLedgerStore = createDispatchLedgerStore(db);
|
|
@@ -239,18 +240,24 @@ export const createRuntimeStoreServices = (options = {}) => {
|
|
|
239
240
|
// agentRuntime is assigned.
|
|
240
241
|
function removeWorkerCompletely(workspaceId, workerId) {
|
|
241
242
|
const activeRun = agentRuntime.getActiveRunByAgentId(workspaceId, workerId);
|
|
242
|
-
|
|
243
|
-
// first, or parked/in-flight work vanishes silently (review finding).
|
|
244
|
-
try {
|
|
245
|
-
teamOps.notifyIssuersOfDroppedDispatches(workspaceId, workerId, 'the worker was dismissed');
|
|
246
|
-
}
|
|
247
|
-
catch (error) {
|
|
248
|
-
console.error('[hive] swallowed:removeWorker.notifyDropped', error);
|
|
249
|
-
}
|
|
243
|
+
const droppedNoticeTargets = new Set();
|
|
250
244
|
db.transaction(() => {
|
|
245
|
+
for (const dispatch of dispatchLedgerStore.listWorkspaceDispatches(workspaceId)) {
|
|
246
|
+
if (dispatch.toAgentId === workerId && dispatch.workflowRunId === null) {
|
|
247
|
+
reportOutbox.deletePendingForDispatch(dispatch.id);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
// Open dispatch rows are about to be hard-deleted — queue issuer notices
|
|
251
|
+
// in the same transaction or the delete must not commit.
|
|
252
|
+
for (const targetAgentId of teamOps.notifyIssuersOfDroppedDispatches(workspaceId, workerId, 'the worker was dismissed')) {
|
|
253
|
+
droppedNoticeTargets.add(targetAgentId);
|
|
254
|
+
}
|
|
251
255
|
dispatchLedgerStore.deleteWorkerDispatches(workspaceId, workerId);
|
|
252
256
|
workspaceStore.deleteWorker(workspaceId, workerId);
|
|
253
257
|
})();
|
|
258
|
+
for (const targetAgentId of droppedNoticeTargets) {
|
|
259
|
+
teamOps.drainReportOutbox(workspaceId, targetAgentId);
|
|
260
|
+
}
|
|
254
261
|
agentRuntime.deleteAgentLaunchConfig(workspaceId, workerId);
|
|
255
262
|
if (activeRun)
|
|
256
263
|
agentRuntime.stopAgentRun(activeRun.runId);
|
|
@@ -283,6 +290,8 @@ export const createRuntimeStoreServices = (options = {}) => {
|
|
|
283
290
|
reparkClaimedDispatch: dispatchLedgerStore.reparkClaimedDispatch,
|
|
284
291
|
reportOutbox,
|
|
285
292
|
notifyWebhook: webhookNotifier.notify,
|
|
293
|
+
runDataMutation: (mutation) => db.transaction(mutation)(),
|
|
294
|
+
isRuntimeClosing: () => closing,
|
|
286
295
|
workflowDispatchAwaiter,
|
|
287
296
|
workspaceStore,
|
|
288
297
|
dismissEphemeralWorker: (workspaceId, workerId) => removeWorkerCompletely(workspaceId, workerId),
|
|
@@ -296,6 +305,10 @@ export const createRuntimeStoreServices = (options = {}) => {
|
|
|
296
305
|
agentRuntime,
|
|
297
306
|
db,
|
|
298
307
|
dispatchLedgerStore,
|
|
308
|
+
isRuntimeClosing: () => closing,
|
|
309
|
+
markRuntimeClosing: () => {
|
|
310
|
+
closing = true;
|
|
311
|
+
},
|
|
299
312
|
messageLogStore,
|
|
300
313
|
remoteAuditStore,
|
|
301
314
|
remoteDeviceSessions,
|
|
@@ -310,6 +323,7 @@ export const createRuntimeStoreServices = (options = {}) => {
|
|
|
310
323
|
teamMemoryDreamScheduler,
|
|
311
324
|
sentinelHeartbeat,
|
|
312
325
|
protocolEventStats,
|
|
326
|
+
reportOutbox,
|
|
313
327
|
teamMemoryDreamStore,
|
|
314
328
|
teamMemoryDiagnostics,
|
|
315
329
|
teamMemoryExport,
|
|
@@ -345,7 +359,15 @@ export const createRuntimeStoreLifecycle = ({ agentManager, services, }) => {
|
|
|
345
359
|
// for orchestrator/workflow pseudo-agents, which never hold queued
|
|
346
360
|
// worker dispatches addressed to themselves). Wait for post-start
|
|
347
361
|
// guidance first so startup instructions never race the first task.
|
|
348
|
-
const
|
|
362
|
+
const deliverPostStartBacklog = () => {
|
|
363
|
+
if (services.isRuntimeClosing())
|
|
364
|
+
return;
|
|
365
|
+
try {
|
|
366
|
+
services.teamOps.drainReportOutbox(workspaceId, agentId);
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
console.error('[hive] swallowed:startAgent.drainOutbox', error);
|
|
370
|
+
}
|
|
349
371
|
try {
|
|
350
372
|
services.teamOps.replayQueuedDispatches(workspaceId, agentId, {
|
|
351
373
|
createdBeforeMs: run.startedAt,
|
|
@@ -356,12 +378,12 @@ export const createRuntimeStoreLifecycle = ({ agentManager, services, }) => {
|
|
|
356
378
|
}
|
|
357
379
|
};
|
|
358
380
|
if (run.postStartInputReady) {
|
|
359
|
-
void run.postStartInputReady.then(
|
|
381
|
+
void run.postStartInputReady.then(deliverPostStartBacklog).catch((error) => {
|
|
360
382
|
console.error('[hive] swallowed:startAgent.replayAfterPostStart', error);
|
|
361
383
|
});
|
|
362
384
|
}
|
|
363
385
|
else {
|
|
364
|
-
|
|
386
|
+
deliverPostStartBacklog();
|
|
365
387
|
}
|
|
366
388
|
}
|
|
367
389
|
return run;
|
|
@@ -406,6 +428,7 @@ export const createRuntimeStoreLifecycle = ({ agentManager, services, }) => {
|
|
|
406
428
|
};
|
|
407
429
|
return {
|
|
408
430
|
close: async () => {
|
|
431
|
+
services.markRuntimeClosing();
|
|
409
432
|
try {
|
|
410
433
|
// Fail in-flight workflow awaiters BEFORE their workers vanish, so the
|
|
411
434
|
// runner's `await agent(...)` rejects with a clear shutdown error
|
|
@@ -29,16 +29,22 @@ export const createRuntimeStoreWorkerMutations = ({ addWorker, configureAgentLau
|
|
|
29
29
|
},
|
|
30
30
|
deleteWorker: (workspaceId, workerId) => {
|
|
31
31
|
const activeRun = services.agentRuntime.getActiveRunByAgentId(workspaceId, workerId);
|
|
32
|
-
|
|
33
|
-
services.teamOps.notifyIssuersOfDroppedDispatches(workspaceId, workerId, 'the worker was removed');
|
|
34
|
-
}
|
|
35
|
-
catch (error) {
|
|
36
|
-
console.error('[hive] swallowed:deleteWorker.notifyDropped', error);
|
|
37
|
-
}
|
|
32
|
+
const droppedNoticeTargets = new Set();
|
|
38
33
|
runDataMutation(() => {
|
|
34
|
+
for (const dispatch of services.dispatchLedgerStore.listWorkspaceDispatches(workspaceId)) {
|
|
35
|
+
if (dispatch.toAgentId === workerId && dispatch.workflowRunId === null) {
|
|
36
|
+
services.reportOutbox.deletePendingForDispatch(dispatch.id);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
for (const targetAgentId of services.teamOps.notifyIssuersOfDroppedDispatches(workspaceId, workerId, 'the worker was removed')) {
|
|
40
|
+
droppedNoticeTargets.add(targetAgentId);
|
|
41
|
+
}
|
|
39
42
|
services.dispatchLedgerStore.deleteWorkerDispatches(workspaceId, workerId);
|
|
40
43
|
services.workspaceStore.deleteWorker(workspaceId, workerId);
|
|
41
44
|
});
|
|
45
|
+
for (const targetAgentId of droppedNoticeTargets) {
|
|
46
|
+
services.teamOps.drainReportOutbox(workspaceId, targetAgentId);
|
|
47
|
+
}
|
|
42
48
|
services.agentRuntime.deleteAgentLaunchConfig(workspaceId, workerId);
|
|
43
49
|
if (activeRun)
|
|
44
50
|
services.agentRuntime.stopAgentRun(activeRun.runId);
|
|
@@ -23,7 +23,13 @@ export const createRuntimeStoreWorkflowRuntime = (services, store) => {
|
|
|
23
23
|
return false;
|
|
24
24
|
services.workspaceStore.markTaskCancelled(workspaceId, openDispatch.toAgentId);
|
|
25
25
|
try {
|
|
26
|
-
services.agentRuntime
|
|
26
|
+
void services.agentRuntime
|
|
27
|
+
.writeCancelPrompt(workspaceId, cancelled.toAgentId, cancelled.id, reason, {
|
|
28
|
+
requireActiveRun: true,
|
|
29
|
+
})
|
|
30
|
+
.catch((error) => {
|
|
31
|
+
console.error('[hive] swallowed:workflow.cancelDispatch.forward', error);
|
|
32
|
+
});
|
|
27
33
|
}
|
|
28
34
|
catch (error) {
|
|
29
35
|
console.error('[hive] swallowed:workflow.cancelDispatch.forward', error);
|
|
@@ -46,6 +46,10 @@ export interface TeamOperationsInput {
|
|
|
46
46
|
reportOutbox: ReportOutboxStore;
|
|
47
47
|
/** Fire an outbound completion webhook (best-effort) when a worker reports. */
|
|
48
48
|
notifyWebhook?: (event: WebhookEvent) => void;
|
|
49
|
+
/** Runs durable protocol writes atomically when backed by SQLite. */
|
|
50
|
+
runDataMutation?: (mutation: () => void) => void;
|
|
51
|
+
/** True once runtime shutdown has begun; late async PTY callbacks must not touch SQLite. */
|
|
52
|
+
isRuntimeClosing?: () => boolean;
|
|
49
53
|
workflowDispatchAwaiter: WorkflowDispatchAwaiter;
|
|
50
54
|
workspaceStore: WorkspaceStore;
|
|
51
55
|
/** Auto-dismiss an ephemeral orchestrator-spawned worker after its
|
|
@@ -90,20 +94,23 @@ export interface ReportTaskResult {
|
|
|
90
94
|
forwarded: boolean;
|
|
91
95
|
pendingWarning?: string;
|
|
92
96
|
}
|
|
93
|
-
export declare const createTeamOperations: ({ agentRuntime, createDispatch, deleteDispatch, deleteMessage, findOpenDispatch, findOpenDispatchById, listOpenWorkspaceDispatches, insertMessage, markDispatchCancelled, markDispatchReportedByWorker, claimQueuedDispatch, reparkClaimedDispatch, reportOutbox, notifyWebhook, workflowDispatchAwaiter, workspaceStore, dismissEphemeralWorker, recordProtocolEvent, getFlags, }: TeamOperationsInput) => {
|
|
94
|
-
cancelTask(workspaceId: string, dispatchId: string, input: CancelTaskInput): {
|
|
97
|
+
export declare const createTeamOperations: ({ agentRuntime, createDispatch, deleteDispatch, deleteMessage, findOpenDispatch, findOpenDispatchById, listOpenWorkspaceDispatches, insertMessage, markDispatchCancelled, markDispatchReportedByWorker, claimQueuedDispatch, reparkClaimedDispatch, reportOutbox, notifyWebhook, runDataMutation, isRuntimeClosing, workflowDispatchAwaiter, workspaceStore, dismissEphemeralWorker, recordProtocolEvent, getFlags, }: TeamOperationsInput) => {
|
|
98
|
+
cancelTask(workspaceId: string, dispatchId: string, input: CancelTaskInput): Promise<{
|
|
95
99
|
dispatch: DispatchRecord;
|
|
96
100
|
forwardError: string | null;
|
|
97
101
|
forwarded: boolean;
|
|
98
|
-
}
|
|
102
|
+
}>;
|
|
99
103
|
dispatchTask: (workspaceId: string, workerId: string, text: string, input?: DispatchTaskInput) => Promise<DispatchRecord>;
|
|
100
|
-
drainReportOutbox: (workspaceId: string) =>
|
|
104
|
+
drainReportOutbox: (workspaceId: string, targetAgentId?: string) => {
|
|
105
|
+
attempted: number;
|
|
106
|
+
firstSyncError: string | null;
|
|
107
|
+
};
|
|
101
108
|
replayQueuedDispatches: (workspaceId: string, workerId: string, options?: {
|
|
102
109
|
beforeSequence?: number;
|
|
103
110
|
createdBeforeMs?: number;
|
|
104
111
|
excludeDispatchId?: string;
|
|
105
112
|
}) => void;
|
|
106
|
-
notifyIssuersOfDroppedDispatches: (workspaceId: string, workerId: string, reason: string) =>
|
|
113
|
+
notifyIssuersOfDroppedDispatches: (workspaceId: string, workerId: string, reason: string) => string[];
|
|
107
114
|
dispatchTaskByWorkerName(workspaceId: string, workerName: string, text: string, input?: DispatchTaskInput): Promise<DispatchRecord & {
|
|
108
115
|
restartedWorker: boolean;
|
|
109
116
|
}>;
|