chore: fetch attached tools for hooks (#683)

This commit is contained in:
jnjpng
2026-01-26 12:18:06 -08:00
committed by GitHub
parent d950db3afd
commit 2a1fde3f62
4 changed files with 44 additions and 11 deletions

View File

@@ -9798,7 +9798,7 @@ Plan file path: ${planFilePath}`;
{/* Hooks Manager - for managing hooks configuration */}
{activeOverlay === "hooks" && (
<HooksManager onClose={closeOverlay} />
<HooksManager onClose={closeOverlay} agentId={agentId} />
)}
{/* New Agent Dialog - for naming new agent before creation */}

View File

@@ -37,6 +37,7 @@ const BOX_VERTICAL = "│";
interface HooksManagerProps {
onClose: () => void;
agentId?: string;
}
type Screen =
@@ -62,8 +63,8 @@ const HOOK_EVENTS: { event: HookEvent; description: string }[] = [
{ event: "SessionEnd", description: "When a session ends" },
];
// Available tools for matcher suggestions
const TOOL_NAMES = [
// Fallback tool names if agent tools can't be fetched
const FALLBACK_TOOL_NAMES = [
"Task",
"Bash",
"Glob",
@@ -71,14 +72,13 @@ const TOOL_NAMES = [
"Read",
"Edit",
"Write",
"WebFetch",
"TodoWrite",
"WebSearch",
"AskUserQuestion",
"Skill",
"EnterPlanMode",
"ExitPlanMode",
"KillShell",
"BashOutput",
"KillBash",
];
// Save location options
@@ -130,6 +130,7 @@ function boxBottom(width: number): string {
export const HooksManager = memo(function HooksManager({
onClose,
agentId,
}: HooksManagerProps) {
const terminalWidth = useTerminalWidth();
const boxWidth = Math.min(terminalWidth - 4, 70);
@@ -141,6 +142,37 @@ export const HooksManager = memo(function HooksManager({
const [hooks, setHooks] = useState<HookWithSource[]>([]);
const [totalHooks, setTotalHooks] = useState(0);
// Dynamic tool names from agent
const [toolNames, setToolNames] = useState<string[]>(FALLBACK_TOOL_NAMES);
// Fetch agent tools on mount
useEffect(() => {
if (!agentId) return;
const fetchAgentTools = async () => {
try {
const { getClient } = await import("../../agent/client");
const client = await getClient();
// Use dedicated tools endpoint instead of fetching whole agent
// Pass limit to avoid pagination issues
const toolsPage = await client.agents.tools.list(agentId, {
limit: 50,
});
const names = toolsPage.items
?.map((t) => t.name)
.filter((n): n is string => !!n);
if (names && names.length > 0) {
// Sort alphabetically for easier scanning
setToolNames(names.sort());
}
} catch {
// Keep fallback tool names on error
}
};
fetchAgentTools();
}, [agentId]);
// New hook state
const [newMatcher, setNewMatcher] = useState("");
const [newCommand, setNewCommand] = useState("");
@@ -476,7 +508,7 @@ export const HooksManager = memo(function HooksManager({
<Text> </Text>
<Text dimColor>Possible matcher values for field tool_name:</Text>
<Text dimColor>{TOOL_NAMES.join(", ")}</Text>
<Text dimColor>{toolNames.join(", ")}</Text>
<Text> </Text>
<Text>Tool matcher:</Text>

View File

@@ -111,10 +111,10 @@ export const McpSelector = memo(function McpSelector({
const fetchAttachedToolIds = useCallback(
async (client: Awaited<ReturnType<typeof getClient>>) => {
const agent = await client.agents.retrieve(agentId, {
include: ["agent.tools"],
});
return new Set(agent.tools?.map((t) => t.id) || []);
// Use dedicated tools endpoint instead of fetching whole agent
// Pass limit to avoid pagination issues
const toolsPage = await client.agents.tools.list(agentId, { limit: 50 });
return new Set(toolsPage.items?.map((t) => t.id) || []);
},
[agentId],
);

View File

@@ -48,6 +48,7 @@ export async function ensureCorrectMemoryTool(
: isOpenAIModel(resolvedModel);
try {
// Need full agent state for tool_rules, so use retrieve with include
const agentWithTools = await client.agents.retrieve(agentId, {
include: ["agent.tools"],
});