forbocai 0.3.13 → 0.3.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +55 -42
- package/dist/cli.js +12 -9
- package/dist/cli.mjs +12 -9
- package/dist/index.d.mts +62 -27
- package/dist/index.d.ts +62 -27
- package/dist/index.js +289 -207
- package/dist/index.mjs +294 -202
- package/package.json +49 -45
- package/postinstall.js +4 -14
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
var __defProp = Object.defineProperty;
|
|
2
|
+
var __export = (target, all) => {
|
|
3
|
+
for (var name in all)
|
|
4
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
+
};
|
|
6
|
+
|
|
1
7
|
// src/cortex.ts
|
|
2
8
|
import * as fs from "fs";
|
|
3
9
|
import * as path from "path";
|
|
@@ -177,26 +183,18 @@ var createCortex = (config) => createNativeCortex(config);
|
|
|
177
183
|
|
|
178
184
|
// src/agent.ts
|
|
179
185
|
var createInitialState = (partial) => {
|
|
180
|
-
return {
|
|
181
|
-
inventory: partial?.inventory ?? [],
|
|
182
|
-
skills: partial?.skills ?? {},
|
|
183
|
-
relationships: partial?.relationships ?? {},
|
|
184
|
-
mood: partial?.mood ?? "neutral"
|
|
185
|
-
};
|
|
186
|
+
return { ...partial };
|
|
186
187
|
};
|
|
187
188
|
var updateAgentState = (currentState, updates) => {
|
|
188
189
|
return {
|
|
189
190
|
...currentState,
|
|
190
|
-
...updates
|
|
191
|
-
// Preserve nested immutability
|
|
192
|
-
inventory: updates.inventory !== void 0 ? [...updates.inventory] : [...currentState.inventory],
|
|
193
|
-
skills: { ...currentState.skills, ...updates.skills || {} },
|
|
194
|
-
relationships: { ...currentState.relationships, ...updates.relationships || {} }
|
|
191
|
+
...updates
|
|
195
192
|
};
|
|
196
193
|
};
|
|
197
194
|
var processAgentInput = (currentState, input, context = {}) => {
|
|
195
|
+
const mood = currentState.mood || "neutral";
|
|
198
196
|
return {
|
|
199
|
-
dialogue: `Processing: "${input}" (Mood: ${
|
|
197
|
+
dialogue: `Processing: "${input}" (Mood: ${mood})`,
|
|
200
198
|
action: {
|
|
201
199
|
type: "respond",
|
|
202
200
|
reason: "Default processing"
|
|
@@ -220,6 +218,7 @@ var createAgent = (config) => {
|
|
|
220
218
|
let memories = [];
|
|
221
219
|
const cortex = config.cortex;
|
|
222
220
|
const apiUrl = config.apiUrl || "http://localhost:8080";
|
|
221
|
+
const agentId = config.id || "agent-" + Math.random().toString(36).substring(7);
|
|
223
222
|
const getAgentState = () => {
|
|
224
223
|
return { ...state };
|
|
225
224
|
};
|
|
@@ -228,44 +227,97 @@ var createAgent = (config) => {
|
|
|
228
227
|
};
|
|
229
228
|
const process2 = async (input, context = {}) => {
|
|
230
229
|
const currentState = getAgentState();
|
|
231
|
-
const hp = currentState.hp || 100;
|
|
232
230
|
const apiContext = Object.entries(context).map(([k, v]) => [k, String(v)]);
|
|
233
|
-
apiContext.push(["hp", String(hp)]);
|
|
234
231
|
let directive = "Respond normally.";
|
|
235
232
|
let instruction = "IDLE";
|
|
233
|
+
let target;
|
|
234
|
+
const timestamp = Date.now();
|
|
235
|
+
apiContext.push(["timestamp", String(timestamp)]);
|
|
236
236
|
try {
|
|
237
|
-
const
|
|
237
|
+
const dirRes = await fetch(`${apiUrl}/agents/${agentId}/directive`, {
|
|
238
238
|
method: "POST",
|
|
239
|
-
headers: {
|
|
239
|
+
headers: {
|
|
240
|
+
"Content-Type": "application/json",
|
|
241
|
+
"X-Request-Timestamp": String(timestamp)
|
|
242
|
+
},
|
|
240
243
|
body: JSON.stringify({
|
|
241
|
-
|
|
242
|
-
|
|
244
|
+
dirContext: apiContext,
|
|
245
|
+
dirState: currentState,
|
|
246
|
+
// Full state dump
|
|
247
|
+
dirMemories: []
|
|
248
|
+
// TODO: Integrate memory lookup
|
|
243
249
|
})
|
|
244
250
|
});
|
|
245
|
-
if (
|
|
246
|
-
const data = await
|
|
247
|
-
directive = data.
|
|
248
|
-
instruction = data.
|
|
251
|
+
if (dirRes.ok) {
|
|
252
|
+
const data = await dirRes.json();
|
|
253
|
+
directive = data.dirReason;
|
|
254
|
+
instruction = data.dirInstruction;
|
|
255
|
+
target = data.dirTarget;
|
|
249
256
|
} else {
|
|
250
|
-
console.warn(
|
|
257
|
+
console.warn(`API Directive Error: ${dirRes.status} ${dirRes.statusText}`);
|
|
258
|
+
if (config.fallbackStrategy) {
|
|
259
|
+
const fallback = config.fallbackStrategy(currentState, context);
|
|
260
|
+
instruction = fallback.instruction;
|
|
261
|
+
directive = fallback.directive;
|
|
262
|
+
}
|
|
251
263
|
}
|
|
252
264
|
} catch (e) {
|
|
253
|
-
console.warn("API
|
|
265
|
+
console.warn("API Directive Failed (Network), falling back to local laws.", e);
|
|
266
|
+
if (config.fallbackStrategy) {
|
|
267
|
+
const fallback = config.fallbackStrategy(currentState, context);
|
|
268
|
+
instruction = fallback.instruction;
|
|
269
|
+
directive = fallback.directive;
|
|
270
|
+
}
|
|
254
271
|
}
|
|
255
|
-
const prompt =
|
|
256
|
-
|
|
272
|
+
const prompt = `System: Follow this directive strictly: ${instruction} (${directive}).
|
|
273
|
+
To Target: ${target || "None"}
|
|
257
274
|
User: ${input}
|
|
258
275
|
Agent:`;
|
|
259
276
|
const generatedText = await cortex.complete(prompt);
|
|
277
|
+
let signature = "unsigned_local_fallback";
|
|
278
|
+
let isValid = true;
|
|
279
|
+
const proposedAction = { type: instruction, reason: directive, target };
|
|
280
|
+
try {
|
|
281
|
+
const verRes = await fetch(`${apiUrl}/agents/${agentId}/verdict`, {
|
|
282
|
+
method: "POST",
|
|
283
|
+
headers: { "Content-Type": "application/json" },
|
|
284
|
+
body: JSON.stringify({
|
|
285
|
+
verDirective: {
|
|
286
|
+
dirInstruction: instruction,
|
|
287
|
+
dirTarget: target,
|
|
288
|
+
dirReason: directive
|
|
289
|
+
},
|
|
290
|
+
verAction: {
|
|
291
|
+
actionType: instruction,
|
|
292
|
+
actionReason: directive,
|
|
293
|
+
actionTarget: target
|
|
294
|
+
},
|
|
295
|
+
verThought: generatedText
|
|
296
|
+
})
|
|
297
|
+
});
|
|
298
|
+
if (verRes.ok) {
|
|
299
|
+
const vData = await verRes.json();
|
|
300
|
+
isValid = vData.verValid;
|
|
301
|
+
signature = vData.verSignature;
|
|
302
|
+
}
|
|
303
|
+
} catch (e) {
|
|
304
|
+
console.warn("API Verdict Failed.", e);
|
|
305
|
+
}
|
|
306
|
+
if (!isValid) {
|
|
307
|
+
return {
|
|
308
|
+
dialogue: "... [Action Blocked by Protocol]",
|
|
309
|
+
action: { type: "BLOCKED", reason: "API Validation Failed" }
|
|
310
|
+
};
|
|
311
|
+
}
|
|
260
312
|
return {
|
|
261
313
|
dialogue: generatedText,
|
|
262
|
-
action: {
|
|
263
|
-
thought: `Directive: ${directive}`
|
|
314
|
+
action: { ...proposedAction, signature },
|
|
315
|
+
thought: `Directive: ${directive} | Sig: ${signature}`
|
|
264
316
|
};
|
|
265
317
|
};
|
|
266
318
|
const exportSoul = () => {
|
|
267
319
|
return exportToSoul(
|
|
268
|
-
|
|
320
|
+
agentId,
|
|
269
321
|
"Agent",
|
|
270
322
|
config.persona,
|
|
271
323
|
state,
|
|
@@ -600,180 +652,12 @@ var createLanceDBMemory = (config) => {
|
|
|
600
652
|
var createMemory = (config = {}) => createLanceDBMemory(config);
|
|
601
653
|
|
|
602
654
|
// src/bridge.ts
|
|
603
|
-
var movementRule = {
|
|
604
|
-
id: "core.movement",
|
|
605
|
-
name: "Movement Validation",
|
|
606
|
-
description: "Ensures MOVE actions have valid x,y coordinates",
|
|
607
|
-
actionTypes: ["MOVE", "move"],
|
|
608
|
-
validate: (action, context) => {
|
|
609
|
-
const payload = action.payload || {};
|
|
610
|
-
const target = payload.target;
|
|
611
|
-
if (!target || typeof target.x !== "number" || typeof target.y !== "number") {
|
|
612
|
-
return {
|
|
613
|
-
valid: false,
|
|
614
|
-
reason: "MOVE action must have target with numeric x,y coordinates",
|
|
615
|
-
correctedAction: {
|
|
616
|
-
...action,
|
|
617
|
-
type: "IDLE",
|
|
618
|
-
reason: "Invalid MOVE target - defaulting to IDLE"
|
|
619
|
-
}
|
|
620
|
-
};
|
|
621
|
-
}
|
|
622
|
-
const world = context.worldState || {};
|
|
623
|
-
const maxX = world.maxX || Infinity;
|
|
624
|
-
const maxY = world.maxY || Infinity;
|
|
625
|
-
if (target.x < 0 || target.x > maxX || target.y < 0 || target.y > maxY) {
|
|
626
|
-
return {
|
|
627
|
-
valid: false,
|
|
628
|
-
reason: `MOVE target (${target.x}, ${target.y}) is out of bounds`,
|
|
629
|
-
correctedAction: {
|
|
630
|
-
...action,
|
|
631
|
-
payload: {
|
|
632
|
-
...payload,
|
|
633
|
-
target: {
|
|
634
|
-
x: Math.max(0, Math.min(maxX, target.x)),
|
|
635
|
-
y: Math.max(0, Math.min(maxY, target.y))
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
};
|
|
640
|
-
}
|
|
641
|
-
return { valid: true };
|
|
642
|
-
}
|
|
643
|
-
};
|
|
644
|
-
var attackRule = {
|
|
645
|
-
id: "core.attack",
|
|
646
|
-
name: "Attack Validation",
|
|
647
|
-
description: "Ensures ATTACK actions have valid targetId",
|
|
648
|
-
actionTypes: ["ATTACK", "attack"],
|
|
649
|
-
validate: (action, context) => {
|
|
650
|
-
if (!action.target && !action.payload?.targetId) {
|
|
651
|
-
return {
|
|
652
|
-
valid: false,
|
|
653
|
-
reason: "ATTACK action must have a target or targetId",
|
|
654
|
-
correctedAction: {
|
|
655
|
-
...action,
|
|
656
|
-
type: "IDLE",
|
|
657
|
-
reason: "Invalid ATTACK - no target specified"
|
|
658
|
-
}
|
|
659
|
-
};
|
|
660
|
-
}
|
|
661
|
-
const world = context.worldState || {};
|
|
662
|
-
const entities = world.entities || [];
|
|
663
|
-
const targetId = action.target || action.payload?.targetId;
|
|
664
|
-
if (entities.length > 0 && !entities.includes(targetId)) {
|
|
665
|
-
return {
|
|
666
|
-
valid: false,
|
|
667
|
-
reason: `ATTACK target '${targetId}' does not exist in world`,
|
|
668
|
-
correctedAction: {
|
|
669
|
-
...action,
|
|
670
|
-
type: "IDLE",
|
|
671
|
-
reason: "Target not found"
|
|
672
|
-
}
|
|
673
|
-
};
|
|
674
|
-
}
|
|
675
|
-
return { valid: true };
|
|
676
|
-
}
|
|
677
|
-
};
|
|
678
|
-
var interactRule = {
|
|
679
|
-
id: "core.interact",
|
|
680
|
-
name: "Interact Validation",
|
|
681
|
-
description: "Ensures INTERACT actions have valid objectId",
|
|
682
|
-
actionTypes: ["INTERACT", "interact"],
|
|
683
|
-
validate: (action, context) => {
|
|
684
|
-
if (!action.target && !action.payload?.objectId) {
|
|
685
|
-
return {
|
|
686
|
-
valid: false,
|
|
687
|
-
reason: "INTERACT action must have objectId",
|
|
688
|
-
correctedAction: {
|
|
689
|
-
...action,
|
|
690
|
-
type: "IDLE",
|
|
691
|
-
reason: "Invalid INTERACT - no object specified"
|
|
692
|
-
}
|
|
693
|
-
};
|
|
694
|
-
}
|
|
695
|
-
return { valid: true };
|
|
696
|
-
}
|
|
697
|
-
};
|
|
698
|
-
var speakRule = {
|
|
699
|
-
id: "core.speak",
|
|
700
|
-
name: "Speak Validation",
|
|
701
|
-
description: "Ensures SPEAK actions have non-empty text",
|
|
702
|
-
actionTypes: ["SPEAK", "speak"],
|
|
703
|
-
validate: (action, context) => {
|
|
704
|
-
const text = action.payload?.text;
|
|
705
|
-
if (!text || text.trim().length === 0) {
|
|
706
|
-
return {
|
|
707
|
-
valid: false,
|
|
708
|
-
reason: "SPEAK action must have non-empty text",
|
|
709
|
-
correctedAction: {
|
|
710
|
-
...action,
|
|
711
|
-
type: "IDLE",
|
|
712
|
-
reason: "Empty speech - defaulting to IDLE"
|
|
713
|
-
}
|
|
714
|
-
};
|
|
715
|
-
}
|
|
716
|
-
const maxLength = context.constraints?.maxSpeechLength || 1e3;
|
|
717
|
-
if (text.length > maxLength) {
|
|
718
|
-
return {
|
|
719
|
-
valid: true,
|
|
720
|
-
// Still valid, but truncated
|
|
721
|
-
reason: `Speech truncated to ${maxLength} characters`,
|
|
722
|
-
correctedAction: {
|
|
723
|
-
...action,
|
|
724
|
-
payload: {
|
|
725
|
-
...action.payload,
|
|
726
|
-
text: text.substring(0, maxLength)
|
|
727
|
-
}
|
|
728
|
-
}
|
|
729
|
-
};
|
|
730
|
-
}
|
|
731
|
-
return { valid: true };
|
|
732
|
-
}
|
|
733
|
-
};
|
|
734
|
-
var resourceRule = {
|
|
735
|
-
id: "core.resources",
|
|
736
|
-
name: "Resource Validation",
|
|
737
|
-
description: "Ensures agent has required resources for action",
|
|
738
|
-
actionTypes: ["ATTACK", "CAST", "USE_ITEM"],
|
|
739
|
-
validate: (action, context) => {
|
|
740
|
-
const agent = context.agentState || {};
|
|
741
|
-
const hp = agent.hp ?? 100;
|
|
742
|
-
const mana = agent.mana ?? 100;
|
|
743
|
-
if (hp <= 0) {
|
|
744
|
-
return {
|
|
745
|
-
valid: false,
|
|
746
|
-
reason: "Agent is dead and cannot perform actions",
|
|
747
|
-
correctedAction: { ...action, type: "IDLE", reason: "Agent dead" }
|
|
748
|
-
};
|
|
749
|
-
}
|
|
750
|
-
if (action.type === "CAST" || action.type === "cast") {
|
|
751
|
-
const manaCost = action.payload?.manaCost || 10;
|
|
752
|
-
if (mana < manaCost) {
|
|
753
|
-
return {
|
|
754
|
-
valid: false,
|
|
755
|
-
reason: `Insufficient mana: need ${manaCost}, have ${mana}`,
|
|
756
|
-
correctedAction: { ...action, type: "IDLE", reason: "Not enough mana" }
|
|
757
|
-
};
|
|
758
|
-
}
|
|
759
|
-
}
|
|
760
|
-
return { valid: true };
|
|
761
|
-
}
|
|
762
|
-
};
|
|
763
|
-
var DEFAULT_RULES = [
|
|
764
|
-
movementRule,
|
|
765
|
-
attackRule,
|
|
766
|
-
interactRule,
|
|
767
|
-
speakRule,
|
|
768
|
-
resourceRule
|
|
769
|
-
];
|
|
770
655
|
var createBridge = (config = {}) => {
|
|
771
656
|
const effectiveConfig = {
|
|
772
657
|
strictMode: config.strictMode ?? false,
|
|
773
658
|
...config
|
|
774
659
|
};
|
|
775
660
|
const rules = /* @__PURE__ */ new Map();
|
|
776
|
-
DEFAULT_RULES.forEach((rule) => rules.set(rule.id, rule));
|
|
777
661
|
if (config.customRules) {
|
|
778
662
|
config.customRules.forEach((rule) => rules.set(rule.id, rule));
|
|
779
663
|
}
|
|
@@ -1081,6 +965,218 @@ var createGhost = (config) => {
|
|
|
1081
965
|
};
|
|
1082
966
|
};
|
|
1083
967
|
|
|
968
|
+
// src/presets.ts
|
|
969
|
+
var presets_exports = {};
|
|
970
|
+
__export(presets_exports, {
|
|
971
|
+
RPG_MEMORY_TYPES: () => RPG_MEMORY_TYPES,
|
|
972
|
+
RPG_MOODS: () => RPG_MOODS,
|
|
973
|
+
attackRule: () => attackRule,
|
|
974
|
+
createRPGState: () => createRPGState,
|
|
975
|
+
interactRule: () => interactRule,
|
|
976
|
+
movementRule: () => movementRule,
|
|
977
|
+
puzzleRules: () => puzzleRules,
|
|
978
|
+
resourceRule: () => resourceRule,
|
|
979
|
+
rpgFallbackStrategy: () => rpgFallbackStrategy,
|
|
980
|
+
rpgRules: () => rpgRules,
|
|
981
|
+
socialRules: () => socialRules,
|
|
982
|
+
spatialRules: () => spatialRules,
|
|
983
|
+
speakRule: () => speakRule
|
|
984
|
+
});
|
|
985
|
+
var RPG_MOODS = {
|
|
986
|
+
hostile: "hostile",
|
|
987
|
+
suspicious: "suspicious",
|
|
988
|
+
neutral: "neutral",
|
|
989
|
+
friendly: "friendly",
|
|
990
|
+
loyal: "loyal"
|
|
991
|
+
};
|
|
992
|
+
var RPG_MEMORY_TYPES = {
|
|
993
|
+
observation: "observation",
|
|
994
|
+
experience: "experience",
|
|
995
|
+
knowledge: "knowledge",
|
|
996
|
+
emotion: "emotion"
|
|
997
|
+
};
|
|
998
|
+
var createRPGState = (partial) => {
|
|
999
|
+
return {
|
|
1000
|
+
inventory: partial?.inventory ?? [],
|
|
1001
|
+
hp: partial?.hp ?? 100,
|
|
1002
|
+
mana: partial?.mana ?? 100,
|
|
1003
|
+
skills: partial?.skills ?? {},
|
|
1004
|
+
relationships: partial?.relationships ?? {},
|
|
1005
|
+
mood: partial?.mood ?? "neutral",
|
|
1006
|
+
...partial
|
|
1007
|
+
};
|
|
1008
|
+
};
|
|
1009
|
+
var rpgFallbackStrategy = (state, context) => {
|
|
1010
|
+
const hp = state.hp || 100;
|
|
1011
|
+
if (hp < 20) {
|
|
1012
|
+
return { instruction: "FLEE", directive: "CRITICAL (Fallback): Low Health detected." };
|
|
1013
|
+
}
|
|
1014
|
+
return { instruction: "IDLE", directive: "Autonomous" };
|
|
1015
|
+
};
|
|
1016
|
+
var movementRule = {
|
|
1017
|
+
id: "core.movement",
|
|
1018
|
+
name: "Movement Validation",
|
|
1019
|
+
description: "Ensures MOVE actions have valid x,y coordinates",
|
|
1020
|
+
actionTypes: ["MOVE", "move"],
|
|
1021
|
+
validate: (action, context) => {
|
|
1022
|
+
const payload = action.payload || {};
|
|
1023
|
+
const target = payload.target;
|
|
1024
|
+
if (!target || typeof target.x !== "number" || typeof target.y !== "number") {
|
|
1025
|
+
return {
|
|
1026
|
+
valid: false,
|
|
1027
|
+
reason: "MOVE action must have target with numeric x,y coordinates",
|
|
1028
|
+
correctedAction: {
|
|
1029
|
+
...action,
|
|
1030
|
+
type: "IDLE",
|
|
1031
|
+
reason: "Invalid MOVE target - defaulting to IDLE"
|
|
1032
|
+
}
|
|
1033
|
+
};
|
|
1034
|
+
}
|
|
1035
|
+
const world = context.worldState || {};
|
|
1036
|
+
const maxX = world.maxX || Infinity;
|
|
1037
|
+
const maxY = world.maxY || Infinity;
|
|
1038
|
+
if (target.x < 0 || target.x > maxX || target.y < 0 || target.y > maxY) {
|
|
1039
|
+
return {
|
|
1040
|
+
valid: false,
|
|
1041
|
+
reason: `MOVE target (${target.x}, ${target.y}) is out of bounds`,
|
|
1042
|
+
correctedAction: {
|
|
1043
|
+
...action,
|
|
1044
|
+
payload: {
|
|
1045
|
+
...payload,
|
|
1046
|
+
target: {
|
|
1047
|
+
x: Math.max(0, Math.min(maxX, target.x)),
|
|
1048
|
+
y: Math.max(0, Math.min(maxY, target.y))
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
}
|
|
1052
|
+
};
|
|
1053
|
+
}
|
|
1054
|
+
return { valid: true };
|
|
1055
|
+
}
|
|
1056
|
+
};
|
|
1057
|
+
var attackRule = {
|
|
1058
|
+
id: "core.attack",
|
|
1059
|
+
name: "Attack Validation",
|
|
1060
|
+
description: "Ensures ATTACK actions have valid targetId",
|
|
1061
|
+
actionTypes: ["ATTACK", "attack"],
|
|
1062
|
+
validate: (action, context) => {
|
|
1063
|
+
if (!action.target && !action.payload?.targetId) {
|
|
1064
|
+
return {
|
|
1065
|
+
valid: false,
|
|
1066
|
+
reason: "ATTACK action must have a target or targetId",
|
|
1067
|
+
correctedAction: {
|
|
1068
|
+
...action,
|
|
1069
|
+
type: "IDLE",
|
|
1070
|
+
reason: "Invalid ATTACK - no target specified"
|
|
1071
|
+
}
|
|
1072
|
+
};
|
|
1073
|
+
}
|
|
1074
|
+
const world = context.worldState || {};
|
|
1075
|
+
const entities = world.entities || [];
|
|
1076
|
+
const targetId = action.target || action.payload?.targetId;
|
|
1077
|
+
if (entities.length > 0 && !entities.includes(targetId)) {
|
|
1078
|
+
return {
|
|
1079
|
+
valid: false,
|
|
1080
|
+
reason: `ATTACK target '${targetId}' does not exist in world`,
|
|
1081
|
+
correctedAction: {
|
|
1082
|
+
...action,
|
|
1083
|
+
type: "IDLE",
|
|
1084
|
+
reason: "Target not found"
|
|
1085
|
+
}
|
|
1086
|
+
};
|
|
1087
|
+
}
|
|
1088
|
+
return { valid: true };
|
|
1089
|
+
}
|
|
1090
|
+
};
|
|
1091
|
+
var interactRule = {
|
|
1092
|
+
id: "core.interact",
|
|
1093
|
+
name: "Interact Validation",
|
|
1094
|
+
description: "Ensures INTERACT actions have valid objectId",
|
|
1095
|
+
actionTypes: ["INTERACT", "interact"],
|
|
1096
|
+
validate: (action, context) => {
|
|
1097
|
+
if (!action.target && !action.payload?.objectId) {
|
|
1098
|
+
return {
|
|
1099
|
+
valid: false,
|
|
1100
|
+
reason: "INTERACT action must have objectId",
|
|
1101
|
+
correctedAction: {
|
|
1102
|
+
...action,
|
|
1103
|
+
type: "IDLE",
|
|
1104
|
+
reason: "Invalid INTERACT - no object specified"
|
|
1105
|
+
}
|
|
1106
|
+
};
|
|
1107
|
+
}
|
|
1108
|
+
return { valid: true };
|
|
1109
|
+
}
|
|
1110
|
+
};
|
|
1111
|
+
var speakRule = {
|
|
1112
|
+
id: "core.speak",
|
|
1113
|
+
name: "Speak Validation",
|
|
1114
|
+
description: "Ensures SPEAK actions have non-empty text",
|
|
1115
|
+
actionTypes: ["SPEAK", "speak"],
|
|
1116
|
+
validate: (action, context) => {
|
|
1117
|
+
const text = action.payload?.text;
|
|
1118
|
+
if (!text || text.trim().length === 0) {
|
|
1119
|
+
return {
|
|
1120
|
+
valid: false,
|
|
1121
|
+
reason: "SPEAK action must have non-empty text",
|
|
1122
|
+
correctedAction: {
|
|
1123
|
+
...action,
|
|
1124
|
+
type: "IDLE",
|
|
1125
|
+
reason: "Empty speech - defaulting to IDLE"
|
|
1126
|
+
}
|
|
1127
|
+
};
|
|
1128
|
+
}
|
|
1129
|
+
const maxLength = context.constraints?.maxSpeechLength || 1e3;
|
|
1130
|
+
if (text.length > maxLength) {
|
|
1131
|
+
return {
|
|
1132
|
+
valid: true,
|
|
1133
|
+
reason: `Speech truncated to ${maxLength} characters`,
|
|
1134
|
+
correctedAction: {
|
|
1135
|
+
...action,
|
|
1136
|
+
payload: {
|
|
1137
|
+
...action.payload,
|
|
1138
|
+
text: text.substring(0, maxLength)
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1143
|
+
return { valid: true };
|
|
1144
|
+
}
|
|
1145
|
+
};
|
|
1146
|
+
var resourceRule = {
|
|
1147
|
+
id: "core.resources",
|
|
1148
|
+
name: "Resource Validation",
|
|
1149
|
+
description: "Ensures agent has required resources for action",
|
|
1150
|
+
actionTypes: ["ATTACK", "CAST", "USE_ITEM"],
|
|
1151
|
+
validate: (action, context) => {
|
|
1152
|
+
const agent = context.agentState || {};
|
|
1153
|
+
const hp = agent.hp ?? 100;
|
|
1154
|
+
const mana = agent.mana ?? 100;
|
|
1155
|
+
if (hp <= 0) {
|
|
1156
|
+
return {
|
|
1157
|
+
valid: false,
|
|
1158
|
+
reason: "Agent is dead and cannot perform actions",
|
|
1159
|
+
correctedAction: { ...action, type: "IDLE", reason: "Agent dead" }
|
|
1160
|
+
};
|
|
1161
|
+
}
|
|
1162
|
+
if (action.type === "CAST" || action.type === "cast") {
|
|
1163
|
+
const manaCost = action.payload?.manaCost || 10;
|
|
1164
|
+
if (mana < manaCost) {
|
|
1165
|
+
return {
|
|
1166
|
+
valid: false,
|
|
1167
|
+
reason: `Insufficient mana: need ${manaCost}, have ${mana}`,
|
|
1168
|
+
correctedAction: { ...action, type: "IDLE", reason: "Not enough mana" }
|
|
1169
|
+
};
|
|
1170
|
+
}
|
|
1171
|
+
}
|
|
1172
|
+
return { valid: true };
|
|
1173
|
+
}
|
|
1174
|
+
};
|
|
1175
|
+
var rpgRules = [movementRule, attackRule, interactRule, speakRule, resourceRule];
|
|
1176
|
+
var spatialRules = [movementRule];
|
|
1177
|
+
var socialRules = [speakRule, interactRule];
|
|
1178
|
+
var puzzleRules = [movementRule, interactRule];
|
|
1179
|
+
|
|
1084
1180
|
// src/index.ts
|
|
1085
1181
|
var init = () => {
|
|
1086
1182
|
console.log(`
|
|
@@ -1098,7 +1194,6 @@ var init = () => {
|
|
|
1098
1194
|
`);
|
|
1099
1195
|
};
|
|
1100
1196
|
export {
|
|
1101
|
-
attackRule,
|
|
1102
1197
|
createAgent,
|
|
1103
1198
|
createAgentFromSoul,
|
|
1104
1199
|
createBridge,
|
|
@@ -1123,12 +1218,9 @@ export {
|
|
|
1123
1218
|
importSoulFromIPFS,
|
|
1124
1219
|
init,
|
|
1125
1220
|
initVectorEngine,
|
|
1126
|
-
|
|
1127
|
-
movementRule,
|
|
1221
|
+
presets_exports as presets,
|
|
1128
1222
|
processAgentInput,
|
|
1129
|
-
resourceRule,
|
|
1130
1223
|
serializeSoul,
|
|
1131
|
-
speakRule,
|
|
1132
1224
|
startGhostSession,
|
|
1133
1225
|
stopGhostSession,
|
|
1134
1226
|
updateAgentState,
|
package/package.json
CHANGED
|
@@ -1,47 +1,51 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
2
|
+
"name": "forbocai",
|
|
3
|
+
"version": "0.3.15",
|
|
4
|
+
"description": "The Infrastructure Layer for Autonomous AI Characters",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"bin": {
|
|
9
|
+
"forbocai": "dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsup src/index.ts src/cli.ts --format cjs,esm --dts",
|
|
13
|
+
"dev": "tsup src/index.ts --watch",
|
|
14
|
+
"test": "vitest",
|
|
15
|
+
"test:watch": "vitest --watch",
|
|
16
|
+
"preinstall": "node scripts/check-cmake.js",
|
|
17
|
+
"postinstall": "node postinstall.js"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@helia/json": "^5.0.6",
|
|
21
|
+
"@lancedb/lancedb": "^0.23.0",
|
|
22
|
+
"@mlc-ai/web-llm": "^0.2.80",
|
|
23
|
+
"@xenova/transformers": "^2.17.2",
|
|
24
|
+
"apache-arrow": "^18.1.0",
|
|
25
|
+
"axios": "^1.6.2",
|
|
26
|
+
"blockstore-core": "^6.1.2",
|
|
27
|
+
"datastore-core": "^11.0.2",
|
|
28
|
+
"helia": "^6.0.18",
|
|
29
|
+
"idb": "^8.0.3",
|
|
30
|
+
"node-llama-cpp": "^3.15.1",
|
|
31
|
+
"onnxruntime-node": "^1.23.2",
|
|
32
|
+
"zod": "^3.22.4"
|
|
33
|
+
},
|
|
34
|
+
"devDependencies": {
|
|
35
|
+
"@types/node": "^20.0.0",
|
|
36
|
+
"tsup": "^8.5.1",
|
|
37
|
+
"typescript": "^5.9.3",
|
|
38
|
+
"vitest": "^1.0.0"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"dist",
|
|
42
|
+
"README.md",
|
|
43
|
+
"package.json",
|
|
44
|
+
"postinstall.js",
|
|
45
|
+
"scripts"
|
|
46
|
+
],
|
|
47
|
+
"overrides": {
|
|
48
|
+
"glob": "^11.0.0",
|
|
49
|
+
"rimraf": "^5.0.0"
|
|
50
|
+
}
|
|
47
51
|
}
|