feat(backends): multi-backend intelligence layer — LLM + Agent backends, persona-loading agents, honest CLI commands
Add IntelligenceBackend abstraction with two categories: - LLMBackend (OllamaLocal, OllamaCloud): CI runs tool loop, provides tools, constructs prompts - AgentBackend (Opencode): agent runs own tool loop, CI serializes request Refactor all 18 agents from hardcoded stubs to persona loaders that delegate to the active backend or fail honestly when no backend is available. Refactor OrchestratorAgent.executeStage() from monolithic switch to agent delegation via STAGE_AGENT_MAP for intelligent stages (research, plan, execute, verify), with mechanical stages (specify, clarify, complete) staying inline. Wire CLI commands with --backend flag and auto-detection (opencode → ollama-local → ollama-cloud). Harden rollback/ship with real git operations. No command returns fake success.
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
import { IntelligenceBackend, BackendConfigSection, BackendUnavailableError } from "./types.js";
|
||||
import { OpencodeBackend } from "./opencode.js";
|
||||
import { OllamaLocalBackend } from "./ollama-local.js";
|
||||
import { OllamaCloudBackend } from "./ollama-cloud.js";
|
||||
|
||||
const AUTO_DETECT_ORDER: Array<"opencode" | "ollama-local" | "ollama-cloud"> = [
|
||||
"opencode",
|
||||
"ollama-local",
|
||||
"ollama-cloud",
|
||||
];
|
||||
|
||||
export function createBackend(
|
||||
name: string,
|
||||
config: BackendConfigSection
|
||||
): IntelligenceBackend {
|
||||
switch (name) {
|
||||
case "opencode":
|
||||
return new OpencodeBackend(config.agent_backends.opencode);
|
||||
case "ollama-local":
|
||||
return new OllamaLocalBackend(config.llm_backends["ollama-local"]);
|
||||
case "ollama-cloud":
|
||||
return new OllamaCloudBackend(config.llm_backends["ollama-cloud"]);
|
||||
default:
|
||||
throw new BackendUnavailableError(name);
|
||||
}
|
||||
}
|
||||
|
||||
export async function resolveBackend(
|
||||
config: BackendConfigSection
|
||||
): Promise<IntelligenceBackend> {
|
||||
if (config.provider !== "auto") {
|
||||
const backend = createBackend(config.provider, config);
|
||||
if (!(await backend.isAvailable())) {
|
||||
throw new BackendUnavailableError(config.provider);
|
||||
}
|
||||
return backend;
|
||||
}
|
||||
|
||||
for (const name of AUTO_DETECT_ORDER) {
|
||||
try {
|
||||
const backend = createBackend(name, config);
|
||||
if (await backend.isAvailable()) {
|
||||
return backend;
|
||||
}
|
||||
} catch {}
|
||||
}
|
||||
|
||||
throw new BackendUnavailableError("auto");
|
||||
}
|
||||
|
||||
export { IntelligenceBackend, BackendConfigSection, BackendUnavailableError } from "./types.js";
|
||||
export { ToolRegistry, ToolDefinition, ToolCall, ToolResult } from "./tool-registry.js";
|
||||
export { OpencodeBackend } from "./opencode.js";
|
||||
export { OllamaLocalBackend } from "./ollama-local.js";
|
||||
export { OllamaCloudBackend } from "./ollama-cloud.js";
|
||||
Reference in New Issue
Block a user