@pellux/goodvibes-sdk 0.18.41 → 0.18.42

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.
@@ -1,4 +1,5 @@
1
1
  import { PersistentStore } from '@pellux/goodvibes-sdk/platform/state/persistent-store';
2
+ import type { RuntimeEventBus } from '../runtime/events/index.js';
2
3
  import { RouteBindingManager } from '../channels/index.js';
3
4
  import type { AutomationRouteBinding } from '@pellux/goodvibes-sdk/platform/automation/routes';
4
5
  import type { SharedSessionCompletion, SharedSessionContinuationRunner, SharedSessionInputRecord } from '@pellux/goodvibes-sdk/platform/control-plane/session-intents';
@@ -15,14 +16,38 @@ export declare class SharedSessionBroker {
15
16
  private eventPublisher;
16
17
  private continuationRunner;
17
18
  private loaded;
19
+ private _gcInterval;
20
+ private _busUnsubs;
21
+ /** Default idle threshold for zero-message sessions (ms). */
22
+ private readonly _idleEmptyMs;
23
+ /** Default idle threshold for sessions with content (ms). */
24
+ private readonly _idleLongMs;
25
+ /**
26
+ * @param config.idleEmptyMs - Idle timeout for empty (0-message) sessions (default: 10 minutes).
27
+ * @param config.idleLongMs - Idle timeout for sessions with content (default: 24 hours).
28
+ */
18
29
  constructor(config: {
19
30
  readonly store?: PersistentStore<SharedSessionStoreSnapshot>;
20
31
  readonly storePath?: string;
21
32
  readonly routeBindings: RouteBindingManager;
22
33
  readonly agentStatusProvider: SharedSessionAgentStatusProvider;
23
34
  readonly messageSender: SharedSessionMessageSender;
35
+ readonly idleEmptyMs?: number;
36
+ readonly idleLongMs?: number;
24
37
  });
25
38
  setEventPublisher(publisher: SharedSessionEventPublisher | null): void;
39
+ /**
40
+ * Wire the broker to a RuntimeEventBus so agent terminal events automatically
41
+ * reconcile session inputs and task state.
42
+ *
43
+ * Call once after both the broker and the bus are constructed. Returns an
44
+ * unsubscribe function that tears down the subscriptions.
45
+ *
46
+ * @param bus - The active RuntimeEventBus.
47
+ * @param sessionResolver - Maps agentId → sessionId for the active session.
48
+ * Return `null` when the agent is not associated with a shared session.
49
+ */
50
+ attachRuntimeBus(bus: RuntimeEventBus, sessionResolver: (agentId: string) => string | null): () => void;
26
51
  setContinuationRunner(runner: SharedSessionContinuationRunner | null): void;
27
52
  start(): Promise<void>;
28
53
  listSessions(limit?: number): SharedSessionRecord[];
@@ -69,5 +94,18 @@ export declare class SharedSessionBroker {
69
94
  private finalizeAgentInputs;
70
95
  private runQueuedFollowUp;
71
96
  private refreshPendingInputCount;
97
+ /**
98
+ * Periodic idle-session GC sweep.
99
+ *
100
+ * Policy:
101
+ * - Sessions with messageCount === 0 AND no active agent AND idle longer than
102
+ * `_idleEmptyMs` (default 10min) are closed with reason `idle-empty`.
103
+ * - Sessions with messageCount > 0 AND no active agent AND idle longer than
104
+ * `_idleLongMs` (default 24h) are closed with reason `idle-long`.
105
+ *
106
+ * "Idle" is measured from `lastActivityAt` (updated on createInput/bindAgent/
107
+ * appendMessage). Sessions with an active agent are never GC'd.
108
+ */
109
+ private _gcSweep;
72
110
  }
73
111
  //# sourceMappingURL=session-broker.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"session-broker.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/control-plane/session-broker.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-broker.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/control-plane/session-broker.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,16 @@ export class SharedSessionBroker {
16
16
  eventPublisher = null;
17
17
  continuationRunner = null;
18
18
  loaded = false;
19
+ _gcInterval = null;
20
+ _busUnsubs = [];
21
+ /** Default idle threshold for zero-message sessions (ms). */
22
+ _idleEmptyMs;
23
+ /** Default idle threshold for sessions with content (ms). */
24
+ _idleLongMs;
25
+ /**
26
+ * @param config.idleEmptyMs - Idle timeout for empty (0-message) sessions (default: 10 minutes).
27
+ * @param config.idleLongMs - Idle timeout for sessions with content (default: 24 hours).
28
+ */
19
29
  constructor(config) {
20
30
  if (!config.store && !config.storePath) {
21
31
  throw new Error('SharedSessionBroker requires an explicit store or storePath.');
@@ -25,10 +35,50 @@ export class SharedSessionBroker {
25
35
  this.routeBindings = config.routeBindings;
26
36
  this.agentStatusProvider = config.agentStatusProvider;
27
37
  this.messageSender = config.messageSender;
38
+ this._idleEmptyMs = config.idleEmptyMs ?? 10 * 60 * 1000; // 10 min
39
+ this._idleLongMs = config.idleLongMs ?? 24 * 60 * 60 * 1000; // 24 h
28
40
  }
29
41
  setEventPublisher(publisher) {
30
42
  this.eventPublisher = publisher;
31
43
  }
44
+ /**
45
+ * Wire the broker to a RuntimeEventBus so agent terminal events automatically
46
+ * reconcile session inputs and task state.
47
+ *
48
+ * Call once after both the broker and the bus are constructed. Returns an
49
+ * unsubscribe function that tears down the subscriptions.
50
+ *
51
+ * @param bus - The active RuntimeEventBus.
52
+ * @param sessionResolver - Maps agentId → sessionId for the active session.
53
+ * Return `null` when the agent is not associated with a shared session.
54
+ */
55
+ attachRuntimeBus(bus, sessionResolver) {
56
+ const onCompleted = bus.on('AGENT_COMPLETED', (envelope) => {
57
+ const sessionId = sessionResolver(envelope.payload.agentId);
58
+ if (!sessionId)
59
+ return;
60
+ void this.completeAgent(sessionId, envelope.payload.agentId, envelope.payload.output ?? '', { status: 'completed', durationMs: envelope.payload.durationMs });
61
+ });
62
+ const onFailed = bus.on('AGENT_FAILED', (envelope) => {
63
+ const sessionId = sessionResolver(envelope.payload.agentId);
64
+ if (!sessionId)
65
+ return;
66
+ void this.completeAgent(sessionId, envelope.payload.agentId, envelope.payload.error, { status: 'failed', durationMs: envelope.payload.durationMs });
67
+ });
68
+ const onCancelled = bus.on('AGENT_CANCELLED', (envelope) => {
69
+ const sessionId = sessionResolver(envelope.payload.agentId);
70
+ if (!sessionId)
71
+ return;
72
+ void this.completeAgent(sessionId, envelope.payload.agentId, envelope.payload.reason ?? 'cancelled', { status: 'cancelled' });
73
+ });
74
+ this._busUnsubs.push(onCompleted, onFailed, onCancelled);
75
+ return () => {
76
+ onCompleted();
77
+ onFailed();
78
+ onCancelled();
79
+ this._busUnsubs = this._busUnsubs.filter((fn) => fn !== onCompleted && fn !== onFailed && fn !== onCancelled);
80
+ };
81
+ }
32
82
  setContinuationRunner(runner) {
33
83
  this.continuationRunner = runner;
34
84
  }
@@ -50,6 +100,9 @@ export class SharedSessionBroker {
50
100
  this.inputs.set(sessionId, bucket);
51
101
  }
52
102
  this.loaded = true;
103
+ if (!this._gcInterval) {
104
+ this._gcInterval = setInterval(() => { this._gcSweep(); }, 60_000);
105
+ }
53
106
  }
54
107
  listSessions(limit = 100) {
55
108
  return sortSessions(this.sessions.values()).slice(0, Math.max(1, limit));
@@ -112,6 +165,7 @@ export class SharedSessionBroker {
112
165
  updatedAt: now,
113
166
  lastMessageAt: undefined,
114
167
  closedAt: undefined,
168
+ lastActivityAt: now,
115
169
  messageCount: 0,
116
170
  pendingInputCount: 0,
117
171
  routeIds,
@@ -175,6 +229,7 @@ export class SharedSessionBroker {
175
229
  activeAgentId: agentId,
176
230
  lastAgentId: agentId,
177
231
  updatedAt: Date.now(),
232
+ lastActivityAt: Date.now(),
178
233
  };
179
234
  this.sessions.set(sessionId, updated);
180
235
  const claimed = this.claimNextQueuedInput(sessionId, agentId);
@@ -306,6 +361,7 @@ export class SharedSessionBroker {
306
361
  messageCount: bucket.length,
307
362
  lastMessageAt: message.createdAt,
308
363
  updatedAt: message.createdAt,
364
+ lastActivityAt: message.createdAt,
309
365
  };
310
366
  this.sessions.set(sessionId, updated);
311
367
  }
@@ -665,4 +721,49 @@ export class SharedSessionBroker {
665
721
  updatedAt: Date.now(),
666
722
  });
667
723
  }
724
+ /**
725
+ * Periodic idle-session GC sweep.
726
+ *
727
+ * Policy:
728
+ * - Sessions with messageCount === 0 AND no active agent AND idle longer than
729
+ * `_idleEmptyMs` (default 10min) are closed with reason `idle-empty`.
730
+ * - Sessions with messageCount > 0 AND no active agent AND idle longer than
731
+ * `_idleLongMs` (default 24h) are closed with reason `idle-long`.
732
+ *
733
+ * "Idle" is measured from `lastActivityAt` (updated on createInput/bindAgent/
734
+ * appendMessage). Sessions with an active agent are never GC'd.
735
+ */
736
+ _gcSweep() {
737
+ const now = Date.now();
738
+ for (const [sessionId, session] of this.sessions.entries()) {
739
+ if (session.status !== 'active')
740
+ continue;
741
+ if (session.activeAgentId)
742
+ continue; // live agent — leave it
743
+ const idle = now - session.lastActivityAt;
744
+ let reason = null;
745
+ if (session.messageCount === 0 && idle >= this._idleEmptyMs) {
746
+ reason = 'idle-empty';
747
+ }
748
+ else if (session.messageCount > 0 && idle >= this._idleLongMs) {
749
+ reason = 'idle-long';
750
+ }
751
+ if (!reason)
752
+ continue;
753
+ const closed = {
754
+ ...session,
755
+ status: 'closed',
756
+ activeAgentId: undefined,
757
+ updatedAt: now,
758
+ closedAt: now,
759
+ };
760
+ this.sessions.set(sessionId, closed);
761
+ this.publishUpdate('session-closed', { ...closed, reason });
762
+ }
763
+ // Persist after a sweep only when something changed.
764
+ const anyChanged = [...this.sessions.values()].some((s) => s.status === 'closed' && s.closedAt && now - s.closedAt < 2_000);
765
+ if (anyChanged) {
766
+ void this.persist();
767
+ }
768
+ }
668
769
  }
