UAT: NodeDefinition.tool_sources field silently dropped by actor compiler — per-node tool source bindings (skills, MCP, builtins) never wired into compiled graph #3610

Open
opened 2026-04-05 20:25:22 +00:00 by freemo · 1 comment
Owner

Metadata

  • Branch: fix/actor-compiler-node-tool-sources
  • Commit Message: fix(actor): pass NodeDefinition.tool_sources through compiler into NodeConfig
  • Milestone: (none — backlog, see note below)
  • Parent Epic: #392

Background and Context

The specification defines that actor graph nodes can declare tool_sources to specify where their tools come from — skills, MCP servers, or builtin tool groups. This is a key feature for hierarchical actor composition, allowing different nodes in a graph to use different tool sets.

The NodeDefinition schema (in src/cleveragents/actor/schema.py) has a tool_sources field:

tool_sources: list[ToolSourceRef] = Field(
    default_factory=list, description="Tool source references"
)

Current Behavior

In src/cleveragents/actor/compiler.py, the _map_node() function maps NodeDefinition to lg_nodes.NodeConfig:

def _map_node(node: NodeDefinition) -> lg_nodes.NodeConfig:
    lg_type = _NODE_TYPE_MAP.get(node.type, lg_nodes.NodeType.FUNCTION)
    config = node.config
    return lg_nodes.NodeConfig(
        name=node.id,
        type=lg_type,
        agent=config.get("agent") if node.type == NodeType.AGENT else None,
        function=config.get("function") if node.type == NodeType.CONDITIONAL else None,
        tools=config.get("tools", []) if node.type == NodeType.TOOL else [],
        subgraph=(config.get("actor_ref") if node.type == NodeType.SUBGRAPH else None),
        metadata=dict(config),
    )

The node.tool_sources field is never passed to NodeConfig. The NodeConfig model in src/cleveragents/langgraph/nodes.py also has no tool_sources field, so per-node tool source bindings are completely lost during compilation.

This means that when a node declares:

tool_sources:
  - type: skill
    name: local/file-ops
  - type: mcp
    name: local/filesystem

These bindings are silently dropped and the node has no way to access the specified tools.

Expected Behavior

Per the specification, nodes should be able to declare their tool sources. The compiler should:

  1. Pass tool_sources from NodeDefinition to the compiled node metadata
  2. The runtime should use these bindings to load the appropriate tools for each node

Code Locations

  • src/cleveragents/actor/compiler.py_map_node() function: does not pass node.tool_sources
  • src/cleveragents/langgraph/nodes.pyNodeConfig class: missing tool_sources field
  • src/cleveragents/actor/schema.pyNodeDefinition.tool_sources: the field that is silently dropped

