From e45401671d02ac792a5b74e64563e295c182b859 Mon Sep 17 00:00:00 2001 From: Till Immer Date: Sun, 5 Jul 2026 09:17:03 +0000 Subject: [PATCH] agent.py aktualisiert --- agent.py | 108 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 38 deletions(-) diff --git a/agent.py b/agent.py index 4d54637..0b205d3 100644 --- a/agent.py +++ b/agent.py @@ -1,43 +1,53 @@ import json -from config import OPENROUTER_MODEL -from openrouter_client import client -from mcp_client import MCPClient +from llm.base import LLMBase +from mcp.client import MCPClient class Agent: - def __init__(self): + def __init__(self, llm: LLMBase): + self.llm = llm self.mcp = MCPClient() + self.tools = [] self.messages = [ { "role": "system", "content": ( - "Du bist N.O.R.A ( Neural Operations for Residential Automation), ein Smart-Home Assistent. Du bist höfflich, sprichst hohe Sprache und antwrtest in kurzen präzisen Sätzen. Auser es wird eine lange Erklärung erbittet. Sei sympatisch und leicht zynisch und ironisch\n" - "Du steuerst ein Haus über MCP Tools.\n" - "Antworte normal kurz und präzise oder nutze Tools wenn nötig." + "Du bist JARVIS, ein Smart-Home Assistent. " + "Du steuerst ein Haus über MCP Tools. " + "Wenn nötig, verwende Tools." ) } ] async def load_tools(self): + """ + Holt MCP Tools und konvertiert sie für Amazon Nova (Bedrock Converse API) + """ + res = await self.mcp.list_tools() self.tools = [] for t in res.tools: self.tools.append({ - "type": "function", - "function": { + "toolSpec": { "name": t.name, "description": t.description, - "parameters": t.inputSchema + "inputSchema": { + "json": t.inputSchema + } } }) print(f"[JARVIS] {len(self.tools)} Tools geladen") - async def _run_tool(self, tool_call): - name = tool_call.function.name - args = json.loads(tool_call.function.arguments or "{}") + async def _run_tool(self, tool_use): + """ + Führt MCP Tool aus + """ + + name = tool_use["name"] + args = tool_use.get("input", {}) result = await self.mcp.call_tool(name, args) @@ -51,42 +61,64 @@ class Agent: for _ in range(8): - response = await client.chat.completions.create( - model=OPENROUTER_MODEL, + response = await self.llm.chat( messages=self.messages, tools=self.tools ) - message = response.choices[0].message + # 🧠 Bedrock Nova Response parsing + output = response.get("output", {}) - # 🧠 TOOL CALL PATH - if getattr(message, "tool_calls", None): + message = output.get("message", {}) - self.messages.append(message) + content = message.get("content", []) + tool_uses = [] - for tool_call in message.tool_calls: - - result = await self._run_tool(tool_call) - - self.messages.append({ - "role": "tool", - "tool_call_id": tool_call.id, - "content": str(result) - }) - - continue - - # 🧠 NORMAL RESPONSE PATH - if message.content: + for c in content: + if "toolUse" in c: + tool_uses.append(c["toolUse"]) + if tool_uses: self.messages.append({ "role": "assistant", - "content": message.content + "content": content }) - return message.content + tool_results = [] - # 🧠 SAFETY FALLBACK - return "Ich konnte keine gültige Antwort generieren." + for tool in tool_uses: - return "Tool Loop Limit erreicht." \ No newline at end of file + result = await self._run_tool(tool) + + tool_results.append({ + "toolResult": { + "toolUseId": tool["toolUseId"], + "content": [ + { + "text": str(result) + } + ] + } + }) + + self.messages.append({ + "role": "user", + "content": tool_results + }) + + continue + final_text = "" + + for c in content: + if "text" in c: + final_text += c["text"] + + if final_text: + self.messages.append({ + "role": "assistant", + "content": content + }) + + return final_text + + return "Tool Loop Limit erreicht" \ No newline at end of file