forbocai 0.4.1 → 0.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +9 -2
- package/dist/index.d.ts +9 -2
- package/dist/index.js +53 -103
- package/dist/index.mjs +52 -103
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -292,6 +292,13 @@ declare const getSoulList: (limit?: number, apiUrl?: string) => Promise<SoulList
|
|
|
292
292
|
* Factory function to create Soul instance
|
|
293
293
|
*/
|
|
294
294
|
declare const createSoulInstance: (id: string, name: string, persona: string, state: AgentState, memories?: MemoryItem[], initialApiUrl?: string) => ISoul;
|
|
295
|
+
/**
|
|
296
|
+
* Pure function to validate a Soul object
|
|
297
|
+
*/
|
|
298
|
+
declare const validateSoul: (soul: Soul) => {
|
|
299
|
+
valid: boolean;
|
|
300
|
+
errors: string[];
|
|
301
|
+
};
|
|
295
302
|
|
|
296
303
|
/**
|
|
297
304
|
* Interface definition for Memory operations.
|
|
@@ -686,10 +693,10 @@ declare namespace index {
|
|
|
686
693
|
export { type index_RPGAgentState as RPGAgentState, index_RPG_MEMORY_TYPES as RPG_MEMORY_TYPES, index_RPG_MOODS as RPG_MOODS, index_attackRule as attackRule, index_createRPGState as createRPGState, index_interactRule as interactRule, index_movementRule as movementRule, index_puzzleRules as puzzleRules, index_resourceRule as resourceRule, index_rpgFallbackStrategy as rpgFallbackStrategy, index_rpgRules as rpgRules, index_socialRules as socialRules, index_spatialRules as spatialRules, index_speakRule as speakRule };
|
|
687
694
|
}
|
|
688
695
|
|
|
689
|
-
declare const SDK_VERSION = "0.
|
|
696
|
+
declare const SDK_VERSION = "0.4.2";
|
|
690
697
|
/**
|
|
691
698
|
* Initializes the ForbocAI SDK, logging status to the console.
|
|
692
699
|
*/
|
|
693
700
|
declare const init: () => void;
|
|
694
701
|
|
|
695
|
-
export { type AgentAction, type AgentConfig, type AgentResponse, type AgentState, type BridgeConfig, type CompletionOptions, type CortexConfig, type CortexStatus, type Directive, type GhostConfig, type GhostHistoryEntry, type GhostResults, type GhostStatus, type GhostTestResult, type IAgent, type IBridge, type ICortex, type IGhost, type IMemory, type ISoul, type MemoryConfig, type MemoryItem, type MemoryModuleConfig, type MemoryType, type Mood, type Observation, SDK_VERSION, type Soul, type SoulExportConfig, type SoulExportResult, type SoulImportConfig, type SoulListEntry, type ValidationContext, type ValidationResult, type ValidationRule, type VectorStatus, createAgent, createBridge, createCortex, createGhost, createInitialState, createMemory, createMemoryItem, createSoul, createSoulInstance, createTable, deserializeSoul, exportSoul, exportToSoul, fromSoul, generateEmbedding, getGhostHistory, getGhostResults, getGhostStatus, getSoulList, getVectorTable, importSoulFromArweave, init, initVectorEngine, index as presets, processAgentInput, serializeSoul, startGhostSession, stopGhostSession, updateAgentState, uploadToArweave, validateAction, waitForGhostCompletion };
|
|
702
|
+
export { type AgentAction, type AgentConfig, type AgentResponse, type AgentState, type BridgeConfig, type CompletionOptions, type CortexConfig, type CortexStatus, type Directive, type GhostConfig, type GhostHistoryEntry, type GhostResults, type GhostStatus, type GhostTestResult, type IAgent, type IBridge, type ICortex, type IGhost, type IMemory, type ISoul, type MemoryConfig, type MemoryItem, type MemoryModuleConfig, type MemoryType, type Mood, type Observation, SDK_VERSION, type Soul, type SoulExportConfig, type SoulExportResult, type SoulImportConfig, type SoulListEntry, type ValidationContext, type ValidationResult, type ValidationRule, type VectorStatus, createAgent, createBridge, createCortex, createGhost, createInitialState, createMemory, createMemoryItem, createSoul, createSoulInstance, createTable, deserializeSoul, exportSoul, exportToSoul, fromSoul, generateEmbedding, getGhostHistory, getGhostResults, getGhostStatus, getSoulList, getVectorTable, importSoulFromArweave, init, initVectorEngine, index as presets, processAgentInput, serializeSoul, startGhostSession, stopGhostSession, updateAgentState, uploadToArweave, validateAction, validateSoul, waitForGhostCompletion };
|
package/dist/index.d.ts
CHANGED
|
@@ -292,6 +292,13 @@ declare const getSoulList: (limit?: number, apiUrl?: string) => Promise<SoulList
|
|
|
292
292
|
* Factory function to create Soul instance
|
|
293
293
|
*/
|
|
294
294
|
declare const createSoulInstance: (id: string, name: string, persona: string, state: AgentState, memories?: MemoryItem[], initialApiUrl?: string) => ISoul;
|
|
295
|
+
/**
|
|
296
|
+
* Pure function to validate a Soul object
|
|
297
|
+
*/
|
|
298
|
+
declare const validateSoul: (soul: Soul) => {
|
|
299
|
+
valid: boolean;
|
|
300
|
+
errors: string[];
|
|
301
|
+
};
|
|
295
302
|
|
|
296
303
|
/**
|
|
297
304
|
* Interface definition for Memory operations.
|
|
@@ -686,10 +693,10 @@ declare namespace index {
|
|
|
686
693
|
export { type index_RPGAgentState as RPGAgentState, index_RPG_MEMORY_TYPES as RPG_MEMORY_TYPES, index_RPG_MOODS as RPG_MOODS, index_attackRule as attackRule, index_createRPGState as createRPGState, index_interactRule as interactRule, index_movementRule as movementRule, index_puzzleRules as puzzleRules, index_resourceRule as resourceRule, index_rpgFallbackStrategy as rpgFallbackStrategy, index_rpgRules as rpgRules, index_socialRules as socialRules, index_spatialRules as spatialRules, index_speakRule as speakRule };
|
|
687
694
|
}
|
|
688
695
|
|
|
689
|
-
declare const SDK_VERSION = "0.
|
|
696
|
+
declare const SDK_VERSION = "0.4.2";
|
|
690
697
|
/**
|
|
691
698
|
* Initializes the ForbocAI SDK, logging status to the console.
|
|
692
699
|
*/
|
|
693
700
|
declare const init: () => void;
|
|
694
701
|
|
|
695
|
-
export { type AgentAction, type AgentConfig, type AgentResponse, type AgentState, type BridgeConfig, type CompletionOptions, type CortexConfig, type CortexStatus, type Directive, type GhostConfig, type GhostHistoryEntry, type GhostResults, type GhostStatus, type GhostTestResult, type IAgent, type IBridge, type ICortex, type IGhost, type IMemory, type ISoul, type MemoryConfig, type MemoryItem, type MemoryModuleConfig, type MemoryType, type Mood, type Observation, SDK_VERSION, type Soul, type SoulExportConfig, type SoulExportResult, type SoulImportConfig, type SoulListEntry, type ValidationContext, type ValidationResult, type ValidationRule, type VectorStatus, createAgent, createBridge, createCortex, createGhost, createInitialState, createMemory, createMemoryItem, createSoul, createSoulInstance, createTable, deserializeSoul, exportSoul, exportToSoul, fromSoul, generateEmbedding, getGhostHistory, getGhostResults, getGhostStatus, getSoulList, getVectorTable, importSoulFromArweave, init, initVectorEngine, index as presets, processAgentInput, serializeSoul, startGhostSession, stopGhostSession, updateAgentState, uploadToArweave, validateAction, waitForGhostCompletion };
|
|
702
|
+
export { type AgentAction, type AgentConfig, type AgentResponse, type AgentState, type BridgeConfig, type CompletionOptions, type CortexConfig, type CortexStatus, type Directive, type GhostConfig, type GhostHistoryEntry, type GhostResults, type GhostStatus, type GhostTestResult, type IAgent, type IBridge, type ICortex, type IGhost, type IMemory, type ISoul, type MemoryConfig, type MemoryItem, type MemoryModuleConfig, type MemoryType, type Mood, type Observation, SDK_VERSION, type Soul, type SoulExportConfig, type SoulExportResult, type SoulImportConfig, type SoulListEntry, type ValidationContext, type ValidationResult, type ValidationRule, type VectorStatus, createAgent, createBridge, createCortex, createGhost, createInitialState, createMemory, createMemoryItem, createSoul, createSoulInstance, createTable, deserializeSoul, exportSoul, exportToSoul, fromSoul, generateEmbedding, getGhostHistory, getGhostResults, getGhostStatus, getSoulList, getVectorTable, importSoulFromArweave, init, initVectorEngine, index as presets, processAgentInput, serializeSoul, startGhostSession, stopGhostSession, updateAgentState, uploadToArweave, validateAction, validateSoul, waitForGhostCompletion };
|
package/dist/index.js
CHANGED
|
@@ -62,6 +62,7 @@ __export(index_exports, {
|
|
|
62
62
|
updateAgentState: () => updateAgentState,
|
|
63
63
|
uploadToArweave: () => uploadToArweave,
|
|
64
64
|
validateAction: () => validateAction,
|
|
65
|
+
validateSoul: () => validateSoul,
|
|
65
66
|
waitForGhostCompletion: () => waitForGhostCompletion
|
|
66
67
|
});
|
|
67
68
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -71,15 +72,10 @@ var fs = __toESM(require("fs"));
|
|
|
71
72
|
var path = __toESM(require("path"));
|
|
72
73
|
var https = __toESM(require("https"));
|
|
73
74
|
var MODEL_URLS = {
|
|
74
|
-
"smollm2-135m": "https://huggingface.co/
|
|
75
|
+
"smollm2-135m": "https://huggingface.co/bartowski/SmolLM2-135M-Instruct-GGUF/resolve/main/SmolLM2-135M-Instruct-Q4_K_M.gguf",
|
|
75
76
|
"llama3-8b": "https://huggingface.co/lmstudio-community/Meta-Llama-3-8B-Instruct-GGUF/resolve/main/Meta-Llama-3-8B-Instruct-Q4_K_M.gguf"
|
|
76
77
|
};
|
|
77
78
|
var DEFAULT_MODEL = "smollm2-135m";
|
|
78
|
-
var ensureDirectoryExists = (dirPath) => {
|
|
79
|
-
if (!fs.existsSync(dirPath)) {
|
|
80
|
-
fs.mkdirSync(dirPath, { recursive: true });
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
79
|
var downloadFile = (url, destPath) => {
|
|
84
80
|
return new Promise((resolve, reject) => {
|
|
85
81
|
const file = fs.createWriteStream(destPath);
|
|
@@ -115,47 +111,36 @@ var createNativeCortex = (config) => {
|
|
|
115
111
|
let model;
|
|
116
112
|
let context;
|
|
117
113
|
let session;
|
|
118
|
-
let
|
|
119
|
-
const createEmbeddingContext = async () => {
|
|
120
|
-
if (!model.embeddingSupported) {
|
|
121
|
-
throw new Error("Model does not support embeddings");
|
|
122
|
-
}
|
|
123
|
-
embeddingContext = await model.createEmbeddingContext();
|
|
124
|
-
};
|
|
114
|
+
let featureExtraction = null;
|
|
125
115
|
const MODELS_DIR = path.join(process.cwd(), "local_infrastructure", "models");
|
|
126
116
|
const init2 = async () => {
|
|
127
117
|
if (status.ready) return status;
|
|
128
118
|
try {
|
|
129
|
-
console.log("> Initializing Native Cortex
|
|
119
|
+
console.log("> Initializing Native Cortex...");
|
|
120
|
+
console.log("> Loading Embedding Model (all-MiniLM-L6-v2)...");
|
|
121
|
+
const { pipeline: pipeline2 } = await import("@xenova/transformers");
|
|
122
|
+
featureExtraction = await pipeline2("feature-extraction", "Xenova/all-MiniLM-L6-v2");
|
|
123
|
+
const ensureDirectoryExists = (dirPath) => {
|
|
124
|
+
if (!fs.existsSync(dirPath)) fs.mkdirSync(dirPath, { recursive: true });
|
|
125
|
+
};
|
|
130
126
|
ensureDirectoryExists(MODELS_DIR);
|
|
131
127
|
const modelKey = config.model || DEFAULT_MODEL;
|
|
132
128
|
const modelUrl = MODEL_URLS[modelKey] || MODEL_URLS[DEFAULT_MODEL];
|
|
133
129
|
const modelFileName = path.basename(modelUrl);
|
|
134
130
|
const modelPath = path.join(MODELS_DIR, modelFileName);
|
|
135
131
|
if (!fs.existsSync(modelPath)) {
|
|
136
|
-
console.log(`> Downloading
|
|
137
|
-
console.log(`> Source: ${modelUrl}`);
|
|
132
|
+
console.log(`> Downloading SLM: ${modelKey}...`);
|
|
138
133
|
await downloadFile(modelUrl, modelPath);
|
|
139
134
|
console.log(`> Download complete.`);
|
|
140
|
-
} else {
|
|
141
|
-
console.log(`> Using cached model: ${modelPath}`);
|
|
142
135
|
}
|
|
143
136
|
const { getLlama, LlamaChatSession } = await import("node-llama-cpp");
|
|
144
137
|
llama = await getLlama();
|
|
145
|
-
console.log("> Loading
|
|
138
|
+
console.log("> Loading SLM into memory...");
|
|
146
139
|
model = await llama.loadModel({
|
|
147
140
|
modelPath,
|
|
148
141
|
gpuLayers: config.gpu ? 99 : 0
|
|
149
|
-
// Try to use GPU if allowed
|
|
150
142
|
});
|
|
151
|
-
console.log("> Creating context...");
|
|
152
143
|
context = await model.createContext();
|
|
153
|
-
if (model.embeddingSupported) {
|
|
154
|
-
console.log("> Creating embedding context...");
|
|
155
|
-
embeddingContext = await model.createEmbeddingContext();
|
|
156
|
-
} else {
|
|
157
|
-
console.log("> Model does not support embeddings");
|
|
158
|
-
}
|
|
159
144
|
session = new LlamaChatSession({
|
|
160
145
|
contextSequence: context.getSequence()
|
|
161
146
|
});
|
|
@@ -181,52 +166,17 @@ var createNativeCortex = (config) => {
|
|
|
181
166
|
};
|
|
182
167
|
const completeStream = async function* (prompt, options = {}) {
|
|
183
168
|
if (!status.ready) await init2();
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
let isComplete = false;
|
|
187
|
-
const generationPromise = session.prompt(prompt, {
|
|
188
|
-
maxTokens: options.maxTokens,
|
|
189
|
-
temperature: options.temperature,
|
|
190
|
-
onToken: (tokens) => {
|
|
191
|
-
try {
|
|
192
|
-
const text = model.detokenize(tokens);
|
|
193
|
-
if (text) {
|
|
194
|
-
tokenQueue.push(text);
|
|
195
|
-
if (resolveNext) {
|
|
196
|
-
resolveNext();
|
|
197
|
-
resolveNext = null;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
} catch {
|
|
201
|
-
tokenQueue.push(tokens.map((t) => String.fromCharCode(t % 256)).join(""));
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}).then(() => {
|
|
205
|
-
isComplete = true;
|
|
206
|
-
if (resolveNext) resolveNext();
|
|
207
|
-
});
|
|
208
|
-
while (!isComplete || tokenQueue.length > 0) {
|
|
209
|
-
if (tokenQueue.length > 0) {
|
|
210
|
-
yield tokenQueue.shift();
|
|
211
|
-
} else if (!isComplete) {
|
|
212
|
-
await new Promise((resolve) => {
|
|
213
|
-
resolveNext = resolve;
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
await generationPromise;
|
|
169
|
+
const result = await session.prompt(prompt, { maxTokens: options.maxTokens });
|
|
170
|
+
yield result;
|
|
218
171
|
};
|
|
219
172
|
const embed = async (text) => {
|
|
220
173
|
if (!status.ready) await init2();
|
|
221
174
|
try {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
}
|
|
225
|
-
const embeddings = await embeddingContext.getEmbeddingFor(text);
|
|
226
|
-
return Array.from(embeddings);
|
|
175
|
+
const output = await featureExtraction(text, { pooling: "mean", normalize: true });
|
|
176
|
+
return Array.from(output.data);
|
|
227
177
|
} catch (e) {
|
|
228
|
-
console.
|
|
229
|
-
return new Array(384).fill(0)
|
|
178
|
+
console.error("Embedding failed:", e);
|
|
179
|
+
return new Array(384).fill(0);
|
|
230
180
|
}
|
|
231
181
|
};
|
|
232
182
|
return {
|
|
@@ -234,7 +184,6 @@ var createNativeCortex = (config) => {
|
|
|
234
184
|
complete,
|
|
235
185
|
completeStream,
|
|
236
186
|
embed
|
|
237
|
-
// Extended interface for private use by Memory
|
|
238
187
|
};
|
|
239
188
|
};
|
|
240
189
|
var createCortex = (config) => createNativeCortex(config);
|
|
@@ -287,9 +236,6 @@ var createAgent = (config) => {
|
|
|
287
236
|
const process2 = async (input, context = {}) => {
|
|
288
237
|
const currentState = getAgentState();
|
|
289
238
|
const apiContext = Object.entries(context).map(([k, v]) => [k, String(v)]);
|
|
290
|
-
let directive = "Respond normally.";
|
|
291
|
-
let instruction = "IDLE";
|
|
292
|
-
let target;
|
|
293
239
|
const timestamp = Date.now();
|
|
294
240
|
apiContext.push(["timestamp", String(timestamp)]);
|
|
295
241
|
let relevantMemories = [];
|
|
@@ -299,6 +245,9 @@ var createAgent = (config) => {
|
|
|
299
245
|
} catch {
|
|
300
246
|
}
|
|
301
247
|
}
|
|
248
|
+
let directive = "Respond normally.";
|
|
249
|
+
let instruction = "IDLE";
|
|
250
|
+
let target;
|
|
302
251
|
try {
|
|
303
252
|
const dirRes = await fetch(`${apiUrl}/agents/${agentId}/directive`, {
|
|
304
253
|
method: "POST",
|
|
@@ -309,7 +258,6 @@ var createAgent = (config) => {
|
|
|
309
258
|
body: JSON.stringify({
|
|
310
259
|
dirContext: apiContext,
|
|
311
260
|
dirState: currentState,
|
|
312
|
-
// Full state dump
|
|
313
261
|
dirMemories: relevantMemories.map((m) => ({ text: m.text, type: m.type, importance: m.importance }))
|
|
314
262
|
})
|
|
315
263
|
});
|
|
@@ -319,39 +267,31 @@ var createAgent = (config) => {
|
|
|
319
267
|
instruction = data.dirInstruction;
|
|
320
268
|
target = data.dirTarget;
|
|
321
269
|
} else {
|
|
322
|
-
|
|
323
|
-
if (config.fallbackStrategy) {
|
|
324
|
-
const fallback = config.fallbackStrategy(currentState, context);
|
|
325
|
-
instruction = fallback.instruction;
|
|
326
|
-
directive = fallback.directive;
|
|
327
|
-
} else {
|
|
328
|
-
instruction = "IDLE";
|
|
329
|
-
directive = "Autonomous behavior";
|
|
330
|
-
}
|
|
270
|
+
throw new Error(`API Error: ${dirRes.status}`);
|
|
331
271
|
}
|
|
332
272
|
} catch (e) {
|
|
333
|
-
console.warn("API Directive Failed (Network),
|
|
273
|
+
console.warn("API Directive Failed (Network/Offline), using fallback.", e);
|
|
334
274
|
if (config.fallbackStrategy) {
|
|
335
275
|
const fallback = config.fallbackStrategy(currentState, context);
|
|
336
276
|
instruction = fallback.instruction;
|
|
337
277
|
directive = fallback.directive;
|
|
338
278
|
} else {
|
|
339
279
|
instruction = "IDLE";
|
|
340
|
-
directive = "Autonomous behavior";
|
|
280
|
+
directive = "Autonomous behavior (Offline)";
|
|
341
281
|
}
|
|
342
282
|
}
|
|
343
283
|
const memoryContext = relevantMemories.length > 0 ? `
|
|
344
284
|
Memories:
|
|
345
285
|
${relevantMemories.map((m) => `- [${m.type}] ${m.text}`).join("\n")}
|
|
346
286
|
` : "";
|
|
347
|
-
const prompt = `System:
|
|
348
|
-
|
|
287
|
+
const prompt = `System: You are ${config.persona}.
|
|
288
|
+
Directive: ${instruction} (${directive}).
|
|
289
|
+
Target: ${target || "None"}${memoryContext}
|
|
349
290
|
User: ${input}
|
|
350
291
|
Agent:`;
|
|
351
292
|
const generatedText = await cortex.complete(prompt);
|
|
352
293
|
let signature = "unsigned_local_fallback";
|
|
353
294
|
let isValid = true;
|
|
354
|
-
const proposedAction = { type: instruction, reason: directive, target };
|
|
355
295
|
try {
|
|
356
296
|
const verRes = await fetch(`${apiUrl}/agents/${agentId}/verdict`, {
|
|
357
297
|
method: "POST",
|
|
@@ -359,13 +299,14 @@ Agent:`;
|
|
|
359
299
|
body: JSON.stringify({
|
|
360
300
|
verDirective: {
|
|
361
301
|
dirInstruction: instruction,
|
|
362
|
-
dirTarget: target,
|
|
302
|
+
dirTarget: target || "",
|
|
363
303
|
dirReason: directive
|
|
364
304
|
},
|
|
365
305
|
verAction: {
|
|
366
|
-
|
|
306
|
+
gaType: instruction,
|
|
307
|
+
// Map to generic action type
|
|
367
308
|
actionReason: directive,
|
|
368
|
-
actionTarget: target
|
|
309
|
+
actionTarget: target || ""
|
|
369
310
|
},
|
|
370
311
|
verThought: generatedText
|
|
371
312
|
})
|
|
@@ -376,7 +317,7 @@ Agent:`;
|
|
|
376
317
|
signature = vData.verSignature;
|
|
377
318
|
}
|
|
378
319
|
} catch (e) {
|
|
379
|
-
console.warn("API Verdict Failed.", e);
|
|
320
|
+
console.warn("API Verdict Failed. Assuming valid locally.", e);
|
|
380
321
|
}
|
|
381
322
|
if (!isValid) {
|
|
382
323
|
return {
|
|
@@ -390,8 +331,13 @@ Agent:`;
|
|
|
390
331
|
}
|
|
391
332
|
return {
|
|
392
333
|
dialogue: generatedText,
|
|
393
|
-
action: {
|
|
394
|
-
|
|
334
|
+
action: {
|
|
335
|
+
type: instruction,
|
|
336
|
+
reason: directive,
|
|
337
|
+
target,
|
|
338
|
+
signature
|
|
339
|
+
},
|
|
340
|
+
thought: `Directive: ${directive}`
|
|
395
341
|
};
|
|
396
342
|
};
|
|
397
343
|
const exportSoul2 = async () => {
|
|
@@ -399,17 +345,10 @@ Agent:`;
|
|
|
399
345
|
if (config.memory && typeof config.memory.export === "function") {
|
|
400
346
|
try {
|
|
401
347
|
exportedMemories = await config.memory.export();
|
|
402
|
-
} catch
|
|
403
|
-
console.warn("Failed to export memories from module:", e);
|
|
348
|
+
} catch {
|
|
404
349
|
}
|
|
405
350
|
}
|
|
406
|
-
return exportToSoul(
|
|
407
|
-
agentId,
|
|
408
|
-
"Agent",
|
|
409
|
-
config.persona,
|
|
410
|
-
state,
|
|
411
|
-
exportedMemories
|
|
412
|
-
);
|
|
351
|
+
return exportToSoul(agentId, "Agent", config.persona, state, exportedMemories);
|
|
413
352
|
};
|
|
414
353
|
return {
|
|
415
354
|
process: process2,
|
|
@@ -573,6 +512,16 @@ var createSoulInstance = (id, name, persona, state, memories = [], initialApiUrl
|
|
|
573
512
|
toJSON: () => ({ ...soulData })
|
|
574
513
|
};
|
|
575
514
|
};
|
|
515
|
+
var validateSoul = (soul) => {
|
|
516
|
+
const errors = [];
|
|
517
|
+
if (!soul.id) errors.push("Missing id");
|
|
518
|
+
if (!soul.persona) errors.push("Missing persona");
|
|
519
|
+
if (!soul.state) errors.push("Missing state");
|
|
520
|
+
return {
|
|
521
|
+
valid: errors.length === 0,
|
|
522
|
+
errors
|
|
523
|
+
};
|
|
524
|
+
};
|
|
576
525
|
|
|
577
526
|
// src/memory.ts
|
|
578
527
|
var path3 = __toESM(require("path"));
|
|
@@ -1268,7 +1217,7 @@ var socialRules = [speakRule, interactRule];
|
|
|
1268
1217
|
var puzzleRules = [movementRule, interactRule];
|
|
1269
1218
|
|
|
1270
1219
|
// src/index.ts
|
|
1271
|
-
var SDK_VERSION = "0.
|
|
1220
|
+
var SDK_VERSION = "0.4.2";
|
|
1272
1221
|
var init = () => {
|
|
1273
1222
|
console.log(`
|
|
1274
1223
|
\x1B[36m _ _ _ ___ _ _
|
|
@@ -1318,5 +1267,6 @@ var init = () => {
|
|
|
1318
1267
|
updateAgentState,
|
|
1319
1268
|
uploadToArweave,
|
|
1320
1269
|
validateAction,
|
|
1270
|
+
validateSoul,
|
|
1321
1271
|
waitForGhostCompletion
|
|
1322
1272
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -9,15 +9,10 @@ import * as fs from "fs";
|
|
|
9
9
|
import * as path from "path";
|
|
10
10
|
import * as https from "https";
|
|
11
11
|
var MODEL_URLS = {
|
|
12
|
-
"smollm2-135m": "https://huggingface.co/
|
|
12
|
+
"smollm2-135m": "https://huggingface.co/bartowski/SmolLM2-135M-Instruct-GGUF/resolve/main/SmolLM2-135M-Instruct-Q4_K_M.gguf",
|
|
13
13
|
"llama3-8b": "https://huggingface.co/lmstudio-community/Meta-Llama-3-8B-Instruct-GGUF/resolve/main/Meta-Llama-3-8B-Instruct-Q4_K_M.gguf"
|
|
14
14
|
};
|
|
15
15
|
var DEFAULT_MODEL = "smollm2-135m";
|
|
16
|
-
var ensureDirectoryExists = (dirPath) => {
|
|
17
|
-
if (!fs.existsSync(dirPath)) {
|
|
18
|
-
fs.mkdirSync(dirPath, { recursive: true });
|
|
19
|
-
}
|
|
20
|
-
};
|
|
21
16
|
var downloadFile = (url, destPath) => {
|
|
22
17
|
return new Promise((resolve, reject) => {
|
|
23
18
|
const file = fs.createWriteStream(destPath);
|
|
@@ -53,47 +48,36 @@ var createNativeCortex = (config) => {
|
|
|
53
48
|
let model;
|
|
54
49
|
let context;
|
|
55
50
|
let session;
|
|
56
|
-
let
|
|
57
|
-
const createEmbeddingContext = async () => {
|
|
58
|
-
if (!model.embeddingSupported) {
|
|
59
|
-
throw new Error("Model does not support embeddings");
|
|
60
|
-
}
|
|
61
|
-
embeddingContext = await model.createEmbeddingContext();
|
|
62
|
-
};
|
|
51
|
+
let featureExtraction = null;
|
|
63
52
|
const MODELS_DIR = path.join(process.cwd(), "local_infrastructure", "models");
|
|
64
53
|
const init2 = async () => {
|
|
65
54
|
if (status.ready) return status;
|
|
66
55
|
try {
|
|
67
|
-
console.log("> Initializing Native Cortex
|
|
56
|
+
console.log("> Initializing Native Cortex...");
|
|
57
|
+
console.log("> Loading Embedding Model (all-MiniLM-L6-v2)...");
|
|
58
|
+
const { pipeline: pipeline2 } = await import("@xenova/transformers");
|
|
59
|
+
featureExtraction = await pipeline2("feature-extraction", "Xenova/all-MiniLM-L6-v2");
|
|
60
|
+
const ensureDirectoryExists = (dirPath) => {
|
|
61
|
+
if (!fs.existsSync(dirPath)) fs.mkdirSync(dirPath, { recursive: true });
|
|
62
|
+
};
|
|
68
63
|
ensureDirectoryExists(MODELS_DIR);
|
|
69
64
|
const modelKey = config.model || DEFAULT_MODEL;
|
|
70
65
|
const modelUrl = MODEL_URLS[modelKey] || MODEL_URLS[DEFAULT_MODEL];
|
|
71
66
|
const modelFileName = path.basename(modelUrl);
|
|
72
67
|
const modelPath = path.join(MODELS_DIR, modelFileName);
|
|
73
68
|
if (!fs.existsSync(modelPath)) {
|
|
74
|
-
console.log(`> Downloading
|
|
75
|
-
console.log(`> Source: ${modelUrl}`);
|
|
69
|
+
console.log(`> Downloading SLM: ${modelKey}...`);
|
|
76
70
|
await downloadFile(modelUrl, modelPath);
|
|
77
71
|
console.log(`> Download complete.`);
|
|
78
|
-
} else {
|
|
79
|
-
console.log(`> Using cached model: ${modelPath}`);
|
|
80
72
|
}
|
|
81
73
|
const { getLlama, LlamaChatSession } = await import("node-llama-cpp");
|
|
82
74
|
llama = await getLlama();
|
|
83
|
-
console.log("> Loading
|
|
75
|
+
console.log("> Loading SLM into memory...");
|
|
84
76
|
model = await llama.loadModel({
|
|
85
77
|
modelPath,
|
|
86
78
|
gpuLayers: config.gpu ? 99 : 0
|
|
87
|
-
// Try to use GPU if allowed
|
|
88
79
|
});
|
|
89
|
-
console.log("> Creating context...");
|
|
90
80
|
context = await model.createContext();
|
|
91
|
-
if (model.embeddingSupported) {
|
|
92
|
-
console.log("> Creating embedding context...");
|
|
93
|
-
embeddingContext = await model.createEmbeddingContext();
|
|
94
|
-
} else {
|
|
95
|
-
console.log("> Model does not support embeddings");
|
|
96
|
-
}
|
|
97
81
|
session = new LlamaChatSession({
|
|
98
82
|
contextSequence: context.getSequence()
|
|
99
83
|
});
|
|
@@ -119,52 +103,17 @@ var createNativeCortex = (config) => {
|
|
|
119
103
|
};
|
|
120
104
|
const completeStream = async function* (prompt, options = {}) {
|
|
121
105
|
if (!status.ready) await init2();
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
let isComplete = false;
|
|
125
|
-
const generationPromise = session.prompt(prompt, {
|
|
126
|
-
maxTokens: options.maxTokens,
|
|
127
|
-
temperature: options.temperature,
|
|
128
|
-
onToken: (tokens) => {
|
|
129
|
-
try {
|
|
130
|
-
const text = model.detokenize(tokens);
|
|
131
|
-
if (text) {
|
|
132
|
-
tokenQueue.push(text);
|
|
133
|
-
if (resolveNext) {
|
|
134
|
-
resolveNext();
|
|
135
|
-
resolveNext = null;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
} catch {
|
|
139
|
-
tokenQueue.push(tokens.map((t) => String.fromCharCode(t % 256)).join(""));
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}).then(() => {
|
|
143
|
-
isComplete = true;
|
|
144
|
-
if (resolveNext) resolveNext();
|
|
145
|
-
});
|
|
146
|
-
while (!isComplete || tokenQueue.length > 0) {
|
|
147
|
-
if (tokenQueue.length > 0) {
|
|
148
|
-
yield tokenQueue.shift();
|
|
149
|
-
} else if (!isComplete) {
|
|
150
|
-
await new Promise((resolve) => {
|
|
151
|
-
resolveNext = resolve;
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
await generationPromise;
|
|
106
|
+
const result = await session.prompt(prompt, { maxTokens: options.maxTokens });
|
|
107
|
+
yield result;
|
|
156
108
|
};
|
|
157
109
|
const embed = async (text) => {
|
|
158
110
|
if (!status.ready) await init2();
|
|
159
111
|
try {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
const embeddings = await embeddingContext.getEmbeddingFor(text);
|
|
164
|
-
return Array.from(embeddings);
|
|
112
|
+
const output = await featureExtraction(text, { pooling: "mean", normalize: true });
|
|
113
|
+
return Array.from(output.data);
|
|
165
114
|
} catch (e) {
|
|
166
|
-
console.
|
|
167
|
-
return new Array(384).fill(0)
|
|
115
|
+
console.error("Embedding failed:", e);
|
|
116
|
+
return new Array(384).fill(0);
|
|
168
117
|
}
|
|
169
118
|
};
|
|
170
119
|
return {
|
|
@@ -172,7 +121,6 @@ var createNativeCortex = (config) => {
|
|
|
172
121
|
complete,
|
|
173
122
|
completeStream,
|
|
174
123
|
embed
|
|
175
|
-
// Extended interface for private use by Memory
|
|
176
124
|
};
|
|
177
125
|
};
|
|
178
126
|
var createCortex = (config) => createNativeCortex(config);
|
|
@@ -225,9 +173,6 @@ var createAgent = (config) => {
|
|
|
225
173
|
const process2 = async (input, context = {}) => {
|
|
226
174
|
const currentState = getAgentState();
|
|
227
175
|
const apiContext = Object.entries(context).map(([k, v]) => [k, String(v)]);
|
|
228
|
-
let directive = "Respond normally.";
|
|
229
|
-
let instruction = "IDLE";
|
|
230
|
-
let target;
|
|
231
176
|
const timestamp = Date.now();
|
|
232
177
|
apiContext.push(["timestamp", String(timestamp)]);
|
|
233
178
|
let relevantMemories = [];
|
|
@@ -237,6 +182,9 @@ var createAgent = (config) => {
|
|
|
237
182
|
} catch {
|
|
238
183
|
}
|
|
239
184
|
}
|
|
185
|
+
let directive = "Respond normally.";
|
|
186
|
+
let instruction = "IDLE";
|
|
187
|
+
let target;
|
|
240
188
|
try {
|
|
241
189
|
const dirRes = await fetch(`${apiUrl}/agents/${agentId}/directive`, {
|
|
242
190
|
method: "POST",
|
|
@@ -247,7 +195,6 @@ var createAgent = (config) => {
|
|
|
247
195
|
body: JSON.stringify({
|
|
248
196
|
dirContext: apiContext,
|
|
249
197
|
dirState: currentState,
|
|
250
|
-
// Full state dump
|
|
251
198
|
dirMemories: relevantMemories.map((m) => ({ text: m.text, type: m.type, importance: m.importance }))
|
|
252
199
|
})
|
|
253
200
|
});
|
|
@@ -257,39 +204,31 @@ var createAgent = (config) => {
|
|
|
257
204
|
instruction = data.dirInstruction;
|
|
258
205
|
target = data.dirTarget;
|
|
259
206
|
} else {
|
|
260
|
-
|
|
261
|
-
if (config.fallbackStrategy) {
|
|
262
|
-
const fallback = config.fallbackStrategy(currentState, context);
|
|
263
|
-
instruction = fallback.instruction;
|
|
264
|
-
directive = fallback.directive;
|
|
265
|
-
} else {
|
|
266
|
-
instruction = "IDLE";
|
|
267
|
-
directive = "Autonomous behavior";
|
|
268
|
-
}
|
|
207
|
+
throw new Error(`API Error: ${dirRes.status}`);
|
|
269
208
|
}
|
|
270
209
|
} catch (e) {
|
|
271
|
-
console.warn("API Directive Failed (Network),
|
|
210
|
+
console.warn("API Directive Failed (Network/Offline), using fallback.", e);
|
|
272
211
|
if (config.fallbackStrategy) {
|
|
273
212
|
const fallback = config.fallbackStrategy(currentState, context);
|
|
274
213
|
instruction = fallback.instruction;
|
|
275
214
|
directive = fallback.directive;
|
|
276
215
|
} else {
|
|
277
216
|
instruction = "IDLE";
|
|
278
|
-
directive = "Autonomous behavior";
|
|
217
|
+
directive = "Autonomous behavior (Offline)";
|
|
279
218
|
}
|
|
280
219
|
}
|
|
281
220
|
const memoryContext = relevantMemories.length > 0 ? `
|
|
282
221
|
Memories:
|
|
283
222
|
${relevantMemories.map((m) => `- [${m.type}] ${m.text}`).join("\n")}
|
|
284
223
|
` : "";
|
|
285
|
-
const prompt = `System:
|
|
286
|
-
|
|
224
|
+
const prompt = `System: You are ${config.persona}.
|
|
225
|
+
Directive: ${instruction} (${directive}).
|
|
226
|
+
Target: ${target || "None"}${memoryContext}
|
|
287
227
|
User: ${input}
|
|
288
228
|
Agent:`;
|
|
289
229
|
const generatedText = await cortex.complete(prompt);
|
|
290
230
|
let signature = "unsigned_local_fallback";
|
|
291
231
|
let isValid = true;
|
|
292
|
-
const proposedAction = { type: instruction, reason: directive, target };
|
|
293
232
|
try {
|
|
294
233
|
const verRes = await fetch(`${apiUrl}/agents/${agentId}/verdict`, {
|
|
295
234
|
method: "POST",
|
|
@@ -297,13 +236,14 @@ Agent:`;
|
|
|
297
236
|
body: JSON.stringify({
|
|
298
237
|
verDirective: {
|
|
299
238
|
dirInstruction: instruction,
|
|
300
|
-
dirTarget: target,
|
|
239
|
+
dirTarget: target || "",
|
|
301
240
|
dirReason: directive
|
|
302
241
|
},
|
|
303
242
|
verAction: {
|
|
304
|
-
|
|
243
|
+
gaType: instruction,
|
|
244
|
+
// Map to generic action type
|
|
305
245
|
actionReason: directive,
|
|
306
|
-
actionTarget: target
|
|
246
|
+
actionTarget: target || ""
|
|
307
247
|
},
|
|
308
248
|
verThought: generatedText
|
|
309
249
|
})
|
|
@@ -314,7 +254,7 @@ Agent:`;
|
|
|
314
254
|
signature = vData.verSignature;
|
|
315
255
|
}
|
|
316
256
|
} catch (e) {
|
|
317
|
-
console.warn("API Verdict Failed.", e);
|
|
257
|
+
console.warn("API Verdict Failed. Assuming valid locally.", e);
|
|
318
258
|
}
|
|
319
259
|
if (!isValid) {
|
|
320
260
|
return {
|
|
@@ -328,8 +268,13 @@ Agent:`;
|
|
|
328
268
|
}
|
|
329
269
|
return {
|
|
330
270
|
dialogue: generatedText,
|
|
331
|
-
action: {
|
|
332
|
-
|
|
271
|
+
action: {
|
|
272
|
+
type: instruction,
|
|
273
|
+
reason: directive,
|
|
274
|
+
target,
|
|
275
|
+
signature
|
|
276
|
+
},
|
|
277
|
+
thought: `Directive: ${directive}`
|
|
333
278
|
};
|
|
334
279
|
};
|
|
335
280
|
const exportSoul2 = async () => {
|
|
@@ -337,17 +282,10 @@ Agent:`;
|
|
|
337
282
|
if (config.memory && typeof config.memory.export === "function") {
|
|
338
283
|
try {
|
|
339
284
|
exportedMemories = await config.memory.export();
|
|
340
|
-
} catch
|
|
341
|
-
console.warn("Failed to export memories from module:", e);
|
|
285
|
+
} catch {
|
|
342
286
|
}
|
|
343
287
|
}
|
|
344
|
-
return exportToSoul(
|
|
345
|
-
agentId,
|
|
346
|
-
"Agent",
|
|
347
|
-
config.persona,
|
|
348
|
-
state,
|
|
349
|
-
exportedMemories
|
|
350
|
-
);
|
|
288
|
+
return exportToSoul(agentId, "Agent", config.persona, state, exportedMemories);
|
|
351
289
|
};
|
|
352
290
|
return {
|
|
353
291
|
process: process2,
|
|
@@ -511,6 +449,16 @@ var createSoulInstance = (id, name, persona, state, memories = [], initialApiUrl
|
|
|
511
449
|
toJSON: () => ({ ...soulData })
|
|
512
450
|
};
|
|
513
451
|
};
|
|
452
|
+
var validateSoul = (soul) => {
|
|
453
|
+
const errors = [];
|
|
454
|
+
if (!soul.id) errors.push("Missing id");
|
|
455
|
+
if (!soul.persona) errors.push("Missing persona");
|
|
456
|
+
if (!soul.state) errors.push("Missing state");
|
|
457
|
+
return {
|
|
458
|
+
valid: errors.length === 0,
|
|
459
|
+
errors
|
|
460
|
+
};
|
|
461
|
+
};
|
|
514
462
|
|
|
515
463
|
// src/memory.ts
|
|
516
464
|
import * as path3 from "path";
|
|
@@ -1206,7 +1154,7 @@ var socialRules = [speakRule, interactRule];
|
|
|
1206
1154
|
var puzzleRules = [movementRule, interactRule];
|
|
1207
1155
|
|
|
1208
1156
|
// src/index.ts
|
|
1209
|
-
var SDK_VERSION = "0.
|
|
1157
|
+
var SDK_VERSION = "0.4.2";
|
|
1210
1158
|
var init = () => {
|
|
1211
1159
|
console.log(`
|
|
1212
1160
|
\x1B[36m _ _ _ ___ _ _
|
|
@@ -1255,5 +1203,6 @@ export {
|
|
|
1255
1203
|
updateAgentState,
|
|
1256
1204
|
uploadToArweave,
|
|
1257
1205
|
validateAction,
|
|
1206
|
+
validateSoul,
|
|
1258
1207
|
waitForGhostCompletion
|
|
1259
1208
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "forbocai",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"description": "The Infrastructure Layer for Autonomous AI Characters",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -45,4 +45,4 @@
|
|
|
45
45
|
"glob": "^11.0.0",
|
|
46
46
|
"rimraf": "^5.0.0"
|
|
47
47
|
}
|
|
48
|
-
}
|
|
48
|
+
}
|