@timmeck/brain-core 2.36.57 → 2.36.59

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/README.md +6 -0
  2. package/command-center.html +133 -2
  3. package/dist/action/__tests__/adjust-parameter-handler.test.d.ts +1 -0
  4. package/dist/action/__tests__/adjust-parameter-handler.test.js +138 -0
  5. package/dist/action/__tests__/adjust-parameter-handler.test.js.map +1 -0
  6. package/dist/action/__tests__/content-handler.test.d.ts +1 -0
  7. package/dist/action/__tests__/content-handler.test.js +100 -0
  8. package/dist/action/__tests__/content-handler.test.js.map +1 -0
  9. package/dist/action/__tests__/creative-seed-handler.test.d.ts +1 -0
  10. package/dist/action/__tests__/creative-seed-handler.test.js +96 -0
  11. package/dist/action/__tests__/creative-seed-handler.test.js.map +1 -0
  12. package/dist/action/__tests__/trade-handler.test.d.ts +1 -0
  13. package/dist/action/__tests__/trade-handler.test.js +165 -0
  14. package/dist/action/__tests__/trade-handler.test.js.map +1 -0
  15. package/dist/action/action-bridge.d.ts +2 -2
  16. package/dist/action/action-bridge.js +1 -0
  17. package/dist/action/action-bridge.js.map +1 -1
  18. package/dist/action/handlers/adjust-parameter-handler.d.ts +28 -0
  19. package/dist/action/handlers/adjust-parameter-handler.js +44 -0
  20. package/dist/action/handlers/adjust-parameter-handler.js.map +1 -0
  21. package/dist/action/handlers/content-handler.d.ts +23 -0
  22. package/dist/action/handlers/content-handler.js +30 -0
  23. package/dist/action/handlers/content-handler.js.map +1 -0
  24. package/dist/action/handlers/creative-seed-handler.d.ts +24 -0
  25. package/dist/action/handlers/creative-seed-handler.js +34 -0
  26. package/dist/action/handlers/creative-seed-handler.js.map +1 -0
  27. package/dist/action/handlers/index.d.ts +8 -0
  28. package/dist/action/handlers/index.js +5 -0
  29. package/dist/action/handlers/index.js.map +1 -0
  30. package/dist/action/handlers/trade-handler.d.ts +43 -0
  31. package/dist/action/handlers/trade-handler.js +43 -0
  32. package/dist/action/handlers/trade-handler.js.map +1 -0
  33. package/dist/action/index.d.ts +2 -0
  34. package/dist/action/index.js +1 -0
  35. package/dist/action/index.js.map +1 -1
  36. package/dist/agent-training/__tests__/agent-trainer.test.d.ts +1 -0
  37. package/dist/agent-training/__tests__/agent-trainer.test.js +158 -0
  38. package/dist/agent-training/__tests__/agent-trainer.test.js.map +1 -0
  39. package/dist/agent-training/__tests__/sub-agent-factory.test.d.ts +1 -0
  40. package/dist/agent-training/__tests__/sub-agent-factory.test.js +100 -0
  41. package/dist/agent-training/__tests__/sub-agent-factory.test.js.map +1 -0
  42. package/dist/agent-training/__tests__/sub-agent.test.d.ts +1 -0
  43. package/dist/agent-training/__tests__/sub-agent.test.js +102 -0
  44. package/dist/agent-training/__tests__/sub-agent.test.js.map +1 -0
  45. package/dist/agent-training/index.d.ts +4 -0
  46. package/dist/agent-training/index.js +2 -0
  47. package/dist/agent-training/index.js.map +1 -1
  48. package/dist/agent-training/sub-agent-factory.d.ts +36 -0
  49. package/dist/agent-training/sub-agent-factory.js +128 -0
  50. package/dist/agent-training/sub-agent-factory.js.map +1 -0
  51. package/dist/agent-training/sub-agent.d.ts +57 -0
  52. package/dist/agent-training/sub-agent.js +135 -0
  53. package/dist/agent-training/sub-agent.js.map +1 -0
  54. package/dist/chat/__tests__/chat-engine.test.d.ts +1 -0
  55. package/dist/chat/__tests__/chat-engine.test.js +209 -0
  56. package/dist/chat/__tests__/chat-engine.test.js.map +1 -0
  57. package/dist/chat/chat-engine.d.ts +55 -0
  58. package/dist/chat/chat-engine.js +222 -0
  59. package/dist/chat/chat-engine.js.map +1 -0
  60. package/dist/chat/index.d.ts +2 -0
  61. package/dist/chat/index.js +2 -0
  62. package/dist/chat/index.js.map +1 -0
  63. package/dist/codegen/codegen-server.js +2 -2
  64. package/dist/codegen/codegen-server.js.map +1 -1
  65. package/dist/content/__tests__/auto-publisher.test.d.ts +1 -0
  66. package/dist/content/__tests__/auto-publisher.test.js +125 -0
  67. package/dist/content/__tests__/auto-publisher.test.js.map +1 -0
  68. package/dist/content/auto-publisher.d.ts +51 -0
  69. package/dist/content/auto-publisher.js +147 -0
  70. package/dist/content/auto-publisher.js.map +1 -0
  71. package/dist/content/content-forge.d.ts +2 -0
  72. package/dist/content/content-forge.js +19 -0
  73. package/dist/content/content-forge.js.map +1 -1
  74. package/dist/content/index.d.ts +2 -0
  75. package/dist/content/index.js +1 -0
  76. package/dist/content/index.js.map +1 -1
  77. package/dist/creative/__tests__/creative-engine.test.d.ts +1 -0
  78. package/dist/creative/__tests__/creative-engine.test.js +151 -0
  79. package/dist/creative/__tests__/creative-engine.test.js.map +1 -0
  80. package/dist/cross-brain/__tests__/signal-router.test.d.ts +1 -0
  81. package/dist/cross-brain/__tests__/signal-router.test.js +218 -0
  82. package/dist/cross-brain/__tests__/signal-router.test.js.map +1 -0
  83. package/dist/cross-brain/signal-router.d.ts +57 -0
  84. package/dist/cross-brain/signal-router.js +148 -0
  85. package/dist/cross-brain/signal-router.js.map +1 -0
  86. package/dist/dashboard/__tests__/command-center-server.test.js +31 -0
  87. package/dist/dashboard/__tests__/command-center-server.test.js.map +1 -1
  88. package/dist/dashboard/command-center-server.d.ts +11 -0
  89. package/dist/dashboard/command-center-server.js +72 -0
  90. package/dist/dashboard/command-center-server.js.map +1 -1
  91. package/dist/dream/__tests__/dream-engine.test.d.ts +1 -0
  92. package/dist/dream/__tests__/dream-engine.test.js +184 -0
  93. package/dist/dream/__tests__/dream-engine.test.js.map +1 -0
  94. package/dist/feedback/__tests__/feedback-router.test.d.ts +1 -0
  95. package/dist/feedback/__tests__/feedback-router.test.js +173 -0
  96. package/dist/feedback/__tests__/feedback-router.test.js.map +1 -0
  97. package/dist/feedback/feedback-router.d.ts +53 -0
  98. package/dist/feedback/feedback-router.js +193 -0
  99. package/dist/feedback/feedback-router.js.map +1 -0
  100. package/dist/feedback/index.d.ts +2 -0
  101. package/dist/feedback/index.js +1 -0
  102. package/dist/feedback/index.js.map +1 -1
  103. package/dist/goals/__tests__/goal-engine.test.d.ts +1 -0
  104. package/dist/goals/__tests__/goal-engine.test.js +203 -0
  105. package/dist/goals/__tests__/goal-engine.test.js.map +1 -0
  106. package/dist/guardrails/__tests__/guardrail-engine.test.d.ts +1 -0
  107. package/dist/guardrails/__tests__/guardrail-engine.test.js +343 -0
  108. package/dist/guardrails/__tests__/guardrail-engine.test.js.map +1 -0
  109. package/dist/index.d.ts +14 -6
  110. package/dist/index.js +8 -3
  111. package/dist/index.js.map +1 -1
  112. package/dist/metacognition/__tests__/auto-experiment-engine.test.d.ts +1 -0
  113. package/dist/metacognition/__tests__/auto-experiment-engine.test.js +218 -0
  114. package/dist/metacognition/__tests__/auto-experiment-engine.test.js.map +1 -0
  115. package/dist/metacognition/__tests__/evolution-engine.test.d.ts +1 -0
  116. package/dist/metacognition/__tests__/evolution-engine.test.js +473 -0
  117. package/dist/metacognition/__tests__/evolution-engine.test.js.map +1 -0
  118. package/dist/metacognition/__tests__/parameter-registry.test.d.ts +1 -0
  119. package/dist/metacognition/__tests__/parameter-registry.test.js +223 -0
  120. package/dist/metacognition/__tests__/parameter-registry.test.js.map +1 -0
  121. package/dist/prediction/__tests__/prediction-engine.test.d.ts +1 -0
  122. package/dist/prediction/__tests__/prediction-engine.test.js +244 -0
  123. package/dist/prediction/__tests__/prediction-engine.test.js.map +1 -0
  124. package/dist/research/research-orchestrator.js +3 -2
  125. package/dist/research/research-orchestrator.js.map +1 -1
  126. package/dist/sandbox/__tests__/code-sandbox.test.d.ts +1 -0
  127. package/dist/sandbox/__tests__/code-sandbox.test.js +182 -0
  128. package/dist/sandbox/__tests__/code-sandbox.test.js.map +1 -0
  129. package/dist/scanner/__tests__/signal-scanner.test.d.ts +1 -0
  130. package/dist/scanner/__tests__/signal-scanner.test.js +142 -0
  131. package/dist/scanner/__tests__/signal-scanner.test.js.map +1 -0
  132. package/dist/self-modification/__tests__/self-modification-engine.test.d.ts +1 -0
  133. package/dist/self-modification/__tests__/self-modification-engine.test.js +313 -0
  134. package/dist/self-modification/__tests__/self-modification-engine.test.js.map +1 -0
  135. package/dist/self-modification/self-modification-engine.d.ts +4 -1
  136. package/dist/self-modification/self-modification-engine.js +41 -3
  137. package/dist/self-modification/self-modification-engine.js.map +1 -1
  138. package/dist/strategy/__tests__/strategy-forge.test.js +69 -0
  139. package/dist/strategy/__tests__/strategy-forge.test.js.map +1 -1
  140. package/dist/strategy/__tests__/strategy-mutator.test.d.ts +1 -0
  141. package/dist/strategy/__tests__/strategy-mutator.test.js +141 -0
  142. package/dist/strategy/__tests__/strategy-mutator.test.js.map +1 -0
  143. package/dist/strategy/index.d.ts +2 -0
  144. package/dist/strategy/index.js +1 -0
  145. package/dist/strategy/index.js.map +1 -1
  146. package/dist/strategy/strategy-forge.d.ts +4 -1
  147. package/dist/strategy/strategy-forge.js +34 -2
  148. package/dist/strategy/strategy-forge.js.map +1 -1
  149. package/dist/strategy/strategy-mutator.d.ts +42 -0
  150. package/dist/strategy/strategy-mutator.js +140 -0
  151. package/dist/strategy/strategy-mutator.js.map +1 -0
  152. package/dist/unified/unified-server.js +2 -2
  153. package/dist/unified/unified-server.js.map +1 -1
  154. package/package.json +1 -1
