Skip to content

plugin-flow-builder: split, rename and reorganize files and functions#3191

Merged
Iru89 merged 4 commits intoBLT-2254-plugin-flow-builder-allow-go-to-flow-to-aia-gent-as-a-follow-upfrom
refactor-split-and-rename-files
Mar 30, 2026
Merged

plugin-flow-builder: split, rename and reorganize files and functions#3191
Iru89 merged 4 commits intoBLT-2254-plugin-flow-builder-allow-go-to-flow-to-aia-gent-as-a-follow-upfrom
refactor-split-and-rename-files

Conversation

@Iru89
Copy link
Copy Markdown
Contributor

@Iru89 Iru89 commented Mar 25, 2026

Description

Pure structural refactor of botonic-plugin-flow-builder across two commits: splits, renames, and relocates files and functions to reduce coupling, improve module boundaries, and align the internal API around BotContext instead of ActionRequest. No logic changes — only file organisation, import updates, and signature alignments.

Context

action/index.tsx was doing too much: it defined FlowBuilderContext, the getContext factory, filterContents, and the full getContents routing logic, all alongside the React component. This forced all action modules (fallback.ts, knowledge-bases.ts, payload.ts, etc.) to import shared types from the entry-point file, creating unnecessary coupling.

Additionally, getContents and the post-processing pipeline (filter → track → resolveAIAgent → handoff/botAction) were inlined inside botonicInit and executeConversationStart, making them harder to reuse and test independently.

Finally, structured-output/flow-builder-content.ts was buried inside action/ai-agent/, making it hard to discover and reuse from other modules.

Approach taken / Explain the design

Files moved / renamed

Before After
action/ai-agent/index.ts action/ai-agent-from-user-input.ts
action/ai-agent/structured-output/flow-builder-content.ts structured-output/flow-builder-content.ts

New file: action/context.ts

Extracted from action/index.tsx. Contains the FlowBuilderContext interface and the getFlowBuilderActionContext factory (formerly getContext). All action modules now import FlowBuilderContext from ./context instead of ./index.

filterContents moved to filters/index.ts

Extracted from action/index.tsx and added to filters/index.ts, next to ContentFilterExecutor where it logically belongs.

Rename: getContentsByAiAgentgetContentsByAiAgentFromUserInput

Clarifies that this function only handles the user-input routing path, not all AI agent invocations.

Import updates

fallback.ts, first-interaction.ts, knowledge-bases.ts, payload.ts, flow-ai-agent.tsx, and types.ts updated to point to the new locations.

New file: action/get-contents.ts

The getContents routing function (first interaction → payload → AI agent → knowledge base → fallback) was extracted from action/index.tsx into its own file. Its signature now receives BotContext instead of ActionRequest:

export async function getContents(
  botContext: BotContext,
  contentID?: string
): Promise<FlowContent[]>

New static method: FlowBuilderAction.processContents

The repeated post-processing pipeline that appeared in both botonicInit and executeConversationStart is now a single reusable method:

static async processContents(
  botContext: BotContext,
  contents: FlowContent[]
): Promise<FlowContent[]> {
  const filteredContents = await filterContents(botContext, contents)
  await FlowBuilderAction.trackAllContents(botContext, filteredContents)
  await FlowBuilderAction.resolveFlowAIAgentMessages(botContext, filteredContents)
  await FlowBuilderAction.doHandoffAndBotActions(botContext, filteredContents)
  return filteredContents
}

ActionRequestBotContext in static methods

executeConversationStart, botonicInit, trackAllContents, and doHandoffAndBotActions now all receive BotContext instead of ActionRequest. This removes the dependency on the React-layer type from the core action logic and makes the functions usable in non-React contexts.

Cleanup in action/index.tsx

Removed now-unused imports: INPUT, EMPTY_PAYLOAD, inputHasTextOrTranscript, getContentsByAiAgentFromUserInput, getContentsByFallback, getContentsByKnowledgeBase, getContentsByPayload.

Testing

