Repository navigation
feat(flows): prompt bar → instant canvas with backend-driven copilot builder - #4578
Conversation
…as with the copilot building Submitting the Workflows-page prompt bar now reacts immediately: it flows_create's a blank flow named from the description, navigates to /flows/:id with a copilotBuild seed in location.state, and the canvas opens with the copilot panel already running the build turn (same seeding pattern as the failed-run repair seed). Previously the builder worked on a hidden thread while the list page sat static. Claude-Session: https://claude.ai/code/session_01SVY5JZydeTRhEeKRG38T9F
…nt node
Implements the tinyflows `AgentRunner` capability over OpenHuman's agent
registry, so an `agent` node's `agent_ref` selects a registered agent KIND
(researcher, code_executor, crypto_agent, …) and runs the completion shaped by
that agent's persona.
- OpenHumanAgentRunner resolves + validates `agent_ref` via agent_registry,
prepends the agent's system_prompt (and adopts its model when the node didn't
pin one), then runs the same provider path as a plain agent turn — so the
{json,text,raw} envelope and structured-output behavior are identical.
- Wired into build_capabilities as `agent: Some(...)`.
- First cut applies persona/model; the agent's private tool loop (run_subagent
needs a full ParentExecutionContext a standalone flow run doesn't establish)
is a documented follow-up — tools still come from the node's inline sub-port.
- `agent_ref` is trusted node config, never model output (injection-safe).
- Also updates the OpenHumanLlm doc to describe the new node output envelope.
- Unit tests for the request-augmentation (prepend_system_message).
Claude-Session: https://claude.ai/code/session_01SNk9tTFTDs5zUbNhaXwABy
…use the reasoning tier The copilot previously ended builds by telling the user to go save the proposal themselves — by design it had no persistence tool. This adds save_workflow, a narrow carve-out from the propose-only belt: it persists a validated graph (and optional rename) onto an ALREADY EXISTING flow via flows_update. It still cannot create a flow, enable or disable one, or touch the approval gate. The instant-create prompt-bar path now delegates with a build-and-save directive (buildSeededBuildPrompt): design the graph, self-check with dry_run_workflow, return the proposal, then save_workflow onto the flow the host just created. Manual copilot revise turns may save only when the user explicitly asks; real run_workflow tests still require explicit confirmation first. Also moves the workflow_builder agent from the burst worker tier to hint:reasoning — graph authoring is multi-step structured reasoning. Claude-Session: https://claude.ai/code/session_01SVY5JZydeTRhEeKRG38T9F
Points the host at the vendored tinyflows commits this branch depends on:
env-leak fix + switch/transform nodes scope, the {json,text,raw} agent output
envelope, and the AgentRunner capability that OpenHumanAgentRunner implements.
Claude-Session: https://claude.ai/code/session_01SNk9tTFTDs5zUbNhaXwABy
…he flows module
The flow-authoring/discovery agents now live under `flows/agents/` alongside the
data model, tools, and RPCs they operate on, instead of being scattered in
`agent_registry/agents/`. Registration stays centralized: the loader's BUILTINS
slice points at the relocated modules by path — the same cross-module pattern
`reasoning_agent` already uses from `orchestration/` (include_str! + a
`crate::openhuman::flows::agents::…::prompt::build` fn ptr).
- git mv workflow_builder/ + flow_discovery/ → src/openhuman/flows/agents/
- new flows/agents/mod.rs; `pub mod agents;` in flows/mod.rs
- drop the two `pub mod` decls from agent_registry/agents/mod.rs
- loader.rs BUILTINS: repoint toml include + prompt_fn at flows::agents
No behavior change — prompt.rs uses only self-relative include_str!("prompt.md")
and absolute crate paths, so the move is mechanical. Loader registration tests
(workflow_builder / flow_discovery scope) and the agents' prompt tests pass.
Claude-Session: https://claude.ai/code/session_01SNk9tTFTDs5zUbNhaXwABy
…backend agent
Moves the builder's turn-prompt construction out of the frontend and invokes
workflow_builder directly, the same way the Flow Scout (flows_discover) runs —
instead of the frontend crafting "delegate directive" strings and relying on the
chat orchestrator to route them to the specialist.
- flows/agents/workflow_builder/builder_prompt.rs: server-side render of the
turn brief from a structured BuilderRequest { mode, instruction, graph,
flow_id, run_id, error, failing_node_ids }. Ports workflowBuilderPrompt.ts;
modes create/revise/repair/build, same persistence contract (propose-only
except build, which saves onto an existing flow). Unit tests per mode.
- flows::ops::flows_build: Agent::from_config_for_agent(config,
"workflow_builder") + run_single under a CLI origin, 300s timeout (mirrors
flows_discover). Captures the proposal from the run's tool history — the
propose/revise/save tools emit a self-describing { type: "workflow_proposal" }
result — and returns { proposal, assistant_text, error }.
- openhuman.flows_build controller schema + handler; schema-consistency tests
updated (21 controllers).
Frontend rewire to call flows_build (retiring workflowBuilderPrompt.ts) is next.
Claude-Session: https://claude.ai/code/session_01SNk9tTFTDs5zUbNhaXwABy
…end prompts)
The Flows prompt bar and canvas copilot now run the workflow_builder agent
server-side through `openhuman.flows_build` instead of crafting "delegate
directive" prompt strings and routing them through the chat orchestrator. The
frontend sends a structured turn request; the core renders the brief and runs
the agent (like the Flow Scout).
- flowsApi: `buildWorkflow(request)` → flows_build, + `mapWorkflowProposal`
(kept in lockstep with ChatRuntimeProvider's parse) and BuilderTurn types.
- useWorkflowBuilderChat: `send({ displayText, request })` calls buildWorkflow,
appends the user turn + the agent's reply to the thread transcript, and sets
the proposal in the same store slice the streamed path used (UI unchanged).
- WorkflowCopilotPanel / SuggestedWorkflows: send structured create/revise/
repair/build requests; RepairPromptContext moved onto the panel.
- Deleted app/src/lib/flows/workflowBuilderPrompt.ts (+ test) — prompt
construction now lives in flows/agents/workflow_builder/builder_prompt.rs.
- Tests updated to assert on the structured request; 43 pass, typecheck clean.
Claude-Session: https://claude.ai/code/session_01SNk9tTFTDs5zUbNhaXwABy
…lope
Points the host at the C2 crate commit: tool_call/http_request now default to
per-item execution (fixing the split_out fan-out silent-drop) and wrap their
output in the same {json,text,raw} envelope as the agent node. Host tool/flow
tests pass unchanged (the ToolInvoker capability still returns the raw result;
enveloping happens in the node).
Claude-Session: https://claude.ai/code/session_01SNk9tTFTDs5zUbNhaXwABy
Add gitbooks/developing/architecture/flows-on-tinyagents.md documenting how a
saved flow runs: the WorkflowGraph → validate → compile → tinyagents GraphBuilder
pipeline, the {run,nodes} run-state + merge reducer + {json,text,raw} envelope +
=-expression scope, agent-nodes-as-nested-graphs (graph within a graph), the
seven-trait capability seam, the two-layer security model (outer Workflow
origin/autonomy gate, inner agent ToolScope/sandbox gate, trusted-config
agent_ref), the one-trigger model with host-side multi-trigger via bus
subscribers, and builder/scout/executor all on one harness. Three Mermaid
diagrams (run pipeline, nested agent node, discover→build→save→run lifecycle).
Link it into gitbooks/SUMMARY.md.
Claude-Session: https://claude.ai/code/session_01H6XV8tbbeRGnd15Z2vUPEF
Add the "Research brief (Opus plans, Sonnet drafts)" curated template:
manual trigger ({topic}) -> reasoning-v1 agent "planner" (output_parser
schema -> {plan, angle}) -> chat-v1 agent "drafter" (prompt binds
=nodes.planner.item.json.plan) -> transform shaping {topic, plan, draft}.
Exercises agent nodes with managed tiers and graph-state data passing.
Registers it in the templates index (onDemand) and adds i18n name/description
keys to en.ts plus real translations in all 13 locale files.
Claude-Session: https://claude.ai/code/session_01H6XV8tbbeRGnd15Z2vUPEF
…s path The workflow_builder / flow_discovery agents moved to src/openhuman/flows/agents/ (commit 2959dcb) but mcp_server/resources.rs still include_str!'d the old agent_registry/agents/ paths, so the lib crate failed to compile. Repoint the two include_str! calls; no behavior change. Claude-Session: https://claude.ai/code/session_01H6XV8tbbeRGnd15Z2vUPEF
…odes run dry_run_workflow wired the sandbox with plain mock_capabilities() (agent: None), so a draft whose agent node selects a named agent kind (agent_ref) errored on a missing capability instead of simulating. Switch to mock_capabilities_with_agent(MockAgentRunner) — a deterministic echo runner, no real turn fires — so the builder can self-test drafts that use agent-kind nodes. Adds a builder_tools test covering an agent_ref draft dry-running green. Claude-Session: https://claude.ai/code/session_01H6XV8tbbeRGnd15Z2vUPEF
`OpenHumanLlm::complete` ignored a node's `config.model`, so a plain `agent` node pinning a managed tier (`reasoning-v1` / `chat-v1`, as the Opus+Sonnet demo template does) routed via the caller's default role instead of the pinned tier. Add `factory::role_for_model_tier` (tier / `hint:*` -> workload role) and consult it in `complete`: when the node pins a model, map that tier back to its role so the completion resolves to the right managed tier (or the role's BYOK model). `config.model` is trusted node config, never model output. Unit tests cover the tier/alias/unknown mappings in factory_tests.rs. Claude-Session: https://claude.ai/code/session_01H6XV8tbbeRGnd15Z2vUPEF
OpenHumanAgentRunner::run_agent applied only a registered agent's persona/model
over a bare OpenHumanLlm::complete — no tool loop, no sandbox (documented as a
first cut). Rewrite it to route by agent_ref:
- Harness path (agent_ref names a harness AgentDefinition): build a real session
agent (Agent::from_config_for_agent + set_agent_definition_name) and drive one
run_single — the full tool loop. The definition's ToolScope / sandbox_mode /
max_iterations govern the turn, so an agent node gains its curated toolset with
no graph change. This is the same harness pattern flows_build / flows_discover /
cron use: a nested tinyagents graph (the agent turn) inside the flow graph.
- Fallback path (only a custom AgentRegistryEntry): keep the persona-shaping
single completion, so custom agents don't regress.
Details:
- node_request_to_prompt maps the node request (prompt or flattened messages)
to run_single's single message; structured-output nodes append JSON steering.
- Model precedence: node config.model > entry model > definition default. The
managed tier is normalised to the hint:<role> form the session builder routes
on (bare tiers otherwise fall through to chat) and applied cron-style on a
cloned Config's default_model — no new Agent setter API.
- Turn is bounded by clamp(timeout_secs, 10..=600).unwrap_or(240). No new origin
wrapper: the engine future already runs under the flow's Workflow origin, so
the autonomy tier + approval gate apply and the definition's ToolScope/sandbox
is the inner gate. agent_ref stays trusted-config-only.
- Result mirrors OpenHumanLlm: parsed JSON for structured nodes, else
{ text, agent_ref }; the vendor agent node folds it into { json, text, raw }.
Adds tinyflows unit tests: route selection (harness vs custom fallback), model
precedence + tier→hint normalisation, prompt mapping, timeout clamp, structured
steering, and result shaping.
Claude-Session: https://claude.ai/code/session_01H6XV8tbbeRGnd15Z2vUPEF
flows_build and flows_discover now accept an optional thread_id (+ request_id,
uuid-generated when absent). When a thread is attached, the builder/scout turn's
AgentProgress is bridged onto the web-channel socket keyed by that thread —
text/thinking/tool deltas, the propose_workflow proposal card, and a terminal
chat_done/chat_error — exactly like an interactive chat turn (blueprint:
task_dispatcher/executor.rs). The blocking {proposal, assistant_text} return is
unchanged, so CLI/tests keep the headless path. New FlowStreamTarget helper +
unit tests for param plumbing and schema exposure.
Claude-Session: https://claude.ai/code/session_01H6XV8tbbeRGnd15Z2vUPEF
Pass the copilot's dedicated chat thread id through to the flows_build / flows_discover RPC params (the Phase B streaming param convention) so the builder/scout turn streams its text/thinking/tool events onto that thread and the shared chat pane can render them live. Omitting the id preserves the existing headless behaviour. Claude-Session: https://claude.ai/code/session_01H6XV8tbbeRGnd15Z2vUPEF
…ipt) useWorkflowBuilderChat now passes its dedicated thread id into flows_build so the builder turn streams onto that thread. The global ChatRuntimeProvider owns the transcript — it appends the final assistant message on chat_done and fills streamingAssistantByThread / toolTimelineByThread — so the hook stops manually appending the agent reply (it would double it) and only appends the local user turn. The hook now also exposes toolTimeline + liveResponse read back from the runtime's per-thread streamed state. WorkflowCopilotPanel binds those into the shared ToolTimelineBlock (tool cards + streaming reply) and shows a live agent bubble in the pre-tool phase, replacing the bespoke thinking-only indicator. The proposal diff accept/reject flow and shared ChatComposer are unchanged. Claude-Session: https://claude.ai/code/session_01H6XV8tbbeRGnd15Z2vUPEF
… the canvas New AgentNodeInspector surfaces an agent node's two harness knobs inside the node-config drawer's AgentForm: an agent_ref picker sourced from openhuman.agent_registry_list (Phase A routes an agent_ref node through the full agent tool loop) and a managed capability-tier model picker (reasoning-v1 / chat-v1 / agentic-v1 / burst-v1, matching the bare tier slugs the runner + the Opus/Sonnet demo template use) with a raw-model escape hatch. It replaces AgentForm's hint-slug model field. Fetch failures degrade to inherit-only; an out-of-list agent_ref is preserved. i18n: new agentRef* / modelManagedTiers keys added to en.ts and translated across all 13 locales (i18n:check passes). Claude-Session: https://claude.ai/code/session_01H6XV8tbbeRGnd15Z2vUPEF
Adds an in-process forced-response queue to `mock_upstream_router`'s chat-completions handler so agent-driven flows can script OpenAI-shape tool calls and plain completions deterministically, mirroring the node mock's `llmForcedResponses` without a node dependency. Entries are optionally gated on a request-body marker so builder/scout side-calls can't drain a scripted response out of order. Claude-Session: https://claude.ai/code/session_01H6XV8tbbeRGnd15Z2vUPEF
Scripts the whole flows arc against the in-process mock via the forced-completion FIFO: the Flow Scout emits a suggest_workflows tool call (asserted persisted via flows_list_suggestions), the workflow_builder emits a propose_workflow tool call carrying the Opus+Sonnet demo graph (asserted returned as a proposal), then the saved graph runs its two agent nodes with scripted planner (structured JSON) and drafter (text) completions. Asserts the planner's structured plan flows into the drafter's prompt and that the nodes route to the expected managed tiers (reasoning-v1 / chat-v1). Disables context compaction so the builder's tool-result history stays JSON-parseable for proposal extraction. Claude-Session: https://claude.ai/code/session_01H6XV8tbbeRGnd15Z2vUPEF
Adds an #[ignore]d live e2e (gated on OPENHUMAN_LIVE_API_URL/TOKEN/USER_ID, guard copied from live_routing_e2e) that drives the full arc against a real backend — flows_discover → flows_build → flows_create (Opus+Sonnet demo graph) → flows_run — and prints each step's output plus the managed tier each agent node used. scripts/live-flows-demo.sh loads .env via load-dotenv and runs it with --ignored --nocapture. Claude-Session: https://claude.ai/code/session_01H6XV8tbbeRGnd15Z2vUPEF
Merge the type-only RepairPromptContext import into the default import to clear the no-duplicate-imports lint error. Claude-Session: https://claude.ai/code/session_01H6XV8tbbeRGnd15Z2vUPEF
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 29 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (15)
📝 WalkthroughWalkthroughThis PR replaces client-built prompt strings with structured builder-turn requests (mode/instruction/graph/flow_id) throughout the workflow-builder UI and hook layer, adds a server-side ChangesFrontend workflow builder UX
Server-side flows_build pipeline, agent runner, and tools
Estimated code review effort: 4 (Complex) | ~75 minutes Sequence Diagram(s)sequenceDiagram
participant User
participant Panel as WorkflowCopilotPanel
participant Hook as useWorkflowBuilderChat
participant API as flowsApi.buildWorkflow
participant RPC as openhuman.flows_build
participant Agent as workflow_builder agent
User->>Panel: request build/revise/repair turn
Panel->>Hook: send({mode, instruction, graph, flowId})
Hook->>API: buildWorkflow(request, threadId)
API->>RPC: openhuman.flows_build(params)
RPC->>Agent: run_via_harness / build_via_registry
Agent-->>RPC: proposal / assistant text / error
RPC-->>API: {proposal, assistant_text, error}
API-->>Hook: BuilderTurnResult
Hook-->>Panel: proposal, toolTimeline, liveResponse
Panel-->>User: render proposal / streamed UI
sequenceDiagram
participant WorkflowPromptBar
participant FlowsAPI as flowsApi.createFlow
participant Router
participant FlowCanvasPage
participant CopilotPanel as WorkflowCopilotPanel
WorkflowPromptBar->>FlowsAPI: createFlow(name, blankGraph)
FlowsAPI-->>WorkflowPromptBar: flowId
WorkflowPromptBar->>Router: navigate(/flows/:id, copilotBuild)
Router->>FlowCanvasPage: load with location.state
FlowCanvasPage->>FlowCanvasPage: asCopilotBuildSeed(state)
FlowCanvasPage->>CopilotPanel: open with buildSeed
CopilotPanel->>CopilotPanel: auto-send build request
Possibly related PRs
Suggested labels: Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d69b017c1c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Prettier line-wraps long flows i18n values across locale files and the opus-sonnet-brief template JSON (fixes the Frontend Checks format:check gate). Also syncs app/src-tauri/Cargo.lock (bytes dep pulled in by the tinyflows bump) regenerated by the pre-push rust check. Claude-Session: https://claude.ai/code/session_01WQfYQwSLuAwmrTXLbZKv6B
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 4b2600f759
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Summary
flows_buildRPC drives the workflow copilot as a first-class backend agent (retires the frontend-side builder prompts);flows_discover/flows_buildnow thread a copilot chat id so copilot/scout turns stream over the shared chat progress bridge.OpenHumanAgentRunner, honoring per-nodeagent_refand managed model tier; agent-node inspector added on the canvas.storage_*agent tools for the backend's managed S3 file storage, plus supportingintegrations/client.rsandinference/provider/factory.rsprovider wiring.flowsmodule;tinyflowsvendor bumped for per-item execution + tool/http envelope.Problem
agent_refnodes or per-node model tiers.Solution
src/openhuman/flows/agents/and exposedflows_build/flows_discoverRPCs that run them as backend agents, streaming turns through the chat progress bridge via a threaded copilot chat id.OpenHumanAgentRunnerto execute a selected agent kind per node through the full harness tool loop, honoring managed model tier; agent-node inspector surfacesagent_ref+ tier on the canvas.AgentRunnersoagent_refnodes run in tests without a live backend.Submission Checklist
diff-cover) meet the gate enforced by.github/workflows/ci-lite.yml. Runpnpm test:coverageandpnpm test:rustlocally; PRs below 80% on changed lines will not merge.docs/TEST-COVERAGE-MATRIX.mdImpact
flows_build/flows_discoverRPC behavior andstorage_*agent tools.Related
AI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch
feat/flows-prompt-instant-canvasd69b017c1Validation Run
pnpm --filter openhuman-app format:checkpnpm typechecktests/json_rpc_e2e.rs,tests/live_flows_demo_e2e.rs, flows unit testscargo fmt --check(pre-pushpnpm rust:checkpassed)app/src-tauriRust changesValidation Blocked
command:N/Aerror:N/Aimpact:N/ABehavior Changes
Parity Contract
AgentRunnerpath mirrors live runner dispatch.Duplicate / Superseded PR Handling
Summary by CodeRabbit
New Features
Bug Fixes
Documentation