feat(routing): routing_rules schema + types — M4-001/002/003 (#315)
Some checks failed
ci/woodpecker/push/ci Pipeline failed

Co-authored-by: Jason Woltje <jason@diversecanvas.com>
Co-committed-by: Jason Woltje <jason@diversecanvas.com>
This commit was merged in pull request #315.
This commit is contained in:
2026-03-23 00:08:56 +00:00
committed by jason.woltje
parent cabd39ba5b
commit 0ee6bfe9de
14 changed files with 3466 additions and 42 deletions

View File

@@ -1,10 +1,15 @@
/** Cost tier for model selection */
export type CostTier = 'cheap' | 'standard' | 'premium';
// ─── Legacy simple-routing types (kept for backward compatibility) ────────────
/** Task type hint for routing */
export type TaskType = 'chat' | 'coding' | 'analysis' | 'summarization' | 'general';
/** Result of a simple scoring-based routing decision */
export interface RoutingResult {
provider: string;
modelId: string;
modelName: string;
score: number;
reasoning: string;
}
/** Routing criteria for model selection */
/** Routing criteria for score-based model selection */
export interface RoutingCriteria {
taskType?: TaskType;
costTier?: CostTier;
@@ -15,11 +20,115 @@ export interface RoutingCriteria {
preferredModel?: string;
}
/** Result of a routing decision */
export interface RoutingResult {
provider: string;
modelId: string;
modelName: string;
score: number;
reasoning: string;
// ─── Classification primitives (M4-002) ──────────────────────────────────────
/** Category of work the agent is being asked to perform */
export type TaskType =
| 'chat'
| 'coding'
| 'research'
| 'summarization'
| 'conversation'
| 'analysis'
| 'creative'
| 'general';
/** Estimated complexity of the task, used to bias toward cheaper or more capable models */
export type Complexity = 'simple' | 'moderate' | 'complex';
/** Primary knowledge domain of the task */
export type Domain = 'frontend' | 'backend' | 'devops' | 'docs' | 'general';
/**
* Cost tier for model selection.
* `local` targets self-hosted/on-premises models.
*/
export type CostTier = 'cheap' | 'standard' | 'premium' | 'local';
/** Special model capability required by the task */
export type Capability = 'tools' | 'vision' | 'long-context' | 'reasoning' | 'embedding';
// ─── Condition types (M4-002) ─────────────────────────────────────────────────
/**
* A single predicate that must be satisfied for a routing rule to match.
*
* - `eq` — scalar equality: `field === value`
* - `in` — set membership: `value` (array) contains `field`
* - `includes` — array containment: `field` (array) includes `value`
*/
export interface RoutingCondition {
/** The task-classification field to test */
field: 'taskType' | 'complexity' | 'domain' | 'costTier' | 'requiredCapabilities';
/** Comparison operator */
operator: 'eq' | 'in' | 'includes';
/** Expected value or set of values */
value: string | string[];
}
// ─── Action types (M4-003) ────────────────────────────────────────────────────
/**
* The routing action to execute when all conditions in a rule are satisfied.
*/
export interface RoutingAction {
/** LLM provider identifier, e.g. `'anthropic'`, `'openai'`, `'ollama'` */
provider: string;
/** Model identifier, e.g. `'claude-opus-4-6'`, `'gpt-4o'` */
model: string;
/** Optional: use a specific pre-configured agent config from the agent registry */
agentConfigId?: string;
/** Optional: override the agent's default system prompt for this route */
systemPromptOverride?: string;
/** Optional: restrict the tool set available to the agent for this route */
toolAllowlist?: string[];
}
/**
* Full routing rule as stored in the database and used at runtime.
*/
export interface RoutingRule {
/** UUID primary key */
id: string;
/** Human-readable rule name */
name: string;
/** Lower number = evaluated first; unique per scope */
priority: number;
/** `'system'` rules apply globally; `'user'` rules override for a specific user */
scope: 'system' | 'user';
/** Present only for `'user'`-scoped rules */
userId?: string;
/** All conditions must match for the rule to fire */
conditions: RoutingCondition[];
/** Action to take when all conditions are met */
action: RoutingAction;
/** Whether this rule is active */
enabled: boolean;
}
/**
* Structured representation of what an agent has been asked to do,
* produced by the task classifier and consumed by the routing engine.
*/
export interface TaskClassification {
taskType: TaskType;
complexity: Complexity;
domain: Domain;
requiredCapabilities: Capability[];
}
/**
* Output of the routing engine — which model to use and why.
*/
export interface RoutingDecision {
/** LLM provider identifier */
provider: string;
/** Model identifier */
model: string;
/** Optional agent config to apply */
agentConfigId?: string;
/** Name of the rule that matched, for observability */
ruleName: string;
/** Human-readable explanation of why this rule was selected */
reason: string;
}