@putervision/behavior-mcp 0.1.1

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/lib.js ADDED
@@ -0,0 +1,443 @@
1
+ import {
2
+ ActionRateLimiter,
3
+ EmergencySafety,
4
+ MetricsEngine,
5
+ PolicyGate,
6
+ SnapshotEngine,
7
+ StuckDetector,
8
+ WatchdogTimer,
9
+ server
10
+ } from "./chunk-MXYFWAJG.js";
11
+ import {
12
+ ExecutionEngine,
13
+ TriggerRegistry
14
+ } from "./chunk-FXYS43D6.js";
15
+ import {
16
+ BehaviorRegistry,
17
+ computeEventHash,
18
+ computeTreeHash,
19
+ generateId,
20
+ getCurrentIsoString,
21
+ getElapsedTimeMs,
22
+ logRuntimeEvent,
23
+ parseIsoString,
24
+ verifyEventChain
25
+ } from "./chunk-QU5PNQP4.js";
26
+ import {
27
+ BehaviorRuntimeError,
28
+ DatabaseError,
29
+ ExecutionError,
30
+ LOG_LEVELS,
31
+ NotFoundError,
32
+ SafetyError,
33
+ ValidationError,
34
+ closeAllDbs,
35
+ closeDb,
36
+ getBaseDir,
37
+ getDb,
38
+ getDbPath,
39
+ getLogLevel,
40
+ getProjectDbDir,
41
+ getProjectSlug,
42
+ getReadOnlyDb,
43
+ getRegistry,
44
+ getRegistryPath,
45
+ logger,
46
+ registerProject,
47
+ resolveProjectRoot,
48
+ sanitizeSlug,
49
+ unregisterProject,
50
+ validatePath
51
+ } from "./chunk-L2LJRSDU.js";
52
+
53
+ // src/schema/schemas.ts
54
+ import { z } from "zod";
55
+ var LoadBehaviorSchema = z.object({
56
+ action: z.enum(["load", "unload", "swap"]),
57
+ behavior_name: z.string(),
58
+ behavior_version: z.number().optional(),
59
+ parameters: z.record(z.any()).optional(),
60
+ session_id: z.string().optional(),
61
+ intention_id: z.string().optional(),
62
+ client_request_id: z.string().optional(),
63
+ project: z.string().optional()
64
+ });
65
+ var SetParametersSchema = z.object({
66
+ action: z.enum(["set", "get", "reset"]),
67
+ execution_id: z.string().optional(),
68
+ parameters: z.record(z.any()).optional(),
69
+ project: z.string().optional()
70
+ });
71
+ var GetStatusSchema = z.object({
72
+ action: z.enum(["current", "history", "tree_state"]),
73
+ execution_id: z.string().optional(),
74
+ limit: z.number().optional(),
75
+ project: z.string().optional()
76
+ });
77
+ var AbortBehaviorSchema = z.object({
78
+ action: z.enum(["abort", "pause", "resume"]),
79
+ execution_id: z.string().optional(),
80
+ reason: z.string().optional(),
81
+ project: z.string().optional()
82
+ });
83
+ var RegisterTriggerSchema = z.object({
84
+ action: z.enum(["register", "list", "update", "remove", "enable", "disable"]),
85
+ name: z.string().optional(),
86
+ behavior_name: z.string().optional(),
87
+ condition_type: z.string().optional(),
88
+ condition_params: z.record(z.any()).optional(),
89
+ priority: z.number().optional(),
90
+ cooldown_ms: z.number().optional(),
91
+ trigger_id: z.string().optional(),
92
+ project: z.string().optional()
93
+ });
94
+ var ReplayRecordingSchema = z.object({
95
+ action: z.enum(["start", "stop", "list", "capture", "delete"]),
96
+ name: z.string().optional(),
97
+ recording_id: z.string().optional(),
98
+ frames: z.array(z.any()).optional(),
99
+ project: z.string().optional()
100
+ });
101
+ var GetMetricsSchema = z.object({
102
+ action: z.enum(["current", "history", "aggregate", "compare"]),
103
+ execution_id: z.string().optional(),
104
+ behavior_name: z.string().optional(),
105
+ limit: z.number().optional(),
106
+ project: z.string().optional()
107
+ });
108
+ var ManageBehaviorsSchema = z.object({
109
+ action: z.enum(["register", "list", "get", "update", "delete", "export", "import"]),
110
+ name: z.string().optional(),
111
+ version: z.number().optional(),
112
+ description: z.string().optional(),
113
+ tree: z.any().optional(),
114
+ tree_json: z.string().optional(),
115
+ client_request_id: z.string().optional(),
116
+ project: z.string().optional()
117
+ });
118
+ var ManageBlackboardSchema = z.object({
119
+ action: z.enum(["get", "set", "clear", "dump"]),
120
+ execution_id: z.string().optional(),
121
+ key: z.string().optional(),
122
+ value: z.any().optional(),
123
+ blackboard: z.record(z.any()).optional(),
124
+ project: z.string().optional()
125
+ });
126
+ var ManageRuntimeDbSchema = z.object({
127
+ action: z.enum(["backup", "stats", "audit", "snapshot", "diff", "restore"]),
128
+ name: z.string().optional(),
129
+ description: z.string().optional(),
130
+ project: z.string().optional()
131
+ });
132
+
133
+ // src/engine/browser/conditions.ts
134
+ var ConditionRegistry = {
135
+ timer_elapsed: (params, ctx) => {
136
+ const threshold = params.threshold_ticks || 60;
137
+ return ctx.tick >= threshold;
138
+ },
139
+ blackboard_check: (params, ctx) => {
140
+ const key = params.key;
141
+ const expected = params.expected;
142
+ return ctx.blackboard[key] === expected;
143
+ },
144
+ proximity_check: (params, ctx) => {
145
+ const dist = ctx.telemetry.target_distance ?? 999;
146
+ const radius = params.radius ?? 10;
147
+ return dist <= radius;
148
+ }
149
+ };
150
+
151
+ // src/engine/browser/conditions-game.ts
152
+ var GameConditionRegistry = {
153
+ hp_below: (params, ctx) => {
154
+ const hp = ctx.telemetry.hp ?? 100;
155
+ const threshold = params.threshold ?? 30;
156
+ return hp < threshold;
157
+ },
158
+ enemy_in_range: (params, ctx) => {
159
+ const enemyDist = ctx.telemetry.enemy_distance ?? 999;
160
+ const range = params.range ?? 15;
161
+ return enemyDist <= range;
162
+ },
163
+ resource_above: (params, ctx) => {
164
+ const amount = ctx.blackboard.resource_count ?? 0;
165
+ const capacity = params.capacity ?? 20;
166
+ return amount >= capacity;
167
+ }
168
+ };
169
+
170
+ // src/engine/browser/actions.ts
171
+ var ActionRegistry = {
172
+ move_to: (params, ctx) => {
173
+ ctx.blackboard.current_destination = params.destination || [0, 0, 0];
174
+ return { status: "SUCCESS", output: { destination: ctx.blackboard.current_destination } };
175
+ },
176
+ wait: (params, ctx) => {
177
+ const ticks = params.ticks || 10;
178
+ if (ctx.tick % ticks === 0) return { status: "SUCCESS" };
179
+ return { status: "RUNNING" };
180
+ },
181
+ interact: (params, ctx) => {
182
+ ctx.blackboard.last_interaction = params.target || "object";
183
+ return { status: "SUCCESS", output: { interacted_with: ctx.blackboard.last_interaction } };
184
+ },
185
+ log: (params, ctx) => {
186
+ return { status: "SUCCESS", output: { message: params.message || "Log action executed" } };
187
+ },
188
+ cast_spell: (params, ctx) => {
189
+ ctx.blackboard.last_spell = params.spell || "default_spell";
190
+ return { status: "SUCCESS", output: { spell: ctx.blackboard.last_spell } };
191
+ },
192
+ swing_sword: (params, ctx) => {
193
+ ctx.blackboard.last_combat_action = "swing_sword";
194
+ return { status: "SUCCESS", output: { combat: "melee" } };
195
+ },
196
+ shoot_arrow: (params, ctx) => {
197
+ ctx.blackboard.last_combat_action = "shoot_arrow";
198
+ return { status: "SUCCESS", output: { combat: "ranged" } };
199
+ },
200
+ patrol_area: (params, ctx) => {
201
+ ctx.blackboard.patrolling = true;
202
+ return { status: "SUCCESS", output: { patrol: true } };
203
+ },
204
+ patrol: (params, ctx) => {
205
+ ctx.blackboard.patrolling = true;
206
+ return { status: "SUCCESS", output: { patrol: true } };
207
+ }
208
+ };
209
+
210
+ // src/engine/browser/actions-game.ts
211
+ var GameActionRegistry = {
212
+ attack_nearest: (params, ctx) => {
213
+ ctx.blackboard.last_attack_target = "nearest_enemy";
214
+ return { status: "SUCCESS", output: { action: "attack", target: "nearest_enemy" } };
215
+ },
216
+ flee_to_safety: (params, ctx) => {
217
+ ctx.blackboard.fleeing = true;
218
+ return { status: "SUCCESS", output: { action: "flee", waypoint: "base" } };
219
+ },
220
+ gather: (params, ctx) => {
221
+ const current = ctx.blackboard.resource_count || 0;
222
+ ctx.blackboard.resource_count = current + 1;
223
+ return { status: "SUCCESS", output: { resource_count: ctx.blackboard.resource_count } };
224
+ },
225
+ heal: (params, ctx) => {
226
+ ctx.blackboard.healing = true;
227
+ return { status: "SUCCESS", output: { action: "use_potion" } };
228
+ }
229
+ };
230
+
231
+ // src/engine/browser/executor-bundle.ts
232
+ var BehaviorTreeEvaluator = class {
233
+ tree;
234
+ blackboard;
235
+ tickCount = 0;
236
+ constructor(tree, initialBlackboard = {}) {
237
+ this.tree = tree;
238
+ this.blackboard = { ...initialBlackboard };
239
+ }
240
+ step(telemetry = {}) {
241
+ this.tickCount++;
242
+ const ctx = {
243
+ blackboard: this.blackboard,
244
+ telemetry,
245
+ tick: this.tickCount
246
+ };
247
+ const res = this.evaluateNode(this.tree, "root", ctx);
248
+ return {
249
+ status: res.status,
250
+ activePath: res.activePath,
251
+ blackboard: this.blackboard
252
+ };
253
+ }
254
+ evaluateNode(node, path, ctx) {
255
+ switch (node.type) {
256
+ case "sequence": {
257
+ const children = node.children || [];
258
+ for (let i = 0; i < children.length; i++) {
259
+ const childPath = `${path}/seq_${i}_${children[i].type}`;
260
+ const childRes = this.evaluateNode(children[i], childPath, ctx);
261
+ if (childRes.status !== "SUCCESS") {
262
+ return { status: childRes.status, activePath: childRes.activePath };
263
+ }
264
+ }
265
+ return { status: "SUCCESS", activePath: path };
266
+ }
267
+ case "selector": {
268
+ const children = node.children || [];
269
+ for (let i = 0; i < children.length; i++) {
270
+ const childPath = `${path}/sel_${i}_${children[i].type}`;
271
+ const childRes = this.evaluateNode(children[i], childPath, ctx);
272
+ if (childRes.status !== "FAILURE") {
273
+ return { status: childRes.status, activePath: childRes.activePath };
274
+ }
275
+ }
276
+ return { status: "FAILURE", activePath: path };
277
+ }
278
+ case "condition": {
279
+ const condFn = ConditionRegistry[node.name || ""] || GameConditionRegistry[node.name || ""];
280
+ const passed = condFn ? condFn(node.parameters || {}, ctx) : true;
281
+ return { status: passed ? "SUCCESS" : "FAILURE", activePath: path };
282
+ }
283
+ case "action": {
284
+ const actFn = ActionRegistry[node.name || ""] || GameActionRegistry[node.name || ""];
285
+ const actRes = actFn ? actFn(node.parameters || {}, ctx) : { status: "SUCCESS" };
286
+ return { status: actRes.status, activePath: path };
287
+ }
288
+ case "inverter": {
289
+ if (!node.children || node.children.length === 0) return { status: "SUCCESS", activePath: path };
290
+ const childRes = this.evaluateNode(node.children[0], `${path}/inv`, ctx);
291
+ if (childRes.status === "SUCCESS") return { status: "FAILURE", activePath: childRes.activePath };
292
+ if (childRes.status === "FAILURE") return { status: "SUCCESS", activePath: childRes.activePath };
293
+ return childRes;
294
+ }
295
+ case "guard": {
296
+ if (node.guard) {
297
+ const guardRes = this.evaluateNode(node.guard, `${path}/guard_cond`, ctx);
298
+ if (guardRes.status !== "SUCCESS") {
299
+ return { status: "FAILURE", activePath: guardRes.activePath };
300
+ }
301
+ } else if (node.name) {
302
+ const condFn = ConditionRegistry[node.name] || GameConditionRegistry[node.name];
303
+ const passed = condFn ? condFn(node.parameters || {}, ctx) : true;
304
+ if (!passed) {
305
+ return { status: "FAILURE", activePath: `${path}/guard_cond` };
306
+ }
307
+ }
308
+ if (!node.children || node.children.length === 0) return { status: "SUCCESS", activePath: path };
309
+ return this.evaluateNode(node.children[0], `${path}/guard_child`, ctx);
310
+ }
311
+ case "timeout": {
312
+ const timeoutMs = node.timeout_ms || node.parameters?.timeout_ms || 5e3;
313
+ const currentElapsedMs = ctx.telemetry?.tick_duration_ms !== void 0 ? ctx.telemetry.tick_duration_ms : (ctx.tick || 1) * 16.6;
314
+ if (currentElapsedMs > timeoutMs) {
315
+ return { status: "FAILURE", activePath: `${path}/timeout_exceeded` };
316
+ }
317
+ if (!node.children || node.children.length === 0) return { status: "SUCCESS", activePath: path };
318
+ return this.evaluateNode(node.children[0], `${path}/timeout_child`, ctx);
319
+ }
320
+ default:
321
+ throw new Error(`Unknown behavior tree node type: "${node?.type}" at path "${path}". Fail-closed enforced.`);
322
+ }
323
+ }
324
+ };
325
+
326
+ // src/engine/browser/injector.ts
327
+ var BrowserInjector = class {
328
+ /**
329
+ * Generates the browser evaluation script injecting the ~60Hz Behavior Tree runtime,
330
+ * safety rate limiters, and the PuterVision Game Telemetry Bridge.
331
+ */
332
+ static getInjectionScript(tree, allowlistOrigins = ["*"]) {
333
+ return `
334
+ (function() {
335
+ const allowed = ${JSON.stringify(allowlistOrigins)};
336
+ const origin = window.location.origin;
337
+ if (!allowed.includes('*') && !allowed.includes(origin)) {
338
+ console.warn('[BEHAVIOR_RUNTIME] Origin rejected: ' + origin);
339
+ return;
340
+ }
341
+
342
+ // Initialize PuterVision Global Runtime
343
+ window.__BEHAVIOR_RUNTIME__ = window.__BEHAVIOR_RUNTIME__ || {
344
+ enabled: true,
345
+ tickCount: 0,
346
+ currentStatus: 'idle',
347
+ activeNodePath: 'root',
348
+ blackboard: {},
349
+ tree: ${JSON.stringify(tree)},
350
+ };
351
+
352
+ // Initialize PuterVision Game Telemetry Bridge
353
+ window.__PUTERVISION_GAME_STATE__ = window.__PUTERVISION_GAME_STATE__ || {};
354
+ window.__PUTERVISION_TELEMETRY__ = {
355
+ update: function(telemetry) {
356
+ if (!telemetry || typeof telemetry !== 'object') return;
357
+ Object.assign(window.__PUTERVISION_GAME_STATE__, telemetry);
358
+ if (window.__BEHAVIOR_RUNTIME__ && window.__BEHAVIOR_RUNTIME__.blackboard) {
359
+ Object.assign(window.__BEHAVIOR_RUNTIME__.blackboard, telemetry);
360
+ }
361
+ },
362
+ get: function() {
363
+ return Object.assign({}, window.__PUTERVISION_GAME_STATE__);
364
+ },
365
+ clear: function() {
366
+ window.__PUTERVISION_GAME_STATE__ = {};
367
+ }
368
+ };
369
+
370
+ // Listen for standard custom telemetry events dispatched by web games
371
+ window.addEventListener('putervision:telemetry', function(evt) {
372
+ if (evt.detail && window.__PUTERVISION_TELEMETRY__) {
373
+ window.__PUTERVISION_TELEMETRY__.update(evt.detail);
374
+ }
375
+ });
376
+
377
+ console.log('[BEHAVIOR_RUNTIME] Injected behavior runtime & PuterVision telemetry bridge for tree: ' + '${tree.id || "root"}');
378
+ })();
379
+ `;
380
+ }
381
+ };
382
+ export {
383
+ AbortBehaviorSchema,
384
+ ActionRateLimiter,
385
+ ActionRegistry,
386
+ BehaviorRegistry,
387
+ BehaviorRuntimeError,
388
+ BehaviorTreeEvaluator,
389
+ BrowserInjector,
390
+ ConditionRegistry,
391
+ DatabaseError,
392
+ EmergencySafety,
393
+ ExecutionEngine,
394
+ ExecutionError,
395
+ GameActionRegistry,
396
+ GameConditionRegistry,
397
+ GetMetricsSchema,
398
+ GetStatusSchema,
399
+ LOG_LEVELS,
400
+ LoadBehaviorSchema,
401
+ ManageBehaviorsSchema,
402
+ ManageBlackboardSchema,
403
+ ManageRuntimeDbSchema,
404
+ MetricsEngine,
405
+ NotFoundError,
406
+ PolicyGate,
407
+ RegisterTriggerSchema,
408
+ ReplayRecordingSchema,
409
+ SafetyError,
410
+ SetParametersSchema,
411
+ SnapshotEngine,
412
+ StuckDetector,
413
+ TriggerRegistry,
414
+ ValidationError,
415
+ WatchdogTimer,
416
+ closeAllDbs,
417
+ closeDb,
418
+ computeEventHash,
419
+ computeTreeHash,
420
+ generateId,
421
+ getBaseDir,
422
+ getCurrentIsoString,
423
+ getDb,
424
+ getDbPath,
425
+ getElapsedTimeMs,
426
+ getLogLevel,
427
+ getProjectDbDir,
428
+ getProjectSlug,
429
+ getReadOnlyDb,
430
+ getRegistry,
431
+ getRegistryPath,
432
+ logRuntimeEvent,
433
+ logger,
434
+ parseIsoString,
435
+ registerProject,
436
+ resolveProjectRoot,
437
+ sanitizeSlug,
438
+ server,
439
+ unregisterProject,
440
+ validatePath,
441
+ verifyEventChain
442
+ };
443
+ //# sourceMappingURL=lib.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schema/schemas.ts","../src/engine/browser/conditions.ts","../src/engine/browser/conditions-game.ts","../src/engine/browser/actions.ts","../src/engine/browser/actions-game.ts","../src/engine/browser/executor-bundle.ts","../src/engine/browser/injector.ts"],"sourcesContent":["import { z } from 'zod';\n\nexport const LoadBehaviorSchema = z.object({\n action: z.enum(['load', 'unload', 'swap']),\n behavior_name: z.string(),\n behavior_version: z.number().optional(),\n parameters: z.record(z.any()).optional(),\n session_id: z.string().optional(),\n intention_id: z.string().optional(),\n client_request_id: z.string().optional(),\n project: z.string().optional(),\n});\n\nexport const SetParametersSchema = z.object({\n action: z.enum(['set', 'get', 'reset']),\n execution_id: z.string().optional(),\n parameters: z.record(z.any()).optional(),\n project: z.string().optional(),\n});\n\nexport const GetStatusSchema = z.object({\n action: z.enum(['current', 'history', 'tree_state']),\n execution_id: z.string().optional(),\n limit: z.number().optional(),\n project: z.string().optional(),\n});\n\nexport const AbortBehaviorSchema = z.object({\n action: z.enum(['abort', 'pause', 'resume']),\n execution_id: z.string().optional(),\n reason: z.string().optional(),\n project: z.string().optional(),\n});\n\nexport const RegisterTriggerSchema = z.object({\n action: z.enum(['register', 'list', 'update', 'remove', 'enable', 'disable']),\n name: z.string().optional(),\n behavior_name: z.string().optional(),\n condition_type: z.string().optional(),\n condition_params: z.record(z.any()).optional(),\n priority: z.number().optional(),\n cooldown_ms: z.number().optional(),\n trigger_id: z.string().optional(),\n project: z.string().optional(),\n});\n\nexport const ReplayRecordingSchema = z.object({\n action: z.enum(['start', 'stop', 'list', 'capture', 'delete']),\n name: z.string().optional(),\n recording_id: z.string().optional(),\n frames: z.array(z.any()).optional(),\n project: z.string().optional(),\n});\n\nexport const GetMetricsSchema = z.object({\n action: z.enum(['current', 'history', 'aggregate', 'compare']),\n execution_id: z.string().optional(),\n behavior_name: z.string().optional(),\n limit: z.number().optional(),\n project: z.string().optional(),\n});\n\nexport const ManageBehaviorsSchema = z.object({\n action: z.enum(['register', 'list', 'get', 'update', 'delete', 'export', 'import']),\n name: z.string().optional(),\n version: z.number().optional(),\n description: z.string().optional(),\n tree: z.any().optional(),\n tree_json: z.string().optional(),\n client_request_id: z.string().optional(),\n project: z.string().optional(),\n});\n\nexport const ManageBlackboardSchema = z.object({\n action: z.enum(['get', 'set', 'clear', 'dump']),\n execution_id: z.string().optional(),\n key: z.string().optional(),\n value: z.any().optional(),\n blackboard: z.record(z.any()).optional(),\n project: z.string().optional(),\n});\n\nexport const ManageRuntimeDbSchema = z.object({\n action: z.enum(['backup', 'stats', 'audit', 'snapshot', 'diff', 'restore']),\n name: z.string().optional(),\n description: z.string().optional(),\n project: z.string().optional(),\n});\n","import { RuntimeContext } from './node-types.js';\n\nexport const ConditionRegistry: Record<\n string,\n (params: Record<string, unknown>, ctx: RuntimeContext) => boolean\n> = {\n timer_elapsed: (params, ctx) => {\n const threshold = (params.threshold_ticks as number) || 60;\n return ctx.tick >= threshold;\n },\n blackboard_check: (params, ctx) => {\n const key = params.key as string;\n const expected = params.expected;\n return ctx.blackboard[key] === expected;\n },\n proximity_check: (params, ctx) => {\n const dist = (ctx.telemetry.target_distance as number) ?? 999;\n const radius = (params.radius as number) ?? 10;\n return dist <= radius;\n },\n};\n","import { RuntimeContext } from './node-types.js';\n\nexport const GameConditionRegistry: Record<\n string,\n (params: Record<string, unknown>, ctx: RuntimeContext) => boolean\n> = {\n hp_below: (params, ctx) => {\n const hp = (ctx.telemetry.hp as number) ?? 100;\n const threshold = (params.threshold as number) ?? 30;\n return hp < threshold;\n },\n enemy_in_range: (params, ctx) => {\n const enemyDist = (ctx.telemetry.enemy_distance as number) ?? 999;\n const range = (params.range as number) ?? 15;\n return enemyDist <= range;\n },\n resource_above: (params, ctx) => {\n const amount = (ctx.blackboard.resource_count as number) ?? 0;\n const capacity = (params.capacity as number) ?? 20;\n return amount >= capacity;\n },\n};\n","import { RuntimeContext } from './node-types.js';\nimport { NodeStatus } from '../../schema/types.js';\n\nexport const ActionRegistry: Record<\n string,\n (params: Record<string, unknown>, ctx: RuntimeContext) => { status: NodeStatus; output?: Record<string, unknown> }\n> = {\n move_to: (params, ctx) => {\n ctx.blackboard.current_destination = params.destination || [0, 0, 0];\n return { status: 'SUCCESS', output: { destination: ctx.blackboard.current_destination } };\n },\n wait: (params, ctx) => {\n const ticks = (params.ticks as number) || 10;\n if (ctx.tick % ticks === 0) return { status: 'SUCCESS' };\n return { status: 'RUNNING' };\n },\n interact: (params, ctx) => {\n ctx.blackboard.last_interaction = params.target || 'object';\n return { status: 'SUCCESS', output: { interacted_with: ctx.blackboard.last_interaction } };\n },\n log: (params, ctx) => {\n return { status: 'SUCCESS', output: { message: params.message || 'Log action executed' } };\n },\n cast_spell: (params, ctx) => {\n ctx.blackboard.last_spell = params.spell || 'default_spell';\n return { status: 'SUCCESS', output: { spell: ctx.blackboard.last_spell } };\n },\n swing_sword: (params, ctx) => {\n ctx.blackboard.last_combat_action = 'swing_sword';\n return { status: 'SUCCESS', output: { combat: 'melee' } };\n },\n shoot_arrow: (params, ctx) => {\n ctx.blackboard.last_combat_action = 'shoot_arrow';\n return { status: 'SUCCESS', output: { combat: 'ranged' } };\n },\n patrol_area: (params, ctx) => {\n ctx.blackboard.patrolling = true;\n return { status: 'SUCCESS', output: { patrol: true } };\n },\n patrol: (params, ctx) => {\n ctx.blackboard.patrolling = true;\n return { status: 'SUCCESS', output: { patrol: true } };\n },\n};\n","import { RuntimeContext } from './node-types.js';\nimport { NodeStatus } from '../../schema/types.js';\n\nexport const GameActionRegistry: Record<\n string,\n (params: Record<string, unknown>, ctx: RuntimeContext) => { status: NodeStatus; output?: Record<string, unknown> }\n> = {\n attack_nearest: (params, ctx) => {\n ctx.blackboard.last_attack_target = 'nearest_enemy';\n return { status: 'SUCCESS', output: { action: 'attack', target: 'nearest_enemy' } };\n },\n flee_to_safety: (params, ctx) => {\n ctx.blackboard.fleeing = true;\n return { status: 'SUCCESS', output: { action: 'flee', waypoint: 'base' } };\n },\n gather: (params, ctx) => {\n const current = (ctx.blackboard.resource_count as number) || 0;\n ctx.blackboard.resource_count = current + 1;\n return { status: 'SUCCESS', output: { resource_count: ctx.blackboard.resource_count } };\n },\n heal: (params, ctx) => {\n ctx.blackboard.healing = true;\n return { status: 'SUCCESS', output: { action: 'use_potion' } };\n },\n};\n","import { BehaviorTreeNode, NodeStatus } from '../../schema/types.js';\nimport { ConditionRegistry } from './conditions.js';\nimport { GameConditionRegistry } from './conditions-game.js';\nimport { ActionRegistry } from './actions.js';\nimport { GameActionRegistry } from './actions-game.js';\n\nexport class BehaviorTreeEvaluator {\n private tree: BehaviorTreeNode;\n private blackboard: Record<string, unknown>;\n private tickCount: number = 0;\n\n constructor(tree: BehaviorTreeNode, initialBlackboard: Record<string, unknown> = {}) {\n this.tree = tree;\n this.blackboard = { ...initialBlackboard };\n }\n\n public step(telemetry: Record<string, unknown> = {}): { status: NodeStatus; activePath: string; blackboard: Record<string, unknown> } {\n this.tickCount++;\n const ctx = {\n blackboard: this.blackboard,\n telemetry,\n tick: this.tickCount,\n };\n\n const res = this.evaluateNode(this.tree, 'root', ctx);\n return {\n status: res.status,\n activePath: res.activePath,\n blackboard: this.blackboard,\n };\n }\n\n private evaluateNode(node: BehaviorTreeNode, path: string, ctx: any): { status: NodeStatus; activePath: string } {\n switch (node.type) {\n case 'sequence': {\n const children = node.children || [];\n for (let i = 0; i < children.length; i++) {\n const childPath = `${path}/seq_${i}_${children[i].type}`;\n const childRes = this.evaluateNode(children[i], childPath, ctx);\n if (childRes.status !== 'SUCCESS') {\n return { status: childRes.status, activePath: childRes.activePath };\n }\n }\n return { status: 'SUCCESS', activePath: path };\n }\n\n case 'selector': {\n const children = node.children || [];\n for (let i = 0; i < children.length; i++) {\n const childPath = `${path}/sel_${i}_${children[i].type}`;\n const childRes = this.evaluateNode(children[i], childPath, ctx);\n if (childRes.status !== 'FAILURE') {\n return { status: childRes.status, activePath: childRes.activePath };\n }\n }\n return { status: 'FAILURE', activePath: path };\n }\n\n case 'condition': {\n const condFn = ConditionRegistry[node.name || ''] || GameConditionRegistry[node.name || ''];\n const passed = condFn ? condFn(node.parameters || {}, ctx) : true;\n return { status: (passed ? 'SUCCESS' : 'FAILURE') as NodeStatus, activePath: path };\n }\n\n case 'action': {\n const actFn = ActionRegistry[node.name || ''] || GameActionRegistry[node.name || ''];\n const actRes = actFn ? actFn(node.parameters || {}, ctx) : { status: 'SUCCESS' as NodeStatus };\n return { status: actRes.status as NodeStatus, activePath: path };\n }\n\n case 'inverter': {\n if (!node.children || node.children.length === 0) return { status: 'SUCCESS', activePath: path };\n const childRes = this.evaluateNode(node.children[0], `${path}/inv`, ctx);\n if (childRes.status === 'SUCCESS') return { status: 'FAILURE', activePath: childRes.activePath };\n if (childRes.status === 'FAILURE') return { status: 'SUCCESS', activePath: childRes.activePath };\n return childRes;\n }\n\n case 'guard': {\n if (node.guard) {\n const guardRes = this.evaluateNode(node.guard, `${path}/guard_cond`, ctx);\n if (guardRes.status !== 'SUCCESS') {\n return { status: 'FAILURE', activePath: guardRes.activePath };\n }\n } else if (node.name) {\n const condFn = ConditionRegistry[node.name] || GameConditionRegistry[node.name];\n const passed = condFn ? condFn(node.parameters || {}, ctx) : true;\n if (!passed) {\n return { status: 'FAILURE', activePath: `${path}/guard_cond` };\n }\n }\n if (!node.children || node.children.length === 0) return { status: 'SUCCESS', activePath: path };\n return this.evaluateNode(node.children[0], `${path}/guard_child`, ctx);\n }\n\n case 'timeout': {\n const timeoutMs = node.timeout_ms || (node.parameters?.timeout_ms as number) || 5000;\n const currentElapsedMs =\n (ctx.telemetry?.tick_duration_ms as number) !== undefined\n ? (ctx.telemetry.tick_duration_ms as number)\n : (ctx.tick || 1) * 16.6;\n if (currentElapsedMs > timeoutMs) {\n return { status: 'FAILURE', activePath: `${path}/timeout_exceeded` };\n }\n if (!node.children || node.children.length === 0) return { status: 'SUCCESS', activePath: path };\n return this.evaluateNode(node.children[0], `${path}/timeout_child`, ctx);\n }\n\n default:\n throw new Error(`Unknown behavior tree node type: \"${(node as any)?.type}\" at path \"${path}\". Fail-closed enforced.`);\n }\n }\n}\n","import { BehaviorTreeNode } from '../../schema/types.js';\n\nexport interface GameTelemetryPayload {\n hp?: number;\n max_hp?: number;\n mana?: number;\n max_mana?: number;\n stamina?: number;\n position?: { x: number; y: number; z?: number };\n inventory_weight?: number;\n inventory?: Array<{ id: string; name: string; quantity: number }>;\n enemies_in_range?: number;\n target_id?: string;\n in_combat?: boolean;\n metadata?: Record<string, unknown>;\n}\n\nexport class BrowserInjector {\n /**\n * Generates the browser evaluation script injecting the ~60Hz Behavior Tree runtime,\n * safety rate limiters, and the PuterVision Game Telemetry Bridge.\n */\n static getInjectionScript(tree: BehaviorTreeNode, allowlistOrigins: string[] = ['*']): string {\n return `\n (function() {\n const allowed = ${JSON.stringify(allowlistOrigins)};\n const origin = window.location.origin;\n if (!allowed.includes('*') && !allowed.includes(origin)) {\n console.warn('[BEHAVIOR_RUNTIME] Origin rejected: ' + origin);\n return;\n }\n\n // Initialize PuterVision Global Runtime\n window.__BEHAVIOR_RUNTIME__ = window.__BEHAVIOR_RUNTIME__ || {\n enabled: true,\n tickCount: 0,\n currentStatus: 'idle',\n activeNodePath: 'root',\n blackboard: {},\n tree: ${JSON.stringify(tree)},\n };\n\n // Initialize PuterVision Game Telemetry Bridge\n window.__PUTERVISION_GAME_STATE__ = window.__PUTERVISION_GAME_STATE__ || {};\n window.__PUTERVISION_TELEMETRY__ = {\n update: function(telemetry) {\n if (!telemetry || typeof telemetry !== 'object') return;\n Object.assign(window.__PUTERVISION_GAME_STATE__, telemetry);\n if (window.__BEHAVIOR_RUNTIME__ && window.__BEHAVIOR_RUNTIME__.blackboard) {\n Object.assign(window.__BEHAVIOR_RUNTIME__.blackboard, telemetry);\n }\n },\n get: function() {\n return Object.assign({}, window.__PUTERVISION_GAME_STATE__);\n },\n clear: function() {\n window.__PUTERVISION_GAME_STATE__ = {};\n }\n };\n\n // Listen for standard custom telemetry events dispatched by web games\n window.addEventListener('putervision:telemetry', function(evt) {\n if (evt.detail && window.__PUTERVISION_TELEMETRY__) {\n window.__PUTERVISION_TELEMETRY__.update(evt.detail);\n }\n });\n\n console.log('[BEHAVIOR_RUNTIME] Injected behavior runtime & PuterVision telemetry bridge for tree: ' + '${tree.id || \"root\"}');\n })();\n `;\n }\n}\n"],"mappings":"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","names":[]}
package/glama.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "$schema": "https://glama.ai/mcp/schemas/server.json",
3
+ "name": "behavior-mcp",
4
+ "title": "Behavior MCP",
5
+ "description": "In-browser ~60Hz behavior tree execution engine with reactive triggers and safety.",
6
+ "maintainers": [
7
+ "putervision"
8
+ ],
9
+ "author": "PuterVision",
10
+ "license": "MIT",
11
+ "homepage": "https://putervision.com",
12
+ "repository": "https://github.com/putervision/behavior-mcp",
13
+ "categories": [
14
+ "developer-tools",
15
+ "ai-agents",
16
+ "behavior-trees",
17
+ "automation"
18
+ ],
19
+ "tags": [
20
+ "mcp",
21
+ "model-context-protocol",
22
+ "behavior-tree",
23
+ "behavior-mcp",
24
+ "60hz",
25
+ "in-browser-execution",
26
+ "playwright",
27
+ "game-ai",
28
+ "sqlite",
29
+ "cursor",
30
+ "claude-code"
31
+ ],
32
+ "keywords": [
33
+ "behavior-tree",
34
+ "behavior-mcp",
35
+ "runtime",
36
+ "60hz",
37
+ "browser-automation",
38
+ "triggers",
39
+ "action-replay",
40
+ "putervision",
41
+ "ai-agents",
42
+ "mcp"
43
+ ]
44
+ }
package/manifest.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "manifest_version": "0.2",
3
+ "name": "@putervision/behavior-mcp",
4
+ "version": "0.1.1",
5
+ "description": "In-browser ~60Hz behavior tree execution engine with reactive triggers and safety.",
6
+ "author": {
7
+ "name": "PuterVision"
8
+ },
9
+ "homepage": "https://github.com/putervision/behavior-mcp#readme",
10
+ "server": {
11
+ "type": "node",
12
+ "entry_point": "./dist/index.js",
13
+ "mcp_config": {
14
+ "command": "node",
15
+ "args": [
16
+ "${__dirname}/./dist/index.js"
17
+ ],
18
+ "env": {}
19
+ }
20
+ },
21
+ "license": "MIT",
22
+ "repository": {
23
+ "type": "git",
24
+ "url": "https://github.com/putervision/behavior-mcp.git"
25
+ }
26
+ }