@@ -0,0 +1,158 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import Database from 'better-sqlite3';
3
+ vi.mock('../../utils/logger.js', () => ({
4
+ getLogger: () => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() }),
5
+ }));
6
+ import { AgentTrainer, runTrainerMigration } from '../agent-trainer.js';
7
+ import { BenchmarkSuite, runBenchmarkMigration } from '../benchmark-suite.js';
8
+ describe('AgentTrainer', () => {
9
+ let db;
10
+ let suite;
11
+ const easyCases = [
12
+ { input: '2+2', expected: '4', category: 'math', difficulty: 'easy' },
13
+ { input: '3+1', expected: '4', category: 'math', difficulty: 'easy' },
14
+ ];
15
+ const mediumCases = [
16
+ { input: '10*5', expected: '50', category: 'math', difficulty: 'medium' },
17
+ { input: '100/4', expected: '25', category: 'math', difficulty: 'medium' },
18
+ ];
19
+ const hardCases = [
20
+ { input: 'sqrt(144)', expected: '12', category: 'math', difficulty: 'hard' },
21
+ { input: '2^10', expected: '1024', category: 'math', difficulty: 'hard' },
22
+ ];
23
+ beforeEach(() => {
24
+ db = new Database(':memory:');
25
+ runBenchmarkMigration(db);
26
+ runTrainerMigration(db);
27
+ suite = new BenchmarkSuite(db);
28
+ suite.addCases([...easyCases, ...mediumCases, ...hardCases]);
29
+ });
30
+ afterEach(() => { db.close(); });
31
+ it('creates trainer without error', () => {
32
+ const trainer = new AgentTrainer(db);
33
+ expect(trainer).toBeInstanceOf(AgentTrainer);
34
+ });
35
+ it('getStatus returns zeros when no training has occurred', () => {
36
+ const trainer = new AgentTrainer(db);
37
+ const status = trainer.getStatus();
38
+ expect(status.totalTrainingSessions).toBe(0);
39
+ expect(status.bestAccuracy).toBe(0);
40
+ expect(status.lastAccuracy).toBeNull();
41
+ expect(status.totalEpochsRun).toBe(0);
42
+ expect(status.avgImprovement).toBe(0);
43
+ });
44
+ it('setBenchmarkSuite sets suite for training', async () => {
45
+ const trainer = new AgentTrainer(db);
46
+ trainer.setBenchmarkSuite(suite);
47
+ // Verifying it doesn't throw when training after setting suite
48
+ const report = await trainer.train(async () => 'ignored', { epochs: 1 });
49
+ expect(report.totalEpochs).toBe(1);
50
+ });
51
+ it('throws if train is called without setBenchmarkSuite', async () => {
52
+ const trainer = new AgentTrainer(db);
53
+ await expect(trainer.train(async () => 'x')).rejects.toThrow('BenchmarkSuite not set');
54
+ });
55
+ it('trains with evalFn that returns correct answers', async () => {
56
+ const trainer = new AgentTrainer(db);
57
+ trainer.setBenchmarkSuite(suite);
58
+ const answers = {
59
+ '2+2': '4', '3+1': '4',
60
+ '10*5': '50', '100/4': '25',
61
+ 'sqrt(144)': '12', '2^10': '1024',
62
+ };
63
+ const report = await trainer.train(async (input) => answers[input] ?? 'unknown', { epochs: 3, name: 'perfect-run' });
64
+ expect(report.name).toBe('perfect-run');
65
+ expect(report.totalEpochs).toBe(3);
66
+ expect(report.bestAccuracy).toBe(1);
67
+ expect(report.finalAccuracy).toBe(1);
68
+ expect(report.passed).toBe(true);
69
+ expect(report.id).toMatch(/^train-/);
70
+ expect(report.durationMs).toBeGreaterThanOrEqual(0);
71
+ });
72
+ it('trains with evalFn that returns wrong answers', async () => {
73
+ const trainer = new AgentTrainer(db);
74
+ trainer.setBenchmarkSuite(suite);
75
+ const report = await trainer.train(async () => 'wrong', { epochs: 1, name: 'fail-run', curriculumLearning: false });
76
+ expect(report.finalAccuracy).toBe(0);
77
+ expect(report.passed).toBe(false);
78
+ expect(report.epochs[0].passed).toBe(false);
79
+ });
80
+ it('getHistory returns persisted sessions', async () => {
81
+ const trainer = new AgentTrainer(db);
82
+ trainer.setBenchmarkSuite(suite);
83
+ await trainer.train(async () => '4', { epochs: 1, name: 'session-1' });
84
+ await trainer.train(async () => '50', { epochs: 1, name: 'session-2' });
85
+ const history = trainer.getHistory();
86
+ expect(history).toHaveLength(2);
87
+ expect(history.map(h => h.name)).toContain('session-1');
88
+ expect(history.map(h => h.name)).toContain('session-2');
89
+ expect(typeof history[0].finalAccuracy).toBe('number');
90
+ expect(typeof history[0].passed).toBe('boolean');
91
+ });
92
+ it('getSession returns full report by id', async () => {
93
+ const trainer = new AgentTrainer(db);
94
+ trainer.setBenchmarkSuite(suite);
95
+ const report = await trainer.train(async () => '4', { epochs: 1, name: 'retrievable' });
96
+ const session = trainer.getSession(report.id);
97
+ expect(session).not.toBeNull();
98
+ expect(session.name).toBe('retrievable');
99
+ expect(session.epochs).toHaveLength(1);
100
+ expect(session.id).toBe(report.id);
101
+ });
102
+ it('getSession returns null for unknown id', () => {
103
+ const trainer = new AgentTrainer(db);
104
+ expect(trainer.getSession('nonexistent-id')).toBeNull();
105
+ });
106
+ it('uses curriculum learning with ascending difficulty', async () => {
107
+ const trainer = new AgentTrainer(db);
108
+ trainer.setBenchmarkSuite(suite);
109
+ const report = await trainer.train(async () => 'any', { epochs: 3, curriculumLearning: true, name: 'curriculum-test' });
110
+ expect(report.epochs).toHaveLength(3);
111
+ expect(report.epochs[0].difficulty).toBe('easy');
112
+ expect(report.epochs[1].difficulty).toBe('medium');
113
+ expect(report.epochs[2].difficulty).toBe('hard');
114
+ });
115
+ it('skips curriculum when curriculumLearning is false', async () => {
116
+ const trainer = new AgentTrainer(db);
117
+ trainer.setBenchmarkSuite(suite);
118
+ const report = await trainer.train(async () => 'any', { epochs: 2, curriculumLearning: false, name: 'no-curriculum' });
119
+ expect(report.epochs).toHaveLength(2);
120
+ expect(report.epochs[0].difficulty).toBe('all');
121
+ expect(report.epochs[1].difficulty).toBe('all');
122
+ });
123
+ it('triggers early stopping when accuracy drops significantly', async () => {
124
+ const trainer = new AgentTrainer(db);
125
+ trainer.setBenchmarkSuite(suite);
126
+ // Easy cases get correct answers, medium/hard get wrong answers
127
+ // Epoch 1 (easy): 100% accuracy, Epoch 2 (medium): 0% accuracy → drop > 0.2 → stop
128
+ const answers = { '2+2': '4', '3+1': '4' };
129
+ const report = await trainer.train(async (input) => answers[input] ?? 'wrong', { epochs: 3, curriculumLearning: true, earlyStop: true, name: 'early-stop-test' });
130
+ // Should stop after epoch 2 due to accuracy drop from 1.0 to 0.0 (> 0.2)
131
+ expect(report.totalEpochs).toBe(2);
132
+ expect(report.epochs).toHaveLength(2);
133
+ expect(report.epochs[0].difficulty).toBe('easy');
134
+ expect(report.epochs[1].difficulty).toBe('medium');
135
+ });
136
+ it('getStatus reflects training history', async () => {
137
+ const trainer = new AgentTrainer(db);
138
+ trainer.setBenchmarkSuite(suite);
139
+ const answers = {
140
+ '2+2': '4', '3+1': '4',
141
+ '10*5': '50', '100/4': '25',
142
+ 'sqrt(144)': '12', '2^10': '1024',
143
+ };
144
+ await trainer.train(async (input) => answers[input] ?? 'unknown', { epochs: 1, name: 'status-check' });
145
+ const status = trainer.getStatus();
146
+ expect(status.totalTrainingSessions).toBe(1);
147
+ expect(status.bestAccuracy).toBeGreaterThan(0);
148
+ expect(status.lastAccuracy).not.toBeNull();
149
+ expect(status.totalEpochsRun).toBe(1);
150
+ });
151
+ it('migration is idempotent', () => {
152
+ runTrainerMigration(db);
153
+ runTrainerMigration(db);
154
+ const trainer = new AgentTrainer(db);
155
+ expect(trainer.getHistory()).toHaveLength(0);
156
+ });
157
+ });
158
+ //# sourceMappingURL=agent-trainer.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent-trainer.test.js","sourceRoot":"","sources":["../../../src/agent-training/__tests__/agent-trainer.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,100 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import Database from 'better-sqlite3';
3
+ vi.mock('../../utils/logger.js', () => ({
4
+ getLogger: () => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() }),
5
+ }));
6
+ import { SubAgentFactory } from '../sub-agent-factory.js';
7
+ describe('SubAgentFactory', () => {
8
+ let db;
9
+ beforeEach(() => { db = new Database(':memory:'); });
10
+ afterEach(() => { db.close(); });
11
+ it('creates a factory with no agents', () => {
12
+ const factory = new SubAgentFactory(db);
13
+ expect(factory.list()).toHaveLength(0);
14
+ expect(factory.getStatus().totalAgents).toBe(0);
15
+ });
16
+ it('creates an agent with config', () => {
17
+ const factory = new SubAgentFactory(db);
18
+ const agent = factory.create({
19
+ name: 'analyst',
20
+ specialization: 'crypto',
21
+ description: 'Crypto analyst',
22
+ systemPrompt: 'Analyze crypto.',
23
+ tools: ['market.data'],
24
+ });
25
+ expect(agent.config.name).toBe('analyst');
26
+ expect(factory.list()).toHaveLength(1);
27
+ });
28
+ it('prevents duplicate agent names', () => {
29
+ const factory = new SubAgentFactory(db);
30
+ factory.create({ name: 'dup', specialization: 'x', description: '', systemPrompt: '', tools: [] });
31
+ expect(() => factory.create({ name: 'dup', specialization: 'y', description: '', systemPrompt: '', tools: [] })).toThrow('already exists');
32
+ });
33
+ it('gets agent by name', () => {
34
+ const factory = new SubAgentFactory(db);
35
+ factory.create({ name: 'writer', specialization: 'content', description: '', systemPrompt: '', tools: [] });
36
+ const agent = factory.get('writer');
37
+ expect(agent).not.toBeNull();
38
+ expect(agent.config.specialization).toBe('content');
39
+ });
40
+ it('returns null for unknown agent', () => {
41
+ const factory = new SubAgentFactory(db);
42
+ expect(factory.get('nonexistent')).toBeNull();
43
+ });
44
+ it('removes an agent', () => {
45
+ const factory = new SubAgentFactory(db);
46
+ factory.create({ name: 'temp', specialization: 'x', description: '', systemPrompt: '', tools: [] });
47
+ expect(factory.remove('temp')).toBe(true);
48
+ expect(factory.list()).toHaveLength(0);
49
+ expect(factory.remove('temp')).toBe(false);
50
+ });
51
+ it('creates agent from preset', () => {
52
+ const factory = new SubAgentFactory(db);
53
+ const agent = factory.createFromPreset('crypto-analyst');
54
+ expect(agent.config.specialization).toBe('cryptocurrency');
55
+ expect(agent.config.tools.length).toBeGreaterThan(0);
56
+ });
57
+ it('creates agent from preset with custom name', () => {
58
+ const factory = new SubAgentFactory(db);
59
+ const agent = factory.createFromPreset('content-writer', 'my-writer');
60
+ expect(agent.config.name).toBe('my-writer');
61
+ expect(agent.config.specialization).toBe('content');
62
+ });
63
+ it('throws for unknown preset', () => {
64
+ const factory = new SubAgentFactory(db);
65
+ expect(() => factory.createFromPreset('nonexistent')).toThrow('Unknown preset');
66
+ });
67
+ it('lists available presets', () => {
68
+ const factory = new SubAgentFactory(db);
69
+ const presets = factory.getPresets();
70
+ expect(presets).toContain('crypto-analyst');
71
+ expect(presets).toContain('content-writer');
72
+ expect(presets).toContain('code-reviewer');
73
+ expect(presets).toContain('research-agent');
74
+ });
75
+ it('sets executor on all agents', async () => {
76
+ const factory = new SubAgentFactory(db);
77
+ factory.setExecutor(async (input) => `echo: ${input}`);
78
+ const agent = factory.create({ name: 'runner', specialization: 'x', description: '', systemPrompt: '', tools: [] });
79
+ const task = await agent.execute('hello');
80
+ expect(task.output).toBe('echo: hello');
81
+ });
82
+ it('persists agents across factory instances', () => {
83
+ const factory1 = new SubAgentFactory(db);
84
+ factory1.create({ name: 'persistent', specialization: 'db', description: 'test', systemPrompt: 'test', tools: ['a'] });
85
+ const factory2 = new SubAgentFactory(db);
86
+ expect(factory2.list()).toHaveLength(1);
87
+ expect(factory2.get('persistent').config.specialization).toBe('db');
88
+ });
89
+ it('returns comprehensive status', async () => {
90
+ const factory = new SubAgentFactory(db);
91
+ factory.setExecutor(async () => 'done');
92
+ const agent = factory.create({ name: 'a1', specialization: 'x', description: '', systemPrompt: '', tools: [] });
93
+ await agent.execute('task');
94
+ const status = factory.getStatus();
95
+ expect(status.totalAgents).toBe(1);
96
+ expect(status.agents[0].name).toBe('a1');
97
+ expect(status.agents[0].completedTasks).toBe(1);
98
+ });
99
+ });
100
+ //# sourceMappingURL=sub-agent-factory.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sub-agent-factory.test.js","sourceRoot":"","sources":["../../../src/agent-training/__tests__/sub-agent-factory.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,102 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import Database from 'better-sqlite3';
3
+ vi.mock('../../utils/logger.js', () => ({
4
+ getLogger: () => ({ info: vi.fn(), warn: vi.fn(), error: vi.fn(), debug: vi.fn() }),
5
+ }));
6
+ import { SubAgent, runSubAgentMigration } from '../sub-agent.js';
7
+ describe('SubAgent', () => {
8
+ let db;
9
+ const config = {
10
+ name: 'test-agent',
11
+ specialization: 'testing',
12
+ description: 'Test agent',
13
+ systemPrompt: 'You are a test agent.',
14
+ tools: ['tool1', 'tool2'],
15
+ };
16
+ beforeEach(() => {
17
+ db = new Database(':memory:');
18
+ runSubAgentMigration(db);
19
+ // Insert agent row
20
+ db.prepare(`INSERT INTO sub_agents (name, specialization, description, system_prompt, tools, max_concurrent, created_at) VALUES (?, ?, ?, ?, ?, 1, ?)`).run(config.name, config.specialization, config.description, config.systemPrompt, JSON.stringify(config.tools), Date.now());
21
+ });
22
+ afterEach(() => { db.close(); });
23
+ it('creates a sub-agent with config', () => {
24
+ const agent = new SubAgent(db, 1, config);
25
+ expect(agent.id).toBe(1);
26
+ expect(agent.config.name).toBe('test-agent');
27
+ expect(agent.config.specialization).toBe('testing');
28
+ });
29
+ it('submits a task', () => {
30
+ const agent = new SubAgent(db, 1, config);
31
+ const taskId = agent.submit('analyze something');
32
+ expect(taskId).toMatch(/^task-/);
33
+ });
34
+ it('lists tasks after submission', () => {
35
+ const agent = new SubAgent(db, 1, config);
36
+ agent.submit('task 1');
37
+ agent.submit('task 2');
38
+ const tasks = agent.getTasks();
39
+ expect(tasks).toHaveLength(2);
40
+ expect(tasks[0].status).toBe('pending');
41
+ });
42
+ it('executes a task with executor', async () => {
43
+ const agent = new SubAgent(db, 1, config);
44
+ agent.setExecutor(async (input) => `Result: ${input}`);
45
+ const task = await agent.execute('analyze BTC');
46
+ expect(task.status).toBe('completed');
47
+ expect(task.output).toBe('Result: analyze BTC');
48
+ });
49
+ it('handles executor failure', async () => {
50
+ const agent = new SubAgent(db, 1, config);
51
+ agent.setExecutor(async () => { throw new Error('LLM timeout'); });
52
+ const task = await agent.execute('fail me');
53
+ expect(task.status).toBe('failed');
54
+ expect(task.error).toBe('LLM timeout');
55
+ });
56
+ it('throws if no executor set', async () => {
57
+ const agent = new SubAgent(db, 1, config);
58
+ agent.submit('task');
59
+ await expect(agent.run('nonexistent')).rejects.toThrow('No executor set');
60
+ });
61
+ it('returns status with counts', async () => {
62
+ const agent = new SubAgent(db, 1, config);
63
+ agent.setExecutor(async (input) => `done: ${input}`);
64
+ await agent.execute('task 1');
65
+ await agent.execute('task 2');
66
+ const status = agent.getStatus();
67
+ expect(status.name).toBe('test-agent');
68
+ expect(status.totalTasks).toBe(2);
69
+ expect(status.completedTasks).toBe(2);
70
+ expect(status.failedTasks).toBe(0);
71
+ expect(status.lastRunAt).toBeTruthy();
72
+ });
73
+ it('tracks mixed task outcomes in status', async () => {
74
+ const agent = new SubAgent(db, 1, config);
75
+ let callCount = 0;
76
+ agent.setExecutor(async () => {
77
+ callCount++;
78
+ if (callCount === 2)
79
+ throw new Error('fail');
80
+ return 'ok';
81
+ });
82
+ await agent.execute('task 1');
83
+ await agent.execute('task 2');
84
+ const status = agent.getStatus();
85
+ expect(status.completedTasks).toBe(1);
86
+ expect(status.failedTasks).toBe(1);
87
+ });
88
+ it('passes system prompt and tools to executor', async () => {
89
+ const agent = new SubAgent(db, 1, config);
90
+ const executor = vi.fn().mockResolvedValue('result');
91
+ agent.setExecutor(executor);
92
+ await agent.execute('input text');
93
+ expect(executor).toHaveBeenCalledWith('input text', 'You are a test agent.', ['tool1', 'tool2']);
94
+ });
95
+ it('migration is idempotent', () => {
96
+ runSubAgentMigration(db);
97
+ runSubAgentMigration(db);
98
+ const agent = new SubAgent(db, 1, config);
99
+ expect(agent.getTasks()).toHaveLength(0);
100
+ });
101
+ });
102
+ //# sourceMappingURL=sub-agent.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sub-agent.test.js","sourceRoot":"","sources":["../../../src/agent-training/__tests__/sub-agent.test.ts"],"names":[],"mappings":"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"}
@@ -2,3 +2,7 @@ export { BenchmarkSuite, runBenchmarkMigration } from './benchmark-suite.js';
2
2
  export type { EvalCase, EvalResult, BenchmarkReport, BenchmarkSuiteStatus, EvalFunction, ScoreFunction, } from './benchmark-suite.js';