@@ -34,6 +34,12 @@ export interface SharedSessionRecord {
34
34
  readonly updatedAt: number;
35
35
  readonly lastMessageAt?: number;
36
36
  readonly closedAt?: number;
37
+ /**
38
+ * Epoch ms of the most recent activity on this session.
39
+ * Updated on every createInput, message post, bindAgent, and heartbeat.
40
+ * Used by the idle-session GC sweep to decide when to close ghost sessions.
41
+ */
42
+ readonly lastActivityAt: number;
37
43
  readonly messageCount: number;
38
44
  readonly pendingInputCount: number;
39
45
  readonly routeIds: readonly string[];
@@ -1 +1 @@
1
- {"version":3,"file":"session-types.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/control-plane/session-types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"session-types.d.ts","sourceRoot":"","sources":["../../../../src/_internal/platform/control-plane/session-types.ts"],"names":[],"mappings":"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"}
@@ -7,6 +7,7 @@
7
7
  */
8
8
  import type { RuntimeStore } from '../../store/index.js';
9
9
  import type { AgentLifecycleState } from '@pellux/goodvibes-sdk/platform/runtime/store/domains/agents';
10
+ import type { RuntimeEventBus } from '../../events/index.js';
10
11
  /** Owner context for an agent task. */
11
12
  export interface AgentOwner {
12
13
  /** Session ID that spawned this agent. */
@@ -31,6 +32,18 @@ export declare class AgentTaskAdapter {
31
32
  private readonly _taskToAgent;
32
33
  private readonly _dispatch;
33
34
  constructor(_store: RuntimeStore);
35
+ /**
36
+ * Subscribe to AGENT_COMPLETED / AGENT_FAILED / AGENT_CANCELLED events on the
37
+ * RuntimeEventBus and propagate them into the task registry.
38
+ *
39
+ * This is the authoritative wire that ensures task records reach terminal state
40
+ * once their backing agent finishes — without it, tasks stay stuck in 'running'
41
+ * indefinitely (the bug observed in daemon state at 192.168.0.61:3421).
42
+ *
43
+ * @param bus - The active RuntimeEventBus instance.
44
+ * @returns An unsubscribe function that removes all three listeners.
45
+ */
46
+ attachRuntimeBus(bus: RuntimeEventBus): () => void;
34
47
  /**
35
48
  * Wrap an agent session as a RuntimeTask.
36
49
  *
@@ -1 +1 @@
1
- {"version":3,"file":"agent-adapter.d.ts","sourceRoot":"","sources":["../../../../../../src/_internal/platform/runtime/tasks/adapters/agent-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,sBAAsB,CAAC;AAEzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AAEvG,uCAAuC;AACvC,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB;AAkCD;;;;;;;;;;GAUG;AACH,qBAAa,gBAAgB;IAQf,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPnC,+BAA+B;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6B;IAC1D,+BAA+B;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6B;IAE1D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;gBAEd,MAAM,EAAE,YAAY;IAMjD;;;;;;;OAOG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM;IA4BnE;;;;;OAKG;IACH,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAmBzE;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IASjC;;;;;OAKG;IACH,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,GAAE,UAAoC,GAAG,IAAI;IAyBlG,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,eAAe;CAkBxB"}
1
+ {"version":3,"file":"agent-adapter.d.ts","sourceRoot":"","sources":["../../../../../../src/_internal/platform/runtime/tasks/adapters/agent-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAkB,MAAM,sBAAsB,CAAC;AAEzE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6DAA6D,CAAC;AACvG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAE7D,uCAAuC;AACvC,MAAM,WAAW,UAAU;IACzB,0CAA0C;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB;AAkCD;;;;;;;;;;GAUG;AACH,qBAAa,gBAAgB;IAQf,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPnC,+BAA+B;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6B;IAC1D,+BAA+B;IAC/B,OAAO,CAAC,QAAQ,CAAC,YAAY,CAA6B;IAE1D,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAiB;gBAEd,MAAM,EAAE,YAAY;IAMjD;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,GAAG,EAAE,eAAe,GAAG,MAAM,IAAI;IAkClD;;;;;;;OAOG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,GAAG,MAAM;IA4BnE;;;;;OAKG;IACH,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,mBAAmB,GAAG,IAAI;IAmBzE;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IASjC;;;;;OAKG;IACH,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,KAAK,GAAE,UAAoC,GAAG,IAAI;IAyBlG,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,eAAe;CAkBxB"}
@@ -61,6 +61,43 @@ export class AgentTaskAdapter {
61
61
  this._store = _store;
62
62
  this._dispatch = createDomainDispatch(_store);
63
63
  }
64
+ // ── Runtime bus wiring ──────────────────────────────────────────────────────
65
+ /**
66
+ * Subscribe to AGENT_COMPLETED / AGENT_FAILED / AGENT_CANCELLED events on the
67
+ * RuntimeEventBus and propagate them into the task registry.
68
+ *
69
+ * This is the authoritative wire that ensures task records reach terminal state
70
+ * once their backing agent finishes — without it, tasks stay stuck in 'running'
71
+ * indefinitely (the bug observed in daemon state at 192.168.0.61:3421).
72
+ *
73
+ * @param bus - The active RuntimeEventBus instance.
74
+ * @returns An unsubscribe function that removes all three listeners.
75
+ */
76
+ attachRuntimeBus(bus) {
77
+ const onCompleted = bus.on('AGENT_COMPLETED', (envelope) => {
78
+ const taskId = this._agentToTask.get(envelope.payload.agentId);
79
+ if (taskId === undefined)
80
+ return; // not a tracked agent — no-op
81
+ this.handleAgentStateChange(envelope.payload.agentId, 'completed');
82
+ });
83
+ const onFailed = bus.on('AGENT_FAILED', (envelope) => {
84
+ const taskId = this._agentToTask.get(envelope.payload.agentId);
85
+ if (taskId === undefined)
86
+ return;
87
+ this.handleAgentStateChange(envelope.payload.agentId, 'failed');
88
+ });
89
+ const onCancelled = bus.on('AGENT_CANCELLED', (envelope) => {
90
+ const taskId = this._agentToTask.get(envelope.payload.agentId);
91
+ if (taskId === undefined)
92
+ return;
93
+ this.handleAgentStateChange(envelope.payload.agentId, 'cancelled');
94
+ });
95
+ return () => {
96
+ onCompleted();
97
+ onFailed();
98
+ onCancelled();
99
+ };
100
+ }
64
101
  // ── Core API ────────────────────────────────────────────────────────────────
65
102
  /**
66
103
  * Wrap an agent session as a RuntimeTask.
@@ -1,6 +1,6 @@
1
1
  import { readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
- let version = '0.18.41';
3
+ let version = '0.18.42';
4
4
  try {
5
5
  const pkg = JSON.parse(readFileSync(join(import.meta.dir, '..', '..', 'package.json'), 'utf-8'));
6
6
  version = pkg.version ?? version;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pellux/goodvibes-sdk",
3
- "version": "0.18.41",
3
+ "version": "0.18.42",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/mgd34msu/goodvibes-sdk.git"