Subtasks

  • Add tool_sources: list[ToolSourceRef] field to NodeConfig in src/cleveragents/langgraph/nodes.py with default_factory=list
  • Update _map_node() in src/cleveragents/actor/compiler.py to pass node.tool_sources to NodeConfig
  • Verify CompilationMetadata captures per-node tool source bindings for diagnostics (add if missing)
  • Audit the actor runtime to ensure tool_sources on NodeConfig is consumed to load the appropriate tools for each node
  • Tests (Behave): Add BDD scenario — actor YAML with tool_sources on a node → compiled NodeConfig retains the bindings
  • Tests (Behave): Add BDD regression scenario — node with tool_sources: [] compiles without error (empty list default)
  • Tests (Robot): Add integration test verifying a node's declared tool sources are available at runtime
  • Verify nox -e typecheck passes (no # type: ignore suppressions added)
  • Verify coverage ≥ 97% via nox -s coverage_report
  • Run nox (all default sessions), fix any errors

Definition of Done

This issue is complete when:

  • NodeConfig in src/cleveragents/langgraph/nodes.py has a tool_sources field of type list[ToolSourceRef]
  • _map_node() passes node.tool_sources to NodeConfig — no silent data loss
  • CompilationMetadata includes per-node tool source bindings for diagnostics
  • The actor runtime uses tool_sources to load the appropriate tools for each node
  • All subtasks above are completed and checked off
  • A Git commit is created where the first line of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation
  • The commit is pushed to the remote on the branch matching the Branch in Metadata exactly
  • The commit is submitted as a pull request to master, reviewed, and merged before this issue is marked done
  • All nox stages pass
  • Coverage ≥ 97%

Backlog note: This issue was discovered during autonomous operation
on milestone v3.2.0. It does not block milestone completion and has been
placed in the backlog for human review and future milestone assignment.


Automated by CleverAgents Bot
Supervisor: UAT Testing | Agent: ca-new-issue-creator

## Metadata - **Branch**: `fix/actor-compiler-node-tool-sources` - **Commit Message**: `fix(actor): pass NodeDefinition.tool_sources through compiler into NodeConfig` - **Milestone**: *(none — backlog, see note below)* - **Parent Epic**: #392 ## Background and Context The specification defines that actor graph nodes can declare `tool_sources` to specify where their tools come from — skills, MCP servers, or builtin tool groups. This is a key feature for hierarchical actor composition, allowing different nodes in a graph to use different tool sets. The `NodeDefinition` schema (in `src/cleveragents/actor/schema.py`) has a `tool_sources` field: ```python tool_sources: list[ToolSourceRef] = Field( default_factory=list, description="Tool source references" ) ``` ## Current Behavior In `src/cleveragents/actor/compiler.py`, the `_map_node()` function maps `NodeDefinition` to `lg_nodes.NodeConfig`: ```python def _map_node(node: NodeDefinition) -> lg_nodes.NodeConfig: lg_type = _NODE_TYPE_MAP.get(node.type, lg_nodes.NodeType.FUNCTION) config = node.config return lg_nodes.NodeConfig( name=node.id, type=lg_type, agent=config.get("agent") if node.type == NodeType.AGENT else None, function=config.get("function") if node.type == NodeType.CONDITIONAL else None, tools=config.get("tools", []) if node.type == NodeType.TOOL else [], subgraph=(config.get("actor_ref") if node.type == NodeType.SUBGRAPH else None), metadata=dict(config), ) ``` The `node.tool_sources` field is **never passed** to `NodeConfig`. The `NodeConfig` model in `src/cleveragents/langgraph/nodes.py` also has no `tool_sources` field, so per-node tool source bindings are completely lost during compilation. This means that when a node declares: ```yaml tool_sources: - type: skill name: local/file-ops - type: mcp name: local/filesystem ``` These bindings are silently dropped and the node has no way to access the specified tools. ## Expected Behavior Per the specification, nodes should be able to declare their tool sources. The compiler should: 1. Pass `tool_sources` from `NodeDefinition` to the compiled node metadata 2. The runtime should use these bindings to load the appropriate tools for each node ## Code Locations - `src/cleveragents/actor/compiler.py` — `_map_node()` function: does not pass `node.tool_sources` - `src/cleveragents/langgraph/nodes.py` — `NodeConfig` class: missing `tool_sources` field - `src/cleveragents/actor/schema.py` — `NodeDefinition.tool_sources`: the field that is silently dropped ## Subtasks - [ ] Add `tool_sources: list[ToolSourceRef]` field to `NodeConfig` in `src/cleveragents/langgraph/nodes.py` with `default_factory=list` - [ ] Update `_map_node()` in `src/cleveragents/actor/compiler.py` to pass `node.tool_sources` to `NodeConfig` - [ ] Verify `CompilationMetadata` captures per-node tool source bindings for diagnostics (add if missing) - [ ] Audit the actor runtime to ensure `tool_sources` on `NodeConfig` is consumed to load the appropriate tools for each node - [ ] Tests (Behave): Add BDD scenario — actor YAML with `tool_sources` on a node → compiled `NodeConfig` retains the bindings - [ ] Tests (Behave): Add BDD regression scenario — node with `tool_sources: []` compiles without error (empty list default) - [ ] Tests (Robot): Add integration test verifying a node's declared tool sources are available at runtime - [ ] Verify `nox -e typecheck` passes (no `# type: ignore` suppressions added) - [ ] Verify coverage ≥ 97% via `nox -s coverage_report` - [ ] Run `nox` (all default sessions), fix any errors ## Definition of Done This issue is complete when: - [ ] `NodeConfig` in `src/cleveragents/langgraph/nodes.py` has a `tool_sources` field of type `list[ToolSourceRef]` - [ ] `_map_node()` passes `node.tool_sources` to `NodeConfig` — no silent data loss - [ ] `CompilationMetadata` includes per-node tool source bindings for diagnostics - [ ] The actor runtime uses `tool_sources` to load the appropriate tools for each node - [ ] All subtasks above are completed and checked off - [ ] A Git commit is created where the **first line** of the commit message matches the Commit Message in Metadata exactly, followed by a blank line, then additional lines providing relevant details about the implementation - [ ] The commit is pushed to the remote on the branch matching the **Branch** in Metadata exactly - [ ] The commit is submitted as a **pull request** to `master`, reviewed, and **merged** before this issue is marked done - [ ] All nox stages pass - [ ] Coverage ≥ 97% > **Backlog note:** This issue was discovered during autonomous operation > on milestone v3.2.0. It does not block milestone completion and has been > placed in the backlog for human review and future milestone assignment. --- **Automated by CleverAgents Bot** Supervisor: UAT Testing | Agent: ca-new-issue-creator
freemo added this to the v3.2.0 milestone 2026-04-05 20:29:26 +00:00
Author
Owner

Issue triaged by project owner:

  • State: Verified
  • Priority: Medium — NodeDefinition.tool_sources is silently dropped by the actor compiler. Per-node tool source bindings (skills, MCP, builtins) are never wired into the compiled graph. Similar to #3568 (actor_ref field ignored).
  • Milestone: v3.2.0
  • Story Points: 3 — M — Add field to NodeConfig, update compiler, and ensure runtime consumes the bindings.
  • MoSCoW: Should Have — Per-node tool source bindings are important for hierarchical actor composition. Without them, all nodes use the same global tool set, limiting the expressiveness of actor graphs.

Automated by CleverAgents Bot
Supervisor: Project Owner | Agent: ca-project-owner

Issue triaged by project owner: - **State**: Verified - **Priority**: Medium — `NodeDefinition.tool_sources` is silently dropped by the actor compiler. Per-node tool source bindings (skills, MCP, builtins) are never wired into the compiled graph. Similar to #3568 (actor_ref field ignored). - **Milestone**: v3.2.0 - **Story Points**: 3 — M — Add field to NodeConfig, update compiler, and ensure runtime consumes the bindings. - **MoSCoW**: Should Have — Per-node tool source bindings are important for hierarchical actor composition. Without them, all nodes use the same global tool set, limiting the expressiveness of actor graphs. --- **Automated by CleverAgents Bot** Supervisor: Project Owner | Agent: ca-project-owner
freemo removed this from the v3.2.0 milestone 2026-04-06 20:51:03 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Blocks
#392 Epic: Actor YAML & Compiler
cleveragents/cleveragents-core
Reference
cleveragents/cleveragents-core#3610
No description provided.