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.js
CHANGED
|
@@ -30,7 +30,6 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
-
attackRule: () => attackRule,
|
|
34
33
|
createAgent: () => createAgent,
|
|
35
34
|
createAgentFromSoul: () => createAgentFromSoul,
|
|
36
35
|
createBridge: () => createBridge,
|
|
@@ -55,12 +54,9 @@ __export(index_exports, {
|
|
|
55
54
|
importSoulFromIPFS: () => importSoulFromIPFS,
|
|
56
55
|
init: () => init,
|
|
57
56
|
initVectorEngine: () => initVectorEngine,
|
|
58
|
-
|
|
59
|
-
movementRule: () => movementRule,
|
|
57
|
+
presets: () => presets_exports,
|
|
60
58
|
processAgentInput: () => processAgentInput,
|
|
61
|
-
resourceRule: () => resourceRule,
|
|
62
59
|
serializeSoul: () => serializeSoul,
|
|
63
|
-
speakRule: () => speakRule,
|
|
64
60
|
startGhostSession: () => startGhostSession,
|
|
65
61
|
stopGhostSession: () => stopGhostSession,
|
|
66
62
|
updateAgentState: () => updateAgentState,
|
|
@@ -249,26 +245,18 @@ var createCortex = (config) => createNativeCortex(config);
|
|
|
249
245
|
|
|
250
246
|
// src/agent.ts
|
|
251
247
|
var createInitialState = (partial) => {
|
|
252
|
-
return {
|
|
253
|
-
inventory: partial?.inventory ?? [],
|
|
254
|
-
skills: partial?.skills ?? {},
|
|
255
|
-
relationships: partial?.relationships ?? {},
|
|
256
|
-
mood: partial?.mood ?? "neutral"
|
|
257
|
-
};
|
|
248
|
+
return { ...partial };
|
|
258
249
|
};
|
|
259
250
|
var updateAgentState = (currentState, updates) => {
|
|
260
251
|
return {
|
|
261
252
|
...currentState,
|
|
262
|
-
...updates
|
|
263
|
-
// Preserve nested immutability
|
|
264
|
-
inventory: updates.inventory !== void 0 ? [...updates.inventory] : [...currentState.inventory],
|
|
265
|
-
skills: { ...currentState.skills, ...updates.skills || {} },
|
|
266
|
-
relationships: { ...currentState.relationships, ...updates.relationships || {} }
|
|
253
|
+
...updates
|
|
267
254
|
};
|
|
268
255
|
};
|
|
269
256
|
var processAgentInput = (currentState, input, context = {}) => {
|
|
257
|
+
const mood = currentState.mood || "neutral";
|
|
270
258
|
return {
|
|
271
|
-
dialogue: `Processing: "${input}" (Mood: ${
|
|
259
|
+
dialogue: `Processing: "${input}" (Mood: ${mood})`,
|
|
272
260
|
action: {
|
|
273
261
|
type: "respond",
|
|
274
262
|
reason: "Default processing"
|
|
@@ -292,6 +280,7 @@ var createAgent = (config) => {
|
|
|
292
280
|
let memories = [];
|
|
293
281
|
const cortex = config.cortex;
|
|
294
282
|
const apiUrl = config.apiUrl || "http://localhost:8080";
|
|
283
|
+
const agentId = config.id || "agent-" + Math.random().toString(36).substring(7);
|
|
295
284
|
const getAgentState = () => {
|
|
296
285
|
return { ...state };
|
|
297
286
|
};
|
|
@@ -300,44 +289,97 @@ var createAgent = (config) => {
|
|
|
300
289
|
};
|
|
301
290
|
const process2 = async (input, context = {}) => {
|
|
302
291
|
const currentState = getAgentState();
|
|
303
|
-
const hp = currentState.hp || 100;
|
|
304
292
|
const apiContext = Object.entries(context).map(([k, v]) => [k, String(v)]);
|
|
305
|
-
apiContext.push(["hp", String(hp)]);
|
|
306
293
|
let directive = "Respond normally.";
|
|
307
294
|
let instruction = "IDLE";
|
|
295
|
+
let target;
|
|
296
|
+
const timestamp = Date.now();
|
|
297
|
+
apiContext.push(["timestamp", String(timestamp)]);
|
|
308
298
|
try {
|
|
309
|
-
const
|
|
299
|
+
const dirRes = await fetch(`${apiUrl}/agents/${agentId}/directive`, {
|
|
310
300
|
method: "POST",
|
|
311
|
-
headers: {
|
|
301
|
+
headers: {
|
|
302
|
+
"Content-Type": "application/json",
|
|
303
|
+
"X-Request-Timestamp": String(timestamp)
|
|
304
|
+
},
|
|
312
305
|
body: JSON.stringify({
|
|
313
|
-
|
|
314
|
-
|
|
306
|
+
dirContext: apiContext,
|
|
307
|
+
dirState: currentState,
|
|
308
|
+
// Full state dump
|
|
309
|
+
dirMemories: []
|
|
310
|
+
// TODO: Integrate memory lookup
|
|
315
311
|
})
|
|
316
312
|
});
|
|
317
|
-
if (
|
|
318
|
-
const data = await
|
|
319
|
-
directive = data.
|
|
320
|
-
instruction = data.
|
|
313
|
+
if (dirRes.ok) {
|
|
314
|
+
const data = await dirRes.json();
|
|
315
|
+
directive = data.dirReason;
|
|
316
|
+
instruction = data.dirInstruction;
|
|
317
|
+
target = data.dirTarget;
|
|
321
318
|
} else {
|
|
322
|
-
console.warn(
|
|
319
|
+
console.warn(`API Directive Error: ${dirRes.status} ${dirRes.statusText}`);
|
|
320
|
+
if (config.fallbackStrategy) {
|
|
321
|
+
const fallback = config.fallbackStrategy(currentState, context);
|
|
322
|
+
instruction = fallback.instruction;
|
|
323
|
+
directive = fallback.directive;
|
|
324
|
+
}
|
|
323
325
|
}
|
|
324
326
|
} catch (e) {
|
|
325
|
-
console.warn("API
|
|
327
|
+
console.warn("API Directive Failed (Network), falling back to local laws.", e);
|
|
328
|
+
if (config.fallbackStrategy) {
|
|
329
|
+
const fallback = config.fallbackStrategy(currentState, context);
|
|
330
|
+
instruction = fallback.instruction;
|
|
331
|
+
directive = fallback.directive;
|
|
332
|
+
}
|
|
326
333
|
}
|
|
327
|
-
const prompt =
|
|
328
|
-
|
|
334
|
+
const prompt = `System: Follow this directive strictly: ${instruction} (${directive}).
|
|
335
|
+
To Target: ${target || "None"}
|
|
329
336
|
User: ${input}
|
|
330
337
|
Agent:`;
|
|
331
338
|
const generatedText = await cortex.complete(prompt);
|
|
339
|
+
let signature = "unsigned_local_fallback";
|
|
340
|
+
let isValid = true;
|
|
341
|
+
const proposedAction = { type: instruction, reason: directive, target };
|
|
342
|
+
try {
|
|
343
|
+
const verRes = await fetch(`${apiUrl}/agents/${agentId}/verdict`, {
|
|
344
|
+
method: "POST",
|
|
345
|
+
headers: { "Content-Type": "application/json" },
|
|
346
|
+
body: JSON.stringify({
|
|
347
|
+
verDirective: {
|
|
348
|
+
dirInstruction: instruction,
|
|
349
|
+
dirTarget: target,
|
|
350
|
+
dirReason: directive
|
|
351
|
+
},
|
|
352
|
+
verAction: {
|
|
353
|
+
actionType: instruction,
|
|
354
|
+
actionReason: directive,
|
|
355
|
+
actionTarget: target
|
|
356
|
+
},
|
|
357
|
+
verThought: generatedText
|
|
358
|
+
})
|
|
359
|
+
});
|
|
360
|
+
if (verRes.ok) {
|
|
361
|
+
const vData = await verRes.json();
|
|
362
|
+
isValid = vData.verValid;
|
|
363
|
+
signature = vData.verSignature;
|
|
364
|
+
}
|
|
365
|
+
} catch (e) {
|
|
366
|
+
console.warn("API Verdict Failed.", e);
|
|
367
|
+
}
|
|
368
|
+
if (!isValid) {
|
|
369
|
+
return {
|
|
370
|
+
dialogue: "... [Action Blocked by Protocol]",
|
|
371
|
+
action: { type: "BLOCKED", reason: "API Validation Failed" }
|
|
372
|
+
};
|
|
373
|
+
}
|
|
332
374
|
return {
|
|
333
375
|
dialogue: generatedText,
|
|
334
|
-
action: {
|
|
335
|
-
thought: `Directive: ${directive}`
|
|
376
|
+
action: { ...proposedAction, signature },
|
|
377
|
+
thought: `Directive: ${directive} | Sig: ${signature}`
|
|
336
378
|
};
|
|
337
379
|
};
|
|
338
380
|
const exportSoul = () => {
|
|
339
381
|
return exportToSoul(
|
|
340
|
-
|
|
382
|
+
agentId,
|
|
341
383
|
"Agent",
|
|
342
384
|
config.persona,
|
|
343
385
|
state,
|
|
@@ -672,180 +714,12 @@ var createLanceDBMemory = (config) => {
|
|
|
672
714
|
var createMemory = (config = {}) => createLanceDBMemory(config);
|
|
673
715
|
|
|
674
716
|
// src/bridge.ts
|
|
675
|
-
var movementRule = {
|
|
676
|
-
id: "core.movement",
|
|
677
|
-
name: "Movement Validation",
|
|
678
|
-
description: "Ensures MOVE actions have valid x,y coordinates",
|
|
679
|
-
actionTypes: ["MOVE", "move"],
|
|
680
|
-
validate: (action, context) => {
|
|
681
|
-
const payload = action.payload || {};
|
|
682
|
-
const target = payload.target;
|
|
683
|
-
if (!target || typeof target.x !== "number" || typeof target.y !== "number") {
|
|
684
|
-
return {
|
|
685
|
-
valid: false,
|
|
686
|
-
reason: "MOVE action must have target with numeric x,y coordinates",
|
|
687
|
-
correctedAction: {
|
|
688
|
-
...action,
|
|
689
|
-
type: "IDLE",
|
|
690
|
-
reason: "Invalid MOVE target - defaulting to IDLE"
|
|
691
|
-
}
|
|
692
|
-
};
|
|
693
|
-
}
|
|
694
|
-
const world = context.worldState || {};
|
|
695
|
-
const maxX = world.maxX || Infinity;
|
|
696
|
-
const maxY = world.maxY || Infinity;
|
|
697
|
-
if (target.x < 0 || target.x > maxX || target.y < 0 || target.y > maxY) {
|
|
698
|
-
return {
|
|
699
|
-
valid: false,
|
|
700
|
-
reason: `MOVE target (${target.x}, ${target.y}) is out of bounds`,
|
|
701
|
-
correctedAction: {
|
|
702
|
-
...action,
|
|
703
|
-
payload: {
|
|
704
|
-
...payload,
|
|
705
|
-
target: {
|
|
706
|
-
x: Math.max(0, Math.min(maxX, target.x)),
|
|
707
|
-
y: Math.max(0, Math.min(maxY, target.y))
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
|
-
}
|
|
711
|
-
};
|
|
712
|
-
}
|
|
713
|
-
return { valid: true };
|
|
714
|
-
}
|
|
715
|
-
};
|
|
716
|
-
var attackRule = {
|
|
717
|
-
id: "core.attack",
|
|
718
|
-
name: "Attack Validation",
|
|
719
|
-
description: "Ensures ATTACK actions have valid targetId",
|
|
720
|
-
actionTypes: ["ATTACK", "attack"],
|
|
721
|
-
validate: (action, context) => {
|
|
722
|
-
if (!action.target && !action.payload?.targetId) {
|
|
723
|
-
return {
|
|
724
|
-
valid: false,
|
|
725
|
-
reason: "ATTACK action must have a target or targetId",
|
|
726
|
-
correctedAction: {
|
|
727
|
-
...action,
|
|
728
|
-
type: "IDLE",
|
|
729
|
-
reason: "Invalid ATTACK - no target specified"
|
|
730
|
-
}
|
|
731
|
-
};
|
|
732
|
-
}
|
|
733
|
-
const world = context.worldState || {};
|
|
734
|
-
const entities = world.entities || [];
|
|
735
|
-
const targetId = action.target || action.payload?.targetId;
|
|
736
|
-
if (entities.length > 0 && !entities.includes(targetId)) {
|
|
737
|
-
return {
|
|
738
|
-
valid: false,
|
|
739
|
-
reason: `ATTACK target '${targetId}' does not exist in world`,
|
|
740
|
-
correctedAction: {
|
|
741
|
-
...action,
|
|
742
|
-
type: "IDLE",
|
|
743
|
-
reason: "Target not found"
|
|
744
|
-
}
|
|
745
|
-
};
|
|
746
|
-
}
|
|
747
|
-
return { valid: true };
|
|
748
|
-
}
|
|
749
|
-
};
|
|
750
|
-
var interactRule = {
|
|
751
|
-
id: "core.interact",
|
|
752
|
-
name: "Interact Validation",
|
|
753
|
-
description: "Ensures INTERACT actions have valid objectId",
|
|
754
|
-
actionTypes: ["INTERACT", "interact"],
|
|
755
|
-
validate: (action, context) => {
|
|
756
|
-
if (!action.target && !action.payload?.objectId) {
|
|
757
|
-
return {
|
|
758
|
-
valid: false,
|
|
759
|
-
reason: "INTERACT action must have objectId",
|
|
760
|
-
correctedAction: {
|
|
761
|
-
...action,
|
|
762
|
-
type: "IDLE",
|
|
763
|
-
reason: "Invalid INTERACT - no object specified"
|
|
764
|
-
}
|
|
765
|
-
};
|
|
766
|
-
}
|
|
767
|
-
return { valid: true };
|
|
768
|
-
}
|
|
769
|
-
};
|
|
770
|
-
var speakRule = {
|
|
771
|
-
id: "core.speak",
|
|
772
|
-
name: "Speak Validation",
|
|
773
|
-
description: "Ensures SPEAK actions have non-empty text",
|
|
774
|
-
actionTypes: ["SPEAK", "speak"],
|
|
775
|
-
validate: (action, context) => {
|
|
776
|
-
const text = action.payload?.text;
|
|
777
|
-
if (!text || text.trim().length === 0) {
|
|
778
|
-
return {
|
|
779
|
-
valid: false,
|
|
780
|
-
reason: "SPEAK action must have non-empty text",
|
|
781
|
-
correctedAction: {
|
|
782
|
-
...action,
|
|
783
|
-
type: "IDLE",
|
|
784
|
-
reason: "Empty speech - defaulting to IDLE"
|
|
785
|
-
}
|
|
786
|
-
};
|
|
787
|
-
}
|
|
788
|
-
const maxLength = context.constraints?.maxSpeechLength || 1e3;
|
|
789
|
-
if (text.length > maxLength) {
|
|
790
|
-
return {
|
|
791
|
-
valid: true,
|
|
792
|
-
// Still valid, but truncated
|
|
793
|
-
reason: `Speech truncated to ${maxLength} characters`,
|
|
794
|
-
correctedAction: {
|
|
795
|
-
...action,
|
|
796
|
-
payload: {
|
|
797
|
-
...action.payload,
|
|
798
|
-
text: text.substring(0, maxLength)
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
};
|
|
802
|
-
}
|
|
803
|
-
return { valid: true };
|
|
804
|
-
}
|
|
805
|
-
};
|
|
806
|
-
var resourceRule = {
|
|
807
|
-
id: "core.resources",
|
|
808
|
-
name: "Resource Validation",
|
|
809
|
-
description: "Ensures agent has required resources for action",
|
|
810
|
-
actionTypes: ["ATTACK", "CAST", "USE_ITEM"],
|
|
811
|
-
validate: (action, context) => {
|
|
812
|
-
const agent = context.agentState || {};
|
|
813
|
-
const hp = agent.hp ?? 100;
|
|
814
|
-
const mana = agent.mana ?? 100;
|
|
815
|
-
if (hp <= 0) {
|
|
816
|
-
return {
|
|
817
|
-
valid: false,
|
|
818
|
-
reason: "Agent is dead and cannot perform actions",
|
|
819
|
-
correctedAction: { ...action, type: "IDLE", reason: "Agent dead" }
|
|
820
|
-
};
|
|
821
|
-
}
|
|
822
|
-
if (action.type === "CAST" || action.type === "cast") {
|
|
823
|
-
const manaCost = action.payload?.manaCost || 10;
|
|
824
|
-
if (mana < manaCost) {
|
|
825
|
-
return {
|
|
826
|
-
valid: false,
|
|
827
|
-
reason: `Insufficient mana: need ${manaCost}, have ${mana}`,
|
|
828
|
-
correctedAction: { ...action, type: "IDLE", reason: "Not enough mana" }
|
|
829
|
-
};
|
|
830
|
-
}
|
|
831
|
-
}
|
|
832
|
-
return { valid: true };
|
|
833
|
-
}
|
|
834
|
-
};
|
|
835
|
-
var DEFAULT_RULES = [
|
|
836
|
-
movementRule,
|
|
837
|
-
attackRule,
|
|
838
|
-
interactRule,
|
|
839
|
-
speakRule,
|
|
840
|
-
resourceRule
|
|
841
|
-
];
|
|
842
717
|
var createBridge = (config = {}) => {
|
|
843
718
|
const effectiveConfig = {
|
|
844
719
|
strictMode: config.strictMode ?? false,
|
|
845
720
|
...config
|
|
846
721
|
};
|
|
847
722
|
const rules = /* @__PURE__ */ new Map();
|
|
848
|
-
DEFAULT_RULES.forEach((rule) => rules.set(rule.id, rule));
|
|
849
723
|
if (config.customRules) {
|
|
850
724
|
config.customRules.forEach((rule) => rules.set(rule.id, rule));
|
|
851
725
|
}
|
|
@@ -1153,6 +1027,218 @@ var createGhost = (config) => {
|
|
|
1153
1027
|
};
|
|
1154
1028
|
};
|
|
1155
1029
|
|
|
1030
|
+
// src/presets.ts
|
|
1031
|
+
var presets_exports = {};
|
|
1032
|
+
__export(presets_exports, {
|
|
1033
|
+
RPG_MEMORY_TYPES: () => RPG_MEMORY_TYPES,
|
|
1034
|
+
RPG_MOODS: () => RPG_MOODS,
|
|
1035
|
+
attackRule: () => attackRule,
|
|
1036
|
+
createRPGState: () => createRPGState,
|
|
1037
|
+
interactRule: () => interactRule,
|
|
1038
|
+
movementRule: () => movementRule,
|
|
1039
|
+
puzzleRules: () => puzzleRules,
|
|
1040
|
+
resourceRule: () => resourceRule,
|
|
1041
|
+
rpgFallbackStrategy: () => rpgFallbackStrategy,
|
|
1042
|
+
rpgRules: () => rpgRules,
|
|
1043
|
+
socialRules: () => socialRules,
|
|
1044
|
+
spatialRules: () => spatialRules,
|
|
1045
|
+
speakRule: () => speakRule
|
|
1046
|
+
});
|
|
1047
|
+
var RPG_MOODS = {
|
|
1048
|
+
hostile: "hostile",
|
|
1049
|
+
suspicious: "suspicious",
|
|
1050
|
+
neutral: "neutral",
|
|
1051
|
+
friendly: "friendly",
|
|
1052
|
+
loyal: "loyal"
|
|
1053
|
+
};
|
|
1054
|
+
var RPG_MEMORY_TYPES = {
|
|
1055
|
+
observation: "observation",
|
|
1056
|
+
experience: "experience",
|
|
1057
|
+
knowledge: "knowledge",
|
|
1058
|
+
emotion: "emotion"
|
|
1059
|
+
};
|
|
1060
|
+
var createRPGState = (partial) => {
|
|
1061
|
+
return {
|
|
1062
|
+
inventory: partial?.inventory ?? [],
|
|
1063
|
+
hp: partial?.hp ?? 100,
|
|
1064
|
+
mana: partial?.mana ?? 100,
|
|
1065
|
+
skills: partial?.skills ?? {},
|
|
1066
|
+
relationships: partial?.relationships ?? {},
|
|
1067
|
+
mood: partial?.mood ?? "neutral",
|
|
1068
|
+
...partial
|
|
1069
|
+
};
|
|
1070
|
+
};
|
|
1071
|
+
var rpgFallbackStrategy = (state, context) => {
|
|
1072
|
+
const hp = state.hp || 100;
|
|
1073
|
+
if (hp < 20) {
|
|
1074
|
+
return { instruction: "FLEE", directive: "CRITICAL (Fallback): Low Health detected." };
|
|
1075
|
+
}
|
|
1076
|
+
return { instruction: "IDLE", directive: "Autonomous" };
|
|
1077
|
+
};
|
|
1078
|
+
var movementRule = {
|
|
1079
|
+
id: "core.movement",
|
|
1080
|
+
name: "Movement Validation",
|
|
1081
|
+
description: "Ensures MOVE actions have valid x,y coordinates",
|
|
1082
|
+
actionTypes: ["MOVE", "move"],
|
|
1083
|
+
validate: (action, context) => {
|
|
1084
|
+
const payload = action.payload || {};
|
|
1085
|
+
const target = payload.target;
|
|
1086
|
+
if (!target || typeof target.x !== "number" || typeof target.y !== "number") {
|
|
1087
|
+
return {
|
|
1088
|
+
valid: false,
|
|
1089
|
+
reason: "MOVE action must have target with numeric x,y coordinates",
|
|
1090
|
+
correctedAction: {
|
|
1091
|
+
...action,
|
|
1092
|
+
type: "IDLE",
|
|
1093
|
+
reason: "Invalid MOVE target - defaulting to IDLE"
|
|
1094
|
+
}
|
|
1095
|
+
};
|
|
1096
|
+
}
|
|
1097
|
+
const world = context.worldState || {};
|
|
1098
|
+
const maxX = world.maxX || Infinity;
|
|
1099
|
+
const maxY = world.maxY || Infinity;
|
|
1100
|
+
if (target.x < 0 || target.x > maxX || target.y < 0 || target.y > maxY) {
|
|
1101
|
+
return {
|
|
1102
|
+
valid: false,
|
|
1103
|
+
reason: `MOVE target (${target.x}, ${target.y}) is out of bounds`,
|
|
1104
|
+
correctedAction: {
|
|
1105
|
+
...action,
|
|
1106
|
+
payload: {
|
|
1107
|
+
...payload,
|
|
1108
|
+
target: {
|
|
1109
|
+
x: Math.max(0, Math.min(maxX, target.x)),
|
|
1110
|
+
y: Math.max(0, Math.min(maxY, target.y))
|
|
1111
|
+
}
|
|
1112
|
+
}
|
|
1113
|
+
}
|
|
1114
|
+
};
|
|
1115
|
+
}
|
|
1116
|
+
return { valid: true };
|
|
1117
|
+
}
|
|
1118
|
+
};
|
|
1119
|
+
var attackRule = {
|
|
1120
|
+
id: "core.attack",
|
|
1121
|
+
name: "Attack Validation",
|
|
1122
|
+
description: "Ensures ATTACK actions have valid targetId",
|
|
1123
|
+
actionTypes: ["ATTACK", "attack"],
|
|
1124
|
+
validate: (action, context) => {
|
|
1125
|
+
if (!action.target && !action.payload?.targetId) {
|
|
1126
|
+
return {
|
|
1127
|
+
valid: false,
|
|
1128
|
+
reason: "ATTACK action must have a target or targetId",
|
|
1129
|
+
correctedAction: {
|
|
1130
|
+
...action,
|
|
1131
|
+
type: "IDLE",
|
|
1132
|
+
reason: "Invalid ATTACK - no target specified"
|
|
1133
|
+
}
|
|
1134
|
+
};
|
|
1135
|
+
}
|
|
1136
|
+
const world = context.worldState || {};
|
|
1137
|
+
const entities = world.entities || [];
|
|
1138
|
+
const targetId = action.target || action.payload?.targetId;
|
|
1139
|
+
if (entities.length > 0 && !entities.includes(targetId)) {
|
|
1140
|
+
return {
|
|
1141
|
+
valid: false,
|
|
1142
|
+
reason: `ATTACK target '${targetId}' does not exist in world`,
|
|
1143
|
+
correctedAction: {
|
|
1144
|
+
...action,
|
|
1145
|
+
type: "IDLE",
|
|
1146
|
+
reason: "Target not found"
|
|
1147
|
+
}
|
|
1148
|
+
};
|
|
1149
|
+
}
|
|
1150
|
+
return { valid: true };
|
|
1151
|
+
}
|
|
1152
|
+
};
|
|
1153
|
+
var interactRule = {
|
|
1154
|
+
id: "core.interact",
|
|
1155
|
+
name: "Interact Validation",
|
|
1156
|
+
description: "Ensures INTERACT actions have valid objectId",
|
|
1157
|
+
actionTypes: ["INTERACT", "interact"],
|
|
1158
|
+
validate: (action, context) => {
|
|
1159
|
+
if (!action.target && !action.payload?.objectId) {
|
|
1160
|
+
return {
|
|
1161
|
+
valid: false,
|
|
1162
|
+
reason: "INTERACT action must have objectId",
|
|
1163
|
+
correctedAction: {
|
|
1164
|
+
...action,
|
|
1165
|
+
type: "IDLE",
|
|
1166
|
+
reason: "Invalid INTERACT - no object specified"
|
|
1167
|
+
}
|
|
1168
|
+
};
|
|
1169
|
+
}
|
|
1170
|
+
return { valid: true };
|
|
1171
|
+
}
|
|
1172
|
+
};
|
|
1173
|
+
var speakRule = {
|
|
1174
|
+
id: "core.speak",
|
|
1175
|
+
name: "Speak Validation",
|
|
1176
|
+
description: "Ensures SPEAK actions have non-empty text",
|
|
1177
|
+
actionTypes: ["SPEAK", "speak"],
|
|
1178
|
+
validate: (action, context) => {
|
|
1179
|
+
const text = action.payload?.text;
|
|
1180
|
+
if (!text || text.trim().length === 0) {
|
|
1181
|
+
return {
|
|
1182
|
+
valid: false,
|
|
1183
|
+
reason: "SPEAK action must have non-empty text",
|
|
1184
|
+
correctedAction: {
|
|
1185
|
+
...action,
|
|
1186
|
+
type: "IDLE",
|
|
1187
|
+
reason: "Empty speech - defaulting to IDLE"
|
|
1188
|
+
}
|
|
1189
|
+
};
|
|
1190
|
+
}
|
|
1191
|
+
const maxLength = context.constraints?.maxSpeechLength || 1e3;
|
|
1192
|
+
if (text.length > maxLength) {
|
|
1193
|
+
return {
|
|
1194
|
+
valid: true,
|
|
1195
|
+
reason: `Speech truncated to ${maxLength} characters`,
|
|
1196
|
+
correctedAction: {
|
|
1197
|
+
...action,
|
|
1198
|
+
payload: {
|
|
1199
|
+
...action.payload,
|
|
1200
|
+
text: text.substring(0, maxLength)
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
};
|
|
1204
|
+
}
|
|
1205
|
+
return { valid: true };
|
|
1206
|
+
}
|
|
1207
|
+
};
|
|
1208
|
+
var resourceRule = {
|
|
1209
|
+
id: "core.resources",
|
|
1210
|
+
name: "Resource Validation",
|
|
1211
|
+
description: "Ensures agent has required resources for action",
|
|
1212
|
+
actionTypes: ["ATTACK", "CAST", "USE_ITEM"],
|
|
1213
|
+
validate: (action, context) => {
|
|
1214
|
+
const agent = context.agentState || {};
|
|
1215
|
+
const hp = agent.hp ?? 100;
|
|
1216
|
+
const mana = agent.mana ?? 100;
|
|
1217
|
+
if (hp <= 0) {
|
|
1218
|
+
return {
|
|
1219
|
+
valid: false,
|
|
1220
|
+
reason: "Agent is dead and cannot perform actions",
|
|
1221
|
+
correctedAction: { ...action, type: "IDLE", reason: "Agent dead" }
|
|
1222
|
+
};
|
|
1223
|
+
}
|
|
1224
|
+
if (action.type === "CAST" || action.type === "cast") {
|
|
1225
|
+
const manaCost = action.payload?.manaCost || 10;
|
|
1226
|
+
if (mana < manaCost) {
|
|
1227
|
+
return {
|
|
1228
|
+
valid: false,
|
|
1229
|
+
reason: `Insufficient mana: need ${manaCost}, have ${mana}`,
|
|
1230
|
+
correctedAction: { ...action, type: "IDLE", reason: "Not enough mana" }
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
}
|
|
1234
|
+
return { valid: true };
|
|
1235
|
+
}
|
|
1236
|
+
};
|
|
1237
|
+
var rpgRules = [movementRule, attackRule, interactRule, speakRule, resourceRule];
|
|
1238
|
+
var spatialRules = [movementRule];
|
|
1239
|
+
var socialRules = [speakRule, interactRule];
|
|
1240
|
+
var puzzleRules = [movementRule, interactRule];
|
|
1241
|
+
|
|
1156
1242
|
// src/index.ts
|
|
1157
1243
|
var init = () => {
|
|
1158
1244
|
console.log(`
|
|
@@ -1171,7 +1257,6 @@ var init = () => {
|
|
|
1171
1257
|
};
|
|
1172
1258
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1173
1259
|
0 && (module.exports = {
|
|
1174
|
-
attackRule,
|
|
1175
1260
|
createAgent,
|
|
1176
1261
|
createAgentFromSoul,
|
|
1177
1262
|
createBridge,
|
|
@@ -1196,12 +1281,9 @@ var init = () => {
|
|
|
1196
1281
|
importSoulFromIPFS,
|
|
1197
1282
|
init,
|
|
1198
1283
|
initVectorEngine,
|
|
1199
|
-
|
|
1200
|
-
movementRule,
|
|
1284
|
+
presets,
|
|
1201
1285
|
processAgentInput,
|
|
1202
|
-
resourceRule,
|
|
1203
1286
|
serializeSoul,
|
|
1204
|
-
speakRule,
|
|
1205
1287
|
startGhostSession,
|
|
1206
1288
|
stopGhostSession,
|
|
1207
1289
|
updateAgentState,
|