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/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
- interactRule: () => interactRule,
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: ${currentState.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 apiResponse = await fetch(`${apiUrl}/agents/mock-agent-id/process`, {
299
+ const dirRes = await fetch(`${apiUrl}/agents/${agentId}/directive`, {
310
300
  method: "POST",
311
- headers: { "Content-Type": "application/json" },
301
+ headers: {
302
+ "Content-Type": "application/json",
303
+ "X-Request-Timestamp": String(timestamp)
304
+ },
312
305
  body: JSON.stringify({
313
- input,
314
- context: apiContext
306
+ dirContext: apiContext,
307
+ dirState: currentState,
308
+ // Full state dump
309
+ dirMemories: []
310
+ // TODO: Integrate memory lookup
315
311
  })
316
312
  });
317
- if (apiResponse.ok) {
318
- const data = await apiResponse.json();
319
- directive = data.directive;
320
- instruction = data.instruction;
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("API Error, falling back to local.");
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 Unreachable, falling back to local.", e);
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 = `${directive}
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: { type: instruction, reason: directive },
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
- "agent-" + Math.random().toString(36).substring(7),
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
- interactRule,
1200
- movementRule,
1284
+ presets,
1201
1285
  processAgentInput,
1202
- resourceRule,
1203
1286
  serializeSoul,
1204
- speakRule,
1205
1287
  startGhostSession,
1206
1288
  stopGhostSession,
1207
1289
  updateAgentState,