behaviortrees 0.0.0-stage → 0.1.0
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/LICENSE +661 -0
- package/LICENSE-MIT +28 -0
- package/README.md +81 -2
- package/dist/chunks/chunk-7LANS4ZA.js +130 -0
- package/dist/chunks/chunk-QW4NPMSB.js +6 -0
- package/dist/chunks/chunk-VTXL3OVS.js +1902 -0
- package/dist/chunks/mcp-CHN7W7L5.js +8 -0
- package/dist/cli.js +169 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +24 -0
- package/dist/mcp.d.ts +7 -0
- package/dist/mcp.js +43 -0
- package/package.json +63 -3
package/LICENSE-MIT
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
This editor is licensed under the AGPL-3.0 (see LICENSE), but portions of it
|
|
2
|
+
are derived from behavior3editor (https://github.com/behavior3/behavior3editor),
|
|
3
|
+
which is licensed under the MIT License reproduced below. Notably:
|
|
4
|
+
|
|
5
|
+
- src/lib/behavior/organize.ts (port of the original OrganizeManager)
|
|
6
|
+
- src/lib/behavior/b3.ts (derived from the original ExportManager/ImportManager)
|
|
7
|
+
|
|
8
|
+
The MIT License (MIT)
|
|
9
|
+
|
|
10
|
+
Copyright (c) 2014 Renato de Pontes Pereira
|
|
11
|
+
|
|
12
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
13
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
14
|
+
in the Software without restriction, including without limitation the rights
|
|
15
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
16
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
17
|
+
furnished to do so, subject to the following conditions:
|
|
18
|
+
|
|
19
|
+
The above copyright notice and this permission notice shall be included in all
|
|
20
|
+
copies or substantial portions of the Software.
|
|
21
|
+
|
|
22
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
23
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
24
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
25
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
26
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
27
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
28
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,82 @@
|
|
|
1
|
-
#
|
|
1
|
+
# behaviortrees
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Validate, convert and share behavior trees from the command line or any MCP client. It uses the same code as the free visual editor at [behaviortrees.com](https://www.behaviortrees.com), so what it accepts, the editor opens.
|
|
4
|
+
|
|
5
|
+
- **Validate** behavior3 JSON and BehaviorTree.CPP XML: dangling children, nodes with two parents, cycles, decorators with more than one child, leaves with children, unknown node names.
|
|
6
|
+
- **Convert** between behavior3 JSON and BehaviorTree.CPP XML (v4 for ROS 2 Jazzy and Groot2, v3 for ROS 2 Humble).
|
|
7
|
+
- **Link**: turn a tree into a URL that opens it in the editor, laid out and editable. The tree travels inside the link, so nothing is uploaded.
|
|
8
|
+
|
|
9
|
+
## CLI
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npx behaviortrees validate tree.json
|
|
13
|
+
npx behaviortrees convert tree.json --to btcpp-v4 -o tree.xml
|
|
14
|
+
npx behaviortrees convert nav2_tree.xml --to behavior3
|
|
15
|
+
npx behaviortrees link tree.json --open
|
|
16
|
+
npx behaviortrees nodes # built-in node types
|
|
17
|
+
npx behaviortrees examples # example trees; add an id to print one
|
|
18
|
+
npx behaviortrees guides # behaviortrees.com guides; add a slug to read one
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Leave out the file, or pass `-`, to read from stdin. `--json` gives machine-readable output, and `validate` exits with status 1 when a tree has errors, so it works in CI.
|
|
22
|
+
|
|
23
|
+
## MCP server
|
|
24
|
+
|
|
25
|
+
Lets an AI assistant write a behavior tree, check it, and hand you a link that opens it in the editor. Tools: `validate_tree`, `create_editor_link`, `convert_tree`, `list_node_types`, `get_example`, `read_guide`.
|
|
26
|
+
|
|
27
|
+
Remote, nothing to install (Streamable HTTP):
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
https://www.behaviortrees.com/mcp
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Or run it locally over stdio:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"mcpServers": {
|
|
38
|
+
"behaviortrees": { "command": "npx", "args": ["-y", "behaviortrees", "mcp"] }
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
For Claude Code: `claude mcp add --transport http behaviortrees https://www.behaviortrees.com/mcp`
|
|
44
|
+
|
|
45
|
+
## Tree format
|
|
46
|
+
|
|
47
|
+
A minimal behavior3 tree. Positions are optional; the editor lays the tree out.
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"title": "Guard",
|
|
52
|
+
"root": "a",
|
|
53
|
+
"nodes": {
|
|
54
|
+
"a": { "name": "Priority", "children": ["b", "c"] },
|
|
55
|
+
"b": { "name": "Sequence", "children": ["d", "e"] },
|
|
56
|
+
"c": { "name": "Patrol" },
|
|
57
|
+
"d": { "name": "IsEnemyVisible" },
|
|
58
|
+
"e": { "name": "Attack" }
|
|
59
|
+
},
|
|
60
|
+
"custom_nodes": [
|
|
61
|
+
{ "name": "IsEnemyVisible", "category": "condition" },
|
|
62
|
+
{ "name": "Attack", "category": "action" },
|
|
63
|
+
{ "name": "Patrol", "category": "action" }
|
|
64
|
+
]
|
|
65
|
+
}
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Composites list `children` in run order, decorators have one `child`, and anything else is a leaf. `Priority` is behavior3's selector (fallback). Declare any node that isn't built in under `custom_nodes`.
|
|
69
|
+
|
|
70
|
+
## Library
|
|
71
|
+
|
|
72
|
+
```js
|
|
73
|
+
import { validateTree, convertTree, createEditorLink } from 'behaviortrees';
|
|
74
|
+
|
|
75
|
+
const { valid, findings } = await validateTree(json);
|
|
76
|
+
const { output } = await convertTree(json, 'btcpp-v4');
|
|
77
|
+
const { url } = await createEditorLink(json);
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
AGPL-3.0-only (see LICENSE). Portions are derived from the MIT-licensed [behavior3editor](https://github.com/behavior3/behavior3editor) by Renato de Pontes Pereira (see LICENSE-MIT). Source: [github.com/behaviortrees/behaviortrees](https://github.com/behaviortrees/behaviortrees/tree/main/packages/cli).
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import {
|
|
2
|
+
VERSION
|
|
3
|
+
} from "./chunk-QW4NPMSB.js";
|
|
4
|
+
import {
|
|
5
|
+
CONVERT_TARGETS,
|
|
6
|
+
SITE,
|
|
7
|
+
convertTree,
|
|
8
|
+
createEditorLink,
|
|
9
|
+
getExample,
|
|
10
|
+
listExamples,
|
|
11
|
+
listGuides,
|
|
12
|
+
listNodeTypes,
|
|
13
|
+
readGuide,
|
|
14
|
+
validateTree
|
|
15
|
+
} from "./chunk-VTXL3OVS.js";
|
|
16
|
+
|
|
17
|
+
// src/mcp.ts
|
|
18
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
19
|
+
import { z } from "zod";
|
|
20
|
+
var INSTRUCTIONS = `Tools for behavior trees (game AI and robotics) from ${SITE}, a free online visual behavior tree editor.
|
|
21
|
+
|
|
22
|
+
Typical flow when a user wants a behavior tree: write it as behavior3 JSON, check it with validate_tree, fix any errors, then call create_editor_link and give the user the link. It opens the tree in the editor in their browser, laid out and editable, with no account needed. convert_tree turns behavior3 JSON into BehaviorTree.CPP XML (Groot2, ROS 2 Nav2) and back. list_node_types shows the built-in nodes; get_example returns complete example trees to copy from; read_guide explains concepts.`;
|
|
23
|
+
var TREE_FORMAT = `behavior3 JSON: {"title": "...", "root": "<id of the first node under the root>", "nodes": {"<id>": {"name": "<node type>", "title": "<optional label>", "children": ["<id>", ...] (composites, in run order) or "child": "<id>" (decorators), "properties": {...}}}, "custom_nodes": [{"name": "IsEnemyVisible", "category": "condition"}]}. Positions ("display") are optional. Any node name that isn't built in (see list_node_types) must be declared in custom_nodes with a category of action, condition, composite or decorator. A whole project ({"trees": [...], "custom_nodes": [...]}) or BehaviorTree.CPP XML also works.`;
|
|
24
|
+
var treeInput = z.union([z.string(), z.record(z.unknown())]).describe(`The tree: ${TREE_FORMAT}`);
|
|
25
|
+
var text = (value) => ({
|
|
26
|
+
content: [{ type: "text", text: typeof value === "string" ? value : JSON.stringify(value, null, 2) }]
|
|
27
|
+
});
|
|
28
|
+
var failure = (error) => ({
|
|
29
|
+
content: [{ type: "text", text: error instanceof Error ? error.message : String(error) }],
|
|
30
|
+
isError: true
|
|
31
|
+
});
|
|
32
|
+
function createMcpServer() {
|
|
33
|
+
const server = new McpServer({ name: "behaviortrees", title: "Behavior Trees", version: VERSION }, { instructions: INSTRUCTIONS });
|
|
34
|
+
const readOnly = { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false };
|
|
35
|
+
server.registerTool(
|
|
36
|
+
"validate_tree",
|
|
37
|
+
{
|
|
38
|
+
title: "Validate a behavior tree",
|
|
39
|
+
description: `Check a behavior tree for errors before using it: missing or dangling children, nodes with two parents, cycles, decorators with more than one child, leaves with children, unknown node names, and BehaviorTree.CPP import problems. Returns valid (true when there are no errors), the trees found, and findings at error, warning or info level.`,
|
|
40
|
+
inputSchema: { tree: treeInput },
|
|
41
|
+
annotations: readOnly
|
|
42
|
+
},
|
|
43
|
+
async ({ tree }) => text(await validateTree(tree))
|
|
44
|
+
);
|
|
45
|
+
server.registerTool(
|
|
46
|
+
"create_editor_link",
|
|
47
|
+
{
|
|
48
|
+
title: "Open a tree in the editor",
|
|
49
|
+
description: `Make a link that opens the tree in the behaviortrees.com editor in the user's browser, auto-laid-out and editable, with no account needed. The tree travels inside the link (the URL fragment), so nothing is uploaded or stored. The tree must validate without errors. Give the user the returned url.`,
|
|
50
|
+
inputSchema: { tree: treeInput },
|
|
51
|
+
annotations: readOnly
|
|
52
|
+
},
|
|
53
|
+
async ({ tree }) => {
|
|
54
|
+
try {
|
|
55
|
+
return text(await createEditorLink(tree));
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return failure(error);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
server.registerTool(
|
|
62
|
+
"convert_tree",
|
|
63
|
+
{
|
|
64
|
+
title: "Convert a behavior tree",
|
|
65
|
+
description: "Convert between behavior3 JSON and BehaviorTree.CPP XML (v4 for ROS 2 Jazzy and Groot2, v3 for ROS 2 Humble), the same way the editor imports and exports. Returns the converted text and any issues (BT.CPP has no equivalent for some behavior3 nodes and vice versa).",
|
|
66
|
+
inputSchema: {
|
|
67
|
+
tree: treeInput,
|
|
68
|
+
to: z.enum(CONVERT_TARGETS).describe("Target format: behavior3, btcpp-v4 or btcpp-v3")
|
|
69
|
+
},
|
|
70
|
+
annotations: readOnly
|
|
71
|
+
},
|
|
72
|
+
async ({ tree, to }) => {
|
|
73
|
+
try {
|
|
74
|
+
const result = await convertTree(tree, to);
|
|
75
|
+
const issues = result.issues.length ? `
|
|
76
|
+
|
|
77
|
+
Issues:
|
|
78
|
+
${result.issues.map((issue) => `- ${issue.level}: ${issue.message}`).join("\n")}` : "";
|
|
79
|
+
return text(`${result.output}${issues}`);
|
|
80
|
+
} catch (error) {
|
|
81
|
+
return failure(error);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
server.registerTool(
|
|
86
|
+
"list_node_types",
|
|
87
|
+
{
|
|
88
|
+
title: "List built-in node types",
|
|
89
|
+
description: "The built-in behavior3 nodes a tree can use without declaring them: composites (Sequence, Priority = selector/fallback, MemSequence, MemPriority), decorators (Inverter, Repeater, MaxTime, ...) and leaves (Wait, Succeeder, Failer, ...), with descriptions and default properties.",
|
|
90
|
+
inputSchema: {},
|
|
91
|
+
annotations: readOnly
|
|
92
|
+
},
|
|
93
|
+
async () => text(listNodeTypes())
|
|
94
|
+
);
|
|
95
|
+
server.registerTool(
|
|
96
|
+
"get_example",
|
|
97
|
+
{
|
|
98
|
+
title: "Get an example tree",
|
|
99
|
+
description: "Complete, working example trees (enemy patrol, cooldown-gated attacks, robot navigation with recovery, and more) to learn the format from or start with. Without an id, lists the examples; with an id, returns that tree as behavior3 JSON.",
|
|
100
|
+
inputSchema: { id: z.string().optional().describe("Example id from the list; omit to list them") },
|
|
101
|
+
annotations: readOnly
|
|
102
|
+
},
|
|
103
|
+
async ({ id }) => {
|
|
104
|
+
if (!id) return text(listExamples());
|
|
105
|
+
const example = getExample(id);
|
|
106
|
+
return example ? text(example) : failure(`No example "${id}". Examples: ${listExamples().map((e) => e.id).join(", ")}`);
|
|
107
|
+
}
|
|
108
|
+
);
|
|
109
|
+
server.registerTool(
|
|
110
|
+
"read_guide",
|
|
111
|
+
{
|
|
112
|
+
title: "Read a behavior tree guide",
|
|
113
|
+
description: "Practical guides from behaviortrees.com/learn as Markdown: what behavior trees are, node types, blackboards, debugging, structuring large trees, and behavior trees in Unity, Unreal, Godot, Python and robotics (BehaviorTree.CPP, ROS 2, Nav2). Without a slug, lists the guides.",
|
|
114
|
+
inputSchema: { slug: z.string().optional().describe("Guide slug from the list; omit to list them") },
|
|
115
|
+
annotations: { ...readOnly, openWorldHint: true }
|
|
116
|
+
},
|
|
117
|
+
async ({ slug }) => {
|
|
118
|
+
try {
|
|
119
|
+
return text(slug ? await readGuide(slug) : await listGuides());
|
|
120
|
+
} catch (error) {
|
|
121
|
+
return failure(error);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
);
|
|
125
|
+
return server;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export {
|
|
129
|
+
createMcpServer
|
|
130
|
+
};
|