@timmeck/brain-core 2.36.57 → 2.36.58
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/README.md +6 -0
- package/command-center.html +133 -2
- package/dist/action/__tests__/content-handler.test.d.ts +1 -0
- package/dist/action/__tests__/content-handler.test.js +100 -0
- package/dist/action/__tests__/content-handler.test.js.map +1 -0
- package/dist/action/__tests__/trade-handler.test.d.ts +1 -0
- package/dist/action/__tests__/trade-handler.test.js +165 -0
- package/dist/action/__tests__/trade-handler.test.js.map +1 -0
- package/dist/action/action-bridge.d.ts +2 -2
- package/dist/action/action-bridge.js +1 -0
- package/dist/action/action-bridge.js.map +1 -1
- package/dist/action/handlers/content-handler.d.ts +23 -0
- package/dist/action/handlers/content-handler.js +30 -0
- package/dist/action/handlers/content-handler.js.map +1 -0
- package/dist/action/handlers/index.d.ts +4 -0
- package/dist/action/handlers/index.js +3 -0
- package/dist/action/handlers/index.js.map +1 -0
- package/dist/action/handlers/trade-handler.d.ts +43 -0
- package/dist/action/handlers/trade-handler.js +43 -0
- package/dist/action/handlers/trade-handler.js.map +1 -0
- package/dist/action/index.d.ts +2 -0
- package/dist/action/index.js +1 -0
- package/dist/action/index.js.map +1 -1
- package/dist/agent-training/__tests__/agent-trainer.test.d.ts +1 -0
- package/dist/agent-training/__tests__/agent-trainer.test.js +158 -0
- package/dist/agent-training/__tests__/agent-trainer.test.js.map +1 -0
- package/dist/agent-training/__tests__/sub-agent-factory.test.d.ts +1 -0
- package/dist/agent-training/__tests__/sub-agent-factory.test.js +100 -0
- package/dist/agent-training/__tests__/sub-agent-factory.test.js.map +1 -0
- package/dist/agent-training/__tests__/sub-agent.test.d.ts +1 -0
- package/dist/agent-training/__tests__/sub-agent.test.js +102 -0
- package/dist/agent-training/__tests__/sub-agent.test.js.map +1 -0
- package/dist/agent-training/index.d.ts +4 -0
- package/dist/agent-training/index.js +2 -0
- package/dist/agent-training/index.js.map +1 -1
- package/dist/agent-training/sub-agent-factory.d.ts +36 -0
- package/dist/agent-training/sub-agent-factory.js +128 -0
- package/dist/agent-training/sub-agent-factory.js.map +1 -0
- package/dist/agent-training/sub-agent.d.ts +57 -0
- package/dist/agent-training/sub-agent.js +135 -0
- package/dist/agent-training/sub-agent.js.map +1 -0
- package/dist/chat/__tests__/chat-engine.test.d.ts +1 -0
- package/dist/chat/__tests__/chat-engine.test.js +128 -0
- package/dist/chat/__tests__/chat-engine.test.js.map +1 -0
- package/dist/chat/chat-engine.d.ts +55 -0
- package/dist/chat/chat-engine.js +186 -0
- package/dist/chat/chat-engine.js.map +1 -0
- package/dist/chat/index.d.ts +2 -0
- package/dist/chat/index.js +2 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/content/__tests__/auto-publisher.test.d.ts +1 -0
- package/dist/content/__tests__/auto-publisher.test.js +125 -0
- package/dist/content/__tests__/auto-publisher.test.js.map +1 -0
- package/dist/content/auto-publisher.d.ts +51 -0
- package/dist/content/auto-publisher.js +147 -0
- package/dist/content/auto-publisher.js.map +1 -0
- package/dist/content/content-forge.d.ts +2 -0
- package/dist/content/content-forge.js +19 -0
- package/dist/content/content-forge.js.map +1 -1
- package/dist/content/index.d.ts +2 -0
- package/dist/content/index.js +1 -0
- package/dist/content/index.js.map +1 -1
- package/dist/creative/__tests__/creative-engine.test.d.ts +1 -0
- package/dist/creative/__tests__/creative-engine.test.js +151 -0
- package/dist/creative/__tests__/creative-engine.test.js.map +1 -0
- package/dist/cross-brain/__tests__/signal-router.test.d.ts +1 -0
- package/dist/cross-brain/__tests__/signal-router.test.js +159 -0
- package/dist/cross-brain/__tests__/signal-router.test.js.map +1 -0
- package/dist/cross-brain/signal-router.d.ts +57 -0
- package/dist/cross-brain/signal-router.js +148 -0
- package/dist/cross-brain/signal-router.js.map +1 -0
- package/dist/dashboard/__tests__/command-center-server.test.js +31 -0
- package/dist/dashboard/__tests__/command-center-server.test.js.map +1 -1
- package/dist/dashboard/command-center-server.d.ts +11 -0
- package/dist/dashboard/command-center-server.js +72 -0
- package/dist/dashboard/command-center-server.js.map +1 -1
- package/dist/dream/__tests__/dream-engine.test.d.ts +1 -0
- package/dist/dream/__tests__/dream-engine.test.js +184 -0
- package/dist/dream/__tests__/dream-engine.test.js.map +1 -0
- package/dist/feedback/__tests__/feedback-router.test.d.ts +1 -0
- package/dist/feedback/__tests__/feedback-router.test.js +173 -0
- package/dist/feedback/__tests__/feedback-router.test.js.map +1 -0
- package/dist/feedback/feedback-router.d.ts +53 -0
- package/dist/feedback/feedback-router.js +193 -0
- package/dist/feedback/feedback-router.js.map +1 -0
- package/dist/feedback/index.d.ts +2 -0
- package/dist/feedback/index.js +1 -0
- package/dist/feedback/index.js.map +1 -1
- package/dist/goals/__tests__/goal-engine.test.d.ts +1 -0
- package/dist/goals/__tests__/goal-engine.test.js +203 -0
- package/dist/goals/__tests__/goal-engine.test.js.map +1 -0
- package/dist/guardrails/__tests__/guardrail-engine.test.d.ts +1 -0
- package/dist/guardrails/__tests__/guardrail-engine.test.js +343 -0
- package/dist/guardrails/__tests__/guardrail-engine.test.js.map +1 -0
- package/dist/index.d.ts +14 -6
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/dist/metacognition/__tests__/auto-experiment-engine.test.d.ts +1 -0
- package/dist/metacognition/__tests__/auto-experiment-engine.test.js +218 -0
- package/dist/metacognition/__tests__/auto-experiment-engine.test.js.map +1 -0
- package/dist/metacognition/__tests__/evolution-engine.test.d.ts +1 -0
- package/dist/metacognition/__tests__/evolution-engine.test.js +473 -0
- package/dist/metacognition/__tests__/evolution-engine.test.js.map +1 -0
- package/dist/metacognition/__tests__/parameter-registry.test.d.ts +1 -0
- package/dist/metacognition/__tests__/parameter-registry.test.js +223 -0
- package/dist/metacognition/__tests__/parameter-registry.test.js.map +1 -0
- package/dist/prediction/__tests__/prediction-engine.test.d.ts +1 -0
- package/dist/prediction/__tests__/prediction-engine.test.js +244 -0
- package/dist/prediction/__tests__/prediction-engine.test.js.map +1 -0
- package/dist/research/research-orchestrator.js +2 -1
- package/dist/research/research-orchestrator.js.map +1 -1
- package/dist/sandbox/__tests__/code-sandbox.test.d.ts +1 -0
- package/dist/sandbox/__tests__/code-sandbox.test.js +182 -0
- package/dist/sandbox/__tests__/code-sandbox.test.js.map +1 -0
- package/dist/scanner/__tests__/signal-scanner.test.d.ts +1 -0
- package/dist/scanner/__tests__/signal-scanner.test.js +142 -0
- package/dist/scanner/__tests__/signal-scanner.test.js.map +1 -0
- package/dist/self-modification/__tests__/self-modification-engine.test.d.ts +1 -0
- package/dist/self-modification/__tests__/self-modification-engine.test.js +255 -0
- package/dist/self-modification/__tests__/self-modification-engine.test.js.map +1 -0
- package/dist/strategy/__tests__/strategy-forge.test.js +69 -0
- package/dist/strategy/__tests__/strategy-forge.test.js.map +1 -1
- package/dist/strategy/__tests__/strategy-mutator.test.d.ts +1 -0
- package/dist/strategy/__tests__/strategy-mutator.test.js +141 -0
- package/dist/strategy/__tests__/strategy-mutator.test.js.map +1 -0
- package/dist/strategy/index.d.ts +2 -0
- package/dist/strategy/index.js +1 -0
- package/dist/strategy/index.js.map +1 -1
- package/dist/strategy/strategy-forge.d.ts +4 -1
- package/dist/strategy/strategy-forge.js +34 -2
- package/dist/strategy/strategy-forge.js.map +1 -1
- package/dist/strategy/strategy-mutator.d.ts +42 -0
- package/dist/strategy/strategy-mutator.js +140 -0
- package/dist/strategy/strategy-mutator.js.map +1 -0
- package/package.json +1 -1
|
@@ -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":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
export interface SubAgentConfig {
|
|
3
|
+
name: string;
|
|
4
|
+
specialization: string;
|
|
5
|
+
description: string;
|
|
6
|
+
systemPrompt: string;
|
|
7
|
+
tools: string[];
|
|
8
|
+
maxConcurrent?: number;
|
|
9
|
+
}
|
|
10
|
+
export interface SubAgentTask {
|
|
11
|
+
id: string;
|
|
12
|
+
agentId: number;
|
|
13
|
+
input: string;
|
|
14
|
+
output: string | null;
|
|
15
|
+
status: 'pending' | 'running' | 'completed' | 'failed';
|
|
16
|
+
error: string | null;
|
|
17
|
+
startedAt: number | null;
|
|
18
|
+
completedAt: number | null;
|
|
19
|
+
createdAt: number;
|
|
20
|
+
}
|
|
21
|
+
export interface SubAgentStatus {
|
|
22
|
+
id: number;
|
|
23
|
+
name: string;
|
|
24
|
+
specialization: string;
|
|
25
|
+
totalTasks: number;
|
|
26
|
+
completedTasks: number;
|
|
27
|
+
failedTasks: number;
|
|
28
|
+
avgDurationMs: number;
|
|
29
|
+
lastRunAt: string | null;
|
|
30
|
+
}
|
|
31
|
+
type TaskExecutor = (input: string, systemPrompt: string, tools: string[]) => Promise<string>;
|
|
32
|
+
export declare function runSubAgentMigration(db: Database.Database): void;
|
|
33
|
+
export declare class SubAgent {
|
|
34
|
+
readonly id: number;
|
|
35
|
+
readonly config: SubAgentConfig;
|
|
36
|
+
private readonly db;
|
|
37
|
+
private executor;
|
|
38
|
+
private readonly stmtInsertTask;
|
|
39
|
+
private readonly stmtUpdateTask;
|
|
40
|
+
private readonly stmtGetTasks;
|
|
41
|
+
private readonly stmtCountTasks;
|
|
42
|
+
constructor(db: Database.Database, id: number, config: SubAgentConfig);
|
|
43
|
+
setExecutor(executor: TaskExecutor): void;
|
|
44
|
+
/** Submit a task to this agent */
|
|
45
|
+
submit(input: string): string;
|
|
46
|
+
/** Run a specific task */
|
|
47
|
+
run(taskId: string): Promise<SubAgentTask>;
|
|
48
|
+
/** Submit and immediately run */
|
|
49
|
+
execute(input: string): Promise<SubAgentTask>;
|
|
50
|
+
/** Get task history */
|
|
51
|
+
getTasks(limit?: number): SubAgentTask[];
|
|
52
|
+
/** Get status */
|
|
53
|
+
getStatus(): SubAgentStatus;
|
|
54
|
+
private getTaskInput;
|
|
55
|
+
private getTask;
|
|
56
|
+
}
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { getLogger } from '../utils/logger.js';
|
|
2
|
+
// ── Migration ──────────────────────────────────────────────
|
|
3
|
+
export function runSubAgentMigration(db) {
|
|
4
|
+
db.exec(`
|
|
5
|
+
CREATE TABLE IF NOT EXISTS sub_agents (
|
|
6
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
7
|
+
name TEXT NOT NULL UNIQUE,
|
|
8
|
+
specialization TEXT NOT NULL,
|
|
9
|
+
description TEXT NOT NULL DEFAULT '',
|
|
10
|
+
system_prompt TEXT NOT NULL DEFAULT '',
|
|
11
|
+
tools TEXT NOT NULL DEFAULT '[]',
|
|
12
|
+
max_concurrent INTEGER NOT NULL DEFAULT 1,
|
|
13
|
+
created_at INTEGER NOT NULL
|
|
14
|
+
);
|
|
15
|
+
CREATE TABLE IF NOT EXISTS sub_agent_tasks (
|
|
16
|
+
id TEXT PRIMARY KEY,
|
|
17
|
+
agent_id INTEGER NOT NULL,
|
|
18
|
+
input TEXT NOT NULL,
|
|
19
|
+
output TEXT,
|
|
20
|
+
status TEXT NOT NULL DEFAULT 'pending',
|
|
21
|
+
error TEXT,
|
|
22
|
+
started_at INTEGER,
|
|
23
|
+
completed_at INTEGER,
|
|
24
|
+
created_at INTEGER NOT NULL,
|
|
25
|
+
FOREIGN KEY (agent_id) REFERENCES sub_agents(id)
|
|
26
|
+
);
|
|
27
|
+
CREATE INDEX IF NOT EXISTS idx_sat_agent ON sub_agent_tasks(agent_id);
|
|
28
|
+
CREATE INDEX IF NOT EXISTS idx_sat_status ON sub_agent_tasks(status);
|
|
29
|
+
`);
|
|
30
|
+
}
|
|
31
|
+
// ── SubAgent ──────────────────────────────────────────────
|
|
32
|
+
const log = getLogger();
|
|
33
|
+
export class SubAgent {
|
|
34
|
+
id;
|
|
35
|
+
config;
|
|
36
|
+
db;
|
|
37
|
+
executor = null;
|
|
38
|
+
stmtInsertTask;
|
|
39
|
+
stmtUpdateTask;
|
|
40
|
+
stmtGetTasks;
|
|
41
|
+
stmtCountTasks;
|
|
42
|
+
constructor(db, id, config) {
|
|
43
|
+
this.db = db;
|
|
44
|
+
this.id = id;
|
|
45
|
+
this.config = config;
|
|
46
|
+
this.stmtInsertTask = db.prepare(`INSERT INTO sub_agent_tasks (id, agent_id, input, status, created_at) VALUES (?, ?, ?, 'pending', ?)`);
|
|
47
|
+
this.stmtUpdateTask = db.prepare(`UPDATE sub_agent_tasks SET status = ?, output = ?, error = ?, started_at = COALESCE(started_at, ?), completed_at = ? WHERE id = ?`);
|
|
48
|
+
this.stmtGetTasks = db.prepare(`SELECT * FROM sub_agent_tasks WHERE agent_id = ? ORDER BY created_at DESC LIMIT ?`);
|
|
49
|
+
this.stmtCountTasks = db.prepare(`SELECT status, COUNT(*) as count FROM sub_agent_tasks WHERE agent_id = ? GROUP BY status`);
|
|
50
|
+
}
|
|
51
|
+
setExecutor(executor) {
|
|
52
|
+
this.executor = executor;
|
|
53
|
+
}
|
|
54
|
+
/** Submit a task to this agent */
|
|
55
|
+
submit(input) {
|
|
56
|
+
const taskId = `task-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`;
|
|
57
|
+
this.stmtInsertTask.run(taskId, this.id, input, Date.now());
|
|
58
|
+
log.info(`[sub-agent:${this.config.name}] Task submitted: ${taskId}`);
|
|
59
|
+
return taskId;
|
|
60
|
+
}
|
|
61
|
+
/** Run a specific task */
|
|
62
|
+
async run(taskId) {
|
|
63
|
+
if (!this.executor)
|
|
64
|
+
throw new Error(`No executor set for agent "${this.config.name}"`);
|
|
65
|
+
this.stmtUpdateTask.run('running', null, null, Date.now(), null, taskId);
|
|
66
|
+
try {
|
|
67
|
+
const output = await this.executor(this.getTaskInput(taskId), this.config.systemPrompt, this.config.tools);
|
|
68
|
+
this.stmtUpdateTask.run('completed', output, null, null, Date.now(), taskId);
|
|
69
|
+
log.info(`[sub-agent:${this.config.name}] Task completed: ${taskId}`);
|
|
70
|
+
return this.getTask(taskId);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
const error = err.message;
|
|
74
|
+
this.stmtUpdateTask.run('failed', null, error, null, Date.now(), taskId);
|
|
75
|
+
log.warn(`[sub-agent:${this.config.name}] Task failed: ${taskId} — ${error}`);
|
|
76
|
+
return this.getTask(taskId);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/** Submit and immediately run */
|
|
80
|
+
async execute(input) {
|
|
81
|
+
const taskId = this.submit(input);
|
|
82
|
+
return this.run(taskId);
|
|
83
|
+
}
|
|
84
|
+
/** Get task history */
|
|
85
|
+
getTasks(limit = 20) {
|
|
86
|
+
const rows = this.stmtGetTasks.all(this.id, limit);
|
|
87
|
+
return rows.map(deserializeTask);
|
|
88
|
+
}
|
|
89
|
+
/** Get status */
|
|
90
|
+
getStatus() {
|
|
91
|
+
const counts = this.stmtCountTasks.all(this.id);
|
|
92
|
+
const statusMap = {};
|
|
93
|
+
for (const row of counts)
|
|
94
|
+
statusMap[row.status] = row.count;
|
|
95
|
+
const tasks = this.getTasks(100);
|
|
96
|
+
const completed = tasks.filter(t => t.status === 'completed');
|
|
97
|
+
const avgDuration = completed.length > 0
|
|
98
|
+
? completed.reduce((sum, t) => sum + ((t.completedAt ?? 0) - (t.startedAt ?? 0)), 0) / completed.length
|
|
99
|
+
: 0;
|
|
100
|
+
return {
|
|
101
|
+
id: this.id,
|
|
102
|
+
name: this.config.name,
|
|
103
|
+
specialization: this.config.specialization,
|
|
104
|
+
totalTasks: Object.values(statusMap).reduce((a, b) => a + b, 0),
|
|
105
|
+
completedTasks: statusMap['completed'] ?? 0,
|
|
106
|
+
failedTasks: statusMap['failed'] ?? 0,
|
|
107
|
+
avgDurationMs: Math.round(avgDuration),
|
|
108
|
+
lastRunAt: completed.length > 0 ? new Date(completed[0].completedAt).toISOString() : null,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
getTaskInput(taskId) {
|
|
112
|
+
const row = this.db.prepare(`SELECT input FROM sub_agent_tasks WHERE id = ?`).get(taskId);
|
|
113
|
+
if (!row)
|
|
114
|
+
throw new Error(`Task ${taskId} not found`);
|
|
115
|
+
return row.input;
|
|
116
|
+
}
|
|
117
|
+
getTask(taskId) {
|
|
118
|
+
const row = this.db.prepare(`SELECT * FROM sub_agent_tasks WHERE id = ?`).get(taskId);
|
|
119
|
+
return row ? deserializeTask(row) : null;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
function deserializeTask(row) {
|
|
123
|
+
return {
|
|
124
|
+
id: row.id,
|
|
125
|
+
agentId: row.agent_id,
|
|
126
|
+
input: row.input,
|
|
127
|
+
output: row.output,
|
|
128
|
+
status: row.status,
|
|
129
|
+
error: row.error,
|
|
130
|
+
startedAt: row.started_at,
|
|
131
|
+
completedAt: row.completed_at,
|
|
132
|
+
createdAt: row.created_at,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=sub-agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sub-agent.js","sourceRoot":"","sources":["../../src/agent-training/sub-agent.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAsC/C,8DAA8D;AAE9D,MAAM,UAAU,oBAAoB,CAAC,EAAqB;IACxD,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;GAyBP,CAAC,CAAC;AACL,CAAC;AAED,6DAA6D;AAE7D,MAAM,GAAG,GAAG,SAAS,EAAE,CAAC;AAExB,MAAM,OAAO,QAAQ;IACV,EAAE,CAAS;IACX,MAAM,CAAiB;IACf,EAAE,CAAoB;IAC/B,QAAQ,GAAwB,IAAI,CAAC;IAE5B,cAAc,CAAC;IACf,cAAc,CAAC;IACf,YAAY,CAAC;IACb,cAAc,CAAC;IAEhC,YAAY,EAAqB,EAAE,EAAU,EAAE,MAAsB;QACnE,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACb,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QAErB,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,OAAO,CAAC,sGAAsG,CAAC,CAAC;QACzI,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,OAAO,CAAC,mIAAmI,CAAC,CAAC;QACtK,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC,OAAO,CAAC,mFAAmF,CAAC,CAAC;QACpH,IAAI,CAAC,cAAc,GAAG,EAAE,CAAC,OAAO,CAAC,0FAA0F,CAAC,CAAC;IAC/H,CAAC;IAED,WAAW,CAAC,QAAsB;QAChC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,kCAAkC;IAClC,MAAM,CAAC,KAAa;QAClB,MAAM,MAAM,GAAG,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QAC9E,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC5D,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,IAAI,qBAAqB,MAAM,EAAE,CAAC,CAAC;QACtE,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,0BAA0B;IAC1B,KAAK,CAAC,GAAG,CAAC,MAAc;QACtB,IAAI,CAAC,IAAI,CAAC,QAAQ;YAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC;QAEvF,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;QAEzE,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,QAAQ,CAChC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,EACzB,IAAI,CAAC,MAAM,CAAC,YAAY,EACxB,IAAI,CAAC,MAAM,CAAC,KAAK,CAClB,CAAC;YACF,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;YAC7E,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,IAAI,qBAAqB,MAAM,EAAE,CAAC,CAAC;YACtE,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,GAAI,GAAa,CAAC,OAAO,CAAC;YACrC,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;YACzE,GAAG,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,MAAM,CAAC,IAAI,kBAAkB,MAAM,MAAM,KAAK,EAAE,CAAC,CAAC;YAC9E,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAE,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,iCAAiC;IACjC,KAAK,CAAC,OAAO,CAAC,KAAa;QACzB,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B,CAAC;IAED,uBAAuB;IACvB,QAAQ,CAAC,KAAK,GAAG,EAAE;QACjB,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAc,CAAC;QAChE,OAAO,IAAI,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACnC,CAAC;IAED,iBAAiB;IACjB,SAAS;QACP,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAwC,CAAC;QACvF,MAAM,SAAS,GAA2B,EAAE,CAAC;QAC7C,KAAK,MAAM,GAAG,IAAI,MAAM;YAAE,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC;QAE5D,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QACjC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,WAAW,CAAC,CAAC;QAC9D,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC;YACtC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,SAAS,CAAC,MAAM;YACvG,CAAC,CAAC,CAAC,CAAC;QAEN,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YACtB,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,cAAc;YAC1C,UAAU,EAAE,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC/D,cAAc,EAAE,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC;YAC3C,WAAW,EAAE,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC;YACrC,aAAa,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC;YACtC,SAAS,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,WAAY,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,IAAI;SAC3F,CAAC;IACJ,CAAC;IAEO,YAAY,CAAC,MAAc;QACjC,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,gDAAgD,CAAC,CAAC,GAAG,CAAC,MAAM,CAAkC,CAAC;QAC3H,IAAI,CAAC,GAAG;YAAE,MAAM,IAAI,KAAK,CAAC,QAAQ,MAAM,YAAY,CAAC,CAAC;QACtD,OAAO,GAAG,CAAC,KAAK,CAAC;IACnB,CAAC;IAEO,OAAO,CAAC,MAAc;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,4CAA4C,CAAC,CAAC,GAAG,CAAC,MAAM,CAAwB,CAAC;QAC7G,OAAO,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC3C,CAAC;CACF;AAgBD,SAAS,eAAe,CAAC,GAAY;IACnC,OAAO;QACL,EAAE,EAAE,GAAG,CAAC,EAAE;QACV,OAAO,EAAE,GAAG,CAAC,QAAQ;QACrB,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,MAAM,EAAE,GAAG,CAAC,MAAgC;QAC5C,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,SAAS,EAAE,GAAG,CAAC,UAAU;QACzB,WAAW,EAAE,GAAG,CAAC,YAAY;QAC7B,SAAS,EAAE,GAAG,CAAC,UAAU;KAC1B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,128 @@
|
|
|
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 { ChatEngine, runChatMigration } from '../chat-engine.js';
|
|
7
|
+
describe('ChatEngine', () => {
|
|
8
|
+
let db;
|
|
9
|
+
beforeEach(() => { db = new Database(':memory:'); });
|
|
10
|
+
afterEach(() => { db.close(); });
|
|
11
|
+
it('creates and runs migration', () => {
|
|
12
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
13
|
+
const status = engine.getStatus();
|
|
14
|
+
expect(status.sessions).toBe(0);
|
|
15
|
+
expect(status.totalMessages).toBe(0);
|
|
16
|
+
});
|
|
17
|
+
it('processes a message and returns response', async () => {
|
|
18
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
19
|
+
const response = await engine.processMessage('session-1', 'Hallo');
|
|
20
|
+
expect(response.role).toBe('assistant');
|
|
21
|
+
expect(response.content).toBeTruthy();
|
|
22
|
+
expect(response.sessionId).toBe('session-1');
|
|
23
|
+
});
|
|
24
|
+
it('stores messages in history', async () => {
|
|
25
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
26
|
+
await engine.processMessage('session-1', 'Hallo');
|
|
27
|
+
const history = engine.getHistory('session-1');
|
|
28
|
+
expect(history).toHaveLength(2); // user + assistant
|
|
29
|
+
expect(history[0].role).toBe('user');
|
|
30
|
+
expect(history[1].role).toBe('assistant');
|
|
31
|
+
});
|
|
32
|
+
it('routes to IPC handler when route matches', async () => {
|
|
33
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
34
|
+
const handler = vi.fn().mockResolvedValue({ balance: 10000, equity: 10500, positions: [] });
|
|
35
|
+
engine.setIpcHandler(handler);
|
|
36
|
+
engine.setAvailableRoutes(['paper.status', 'action.status']);
|
|
37
|
+
const response = await engine.processMessage('session-1', 'Wie läuft das paper trading?');
|
|
38
|
+
expect(handler).toHaveBeenCalledWith('paper.status', expect.any(Object));
|
|
39
|
+
expect(response.content).toContain('10000');
|
|
40
|
+
expect(response.toolCalls).toBeTruthy();
|
|
41
|
+
});
|
|
42
|
+
it('matches status route for generic status question', async () => {
|
|
43
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
44
|
+
const handler = vi.fn().mockResolvedValue({ uptime: 3600 });
|
|
45
|
+
engine.setIpcHandler(handler);
|
|
46
|
+
engine.setAvailableRoutes(['status']);
|
|
47
|
+
const response = await engine.processMessage('s1', 'Wie ist der Status?');
|
|
48
|
+
expect(handler).toHaveBeenCalled();
|
|
49
|
+
});
|
|
50
|
+
it('returns fallback when no route matches', async () => {
|
|
51
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
52
|
+
engine.setIpcHandler(vi.fn());
|
|
53
|
+
const response = await engine.processMessage('s1', 'Was ist die Farbe des Himmels?');
|
|
54
|
+
expect(response.content).toContain('konnte deine Frage nicht zuordnen');
|
|
55
|
+
});
|
|
56
|
+
it('handles IPC handler errors gracefully', async () => {
|
|
57
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
58
|
+
engine.setIpcHandler(vi.fn().mockRejectedValue(new Error('DB locked')));
|
|
59
|
+
engine.setAvailableRoutes(['status']);
|
|
60
|
+
const response = await engine.processMessage('s1', 'Status bitte');
|
|
61
|
+
expect(response.content).toContain('Fehler');
|
|
62
|
+
});
|
|
63
|
+
it('tracks multiple sessions', async () => {
|
|
64
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
65
|
+
await engine.processMessage('session-a', 'Hallo');
|
|
66
|
+
await engine.processMessage('session-b', 'Hi');
|
|
67
|
+
const status = engine.getStatus();
|
|
68
|
+
expect(status.sessions).toBe(2);
|
|
69
|
+
expect(status.totalMessages).toBe(4); // 2 user + 2 assistant
|
|
70
|
+
});
|
|
71
|
+
it('getHistory respects session isolation', async () => {
|
|
72
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
73
|
+
await engine.processMessage('session-a', 'A1');
|
|
74
|
+
await engine.processMessage('session-b', 'B1');
|
|
75
|
+
const historyA = engine.getHistory('session-a');
|
|
76
|
+
expect(historyA).toHaveLength(2);
|
|
77
|
+
expect(historyA[0].content).toBe('A1');
|
|
78
|
+
const historyB = engine.getHistory('session-b');
|
|
79
|
+
expect(historyB).toHaveLength(2);
|
|
80
|
+
expect(historyB[0].content).toBe('B1');
|
|
81
|
+
});
|
|
82
|
+
it('matches routes for insight queries', async () => {
|
|
83
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
84
|
+
const handler = vi.fn().mockResolvedValue([{ title: 'Test insight' }]);
|
|
85
|
+
engine.setIpcHandler(handler);
|
|
86
|
+
engine.setAvailableRoutes(['insight.list']);
|
|
87
|
+
await engine.processMessage('s1', 'Zeig mir die Erkenntnisse');
|
|
88
|
+
expect(handler).toHaveBeenCalledWith('insight.list', expect.any(Object));
|
|
89
|
+
});
|
|
90
|
+
it('matches routes for signal queries', async () => {
|
|
91
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
92
|
+
const handler = vi.fn().mockResolvedValue({ totalSignals: 5 });
|
|
93
|
+
engine.setIpcHandler(handler);
|
|
94
|
+
engine.setAvailableRoutes(['signal.cross.status']);
|
|
95
|
+
await engine.processMessage('s1', 'Cross-brain signal status');
|
|
96
|
+
expect(handler).toHaveBeenCalledWith('signal.cross.status', expect.any(Object));
|
|
97
|
+
});
|
|
98
|
+
it('extracts limit param from message', async () => {
|
|
99
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
100
|
+
const handler = vi.fn().mockResolvedValue([]);
|
|
101
|
+
engine.setIpcHandler(handler);
|
|
102
|
+
engine.setAvailableRoutes(['insight.list']);
|
|
103
|
+
await engine.processMessage('s1', 'Zeig mir die letzten 5 insights');
|
|
104
|
+
expect(handler).toHaveBeenCalledWith('insight.list', expect.objectContaining({ limit: 5 }));
|
|
105
|
+
});
|
|
106
|
+
it('migration is idempotent', () => {
|
|
107
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
108
|
+
runChatMigration(db);
|
|
109
|
+
const status = engine.getStatus();
|
|
110
|
+
expect(status.sessions).toBe(0);
|
|
111
|
+
});
|
|
112
|
+
it('formats paper status result nicely', async () => {
|
|
113
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
114
|
+
engine.setIpcHandler(vi.fn().mockResolvedValue({ balance: 9500.50, equity: 10200.75, positions: [{ symbol: 'BTC' }] }));
|
|
115
|
+
engine.setAvailableRoutes(['paper.status']);
|
|
116
|
+
const response = await engine.processMessage('s1', 'paper trading status');
|
|
117
|
+
expect(response.content).toContain('9500.50');
|
|
118
|
+
expect(response.content).toContain('1 Position');
|
|
119
|
+
});
|
|
120
|
+
it('handles null IPC result', async () => {
|
|
121
|
+
const engine = new ChatEngine(db, { brainName: 'test' });
|
|
122
|
+
engine.setIpcHandler(vi.fn().mockResolvedValue(null));
|
|
123
|
+
engine.setAvailableRoutes(['status']);
|
|
124
|
+
const response = await engine.processMessage('s1', 'Status');
|
|
125
|
+
expect(response.content).toContain('Keine Daten');
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
//# sourceMappingURL=chat-engine.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chat-engine.test.js","sourceRoot":"","sources":["../../../src/chat/__tests__/chat-engine.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type Database from 'better-sqlite3';
|
|
2
|
+
export interface ChatMessage {
|
|
3
|
+
id: string;
|
|
4
|
+
sessionId: string;
|
|
5
|
+
role: 'user' | 'assistant' | 'system';
|
|
6
|
+
content: string;
|
|
7
|
+
toolCalls?: string;
|
|
8
|
+
timestamp: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ChatEngineConfig {
|
|
11
|
+
brainName: string;
|
|
12
|
+
maxHistoryPerSession?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface ChatEngineStatus {
|
|
15
|
+
sessions: number;
|
|
16
|
+
totalMessages: number;
|
|
17
|
+
routesAvailable: number;
|
|
18
|
+
}
|
|
19
|
+
type IpcHandler = (method: string, params?: unknown) => unknown | Promise<unknown>;
|
|
20
|
+
export declare function runChatMigration(db: Database.Database): void;
|
|
21
|
+
/**
|
|
22
|
+
* ChatEngine — processes natural language messages and routes them to IPC endpoints.
|
|
23
|
+
* Uses simple keyword matching for NLU (LLM-powered NLU is optional enhancement).
|
|
24
|
+
*/
|
|
25
|
+
export declare class ChatEngine {
|
|
26
|
+
private readonly db;
|
|
27
|
+
private readonly config;
|
|
28
|
+
private ipcHandler;
|
|
29
|
+
private availableRoutes;
|
|
30
|
+
private readonly stmtInsert;
|
|
31
|
+
private readonly stmtGetSession;
|
|
32
|
+
private readonly stmtCountSessions;
|
|
33
|
+
private readonly stmtCountMessages;
|
|
34
|
+
constructor(db: Database.Database, config: ChatEngineConfig);
|
|
35
|
+
/** Set the IPC handler for routing commands */
|
|
36
|
+
setIpcHandler(handler: IpcHandler): void;
|
|
37
|
+
/** Set the list of available IPC routes for NLU matching */
|
|
38
|
+
setAvailableRoutes(routes: string[]): void;
|
|
39
|
+
/** Process a user message and generate a response */
|
|
40
|
+
processMessage(sessionId: string, content: string): Promise<ChatMessage>;
|
|
41
|
+
/** Get chat history for a session */
|
|
42
|
+
getHistory(sessionId: string, limit?: number): ChatMessage[];
|
|
43
|
+
/** Get status */
|
|
44
|
+
getStatus(): ChatEngineStatus;
|
|
45
|
+
private storeMessage;
|
|
46
|
+
/** Simple keyword-based NLU: match user input to IPC routes */
|
|
47
|
+
private matchRoute;
|
|
48
|
+
/** Extract parameters from user input */
|
|
49
|
+
private extractParams;
|
|
50
|
+
/** Format IPC result as human-readable text */
|
|
51
|
+
private formatResult;
|
|
52
|
+
/** Fallback response when no route matches */
|
|
53
|
+
private generateFallback;
|
|
54
|
+
}
|
|
55
|
+
export {};
|