- Updated all package.json name fields and dependency references - Updated all TypeScript/JavaScript imports - Updated .woodpecker/publish.yml filters and registry paths - Updated tools/install.sh scope default - Updated .npmrc registry paths (worktree + host) - Enhanced update-checker.ts with checkForAllUpdates() multi-package support - Updated CLI update command to show table of all packages - Added KNOWN_PACKAGES, formatAllPackagesTable, getInstallAllCommand - Marked checkForUpdate() with @deprecated JSDoc Closes #391
139 lines
4.2 KiB
TypeScript
139 lines
4.2 KiB
TypeScript
import { Inject, Injectable, Logger, type OnModuleInit } from '@nestjs/common';
|
|
import { routingRules, type Db, sql } from '@mosaicstack/db';
|
|
import { DB } from '../../database/database.module.js';
|
|
import type { RoutingCondition, RoutingAction } from './routing.types.js';
|
|
|
|
/** Seed-time routing rule descriptor */
|
|
interface RoutingRuleSeed {
|
|
name: string;
|
|
priority: number;
|
|
conditions: RoutingCondition[];
|
|
action: RoutingAction;
|
|
}
|
|
|
|
export const DEFAULT_ROUTING_RULES: RoutingRuleSeed[] = [
|
|
{
|
|
name: 'Complex coding → Opus',
|
|
priority: 1,
|
|
conditions: [
|
|
{ field: 'taskType', operator: 'eq', value: 'coding' },
|
|
{ field: 'complexity', operator: 'eq', value: 'complex' },
|
|
],
|
|
action: { provider: 'anthropic', model: 'claude-opus-4-6' },
|
|
},
|
|
{
|
|
name: 'Moderate coding → Sonnet',
|
|
priority: 2,
|
|
conditions: [
|
|
{ field: 'taskType', operator: 'eq', value: 'coding' },
|
|
{ field: 'complexity', operator: 'eq', value: 'moderate' },
|
|
],
|
|
action: { provider: 'anthropic', model: 'claude-sonnet-4-6' },
|
|
},
|
|
{
|
|
name: 'Simple coding → Codex',
|
|
priority: 3,
|
|
conditions: [
|
|
{ field: 'taskType', operator: 'eq', value: 'coding' },
|
|
{ field: 'complexity', operator: 'eq', value: 'simple' },
|
|
],
|
|
action: { provider: 'openai', model: 'codex-gpt-5-4' },
|
|
},
|
|
{
|
|
name: 'Research → Codex',
|
|
priority: 4,
|
|
conditions: [{ field: 'taskType', operator: 'eq', value: 'research' }],
|
|
action: { provider: 'openai', model: 'codex-gpt-5-4' },
|
|
},
|
|
{
|
|
name: 'Summarization → GLM-5',
|
|
priority: 5,
|
|
conditions: [{ field: 'taskType', operator: 'eq', value: 'summarization' }],
|
|
action: { provider: 'zai', model: 'glm-5' },
|
|
},
|
|
{
|
|
name: 'Analysis with reasoning → Opus',
|
|
priority: 6,
|
|
conditions: [
|
|
{ field: 'taskType', operator: 'eq', value: 'analysis' },
|
|
{ field: 'requiredCapabilities', operator: 'includes', value: 'reasoning' },
|
|
],
|
|
action: { provider: 'anthropic', model: 'claude-opus-4-6' },
|
|
},
|
|
{
|
|
name: 'Conversation → Sonnet',
|
|
priority: 7,
|
|
conditions: [{ field: 'taskType', operator: 'eq', value: 'conversation' }],
|
|
action: { provider: 'anthropic', model: 'claude-sonnet-4-6' },
|
|
},
|
|
{
|
|
name: 'Creative → Sonnet',
|
|
priority: 8,
|
|
conditions: [{ field: 'taskType', operator: 'eq', value: 'creative' }],
|
|
action: { provider: 'anthropic', model: 'claude-sonnet-4-6' },
|
|
},
|
|
{
|
|
name: 'Cheap/general → Haiku',
|
|
priority: 9,
|
|
conditions: [{ field: 'costTier', operator: 'eq', value: 'cheap' }],
|
|
action: { provider: 'anthropic', model: 'claude-haiku-4-5' },
|
|
},
|
|
{
|
|
name: 'Fallback → Sonnet',
|
|
priority: 10,
|
|
conditions: [],
|
|
action: { provider: 'anthropic', model: 'claude-sonnet-4-6' },
|
|
},
|
|
{
|
|
name: 'Offline → Ollama',
|
|
priority: 99,
|
|
conditions: [{ field: 'costTier', operator: 'eq', value: 'local' }],
|
|
action: { provider: 'ollama', model: 'llama3.2' },
|
|
},
|
|
];
|
|
|
|
@Injectable()
|
|
export class DefaultRoutingRulesSeed implements OnModuleInit {
|
|
private readonly logger = new Logger(DefaultRoutingRulesSeed.name);
|
|
|
|
constructor(@Inject(DB) private readonly db: Db) {}
|
|
|
|
async onModuleInit(): Promise<void> {
|
|
await this.seedDefaultRules();
|
|
}
|
|
|
|
/**
|
|
* Insert default routing rules into the database if the table is empty.
|
|
* Skips seeding if any system-scoped rules already exist.
|
|
*/
|
|
async seedDefaultRules(): Promise<void> {
|
|
const rows = await this.db
|
|
.select({ count: sql<number>`count(*)::int` })
|
|
.from(routingRules)
|
|
.where(sql`scope = 'system'`);
|
|
|
|
const count = rows[0]?.count ?? 0;
|
|
if (count > 0) {
|
|
this.logger.debug(
|
|
`Skipping default routing rules seed — ${count} system rule(s) already exist`,
|
|
);
|
|
return;
|
|
}
|
|
|
|
this.logger.log(`Seeding ${DEFAULT_ROUTING_RULES.length} default routing rules`);
|
|
|
|
await this.db.insert(routingRules).values(
|
|
DEFAULT_ROUTING_RULES.map((rule) => ({
|
|
name: rule.name,
|
|
priority: rule.priority,
|
|
scope: 'system' as const,
|
|
conditions: rule.conditions as unknown as Record<string, unknown>[],
|
|
action: rule.action as unknown as Record<string, unknown>,
|
|
enabled: true,
|
|
})),
|
|
);
|
|
|
|
this.logger.log('Default routing rules seeded successfully');
|
|
}
|
|
}
|