The pull request...

  • doesn't need tests because it is a pure file reorganisation with no logic changes (all existing tests continue to pass)

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@Iru89 Iru89 self-assigned this Mar 25, 2026
@Iru89 Iru89 requested review from asastre and vanbasten17 March 25, 2026 17:15
…nt-as-a-follow-up' into refactor-split-and-rename-files
@Iru89 Iru89 changed the title refactor: split rename and reorganize files and functions plugin-flow-builder: split, rename and reorganize files and functions Mar 27, 2026
…do handoff, do actions and resolve AI Agent response (#3193)

## Description

Introduces a unified `processContent()` abstract method in the
`ContentFieldsBase` class so that every content type handles its own
side effects (handoff, bot action, AI agent response). Alongside this,
the AI Agent node is now resolved as a follow-up within any content
sequence, and it receives preceding contents as context for better
conversation continuity.

## Context

Previously, side effects such as triggering a handoff, redirecting via a
bot action, or calling the AI Agent inference API were scattered across
`FlowBuilderAction.botonicInit()` and helper functions in
`action/index.tsx`. This made the flow of execution hard to follow and
difficult to extend.

Additionally, AI Agent nodes could only be triggered as a top-level flow
entry point, preventing them from being combined with other content
nodes (e.g., a text message before the agent response). The agent also
lacked awareness of previously sent messages in the same interaction.

Goals:
- Decouple "which contents to show" from "what side effects each content
triggers".
- Enable AI Agent nodes to be positioned anywhere in a content sequence
(as follow-ups).
- Pass preceding contents as conversation context to the AI Agent.
- Improve code organisation and testability by splitting large files
into focused modules.

## Approach taken / Explain the design

### 1. Abstract `processContent()` in `ContentFieldsBase`

```typescript
abstract processContent(botContext: BotContext): Promise<void>
```

Each subclass now owns its side effects:

| Content class | `processContent` behavior |
|---|---|
| `FlowHandoff` | Calls `doHandoff()` |
| `FlowBotAction` | Calls `doBotAction()` + `trackFlow()` |
| `FlowAiAgent` | Calls `resolveAIAgentResponse()` |
| Others (text, image, …) | Calls `trackFlow()` |

`FlowBuilderAction.prepareContentsToRender()` now iterates filtered
contents and calls `content.processContent()` uniformly:

```typescript
for (const content of filteredContents) {
  if (content instanceof FlowAiAgent) {
    await content.processContent(botContext, contentsBeforeAiAgent)
  } else {
    await content.processContent(botContext)
  }
}
```

### 2. AI Agent resolved as a follow-up

`FlowAiAgent` nodes can now appear anywhere in a content sequence. The
`splitAiAgentContents()` helper separates the preceding contents from
the agent node so they can be forwarded as context:

```typescript
export function splitAiAgentContents(contents: FlowContent[]) {
  const aiAgentIndex = contents.findIndex(c => c instanceof FlowAiAgent)
  const aiAgentContent = contents[aiAgentIndex] as FlowAiAgent
  const contentsBeforeAiAgent = contents.slice(0, aiAgentIndex)
  return { aiAgentContent, contentsBeforeAiAgent }
}
```

### 3. Previous contents forwarded as `previousHubtypeMessages`

When calling the inference API, the contents rendered before the agent
node are mapped to `HubtypeAssistantMessage` objects and sent as
`previousHubtypeMessages`, giving the AI Agent awareness of what was
already shown to the user in the same turn.

### 4. File reorganisation

The monolithic `action/index.tsx` and `action/ai-agent.ts` were split
into focused modules:

| New file | Responsibility |
|---|---|
| `action/context.ts` | `FlowBuilderContext` interface + factory
function |
| `action/get-contents.ts` | `getContents()` — routing logic to select
which flow contents to load |
| `action/ai-agent-from-user-input.ts` |
`getContentsByAiAgentFromUserInput()` + `splitAiAgentContents()` |
| `filters/index.ts` | `ContentFilterExecutor` + `filterContents()` |

`FlowAiAgent` now owns tracking (`trackAiAgentResponse`) and response
resolution (`resolveAIAgentResponse`, `getAIAgentResponse`,
`messagesToBotonicJSXElements`), removing the need for standalone
helpers in the action layer.

### 5. Removal of unused Go-To-Flow → AI Agent redirect code

Dead code paths that redirected Go-To-Flow nodes to the AI Agents flow
were removed from `FlowGoToFlow`, `FlowBuilderApi`, and
`BotonicPluginFlowBuilder`.

## To document / Usage example

No public API changes. The `processContent()` method is internal to the
plugin and does not need to be called by end users.

If you implement a custom `ContentFilter`, note that `processContent()`
is now called **after** filtering in `prepareContentsToRender()`.
Filters should remain pure transformations and must not trigger side
effects.
@Iru89 Iru89 merged commit 8ec9aa3 into BLT-2254-plugin-flow-builder-allow-go-to-flow-to-aia-gent-as-a-follow-up Mar 30, 2026
4 checks passed
@Iru89 Iru89 deleted the refactor-split-and-rename-files branch March 30, 2026 10:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants