@cleocode/core 2026.3.57 → 2026.3.59

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 (136) hide show
  1. package/dist/agents/agent-registry.d.ts +206 -0
  2. package/dist/agents/agent-registry.d.ts.map +1 -0
  3. package/dist/agents/agent-schema.d.ts.map +1 -1
  4. package/dist/agents/execution-learning.d.ts +223 -0
  5. package/dist/agents/execution-learning.d.ts.map +1 -0
  6. package/dist/agents/health-monitor.d.ts +161 -0
  7. package/dist/agents/health-monitor.d.ts.map +1 -0
  8. package/dist/agents/index.d.ts +4 -1
  9. package/dist/agents/index.d.ts.map +1 -1
  10. package/dist/agents/retry.d.ts +57 -4
  11. package/dist/agents/retry.d.ts.map +1 -1
  12. package/dist/backfill/index.d.ts +83 -0
  13. package/dist/backfill/index.d.ts.map +1 -0
  14. package/dist/bootstrap.d.ts +1 -1
  15. package/dist/config.d.ts +47 -0
  16. package/dist/config.d.ts.map +1 -1
  17. package/dist/index.d.ts +2 -1
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +6985 -5068
  20. package/dist/index.js.map +4 -4
  21. package/dist/intelligence/adaptive-validation.d.ts +151 -0
  22. package/dist/intelligence/adaptive-validation.d.ts.map +1 -0
  23. package/dist/intelligence/impact.d.ts +34 -1
  24. package/dist/intelligence/impact.d.ts.map +1 -1
  25. package/dist/intelligence/index.d.ts +7 -2
  26. package/dist/intelligence/index.d.ts.map +1 -1
  27. package/dist/intelligence/types.d.ts +60 -0
  28. package/dist/intelligence/types.d.ts.map +1 -1
  29. package/dist/internal.d.ts +8 -4
  30. package/dist/internal.d.ts.map +1 -1
  31. package/dist/lib/index.d.ts +10 -0
  32. package/dist/lib/index.d.ts.map +1 -0
  33. package/dist/lib/retry.d.ts +128 -0
  34. package/dist/lib/retry.d.ts.map +1 -0
  35. package/dist/nexus/sharing/index.d.ts +48 -2
  36. package/dist/nexus/sharing/index.d.ts.map +1 -1
  37. package/dist/sessions/session-enforcement.d.ts.map +1 -1
  38. package/dist/stats/index.d.ts +1 -0
  39. package/dist/stats/index.d.ts.map +1 -1
  40. package/dist/stats/workflow-telemetry.d.ts +89 -0
  41. package/dist/stats/workflow-telemetry.d.ts.map +1 -0
  42. package/dist/store/brain-schema.d.ts.map +1 -1
  43. package/dist/store/converters.d.ts.map +1 -1
  44. package/dist/store/cross-db-cleanup.d.ts +93 -0
  45. package/dist/store/cross-db-cleanup.d.ts.map +1 -0
  46. package/dist/store/db-helpers.d.ts.map +1 -1
  47. package/dist/store/migration-sqlite.d.ts.map +1 -1
  48. package/dist/store/sqlite-data-accessor.d.ts.map +1 -1
  49. package/dist/store/sqlite.d.ts.map +1 -1
  50. package/dist/store/task-store.d.ts.map +1 -1
  51. package/dist/store/tasks-schema.d.ts +18 -3
  52. package/dist/store/tasks-schema.d.ts.map +1 -1
  53. package/dist/store/validation-schemas.d.ts +32 -0
  54. package/dist/store/validation-schemas.d.ts.map +1 -1
  55. package/dist/tasks/add.d.ts +10 -1
  56. package/dist/tasks/add.d.ts.map +1 -1
  57. package/dist/tasks/complete.d.ts.map +1 -1
  58. package/dist/tasks/enforcement.d.ts +22 -0
  59. package/dist/tasks/enforcement.d.ts.map +1 -0
  60. package/dist/tasks/epic-enforcement.d.ts +199 -0
  61. package/dist/tasks/epic-enforcement.d.ts.map +1 -0
  62. package/dist/tasks/index.d.ts +1 -1
  63. package/dist/tasks/index.d.ts.map +1 -1
  64. package/dist/tasks/pipeline-stage.d.ts +181 -0
  65. package/dist/tasks/pipeline-stage.d.ts.map +1 -0
  66. package/dist/tasks/update.d.ts +2 -0
  67. package/dist/tasks/update.d.ts.map +1 -1
  68. package/migrations/drizzle-brain/20260321000001_t033-brain-indexes/migration.sql +12 -0
  69. package/migrations/drizzle-brain/20260321000001_t033-brain-indexes/snapshot.json +1232 -0
  70. package/migrations/drizzle-tasks/20260321000000_t033-connection-health/migration.sql +518 -0
  71. package/migrations/drizzle-tasks/20260321000000_t033-connection-health/snapshot.json +4312 -0
  72. package/migrations/drizzle-tasks/20260321000002_t060-pipeline-stage-binding/migration.sql +82 -0
  73. package/migrations/drizzle-tasks/20260321000002_t060-pipeline-stage-binding/snapshot.json +9 -0
  74. package/package.json +5 -5
  75. package/schemas/config.schema.json +37 -1547
  76. package/src/__tests__/sharing.test.ts +24 -0
  77. package/src/agents/__tests__/agent-registry.test.ts +351 -0
  78. package/src/agents/__tests__/execution-learning.test.ts +684 -0
  79. package/src/agents/__tests__/health-monitor.test.ts +332 -0
  80. package/src/agents/__tests__/registry.test.ts +30 -2
  81. package/src/agents/agent-registry.ts +394 -0
  82. package/src/agents/agent-schema.ts +5 -0
  83. package/src/agents/execution-learning.ts +675 -0
  84. package/src/agents/health-monitor.ts +279 -0
  85. package/src/agents/index.ts +37 -1
  86. package/src/agents/retry.ts +57 -4
  87. package/src/backfill/index.ts +309 -0
  88. package/src/bootstrap.ts +1 -1
  89. package/src/config.ts +126 -0
  90. package/src/index.ts +8 -1
  91. package/src/intelligence/__tests__/adaptive-validation.test.ts +694 -0
  92. package/src/intelligence/__tests__/impact.test.ts +165 -1
  93. package/src/intelligence/adaptive-validation.ts +764 -0
  94. package/src/intelligence/impact.ts +203 -0
  95. package/src/intelligence/index.ts +19 -0
  96. package/src/intelligence/types.ts +76 -0
  97. package/src/internal.ts +39 -0
  98. package/src/lib/__tests__/retry.test.ts +321 -0
  99. package/src/lib/index.ts +16 -0
  100. package/src/lib/retry.ts +224 -0
  101. package/src/lifecycle/__tests__/chain-store.test.ts +7 -0
  102. package/src/lifecycle/__tests__/tessera-engine.test.ts +52 -0
  103. package/src/nexus/sharing/index.ts +142 -2
  104. package/src/sessions/__tests__/session-edge-cases.test.ts +24 -1
  105. package/src/sessions/session-enforcement.ts +13 -2
  106. package/src/stats/index.ts +7 -0
  107. package/src/stats/workflow-telemetry.ts +502 -0
  108. package/src/store/__tests__/migration-safety.test.ts +3 -0
  109. package/src/store/__tests__/session-store.test.ts +132 -1
  110. package/src/store/__tests__/task-store.test.ts +22 -1
  111. package/src/store/__tests__/test-db-helper.ts +29 -2
  112. package/src/store/brain-schema.ts +4 -1
  113. package/src/store/converters.ts +2 -0
  114. package/src/store/cross-db-cleanup.ts +192 -0
  115. package/src/store/db-helpers.ts +2 -0
  116. package/src/store/migration-sqlite.ts +6 -0
  117. package/src/store/sqlite-data-accessor.ts +20 -28
  118. package/src/store/sqlite.ts +14 -2
  119. package/src/store/task-store.ts +6 -0
  120. package/src/store/tasks-schema.ts +59 -20
  121. package/src/tasks/__tests__/add.test.ts +16 -0
  122. package/src/tasks/__tests__/complete-unblocks.test.ts +10 -1
  123. package/src/tasks/__tests__/complete.test.ts +11 -2
  124. package/src/tasks/__tests__/epic-enforcement.test.ts +909 -0
  125. package/src/tasks/__tests__/minimal-test.test.ts +28 -0
  126. package/src/tasks/__tests__/pipeline-stage.test.ts +403 -0
  127. package/src/tasks/__tests__/update.test.ts +40 -6
  128. package/src/tasks/add.ts +128 -2
  129. package/src/tasks/complete.ts +29 -17
  130. package/src/tasks/enforcement.ts +127 -0
  131. package/src/tasks/epic-enforcement.ts +364 -0
  132. package/src/tasks/index.ts +1 -0
  133. package/src/tasks/pipeline-stage.ts +293 -0
  134. package/src/tasks/update.ts +62 -0
  135. package/templates/config.template.json +34 -111
  136. package/templates/global-config.template.json +24 -40
