amalfa 1.0.3 → 1.0.5
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 +7 -8
- package/package.json +1 -1
- package/src/cli.ts +1 -1
- package/polyvis.settings.json.bak +0 -38
- package/src/EnlightenedTriad.ts +0 -146
- package/src/JIT_Triad.ts +0 -137
- package/src/data/experience/test_doc_1.md +0 -2
- package/src/data/experience/test_doc_2.md +0 -2
- package/src/demo-triad.ts +0 -45
- package/src/gardeners/BaseGardener.ts +0 -55
- package/src/llm/EnlightenedProvider.ts +0 -95
- package/src/services/README.md +0 -56
- package/src/services/llama.ts +0 -59
- package/src/services/llamauv.ts +0 -56
- package/src/services/olmo3.ts +0 -58
- package/src/services/phi.ts +0 -52
package/README.md
CHANGED
|
@@ -140,9 +140,9 @@ bun install
|
|
|
140
140
|
|
|
141
141
|
5. **Restart Claude Desktop**
|
|
142
142
|
|
|
143
|
-
**Full setup guide:**
|
|
143
|
+
**Full setup guide:** See repository docs for detailed MCP setup
|
|
144
144
|
|
|
145
|
-
**Package
|
|
145
|
+
**Package:** Available at https://www.npmjs.com/package/amalfa
|
|
146
146
|
|
|
147
147
|
---
|
|
148
148
|
|
|
@@ -313,15 +313,14 @@ Amalfa evolved from patterns discovered in the [PolyVis](https://github.com/pjsv
|
|
|
313
313
|
|
|
314
314
|
## Roadmap
|
|
315
315
|
|
|
316
|
-
### v1.0 (
|
|
316
|
+
### v1.0 (Released)
|
|
317
317
|
|
|
318
|
-
- ✅
|
|
318
|
+
- ✅ Published to npm
|
|
319
319
|
- ✅ Core vision documented
|
|
320
320
|
- ✅ Auto-augmentation design complete
|
|
321
|
-
-
|
|
322
|
-
-
|
|
323
|
-
-
|
|
324
|
-
- [ ] Initial release
|
|
321
|
+
- ✅ MCP server functional
|
|
322
|
+
- ✅ Basic semantic search working
|
|
323
|
+
- ✅ Initial release
|
|
325
324
|
|
|
326
325
|
### v1.1+ (Future)
|
|
327
326
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "amalfa",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.5",
|
|
4
4
|
"description": "Local-first knowledge graph engine for AI agents. Transforms markdown into searchable memory with MCP protocol.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/pjsvis/amalfa#readme",
|
package/src/cli.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { existsSync, statSync } from "node:fs";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { spawn } from "node:child_process";
|
|
5
5
|
|
|
6
|
-
const VERSION = "1.0.
|
|
6
|
+
const VERSION = "1.0.5";
|
|
7
7
|
|
|
8
8
|
// Database path loaded from config (lazy loaded per command)
|
|
9
9
|
let DB_PATH: string | null = null;
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"_comment": "⚠️ DEPRECATED: This file will be removed in v2.0. Use amalfa.config.json for user-facing settings. See docs/CONFIG_UNIFICATION.md",
|
|
3
|
-
"paths": {
|
|
4
|
-
"database": {
|
|
5
|
-
"resonance": "public/resonance.db"
|
|
6
|
-
},
|
|
7
|
-
"docs": {
|
|
8
|
-
"root": "docs",
|
|
9
|
-
"webdocs": "docs/webdocs",
|
|
10
|
-
"architecture": "docs/architecture",
|
|
11
|
-
"public": "public/docs"
|
|
12
|
-
},
|
|
13
|
-
"sources": {
|
|
14
|
-
"experience": [
|
|
15
|
-
{ "path": "debriefs", "name": "Debrief" },
|
|
16
|
-
{ "path": "playbooks", "name": "Playbook" },
|
|
17
|
-
{ "path": "briefs", "name": "Brief" },
|
|
18
|
-
{ "path": "docs", "name": "Docs" }
|
|
19
|
-
],
|
|
20
|
-
"persona": {
|
|
21
|
-
"lexicon": "scripts/fixtures/conceptual-lexicon-ref-v1.79.json",
|
|
22
|
-
"cda": "scripts/fixtures/cda-ref-v63.json"
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
},
|
|
26
|
-
"graph": {
|
|
27
|
-
"tuning": {
|
|
28
|
-
"louvain": {
|
|
29
|
-
"persona": 0.3,
|
|
30
|
-
"experience": 0.25
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
},
|
|
34
|
-
|
|
35
|
-
"schema": {
|
|
36
|
-
"version": "1.0.0"
|
|
37
|
-
}
|
|
38
|
-
}
|
package/src/EnlightenedTriad.ts
DELETED
|
@@ -1,146 +0,0 @@
|
|
|
1
|
-
// --- CONFIGURATION ---
|
|
2
|
-
const PORTS = {
|
|
3
|
-
SCOUT: 8082, // Phi-3.5 (Fast Entity Extraction)
|
|
4
|
-
ARCHITECT: 8083, // Llama-3 (Strict Logic/JSON)
|
|
5
|
-
AUDITOR: 8084, // Olmo-3 (Deep Thinking)
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
interface AuditResult {
|
|
9
|
-
passed: boolean;
|
|
10
|
-
verdict: string;
|
|
11
|
-
thought_trace: string;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export class EnlightenedTriad {
|
|
15
|
-
/**
|
|
16
|
-
* THE SCOUT (Phi-3.5)
|
|
17
|
-
* "The Bouncer"
|
|
18
|
-
* Task: Fast, cheap filtering.
|
|
19
|
-
*/
|
|
20
|
-
async scout(context: string, extractionTask: string): Promise<string> {
|
|
21
|
-
return this.callAgent(PORTS.SCOUT, [
|
|
22
|
-
{
|
|
23
|
-
role: "system",
|
|
24
|
-
content:
|
|
25
|
-
"You are a precise data extractor. Return only the requested data. No filler.",
|
|
26
|
-
},
|
|
27
|
-
{
|
|
28
|
-
role: "user",
|
|
29
|
-
content: `Context: ${context}\n\nTask: ${extractionTask}`,
|
|
30
|
-
},
|
|
31
|
-
]);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* THE ARCHITECT (Llama-3 + Accountant Vector)
|
|
36
|
-
* "The Builder"
|
|
37
|
-
* Task: Structure raw text into strict JSON.
|
|
38
|
-
*/
|
|
39
|
-
async architect(unstructuredData: string): Promise<unknown> {
|
|
40
|
-
const response = await this.callAgent(PORTS.ARCHITECT, [
|
|
41
|
-
{ role: "system", content: "Output JSON only." },
|
|
42
|
-
{
|
|
43
|
-
role: "user",
|
|
44
|
-
content: `Convert to Causal Graph JSON: ${unstructuredData}`,
|
|
45
|
-
},
|
|
46
|
-
]);
|
|
47
|
-
|
|
48
|
-
try {
|
|
49
|
-
// Strip markdown code blocks if present
|
|
50
|
-
const cleanJson = response
|
|
51
|
-
.replace(/```json/g, "")
|
|
52
|
-
.replace(/```/g, "")
|
|
53
|
-
.trim();
|
|
54
|
-
return JSON.parse(cleanJson);
|
|
55
|
-
} catch (_e) {
|
|
56
|
-
console.error("❌ Architect JSON Error. Raw output:", response);
|
|
57
|
-
return null;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* THE AUDITOR (Olmo-3-Think)
|
|
63
|
-
* "The QA Department"
|
|
64
|
-
* Task: Think for 2 minutes, then vote Yes/No.
|
|
65
|
-
*/
|
|
66
|
-
async audit(claim: string): Promise<AuditResult> {
|
|
67
|
-
// High temp for creative debugging/thinking
|
|
68
|
-
const rawOutput = await this.callAgent(
|
|
69
|
-
PORTS.AUDITOR,
|
|
70
|
-
[
|
|
71
|
-
{
|
|
72
|
-
role: "user",
|
|
73
|
-
content: `Analyze the validity of this logical claim. \n\nClaim: "${claim}"\n\nShow your thinking process wrapped in <think> tags like this: <think> ... </think>, then end with 'VERDICT: PASS' or 'VERDICT: FAIL'.`,
|
|
74
|
-
},
|
|
75
|
-
],
|
|
76
|
-
{ temperature: 0.6, max_tokens: 2048 },
|
|
77
|
-
);
|
|
78
|
-
|
|
79
|
-
// --- THE PARSER ---
|
|
80
|
-
// Olmo uses <think> tags. We split the "Raj" monologue from the Answer.
|
|
81
|
-
let thoughtTrace = "";
|
|
82
|
-
let finalAnswer = "";
|
|
83
|
-
|
|
84
|
-
const thinkMatch = rawOutput.match(/<think>([\s\S]*?)<\/think>/);
|
|
85
|
-
|
|
86
|
-
if (thinkMatch?.[1]) {
|
|
87
|
-
// case 1: structured output
|
|
88
|
-
thoughtTrace = thinkMatch[1].trim();
|
|
89
|
-
finalAnswer = rawOutput.replace(thinkMatch[0], "").trim();
|
|
90
|
-
} else if (rawOutput.includes("VERDICT:")) {
|
|
91
|
-
// case 2: implicit separation (fallback)
|
|
92
|
-
const parts = rawOutput.split("VERDICT:");
|
|
93
|
-
thoughtTrace = parts[0]?.trim() ?? "";
|
|
94
|
-
// Reconstruct the verdict part
|
|
95
|
-
finalAnswer = `VERDICT:${parts.slice(1).join("VERDICT:")}`.trim();
|
|
96
|
-
} else {
|
|
97
|
-
// case 3: total failure to structure
|
|
98
|
-
thoughtTrace = rawOutput;
|
|
99
|
-
finalAnswer = "VERDICT: FAIL (Parse Error)";
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const passed = finalAnswer.includes("VERDICT: PASS");
|
|
103
|
-
|
|
104
|
-
return {
|
|
105
|
-
passed,
|
|
106
|
-
verdict: finalAnswer, // The short answer for UI
|
|
107
|
-
thought_trace: thoughtTrace, // The monologue for DB/Audit
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// --- UTILS (Bun Native Fetch) ---
|
|
112
|
-
private async callAgent(
|
|
113
|
-
port: number,
|
|
114
|
-
messages: { role: string; content: string }[],
|
|
115
|
-
options: { temperature?: number; max_tokens?: number } = {},
|
|
116
|
-
): Promise<string> {
|
|
117
|
-
try {
|
|
118
|
-
const response = await fetch(
|
|
119
|
-
`http://127.0.0.1:${port}/v1/chat/completions`,
|
|
120
|
-
{
|
|
121
|
-
method: "POST",
|
|
122
|
-
headers: { "Content-Type": "application/json" },
|
|
123
|
-
body: JSON.stringify({
|
|
124
|
-
messages,
|
|
125
|
-
temperature: options.temperature || 0.1,
|
|
126
|
-
n_predict: options.max_tokens || 512,
|
|
127
|
-
}),
|
|
128
|
-
},
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
if (!response.ok) {
|
|
132
|
-
throw new Error(
|
|
133
|
-
`HTTP Error ${response.status}: ${response.statusText}`,
|
|
134
|
-
);
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
const data = (await response.json()) as {
|
|
138
|
-
choices: { message: { content: string } }[];
|
|
139
|
-
};
|
|
140
|
-
return data.choices?.[0]?.message?.content || "";
|
|
141
|
-
} catch (_error) {
|
|
142
|
-
console.error(`❌ Agent at Port ${port} is offline/unreachable.`);
|
|
143
|
-
return "AGENT_OFFLINE";
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
package/src/JIT_Triad.ts
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
import { type Subprocess, spawn } from "bun";
|
|
2
|
-
import { EnlightenedTriad } from "./EnlightenedTriad"; // Re-using your existing interface
|
|
3
|
-
|
|
4
|
-
// --- CONFIGURATION ---
|
|
5
|
-
const BASE_DIR = `${import.meta.dir}/../experiments/enlightenment`; // Adjust relative to src/
|
|
6
|
-
const BIN_PATH = `${BASE_DIR}/llama.cpp/build/bin/llama-server`;
|
|
7
|
-
const VECTORS_DIR = `${BASE_DIR}/vectors`;
|
|
8
|
-
|
|
9
|
-
const AGENTS = {
|
|
10
|
-
SCOUT: {
|
|
11
|
-
port: 8082,
|
|
12
|
-
model: `${VECTORS_DIR}/Phi-3.5-mini-instruct-Q4_K_M.gguf`,
|
|
13
|
-
ctx: 4096,
|
|
14
|
-
vector: null,
|
|
15
|
-
},
|
|
16
|
-
ARCHITECT: {
|
|
17
|
-
port: 8083,
|
|
18
|
-
model: `${VECTORS_DIR}/Meta-Llama-3-8B-Instruct-Q4_K_M.gguf`,
|
|
19
|
-
ctx: 8192,
|
|
20
|
-
vector: `${VECTORS_DIR}/enlightenment_vector_v2.gguf`,
|
|
21
|
-
scale: "-0.3",
|
|
22
|
-
},
|
|
23
|
-
AUDITOR: {
|
|
24
|
-
port: 8084,
|
|
25
|
-
model: `${VECTORS_DIR}/Olmo-3-7B-Think-Q4_K_M.gguf`,
|
|
26
|
-
ctx: 8192,
|
|
27
|
-
vector: null,
|
|
28
|
-
},
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
let currentProcess: Subprocess | null = null;
|
|
32
|
-
|
|
33
|
-
// --- LIFECYCLE MANAGER ---
|
|
34
|
-
async function bootAgent(role: keyof typeof AGENTS) {
|
|
35
|
-
if (currentProcess) {
|
|
36
|
-
console.log("♻️ Freeing VRAM (Stopping previous agent)...");
|
|
37
|
-
currentProcess.kill();
|
|
38
|
-
await new Promise((r) => setTimeout(r, 1000)); // Cool down
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const config = AGENTS[role];
|
|
42
|
-
console.log(`🚀 Booting ${role} on Port ${config.port}...`);
|
|
43
|
-
|
|
44
|
-
const args = [
|
|
45
|
-
BIN_PATH,
|
|
46
|
-
"-m",
|
|
47
|
-
config.model,
|
|
48
|
-
"--port",
|
|
49
|
-
config.port.toString(),
|
|
50
|
-
"--ctx-size",
|
|
51
|
-
config.ctx.toString(),
|
|
52
|
-
"--n-gpu-layers",
|
|
53
|
-
"99", // Metal
|
|
54
|
-
"--log-disable", // Keep console clean
|
|
55
|
-
];
|
|
56
|
-
|
|
57
|
-
if (config.vector) {
|
|
58
|
-
args.push("--control-vector-scaled", `${config.vector}:${config.scale}`);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
// Spawn via Bun
|
|
62
|
-
currentProcess = spawn(args, {
|
|
63
|
-
stdout: "ignore", // Silence server logs
|
|
64
|
-
stderr: "ignore",
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
// Wait for Health Check
|
|
68
|
-
process.stdout.write(" Waiting for neural activity...");
|
|
69
|
-
for (let i = 0; i < 30; i++) {
|
|
70
|
-
try {
|
|
71
|
-
const res = await fetch(`http://127.0.0.1:${config.port}/health`);
|
|
72
|
-
if (res.ok) {
|
|
73
|
-
console.log(" Online! 🟢");
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
} catch (_e) {}
|
|
77
|
-
await new Promise((r) => setTimeout(r, 500));
|
|
78
|
-
process.stdout.write(".");
|
|
79
|
-
}
|
|
80
|
-
throw new Error(`${role} failed to start.`);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
async function shutdown() {
|
|
84
|
-
if (currentProcess) {
|
|
85
|
-
console.log("\n🛑 Shutting down final agent...");
|
|
86
|
-
currentProcess.kill();
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
// --- THE DEMO FLOW ---
|
|
91
|
-
async function runOptimizedPipeline() {
|
|
92
|
-
const triad = new EnlightenedTriad();
|
|
93
|
-
|
|
94
|
-
try {
|
|
95
|
-
console.log("⚡️ SYSTEM ONLINE: Engaging OPTIMIZED Intelligence...\n");
|
|
96
|
-
const rawLog =
|
|
97
|
-
"2025-12-19 14:02:11 [CRITICAL] Connection refused at 192.168.1.5 (DB_SHARD_04). Latency 4005ms.";
|
|
98
|
-
|
|
99
|
-
// --- STEP 1: SCOUT ---
|
|
100
|
-
await bootAgent("SCOUT");
|
|
101
|
-
console.log("\n--- 🕵️ SCOUT TASK ---");
|
|
102
|
-
const scoutResult = await triad.scout(
|
|
103
|
-
rawLog,
|
|
104
|
-
"Extract IP and Error Message. No notes.",
|
|
105
|
-
);
|
|
106
|
-
console.log(`>> Output: ${scoutResult}`);
|
|
107
|
-
|
|
108
|
-
// --- STEP 2: ARCHITECT ---
|
|
109
|
-
await bootAgent("ARCHITECT");
|
|
110
|
-
console.log("\n--- 📐 ARCHITECT TASK ---");
|
|
111
|
-
const architectResult = await triad.architect(scoutResult);
|
|
112
|
-
console.log(`>> Output:`, JSON.stringify(architectResult, null, 2));
|
|
113
|
-
|
|
114
|
-
// --- STEP 3: AUDITOR ---
|
|
115
|
-
await bootAgent("AUDITOR");
|
|
116
|
-
console.log("\n--- 🧠 AUDITOR TASK ---");
|
|
117
|
-
const claim = `The error 'Connection refused' caused the high latency.`;
|
|
118
|
-
const auditResult = await triad.audit(claim);
|
|
119
|
-
|
|
120
|
-
console.log(
|
|
121
|
-
`\n📝 THOUGHT TRACE:\n${auditResult.thought_trace.substring(0, 300)}...`,
|
|
122
|
-
);
|
|
123
|
-
console.log(`\n⚖️ VERDICT: ${auditResult.passed ? "✅ PASS" : "❌ FAIL"}`);
|
|
124
|
-
} catch (error) {
|
|
125
|
-
console.error("\n💥 Pipeline Error:", error);
|
|
126
|
-
} finally {
|
|
127
|
-
await shutdown();
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
// Handle Ctrl+C
|
|
132
|
-
process.on("SIGINT", async () => {
|
|
133
|
-
await shutdown();
|
|
134
|
-
process.exit(0);
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
runOptimizedPipeline();
|
package/src/demo-triad.ts
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { EnlightenedTriad } from "./EnlightenedTriad";
|
|
2
|
-
|
|
3
|
-
async function runPipeline() {
|
|
4
|
-
const triad = new EnlightenedTriad();
|
|
5
|
-
|
|
6
|
-
console.log("\n⚡️ SYSTEM ONLINE: Engaging Heterogeneous Intelligence...\n");
|
|
7
|
-
|
|
8
|
-
// --- STEP 1: RAW INPUT ---
|
|
9
|
-
const rawLog =
|
|
10
|
-
"2025-12-19 14:02:11 [CRITICAL] Connection refused at 192.168.1.5 (DB_SHARD_04). Latency 4005ms.";
|
|
11
|
-
console.log(`📄 INPUT: "${rawLog}"\n`);
|
|
12
|
-
|
|
13
|
-
// --- STEP 2: SCOUT (Extraction) ---
|
|
14
|
-
console.log("--- 🕵️ SCOUT (Phi-3.5) ---");
|
|
15
|
-
const scoutResult = await triad.scout(
|
|
16
|
-
rawLog,
|
|
17
|
-
"Extract the IP address and the specific Error Message.",
|
|
18
|
-
);
|
|
19
|
-
console.log(`>> Output: ${scoutResult}\n`);
|
|
20
|
-
|
|
21
|
-
// --- STEP 3: ARCHITECT (Structure) ---
|
|
22
|
-
console.log("--- 📐 ARCHITECT (Llama-3) ---");
|
|
23
|
-
// Feed Scout's output into Architect
|
|
24
|
-
const architectResult = await triad.architect(scoutResult);
|
|
25
|
-
console.log(`>> Output (JSON):`, JSON.stringify(architectResult, null, 2));
|
|
26
|
-
console.log("");
|
|
27
|
-
|
|
28
|
-
// --- STEP 4: AUDITOR (Verification) ---
|
|
29
|
-
console.log("--- 🧠 AUDITOR (Olmo-3) ---");
|
|
30
|
-
// Feed a claim based on the structure to the Auditor
|
|
31
|
-
const claim = `The error 'Connection refused' at 192.168.1.5 caused the high latency.`;
|
|
32
|
-
const auditResult = await triad.audit(claim);
|
|
33
|
-
|
|
34
|
-
console.log(`\n📝 THOUGHT TRACE (The 'Raj' Monologue):`);
|
|
35
|
-
// Truncate for console readability
|
|
36
|
-
console.log(
|
|
37
|
-
`${auditResult.thought_trace.substring(0, 300)}... [truncated] ...`,
|
|
38
|
-
);
|
|
39
|
-
|
|
40
|
-
console.log(
|
|
41
|
-
`\n⚖️ FINAL VERDICT: ${auditResult.passed ? "✅ PASS" : "❌ FAIL"}`,
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
runPipeline();
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import type { ResonanceDB } from "@src/resonance/db";
|
|
2
|
-
import { getLogger, type Logger } from "@src/utils/Logger";
|
|
3
|
-
|
|
4
|
-
export interface Candidate {
|
|
5
|
-
nodeId: string;
|
|
6
|
-
filePath: string;
|
|
7
|
-
content: string;
|
|
8
|
-
type: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export abstract class BaseGardener {
|
|
12
|
-
protected db: ResonanceDB;
|
|
13
|
-
protected log: Logger;
|
|
14
|
-
|
|
15
|
-
constructor(db: ResonanceDB) {
|
|
16
|
-
this.db = db;
|
|
17
|
-
// We use a generic name initially, subclasses can override or we rely on 'name' property later
|
|
18
|
-
// Actually, we can't access 'this.name' safely in constructor if it's a property.
|
|
19
|
-
// Let's use "Gardener" as the component.
|
|
20
|
-
this.log = getLogger("Gardener");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
abstract name: string;
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* Finds candidates that need attention.
|
|
27
|
-
*/
|
|
28
|
-
abstract scan(limit: number): Promise<Candidate[]>;
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Applies changes to a single candidate.
|
|
32
|
-
*/
|
|
33
|
-
abstract cultivate(candidate: Candidate): Promise<void>;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Main loop.
|
|
37
|
-
*/
|
|
38
|
-
public async run(limit: number = 10) {
|
|
39
|
-
this.log.info({ gardener: this.name }, "🌿 Gardener starting...");
|
|
40
|
-
const candidates = await this.scan(limit);
|
|
41
|
-
this.log.info(
|
|
42
|
-
{ gardener: this.name, count: candidates.length },
|
|
43
|
-
"Found candidates",
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
for (const candidate of candidates) {
|
|
47
|
-
this.log.debug(
|
|
48
|
-
{ gardener: this.name, nodeId: candidate.nodeId },
|
|
49
|
-
"Processing candidate",
|
|
50
|
-
);
|
|
51
|
-
await this.cultivate(candidate);
|
|
52
|
-
}
|
|
53
|
-
this.log.info({ gardener: this.name }, "✅ Gardener finished");
|
|
54
|
-
}
|
|
55
|
-
}
|
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
// src/llm/EnlightenedProvider.ts
|
|
2
|
-
|
|
3
|
-
export interface Message {
|
|
4
|
-
role: "system" | "user" | "assistant";
|
|
5
|
-
content: string;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
export interface EnlightenmentConfig {
|
|
9
|
-
port?: number;
|
|
10
|
-
modelAlias?: string;
|
|
11
|
-
temperature?: number;
|
|
12
|
-
maxTokens?: number;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* THE ENLIGHTENED PROVIDER
|
|
17
|
-
* A specialized adapter for the "Kirkcaldy Accountant" vector-steered model.
|
|
18
|
-
* Default Port: 8083
|
|
19
|
-
*/
|
|
20
|
-
export class EnlightenedProvider {
|
|
21
|
-
private baseUrl: string;
|
|
22
|
-
private modelAlias: string;
|
|
23
|
-
private defaultTemp: number;
|
|
24
|
-
|
|
25
|
-
constructor(config: EnlightenmentConfig = {}) {
|
|
26
|
-
this.baseUrl = `http://127.0.0.1:${config.port || 8083}/v1`;
|
|
27
|
-
this.modelAlias = config.modelAlias || "enlightened-llama";
|
|
28
|
-
this.defaultTemp = config.temperature || 0.1; // Keep it cold for logic
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* THE RATIONALITY CHECK
|
|
33
|
-
* Pings the server to ensure the Enlightenment engine is online.
|
|
34
|
-
*/
|
|
35
|
-
async isOnline(): Promise<boolean> {
|
|
36
|
-
try {
|
|
37
|
-
const response = await fetch(`${this.baseUrl}/models`);
|
|
38
|
-
return response.ok;
|
|
39
|
-
} catch {
|
|
40
|
-
return false;
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* THE THINK METHOD
|
|
46
|
-
* Sends the prompt to the vector-clamped model.
|
|
47
|
-
*/
|
|
48
|
-
async think(messages: Message[]): Promise<string> {
|
|
49
|
-
try {
|
|
50
|
-
const response = await fetch(`${this.baseUrl}/chat/completions`, {
|
|
51
|
-
method: "POST",
|
|
52
|
-
headers: {
|
|
53
|
-
"Content-Type": "application/json",
|
|
54
|
-
Authorization: "Bearer sk-dummy-key", // Required by protocol, ignored by server
|
|
55
|
-
},
|
|
56
|
-
body: JSON.stringify({
|
|
57
|
-
model: this.modelAlias,
|
|
58
|
-
messages: messages,
|
|
59
|
-
temperature: this.defaultTemp,
|
|
60
|
-
max_tokens: 1024,
|
|
61
|
-
stream: false,
|
|
62
|
-
}),
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
if (!response.ok) {
|
|
66
|
-
throw new Error(
|
|
67
|
-
`Enlightenment Error: ${response.status} ${response.statusText}`,
|
|
68
|
-
);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
const data = (await response.json()) as {
|
|
72
|
-
choices: { message: { content: string } }[];
|
|
73
|
-
};
|
|
74
|
-
return data?.choices?.[0]?.message?.content?.trim() || "";
|
|
75
|
-
} catch (error) {
|
|
76
|
-
console.error("🏴 The Philosopher is silent (Connection Error).", error);
|
|
77
|
-
throw error;
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* SPECIALIST METHOD: DE-FLUFF
|
|
83
|
-
* A pre-configured routine to strip buzzwords from text.
|
|
84
|
-
*/
|
|
85
|
-
async defluff(inputText: string): Promise<string> {
|
|
86
|
-
return this.think([
|
|
87
|
-
{
|
|
88
|
-
role: "system",
|
|
89
|
-
content:
|
|
90
|
-
"You are a ruthless editor. Rewrite the following text to be concise, factual, and free of corporate buzzwords. Return ONLY the rewritten text.",
|
|
91
|
-
},
|
|
92
|
-
{ role: "user", content: inputText },
|
|
93
|
-
]);
|
|
94
|
-
}
|
|
95
|
-
}
|
package/src/services/README.md
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
# PolyVis Services
|
|
2
|
-
|
|
3
|
-
This directory contains the service wrappers for the PolyVis backend infrastructure, including the AI model servers.
|
|
4
|
-
|
|
5
|
-
## Service Lifecycle Management
|
|
6
|
-
|
|
7
|
-
All services in this directory must implement the `ServiceLifecycle` pattern (`src/utils/ServiceLifecycle.ts`). This ensures consistent behavior for:
|
|
8
|
-
- **Startup**: checking for zombie processes, stale PID files, and creating log files.
|
|
9
|
-
- **Process Management**: standard `start`, `stop`, `restart`, `status` commands.
|
|
10
|
-
- **Zombie Defense**: Integration with the `ZombieDefense` system to prevent rogue processes.
|
|
11
|
-
|
|
12
|
-
## Available Services
|
|
13
|
-
|
|
14
|
-
| Service | Script | Port | Description |
|
|
15
|
-
| :--- | :--- | :--- | :--- |
|
|
16
|
-
| **Olmo-3** | `olmo3.ts` | `8084` | The "Auditor" model. Runs with DeepSeek reasoning format for heavy verification tasks. |
|
|
17
|
-
| **Phi-3.5** | `phi.ts` | `8082` | The "Scout" model. Fast, lightweight model for initial queries. |
|
|
18
|
-
| **Llama-3** | `llama.ts` | `8083` | The "Architect" / "Accountant". Steered via Control Vector (Scale: -0.11) for professional, structured output. |
|
|
19
|
-
| **Llama-3-UV** | `llamauv.ts` | `8085` | Unvectored Llama-3. Runs the raw base model for comparison/baseline purposes. |
|
|
20
|
-
|
|
21
|
-
## Usage
|
|
22
|
-
|
|
23
|
-
All services can be managed via `bun run`.
|
|
24
|
-
|
|
25
|
-
```bash
|
|
26
|
-
# Start a service
|
|
27
|
-
bun run <service_name> start
|
|
28
|
-
|
|
29
|
-
# Stop a service
|
|
30
|
-
bun run <service_name> stop
|
|
31
|
-
|
|
32
|
-
# Check status
|
|
33
|
-
bun run <service_name> status
|
|
34
|
-
|
|
35
|
-
# Restart
|
|
36
|
-
bun run <service_name> restart
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
### Master Status CLI
|
|
40
|
-
|
|
41
|
-
To view the status of ALL running services:
|
|
42
|
-
|
|
43
|
-
```bash
|
|
44
|
-
bun run servers
|
|
45
|
-
```
|
|
46
|
-
|
|
47
|
-
## Adding a New Service
|
|
48
|
-
|
|
49
|
-
1. **Duplicate** an existing wrapper (e.g., `src/services/llamauv.ts`).
|
|
50
|
-
2. **Configure**:
|
|
51
|
-
* Update `PORT`, `name`, `pidFile`, and `logFile`.
|
|
52
|
-
* Set the correct binary path and arguments in `runServer()`.
|
|
53
|
-
3. **Register**:
|
|
54
|
-
* Add a script to `package.json`.
|
|
55
|
-
* Add to the whitelist in `src/utils/ZombieDefense.ts`.
|
|
56
|
-
* Add to the status list in `scripts/cli/servers.ts`.
|
package/src/services/llama.ts
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { ServiceLifecycle } from "../utils/ServiceLifecycle";
|
|
3
|
-
|
|
4
|
-
// --- Configuration ---
|
|
5
|
-
const BASE_DIR = join(import.meta.dir, "../../experiments/enlightenment");
|
|
6
|
-
const BIN_PATH = join(BASE_DIR, "llama.cpp/build/bin/llama-server");
|
|
7
|
-
const MODEL_PATH = join(
|
|
8
|
-
BASE_DIR,
|
|
9
|
-
"vectors/Meta-Llama-3-8B-Instruct-Q4_K_M.gguf",
|
|
10
|
-
);
|
|
11
|
-
const VECTOR_PATH = join(BASE_DIR, "vectors/enlightenment_vector_v2.gguf");
|
|
12
|
-
|
|
13
|
-
const PORT = 8083;
|
|
14
|
-
|
|
15
|
-
const args = process.argv.slice(2);
|
|
16
|
-
const command = args[0] || "serve";
|
|
17
|
-
|
|
18
|
-
// --- Service Lifecycle ---
|
|
19
|
-
|
|
20
|
-
const lifecycle = new ServiceLifecycle({
|
|
21
|
-
name: "Llama-3",
|
|
22
|
-
pidFile: ".llama.pid",
|
|
23
|
-
logFile: ".llama.log",
|
|
24
|
-
entryPoint: "src/services/llama.ts",
|
|
25
|
-
});
|
|
26
|
-
|
|
27
|
-
// --- Server Logic ---
|
|
28
|
-
|
|
29
|
-
async function runServer() {
|
|
30
|
-
console.log(`🚀 Starting Llama-3 Server on port ${PORT}...`);
|
|
31
|
-
console.log(` 🧠 Applying Control Vector: The Accountant (-0.11)`);
|
|
32
|
-
|
|
33
|
-
const cmd = [
|
|
34
|
-
BIN_PATH,
|
|
35
|
-
"-m",
|
|
36
|
-
MODEL_PATH,
|
|
37
|
-
"--port",
|
|
38
|
-
PORT.toString(),
|
|
39
|
-
"--ctx-size",
|
|
40
|
-
"8192",
|
|
41
|
-
"--n-gpu-layers",
|
|
42
|
-
"99", // Offload to GPU/Metal
|
|
43
|
-
"--control-vector-scaled",
|
|
44
|
-
`${VECTOR_PATH}:-0.11`, // The Accountant (Calibrated: Optimal Strength)
|
|
45
|
-
"--log-disable",
|
|
46
|
-
];
|
|
47
|
-
|
|
48
|
-
const serverProcess = Bun.spawn(cmd, {
|
|
49
|
-
stdout: "inherit",
|
|
50
|
-
stderr: "inherit",
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// Wait for process to exit
|
|
54
|
-
await serverProcess.exited;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
// --- Dispatch ---
|
|
58
|
-
|
|
59
|
-
await lifecycle.run(command, runServer);
|
package/src/services/llamauv.ts
DELETED
|
@@ -1,56 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { ServiceLifecycle } from "../utils/ServiceLifecycle";
|
|
3
|
-
|
|
4
|
-
// --- Configuration ---
|
|
5
|
-
const BASE_DIR = join(import.meta.dir, "../../experiments/enlightenment");
|
|
6
|
-
const BIN_PATH = join(BASE_DIR, "llama.cpp/build/bin/llama-server");
|
|
7
|
-
const MODEL_PATH = join(
|
|
8
|
-
BASE_DIR,
|
|
9
|
-
"vectors/Meta-Llama-3-8B-Instruct-Q4_K_M.gguf",
|
|
10
|
-
);
|
|
11
|
-
|
|
12
|
-
const PORT = 8085;
|
|
13
|
-
|
|
14
|
-
const args = process.argv.slice(2);
|
|
15
|
-
const command = args[0] || "serve";
|
|
16
|
-
|
|
17
|
-
// --- Service Lifecycle ---
|
|
18
|
-
|
|
19
|
-
const lifecycle = new ServiceLifecycle({
|
|
20
|
-
name: "Llama-3-UV",
|
|
21
|
-
pidFile: ".llamauv.pid",
|
|
22
|
-
logFile: ".llamauv.log",
|
|
23
|
-
entryPoint: "src/services/llamauv.ts",
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
// --- Server Logic ---
|
|
27
|
-
|
|
28
|
-
async function runServer() {
|
|
29
|
-
console.log(`🚀 Starting Llama-3-UV (Unvectored) Server on port ${PORT}...`);
|
|
30
|
-
console.log(` 🧠 Mode: RAW (No Control Vector)`);
|
|
31
|
-
|
|
32
|
-
const cmd = [
|
|
33
|
-
BIN_PATH,
|
|
34
|
-
"-m",
|
|
35
|
-
MODEL_PATH,
|
|
36
|
-
"--port",
|
|
37
|
-
PORT.toString(),
|
|
38
|
-
"--ctx-size",
|
|
39
|
-
"8192",
|
|
40
|
-
"--n-gpu-layers",
|
|
41
|
-
"99", // Offload to GPU/Metal
|
|
42
|
-
"--log-disable",
|
|
43
|
-
];
|
|
44
|
-
|
|
45
|
-
const serverProcess = Bun.spawn(cmd, {
|
|
46
|
-
stdout: "inherit",
|
|
47
|
-
stderr: "inherit",
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
// Wait for process to exit
|
|
51
|
-
await serverProcess.exited;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
// --- Dispatch ---
|
|
55
|
-
|
|
56
|
-
await lifecycle.run(command, runServer);
|
package/src/services/olmo3.ts
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { ServiceLifecycle } from "../utils/ServiceLifecycle";
|
|
3
|
-
|
|
4
|
-
// --- Configuration ---
|
|
5
|
-
const BASE_DIR = join(import.meta.dir, "../../experiments/enlightenment");
|
|
6
|
-
const BIN_PATH = join(BASE_DIR, "llama.cpp/build/bin/llama-server");
|
|
7
|
-
const MODEL_PATH = join(BASE_DIR, "vectors/Olmo-3-7B-Think-Q4_K_M.gguf");
|
|
8
|
-
|
|
9
|
-
const PORT = 8084;
|
|
10
|
-
|
|
11
|
-
const args = process.argv.slice(2);
|
|
12
|
-
const command = args[0] || "serve";
|
|
13
|
-
|
|
14
|
-
// --- Service Lifecycle ---
|
|
15
|
-
|
|
16
|
-
const lifecycle = new ServiceLifecycle({
|
|
17
|
-
name: "Olmo-3",
|
|
18
|
-
pidFile: ".olmo3.pid",
|
|
19
|
-
logFile: ".olmo3.log",
|
|
20
|
-
entryPoint: "src/services/olmo3.ts",
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// --- Server Logic ---
|
|
24
|
-
|
|
25
|
-
async function runServer() {
|
|
26
|
-
console.log(`🚀 Starting Olmo-3 Server on port ${PORT}...`);
|
|
27
|
-
|
|
28
|
-
const cmd = [
|
|
29
|
-
BIN_PATH,
|
|
30
|
-
"-m",
|
|
31
|
-
MODEL_PATH,
|
|
32
|
-
"--port",
|
|
33
|
-
PORT.toString(),
|
|
34
|
-
"--ctx-size",
|
|
35
|
-
"8192", // Reduced context for stability on Metal
|
|
36
|
-
"--n-gpu-layers",
|
|
37
|
-
"99", // Offload to GPU/Metal
|
|
38
|
-
"--jinja", // Jinja2 template support
|
|
39
|
-
"--reasoning-format",
|
|
40
|
-
"deepseek", // Separate partial thinking
|
|
41
|
-
"-fa",
|
|
42
|
-
"on", // Flash Attention
|
|
43
|
-
"--temp",
|
|
44
|
-
"0.6",
|
|
45
|
-
];
|
|
46
|
-
|
|
47
|
-
const serverProcess = Bun.spawn(cmd, {
|
|
48
|
-
stdout: "inherit",
|
|
49
|
-
stderr: "inherit",
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
// Wait for process to exit
|
|
53
|
-
await serverProcess.exited;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// --- Dispatch ---
|
|
57
|
-
|
|
58
|
-
await lifecycle.run(command, runServer);
|
package/src/services/phi.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
import { join } from "node:path";
|
|
2
|
-
import { ServiceLifecycle } from "../utils/ServiceLifecycle";
|
|
3
|
-
|
|
4
|
-
// --- Configuration ---
|
|
5
|
-
const BASE_DIR = join(import.meta.dir, "../../experiments/enlightenment");
|
|
6
|
-
const BIN_PATH = join(BASE_DIR, "llama.cpp/build/bin/llama-server");
|
|
7
|
-
const MODEL_PATH = join(BASE_DIR, "vectors/Phi-3.5-mini-instruct-Q4_K_M.gguf");
|
|
8
|
-
|
|
9
|
-
const PORT = 8082;
|
|
10
|
-
|
|
11
|
-
const args = process.argv.slice(2);
|
|
12
|
-
const command = args[0] || "serve";
|
|
13
|
-
|
|
14
|
-
// --- Service Lifecycle ---
|
|
15
|
-
|
|
16
|
-
const lifecycle = new ServiceLifecycle({
|
|
17
|
-
name: "Phi-3.5",
|
|
18
|
-
pidFile: ".phi.pid",
|
|
19
|
-
logFile: ".phi.log",
|
|
20
|
-
entryPoint: "src/services/phi.ts",
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// --- Server Logic ---
|
|
24
|
-
|
|
25
|
-
async function runServer() {
|
|
26
|
-
console.log(`🚀 Starting Phi-3.5 Server on port ${PORT}...`);
|
|
27
|
-
|
|
28
|
-
const cmd = [
|
|
29
|
-
BIN_PATH,
|
|
30
|
-
"-m",
|
|
31
|
-
MODEL_PATH,
|
|
32
|
-
"--port",
|
|
33
|
-
PORT.toString(),
|
|
34
|
-
"--ctx-size",
|
|
35
|
-
"4096",
|
|
36
|
-
"--n-gpu-layers",
|
|
37
|
-
"99", // Offload to GPU/Metal
|
|
38
|
-
"--log-disable", // Keep clean for Phi
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
const serverProcess = Bun.spawn(cmd, {
|
|
42
|
-
stdout: "inherit",
|
|
43
|
-
stderr: "inherit",
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
// Wait for process to exit
|
|
47
|
-
await serverProcess.exited;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// --- Dispatch ---
|
|
51
|
-
|
|
52
|
-
await lifecycle.run(command, runServer);
|