@forbocai/core 0.5.2 → 0.5.6

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.js CHANGED
@@ -5,6 +5,9 @@ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
5
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
6
  var __getProtoOf = Object.getPrototypeOf;
7
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __esm = (fn, res) => function __init() {
9
+ return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
10
+ };
8
11
  var __export = (target, all) => {
9
12
  for (var name in all)
10
13
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -27,6 +30,236 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
27
30
  ));
28
31
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
32
 
33
+ // src/ans104.ts
34
+ var ans104_exports = {};
35
+ __export(ans104_exports, {
36
+ createArweaveDataItem: () => createArweaveDataItem
37
+ });
38
+ var import_base64url, import_buffer, import_crypto, import_pem, SIGNATURE_TYPE_ARWEAVE, SIGNATURE_LENGTH, OWNER_LENGTH, MAX_TAG_BYTES, stringToBuffer, concatBuffers, longToNByteArray, longTo8ByteArray, shortTo2ByteArray, AVSCTap, serializeTags, hash, deepHash, deepHashChunks, getSignatureData, signData, getOwner, getPem, createArweaveDataItem;
39
+ var init_ans104 = __esm({
40
+ "src/ans104.ts"() {
41
+ "use strict";
42
+ import_base64url = __toESM(require("base64url"));
43
+ import_buffer = require("buffer");
44
+ import_crypto = require("crypto");
45
+ import_pem = require("arweave/node/lib/crypto/pem");
46
+ SIGNATURE_TYPE_ARWEAVE = 1;
47
+ SIGNATURE_LENGTH = 512;
48
+ OWNER_LENGTH = 512;
49
+ MAX_TAG_BYTES = 4096;
50
+ stringToBuffer = (value) => import_buffer.Buffer.from(value);
51
+ concatBuffers = (buffers) => import_buffer.Buffer.concat(buffers);
52
+ longToNByteArray = (bytes, long) => {
53
+ const byteArray = new Uint8Array(bytes);
54
+ if (long < 0) throw new Error("Array is unsigned, cannot represent -ve numbers");
55
+ if (long > 2 ** (bytes * 8) - 1) throw new Error(`Number ${long} is too large for an array of ${bytes} bytes`);
56
+ for (let index = 0; index < byteArray.length; index++) {
57
+ const byte = long & 255;
58
+ byteArray[index] = byte;
59
+ long = (long - byte) / 256;
60
+ }
61
+ return byteArray;
62
+ };
63
+ longTo8ByteArray = (long) => longToNByteArray(8, long);
64
+ shortTo2ByteArray = (short) => longToNByteArray(2, short);
65
+ AVSCTap = class {
66
+ constructor(buf = import_buffer.Buffer.alloc(MAX_TAG_BYTES), pos = 0) {
67
+ this.buf = buf;
68
+ this.pos = pos;
69
+ }
70
+ writeTags(tags) {
71
+ if (!Array.isArray(tags)) {
72
+ throw new Error("input must be array");
73
+ }
74
+ const n = tags.length;
75
+ if (n) {
76
+ this.writeLong(n);
77
+ for (let i = 0; i < n; i++) {
78
+ const tag = tags[i];
79
+ if (typeof tag?.name !== "string" || typeof tag?.value !== "string") {
80
+ throw new Error(`Invalid tag format for ${tag}, expected {name:string, value: string}`);
81
+ }
82
+ this.writeString(tag.name);
83
+ this.writeString(tag.value);
84
+ }
85
+ }
86
+ this.writeLong(0);
87
+ }
88
+ toBuffer() {
89
+ const buffer = import_buffer.Buffer.alloc(this.pos);
90
+ if (this.pos > this.buf.length) throw new Error(`Too many tag bytes (${this.pos} > ${this.buf.length})`);
91
+ this.buf.copy(buffer, 0, 0, this.pos);
92
+ return buffer;
93
+ }
94
+ writeLong(n) {
95
+ const buf = this.buf;
96
+ let f, m;
97
+ if (n >= -1073741824 && n < 1073741824) {
98
+ m = n >= 0 ? n << 1 : ~n << 1 | 1;
99
+ do {
100
+ buf[this.pos] = m & 127;
101
+ m >>= 7;
102
+ } while (m && (buf[this.pos++] |= 128));
103
+ } else {
104
+ f = n >= 0 ? n * 2 : -n * 2 - 1;
105
+ do {
106
+ buf[this.pos] = f & 127;
107
+ f /= 128;
108
+ } while (f >= 1 && (buf[this.pos++] |= 128));
109
+ }
110
+ this.pos++;
111
+ this.buf = buf;
112
+ }
113
+ writeString(s) {
114
+ const len = import_buffer.Buffer.byteLength(s);
115
+ const buf = this.buf;
116
+ this.writeLong(len);
117
+ let pos = this.pos;
118
+ this.pos += len;
119
+ if (this.pos > buf.length) {
120
+ return;
121
+ }
122
+ if (len > 64) {
123
+ this.buf.write(s, this.pos - len, len, "utf8");
124
+ } else {
125
+ let i, l, c1, c2;
126
+ for (i = 0, l = len; i < l; i++) {
127
+ c1 = s.charCodeAt(i);
128
+ if (c1 < 128) {
129
+ buf[pos++] = c1;
130
+ } else if (c1 < 2048) {
131
+ buf[pos++] = c1 >> 6 | 192;
132
+ buf[pos++] = c1 & 63 | 128;
133
+ } else if ((c1 & 64512) === 55296 && ((c2 = s.charCodeAt(i + 1)) & 64512) === 56320) {
134
+ c1 = 65536 + ((c1 & 1023) << 10) + (c2 & 1023);
135
+ i++;
136
+ buf[pos++] = c1 >> 18 | 240;
137
+ buf[pos++] = c1 >> 12 & 63 | 128;
138
+ buf[pos++] = c1 >> 6 & 63 | 128;
139
+ buf[pos++] = c1 & 63 | 128;
140
+ } else {
141
+ buf[pos++] = c1 >> 12 | 224;
142
+ buf[pos++] = c1 >> 6 & 63 | 128;
143
+ buf[pos++] = c1 & 63 | 128;
144
+ }
145
+ }
146
+ }
147
+ this.buf = buf;
148
+ }
149
+ };
150
+ serializeTags = (tags) => {
151
+ if (tags?.length === 0) {
152
+ return import_buffer.Buffer.allocUnsafe(0);
153
+ }
154
+ const tap = new AVSCTap();
155
+ tap.writeTags(tags);
156
+ return tap.toBuffer();
157
+ };
158
+ hash = (data, algorithm) => {
159
+ const algo = algorithm === "SHA-256" ? "sha256" : "sha384";
160
+ return (0, import_crypto.createHash)(algo).update(data).digest();
161
+ };
162
+ deepHash = async (data) => {
163
+ if (Array.isArray(data)) {
164
+ const tag2 = concatBuffers([stringToBuffer("list"), stringToBuffer(data.length.toString())]);
165
+ return deepHashChunks(data, hash(tag2, "SHA-384"));
166
+ }
167
+ const _data = data;
168
+ const tag = concatBuffers([stringToBuffer("blob"), stringToBuffer(_data.byteLength.toString())]);
169
+ const taggedHash = concatBuffers([hash(tag, "SHA-384"), hash(_data, "SHA-384")]);
170
+ return hash(taggedHash, "SHA-384");
171
+ };
172
+ deepHashChunks = async (chunks, acc) => {
173
+ if (chunks.length < 1) {
174
+ return acc;
175
+ }
176
+ const hashPair = concatBuffers([acc, await deepHash(chunks[0])]);
177
+ const newAcc = hash(hashPair, "SHA-384");
178
+ return deepHashChunks(chunks.slice(1), newAcc);
179
+ };
180
+ getSignatureData = async (signatureType, rawOwner, rawTarget, rawAnchor, rawTags, rawData) => {
181
+ return deepHash([
182
+ stringToBuffer("dataitem"),
183
+ stringToBuffer("1"),
184
+ stringToBuffer(signatureType.toString()),
185
+ rawOwner,
186
+ rawTarget,
187
+ rawAnchor,
188
+ rawTags,
189
+ rawData
190
+ ]);
191
+ };
192
+ signData = async (pemKey, message) => {
193
+ return (0, import_crypto.createSign)("sha256").update(message).sign({
194
+ key: pemKey,
195
+ padding: import_crypto.constants.RSA_PKCS1_PSS_PADDING
196
+ });
197
+ };
198
+ getOwner = (jwk) => {
199
+ return import_base64url.default.toBuffer(jwk.n);
200
+ };
201
+ getPem = (jwk) => {
202
+ const pem = (0, import_pem.jwkTopem)(jwk);
203
+ return typeof pem === "string" ? pem : pem.toString();
204
+ };
205
+ createArweaveDataItem = async (data, jwk, opts) => {
206
+ const rawOwner = getOwner(jwk);
207
+ if (rawOwner.byteLength !== OWNER_LENGTH) {
208
+ throw new Error(`Owner must be ${OWNER_LENGTH} bytes, but was ${rawOwner.byteLength}`);
209
+ }
210
+ const rawTarget = opts?.target ? import_base64url.default.toBuffer(opts.target) : import_buffer.Buffer.alloc(0);
211
+ const rawAnchor = opts?.anchor ? import_buffer.Buffer.from(opts.anchor) : import_buffer.Buffer.alloc(0);
212
+ const rawTags = (opts?.tags?.length ?? 0) > 0 ? serializeTags(opts?.tags) : import_buffer.Buffer.alloc(0);
213
+ const rawData = typeof data === "string" ? import_buffer.Buffer.from(data) : import_buffer.Buffer.from(data);
214
+ const targetLength = 1 + (rawTarget?.byteLength ?? 0);
215
+ const anchorLength = 1 + (rawAnchor?.byteLength ?? 0);
216
+ const tagsLength = 16 + (rawTags ? rawTags.byteLength : 0);
217
+ const dataLength = rawData.byteLength;
218
+ const length = 2 + SIGNATURE_LENGTH + OWNER_LENGTH + targetLength + anchorLength + tagsLength + dataLength;
219
+ const bytes = import_buffer.Buffer.alloc(length);
220
+ bytes.set(shortTo2ByteArray(SIGNATURE_TYPE_ARWEAVE), 0);
221
+ bytes.set(new Uint8Array(SIGNATURE_LENGTH).fill(0), 2);
222
+ bytes.set(rawOwner, 2 + SIGNATURE_LENGTH);
223
+ const position = 2 + SIGNATURE_LENGTH + OWNER_LENGTH;
224
+ bytes[position] = rawTarget.length > 0 ? 1 : 0;
225
+ if (rawTarget.length > 0) {
226
+ if (rawTarget.byteLength !== 32) throw new Error("Target must be 32 bytes");
227
+ bytes.set(rawTarget, position + 1);
228
+ }
229
+ const anchorStart = position + targetLength;
230
+ let tagsStart = anchorStart + 1;
231
+ bytes[anchorStart] = rawAnchor.length > 0 ? 1 : 0;
232
+ if (rawAnchor.length > 0) {
233
+ tagsStart += rawAnchor.byteLength;
234
+ if (rawAnchor.byteLength !== 32) throw new Error("Anchor must be 32 bytes");
235
+ bytes.set(rawAnchor, anchorStart + 1);
236
+ }
237
+ bytes.set(longTo8ByteArray(opts?.tags?.length ?? 0), tagsStart);
238
+ bytes.set(longTo8ByteArray(rawTags?.byteLength ?? 0), tagsStart + 8);
239
+ if (rawTags.length > 0) {
240
+ bytes.set(rawTags, tagsStart + 16);
241
+ }
242
+ const dataStart = tagsStart + tagsLength;
243
+ bytes.set(rawData, dataStart);
244
+ const signatureData = await getSignatureData(
245
+ SIGNATURE_TYPE_ARWEAVE,
246
+ rawOwner,
247
+ rawTarget,
248
+ rawAnchor,
249
+ rawTags,
250
+ rawData
251
+ );
252
+ const signature = await signData(getPem(jwk), signatureData);
253
+ bytes.set(signature, 2);
254
+ const id = hash(signature, "SHA-256");
255
+ return {
256
+ id: import_base64url.default.encode(id),
257
+ raw: bytes
258
+ };
259
+ };
260
+ }
261
+ });
262
+
30
263
  // src/index.ts
