mirror of
https://github.com/eigent-ai/eigent.git
synced 2026-05-16 19:50:50 +00:00
update
This commit is contained in:
parent
033bd19c93
commit
bea6b7634c
3 changed files with 88 additions and 59 deletions
|
|
@ -4,7 +4,7 @@ from pathlib import Path
|
|||
import re
|
||||
from typing import Literal
|
||||
from loguru import logger
|
||||
from pydantic import BaseModel, field_validator
|
||||
from pydantic import BaseModel, Field, field_validator
|
||||
from camel.types import ModelType, RoleType
|
||||
|
||||
|
||||
|
|
@ -20,6 +20,16 @@ class ChatHistory(BaseModel):
|
|||
content: str
|
||||
|
||||
|
||||
class QuestionAnalysisResult(BaseModel):
|
||||
type: Literal["simple", "complex"] = Field(
|
||||
description="Whether this is a simple question or complex task"
|
||||
)
|
||||
answer: str | None = Field(
|
||||
default=None,
|
||||
description="Direct answer for simple questions. None for complex tasks."
|
||||
)
|
||||
|
||||
|
||||
McpServers = dict[Literal["mcpServers"], dict[str, dict]]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ from app.utils.toolkit.human_toolkit import HumanToolkit
|
|||
from app.utils.toolkit.note_taking_toolkit import NoteTakingToolkit
|
||||
from app.utils.workforce import Workforce
|
||||
from loguru import logger
|
||||
from app.model.chat import Chat, NewAgent, Status, sse_json, TaskContent
|
||||
from app.model.chat import Chat, NewAgent, QuestionAnalysisResult, Status, sse_json, TaskContent
|
||||
from camel.tasks import Task
|
||||
from app.utils.agent import (
|
||||
ListenChatAgent,
|
||||
|
|
@ -708,7 +708,7 @@ def add_sub_tasks(camel_task: Task, update_tasks: list[TaskContent]):
|
|||
|
||||
async def question_confirm(agent: ListenChatAgent, prompt: str, task_lock: TaskLock = None) -> str | Literal[True]:
|
||||
"""
|
||||
Unified question confirmation that can work with or without context.
|
||||
Unified question confirmation using structured output.
|
||||
|
||||
Args:
|
||||
agent: The agent to perform the confirmation
|
||||
|
|
@ -719,46 +719,57 @@ async def question_confirm(agent: ListenChatAgent, prompt: str, task_lock: TaskL
|
|||
Either the answer for simple queries or True for complex tasks
|
||||
"""
|
||||
|
||||
# Build context if available
|
||||
context_prompt = ""
|
||||
|
||||
if task_lock and task_lock.conversation_history:
|
||||
context_prompt = "=== Previous Conversation ===\n"
|
||||
|
||||
for entry in task_lock.conversation_history:
|
||||
role = entry['role']
|
||||
content = entry['content']
|
||||
|
||||
if role == 'task_result':
|
||||
# Include full task result context
|
||||
context_prompt += f"[Task Completed]:\n{content}\n"
|
||||
else:
|
||||
context_prompt += f"{role.capitalize()}: {content}\n"
|
||||
|
||||
context_prompt += "\n"
|
||||
|
||||
if task_lock and task_lock.last_task_result:
|
||||
context_prompt += f"=== Last Task Result ===\n{task_lock.last_task_result}\n\n"
|
||||
|
||||
# Build unified prompt
|
||||
full_prompt = f"""{context_prompt}User Query: {prompt}
|
||||
|
||||
Determine if this is:
|
||||
- A simple question/greeting that can be answered directly → Provide a direct response
|
||||
- A complex task requiring tools, code execution, or multiple steps → Respond with only "yes"
|
||||
Analyze if this is a simple question or complex task:
|
||||
|
||||
Note: If you can answer using the conversation history or previous results, provide the answer directly.
|
||||
"""
|
||||
**Simple question**: Can be answered directly using knowledge or conversation history
|
||||
- Examples: greetings, fact queries, clarifications about previous results
|
||||
- Response: Provide a direct, helpful answer
|
||||
|
||||
**Complex task**: Requires tools, code execution, file operations, or multi-step planning
|
||||
- Examples: "create a file", "search for", "implement feature X"
|
||||
- Response: Indicate this is complex
|
||||
|
||||
# Execute agent
|
||||
resp = agent.step(full_prompt)
|
||||
Based on the user query, determine the type and provide appropriate response."""
|
||||
|
||||
is_complex = resp.msgs[0].content.lower() == "yes"
|
||||
try:
|
||||
resp = agent.step(full_prompt, response_format=QuestionAnalysisResult)
|
||||
|
||||
if not is_complex:
|
||||
return sse_json("wait_confirm", {"content": resp.msgs[0].content, "question": prompt})
|
||||
else:
|
||||
if not resp or not resp.msgs or len(resp.msgs) == 0:
|
||||
return True
|
||||
|
||||
result = resp.msgs[0].parsed
|
||||
|
||||
if not result:
|
||||
content = resp.msgs[0].content
|
||||
if not content:
|
||||
return True
|
||||
normalized = content.strip().lower()
|
||||
if normalized in ["yes", "complex"]:
|
||||
return True
|
||||
return sse_json("wait_confirm", {"content": content, "question": prompt})
|
||||
|
||||
if result.type == "simple" and result.answer:
|
||||
return sse_json("wait_confirm", {"content": result.answer, "question": prompt})
|
||||
else:
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Error in question_confirm: {e}")
|
||||
return True
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -450,34 +450,37 @@ const chatStore = (initial?: Partial<ChatStore>) => createStore<ChatStore>()(
|
|||
*/
|
||||
let currentTaskId = getCurrentTaskId();
|
||||
const previousChatStore = getCurrentChatStore()
|
||||
if(agentMessages.step === "confirmed" &&
|
||||
previousChatStore.tasks[currentTaskId].messages.some(m => m.step === "to_sub_tasks")) {
|
||||
//Create a newChatStore as we are not touching startTask
|
||||
const initResult = projectStore.appendInitChatStore(projectStore.activeProjectId!);
|
||||
if(initResult) {
|
||||
const {taskId: newTaskId, chatStore: newChatStore} = initResult;
|
||||
if(agentMessages.step === "confirmed" &&
|
||||
previousChatStore.tasks[currentTaskId]?.messages?.some(m => m.step === "to_sub_tasks")) {
|
||||
if(projectStore.activeProjectId) {
|
||||
const initResult = projectStore.appendInitChatStore(projectStore.activeProjectId);
|
||||
if(initResult) {
|
||||
const {taskId: newTaskId, chatStore: newChatStore} = initResult;
|
||||
|
||||
/**
|
||||
* Get Last user message
|
||||
* @todo TODO: Internalize the message function when Continuing conversation with improve API
|
||||
* Just like @function chatStore.startTask(_taskId, undefined, undefined, undefined, tempMessageContent, attachesToSend);
|
||||
* Instead of manually removing the message if its a new workforce is needed
|
||||
*/
|
||||
const lastMessage = previousChatStore.tasks[currentTaskId].messages.at(-1);
|
||||
previousChatStore.removeMessage(currentTaskId, lastMessage?.id!);
|
||||
/**
|
||||
* Get Last user message
|
||||
* @todo TODO: Internalize the message function when Continuing conversation with improve API
|
||||
* Just like @function chatStore.startTask(_taskId, undefined, undefined, undefined, tempMessageContent, attachesToSend);
|
||||
* Instead of manually removing the message if its a new workforce is needed
|
||||
*/
|
||||
const lastMessage = previousChatStore.tasks[currentTaskId]?.messages.at(-1);
|
||||
if(lastMessage?.id) {
|
||||
previousChatStore.removeMessage(currentTaskId, lastMessage.id);
|
||||
}
|
||||
|
||||
newChatStore?.getState().setIsPending(newTaskId, true);
|
||||
// Add the user message to show it in UI
|
||||
newChatStore?.getState().addMessages(newTaskId, {
|
||||
id: generateUniqueId(),
|
||||
role: "user",
|
||||
content: lastMessage?.content ?? "",
|
||||
//Use previous chatStore's attaches
|
||||
attaches: JSON.parse(JSON.stringify(previousChatStore.tasks[currentTaskId]?.attaches)) || [],
|
||||
});
|
||||
newChatStore?.getState().setIsPending(newTaskId, true);
|
||||
if(lastMessage) {
|
||||
newChatStore?.getState().addMessages(newTaskId, {
|
||||
id: generateUniqueId(),
|
||||
role: "user",
|
||||
content: lastMessage.content ?? "",
|
||||
attaches: [...(previousChatStore.tasks[currentTaskId]?.attaches || [])],
|
||||
});
|
||||
}
|
||||
|
||||
updateLockedReferences(newChatStore, newTaskId);
|
||||
console.log("[NEW CHATSTORE] In current workforce instance");
|
||||
updateLockedReferences(newChatStore, newTaskId);
|
||||
console.log("[NEW CHATSTORE] In current workforce instance");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1513,18 +1516,23 @@ const chatStore = (initial?: Partial<ChatStore>) => createStore<ChatStore>()(
|
|||
}))
|
||||
},
|
||||
removeMessage(taskId, messageId) {
|
||||
set((state) => ({
|
||||
...state,
|
||||
tasks: {
|
||||
...state.tasks,
|
||||
[taskId]: {
|
||||
...state.tasks[taskId],
|
||||
messages: state.tasks[taskId].messages.filter(
|
||||
(message) => message.id !== messageId
|
||||
),
|
||||
set((state) => {
|
||||
if (!state.tasks[taskId]) {
|
||||
return state;
|
||||
}
|
||||
return {
|
||||
...state,
|
||||
tasks: {
|
||||
...state.tasks,
|
||||
[taskId]: {
|
||||
...state.tasks[taskId],
|
||||
messages: state.tasks[taskId].messages.filter(
|
||||
(message) => message.id !== messageId
|
||||
),
|
||||
},
|
||||
},
|
||||
},
|
||||
}))
|
||||
};
|
||||
})
|
||||
},
|
||||
setCotList(taskId, cotList) {
|
||||
set((state) => ({
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue