| 6605 | } |
| 6606 | |
| 6607 | func allowedExploreToolNames(allTools []fantasy.AgentTool) []string { |
| 6608 | builtinExplorePolicy := map[string]bool{ |
| 6609 | "read_file": true, |
| 6610 | "write_file": false, |
| 6611 | "edit_files": false, |
| 6612 | "execute": true, |
| 6613 | "process_output": true, |
| 6614 | "process_list": false, |
| 6615 | "process_signal": false, |
| 6616 | "list_templates": false, |
| 6617 | "read_template": false, |
| 6618 | "create_workspace": false, |
| 6619 | "start_workspace": false, |
| 6620 | "stop_workspace": false, |
| 6621 | "propose_plan": false, |
| 6622 | "spawn_agent": false, |
| 6623 | "wait_agent": false, |
| 6624 | "message_agent": false, |
| 6625 | "close_agent": false, |
| 6626 | "read_skill": true, |
| 6627 | "read_skill_file": true, |
| 6628 | "ask_user_question": false, |
| 6629 | } |
| 6630 | |
| 6631 | toolNames := make([]string, 0, len(allTools)) |
| 6632 | for _, tool := range allTools { |
| 6633 | name := tool.Info().Name |
| 6634 | if builtinExplorePolicy[name] { |
| 6635 | toolNames = append(toolNames, name) |
| 6636 | continue |
| 6637 | } |
| 6638 | // External MCP tools pass through here. They were snapshot-filtered |
| 6639 | // at spawn time on chat.MCPServerIDs. WorkspaceMCPTool does not |
| 6640 | // implement MCPToolIdentifier, so workspace tools are excluded |
| 6641 | // here too, in addition to the structural exclusion in runChat |
| 6642 | // tool assembly. |
| 6643 | if _, ok := tool.(mcpclient.MCPToolIdentifier); ok { |
| 6644 | toolNames = append(toolNames, name) |
| 6645 | } |
| 6646 | } |
| 6647 | return toolNames |
| 6648 | } |
| 6649 | |
| 6650 | // allowedBehaviorToolNames runs only on non-plan turns because |
| 6651 | // appendDynamicTools returns early for plan mode. Within that boundary, |