Talk to wren nodes from the chat's Control tab, opened from Home

This commit is contained in:
2026-10-05 20:59:11 +02:00
parent 14d3208a5d
commit afe0c94a24
11 changed files with 417 additions and 42 deletions
+50 -1
View File
@@ -21,8 +21,14 @@ from pydantic import BaseModel, Field
from fluksio.ai import agent, client
from fluksio.ai import config as ai_config
from fluksio.api.deps import CurrentUser, TokenDep, get_current_active_superuser
from fluksio.api.deps import (
CurrentUser,
FlowControllerDep,
TokenDep,
get_current_active_superuser,
)
from fluksio.core.config import settings
from fluksio.flow.messages import qualify
from fluksio.flow.schemas import NAME_PATTERN
from fluksio.mcp import server as tools
@@ -71,6 +77,17 @@ class ChatItem(BaseModel):
error: str | None = None
class ControlNode(BaseModel):
"""A wren node the chat can talk to: where it sends and where it reads."""
#: Qualified, ``flow.node``.
id: str
flow: str
title: str
prompt_msg: str
actions_msg: str
class TurnBody(BaseModel):
message: str = Field(min_length=1, max_length=20_000)
#: The flow open in the editor, when the chat is opened from one.
@@ -156,6 +173,38 @@ def read_ai_status(_: CurrentUser) -> Any:
return AIStatus(available=True, model=config.model)
@router.get("/control", response_model=list[ControlNode])
def read_control_nodes(_: CurrentUser, controller: FlowControllerDep) -> Any:
"""The wren nodes of the running live flows, for the chat's Control tab.
Only those with both ends wired: the chat publishes the command on the
prompt's message and reads the answer off the actions'.
"""
found = []
for flow in controller.store.read_all():
if flow.mode != "live" or flow.name in controller.disabled:
continue
for node in flow.nodes:
if node.type != "wren":
continue
ends = {
spec.port: qualify(flow.name, spec.name)
for spec in [*node.requires, *node.provides]
if spec.port in ("prompt", "actions") and spec.name
}
if len(ends) == 2:
found.append(
ControlNode(
id=f"{flow.name}.{node.id}",
flow=flow.name,
title=node.title or node.id,
prompt_msg=ends["prompt"],
actions_msg=ends["actions"],
)
)
return found
def _chat_file(user_id: uuid.UUID) -> Any:
return settings.CHATS_DIR / f"{user_id}.json"