@@ -0,0 +1,206 @@
1
+ /**
2
+ * Agent registry with capacity tracking for load balancing.
3
+ *
4
+ * Provides task-count-based capacity queries, specialization lookup,
5
+ * and performance recording on top of the existing `agent_instances` schema.
6
+ *
7
+ * Capacity model: each agent has a maximum of {@link MAX_TASKS_PER_AGENT}
8
+ * concurrent tasks. "Remaining capacity" is that constant minus the number of
9
+ * tasks currently assigned to an active agent instance.
10
+ *
11
+ * Specializations are stored as a `specializations` array inside the agent's
12
+ * `metadata_json` column. Use {@link updateAgentSpecializations} to write them.
13
+ *
14
+ * Performance recording delegates to the existing `recordAgentExecution`
15
+ * function in `execution-learning.ts` and wraps it with a simpler metrics
16
+ * interface suited for load-balancer callers.
17
+ *
18
+ * @module agents/agent-registry
19
+ * @task T041
20
+ * @epic T038
21
+ */
22
+ import { type AgentInstanceRow, type AgentType } from './agent-schema.js';
23
+ import { type AgentExecutionOutcome } from './execution-learning.js';
24
+ /**
25
+ * Maximum number of tasks that can be concurrently assigned to one agent.
26
+ * Used as the upper bound for task-count-based capacity calculation.
27
+ */
28
+ export declare const MAX_TASKS_PER_AGENT = 5;
29
+ /**
30
+ * Task-count-based capacity for a single agent instance.
31
+ */
32
+ export interface AgentCapacity {
33
+ /** Agent instance ID. */
34
+ agentId: string;
35
+ /** Agent type classification. */
36
+ agentType: AgentType;
37
+ /** Current status of the agent. */
38
+ status: AgentInstanceRow['status'];
39
+ /** Number of tasks currently assigned to this agent. */
40
+ activeTasks: number;
41
+ /** Number of additional tasks this agent can accept (max - active). */
42
+ remainingCapacity: number;
43
+ /** Maximum tasks this agent can hold ({@link MAX_TASKS_PER_AGENT}). */
44
+ maxCapacity: number;
45
+ /** Whether this agent can accept new tasks. */
46
+ available: boolean;
47
+ }
48
+ /**
49
+ * Metrics provided when recording agent performance.
50
+ */
51
+ export interface AgentPerformanceMetrics {
52
+ /** Task ID that was processed. */
53
+ taskId: string;
54
+ /** Task type label (e.g. "epic", "task", "subtask"). */
55
+ taskType: string;
56
+ /** Outcome of the agent's work on the task. */
57
+ outcome: AgentExecutionOutcome;
58
+ /** Optional task labels for richer pattern classification. */
59
+ taskLabels?: string[];
60
+ /** Session ID the agent was operating under. */
61
+ sessionId?: string;
62
+ /** Duration of execution in milliseconds. */
63
+ durationMs?: number;
64
+ /** Error message if outcome is "failure". */
65
+ errorMessage?: string;
66
+ /** Error classification if outcome is "failure". */
67
+ errorType?: 'retriable' | 'permanent' | 'unknown';
68
+ }
69
+ /**
70
+ * Get task-count-based remaining capacity for an agent.
71
+ *
72
+ * Remaining capacity = {@link MAX_TASKS_PER_AGENT} minus the number of tasks
73
+ * currently routed to this agent instance (tracked via the `task_id` column
74
+ * on `agent_instances` — each instance handles one task at a time; child agents
75
+ * spawned by an orchestrator appear as sibling rows referencing the same
76
+ * `parent_agent_id`).
77
+ *
78
+ * For capacity purposes the "active tasks" count is derived from the number of
79
+ * non-terminal sibling rows that share the same `parent_agent_id` as this
80
+ * agent, plus 1 for the agent's own current task when `task_id` is set.
81
+ *
82
+ * @remarks
83
+ * Agents in terminal states (`stopped`, `crashed`) always return 0 remaining
84
+ * capacity because they cannot accept work.
85
+ *
86
+ * @param agentId - Agent instance ID (agt_...) to check
87
+ * @param cwd - Working directory used to resolve tasks.db path
88
+ * @returns Capacity breakdown or null if the agent does not exist
89
+ *
90
+ * @example
91
+ * ```ts
92
+ * const cap = await getAgentCapacity('agt_20260321120000_ab12cd', '/project');
93
+ * if (cap && cap.available) {
94
+ * console.log(`Agent can take ${cap.remainingCapacity} more tasks`);
95
+ * }
96
+ * ```
97
+ */
98
+ export declare function getAgentCapacity(agentId: string, cwd?: string): Promise<AgentCapacity | null>;
99
+ /**
100
+ * List all non-terminal agents sorted by remaining task capacity (descending).
101
+ *
102
+ * Returns agents with the most available slots first, enabling callers to
103
+ * select the least-loaded agent for new work assignment.
104
+ *
105
+ * @remarks
106
+ * Only agents in `active` or `idle` states are included — `starting` agents
107
+ * are excluded because they may not yet be ready to accept work.
108
+ * Terminal agents (`stopped`, `crashed`) are always omitted.
109
+ *
110
+ * @param agentType - Optional filter to limit results to one agent type
111
+ * @param cwd - Working directory used to resolve tasks.db path
112
+ * @returns Array of capacity entries sorted highest remaining capacity first
113
+ *
114
+ * @example
115
+ * ```ts
116
+ * const agents = await getAgentsByCapacity('executor', '/project');
117
+ * const best = agents[0]; // most available slots
118
+ * if (best && best.available) {
119
+ * await assignTask(best.agentId, taskId);
120
+ * }
121
+ * ```
122
+ */
123
+ export declare function getAgentsByCapacity(agentType?: AgentType, cwd?: string): Promise<AgentCapacity[]>;
124
+ /**
125
+ * Get the specialization/skills list for an agent.
126
+ *
127
+ * Specializations are stored as a string array under the `specializations`
128
+ * key in the agent's `metadata_json` column. An empty array is returned when
129
+ * the field is absent or the agent is not found.
130
+ *
131
+ * @remarks
132
+ * Write specializations with {@link updateAgentSpecializations} when
133
+ * registering or updating an agent. The metadata column is a free-form JSON
134
+ * blob — specializations are one namespaced key inside it.
135
+ *
136
+ * @param agentId - Agent instance ID (agt_...)
137
+ * @param cwd - Working directory used to resolve tasks.db path
138
+ * @returns Array of specialization strings (empty if none recorded)
139
+ *
140
+ * @example
141
+ * ```ts
142
+ * const skills = await getAgentSpecializations('agt_20260321120000_ab12cd', '/project');
143
+ * // ['typescript', 'testing', 'documentation']
144
+ * if (skills.includes('typescript')) {
145
+ * console.log('Agent can handle TypeScript tasks');
146
+ * }
147
+ * ```
148
+ */
149
+ export declare function getAgentSpecializations(agentId: string, cwd?: string): Promise<string[]>;
150
+ /**
151
+ * Update the specializations list stored in an agent's metadata.
152
+ *
153
+ * Merges the new list into the existing `metadata_json` object, preserving
154
+ * any other keys already present. Returns the updated specializations list,
155
+ * or null if the agent was not found.
156
+ *
157
+ * @remarks
158
+ * This is a write-side companion to {@link getAgentSpecializations}. Call it
159
+ * after {@link registerAgent} to record the skills an agent was spawned with.
160
+ *
161
+ * @param agentId - Agent instance ID (agt_...)
162
+ * @param specializations - New specializations list (replaces existing)
163
+ * @param cwd - Working directory used to resolve tasks.db path
164
+ * @returns Updated specializations list, or null if agent not found
165
+ *
166
+ * @example
167
+ * ```ts
168
+ * await updateAgentSpecializations(
169
+ * 'agt_20260321120000_ab12cd',
170
+ * ['typescript', 'testing'],
171
+ * '/project',
172
+ * );
173
+ * ```
174
+ */
175
+ export declare function updateAgentSpecializations(agentId: string, specializations: string[], cwd?: string): Promise<string[] | null>;
176
+ /**
177
+ * Record agent performance metrics to the BRAIN execution history.
178
+ *
179
+ * Translates a simplified {@link AgentPerformanceMetrics} object into the
180
+ * {@link AgentExecutionEvent} format expected by `execution-learning.ts` and
181
+ * delegates to {@link recordAgentExecution}. The agent type is resolved from
182
+ * the `agent_instances` table so callers only need to supply the agent ID.
183
+ *
184
+ * @remarks
185
+ * Recording is best-effort — if brain.db is unavailable the error is swallowed
186
+ * and null is returned, consistent with the rest of the execution-learning
187
+ * module. Agent lifecycle code is never disrupted by a brain write failure.
188
+ *
189
+ * @param agentId - Agent instance ID whose performance is being recorded
190
+ * @param metrics - Performance metrics for the task that was processed
191
+ * @param cwd - Working directory used to resolve tasks.db and brain.db paths
192
+ * @returns The brain decision ID if recorded, null on failure or not found
193
+ *
194
+ * @example
195
+ * ```ts
196
+ * const decisionId = await recordAgentPerformance('agt_20260321120000_ab12cd', {
197
+ * taskId: 'T041',
198
+ * taskType: 'task',
199
+ * outcome: 'success',
200
+ * durationMs: 4200,
201
+ * sessionId: 'ses_20260321_abc',
202
+ * }, '/project');
203
+ * ```
204
+ */
205
+ export declare function recordAgentPerformance(agentId: string, metrics: AgentPerformanceMetrics, cwd?: string): Promise<string | null>;
206
+ //# sourceMappingURL=agent-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-registry.d.ts","sourceRoot":"","sources":["../../src/agents/agent-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,SAAS,EAAkB,MAAM,mBAAmB,CAAC;AAC1F,OAAO,EAEL,KAAK,qBAAqB,EAE3B,MAAM,yBAAyB,CAAC;AAOjC;;;GAGG;AACH,eAAO,MAAM,mBAAmB,IAAI,CAAC;AAMrC;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,SAAS,EAAE,SAAS,CAAC;IACrB,mCAAmC;IACnC,MAAM,EAAE,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACnC,wDAAwD;IACxD,WAAW,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,uEAAuE;IACvE,WAAW,EAAE,MAAM,CAAC;IACpB,+CAA+C;IAC/C,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,QAAQ,EAAE,MAAM,CAAC;IACjB,+CAA+C;IAC/C,OAAO,EAAE,qBAAqB,CAAC;IAC/B,8DAA8D;IAC9D,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,gDAAgD;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,SAAS,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;CACnD;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CA+C/B;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAsB,mBAAmB,CACvC,SAAS,CAAC,EAAE,SAAS,EACrB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,aAAa,EAAE,CAAC,CAc1B;AAiBD;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAkB9F;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,EAAE,EACzB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,CAwB1B;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,uBAAuB,EAChC,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAyBxB"}
@@ -1 +1 @@
1
- {"version":3,"file":"agent-schema.d.ts","sourceRoot":"","sources":["../../src/agents/agent-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,iEAAiE;AACjE,eAAO,MAAM,uBAAuB,wEAO1B,CAAC;AAEX,4CAA4C;AAC5C,eAAO,MAAM,WAAW,uGAQd,CAAC;AAMX,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyB1B,CAAC;AAMF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBzB,CAAC;AAMF,MAAM,MAAM,gBAAgB,GAAG,OAAO,cAAc,CAAC,YAAY,CAAC;AAClE,MAAM,MAAM,mBAAmB,GAAG,OAAO,cAAc,CAAC,YAAY,CAAC;AACrE,MAAM,MAAM,gBAAgB,GAAG,OAAO,aAAa,CAAC,YAAY,CAAC;AACjE,MAAM,MAAM,mBAAmB,GAAG,OAAO,aAAa,CAAC,YAAY,CAAC;AACpE,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC3E,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AACrD,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC"}
1
+ {"version":3,"file":"agent-schema.d.ts","sourceRoot":"","sources":["../../src/agents/agent-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AASH,iEAAiE;AACjE,eAAO,MAAM,uBAAuB,wEAO1B,CAAC;AAEX,4CAA4C;AAC5C,eAAO,MAAM,WAAW,uGAQd,CAAC;AAMX,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8B1B,CAAC;AAMF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBzB,CAAC;AAMF,MAAM,MAAM,gBAAgB,GAAG,OAAO,cAAc,CAAC,YAAY,CAAC;AAClE,MAAM,MAAM,mBAAmB,GAAG,OAAO,cAAc,CAAC,YAAY,CAAC;AACrE,MAAM,MAAM,gBAAgB,GAAG,OAAO,aAAa,CAAC,YAAY,CAAC;AACjE,MAAM,MAAM,mBAAmB,GAAG,OAAO,aAAa,CAAC,YAAY,CAAC;AACpE,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAC3E,MAAM,MAAM,SAAS,GAAG,CAAC,OAAO,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AACrD,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC"}
@@ -0,0 +1,223 @@
1
+ /**
2
+ * Agent Execution Learning — Agent dimension BRAIN integration.
3
+ *
4
+ * Tracks which agent types succeed or fail on which task types, logs agent
5
+ * decisions to brain_decisions with structured context, provides queries to
6
+ * retrieve agent performance history, and implements basic self-healing by
7
+ * recording failure patterns as brain_observations and surfacing healing
8
+ * suggestions when the same failure pattern recurs.
9
+ *
10
+ * This module bridges the agent registry (tasks.db) with the cognitive
11
+ * memory layer (brain.db) without introducing circular dependencies:
12
+ * - Tasks.db agent tables: agent_instances, agent_error_log (agent-schema.ts)
13
+ * - Brain.db tables: brain_decisions, brain_patterns, brain_observations
14
+ *
15
+ * All brain.db writes are best-effort — failures are silently swallowed so
16
+ * agent lifecycle events never fail due to a brain.db write error.
17
+ *
18
+ * @module agents/execution-learning
19
+ * @task T034
20
+ * @epic T029
21
+ */
22
+ import type { BrainDataAccessor } from '../store/brain-accessor.js';
23
+ import type { BrainDecisionRow, BrainObservationRow, BrainPatternRow } from '../store/brain-schema.js';
24
+ import type { AgentType } from './agent-schema.js';
25
+ /**
26
+ * The outcome of an agent's execution attempt on a task.
27
+ */
28
+ export type AgentExecutionOutcome = 'success' | 'failure' | 'partial';
29
+ /**
30
+ * Context recorded when an agent completes or fails a task.
31
+ */
32
+ export interface AgentExecutionEvent {
33
+ /** Agent instance ID (agt_...). */
34
+ agentId: string;
35
+ /** Agent type classification. */
36
+ agentType: AgentType;
37
+ /** Task ID that was attempted. */
38
+ taskId: string;
39
+ /** Task type: 'epic' | 'task' | 'subtask'. */
40
+ taskType: string;
41
+ /** Task labels for richer pattern classification. */
42
+ taskLabels?: string[];
43
+ /** Execution outcome. */
44
+ outcome: AgentExecutionOutcome;
45
+ /** Error message if outcome is 'failure'. */
46
+ errorMessage?: string;
47
+ /** Error classification if outcome is 'failure'. */
48
+ errorType?: 'retriable' | 'permanent' | 'unknown';
49
+ /** Session ID the agent was running under. */
50
+ sessionId?: string;
51
+ /** Duration of execution in milliseconds (optional). */
52
+ durationMs?: number;
53
+ }
54
+ /**
55
+ * Summary of an agent type's execution performance on a task type.
56
+ */
57
+ export interface AgentPerformanceSummary {
58
+ /** Agent type. */
59
+ agentType: AgentType;
60
+ /** Task type this summary is for. */
61
+ taskType: string;
62
+ /** Total execution attempts tracked. */
63
+ totalAttempts: number;
64
+ /** Number of successful attempts. */
65
+ successCount: number;
66
+ /** Number of failed attempts. */
67
+ failureCount: number;
68
+ /** Success rate [0.0 – 1.0]. */
69
+ successRate: number;
70
+ /** Most recent attempt outcome. */
71
+ lastOutcome: AgentExecutionOutcome | null;
72
+ /** Timestamp of the most recent tracked decision. */
73
+ lastSeenAt: string | null;
74
+ }
75
+ /**
76
+ * A self-healing suggestion derived from failure pattern history.
77
+ */
78
+ export interface HealingSuggestion {
79
+ /** Pattern ID from brain_patterns. */
80
+ patternId: string;
81
+ /** Human-readable description of the failure pattern. */
82
+ failurePattern: string;
83
+ /** Times this pattern has been seen. */
84
+ frequency: number;
85
+ /** Mitigation / suggested next action. */
86
+ suggestion: string;
87
+ /** How confident the system is in this suggestion [0.0 – 1.0]. */
88
+ confidence: number;
89
+ }
90
+ /**
91
+ * Record an agent execution event to brain_decisions.
92
+ *
93
+ * Each event becomes a `tactical` decision entry describing which agent type
94
+ * handled which task type and whether it succeeded. This gives the BRAIN
95
+ * system a queryable history of agent-task execution for pattern extraction.
96
+ *
97
+ * The call is best-effort — if brain.db is unavailable the error is swallowed
98
+ * and null is returned so agent lifecycle code is never disrupted.
99
+ *
100
+ * @param event - Execution event to record
101
+ * @param cwd - Working directory (resolves brain.db path)
102
+ * @returns The stored decision row, or null on failure
103
+ */
104
+ export declare function recordAgentExecution(event: AgentExecutionEvent, cwd?: string): Promise<BrainDecisionRow | null>;
105
+ /**
106
+ * Internal implementation that accepts a pre-constructed accessor.
107
+ * Separated for testability without touching the real file system.
108
+ *
109
+ * @internal
110
+ */
111
+ export declare function _recordAgentExecutionWithAccessor(event: AgentExecutionEvent, brain: BrainDataAccessor): Promise<BrainDecisionRow | null>;
112
+ /**
113
+ * Retrieve agent execution performance history from brain_decisions.
114
+ *
115
+ * Queries all `tactical` decisions recorded by `recordAgentExecution` and
116
+ * aggregates them into per-(agentType, taskType) performance summaries.
117
+ *
118
+ * @param filters - Optional filters to narrow results
119
+ * @param cwd - Working directory
120
+ * @returns Array of performance summaries sorted by agentType then taskType
121
+ */
122
+ export declare function getAgentPerformanceHistory(filters?: {
123
+ agentType?: AgentType;
124
+ taskType?: string;
125
+ limit?: number;
126
+ }, cwd?: string): Promise<AgentPerformanceSummary[]>;
127
+ /**
128
+ * Internal implementation with injected accessor for testability.
129
+ *
130
+ * @internal
131
+ */
132
+ export declare function _getAgentPerformanceHistoryWithAccessor(filters: {
133
+ agentType?: AgentType;
134
+ taskType?: string;
135
+ limit?: number;
136
+ }, brain: BrainDataAccessor): Promise<AgentPerformanceSummary[]>;
137
+ /**
138
+ * Record a task failure pattern to brain_patterns.
139
+ *
140
+ * When a task fails, the (agentType, taskType, errorType) combination is
141
+ * stored as a `failure` pattern in brain.db. On subsequent failures matching
142
+ * the same combination, the frequency counter is incremented and the success
143
+ * rate updated. This data is what powers `getSelfHealingSuggestions`.
144
+ *
145
+ * The call is best-effort and never throws.
146
+ *
147
+ * @param event - A failure execution event (outcome must be 'failure')
148
+ * @param cwd - Working directory
149
+ * @returns The upserted pattern row, or null on error
150
+ */
151
+ export declare function recordFailurePattern(event: AgentExecutionEvent, cwd?: string): Promise<BrainPatternRow | null>;
152
+ /**
153
+ * Internal implementation with injected accessor.
154
+ *
155
+ * @internal
156
+ */
157
+ export declare function _recordFailurePatternWithAccessor(event: AgentExecutionEvent, brain: BrainDataAccessor): Promise<BrainPatternRow | null>;
158
+ /**
159
+ * Store a healing strategy observation to brain_observations.
160
+ *
161
+ * When a failure pattern reaches a significant frequency threshold (≥ 3),
162
+ * a `change` observation is recorded to represent the healing action
163
+ * recommended for future recurrences of the same pattern.
164
+ *
165
+ * The call is best-effort and never throws.
166
+ *
167
+ * @param event - The failure event that triggered healing
168
+ * @param strategy - Human-readable healing strategy description
169
+ * @param cwd - Working directory
170
+ * @returns The stored observation row, or null on error
171
+ */
172
+ export declare function storeHealingStrategy(event: AgentExecutionEvent, strategy: string, cwd?: string): Promise<BrainObservationRow | null>;
173
+ /**
174
+ * Internal implementation with injected accessor.
175
+ *
176
+ * @internal
177
+ */
178
+ export declare function _storeHealingStrategyWithAccessor(event: AgentExecutionEvent, strategy: string, brain: BrainDataAccessor): Promise<BrainObservationRow | null>;
179
+ /**
180
+ * Get self-healing suggestions for a given agent type and task type.
181
+ *
182
+ * Queries brain_patterns for known failure patterns matching the
183
+ * (agentType, taskType) combination and returns healing suggestions
184
+ * ordered by frequency (most-seen first).
185
+ *
186
+ * Returns an empty array if no failure patterns are found or brain.db
187
+ * is unavailable.
188
+ *
189
+ * @param agentType - The agent type to check
190
+ * @param taskType - The task type to check
191
+ * @param cwd - Working directory
192
+ * @returns Array of healing suggestions, highest frequency first
193
+ */
194
+ export declare function getSelfHealingSuggestions(agentType: AgentType, taskType: string, cwd?: string): Promise<HealingSuggestion[]>;
195
+ /**
196
+ * Internal implementation with injected accessor.
197
+ *
198
+ * @internal
199
+ */
200
+ export declare function _getSelfHealingSuggestionsWithAccessor(agentType: AgentType, taskType: string, brain: BrainDataAccessor): Promise<HealingSuggestion[]>;
201
+ /**
202
+ * Full agent lifecycle event processor.
203
+ *
204
+ * Convenience function that:
205
+ * 1. Records the execution event to brain_decisions
206
+ * 2. On failure: records/updates the failure pattern in brain_patterns
207
+ * 3. On failure with frequency ≥ 3: stores a healing strategy observation
208
+ *
209
+ * Returns a structured result with the recorded IDs and any healing
210
+ * suggestions that now apply.
211
+ *
212
+ * All operations are best-effort — the call never throws.
213
+ *
214
+ * @param event - The execution event
215
+ * @param cwd - Working directory
216
+ */
217
+ export declare function processAgentLifecycleEvent(event: AgentExecutionEvent, cwd?: string): Promise<{
218
+ decisionId: string | null;
219
+ patternId: string | null;
220
+ observationId: string | null;
221
+ healingSuggestions: HealingSuggestion[];
222
+ }>;
223
+ //# sourceMappingURL=execution-learning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execution-learning.d.ts","sourceRoot":"","sources":["../../src/agents/execution-learning.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAGH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAEpE,OAAO,KAAK,EACV,gBAAgB,EAChB,mBAAmB,EACnB,eAAe,EAChB,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAMnD;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,iCAAiC;IACjC,SAAS,EAAE,SAAS,CAAC;IACrB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,yBAAyB;IACzB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,6CAA6C;IAC7C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,SAAS,CAAC,EAAE,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;IAClD,8CAA8C;IAC9C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,kBAAkB;IAClB,SAAS,EAAE,SAAS,CAAC;IACrB,qCAAqC;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,aAAa,EAAE,MAAM,CAAC;IACtB,qCAAqC;IACrC,YAAY,EAAE,MAAM,CAAC;IACrB,iCAAiC;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,gCAAgC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,mCAAmC;IACnC,WAAW,EAAE,qBAAqB,GAAG,IAAI,CAAC;IAC1C,qDAAqD;IACrD,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,sCAAsC;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,yDAAyD;IACzD,cAAc,EAAE,MAAM,CAAC;IACvB,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,UAAU,EAAE,MAAM,CAAC;IACnB,kEAAkE;IAClE,UAAU,EAAE,MAAM,CAAC;CACpB;AA8BD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,mBAAmB,EAC1B,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAQlC;AAED;;;;;GAKG;AACH,wBAAsB,iCAAiC,CACrD,KAAK,EAAE,mBAAmB,EAC1B,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CAgDlC;AAMD;;;;;;;;;GASG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CACX,EACN,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAOpC;AAED;;;;GAIG;AACH,wBAAsB,uCAAuC,CAC3D,OAAO,EAAE;IACP,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,EACD,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,uBAAuB,EAAE,CAAC,CAoFpC;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,mBAAmB,EAC1B,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CASjC;AAED;;;;GAIG;AACH,wBAAsB,iCAAiC,CACrD,KAAK,EAAE,mBAAmB,EAC1B,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAoDjC;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,mBAAmB,EAC1B,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CASrC;AAED;;;;GAIG;AACH,wBAAsB,iCAAiC,CACrD,KAAK,EAAE,mBAAmB,EAC1B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAgCrC;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,yBAAyB,CAC7C,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAO9B;AAED;;;;GAIG;AACH,wBAAsB,sCAAsC,CAC1D,SAAS,EAAE,SAAS,EACpB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,iBAAiB,GACvB,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAe9B;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,0BAA0B,CAC9C,KAAK,EAAE,mBAAmB,EAC1B,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC;IACT,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;CACzC,CAAC,CA2CD"}
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Agent Health Monitoring -- Heartbeat and crash detection for live agent instances.
3
+ *
4
+ * Provides the public-facing health API specified by T039:
5
+ * - `recordHeartbeat` — update last_heartbeat for a live agent
6
+ * - `checkAgentHealth` — check health of a specific agent by ID
7
+ * - `detectStaleAgents` — find agents whose heartbeat is older than threshold
8
+ * - `detectCrashedAgents` — find active agents with no heartbeat for >3 min
9
+ *
10
+ * These functions delegate to the lower-level `registry.ts` primitives
11
+ * (`heartbeat`, `checkAgentHealth`, `listAgentInstances`) and add the
12
+ * named, task-spec-aligned surface required for T039.
13
+ *
14
+ * @module agents/health-monitor
15
+ * @task T039
16
+ * @epic T038
17
+ */
18
+ import type { AgentInstanceRow, AgentInstanceStatus } from './agent-schema.js';
19
+ /** Default heartbeat interval (30 seconds) per BRAIN spec. */
20
+ export declare const HEARTBEAT_INTERVAL_MS = 30000;
21
+ /** Default staleness threshold: 3 minutes without a heartbeat. */
22
+ export declare const STALE_THRESHOLD_MS: number;
23
+ /**
24
+ * Health status of a specific agent instance.
25
+ */
26
+ export interface AgentHealthStatus {
27
+ /** Agent instance ID. */
28
+ agentId: string;
29
+ /** Current DB status. */
30
+ status: AgentInstanceStatus;
31
+ /** ISO timestamp of the last recorded heartbeat. */
32
+ lastHeartbeat: string;
33
+ /** Milliseconds since the last heartbeat (at call time). */
34
+ heartbeatAgeMs: number;
35
+ /** Whether the agent is considered healthy (heartbeat within threshold). */
36
+ healthy: boolean;
37
+ /** Whether the agent is considered stale (heartbeat older than threshold). */
38
+ stale: boolean;
39
+ /** Threshold used for staleness determination (ms). */
40
+ thresholdMs: number;
41
+ }
42
+ /**
43
+ * Record a heartbeat for an agent instance.
44
+ *
45
+ * Updates `last_heartbeat` to the current time and returns the agent's
46
+ * current {@link AgentInstanceStatus}. Returns `null` if the agent does not
47
+ * exist or is already in a terminal state (`stopped` / `crashed`).
48
+ *
49
+ * This is the primary mechanism by which long-running agents signal liveness.
50
+ * Call this every {@link HEARTBEAT_INTERVAL_MS} (30 s) from the agent loop.
51
+ *
52
+ * @param agentId - The agent instance ID (e.g. `agt_20260322120000_a1b2c3`)
53
+ * @param cwd - Working directory used to resolve the tasks.db path (optional)
54
+ * @returns The agent's current status, or `null` if not found / terminal
55
+ *
56
+ * @remarks
57
+ * Terminal agents (`stopped`, `crashed`) will NOT have their heartbeat
58
+ * updated — the existing status is returned as-is so callers can detect
59
+ * external shutdown signals.
60
+ *
61
+ * @example
62
+ * ```ts
63
+ * // Inside the agent's main loop:
64
+ * const heartbeatTimer = setInterval(async () => {
65
+ * const status = await recordHeartbeat(agentId);
66
+ * if (status === 'stopped' || status === null) {
67
+ * // Orchestrator shut us down — exit cleanly
68
+ * clearInterval(heartbeatTimer);
69
+ * process.exit(0);
70
+ * }
71
+ * }, HEARTBEAT_INTERVAL_MS);
72
+ * ```
73
+ */
74
+ export declare function recordHeartbeat(agentId: string, cwd?: string): Promise<AgentInstanceStatus | null>;
75
+ /**
76
+ * Check the health of a specific agent instance by ID.
77
+ *
78
+ * Queries the agent's current record and returns a structured
79
+ * {@link AgentHealthStatus} describing staleness, heartbeat age, and
80
+ * whether the agent is considered healthy relative to `thresholdMs`.
81
+ *
82
+ * Returns `null` if the agent ID is not found in the database.
83
+ *
84
+ * @param agentId - The agent instance ID to check
85
+ * @param thresholdMs - Staleness threshold in milliseconds (default: 3 minutes)
86
+ * @param cwd - Working directory used to resolve the tasks.db path (optional)
87
+ * @returns {@link AgentHealthStatus} or `null` if the agent does not exist
88
+ *
89
+ * @remarks
90
+ * Returns null if the agent is not found. A non-null result includes
91
+ * staleness status based on the threshold comparison.
92
+ *
93
+ * @example
94
+ * ```ts
95
+ * const health = await checkAgentHealth('agt_20260322120000_a1b2c3');
96
+ * if (health && health.stale) {
97
+ * console.log(`Agent stale for ${health.heartbeatAgeMs}ms — presumed crashed`);
98
+ * }
99
+ * ```
100
+ */
101
+ export declare function checkAgentHealth(agentId: string, thresholdMs?: number, cwd?: string): Promise<AgentHealthStatus | null>;
102
+ /**
103
+ * Find all non-terminal agents whose last heartbeat is older than `thresholdMs`.
104
+ *
105
+ * "Stale" means an agent with status `starting`, `active`, or `idle` has
106
+ * not sent a heartbeat within the threshold window. This is a precursor to
107
+ * crash detection — a stale agent may still recover if it is under heavy load.
108
+ *
109
+ * Agents with status `stopped` or `crashed` are excluded — they are already
110
+ * in a terminal state and do not participate in the heartbeat protocol.
111
+ *
112
+ * @param thresholdMs - Staleness threshold in ms (default: 3 minutes / 180 000 ms)
113
+ * @param cwd - Working directory used to resolve the tasks.db path (optional)
114
+ * @returns Array of {@link AgentHealthStatus} for each stale agent, sorted by
115
+ * heartbeat age descending (most-stale first)
116
+ *
117
+ * @remarks
118
+ * The default threshold matches the crash-detection window specified in T039:
119
+ * "timeout detection after 3 minutes".
120
+ *
121
+ * @example
122
+ * ```ts
123
+ * const stale = await detectStaleAgents();
124
+ * for (const s of stale) {
125
+ * console.log(`${s.agentId} has been stale for ${s.heartbeatAgeMs / 1000}s`);
126
+ * }
127
+ * ```
128
+ */
129
+ export declare function detectStaleAgents(thresholdMs?: number, cwd?: string): Promise<AgentHealthStatus[]>;
130
+ /**
131
+ * Find agents with status `active` whose heartbeat has been silent for
132
+ * longer than `thresholdMs`, and mark them as `crashed` in the database.
133
+ *
134
+ * An agent is considered crashed when it:
135
+ * 1. Has status `active` (not `idle`, `starting`, `stopped`, or `crashed`)
136
+ * 2. Has not sent a heartbeat for longer than `thresholdMs`
137
+ *
138
+ * Each detected agent is immediately marked `crashed` via {@link markCrashed},
139
+ * incrementing its error count and writing a reason to `agent_error_log`.
140
+ *
141
+ * @param thresholdMs - Crash threshold in ms (default: 3 minutes / 180 000 ms)
142
+ * @param cwd - Working directory used to resolve the tasks.db path (optional)
143
+ * @returns Array of agent instance rows for each agent that was just marked
144
+ * `crashed`, sorted by last heartbeat ascending (oldest first).
145
+ *
146
+ * @remarks
147
+ * This function is WRITE-side: it mutates the database. Callers should run
148
+ * it on a schedule (e.g. every 60 s) from an orchestrator or health watchdog.
149
+ * For a read-only view, use {@link detectStaleAgents} instead.
150
+ *
151
+ * @example
152
+ * ```ts
153
+ * // Inside an orchestrator health watchdog:
154
+ * const crashed = await detectCrashedAgents();
155
+ * if (crashed.length > 0) {
156
+ * logger.warn({ crashed: crashed.map(a => a.id) }, 'Agents marked crashed');
157
+ * }
158
+ * ```
159
+ */
160
+ export declare function detectCrashedAgents(thresholdMs?: number, cwd?: string): Promise<AgentInstanceRow[]>;
161
+ //# sourceMappingURL=health-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"health-monitor.d.ts","sourceRoot":"","sources":["../../src/agents/health-monitor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAO/E,8DAA8D;AAC9D,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAE5C,kEAAkE;AAClE,eAAO,MAAM,kBAAkB,QAAa,CAAC;AAS7C;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,yBAAyB;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,yBAAyB;IACzB,MAAM,EAAE,mBAAmB,CAAC;IAC5B,oDAAoD;IACpD,aAAa,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,cAAc,EAAE,MAAM,CAAC;IACvB,4EAA4E;IAC5E,OAAO,EAAE,OAAO,CAAC;IACjB,8EAA8E;IAC9E,KAAK,EAAE,OAAO,CAAC;IACf,uDAAuD;IACvD,WAAW,EAAE,MAAM,CAAC;CACrB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAErC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,MAA2B,EACxC,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAMnC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAsB,iBAAiB,CACrC,WAAW,GAAE,MAA2B,EACxC,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAO9B;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,GAAE,MAA2B,EACxC,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA6B7B"}
@@ -10,8 +10,11 @@
10
10
  *
11
11
  * @module agents
12
12
  */
13
+ export { type AgentCapacity, type AgentPerformanceMetrics, getAgentCapacity, getAgentSpecializations, getAgentsByCapacity, MAX_TASKS_PER_AGENT, recordAgentPerformance, updateAgentSpecializations, } from './agent-registry.js';
13
14
  export { AGENT_INSTANCE_STATUSES, AGENT_TYPES, type AgentErrorLogRow, type AgentErrorType, type AgentInstanceRow, type AgentInstanceStatus, type AgentType, agentErrorLog, agentInstances, type NewAgentErrorLogRow, type NewAgentInstanceRow, } from './agent-schema.js';
14
15
  export { type CapacitySummary, findLeastLoadedAgent, getAvailableCapacity, getCapacitySummary, isOverloaded, updateCapacity, } from './capacity.js';
15
- export { type AgentHealthReport, checkAgentHealth, classifyError, deregisterAgent, generateAgentId, getAgentErrorHistory, getAgentInstance, getHealthReport, heartbeat, incrementTasksCompleted, type ListAgentFilters, listAgentInstances, markCrashed, type RegisterAgentOptions, registerAgent, type UpdateStatusOptions, updateAgentStatus, } from './registry.js';
16
+ export { type AgentExecutionEvent, type AgentExecutionOutcome, type AgentPerformanceSummary, getAgentPerformanceHistory, getSelfHealingSuggestions, type HealingSuggestion, processAgentLifecycleEvent, recordAgentExecution, recordFailurePattern, storeHealingStrategy, } from './execution-learning.js';
17
+ export { type AgentHealthStatus, checkAgentHealth, detectCrashedAgents, detectStaleAgents, HEARTBEAT_INTERVAL_MS, recordHeartbeat, STALE_THRESHOLD_MS, } from './health-monitor.js';
18
+ export { type AgentHealthReport, checkAgentHealth as findStaleAgentRows, classifyError, deregisterAgent, generateAgentId, getAgentErrorHistory, getAgentInstance, getHealthReport, heartbeat, incrementTasksCompleted, type ListAgentFilters, listAgentInstances, markCrashed, type RegisterAgentOptions, registerAgent, type UpdateStatusOptions, updateAgentStatus, } from './registry.js';
16
19
  export { type AgentRecoveryResult, calculateDelay, createRetryPolicy, DEFAULT_RETRY_POLICY, type RetryPolicy, type RetryResult, recoverCrashedAgents, shouldRetry, withRetry, } from './retry.js';
17
20
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agents/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EACL,uBAAuB,EACvB,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,aAAa,EACb,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,KAAK,eAAe,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,cAAc,GACf,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,aAAa,EACb,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,uBAAuB,EACvB,KAAK,gBAAgB,EACrB,kBAAkB,EAClB,WAAW,EACX,KAAK,oBAAoB,EACzB,aAAa,EACb,KAAK,mBAAmB,EACxB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,mBAAmB,EACxB,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,oBAAoB,EACpB,WAAW,EACX,SAAS,GACV,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/agents/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,uBAAuB,EAC5B,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,GAC3B,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,uBAAuB,EACvB,WAAW,EACX,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,SAAS,EACd,aAAa,EACb,cAAc,EACd,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,GACzB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,KAAK,eAAe,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,YAAY,EACZ,cAAc,GACf,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC5B,0BAA0B,EAC1B,yBAAyB,EACzB,KAAK,iBAAiB,EACtB,0BAA0B,EAC1B,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,GACrB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,KAAK,iBAAiB,EACtB,gBAAgB,EAChB,mBAAmB,EACnB,iBAAiB,EACjB,qBAAqB,EACrB,eAAe,EACf,kBAAkB,GACnB,MAAM,qBAAqB,CAAC;AAI7B,OAAO,EACL,KAAK,iBAAiB,EACtB,gBAAgB,IAAI,kBAAkB,EACtC,aAAa,EACb,eAAe,EACf,eAAe,EACf,oBAAoB,EACpB,gBAAgB,EAChB,eAAe,EACf,SAAS,EACT,uBAAuB,EACvB,KAAK,gBAAgB,EACrB,kBAAkB,EAClB,WAAW,EACX,KAAK,oBAAoB,EACzB,aAAa,EACb,KAAK,mBAAmB,EACxB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,mBAAmB,EACxB,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,oBAAoB,EACpB,WAAW,EACX,SAAS,GACV,MAAM,YAAY,CAAC"}