agents: add engine router for multi-backend support
Add router that can switch between different agent engines embedded runner vs AI SDK. Allows runtime selection based on configuration or feature flags.
This commit is contained in:
parent
7dba076e06
commit
bfee272ac6
118
src/agents/engine-router.ts
Normal file
118
src/agents/engine-router.ts
Normal file
@ -0,0 +1,118 @@
|
||||
/**
|
||||
* LLM Engine Router for openclaw.
|
||||
*
|
||||
* This module provides a thin routing layer that dispatches agent runs
|
||||
* to either the original pi-agent engine or the new AI SDK engine
|
||||
* based on configuration.
|
||||
*
|
||||
* Fork-friendly: minimal integration point that reads config and routes.
|
||||
*/
|
||||
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import type { LlmEngineType } from "../config/types.agents.js";
|
||||
import type { RunEmbeddedPiAgentParams } from "./pi-embedded-runner/run/params.js";
|
||||
import type { EmbeddedPiRunResult } from "./pi-embedded-runner/types.js";
|
||||
|
||||
/**
|
||||
* Re-export for convenience.
|
||||
*/
|
||||
export type LlmEngine = LlmEngineType;
|
||||
|
||||
/**
|
||||
* Default engine to use when not configured.
|
||||
*/
|
||||
export const DEFAULT_ENGINE: LlmEngine = "aisdk";
|
||||
|
||||
/**
|
||||
* Get the configured LLM engine from config.
|
||||
*
|
||||
* @param config - OpenClaw configuration
|
||||
* @returns The configured engine or default
|
||||
*/
|
||||
export function getConfiguredEngine(config?: OpenClawConfig): LlmEngine {
|
||||
const engineConfig = config?.agents?.engine;
|
||||
if (engineConfig === "pi-agent" || engineConfig === "aisdk") {
|
||||
return engineConfig;
|
||||
}
|
||||
return DEFAULT_ENGINE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if AI SDK engine is available (has required API keys).
|
||||
*/
|
||||
async function isAiSdkAvailable(): Promise<boolean> {
|
||||
try {
|
||||
const { isAiSdkEngineAvailable } = await import("./aisdk/run.js");
|
||||
return isAiSdkEngineAvailable();
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the agent using the appropriate engine based on configuration.
|
||||
*
|
||||
* This is the main entry point that should be used instead of calling
|
||||
* runEmbeddedPiAgent directly. It automatically routes to the correct
|
||||
* engine based on config.
|
||||
*
|
||||
* @param params - Run parameters (same as runEmbeddedPiAgent)
|
||||
* @returns Run result
|
||||
*/
|
||||
export async function runAgent(params: RunEmbeddedPiAgentParams): Promise<EmbeddedPiRunResult> {
|
||||
const engine = getConfiguredEngine(params.config);
|
||||
|
||||
if (engine === "aisdk") {
|
||||
// Check if AI SDK is available
|
||||
const available = await isAiSdkAvailable();
|
||||
if (!available) {
|
||||
// Fall back to pi-agent if AI SDK is not configured
|
||||
console.warn(
|
||||
"[Engine Router] AI SDK engine selected but not available (missing API keys?). Falling back to pi-agent.",
|
||||
);
|
||||
return runPiAgent(params);
|
||||
}
|
||||
|
||||
return runAiSdk(params);
|
||||
}
|
||||
|
||||
return runPiAgent(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run using pi-agent engine.
|
||||
*/
|
||||
async function runPiAgent(params: RunEmbeddedPiAgentParams): Promise<EmbeddedPiRunResult> {
|
||||
const { runEmbeddedPiAgent } = await import("./pi-embedded-runner/run.js");
|
||||
return runEmbeddedPiAgent(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Run using AI SDK engine.
|
||||
*/
|
||||
async function runAiSdk(params: RunEmbeddedPiAgentParams): Promise<EmbeddedPiRunResult> {
|
||||
const { runAiSdkAgent } = await import("./aisdk/run.js");
|
||||
|
||||
// Map provider/model to AI SDK model reference
|
||||
const provider = params.provider ?? "anthropic";
|
||||
const model = params.model ?? "claude-sonnet-4";
|
||||
|
||||
return runAiSdkAgent(params, {
|
||||
modelRef: `${provider}/${model}`,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get information about the current engine configuration.
|
||||
*/
|
||||
export function getEngineInfo(config?: OpenClawConfig): {
|
||||
current: LlmEngine;
|
||||
default: LlmEngine;
|
||||
configPath: string;
|
||||
} {
|
||||
return {
|
||||
current: getConfiguredEngine(config),
|
||||
default: DEFAULT_ENGINE,
|
||||
configPath: "agents.engine",
|
||||
};
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user