31
264
  var index_exports = {};
32
265
  __export(index_exports, {
@@ -48,7 +281,6 @@ __export(index_exports, {
48
281
  getSoulList: () => getSoulList,
49
282
  importSoulFromArweave: () => importSoulFromArweave,
50
283
  presets: () => presets_exports,
51
- processAgentInput: () => processAgentInput,
52
284
  serializeSoul: () => serializeSoul,
53
285
  startGhostSession: () => startGhostSession,
54
286
  stopGhostSession: () => stopGhostSession,
@@ -70,17 +302,6 @@ var updateAgentState = (currentState, updates) => {
70
302
  ...updates
71
303
  };
72
304
  };
73
- var processAgentInput = (currentState, input, context = {}) => {
74
- const stateKeys = Object.keys(currentState);
75
- const stateSummary = stateKeys.length > 0 ? stateKeys.map((k) => `${k}=${JSON.stringify(currentState[k])}`).join(", ") : "empty";
76
- return {
77
- dialogue: `Processing: "${input}" (State: ${stateSummary})`,
78
- action: {
79
- type: "respond",
80
- reason: "Default processing"
81
- }
82
- };
83
- };
84
305
  var exportToSoul = (agentId, name, persona, state, memories) => {
85
306
  return {
86
307
  id: agentId,
@@ -93,9 +314,8 @@ var exportToSoul = (agentId, name, persona, state, memories) => {
93
314
  };
94
315
  var createAgent = (config) => {
95
316
  let state = createInitialState(config.initialState);
96
- let memories = [];
97
317
  const cortex = config.cortex;
98
- const apiUrl = config.apiUrl || "http://localhost:8080";
318
+ const apiUrl = config.apiUrl || "https://api.forboc.ai";
99
319
  const agentId = config.id || "agent-" + Math.random().toString(36).substring(7);
100
320
  const getAgentState = () => {
101
321
  return { ...state };
@@ -124,7 +344,8 @@ var createAgent = (config) => {
124
344
  try {
125
345
  const rawMemories = await config.memory.recall(
126
346
  directiveData.memoryRecall.query,
127
- directiveData.memoryRecall.limit
347
+ directiveData.memoryRecall.limit,
348
+ directiveData.memoryRecall.threshold
128
349
  );
129
350
  recalledMemories = rawMemories.map((m) => ({
130
351
  text: m.text,
@@ -132,7 +353,8 @@ var createAgent = (config) => {
132
353
  importance: m.importance,
133
354
  similarity: void 0
134
355
  }));
135
- } catch {
356
+ } catch (e) {
357
+ console.warn("Memory recall failed, continuing with empty memories:", e);
136
358
  }
137
359
  }
138
360
  const contextBody = {
@@ -176,8 +398,7 @@ var createAgent = (config) => {
176
398
  }
177
399
  if (config.memory && typeof config.memory.store === "function" && verdictData.memoryStore) {
178
400
  for (const instruction of verdictData.memoryStore) {
179
- config.memory.store(instruction.text, instruction.type, instruction.importance).catch(() => {
180
- });
401
+ config.memory.store(instruction.text, instruction.type, instruction.importance).catch((e) => console.warn("Memory store failed:", e));
181
402
  }
182
403
  }
183
404
  if (verdictData.stateDelta && Object.keys(verdictData.stateDelta).length > 0) {
@@ -193,11 +414,12 @@ var createAgent = (config) => {
193
414
  };
194
415
  };
195
416
  const exportSoul2 = async () => {
196
- let exportedMemories = [...memories];
417
+ let exportedMemories = [];
197
418
  if (config.memory && typeof config.memory.export === "function") {
198
419
  try {
199
420
  exportedMemories = await config.memory.export();
200
- } catch {
421
+ } catch (e) {
422
+ console.warn("Memory export failed, exporting with empty memories:", e);
201
423
  }
202
424
  }
203
425
  return exportToSoul(agentId, "Agent", config.persona, state, exportedMemories);
@@ -220,7 +442,8 @@ var fromSoul = async (soul, cortex, memory) => {
220
442
  if (memory && soul.memories && soul.memories.length > 0 && typeof memory.import === "function") {
221
443
  try {
222
444
  await memory.import(soul.memories);
223
- } catch {
445
+ } catch (e) {
446
+ console.warn("Memory hydration failed, continuing without memories:", e);
224
447
  }
225
448
  }
226
449
  return agent;
@@ -274,10 +497,6 @@ var createBridge = (config = {}) => {
274
497
  for (const rule of applicableRules) {
275
498
  const result = rule.validate(currentAction, context);
276
499
  if (!result.valid) {
277
- if (effectiveConfig.apiUrl) {
278
- const apiResult = await validateRemote(action);
279
- console.debug("API validation result:", apiResult);
280
- }
281
500
  return result;
282
501
  }
283
502
  if (result.correctedAction) {
@@ -291,8 +510,6 @@ var createBridge = (config = {}) => {
291
510
  };
292
511
  const registerRule = (rule) => {
293
512
  rules.set(rule.id, rule);
294
- if (effectiveConfig.apiUrl) {
295
- }
296
513
  };
297
514
  const listRules = () => {
298
515
  return Array.from(rules.values());
@@ -320,7 +537,6 @@ var validateAction = (action, rules, context = {}) => {
320
537
  };
321
538
 
322
539
  // src/soul.ts
323
- var import_sdk = __toESM(require("@irys/sdk"));
324
540
  var createSoul = (id, name, persona, state, memories = []) => {
325
541
  return {
326
542
  id,
@@ -350,63 +566,69 @@ var deserializeSoul = (json) => {
350
566
  };
351
567
  };
352
568
  var uploadToArweave = async (soul, config) => {
353
- if (!config.privateKey) {
354
- throw new Error("Private key required for direct Arweave upload");
569
+ const wallet = config.walletJwk || config.privateKey;
570
+ if (!wallet) {
571
+ throw new Error("Arweave wallet JWK required for direct upload");
355
572
  }
356
- const irys = new import_sdk.default({
357
- url: config.irysUrl || "https://node1.irys.xyz",
358
- token: config.token || "solana",
359
- key: config.privateKey
360
- });
361
- const dataToUpload = serializeSoul(soul);
573
+ let createArweaveDataItem2;
362
574
  try {
363
- const receipt = await irys.upload(dataToUpload);
364
- return {
365
- txId: receipt.id,
366
- url: `https://gateway.irys.xyz/${receipt.id}`,
367
- soul
368
- };
575
+ const imported = await Promise.resolve().then(() => (init_ans104(), ans104_exports));
576
+ createArweaveDataItem2 = imported.createArweaveDataItem;
369
577
  } catch (e) {
370
- throw new Error(`Failed to upload to Arweave: ${e}`);
578
+ throw new Error("Missing ANS-104 Arweave module. Rebuild the SDK to enable direct uploads.");
371
579
  }
372
- };
373
- var exportSoul = async (agentId, soul, config = {}) => {
374
- if (config.privateKey) {
375
- try {
376
- return await uploadToArweave(soul, config);
377
- } catch (e) {
378
- console.warn("Direct Arweave upload failed, falling back to API", e);
379
- }
580
+ const jwk = typeof wallet === "string" ? JSON.parse(wallet) : wallet;
581
+ const dataToUpload = serializeSoul(soul);
582
+ const tags = [
583
+ { name: "Content-Type", value: "application/json" },
584
+ { name: "App-Name", value: "ForbocAI" },
585
+ { name: "App-Version", value: "soul-1" }
586
+ ];
587
+ const dataItem = await createArweaveDataItem2(dataToUpload, jwk, { tags });
588
+ const rawData = dataItem.raw;
589
+ if (!rawData) {
590
+ throw new Error("Failed to build ANS-104 data item");
380
591
  }
381
- const apiUrl = config.apiUrl || "https://api.forboc.ai";
592
+ const bundlerUrl = config.bundlerUrl || "https://upload.ardrive.io/v1/tx";
593
+ const gatewayUrl = config.gatewayUrl || "https://arweave.net";
382
594
  try {
383
- const response = await fetch(`${apiUrl}/agents/${agentId}/soul/export`, {
595
+ const response = await fetch(bundlerUrl, {
384
596
  method: "POST",
385
- headers: { "Content-Type": "application/json" },
386
- body: JSON.stringify({ soul })
387
- // Sending full soul for server to sign/upload
597
+ headers: { "Content-Type": "application/octet-stream" },
598
+ body: rawData
388
599
  });
389
600
  if (!response.ok) {
390
- throw new Error(`Export failed: ${response.statusText}`);
601
+ const message = await response.text().catch(() => response.statusText);
602
+ throw new Error(message || response.statusText);
603
+ }
604
+ const responseText = await response.text();
605
+ let responseJson = null;
606
+ try {
607
+ responseJson = JSON.parse(responseText);
608
+ } catch {
609
+ responseJson = null;
610
+ }
611
+ const txId = responseJson?.id || responseJson?.dataItemId || responseJson?.txId || (typeof responseText === "string" && responseText.trim().length > 0 ? responseText.trim() : null) || dataItem.id;
612
+ if (!txId) {
613
+ throw new Error("Bundler response did not include a data item id");
391
614
  }
392
- const data = await response.json();
393
615
  return {
394
- txId: data.txId,
395
- url: data.url,
616
+ txId,
617
+ url: `${gatewayUrl}/${txId}`,
396
618
  soul
397
619
  };
398
620
  } catch (e) {
399
- console.warn("API export failed, returning mock Arweave TXID used for dev");
400
- const mockTxId = `mock_ar_${Date.now()}`;
401
- return {
402
- txId: mockTxId,
403
- url: `https://arweave.net/${mockTxId}`,
404
- soul
405
- };
621
+ throw new Error(`Failed to upload to Arweave: ${e}`);
622
+ }
623
+ };
624
+ var exportSoul = async (_agentId, soul, config = {}) => {
625
+ if (!config.walletJwk && !config.privateKey) {
626
+ throw new Error("walletJwk required for Arweave ANS-104 export");
406
627
  }
628
+ return uploadToArweave(soul, config);
407
629
  };
408
630
  var importSoulFromArweave = async (txId, config = {}) => {
409
- const gateway = config.gatewayUrl || "https://gateway.irys.xyz";
631
+ const gateway = config.gatewayUrl || "https://arweave.net";
410
632
  try {
411
633
  const response = await fetch(`${gateway}/${txId}`, {
412
634
  method: "GET",
@@ -430,25 +652,22 @@ var getSoulList = async (limit = 50, apiUrl) => {
430
652
  const response = await fetch(`${url}/souls?limit=${limit}`);
431
653
  if (!response.ok) throw new Error(response.statusText);
432
654
  const data = await response.json();
433
- return data.souls.map((s) => ({
434
- txId: s.txId,
435
- name: s.name,
436
- agentId: s.agentId,
437
- exportedAt: s.exportedAt,
438
- url: s.url || `https://gateway.irys.xyz/${s.txId}`
439
- }));
655
+ return data.souls.map((s) => {
656
+ const txId = s.txId || s.soulEntryTxId || s.cid;
657
+ const name = s.name || s.soulEntryName;
658
+ const agentId = s.agentId || s.soulEntryAgentId;
659
+ const exportedAt = s.exportedAt || s.soulEntryExportedAt;
660
+ const url2 = s.url || s.soulEntryArweaveUrl || `https://arweave.net/${txId}`;
661
+ return { txId, name, agentId, exportedAt, url: url2 };
662
+ });
440
663
  } catch (e) {
441
664
  return [];
442
665
  }
443
666
  };
444
- var createSoulInstance = (id, name, persona, state, memories = [], initialApiUrl) => {
667
+ var createSoulInstance = (id, name, persona, state, memories = []) => {
445
668
  const soulData = createSoul(id, name, persona, state, memories);
446
- const defaultApiUrl = initialApiUrl || "https://api.forboc.ai";
447
669
  const performExport = async (config) => {
448
- return exportSoul(soulData.id, soulData, {
449
- ...config,
450
- apiUrl: config?.apiUrl || defaultApiUrl
451
- });
670
+ return exportSoul(soulData.id, soulData, { ...config });
452
671
  };
453
672
  return {
454
673
  export: performExport,
@@ -660,6 +879,9 @@ var createGhost = (config) => {
660
879
  return getGhostResults(sessionId, apiUrl);
661
880
  };
662
881
  const stop = async () => {
882
+ if (sessionId) {
883
+ await stopGhostSession(sessionId, apiUrl);
884
+ }
663
885
  sessionId = null;
664
886
  };
665
887
  const waitForCompletion = async (pollIntervalMs, timeoutMs, onProgress) => {
@@ -684,7 +906,7 @@ var createGhost = (config) => {
684
906
  };
685
907
 
686
908
  // src/cortex-remote.ts
687
- var createRemoteCortex = (apiUrl) => {
909
+ var createRemoteCortex = (apiUrl, cortexId = "local") => {
688
910
  const init = async () => ({
689
911
  id: `remote_${Date.now()}`,
690
912
  model: "api-integrated",
@@ -692,7 +914,7 @@ var createRemoteCortex = (apiUrl) => {
692
914
  engine: "remote"
693
915
  });
694
916
  const complete = async (prompt, options) => {
695
- const response = await fetch(`${apiUrl}/cortex/complete`, {
917
+ const response = await fetch(`${apiUrl}/cortex/${cortexId}/complete`, {
696
918
  method: "POST",
697
919
  headers: { "Content-Type": "application/json" },
698
920
  body: JSON.stringify({ prompt, ...options })
@@ -915,7 +1137,7 @@ var socialRules = [speakRule, interactRule];
915
1137
  var puzzleRules = [movementRule, interactRule];
916
1138
 
917
1139
  // src/index.ts
918
- var SDK_VERSION = "0.5.2";
1140
+ var SDK_VERSION = "0.5.6";
919
1141
  // Annotate the CommonJS export names for ESM import in node:
920
1142
  0 && (module.exports = {
921
1143
  SDK_VERSION,
@@ -936,7 +1158,6 @@ var SDK_VERSION = "0.5.2";
936
1158
  getSoulList,
937
1159
  importSoulFromArweave,
938
1160
  presets,
939
- processAgentInput,
940
1161
  serializeSoul,
941
1162
  startGhostSession,
942
1163
  stopGhostSession,