From 1faf90e8b98b038eb03c8bab6525f0736ae5c664 Mon Sep 17 00:00:00 2001 From: Matias Molinas Date: Sun, 29 Dec 2024 09:54:01 -0300 Subject: [PATCH] feat(tools): partial commit for step 2 - work in progress on Human Intervention Tool This commit includes progress towards the Human Intervention Tool as an extension of the Human Tool. It lays groundwork for future enhancements in user-agent interaction. Ref: #121 Signed-off-by: Matias Molinas --- .../agents/experimental/replan_extended.ts | 19 ++-- examples/tools/experimental/human.ts | 79 ++++++++-------- examples/tools/experimental/intervention.ts | 93 +++++++++++++++---- 3 files changed, 126 insertions(+), 65 deletions(-) diff --git a/examples/agents/experimental/replan_extended.ts b/examples/agents/experimental/replan_extended.ts index bca2cdda..b90425d3 100644 --- a/examples/agents/experimental/replan_extended.ts +++ b/examples/agents/experimental/replan_extended.ts @@ -1,12 +1,11 @@ import "dotenv/config.js"; import { FrameworkError } from "bee-agent-framework/errors"; -import { DuckDuckGoSearchTool } from "bee-agent-framework/tools/search/duckDuckGoSearch"; -import { OpenMeteoTool } from "bee-agent-framework/tools/weather/openMeteo"; import { UnconstrainedMemory } from "bee-agent-framework/memory/unconstrainedMemory"; import { createConsoleReader } from "examples/helpers/io.js"; import { RePlanAgent } from "bee-agent-framework/agents/experimental/replan/agent"; import { OllamaChatLLM } from "bee-agent-framework/adapters/ollama/chat"; import { OpenAIChatLLM } from "bee-agent-framework/adapters/openai/chat"; +import { GroqChatLLM } from "bee-agent-framework/adapters/groq/chat"; import { InterventionTool } from "../../tools/experimental/intervention.js"; import { HumanTool } from "../../tools/experimental/human.js"; import { InterventionManager } from "../../managers/interventionManager.js"; @@ -17,23 +16,27 @@ const reader = createConsoleReader(); // Initialize LLM //const llm = new OllamaChatLLM({ -// modelId: "granite3.1-dense:8b", +// modelId: "llama3.1:latest", +//}); +//const llm = new OpenAIChatLLM({ +// modelId: "gpt-4o-mini", //}); -const llm = new OpenAIChatLLM({ - modelId: "gpt-4o-mini", -}); + +const llm = new GroqChatLLM(); const memory = new UnconstrainedMemory(); const humanTool = new HumanTool(reader); +const interventionTool = new InterventionTool(reader); + const agent = new RePlanAgent({ llm, memory, - tools: [new OpenMeteoTool(), humanTool], + tools: [humanTool, interventionTool], }); -//const interventionManager = new InterventionManager(Emitter.root, interventionTool); +const interventionManager = new InterventionManager(Emitter.root, interventionTool); try { for await (const { prompt } of reader) { diff --git a/examples/tools/experimental/human.ts b/examples/tools/experimental/human.ts index deaf3aff..1f79d778 100644 --- a/examples/tools/experimental/human.ts +++ b/examples/tools/experimental/human.ts @@ -11,45 +11,48 @@ import { z } from "zod"; export class HumanTool extends Tool { name = "HumanTool"; description = ` - This tool is strictly used whenever the user's input is unclear, ambiguous, or incomplete. - The assistant - MUST NOT ask the user for clarification directly as an assistant message. Instead, it - must invoke this tool to obtain the necessary details. If at any point the assistant - finds the user’s request ambiguous, vague, incomplete, or unclear, the assistant - should call this HumanTool. - - The output must adhere strictly to the following structure: - - Thought: A single-line description of the need for clarification. - - Function Name: HumanTool - - Function Input: { "message": "Your question to the user for clarification." } - - Function Output: The user's response in JSON format. + This tool enables initial information gathering and basic clarifications at the start of interactions. + It should be used as the first point of contact when the agent needs to understand user preferences, + requirements, or constraints before beginning the planning process. + + PRIMARY USE CASES: + 1. Initial information gathering + 2. Basic preference collection + 3. Constraint identification + 4. General clarifications before planning begins + + The output must adhere to this structure: + - Thought: A clear description of what initial information is needed + - Function Name: HumanTool + - Function Input: { "message": "Your question to the user." } + - Function Output: The user's response in JSON format + Examples: - - Example 1: - Input: "What is the weather?" - Thought: "The user's request lacks a location. I need to ask for clarification." - Function Name: HumanTool - Function Input: { "message": "Could you provide the location for which you would like to know the weather?" } - Function Output: { "clarification": "Santa Fe, Argentina" } - Final Answer: The current weather in Santa Fe, Argentina is 17.3°C with a relative humidity of 48% and a wind speed of 10.1 km/h. - - - Example 2: - Input: "Can you help me?" - Thought: "The user's request is too vague. I need to ask for more details." - Function Name: HumanTool - Function Input: { "message": "Could you clarify what kind of help you need?" } - Function Output: { "clarification": "I need help understanding how to use the project management tool." } - Final Answer: Sure, I can help you with the project management tool. Let me know which feature you'd like to learn about or if you'd like a general overview. - - - Example 3: - Input: "Translate this sentence." - Thought: "The user's request is incomplete. I need to ask for the sentence they want translated." - Function Name: HumanTool - Function Input: { "message": "Could you specify the sentence you would like me to translate?" } - Function Output: { "clarification": "Translate 'Hello, how are you?' to French." } - Final Answer: The French translation of 'Hello, how are you?' is 'Bonjour, comment vas-tu?' - - Note: Do NOT attempt to guess or provide incomplete responses. Always use this tool when in doubt to ensure accurate and meaningful interactions. -`; + + - Example (Initial Query): + Input: "Help me plan a trip to Europe" + Thought: "Need to understand basic preferences before starting plan" + Function Name: HumanTool + Function Input: { "message": "Could you tell me your preferred type of activities (cultural, outdoor, etc.) and any specific cities you're interested in?" } + Function Output: { "clarification": "I enjoy cultural activities and would like to visit Prague" } + + - Example (Constraint Identification): + Input: "Create a weekend itinerary" + Thought: "Need to understand time and preference constraints" + Function Name: HumanTool + Function Input: { "message": "What kind of activities interest you and do you have any time constraints I should know about?" } + Function Output: { "clarification": "I prefer outdoor activities and have Saturday from 9 AM to 6 PM" } + + USAGE GUIDELINES: + 1. Use at the START of interactions + 2. Focus on gathering INITIAL information + 3. Keep questions open-ended but specific + 4. Avoid asking about plan details - that comes later with InterventionTool + 5. Gather enough information to start creating options + + Note: This tool is for initial information gathering only. Once you have basic information + and start creating plans, switch to InterventionTool for refinements and choices. + `; public readonly emitter: Emitter, StringToolOutput>> = Emitter.root.child({ diff --git a/examples/tools/experimental/intervention.ts b/examples/tools/experimental/intervention.ts index 8ca25c5d..da0e1d48 100644 --- a/examples/tools/experimental/intervention.ts +++ b/examples/tools/experimental/intervention.ts @@ -17,26 +17,81 @@ interface InterventionToolEvents extends ToolEvents, export class InterventionTool extends Tool { name = "InterventionTool"; description = ` - This tool handles various human interventions such as validation, correction, and clarification. - - The agent MUST invoke this tool when a specific type of human interaction is required. - - The output must adhere strictly to the following structure: - - Type: The type of intervention (e.g., "validation", "correction", "clarification"). - - Function Name: InterventionTool - - Function Input: { "message": "Your intervention message to the user." } - - Function Output: The user's response in JSON format. - + This tool enables collaborative decision-making and plan refinement AFTER initial information + gathering. It creates "decision hooks" where humans can guide the planning process through + validation, correction, and choice between multiple options. + + PRIMARY USE CASES: + 1. Presenting multiple solution options for user choice + 2. Validating proposed plans or assumptions + 3. Correcting and refining plan elements + 4. Enabling mix-and-match of different options + + The tool supports three intervention types: + - "clarification": Refining specific aspects of proposed options + - "validation": Confirming plans align with user preferences + - "correction": Adjusting plans based on user feedback + + The output must follow this structure: + - Thought: Why this intervention point needs user input + - Type: One of "clarification", "validation", or "correction" + - Function Name: InterventionTool + - Function Input: { "message": "Your intervention message to the user." } + - Function Output: The user's response in JSON format + Examples: - - Validation: - Input: "Please confirm the following data." - Output: { "confirmation": "Yes, the data is correct." } - - - Correction: - Input: "There seems to be an error in the previous step. Please provide the correct value." - Output: { "correction": "The value should be 42 instead of 24." } - `; + - Example (Multiple Options): + Context: After gathering basic preferences for Prague trip + Thought: "Present two distinct planning options for user choice" + Type: clarification + Function Name: InterventionTool + Function Input: { + "message": "I've prepared two options: + Option A (Cultural): Morning castle tour, afternoon Old Town, evening concert + Option B (Adventure): Morning bike ride, afternoon kayaking, evening local bars + Would you prefer one of these or would you like to mix elements from both?" + } + Function Output: { "clarification": "I'd like to mix them - castle tour and bike ride sound great" } + + - Example (Plan Refinement): + Context: After user chooses to mix activities + Thought: "Need to refine combined plan details" + Type: correction + Function Name: InterventionTool + Function Input: { + "message": "I'll combine the castle tour and bike ride. For the afternoon, would you prefer a relaxing activity like a café visit or something more active?" + } + Function Output: { "correction": "A café visit would be perfect for the afternoon" } + + - Example (Plan Validation): + Context: After creating mixed itinerary + Thought: "Validate final plan timing and preferences" + Type: validation + Function Name: InterventionTool + Function Input: { + "message": "Here's the plan: Castle tour (9-11), bike ride (11:30-1), café (2-4). Does this timing and order work for you?" + } + Function Output: { "validation": "Yes, but can we start the castle tour earlier?" } + + WHEN TO USE: + 1. After initial information gathering (post-HumanTool) + 2. When presenting multiple viable options + 3. When refining and combining plan elements + 4. When validating final plans + 5. When user feedback indicates need for adjustments + + DECISION HOOKS GUIDELINES: + 1. Present clear, distinct options when possible + 2. Allow mixing and matching of elements + 3. Make decision points explicit + 4. Maintain context between interventions + 5. Show how user choices influence the final plan + + Note: This tool is for collaborative refinement AFTER initial planning starts. + For initial information gathering, use HumanTool instead. + `; + public readonly emitter: Emitter = Emitter.root.child({ namespace: ["tool", "intervention"], creator: this, @@ -92,4 +147,4 @@ export class InterventionTool extends Tool { return new StringToolOutput(formattedOutput); } -} \ No newline at end of file +}