Skip to content

Instantly share code, notes, and snippets.

@vapvarun
Created April 28, 2026 07:39
Show Gist options
  • Select an option

  • Save vapvarun/a58fd5b51e75ecba61885621b04aa061 to your computer and use it in GitHub Desktop.

Select an option

Save vapvarun/a58fd5b51e75ecba61885621b04aa061 to your computer and use it in GitHub Desktop.
Claude Haiku WP Dev Benchmarks (vapvarun.com)
/**
* Model routing for WordPress plugin tasks in Claude Code.
* Routes tasks to the appropriate Claude model based on task type,
* file count, and whether security judgment is required.
*
* Usage: import and call routeToModel(taskType, fileCount, requiresSecurity)
* Returns: model ID string to pass as --model flag in Claude Code
*/
const MODELS = {
haiku: "claude-haiku-4-5",
sonnet: "claude-sonnet-4-6",
opus: "claude-opus-4-7"
};
// Task types that Haiku handles at acceptable quality
const HAIKU_TASKS = new Set([
"phpdoc",
"wpcs_fix",
"changelog",
"readme_stub",
"pot_file",
"translation_strings",
"unit_test_stubs",
"simple_rest_endpoint",
"admin_page_html",
"boilerplate"
]);
// Task types that always need Sonnet minimum
const SONNET_TASKS = new Set([
"dynamic_block_scaffold",
"complex_rest_schema",
"hook_timing_debug",
"architecture_decision",
"pr_review",
"content_writing",
"multi_file_refactor"
]);
/**
* Route a plugin task to the right Claude model.
*
* @param {string} taskType - One of the task type keys above
* @param {number} fileCount - Number of files involved in the task
* @param {boolean} requiresSecurity - Whether the task involves security review
* @returns {string} Model ID
*/
function routeToModel(taskType, fileCount = 1, requiresSecurity = false) {
// Security review always gets Opus - cost is irrelevant here
if (requiresSecurity) {
return MODELS.opus;
}
// Multi-file tasks (5+ files) lose coherence on Haiku by file 5-6
if (fileCount >= 5 && !HAIKU_TASKS.has(taskType)) {
return MODELS.sonnet;
}
// Explicit Sonnet/Opus task types
if (SONNET_TASKS.has(taskType)) {
return MODELS.sonnet;
}
// Structured, low-ambiguity tasks: Haiku
if (HAIKU_TASKS.has(taskType)) {
return MODELS.haiku;
}
// Default: Sonnet for anything not explicitly classified
return MODELS.sonnet;
}
/**
* Estimate cost for a task before running it.
* Based on median token counts observed across 300 Wbcom plugin tasks.
*
* @param {string} model - Model ID
* @param {number} inputK - Estimated input tokens in thousands
* @param {number} outputK - Estimated output tokens in thousands
* @returns {number} Estimated cost in USD
*/
function estimateCost(model, inputK, outputK) {
const pricing = {
[MODELS.haiku]: { input: 0.00080, output: 0.00400 },
[MODELS.sonnet]: { input: 0.00300, output: 0.01500 },
[MODELS.opus]: { input: 0.01500, output: 0.07500 }
};
const p = pricing[model];
if (!p) throw new Error(`Unknown model: ${model}`);
return (inputK * p.input) + (outputK * p.output);
}
// Example usage
const task = "phpdoc";
const model = routeToModel(task, 1, false);
const estimatedCost = estimateCost(model, 2, 1); // 2K input, 1K output
console.log(`Task: ${task}`);
console.log(`Model: ${model}`);
console.log(`Estimated cost: $${estimatedCost.toFixed(4)}`);
// Output:
// Task: phpdoc
// Model: claude-haiku-4-5
// Estimated cost: $0.0060
module.exports = { routeToModel, estimateCost, MODELS };
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment