fix(gateway): repair routing health and MCP command wiring
ci/woodpecker/pr/ci Pipeline was successful
ci/woodpecker/pr/ci Pipeline was successful
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { Inject, Injectable, Logger } from '@nestjs/common';
|
||||
import { routingRules, type Db, and, asc, eq, or } from '@mosaicstack/db';
|
||||
import type { ProviderHealthStatus } from '@mosaicstack/types';
|
||||
import { DB } from '../../database/database.module.js';
|
||||
import { ProviderService } from '../provider.service.js';
|
||||
import { classifyTask } from './task-classifier.js';
|
||||
@@ -49,7 +50,7 @@ export class RoutingEngineService {
|
||||
async resolve(
|
||||
message: string,
|
||||
userId?: string,
|
||||
availableProviders?: Record<string, { status: string }>,
|
||||
availableProviders?: Record<string, { status: ProviderHealthStatus }>,
|
||||
): Promise<RoutingDecision> {
|
||||
const classification = classifyTask(message);
|
||||
this.logger.debug(
|
||||
@@ -69,9 +70,8 @@ export class RoutingEngineService {
|
||||
if (!this.matchConditions(rule, classification)) continue;
|
||||
|
||||
const providerStatus = health[rule.action.provider]?.status;
|
||||
const isHealthy = providerStatus === 'up' || providerStatus === 'ok';
|
||||
|
||||
if (!isHealthy) {
|
||||
if (!this.isRoutable(providerStatus)) {
|
||||
this.logger.debug(
|
||||
`Rule "${rule.name}" matched but provider "${rule.action.provider}" is unhealthy (status: ${providerStatus ?? 'unknown'})`,
|
||||
);
|
||||
@@ -111,6 +111,10 @@ export class RoutingEngineService {
|
||||
|
||||
// ─── Private helpers ───────────────────────────────────────────────────────
|
||||
|
||||
private isRoutable(status: ProviderHealthStatus | undefined): boolean {
|
||||
return status === 'healthy' || status === 'degraded';
|
||||
}
|
||||
|
||||
private evaluateCondition(
|
||||
condition: RoutingCondition,
|
||||
classification: TaskClassification,
|
||||
@@ -186,11 +190,12 @@ export class RoutingEngineService {
|
||||
* Walk the fallback chain and return the first healthy provider/model pair.
|
||||
* If none are healthy, return the first entry unconditionally (last resort).
|
||||
*/
|
||||
private applyFallbackChain(health: Record<string, { status: string }>): RoutingDecision {
|
||||
private applyFallbackChain(
|
||||
health: Record<string, { status: ProviderHealthStatus }>,
|
||||
): RoutingDecision {
|
||||
for (const candidate of FALLBACK_CHAIN) {
|
||||
const providerStatus = health[candidate.provider]?.status;
|
||||
const isHealthy = providerStatus === 'up' || providerStatus === 'ok';
|
||||
if (isHealthy) {
|
||||
if (this.isRoutable(providerStatus)) {
|
||||
this.logger.debug(`Fallback resolved: ${candidate.provider}/${candidate.model}`);
|
||||
return {
|
||||
provider: candidate.provider,
|
||||
|
||||
Reference in New Issue
Block a user