diff --git a/agent.py b/agent.py index 9a970cd..e9bf434 100644 --- a/agent.py +++ b/agent.py @@ -1,7 +1,8 @@ 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 util.logger import get_logger +import asyncio class Agent: @@ -12,7 +13,6 @@ class Agent: self.mcp = MCPClient(MCP_URL) self.tools = [] - self.messages = [ { "role": "system", @@ -21,7 +21,7 @@ class Agent: "text": ( "Du bist N.O.R.A, ein Smart-Home Assistent. " "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 ] - self.logger.info(f"{len(self.tools)} Tools geladen") + self.logger.info(f"{len(self.tools)} Tools erfolgreich geladen") except Exception as e: self.logger.error(f"Tool Load Error: {e}") @@ -57,8 +57,10 @@ class Agent: # ------------------------- async def _run_tool(self, tool): try: - name = tool.get("name") - args = tool.get("input", {}) or {} + # Robustere Extraktion + 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}") @@ -67,35 +69,33 @@ class Agent: # MCP result stabilisieren if hasattr(result, "content"): return result.content - return result 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}" # ------------------------- # MAIN LOOP # ------------------------- async def run(self, user_input: str): - self.messages.append({ "role": "user", "content": [{"text": user_input}] }) - for _ in range(8): - + for iteration in range(10): # etwas mehr Schleifendurchläufe erlaubt try: response = await self.llm.chat( messages=self.messages, - tools=self.tools + tools=self.tools if self.tools else None ) except Exception as e: self.logger.error(f"LLM Error: {e}") return f"LLM Fehler: {e}" + # Response-Struktur von Bedrock Converse output = response.get("output", {}) message = output.get("message", {}) content = message.get("content", []) @@ -103,25 +103,18 @@ class Agent: tool_uses = [] final_text = [] - # ------------------------- - # PARSE RESPONSE SAFE - # ------------------------- + # Verbessertes Parsing for c in content: - - tool = c.get("toolUse") - if tool: - tool_uses.append(tool) - - if "text" in c: + if "toolUse" in c: + tool_uses.append(c) + elif "text" in c: final_text.append(c["text"]) - # ------------------------- # TOOL EXECUTION PATH - # ------------------------- if tool_uses: - self.logger.info(f"{len(tool_uses)} Tool(s) detected") + # Assistant-Nachricht mit Tool-Call speichern self.messages.append({ "role": "assistant", "content": content @@ -130,32 +123,25 @@ class Agent: tool_results = [] for tool in tool_uses: - result = await self._run_tool(tool) tool_results.append({ "toolResult": { - "toolUseId": tool.get("toolUseId"), - "content": [ - { - "text": str(result) - } - ] + "toolUseId": tool.get("toolUse", tool).get("toolUseId"), + "content": [{"text": str(result)}] } }) + # Tool-Ergebnisse zurück an das Modell self.messages.append({ "role": "user", "content": tool_results }) - continue + continue # nächste Runde für finale Antwort - # ------------------------- # FINAL RESPONSE - # ------------------------- if final_text: - text = "\n".join(final_text) self.messages.append({ @@ -165,4 +151,4 @@ class Agent: return text - return "Tool Loop Limit erreicht" \ No newline at end of file + return "Tool Loop Limit erreicht. Bitte versuche es erneut." \ No newline at end of file