agent.py aktualisiert

This commit is contained in:
2026-07-05 09:54:46 +00:00
parent af9fed431f
commit f291cb950a
+22 -36
View File
@@ -1,7 +1,8 @@
from llm.bedrock import BedrockClient from llm.bedrock import BedrockClient
from jarvis_mcp.client import MCPClient from jarvis_mcp.client import MCPClient # oder wo auch immer dein MCP-Client liegt
from config import MCP_URL from config import MCP_URL
from util.logger import get_logger from util.logger import get_logger
import asyncio
class Agent: class Agent:
@@ -12,7 +13,6 @@ class Agent:
self.mcp = MCPClient(MCP_URL) self.mcp = MCPClient(MCP_URL)
self.tools = [] self.tools = []
self.messages = [ self.messages = [
{ {
"role": "system", "role": "system",
@@ -21,7 +21,7 @@ class Agent:
"text": ( "text": (
"Du bist N.O.R.A, ein Smart-Home Assistent. " "Du bist N.O.R.A, ein Smart-Home Assistent. "
"Du steuerst Geräte über Tools. " "Du steuerst Geräte über Tools. "
"Nutze Tools wenn sinnvoll." "Nutze Tools wenn sinnvoll. Sei präzise und hilfreich."
) )
} }
] ]
@@ -46,7 +46,7 @@ class Agent:
for t in res.tools for t in res.tools
] ]
self.logger.info(f"{len(self.tools)} Tools geladen") self.logger.info(f"{len(self.tools)} Tools erfolgreich geladen")
except Exception as e: except Exception as e:
self.logger.error(f"Tool Load Error: {e}") self.logger.error(f"Tool Load Error: {e}")
@@ -57,8 +57,10 @@ class Agent:
# ------------------------- # -------------------------
async def _run_tool(self, tool): async def _run_tool(self, tool):
try: try:
name = tool.get("name") # Robustere Extraktion
args = tool.get("input", {}) or {} tool_use = tool.get("toolUse", tool) # falls schon extrahiert
name = tool_use.get("name")
args = tool_use.get("input", {}) or {}
self.logger.info(f"Tool Call → {name} | args={args}") self.logger.info(f"Tool Call → {name} | args={args}")
@@ -67,35 +69,33 @@ class Agent:
# MCP result stabilisieren # MCP result stabilisieren
if hasattr(result, "content"): if hasattr(result, "content"):
return result.content return result.content
return result return result
except Exception as e: except Exception as e:
self.logger.error(f"Tool Error ({tool.get('name')}): {e}") self.logger.error(f"Tool Error ({name}): {e}")
return f"ERROR: {e}" return f"ERROR: {e}"
# ------------------------- # -------------------------
# MAIN LOOP # MAIN LOOP
# ------------------------- # -------------------------
async def run(self, user_input: str): async def run(self, user_input: str):
self.messages.append({ self.messages.append({
"role": "user", "role": "user",
"content": [{"text": user_input}] "content": [{"text": user_input}]
}) })
for _ in range(8): for iteration in range(10): # etwas mehr Schleifendurchläufe erlaubt
try: try:
response = await self.llm.chat( response = await self.llm.chat(
messages=self.messages, messages=self.messages,
tools=self.tools tools=self.tools if self.tools else None
) )
except Exception as e: except Exception as e:
self.logger.error(f"LLM Error: {e}") self.logger.error(f"LLM Error: {e}")
return f"LLM Fehler: {e}" return f"LLM Fehler: {e}"
# Response-Struktur von Bedrock Converse
output = response.get("output", {}) output = response.get("output", {})
message = output.get("message", {}) message = output.get("message", {})
content = message.get("content", []) content = message.get("content", [])
@@ -103,25 +103,18 @@ class Agent:
tool_uses = [] tool_uses = []
final_text = [] final_text = []
# ------------------------- # Verbessertes Parsing
# PARSE RESPONSE SAFE
# -------------------------
for c in content: for c in content:
if "toolUse" in c:
tool = c.get("toolUse") tool_uses.append(c)
if tool: elif "text" in c:
tool_uses.append(tool)
if "text" in c:
final_text.append(c["text"]) final_text.append(c["text"])
# -------------------------
# TOOL EXECUTION PATH # TOOL EXECUTION PATH
# -------------------------
if tool_uses: if tool_uses:
self.logger.info(f"{len(tool_uses)} Tool(s) detected") self.logger.info(f"{len(tool_uses)} Tool(s) detected")
# Assistant-Nachricht mit Tool-Call speichern
self.messages.append({ self.messages.append({
"role": "assistant", "role": "assistant",
"content": content "content": content
@@ -130,32 +123,25 @@ class Agent:
tool_results = [] tool_results = []
for tool in tool_uses: for tool in tool_uses:
result = await self._run_tool(tool) result = await self._run_tool(tool)
tool_results.append({ tool_results.append({
"toolResult": { "toolResult": {
"toolUseId": tool.get("toolUseId"), "toolUseId": tool.get("toolUse", tool).get("toolUseId"),
"content": [ "content": [{"text": str(result)}]
{
"text": str(result)
}
]
} }
}) })
# Tool-Ergebnisse zurück an das Modell
self.messages.append({ self.messages.append({
"role": "user", "role": "user",
"content": tool_results "content": tool_results
}) })
continue continue # nächste Runde für finale Antwort
# -------------------------
# FINAL RESPONSE # FINAL RESPONSE
# -------------------------
if final_text: if final_text:
text = "\n".join(final_text) text = "\n".join(final_text)
self.messages.append({ self.messages.append({
@@ -165,4 +151,4 @@ class Agent:
return text return text
return "Tool Loop Limit erreicht" return "Tool Loop Limit erreicht. Bitte versuche es erneut."