@framers/agentos 0.1.94 → 0.1.95

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 (55) hide show
  1. package/README.md +10 -0
  2. package/dist/api/AgentOS.d.ts +13 -0
  3. package/dist/api/AgentOS.d.ts.map +1 -1
  4. package/dist/api/AgentOS.js +36 -1
  5. package/dist/api/AgentOS.js.map +1 -1
  6. package/dist/core/tools/IToolOrchestrator.d.ts +38 -1
  7. package/dist/core/tools/IToolOrchestrator.d.ts.map +1 -1
  8. package/dist/core/tools/ToolOrchestrator.d.ts +58 -1
  9. package/dist/core/tools/ToolOrchestrator.d.ts.map +1 -1
  10. package/dist/core/tools/ToolOrchestrator.js +116 -1
  11. package/dist/core/tools/ToolOrchestrator.js.map +1 -1
  12. package/dist/discovery/CapabilityDiscoveryEngine.d.ts +19 -0
  13. package/dist/discovery/CapabilityDiscoveryEngine.d.ts.map +1 -1
  14. package/dist/discovery/CapabilityDiscoveryEngine.js +54 -0
  15. package/dist/discovery/CapabilityDiscoveryEngine.js.map +1 -1
  16. package/dist/discovery/types.d.ts +8 -1
  17. package/dist/discovery/types.d.ts.map +1 -1
  18. package/dist/discovery/types.js.map +1 -1
  19. package/dist/emergent/ComposableToolBuilder.d.ts +125 -0
  20. package/dist/emergent/ComposableToolBuilder.d.ts.map +1 -0
  21. package/dist/emergent/ComposableToolBuilder.js +318 -0
  22. package/dist/emergent/ComposableToolBuilder.js.map +1 -0
  23. package/dist/emergent/EmergentCapabilityEngine.d.ts +168 -0
  24. package/dist/emergent/EmergentCapabilityEngine.d.ts.map +1 -0
  25. package/dist/emergent/EmergentCapabilityEngine.js +437 -0
  26. package/dist/emergent/EmergentCapabilityEngine.js.map +1 -0
  27. package/dist/emergent/EmergentJudge.d.ts +283 -0
  28. package/dist/emergent/EmergentJudge.d.ts.map +1 -0
  29. package/dist/emergent/EmergentJudge.js +463 -0
  30. package/dist/emergent/EmergentJudge.js.map +1 -0
  31. package/dist/emergent/EmergentToolRegistry.d.ts +286 -0
  32. package/dist/emergent/EmergentToolRegistry.d.ts.map +1 -0
  33. package/dist/emergent/EmergentToolRegistry.js +546 -0
  34. package/dist/emergent/EmergentToolRegistry.js.map +1 -0
  35. package/dist/emergent/ForgeToolMetaTool.d.ts +124 -0
  36. package/dist/emergent/ForgeToolMetaTool.d.ts.map +1 -0
  37. package/dist/emergent/ForgeToolMetaTool.js +170 -0
  38. package/dist/emergent/ForgeToolMetaTool.js.map +1 -0
  39. package/dist/emergent/SandboxedToolForge.d.ts +185 -0
  40. package/dist/emergent/SandboxedToolForge.d.ts.map +1 -0
  41. package/dist/emergent/SandboxedToolForge.js +383 -0
  42. package/dist/emergent/SandboxedToolForge.js.map +1 -0
  43. package/dist/emergent/index.d.ts +25 -0
  44. package/dist/emergent/index.d.ts.map +1 -0
  45. package/dist/emergent/index.js +20 -0
  46. package/dist/emergent/index.js.map +1 -0
  47. package/dist/emergent/types.d.ts +596 -0
  48. package/dist/emergent/types.d.ts.map +1 -0
  49. package/dist/emergent/types.js +36 -0
  50. package/dist/emergent/types.js.map +1 -0
  51. package/dist/index.d.ts +1 -0
  52. package/dist/index.d.ts.map +1 -1
  53. package/dist/index.js +2 -0
  54. package/dist/index.js.map +1 -1
  55. package/package.json +1 -1
