@agent-evolve/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,1812 @@
1
+ // intent/context-fill.ts
2
+ var STOP_WORDS = /* @__PURE__ */ new Set([
3
+ "a",
4
+ "an",
5
+ "and",
6
+ "are",
7
+ "as",
8
+ "at",
9
+ "be",
10
+ "by",
11
+ "for",
12
+ "from",
13
+ "how",
14
+ "i",
15
+ "in",
16
+ "is",
17
+ "it",
18
+ "of",
19
+ "on",
20
+ "or",
21
+ "that",
22
+ "the",
23
+ "this",
24
+ "to",
25
+ "we",
26
+ "with",
27
+ "you"
28
+ ]);
29
+ function extractKeywords(userMsg) {
30
+ const matches = userMsg.toLowerCase().match(/[a-z0-9_-]+/g) ?? [];
31
+ return [...new Set(matches.filter((word) => word.length > 2 && !STOP_WORDS.has(word)))];
32
+ }
33
+ function resolveSource(entry) {
34
+ if (entry.data_type === "knowledge") {
35
+ return "knowledge";
36
+ }
37
+ if (entry.status === "rolled_back") {
38
+ return "memory(conflict)";
39
+ }
40
+ return "memory";
41
+ }
42
+ function dedup(results) {
43
+ const seen = /* @__PURE__ */ new Set();
44
+ return results.filter((result) => {
45
+ if (seen.has(result.id)) {
46
+ return false;
47
+ }
48
+ seen.add(result.id);
49
+ return true;
50
+ });
51
+ }
52
+ async function contextFill(userMsg, registry, agentConfig) {
53
+ const keywords = extractKeywords(userMsg);
54
+ return registry.search({
55
+ tags: keywords,
56
+ partition: agentConfig.readable_partitions,
57
+ minConfidence: 0.3,
58
+ limit: 20
59
+ }).map((result) => ({ ...result, source: resolveSource(result) }));
60
+ }
61
+ async function contextFillRefine(rough, initial, registry, agentConfig) {
62
+ const refined = registry.search({
63
+ tags: [rough.task_type, rough.domain, ...rough.key_entities],
64
+ partition: agentConfig.readable_partitions,
65
+ limit: 10
66
+ }).map((result) => ({ ...result, source: resolveSource(result) }));
67
+ return dedup([...initial, ...refined]);
68
+ }
69
+
70
+ // types/intent-object.ts
71
+ var DEFAULT_ROUGH_INTENT = {
72
+ task_type: "unknown",
73
+ domain: "general",
74
+ complexity: "medium",
75
+ key_entities: [],
76
+ missing: []
77
+ };
78
+
79
+ // intent/rough-parse.ts
80
+ var EXTRACTION_PROMPT = `
81
+ After your response, output a JSON block (invisible to user):
82
+ \`\`\`intent
83
+ {"task_type":"...","domain":"...","complexity":"low|medium|high",
84
+ "key_entities":["..."],"missing":["..."]}
85
+ \`\`\``;
86
+ function parseIntentBlock(response) {
87
+ const match = response.match(/```intent\n([\s\S]*?)\n```/);
88
+ if (!match?.[1]) {
89
+ return DEFAULT_ROUGH_INTENT;
90
+ }
91
+ try {
92
+ return JSON.parse(match[1]);
93
+ } catch {
94
+ return DEFAULT_ROUGH_INTENT;
95
+ }
96
+ }
97
+ function stripIntentBlock(response) {
98
+ return response.replace(/```intent[\s\S]*?```/g, "").trim();
99
+ }
100
+
101
+ // intent/conflict-detect.ts
102
+ var DEFAULT_PRIORITY_ORDER = [
103
+ "user_input",
104
+ "recent_pref",
105
+ "default",
106
+ "knowledge",
107
+ "memory",
108
+ "llm_extract",
109
+ "memory(conflict)"
110
+ ];
111
+ function groupByField(fills) {
112
+ const groups = {};
113
+ for (const fill of fills) {
114
+ const field = fill.field ?? fill.data_type;
115
+ const existing = groups[field];
116
+ if (existing) {
117
+ existing.push(fill);
118
+ } else {
119
+ groups[field] = [fill];
120
+ }
121
+ }
122
+ return groups;
123
+ }
124
+ function isConflicting(a, b) {
125
+ if (!a.value || !b.value) return false;
126
+ return a.value.toLowerCase() !== b.value.toLowerCase();
127
+ }
128
+ function conflictDetect(fills, rules) {
129
+ const order = rules?.order ?? DEFAULT_PRIORITY_ORDER;
130
+ const byField = groupByField(fills);
131
+ const resolved = {};
132
+ const conflicts = [];
133
+ for (const [field, candidates] of Object.entries(byField)) {
134
+ if (candidates.length === 1) {
135
+ resolved[field] = candidates[0];
136
+ continue;
137
+ }
138
+ candidates.sort(
139
+ (a, b) => order.indexOf(a.source) - order.indexOf(b.source)
140
+ );
141
+ resolved[field] = candidates[0];
142
+ if (candidates.length >= 2 && isConflicting(candidates[0], candidates[1])) {
143
+ conflicts.push({ field, options: candidates.slice(0, 2) });
144
+ }
145
+ }
146
+ return { resolved, conflicts };
147
+ }
148
+
149
+ // intent/structure.ts
150
+ function calcConfidence(rough, resolved) {
151
+ const unresolvedCount = rough.missing.length + resolved.conflicts.length;
152
+ const hasKnownType = rough.task_type !== "unknown";
153
+ const hasKnownDomain = rough.domain !== "general";
154
+ let confidence = 0.5;
155
+ if (hasKnownType) confidence += 0.2;
156
+ if (hasKnownDomain) confidence += 0.15;
157
+ if (Object.keys(resolved.resolved).length > 0) confidence += 0.1;
158
+ confidence -= unresolvedCount * 0.15;
159
+ return Math.max(0, Math.min(1, Number(confidence.toFixed(2))));
160
+ }
161
+ function extractConstraints(resolved) {
162
+ const constraints = [];
163
+ for (const [field, fill] of Object.entries(resolved.resolved)) {
164
+ if (fill.value && field.startsWith("constraint")) {
165
+ constraints.push(fill.value);
166
+ }
167
+ }
168
+ return constraints;
169
+ }
170
+ function toIntentSource(s) {
171
+ if (s === "recent_pref") return "user_input";
172
+ return s;
173
+ }
174
+ function buildSourceTrace(rough, resolved) {
175
+ const trace = {
176
+ task_type: "llm_extract",
177
+ domain: "llm_extract",
178
+ complexity: "llm_extract"
179
+ };
180
+ for (const [field, fill] of Object.entries(resolved.resolved)) {
181
+ trace[field] = toIntentSource(fill.source);
182
+ }
183
+ return trace;
184
+ }
185
+ function structure(rough, resolved, _userMsg) {
186
+ return {
187
+ task_type: rough.task_type,
188
+ domain: rough.domain,
189
+ complexity: resolved.resolved["complexity"]?.value ?? rough.complexity,
190
+ target_audience: resolved.resolved["target_audience"]?.value ?? "",
191
+ output_format: resolved.resolved["output_format"]?.value ?? "markdown",
192
+ style: resolved.resolved["style"]?.value ?? "",
193
+ key_entities: rough.key_entities,
194
+ constraints: extractConstraints(resolved),
195
+ confidence: calcConfidence(rough, resolved),
196
+ unresolved: [...rough.missing, ...resolved.conflicts.map((c) => c.field)],
197
+ source_trace: buildSourceTrace(rough, resolved)
198
+ };
199
+ }
200
+
201
+ // intent/confirm.ts
202
+ var DEFAULT_THRESHOLD = { skip: 0.9, quick: 0.7 };
203
+ function buildQuestions(intent) {
204
+ const questions = [];
205
+ for (const field of intent.unresolved) {
206
+ if (questions.length >= 2) break;
207
+ questions.push(`What should "${field}" be for this task?`);
208
+ }
209
+ if (questions.length === 0 && intent.confidence < 0.7) {
210
+ questions.push(`Can you clarify what you need? (detected: ${intent.task_type} in ${intent.domain})`);
211
+ }
212
+ return questions;
213
+ }
214
+ function updateIntent(intent, answers) {
215
+ const updated = { ...intent, unresolved: [...intent.unresolved] };
216
+ for (const [field, value] of Object.entries(answers)) {
217
+ if (field in updated) {
218
+ updated[field] = value;
219
+ }
220
+ updated.unresolved = updated.unresolved.filter((u) => u !== field);
221
+ updated.source_trace = { ...updated.source_trace, [field]: "user_input" };
222
+ }
223
+ updated.confidence = Math.min(1, intent.confidence + Object.keys(answers).length * 0.1);
224
+ return updated;
225
+ }
226
+ async function confirmIfNeeded(intent, adapter, threshold = DEFAULT_THRESHOLD) {
227
+ if (intent.confidence >= threshold.skip && intent.unresolved.length === 0) {
228
+ return intent;
229
+ }
230
+ if (intent.confidence >= threshold.quick) {
231
+ const ok = await adapter.sendConfirmation(intent);
232
+ if (ok) return intent;
233
+ }
234
+ const questions = buildQuestions(intent);
235
+ const answers = await adapter.askQuestions(questions);
236
+ return updateIntent(intent, answers);
237
+ }
238
+
239
+ // intent/pipeline.ts
240
+ function buildTrace(rough, searchResults, refined, _resolved, confirmed) {
241
+ return {
242
+ id: `trace_${Math.random().toString(36).slice(2, 10)}`,
243
+ intent_id: `${confirmed.task_type}_${confirmed.domain}`,
244
+ query_tags: [rough.task_type, rough.domain, ...rough.key_entities],
245
+ partitions_searched: [...new Set(searchResults.map((r) => r.partition))],
246
+ hits: searchResults.map((r) => r.id),
247
+ loaded_l0: searchResults.map((r) => r.id),
248
+ promoted_l1: refined.map((r) => r.id),
249
+ promoted_l2: [],
250
+ injected: Object.values(_resolved.resolved).map((r) => r.id)
251
+ };
252
+ }
253
+ async function intentPipeline(userMsg, adapter, registry, agentConfig, config) {
254
+ const [roughIntent, searchResults] = await Promise.all([
255
+ Promise.resolve(adapter.parseIntentFromResponse(userMsg)),
256
+ contextFill(userMsg, registry, agentConfig)
257
+ ]);
258
+ const refined = await contextFillRefine(roughIntent, searchResults, registry, agentConfig);
259
+ const resolved = conflictDetect(refined, config.priorityRules);
260
+ const intent = structure(roughIntent, resolved, userMsg);
261
+ const confirmed = await confirmIfNeeded(intent, adapter, config.confirmThreshold);
262
+ const trace = buildTrace(roughIntent, searchResults, refined, resolved, confirmed);
263
+ registry.saveTrace(trace);
264
+ return {
265
+ intent: confirmed,
266
+ trace,
267
+ needsConfirmation: confirmed.confidence < config.confirmThreshold.skip
268
+ };
269
+ }
270
+
271
+ // intent/attention-control.ts
272
+ var DEFAULT_ATTENTION_BUDGET = {
273
+ maxTokens: 4e3,
274
+ globalPrinciplesRatio: 0.15,
275
+ memoryRatio: 0.5,
276
+ skillDocsRatio: 0.35
277
+ };
278
+ function estimateTokens(text) {
279
+ return Math.ceil(text.length / 4);
280
+ }
281
+ function scoreRelevance(item, intent) {
282
+ let score = item.confidence;
283
+ const entitySet = new Set(intent.key_entities.map((e) => e.toLowerCase()));
284
+ for (const tag of item.tags) {
285
+ if (entitySet.has(tag.toLowerCase())) score += 0.2;
286
+ }
287
+ if (item.data_type === "knowledge") score += 0.1;
288
+ if (item.status === "stale") score -= 0.3;
289
+ return Math.max(0, Math.min(1, score));
290
+ }
291
+ function selectAttentionSlots(fills, intent, globalPrinciples, skillDocs, budget = DEFAULT_ATTENTION_BUDGET) {
292
+ const slots = [];
293
+ let remainingTokens = budget.maxTokens;
294
+ const principlesBudget = Math.floor(budget.maxTokens * budget.globalPrinciplesRatio);
295
+ let principleTokens = 0;
296
+ for (const p of globalPrinciples) {
297
+ const tokens = estimateTokens(p);
298
+ if (principleTokens + tokens <= principlesBudget) {
299
+ slots.push({ category: "global_principle", content: p, relevanceScore: 1, tokenEstimate: tokens });
300
+ principleTokens += tokens;
301
+ }
302
+ }
303
+ remainingTokens -= principleTokens;
304
+ const memoryBudget = Math.floor(budget.maxTokens * budget.memoryRatio);
305
+ const scored = fills.map((f) => ({ fill: f, score: scoreRelevance(f, intent), tokens: estimateTokens(f.summary) })).sort((a, b) => b.score - a.score);
306
+ let memoryTokens = 0;
307
+ for (const { fill, score, tokens } of scored) {
308
+ if (memoryTokens + tokens > memoryBudget) continue;
309
+ slots.push({ category: "memory", content: fill.summary, relevanceScore: score, tokenEstimate: tokens });
310
+ memoryTokens += tokens;
311
+ }
312
+ remainingTokens -= memoryTokens;
313
+ const skillBudget = Math.min(Math.floor(budget.maxTokens * budget.skillDocsRatio), remainingTokens);
314
+ let skillTokens = 0;
315
+ for (const doc of skillDocs) {
316
+ const tokens = estimateTokens(doc);
317
+ if (skillTokens + tokens > skillBudget) continue;
318
+ slots.push({ category: "skill_doc", content: doc, relevanceScore: 0.8, tokenEstimate: tokens });
319
+ skillTokens += tokens;
320
+ }
321
+ return slots;
322
+ }
323
+ function assembleContext(slots) {
324
+ const sections = [];
325
+ const principles = slots.filter((s) => s.category === "global_principle");
326
+ if (principles.length > 0) {
327
+ sections.push("## Guidelines\n" + principles.map((s) => `- ${s.content}`).join("\n"));
328
+ }
329
+ const memories = slots.filter((s) => s.category === "memory");
330
+ if (memories.length > 0) {
331
+ sections.push("## Relevant Context\n" + memories.map((s) => `- ${s.content}`).join("\n"));
332
+ }
333
+ const skills = slots.filter((s) => s.category === "skill_doc");
334
+ if (skills.length > 0) {
335
+ sections.push("## Skill Reference\n" + skills.map((s) => s.content).join("\n\n"));
336
+ }
337
+ return sections.join("\n\n");
338
+ }
339
+
340
+ // registry/index-table.ts
341
+ import Database from "better-sqlite3";
342
+ var SCHEMA_SQL = `
343
+ CREATE TABLE IF NOT EXISTS registry (
344
+ id TEXT PRIMARY KEY,
345
+ summary TEXT NOT NULL,
346
+ tags TEXT NOT NULL DEFAULT '[]',
347
+ storage_ptr TEXT NOT NULL,
348
+ data_type TEXT DEFAULT 'memory',
349
+ confidence REAL DEFAULT 0.5,
350
+ verified_cnt INTEGER DEFAULT 0,
351
+ partition TEXT DEFAULT 'global',
352
+ source_agent TEXT,
353
+ created_at TEXT NOT NULL DEFAULT (datetime('now')),
354
+ last_accessed TEXT,
355
+ access_count INTEGER DEFAULT 0,
356
+ status TEXT DEFAULT 'active'
357
+ );
358
+
359
+ CREATE INDEX IF NOT EXISTS idx_tags ON registry(tags);
360
+ CREATE INDEX IF NOT EXISTS idx_partition ON registry(partition);
361
+ CREATE INDEX IF NOT EXISTS idx_data_type ON registry(data_type);
362
+ CREATE INDEX IF NOT EXISTS idx_status ON registry(status);
363
+
364
+ CREATE TABLE IF NOT EXISTS retrieval_traces (
365
+ id TEXT PRIMARY KEY,
366
+ intent_id TEXT,
367
+ query_tags TEXT,
368
+ partitions_searched TEXT,
369
+ hits TEXT,
370
+ loaded_l0 TEXT,
371
+ promoted_l1 TEXT,
372
+ promoted_l2 TEXT,
373
+ injected TEXT,
374
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
375
+ );
376
+
377
+ CREATE TABLE IF NOT EXISTS prediction_log (
378
+ id TEXT PRIMARY KEY,
379
+ intent_id TEXT,
380
+ task_type TEXT,
381
+ dimension TEXT,
382
+ estimated REAL,
383
+ actual REAL,
384
+ deviation REAL,
385
+ level TEXT,
386
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
387
+ );
388
+
389
+ CREATE TABLE IF NOT EXISTS codec_table (
390
+ short_code TEXT PRIMARY KEY,
391
+ full_value TEXT NOT NULL,
392
+ usage_count INTEGER DEFAULT 1,
393
+ created_at TEXT NOT NULL DEFAULT (datetime('now'))
394
+ );
395
+ `;
396
+ function randomId(prefix) {
397
+ return `${prefix}_${Math.random().toString(36).slice(2, 10)}`;
398
+ }
399
+ function parseJsonArray(value) {
400
+ if (!value) {
401
+ return [];
402
+ }
403
+ try {
404
+ const parsed = JSON.parse(value);
405
+ return Array.isArray(parsed) ? parsed.filter((item) => typeof item === "string") : [];
406
+ } catch {
407
+ return [];
408
+ }
409
+ }
410
+ function normalizeRegistryRow(row) {
411
+ return {
412
+ ...row,
413
+ tags: parseJsonArray(row.tags)
414
+ };
415
+ }
416
+ function normalizeTraceRow(row) {
417
+ return {
418
+ id: row.id,
419
+ intent_id: row.intent_id ?? void 0,
420
+ query_tags: parseJsonArray(row.query_tags),
421
+ partitions_searched: parseJsonArray(row.partitions_searched),
422
+ hits: parseJsonArray(row.hits),
423
+ loaded_l0: parseJsonArray(row.loaded_l0),
424
+ promoted_l1: parseJsonArray(row.promoted_l1),
425
+ promoted_l2: parseJsonArray(row.promoted_l2),
426
+ injected: parseJsonArray(row.injected),
427
+ created_at: row.created_at
428
+ };
429
+ }
430
+ var IndexTable = class {
431
+ db;
432
+ constructor(dbPath = ":memory:") {
433
+ this.db = new Database(dbPath);
434
+ this.db.pragma("journal_mode = WAL");
435
+ this.db.exec(SCHEMA_SQL);
436
+ }
437
+ insert(entry) {
438
+ const id = entry.id ?? randomId("reg");
439
+ const stmt = this.db.prepare(`
440
+ INSERT INTO registry (
441
+ id, summary, tags, storage_ptr, data_type, confidence, verified_cnt,
442
+ partition, source_agent, created_at, last_accessed, access_count, status
443
+ ) VALUES (
444
+ @id, @summary, @tags, @storage_ptr, @data_type, @confidence, @verified_cnt,
445
+ @partition, @source_agent, COALESCE(@created_at, datetime('now')),
446
+ @last_accessed, @access_count, @status
447
+ )
448
+ `);
449
+ stmt.run({
450
+ id,
451
+ summary: entry.summary,
452
+ tags: JSON.stringify(entry.tags ?? []),
453
+ storage_ptr: entry.storage_ptr,
454
+ data_type: entry.data_type ?? "memory",
455
+ confidence: entry.confidence ?? 0.5,
456
+ verified_cnt: entry.verified_cnt ?? 0,
457
+ partition: entry.partition ?? "global",
458
+ source_agent: entry.source_agent ?? null,
459
+ created_at: entry.created_at ?? null,
460
+ last_accessed: entry.last_accessed ?? null,
461
+ access_count: entry.access_count ?? 0,
462
+ status: entry.status ?? "active"
463
+ });
464
+ return id;
465
+ }
466
+ get(id) {
467
+ const row = this.db.prepare("SELECT * FROM registry WHERE id = ?").get(id);
468
+ return row ? normalizeRegistryRow(row) : null;
469
+ }
470
+ update(id, updates) {
471
+ const current = this.get(id);
472
+ if (!current) {
473
+ return false;
474
+ }
475
+ const merged = {
476
+ ...current,
477
+ ...updates,
478
+ tags: updates.tags ?? current.tags
479
+ };
480
+ const stmt = this.db.prepare(`
481
+ UPDATE registry
482
+ SET summary = @summary,
483
+ tags = @tags,
484
+ storage_ptr = @storage_ptr,
485
+ data_type = @data_type,
486
+ confidence = @confidence,
487
+ verified_cnt = @verified_cnt,
488
+ partition = @partition,
489
+ source_agent = @source_agent,
490
+ created_at = @created_at,
491
+ last_accessed = @last_accessed,
492
+ access_count = @access_count,
493
+ status = @status
494
+ WHERE id = @id
495
+ `);
496
+ const { id: _ignoreId, ...rest } = merged;
497
+ const result = stmt.run({
498
+ ...rest,
499
+ id,
500
+ tags: JSON.stringify(merged.tags),
501
+ source_agent: merged.source_agent ?? null,
502
+ last_accessed: merged.last_accessed ?? null
503
+ });
504
+ return result.changes > 0;
505
+ }
506
+ delete(id) {
507
+ const result = this.db.prepare("DELETE FROM registry WHERE id = ?").run(id);
508
+ return result.changes > 0;
509
+ }
510
+ search(filters = {}) {
511
+ const clauses = [];
512
+ const params = {};
513
+ if (filters.partition) {
514
+ const partitions = Array.isArray(filters.partition) ? filters.partition : [filters.partition];
515
+ clauses.push(`partition IN (${partitions.map((_, index) => `@partition${index}`).join(", ")})`);
516
+ partitions.forEach((partition, index) => {
517
+ params[`partition${index}`] = partition;
518
+ });
519
+ }
520
+ if (filters.dataType) {
521
+ const dataTypes = Array.isArray(filters.dataType) ? filters.dataType : [filters.dataType];
522
+ clauses.push(`data_type IN (${dataTypes.map((_, index) => `@dataType${index}`).join(", ")})`);
523
+ dataTypes.forEach((dataType, index) => {
524
+ params[`dataType${index}`] = dataType;
525
+ });
526
+ }
527
+ if (typeof filters.minConfidence === "number") {
528
+ clauses.push("confidence >= @minConfidence");
529
+ params.minConfidence = filters.minConfidence;
530
+ }
531
+ clauses.push(`status != 'rolled_back'`);
532
+ const limit = filters.limit ?? 20;
533
+ const whereClause = clauses.length > 0 ? `WHERE ${clauses.join(" AND ")}` : "";
534
+ const rows = this.db.prepare(
535
+ `
536
+ SELECT *
537
+ FROM registry
538
+ ${whereClause}
539
+ ORDER BY confidence DESC, verified_cnt DESC, created_at DESC
540
+ LIMIT @limit
541
+ `
542
+ ).all({ ...params, limit });
543
+ const normalized = rows.map(normalizeRegistryRow);
544
+ if (!filters.tags || filters.tags.length === 0) {
545
+ return normalized;
546
+ }
547
+ const tagSet = new Set(filters.tags.map((tag) => tag.toLowerCase()));
548
+ return normalized.filter(
549
+ (entry) => entry.tags.some((tag) => tagSet.has(tag.toLowerCase()))
550
+ );
551
+ }
552
+ recordAccess(id) {
553
+ const result = this.db.prepare(`
554
+ UPDATE registry
555
+ SET access_count = access_count + 1,
556
+ last_accessed = datetime('now')
557
+ WHERE id = ?
558
+ `).run(id);
559
+ return result.changes > 0;
560
+ }
561
+ saveTrace(trace) {
562
+ const id = trace.id ?? randomId("trace");
563
+ this.db.prepare(`
564
+ INSERT OR REPLACE INTO retrieval_traces (
565
+ id, intent_id, query_tags, partitions_searched, hits,
566
+ loaded_l0, promoted_l1, promoted_l2, injected, created_at
567
+ ) VALUES (
568
+ @id, @intent_id, @query_tags, @partitions_searched, @hits,
569
+ @loaded_l0, @promoted_l1, @promoted_l2, @injected,
570
+ COALESCE(@created_at, datetime('now'))
571
+ )
572
+ `).run({
573
+ id,
574
+ intent_id: trace.intent_id ?? null,
575
+ query_tags: JSON.stringify(trace.query_tags ?? []),
576
+ partitions_searched: JSON.stringify(trace.partitions_searched ?? []),
577
+ hits: JSON.stringify(trace.hits ?? []),
578
+ loaded_l0: JSON.stringify(trace.loaded_l0 ?? []),
579
+ promoted_l1: JSON.stringify(trace.promoted_l1 ?? []),
580
+ promoted_l2: JSON.stringify(trace.promoted_l2 ?? []),
581
+ injected: JSON.stringify(trace.injected ?? []),
582
+ created_at: trace.created_at ?? null
583
+ });
584
+ return id;
585
+ }
586
+ getTrace(id) {
587
+ const row = this.db.prepare("SELECT * FROM retrieval_traces WHERE id = ?").get(id);
588
+ return row ? normalizeTraceRow(row) : null;
589
+ }
590
+ close() {
591
+ this.db.close();
592
+ }
593
+ };
594
+
595
+ // registry/auto-ingest.ts
596
+ function extractTags(data) {
597
+ const tags = new Set(data.tags ?? []);
598
+ const words = data.content.toLowerCase().match(/[a-z0-9_-]+/g) ?? [];
599
+ for (const word of words) {
600
+ if (word.length > 3 && tags.size < 10) {
601
+ tags.add(word);
602
+ }
603
+ }
604
+ return [...tags];
605
+ }
606
+ function resolvePartition(sourceAgent) {
607
+ if (!sourceAgent) return "global";
608
+ return `agent_${sourceAgent.replace(/[^a-z0-9_-]/gi, "_")}`;
609
+ }
610
+ async function autoIngest(data, registry) {
611
+ const summary = data.content.slice(0, 200);
612
+ const tags = extractTags(data);
613
+ const partition = data.partition ?? resolvePartition(data.sourceAgent);
614
+ return registry.insert({
615
+ ...data.id ? { id: data.id } : {},
616
+ summary,
617
+ tags,
618
+ storage_ptr: data.storageLocation,
619
+ data_type: data.type,
620
+ partition,
621
+ source_agent: data.sourceAgent
622
+ });
623
+ }
624
+
625
+ // evaluate/deterministic.ts
626
+ function verifyRegex(output, pattern) {
627
+ try {
628
+ return new RegExp(pattern).test(output);
629
+ } catch {
630
+ return false;
631
+ }
632
+ }
633
+ function verifyFieldPresence(output, fields) {
634
+ const lower = output.toLowerCase();
635
+ const present = [];
636
+ const missing = [];
637
+ for (const field of fields) {
638
+ if (lower.includes(field.toLowerCase())) {
639
+ present.push(field);
640
+ } else {
641
+ missing.push(field);
642
+ }
643
+ }
644
+ return { present, missing };
645
+ }
646
+ function verifyJsonSchema(output, fields) {
647
+ try {
648
+ const parsed = JSON.parse(output);
649
+ return fields.every((f) => f in parsed);
650
+ } catch {
651
+ return false;
652
+ }
653
+ }
654
+ function runVerification(output, rules) {
655
+ const checks = [];
656
+ for (const rule of rules) {
657
+ switch (rule.type) {
658
+ case "regex": {
659
+ const passed = verifyRegex(output, rule.pattern ?? "");
660
+ checks.push({ rule: `regex:${rule.pattern}`, passed, message: passed ? "Match found" : "No match" });
661
+ break;
662
+ }
663
+ case "field_presence": {
664
+ const { present, missing } = verifyFieldPresence(output, rule.fields ?? []);
665
+ const passed = missing.length === 0;
666
+ checks.push({ rule: "field_presence", passed, message: passed ? "All fields present" : `Missing: ${missing.join(", ")}` });
667
+ break;
668
+ }
669
+ case "json_schema": {
670
+ const passed = verifyJsonSchema(output, rule.fields ?? []);
671
+ checks.push({ rule: "json_schema", passed, message: passed ? "Valid schema" : "Schema mismatch" });
672
+ break;
673
+ }
674
+ case "custom": {
675
+ const passed = rule.validator ? rule.validator(output) : false;
676
+ checks.push({ rule: "custom", passed });
677
+ break;
678
+ }
679
+ }
680
+ }
681
+ const passedCount = checks.filter((c) => c.passed).length;
682
+ return {
683
+ passed: checks.every((c) => c.passed),
684
+ checks,
685
+ overallScore: checks.length > 0 ? passedCount / checks.length : 1
686
+ };
687
+ }
688
+
689
+ // evaluate/subdimension.ts
690
+ function checkWordCount(min, max) {
691
+ return (output) => {
692
+ const count = output.split(/\s+/).length;
693
+ if (count >= min && count <= max) return 1;
694
+ if (count < min) return count / min;
695
+ return max / count;
696
+ };
697
+ }
698
+ function checkKeywordCoverage(keywords) {
699
+ return (output) => {
700
+ const lower = output.toLowerCase();
701
+ const found = keywords.filter((k) => lower.includes(k.toLowerCase()));
702
+ return keywords.length > 0 ? found.length / keywords.length : 1;
703
+ };
704
+ }
705
+ function checkFormatCompliance(expectedFormat) {
706
+ return (output) => {
707
+ switch (expectedFormat) {
708
+ case "markdown":
709
+ return output.includes("#") || output.includes("- ") ? 1 : 0.3;
710
+ case "json":
711
+ try {
712
+ JSON.parse(output);
713
+ return 1;
714
+ } catch {
715
+ return 0;
716
+ }
717
+ case "html":
718
+ return output.includes("<") && output.includes(">") ? 1 : 0.3;
719
+ default:
720
+ return 0.5;
721
+ }
722
+ };
723
+ }
724
+ function evaluate(output, template, agentScores, humanScores) {
725
+ const scores = [];
726
+ const needsHuman = [];
727
+ const needsAgent = [];
728
+ for (const dim of template.dimensions) {
729
+ if (dim.evaluator === "auto" && dim.autoCheck) {
730
+ scores.push({
731
+ dimension: dim.name,
732
+ score: dim.autoCheck(output),
733
+ evaluator: "auto"
734
+ });
735
+ } else if (dim.evaluator === "agent_review") {
736
+ const score = agentScores?.[dim.name];
737
+ if (score !== void 0) {
738
+ scores.push({ dimension: dim.name, score, evaluator: "agent_review" });
739
+ } else {
740
+ needsAgent.push(dim.name);
741
+ scores.push({ dimension: dim.name, score: 0, evaluator: "agent_review", feedback: "Pending agent review" });
742
+ }
743
+ } else {
744
+ const score = humanScores?.[dim.name];
745
+ if (score !== void 0) {
746
+ scores.push({ dimension: dim.name, score, evaluator: "human" });
747
+ } else {
748
+ needsHuman.push(dim.name);
749
+ scores.push({ dimension: dim.name, score: 0, evaluator: "human", feedback: "Pending human review" });
750
+ }
751
+ }
752
+ }
753
+ const totalWeight = template.dimensions.reduce((s, d) => s + d.weight, 0);
754
+ const overallScore = totalWeight > 0 ? template.dimensions.reduce((s, d, i) => s + d.weight * (scores[i]?.score ?? 0), 0) / totalWeight : 0;
755
+ return {
756
+ templateId: template.id,
757
+ scores,
758
+ overallScore: Number(overallScore.toFixed(3)),
759
+ needsHumanReview: needsHuman,
760
+ needsAgentReview: needsAgent
761
+ };
762
+ }
763
+ var TEMPLATES = {
764
+ copywriting: {
765
+ id: "tmpl-copywriting",
766
+ name: "Copywriting Evaluation",
767
+ taskTypes: ["email_copy", "social_media", "blog_post", "ad_copy", "web_copy", "press_release"],
768
+ dimensions: [
769
+ { name: "keyword_coverage", weight: 0.2, evaluator: "auto", autoCheck: checkKeywordCoverage([]) },
770
+ { name: "word_count", weight: 0.1, evaluator: "auto", autoCheck: checkWordCount(50, 2e3) },
771
+ { name: "format", weight: 0.1, evaluator: "auto", autoCheck: checkFormatCompliance("markdown") },
772
+ { name: "audience_fit", weight: 0.25, evaluator: "agent_review", description: "Does the tone match the target audience?" },
773
+ { name: "brand_consistency", weight: 0.15, evaluator: "agent_review", description: "Consistent with brand voice?" },
774
+ { name: "strategic_direction", weight: 0.2, evaluator: "human", description: "Aligns with business goals?" }
775
+ ]
776
+ },
777
+ code: {
778
+ id: "tmpl-code",
779
+ name: "Code Evaluation",
780
+ taskTypes: ["api_development", "feature", "bug_fix", "refactor"],
781
+ dimensions: [
782
+ { name: "syntax_valid", weight: 0.2, evaluator: "auto", autoCheck: (output) => output.includes("function") || output.includes("const") || output.includes("class") ? 1 : 0.3 },
783
+ { name: "format", weight: 0.1, evaluator: "auto", autoCheck: checkFormatCompliance("typescript") },
784
+ { name: "completeness", weight: 0.3, evaluator: "agent_review", description: "Covers all requirements?" },
785
+ { name: "code_quality", weight: 0.2, evaluator: "agent_review", description: "Clean, idiomatic code?" },
786
+ { name: "architecture", weight: 0.2, evaluator: "human", description: "Sound architectural decisions?" }
787
+ ]
788
+ },
789
+ research: {
790
+ id: "tmpl-research",
791
+ name: "Research Evaluation",
792
+ taskTypes: ["competitive_analysis", "market_research", "literature_review", "technical_research"],
793
+ dimensions: [
794
+ { name: "source_count", weight: 0.15, evaluator: "auto", autoCheck: (output) => {
795
+ const m = output.match(/https?:\/\//g);
796
+ return m ? Math.min(m.length / 5, 1) : 0;
797
+ } },
798
+ { name: "word_count", weight: 0.1, evaluator: "auto", autoCheck: checkWordCount(300, 5e3) },
799
+ { name: "depth", weight: 0.25, evaluator: "agent_review", description: "Sufficient analysis depth?" },
800
+ { name: "accuracy", weight: 0.25, evaluator: "agent_review", description: "Claims are factually correct?" },
801
+ { name: "actionability", weight: 0.25, evaluator: "human", description: "Provides actionable insights?" }
802
+ ]
803
+ },
804
+ data_analysis: {
805
+ id: "tmpl-data",
806
+ name: "Data Analysis Evaluation",
807
+ taskTypes: ["sales_analysis", "dashboard", "ab_test", "segmentation", "trend_analysis"],
808
+ dimensions: [
809
+ { name: "has_numbers", weight: 0.2, evaluator: "auto", autoCheck: (output) => /\d+(\.\d+)?%?/.test(output) ? 1 : 0 },
810
+ { name: "format", weight: 0.1, evaluator: "auto", autoCheck: checkFormatCompliance("markdown") },
811
+ { name: "methodology", weight: 0.3, evaluator: "agent_review", description: "Sound analytical methodology?" },
812
+ { name: "visualization", weight: 0.15, evaluator: "agent_review", description: "Appropriate data presentation?" },
813
+ { name: "business_relevance", weight: 0.25, evaluator: "human", description: "Answers the business question?" }
814
+ ]
815
+ }
816
+ };
817
+
818
+ // evaluate/prediction.ts
819
+ function classifyDeviation(ratio) {
820
+ if (ratio <= 1.3) return { level: "normal", alpha: 0 };
821
+ if (ratio <= 2) return { level: "mild", alpha: 0.3 };
822
+ if (ratio > 2) return { level: "significant", alpha: 0.6 };
823
+ return { level: "normal", alpha: 0 };
824
+ }
825
+ function classifyReverseDeviation(ratio) {
826
+ if (ratio < 0.5) return { level: "reverse", alpha: 0.5 };
827
+ return { level: "normal", alpha: 0 };
828
+ }
829
+ function analyzeOneDimension(dimension, estimated, actual) {
830
+ if (estimated === 0) {
831
+ return { dimension, estimated, actual, ratio: actual > 0 ? Infinity : 1, level: "significant", alpha: 0.6, newEstimate: actual };
832
+ }
833
+ const ratio = actual / estimated;
834
+ let classification;
835
+ if (ratio < 1) {
836
+ classification = classifyReverseDeviation(ratio);
837
+ } else {
838
+ classification = classifyDeviation(ratio);
839
+ }
840
+ const newEstimate = classification.alpha > 0 ? estimated * (1 - classification.alpha) + actual * classification.alpha : estimated;
841
+ return {
842
+ dimension,
843
+ estimated,
844
+ actual,
845
+ ratio: Number(ratio.toFixed(3)),
846
+ level: classification.level,
847
+ alpha: classification.alpha,
848
+ newEstimate: Math.round(newEstimate)
849
+ };
850
+ }
851
+ function analyzePrediction(prediction, actual) {
852
+ const deviations = [];
853
+ const dims = [
854
+ { key: "tokens", name: "tokens" },
855
+ { key: "durationMs", name: "duration" },
856
+ { key: "steps", name: "steps" },
857
+ { key: "skillCount", name: "skill_count" }
858
+ ];
859
+ for (const { key, name } of dims) {
860
+ const est = prediction.estimates[key];
861
+ const act = actual[key];
862
+ if (est !== void 0 && act !== void 0) {
863
+ deviations.push(analyzeOneDimension(name, est, act));
864
+ }
865
+ }
866
+ const needsModelUpdate = deviations.some((d) => d.level === "significant" || d.level === "reverse");
867
+ return {
868
+ intentId: prediction.intentId,
869
+ taskType: prediction.taskType,
870
+ deviations,
871
+ needsModelUpdate
872
+ };
873
+ }
874
+ var DeviationAccumulator = class {
875
+ counts = /* @__PURE__ */ new Map();
876
+ record(taskType, dimension, level) {
877
+ if (level !== "mild") return false;
878
+ const key = `${taskType}:${dimension}`;
879
+ const count = (this.counts.get(key) ?? 0) + 1;
880
+ this.counts.set(key, count);
881
+ return count >= 3;
882
+ }
883
+ getCount(taskType, dimension) {
884
+ return this.counts.get(`${taskType}:${dimension}`) ?? 0;
885
+ }
886
+ reset(taskType, dimension) {
887
+ this.counts.delete(`${taskType}:${dimension}`);
888
+ }
889
+ };
890
+
891
+ // feedback/structured.ts
892
+ var FEEDBACK_TEMPLATES = {
893
+ copywriting: {
894
+ id: "fb-copywriting",
895
+ taskType: "copywriting",
896
+ dimensions: [
897
+ { id: "tone", label: "Tone matches expectations?", type: "rating", scale: [1, 5] },
898
+ { id: "length", label: "Length appropriate?", type: "select", options: ["too_short", "just_right", "too_long"] },
899
+ { id: "accuracy", label: "Factually accurate?", type: "boolean" },
900
+ { id: "actionable", label: "Would you use this as-is?", type: "boolean" },
901
+ { id: "overall", label: "Overall quality", type: "rating", scale: [1, 5] }
902
+ ]
903
+ },
904
+ code: {
905
+ id: "fb-code",
906
+ taskType: "code",
907
+ dimensions: [
908
+ { id: "works", label: "Code runs correctly?", type: "boolean" },
909
+ { id: "complete", label: "Covers all requirements?", type: "rating", scale: [1, 5] },
910
+ { id: "quality", label: "Code quality", type: "rating", scale: [1, 5] },
911
+ { id: "approach", label: "Right approach?", type: "select", options: ["perfect", "acceptable", "wrong_approach"] },
912
+ { id: "overall", label: "Overall quality", type: "rating", scale: [1, 5] }
913
+ ]
914
+ },
915
+ research: {
916
+ id: "fb-research",
917
+ taskType: "research",
918
+ dimensions: [
919
+ { id: "depth", label: "Research depth", type: "rating", scale: [1, 5] },
920
+ { id: "accuracy", label: "Information accurate?", type: "boolean" },
921
+ { id: "coverage", label: "Covers the topic well?", type: "rating", scale: [1, 5] },
922
+ { id: "useful", label: "Findings are useful?", type: "boolean" },
923
+ { id: "overall", label: "Overall quality", type: "rating", scale: [1, 5] }
924
+ ]
925
+ },
926
+ general: {
927
+ id: "fb-general",
928
+ taskType: "general",
929
+ dimensions: [
930
+ { id: "understood", label: "Understood your intent?", type: "boolean" },
931
+ { id: "quality", label: "Output quality", type: "rating", scale: [1, 5] },
932
+ { id: "useful", label: "Result is useful?", type: "boolean" },
933
+ { id: "overall", label: "Overall satisfaction", type: "rating", scale: [1, 5] }
934
+ ]
935
+ }
936
+ };
937
+ function selectTemplate(taskType) {
938
+ if (taskType in FEEDBACK_TEMPLATES) return FEEDBACK_TEMPLATES[taskType];
939
+ const categoryMap = {
940
+ email_copy: "copywriting",
941
+ social_media: "copywriting",
942
+ blog_post: "copywriting",
943
+ ad_copy: "copywriting",
944
+ web_copy: "copywriting",
945
+ press_release: "copywriting",
946
+ api_development: "code",
947
+ feature: "code",
948
+ bug_fix: "code",
949
+ refactor: "code",
950
+ competitive_analysis: "research",
951
+ market_research: "research",
952
+ literature_review: "research"
953
+ };
954
+ const category = categoryMap[taskType];
955
+ if (category && category in FEEDBACK_TEMPLATES) return FEEDBACK_TEMPLATES[category];
956
+ return FEEDBACK_TEMPLATES["general"];
957
+ }
958
+ function normalizeFeedback(response, template) {
959
+ const normalized = {};
960
+ for (const dim of template.dimensions) {
961
+ const val = response.responses[dim.id];
962
+ if (val === void 0) continue;
963
+ if (dim.type === "boolean") {
964
+ normalized[dim.id] = val ? 1 : 0;
965
+ } else if (dim.type === "rating" && typeof val === "number") {
966
+ const [min, max] = dim.scale ?? [1, 5];
967
+ normalized[dim.id] = (val - min) / (max - min);
968
+ } else if (dim.type === "select" && typeof val === "string") {
969
+ const options = dim.options ?? [];
970
+ const idx = options.indexOf(val);
971
+ normalized[dim.id] = idx >= 0 ? idx / Math.max(1, options.length - 1) : 0.5;
972
+ }
973
+ }
974
+ return normalized;
975
+ }
976
+ function summarizeFeedback(responses, template) {
977
+ const allNormalized = responses.map((r) => normalizeFeedback(r, template));
978
+ const dims = template.dimensions.map((d) => d.id);
979
+ const averages = {};
980
+ for (const dim of dims) {
981
+ const values = allNormalized.map((n) => n[dim]).filter((v) => v !== void 0);
982
+ averages[dim] = values.length > 0 ? Number((values.reduce((a, b) => a + b, 0) / values.length).toFixed(3)) : 0;
983
+ }
984
+ const issues = Object.entries(averages).filter(([, v]) => v < 0.5).map(([k]) => k);
985
+ return {
986
+ taskType: template.taskType,
987
+ totalResponses: responses.length,
988
+ dimensionAverages: averages,
989
+ commonIssues: issues
990
+ };
991
+ }
992
+
993
+ // learn/attribution.ts
994
+ function attributeIntentError(intent, groundTruth) {
995
+ const typeMatch = intent.task_type === groundTruth.task_type;
996
+ const domainMatch = intent.domain === groundTruth.domain;
997
+ if (typeMatch && domainMatch) return null;
998
+ return {
999
+ target: "intent_recognition",
1000
+ confidence: typeMatch ? 0.5 : 0.85,
1001
+ evidence: !typeMatch ? `task_type mismatch: got "${intent.task_type}", expected "${groundTruth.task_type}"` : `domain mismatch: got "${intent.domain}", expected "${groundTruth.domain}"`,
1002
+ isHypothesis: typeMatch
1003
+ // Domain-only mismatch is less certain
1004
+ };
1005
+ }
1006
+ function attributeRetrievalError(trace, expectedHits) {
1007
+ const hitSet = new Set(trace.hits);
1008
+ const missed = expectedHits.filter((h) => !hitSet.has(h));
1009
+ if (missed.length === 0) return null;
1010
+ const missRate = missed.length / expectedHits.length;
1011
+ return {
1012
+ target: "memory_retrieval",
1013
+ confidence: Math.min(0.9, 0.4 + missRate * 0.5),
1014
+ evidence: `Missed ${missed.length}/${expectedHits.length} expected retrievals: ${missed.join(", ")}`,
1015
+ isHypothesis: missRate < 0.5
1016
+ };
1017
+ }
1018
+ function attributeOutputError(evaluation) {
1019
+ const lowDims = evaluation.scores.filter((s) => s.score < 0.5);
1020
+ if (lowDims.length === 0) return null;
1021
+ return {
1022
+ target: "output_quality",
1023
+ confidence: Math.min(0.9, 0.3 + lowDims.length * 0.15),
1024
+ evidence: `Low scores in: ${lowDims.map((d) => `${d.dimension}(${d.score})`).join(", ")}`,
1025
+ isHypothesis: lowDims.length < 2
1026
+ };
1027
+ }
1028
+ function analyzeAttribution(intent, trace, evaluation, groundTruth, expectedHits) {
1029
+ const attributions = [];
1030
+ if (groundTruth) {
1031
+ const intentAttr = attributeIntentError(intent, groundTruth);
1032
+ if (intentAttr) attributions.push(intentAttr);
1033
+ }
1034
+ if (expectedHits) {
1035
+ const retrievalAttr = attributeRetrievalError(trace, expectedHits);
1036
+ if (retrievalAttr) attributions.push(retrievalAttr);
1037
+ }
1038
+ const outputAttr = attributeOutputError(evaluation);
1039
+ if (outputAttr) attributions.push(outputAttr);
1040
+ attributions.sort((a, b) => b.confidence - a.confidence);
1041
+ const primaryCause = attributions[0]?.target ?? "unknown";
1042
+ const actionable = attributions.length > 0 && attributions[0].confidence >= 0.7;
1043
+ return {
1044
+ intentId: `${intent.task_type}_${intent.domain}`,
1045
+ attributions,
1046
+ primaryCause,
1047
+ actionable
1048
+ };
1049
+ }
1050
+
1051
+ // learn/experience-router.ts
1052
+ function routeExperience(attribution, taskType, domain, sourceAgent) {
1053
+ if (attribution.isHypothesis) {
1054
+ return {
1055
+ target: "memory",
1056
+ partition: `agent_${sourceAgent}`,
1057
+ reason: `Low confidence hypothesis (${attribution.confidence.toFixed(2)}), stored in agent memory for validation`
1058
+ };
1059
+ }
1060
+ switch (attribution.target) {
1061
+ case "intent_recognition":
1062
+ return {
1063
+ target: "knowledge_global",
1064
+ partition: "global",
1065
+ reason: "Intent recognition pattern applicable across agents"
1066
+ };
1067
+ case "skill_selection":
1068
+ return {
1069
+ target: "skill_doc",
1070
+ partition: `skill_${taskType}`,
1071
+ reason: `Skill-specific learning for ${taskType}`
1072
+ };
1073
+ case "memory_retrieval":
1074
+ return {
1075
+ target: "knowledge_dept",
1076
+ partition: `dept_${domain}`,
1077
+ reason: `Retrieval pattern specific to ${domain} domain`
1078
+ };
1079
+ case "output_quality":
1080
+ return {
1081
+ target: "skill_doc",
1082
+ partition: `skill_${taskType}`,
1083
+ reason: `Output quality improvement for ${taskType} tasks`
1084
+ };
1085
+ default:
1086
+ return {
1087
+ target: "memory",
1088
+ partition: `agent_${sourceAgent}`,
1089
+ reason: "Unknown attribution, stored in agent memory"
1090
+ };
1091
+ }
1092
+ }
1093
+ function createExperienceEntry(attribution, routing, taskType, domain, sourceAgent, traceId) {
1094
+ return {
1095
+ id: `exp_${Math.random().toString(36).slice(2, 10)}`,
1096
+ summary: attribution.evidence.slice(0, 200),
1097
+ condition: {
1098
+ task_type: taskType,
1099
+ domain
1100
+ },
1101
+ conclusion: `Issue: ${attribution.target}`,
1102
+ action: attribution.evidence,
1103
+ confidence: attribution.confidence,
1104
+ source_agent: sourceAgent,
1105
+ source_trace_id: traceId,
1106
+ verified_count: 0,
1107
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
1108
+ status: attribution.isHypothesis ? "hypothesis" : "active",
1109
+ target: routing.target,
1110
+ partition: routing.partition,
1111
+ is_abstract: false
1112
+ };
1113
+ }
1114
+
1115
+ // learn/distill.ts
1116
+ function findDistillationCandidates(experiences, minGroupSize = 3) {
1117
+ const groups = /* @__PURE__ */ new Map();
1118
+ for (const exp of experiences) {
1119
+ if (exp.is_abstract || exp.status !== "active") continue;
1120
+ const key = `${exp.condition.task_type ?? "unknown"}::${exp.conclusion}`;
1121
+ const group = groups.get(key) ?? [];
1122
+ group.push(exp);
1123
+ groups.set(key, group);
1124
+ }
1125
+ const candidates = /* @__PURE__ */ new Map();
1126
+ for (const [key, group] of groups) {
1127
+ if (group.length >= minGroupSize) {
1128
+ candidates.set(key, group);
1129
+ }
1130
+ }
1131
+ return candidates;
1132
+ }
1133
+ function abstractify(conclusion, action) {
1134
+ const absConclusion = conclusion.replace(/\d+(\.\d+)?(%| tokens?| chars?| words?| 字|字)/g, "[optimal value]").replace(/\d+/g, "[optimal value]").replace(/(中文|英文|Japanese|Chinese|English)/gi, "[language]").replace(/(社交媒体|email|slack|twitter|instagram)/gi, "[platform]");
1135
+ const absAction = action.replace(/\d+(\.\d+)?(%| tokens?| chars?| words?| 字|字)/g, "[optimal value]").replace(/\d+/g, "[optimal value]").replace(/(中文|英文|Japanese|Chinese|English)/gi, "[language]").replace(/(社交媒体|email|slack|twitter|instagram)/gi, "[platform]");
1136
+ return { conclusion: absConclusion, action: absAction };
1137
+ }
1138
+ function distillGroup(group) {
1139
+ if (group.length === 0) return null;
1140
+ const first = group[0];
1141
+ const { conclusion, action } = abstractify(first.conclusion, first.action);
1142
+ const abstractEntry = {
1143
+ id: `abs_${Math.random().toString(36).slice(2, 10)}`,
1144
+ summary: `Abstract: ${conclusion.slice(0, 150)}`,
1145
+ condition: {
1146
+ task_type: first.condition.task_type,
1147
+ domain: first.condition.domain
1148
+ // No environment — that's the point of abstraction
1149
+ },
1150
+ conclusion,
1151
+ action,
1152
+ confidence: Math.min(0.95, group.reduce((s, e) => s + e.confidence, 0) / group.length + 0.1),
1153
+ source_agent: "distiller",
1154
+ source_trace_id: group.map((e) => e.source_trace_id).join(","),
1155
+ verified_count: group.length,
1156
+ created_at: (/* @__PURE__ */ new Date()).toISOString(),
1157
+ status: "active",
1158
+ target: "knowledge_global",
1159
+ partition: "global",
1160
+ abstracted_from: group.map((e) => e.id),
1161
+ is_abstract: true
1162
+ };
1163
+ return {
1164
+ abstractEntry,
1165
+ sourceIds: group.map((e) => e.id),
1166
+ pattern: `${first.condition.task_type}::${first.conclusion}`
1167
+ };
1168
+ }
1169
+ function runDistillation(experiences, minGroupSize = 3) {
1170
+ const candidates = findDistillationCandidates(experiences, minGroupSize);
1171
+ const results = [];
1172
+ for (const [, group] of candidates) {
1173
+ const result = distillGroup(group);
1174
+ if (result) results.push(result);
1175
+ }
1176
+ return results;
1177
+ }
1178
+
1179
+ // learn/propagate.ts
1180
+ function publishToGlobal(experience) {
1181
+ return {
1182
+ experienceId: experience.id,
1183
+ fromAgent: experience.source_agent,
1184
+ toPartition: "global",
1185
+ action: "publish",
1186
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1187
+ };
1188
+ }
1189
+ function verifyExperience(experience, verifyingAgent) {
1190
+ const updated = {
1191
+ ...experience,
1192
+ verified_count: experience.verified_count + 1,
1193
+ confidence: Math.min(0.99, experience.confidence + 0.05)
1194
+ };
1195
+ return {
1196
+ updated,
1197
+ event: {
1198
+ experienceId: experience.id,
1199
+ fromAgent: verifyingAgent,
1200
+ toPartition: experience.partition,
1201
+ action: "verify",
1202
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1203
+ }
1204
+ };
1205
+ }
1206
+ function challengeExperience(experience, challengingAgent, evidence) {
1207
+ const newConfidence = Math.max(0.1, experience.confidence - 0.15);
1208
+ const updated = {
1209
+ ...experience,
1210
+ confidence: newConfidence,
1211
+ status: newConfidence < 0.3 ? "hypothesis" : experience.status
1212
+ };
1213
+ return {
1214
+ updated,
1215
+ event: {
1216
+ experienceId: experience.id,
1217
+ fromAgent: challengingAgent,
1218
+ toPartition: experience.partition,
1219
+ action: "challenge",
1220
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1221
+ }
1222
+ };
1223
+ }
1224
+ function rankByReliability(experiences) {
1225
+ return [...experiences].sort((a, b) => {
1226
+ const scoreA = (a.verified_count + 1) * a.confidence;
1227
+ const scoreB = (b.verified_count + 1) * b.confidence;
1228
+ return scoreB - scoreA;
1229
+ });
1230
+ }
1231
+ function filterPropagatable(experiences) {
1232
+ return experiences.filter(
1233
+ (e) => e.status === "active" && e.confidence >= 0.5 && e.verified_count >= 1
1234
+ );
1235
+ }
1236
+
1237
+ // learn/rollback.ts
1238
+ function checkPerformanceDegradation(window, degradationThreshold = 0.15) {
1239
+ if (window.recentScores.length < 3) return false;
1240
+ const diff = window.baselineAvg - window.currentAvg;
1241
+ return diff > degradationThreshold;
1242
+ }
1243
+ function decideRollback(experience, window, threshold = 0.15) {
1244
+ const shouldRollback = checkPerformanceDegradation(window, threshold);
1245
+ const degradation = window.baselineAvg - window.currentAvg;
1246
+ return {
1247
+ shouldRollback,
1248
+ experienceId: experience.id,
1249
+ reason: shouldRollback ? `Performance dropped ${(degradation * 100).toFixed(1)}% after writing experience ${experience.id}` : "Performance stable",
1250
+ baselineAvg: window.baselineAvg,
1251
+ currentAvg: window.currentAvg,
1252
+ degradation: Math.max(0, degradation)
1253
+ };
1254
+ }
1255
+ function executeRollback(experience, relatedAbstracts = []) {
1256
+ const rolledBack = {
1257
+ ...experience,
1258
+ status: "rolled_back"
1259
+ };
1260
+ const affectedAbstracts = relatedAbstracts.filter((a) => a.abstracted_from?.includes(experience.id)).map((a) => ({
1261
+ ...a,
1262
+ status: "hypothesis",
1263
+ confidence: Math.max(0.1, a.confidence - 0.2)
1264
+ }));
1265
+ return { rolledBack, affectedAbstracts };
1266
+ }
1267
+ function buildPerformanceWindow(taskType, allScores, splitAt) {
1268
+ const before = allScores.slice(0, splitAt);
1269
+ const after = allScores.slice(splitAt);
1270
+ const baselineAvg = before.length > 0 ? before.reduce((a, b) => a + b, 0) / before.length : 0.5;
1271
+ const currentAvg = after.length > 0 ? after.reduce((a, b) => a + b, 0) / after.length : baselineAvg;
1272
+ return {
1273
+ taskType,
1274
+ recentScores: after,
1275
+ baselineAvg: Number(baselineAvg.toFixed(3)),
1276
+ currentAvg: Number(currentAvg.toFixed(3))
1277
+ };
1278
+ }
1279
+
1280
+ // comm/codec.ts
1281
+ var Codec = class {
1282
+ codeToValue = /* @__PURE__ */ new Map();
1283
+ valueToCode = /* @__PURE__ */ new Map();
1284
+ usageCounts = /* @__PURE__ */ new Map();
1285
+ nextCodeId = 0;
1286
+ autoRegisterThreshold;
1287
+ constructor(options) {
1288
+ this.autoRegisterThreshold = options?.autoRegisterThreshold ?? 3;
1289
+ }
1290
+ /**
1291
+ * Register a short code for a frequently used value.
1292
+ */
1293
+ register(fullValue, shortCode) {
1294
+ if (this.valueToCode.has(fullValue)) {
1295
+ return this.valueToCode.get(fullValue);
1296
+ }
1297
+ const code = shortCode ?? `@${this.nextCodeId++}`;
1298
+ this.codeToValue.set(code, fullValue);
1299
+ this.valueToCode.set(fullValue, code);
1300
+ this.usageCounts.set(code, 0);
1301
+ return code;
1302
+ }
1303
+ /**
1304
+ * Record usage of a value. Auto-registers after threshold.
1305
+ * Returns short code if registered, undefined otherwise.
1306
+ */
1307
+ recordUsage(value) {
1308
+ if (this.valueToCode.has(value)) {
1309
+ const code = this.valueToCode.get(value);
1310
+ this.usageCounts.set(code, (this.usageCounts.get(code) ?? 0) + 1);
1311
+ return code;
1312
+ }
1313
+ const trackKey = `_pending:${value}`;
1314
+ const count = (this.usageCounts.get(trackKey) ?? 0) + 1;
1315
+ this.usageCounts.set(trackKey, count);
1316
+ if (count >= this.autoRegisterThreshold) {
1317
+ this.usageCounts.delete(trackKey);
1318
+ return this.register(value);
1319
+ }
1320
+ return void 0;
1321
+ }
1322
+ /**
1323
+ * Encode a message: replace registered full values with short codes.
1324
+ */
1325
+ encode(message) {
1326
+ const encoded = {};
1327
+ for (const [key, value] of Object.entries(message)) {
1328
+ const code = this.valueToCode.get(value);
1329
+ encoded[key] = code ?? value;
1330
+ }
1331
+ return encoded;
1332
+ }
1333
+ /**
1334
+ * Decode a message: replace short codes with full values.
1335
+ */
1336
+ decode(message) {
1337
+ const decoded = {};
1338
+ for (const [key, value] of Object.entries(message)) {
1339
+ const full = this.codeToValue.get(value);
1340
+ decoded[key] = full ?? value;
1341
+ }
1342
+ return decoded;
1343
+ }
1344
+ /**
1345
+ * Get all registered entries for persistence.
1346
+ */
1347
+ getEntries() {
1348
+ const entries = [];
1349
+ for (const [code, value] of this.codeToValue) {
1350
+ entries.push({
1351
+ shortCode: code,
1352
+ fullValue: value,
1353
+ usageCount: this.usageCounts.get(code) ?? 0
1354
+ });
1355
+ }
1356
+ return entries;
1357
+ }
1358
+ /**
1359
+ * Load entries from persistence.
1360
+ */
1361
+ loadEntries(entries) {
1362
+ for (const entry of entries) {
1363
+ this.codeToValue.set(entry.shortCode, entry.fullValue);
1364
+ this.valueToCode.set(entry.fullValue, entry.shortCode);
1365
+ this.usageCounts.set(entry.shortCode, entry.usageCount);
1366
+ }
1367
+ const maxId = entries.map((e) => e.shortCode).filter((c) => c.startsWith("@")).map((c) => parseInt(c.slice(1), 10)).reduce((max, n) => Math.max(max, n + 1), this.nextCodeId);
1368
+ this.nextCodeId = maxId;
1369
+ }
1370
+ /**
1371
+ * Cleanup: remove low-frequency codes.
1372
+ */
1373
+ cleanup(minUsage = 2) {
1374
+ let removed = 0;
1375
+ for (const [code, count] of this.usageCounts) {
1376
+ if (code.startsWith("_pending:")) continue;
1377
+ if (count < minUsage) {
1378
+ const value = this.codeToValue.get(code);
1379
+ if (value) {
1380
+ this.codeToValue.delete(code);
1381
+ this.valueToCode.delete(value);
1382
+ this.usageCounts.delete(code);
1383
+ removed++;
1384
+ }
1385
+ }
1386
+ }
1387
+ return removed;
1388
+ }
1389
+ };
1390
+
1391
+ // ecosystem/template-market.ts
1392
+ var TemplateMarket = class {
1393
+ templates = /* @__PURE__ */ new Map();
1394
+ ratings = /* @__PURE__ */ new Map();
1395
+ /**
1396
+ * Submit a new template for review.
1397
+ */
1398
+ submit(submission) {
1399
+ const id = submission.template.id;
1400
+ this.templates.set(id, submission);
1401
+ this.ratings.set(id, {
1402
+ templateId: id,
1403
+ usageCount: 0,
1404
+ avgEffectiveness: 0,
1405
+ upvotes: 0,
1406
+ downvotes: 0
1407
+ });
1408
+ return id;
1409
+ }
1410
+ /**
1411
+ * Approve a pending template.
1412
+ */
1413
+ approve(templateId) {
1414
+ const sub = this.templates.get(templateId);
1415
+ if (!sub || sub.status !== "pending") return false;
1416
+ sub.status = "approved";
1417
+ return true;
1418
+ }
1419
+ /**
1420
+ * Reject a pending template.
1421
+ */
1422
+ reject(templateId) {
1423
+ const sub = this.templates.get(templateId);
1424
+ if (!sub || sub.status !== "pending") return false;
1425
+ sub.status = "rejected";
1426
+ return true;
1427
+ }
1428
+ /**
1429
+ * Search templates by criteria.
1430
+ */
1431
+ search(query = {}) {
1432
+ let results = [...this.templates.entries()].filter(([, s]) => s.status === "approved").map(([id, submission]) => ({
1433
+ submission,
1434
+ rating: this.ratings.get(id) ?? { templateId: id, usageCount: 0, avgEffectiveness: 0, upvotes: 0, downvotes: 0 }
1435
+ }));
1436
+ if (query.taskType) {
1437
+ results = results.filter(
1438
+ (r) => r.submission.template.taskTypes.includes(query.taskType)
1439
+ );
1440
+ }
1441
+ if (query.minRating !== void 0) {
1442
+ results = results.filter((r) => r.rating.avgEffectiveness >= query.minRating);
1443
+ }
1444
+ const sortBy = query.sortBy ?? "rating";
1445
+ results.sort((a, b) => {
1446
+ switch (sortBy) {
1447
+ case "rating":
1448
+ return b.rating.avgEffectiveness - a.rating.avgEffectiveness;
1449
+ case "usage":
1450
+ return b.rating.usageCount - a.rating.usageCount;
1451
+ case "newest":
1452
+ return b.submission.submittedAt.localeCompare(a.submission.submittedAt);
1453
+ default:
1454
+ return 0;
1455
+ }
1456
+ });
1457
+ return results.slice(0, query.limit ?? 20);
1458
+ }
1459
+ /**
1460
+ * Record a template usage and update effectiveness.
1461
+ */
1462
+ recordUsage(templateId, effectiveness) {
1463
+ const rating = this.ratings.get(templateId);
1464
+ if (!rating) return;
1465
+ const total = rating.usageCount * rating.avgEffectiveness + effectiveness;
1466
+ rating.usageCount++;
1467
+ rating.avgEffectiveness = Number((total / rating.usageCount).toFixed(3));
1468
+ }
1469
+ /**
1470
+ * Upvote a template.
1471
+ */
1472
+ upvote(templateId) {
1473
+ const rating = this.ratings.get(templateId);
1474
+ if (rating) rating.upvotes++;
1475
+ }
1476
+ /**
1477
+ * Downvote a template.
1478
+ */
1479
+ downvote(templateId) {
1480
+ const rating = this.ratings.get(templateId);
1481
+ if (rating) rating.downvotes++;
1482
+ }
1483
+ /**
1484
+ * Get a specific template by ID.
1485
+ */
1486
+ get(templateId) {
1487
+ return this.templates.get(templateId);
1488
+ }
1489
+ /**
1490
+ * Get rating for a template.
1491
+ */
1492
+ getRating(templateId) {
1493
+ return this.ratings.get(templateId);
1494
+ }
1495
+ /**
1496
+ * List all templates (including pending/rejected for admin).
1497
+ */
1498
+ listAll() {
1499
+ return [...this.templates.values()];
1500
+ }
1501
+ };
1502
+
1503
+ // ecosystem/industry-packs.ts
1504
+ var MARKETING_PACK = {
1505
+ id: "pack-marketing",
1506
+ name: "Marketing & Advertising",
1507
+ industry: "marketing",
1508
+ description: "Brand tone guidelines, campaign templates, audience analysis frameworks",
1509
+ knowledge: [
1510
+ { summary: "Email subject lines perform best at 6-10 words", tags: ["email", "subject_line", "best_practice"], partition: "global" },
1511
+ { summary: "Social media posts with images get 2.3x more engagement", tags: ["social_media", "engagement"], partition: "global" },
1512
+ { summary: "CTA buttons in contrasting colors increase click-through by 21%", tags: ["cta", "conversion", "design"], partition: "global" },
1513
+ { summary: "Personalized email campaigns have 29% higher open rates", tags: ["email", "personalization"], partition: "global" },
1514
+ { summary: "Video content under 2 minutes has highest completion rate", tags: ["video", "content", "engagement"], partition: "global" }
1515
+ ],
1516
+ templates: [
1517
+ {
1518
+ id: "tmpl-campaign-brief",
1519
+ name: "Campaign Brief Evaluation",
1520
+ taskTypes: ["campaign_brief", "marketing_plan"],
1521
+ dimensions: [
1522
+ { name: "target_audience_clarity", weight: 0.25, evaluator: "auto", autoCheck: checkKeywordCoverage(["audience", "target", "demographic", "persona"]) },
1523
+ { name: "kpi_defined", weight: 0.2, evaluator: "auto", autoCheck: checkKeywordCoverage(["kpi", "metric", "goal", "objective", "conversion"]) },
1524
+ { name: "budget_mentioned", weight: 0.15, evaluator: "auto", autoCheck: checkKeywordCoverage(["budget", "cost", "spend", "investment"]) },
1525
+ { name: "creative_direction", weight: 0.2, evaluator: "agent_review", description: "Clear creative direction?" },
1526
+ { name: "strategic_alignment", weight: 0.2, evaluator: "human", description: "Aligns with brand strategy?" }
1527
+ ]
1528
+ }
1529
+ ],
1530
+ rules: [
1531
+ { field: "tone", value: "engaging", source: "marketing_default" },
1532
+ { field: "output_format", value: "markdown", source: "marketing_default" }
1533
+ ]
1534
+ };
1535
+ var SOFTWARE_DEV_PACK = {
1536
+ id: "pack-software",
1537
+ name: "Software Development",
1538
+ industry: "software",
1539
+ description: "Code standards, CI/CD patterns, common pitfalls",
1540
+ knowledge: [
1541
+ { summary: "Always validate user input at API boundaries", tags: ["security", "api", "validation"], partition: "global" },
1542
+ { summary: "Database queries should use parameterized statements to prevent SQL injection", tags: ["security", "database", "sql"], partition: "global" },
1543
+ { summary: "Unit tests should cover edge cases: null, empty, boundary values", tags: ["testing", "best_practice"], partition: "global" },
1544
+ { summary: "API endpoints should return consistent error response format", tags: ["api", "error_handling", "consistency"], partition: "global" },
1545
+ { summary: "Use semantic versioning (semver) for all package releases", tags: ["versioning", "release", "npm"], partition: "global" },
1546
+ { summary: "Git commit messages should follow conventional commits format", tags: ["git", "conventions"], partition: "global" }
1547
+ ],
1548
+ templates: [
1549
+ {
1550
+ id: "tmpl-code-review",
1551
+ name: "Code Review Evaluation",
1552
+ taskTypes: ["code_review", "pr_review"],
1553
+ dimensions: [
1554
+ { name: "security_check", weight: 0.2, evaluator: "auto", autoCheck: checkKeywordCoverage(["security", "vulnerability", "injection", "auth"]) },
1555
+ { name: "test_coverage", weight: 0.2, evaluator: "auto", autoCheck: checkKeywordCoverage(["test", "coverage", "spec", "assert"]) },
1556
+ { name: "error_handling", weight: 0.15, evaluator: "auto", autoCheck: checkKeywordCoverage(["error", "catch", "throw", "handle"]) },
1557
+ { name: "code_clarity", weight: 0.25, evaluator: "agent_review", description: "Code is clear and well-documented?" },
1558
+ { name: "architecture_fit", weight: 0.2, evaluator: "human", description: "Fits the overall architecture?" }
1559
+ ]
1560
+ }
1561
+ ],
1562
+ rules: [
1563
+ { field: "output_format", value: "typescript", source: "software_default" },
1564
+ { field: "style", value: "technical", source: "software_default" }
1565
+ ]
1566
+ };
1567
+ var CONTENT_PACK = {
1568
+ id: "pack-content",
1569
+ name: "Content Creation",
1570
+ industry: "content",
1571
+ description: "SEO rules, platform norms, content calendar templates",
1572
+ knowledge: [
1573
+ { summary: "Blog posts between 1500-2500 words rank highest on Google", tags: ["seo", "blog", "word_count"], partition: "global" },
1574
+ { summary: "Use H2/H3 headers every 300 words for readability", tags: ["seo", "structure", "readability"], partition: "global" },
1575
+ { summary: "Meta descriptions should be 150-160 characters", tags: ["seo", "meta", "description"], partition: "global" },
1576
+ { summary: "Include at least one internal and one external link per 500 words", tags: ["seo", "links"], partition: "global" },
1577
+ { summary: "Twitter/X posts perform best at 71-100 characters", tags: ["social_media", "twitter", "length"], partition: "global" }
1578
+ ],
1579
+ templates: [
1580
+ {
1581
+ id: "tmpl-seo-content",
1582
+ name: "SEO Content Evaluation",
1583
+ taskTypes: ["blog_post", "article", "landing_page"],
1584
+ dimensions: [
1585
+ { name: "word_count", weight: 0.15, evaluator: "auto", autoCheck: checkWordCount(1e3, 3e3) },
1586
+ { name: "heading_structure", weight: 0.15, evaluator: "auto", autoCheck: (output) => {
1587
+ const h = output.match(/^#{2,3}\s/gm);
1588
+ return h ? Math.min(h.length / 5, 1) : 0;
1589
+ } },
1590
+ { name: "keyword_density", weight: 0.2, evaluator: "auto", autoCheck: checkFormatCompliance("markdown") },
1591
+ { name: "readability", weight: 0.25, evaluator: "agent_review", description: "Easy to read for target audience?" },
1592
+ { name: "seo_optimization", weight: 0.25, evaluator: "human", description: "Properly optimized for search?" }
1593
+ ]
1594
+ }
1595
+ ],
1596
+ rules: [
1597
+ { field: "output_format", value: "markdown", source: "content_default" },
1598
+ { field: "style", value: "engaging", source: "content_default" }
1599
+ ]
1600
+ };
1601
+ var ALL_PACKS = {
1602
+ marketing: MARKETING_PACK,
1603
+ software: SOFTWARE_DEV_PACK,
1604
+ content: CONTENT_PACK
1605
+ };
1606
+ function getPackKnowledge(packId) {
1607
+ const pack = Object.values(ALL_PACKS).find((p) => p.id === packId);
1608
+ return pack?.knowledge ?? [];
1609
+ }
1610
+ function getPackTemplates(packId) {
1611
+ const pack = Object.values(ALL_PACKS).find((p) => p.id === packId);
1612
+ return pack?.templates ?? [];
1613
+ }
1614
+ function getPackRules(packId) {
1615
+ const pack = Object.values(ALL_PACKS).find((p) => p.id === packId);
1616
+ return pack?.rules ?? [];
1617
+ }
1618
+ function listPacks() {
1619
+ return Object.values(ALL_PACKS).map((p) => ({
1620
+ id: p.id,
1621
+ name: p.name,
1622
+ industry: p.industry,
1623
+ description: p.description
1624
+ }));
1625
+ }
1626
+
1627
+ // ecosystem/dashboard.ts
1628
+ function computeOverview(experiences) {
1629
+ const active = experiences.filter((e) => e.status === "active");
1630
+ const hypos = experiences.filter((e) => e.status === "hypothesis");
1631
+ const rolled = experiences.filter((e) => e.status === "rolled_back");
1632
+ const abstracts = experiences.filter((e) => e.is_abstract);
1633
+ const avgConf = experiences.length > 0 ? experiences.reduce((s, e) => s + e.confidence, 0) / experiences.length : 0;
1634
+ return {
1635
+ totalTasks: 0,
1636
+ // Filled externally
1637
+ totalExperiences: experiences.length,
1638
+ activeExperiences: active.length,
1639
+ hypotheses: hypos.length,
1640
+ rolledBack: rolled.length,
1641
+ abstractMethods: abstracts.length,
1642
+ avgConfidence: Number(avgConf.toFixed(3))
1643
+ };
1644
+ }
1645
+ function computeRetrievalStats(traces) {
1646
+ if (traces.length === 0) {
1647
+ return { totalQueries: 0, avgHitsPerQuery: 0, avgInjectedPerQuery: 0, topPartitions: [], topTags: [] };
1648
+ }
1649
+ const partitionCounts = /* @__PURE__ */ new Map();
1650
+ const tagCounts = /* @__PURE__ */ new Map();
1651
+ let totalHits = 0;
1652
+ let totalInjected = 0;
1653
+ for (const trace of traces) {
1654
+ totalHits += trace.hits.length;
1655
+ totalInjected += trace.injected.length;
1656
+ for (const p of trace.partitions_searched) {
1657
+ partitionCounts.set(p, (partitionCounts.get(p) ?? 0) + 1);
1658
+ }
1659
+ for (const t of trace.query_tags) {
1660
+ tagCounts.set(t, (tagCounts.get(t) ?? 0) + 1);
1661
+ }
1662
+ }
1663
+ const topPartitions = [...partitionCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10).map(([partition, count]) => ({ partition, count }));
1664
+ const topTags = [...tagCounts.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10).map(([tag, count]) => ({ tag, count }));
1665
+ return {
1666
+ totalQueries: traces.length,
1667
+ avgHitsPerQuery: Number((totalHits / traces.length).toFixed(2)),
1668
+ avgInjectedPerQuery: Number((totalInjected / traces.length).toFixed(2)),
1669
+ topPartitions,
1670
+ topTags
1671
+ };
1672
+ }
1673
+ function computeAttributionBreakdown(attributions) {
1674
+ const byTarget = {};
1675
+ let actionableCount = 0;
1676
+ for (const attr of attributions) {
1677
+ byTarget[attr.primaryCause] = (byTarget[attr.primaryCause] ?? 0) + 1;
1678
+ if (attr.actionable) actionableCount++;
1679
+ }
1680
+ const topIssues = Object.entries(byTarget).sort((a, b) => b[1] - a[1]).map(([target, count]) => ({ target, count }));
1681
+ return {
1682
+ total: attributions.length,
1683
+ byTarget,
1684
+ actionableRate: attributions.length > 0 ? Number((actionableCount / attributions.length).toFixed(3)) : 0,
1685
+ topIssues
1686
+ };
1687
+ }
1688
+ function computeDeviationTrends(analyses) {
1689
+ const groups = /* @__PURE__ */ new Map();
1690
+ for (const a of analyses) {
1691
+ for (const d of a.deviations) {
1692
+ const key = `${a.taskType}::${d.dimension}`;
1693
+ const group = groups.get(key) ?? [];
1694
+ group.push(a);
1695
+ groups.set(key, group);
1696
+ }
1697
+ }
1698
+ const trends = [];
1699
+ for (const [key, group] of groups) {
1700
+ const [taskType, dimension] = key.split("::");
1701
+ const deviations = group.flatMap((a) => a.deviations.filter((d) => d.dimension === dimension));
1702
+ const avgRatio = deviations.reduce((s, d) => s + d.ratio, 0) / deviations.length;
1703
+ const dist = { normal: 0, mild: 0, significant: 0, reverse: 0 };
1704
+ for (const d of deviations) dist[d.level]++;
1705
+ trends.push({ taskType, dimension, avgRatio: Number(avgRatio.toFixed(3)), levelDistribution: dist });
1706
+ }
1707
+ return trends;
1708
+ }
1709
+ function computePropagationFlow(experiences) {
1710
+ const published = experiences.filter((e) => e.partition === "global" && e.status === "active");
1711
+ const verified = experiences.filter((e) => e.verified_count > 0);
1712
+ const avgVC = experiences.length > 0 ? experiences.reduce((s, e) => s + e.verified_count, 0) / experiences.length : 0;
1713
+ return {
1714
+ totalPublished: published.length,
1715
+ totalVerified: verified.length,
1716
+ totalChallenged: experiences.filter((e) => e.status === "hypothesis").length,
1717
+ avgVerifiedCount: Number(avgVC.toFixed(2))
1718
+ };
1719
+ }
1720
+
1721
+ // utils/fallback.ts
1722
+ async function safeguard(fn, fallbackValue, options) {
1723
+ try {
1724
+ return await fn();
1725
+ } catch (error) {
1726
+ if (options?.logError !== false) {
1727
+ console.error("[AgentEvolve] Fallback:", error);
1728
+ }
1729
+ return fallbackValue;
1730
+ }
1731
+ }
1732
+ export {
1733
+ ALL_PACKS,
1734
+ CONTENT_PACK,
1735
+ Codec,
1736
+ DEFAULT_ATTENTION_BUDGET,
1737
+ DEFAULT_ROUGH_INTENT,
1738
+ DEFAULT_THRESHOLD,
1739
+ DeviationAccumulator,
1740
+ EXTRACTION_PROMPT,
1741
+ FEEDBACK_TEMPLATES,
1742
+ IndexTable,
1743
+ MARKETING_PACK,
1744
+ SOFTWARE_DEV_PACK,
1745
+ TEMPLATES,
1746
+ TemplateMarket,
1747
+ abstractify,
1748
+ analyzeAttribution,
1749
+ analyzePrediction,
1750
+ assembleContext,
1751
+ attributeIntentError,
1752
+ attributeOutputError,
1753
+ attributeRetrievalError,
1754
+ autoIngest,
1755
+ buildPerformanceWindow,
1756
+ buildQuestions,
1757
+ buildSourceTrace,
1758
+ buildTrace,
1759
+ calcConfidence,
1760
+ challengeExperience,
1761
+ checkFormatCompliance,
1762
+ checkKeywordCoverage,
1763
+ checkPerformanceDegradation,
1764
+ checkWordCount,
1765
+ computeAttributionBreakdown,
1766
+ computeDeviationTrends,
1767
+ computeOverview,
1768
+ computePropagationFlow,
1769
+ computeRetrievalStats,
1770
+ confirmIfNeeded,
1771
+ conflictDetect,
1772
+ contextFill,
1773
+ contextFillRefine,
1774
+ createExperienceEntry,
1775
+ decideRollback,
1776
+ dedup,
1777
+ distillGroup,
1778
+ evaluate,
1779
+ executeRollback,
1780
+ extractConstraints,
1781
+ extractKeywords,
1782
+ extractTags,
1783
+ filterPropagatable,
1784
+ findDistillationCandidates,
1785
+ getPackKnowledge,
1786
+ getPackRules,
1787
+ getPackTemplates,
1788
+ groupByField,
1789
+ intentPipeline,
1790
+ isConflicting,
1791
+ listPacks,
1792
+ normalizeFeedback,
1793
+ parseIntentBlock,
1794
+ publishToGlobal,
1795
+ rankByReliability,
1796
+ resolvePartition,
1797
+ resolveSource,
1798
+ routeExperience,
1799
+ runDistillation,
1800
+ runVerification,
1801
+ safeguard,
1802
+ selectAttentionSlots,
1803
+ selectTemplate,
1804
+ stripIntentBlock,
1805
+ structure,
1806
+ summarizeFeedback,
1807
+ updateIntent,
1808
+ verifyExperience,
1809
+ verifyFieldPresence,
1810
+ verifyJsonSchema,
1811
+ verifyRegex
1812
+ };