Talk to wren nodes from the chat's Control tab, opened from Home
This commit is contained in:
@@ -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"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user