@@ -0,0 +1,546 @@
1
+ /**
2
+ * @fileoverview EmergentToolRegistry — tiered lifecycle manager for emergent tools.
3
+ * @module @framers/agentos/emergent/EmergentToolRegistry
4
+ *
5
+ * Manages the lifecycle of emergent tools across three trust tiers:
6
+ *
7
+ * - **Session tier**: In-memory `Map`, auto-cleaned when the session ends.
8
+ * Tools at this tier live only for the duration of the agent session and are
9
+ * never persisted.
10
+ *
11
+ * - **Agent tier**: Persisted in SQLite via the `agentos_emergent_tools` table.
12
+ * Tools at this tier are scoped to the agent that created them and survive
13
+ * across sessions.
14
+ *
15
+ * - **Shared tier**: Same SQLite table, discoverable by all agents. Promotion
16
+ * to shared tier requires explicit human or system approval.
17
+ *
18
+ * All state changes are logged to an in-memory audit trail (and to the
19
+ * `agentos_emergent_audit_log` table when a storage adapter is provided).
20
+ *
21
+ * The registry operates fully in-memory when no storage adapter is supplied,
22
+ * making it suitable for testing and ephemeral agents.
23
+ */
24
+ import { randomUUID } from 'node:crypto';
25
+ import { DEFAULT_EMERGENT_CONFIG } from './types.js';
26
+ // ============================================================================
27
+ // TIER ORDER
28
+ // ============================================================================
29
+ /**
30
+ * Tier ordering used for promotion validation.
31
+ * Higher index = broader scope = higher trust.
32
+ */
33
+ const TIER_ORDER = ['session', 'agent', 'shared'];
34
+ // ============================================================================
35
+ // EMERGENT TOOL REGISTRY
36
+ // ============================================================================
37
+ /**
38
+ * Manages the lifecycle of emergent tools across three trust tiers.
39
+ *
40
+ * The registry stores session-tier tools in an in-memory Map (keyed by tool ID)
41
+ * and agent/shared-tier tools in SQLite (when a storage adapter is provided) or
42
+ * in a separate in-memory Map as fallback.
43
+ *
44
+ * Key responsibilities:
45
+ * - **Registration**: Accept new tools at a given tier, enforcing config limits.
46
+ * - **Lookup**: Retrieve tools by ID or filter by tier with optional scope.
47
+ * - **Usage tracking**: Record invocations and update rolling statistics.
48
+ * - **Promotion / demotion**: Move tools between tiers with audit logging.
49
+ * - **Session cleanup**: Bulk-remove all session-scoped tools for a given session.
50
+ * - **Audit trail**: Log every state change for observability and debugging.
51
+ *
52
+ * @example
53
+ * ```ts
54
+ * const registry = new EmergentToolRegistry({ ...DEFAULT_EMERGENT_CONFIG, enabled: true });
55
+ * registry.register(tool, 'session');
56
+ * registry.recordUse(tool.id, { x: 1 }, { y: 2 }, true, 42);
57
+ * const stats = registry.getUsageStats(tool.id);
58
+ * ```
59
+ */
60
+ export class EmergentToolRegistry {
61
+ /**
62
+ * Create a new EmergentToolRegistry.
63
+ *
64
+ * @param config - Emergent capability configuration. Missing fields are
65
+ * filled from {@link DEFAULT_EMERGENT_CONFIG}.
66
+ * @param db - Optional SQLite storage adapter. When provided, agent and
67
+ * shared tier tools are persisted to the `agentos_emergent_tools` table.
68
+ * When omitted, all tiers use in-memory storage only.
69
+ */
70
+ constructor(config = {}, db) {
71
+ /** In-memory store for session-tier tools, keyed by tool ID. */
72
+ this.sessionTools = new Map();
73
+ /** In-memory store for agent/shared-tier tools when no DB is available. */
74
+ this.persistedTools = new Map();
75
+ /** In-memory audit log. Always populated regardless of DB availability. */
76
+ this.auditLog = [];
77
+ /** Whether `ensureSchema()` has been called and completed. */
78
+ this.schemaReady = false;
79
+ this.config = { ...DEFAULT_EMERGENT_CONFIG, ...config };
80
+ this.db = db;
81
+ }
82
+ // --------------------------------------------------------------------------
83
+ // SCHEMA
84
+ // --------------------------------------------------------------------------
85
+ /**
86
+ * Initialize the database schema for emergent tool persistence.
87
+ *
88
+ * Creates the `agentos_emergent_tools` and `agentos_emergent_audit_log`
89
+ * tables along with their indexes. Safe to call multiple times — all
90
+ * statements use `CREATE TABLE IF NOT EXISTS` / `CREATE INDEX IF NOT EXISTS`.
91
+ *
92
+ * This method is a no-op when no storage adapter was provided.
93
+ *
94
+ * @throws If the storage adapter's `exec` or `run` method rejects.
95
+ */
96
+ async ensureSchema() {
97
+ if (!this.db || this.schemaReady) {
98
+ return;
99
+ }
100
+ const toolsTable = `
101
+ CREATE TABLE IF NOT EXISTS agentos_emergent_tools (
102
+ id TEXT PRIMARY KEY,
103
+ name TEXT NOT NULL,
104
+ description TEXT NOT NULL,
105
+ input_schema TEXT NOT NULL,
106
+ output_schema TEXT,
107
+ implementation_mode TEXT NOT NULL,
108
+ implementation_source TEXT NOT NULL,
109
+ tier TEXT NOT NULL DEFAULT 'session',
110
+ created_by_agent TEXT NOT NULL,
111
+ created_by_session TEXT NOT NULL,
112
+ created_at BIGINT NOT NULL,
113
+ promoted_at BIGINT,
114
+ promoted_by TEXT,
115
+ judge_verdicts TEXT,
116
+ confidence_score REAL DEFAULT 0,
117
+ total_uses INTEGER DEFAULT 0,
118
+ success_count INTEGER DEFAULT 0,
119
+ failure_count INTEGER DEFAULT 0,
120
+ avg_execution_ms REAL DEFAULT 0,
121
+ last_used_at BIGINT,
122
+ is_active INTEGER DEFAULT 1
123
+ );`;
124
+ const toolsTierIndex = `CREATE INDEX IF NOT EXISTS idx_emergent_tools_tier ON agentos_emergent_tools(tier, is_active);`;
125
+ const toolsAgentIndex = `CREATE INDEX IF NOT EXISTS idx_emergent_tools_agent ON agentos_emergent_tools(created_by_agent, tier);`;
126
+ const auditTable = `
127
+ CREATE TABLE IF NOT EXISTS agentos_emergent_audit_log (
128
+ id TEXT PRIMARY KEY,
129
+ tool_id TEXT NOT NULL,
130
+ event_type TEXT NOT NULL,
131
+ event_data TEXT,
132
+ timestamp BIGINT NOT NULL
133
+ );`;
134
+ const auditIndex = `CREATE INDEX IF NOT EXISTS idx_emergent_audit_tool ON agentos_emergent_audit_log(tool_id, timestamp);`;
135
+ // Prefer `exec` for multi-statement DDL; fall back to individual `run` calls.
136
+ if (this.db.exec) {
137
+ await this.db.exec([toolsTable, toolsTierIndex, toolsAgentIndex, auditTable, auditIndex].join('\n'));
138
+ }
139
+ else {
140
+ await this.db.run(toolsTable);
141
+ await this.db.run(toolsTierIndex);
142
+ await this.db.run(toolsAgentIndex);
143
+ await this.db.run(auditTable);
144
+ await this.db.run(auditIndex);
145
+ }
146
+ this.schemaReady = true;
147
+ }
148
+ // --------------------------------------------------------------------------
149
+ // REGISTER
150
+ // --------------------------------------------------------------------------
151
+ /**
152
+ * Register a new emergent tool at the given tier.
153
+ *
154
+ * Session-tier tools are stored in the in-memory session map. Agent and shared
155
+ * tier tools are stored in the persisted map (and will be written to SQLite on
156
+ * the next DB sync if a storage adapter is available).
157
+ *
158
+ * @param tool - The emergent tool to register. Must have a unique `id`.
159
+ * @param tier - The tier to register the tool at. The tool's `tier` property
160
+ * is updated to match.
161
+ *
162
+ * @throws {Error} If the maximum tool count for the target tier is exceeded
163
+ * (checked against `maxSessionTools` or `maxAgentTools` from config).
164
+ * @throws {Error} If a tool with the same ID is already registered.
165
+ */
166
+ register(tool, tier) {
167
+ // Check for duplicates across all stores.
168
+ if (this.sessionTools.has(tool.id) || this.persistedTools.has(tool.id)) {
169
+ throw new Error(`Tool "${tool.id}" is already registered.`);
170
+ }
171
+ // Enforce tier-specific limits.
172
+ if (tier === 'session') {
173
+ const sessionCount = this.sessionTools.size;
174
+ if (sessionCount >= this.config.maxSessionTools) {
175
+ throw new Error(`Session tool limit reached (${this.config.maxSessionTools}). ` +
176
+ `Remove or promote existing tools before registering new ones.`);
177
+ }
178
+ }
179
+ else if (tier === 'agent') {
180
+ const agentCount = this.getByTier('agent').length;
181
+ if (agentCount >= this.config.maxAgentTools) {
182
+ throw new Error(`Agent tool limit reached (${this.config.maxAgentTools}). ` +
183
+ `Remove or promote existing tools before registering new ones.`);
184
+ }
185
+ }
186
+ // Stamp the tier on the tool object.
187
+ const registered = { ...tool, tier };
188
+ if (tier === 'session') {
189
+ this.sessionTools.set(registered.id, registered);
190
+ }
191
+ else {
192
+ this.persistedTools.set(registered.id, registered);
193
+ }
194
+ if (this.db && this.schemaReady) {
195
+ this.persistToolToDb(registered).catch(() => {
196
+ // Best-effort persistence mirror. In-memory state remains authoritative.
197
+ });
198
+ }
199
+ this.logAudit(registered.id, 'register', { tier });
200
+ }
201
+ // --------------------------------------------------------------------------
202
+ // GET
203
+ // --------------------------------------------------------------------------
204
+ /**
205
+ * Retrieve a tool by its unique identifier.
206
+ *
207
+ * Searches all tiers (session first, then persisted agent/shared).
208
+ *
209
+ * @param toolId - The tool ID to look up.
210
+ * @returns The tool if found, or `undefined` if no tool with that ID exists.
211
+ */
212
+ get(toolId) {
213
+ return this.sessionTools.get(toolId) ?? this.persistedTools.get(toolId);
214
+ }
215
+ /**
216
+ * Remove a tool from the registry entirely.
217
+ *
218
+ * Used to roll back newly forged tools when downstream activation fails.
219
+ */
220
+ remove(toolId) {
221
+ const removed = this.sessionTools.delete(toolId) || this.persistedTools.delete(toolId);
222
+ if (removed) {
223
+ if (this.db && this.schemaReady) {
224
+ this.db
225
+ .run(`DELETE FROM agentos_emergent_tools WHERE id = ?`, [toolId])
226
+ .catch(() => {
227
+ // Best-effort cleanup only.
228
+ });
229
+ }
230
+ this.logAudit(toolId, 'remove');
231
+ }
232
+ return removed;
233
+ }
234
+ // --------------------------------------------------------------------------
235
+ // GET BY TIER
236
+ // --------------------------------------------------------------------------
237
+ /**
238
+ * Get all tools registered at a specific tier, optionally filtered by scope.
239
+ *
240
+ * @param tier - The tier to query (`'session'`, `'agent'`, or `'shared'`).
241
+ * @param scope - Optional scope filter. When provided, results are narrowed:
242
+ * - `sessionId`: Match tools whose `source` string contains the session ID.
243
+ * - `agentId`: Match tools whose `createdBy` equals the agent ID.
244
+ * @returns An array of matching tools (may be empty).
245
+ */
246
+ getByTier(tier, scope) {
247
+ let tools;
248
+ if (tier === 'session') {
249
+ tools = Array.from(this.sessionTools.values());
250
+ }
251
+ else {
252
+ tools = Array.from(this.persistedTools.values()).filter((t) => t.tier === tier);
253
+ }
254
+ // Apply optional scope filters.
255
+ if (scope?.sessionId) {
256
+ const sid = scope.sessionId;
257
+ tools = tools.filter((t) => t.source.includes(sid));
258
+ }
259
+ if (scope?.agentId) {
260
+ const aid = scope.agentId;
261
+ tools = tools.filter((t) => t.createdBy === aid);
262
+ }
263
+ return tools;
264
+ }
265
+ // --------------------------------------------------------------------------
266
+ // RECORD USE
267
+ // --------------------------------------------------------------------------
268
+ /**
269
+ * Record a tool invocation, updating rolling usage statistics.
270
+ *
271
+ * Updates the tool's {@link ToolUsageStats} in place:
272
+ * - Increments `totalUses`.
273
+ * - Increments `successCount` or `failureCount` based on the `success` flag.
274
+ * - Recalculates `avgExecutionTimeMs` as a running average.
275
+ * - Recalculates `confidenceScore` as `successCount / totalUses`.
276
+ * - Sets `lastUsedAt` to the current ISO-8601 timestamp.
277
+ *
278
+ * @param toolId - The ID of the tool that was invoked.
279
+ * @param _input - The input arguments passed to the tool (logged for audit).
280
+ * @param _output - The output returned by the tool (logged for audit).
281
+ * @param success - Whether the invocation completed successfully.
282
+ * @param executionTimeMs - Wall-clock execution time in milliseconds.
283
+ *
284
+ * @throws {Error} If no tool with the given ID is registered.
285
+ */
286
+ recordUse(toolId, _input, _output, success, executionTimeMs) {
287
+ const tool = this.get(toolId);
288
+ if (!tool) {
289
+ throw new Error(`Cannot record use: tool "${toolId}" not found.`);
290
+ }
291
+ const stats = tool.usageStats;
292
+ const prevTotal = stats.totalUses;
293
+ stats.totalUses += 1;
294
+ if (success) {
295
+ stats.successCount += 1;
296
+ }
297
+ else {
298
+ stats.failureCount += 1;
299
+ }
300
+ // Running average: newAvg = (oldAvg * prevTotal + newValue) / newTotal
301
+ stats.avgExecutionTimeMs =
302
+ (stats.avgExecutionTimeMs * prevTotal + executionTimeMs) / stats.totalUses;
303
+ // Confidence is success rate.
304
+ stats.confidenceScore = stats.successCount / stats.totalUses;
305
+ stats.lastUsedAt = new Date().toISOString();
306
+ if (this.db && this.schemaReady) {
307
+ this.persistToolToDb(tool).catch(() => {
308
+ // Best-effort persistence mirror. Usage stats still live in memory.
309
+ });
310
+ }
311
+ this.logAudit(toolId, 'use', { success, executionTimeMs });
312
+ }
313
+ // --------------------------------------------------------------------------
314
+ // GET USAGE STATS
315
+ // --------------------------------------------------------------------------
316
+ /**
317
+ * Retrieve usage statistics for a registered tool.
318
+ *
319
+ * @param toolId - The tool ID to look up.
320
+ * @returns The tool's {@link ToolUsageStats}, or `undefined` if the tool
321
+ * is not registered.
322
+ */
323
+ getUsageStats(toolId) {
324
+ return this.get(toolId)?.usageStats;
325
+ }
326
+ // --------------------------------------------------------------------------
327
+ // PROMOTE
328
+ // --------------------------------------------------------------------------
329
+ /**
330
+ * Promote a tool to a higher lifecycle tier.
331
+ *
332
+ * Moves the tool from its current tier to `targetTier`. If the tool was at
333
+ * session tier, it is removed from the session map and added to the persisted
334
+ * map. If a storage adapter is available and the target tier is agent or
335
+ * shared, the tool is persisted to the database.
336
+ *
337
+ * @param toolId - The ID of the tool to promote.
338
+ * @param targetTier - The target tier to promote to. Must be strictly higher
339
+ * than the tool's current tier.
340
+ * @param approvedBy - Optional identifier of the human or system entity that
341
+ * approved the promotion.
342
+ *
343
+ * @throws {Error} If the tool is not found.
344
+ * @throws {Error} If `targetTier` is not higher than the tool's current tier.
345
+ */
346
+ async promote(toolId, targetTier, approvedBy) {
347
+ const tool = this.get(toolId);
348
+ if (!tool) {
349
+ throw new Error(`Cannot promote: tool "${toolId}" not found.`);
350
+ }
351
+ const currentIndex = TIER_ORDER.indexOf(tool.tier);
352
+ const targetIndex = TIER_ORDER.indexOf(targetTier);
353
+ if (targetIndex <= currentIndex) {
354
+ throw new Error(`Cannot promote tool from "${tool.tier}" to "${targetTier}": ` +
355
+ `target tier must be strictly higher than current tier.`);
356
+ }
357
+ const previousTier = tool.tier;
358
+ // If moving from session to a persisted tier, migrate between maps.
359
+ if (previousTier === 'session') {
360
+ this.sessionTools.delete(toolId);
361
+ tool.tier = targetTier;
362
+ this.persistedTools.set(toolId, tool);
363
+ }
364
+ else {
365
+ tool.tier = targetTier;
366
+ }
367
+ // Persist to DB if adapter is available and target is a persisted tier.
368
+ if (this.db && this.schemaReady) {
369
+ await this.persistToolToDb(tool, approvedBy);
370
+ }
371
+ this.logAudit(toolId, 'promote', {
372
+ from: previousTier,
373
+ to: targetTier,
374
+ approvedBy: approvedBy ?? null,
375
+ });
376
+ }
377
+ // --------------------------------------------------------------------------
378
+ // DEMOTE
379
+ // --------------------------------------------------------------------------
380
+ /**
381
+ * Demote or deactivate a tool.
382
+ *
383
+ * Marks the tool as inactive by setting a sentinel on its usage stats
384
+ * (`confidenceScore` set to 0) and logs the demotion event with a reason.
385
+ *
386
+ * Inactive tools are still retrievable via `get()` but should be filtered
387
+ * out by callers when building tool lists for the LLM.
388
+ *
389
+ * @param toolId - The ID of the tool to demote.
390
+ * @param reason - Human-readable explanation for why the tool is being demoted.
391
+ *
392
+ * @throws {Error} If the tool is not found.
393
+ */
394
+ demote(toolId, reason) {
395
+ const tool = this.get(toolId);
396
+ if (!tool) {
397
+ throw new Error(`Cannot demote: tool "${toolId}" not found.`);
398
+ }
399
+ tool.usageStats.confidenceScore = 0;
400
+ // Mark as inactive via a convention property.
401
+ tool.isActive = false;
402
+ if (this.db && this.schemaReady) {
403
+ this.db
404
+ .run(`UPDATE agentos_emergent_tools SET is_active = 0 WHERE id = ?`, [toolId])
405
+ .catch(() => {
406
+ // Best-effort persistence only.
407
+ });
408
+ }
409
+ this.logAudit(toolId, 'demote', { reason });
410
+ }
411
+ // --------------------------------------------------------------------------
412
+ // CLEANUP SESSION
413
+ // --------------------------------------------------------------------------
414
+ /**
415
+ * Remove all session-tier tools associated with a specific session.
416
+ *
417
+ * Iterates the session map and deletes every tool whose `source` string
418
+ * contains the given session ID. Logs a cleanup audit event for each
419
+ * removed tool.
420
+ *
421
+ * @param sessionId - The session identifier to match against tool `source`
422
+ * strings.
423
+ * @returns The number of tools removed.
424
+ */
425
+ cleanupSession(sessionId) {
426
+ let removedCount = 0;
427
+ for (const [id, tool] of this.sessionTools) {
428
+ if (tool.source.includes(sessionId)) {
429
+ this.sessionTools.delete(id);
430
+ if (this.db && this.schemaReady) {
431
+ this.db
432
+ .run(`DELETE FROM agentos_emergent_tools WHERE id = ?`, [id])
433
+ .catch(() => {
434
+ // Best-effort cleanup only.
435
+ });
436
+ }
437
+ this.logAudit(id, 'cleanup', { sessionId });
438
+ removedCount += 1;
439
+ }
440
+ }
441
+ return removedCount;
442
+ }
443
+ // --------------------------------------------------------------------------
444
+ // AUDIT LOG ACCESSORS
445
+ // --------------------------------------------------------------------------
446
+ /**
447
+ * Retrieve audit log entries, optionally filtered by tool ID.
448
+ *
449
+ * @param toolId - When provided, only entries for this tool are returned.
450
+ * @returns An array of {@link AuditEntry} objects in chronological order.
451
+ */
452
+ getAuditLog(toolId) {
453
+ if (toolId) {
454
+ return this.auditLog.filter((e) => e.toolId === toolId);
455
+ }
456
+ return [...this.auditLog];
457
+ }
458
+ // --------------------------------------------------------------------------
459
+ // PRIVATE: logAudit
460
+ // --------------------------------------------------------------------------
461
+ /**
462
+ * Log an audit event to both the in-memory trail and (optionally) the database.
463
+ *
464
+ * @param toolId - The tool this event pertains to.
465
+ * @param eventType - Machine-readable event type string.
466
+ * @param data - Optional structured data to attach to the event.
467
+ */
468
+ logAudit(toolId, eventType, data) {
469
+ const entry = {
470
+ id: randomUUID(),
471
+ toolId,
472
+ eventType,
473
+ data,
474
+ timestamp: Date.now(),
475
+ };
476
+ this.auditLog.push(entry);
477
+ // Best-effort DB write — do not await or throw if it fails.
478
+ if (this.db && this.schemaReady) {
479
+ this.db
480
+ .run(`INSERT INTO agentos_emergent_audit_log (id, tool_id, event_type, event_data, timestamp)
481
+ VALUES (?, ?, ?, ?, ?)`, [
482
+ entry.id,
483
+ entry.toolId,
484
+ entry.eventType,
485
+ data != null ? JSON.stringify(data) : null,
486
+ entry.timestamp,
487
+ ])
488
+ .catch(() => {
489
+ // Swallow DB write errors for audit logs — the in-memory log is
490
+ // the authoritative source and we should not disrupt the caller.
491
+ });
492
+ }
493
+ }
494
+ // --------------------------------------------------------------------------
495
+ // PRIVATE: persistToolToDb
496
+ // --------------------------------------------------------------------------
497
+ /**
498
+ * Upsert a tool record into the `agentos_emergent_tools` SQLite table.
499
+ *
500
+ * Uses INSERT OR REPLACE to handle both initial persistence and updates
501
+ * after promotion.
502
+ *
503
+ * @param tool - The emergent tool to persist.
504
+ * @param approvedBy - Optional identifier of the promotion approver.
505
+ */
506
+ async persistToolToDb(tool, approvedBy) {
507
+ if (!this.db) {
508
+ return;
509
+ }
510
+ // Extract the session ID from the source string if present.
511
+ const sessionMatch = tool.source.match(/session\s+([\w-]+)/);
512
+ const sessionId = sessionMatch?.[1] ?? 'unknown';
513
+ await this.db.run(`INSERT OR REPLACE INTO agentos_emergent_tools
514
+ (id, name, description, input_schema, output_schema, implementation_mode,
515
+ implementation_source, tier, created_by_agent, created_by_session,
516
+ created_at, promoted_at, promoted_by, judge_verdicts, confidence_score,
517
+ total_uses, success_count, failure_count, avg_execution_ms, last_used_at,
518
+ is_active)
519
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
520
+ tool.id,
521
+ tool.name,
522
+ tool.description,
523
+ JSON.stringify(tool.inputSchema),
524
+ JSON.stringify(tool.outputSchema),
525
+ tool.implementation.mode,
526
+ JSON.stringify(tool.implementation),
527
+ tool.tier,
528
+ tool.createdBy,
529
+ sessionId,
530
+ new Date(tool.createdAt).getTime(),
531
+ tool.tier === 'session' ? null : Date.now(),
532
+ approvedBy ?? null,
533
+ JSON.stringify(tool.judgeVerdicts),
534
+ tool.usageStats.confidenceScore,
535
+ tool.usageStats.totalUses,
536
+ tool.usageStats.successCount,
537
+ tool.usageStats.failureCount,
538
+ tool.usageStats.avgExecutionTimeMs,
539
+ tool.usageStats.lastUsedAt
540
+ ? new Date(tool.usageStats.lastUsedAt).getTime()
541
+ : null,
542
+ 1,
543
+ ]);
544
+ }
545
+ }
546
+ //# sourceMappingURL=EmergentToolRegistry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EmergentToolRegistry.js","sourceRoot":"","sources":["../../src/emergent/EmergentToolRegistry.ts"],"names":[],"mappings":"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"}