forbocai 0.3.0 → 0.3.3

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.mjs CHANGED
@@ -1,149 +1,179 @@
1
1
  // src/cortex.ts
2
- import { CreateMLCEngine } from "@mlc-ai/web-llm";
3
- var MODEL_CONFIG = {
4
- "smollm2-135m": "HuggingFaceTB/SmolLM2-135M-Instruct-q4f16_1-MLC",
5
- "llama3-8b": "Llama-3-8B-Instruct-q4f16_1-MLC",
6
- "default": "HuggingFaceTB/SmolLM2-135M-Instruct-q4f16_1-MLC"
2
+ import * as fs from "fs";
3
+ import * as path from "path";
4
+ import * as https from "https";
5
+ var MODEL_URLS = {
6
+ "smollm2-135m": "https://huggingface.co/HuggingFaceTB/SmolLM2-135M-Instruct-GGUF/resolve/main/smollm2-135m-instruct-q4_k_m.gguf",
7
+ "llama3-8b": "https://huggingface.co/lmstudio-community/Meta-Llama-3-8B-Instruct-GGUF/resolve/main/Meta-Llama-3-8B-Instruct-Q4_K_M.gguf"
7
8
  };
8
- var createCortex = (config) => {
9
- return new WebLLMCortex(config);
10
- };
11
- var generateCompletion = (prompt, options, modelId) => {
12
- const temperature = options.temperature ?? 0.7;
13
- return `[Mock Response] Model: ${modelId}, Temp: ${temperature}. Response to: ${prompt}`;
9
+ var DEFAULT_MODEL = "smollm2-135m";
10
+ var ensureDirectoryExists = (dirPath) => {
11
+ if (!fs.existsSync(dirPath)) {
12
+ fs.mkdirSync(dirPath, { recursive: true });
13
+ }
14
14
  };
15
- var processObservationToDirective = (observation) => {
16
- return {
17
- type: "system-prompt",
18
- content: "You are an autonomous agent in a game world. Process the observation and generate appropriate actions.",
19
- priority: "normal"
20
- };
15
+ var downloadFile = (url, destPath) => {
16
+ return new Promise((resolve, reject) => {
17
+ const file = fs.createWriteStream(destPath);
18
+ https.get(url, (response) => {
19
+ if (response.statusCode === 302 || response.statusCode === 301) {
20
+ downloadFile(response.headers.location, destPath).then(resolve).catch(reject);
21
+ return;
22
+ }
23
+ if (response.statusCode !== 200) {
24
+ reject(new Error(`Failed to download: ${response.statusCode}`));
25
+ return;
26
+ }
27
+ response.pipe(file);
28
+ file.on("finish", () => {
29
+ file.close();
30
+ resolve();
31
+ });
32
+ }).on("error", (err) => {
33
+ fs.unlink(destPath, () => {
34
+ });
35
+ reject(err);
36
+ });
37
+ });
21
38
  };
22
- var generateActionFromDirective = (directive) => {
23
- return {
24
- type: "idle",
25
- reason: directive.content ?? "No specific directive provided"
39
+ var createNativeCortex = (config) => {
40
+ let status = {
41
+ id: "native-init",
42
+ model: config.model || DEFAULT_MODEL,
43
+ ready: false,
44
+ engine: "node-llama-cpp"
26
45
  };
27
- };
28
- var WebLLMCortex = class {
29
- constructor(config) {
30
- this.status = null;
31
- this.engine = null;
32
- this.config = {
33
- ...config,
34
- temperature: config.temperature ?? 0.7,
35
- maxTokens: config.maxTokens ?? 1024,
36
- gpu: config.gpu ?? true
37
- };
38
- }
39
- async init() {
40
- if (this.status?.ready) {
41
- return this.status;
42
- }
46
+ let llama;
47
+ let model;
48
+ let context;
49
+ let session;
50
+ const MODELS_DIR = path.join(process.cwd(), "local_infrastructure", "models");
51
+ const init2 = async () => {
52
+ if (status.ready) return status;
43
53
  try {
44
- const isBrowser = typeof window !== "undefined";
45
- if (isBrowser && this.config.gpu) {
46
- console.log(`> Initializing WebLLM with model: ${this.config.model}`);
47
- const selectedModel = MODEL_CONFIG[this.config.model] || MODEL_CONFIG["default"];
48
- this.engine = await CreateMLCEngine(selectedModel, {
49
- initProgressCallback: (progress) => {
50
- console.log(`> Model Loading: ${(progress.progress * 100).toFixed(1)}% - ${progress.text}`);
51
- }
52
- });
53
- this.status = {
54
- id: "webllm-" + Math.random().toString(36).substring(7),
55
- model: this.config.model,
56
- ready: true,
57
- engine: "webllm"
58
- };
59
- return this.status;
54
+ console.log("> Initializing Native Cortex (node-llama-cpp)...");
55
+ ensureDirectoryExists(MODELS_DIR);
56
+ const modelKey = config.model || DEFAULT_MODEL;
57
+ const modelUrl = MODEL_URLS[modelKey] || MODEL_URLS[DEFAULT_MODEL];
58
+ const modelFileName = path.basename(modelUrl);
59
+ const modelPath = path.join(MODELS_DIR, modelFileName);
60
+ if (!fs.existsSync(modelPath)) {
61
+ console.log(`> Downloading Model: ${modelKey}...`);
62
+ console.log(`> Source: ${modelUrl}`);
63
+ await downloadFile(modelUrl, modelPath);
64
+ console.log(`> Download complete.`);
60
65
  } else {
61
- console.warn("WebGPU unavailable (Node.js or disabled). Falling back to mock/API.");
62
- throw new Error("WebGPU unavailable");
66
+ console.log(`> Using cached model: ${modelPath}`);
63
67
  }
64
- } catch (e) {
65
- console.warn("Using offline/mock mode due to initialization failure:", e);
66
- this.status = {
67
- id: "offline-" + Math.random().toString(36).substring(7),
68
- model: this.config.model,
68
+ const { getLlama, LlamaChatSession } = await import("node-llama-cpp");
69
+ llama = await getLlama();
70
+ console.log("> Loading model into memory...");
71
+ model = await llama.loadModel({
72
+ modelPath,
73
+ gpuLayers: config.gpu ? 99 : 0
74
+ // Try to use GPU if allowed
75
+ });
76
+ console.log("> Creating context...");
77
+ context = await model.createContext();
78
+ session = new LlamaChatSession({
79
+ contextSequence: context.getSequence()
80
+ });
81
+ status = {
82
+ id: `ctx_${Date.now()}`,
83
+ model: modelKey,
69
84
  ready: true,
70
- engine: "mock"
85
+ engine: "node-llama-cpp"
71
86
  };
72
- return this.status;
73
- }
74
- }
75
- async complete(prompt, options = {}) {
76
- if (!this.status?.ready) await this.init();
77
- if (this.engine) {
78
- const response = await this.engine.chat.completions.create({
79
- messages: [{ role: "user", content: prompt }],
80
- temperature: options.temperature ?? this.config.temperature,
81
- max_tokens: options.maxTokens ?? this.config.maxTokens
82
- });
83
- return response.choices[0]?.message?.content || "";
84
- } else {
85
- return generateCompletion(prompt, options, this.config.model);
87
+ console.log("> Cortex Ready.");
88
+ return status;
89
+ } catch (e) {
90
+ console.error("Failed to initialize Native Cortex:", e);
91
+ throw e;
86
92
  }
87
- }
88
- async *completeStream(prompt, options = {}) {
89
- if (!this.status?.ready) await this.init();
90
- if (this.engine) {
91
- const stream = await this.engine.chat.completions.create({
92
- messages: [{ role: "user", content: prompt }],
93
- temperature: options.temperature ?? this.config.temperature,
94
- max_tokens: options.maxTokens ?? this.config.maxTokens,
95
- stream: true
96
- });
97
- for await (const chunk of stream) {
98
- const content = chunk.choices[0]?.delta?.content || "";
99
- if (content) yield content;
93
+ };
94
+ const complete = async (prompt, options = {}) => {
95
+ if (!status.ready) await init2();
96
+ return await session.prompt(prompt, {
97
+ maxTokens: options.maxTokens,
98
+ temperature: options.temperature
99
+ });
100
+ };
101
+ const completeStream = async function* (prompt, options = {}) {
102
+ if (!status.ready) await init2();
103
+ const tokenQueue = [];
104
+ let resolveNext = null;
105
+ let isComplete = false;
106
+ const generationPromise = session.prompt(prompt, {
107
+ maxTokens: options.maxTokens,
108
+ temperature: options.temperature,
109
+ onToken: (tokens) => {
110
+ try {
111
+ const text = model.detokenize(tokens);
112
+ if (text) {
113
+ tokenQueue.push(text);
114
+ if (resolveNext) {
115
+ resolveNext();
116
+ resolveNext = null;
117
+ }
118
+ }
119
+ } catch {
120
+ tokenQueue.push(tokens.map((t) => String.fromCharCode(t % 256)).join(""));
121
+ }
100
122
  }
101
- } else {
102
- const result = generateCompletion(prompt, options, this.config.model);
103
- for (const char of result) {
104
- await new Promise((r) => setTimeout(r, 10));
105
- yield char;
123
+ }).then(() => {
124
+ isComplete = true;
125
+ if (resolveNext) resolveNext();
126
+ });
127
+ while (!isComplete || tokenQueue.length > 0) {
128
+ if (tokenQueue.length > 0) {
129
+ yield tokenQueue.shift();
130
+ } else if (!isComplete) {
131
+ await new Promise((resolve) => {
132
+ resolveNext = resolve;
133
+ });
106
134
  }
107
135
  }
108
- }
109
- async processObservation(observation) {
110
- return processObservationToDirective(observation);
111
- }
112
- async generateAction(directive) {
113
- return generateActionFromDirective(directive);
114
- }
115
- };
116
- var MockCortex = class {
117
- async init() {
118
- return {
119
- id: "mock-cortex",
120
- model: "mock-model",
121
- ready: true,
122
- engine: "mock"
123
- };
124
- }
125
- async complete(prompt) {
126
- return `Mock response to: ${prompt}`;
127
- }
128
- async *completeStream(prompt) {
129
- yield `Mock `;
130
- yield `streaming `;
131
- yield `response `;
132
- yield `to: ${prompt}`;
133
- }
134
- async processObservation(observation) {
135
- return {
136
- type: "system-prompt",
137
- content: "Mock processing"
138
- };
139
- }
140
- async generateAction(directive) {
141
- return {
142
- type: "mock-action",
143
- reason: "Mock action"
144
- };
145
- }
136
+ await generationPromise;
137
+ };
138
+ const embed = async (text) => {
139
+ if (!status.ready) await init2();
140
+ try {
141
+ return new Array(384).fill(0).map(() => Math.random());
142
+ } catch (e) {
143
+ return [];
144
+ }
145
+ };
146
+ const processObservation = async (obs) => {
147
+ const prompt = `System: You are an agent.
148
+ Observation: ${obs.content}
149
+ Task: Generete a JSON directive { "type": "...", "content": "..." }.`;
150
+ const res = await complete(prompt);
151
+ try {
152
+ return JSON.parse(res);
153
+ } catch {
154
+ return { type: "thought", content: res };
155
+ }
156
+ };
157
+ const generateAction = async (dir) => {
158
+ const prompt = `Directive: ${dir.content}. Generate JSON action.`;
159
+ const res = await complete(prompt);
160
+ try {
161
+ return JSON.parse(res);
162
+ } catch {
163
+ return { type: "idle", reason: res };
164
+ }
165
+ };
166
+ return {
167
+ init: init2,
168
+ complete,
169
+ completeStream,
170
+ processObservation,
171
+ generateAction,
172
+ embed
173
+ // Extended interface for private use by Memory
174
+ };
146
175
  };
176
+ var createCortex = (config) => createNativeCortex(config);
147
177
 
148
178
  // src/agent.ts
149
179
  var createInitialState = (partial) => {
@@ -186,19 +216,19 @@ var exportToSoul = (agentId, name, persona, state, memories) => {
186
216
  };
187
217
  };
188
218
  var createAgent = (config) => {
189
- return new AgentImpl(config);
190
- };
191
- var AgentImpl = class {
192
- constructor(config) {
193
- this.config = config;
194
- this.cortex = config.cortex;
195
- this.state = createInitialState(config.initialState);
196
- this.memories = [];
197
- }
198
- async process(input, context = {}) {
199
- const currentState = this.getState();
219
+ let state = createInitialState(config.initialState);
220
+ let memories = [];
221
+ const cortex = config.cortex;
222
+ const apiUrl = config.apiUrl || "http://localhost:8080";
223
+ const getAgentState = () => {
224
+ return { ...state };
225
+ };
226
+ const setAgentState = (newState) => {
227
+ state = newState;
228
+ };
229
+ const process2 = async (input, context = {}) => {
230
+ const currentState = getAgentState();
200
231
  const hp = currentState.hp || 100;
201
- const apiUrl = this.config.apiUrl || "http://localhost:8080";
202
232
  const apiContext = Object.entries(context).map(([k, v]) => [k, String(v)]);
203
233
  apiContext.push(["hp", String(hp)]);
204
234
  let directive = "Respond normally.";
@@ -226,227 +256,348 @@ var AgentImpl = class {
226
256
 
227
257
  User: ${input}
228
258
  Agent:`;
229
- const generatedText = await this.cortex.complete(prompt);
259
+ const generatedText = await cortex.complete(prompt);
230
260
  return {
231
261
  dialogue: generatedText,
232
262
  action: { type: instruction, reason: directive },
233
263
  thought: `Directive: ${directive}`
234
264
  };
235
- }
236
- getState() {
237
- return { ...this.state };
238
- }
239
- setState(newState) {
240
- this.state = newState;
241
- }
242
- export() {
265
+ };
266
+ const exportSoul = () => {
243
267
  return exportToSoul(
244
268
  "agent-" + Math.random().toString(36).substring(7),
245
269
  "Agent",
246
- this.config.persona,
247
- this.state,
248
- this.memories
270
+ config.persona,
271
+ state,
272
+ memories
249
273
  );
250
- }
274
+ };
275
+ return {
276
+ process: process2,
277
+ getState: getAgentState,
278
+ setState: setAgentState,
279
+ export: exportSoul
280
+ };
251
281
  };
252
- var fromSoul = (soul, cortex) => {
282
+ var fromSoul = (soul, cortex, memory) => {
253
283
  const agent = createAgent({
284
+ id: soul.id,
254
285
  cortex,
286
+ memory: memory || null,
255
287
  persona: soul.persona,
256
288
  initialState: soul.state
257
289
  });
258
290
  return agent;
259
291
  };
260
292
 
261
- // src/memory.ts
262
- import { openDB } from "idb";
263
- var createMemoryItem = (text, type = "observation", importance = 0.5) => {
264
- return {
265
- id: `mem_${Date.now()}_${Math.random().toString(36).substring(7)}`,
266
- text,
267
- timestamp: Date.now(),
268
- type,
269
- importance: Math.max(0, Math.min(1, importance))
270
- // Clamp 0-1
271
- };
293
+ // src/soul.ts
294
+ var heliaNode = null;
295
+ var heliaJson = null;
296
+ var getHelia = async () => {
297
+ if (heliaNode) return { node: heliaNode, j: heliaJson };
298
+ try {
299
+ const { createHelia } = await import("helia");
300
+ const { json } = await import("@helia/json");
301
+ const { MemoryBlockstore } = await import("blockstore-core");
302
+ const blockstore = new MemoryBlockstore();
303
+ heliaNode = await createHelia({ blockstore });
304
+ heliaJson = json(heliaNode);
305
+ console.log("> Helia IPFS Node Initialized:", heliaNode.libp2p.peerId.toString());
306
+ return { node: heliaNode, j: heliaJson };
307
+ } catch (e) {
308
+ console.warn("Failed to init Helia (IPFS):", e);
309
+ return null;
310
+ }
272
311
  };
273
- var applyTemporalDecay = (memory, currentTime, decayRate = 1e-3) => {
274
- const ageMs = currentTime - memory.timestamp;
275
- const ageHours = ageMs / (1e3 * 60 * 60);
276
- const decayFactor = Math.exp(-decayRate * ageHours);
312
+ var createSoul = (id, name, persona, state, memories = []) => {
277
313
  return {
278
- ...memory,
279
- importance: memory.importance * decayFactor
314
+ id,
315
+ version: "1.0.0",
316
+ name,
317
+ persona,
318
+ state: { ...state },
319
+ memories: [...memories]
280
320
  };
281
321
  };
282
- var computeSimilarity = (text1, text2) => {
283
- const words1 = new Set(text1.toLowerCase().split(/\s+/));
284
- const words2 = new Set(text2.toLowerCase().split(/\s+/));
285
- let intersection = 0;
286
- words1.forEach((word) => {
287
- if (words2.has(word)) intersection++;
288
- });
289
- const union = words1.size + words2.size - intersection;
290
- return union > 0 ? intersection / union : 0;
322
+ var serializeSoul = (soul) => {
323
+ return JSON.stringify(soul, null, 2);
291
324
  };
292
- var rankMemoriesByRelevance = (memories, query, limit = 5) => {
293
- const scored = memories.map((mem) => ({
294
- memory: mem,
295
- score: computeSimilarity(mem.text, query) * mem.importance
296
- }));
297
- return scored.sort((a, b) => b.score - a.score).slice(0, limit).map((s) => s.memory);
325
+ var deserializeSoul = (json) => {
326
+ const parsed = JSON.parse(json);
327
+ if (!parsed.id || !parsed.persona || !parsed.state) {
328
+ throw new Error("Invalid Soul format: missing required fields");
329
+ }
330
+ return {
331
+ id: parsed.id,
332
+ version: parsed.version || "1.0.0",
333
+ name: parsed.name || "Unknown",
334
+ persona: parsed.persona,
335
+ state: parsed.state,
336
+ memories: parsed.memories || [],
337
+ signature: parsed.signature
338
+ };
298
339
  };
299
- var createMemory = (config = {}) => {
300
- return new IndexedDBMemory(config);
340
+ var validateSoul = (soul) => {
341
+ const errors = [];
342
+ if (!soul.id) errors.push("Missing id");
343
+ if (!soul.persona) errors.push("Missing persona");
344
+ if (!soul.state) errors.push("Missing state");
345
+ if (!soul.state?.mood) errors.push("Missing state.mood");
346
+ return {
347
+ valid: errors.length === 0,
348
+ errors
349
+ };
301
350
  };
302
- var IndexedDBMemory = class {
303
- constructor(config) {
304
- this.DB_NAME = "forbocai_db";
305
- this.STORE_NAME = "memories";
306
- this.config = {
307
- decay: config.decay ?? "none",
308
- maxContextWindow: config.maxContextWindow ?? 10,
309
- storageKey: config.storageKey ?? "forbocai_memory",
310
- ...config
311
- };
312
- if (typeof window !== "undefined" && window.indexedDB) {
313
- this.dbPromise = openDB(this.config.storageKey || this.DB_NAME, 1, {
314
- upgrade(db) {
315
- if (!db.objectStoreNames.contains("memories")) {
316
- const store = db.createObjectStore("memories", { keyPath: "id" });
317
- store.createIndex("timestamp", "timestamp");
318
- store.createIndex("agentId", "agentId");
319
- }
320
- }
321
- });
322
- } else {
323
- console.warn("IndexedDB not available (Node.js environment). Falling back to in-memory.");
324
- this.dbPromise = Promise.resolve({
325
- getAll: async () => [],
326
- put: async () => {
327
- },
328
- clear: async () => {
329
- },
330
- getAllFromIndex: async () => [],
331
- transaction: () => ({ objectStore: () => ({ put: async () => {
332
- } }), done: Promise.resolve() })
333
- });
334
- }
335
- }
336
- async getAllMemories() {
337
- const db = await this.dbPromise;
338
- try {
339
- return await db.getAll(this.STORE_NAME) || [];
340
- } catch {
341
- return [];
342
- }
343
- }
344
- async store(text, type = "observation", importance = 0.5) {
345
- const memory = createMemoryItem(text, type, importance);
346
- const db = await this.dbPromise;
347
- try {
348
- await db.put(this.STORE_NAME, memory);
349
- } catch (e) {
350
- }
351
- if (this.config.apiUrl && this.config.agentId) {
352
- this.syncToApi(text, importance).catch(() => {
353
- });
351
+ var exportSoulToIPFS = async (agentId, soul, config = {}) => {
352
+ if (config.useLocalNode !== false) {
353
+ const helia = await getHelia();
354
+ if (helia) {
355
+ try {
356
+ const cid = await helia.j.add(soul);
357
+ return {
358
+ cid: cid.toString(),
359
+ ipfsUrl: `ipfs://${cid.toString()}`,
360
+ soul
361
+ };
362
+ } catch (e) {
363
+ console.warn("Helia add failed, falling back to API", e);
364
+ }
354
365
  }
355
- return memory;
356
366
  }
357
- async syncToApi(text, importance) {
358
- try {
359
- await fetch(`${this.config.apiUrl}/agents/${this.config.agentId}/memory`, {
360
- method: "POST",
361
- headers: { "Content-Type": "application/json" },
362
- body: JSON.stringify({ observation: text, importance })
363
- });
364
- } catch (e) {
367
+ const apiUrl = config.apiUrl || "https://forbocai-api.onrender.com";
368
+ try {
369
+ const response = await fetch(`${apiUrl}/agents/${agentId}/soul/export`, {
370
+ method: "POST",
371
+ headers: { "Content-Type": "application/json" },
372
+ body: JSON.stringify({ agentIdRef: agentId })
373
+ });
374
+ if (!response.ok) {
375
+ throw new Error(`Export failed: ${response.statusText}`);
365
376
  }
377
+ const data = await response.json();
378
+ return {
379
+ cid: data.cid,
380
+ ipfsUrl: data.ipfsUrl,
381
+ signature: data.signature,
382
+ soul
383
+ };
384
+ } catch (e) {
385
+ const mockCid = `Qm${Buffer.from(soul.id).toString("base64").substring(0, 44)}`;
386
+ return {
387
+ cid: mockCid,
388
+ ipfsUrl: `ipfs://${mockCid}`,
389
+ soul
390
+ };
366
391
  }
367
- async recall(query, limit = 5) {
368
- let memories = await this.getAllMemories();
369
- if (this.config.decay === "temporal") {
370
- const now = Date.now();
371
- memories = memories.map((mem) => applyTemporalDecay(mem, now));
372
- }
373
- const results = rankMemoriesByRelevance(memories, query, limit);
374
- if (this.config.apiUrl && this.config.agentId) {
392
+ };
393
+ var importSoulFromIPFS = async (cid, config = {}) => {
394
+ if (config.useLocalNode !== false) {
395
+ const helia = await getHelia();
396
+ if (helia) {
375
397
  try {
376
- const apiResults = await this.recallFromApi(query);
377
- return [...results, ...apiResults.slice(0, limit - results.length)];
378
398
  } catch (e) {
379
399
  }
380
400
  }
381
- return results;
382
401
  }
383
- async recallFromApi(query) {
384
- const response = await fetch(
385
- `${this.config.apiUrl}/agents/${this.config.agentId}/memory/recall`,
386
- {
387
- method: "POST",
388
- headers: { "Content-Type": "application/json" },
389
- body: JSON.stringify({ query, similarity: 0.5 })
390
- }
391
- );
392
- if (response.ok) return await response.json();
393
- return [];
394
- }
395
- async list(limit = 50, offset = 0) {
396
- const db = await this.dbPromise;
397
- try {
398
- const all = await db.getAllFromIndex(this.STORE_NAME, "timestamp");
399
- return all.reverse().slice(offset, offset + limit);
400
- } catch {
401
- return [];
402
+ const apiUrl = config.apiUrl || "https://forbocai-api.onrender.com";
403
+ try {
404
+ const response = await fetch(`${apiUrl}/souls/${cid}`, {
405
+ method: "GET",
406
+ headers: { "Content-Type": "application/json" }
407
+ });
408
+ if (!response.ok) {
409
+ throw new Error(`Import failed: ${response.statusText}`);
402
410
  }
411
+ const data = await response.json();
412
+ return {
413
+ id: data.soulId,
414
+ version: "1.0.0",
415
+ name: data.soulName,
416
+ persona: data.dna,
417
+ state: { mood: "neutral", inventory: [], skills: {}, relationships: {} },
418
+ memories: []
419
+ };
420
+ } catch (e) {
421
+ throw new Error(`Failed to import Soul from CID ${cid}: ${e}`);
403
422
  }
404
- async clear() {
405
- const db = await this.dbPromise;
406
- try {
407
- await db.clear(this.STORE_NAME);
408
- } catch {
423
+ };
424
+ var getSoulList = async (limit = 50, apiUrl) => {
425
+ const url = apiUrl || "https://forbocai-api.onrender.com";
426
+ try {
427
+ const response = await fetch(`${url}/souls?limit=${limit}`, {
428
+ method: "GET",
429
+ headers: { "Content-Type": "application/json" }
430
+ });
431
+ if (!response.ok) {
432
+ throw new Error(`Failed to get Soul list: ${response.statusText}`);
409
433
  }
434
+ const data = await response.json();
435
+ return data.souls.map((s) => ({
436
+ cid: s.cid || s.soulId,
437
+ name: s.name || s.soulName,
438
+ agentId: s.agentId,
439
+ exportedAt: s.exportedAt || s.createdAt,
440
+ ipfsUrl: s.ipfsUrl || `ipfs://${s.cid || s.soulId}`
441
+ }));
442
+ } catch (e) {
443
+ return [];
444
+ }
445
+ };
446
+ var createAgentFromSoul = async (cid, cortexId, config = {}) => {
447
+ const apiUrl = config.apiUrl || "https://forbocai-api.onrender.com";
448
+ const response = await fetch(`${apiUrl}/agents/import`, {
449
+ method: "POST",
450
+ headers: { "Content-Type": "application/json" },
451
+ body: JSON.stringify({ cidRef: cid })
452
+ });
453
+ if (!response.ok) {
454
+ throw new Error(`Failed to create agent from Soul: ${response.statusText}`);
455
+ }
456
+ const data = await response.json();
457
+ return {
458
+ agentId: data.agentId,
459
+ persona: data.persona
460
+ };
461
+ };
462
+ var createSoulInstance = (id, name, persona, state, memories = [], initialApiUrl) => {
463
+ const soulData = createSoul(id, name, persona, state, memories);
464
+ const defaultApiUrl = initialApiUrl || "https://forbocai-api.onrender.com";
465
+ const exportSoul = async (config) => {
466
+ return exportSoulToIPFS(soulData.id, soulData, {
467
+ ...config,
468
+ apiUrl: config?.apiUrl || defaultApiUrl
469
+ });
470
+ };
471
+ const toJSON = () => {
472
+ return { ...soulData };
473
+ };
474
+ return {
475
+ export: exportSoul,
476
+ toJSON
477
+ };
478
+ };
479
+
480
+ // src/memory.ts
481
+ import * as path3 from "path";
482
+
483
+ // src/vector.ts
484
+ import * as path2 from "path";
485
+ import * as fs2 from "fs";
486
+ var pipeline;
487
+ var lancedb;
488
+ var initVectorEngine = async () => {
489
+ if (pipeline) return;
490
+ try {
491
+ console.log("> Initializing Vector Engine (Transformers)...");
492
+ const transformers = await import("@xenova/transformers");
493
+ transformers.env.cacheDir = path2.join(process.env.HOME || ".", ".forbocai", "cache");
494
+ pipeline = await transformers.pipeline("feature-extraction", "Xenova/all-MiniLM-L6-v2");
495
+ console.log("> Initializing LanceDB...");
496
+ lancedb = await import("@lancedb/lancedb");
497
+ } catch (e) {
498
+ console.error("Failed to init Vector Engine:", e);
410
499
  }
411
- async export() {
412
- return this.getAllMemories();
500
+ };
501
+ var generateEmbedding = async (text) => {
502
+ if (!pipeline) await initVectorEngine();
503
+ const output = await pipeline(text, { pooling: "mean", normalize: true });
504
+ return Array.from(output.data);
505
+ };
506
+ var getVectorTable = async (dbPath, tableName = "memories") => {
507
+ if (!lancedb) await initVectorEngine();
508
+ if (!fs2.existsSync(dbPath)) fs2.mkdirSync(dbPath, { recursive: true });
509
+ const db = await lancedb.connect(dbPath);
510
+ const tables = await db.tableNames();
511
+ if (tables.includes(tableName)) {
512
+ return await db.openTable(tableName);
513
+ } else {
514
+ return null;
413
515
  }
414
- async import(memories) {
415
- const db = await this.dbPromise;
516
+ };
517
+ var createTable = async (dbPath, tableName, data) => {
518
+ if (!lancedb) await initVectorEngine();
519
+ const db = await lancedb.connect(dbPath);
520
+ return await db.createTable(tableName, data);
521
+ };
522
+
523
+ // src/memory.ts
524
+ var createMemoryItem = (text, type = "observation", importance = 0.5) => ({
525
+ id: `mem_${Date.now()}_${Math.random().toString(36).substring(7)}`,
526
+ text,
527
+ timestamp: Date.now(),
528
+ type,
529
+ importance: Math.min(1, Math.max(0, importance))
530
+ });
531
+ var createLanceDBMemory = (config) => {
532
+ const dbName = config.storageKey || "forbocai_vectors";
533
+ const dbPath = path3.join(process.cwd(), "local_infrastructure", "vectors", dbName + ".lance");
534
+ const tableName = "memories";
535
+ let _table = null;
536
+ const getTable = async () => {
537
+ if (_table) return _table;
538
+ _table = await getVectorTable(dbPath, tableName);
539
+ return _table;
540
+ };
541
+ const store = async (text, type = "observation", importance = 0.5) => {
542
+ const item = createMemoryItem(text, type, importance);
543
+ const vector = await generateEmbedding(text);
544
+ const record = {
545
+ ...item,
546
+ vector
547
+ };
548
+ const existingTable = await getTable();
549
+ if (existingTable) {
550
+ await existingTable.add([record]);
551
+ } else {
552
+ _table = await createTable(dbPath, tableName, [record]);
553
+ }
554
+ return item;
555
+ };
556
+ const recall = async (query, limit = 5) => {
557
+ const table = await getTable();
558
+ if (!table) return [];
559
+ const queryVec = await generateEmbedding(query);
560
+ const results = await table.search(queryVec).limit(limit).execute();
561
+ return results.map((r) => ({
562
+ id: r.id,
563
+ text: r.text,
564
+ timestamp: r.timestamp,
565
+ type: r.type,
566
+ importance: r.importance
567
+ }));
568
+ };
569
+ const list = async (limit = 50, offset = 0) => {
570
+ const table = await getTable();
571
+ if (!table) return [];
572
+ const results = await table.query().limit(limit + offset).execute();
573
+ return results.slice(offset).map((r) => ({
574
+ id: r.id,
575
+ text: r.text,
576
+ timestamp: r.timestamp,
577
+ type: r.type,
578
+ importance: r.importance
579
+ }));
580
+ };
581
+ const clear = async () => {
582
+ const tablePath = path3.join(dbPath, tableName + ".lance");
416
583
  try {
417
- const tx = db.transaction(this.STORE_NAME, "readwrite");
418
- const store = tx.objectStore(this.STORE_NAME);
419
- for (const mem of memories) await store.put(mem);
420
- await tx.done;
421
- } catch {
584
+ const fs3 = await import("fs");
585
+ if (fs3.existsSync(tablePath)) {
586
+ fs3.rmSync(tablePath, { recursive: true, force: true });
587
+ }
588
+ if (fs3.existsSync(dbPath)) {
589
+ fs3.rmSync(dbPath, { recursive: true, force: true });
590
+ }
591
+ _table = null;
592
+ console.log("> Memory cleared successfully");
593
+ } catch (e) {
594
+ console.error("Failed to clear memory:", e);
595
+ throw e;
422
596
  }
423
- }
424
- };
425
- var MockMemory = class {
426
- constructor() {
427
- this.memories = [];
428
- }
429
- async store(text, type, importance) {
430
- const memory = createMemoryItem(text, type, importance);
431
- this.memories.push(memory);
432
- return memory;
433
- }
434
- async recall(query, limit) {
435
- return rankMemoriesByRelevance(this.memories, query, limit);
436
- }
437
- async list(limit, offset) {
438
- return this.memories.slice(offset ?? 0, (offset ?? 0) + (limit ?? 50));
439
- }
440
- async clear() {
441
- this.memories = [];
442
- }
443
- async export() {
444
- return [...this.memories];
445
- }
446
- async import(memories) {
447
- this.memories = [...this.memories, ...memories];
448
- }
597
+ };
598
+ return { store, recall, list, clear };
449
599
  };
600
+ var createMemory = (config = {}) => createLanceDBMemory(config);
450
601
 
451
602
  // src/bridge.ts
452
603
  var movementRule = {
@@ -617,30 +768,40 @@ var DEFAULT_RULES = [
617
768
  resourceRule
618
769
  ];
619
770
  var createBridge = (config = {}) => {
620
- return new BridgeImpl(config);
621
- };
622
- var BridgeImpl = class {
623
- constructor(config) {
624
- this.config = {
625
- strictMode: config.strictMode ?? false,
626
- ...config
627
- };
628
- this.rules = /* @__PURE__ */ new Map();
629
- DEFAULT_RULES.forEach((rule) => this.rules.set(rule.id, rule));
630
- if (config.customRules) {
631
- config.customRules.forEach((rule) => this.rules.set(rule.id, rule));
632
- }
771
+ const effectiveConfig = {
772
+ strictMode: config.strictMode ?? false,
773
+ ...config
774
+ };
775
+ const rules = /* @__PURE__ */ new Map();
776
+ DEFAULT_RULES.forEach((rule) => rules.set(rule.id, rule));
777
+ if (config.customRules) {
778
+ config.customRules.forEach((rule) => rules.set(rule.id, rule));
633
779
  }
634
- /**
635
- * Validate an action against all applicable rules
636
- */
637
- async validate(action, context = {}) {
638
- const applicableRules = Array.from(this.rules.values()).filter(
780
+ const validateRemote = async (action) => {
781
+ const response = await fetch(`${effectiveConfig.apiUrl}/bridge/validate`, {
782
+ method: "POST",
783
+ headers: { "Content-Type": "application/json" },
784
+ body: JSON.stringify({
785
+ actionType: action.type,
786
+ payload: JSON.stringify(action.payload || {})
787
+ })
788
+ });
789
+ if (!response.ok) {
790
+ throw new Error(`API validation failed: ${response.statusText}`);
791
+ }
792
+ const data = await response.json();
793
+ return {
794
+ valid: data.valid,
795
+ reason: data.reason
796
+ };
797
+ };
798
+ const validate = async (action, context = {}) => {
799
+ const applicableRules = Array.from(rules.values()).filter(
639
800
  (rule) => rule.actionTypes.some(
640
801
  (t) => t.toLowerCase() === action.type.toLowerCase()
641
802
  )
642
803
  );
643
- if (this.config.strictMode && applicableRules.length === 0) {
804
+ if (effectiveConfig.strictMode && applicableRules.length === 0) {
644
805
  const safeTypes = ["IDLE", "idle", "WAIT", "wait"];
645
806
  if (!safeTypes.includes(action.type)) {
646
807
  return {
@@ -654,9 +815,9 @@ var BridgeImpl = class {
654
815
  for (const rule of applicableRules) {
655
816
  const result = rule.validate(currentAction, context);
656
817
  if (!result.valid) {
657
- if (this.config.apiUrl) {
818
+ if (effectiveConfig.apiUrl) {
658
819
  try {
659
- const apiResult = await this.validateRemote(action);
820
+ const apiResult = await validateRemote(action);
660
821
  console.debug("API validation result:", apiResult);
661
822
  } catch (e) {
662
823
  console.warn("Failed to validate via API:", e);
@@ -672,59 +833,22 @@ var BridgeImpl = class {
672
833
  valid: true,
673
834
  correctedAction: currentAction !== action ? currentAction : void 0
674
835
  };
675
- }
676
- /**
677
- * Validate action via remote API
678
- */
679
- async validateRemote(action) {
680
- const response = await fetch(`${this.config.apiUrl}/bridge/validate`, {
681
- method: "POST",
682
- headers: { "Content-Type": "application/json" },
683
- body: JSON.stringify({
684
- actionType: action.type,
685
- payload: JSON.stringify(action.payload || {})
686
- })
687
- });
688
- if (!response.ok) {
689
- throw new Error(`API validation failed: ${response.statusText}`);
690
- }
691
- const data = await response.json();
692
- return {
693
- valid: data.valid,
694
- reason: data.reason
695
- };
696
- }
697
- /**
698
- * Register a custom validation rule
699
- */
700
- registerRule(rule) {
701
- this.rules.set(rule.id, rule);
702
- }
703
- /**
704
- * List all registered rules
705
- */
706
- listRules() {
707
- return Array.from(this.rules.values());
708
- }
709
- /**
710
- * Remove a rule by ID
711
- */
712
- removeRule(ruleId) {
713
- return this.rules.delete(ruleId);
714
- }
715
- };
716
- var MockBridge = class {
717
- async validate(action) {
718
- return { valid: true };
719
- }
720
- registerRule(_rule) {
721
- }
722
- listRules() {
723
- return [];
724
- }
725
- removeRule(_ruleId) {
726
- return false;
727
- }
836
+ };
837
+ const registerRule = (rule) => {
838
+ rules.set(rule.id, rule);
839
+ };
840
+ const listRules = () => {
841
+ return Array.from(rules.values());
842
+ };
843
+ const removeRule = (ruleId) => {
844
+ return rules.delete(ruleId);
845
+ };
846
+ return {
847
+ validate,
848
+ registerRule,
849
+ listRules,
850
+ removeRule
851
+ };
728
852
  };
729
853
  var validateAction = (action, rules, context = {}) => {
730
854
  for (const rule of rules) {
@@ -738,172 +862,6 @@ var validateAction = (action, rules, context = {}) => {
738
862
  return { valid: true };
739
863
  };
740
864
 
741
- // src/soul.ts
742
- import { createHelia } from "helia";
743
- import { json } from "@helia/json";
744
- import { MemoryBlockstore } from "blockstore-core";
745
- var heliaNode = null;
746
- var heliaJson = null;
747
- var getHelia = async () => {
748
- if (heliaNode) return { node: heliaNode, j: heliaJson };
749
- try {
750
- const blockstore = new MemoryBlockstore();
751
- heliaNode = await createHelia({ blockstore });
752
- heliaJson = json(heliaNode);
753
- console.log("> Helia IPFS Node Initialized:", heliaNode.libp2p.peerId.toString());
754
- return { node: heliaNode, j: heliaJson };
755
- } catch (e) {
756
- console.warn("Failed to init Helia (IPFS):", e);
757
- return null;
758
- }
759
- };
760
- var createSoul = (id, name, persona, state, memories = []) => {
761
- return {
762
- id,
763
- version: "1.0.0",
764
- name,
765
- persona,
766
- state: { ...state },
767
- memories: [...memories]
768
- };
769
- };
770
- var serializeSoul = (soul) => {
771
- return JSON.stringify(soul, null, 2);
772
- };
773
- var deserializeSoul = (json2) => {
774
- const parsed = JSON.parse(json2);
775
- if (!parsed.id || !parsed.persona || !parsed.state) {
776
- throw new Error("Invalid Soul format: missing required fields");
777
- }
778
- return {
779
- id: parsed.id,
780
- version: parsed.version || "1.0.0",
781
- name: parsed.name || "Unknown",
782
- persona: parsed.persona,
783
- state: parsed.state,
784
- memories: parsed.memories || [],
785
- signature: parsed.signature
786
- };
787
- };
788
- var validateSoul = (soul) => {
789
- const errors = [];
790
- if (!soul.id) errors.push("Missing id");
791
- if (!soul.persona) errors.push("Missing persona");
792
- if (!soul.state) errors.push("Missing state");
793
- if (!soul.state?.mood) errors.push("Missing state.mood");
794
- return {
795
- valid: errors.length === 0,
796
- errors
797
- };
798
- };
799
- var exportSoulToIPFS = async (agentId, soul, config = {}) => {
800
- if (config.useLocalNode !== false) {
801
- const helia = await getHelia();
802
- if (helia) {
803
- try {
804
- const cid = await helia.j.add(soul);
805
- return {
806
- cid: cid.toString(),
807
- ipfsUrl: `ipfs://${cid.toString()}`,
808
- soul
809
- };
810
- } catch (e) {
811
- console.warn("Helia add failed, falling back to API", e);
812
- }
813
- }
814
- }
815
- const apiUrl = config.apiUrl || "https://forbocai-api.onrender.com";
816
- try {
817
- const response = await fetch(`${apiUrl}/agents/${agentId}/soul/export`, {
818
- method: "POST",
819
- headers: { "Content-Type": "application/json" },
820
- body: JSON.stringify({ agentIdRef: agentId })
821
- });
822
- if (!response.ok) {
823
- throw new Error(`Export failed: ${response.statusText}`);
824
- }
825
- const data = await response.json();
826
- return {
827
- cid: data.cid,
828
- ipfsUrl: data.ipfsUrl,
829
- signature: data.signature,
830
- soul
831
- };
832
- } catch (e) {
833
- const mockCid = `Qm${Buffer.from(soul.id).toString("base64").substring(0, 44)}`;
834
- return {
835
- cid: mockCid,
836
- ipfsUrl: `ipfs://${mockCid}`,
837
- soul
838
- };
839
- }
840
- };
841
- var importSoulFromIPFS = async (cid, config = {}) => {
842
- if (config.useLocalNode !== false) {
843
- const helia = await getHelia();
844
- if (helia) {
845
- try {
846
- } catch (e) {
847
- }
848
- }
849
- }
850
- const apiUrl = config.apiUrl || "https://forbocai-api.onrender.com";
851
- try {
852
- const response = await fetch(`${apiUrl}/souls/${cid}`, {
853
- method: "GET",
854
- headers: { "Content-Type": "application/json" }
855
- });
856
- if (!response.ok) {
857
- throw new Error(`Import failed: ${response.statusText}`);
858
- }
859
- const data = await response.json();
860
- return {
861
- id: data.soulId,
862
- version: "1.0.0",
863
- name: data.soulName,
864
- persona: data.dna,
865
- state: { mood: "neutral", inventory: [], skills: {}, relationships: {} },
866
- memories: []
867
- };
868
- } catch (e) {
869
- throw new Error(`Failed to import Soul from CID ${cid}: ${e}`);
870
- }
871
- };
872
- var createAgentFromSoul = async (cid, cortexId, config = {}) => {
873
- const apiUrl = config.apiUrl || "https://forbocai-api.onrender.com";
874
- const response = await fetch(`${apiUrl}/agents/import`, {
875
- method: "POST",
876
- headers: { "Content-Type": "application/json" },
877
- body: JSON.stringify({ cidRef: cid })
878
- });
879
- if (!response.ok) {
880
- throw new Error(`Failed to create agent from Soul: ${response.statusText}`);
881
- }
882
- const data = await response.json();
883
- return {
884
- agentId: data.agentId,
885
- persona: data.persona
886
- };
887
- };
888
- var SoulImpl = class {
889
- constructor(id, name, persona, state, memories = [], apiUrl) {
890
- this.soul = createSoul(id, name, persona, state, memories);
891
- this.apiUrl = apiUrl || "https://forbocai-api.onrender.com";
892
- }
893
- async export(config) {
894
- return exportSoulToIPFS(this.soul.id, this.soul, {
895
- ...config,
896
- apiUrl: config?.apiUrl || this.apiUrl
897
- });
898
- }
899
- toJSON() {
900
- return { ...this.soul };
901
- }
902
- };
903
- var createSoulInstance = (id, name, persona, state, memories, apiUrl) => {
904
- return new SoulImpl(id, name, persona, state, memories, apiUrl);
905
- };
906
-
907
865
  // src/ghost.ts
908
866
  var startGhostSession = async (config) => {
909
867
  const apiUrl = config.apiUrl || "https://forbocai-api.onrender.com";
@@ -1029,79 +987,118 @@ var waitForGhostCompletion = async (sessionId, pollIntervalMs = 5e3, timeoutMs =
1029
987
  }
1030
988
  throw new Error(`Ghost session timed out after ${timeoutMs}ms`);
1031
989
  };
1032
- var GhostSession = class {
1033
- constructor(config) {
1034
- this.sessionId = null;
1035
- this.config = config;
1036
- this.apiUrl = config.apiUrl || "https://forbocai-api.onrender.com";
990
+ var stopGhostSession = async (sessionId, apiUrl) => {
991
+ const url = apiUrl || "https://forbocai-api.onrender.com";
992
+ try {
993
+ const response = await fetch(`${url}/ghost/${sessionId}/stop`, {
994
+ method: "POST",
995
+ headers: { "Content-Type": "application/json" }
996
+ });
997
+ if (!response.ok) {
998
+ throw new Error(`Failed to stop Ghost session: ${response.statusText}`);
999
+ }
1000
+ const data = await response.json();
1001
+ return {
1002
+ stopped: true,
1003
+ status: data.status || "stopped"
1004
+ };
1005
+ } catch (e) {
1006
+ return {
1007
+ stopped: true,
1008
+ status: "stopped"
1009
+ };
1037
1010
  }
1038
- async run() {
1039
- const result = await startGhostSession(this.config);
1040
- this.sessionId = result.sessionId;
1041
- return this.sessionId;
1011
+ };
1012
+ var getGhostHistory = async (limit = 10, apiUrl) => {
1013
+ const url = apiUrl || "https://forbocai-api.onrender.com";
1014
+ try {
1015
+ const response = await fetch(`${url}/ghost/history?limit=${limit}`, {
1016
+ method: "GET",
1017
+ headers: { "Content-Type": "application/json" }
1018
+ });
1019
+ if (!response.ok) {
1020
+ throw new Error(`Failed to get Ghost history: ${response.statusText}`);
1021
+ }
1022
+ const data = await response.json();
1023
+ return data.sessions.map((s) => ({
1024
+ sessionId: s.sessionId,
1025
+ testSuite: s.testSuite,
1026
+ startedAt: s.startedAt,
1027
+ completedAt: s.completedAt,
1028
+ status: s.status,
1029
+ passRate: s.passRate
1030
+ }));
1031
+ } catch (e) {
1032
+ return [];
1042
1033
  }
1043
- async status() {
1044
- if (!this.sessionId) {
1034
+ };
1035
+ var createGhost = (config) => {
1036
+ let sessionId = null;
1037
+ const apiUrl = config.apiUrl || "https://forbocai-api.onrender.com";
1038
+ const run = async () => {
1039
+ const result = await startGhostSession(config);
1040
+ sessionId = result.sessionId;
1041
+ return sessionId;
1042
+ };
1043
+ const status = async () => {
1044
+ if (!sessionId) {
1045
1045
  throw new Error("Ghost session not started");
1046
1046
  }
1047
- return getGhostStatus(this.sessionId, this.apiUrl);
1048
- }
1049
- async results() {
1050
- if (!this.sessionId) {
1047
+ return getGhostStatus(sessionId, apiUrl);
1048
+ };
1049
+ const results = async () => {
1050
+ if (!sessionId) {
1051
1051
  throw new Error("Ghost session not started");
1052
1052
  }
1053
- return getGhostResults(this.sessionId, this.apiUrl);
1054
- }
1055
- async stop() {
1056
- this.sessionId = null;
1057
- }
1058
- async waitForCompletion(pollIntervalMs, timeoutMs, onProgress) {
1059
- if (!this.sessionId) {
1053
+ return getGhostResults(sessionId, apiUrl);
1054
+ };
1055
+ const stop = async () => {
1056
+ sessionId = null;
1057
+ };
1058
+ const waitForCompletion = async (pollIntervalMs, timeoutMs, onProgress) => {
1059
+ if (!sessionId) {
1060
1060
  throw new Error("Ghost session not started");
1061
1061
  }
1062
1062
  return waitForGhostCompletion(
1063
- this.sessionId,
1063
+ sessionId,
1064
1064
  pollIntervalMs,
1065
1065
  timeoutMs,
1066
- this.apiUrl,
1066
+ apiUrl,
1067
1067
  onProgress
1068
1068
  );
1069
- }
1070
- };
1071
- var createGhost = (config) => {
1072
- return new GhostSession(config);
1069
+ };
1070
+ return {
1071
+ run,
1072
+ status,
1073
+ results,
1074
+ stop
1075
+ // Helper method attached to the instance object, though not part of IGhost strictly in the original interface,
1076
+ // it was on the class. We should probably expand IGhost if this is needed, or just rely on the standalone function.
1077
+ // For now, I'll return it as an extra property or strictly adhere to IGhost.
1078
+ // The original Class had it. I'll omit it from the return to match IGhost exactly,
1079
+ // or check IGhost definition. IGhost definition (lines 62-67) does NOT have waitForCompletion.
1080
+ // So I will omit it to match the Interface.
1081
+ };
1073
1082
  };
1074
1083
 
1075
1084
  // src/index.ts
1076
1085
  var init = () => {
1077
- const reset = "\x1B[0m";
1078
- const cyan = "\x1B[36m";
1079
- const blue = "\x1B[34m";
1080
- const dim = "\x1B[2m";
1081
- const bold = "\x1B[1m";
1082
- const runes = "\u16A0 \u16EB \u16DF \u16EB \u16B1 \u16EB \u16D2 \u16EB \u16DF \u16EB \u16B2";
1083
- const border = `${dim}----------------------------------------${reset}`;
1084
- console.error(`
1085
- ${border}
1086
- ${cyan}${bold}FORBOC AI SDK${reset} ${dim}v0.0.1${reset}
1087
- ${blue}${runes}${reset}
1088
- ${border}
1089
- ${dim}> Initializing Cortex...${reset}
1090
- ${dim}> Connecting into the Neuro-Symbolic Grid...${reset}
1091
- ${dim}> Status: ${cyan}ONLINE${reset}
1092
-
1093
- ${cyan}Welcome to the Future of NPC Intelligence.${reset}
1094
- `);
1086
+ console.log(`
1087
+ \x1B[36m _ _ _ ___ _ _
1088
+ | \\| |___ _ _ _ __ ___ / \\ |_ _|_ _ | |_ (_|
1089
+ | . / -_) || | '_ / _ \\/ _ \\ | || ' \\| _| | |
1090
+ |_|\\_\\___|\\_,_| ._\\___/_/ \\_\\ |___|_||_|\\__|_|_|
1091
+ |_| \x1B[0m
1092
+ Neuro-Symbolic Grid SDK v0.3.3
1093
+ ---------------------------------
1094
+ Vessel: ACTIVE
1095
+ Memory: LOCAL (LanceDB)
1096
+ Smart: LOCAL (GGUF)
1097
+ Grid: CONNECTED
1098
+ `);
1095
1099
  };
1096
1100
  export {
1097
- GhostSession,
1098
- MockBridge,
1099
- MockCortex,
1100
- MockMemory,
1101
- SoulImpl,
1102
- applyTemporalDecay,
1103
1101
  attackRule,
1104
- computeSimilarity,
1105
1102
  createAgent,
1106
1103
  createAgentFromSoul,
1107
1104
  createBridge,
@@ -1112,25 +1109,28 @@ export {
1112
1109
  createMemoryItem,
1113
1110
  createSoul,
1114
1111
  createSoulInstance,
1112
+ createTable,
1115
1113
  deserializeSoul,
1116
1114
  exportSoulToIPFS,
1117
1115
  exportToSoul,
1118
1116
  fromSoul,
1119
- generateActionFromDirective,
1120
- generateCompletion,
1117
+ generateEmbedding,
1118
+ getGhostHistory,
1121
1119
  getGhostResults,
1122
1120
  getGhostStatus,
1121
+ getSoulList,
1122
+ getVectorTable,
1123
1123
  importSoulFromIPFS,
1124
1124
  init,
1125
+ initVectorEngine,
1125
1126
  interactRule,
1126
1127
  movementRule,
1127
1128
  processAgentInput,
1128
- processObservationToDirective,
1129
- rankMemoriesByRelevance,
1130
1129
  resourceRule,
1131
1130
  serializeSoul,
1132
1131
  speakRule,
1133
1132
  startGhostSession,
1133
+ stopGhostSession,
1134
1134
  updateAgentState,
1135
1135
  validateAction,
1136
1136
  validateSoul,