ビルドパイプライン
プロジェクトを ColdBox アプリケーションへと変換する、固定されたフェーズの並び。
ビルドパイプライン
bxAgents build は固定されたフェーズの並びを一度だけ実行し、ただの ColdBox アプリケーションを生成します。ここで行われることはリクエスト時には二度と実行されません - それがビルド時組み立ての意義そのものです。このページでは BuildPipeline.bx が各フェーズを実行する順序どおりに解説します。
flowchart TD
A["1 · Resolve config<br/><small>AgentConfigResolver</small>"] --> B["2 · Discover<br/><small>ProjectDiscoverer</small>"]
B --> C{"3 · Validate<br/><small>ProjectValidator</small>"}
C -->|"any error"| X["Build throws.<br/>.build/app is never written or touched"]
C -->|"clean<br/><small>warnings never block</small>"| D["4 · Generate"]
D --> D1["1 Interceptors"] --> D2["2 Gateways"] --> D3["3 MCP"] --> D4["4 Router"]
D4 --> D5["5 Web UI"] --> D6["6 Core app skeleton"] --> D7["7 Tools/skills copy"] --> D8["8 Scheduler"]
D8 --> E["5 · Normalize + write<br/><small>ManifestNormalizer</small>"]
E --> F[".build/manifest.json<br/>+ .build/app - a plain ColdBox application"]
style C fill:#fff3cd,stroke:#856404
style X fill:#f8d7da,stroke:#721c24
style F fill:#d4edda,stroke:#155724
検証はゲートです。フェイルファストせずすべてのエラーを収集し、クリーンな結果が返るまでは何も生成されません。
(.bxa へのパッケージングは意図的に分離されたステップです - デプロイとシークレット 参照 - そのため、高速な build → 確認 → 再度 build というループが、不要なパッケージングのコストを一切払わずに済みます。)
1. config の解決
AgentConfigResolver が Agent.bx を読み込み、configure() とアクティブな環境のオーバーライドメソッドを呼び出したうえで、存在すれば boxlang.json/boxlang-{env}.json/miniserver.json/miniserver-{env}.json を深いマージで取り込みます。これにより、以降のすべてのフェーズが参照する、単一の解決済み config 構造体が生成されます。
2. 発見 (Discover)
ProjectDiscoverer がプロジェクトルートを走査し、すべてのコンベンションフォルダ (models/、tools/、skills/、subagents/、gateways/、mcp/、interceptors/、modules/) を生の { name, path, type } エントリとして列挙します。schedules/ だけは例外で、エントリの一覧ではなく単一の hasScheduler/schedulerPath のペアです。これは、BX Agents が定義する config エントリの集合ではなく、実際の ColdBox スケジューラファイルを 1 つ保持するだけだからです。この段階では純粋な発見のみで、ファイル内容の解釈はまだ行われません。
3. 検証 (Validate)
ProjectValidator はすべてのバリデータを実行し、(フェイルファストせずに) すべてのエラーと警告を収集します。重複したツール/スキル/モデル/サブエージェント名、サブエージェントツリー全体にわたるエージェント name の重複 (see subagents/)、循環したサブエージェント/モジュール参照、2 種類のゲートウェイエントリ形状、リモート MCP config の完全性、モデル/プロバイダーの妥当性などです。エラーが 1 つでも収集された場合、ビルドはここで即座に例外を投げます - .build/app は一切書き込まれず、触れられもしません。警告 (例えば Scheduler.bx を持たない schedules/ フォルダ) はビルドをブロックしません。
4. 生成 (Generate)
検証がクリーンな場合にのみ到達します。順序は以下の通りです。
- インターセプター -
InterceptorSplitterがagentスコープのインターセプターを.build/app/interceptorsにコピーし、runtimeスコープのものは別の.build/runtime-interceptorsディレクトリにコピーします。 - ゲートウェイ -
GatewayGeneratorがチャネルアダプタエントリ向けにaiGatewayRegistry().register(...)文を出力し、(いずれかがtype: "http"であれば).build/app/handlers/Gateway.bxを書き込みます。エントリのいずれかが push 型ゲートウェイ (例えばtype: "telegram") であれば、.build/app/interceptors/GatewaySessionBootstrap.bxも書き込み、(すべての push 型ゲートウェイをまとめた) 単一の bx-aiGatewaySessionをプロジェクトのルートエージェントに配線します。 - MCP -
McpGeneratorがローカルのmcp/*サーバーを.build/app/mcpにコピーし、そのmcpServer(...).registerTool(...)の登録文を出力します。 - ルーター -
RouterGeneratorが.build/app/config/Router.bxを書き込みます。公開エントリごとに 1 つのroute(path).toAi(...)/toMCP(...)、加えてhttpタイプのチャネルゲートウェイが存在する場合は 3 つの固定ゲートウェイ Webhook ルートも書き込みます。 - Web UI -
WebUiGeneratorがexposes: "webui"エントリごとに実行され、静的な<path>/index.html、handlers/ChatUi.bx(20 個のアクションを持つ API)、models/ChatDb.bx(SQLite ストアとその前方向専用マイグレーション)、interceptors/WebUiSchema.bx(どのリクエストが最初にデータベースへ触れるかに関わらず、起動時にマイグレーションを行う)、そしてapiKeyEnvVarが設定されている場合に限りinterceptors/WebUiAuthGate.bxを書き込みます。これは解決済みのデータベース config を返し、次のステップがそれを必要とします。 - コアアプリスケルトン -
ColdBoxAppGeneratorがApplication.bx、config/ColdBox.bx、config/WireBox.bx、agent/GeneratedAgentFactory.bx、index.bxmを書き込み、これまでに集められたすべての文 (ゲートウェイ登録、MCP 登録、そしてtools/にファイルが 1 つでもあればシンプルなaiToolRegistry().scan("tools")呼び出し) をApplication.bxのonApplicationStart()に、そして (生成されていれば) フェーズ 1 のGatewaySessionBootstrap.bxをconfig/ColdBox.bxが参照するinterceptorsリストに、それぞれ差し込みます。生成されるすべてのエージェントは今や常にチェックポインターを受け取ります (withCheckpointer(...)- プロジェクトがcheckpointerconfig を宣言しておらず、クラス自身も設定していない場合はcacheバックエンドのaiMemory()がデフォルトになります)。これがないと、cli以外のどのゲートウェイを通した human-in-the-loop 承認フローも完全に壊れてしまいます。config/WireBox.bxは、固定されたルートの"GeneratedAgent"エイリアスだけでなく、ツリー内のすべてのエージェント (ルート + すべてのサブエージェント) をそれぞれの宣言されたnameでマッピングします - see schedules/。webui公開を持つプロジェクトでは、セッション管理も有効化し、SQLite データソースを登録し (this.datasourceによりアプリのデフォルトとして命名)、onApplicationStart()でデータベースの親ディレクトリを作成し (SQLite はファイルは作成しますがそれを収めるフォルダは作成しません)、config/ColdBox.bxで qb のグラマーを固定します。 - ツール/スキルのコピー -
ToolsSkillsCopierが.build/app/toolsと.build/app/skillsを消去し、あなたのプロジェクト自身のフォルダからそのまま書き直します。 - スケジューラ -
SchedulerGeneratorが、存在すればschedules/Scheduler.bxをそのまま.build/app/config/Scheduler.bxにコピーします - 生成は行われません。あなた自身が書いた実際の ColdBox コードだからです。
5. マニフェストの正規化と書き込み
ManifestNormalizer が、発見データと解決済み config データから、正規で内容ハッシュ付きの内部マニフェストを生成し、パイプラインがそれを .build/manifest.json に書き込みます。
冪等性
変更のないプロジェクトを再ビルドすると、マニフェストのファイルごとの内容ハッシュに至るまで、バイト単位で同一の出力が生成されます - この組み立てコストをビルド時に一度だけ払い、その作業をリクエスト処理へ一切先送りしないという、この仕組み全体の意義そのものです。