@dorokuma/herdsman 0.9.0 → 0.11.5

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.
Files changed (122) hide show
  1. package/README.ja.md +4 -2
  2. package/README.md +5 -3
  3. package/dist/src/agent-history/antigravity-proto.js +1 -1
  4. package/dist/src/agent-history/antigravity-proto.js.map +1 -1
  5. package/dist/src/agent-history/antigravity-reader.d.ts +13 -1
  6. package/dist/src/agent-history/antigravity-reader.d.ts.map +1 -1
  7. package/dist/src/agent-history/antigravity-reader.js +22 -1
  8. package/dist/src/agent-history/antigravity-reader.js.map +1 -1
  9. package/dist/src/agent-history/discovery.d.ts +8 -2
  10. package/dist/src/agent-history/discovery.d.ts.map +1 -1
  11. package/dist/src/agent-history/discovery.js +89 -9
  12. package/dist/src/agent-history/discovery.js.map +1 -1
  13. package/dist/src/agent-history/readers.d.ts +15 -1
  14. package/dist/src/agent-history/readers.d.ts.map +1 -1
  15. package/dist/src/agent-history/readers.js +77 -31
  16. package/dist/src/agent-history/readers.js.map +1 -1
  17. package/dist/src/agent-history/service.d.ts +4 -2
  18. package/dist/src/agent-history/service.d.ts.map +1 -1
  19. package/dist/src/agent-history/service.js +22 -22
  20. package/dist/src/agent-history/service.js.map +1 -1
  21. package/dist/src/agent-history/source-fingerprint.d.ts +7 -0
  22. package/dist/src/agent-history/source-fingerprint.d.ts.map +1 -0
  23. package/dist/src/agent-history/source-fingerprint.js +26 -0
  24. package/dist/src/agent-history/source-fingerprint.js.map +1 -0
  25. package/dist/src/agent-history/text.d.ts.map +1 -1
  26. package/dist/src/agent-history/text.js +5 -0
  27. package/dist/src/agent-history/text.js.map +1 -1
  28. package/dist/src/cli/herdsman.d.ts.map +1 -1
  29. package/dist/src/cli/herdsman.js +31 -9
  30. package/dist/src/cli/herdsman.js.map +1 -1
  31. package/dist/src/daemon/agent-event-reconciler.d.ts +25 -4
  32. package/dist/src/daemon/agent-event-reconciler.d.ts.map +1 -1
  33. package/dist/src/daemon/agent-event-reconciler.js +84 -6
  34. package/dist/src/daemon/agent-event-reconciler.js.map +1 -1
  35. package/dist/src/daemon/herdr-session-watch-manager.d.ts +1 -0
  36. package/dist/src/daemon/herdr-session-watch-manager.d.ts.map +1 -1
  37. package/dist/src/daemon/herdr-session-watch-manager.js +176 -55
  38. package/dist/src/daemon/herdr-session-watch-manager.js.map +1 -1
  39. package/dist/src/daemon/observability-server.d.ts +3 -0
  40. package/dist/src/daemon/observability-server.d.ts.map +1 -1
  41. package/dist/src/daemon/observability-server.js +73 -24
  42. package/dist/src/daemon/observability-server.js.map +1 -1
  43. package/dist/src/daemon/process-manager.d.ts +41 -2
  44. package/dist/src/daemon/process-manager.d.ts.map +1 -1
  45. package/dist/src/daemon/process-manager.js +340 -19
  46. package/dist/src/daemon/process-manager.js.map +1 -1
  47. package/dist/src/daemon/service.d.ts +46 -0
  48. package/dist/src/daemon/service.d.ts.map +1 -1
  49. package/dist/src/daemon/service.js +172 -12
  50. package/dist/src/daemon/service.js.map +1 -1
  51. package/dist/src/db/agent-events.d.ts +34 -1
  52. package/dist/src/db/agent-events.d.ts.map +1 -1
  53. package/dist/src/db/agent-events.js +168 -28
  54. package/dist/src/db/agent-events.js.map +1 -1
  55. package/dist/src/db/agent-history-cache.d.ts +4 -0
  56. package/dist/src/db/agent-history-cache.d.ts.map +1 -1
  57. package/dist/src/db/agent-history-cache.js +27 -0
  58. package/dist/src/db/agent-history-cache.js.map +1 -1
  59. package/dist/src/db/agent-orchestrator-scopes.d.ts +8 -0
  60. package/dist/src/db/agent-orchestrator-scopes.d.ts.map +1 -1
  61. package/dist/src/db/agent-orchestrator-scopes.js +13 -0
  62. package/dist/src/db/agent-orchestrator-scopes.js.map +1 -1
  63. package/dist/src/db/agents.d.ts +44 -0
  64. package/dist/src/db/agents.d.ts.map +1 -1
  65. package/dist/src/db/agents.js +91 -5
  66. package/dist/src/db/agents.js.map +1 -1
  67. package/dist/src/db/client.d.ts +1 -0
  68. package/dist/src/db/client.d.ts.map +1 -1
  69. package/dist/src/db/client.js +12 -0
  70. package/dist/src/db/client.js.map +1 -1
  71. package/dist/src/db/schema.d.ts +391 -0
  72. package/dist/src/db/schema.d.ts.map +1 -1
  73. package/dist/src/db/schema.js +34 -0
  74. package/dist/src/db/schema.js.map +1 -1
  75. package/dist/src/db/status-event-plans.d.ts +62 -0
  76. package/dist/src/db/status-event-plans.d.ts.map +1 -0
  77. package/dist/src/db/status-event-plans.js +147 -0
  78. package/dist/src/db/status-event-plans.js.map +1 -0
  79. package/dist/src/herdr/pane-identity-resolver.d.ts +4 -0
  80. package/dist/src/herdr/pane-identity-resolver.d.ts.map +1 -1
  81. package/dist/src/herdr/pane-identity-resolver.js +13 -1
  82. package/dist/src/herdr/pane-identity-resolver.js.map +1 -1
  83. package/dist/src/herdr/socket-client.d.ts +2 -0
  84. package/dist/src/herdr/socket-client.d.ts.map +1 -1
  85. package/dist/src/herdr/socket-client.js +64 -20
  86. package/dist/src/herdr/socket-client.js.map +1 -1
  87. package/dist/src/observability/agent-context-service.d.ts +17 -1
  88. package/dist/src/observability/agent-context-service.d.ts.map +1 -1
  89. package/dist/src/observability/agent-context-service.js +85 -21
  90. package/dist/src/observability/agent-context-service.js.map +1 -1
  91. package/dist/src/observability/agent-index-service.d.ts +47 -2
  92. package/dist/src/observability/agent-index-service.d.ts.map +1 -1
  93. package/dist/src/observability/agent-index-service.js +1125 -115
  94. package/dist/src/observability/agent-index-service.js.map +1 -1
  95. package/dist/src/observability/agent-orchestrator-service.d.ts.map +1 -1
  96. package/dist/src/observability/agent-orchestrator-service.js +34 -12
  97. package/dist/src/observability/agent-orchestrator-service.js.map +1 -1
  98. package/dist/src/observability/contracts.d.ts +2 -1
  99. package/dist/src/observability/contracts.d.ts.map +1 -1
  100. package/dist/src/observability/contracts.js.map +1 -1
  101. package/dist/src/observability/interactive-pi.d.ts +1 -1
  102. package/dist/src/observability/interactive-pi.d.ts.map +1 -1
  103. package/dist/src/observability/interactive-pi.js +1 -1
  104. package/dist/src/observability/interactive-pi.js.map +1 -1
  105. package/dist/src/observability/schemas.d.ts +1 -0
  106. package/dist/src/observability/schemas.d.ts.map +1 -1
  107. package/dist/src/observability/schemas.js +1 -0
  108. package/dist/src/observability/schemas.js.map +1 -1
  109. package/dist/src/observability/turn-completion.d.ts +2 -1
  110. package/dist/src/observability/turn-completion.d.ts.map +1 -1
  111. package/dist/src/observability/turn-completion.js +10 -1
  112. package/dist/src/observability/turn-completion.js.map +1 -1
  113. package/dist/src/shared/unix-peercred.d.ts +14 -0
  114. package/dist/src/shared/unix-peercred.d.ts.map +1 -0
  115. package/dist/src/shared/unix-peercred.js +144 -0
  116. package/dist/src/shared/unix-peercred.js.map +1 -0
  117. package/drizzle/0008_pane_tombstones.sql +9 -0
  118. package/drizzle/0009_high_lake.sql +24 -0
  119. package/drizzle/meta/0008_snapshot.json +823 -0
  120. package/drizzle/meta/0009_snapshot.json +975 -0
  121. package/drizzle/meta/_journal.json +14 -0
  122. package/package.json +24 -22
