Skip to content

Inject automation tool for closed-loop development in FlowFuse Expert #427

Closed
7 of 7 issues completed
Closed

Description

@Steve-Mcl

Description

Explore adding an inject automation capability for closed-loop development within FlowFuse Expert. This would allow the agent to push a test message directly into any deployed node with an input (e.g., simulating an MCP-tool request) without needing to add inject nodes and deploy first, then read the debug output back to verify its work.

Additionally, consider including a tool to retrieve node status.

Key Considerations / Discussion Points

  • Security & Feasibility: Evaluate whether this capability meaningfully improves AI utility versus introducing security risks.
  • Enablement: A well-defined enablement option should be considered (potentially linked to the deployment toggle).
  • Next Steps: Worth a go / evaluate as a spike.

Epic/Story

No response

Activity

  1. added
    taskA piece of work that isn't necessarily tied to a specific Epic or Story.
    on Oct 15, 2026
  2. added this to the 3.2 milestone on Oct 15, 2026
  3. self-assigned this
    on Oct 19, 2026
  4. Steve-Mcl commented on Oct 19, 2026

    @Steve-Mcl
    ContributorAuthor

    Spike: Inject automation for closed-loop development in FlowFuse Expert (nr-assistant#427)

    Goal
    Find out whether the agent can push a test message into any deployed node with an input, then read the result back from the debug sidebar. That would remove the "add inject node → deploy → ask the user to click" step. Identify the components to touch and break the work into estimated tasks.

    Outcome: feasible. A working prototype is on nr-assistant branch feat/427-inject-automation and was verified end to end on a local instance:

    • MCP tool → editor automation → runtime → deployed flow → debug output.
    • With AI Flow Deploy turned off, the inject was refused.
    • A node with undeployed changes was refused, as were nodes with no input port.

    How it works

    • Node-RED's runtime already has Node.prototype.receive(msg). It emits input exactly as if a wire delivered the message.
    • The RED API given to plugins exposes nodes.getNode, util.generateId and log.audit, so nr-assistant can do this without touching core.
    • Editor action automation/inject-message { id, msg }: refuses unknown nodes, nodes with no input port (inject, link in, config), disabled nodes and tabs, nodes inside subflow definitions, and nodes with undeployed changes. The runtime would otherwise use its stale copy.
    • Runtime route POST /nr-assistant/inject: this is the enforcement point.
      • It requires write permission.
      • It re-checks the team's AI Flow Deploy policy against forge on every call, uncached and failing closed.
      • It calls receive() with a fresh _msgid, writes an nr-assistant.inject audit event, and returns msgid so the agent can match its own message in the debug output.

    Security and enablement decisions

    • Enablement: reuses the team "AI Flow Deploy" setting, the same opt-in that already lets the agent change running flows. No new setting.
    • Server-side enforcement: the editor checks are for helpful errors only, so bypassing the browser gains nothing.
    • Tool class: the MCP tool is destructiveHint: true and openWorldHint: true, because downstream nodes act for real. This needs destructive permission at MCP connect.
    • Audit: every inject is audit-logged against the user.

    Findings from the prototype

    1. Audit log: the inject entries show "We have no details available for event type 'nr-assistant.inject'", and carry no AI sparkle.
    2. Result-code wording: the platform maps result codes to agent-facing text. Reusing AUTO_DEPLOY_DISABLED produced "flow changes were saved but not deployed", which is wrong for an inject. So inject needs its own code, INJECT_NOT_ALLOWED.
    3. The code-to-message map is duplicated in the MCP Gateway (MQTTCOMMS on-start) and the Chatbot Support Agent. Both must be kept in sync.
    4. The skills currently tell the agent "you cannot click an inject yourself". They should prefer the new tool when it's available.

    Areas touched

    ┌────────────────────────────────────────────────┬───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
    │                   Component                    │                                                                   Files / location                                                                    │
    ├────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ nr-assistant                                   │ resources/expertAutomations.js, lib/assistant.js, tests                                                                                               │
    ├────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ forge: audit attribution                       │ forge/routes/logging/index.js (agentAttributableEvents, shared by the instance and device paths)                                                      │
    ├────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ forge: audit display                           │ forge/auditLog/formatters.js, frontend/src/data/audit-events.json, frontend/src/components/audit-log/AuditEntryVerbose.vue, AuditEntryIcon.vue        │
    ├────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ MCP Gateway (flowfuse-expert-flow-gen-mcp-dev) │ Flow Builder MCP tab (new mcp-tool + function); MQTTCOMMS on-start (AGENT_ATTRIBUTABLE_ACTIONS, AUTOMATION_RESULT_MESSAGES, AGENT_ACTION_NO_OP_CODES) │
    ├────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ Chatbot (Support Agent)                        │ AUTOMATION_RESULT_MESSAGES, AGENT_ACTION_NO_OP_CODES                                                                                                  │
    ├────────────────────────────────────────────────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤
    │ Skills                                         │ flow-editing-workflow, mcp-tool-verification, verifying-debug-output                                                                                  │
    └────────────────────────────────────────────────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
    

    Open questions

    • Do we need a rate limit or a maximum msg size beyond Node-RED's apiMaxLength?
    • Remote instances (device agent) haven't been tested. The forge device audit path shares agentAttributableEvents, so attribution should carry over, but needs checking.
    • Node-status tool (also suggested in the issue): this would be a separate follow-up.

    I will generate sub tasks to cover the work

  5. moved this from Todo to In Progress in 🛠 Developmenton Oct 20, 2026
  6. moved this from In Progress to Done in 🛠 Developmenton Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

taskA piece of work that isn't necessarily tied to a specific Epic or Story.

Type

No type

Projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions