Initial public upload from Projekte/Agent8Agent
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- .codex/config.toml +31 -0
- .gitattributes +1 -0
- .gitignore +10 -0
- .langgraph_api/.langgraph_checkpoint.1.pckl +0 -0
- .langgraph_api/.langgraph_checkpoint.2.pckl +0 -0
- .langgraph_api/.langgraph_checkpoint.3.pckl +0 -0
- .langgraph_api/.langgraph_ops.pckl +0 -0
- .langgraph_api/.langgraph_retry_counter.pckl +0 -0
- .langgraph_api/store.pckl +0 -0
- .langgraph_api/store.vectors.pckl +0 -0
- .python-version +1 -0
- README.md +0 -0
- agent8agent/__init__.py +1 -0
- agent8agent/config.py +37 -0
- agent8agent/graph.py +94 -0
- agent8agent/mcp_client.py +45 -0
- agent8agent/nodes.py +241 -0
- agent8agent/state.py +30 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/HAI_LANGGRAPH_MULTIVOICE_PODCAST.md +158 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/HAI_LANGGRAPH_MULTIVOICE_PODCAST.mp3 +3 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/ffmpeg_concat.txt +48 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/manifest.json +21 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/001_moderatorin.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/002_coach.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/003_samuel_stimme.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/004_architektin.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/005_moderatorin.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/006_coach.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/007_architektin.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/008_kritiker.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/009_merksatz.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/010_moderatorin.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/011_coach.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/012_samuel_stimme.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/013_architektin.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/014_kritiker.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/015_moderatorin.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/016_coach.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/017_architektin.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/018_samuel_stimme.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/019_merksatz.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/020_moderatorin.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/021_coach.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/022_kritiker.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/023_architektin.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/024_merksatz.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/025_moderatorin.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/026_coach.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/027_samuel_stimme.mp3 +0 -0
- artifacts/hai_langgraph_multivoice_podcast_20260608/segments/028_kritiker.mp3 +0 -0
.codex/config.toml
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Coding MCPs: project-local registration (2026-09-07).
|
| 2 |
+
|
| 3 |
+
[mcp_servers.serena]
|
| 4 |
+
command = "/home/smlflg/.local/share/coding-mcp/serena/.venv/bin/serena"
|
| 5 |
+
args = ["start-mcp-server", "--context=codex", "--project", "/home/smlflg/Projekte/Agent8Agent", "--enable-web-dashboard", "false", "--open-web-dashboard", "false", "--enable-gui-log-window", "false"]
|
| 6 |
+
cwd = "/home/smlflg/Projekte/Agent8Agent"
|
| 7 |
+
enabled = true
|
| 8 |
+
startup_timeout_sec = 120
|
| 9 |
+
tool_timeout_sec = 180
|
| 10 |
+
|
| 11 |
+
[mcp_servers.serena.env]
|
| 12 |
+
"SERENA_HOME" = "/home/smlflg/.local/share/coding-mcp/serena/state"
|
| 13 |
+
|
| 14 |
+
[mcp_servers.gitnexus]
|
| 15 |
+
command = "/home/smlflg/.nvm/versions/node/v24.13.0/bin/node"
|
| 16 |
+
args = ["/home/smlflg/.local/share/coding-mcp/gitnexus/node_modules/gitnexus/dist/cli/index.js", "mcp"]
|
| 17 |
+
cwd = "/home/smlflg/Projekte/Agent8Agent"
|
| 18 |
+
enabled = true
|
| 19 |
+
startup_timeout_sec = 120
|
| 20 |
+
tool_timeout_sec = 180
|
| 21 |
+
|
| 22 |
+
[mcp_servers.gitnexus.env]
|
| 23 |
+
"GITNEXUS_HOME" = "/home/smlflg/.local/share/coding-mcp/gitnexus/runtime"
|
| 24 |
+
|
| 25 |
+
[mcp_servers.context7]
|
| 26 |
+
command = "/home/smlflg/.nvm/versions/node/v24.13.0/bin/node"
|
| 27 |
+
args = ["/home/smlflg/.local/share/coding-mcp/context7/node_modules/@upstash/context7-mcp/dist/index.js"]
|
| 28 |
+
cwd = "/home/smlflg/Projekte/Agent8Agent"
|
| 29 |
+
enabled = true
|
| 30 |
+
startup_timeout_sec = 120
|
| 31 |
+
tool_timeout_sec = 180
|
.gitattributes
CHANGED
|
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
| 33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
| 34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
| 35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
| 36 |
+
artifacts/hai_langgraph_multivoice_podcast_20260608/HAI_LANGGRAPH_MULTIVOICE_PODCAST.mp3 filter=lfs diff=lfs merge=lfs -text
|
.gitignore
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Python-generated files
|
| 2 |
+
__pycache__/
|
| 3 |
+
*.py[oc]
|
| 4 |
+
build/
|
| 5 |
+
dist/
|
| 6 |
+
wheels/
|
| 7 |
+
*.egg-info
|
| 8 |
+
|
| 9 |
+
# Virtual environments
|
| 10 |
+
.venv
|
.langgraph_api/.langgraph_checkpoint.1.pckl
ADDED
|
Binary file (6 Bytes). View file
|
|
|
.langgraph_api/.langgraph_checkpoint.2.pckl
ADDED
|
Binary file (6 Bytes). View file
|
|
|
.langgraph_api/.langgraph_checkpoint.3.pckl
ADDED
|
Binary file (6 Bytes). View file
|
|
|
.langgraph_api/.langgraph_ops.pckl
ADDED
|
Binary file (839 Bytes). View file
|
|
|
.langgraph_api/.langgraph_retry_counter.pckl
ADDED
|
Binary file (6 Bytes). View file
|
|
|
.langgraph_api/store.pckl
ADDED
|
Binary file (6 Bytes). View file
|
|
|
.langgraph_api/store.vectors.pckl
ADDED
|
Binary file (6 Bytes). View file
|
|
|
.python-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
3.13
|
README.md
ADDED
|
File without changes
|
agent8agent/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
"""Agent8Agent — die agentische Sanduhr als LangGraph (Mockup)."""
|
agent8agent/config.py
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Konfiguration für echte Substrat-Bindings."""
|
| 2 |
+
|
| 3 |
+
from __future__ import annotations
|
| 4 |
+
|
| 5 |
+
import sys
|
| 6 |
+
|
| 7 |
+
# intake-router-hermes MCP (read-only Register-Suche).
|
| 8 |
+
# Wir starten den Server mit unserem venv-Python (sys.executable), das `mcp` hat;
|
| 9 |
+
# der Server selbst hat keine weiteren Deps (parst YAML manuell).
|
| 10 |
+
INTAKE_MCP_COMMAND = sys.executable
|
| 11 |
+
INTAKE_MCP_ARGS = [
|
| 12 |
+
"/home/smlflg/.hermes/profiles/intake-router-hermes/mcp/intake_router_fastmcp.py"
|
| 13 |
+
]
|
| 14 |
+
|
| 15 |
+
# action_type (Register-Vokabular) → (Route-Buchstabe, Ziel-Node)
|
| 16 |
+
ACTION_TO_ROUTE = {
|
| 17 |
+
"aufgabe": ("A", "execute_with_codex"), # klare Umsetzung → Executor
|
| 18 |
+
"idee": ("B", "research_with_opus"), # "was gibt's schon" → Research
|
| 19 |
+
"entscheidung": ("B", "research_with_opus"), # Evidence sammeln, Owner entscheidet an der Taille
|
| 20 |
+
"reflexion": ("D", "meta_agent"), # Rückschau/Optimierung → Meta
|
| 21 |
+
"meeting": ("E", "park"), # nicht agenten-actionable
|
| 22 |
+
"sonstiges": ("E", "park"),
|
| 23 |
+
}
|
| 24 |
+
DEFAULT_ROUTE = ("B", "research_with_opus") # unbekannt → erst mal erkunden
|
| 25 |
+
|
| 26 |
+
# urgency → priority-Tier (für späteres echtes priority_gate; Carry hier schon mit)
|
| 27 |
+
URGENCY_TO_PRIORITY = {"hoch": "P0", "mittel": "P2", "niedrig": "P3"}
|
| 28 |
+
|
| 29 |
+
# Keyword-Fallback, wenn das Register keinen Treffer liefert (freier Text / Studio-Demo).
|
| 30 |
+
KEYWORD_FALLBACK = {
|
| 31 |
+
"execute": "aufgabe", "aufgabe": "aufgabe", "task": "aufgabe",
|
| 32 |
+
"research": "idee", "idee": "idee", "idea": "idee",
|
| 33 |
+
"reflex": "reflexion", "meta": "reflexion", "optimier": "reflexion",
|
| 34 |
+
"entscheid": "entscheidung", "decide": "entscheidung", "decision": "entscheidung",
|
| 35 |
+
"meeting": "meeting", "park": "sonstiges",
|
| 36 |
+
}
|
| 37 |
+
KEYWORD_FALLBACK_DEFAULT = "idee"
|
agent8agent/graph.py
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Graph-Aufbau der agentischen Sanduhr (Mockup).
|
| 2 |
+
|
| 3 |
+
build_graph(checkpointer=None):
|
| 4 |
+
- checkpointer=None → für `langgraph dev` (Studio injiziert eigene Persistenz)
|
| 5 |
+
- checkpointer=... → für direkten Invoke/Tests (interrupt braucht einen Saver)
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
from __future__ import annotations
|
| 9 |
+
|
| 10 |
+
from langgraph.graph import END, START, StateGraph
|
| 11 |
+
|
| 12 |
+
from .nodes import (
|
| 13 |
+
automation_output,
|
| 14 |
+
execute_with_codex,
|
| 15 |
+
fan_out_research,
|
| 16 |
+
hai_owner_packet,
|
| 17 |
+
human_escalation,
|
| 18 |
+
intake_router,
|
| 19 |
+
learning_agent,
|
| 20 |
+
meta_agent,
|
| 21 |
+
park,
|
| 22 |
+
priority_gate,
|
| 23 |
+
research_subagent,
|
| 24 |
+
research_with_opus,
|
| 25 |
+
route_after_verifier,
|
| 26 |
+
route_thought,
|
| 27 |
+
verifier_mediator,
|
| 28 |
+
)
|
| 29 |
+
from .state import ThoughtState
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def build_graph(checkpointer=None):
|
| 33 |
+
g = StateGraph(ThoughtState)
|
| 34 |
+
|
| 35 |
+
# Nodes
|
| 36 |
+
g.add_node("intake_router", intake_router)
|
| 37 |
+
g.add_node("priority_gate", priority_gate)
|
| 38 |
+
g.add_node("execute_with_codex", execute_with_codex)
|
| 39 |
+
g.add_node("research_with_opus", research_with_opus)
|
| 40 |
+
g.add_node("research_subagent", research_subagent)
|
| 41 |
+
g.add_node("learning_agent", learning_agent)
|
| 42 |
+
g.add_node("meta_agent", meta_agent)
|
| 43 |
+
g.add_node("park", park)
|
| 44 |
+
g.add_node("verifier_mediator", verifier_mediator)
|
| 45 |
+
g.add_node("human_escalation", human_escalation)
|
| 46 |
+
g.add_node("hai_owner_packet", hai_owner_packet)
|
| 47 |
+
g.add_node("automation_output", automation_output)
|
| 48 |
+
|
| 49 |
+
# Intake-Pyramide
|
| 50 |
+
g.add_edge(START, "intake_router")
|
| 51 |
+
g.add_edge("intake_router", "priority_gate")
|
| 52 |
+
|
| 53 |
+
# prio-Gate → Lane (A/B/C/D/E)
|
| 54 |
+
g.add_conditional_edges(
|
| 55 |
+
"priority_gate",
|
| 56 |
+
route_thought,
|
| 57 |
+
{
|
| 58 |
+
"execute_with_codex": "execute_with_codex",
|
| 59 |
+
"research_with_opus": "research_with_opus",
|
| 60 |
+
"learning_agent": "learning_agent",
|
| 61 |
+
"meta_agent": "meta_agent",
|
| 62 |
+
"park": "park",
|
| 63 |
+
},
|
| 64 |
+
)
|
| 65 |
+
|
| 66 |
+
# Research-Lane: Send-Fanout → Subagenten → join
|
| 67 |
+
g.add_conditional_edges("research_with_opus", fan_out_research, ["research_subagent"])
|
| 68 |
+
g.add_edge("research_subagent", "verifier_mediator")
|
| 69 |
+
|
| 70 |
+
# Übrige Lanes → Verifier
|
| 71 |
+
g.add_edge("execute_with_codex", "verifier_mediator")
|
| 72 |
+
g.add_edge("learning_agent", "verifier_mediator")
|
| 73 |
+
g.add_edge("meta_agent", "verifier_mediator")
|
| 74 |
+
|
| 75 |
+
# park ist terminal (Anti-Fanout-Ventil)
|
| 76 |
+
g.add_edge("park", END)
|
| 77 |
+
|
| 78 |
+
# Konflikt-Lane
|
| 79 |
+
g.add_conditional_edges(
|
| 80 |
+
"verifier_mediator",
|
| 81 |
+
route_after_verifier,
|
| 82 |
+
{"human_escalation": "human_escalation", "hai_owner_packet": "hai_owner_packet"},
|
| 83 |
+
)
|
| 84 |
+
g.add_edge("human_escalation", "hai_owner_packet")
|
| 85 |
+
|
| 86 |
+
# Taille → Automation-Output → Ende
|
| 87 |
+
g.add_edge("hai_owner_packet", "automation_output")
|
| 88 |
+
g.add_edge("automation_output", END)
|
| 89 |
+
|
| 90 |
+
return g.compile(checkpointer=checkpointer)
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
# Modul-Level-Graph für LangGraph Studio (langgraph.json).
|
| 94 |
+
graph = build_graph()
|
agent8agent/mcp_client.py
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Minimaler stdio-Client für den intake-router-hermes MCP-Server.
|
| 2 |
+
|
| 3 |
+
LangGraph läuft als eigener Prozess; wir starten den read-only MCP-Server per
|
| 4 |
+
stdio, rufen ein Tool, parsen die JSON-Antwort. Synchron nutzbar via run_sync()
|
| 5 |
+
(eigener Thread + eigener Event-Loop → funktioniert auch unter Studio/asyncio).
|
| 6 |
+
"""
|
| 7 |
+
|
| 8 |
+
from __future__ import annotations
|
| 9 |
+
|
| 10 |
+
import asyncio
|
| 11 |
+
import concurrent.futures
|
| 12 |
+
import json
|
| 13 |
+
from typing import Any
|
| 14 |
+
|
| 15 |
+
from mcp import ClientSession, StdioServerParameters
|
| 16 |
+
from mcp.client.stdio import stdio_client
|
| 17 |
+
|
| 18 |
+
from .config import INTAKE_MCP_ARGS, INTAKE_MCP_COMMAND
|
| 19 |
+
|
| 20 |
+
|
| 21 |
+
async def call_intake_tool(name: str, arguments: dict | None = None) -> dict[str, Any]:
|
| 22 |
+
"""Einen Tool-Call gegen den intake-router MCP fahren und JSON zurückgeben."""
|
| 23 |
+
params = StdioServerParameters(
|
| 24 |
+
command=INTAKE_MCP_COMMAND, args=INTAKE_MCP_ARGS, env=None
|
| 25 |
+
)
|
| 26 |
+
async with stdio_client(params) as (read, write):
|
| 27 |
+
async with ClientSession(read, write) as session:
|
| 28 |
+
await session.initialize()
|
| 29 |
+
result = await session.call_tool(name, arguments or {})
|
| 30 |
+
# Server liefert genau ein TextContent mit JSON-String.
|
| 31 |
+
for block in result.content:
|
| 32 |
+
text = getattr(block, "text", None)
|
| 33 |
+
if text:
|
| 34 |
+
return json.loads(text)
|
| 35 |
+
return {}
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def run_sync(coro):
|
| 39 |
+
"""Coroutine in einem frischen Thread+Loop ausführen (kollisionsfrei)."""
|
| 40 |
+
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as ex:
|
| 41 |
+
return ex.submit(lambda: asyncio.run(coro)).result()
|
| 42 |
+
|
| 43 |
+
|
| 44 |
+
def call_intake_tool_sync(name: str, arguments: dict | None = None) -> dict[str, Any]:
|
| 45 |
+
return run_sync(call_intake_tool(name, arguments))
|
agent8agent/nodes.py
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""Nodes der Sanduhr.
|
| 2 |
+
|
| 3 |
+
Status: `intake_router` ist SCHARF (echter intake-router-hermes MCP). Alle anderen
|
| 4 |
+
Nodes sind weiterhin Mock — Interrupt und Send-Fanout sind echte LangGraph-Mechanik.
|
| 5 |
+
"""
|
| 6 |
+
|
| 7 |
+
from __future__ import annotations
|
| 8 |
+
|
| 9 |
+
import re
|
| 10 |
+
|
| 11 |
+
from langgraph.types import Send, interrupt
|
| 12 |
+
|
| 13 |
+
from . import config
|
| 14 |
+
from .mcp_client import call_intake_tool_sync
|
| 15 |
+
|
| 16 |
+
N_RESEARCH_SUBAGENTS = 3
|
| 17 |
+
_IR_RE = re.compile(r"\bIR-\d{4}-\d{4}\b", re.IGNORECASE)
|
| 18 |
+
|
| 19 |
+
|
| 20 |
+
# --- Helpers ---------------------------------------------------------------
|
| 21 |
+
|
| 22 |
+
def _keyword_action(raw: str) -> str:
|
| 23 |
+
low = raw.lower()
|
| 24 |
+
for kw, action in config.KEYWORD_FALLBACK.items():
|
| 25 |
+
if kw in low:
|
| 26 |
+
return action
|
| 27 |
+
return config.KEYWORD_FALLBACK_DEFAULT
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
def _as_list(value) -> list[str]:
|
| 31 |
+
if not value:
|
| 32 |
+
return []
|
| 33 |
+
if isinstance(value, str):
|
| 34 |
+
return [value] if value.strip() else []
|
| 35 |
+
return [str(x) for x in value if x and str(x).strip()]
|
| 36 |
+
|
| 37 |
+
|
| 38 |
+
def _fetch_intake(raw: str) -> tuple[dict | None, list[dict], str]:
|
| 39 |
+
"""Register abfragen. Returns (top_intake | None, sources, note).
|
| 40 |
+
|
| 41 |
+
Resilient: fällt bei MCP-Fehler auf (None, [], 'mcp-unavailable') zurück,
|
| 42 |
+
damit der Graph nie deadlockt, wenn hermes down ist.
|
| 43 |
+
"""
|
| 44 |
+
try:
|
| 45 |
+
m = _IR_RE.search(raw)
|
| 46 |
+
if m:
|
| 47 |
+
resp = call_intake_tool_sync("get_intake_details", {"intake_id": m.group(0).upper()})
|
| 48 |
+
if resp.get("success"):
|
| 49 |
+
return resp.get("intake"), [], f"register-id {m.group(0).upper()}"
|
| 50 |
+
return None, [], f"id {m.group(0).upper()} nicht gefunden"
|
| 51 |
+
resp = call_intake_tool_sync("query_intakes", {"query": raw, "limit": 5})
|
| 52 |
+
matches = resp.get("matches", [])
|
| 53 |
+
if matches:
|
| 54 |
+
return matches[0], matches, f"register-match {matches[0].get('id')}"
|
| 55 |
+
return None, [], "kein register-treffer"
|
| 56 |
+
except Exception as exc: # hermes nicht erreichbar
|
| 57 |
+
return None, [], f"mcp-unavailable: {type(exc).__name__}"
|
| 58 |
+
|
| 59 |
+
|
| 60 |
+
# --- Intake-Pyramide -------------------------------------------------------
|
| 61 |
+
|
| 62 |
+
def intake_router(state: dict) -> dict:
|
| 63 |
+
"""SCHARF: echter intake-router-hermes MCP (read-only Register-Suche).
|
| 64 |
+
|
| 65 |
+
raw_input == IR-id → get_intake_details, sonst query_intakes. Top-Treffer →
|
| 66 |
+
classification (action_type), active_project, evidence. Ohne Treffer:
|
| 67 |
+
Keyword-Fallback, damit freier Text / Studio-Demo trotzdem routet.
|
| 68 |
+
"""
|
| 69 |
+
raw = state.get("raw_input", "")
|
| 70 |
+
intake, sources, note = _fetch_intake(raw)
|
| 71 |
+
|
| 72 |
+
if intake:
|
| 73 |
+
action = (intake.get("action_type") or "").strip().lower() or _keyword_action(raw)
|
| 74 |
+
summary = intake.get("summary") or intake.get("title") or raw[:80]
|
| 75 |
+
projects = _as_list(intake.get("projects"))
|
| 76 |
+
topics = _as_list(intake.get("topics"))
|
| 77 |
+
urgency = (intake.get("urgency") or "").strip().lower()
|
| 78 |
+
evidence = [{
|
| 79 |
+
"agent": "intake-router-hermes", "kind": "intake-match",
|
| 80 |
+
"id": intake.get("id"), "title": intake.get("title"),
|
| 81 |
+
"action_type": action, "urgency": urgency,
|
| 82 |
+
}]
|
| 83 |
+
intake_id = intake.get("id")
|
| 84 |
+
status = intake.get("status", "")
|
| 85 |
+
confidence = intake.get("confidence", "")
|
| 86 |
+
else:
|
| 87 |
+
action = _keyword_action(raw)
|
| 88 |
+
summary = f"[{note}] {raw[:80]}"
|
| 89 |
+
projects, topics, urgency, evidence = [], [], "", []
|
| 90 |
+
intake_id = status = confidence = None
|
| 91 |
+
|
| 92 |
+
return {
|
| 93 |
+
"classification": action,
|
| 94 |
+
"summary": summary,
|
| 95 |
+
"active_project": projects[0] if projects else None,
|
| 96 |
+
"topics": topics,
|
| 97 |
+
"selected_agents": ["intake-router-hermes"],
|
| 98 |
+
"current_gate": "intake_router",
|
| 99 |
+
"evidence": evidence,
|
| 100 |
+
"intake": {
|
| 101 |
+
"id": intake_id, "urgency": urgency, "status": status,
|
| 102 |
+
"confidence": confidence, "note": note, "sources": sources,
|
| 103 |
+
},
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
|
| 107 |
+
def priority_gate(state: dict) -> dict:
|
| 108 |
+
"""Mappt classification → Route und urgency → priority. park = Anti-Fanout-Ventil."""
|
| 109 |
+
classification = state.get("classification", "idee")
|
| 110 |
+
urgency = (state.get("intake") or {}).get("urgency", "")
|
| 111 |
+
route, _ = config.ACTION_TO_ROUTE.get(classification, config.DEFAULT_ROUTE)
|
| 112 |
+
priority = "park" if route == "E" else config.URGENCY_TO_PRIORITY.get(urgency, "P2")
|
| 113 |
+
return {
|
| 114 |
+
"priority": priority,
|
| 115 |
+
"route": route,
|
| 116 |
+
"owner_decision_needed": route != "E",
|
| 117 |
+
"current_gate": "priority_gate",
|
| 118 |
+
}
|
| 119 |
+
|
| 120 |
+
|
| 121 |
+
def route_thought(state: dict) -> str:
|
| 122 |
+
"""Conditional-Edge-Fn: prio-Gate → Lane."""
|
| 123 |
+
if state.get("priority") == "park":
|
| 124 |
+
return "park"
|
| 125 |
+
classification = state.get("classification", "idee")
|
| 126 |
+
_, target = config.ACTION_TO_ROUTE.get(classification, config.DEFAULT_ROUTE)
|
| 127 |
+
return target
|
| 128 |
+
|
| 129 |
+
|
| 130 |
+
# --- Executor-Pyramide (Lanes, weiterhin Mock) -----------------------------
|
| 131 |
+
|
| 132 |
+
def execute_with_codex(state: dict) -> dict:
|
| 133 |
+
return {
|
| 134 |
+
"selected_agents": ["codex"],
|
| 135 |
+
"execution_status": "[mock] codex hätte ausgeführt",
|
| 136 |
+
"evidence": [{"agent": "codex", "kind": "execution", "note": "mock diff/patch"}],
|
| 137 |
+
"current_gate": "execute_with_codex",
|
| 138 |
+
}
|
| 139 |
+
|
| 140 |
+
|
| 141 |
+
def research_with_opus(state: dict) -> dict:
|
| 142 |
+
return {
|
| 143 |
+
"selected_agents": ["opus-research"],
|
| 144 |
+
"execution_status": "[mock] opus startet Prior-Art-Schwarm",
|
| 145 |
+
"current_gate": "research_with_opus",
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
|
| 149 |
+
def fan_out_research(state: dict) -> list[Send]:
|
| 150 |
+
raw = state.get("raw_input", "")
|
| 151 |
+
return [
|
| 152 |
+
Send("research_subagent", {"raw_input": raw, "_idx": i})
|
| 153 |
+
for i in range(N_RESEARCH_SUBAGENTS)
|
| 154 |
+
]
|
| 155 |
+
|
| 156 |
+
|
| 157 |
+
def research_subagent(state: dict) -> dict:
|
| 158 |
+
idx = state.get("_idx", 0)
|
| 159 |
+
return {
|
| 160 |
+
"evidence": [
|
| 161 |
+
{"agent": f"opus-subagent-{idx}", "kind": "prior-art",
|
| 162 |
+
"note": f"[mock] Fund #{idx}: 'gibt's schon' …"}
|
| 163 |
+
],
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
|
| 167 |
+
def learning_agent(state: dict) -> dict:
|
| 168 |
+
return {
|
| 169 |
+
"selected_agents": ["learning-agent"],
|
| 170 |
+
"execution_status": "[mock] learnmode hätte Lernlücke geschlossen",
|
| 171 |
+
"evidence": [{"agent": "learning-agent", "kind": "explanation", "note": "mock"}],
|
| 172 |
+
"current_gate": "learning_agent",
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
def meta_agent(state: dict) -> dict:
|
| 177 |
+
return {
|
| 178 |
+
"selected_agents": ["meta-agent"],
|
| 179 |
+
"execution_status": "[mock] metamode hätte Workflow optimiert",
|
| 180 |
+
"evidence": [{"agent": "meta-agent", "kind": "optimization", "note": "mock"}],
|
| 181 |
+
"current_gate": "meta_agent",
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
|
| 185 |
+
def park(state: dict) -> dict:
|
| 186 |
+
return {
|
| 187 |
+
"execution_status": "[mock] geparkt — low prio / nicht actionable",
|
| 188 |
+
"current_gate": "park",
|
| 189 |
+
"owner_decision_needed": False,
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
|
| 193 |
+
# --- Konflikt-Lane (Mock) --------------------------------------------------
|
| 194 |
+
|
| 195 |
+
def verifier_mediator(state: dict) -> dict:
|
| 196 |
+
raw = state.get("raw_input", "").lower()
|
| 197 |
+
status = "conflict" if "conflict" in raw else "ok"
|
| 198 |
+
return {"verifier_status": status, "current_gate": "verifier_mediator"}
|
| 199 |
+
|
| 200 |
+
|
| 201 |
+
def route_after_verifier(state: dict) -> str:
|
| 202 |
+
return "human_escalation" if state.get("verifier_status") == "conflict" else "hai_owner_packet"
|
| 203 |
+
|
| 204 |
+
|
| 205 |
+
def human_escalation(state: dict) -> dict:
|
| 206 |
+
return {
|
| 207 |
+
"execution_status": "[mock] Konflikt → an Human eskaliert",
|
| 208 |
+
"current_gate": "human_escalation",
|
| 209 |
+
}
|
| 210 |
+
|
| 211 |
+
|
| 212 |
+
# --- Taille (HAI Owner Packet, echtes interrupt) ---------------------------
|
| 213 |
+
|
| 214 |
+
def hai_owner_packet(state: dict) -> dict:
|
| 215 |
+
packet = {
|
| 216 |
+
"decisions": [
|
| 217 |
+
{"id": "approve", "label": "Freigeben & ausführen"},
|
| 218 |
+
{"id": "revise", "label": "Überarbeiten"},
|
| 219 |
+
{"id": "drop", "label": "Verwerfen"},
|
| 220 |
+
],
|
| 221 |
+
"evidence": state.get("evidence", []),
|
| 222 |
+
"next_action": "[mock] nächster Schritt laut Lane",
|
| 223 |
+
"summary": state.get("summary", ""),
|
| 224 |
+
}
|
| 225 |
+
decision = interrupt(packet)
|
| 226 |
+
return {
|
| 227 |
+
"owner_packet": packet,
|
| 228 |
+
"owner_decision_needed": False,
|
| 229 |
+
"execution_status": f"[mock] owner entschied: {decision}",
|
| 230 |
+
"current_gate": "hai_owner_packet",
|
| 231 |
+
}
|
| 232 |
+
|
| 233 |
+
|
| 234 |
+
# --- Automation-Output (n8n-Sink, Mock) ------------------------------------
|
| 235 |
+
|
| 236 |
+
def automation_output(state: dict) -> dict:
|
| 237 |
+
sinks = ["mail", "notion", "obsidian", "github", "calendar"]
|
| 238 |
+
return {
|
| 239 |
+
"execution_status": f"[mock] würde an n8n posten → {', '.join(sinks)}",
|
| 240 |
+
"current_gate": "automation_output",
|
| 241 |
+
}
|
agent8agent/state.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
"""ThoughtState — der State, der durch die Sanduhr fließt.
|
| 2 |
+
|
| 3 |
+
Feldnamen verbatim nach Samuels Spec, plus ein paar Carry-Felder für den Mockup-Lauf.
|
| 4 |
+
"""
|
| 5 |
+
|
| 6 |
+
from __future__ import annotations
|
| 7 |
+
|
| 8 |
+
import operator
|
| 9 |
+
from typing import Annotated, TypedDict
|
| 10 |
+
|
| 11 |
+
|
| 12 |
+
class ThoughtState(TypedDict, total=False):
|
| 13 |
+
# --- Samuels Spec (verbatim) ---
|
| 14 |
+
raw_input: str
|
| 15 |
+
classification: str # task | research | learning | meta | noise
|
| 16 |
+
priority: str # P0..P3 | park
|
| 17 |
+
active_project: str | None
|
| 18 |
+
selected_agents: list[str] # gewählte Lane(s)
|
| 19 |
+
current_gate: str # wo im Graph wir gerade stehen
|
| 20 |
+
evidence: Annotated[list[dict], operator.add] # reducer → merge'd Fanout-Beiträge
|
| 21 |
+
owner_decision_needed: bool
|
| 22 |
+
execution_status: str
|
| 23 |
+
verifier_status: str
|
| 24 |
+
|
| 25 |
+
# --- Carry ---
|
| 26 |
+
summary: str
|
| 27 |
+
topics: list[str] # aus dem Register (best effort)
|
| 28 |
+
intake: dict # roh: id/urgency/status/confidence/note/sources
|
| 29 |
+
route: str # A | B | C | D | E
|
| 30 |
+
owner_packet: dict
|
artifacts/hai_langgraph_multivoice_podcast_20260608/HAI_LANGGRAPH_MULTIVOICE_PODCAST.md
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Multivoice-Erklärpodcast: LangGraph für Samuels HAI-Sanduhr
|
| 2 |
+
|
| 3 |
+
Quelle: Samuels Task-Package im Chat vom 2026-06-08.
|
| 4 |
+
Modus: EXPLAIN mit Rückaneignungs-Check, kein Full-Build.
|
| 5 |
+
|
| 6 |
+
## Stimmen
|
| 7 |
+
- MODERATORIN: de-DE-KatjaNeural
|
| 8 |
+
- COACH: de-DE-FlorianMultilingualNeural
|
| 9 |
+
- ARCHITEKTIN: de-DE-SeraphinaMultilingualNeural
|
| 10 |
+
- KRITIKER: de-DE-ConradNeural
|
| 11 |
+
- SAMUEL-STIMME: de-DE-KillianNeural
|
| 12 |
+
- MERKSATZ: de-DE-AmalaNeural
|
| 13 |
+
|
| 14 |
+
## Skript
|
| 15 |
+
|
| 16 |
+
### 01. MODERATORIN
|
| 17 |
+
Willkommen zum HAI-LangGraph-Podcast. Heute geht es nicht um ein großes Framework-Tutorial, sondern um einen einzigen Gedanken, der sauber durch Samuels HAI-Sanduhr läuft.
|
| 18 |
+
|
| 19 |
+
### 02. COACH
|
| 20 |
+
Lernziel: Am Ende kannst du sagen: Mein HAI-Loop besteht aus State X, Knoten Y, Übergängen Z und einem Human-Gate. Wenn du genau diesen Satz füllen kannst, hast du das Modell verstanden.
|
| 21 |
+
|
| 22 |
+
### 03. SAMUEL-STIMME
|
| 23 |
+
Also nicht: Baue komplettes HAI. Sondern: Baue einen Graphen, der einen Gedanken aufnimmt, Samuel entscheiden lässt, fokussiert ausführt, prüft und ins Register zurückbringt.
|
| 24 |
+
|
| 25 |
+
### 04. ARCHITEKTIN
|
| 26 |
+
LangGraph ist hier das Schienensystem. Der State ist der gemeinsame Zettel. Nodes sind Arbeitsschritte. Edges sind Gleise. Conditional Edges sind Weichen. Das Human-Gate ist die Stelle, an der Samuel Owner bleibt.
|
| 27 |
+
|
| 28 |
+
### 05. MODERATORIN
|
| 29 |
+
Kapitel eins: State. Die Kernfrage lautet: Was muss der Graph wissen, damit Samuel es nicht im Kopf halten muss?
|
| 30 |
+
|
| 31 |
+
### 06. COACH
|
| 32 |
+
Für HAI enthält der State mindestens: aktueller Gedanke oder Intake, Kategorie, ob eine Entscheidung nötig ist, gewählter nächster Schritt, aktiver Executor, Ergebnis, Verifikation und Status im Register.
|
| 33 |
+
|
| 34 |
+
### 07. ARCHITEKTIN
|
| 35 |
+
Denke nicht an State als Datenbank-Monster. Denke an eine Prozesskarte. Wenn der Gedanke später wieder auftaucht, soll der Graph wissen: Was war entschieden, was ist offen, und wo steht die Arbeit?
|
| 36 |
+
|
| 37 |
+
### 08. KRITIKER
|
| 38 |
+
Wenn etwas nur in Samuels Kopf bleibt, ist es kein robuster HAI-Prozess. Es wird wieder Chat-Nebel. State heißt: Der Graph trägt die Last, nicht Samuels Arbeitsgedächtnis.
|
| 39 |
+
|
| 40 |
+
### 09. MERKSATZ
|
| 41 |
+
State ist der gemeinsame Arbeitsstand. Er beantwortet: Was wissen wir gerade, was wurde entschieden, und was darf als Nächstes passieren?
|
| 42 |
+
|
| 43 |
+
### 10. MODERATORIN
|
| 44 |
+
Kapitel zwei: Nodes. Die Kernfrage lautet: Welche Schritte mache ich heute manuell immer wieder?
|
| 45 |
+
|
| 46 |
+
### 11. COACH
|
| 47 |
+
Ein Node ist ein Arbeitsschritt im Graphen. Für HAI wären das: intake_node, classify_node, owner_decision_node, task_package_node, executor_node, verifier_node, return_node und register_update_node.
|
| 48 |
+
|
| 49 |
+
### 12. SAMUEL-STIMME
|
| 50 |
+
Intake nimmt Chaos auf. Classify sortiert. Owner Decision fragt mich. Task Package macht Arbeit greifbar. Executor arbeitet. Verifier prüft. Return bringt das Ergebnis zurück. Register Update verhindert, dass es verschwindet.
|
| 51 |
+
|
| 52 |
+
### 13. ARCHITEKTIN
|
| 53 |
+
Das ist die Sanduhr: oben breit, in der Mitte eng, unten wieder strukturiert. Oben darf Chaos rein. In der Taille entscheidet Samuel. Danach darf genau eine fokussierte Ausführung passieren.
|
| 54 |
+
|
| 55 |
+
### 14. KRITIKER
|
| 56 |
+
Wichtig: Ein Node ist nicht automatisch ein Agent. Ein Node kann auch nur eine kleine Regel sein: Kategorie setzen, Stop-Kriterium prüfen, oder einen Status ins Register schreiben.
|
| 57 |
+
|
| 58 |
+
### 15. MODERATORIN
|
| 59 |
+
Kapitel drei: Edges. Die Kernfrage lautet: Welche Übergänge dürfen automatisch passieren, welche nicht?
|
| 60 |
+
|
| 61 |
+
### 16. COACH
|
| 62 |
+
Einfache Edges sind feste Übergänge. Intake geht immer zu Classify. Executor geht immer zu Verify. Return geht danach zum Register Update. Das sind sichere Gleise.
|
| 63 |
+
|
| 64 |
+
### 17. ARCHITEKTIN
|
| 65 |
+
Aber Classify darf nicht blind in Ausführung springen. Nach der Klassifikation kommt entweder Review, Owner Gate oder Stop. Genau dort wird aus Automation ein verantwortbarer Prozess.
|
| 66 |
+
|
| 67 |
+
### 18. SAMUEL-STIMME
|
| 68 |
+
Automatisch darf passieren, was nur sortiert oder prüft. Nicht automatisch darf passieren, was Arbeit auslöst, sensible Entscheidungen trifft oder Agenten losschickt.
|
| 69 |
+
|
| 70 |
+
### 19. MERKSATZ
|
| 71 |
+
Edges sind nicht nur technische Pfeile. Edges sind Erlaubnisse: Dieser Schritt darf jetzt in jenen Schritt übergehen.
|
| 72 |
+
|
| 73 |
+
### 20. MODERATORIN
|
| 74 |
+
Kapitel vier: Conditional Edges. Die Kernfrage lautet: Wo soll das System Samuel bremsen?
|
| 75 |
+
|
| 76 |
+
### 21. COACH
|
| 77 |
+
Conditional Edges sind Weichen. Sensibel? Dann nur Samuel. Confidence unter null Komma fünf? Dann Review. Samuel sagt Go? Dann Executor. Verifikation fehlgeschlagen? Dann zurück, retry oder stop.
|
| 78 |
+
|
| 79 |
+
### 22. KRITIKER
|
| 80 |
+
Das ist kein Misstrauen gegen Automation. Das ist gutes Systemdesign. Ein HAI-Graph ohne Bremsen wird zur Agenten-Rutschbahn. Ein HAI-Graph mit Weichen bleibt führbar.
|
| 81 |
+
|
| 82 |
+
### 23. ARCHITEKTIN
|
| 83 |
+
Die wichtigsten Bedingungen sind nicht kompliziert: Ist es sensibel? Ist genug Sicherheit da? Hat Samuel zugestimmt? Hat die Prüfung bestanden? Daraus entsteht der Kontrollfluss.
|
| 84 |
+
|
| 85 |
+
### 24. MERKSATZ
|
| 86 |
+
Conditional Edges sind die Sicherheitslogik des Graphen. Sie sagen nicht nur wohin, sondern unter welcher Bedingung.
|
| 87 |
+
|
| 88 |
+
### 25. MODERATORIN
|
| 89 |
+
Kapitel fünf: Human-in-the-loop. Das ist der wichtigste Teil.
|
| 90 |
+
|
| 91 |
+
### 26. COACH
|
| 92 |
+
Der Graph muss an der Taille stoppen und Samuel fragen: Willst du daraus Arbeit machen? Ja, nein, oder welcher Modus? Vor diesem Gate wird sortiert. Nach diesem Gate wird ausgeführt.
|
| 93 |
+
|
| 94 |
+
### 27. SAMUEL-STIMME
|
| 95 |
+
Das Human-Gate ist also nicht ein nettes Popup. Es ist der Ownership-Punkt. HAI darf vorbereiten, aber ich entscheide, ob daraus echte Arbeit wird.
|
| 96 |
+
|
| 97 |
+
### 28. KRITIKER
|
| 98 |
+
Wenn der Graph hier nicht stoppt, verliert Samuel die Autorenschaft. Dann optimiert das System vielleicht fleißig, aber nicht unbedingt in Samuels Richtung.
|
| 99 |
+
|
| 100 |
+
### 29. MERKSATZ
|
| 101 |
+
Human-in-the-loop heißt: Samuel bleibt Owner an der Entscheidung, nicht Zuschauer nach der Ausführung.
|
| 102 |
+
|
| 103 |
+
### 30. MODERATORIN
|
| 104 |
+
Kapitel sechs: Checkpointing und Persistence. Die Kernfrage lautet: Wie verhindere ich, dass Arbeit wieder in Chats verschwindet?
|
| 105 |
+
|
| 106 |
+
### 31. ARCHITEKTIN
|
| 107 |
+
Checkpointing heißt: Der Graph kann seinen Zustand speichern und wieder aufnehmen. Für HAI heißt das: Was war entschieden, was wurde delegiert, was ist offen, wo kam Ergebnis zurück, und was wurde im Register aktualisiert?
|
| 108 |
+
|
| 109 |
+
### 32. COACH
|
| 110 |
+
Ohne Persistence ist LangGraph nur ein hübscher Ablauf im Moment. Mit Persistence wird HAI zu einem Arbeitsgedächtnis: Entscheidungen, Pakete, Ergebnisse und offene Knoten bleiben auffindbar.
|
| 111 |
+
|
| 112 |
+
### 33. SAMUEL-STIMME
|
| 113 |
+
Das Register ist die sichtbare Rückgabe in mein System. Nicht nur: Agent hat etwas gesagt. Sondern: Status, Ergebnis, Prüfung und nächster offener Punkt sind eingetragen.
|
| 114 |
+
|
| 115 |
+
### 34. MODERATORIN
|
| 116 |
+
Kapitel sieben: Tool- und Agent-Calls. Die Kernfrage lautet: Wie verhindere ich unkontrollierten Agenten-Fanout?
|
| 117 |
+
|
| 118 |
+
### 35. COACH
|
| 119 |
+
Die Regel für HAI ist eng: Erst nach Owner-Go. Genau ein Executor. Mit Task-Package. Mit Stop-Kriterium. Danach Verifikation. Kein breiter Fanout, kein autonomes Herumwuchern.
|
| 120 |
+
|
| 121 |
+
### 36. KRITIKER
|
| 122 |
+
Ein Executor ohne Task-Package ist ein Risiko. Ein Task-Package ohne Stop-Kriterium ist ein offener Sumpf. Ein Ergebnis ohne Verifikation ist nur eine Behauptung.
|
| 123 |
+
|
| 124 |
+
### 37. ARCHITEKTIN
|
| 125 |
+
Deshalb erzeugt task_package_node nicht einfach Prompt-Text. Er begrenzt Arbeit: Ziel, Input, erlaubte Tools, Definition von fertig, Verifikationskriterium und Rückgabeformat.
|
| 126 |
+
|
| 127 |
+
### 38. MERKSATZ
|
| 128 |
+
Agent Calls passieren in HAI nicht, weil ein Agent könnte. Sie passieren, weil Samuel nach dem Gate genau eine begrenzte Ausführung erlaubt hat.
|
| 129 |
+
|
| 130 |
+
### 39. MODERATORIN
|
| 131 |
+
Kapitel acht: Minimaler Graph statt Mega-System.
|
| 132 |
+
|
| 133 |
+
### 40. COACH
|
| 134 |
+
Der kleinste sinnvolle Graph führt genau einen Gedanken durch die Sanduhr: Intake, Classify, Owner Gate, Task Package, Executor, Verify, Return, Register Update.
|
| 135 |
+
|
| 136 |
+
### 41. SAMUEL-STIMME
|
| 137 |
+
Wenn ich diesen einen Gedanken sauber durchbekomme, verstehe ich LangGraph praktisch. Wenn ich sofort HAI komplett baue, verstecke ich mein fehlendes Modell unter Architektur.
|
| 138 |
+
|
| 139 |
+
### 42. KRITIKER
|
| 140 |
+
Das Ziel ist nicht Größe. Das Ziel ist Kontrollierbarkeit. Ein kleiner Graph, den Samuel erklären kann, ist wertvoller als ein großes System, das niemand mehr besitzt.
|
| 141 |
+
|
| 142 |
+
### 43. MODERATORIN
|
| 143 |
+
Jetzt die Rückaneignung. Pausiere nach diesem Podcast und fülle den Satz selbst.
|
| 144 |
+
|
| 145 |
+
### 44. COACH
|
| 146 |
+
Mein HAI-Loop besteht aus State: Gedankenstatus, Kategorie, Entscheidung, nächster Schritt, Executor, Ergebnis, Verifikation und Registerstatus.
|
| 147 |
+
|
| 148 |
+
### 45. ARCHITEKTIN
|
| 149 |
+
Knoten: Intake, Classify, Owner Decision, Task Package, Executor, Verifier, Return und Register Update.
|
| 150 |
+
|
| 151 |
+
### 46. KRITIKER
|
| 152 |
+
Übergänge: sichere automatische Edges für Sortieren und Prüfen; Conditional Edges für Sensibilität, Confidence, Samuel-Go und Verifikationsfehler.
|
| 153 |
+
|
| 154 |
+
### 47. MERKSATZ
|
| 155 |
+
Human-Gate: An der Taille bleibt Samuel Owner und entscheidet, ob aus einem Gedanken Arbeit wird.
|
| 156 |
+
|
| 157 |
+
### 48. COACH
|
| 158 |
+
Dein Check: Erkläre jetzt in deinen eigenen Worten einen einzigen HAI-Durchlauf. Nicht perfekt. Nur: State, Nodes, Edges, Conditional Edges und Human-Gate. Wenn du das kannst, ist das mentale Modell da.
|
artifacts/hai_langgraph_multivoice_podcast_20260608/HAI_LANGGRAPH_MULTIVOICE_PODCAST.mp3
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:ca2dfcee04c7e205261dbb0b505d6b0acba35bc44c80b50daaf63e9f90a87a22
|
| 3 |
+
size 2440173
|
artifacts/hai_langgraph_multivoice_podcast_20260608/ffmpeg_concat.txt
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/001_moderatorin.mp3'
|
| 2 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/002_coach.mp3'
|
| 3 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/003_samuel_stimme.mp3'
|
| 4 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/004_architektin.mp3'
|
| 5 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/005_moderatorin.mp3'
|
| 6 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/006_coach.mp3'
|
| 7 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/007_architektin.mp3'
|
| 8 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/008_kritiker.mp3'
|
| 9 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/009_merksatz.mp3'
|
| 10 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/010_moderatorin.mp3'
|
| 11 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/011_coach.mp3'
|
| 12 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/012_samuel_stimme.mp3'
|
| 13 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/013_architektin.mp3'
|
| 14 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/014_kritiker.mp3'
|
| 15 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/015_moderatorin.mp3'
|
| 16 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/016_coach.mp3'
|
| 17 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/017_architektin.mp3'
|
| 18 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/018_samuel_stimme.mp3'
|
| 19 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/019_merksatz.mp3'
|
| 20 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/020_moderatorin.mp3'
|
| 21 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/021_coach.mp3'
|
| 22 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/022_kritiker.mp3'
|
| 23 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/023_architektin.mp3'
|
| 24 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/024_merksatz.mp3'
|
| 25 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/025_moderatorin.mp3'
|
| 26 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/026_coach.mp3'
|
| 27 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/027_samuel_stimme.mp3'
|
| 28 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/028_kritiker.mp3'
|
| 29 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/029_merksatz.mp3'
|
| 30 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/030_moderatorin.mp3'
|
| 31 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/031_architektin.mp3'
|
| 32 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/032_coach.mp3'
|
| 33 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/033_samuel_stimme.mp3'
|
| 34 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/034_moderatorin.mp3'
|
| 35 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/035_coach.mp3'
|
| 36 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/036_kritiker.mp3'
|
| 37 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/037_architektin.mp3'
|
| 38 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/038_merksatz.mp3'
|
| 39 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/039_moderatorin.mp3'
|
| 40 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/040_coach.mp3'
|
| 41 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/041_samuel_stimme.mp3'
|
| 42 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/042_kritiker.mp3'
|
| 43 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/043_moderatorin.mp3'
|
| 44 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/044_coach.mp3'
|
| 45 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/045_architektin.mp3'
|
| 46 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/046_kritiker.mp3'
|
| 47 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/047_merksatz.mp3'
|
| 48 |
+
file '/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/segments/048_coach.mp3'
|
artifacts/hai_langgraph_multivoice_podcast_20260608/manifest.json
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"mode": "EXPLAIN",
|
| 3 |
+
"summary_mode": false,
|
| 4 |
+
"source": "user-provided HAI LangGraph task package in current chat",
|
| 5 |
+
"segment_count": 48,
|
| 6 |
+
"voices_used": [
|
| 7 |
+
"de-DE-AmalaNeural",
|
| 8 |
+
"de-DE-ConradNeural",
|
| 9 |
+
"de-DE-FlorianMultilingualNeural",
|
| 10 |
+
"de-DE-KatjaNeural",
|
| 11 |
+
"de-DE-KillianNeural",
|
| 12 |
+
"de-DE-SeraphinaMultilingualNeural"
|
| 13 |
+
],
|
| 14 |
+
"markdown_path": "/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/HAI_LANGGRAPH_MULTIVOICE_PODCAST.md",
|
| 15 |
+
"audio_path": "/home/smlflg/Projekte/Agent8Agent/artifacts/hai_langgraph_multivoice_podcast_20260608/HAI_LANGGRAPH_MULTIVOICE_PODCAST.mp3",
|
| 16 |
+
"duration_seconds": 406.656,
|
| 17 |
+
"max_segment_chars": 225,
|
| 18 |
+
"playback_returncode": 0,
|
| 19 |
+
"played_detected": true,
|
| 20 |
+
"elapsed_seconds": 524.33
|
| 21 |
+
}
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/001_moderatorin.mp3
ADDED
|
Binary file (56 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/002_coach.mp3
ADDED
|
Binary file (52.6 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/003_samuel_stimme.mp3
ADDED
|
Binary file (56 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/004_architektin.mp3
ADDED
|
Binary file (69.8 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/005_moderatorin.mp3
ADDED
|
Binary file (39.9 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/006_coach.mp3
ADDED
|
Binary file (55 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/007_architektin.mp3
ADDED
|
Binary file (61.5 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/008_kritiker.mp3
ADDED
|
Binary file (54.3 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/009_merksatz.mp3
ADDED
|
Binary file (47.2 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/010_moderatorin.mp3
ADDED
|
Binary file (35.7 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/011_coach.mp3
ADDED
|
Binary file (77.6 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/012_samuel_stimme.mp3
ADDED
|
Binary file (91.3 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/013_architektin.mp3
ADDED
|
Binary file (65.1 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/014_kritiker.mp3
ADDED
|
Binary file (55.2 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/015_moderatorin.mp3
ADDED
|
Binary file (40.3 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/016_coach.mp3
ADDED
|
Binary file (48.2 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/017_architektin.mp3
ADDED
|
Binary file (58 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/018_samuel_stimme.mp3
ADDED
|
Binary file (50 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/019_merksatz.mp3
ADDED
|
Binary file (40.3 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/020_moderatorin.mp3
ADDED
|
Binary file (35.7 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/021_coach.mp3
ADDED
|
Binary file (69.4 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/022_kritiker.mp3
ADDED
|
Binary file (57 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/023_architektin.mp3
ADDED
|
Binary file (58.5 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/024_merksatz.mp3
ADDED
|
Binary file (39.6 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/025_moderatorin.mp3
ADDED
|
Binary file (25.1 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/026_coach.mp3
ADDED
|
Binary file (54 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/027_samuel_stimme.mp3
ADDED
|
Binary file (48.8 kB). View file
|
|
|
artifacts/hai_langgraph_multivoice_podcast_20260608/segments/028_kritiker.mp3
ADDED
|
Binary file (44.5 kB). View file
|
|
|