@forbocai/core 0.5.4 → 0.5.7
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/ans104-GLQVFKBA.mjs +224 -0
- package/dist/chunk-7P6ASYW6.mjs +9 -0
- package/dist/index.d.mts +96 -70
- package/dist/index.d.ts +96 -70
- package/dist/index.js +383 -89
- package/dist/index.mjs +149 -93
- package/package.json +3 -2
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,10 +281,13 @@ __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,
|
|
287
|
+
streamFromCortex: () => streamFromCortex,
|
|
288
|
+
streamFromCortexWithDelay: () => streamFromCortexWithDelay,
|
|
289
|
+
streamToCallback: () => streamToCallback,
|
|
290
|
+
streamToString: () => streamToString,
|
|
55
291
|
updateAgentState: () => updateAgentState,
|
|
56
292
|
uploadToArweave: () => uploadToArweave,
|
|
57
293
|
validateAction: () => validateAction,
|
|
@@ -70,17 +306,6 @@ var updateAgentState = (currentState, updates) => {
|
|
|
70
306
|
...updates
|
|
71
307
|
};
|
|
72
308
|
};
|
|
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
309
|
var exportToSoul = (agentId, name, persona, state, memories) => {
|
|
85
310
|
return {
|
|
86
311
|
id: agentId,
|
|
@@ -93,10 +318,10 @@ var exportToSoul = (agentId, name, persona, state, memories) => {
|
|
|
93
318
|
};
|
|
94
319
|
var createAgent = (config) => {
|
|
95
320
|
let state = createInitialState(config.initialState);
|
|
96
|
-
let memories = [];
|
|
97
321
|
const cortex = config.cortex;
|
|
98
|
-
const apiUrl = config.apiUrl || "
|
|
322
|
+
const apiUrl = config.apiUrl || "https://api.forboc.ai";
|
|
99
323
|
const agentId = config.id || "agent-" + Math.random().toString(36).substring(7);
|
|
324
|
+
const authHeaders = config.apiKey ? { "Content-Type": "application/json", "Authorization": `Bearer ${config.apiKey}` } : { "Content-Type": "application/json" };
|
|
100
325
|
const getAgentState = () => {
|
|
101
326
|
return { ...state };
|
|
102
327
|
};
|
|
@@ -112,7 +337,7 @@ var createAgent = (config) => {
|
|
|
112
337
|
};
|
|
113
338
|
const dirRes = await fetch(`${apiUrl}/agents/${agentId}/directive`, {
|
|
114
339
|
method: "POST",
|
|
115
|
-
headers:
|
|
340
|
+
headers: authHeaders,
|
|
116
341
|
body: JSON.stringify(directiveBody)
|
|
117
342
|
});
|
|
118
343
|
if (!dirRes.ok) {
|
|
@@ -124,7 +349,8 @@ var createAgent = (config) => {
|
|
|
124
349
|
try {
|
|
125
350
|
const rawMemories = await config.memory.recall(
|
|
126
351
|
directiveData.memoryRecall.query,
|
|
127
|
-
directiveData.memoryRecall.limit
|
|
352
|
+
directiveData.memoryRecall.limit,
|
|
353
|
+
directiveData.memoryRecall.threshold
|
|
128
354
|
);
|
|
129
355
|
recalledMemories = rawMemories.map((m) => ({
|
|
130
356
|
text: m.text,
|
|
@@ -132,7 +358,8 @@ var createAgent = (config) => {
|
|
|
132
358
|
importance: m.importance,
|
|
133
359
|
similarity: void 0
|
|
134
360
|
}));
|
|
135
|
-
} catch {
|
|
361
|
+
} catch (e) {
|
|
362
|
+
console.warn("Memory recall failed, continuing with empty memories:", e);
|
|
136
363
|
}
|
|
137
364
|
}
|
|
138
365
|
const contextBody = {
|
|
@@ -142,7 +369,7 @@ var createAgent = (config) => {
|
|
|
142
369
|
};
|
|
143
370
|
const ctxRes = await fetch(`${apiUrl}/agents/${agentId}/context`, {
|
|
144
371
|
method: "POST",
|
|
145
|
-
headers:
|
|
372
|
+
headers: authHeaders,
|
|
146
373
|
body: JSON.stringify(contextBody)
|
|
147
374
|
});
|
|
148
375
|
if (!ctxRes.ok) {
|
|
@@ -161,7 +388,7 @@ var createAgent = (config) => {
|
|
|
161
388
|
};
|
|
162
389
|
const verRes = await fetch(`${apiUrl}/agents/${agentId}/verdict`, {
|
|
163
390
|
method: "POST",
|
|
164
|
-
headers:
|
|
391
|
+
headers: authHeaders,
|
|
165
392
|
body: JSON.stringify(verdictBody)
|
|
166
393
|
});
|
|
167
394
|
if (!verRes.ok) {
|
|
@@ -176,8 +403,7 @@ var createAgent = (config) => {
|
|
|
176
403
|
}
|
|
177
404
|
if (config.memory && typeof config.memory.store === "function" && verdictData.memoryStore) {
|
|
178
405
|
for (const instruction of verdictData.memoryStore) {
|
|
179
|
-
config.memory.store(instruction.text, instruction.type, instruction.importance).catch(() =>
|
|
180
|
-
});
|
|
406
|
+
config.memory.store(instruction.text, instruction.type, instruction.importance).catch((e) => console.warn("Memory store failed:", e));
|
|
181
407
|
}
|
|
182
408
|
}
|
|
183
409
|
if (verdictData.stateDelta && Object.keys(verdictData.stateDelta).length > 0) {
|
|
@@ -192,18 +418,43 @@ var createAgent = (config) => {
|
|
|
192
418
|
thought: generatedText
|
|
193
419
|
};
|
|
194
420
|
};
|
|
421
|
+
const speak = async (message, context = {}) => {
|
|
422
|
+
const currentState = getAgentState();
|
|
423
|
+
const speakBody = {
|
|
424
|
+
speakMessage: message,
|
|
425
|
+
speakContext: Object.keys(context).length > 0 ? context : void 0,
|
|
426
|
+
speakAgentState: currentState
|
|
427
|
+
};
|
|
428
|
+
const res = await fetch(`${apiUrl}/agents/${agentId}/speak`, {
|
|
429
|
+
method: "POST",
|
|
430
|
+
headers: authHeaders,
|
|
431
|
+
body: JSON.stringify(speakBody)
|
|
432
|
+
});
|
|
433
|
+
if (!res.ok) {
|
|
434
|
+
throw new Error(`API Speak Error: ${res.status}`);
|
|
435
|
+
}
|
|
436
|
+
const data = await res.json();
|
|
437
|
+
if (data.speakHistory) {
|
|
438
|
+
state = updateAgentState(state, { conversationHistory: data.speakHistory });
|
|
439
|
+
}
|
|
440
|
+
return data.speakReply;
|
|
441
|
+
};
|
|
442
|
+
const reply = speak;
|
|
195
443
|
const exportSoul2 = async () => {
|
|
196
|
-
let exportedMemories = [
|
|
444
|
+
let exportedMemories = [];
|
|
197
445
|
if (config.memory && typeof config.memory.export === "function") {
|
|
198
446
|
try {
|
|
199
447
|
exportedMemories = await config.memory.export();
|
|
200
|
-
} catch {
|
|
448
|
+
} catch (e) {
|
|
449
|
+
console.warn("Memory export failed, exporting with empty memories:", e);
|
|
201
450
|
}
|
|
202
451
|
}
|
|
203
452
|
return exportToSoul(agentId, "Agent", config.persona, state, exportedMemories);
|
|
204
453
|
};
|
|
205
454
|
return {
|
|
206
455
|
process,
|
|
456
|
+
speak,
|
|
457
|
+
reply,
|
|
207
458
|
getState: getAgentState,
|
|
208
459
|
setState: setAgentState,
|
|
209
460
|
export: exportSoul2
|
|
@@ -220,7 +471,8 @@ var fromSoul = async (soul, cortex, memory) => {
|
|
|
220
471
|
if (memory && soul.memories && soul.memories.length > 0 && typeof memory.import === "function") {
|
|
221
472
|
try {
|
|
222
473
|
await memory.import(soul.memories);
|
|
223
|
-
} catch {
|
|
474
|
+
} catch (e) {
|
|
475
|
+
console.warn("Memory hydration failed, continuing without memories:", e);
|
|
224
476
|
}
|
|
225
477
|
}
|
|
226
478
|
return agent;
|
|
@@ -274,10 +526,6 @@ var createBridge = (config = {}) => {
|
|
|
274
526
|
for (const rule of applicableRules) {
|
|
275
527
|
const result = rule.validate(currentAction, context);
|
|
276
528
|
if (!result.valid) {
|
|
277
|
-
if (effectiveConfig.apiUrl) {
|
|
278
|
-
const apiResult = await validateRemote(action);
|
|
279
|
-
console.debug("API validation result:", apiResult);
|
|
280
|
-
}
|
|
281
529
|
return result;
|
|
282
530
|
}
|
|
283
531
|
if (result.correctedAction) {
|
|
@@ -291,8 +539,6 @@ var createBridge = (config = {}) => {
|
|
|
291
539
|
};
|
|
292
540
|
const registerRule = (rule) => {
|
|
293
541
|
rules.set(rule.id, rule);
|
|
294
|
-
if (effectiveConfig.apiUrl) {
|
|
295
|
-
}
|
|
296
542
|
};
|
|
297
543
|
const listRules = () => {
|
|
298
544
|
return Array.from(rules.values());
|
|
@@ -320,7 +566,6 @@ var validateAction = (action, rules, context = {}) => {
|
|
|
320
566
|
};
|
|
321
567
|
|
|
322
568
|
// src/soul.ts
|
|
323
|
-
var import_sdk = __toESM(require("@irys/sdk"));
|
|
324
569
|
var createSoul = (id, name, persona, state, memories = []) => {
|
|
325
570
|
return {
|
|
326
571
|
id,
|
|
@@ -350,63 +595,69 @@ var deserializeSoul = (json) => {
|
|
|
350
595
|
};
|
|
351
596
|
};
|
|
352
597
|
var uploadToArweave = async (soul, config) => {
|
|
353
|
-
|
|
354
|
-
|
|
598
|
+
const wallet = config.walletJwk || config.privateKey;
|
|
599
|
+
if (!wallet) {
|
|
600
|
+
throw new Error("Arweave wallet JWK required for direct upload");
|
|
355
601
|
}
|
|
356
|
-
|
|
357
|
-
url: config.irysUrl || "https://node1.irys.xyz",
|
|
358
|
-
token: config.token || "solana",
|
|
359
|
-
key: config.privateKey
|
|
360
|
-
});
|
|
361
|
-
const dataToUpload = serializeSoul(soul);
|
|
602
|
+
let createArweaveDataItem2;
|
|
362
603
|
try {
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
txId: receipt.id,
|
|
366
|
-
url: `https://gateway.irys.xyz/${receipt.id}`,
|
|
367
|
-
soul
|
|
368
|
-
};
|
|
604
|
+
const imported = await Promise.resolve().then(() => (init_ans104(), ans104_exports));
|
|
605
|
+
createArweaveDataItem2 = imported.createArweaveDataItem;
|
|
369
606
|
} catch (e) {
|
|
370
|
-
throw new Error(
|
|
607
|
+
throw new Error("Missing ANS-104 Arweave module. Rebuild the SDK to enable direct uploads.");
|
|
371
608
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
609
|
+
const jwk = typeof wallet === "string" ? JSON.parse(wallet) : wallet;
|
|
610
|
+
const dataToUpload = serializeSoul(soul);
|
|
611
|
+
const tags = [
|
|
612
|
+
{ name: "Content-Type", value: "application/json" },
|
|
613
|
+
{ name: "App-Name", value: "ForbocAI" },
|
|
614
|
+
{ name: "App-Version", value: "soul-1" }
|
|
615
|
+
];
|
|
616
|
+
const dataItem = await createArweaveDataItem2(dataToUpload, jwk, { tags });
|
|
617
|
+
const rawData = dataItem.raw;
|
|
618
|
+
if (!rawData) {
|
|
619
|
+
throw new Error("Failed to build ANS-104 data item");
|
|
380
620
|
}
|
|
381
|
-
const
|
|
621
|
+
const bundlerUrl = config.bundlerUrl || "https://upload.ardrive.io/v1/tx";
|
|
622
|
+
const gatewayUrl = config.gatewayUrl || "https://arweave.net";
|
|
382
623
|
try {
|
|
383
|
-
const response = await fetch(
|
|
624
|
+
const response = await fetch(bundlerUrl, {
|
|
384
625
|
method: "POST",
|
|
385
|
-
headers: { "Content-Type": "application/
|
|
386
|
-
body:
|
|
387
|
-
// Sending full soul for server to sign/upload
|
|
626
|
+
headers: { "Content-Type": "application/octet-stream" },
|
|
627
|
+
body: rawData
|
|
388
628
|
});
|
|
389
629
|
if (!response.ok) {
|
|
390
|
-
|
|
630
|
+
const message = await response.text().catch(() => response.statusText);
|
|
631
|
+
throw new Error(message || response.statusText);
|
|
632
|
+
}
|
|
633
|
+
const responseText = await response.text();
|
|
634
|
+
let responseJson = null;
|
|
635
|
+
try {
|
|
636
|
+
responseJson = JSON.parse(responseText);
|
|
637
|
+
} catch {
|
|
638
|
+
responseJson = null;
|
|
639
|
+
}
|
|
640
|
+
const txId = responseJson?.id || responseJson?.dataItemId || responseJson?.txId || (typeof responseText === "string" && responseText.trim().length > 0 ? responseText.trim() : null) || dataItem.id;
|
|
641
|
+
if (!txId) {
|
|
642
|
+
throw new Error("Bundler response did not include a data item id");
|
|
391
643
|
}
|
|
392
|
-
const data = await response.json();
|
|
393
644
|
return {
|
|
394
|
-
txId
|
|
395
|
-
url:
|
|
645
|
+
txId,
|
|
646
|
+
url: `${gatewayUrl}/${txId}`,
|
|
396
647
|
soul
|
|
397
648
|
};
|
|
398
649
|
} catch (e) {
|
|
399
|
-
|
|
400
|
-
const mockTxId = `mock_ar_${Date.now()}`;
|
|
401
|
-
return {
|
|
402
|
-
txId: mockTxId,
|
|
403
|
-
url: `https://arweave.net/${mockTxId}`,
|
|
404
|
-
soul
|
|
405
|
-
};
|
|
650
|
+
throw new Error(`Failed to upload to Arweave: ${e}`);
|
|
406
651
|
}
|
|
407
652
|
};
|
|
653
|
+
var exportSoul = async (_agentId, soul, config = {}) => {
|
|
654
|
+
if (!config.walletJwk && !config.privateKey) {
|
|
655
|
+
throw new Error("walletJwk required for Arweave ANS-104 export");
|
|
656
|
+
}
|
|
657
|
+
return uploadToArweave(soul, config);
|
|
658
|
+
};
|
|
408
659
|
var importSoulFromArweave = async (txId, config = {}) => {
|
|
409
|
-
const gateway = config.gatewayUrl || "https://
|
|
660
|
+
const gateway = config.gatewayUrl || "https://arweave.net";
|
|
410
661
|
try {
|
|
411
662
|
const response = await fetch(`${gateway}/${txId}`, {
|
|
412
663
|
method: "GET",
|
|
@@ -430,25 +681,22 @@ var getSoulList = async (limit = 50, apiUrl) => {
|
|
|
430
681
|
const response = await fetch(`${url}/souls?limit=${limit}`);
|
|
431
682
|
if (!response.ok) throw new Error(response.statusText);
|
|
432
683
|
const data = await response.json();
|
|
433
|
-
return data.souls.map((s) =>
|
|
434
|
-
txId
|
|
435
|
-
name
|
|
436
|
-
agentId
|
|
437
|
-
exportedAt
|
|
438
|
-
|
|
439
|
-
|
|
684
|
+
return data.souls.map((s) => {
|
|
685
|
+
const txId = s.txId || s.soulEntryTxId || s.cid;
|
|
686
|
+
const name = s.name || s.soulEntryName;
|
|
687
|
+
const agentId = s.agentId || s.soulEntryAgentId;
|
|
688
|
+
const exportedAt = s.exportedAt || s.soulEntryExportedAt;
|
|
689
|
+
const url2 = s.url || s.soulEntryArweaveUrl || `https://arweave.net/${txId}`;
|
|
690
|
+
return { txId, name, agentId, exportedAt, url: url2 };
|
|
691
|
+
});
|
|
440
692
|
} catch (e) {
|
|
441
693
|
return [];
|
|
442
694
|
}
|
|
443
695
|
};
|
|
444
|
-
var createSoulInstance = (id, name, persona, state, memories = []
|
|
696
|
+
var createSoulInstance = (id, name, persona, state, memories = []) => {
|
|
445
697
|
const soulData = createSoul(id, name, persona, state, memories);
|
|
446
|
-
const defaultApiUrl = initialApiUrl || "https://api.forboc.ai";
|
|
447
698
|
const performExport = async (config) => {
|
|
448
|
-
return exportSoul(soulData.id, soulData, {
|
|
449
|
-
...config,
|
|
450
|
-
apiUrl: config?.apiUrl || defaultApiUrl
|
|
451
|
-
});
|
|
699
|
+
return exportSoul(soulData.id, soulData, { ...config });
|
|
452
700
|
};
|
|
453
701
|
return {
|
|
454
702
|
export: performExport,
|
|
@@ -660,6 +908,9 @@ var createGhost = (config) => {
|
|
|
660
908
|
return getGhostResults(sessionId, apiUrl);
|
|
661
909
|
};
|
|
662
910
|
const stop = async () => {
|
|
911
|
+
if (sessionId) {
|
|
912
|
+
await stopGhostSession(sessionId, apiUrl);
|
|
913
|
+
}
|
|
663
914
|
sessionId = null;
|
|
664
915
|
};
|
|
665
916
|
const waitForCompletion = async (pollIntervalMs, timeoutMs, onProgress) => {
|
|
@@ -684,7 +935,11 @@ var createGhost = (config) => {
|
|
|
684
935
|
};
|
|
685
936
|
|
|
686
937
|
// src/cortex-remote.ts
|
|
687
|
-
var createRemoteCortex = (apiUrl) => {
|
|
938
|
+
var createRemoteCortex = (apiUrl, cortexId = "local", apiKey) => {
|
|
939
|
+
const authHeaders = {
|
|
940
|
+
"Content-Type": "application/json",
|
|
941
|
+
...apiKey ? { "Authorization": `Bearer ${apiKey}` } : {}
|
|
942
|
+
};
|
|
688
943
|
const init = async () => ({
|
|
689
944
|
id: `remote_${Date.now()}`,
|
|
690
945
|
model: "api-integrated",
|
|
@@ -692,9 +947,9 @@ var createRemoteCortex = (apiUrl) => {
|
|
|
692
947
|
engine: "remote"
|
|
693
948
|
});
|
|
694
949
|
const complete = async (prompt, options) => {
|
|
695
|
-
const response = await fetch(`${apiUrl}/cortex/complete`, {
|
|
950
|
+
const response = await fetch(`${apiUrl}/cortex/${cortexId}/complete`, {
|
|
696
951
|
method: "POST",
|
|
697
|
-
headers:
|
|
952
|
+
headers: authHeaders,
|
|
698
953
|
body: JSON.stringify({ prompt, ...options })
|
|
699
954
|
});
|
|
700
955
|
if (!response.ok) throw new Error(`Remote Cortex failed: ${response.statusText}`);
|
|
@@ -708,6 +963,42 @@ var createRemoteCortex = (apiUrl) => {
|
|
|
708
963
|
return { init, complete, completeStream };
|
|
709
964
|
};
|
|
710
965
|
|
|
966
|
+
// src/stream.ts
|
|
967
|
+
async function streamToCallback(stream, onChunk) {
|
|
968
|
+
for await (const chunk of stream) {
|
|
969
|
+
onChunk(chunk);
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
async function streamToString(stream) {
|
|
973
|
+
let fullText = "";
|
|
974
|
+
for await (const chunk of stream) {
|
|
975
|
+
fullText += chunk;
|
|
976
|
+
}
|
|
977
|
+
return fullText;
|
|
978
|
+
}
|
|
979
|
+
async function streamFromCortex(cortex, prompt, onChunk, options) {
|
|
980
|
+
const stream = cortex.completeStream(prompt, options);
|
|
981
|
+
let fullText = "";
|
|
982
|
+
for await (const chunk of stream) {
|
|
983
|
+
fullText += chunk;
|
|
984
|
+
onChunk(chunk);
|
|
985
|
+
}
|
|
986
|
+
return fullText;
|
|
987
|
+
}
|
|
988
|
+
async function streamFromCortexWithDelay(cortex, prompt, onChunk, options) {
|
|
989
|
+
const { delayMs = 30, ...completionOptions } = options ?? {};
|
|
990
|
+
const stream = cortex.completeStream(prompt, completionOptions);
|
|
991
|
+
let fullText = "";
|
|
992
|
+
for await (const chunk of stream) {
|
|
993
|
+
fullText += chunk;
|
|
994
|
+
onChunk(chunk);
|
|
995
|
+
if (delayMs > 0) {
|
|
996
|
+
await new Promise((resolve) => setTimeout(resolve, delayMs));
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
return fullText;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
711
1002
|
// src/presets/index.ts
|
|
712
1003
|
var presets_exports = {};
|
|
713
1004
|
__export(presets_exports, {
|
|
@@ -915,7 +1206,7 @@ var socialRules = [speakRule, interactRule];
|
|
|
915
1206
|
var puzzleRules = [movementRule, interactRule];
|
|
916
1207
|
|
|
917
1208
|
// src/index.ts
|
|
918
|
-
var SDK_VERSION = "0.5.
|
|
1209
|
+
var SDK_VERSION = "0.5.7";
|
|
919
1210
|
// Annotate the CommonJS export names for ESM import in node:
|
|
920
1211
|
0 && (module.exports = {
|
|
921
1212
|
SDK_VERSION,
|
|
@@ -936,10 +1227,13 @@ var SDK_VERSION = "0.5.4";
|
|
|
936
1227
|
getSoulList,
|
|
937
1228
|
importSoulFromArweave,
|
|
938
1229
|
presets,
|
|
939
|
-
processAgentInput,
|
|
940
1230
|
serializeSoul,
|
|
941
1231
|
startGhostSession,
|
|
942
1232
|
stopGhostSession,
|
|
1233
|
+
streamFromCortex,
|
|
1234
|
+
streamFromCortexWithDelay,
|
|
1235
|
+
streamToCallback,
|
|
1236
|
+
streamToString,
|
|
943
1237
|
updateAgentState,
|
|
944
1238
|
uploadToArweave,
|
|
945
1239
|
validateAction,
|