mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-02-09 06:15:41 -05:00
refactor: look up block name from API instead of LLM input
Addresses review feedback from ntindle: - Remove block_name parameter from run_block tool (no longer required from LLM) - Frontend now fetches blocks via useGetV1ListAvailableBlocks hook - Creates memoized Map<blockId, blockName> for efficient lookup - Falls back to block_id if name lookup fails This approach: - Doesn't increase LLM context requirements - Reduces chance of LLM messing up the name - Uses existing generated types/hooks - Only fetches blocks when run_block tool is used (enabled: toolName === 'run_block') - Caches result for 5 minutes (staleTime)
This commit is contained in:
@@ -178,8 +178,8 @@ class FindBlockTool(BaseTool):
|
||||
message=(
|
||||
f"Found {len(blocks)} block(s) matching '{query}'. "
|
||||
"To execute a block, use run_block with the block's "
|
||||
"'id' and 'name' fields and provide 'input_data' "
|
||||
"matching the block's input_schema."
|
||||
"'id' field and provide 'input_data' matching the "
|
||||
"block's input_schema."
|
||||
),
|
||||
blocks=blocks,
|
||||
count=len(blocks),
|
||||
|
||||
@@ -353,9 +353,8 @@ class BlockListResponse(ToolResponseBase):
|
||||
usage_hint: str = Field(
|
||||
default=(
|
||||
"To execute a block, call run_block with block_id set to "
|
||||
"the block's 'id' field, block_name set to the block's 'name' "
|
||||
"field, and input_data containing the required fields from "
|
||||
"input_schema."
|
||||
"the block's 'id' field and input_data containing the required "
|
||||
"fields from input_schema."
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
@@ -58,14 +58,6 @@ class RunBlockTool(BaseTool):
|
||||
"NEVER guess this - always get it from find_block first."
|
||||
),
|
||||
},
|
||||
"block_name": {
|
||||
"type": "string",
|
||||
"description": (
|
||||
"The block's human-readable 'name' field from "
|
||||
"find_block results. Include this for better user "
|
||||
"experience."
|
||||
),
|
||||
},
|
||||
"input_data": {
|
||||
"type": "object",
|
||||
"description": (
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
import { Text } from "@/components/atoms/Text/Text";
|
||||
import { cn } from "@/lib/utils";
|
||||
import type { ToolArguments } from "@/types/chat";
|
||||
import type { Block } from "@/lib/autogpt-server-api/types";
|
||||
import { useGetV1ListAvailableBlocks } from "@/app/api/__generated__/endpoints/blocks/blocks";
|
||||
import { useMemo } from "react";
|
||||
import { AIChatBubble } from "../AIChatBubble/AIChatBubble";
|
||||
import {
|
||||
formatToolArguments,
|
||||
@@ -22,8 +25,23 @@ export function ToolCallMessage({
|
||||
isStreaming = false,
|
||||
className,
|
||||
}: ToolCallMessageProps) {
|
||||
// Fetch blocks only when needed for run_block tool
|
||||
const { data: blocksResponse } = useGetV1ListAvailableBlocks({
|
||||
query: {
|
||||
enabled: toolName === "run_block",
|
||||
staleTime: 5 * 60 * 1000, // Cache for 5 minutes
|
||||
},
|
||||
});
|
||||
|
||||
// Create a memoized map of block IDs to names
|
||||
const blocksById = useMemo(() => {
|
||||
if (!blocksResponse?.data) return undefined;
|
||||
const blocks = blocksResponse.data as Block[];
|
||||
return new Map(blocks.map((block) => [block.id, block.name]));
|
||||
}, [blocksResponse?.data]);
|
||||
|
||||
const actionPhrase = getToolActionPhrase(toolName);
|
||||
const argumentsText = formatToolArguments(toolName, toolArguments);
|
||||
const argumentsText = formatToolArguments(toolName, toolArguments, blocksById);
|
||||
const displayText = `${actionPhrase}${argumentsText}`;
|
||||
const IconComponent = getToolIcon(toolName);
|
||||
|
||||
|
||||
@@ -62,11 +62,13 @@ export function getToolActionPhrase(toolName: string): string {
|
||||
*
|
||||
* @param toolName - The tool name
|
||||
* @param args - The tool arguments
|
||||
* @param blocksById - Optional map of block IDs to block names for lookup
|
||||
* @returns Formatted user-friendly text to append to action phrase
|
||||
*/
|
||||
export function formatToolArguments(
|
||||
toolName: string,
|
||||
args: ToolArguments | undefined,
|
||||
blocksById?: Map<string, string>,
|
||||
): string {
|
||||
if (!args || Object.keys(args).length === 0) {
|
||||
return "";
|
||||
@@ -109,17 +111,16 @@ export function formatToolArguments(
|
||||
break;
|
||||
|
||||
case "run_block":
|
||||
// Prefer block_name if provided, otherwise fall back to block_id
|
||||
if (args.block_name) {
|
||||
// Beautify and remove redundant "Block" suffix (same pattern as blocks menu)
|
||||
const displayName = beautifyString(args.block_name as string).replace(
|
||||
/ Block$/,
|
||||
"",
|
||||
);
|
||||
return ` "${displayName}"`;
|
||||
}
|
||||
// Look up block name from blocksById map, fall back to block_id
|
||||
if (args.block_id) {
|
||||
return ` "${args.block_id as string}"`;
|
||||
const blockId = args.block_id as string;
|
||||
const blockName = blocksById?.get(blockId);
|
||||
if (blockName) {
|
||||
// Beautify and remove redundant "Block" suffix (same pattern as blocks menu)
|
||||
const displayName = beautifyString(blockName).replace(/ Block$/, "");
|
||||
return ` "${displayName}"`;
|
||||
}
|
||||
return ` "${blockId}"`;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user