@@ -4,6 +4,7 @@ import { env, exit } from "node:process";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { createAgentHistoryService } from "../agent-history/service.js";
6
6
  import { resolveRuntime } from "../config/runtime.js";
7
+ import { acquireDaemonLock, daemonInstanceLockPath, removeDaemonPidFile, writeDaemonPidFile, } from "../daemon/process-manager.js";
7
8
  import { AgentContextSnapshotStore } from "../db/agent-context-snapshots.js";
8
9
  import { AgentEventStore } from "../db/agent-events.js";
9
10
  import { AgentHistoryCacheStore } from "../db/agent-history-cache.js";
@@ -13,6 +14,7 @@ import { applyMigrations } from "../db/apply-migrations.js";
13
14
  import { openSqlite } from "../db/client.js";
14
15
  import { HerdrSessionStore } from "../db/herdr-sessions.js";
15
16
  import { HerdrWorkspaceStore } from "../db/herdr-workspaces.js";
17
+ import { StatusEventPlanStore } from "../db/status-event-plans.js";
16
18
  import { createHerdrSessionListRunner } from "../herdr/session-list.js";
17
19
  import { AgentContextService } from "../observability/agent-context-service.js";
18
20
  import { AgentIndexService } from "../observability/agent-index-service.js";
@@ -21,6 +23,63 @@ import { TurnCompletionRegistry } from "../observability/turn-completion.js";
21
23
  import { AgentEventReconciler } from "./agent-event-reconciler.js";
22
24
  import { HerdrSessionWatchManager } from "./herdr-session-watch-manager.js";
23
25
  import { ObservabilityRpcServer } from "./observability-server.js";
