Skip to content

feat(runs): show AI request + structured response in step inspector#42

Merged
hoootan merged 2 commits into
mainfrom
feat/run-inspector-ai-response
May 2, 2026
Merged

feat(runs): show AI request + structured response in step inspector#42
hoootan merged 2 commits into
mainfrom
feat/run-inspector-ai-response

Conversation

@hoootan
Copy link
Copy Markdown
Owner

@hoootan hoootan commented May 2, 2026

Summary

  • Server: snapshot the AI step request (model, messages, temperature, max_tokens, tools, tool_choice, use_cache) onto step.input before the LiteLLM call, so the dashboard can show what was sent alongside the response. Previously this data was lost when step.output was overwritten with the LLM result.
  • Dashboard: restructure StepInspector to render input and output side-by-side in NB/IDE modes via a responsive auto-fit, minmax(320px, 1fr) grid (collapses to one column on narrow widths).
  • Dashboard: detect AI-shaped output (content + usage + model) and render a new AI Response sub-section with content (text or JSON), tool calls (per-call name + args), usage pills (model, tokens, cost, latency, finish_reason), and a collapsible raw JSON toggle — instead of a single JSON dump.
  • Dashboard: detect agent-shaped output (messages[] + iterations) and render an Agent Conversation sub-section with status/iteration/token pills, final output, and a role-tagged message thread.
  • Dashboard: AI input renders as an AI Request card with model / temp / max_tokens / tool-count chips above a role-tagged message thread.
  • Plain step.run outputs (e.g. the plan_searches case) still render as JSON.

Test plan

  • Trigger a function that uses step.ai; confirm steps.input is now populated in the DB and appears in the run detail panel
  • On the run detail page in NB/IDE mode, verify input and output render in two columns (collapse to one on a narrow viewport)
  • AI step Output column shows AI Response card with content, tool calls (if any), and usage pills; raw JSON hidden behind the toggle
  • Agent step shows the Agent Conversation card with role-tagged messages
  • Plain step.run step still renders raw JSON (no regression)
  • THR mode still works and now uses the same shape-aware blocks

- Snapshot AI step request (model, messages, temperature, tools, …) onto
  step.input before the LLM call so it survives the response overwrite.
- Restructure StepInspector to render input alongside output via a
  responsive 2-column grid in NB/IDE modes.
- Detect AI-shaped output (content + usage + model) and render an
  AI Response card with content, tool calls, usage pills, and a raw
  JSON toggle instead of a single JSON dump.
- Detect agent-shaped output (messages + iterations) and render a
  conversation thread with status / iteration / token pills.
- AI input renders as a request card with model / temp / max_tokens
  chips and a role-tagged message thread.
Copilot AI review requested due to automatic review settings May 2, 2026 21:38
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enhances run step inspection by persisting AI step request payloads on the server and improving the dashboard inspector UI to render AI/agent inputs and outputs in a more structured, side-by-side format.

Changes:

  • Server: snapshot AI step request parameters onto step.input before executing the LiteLLM call.
  • Dashboard: refactor StepInspector to show input/output side-by-side in NB/IDE modes and add shape-aware rendering blocks for AI responses and agent conversations.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 2 comments.

File Description
server/src/flowforge_server/services/executor.py Stores the AI request payload in step.input before the model call so it remains visible after step.output is set.
dashboard/src/app/(dashboard)/runs/[id]/page.tsx Adds shape-aware UI blocks for AI request/response + agent conversation and updates NB/IDE layouts to a responsive two-column grid.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +336 to +342
type AiOutput = {
content?: string;
model?: string;
provider?: string;
usage?: { prompt_tokens?: number; completion_tokens?: number; total_tokens?: number; cost_usd?: number; latency_ms?: number };
finish_reason?: string;
tool_calls?: Array<{ id?: string; function?: { name?: string; arguments?: unknown } }>;
Comment on lines +446 to +454
{toolCalls.map((tc, idx) => {
const name = tc.function?.name ?? '(unnamed)';
const args = tc.function?.arguments;
const argsStr = typeof args === 'string' ? args : JSON.stringify(args ?? {}, null, 2);
return (
<div key={tc.id ?? idx} style={{ borderLeft: '2px solid var(--brand)', paddingLeft: 10 }}>
<div className="mono" style={{ fontSize: 12, marginBottom: 4 }}><b>{name}</b></div>
<CodeBlock language="json" code={argsStr} />
</div>
AIResponse.to_dict() emits tool calls as {id, name, arguments}, not
the OpenAI-wrapped {function: {name, arguments}}. The inspector was
reading tc.function.name / tc.function.arguments and would always
render "(unnamed)" with empty args. Switch to tc.name / tc.arguments
with a fallback to the wrapped shape for safety.
@hoootan hoootan merged commit 37e27ae into main May 2, 2026
4 checks passed
@hoootan hoootan deleted the feat/run-inspector-ai-response branch May 2, 2026 21:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants