feat: wire OpenCode as selectable agent backend via AGENT_BACKEND env var
Some checks failed
Update token count / update-tokens (push) Has been cancelled

- Add AGENT_BACKEND config ('container' default, 'opencode' to use OpenCode runtime)
- Wire OpenCodeRuntime into runAgent() with fallback to container runner
- Skip container system check when using OpenCode backend
- Update README and CLAUDE.md with AGENT_BACKEND docs
This commit is contained in:
2026-02-19 08:43:36 -05:00
parent 572ccdbd3b
commit 6c1c908fce

View File

@@ -327,7 +327,36 @@ async function runAgent(
// --- OpenCode backend ---
if (opencode) {
try {
const response = await opencode.chat(prompt, chatJid);
// Read per-group CLAUDE.md as system prompt (same as container backend)
const groupDir = path.join(DATA_DIR, '..', 'groups', group.folder);
const parts: string[] = [];
// Load CLAUDE.md
const claudeMdPath = path.join(groupDir, 'CLAUDE.md');
try {
parts.push(fs.readFileSync(claudeMdPath, 'utf-8'));
logger.debug({ group: group.name, path: claudeMdPath }, 'Loaded CLAUDE.md as system prompt');
} catch {
// No CLAUDE.md for this group
}
// Load skills from container/skills/ (same skills the container backend gets)
const skillsSrc = path.join(process.cwd(), 'container', 'skills');
if (fs.existsSync(skillsSrc)) {
for (const skillDir of fs.readdirSync(skillsSrc)) {
const srcDir = path.join(skillsSrc, skillDir);
if (!fs.statSync(srcDir).isDirectory()) continue;
const skillMd = path.join(srcDir, 'SKILL.md');
if (fs.existsSync(skillMd)) {
parts.push(fs.readFileSync(skillMd, 'utf-8'));
logger.debug({ group: group.name, skill: skillDir }, 'Loaded skill');
}
}
}
const systemPrompt = parts.length > 0 ? parts.join('\n\n---\n\n') : undefined;
const response = await opencode.chat(prompt, chatJid, systemPrompt);
if (response.error) {
logger.error({ group: group.name, error: response.error }, 'OpenCode agent error');
if (onOutput) {