- BuiltInToolRegistrar: 18 tools from stub to real executors (fs.stat, process.kill, git.worktree, project.scan, cpp.*, debug.*, etc.) - ClangdClient: implement real clangd CLI query + diagnostic parsing - CapabilityRegistry: real create_capability_executor - WavePlanner: extract write areas from task metadata - DeveloperLogEncryptor: clean TODO, read() already works - Clean placeholder/TODO comments across ContextAssembler, EventStore, ToolRegistry, PermissionEngine, DoctorService Stub count: 14 → 4 (valid patterns only) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
407 lines
10 KiB
TypeScript
Executable File
407 lines
10 KiB
TypeScript
Executable File
/**
|
|
* CapabilityMatrixRegistry - Provider capability matrix lookup
|
|
*
|
|
* Implements DD §12.2.
|
|
* Holds ProviderCapabilityMatrix rows with nested supports/conversion/quality/cost tiers.
|
|
*
|
|
* @module packages/llm/src/CapabilityMatrix
|
|
*/
|
|
|
|
export interface SupportsMap {
|
|
text_input: boolean
|
|
text_output: boolean
|
|
streaming: boolean
|
|
tool_use: boolean
|
|
parallel_tool_use: boolean
|
|
structured_output: boolean
|
|
json_mode: boolean
|
|
thinking: boolean
|
|
prompt_cache: boolean
|
|
system_prompt: boolean
|
|
image_input: boolean
|
|
image_output: boolean
|
|
audio_input: boolean
|
|
audio_output: boolean
|
|
file_input: boolean
|
|
computer_use: boolean
|
|
long_context: boolean
|
|
}
|
|
|
|
export interface ConversionMap {
|
|
from_anthropic_canonical?: boolean
|
|
tool_schema?: 'native' | 'emulated' | 'none'
|
|
image_input?: 'base64' | 'url' | 'none'
|
|
thinking?: 'native' | 'emulated' | 'none'
|
|
cache_control?: 'anthropic' | 'openai' | 'none'
|
|
}
|
|
|
|
export interface ProviderCapability {
|
|
provider: string
|
|
model: string
|
|
max_tokens_output?: number
|
|
max_tokens_input?: number
|
|
supports: SupportsMap
|
|
conversion?: ConversionMap
|
|
quality_tier?: 'flagship' | 'balanced' | 'economy'
|
|
cost_tier?: 'high' | 'medium' | 'low'
|
|
}
|
|
|
|
export interface ProviderCapabilityMatrix {
|
|
provider: string
|
|
model_pattern: string
|
|
capabilities: Omit<ProviderCapability, 'provider' | 'model'>
|
|
}
|
|
|
|
// Capability matrix — loaded from provider-capability-matrix-v1.md
|
|
const CAPABILITY_MATRIX: ProviderCapabilityMatrix[] = [
|
|
{
|
|
provider: 'anthropic',
|
|
model_pattern: '^claude-opus-4-.*',
|
|
capabilities: {
|
|
max_tokens_output: 200000,
|
|
max_tokens_input: 200000,
|
|
supports: {
|
|
text_input: true,
|
|
text_output: true,
|
|
streaming: true,
|
|
tool_use: true,
|
|
parallel_tool_use: true,
|
|
structured_output: true,
|
|
json_mode: true,
|
|
thinking: true,
|
|
prompt_cache: true,
|
|
system_prompt: true,
|
|
image_input: true,
|
|
image_output: false,
|
|
audio_input: false,
|
|
audio_output: false,
|
|
file_input: true,
|
|
computer_use: true,
|
|
long_context: true
|
|
},
|
|
conversion: {
|
|
from_anthropic_canonical: true,
|
|
tool_schema: 'native',
|
|
image_input: 'base64',
|
|
thinking: 'native',
|
|
cache_control: 'anthropic'
|
|
},
|
|
quality_tier: 'flagship',
|
|
cost_tier: 'high'
|
|
}
|
|
},
|
|
{
|
|
provider: 'anthropic',
|
|
model_pattern: '^claude-sonnet-4-.*',
|
|
capabilities: {
|
|
max_tokens_output: 200000,
|
|
max_tokens_input: 200000,
|
|
supports: {
|
|
text_input: true,
|
|
text_output: true,
|
|
streaming: true,
|
|
tool_use: true,
|
|
parallel_tool_use: true,
|
|
structured_output: true,
|
|
json_mode: true,
|
|
thinking: true,
|
|
prompt_cache: true,
|
|
system_prompt: true,
|
|
image_input: true,
|
|
image_output: false,
|
|
audio_input: false,
|
|
audio_output: false,
|
|
file_input: true,
|
|
computer_use: true,
|
|
long_context: true
|
|
},
|
|
conversion: {
|
|
from_anthropic_canonical: true,
|
|
tool_schema: 'native',
|
|
image_input: 'base64',
|
|
thinking: 'native',
|
|
cache_control: 'anthropic'
|
|
},
|
|
quality_tier: 'balanced',
|
|
cost_tier: 'medium'
|
|
}
|
|
},
|
|
{
|
|
provider: 'anthropic',
|
|
model_pattern: '^claude-haiku-4-.*',
|
|
capabilities: {
|
|
max_tokens_output: 200000,
|
|
max_tokens_input: 200000,
|
|
supports: {
|
|
text_input: true,
|
|
text_output: true,
|
|
streaming: true,
|
|
tool_use: true,
|
|
parallel_tool_use: true,
|
|
structured_output: true,
|
|
json_mode: true,
|
|
thinking: false,
|
|
prompt_cache: true,
|
|
system_prompt: true,
|
|
image_input: true,
|
|
image_output: false,
|
|
audio_input: false,
|
|
audio_output: false,
|
|
file_input: true,
|
|
computer_use: false,
|
|
long_context: true
|
|
},
|
|
conversion: {
|
|
from_anthropic_canonical: true,
|
|
tool_schema: 'native',
|
|
image_input: 'base64',
|
|
thinking: 'none',
|
|
cache_control: 'anthropic'
|
|
},
|
|
quality_tier: 'economy',
|
|
cost_tier: 'low'
|
|
}
|
|
},
|
|
{
|
|
provider: 'openai',
|
|
model_pattern: '^gpt-5-.*',
|
|
capabilities: {
|
|
max_tokens_output: 128000,
|
|
max_tokens_input: 128000,
|
|
supports: {
|
|
text_input: true,
|
|
text_output: true,
|
|
streaming: true,
|
|
tool_use: true,
|
|
parallel_tool_use: true,
|
|
structured_output: true,
|
|
json_mode: true,
|
|
thinking: true,
|
|
prompt_cache: true,
|
|
system_prompt: true,
|
|
image_input: true,
|
|
image_output: false,
|
|
audio_input: true,
|
|
audio_output: true,
|
|
file_input: true,
|
|
computer_use: false,
|
|
long_context: true
|
|
},
|
|
conversion: {
|
|
from_anthropic_canonical: true,
|
|
tool_schema: 'native',
|
|
image_input: 'url',
|
|
thinking: 'native',
|
|
cache_control: 'openai'
|
|
},
|
|
quality_tier: 'flagship',
|
|
cost_tier: 'high'
|
|
}
|
|
},
|
|
{
|
|
provider: 'openai',
|
|
model_pattern: '^gpt-4[ot]-.*',
|
|
capabilities: {
|
|
max_tokens_output: 128000,
|
|
max_tokens_input: 128000,
|
|
supports: {
|
|
text_input: true,
|
|
text_output: true,
|
|
streaming: true,
|
|
tool_use: true,
|
|
parallel_tool_use: true,
|
|
structured_output: true,
|
|
json_mode: true,
|
|
thinking: false,
|
|
prompt_cache: false,
|
|
system_prompt: true,
|
|
image_input: true,
|
|
image_output: false,
|
|
audio_input: false,
|
|
audio_output: false,
|
|
file_input: true,
|
|
computer_use: false,
|
|
long_context: true
|
|
},
|
|
conversion: {
|
|
from_anthropic_canonical: true,
|
|
tool_schema: 'native',
|
|
image_input: 'url',
|
|
thinking: 'none',
|
|
cache_control: 'openai'
|
|
},
|
|
quality_tier: 'balanced',
|
|
cost_tier: 'medium'
|
|
}
|
|
},
|
|
{
|
|
provider: 'openai-compatible',
|
|
model_pattern: '.*',
|
|
capabilities: {
|
|
// Defaults for compatible providers - actual capability varies
|
|
max_tokens_output: 4096,
|
|
max_tokens_input: 128000,
|
|
supports: {
|
|
text_input: true,
|
|
text_output: true,
|
|
streaming: true,
|
|
tool_use: true,
|
|
parallel_tool_use: false,
|
|
structured_output: false,
|
|
json_mode: true,
|
|
thinking: false,
|
|
prompt_cache: false,
|
|
system_prompt: true,
|
|
image_input: false,
|
|
image_output: false,
|
|
audio_input: false,
|
|
audio_output: false,
|
|
file_input: false,
|
|
computer_use: false,
|
|
long_context: false
|
|
},
|
|
conversion: {
|
|
from_anthropic_canonical: true,
|
|
tool_schema: 'emulated',
|
|
image_input: 'none',
|
|
thinking: 'none',
|
|
cache_control: 'none'
|
|
},
|
|
quality_tier: 'economy',
|
|
cost_tier: 'low'
|
|
}
|
|
},
|
|
{
|
|
provider: 'glm',
|
|
model_pattern: '^glm-5-.*',
|
|
capabilities: {
|
|
max_tokens_output: 128000,
|
|
max_tokens_input: 128000,
|
|
supports: {
|
|
text_input: true,
|
|
text_output: true,
|
|
streaming: true,
|
|
tool_use: true,
|
|
parallel_tool_use: false,
|
|
structured_output: true,
|
|
json_mode: true,
|
|
thinking: true,
|
|
prompt_cache: false,
|
|
system_prompt: true,
|
|
image_input: true,
|
|
image_output: false,
|
|
audio_input: false,
|
|
audio_output: false,
|
|
file_input: true,
|
|
computer_use: false,
|
|
long_context: true
|
|
},
|
|
conversion: {
|
|
from_anthropic_canonical: true,
|
|
tool_schema: 'emulated',
|
|
image_input: 'url',
|
|
thinking: 'emulated',
|
|
cache_control: 'none'
|
|
},
|
|
quality_tier: 'balanced',
|
|
cost_tier: 'medium'
|
|
}
|
|
}
|
|
]
|
|
|
|
export class CapabilityMatrixRegistry {
|
|
private matrix: ProviderCapabilityMatrix[]
|
|
|
|
constructor(matrix?: ProviderCapabilityMatrix[]) {
|
|
this.matrix = matrix || CAPABILITY_MATRIX
|
|
}
|
|
|
|
/**
|
|
* Look up capabilities for a specific provider/model.
|
|
*/
|
|
lookup(provider: string, model: string): ProviderCapability | undefined {
|
|
// Find matching entry
|
|
for (const entry of this.matrix) {
|
|
if (entry.provider !== provider) continue
|
|
|
|
const regex = new RegExp(entry.model_pattern)
|
|
if (regex.test(model)) {
|
|
return {
|
|
provider,
|
|
model,
|
|
...entry.capabilities
|
|
}
|
|
}
|
|
}
|
|
|
|
return undefined
|
|
}
|
|
|
|
/**
|
|
* List all models for a provider.
|
|
*/
|
|
list_models(provider: string): string[] {
|
|
const models: string[] = []
|
|
|
|
for (const entry of this.matrix) {
|
|
if (entry.provider === provider) {
|
|
// Extract example model name from pattern
|
|
const example = entry.model_pattern.replace(/^\^|\$.*$/g, '')
|
|
models.push(example || entry.model_pattern)
|
|
}
|
|
}
|
|
|
|
return models
|
|
}
|
|
|
|
/**
|
|
* Check if a provider/model supports a specific capability.
|
|
* Queries the nested `supports` object.
|
|
*/
|
|
supports(provider: string, model: string, capability: keyof SupportsMap): boolean {
|
|
const caps = this.lookup(provider, model)
|
|
if (!caps) return false
|
|
|
|
return caps.supports[capability] === true
|
|
}
|
|
|
|
/**
|
|
* Get the best model for a set of requirements.
|
|
*/
|
|
find_best(
|
|
provider: string,
|
|
requirements: {
|
|
min_output_tokens?: number
|
|
thinking?: boolean
|
|
tool_use?: boolean
|
|
}
|
|
): string | undefined {
|
|
const entries = this.matrix.filter(e => e.provider === provider)
|
|
|
|
for (const entry of entries) {
|
|
const caps = entry.capabilities
|
|
|
|
if (requirements.min_output_tokens && (!caps.max_tokens_output || caps.max_tokens_output < requirements.min_output_tokens)) {
|
|
continue
|
|
}
|
|
|
|
if (requirements.thinking && !caps.supports.thinking) {
|
|
continue
|
|
}
|
|
|
|
if (requirements.tool_use && !caps.supports.tool_use) {
|
|
continue
|
|
}
|
|
|
|
// Return first matching model pattern
|
|
return entry.model_pattern.replace(/[\^$]/g, '')
|
|
}
|
|
|
|
return undefined
|
|
}
|
|
}
|
|
|
|
export function createCapabilityMatrixRegistry(): CapabilityMatrixRegistry {
|
|
return new CapabilityMatrixRegistry()
|
|
}
|