Skip to content

feat: Add deploy policy endpoint and deploy flows action - #406

Merged
andypalmi merged 9 commits into
mainfrom
405-agent-flow-deploy
Sep 18, 2026
Merged

andypalmi merged 9 commits into
mainfrom
405-agent-flow-deploy

Conversation

@Steve-Mcl

Copy link
Copy Markdown
Contributor

Description

Summary

Adds a deploy_flows automation action so an agent can deploy the flow changes it just made, instead of leaving them staged. It checks the team's agentAutoDeploy setting live, at the moment of the deploy attempt, and no-ops safely (with a clear message) rather than deploying when the setting is off.

Changes

  • lib/assistant.js: new GET /nr-assistant/deploy-policy route and handleGetDeployPolicyRequest handler. Relays the live check to forge's /api/v1/assistant/deploy-policy using the existing got/token pattern, and fails safe to autoDeploy: false on any error.
  • resources/expertAutomations.js: new DEPLOY_FLOWS (automation/deploy-flows) action, following the same shape as SET_DEPLOY_MODE. Its dispatch case calls the new local proxy route, then either invokes core:deploy-flows or returns deployed: false with a message that explicitly tells the model to call ui_navigate (route team-settings-danger) rather than just describing the setting in prose.
  • test/unit/resources/expertAutomations.test.js: add automation/deploy-flows to the supportedActions key-list test.

Testing

Tested end to end against a live instance with the setting both on and off, and over both the embedded Expert chat and a third-party MCP client (Claude). Unit test updated for the new action's presence; the action's actual dispatch behavior isn't independently unit-tested here, matching the existing coverage level for SET_DEPLOY_MODE and its siblings.

Notes

The corresponding forge-side setting and policy endpoint, and the deploy_flows MCP tool that exposes this action to a model need to ship alongside this in flowfuse and a separate Flow Builder MCP tool surface respectively. This PR is the nr-assistant half: the local policy proxy and the actual deploy action.

Can/should be merged (and released) before FlowFuse PR is merged

Related Issue(s)

closes #405

Checklist

  • I have read the contribution guidelines
  • Suitable unit/system level tests have been added and they pass
  • Documentation has been updated
    • Upgrade instructions
    • Configuration details
    • Concepts
  • Changes flowforge.yml?
    • Issue/PR raised on FlowFuse/helm to update ConfigMap Template
    • Issue/PR raised on FlowFuse/CloudProject to update values for Staging/Production
  • Link to Changelog Entry PR, or note why one is not needed.

Labels

  • Includes a DB migration? -> add the area:migration label

@Steve-Mcl
Steve-Mcl requested a review from andypalmi September 17, 2026 13:41
andypalmi
andypalmi previously approved these changes Sep 17, 2026

@andypalmi andypalmi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Looks good to me, I only have a question but otherwise we can merge it