26
+ /**
27
+ * Periodic reconcile cadence. The 7-day (settled events) and 30-day (released
28
+ * scopes) TTLs only converge when AgentEventReconciler.reconcile runs, so the
29
+ * daemon drives it on a fixed 15-minute cycle instead of only at startup.
30
+ * 15 minutes is deliberately coarser than the watch manager's 10s/60s refresh
31
+ * ticks: reconcile opens sockets to every running Herdr session, while the TTLs
32
+ * it enforces are days long, so a 15-minute cycle converges promptly without
33
+ * per-tick socket traffic.
34
+ */
35
+ export const RECONCILE_INTERVAL_MS = 15 * 60 * 1000;
36
+ /**
37
+ * Runs the reconcile cycle on a fixed cadence while guaranteeing at most one
38
+ * in-flight run: a tick that fires while the previous run is still executing is
39
+ * skipped. This mirrors HerdrSessionWatchManager's in-flight tick guard. SQLite
40
+ * writes on the daemon's single shared connection are synchronous, so the only
41
+ * concurrency hazard between periodic reconcile and live event writes would be
42
+ * two reconcile loops interleaving at their await points; the in-flight guard
43
+ * prevents that, keeping event writes and reconcile serialized exactly like the
44
+ * rest of the daemon.
45
+ */
46
+ export class PeriodicReconcileScheduler {
47
+ #clearInterval;
48
+ #intervalMs;
49
+ #run;
50
+ #setInterval;
51
+ #handle;
52
+ #inFlight;
53
+ constructor(options) {
54
+ this.#clearInterval = options.clearInterval ?? clearInterval;
55
+ this.#intervalMs = options.intervalMs;
56
+ this.#run = options.run;
57
+ this.#setInterval = options.setInterval ?? setInterval;
58
+ }
59
+ start() {
60
+ if (this.#handle !== undefined)
61
+ return;
62
+ this.#handle = this.#setInterval(() => {
63
+ if (this.#inFlight)
64
+ return;
65
+ this.#inFlight = Promise.resolve()
66
+ .then(this.#run)
67
+ .catch((error) => {
68
+ console.warn("Herdsman periodic reconcile failed", error);
69
+ })
70
+ .finally(() => {
71
+ this.#inFlight = undefined;
72
+ });
73
+ }, this.#intervalMs);
74
+ }
75
+ async stop() {
76
+ if (this.#handle !== undefined) {
77
+ this.#clearInterval(this.#handle);
78
+ this.#handle = undefined;
79
+ }
80
+ await this.#inFlight?.catch(() => undefined);
81
+ }
82
+ }
24
83
  export async function runObservabilityDaemonService(input = {}) {
25
84
  const runtime = resolveRuntime({ environment: input.environment });
26
85
  applyEnvironment(runtime.environment);
@@ -49,6 +108,7 @@ export async function runObservabilityDaemonService(input = {}) {
49
108
  const agentHistoryCache = new AgentHistoryCacheStore(sqlite);
50
109
  const agentContextSnapshots = new AgentContextSnapshotStore(sqlite);
51
110
  const agentOrchestratorScopes = new AgentOrchestratorScopeStore(sqlite);
111
+ const statusEventPlans = new StatusEventPlanStore(sqlite);
52
112
  const history = createAgentHistoryService({ cache: agentHistoryCache });
53
113
  const context = new AgentContextService({
54
114
  history,
@@ -70,17 +130,23 @@ export async function runObservabilityDaemonService(input = {}) {
70
130
  agents,
71
131
  herdrSessions,
72
132
  herdrWorkspaces,
133
+ sqlite,
134
+ statusEventPlans,
73
135
  },
74
136
  turnCompletions,
75
137
  });
138
+ const sessionList = input.sessionList ?? createHerdrSessionListRunner({ env: runtime.environment });
76
139
  let connectedTerminal = (_input) => false;
77
140
  const reconciler = new AgentEventReconciler({
141
+ agentHistoryCache,
78
142
  connectedTerminal: (input) => connectedTerminal(input),
79
143
  events: agentEvents,
80
144
  scopes: agentOrchestratorScopes,
81
- sessionList: createHerdrSessionListRunner({ env: runtime.environment }),
145
+ sessionList,
146
+ statusEventPlans,
82
147
  });
83
148
  const server = new ObservabilityRpcServer({
149
+ ...(input.connectSocket !== undefined ? { connectSocket: input.connectSocket } : {}),
84
150
  context: daemonServices.context,
85
151
  history: daemonServices.history,
86
152
  orchestrator,
@@ -97,20 +163,114 @@ export async function runObservabilityDaemonService(input = {}) {
97
163
  onAgentContextChanged: (scope) => server.publishAgentContext(scope),
98
164
  onAgentEvent: (event) => server.publishAgentEvent(event),
99
165
  onAgentIndexRefreshed: (refreshed) => server.reconcileAgentLocations(refreshed),
100
- sessionList: createHerdrSessionListRunner({ env: runtime.environment }),
166
+ sessionList,
101
167
  });
102
- await server.start();
103
- await reconciler.reconcile({ releaseStaleOwners: false });
104
- await watchManager.start();
105
- console.log(`Herdsman daemon listening on ${runtime.paths.socketPath}`);
168
+ const onUnhandledRejection = (reason) => {
169
+ console.error("Herdsman daemon unhandled rejection", reason);
170
+ };
171
+ const onUncaughtException = (error) => {
172
+ console.error("Herdsman daemon uncaught exception", error);
173
+ };
174
+ process.on("unhandledRejection", onUnhandledRejection);
175
+ process.on("uncaughtException", onUncaughtException);
176
+ const currentPid = input.pid ?? process.pid;
177
+ const signalTarget = input.signalTarget ?? process;
178
+ const doExit = input.exit ?? exit;
179
+ // Register signal handlers before the first await that can block (server
180
+ // start, reconcile): once the pid file is written the daemon must always
181
+ // clean it up on a graceful shutdown, even if startup is still in progress.
182
+ let reconcileScheduler;
183
+ let releaseInstanceLock;
184
+ const releaseInstanceLockIfHeld = () => {
185
+ if (releaseInstanceLock) {
186
+ releaseInstanceLock();
187
+ releaseInstanceLock = undefined;
188
+ }
189
+ };
106
190
  const stop = async () => {
107
- await watchManager.stop();
108
- await server.stop();
109
- sqlite.close();
110
- exit(0);
191
+ let exitCode = 0;
192
+ try {
193
+ process.off("unhandledRejection", onUnhandledRejection);
194
+ process.off("uncaughtException", onUncaughtException);
195
+ index.stopWaitingHistoryRetries();
196
+ await index.drainInFlightPlans();
197
+ await reconcileScheduler?.stop();
198
+ await watchManager.stop();
199
+ await server.stop();
200
+ sqlite.close();
201
+ }
202
+ catch (error) {
203
+ console.error("Herdsman daemon shutdown failed", error);
204
+ exitCode = 1;
205
+ }
206
+ finally {
207
+ removeDaemonPidFile(runtime.paths.pidPath, currentPid);
208
+ releaseInstanceLockIfHeld();
209
+ doExit(exitCode);
210
+ }
111
211
  };
112
- process.once("SIGINT", stop);
113
- process.once("SIGTERM", stop);
212
+ signalTarget.once("SIGINT", stop);
213
+ signalTarget.once("SIGTERM", stop);
214
+ try {
215
+ // The bare daemon entrypoint (herdsman-daemon.js) takes an instance lock
216
+ // distinct from the CLI operation lock so two daemon processes cannot
217
+ // share one HERDSMAN_HOME even when neither goes through the CLI. The lock
218
+ // is released on graceful stop and on every startup failure path.
219
+ releaseInstanceLock = acquireDaemonLock(daemonInstanceLockPath(runtime.paths.pidPath), {
220
+ pid: currentPid,
221
+ });
222
+ await server.start();
223
+ writeDaemonPidFile(runtime.paths.pidPath, currentPid);
224
+ await reconciler.reconcile({ releaseStaleOwners: false });
225
+ await index.drainPendingPlans();
226
+ // Periodic reconcile keeps the 7-day/30-day TTLs converging on long-running
227
+ // daemons; the in-flight guard inside the scheduler prevents overlapping runs.
228
+ reconcileScheduler = new PeriodicReconcileScheduler({
229
+ ...(input.reconcileClearInterval === undefined
230
+ ? {}
231
+ : { clearInterval: input.reconcileClearInterval }),
232
+ intervalMs: input.reconcileIntervalMs ?? RECONCILE_INTERVAL_MS,
233
+ // Long-lived daemons must also keep retrying runtime-failed status event
234
+ // plans: drainPendingPlans is idempotent (pending/running rows only,
235
+ // per-agent serial, attempts capped) and the periodic cadence prevents a
236
+ // hot loop, so piggybacking it on the reconcile cycle completes the retry
237
+ // path that the startup-only drain leaves open.
238
+ run: async () => {
239
+ await reconciler.reconcile({ releaseStaleOwners: false });
240
+ await index.drainPendingPlans();
241
+ },
242
+ ...(input.reconcileSetInterval === undefined
243
+ ? {}
244
+ : { setInterval: input.reconcileSetInterval }),
245
+ });
246
+ reconcileScheduler.start();
247
+ await watchManager.start();
248
+ console.log(`Herdsman daemon listening on ${runtime.paths.socketPath}`);
249
+ }
250
+ catch (error) {
251
+ process.off("unhandledRejection", onUnhandledRejection);
252
+ process.off("uncaughtException", onUncaughtException);
253
+ if (typeof signalTarget.off === "function") {
254
+ signalTarget.off("SIGINT", stop);
255
+ signalTarget.off("SIGTERM", stop);
256
+ }
257
+ try {
258
+ await reconcileScheduler?.stop();
259
+ }
260
+ catch { }
261
+ try {
262
+ await watchManager.stop();
263
+ }
264
+ catch { }
265
+ try {
266
+ await server.stop();
267
+ }
268
+ catch { }
269
+ removeDaemonPidFile(runtime.paths.pidPath, currentPid);
270
+ releaseInstanceLockIfHeld();
271
+ sqlite.close();
272
+ throw error;
273
+ }
114
274
  }
115
275
  export function resolveMigrationsFolder(startDir) {
116
276
  let current = resolve(startDir);
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/daemon/service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../../src/daemon/service.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,24 @@
1
1
  import type { DatabaseSync } from "node:sqlite";
2
2
  import type { AgentEventRecord, AgentEventType, AgentIndexRecord, AgentQueryScope, CompactAgentHistory } from "../observability/contracts.js";
3
+ /**
4
+ * A delivered event is re-listed for the same owner terminal only within this
5
+ * freshness window after its last delivery attempt. The window covers the
6
+ * crash/redelivery path (an extension that missed the first delivery re-fetches
7
+ * it right after reconnecting) while preventing an unacked delivered event from
8
+ * being re-returned indefinitely on every orchestrator.get, which would feed
9
+ * duplicate presentations whenever the extension's local dedup state is lost.
10
+ */
11
+ export declare const REDELIVERY_FRESHNESS_MS = 300000;
12
+ /**
13
+ * Persist interval for the monotonic logical clock. The clock is written to
14
+ * daemon_meta only when it advances by at least this much since the last
15
+ * persist, so read-only queries do not trigger a write+fsync on every call.
16
+ * The freshness window is 300s, so a 60s persist granularity does not weaken
17
+ * the anti-rollback semantics.
18
+ */
19
+ export declare const LOGICAL_CLOCK_PERSIST_INTERVAL_MS = 60000;
20
+ export declare const LOGICAL_CLOCK_META_KEY = "logical_now_ms";
21
+ export declare function hasNonEmptyAssistantMessage(compactHistory: CompactAgentHistory | null | undefined): boolean;
3
22
  /** The single delivery predicate shared by pending discovery and acknowledgement. */
4
23
  export declare function isDeliverableAgentEvent(event: AgentEventRecord, agent: AgentIndexRecord | undefined, scope: {
5
24
  herdrSessionName: string;
@@ -50,7 +69,19 @@ export declare class AgentEventStore {
50
69
  }): void;
51
70
  listReconcileCandidates(limit?: number, afterId?: number): AgentEventRecord[];
52
71
  deleteReconcileCandidate(id: number): boolean;
53
- deleteInvalidated(): number;
72
+ /**
73
+ * Physically removes invalidated events older than the given age, measured from
74
+ * coalesce(last_attempt_at, created_at) so a delivered-then-invalidated event is
75
+ * aged from its last delivery. A short grace window lets the owner that already
76
+ * received the event ack it and advance the cursor.
77
+ */
78
+ deleteInvalidatedOlderThan(ageMs: number): number;
79
+ /**
80
+ * Physically removes terminal events (acked/failed) older than the given age.
81
+ * These statuses are never redelivered or reconciled, so a periodic TTL bounds
82
+ * the table's growth without touching pending/delivered/invalidated rows.
83
+ */
84
+ deleteSettledOlderThan(ageMs: number): number;
54
85
  ackSelfOwned(input: {
55
86
  herdrSessionName: string;
56
87
  workspaceId: string;
@@ -58,6 +89,8 @@ export declare class AgentEventStore {
58
89
  }): number;
59
90
  invalidateById(id: number, reason: string): boolean;
60
91
  latestStatusTransition(agentId: string, herdrSessionName: string): AgentEventRecord | undefined;
92
+ hasTerminalEventAfter(agentId: string, herdrSessionName: string, afterId: number): boolean;
93
+ latestTerminalEvent(agentId: string, herdrSessionName: string): AgentEventRecord | undefined;
61
94
  listAfter(input: AgentQueryScope & {
62
95
  afterEventId?: number;
63
96
  limit?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"agent-events.d.ts","sourceRoot":"","sources":["../../../src/db/agent-events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"agent-events.d.ts","sourceRoot":"","sources":["../../../src/db/agent-events.ts"],"names":[],"mappings":"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"}
@@ -1,24 +1,51 @@
1
1
  import { isInteractivePiAgent } from "../observability/interactive-pi.js";
2
+ /**
3
+ * A delivered event is re-listed for the same owner terminal only within this
4
+ * freshness window after its last delivery attempt. The window covers the
5
+ * crash/redelivery path (an extension that missed the first delivery re-fetches
6
+ * it right after reconnecting) while preventing an unacked delivered event from
7
+ * being re-returned indefinitely on every orchestrator.get, which would feed
8
+ * duplicate presentations whenever the extension's local dedup state is lost.
9
+ */
10
+ export const REDELIVERY_FRESHNESS_MS = 300_000;
11
+ /**
12
+ * Persist interval for the monotonic logical clock. The clock is written to
13
+ * daemon_meta only when it advances by at least this much since the last
14
+ * persist, so read-only queries do not trigger a write+fsync on every call.
15
+ * The freshness window is 300s, so a 60s persist granularity does not weaken
16
+ * the anti-rollback semantics.
17
+ */
18
+ export const LOGICAL_CLOCK_PERSIST_INTERVAL_MS = 60_000;
19
+ export const LOGICAL_CLOCK_META_KEY = "logical_now_ms";
20
+ export function hasNonEmptyAssistantMessage(compactHistory) {
21
+ const text = compactHistory?.lastAssistantMessage?.text;
22
+ return typeof text === "string" && text.trim().length > 0;
23
+ }
2
24
  /** The single delivery predicate shared by pending discovery and acknowledgement. */
3
25
  export function isDeliverableAgentEvent(event, agent, scope, ownerTerminalId) {
26
+ const failed = event.type === "agent.failed";
4
27
  return ((event.status === "pending" || event.status === "delivered") &&
5
28
  (event.status === "delivered" ||
6
29
  event.nextAttemptAt === null ||
7
30
  event.nextAttemptAt === undefined ||
8
31
  event.nextAttemptAt <= new Date()) &&
9
32
  (event.status === "pending" || event.deliveredToTerminalId === ownerTerminalId) &&
10
- event.agentId !== null &&
11
- agent !== undefined &&
33
+ (failed || event.agentId !== null) &&
12
34
  event.type !== "agent.status.changed" &&
13
35
  !(event.type === "agent.idle" && asRecord(event.payload).from !== "working") &&
14
- !(isInteractivePiAgent(agent) && event.type === "agent.idle") &&
15
- agent.paneId === event.paneId &&
16
- (event.paneGeneration === null || agent.paneGeneration === event.paneGeneration) &&
17
- agent.workspaceId === scope.workspaceId &&
18
36
  event.workspaceId === scope.workspaceId &&
19
37
  event.herdrSessionName === scope.herdrSessionName &&
20
38
  event.terminalId !== null &&
21
- event.terminalId !== ownerTerminalId);
39
+ event.terminalId !== ownerTerminalId &&
40
+ (failed ||
41
+ (agent !== undefined &&
42
+ !(isInteractivePiAgent(agent) && event.type === "agent.idle") &&
43
+ !(agent.agent !== "pi" &&
44
+ (event.type === "agent.idle" || event.type === "agent.done") &&
45
+ !hasNonEmptyAssistantMessage(event.compactHistory)) &&
46
+ agent.paneId === event.paneId &&
47
+ (event.paneGeneration === null || agent.paneGeneration === event.paneGeneration) &&
48
+ agent.workspaceId === scope.workspaceId)));
22
49
  }
23
50
  function asRecord(value) {
24
51
  return value !== null && typeof value === "object" && !Array.isArray(value)
@@ -27,8 +54,39 @@ function asRecord(value) {
27
54
  }
28
55
  export class AgentEventStore {
29
56
  #sqlite;
57
+ #lastPersistedLogicalNowMs;
58
+ #logicalNowMs;
30
59
  constructor(sqlite) {
31
60
  this.#sqlite = sqlite;
61
+ const row = this.#sqlite
62
+ .prepare("select value from daemon_meta where key = ?")
63
+ .get(LOGICAL_CLOCK_META_KEY);
64
+ const persisted = row ? Number(row.value) : 0;
65
+ this.#logicalNowMs = Number.isFinite(persisted) && persisted > 0 ? persisted : 0;
66
+ this.#lastPersistedLogicalNowMs = this.#logicalNowMs;
67
+ }
68
+ /**
69
+ * Monotonic logical clock: never goes backwards, even when the wall clock
70
+ * is rolled back. The in-memory value is seeded from daemon_meta on
71
+ * construction and advanced to the wall clock when the wall clock is ahead.
72
+ * Persistence is throttled so read-only queries do not write+fsync every
73
+ * call; on crash the persisted value is only ever stale (never ahead of the
74
+ * last persisted value), so the anti-rollback invariant holds across
75
+ * restarts.
76
+ */
77
+ #now() {
78
+ const wallClock = Date.now();
79
+ if (wallClock <= this.#logicalNowMs)
80
+ return this.#logicalNowMs;
81
+ this.#logicalNowMs = wallClock;
82
+ if (this.#logicalNowMs - this.#lastPersistedLogicalNowMs >= LOGICAL_CLOCK_PERSIST_INTERVAL_MS) {
83
+ this.#lastPersistedLogicalNowMs = this.#logicalNowMs;
84
+ this.#sqlite
85
+ .prepare(`insert into daemon_meta (key, value) values (?, ?)
86
+ on conflict(key) do update set value = excluded.value`)
87
+ .run(LOGICAL_CLOCK_META_KEY, String(this.#logicalNowMs));
88
+ }
89
+ return this.#logicalNowMs;
32
90
  }
33
91
  append(input) {
34
92
  const existing = input.idempotencyKey
@@ -42,7 +100,7 @@ export class AgentEventStore {
42
100
  .prepare(`insert into agent_events
43
101
  (herdr_session_name, agent_id, pane_id, pane_generation, workspace_id, terminal_id, type, payload_json, compact_history_json, idempotency_key, deliverable, status, delivery_attempts, created_at)
44
102
  values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 1, 'pending', 0, ?)`)
45
- .run(input.herdrSessionName, input.agentId ?? null, input.paneId ?? null, input.paneGeneration ?? null, input.workspaceId ?? null, input.terminalId ?? null, input.type, JSON.stringify(input.payload), input.compactHistory ? JSON.stringify(input.compactHistory) : null, input.idempotencyKey ?? null, Date.now());
103
+ .run(input.herdrSessionName, input.agentId ?? null, input.paneId ?? null, input.paneGeneration ?? null, input.workspaceId ?? null, input.terminalId ?? null, input.type, JSON.stringify(input.payload), input.compactHistory ? JSON.stringify(input.compactHistory) : null, input.idempotencyKey ?? null, this.#now());
46
104
  return this.get(Number(result.lastInsertRowid));
47
105
  }
48
106
  invalidatePane(input) {
@@ -65,8 +123,27 @@ export class AgentEventStore {
65
123
  .prepare("delete from agent_events where id = ? and status in ('pending', 'delivered')")
66
124
  .run(id).changes) > 0);
67
125
  }
68
- deleteInvalidated() {
69
- return Number(this.#sqlite.prepare("delete from agent_events where status = 'invalidated'").run().changes);
126
+ /**
127
+ * Physically removes invalidated events older than the given age, measured from
128
+ * coalesce(last_attempt_at, created_at) so a delivered-then-invalidated event is
129
+ * aged from its last delivery. A short grace window lets the owner that already
130
+ * received the event ack it and advance the cursor.
131
+ */
132
+ deleteInvalidatedOlderThan(ageMs) {
133
+ return Number(this.#sqlite
134
+ .prepare(`delete from agent_events
135
+ where status = 'invalidated' and coalesce(last_attempt_at, created_at) < ?`)
136
+ .run(Date.now() - ageMs).changes);
137
+ }
138
+ /**
139
+ * Physically removes terminal events (acked/failed) older than the given age.
140
+ * These statuses are never redelivered or reconciled, so a periodic TTL bounds
141
+ * the table's growth without touching pending/delivered/invalidated rows.
142
+ */
143
+ deleteSettledOlderThan(ageMs) {
144
+ return Number(this.#sqlite
145
+ .prepare(`delete from agent_events where status in ('acked', 'failed') and created_at < ?`)
146
+ .run(Date.now() - ageMs).changes);
70
147
  }
71
148
  ackSelfOwned(input) {
72
149
  return Number(this.#sqlite
@@ -88,16 +165,35 @@ export class AgentEventStore {
88
165
  .get(agentId, herdrSessionName);
89
166
  return row ? mapAgentEvent(row) : undefined;
90
167
  }
168
+ hasTerminalEventAfter(agentId, herdrSessionName, afterId) {
169
+ const row = this.#sqlite
170
+ .prepare(`select 1 from agent_events
171
+ where agent_id = ? and herdr_session_name = ? and id > ?
172
+ and type in ('agent.idle', 'agent.done', 'agent.blocked')
173
+ limit 1`)
174
+ .get(agentId, herdrSessionName, afterId);
175
+ return Boolean(row);
176
+ }
177
+ latestTerminalEvent(agentId, herdrSessionName) {
178
+ const row = this.#sqlite
179
+ .prepare(`select * from agent_events
180
+ where agent_id = ? and herdr_session_name = ?
181
+ and type in ('agent.idle', 'agent.done', 'agent.blocked')
182
+ order by id desc limit 1`)
183
+ .get(agentId, herdrSessionName);
184
+ return row ? mapAgentEvent(row) : undefined;
185
+ }
91
186
  listAfter(input) {
92
187
  const clauses = [
93
188
  "id > ?",
94
- "((status = 'pending' and (next_attempt_at is null or next_attempt_at <= ?)) or (status = 'delivered' and delivered_to_terminal_id = ? and id > ?))",
189
+ "((status = 'pending' and (next_attempt_at is null or next_attempt_at <= ?)) or (status = 'delivered' and delivered_to_terminal_id = ? and id > ? and last_attempt_at >= ?))",
95
190
  ];
96
191
  const params = [
97
192
  input.afterEventId ?? 0,
98
- Date.now(),
193
+ this.#now(),
99
194
  input.ownerTerminalId ?? null,
100
195
  input.afterEventId ?? 0,
196
+ this.#now() - REDELIVERY_FRESHNESS_MS,
101
197
  ];
102
198
  if (input.herdrSessionName) {
103
199
  clauses.push("herdr_session_name = ?");
@@ -128,15 +224,16 @@ export class AgentEventStore {
128
224
  for (let page = 0; page < 50; page += 1) {
129
225
  const params = [
130
226
  afterEventId,
131
- Date.now(),
227
+ this.#now(),
132
228
  input.ownerTerminalId,
229
+ this.#now() - REDELIVERY_FRESHNESS_MS,
133
230
  input.herdrSessionName,
134
231
  input.workspaceId,
135
232
  input.ownerTerminalId,
136
233
  ];
137
234
  const rows = this.#sqlite
138
235
  .prepare(`select * from agent_events
139
- where id > ? and ((status = 'pending' and (next_attempt_at is null or next_attempt_at <= ?)) or (status = 'delivered' and delivered_to_terminal_id = ?)) and herdr_session_name = ? and workspace_id = ?
236
+ where id > ? and ((status = 'pending' and (next_attempt_at is null or next_attempt_at <= ?)) or (status = 'delivered' and delivered_to_terminal_id = ? and last_attempt_at >= ?)) and herdr_session_name = ? and workspace_id = ?
140
237
  and terminal_id is not null and terminal_id != ? and agent_id is not null
141
238
  ${agentFilter}
142
239
  order by id asc limit 1000`)
@@ -158,14 +255,14 @@ export class AgentEventStore {
158
255
  }
159
256
  reservePending(terminalId, limit = 100, ids) {
160
257
  return this.#transaction(() => {
161
- const now = Date.now();
258
+ const now = this.#now();
162
259
  const idClause = ids && ids.length > 0 ? `and id in (${ids.map(() => "?").join(",")})` : "";
163
- const params = [now, terminalId];
260
+ const params = [now, terminalId, now - REDELIVERY_FRESHNESS_MS];
164
261
  if (ids && ids.length > 0)
165
262
  params.push(...ids);
166
263
  params.push(limit);
167
264
  const rows = this.#sqlite
168
- .prepare(`select * from agent_events where ((status = 'pending' and (next_attempt_at is null or next_attempt_at <= ?)) or (status = 'delivered' and delivered_to_terminal_id = ?)) ${idClause} order by id asc limit ?`)
265
+ .prepare(`select * from agent_events where ((status = 'pending' and (next_attempt_at is null or next_attempt_at <= ?)) or (status = 'delivered' and delivered_to_terminal_id = ? and last_attempt_at >= ?)) ${idClause} order by id asc limit ?`)
169
266
  .all(...params);
170
267
  for (const row of rows) {
171
268
  this.#sqlite
@@ -185,18 +282,61 @@ export class AgentEventStore {
185
282
  }
186
283
  reclaimDelivered(timeoutMs) {
187
284
  return this.#transaction(() => {
188
- const result = this.#sqlite
189
- .prepare(`update agent_events set status = case when delivery_attempts >= 10 then 'failed' else 'pending' end, deliverable = case when delivery_attempts >= 10 then 0 else 1 end, last_failure_code = case when delivery_attempts >= 10 then 'DELIVERY_ATTEMPTS_EXCEEDED' else last_failure_code end, delivered_to_terminal_id = null, next_attempt_at = null where status = 'delivered' and last_attempt_at < ?
285
+ const cutoff = this.#now() - timeoutMs;
286
+ // The delivered event's own agent row (matched by pane) is the pane-open
287
+ // guard: it decides whether branch (a) and branch (b) apply.
288
+ const agentPaneOpen = `exists (
289
+ select 1 from agents
290
+ where agents.id = agent_events.agent_id
291
+ and agents.herdr_session_name = agent_events.herdr_session_name
292
+ and agents.workspace_id = agent_events.workspace_id
293
+ and agents.pane_id = agent_events.pane_id
294
+ )`;
295
+ // Branch (b): the agent pane is closed/retired, so the delivered event is
296
+ // invalidated instead of being reclaimed and redelivered.
297
+ const invalidated = this.#sqlite
298
+ .prepare(`update agent_events
299
+ set deliverable = 0, status = 'invalidated', invalidated_reason = 'PANE_CLOSED_RECLAIM'
300
+ where status = 'delivered' and last_attempt_at < ? and not ${agentPaneOpen}`)
301
+ .run(cutoff).changes;
302
+ // Branch (c): the pane is still open but the delivery terminal no longer
303
+ // holds the orchestrator scope (owner_terminal_id != delivered_to_terminal_id
304
+ // or no owner), so reclaim immediately without waiting for last_attempt_at
305
+ // timeout. If the scope is still owned by the delivery terminal (branch a),
306
+ // the event remains in-flight with the owner.
307
+ const reclaimWhere = `status = 'delivered'
308
+ and ${agentPaneOpen}
190
309
  and not exists (
191
- select 1 from agents
192
- inner join herdr_sessions on herdr_sessions.name = agents.herdr_session_name
193
- where herdr_sessions.running = 1
194
- and agents.herdr_session_name = agent_events.herdr_session_name
195
- and agents.terminal_id = agent_events.delivered_to_terminal_id
196
- and agents.agent_status = 'working'
197
- )`)
198
- .run(Date.now() - timeoutMs);
199
- return Number(result.changes);
310
+ select 1 from agent_orchestrator_scopes
311
+ where agent_orchestrator_scopes.herdr_session_name = agent_events.herdr_session_name
312
+ and agent_orchestrator_scopes.workspace_id = agent_events.workspace_id
313
+ and agent_orchestrator_scopes.owner_terminal_id = agent_events.delivered_to_terminal_id
314
+ )`;
315
+ const exceeded = this.#sqlite
316
+ .prepare(`select id, agent_id, herdr_session_name, workspace_id, delivery_attempts
317
+ from agent_events
318
+ where ${reclaimWhere} and delivery_attempts >= 10`)
319
+ .all();
320
+ const reclaimed = this.#sqlite
321
+ .prepare(`update agent_events
322
+ set status = case when delivery_attempts >= 10 then 'failed' else 'pending' end,
323
+ deliverable = case when delivery_attempts >= 10 then 0 else 1 end,
324
+ last_failure_code = case when delivery_attempts >= 10 then 'DELIVERY_ATTEMPTS_EXCEEDED' else last_failure_code end,
325
+ delivered_to_terminal_id = null,
326
+ next_attempt_at = null
327
+ where ${reclaimWhere}`)
328
+ .run().changes;
329
+ for (const row of exceeded) {
330
+ console.error("Herdsman agent event delivery attempts exceeded", {
331
+ eventId: row.id,
332
+ agentId: row.agent_id,
333
+ herdrSessionName: row.herdr_session_name,
334
+ workspaceId: row.workspace_id,
335
+ deliveryAttempts: row.delivery_attempts,
336
+ lastFailureCode: "DELIVERY_ATTEMPTS_EXCEEDED",
337
+ });
338
+ }
339
+ return Number(invalidated) + Number(reclaimed);
200
340
  });
201
341
  }
202
342
  markAcked(id, scope) {