-
Notifications
You must be signed in to change notification settings - Fork 0
Tools
Tools are resources the planner can invoke. They are very loosely modelled on the simpler forms of Anthropic Skills, but strict compatibility is neither intended not likely forthcoming.
- They come in two flavors: primitives (core hardoced infospace operations) and external.
- External tools can be any one of three types:
- instruction tools are text that is added to the planner context - generally 'how to' hints
- llm tools contain a text prompt and invoke the internal llm
- Python tools run the tool method in a required tool.py file in the same directory as the Skill.md
A Note is a single persisted resource that contains either:
- Text (free-form narrative, excerpts, logs, etc.), or
- A structured object (dict/JSON) for machine-readable state/results.
Notes are the primary unit of memory and interchange between tools and planner.
A Collection is an ordered list of Notes. Common producers:
- web / academic search tools
- filters and transforms (
filter-*,map,project,pluck, joins) - batching (group related Notes for later summarization or extraction)
Most “built-in” tools are CRUD + processing primitives over Notes and Collections:
- CRUD: create notes, load notes, save notes, store results
- Processing: map/filter/join/project/transform/summarize/extract## Tool Structure Each tool is defined by its Skill.md file:
-
Skill.md: Tool interface/contract- frontmatter: name, type, and short description (strict format)
- inputs / outputs (contract)
- behavior and “when to use” guidance (tool selection)
- In addition, python tools require a
tool.py: Implementation (for Python tools only) - While some minecraft world tools directly invoke other tools for efficiency, most tools should be written to return results to the planner.
Tool Locations:
- Core tools:
src/tools/<tool-name>/ - World tools:
src/world-tools/<world_name>/<tool-name>/
**The easiest way to understand tools is to look at one of the simpler existing tools of the type you are interested in.
- At the planner / reasoning level, tools create a Note or Collection, as described above (if a text or dict is returned, a Note will be created to wrap the return by the InfospaceExecutor.
- At the engineering level, all python tools must return a uniform dictionary** via
InfospaceExecutor._create_uniform_return():
{
"status": "success" | "failed",
"data": <raw_value>, # Dict/list/etc. on success, or reason/value on failure
"value": <formatted_string>, # Display/logging string (may be truncated)
"reason": <failure_reason>, # Only present on failure
"resource_id": <resource_id> # Optional: ID of created/updated resource
}Critical: When consuming tool outputs programmatically, use result["data"], not result["value"]. The value field is for display/logging and may be truncated.
The planner sees tools grouped by source:
-
World tools first (e.g.,
#MINECRAFT) -
Core infospace tools (
#INFOSPACE CORE)
Each tool entry includes:
-
description: Brief description for tool catalog -
source:"core"or"<world_name>" -
schema_hint: JSON schema for arguments (if available) -
type:"method"for method tools, omitted for standard tools
Built-in infospace operations executed directly by InfospaceExecutor:
Storage:
-
save,load,create-note,create-collection
Computation:
-
apply,map,coerce
Indexing & Search:
-
index,search-notes,search-collections,search-within-collection
Structured Operations:
-
project,pluck,filter-structured,sort,join
Communication:
-
say,think
Custom tools implemented in Python. Must follow conventions:
Function Signature:
def tool(input_value=None, **kwargs):
executor: InfospaceExecutor = kwargs.get("executor")
if not executor:
return executor._create_uniform_return(
status="failed",
reason="executor not available",
value=None
)
# ... tool logic ...
return executor._create_uniform_return(
status="success",
data=<raw_result>,
value=<formatted_string>
)Required:
- Top-level
tool()function - Retrieve
executorfromkwargs - Use
executor._create_uniform_return()for all returns - Use
executor.execute_action_with_log()for nested tool calls
Special tools that define protocols rather than direct actions. The planner executes these as bounded inner loops.
Characteristics:
- Defined with
type: methodinSkill.mdfrontmatter - Protocol defined as numbered steps in
Skill.mdbody - Planner interprets protocol and selects tools at each step
- Cannot invoke other method tools (prevents recursion)
See Method-Tools for detailed documentation.
Tools are loaded on executor initialization:
- Core tools from
src/tools/(always loaded) - World tools from
src/world-tools/<world_name>/(ifworld_config.world_nameis set)
Tools are discovered by scanning subdirectories for Skill.md files.
Planner selects tool
└─> InfospaceExecutor.execute_action()
├─> If primitive → execute directly
├─> If Python tool → import and call tool()
└─> If method tool → run_method_protocol() (inner loop)
└─> Planner executes protocol steps iteratively
-
Always use
_create_uniform_return(): Ensures consistent format -
Return raw data in
data: Don't truncate or format fordatafield -
Format
valuefor display: Human-readable string for logging/UI -
Handle executor absence: Check for
executorin kwargs -
Use
execute_action_with_log(): For nested tool calls (ensures logging) -
Document clearly:
Skill.mdshould be precise and minimal for LLM consumption