Skip to main content
Glama
opinionStrategy.ts3.04 kB
/** * Expert opinion debate strategy * * This strategy handles the debate process for expert opinions. */ import { ToolType } from "../types/public"; import { DebateContext, DebatePhase, DebateStrategy } from "./strategyTypes"; import { loadPrompt, escapeUserInput } from "../prompts/promptFactory"; import { registerStrategy } from "./registry"; /** * Strategy for expert opinion debates */ class OpinionStrategy implements DebateStrategy { readonly toolType = ToolType.Opinion; /** * Default configuration for opinion debates */ readonly configDefaults = { rounds: 1, logLevel: "info" as const, }; /** * Generate a prompt for the specified debate phase */ getPrompt(phase: DebatePhase, ctx: DebateContext): string { const template = loadPrompt(this.toolType, phase); // Replace placeholders based on the phase switch (phase) { case "generate": return template .replace(/\${modelId}/g, String(ctx.round)) .replace(/\${userPrompt}/g, escapeUserInput(ctx.userPrompt)); case "critique": const opinionEntries = ctx.candidates .map((opinion, idx) => `## OPINION ${idx + 1}\n${opinion.trim()}`) .join("\n\n"); return template .replace(/\${modelId}/g, String(ctx.round)) .replace(/\${planEntries}/g, opinionEntries); case "judge": const judgeOpinionEntries = ctx.candidates .map((opinion, idx) => `## OPINION ${idx + 1}\n${opinion.trim()}`) .join("\n\n"); return template.replace(/\${planEntries}/g, judgeOpinionEntries); default: throw new Error(`Unknown debate phase: ${phase}`); } } /** * Parse the judge's decision to determine the winning opinion */ parseJudge( raw: string, candidates: string[], ): { success: true; winnerIdx: number } | { success: false; error: string } { // check if there was only one candidate if (candidates.length === 1) { return { success: true, winnerIdx: 0 }; } // Try to find explicit winner marker (e.g., [[WINNER: #]]) const winnerMatch = raw.match(/\[\[WINNER:\s*(\d+)\]\]/i); if (winnerMatch && winnerMatch[1]) { const winnerIdx = parseInt(winnerMatch[1], 10) - 1; // Convert to 0-based if (winnerIdx >= 0 && winnerIdx < candidates.length) { return { success: true, winnerIdx }; } } // For opinions, we don't allow synthesis - look for references to specific candidates for (let i = 0; i < candidates.length; i++) { const candidateNumber = i + 1; if (raw.toLowerCase().includes(`opinion ${candidateNumber}`)) { return { success: true, winnerIdx: i }; } } // If we can't determine a winner, default to the first candidate return { success: true, winnerIdx: 0, }; } } // Create and export the singleton instance export const opinionStrategy = new OpinionStrategy(); // Register this strategy with the registry registerStrategy(opinionStrategy);

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/jalehman/mcp-sage'

If you have feedback or need assistance with the MCP directory API, please join our Discord server