Merge branch 'main' into feature/openrouter-provider
This commit is contained in:
@@ -128,6 +128,12 @@ async def is_active():
|
|||||||
logger.info("Is active endpoint called")
|
logger.info("Is active endpoint called")
|
||||||
return {"is_active": interaction.is_active}
|
return {"is_active": interaction.is_active}
|
||||||
|
|
||||||
|
@api.get("/stop")
|
||||||
|
async def stop():
|
||||||
|
logger.info("Stop endpoint called")
|
||||||
|
interaction.current_agent.request_stop()
|
||||||
|
return JSONResponse(status_code=200, content={"status": "stopped"})
|
||||||
|
|
||||||
@api.get("/latest_answer")
|
@api.get("/latest_answer")
|
||||||
async def get_latest_answer():
|
async def get_latest_answer():
|
||||||
global query_resp_history
|
global query_resp_history
|
||||||
@@ -138,6 +144,7 @@ async def get_latest_answer():
|
|||||||
query_resp = {
|
query_resp = {
|
||||||
"done": "false",
|
"done": "false",
|
||||||
"answer": interaction.current_agent.last_answer,
|
"answer": interaction.current_agent.last_answer,
|
||||||
|
"reasoning": interaction.current_agent.last_reasoning,
|
||||||
"agent_name": interaction.current_agent.agent_name if interaction.current_agent else "None",
|
"agent_name": interaction.current_agent.agent_name if interaction.current_agent else "None",
|
||||||
"success": interaction.current_agent.success,
|
"success": interaction.current_agent.success,
|
||||||
"blocks": {f'{i}': block.jsonify() for i, block in enumerate(interaction.get_last_blocks_result())} if interaction.current_agent else {},
|
"blocks": {f'{i}': block.jsonify() for i, block in enumerate(interaction.get_last_blocks_result())} if interaction.current_agent else {},
|
||||||
@@ -145,6 +152,7 @@ async def get_latest_answer():
|
|||||||
"uid": uid
|
"uid": uid
|
||||||
}
|
}
|
||||||
interaction.current_agent.last_answer = ""
|
interaction.current_agent.last_answer = ""
|
||||||
|
interaction.current_agent.last_reasoning = ""
|
||||||
query_resp_history.append(query_resp)
|
query_resp_history.append(query_resp)
|
||||||
return JSONResponse(status_code=200, content=query_resp)
|
return JSONResponse(status_code=200, content=query_resp)
|
||||||
if query_resp_history:
|
if query_resp_history:
|
||||||
@@ -158,6 +166,7 @@ async def think_wrapper(interaction, query):
|
|||||||
success = await interaction.think()
|
success = await interaction.think()
|
||||||
if not success:
|
if not success:
|
||||||
interaction.last_answer = "Error: No answer from agent"
|
interaction.last_answer = "Error: No answer from agent"
|
||||||
|
interaction.last_reasoning = "Error: No reasoning from agent"
|
||||||
interaction.last_success = False
|
interaction.last_success = False
|
||||||
else:
|
else:
|
||||||
interaction.last_success = True
|
interaction.last_success = True
|
||||||
@@ -166,7 +175,8 @@ async def think_wrapper(interaction, query):
|
|||||||
return success
|
return success
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Error in think_wrapper: {str(e)}")
|
logger.error(f"Error in think_wrapper: {str(e)}")
|
||||||
interaction.last_answer = f"Error: {str(e)}"
|
interaction.last_answer = f""
|
||||||
|
interaction.last_reasoning = f"Error: {str(e)}"
|
||||||
interaction.last_success = False
|
interaction.last_success = False
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
@@ -177,6 +187,7 @@ async def process_query(request: QueryRequest):
|
|||||||
query_resp = QueryResponse(
|
query_resp = QueryResponse(
|
||||||
done="false",
|
done="false",
|
||||||
answer="",
|
answer="",
|
||||||
|
reasoning="",
|
||||||
agent_name="Unknown",
|
agent_name="Unknown",
|
||||||
success="false",
|
success="false",
|
||||||
blocks={},
|
blocks={},
|
||||||
@@ -194,6 +205,7 @@ async def process_query(request: QueryRequest):
|
|||||||
|
|
||||||
if not success:
|
if not success:
|
||||||
query_resp.answer = interaction.last_answer
|
query_resp.answer = interaction.last_answer
|
||||||
|
query_resp.reasoning = interaction.last_reasoning
|
||||||
return JSONResponse(status_code=400, content=query_resp.jsonify())
|
return JSONResponse(status_code=400, content=query_resp.jsonify())
|
||||||
|
|
||||||
if interaction.current_agent:
|
if interaction.current_agent:
|
||||||
@@ -208,6 +220,7 @@ async def process_query(request: QueryRequest):
|
|||||||
logger.info(f"Blocks: {blocks_json}")
|
logger.info(f"Blocks: {blocks_json}")
|
||||||
query_resp.done = "true"
|
query_resp.done = "true"
|
||||||
query_resp.answer = interaction.last_answer
|
query_resp.answer = interaction.last_answer
|
||||||
|
query_resp.reasoning = interaction.last_reasoning
|
||||||
query_resp.agent_name = interaction.current_agent.agent_name
|
query_resp.agent_name = interaction.current_agent.agent_name
|
||||||
query_resp.success = str(interaction.last_success)
|
query_resp.success = str(interaction.last_success)
|
||||||
query_resp.blocks = blocks_json
|
query_resp.blocks = blocks_json
|
||||||
|
|||||||
@@ -167,6 +167,88 @@ body {
|
|||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Message header layout */
|
||||||
|
.message-header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: flex-start;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reasoning-toggle {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
border: 1px solid rgba(255, 255, 255, 0.2);
|
||||||
|
border-radius: 4px;
|
||||||
|
color: #fff;
|
||||||
|
padding: 4px 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reasoning-toggle:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.2);
|
||||||
|
border-color: rgba(255, 255, 255, 0.3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reasoning-toggle:active {
|
||||||
|
transform: translateY(1px);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Reasoning content container */
|
||||||
|
.reasoning-content {
|
||||||
|
margin-top: 12px;
|
||||||
|
padding: 12px;
|
||||||
|
background: rgba(0, 0, 0, 0.2);
|
||||||
|
border-left: 3px solid rgba(255, 255, 255, 0.3);
|
||||||
|
border-radius: 0 4px 4px 0;
|
||||||
|
font-size: 0.9em;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reasoning-content h1,
|
||||||
|
.reasoning-content h2,
|
||||||
|
.reasoning-content h3,
|
||||||
|
.reasoning-content h4,
|
||||||
|
.reasoning-content h5,
|
||||||
|
.reasoning-content h6 {
|
||||||
|
font-size: 1em;
|
||||||
|
margin: 8px 0 4px 0;
|
||||||
|
color: rgba(255, 255, 255, 0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
.reasoning-content p {
|
||||||
|
margin: 6px 0;
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Alternative light theme styles */
|
||||||
|
.message.user-message .reasoning-toggle {
|
||||||
|
background: rgba(0, 0, 0, 0.05);
|
||||||
|
border-color: rgba(0, 0, 0, 0.1);
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message.user-message .reasoning-toggle:hover {
|
||||||
|
background: rgba(0, 0, 0, 0.1);
|
||||||
|
border-color: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message.user-message .reasoning-content {
|
||||||
|
background: rgba(0, 0, 0, 0.03);
|
||||||
|
border-left-color: rgba(0, 0, 0, 0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.message.user-message .reasoning-content p {
|
||||||
|
color: rgba(0, 0, 0, 0.7);
|
||||||
|
}
|
||||||
|
|
||||||
.placeholder {
|
.placeholder {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #64748b; /* lighter gray */
|
color: #64748b; /* lighter gray */
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ function App() {
|
|||||||
const [responseData, setResponseData] = useState(null);
|
const [responseData, setResponseData] = useState(null);
|
||||||
const [isOnline, setIsOnline] = useState(false);
|
const [isOnline, setIsOnline] = useState(false);
|
||||||
const [status, setStatus] = useState('Agents ready');
|
const [status, setStatus] = useState('Agents ready');
|
||||||
|
const [expandedReasoning, setExpandedReasoning] = useState(new Set());
|
||||||
const messagesEndRef = useRef(null);
|
const messagesEndRef = useRef(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -75,6 +76,18 @@ function App() {
|
|||||||
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
|
messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toggleReasoning = (messageIndex) => {
|
||||||
|
setExpandedReasoning(prev => {
|
||||||
|
const newSet = new Set(prev);
|
||||||
|
if (newSet.has(messageIndex)) {
|
||||||
|
newSet.delete(messageIndex);
|
||||||
|
} else {
|
||||||
|
newSet.add(messageIndex);
|
||||||
|
}
|
||||||
|
return newSet;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
const fetchLatestAnswer = async () => {
|
const fetchLatestAnswer = async () => {
|
||||||
try {
|
try {
|
||||||
const res = await axios.get('http://127.0.0.1:8000/latest_answer');
|
const res = await axios.get('http://127.0.0.1:8000/latest_answer');
|
||||||
@@ -94,6 +107,7 @@ function App() {
|
|||||||
{
|
{
|
||||||
type: 'agent',
|
type: 'agent',
|
||||||
content: data.answer,
|
content: data.answer,
|
||||||
|
reasoning: data.reasoning,
|
||||||
agentName: data.agent_name,
|
agentName: data.agent_name,
|
||||||
status: data.status,
|
status: data.status,
|
||||||
uid: data.uid,
|
uid: data.uid,
|
||||||
@@ -121,6 +135,19 @@ function App() {
|
|||||||
}));
|
}));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleStop = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
checkHealth();
|
||||||
|
setIsLoading(false);
|
||||||
|
setError(null);
|
||||||
|
try {
|
||||||
|
const res = await axios.get('http://127.0.0.1:8000/stop');
|
||||||
|
setStatus("Requesting stop...");
|
||||||
|
} catch (err) {
|
||||||
|
console.error('Error stopping the agent:', err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const handleSubmit = async (e) => {
|
const handleSubmit = async (e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
checkHealth();
|
checkHealth();
|
||||||
@@ -172,8 +199,6 @@ function App() {
|
|||||||
</header>
|
</header>
|
||||||
<main className="main">
|
<main className="main">
|
||||||
<div className="app-sections">
|
<div className="app-sections">
|
||||||
|
|
||||||
|
|
||||||
<div className="chat-section">
|
<div className="chat-section">
|
||||||
<h2>Chat Interface</h2>
|
<h2>Chat Interface</h2>
|
||||||
<div className="messages">
|
<div className="messages">
|
||||||
@@ -191,10 +216,28 @@ function App() {
|
|||||||
: 'error-message'
|
: 'error-message'
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
{msg.type === 'agent' && (
|
<div className="message-header">
|
||||||
<span className="agent-name">{msg.agentName}</span>
|
{msg.type === 'agent' && (
|
||||||
)}
|
<span className="agent-name">{msg.agentName}</span>
|
||||||
<ReactMarkdown>{msg.content}</ReactMarkdown>
|
)}
|
||||||
|
{msg.type === 'agent' && msg.reasoning && expandedReasoning.has(index) && (
|
||||||
|
<div className="reasoning-content">
|
||||||
|
<ReactMarkdown>{msg.reasoning}</ReactMarkdown>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{msg.type === 'agent' && (
|
||||||
|
<button
|
||||||
|
className="reasoning-toggle"
|
||||||
|
onClick={() => toggleReasoning(index)}
|
||||||
|
title={expandedReasoning.has(index) ? "Hide reasoning" : "Show reasoning"}
|
||||||
|
>
|
||||||
|
{expandedReasoning.has(index) ? '▼' : '▶'} Reasoning
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="message-content">
|
||||||
|
<ReactMarkdown>{msg.content}</ReactMarkdown>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
@@ -213,6 +256,9 @@ function App() {
|
|||||||
<button type="submit" disabled={isLoading}>
|
<button type="submit" disabled={isLoading}>
|
||||||
Send
|
Send
|
||||||
</button>
|
</button>
|
||||||
|
<button onClick={handleStop}>
|
||||||
|
Stop
|
||||||
|
</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,9 @@ class Agent():
|
|||||||
self.blocks_result = []
|
self.blocks_result = []
|
||||||
self.success = True
|
self.success = True
|
||||||
self.last_answer = ""
|
self.last_answer = ""
|
||||||
|
self.last_reasoning = ""
|
||||||
self.status_message = "Haven't started yet"
|
self.status_message = "Haven't started yet"
|
||||||
|
self.stop = False
|
||||||
self.verbose = verbose
|
self.verbose = verbose
|
||||||
self.executor = ThreadPoolExecutor(max_workers=1)
|
self.executor = ThreadPoolExecutor(max_workers=1)
|
||||||
|
|
||||||
@@ -64,6 +66,10 @@ class Agent():
|
|||||||
def get_last_answer(self) -> str:
|
def get_last_answer(self) -> str:
|
||||||
return self.last_answer
|
return self.last_answer
|
||||||
|
|
||||||
|
@property
|
||||||
|
def get_last_reasoning(self) -> str:
|
||||||
|
return self.last_reasoning
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def get_blocks(self) -> list:
|
def get_blocks(self) -> list:
|
||||||
return self.blocks_result
|
return self.blocks_result
|
||||||
@@ -114,6 +120,13 @@ class Agent():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise e
|
||||||
|
|
||||||
|
def request_stop(self) -> None:
|
||||||
|
"""
|
||||||
|
Request the agent to stop.
|
||||||
|
"""
|
||||||
|
self.stop = True
|
||||||
|
self.status_message = "Stopped"
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def process(self, prompt, speech_module) -> str:
|
def process(self, prompt, speech_module) -> str:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -181,6 +181,7 @@ class BrowserAgent(Agent):
|
|||||||
animate_thinking("Thinking...", color="status")
|
animate_thinking("Thinking...", color="status")
|
||||||
self.memory.push('user', prompt)
|
self.memory.push('user', prompt)
|
||||||
answer, reasoning = await self.llm_request()
|
answer, reasoning = await self.llm_request()
|
||||||
|
self.last_reasoning = reasoning
|
||||||
if show_reasoning:
|
if show_reasoning:
|
||||||
pretty_print(reasoning, color="failure")
|
pretty_print(reasoning, color="failure")
|
||||||
pretty_print(answer, color="output")
|
pretty_print(answer, color="output")
|
||||||
@@ -349,11 +350,13 @@ class BrowserAgent(Agent):
|
|||||||
self.show_search_results(search_result)
|
self.show_search_results(search_result)
|
||||||
prompt = self.make_newsearch_prompt(user_prompt, search_result)
|
prompt = self.make_newsearch_prompt(user_prompt, search_result)
|
||||||
unvisited = [None]
|
unvisited = [None]
|
||||||
while not complete and len(unvisited) > 0:
|
while not complete and len(unvisited) > 0 and not self.stop:
|
||||||
|
|
||||||
self.memory.clear()
|
self.memory.clear()
|
||||||
unvisited = self.select_unvisited(search_result)
|
unvisited = self.select_unvisited(search_result)
|
||||||
answer, reasoning = await self.llm_decide(prompt, show_reasoning = False)
|
answer, reasoning = await self.llm_decide(prompt, show_reasoning = False)
|
||||||
|
if self.stop:
|
||||||
|
pretty_print(f"Requested stop.", color="failure")
|
||||||
|
break
|
||||||
if self.last_answer == answer:
|
if self.last_answer == answer:
|
||||||
prompt = self.stuck_prompt(user_prompt, unvisited)
|
prompt = self.stuck_prompt(user_prompt, unvisited)
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -51,10 +51,12 @@ class CoderAgent(Agent):
|
|||||||
self.memory.push('user', prompt)
|
self.memory.push('user', prompt)
|
||||||
clarify_trigger = "REQUEST_CLARIFICATION"
|
clarify_trigger = "REQUEST_CLARIFICATION"
|
||||||
|
|
||||||
while attempt < max_attempts:
|
while attempt < max_attempts and not self.stop:
|
||||||
|
print("Stopped?", self.stop)
|
||||||
animate_thinking("Thinking...", color="status")
|
animate_thinking("Thinking...", color="status")
|
||||||
await self.wait_message(speech_module)
|
await self.wait_message(speech_module)
|
||||||
answer, reasoning = await self.llm_request()
|
answer, reasoning = await self.llm_request()
|
||||||
|
self.last_reasoning = reasoning
|
||||||
if clarify_trigger in answer:
|
if clarify_trigger in answer:
|
||||||
self.last_answer = answer
|
self.last_answer = answer
|
||||||
await asyncio.sleep(0)
|
await asyncio.sleep(0)
|
||||||
|
|||||||
@@ -28,10 +28,11 @@ class FileAgent(Agent):
|
|||||||
exec_success = False
|
exec_success = False
|
||||||
prompt += f"\nYou must work in directory: {self.work_dir}"
|
prompt += f"\nYou must work in directory: {self.work_dir}"
|
||||||
self.memory.push('user', prompt)
|
self.memory.push('user', prompt)
|
||||||
while exec_success is False:
|
while exec_success is False and not self.stop:
|
||||||
await self.wait_message(speech_module)
|
await self.wait_message(speech_module)
|
||||||
animate_thinking("Thinking...", color="status")
|
animate_thinking("Thinking...", color="status")
|
||||||
answer, reasoning = await self.llm_request()
|
answer, reasoning = await self.llm_request()
|
||||||
|
self.last_reasoning = reasoning
|
||||||
exec_success, _ = self.execute_modules(answer)
|
exec_success, _ = self.execute_modules(answer)
|
||||||
answer = self.remove_blocks(answer)
|
answer = self.remove_blocks(answer)
|
||||||
self.last_answer = answer
|
self.last_answer = answer
|
||||||
|
|||||||
@@ -83,11 +83,15 @@ class PlannerAgent(Agent):
|
|||||||
self.logger.warning(f"Agent {task['agent']} does not exist.")
|
self.logger.warning(f"Agent {task['agent']} does not exist.")
|
||||||
pretty_print(f"Agent {task['agent']} does not exist.", color="warning")
|
pretty_print(f"Agent {task['agent']} does not exist.", color="warning")
|
||||||
return []
|
return []
|
||||||
agent = {
|
try:
|
||||||
'agent': task['agent'],
|
agent = {
|
||||||
'id': task['id'],
|
'agent': task['agent'],
|
||||||
'task': task['task']
|
'id': task['id'],
|
||||||
}
|
'task': task['task']
|
||||||
|
}
|
||||||
|
except:
|
||||||
|
self.logger.warning("Missing field in json plan.")
|
||||||
|
return []
|
||||||
self.logger.info(f"Created agent {task['agent']} with task: {task['task']}")
|
self.logger.info(f"Created agent {task['agent']} with task: {task['task']}")
|
||||||
if 'need' in task:
|
if 'need' in task:
|
||||||
self.logger.info(f"Agent {task['agent']} was given info:\n {task['need']}")
|
self.logger.info(f"Agent {task['agent']} was given info:\n {task['need']}")
|
||||||
@@ -156,6 +160,7 @@ class PlannerAgent(Agent):
|
|||||||
return []
|
return []
|
||||||
agents_tasks = self.parse_agent_tasks(answer)
|
agents_tasks = self.parse_agent_tasks(answer)
|
||||||
if agents_tasks == []:
|
if agents_tasks == []:
|
||||||
|
self.show_plan(agents_tasks, answer)
|
||||||
prompt = f"Failed to parse the tasks. Please write down your task followed by a json plan within ```json. Do not ask for clarification.\n"
|
prompt = f"Failed to parse the tasks. Please write down your task followed by a json plan within ```json. Do not ask for clarification.\n"
|
||||||
pretty_print("Failed to make plan. Retrying...", color="warning")
|
pretty_print("Failed to make plan. Retrying...", color="warning")
|
||||||
continue
|
continue
|
||||||
@@ -178,7 +183,11 @@ class PlannerAgent(Agent):
|
|||||||
last_agent_work = agents_work_result[id]
|
last_agent_work = agents_work_result[id]
|
||||||
tool_success_str = "success" if success else "failure"
|
tool_success_str = "success" if success else "failure"
|
||||||
pretty_print(f"Agent {id} work {tool_success_str}.", color="success" if success else "failure")
|
pretty_print(f"Agent {id} work {tool_success_str}.", color="success" if success else "failure")
|
||||||
if int(id) == len(agents_tasks):
|
try:
|
||||||
|
id_int = int(id)
|
||||||
|
except Exception as e:
|
||||||
|
return agents_tasks
|
||||||
|
if id_int == len(agents_tasks):
|
||||||
next_task = "No task follow, this was the last step. If it failed add a task to recover."
|
next_task = "No task follow, this was the last step. If it failed add a task to recover."
|
||||||
else:
|
else:
|
||||||
next_task = f"Next task is: {agents_tasks[int(id)][0]}."
|
next_task = f"Next task is: {agents_tasks[int(id)][0]}."
|
||||||
@@ -221,8 +230,9 @@ class PlannerAgent(Agent):
|
|||||||
agent_prompt = self.make_prompt(task['task'], required_infos)
|
agent_prompt = self.make_prompt(task['task'], required_infos)
|
||||||
pretty_print(f"Agent {task['agent']} started working...", color="status")
|
pretty_print(f"Agent {task['agent']} started working...", color="status")
|
||||||
self.logger.info(f"Agent {task['agent']} started working on {task['task']}.")
|
self.logger.info(f"Agent {task['agent']} started working on {task['task']}.")
|
||||||
answer, _ = await self.agents[task['agent'].lower()].process(agent_prompt, None)
|
answer, reasoning = await self.agents[task['agent'].lower()].process(agent_prompt, None)
|
||||||
self.last_answer = answer
|
self.last_answer = answer
|
||||||
|
self.last_reasoning = reasoning
|
||||||
self.blocks_result = self.agents[task['agent'].lower()].blocks_result
|
self.blocks_result = self.agents[task['agent'].lower()].blocks_result
|
||||||
agent_answer = self.agents[task['agent'].lower()].raw_answer_blocks(answer)
|
agent_answer = self.agents[task['agent'].lower()].raw_answer_blocks(answer)
|
||||||
success = self.agents[task['agent'].lower()].get_success
|
success = self.agents[task['agent'].lower()].get_success
|
||||||
@@ -257,7 +267,7 @@ class PlannerAgent(Agent):
|
|||||||
return "Failed to parse the tasks.", ""
|
return "Failed to parse the tasks.", ""
|
||||||
i = 0
|
i = 0
|
||||||
steps = len(agents_tasks)
|
steps = len(agents_tasks)
|
||||||
while i < steps:
|
while i < steps and not self.stop:
|
||||||
task_name, task = agents_tasks[i][0], agents_tasks[i][1]
|
task_name, task = agents_tasks[i][0], agents_tasks[i][1]
|
||||||
self.status_message = "Starting agents..."
|
self.status_message = "Starting agents..."
|
||||||
pretty_print(f"I will {task_name}.", color="info")
|
pretty_print(f"I will {task_name}.", color="info")
|
||||||
@@ -271,6 +281,8 @@ class PlannerAgent(Agent):
|
|||||||
answer, success = await self.start_agent_process(task, required_infos)
|
answer, success = await self.start_agent_process(task, required_infos)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
raise e
|
raise e
|
||||||
|
if self.stop:
|
||||||
|
pretty_print(f"Requested stop.", color="failure")
|
||||||
agents_work_result[task['id']] = answer
|
agents_work_result[task['id']] = answer
|
||||||
agents_tasks = await self.update_plan(goal, agents_tasks, agents_work_result, task['id'], success)
|
agents_tasks = await self.update_plan(goal, agents_tasks, agents_work_result, task['id'], success)
|
||||||
steps = len(agents_tasks)
|
steps = len(agents_tasks)
|
||||||
|
|||||||
+14
-5
@@ -206,7 +206,11 @@ class Browser:
|
|||||||
|
|
||||||
def setup_tabs(self):
|
def setup_tabs(self):
|
||||||
self.tabs = self.driver.window_handles
|
self.tabs = self.driver.window_handles
|
||||||
self.driver.get("https://www.google.com")
|
try:
|
||||||
|
self.driver.get("https://www.google.com")
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.log(f"Failed to setup initial tab:" + str(e))
|
||||||
|
pass
|
||||||
self.screenshot()
|
self.screenshot()
|
||||||
|
|
||||||
def switch_control_tab(self):
|
def switch_control_tab(self):
|
||||||
@@ -215,7 +219,11 @@ class Browser:
|
|||||||
|
|
||||||
def load_anticatpcha_manually(self):
|
def load_anticatpcha_manually(self):
|
||||||
pretty_print("You might want to install the AntiCaptcha extension for captchas.", color="warning")
|
pretty_print("You might want to install the AntiCaptcha extension for captchas.", color="warning")
|
||||||
self.driver.get(self.anticaptcha)
|
try:
|
||||||
|
self.driver.get(self.anticaptcha)
|
||||||
|
except Exception as e:
|
||||||
|
self.logger.log(f"Failed to setup initial tab:" + str(e))
|
||||||
|
pass
|
||||||
|
|
||||||
def human_move(element):
|
def human_move(element):
|
||||||
actions = ActionChains(driver)
|
actions = ActionChains(driver)
|
||||||
@@ -685,15 +693,16 @@ class Browser:
|
|||||||
input_elements = self.driver.execute_script(script)
|
input_elements = self.driver.execute_script(script)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
driver = create_driver(headless=False, stealth_mode=True)
|
driver = create_driver(headless=False, stealth_mode=True, crx_path="../crx/nopecha.crx")
|
||||||
browser = Browser(driver, anticaptcha_manual_install=False)
|
browser = Browser(driver, anticaptcha_manual_install=True)
|
||||||
|
|
||||||
input("press enter to continue")
|
input("press enter to continue")
|
||||||
print("AntiCaptcha / Form Test")
|
print("AntiCaptcha / Form Test")
|
||||||
|
browser.go_to("https://www.google.com/recaptcha/api2/demo")
|
||||||
|
time.sleep(50)
|
||||||
browser.go_to("https://bot.sannysoft.com")
|
browser.go_to("https://bot.sannysoft.com")
|
||||||
time.sleep(5)
|
time.sleep(5)
|
||||||
#txt = browser.get_text()
|
#txt = browser.get_text()
|
||||||
#browser.go_to("https://www.google.com/recaptcha/api2/demo")
|
|
||||||
browser.go_to("https://home.openweathermap.org/users/sign_up")
|
browser.go_to("https://home.openweathermap.org/users/sign_up")
|
||||||
inputs_visible = browser.get_form_inputs()
|
inputs_visible = browser.get_form_inputs()
|
||||||
print("inputs:", inputs_visible)
|
print("inputs:", inputs_visible)
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ class Interaction:
|
|||||||
self.current_agent = None
|
self.current_agent = None
|
||||||
self.last_query = None
|
self.last_query = None
|
||||||
self.last_answer = None
|
self.last_answer = None
|
||||||
|
self.last_reasoning = None
|
||||||
self.agents = agents
|
self.agents = agents
|
||||||
self.tts_enabled = tts_enabled
|
self.tts_enabled = tts_enabled
|
||||||
self.stt_enabled = stt_enabled
|
self.stt_enabled = stt_enabled
|
||||||
@@ -158,7 +159,7 @@ class Interaction:
|
|||||||
tmp = self.last_answer
|
tmp = self.last_answer
|
||||||
self.current_agent = agent
|
self.current_agent = agent
|
||||||
self.is_generating = True
|
self.is_generating = True
|
||||||
self.last_answer, _ = await agent.process(self.last_query, self.speech)
|
self.last_answer, self.last_reasoning = await agent.process(self.last_query, self.speech)
|
||||||
self.is_generating = False
|
self.is_generating = False
|
||||||
if push_last_agent_memory:
|
if push_last_agent_memory:
|
||||||
self.current_agent.memory.push('user', self.last_query)
|
self.current_agent.memory.push('user', self.last_query)
|
||||||
|
|||||||
@@ -58,6 +58,38 @@ class Provider:
|
|||||||
exit(1)
|
exit(1)
|
||||||
return api_key
|
return api_key
|
||||||
|
|
||||||
|
def anthropic_fn(self, history, verbose=False):
|
||||||
|
"""
|
||||||
|
Use Anthropic to generate text.
|
||||||
|
"""
|
||||||
|
from anthropic import Anthropic
|
||||||
|
|
||||||
|
client = Anthropic(api_key=self.api_key)
|
||||||
|
system_message = None
|
||||||
|
messages = []
|
||||||
|
for message in history:
|
||||||
|
clean_message = {'role': message['role'], 'content': message['content']}
|
||||||
|
if message['role'] == 'system':
|
||||||
|
system_message = message['content']
|
||||||
|
else:
|
||||||
|
messages.append(clean_message)
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = client.messages.create(
|
||||||
|
model=self.model,
|
||||||
|
max_tokens=1024,
|
||||||
|
messages=messages,
|
||||||
|
system=system_message
|
||||||
|
)
|
||||||
|
if response is None:
|
||||||
|
raise Exception("Anthropic response is empty.")
|
||||||
|
thought = response.content[0].text
|
||||||
|
if verbose:
|
||||||
|
print(thought)
|
||||||
|
return thought
|
||||||
|
except Exception as e:
|
||||||
|
raise Exception(f"Anthropic API error: {str(e)}") from e
|
||||||
|
|
||||||
def respond(self, history, verbose=True):
|
def respond(self, history, verbose=True):
|
||||||
"""
|
"""
|
||||||
Use the choosen provider to generate text.
|
Use the choosen provider to generate text.
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ class QueryRequest(BaseModel):
|
|||||||
class QueryResponse(BaseModel):
|
class QueryResponse(BaseModel):
|
||||||
done: str
|
done: str
|
||||||
answer: str
|
answer: str
|
||||||
|
reasoning: str
|
||||||
agent_name: str
|
agent_name: str
|
||||||
success: str
|
success: str
|
||||||
blocks: dict
|
blocks: dict
|
||||||
@@ -32,6 +33,7 @@ class QueryResponse(BaseModel):
|
|||||||
return {
|
return {
|
||||||
"done": self.done,
|
"done": self.done,
|
||||||
"answer": self.answer,
|
"answer": self.answer,
|
||||||
|
"reasoning": self.reasoning,
|
||||||
"agent_name": self.agent_name,
|
"agent_name": self.agent_name,
|
||||||
"success": self.success,
|
"success": self.success,
|
||||||
"blocks": self.blocks,
|
"blocks": self.blocks,
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ if __name__ == "__main__": # if running as a script for individual testing
|
|||||||
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
|
||||||
|
|
||||||
from sources.tools.tools import Tools
|
from sources.tools.tools import Tools
|
||||||
from sources.tools.safety import is_unsafe
|
from sources.tools.safety import is_any_unsafe
|
||||||
|
|
||||||
class BashInterpreter(Tools):
|
class BashInterpreter(Tools):
|
||||||
"""
|
"""
|
||||||
@@ -43,9 +43,9 @@ class BashInterpreter(Tools):
|
|||||||
for command in commands:
|
for command in commands:
|
||||||
command = f"cd {self.work_dir} && {command}"
|
command = f"cd {self.work_dir} && {command}"
|
||||||
command = command.replace('\n', '')
|
command = command.replace('\n', '')
|
||||||
if self.safe_mode and is_unsafe(commands):
|
if self.safe_mode and is_any_unsafe(commands):
|
||||||
print(f"Unsafe command rejected: {command}")
|
print(f"Unsafe command rejected: {command}")
|
||||||
return "Unsafe command detected, execution aborted."
|
return "\nUnsafe command: {command}. Execution aborted. This is beyond allowed capabilities report to user."
|
||||||
if self.language_bash_attempt(command) and self.allow_language_exec_bash == False:
|
if self.language_bash_attempt(command) and self.allow_language_exec_bash == False:
|
||||||
continue
|
continue
|
||||||
try:
|
try:
|
||||||
@@ -100,6 +100,7 @@ class BashInterpreter(Tools):
|
|||||||
r"not permitted",
|
r"not permitted",
|
||||||
r"not installed",
|
r"not installed",
|
||||||
r"not found",
|
r"not found",
|
||||||
|
r"aborted",
|
||||||
r"no such",
|
r"no such",
|
||||||
r"too many",
|
r"too many",
|
||||||
r"too few",
|
r"too few",
|
||||||
|
|||||||
@@ -66,6 +66,15 @@ unsafe_commands_windows = [
|
|||||||
"bootcfg"
|
"bootcfg"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
def is_any_unsafe(cmds):
|
||||||
|
"""
|
||||||
|
check if any bash command is unsafe.
|
||||||
|
"""
|
||||||
|
for cmd in cmds:
|
||||||
|
if is_unsafe(cmd):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def is_unsafe(cmd):
|
def is_unsafe(cmd):
|
||||||
"""
|
"""
|
||||||
check if a bash command is unsafe.
|
check if a bash command is unsafe.
|
||||||
|
|||||||
Reference in New Issue
Block a user