3
3
  export { AgentTrainer, runTrainerMigration } from './agent-trainer.js';
4
4
  export type { TrainingConfig, EpochResult, TrainingReport, AgentTrainerStatus, } from './agent-trainer.js';
5
+ export { SubAgent, runSubAgentMigration } from './sub-agent.js';
6
+ export type { SubAgentConfig, SubAgentTask, SubAgentStatus, } from './sub-agent.js';
7
+ export { SubAgentFactory } from './sub-agent-factory.js';
8
+ export type { SubAgentFactoryStatus } from './sub-agent-factory.js';
@@ -1,3 +1,5 @@
1
1
  export { BenchmarkSuite, runBenchmarkMigration } from './benchmark-suite.js';
2
2
  export { AgentTrainer, runTrainerMigration } from './agent-trainer.js';
3
+ export { SubAgent, runSubAgentMigration } from './sub-agent.js';
4
+ export { SubAgentFactory } from './sub-agent-factory.js';
3
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent-training/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAM7E,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent-training/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAM7E,OAAO,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAKvE,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAKhE,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,36 @@
1
+ import type Database from 'better-sqlite3';
2
+ import { SubAgent } from './sub-agent.js';
3
+ import type { SubAgentConfig, SubAgentStatus } from './sub-agent.js';
4
+ export interface SubAgentFactoryStatus {
5
+ totalAgents: number;
6
+ agents: SubAgentStatus[];
7
+ }
8
+ type TaskExecutor = (input: string, systemPrompt: string, tools: string[]) => Promise<string>;
9
+ export declare class SubAgentFactory {
10
+ private readonly db;
11
+ private readonly agents;
12
+ private executor;
13
+ private readonly stmtInsert;
14
+ private readonly stmtGetByName;
15
+ private readonly stmtGetAll;
16
+ private readonly stmtDelete;
17
+ constructor(db: Database.Database);
18
+ /** Set the executor used to run all sub-agent tasks */
19
+ setExecutor(executor: TaskExecutor): void;
20
+ /** Create a new sub-agent from config */
21
+ create(config: SubAgentConfig): SubAgent;
22
+ /** Create a sub-agent from a preset template */
23
+ createFromPreset(presetName: string, name?: string): SubAgent;
24
+ /** Get a sub-agent by name */
25
+ get(name: string): SubAgent | null;
26
+ /** List all sub-agents */
27
+ list(): SubAgent[];
28
+ /** Remove a sub-agent */
29
+ remove(name: string): boolean;
30
+ /** Get available preset names */
31
+ getPresets(): string[];
32
+ /** Get factory status */
33
+ getStatus(): SubAgentFactoryStatus;
34
+ private loadFromDb;
35
+ }
36
+ export {};
@@ -0,0 +1,128 @@
1
+ import { getLogger } from '../utils/logger.js';
2
+ import { SubAgent, runSubAgentMigration } from './sub-agent.js';
3
+ // ── Preset Templates ──────────────────────────────────────
4
+ const PRESETS = {
5
+ 'crypto-analyst': {
6
+ specialization: 'cryptocurrency',
7
+ description: 'Analyzes crypto markets, trends, and trading signals',
8
+ systemPrompt: 'You are a crypto market analyst. Analyze the given data and provide actionable insights about market trends, price movements, and trading signals.',
9
+ tools: ['market.data', 'signal.cross.status', 'paper.status'],
10
+ },
11
+ 'content-writer': {
12
+ specialization: 'content',
13
+ description: 'Writes and optimizes social media content',
14
+ systemPrompt: 'You are a content strategist. Create engaging, informative social media posts about the given topics. Focus on clarity, engagement, and value.',
15
+ tools: ['content.generate', 'content.best', 'insight.list'],
16
+ },
17
+ 'code-reviewer': {
18
+ specialization: 'code',
19
+ description: 'Reviews code patterns and suggests improvements',
20
+ systemPrompt: 'You are a senior code reviewer. Analyze the given code patterns, identify issues, and suggest improvements based on best practices.',
21
+ tools: ['codeforge.patterns', 'codeforge.products', 'code.health'],
22
+ },
23
+ 'research-agent': {
24
+ specialization: 'research',
25
+ description: 'Conducts deep research on given topics',
26
+ systemPrompt: 'You are a research agent. Investigate the given topic thoroughly, gather evidence, form hypotheses, and synthesize findings.',
27
+ tools: ['insight.list', 'memory.query', 'knowledge.search'],
28
+ },
29
+ };
30
+ // ── Factory ──────────────────────────────────────────────
31
+ const log = getLogger();
32
+ export class SubAgentFactory {
33
+ db;
34
+ agents = new Map();
35
+ executor = null;
36
+ stmtInsert;
37
+ stmtGetByName;
38
+ stmtGetAll;
39
+ stmtDelete;
40
+ constructor(db) {
41
+ this.db = db;
42
+ runSubAgentMigration(db);
43
+ this.stmtInsert = db.prepare(`INSERT INTO sub_agents (name, specialization, description, system_prompt, tools, max_concurrent, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)`);
44
+ this.stmtGetByName = db.prepare(`SELECT * FROM sub_agents WHERE name = ?`);
45
+ this.stmtGetAll = db.prepare(`SELECT * FROM sub_agents ORDER BY created_at ASC`);
46
+ this.stmtDelete = db.prepare(`DELETE FROM sub_agents WHERE name = ?`);
47
+ // Load existing agents from DB
48
+ this.loadFromDb();
49
+ }
50
+ /** Set the executor used to run all sub-agent tasks */
51
+ setExecutor(executor) {
52
+ this.executor = executor;
53
+ for (const agent of this.agents.values()) {
54
+ agent.setExecutor(executor);
55
+ }
56
+ }
57
+ /** Create a new sub-agent from config */
58
+ create(config) {
59
+ if (this.agents.has(config.name)) {
60
+ throw new Error(`Agent "${config.name}" already exists`);
61
+ }
62
+ const result = this.stmtInsert.run(config.name, config.specialization, config.description, config.systemPrompt, JSON.stringify(config.tools), config.maxConcurrent ?? 1, Date.now());
63
+ const agent = new SubAgent(this.db, Number(result.lastInsertRowid), config);
64
+ if (this.executor)
65
+ agent.setExecutor(this.executor);
66
+ this.agents.set(config.name, agent);
67
+ log.info(`[sub-agent-factory] Created agent: ${config.name} (${config.specialization})`);
68
+ return agent;
69
+ }
70
+ /** Create a sub-agent from a preset template */
71
+ createFromPreset(presetName, name) {
72
+ const preset = PRESETS[presetName];
73
+ if (!preset) {
74
+ throw new Error(`Unknown preset: "${presetName}". Available: ${Object.keys(PRESETS).join(', ')}`);
75
+ }
76
+ return this.create({ name: name ?? presetName, ...preset });
77
+ }
78
+ /** Get a sub-agent by name */
79
+ get(name) {
80
+ return this.agents.get(name) ?? null;
81
+ }
82
+ /** List all sub-agents */
83
+ list() {
84
+ return Array.from(this.agents.values());
85
+ }
86
+ /** Remove a sub-agent */
87
+ remove(name) {
88
+ if (!this.agents.has(name))
89
+ return false;
90
+ this.stmtDelete.run(name);
91
+ this.agents.delete(name);
92
+ log.info(`[sub-agent-factory] Removed agent: ${name}`);
93
+ return true;
94
+ }
95
+ /** Get available preset names */
96
+ getPresets() {
97
+ return Object.keys(PRESETS);
98
+ }
99
+ /** Get factory status */
100
+ getStatus() {
101
+ return {
102
+ totalAgents: this.agents.size,
103
+ agents: Array.from(this.agents.values()).map(a => a.getStatus()),
104
+ };
105
+ }
106
+ // ── Private ──────────────────────────────────────────────
107
+ loadFromDb() {
108
+ const rows = this.stmtGetAll.all();
109
+ for (const row of rows) {
110
+ const config = {
111
+ name: row.name,
112
+ specialization: row.specialization,
113
+ description: row.description,
114
+ systemPrompt: row.system_prompt,
115
+ tools: JSON.parse(row.tools),
116
+ maxConcurrent: row.max_concurrent,
117
+ };
118
+ const agent = new SubAgent(this.db, row.id, config);
119
+ if (this.executor)
120
+ agent.setExecutor(this.executor);
121
+ this.agents.set(row.name, agent);
122
+ }
123
+ if (rows.length > 0) {
124
+ log.info(`[sub-agent-factory] Loaded ${rows.length} agents from DB`);
125
+ }
126
+ }
127
+ }
128
+ //# sourceMappingURL=sub-agent-factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sub-agent-factory.js","sourceRoot":"","sources":["../../src/agent-training/sub-agent-factory.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAYhE,6DAA6D;AAE7D,MAAM,OAAO,GAAiD;IAC5D,gBAAgB,EAAE;QAChB,cAAc,EAAE,gBAAgB;QAChC,WAAW,EAAE,sDAAsD;QACnE,YAAY,EAAE,oJAAoJ;QAClK,KAAK,EAAE,CAAC,aAAa,EAAE,qBAAqB,EAAE,cAAc,CAAC;KAC9D;IACD,gBAAgB,EAAE;QAChB,cAAc,EAAE,SAAS;QACzB,WAAW,EAAE,2CAA2C;QACxD,YAAY,EAAE,gJAAgJ;QAC9J,KAAK,EAAE,CAAC,kBAAkB,EAAE,cAAc,EAAE,cAAc,CAAC;KAC5D;IACD,eAAe,EAAE;QACf,cAAc,EAAE,MAAM;QACtB,WAAW,EAAE,iDAAiD;QAC9D,YAAY,EAAE,qIAAqI;QACnJ,KAAK,EAAE,CAAC,oBAAoB,EAAE,oBAAoB,EAAE,aAAa,CAAC;KACnE;IACD,gBAAgB,EAAE;QAChB,cAAc,EAAE,UAAU;QAC1B,WAAW,EAAE,wCAAwC;QACrD,YAAY,EAAE,8HAA8H;QAC5I,KAAK,EAAE,CAAC,cAAc,EAAE,cAAc,EAAE,kBAAkB,CAAC;KAC5D;CACF,CAAC;AAEF,4DAA4D;AAE5D,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;AAExB,MAAM,OAAO,eAAe;IACT,EAAE,CAAoB;IACtB,MAAM,GAAG,IAAI,GAAG,EAAoB,CAAC;IAC9C,QAAQ,GAAwB,IAAI,CAAC;IAE5B,UAAU,CAAC;IACX,aAAa,CAAC;IACd,UAAU,CAAC;IACX,UAAU,CAAC;IAE5B,YAAY,EAAqB;QAC/B,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,oBAAoB,CAAC,EAAE,CAAC,CAAC;QAEzB,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC,2IAA2I,CAAC,CAAC;QAC1K,IAAI,CAAC,aAAa,GAAG,EAAE,CAAC,OAAO,CAAC,yCAAyC,CAAC,CAAC;QAC3E,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC,kDAAkD,CAAC,CAAC;QACjF,IAAI,CAAC,UAAU,GAAG,EAAE,CAAC,OAAO,CAAC,uCAAuC,CAAC,CAAC;QAEtE,+BAA+B;QAC/B,IAAI,CAAC,UAAU,EAAE,CAAC;IACpB,CAAC;IAED,uDAAuD;IACvD,WAAW,CAAC,QAAsB;QAChC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC;YACzC,KAAK,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,MAAM,CAAC,MAAsB;QAC3B,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;YACjC,MAAM,IAAI,KAAK,CAAC,UAAU,MAAM,CAAC,IAAI,kBAAkB,CAAC,CAAC;QAC3D,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAChC,MAAM,CAAC,IAAI,EACX,MAAM,CAAC,cAAc,EACrB,MAAM,CAAC,WAAW,EAClB,MAAM,CAAC,YAAY,EACnB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,EAC5B,MAAM,CAAC,aAAa,IAAI,CAAC,EACzB,IAAI,CAAC,GAAG,EAAE,CACX,CAAC;QAEF,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,EAAE,MAAM,CAAC,CAAC;QAC5E,IAAI,IAAI,CAAC,QAAQ;YAAE,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAEpC,GAAG,CAAC,IAAI,CAAC,sCAAsC,MAAM,CAAC,IAAI,KAAK,MAAM,CAAC,cAAc,GAAG,CAAC,CAAC;QACzF,OAAO,KAAK,CAAC;IACf,CAAC;IAED,gDAAgD;IAChD,gBAAgB,CAAC,UAAkB,EAAE,IAAa;QAChD,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;QACnC,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,oBAAoB,UAAU,iBAAiB,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpG,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,UAAU,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,8BAA8B;IAC9B,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;IACvC,CAAC;IAED,0BAA0B;IAC1B,IAAI;QACF,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;IAC1C,CAAC;IAED,yBAAyB;IACzB,MAAM,CAAC,IAAY;QACjB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAC;QACzC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACzB,GAAG,CAAC,IAAI,CAAC,sCAAsC,IAAI,EAAE,CAAC,CAAC;QACvD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,iCAAiC;IACjC,UAAU;QACR,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,yBAAyB;IACzB,SAAS;QACP,OAAO;YACL,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YAC7B,MAAM,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC;SACjE,CAAC;IACJ,CAAC;IAED,4DAA4D;IAEpD,UAAU;QAChB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,EAAgB,CAAC;QACjD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,MAAM,GAAmB;gBAC7B,IAAI,EAAE,GAAG,CAAC,IAAI;gBACd,cAAc,EAAE,GAAG,CAAC,cAAc;gBAClC,WAAW,EAAE,GAAG,CAAC,WAAW;gBAC5B,YAAY,EAAE,GAAG,CAAC,aAAa;gBAC/B,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC;gBAC5B,aAAa,EAAE,GAAG,CAAC,cAAc;aAClC,CAAC;YACF,MAAM,KAAK,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACpD,IAAI,IAAI,CAAC,QAAQ;gBAAE,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACpD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QACnC,CAAC;QACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpB,GAAG,CAAC,IAAI,CAAC,8BAA8B,IAAI,CAAC,MAAM,iBAAiB,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;CACF"}