Skip to content

tdfs4ds.serve.chat

tdfs4ds.serve.chat

Native chat panel of the admin shell (v0.3.2.0).

The shell used to embed the Gradio chat in an iframe. The chat is now part of the shell itself: app.js opens an SSE stream on /ui/chat/stream and this module turns :func:tdfs4ds.agent.graph.consumer_agent_stream events into small JSON messages. The agent is unchanged; the Gradio chat stays mounted at /chatbot for existing deployments.

Events (name, payload), in order:

  • status {step, node, label, intent, object, domain} -- one per graph node
  • tool {name, input} -- an MCP tool call
  • answer {html, sources_html, markdown, charts} -- the answer, rendered server-side by the panels' Markdown renderer, its Sources footer split off so the user view can fold it, and the charts as sandboxed iframes
  • admin {intent, skill, domain, object, steps, total_ms, tokens, trace_html, has_graph} -- the observability detail, shown only in the admin view (sent always, so switching view needs no new request)
  • error {message} -- the whole error text, never cut

The context knowledge graph is large (an inlined pyvis page), so it is not sent with every answer: it is kept per thread (:data:_LAST_GRAPH) and fetched by the admin view on demand (/ui/chat/graph).

_THREAD_RE module-attribute

_THREAD_RE = compile('^[A-Za-z0-9_.:-]{1,80}$')

_SOURCES_RE module-attribute

_SOURCES_RE = compile('^\\s*\\*\\*Sources\\*\\*', MULTILINE)

_LAST_GRAPH module-attribute

_LAST_GRAPH: 'OrderedDict[str, str]' = OrderedDict()

_GRAPH_KEEP module-attribute

_GRAPH_KEEP = 64

_TURN_LOCK module-attribute

_TURN_LOCK = Lock()

new_thread_id

new_thread_id() -> str

valid_thread_id

valid_thread_id(thread_id: Optional[str]) -> str

The caller's thread id when well-formed, else a fresh one.

default_view

default_view() -> str

TDFS4DS_SERVE_DEFAULT_VIEW: 'user' or 'admin' (default, unchanged).

split_sources

split_sources(markdown: str) -> Tuple[str, str]

Split an answer into (body, Sources footer). No footer -> ("…", "").

_plain_label

_plain_label(node: str, state: dict) -> str

The Gradio chat's step label, without its emoji and Markdown.

_render

_render(md: str) -> str

_skill_of

_skill_of(steps: list) -> str

chat_events

chat_events(stream: Iterable[tuple], *, thread_id: str = '', clock: Callable[[], float] = time.perf_counter) -> Iterator[Tuple[str, dict]]

Map consumer_agent_stream events to chat-panel events (pure, no I/O besides Markdown rendering). A failure of the stream ends with an error event carrying the full message; nothing is truncated.

run_turn

run_turn(question: str, thread_id: str, mcp_enabled: bool = False) -> Iterator[Tuple[str, dict]]

Run one turn of the consumer agent and yield chat-panel events.

last_graph

last_graph(thread_id: str) -> str

suggestions

suggestions(limit: int = 4) -> list

Starter questions, named after real objects of the connected store.

One definition, shared with the Gradio chat: see :func:tdfs4ds.agent.chatbot.chat_suggestions.