Comment thread lib/assistant.js Outdated
*/
async handleGetDeployPolicyRequest (req, res) {
if (!this.isInitialized || this.isLoading) {
return res.status(503).send('Expert is not ready')

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why expert? Should we say assistant?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Or nr-assistant

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

addressed in 8a5f1f5

@andypalmi

Copy link
Copy Markdown
Contributor

One finding from testing: core:deploy-flows maps to the editor's save(), which returns before the POST /flows resolves, so the action reports deployed: true even when the deploy later fails (for example a 409 conflict). When there are unknown or invalid nodes, save() shows the confirmation dialog and deploys nothing, and the response still says deployed: true. The action should wait on the actual deploy outcome before responding, for example resolving on the runtime deploy notification with a timeout, and report the dialog path as deployed: false.

@andypalmi
andypalmi dismissed their stale review September 17, 2026 15:21

see latest comment

@Steve-Mcl

Copy link
Copy Markdown
Contributor Author

One finding from testing: core:deploy-flows maps to the editor's save(), which returns before the POST /flows resolves, so the action reports deployed: true even when the deploy later fails (for example a 409 conflict). When there are unknown or invalid nodes, save() shows the confirmation dialog and deploys nothing, and the response still says deployed: true. The action should wait on the actual deploy outcome before responding, for example resolving on the runtime deploy notification with a timeout, and report the dialog path as deployed: false.

Addressed in bbe95d0 (with tests))

@Steve-Mcl

Copy link
Copy Markdown
Contributor Author

@andypalmi would appreciate a pull and retest please

@Steve-Mcl
Steve-Mcl requested a review from andypalmi September 17, 2026 16:05
@andypalmi

Copy link
Copy Markdown
Contributor

Pulled and re-reviewed bbe95d0. The wait-on-deploy approach is right and I verified it against deploy.js: RED.events.emit("deploy") fires only inside the POST success handler, both the confirmation-dialog path and the 409 conflict path return without emitting, and invokeActionAndWait attaches the listener before invoking and cleans it up on resolve, timeout, and throw. The four new tests pass locally.

One edge remains: save() returns immediately when the Deploy button is disabled, and the button is disabled whenever the workspace has no undeployed changes (workspace:dirty handler in deploy.js). So calling the action on a clean workspace burns the full 15s and answers deployed: false with the "server rejected it or a dialog is blocking" message, which misleads the agent when everything is in fact already live. A pre-check on this.RED.nodes.dirty() avoids it: when false, respond immediately with deployed: true and a message like "there were no undeployed changes, the flows are already live", so the agent does not relay a failure for a no-op.

@Steve-Mcl

Copy link
Copy Markdown
Contributor Author

@andypalmi should be covered now (see 483d614)

@Steve-Mcl

Copy link
Copy Markdown
Contributor Author

@andypalmi reduced timeout to 8s as discussed

@andypalmi

andypalmi commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

Follow-up on the 15s wait: the transports dispatching these actions give up sooner, so the graceful timeout response cannot reach the agent.

  • FlowFuse's invokeActionAwaitResponse defaults to 5s (frontend/src/stores/product-assistant.js:628) and the automation:* dispatch does not pass a longer value; the MCP transport above it caps at 10s. A fast successful deploy is fine, but every path that reaches DEPLOY_WAIT_TIMEOUT_MS (open dialog, 409 conflict, nothing to deploy) hits the 5s bridge timeout first and the agent receives a generic timeout instead of deployed: false and the guidance message.
  • For this PR: cap the wait at 4s so the response fits today's tightest budget on every platform. With the RED.nodes.dirty() pre-check the nothing-to-deploy case is answered up front; a genuinely slow deploy then reports deployed: false while it may still complete, which the message text can acknowledge.
  • Platform-side follow-up: raise the deploy dispatch timeout in the browser to 10s (per-action, in the automation:* dispatch) and the MCP gateway transport timeout to 15s, keeping the layers nested. Once those are released the wait here can go to 8-9s, since this plugin cannot assume the platform's budgets at install time.

@andypalmi andypalmi left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Drop timeout from 8 to 4 like in above comment (and not 8 as said in huddle unfortunately) and I'm okay with the changes

@Steve-Mcl

Copy link
Copy Markdown
Contributor Author

sometime deploy (especially on large flows / full deploy and especially where nodes either misbehave or teardown/rebuild external connections) can easily take more than 4 sec :(

Will need to think this over.

@andypalmi

Copy link
Copy Markdown
Contributor

We could increase browser timeout to 10 seconds in flowfuse and also increase it to 15 in gateway

@andypalmi

andypalmi commented Sep 17, 2026 •

Copy link
Copy Markdown
Contributor

On second thought: instead of setting error the error message and the guidance for the agent, can we return a error code and handle the message returned in the MCP tool based on the error? This gives us deploy logic in nr-assistant with the flexibility of changing the error message regardless of the installed version if we ever change tool names or flag location in the UI

@Steve-Mcl

@Steve-Mcl

Copy link
Copy Markdown
Contributor Author

On second thought: instead of setting error the error message and the guidance for the agent, can we return a error code and handle the message returned in the MCP tool based on the error? This gives us deploy logic in nr-assistant with the flexibility of changing the error message regardless of the installed version if we ever change tool names or flag location in the UI

@Steve-Mcl

Can you give me some detail of what you would expect here - same me time inventing something you were not intending? Ta son ;)

@andypalmi andypalmi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Approved

@andypalmi
andypalmi merged commit 7cd6f08 into main Sep 18, 2026
6 checks passed
@andypalmi
andypalmi deleted the 405-agent-flow-deploy branch September 18, 2026 10:26
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.

Add deploy_flows action

2 participants