mirror of
https://github.com/Jeuners/astra-vision.git
synced 2026-09-16 14:46:13 +02:00
Zwei neue, sauber getrennte Fähigkeiten, jede in ihrem eigenen Modul: - astra/comfyui.py: async HTTP-Client für einen lokalen ComfyUI-Server (z-image-turbo-Workflow), kennt nichts von der Pipeline. - astra/documents.py: PDF-Textextraktion via pypdf, keine Netzwerkzugriffe. - astra/tools.py: verdrahtet generate_image als natives Ollama-Tool-Call — Qwen 3.5 unterstützt Tools und Vision bereits nativ laut `ollama show`. Dafür wurde astra/services.py so erweitert, dass NativeOllamaService Ollamas native tool_calls im Streaming-Response erkennt und als ChatCompletionChunk-Deltas an Pipecats bereits vorhandene, generische Function-Calling-Maschinerie (_process_context/run_function_calls) weiterreicht — die musste dafür nicht angefasst werden. trim_messages in core.py bewahrt jetzt Tool-Roundtrips und Bild-Anhänge vollständig statt sie auf role/content zu reduzieren. Neuer Upload-Button im UI (Bild oder PDF, während eines laufenden Gesprächs): PDFs gehen als Text, Bilder als Base64 über Qwens Vision in den Gesprächskontext ein. Generierte Bilder werden über /api/media/<id> ausgeliefert und per Datenkanal im Transkript angezeigt. Kompletter Function-Calling-Roundtrip end-to-end gegen echtes Ollama und echtes ComfyUI verifiziert (Modell ruft generate_image korrekt auf, Bild wird erzeugt und im media_store abgelegt). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LVgSHNHdRx3UNTBodFmhRA
52 lines
2 KiB
Python
52 lines
2 KiB
Python
"""LLM-callable tools. Each tool owns its handler; server.py only wires in
|
|
per-session dependencies (notify, media_store) and hands the result to pipecat.
|
|
"""
|
|
|
|
import uuid
|
|
from collections.abc import Callable
|
|
|
|
from pipecat.adapters.schemas.function_schema import FunctionSchema
|
|
from pipecat.adapters.schemas.tools_schema import ToolsSchema
|
|
|
|
from astra.comfyui import ComfyUIError, generate_image
|
|
from astra.core import Settings
|
|
|
|
|
|
def build_tools(config: Settings, notify: Callable[[dict], None], media_store: dict[str, bytes]) -> ToolsSchema:
|
|
"""Assemble the tool set available to the LLM for one session."""
|
|
|
|
async def handle_generate_image(params):
|
|
prompt = params.arguments.get("prompt", "")
|
|
try:
|
|
image = await generate_image(config.comfyui_url, prompt)
|
|
except ComfyUIError as exc:
|
|
await params.result_callback({"error": str(exc)})
|
|
return
|
|
image_id = uuid.uuid4().hex
|
|
media_store[image_id] = image
|
|
notify({"type": "image", "url": f"/api/media/{image_id}"})
|
|
await params.result_callback(
|
|
{"status": "ok", "message": "Bild wurde erzeugt und dem Nutzer angezeigt."}
|
|
)
|
|
|
|
generate_image_schema = FunctionSchema(
|
|
name="generate_image",
|
|
description=(
|
|
"Erzeuge ein Bild anhand einer Beschreibung und zeige es dem Nutzer an. "
|
|
"Nutze dieses Werkzeug, wenn der Nutzer explizit ein Bild, eine Grafik "
|
|
"oder eine Illustration wünscht."
|
|
),
|
|
properties={
|
|
"prompt": {
|
|
"type": "string",
|
|
"description": (
|
|
"Konkrete, szenenorientierte Bildbeschreibung auf Englisch, "
|
|
"mit Hinweisen zu Licht und Kamera, z.B. "
|
|
"'close-up, cinematic light, warm tones'."
|
|
),
|
|
},
|
|
},
|
|
required=["prompt"],
|
|
handler=handle_generate_image,
|
|
)
|
|
return ToolsSchema(standard_tools=[generate_image_schema])
|