From f966c5db64ad64d055d59dd606459a4942130310 Mon Sep 17 00:00:00 2001 From: Zhaofeng Zhang <24791380+vcfgv@users.noreply.github.com> Date: Fri, 17 Oct 2025 10:55:14 +0800 Subject: [PATCH 1/5] refactor: rename desired_agent_name to target_agent_name in UserInput and related classes --- python/valuecell/core/coordinate/models.py | 2 +- python/valuecell/core/coordinate/planner.py | 2 +- .../valuecell/core/coordinate/tests/test_e2e_persistence.py | 2 +- python/valuecell/core/coordinate/tests/test_orchestrator.py | 2 +- python/valuecell/core/types.py | 2 +- python/valuecell/server/services/agent_stream_service.py | 4 ++-- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/python/valuecell/core/coordinate/models.py b/python/valuecell/core/coordinate/models.py index 55acd98e1..6ff3269f8 100644 --- a/python/valuecell/core/coordinate/models.py +++ b/python/valuecell/core/coordinate/models.py @@ -49,7 +49,7 @@ class PlannerInput(BaseModel): when determining what tasks should be executed. """ - desired_agent_name: str = Field( + target_agent_name: str = Field( ..., description="The name of the agent the user wants to use for the task" ) query: str = Field( diff --git a/python/valuecell/core/coordinate/planner.py b/python/valuecell/core/coordinate/planner.py index 19cdaf720..372332e86 100644 --- a/python/valuecell/core/coordinate/planner.py +++ b/python/valuecell/core/coordinate/planner.py @@ -173,7 +173,7 @@ async def _analyze_input_and_create_tasks( # Execute planning with the agent run_response = agent.run( PlannerInput( - desired_agent_name=user_input.desired_agent_name, + target_agent_name=user_input.target_agent_name, query=user_input.query, ), session_id=conversation_id, diff --git a/python/valuecell/core/coordinate/tests/test_e2e_persistence.py b/python/valuecell/core/coordinate/tests/test_e2e_persistence.py index 5aed51c79..3a3e4b762 100644 --- a/python/valuecell/core/coordinate/tests/test_e2e_persistence.py +++ b/python/valuecell/core/coordinate/tests/test_e2e_persistence.py @@ -18,7 +18,7 @@ async def test_orchestrator_buffer_store_e2e(tmp_path, monkeypatch): user_id = "e2e-user" ui = UserInput( query="hello world", - desired_agent_name="TestAgent", + target_agent_name="TestAgent", meta=UserInputMetadata(conversation_id=conversation_id, user_id=user_id), ) diff --git a/python/valuecell/core/coordinate/tests/test_orchestrator.py b/python/valuecell/core/coordinate/tests/test_orchestrator.py index fcc947a34..7d2433aa7 100644 --- a/python/valuecell/core/coordinate/tests/test_orchestrator.py +++ b/python/valuecell/core/coordinate/tests/test_orchestrator.py @@ -58,7 +58,7 @@ def _sample_user_input( ) -> UserInput: return UserInput( query=sample_query, - desired_agent_name="TestAgent", + target_agent_name="TestAgent", meta=UserInputMetadata(conversation_id=conversation_id, user_id=user_id), ) diff --git a/python/valuecell/core/types.py b/python/valuecell/core/types.py index 81aa0b039..9f748be8c 100644 --- a/python/valuecell/core/types.py +++ b/python/valuecell/core/types.py @@ -21,7 +21,7 @@ class UserInput(BaseModel): """Unified abstraction for user input containing all necessary parameters""" query: str = Field(..., description="The actual user input text") - desired_agent_name: Optional[str] = Field( + target_agent_name: Optional[str] = Field( None, description="Specific agent name to use for processing this input" ) meta: UserInputMetadata = Field( diff --git a/python/valuecell/server/services/agent_stream_service.py b/python/valuecell/server/services/agent_stream_service.py index 379afa1df..c4e6042a5 100644 --- a/python/valuecell/server/services/agent_stream_service.py +++ b/python/valuecell/server/services/agent_stream_service.py @@ -36,7 +36,7 @@ async def stream_query_agent( logger.info(f"Processing streaming query: {query[:100]}...") user_id = "default_user" - desired_agent_name = agent_name + target_agent_name = agent_name conversation_id = agent_name + "_conv_" + user_id @@ -45,7 +45,7 @@ async def stream_query_agent( ) user_input = UserInput( - query=query, desired_agent_name=desired_agent_name, meta=user_input_meta + query=query, target_agent_name=target_agent_name, meta=user_input_meta ) # Use the orchestrator's process_user_input method for streaming From edec13fbe17850744c72cf7d02e7b33d83b4c0ab Mon Sep 17 00:00:00 2001 From: Zhaofeng Zhang <24791380+vcfgv@users.noreply.github.com> Date: Fri, 17 Oct 2025 10:55:23 +0800 Subject: [PATCH 2/5] refactor: update planner instructions and output format for clarity and consistency --- .../core/coordinate/planner_prompts.py | 243 +++++++++++++++--- 1 file changed, 214 insertions(+), 29 deletions(-) diff --git a/python/valuecell/core/coordinate/planner_prompts.py b/python/valuecell/core/coordinate/planner_prompts.py index 8dc2cd39b..ae5bd8094 100644 --- a/python/valuecell/core/coordinate/planner_prompts.py +++ b/python/valuecell/core/coordinate/planner_prompts.py @@ -7,48 +7,73 @@ """ # noqa: E501 -PLANNER_INSTRUCTIONS = """ +PLANNER_INSTRUCTION = """ You are an AI Agent execution planner that analyzes user requests and creates executable task plans using available agents. -**If user specifies a target agent:** -1. **Verify agent exists**: Call `get_agent_card` to confirm the agent is available -2. **Check principle-level validity**: Ensure the query is not fundamentally out-of-scope or unexecutable -3. **Forward as-is**: Create a single task with the user's query unchanged (unless a critical issue exists) -4. **Generate plan**: Return the task plan immediately - -**If no target agent specified:** -1. **Understand capabilities**: Call `get_agent_card` to explore available agents -2. **Assess completeness**: Determine if the user request contains sufficient information -3. **Clarify if needed**: Call `get_user_input` only when essential information is missing - - Don't ask for information that can be inferred or researched (e.g., current date, time ranges, stock symbols, ciks) - - Don't ask for non-essential details or information already provided - - Proceed directly if the request is reasonably complete - - Make your best guess before asking for clarification -4. **Generate plan**: Create a structured execution plan with clear, actionable tasks + +**Step 1: Identify Query Type** + + +If the query is a short or contextual reply (e.g., "Go on", "yes", "tell me more", "this one", "that's good"): +- Forward it directly without rewriting or splitting +- These are continuations of an ongoing conversation and should be preserved as-is +- Create a single task with the query unchanged + + + +If the query is vague or ambiguous without conversation context: +- Return `adequate: false` +- Provide specific clarification questions in the `reason` field + + + +If the query suggests recurring monitoring or periodic updates: +- Return `adequate: false` +- Ask for confirmation in the `reason` field: "Do you want regular updates on this, or a one-time analysis?" +- Only create recurring tasks after explicit user confirmation + + +**Step 2: Create Task Plan** + +For clear, actionable queries: +- Create specific tasks with optimized queries +- Use `**bold**` to highlight key details (stock symbols, dates, names) +- Set appropriate pattern (once/recurring) +- Provide brief reasoning + -If the user specifies a target agent name, the planner should only check for principle-level issues: -- Do not rewrite or expand the query unless it contains a fundamental problem (e.g., illegal, unsupported, or out-of-scope for the agent). -- Do not clarify, split, or optimize the query for style or detail—just forward it as-is to the target agent. -- Only rewrite or block the query if it is ambiguous to the point of being unexecutable, or if it asks for something the agent fundamentally cannot do. -- If the query is valid for the agent's core function, pass it through unchanged. -- If the user does not specify a target agent, follow normal planning and task creation guidelines. +Trust the target agent's capabilities: +- Do not over-validate or rewrite queries unless fundamentally broken (illegal, nonsensical, or completely out of scope) +- Do not split queries into multiple tasks unless complexity genuinely requires it +- For contextual/short replies, forward directly without rewriting +- For reasonable domain-specific requests, pass through unchanged or lightly optimized +""" +PLANNER_EXPECTED_OUTPUT = """ -- Transform vague requests into clear, specific, actionable queries -- Tailor language to target agent capabilities +**For contextual/short replies:** +- Forward as-is: "Go on", "yes", "no", "this", "that", "tell me more" +- Preserve conversation continuity without rewriting + +**For actionable queries:** +- Transform vague requests into clear, specific tasks - Use formatting (`**bold**`) to highlight critical details (stock symbols, dates, names) - Be precise and avoid ambiguous language -- For continuation requests (e.g., "go on", "tell me more"), formulate the query to explicitly reference what should be expanded: - * Good: "Provide additional analysis on **Apple's** Q2 2024 profitability metrics beyond revenue" - * Avoid: "Tell me more" (too vague for the executing agent) +- For complex queries, break down into specific tasks with clear objectives (but avoid over-splitting) +- Ensure each task is self-contained and actionable by the target agent + +**When to avoid optimization:** +- Query is already clear and specific +- Query contains contextual references that need conversation history +- Over-optimization would lose user intent or context @@ -72,7 +97,7 @@ **Output valid JSON only (no markdown, backticks, or comments):** - + { "tasks": [ { @@ -84,7 +109,167 @@ "adequate": true/false, "reason": "Brief explanation of planning decision" } - + + + + + +Input: +{ + "target_agent_name": "research_agent", + "query": "What was Tesla's Q3 2024 revenue?" +} + +Output: +{ + "tasks": [ + { + "query": "What was Tesla's Q3 2024 revenue?", + "agent_name": "research_agent", + "pattern": "once" + } + ], + "adequate": true, + "reason": "Clear, specific query; forwarding as-is." +} + + + +Input: +{ + "target_agent_name": "research_agent", + "query": "Go on" +} + +Output: +{ + "tasks": [ + { + "query": "Go on", + "agent_name": "research_agent", + "pattern": "once" + } + ], + "adequate": true, + "reason": "Contextual continuation; forwarding directly to current agent." +} + + + +Input: +{ + "target_agent_name": "research_agent", + "query": "Tell me more about that risk" +} + +Output: +{ + "tasks": [ + { + "query": "Tell me more about that risk", + "agent_name": "research_agent", + "pattern": "once" + } + ], + "adequate": true, + "reason": "Contextual query with reference pronoun; preserving as-is for conversation continuity." +} + + + +Input: +{ + "target_agent_name": "research_agent", + "query": "yes" +} + +Output: +{ + "tasks": [ + { + "query": "yes", + "agent_name": "research_agent", + "pattern": "once" + } + ], + "adequate": true, + "reason": "User confirmation; forwarding to current agent." +} + + + +// Step 1: User requests recurring monitoring (needs confirmation) +Input: +{ + "target_agent_name": "research_agent", + "query": "Monitor Apple's quarterly earnings and notify me each time they release results" +} + +Output: +{ + "tasks": [], + "adequate": false, + "reason": "User request suggests recurring monitoring. Need to confirm: 'Do you want me to set up regular updates for Apple's quarterly earnings, or would you prefer a one-time analysis of the latest report?'" +} + +// Step 2: User confirms recurring intent +Input: +{ + "target_agent_name": "research_agent", + "query": "Yes, set up regular updates" +} + +Output: +{ + "tasks": [ + { + "query": "Retrieve and analyze **Apple's** latest quarterly earnings report, highlighting revenue, net income, and key business segment performance", + "agent_name": "research_agent", + "pattern": "recurring" + } + ], + "adequate": true, + "reason": "User confirmed recurring monitoring intent. Created recurring task for quarterly earnings tracking." +} + + + +Input: +{ + "target_agent_name": "research_agent", + "query": "Tell me about Apple's recent performance" +} + +Output: +{ + "tasks": [ + { + "query": "Analyze **Apple's** most recent quarterly financial performance, including revenue, profit margins, and key business segment results from the latest 10-Q filing", + "agent_name": "research_agent", + "pattern": "once" + } + ], + "adequate": true, + "reason": "Vague query optimized to specific, actionable task with clear objectives." +} + + + +Input: +{ + "target_agent_name": "research_agent", + "query": "What about the numbers?" +} + +Output: +{ + "tasks": [], + "adequate": false, + "reason": "Query is too vague without conversation context. Need clarification: Which company's numbers? Which metrics (revenue, earnings, margins)? Which time period?" +} + + + """ From cd739eaf9b58f50b6b01f5f8d5758db397aa8acb Mon Sep 17 00:00:00 2001 From: Zhaofeng Zhang <24791380+vcfgv@users.noreply.github.com> Date: Fri, 17 Oct 2025 11:14:56 +0800 Subject: [PATCH 3/5] fix: add item_id to response in tool call handling --- python/valuecell/core/coordinate/response.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/valuecell/core/coordinate/response.py b/python/valuecell/core/coordinate/response.py index 4c2f7c6ad..de97cdfaa 100644 --- a/python/valuecell/core/coordinate/response.py +++ b/python/valuecell/core/coordinate/response.py @@ -380,6 +380,7 @@ def tool_call( tool_result=tool_result, ), role=Role.AGENT, + item_id=tool_call_id, ), ) From 766961f43e785b00e7214070f3d57cc101dc50c0 Mon Sep 17 00:00:00 2001 From: Zhaofeng Zhang <24791380+vcfgv@users.noreply.github.com> Date: Fri, 17 Oct 2025 11:16:33 +0800 Subject: [PATCH 4/5] refactor: update planner prompts to use expected output and correct instruction variable --- python/valuecell/core/coordinate/planner.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/python/valuecell/core/coordinate/planner.py b/python/valuecell/core/coordinate/planner.py index 372332e86..fef698713 100644 --- a/python/valuecell/core/coordinate/planner.py +++ b/python/valuecell/core/coordinate/planner.py @@ -22,7 +22,7 @@ from agno.models.openrouter import OpenRouter from valuecell.core.agent.connect import RemoteConnections -from valuecell.core.coordinate.planner_prompts import PLANNER_INSTRUCTIONS +from valuecell.core.coordinate.planner_prompts import PLANNER_INSTRUCTION, PLANNER_EXPECTED_OUTPUT from valuecell.core.task import Task, TaskPattern, TaskStatus from valuecell.core.types import UserInput from valuecell.utils import generate_uuid @@ -160,7 +160,8 @@ async def _analyze_input_and_create_tasks( ], markdown=False, debug_mode=agent_debug_mode_enabled(), - instructions=[PLANNER_INSTRUCTIONS], + instructions=[PLANNER_INSTRUCTION], + expected_output=PLANNER_EXPECTED_OUTPUT, # context db=InMemoryDb(), add_datetime_to_context=True, From c20156440eb5171f818a511808c63b8bdf366726 Mon Sep 17 00:00:00 2001 From: Zhaofeng Zhang <24791380+vcfgv@users.noreply.github.com> Date: Fri, 17 Oct 2025 13:33:53 +0800 Subject: [PATCH 5/5] fix format --- python/valuecell/core/coordinate/planner.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python/valuecell/core/coordinate/planner.py b/python/valuecell/core/coordinate/planner.py index fef698713..eca84a19b 100644 --- a/python/valuecell/core/coordinate/planner.py +++ b/python/valuecell/core/coordinate/planner.py @@ -22,7 +22,10 @@ from agno.models.openrouter import OpenRouter from valuecell.core.agent.connect import RemoteConnections -from valuecell.core.coordinate.planner_prompts import PLANNER_INSTRUCTION, PLANNER_EXPECTED_OUTPUT +from valuecell.core.coordinate.planner_prompts import ( + PLANNER_EXPECTED_OUTPUT, + PLANNER_INSTRUCTION, +) from valuecell.core.task import Task, TaskPattern, TaskStatus from valuecell.core.types import UserInput from valuecell.utils import generate_uuid