fix(server): log each provider fallback during metadata generation

This commit is contained in:
Mohamed Boudra
2026-05-24 12:54:08 +07:00
parent 83f205bd3d
commit d43d30eeeb
3 changed files with 42 additions and 20 deletions
@@ -132,25 +132,19 @@ export async function generateAndApplyAgentMetadata(
maxRetries: 2, maxRetries: 2,
providers: DEFAULT_STRUCTURED_GENERATION_PROVIDERS, providers: DEFAULT_STRUCTURED_GENERATION_PROVIDERS,
persistSession: false, persistSession: false,
logger: options.logger,
agentConfigOverrides: { agentConfigOverrides: {
title: "Agent metadata generator", title: "Agent metadata generator",
internal: true, internal: true,
}, },
}); });
} catch (error) { } catch (error) {
if ( const attempts = error instanceof StructuredAgentFallbackError ? error.attempts : undefined;
error instanceof StructuredAgentResponseError ||
error instanceof StructuredAgentFallbackError
) {
options.logger.warn(
{ err: error, agentId: options.agentId },
"Structured metadata generation failed",
);
return;
}
options.logger.error( options.logger.error(
{ err: error, agentId: options.agentId }, { err: error, agentId: options.agentId, attempts },
"Agent metadata generation failed", error instanceof StructuredAgentResponseError || error instanceof StructuredAgentFallbackError
? "Structured metadata generation failed"
: "Agent metadata generation failed",
); );
return; return;
} }
@@ -5,6 +5,11 @@ import type { AgentProvider, AgentSessionConfig } from "./agent-sdk-types.js";
import type { AgentManager } from "./agent-manager.js"; import type { AgentManager } from "./agent-manager.js";
import { getAgentProviderDefinition } from "./provider-manifest.js"; import { getAgentProviderDefinition } from "./provider-manifest.js";
export interface StructuredGenerationLogger {
info: (obj: object, msg?: string) => void;
warn: (obj: object, msg?: string) => void;
}
export type JsonSchema = Record<string, unknown>; export type JsonSchema = Record<string, unknown>;
export type AgentCaller = (prompt: string) => Promise<string>; export type AgentCaller = (prompt: string) => Promise<string>;
@@ -90,6 +95,7 @@ export interface StructuredAgentGenerationWithFallbackOptions<T> {
persistSession?: boolean; persistSession?: boolean;
maxRetries?: number; maxRetries?: number;
schemaName?: string; schemaName?: string;
logger?: StructuredGenerationLogger;
runner?: <TResult>(options: StructuredAgentGenerationOptions<TResult>) => Promise<TResult>; runner?: <TResult>(options: StructuredAgentGenerationOptions<TResult>) => Promise<TResult>;
} }
@@ -397,6 +403,7 @@ export async function generateStructuredAgentResponseWithFallback<T>(
persistSession, persistSession,
maxRetries, maxRetries,
schemaName, schemaName,
logger,
runner, runner,
} = options; } = options;
@@ -414,12 +421,17 @@ export async function generateStructuredAgentResponseWithFallback<T>(
for (const candidate of providers) { for (const candidate of providers) {
const availabilityEntry = availabilityByProvider.get(candidate.provider); const availabilityEntry = availabilityByProvider.get(candidate.provider);
if (availabilityEntry && !availabilityEntry.available) { if (availabilityEntry && !availabilityEntry.available) {
const reason = availabilityEntry.error ?? "unavailable";
attempts.push({ attempts.push({
provider: candidate.provider, provider: candidate.provider,
model: candidate.model ?? null, model: candidate.model ?? null,
available: false, available: false,
error: availabilityEntry.error ?? null, error: availabilityEntry.error ?? null,
}); });
logger?.warn(
{ provider: candidate.provider, model: candidate.model, schemaName, reason },
"Structured generation: skipping unavailable provider",
);
continue; continue;
} }
@@ -439,6 +451,17 @@ export async function generateStructuredAgentResponseWithFallback<T>(
...(candidate.thinkingOptionId ? { thinkingOptionId: candidate.thinkingOptionId } : {}), ...(candidate.thinkingOptionId ? { thinkingOptionId: candidate.thinkingOptionId } : {}),
}, },
}); });
if (attempts.length > 0) {
logger?.info(
{
provider: candidate.provider,
model: candidate.model,
schemaName,
priorAttempts: attempts,
},
"Structured generation: succeeded after fallback",
);
}
return result; return result;
} catch (error) { } catch (error) {
attempts.push({ attempts.push({
@@ -447,6 +470,10 @@ export async function generateStructuredAgentResponseWithFallback<T>(
available: true, available: true,
error: errorMessage(error), error: errorMessage(error),
}); });
logger?.warn(
{ err: error, provider: candidate.provider, model: candidate.model, schemaName },
"Structured generation: provider failed, trying next",
);
} }
} }
@@ -12,6 +12,7 @@ import { buildMetadataPrompt } from "../utils/build-metadata-prompt.js";
import type { WorkspaceGitService } from "./workspace-git-service.js"; import type { WorkspaceGitService } from "./workspace-git-service.js";
interface BranchNameGeneratorLogger { interface BranchNameGeneratorLogger {
info: (obj: object, msg?: string) => void;
warn: (obj: object, msg?: string) => void; warn: (obj: object, msg?: string) => void;
error: (obj: object, msg?: string) => void; error: (obj: object, msg?: string) => void;
} }
@@ -77,6 +78,7 @@ export async function generateBranchNameFromFirstAgentContext(
maxRetries: 2, maxRetries: 2,
providers: DEFAULT_STRUCTURED_GENERATION_PROVIDERS, providers: DEFAULT_STRUCTURED_GENERATION_PROVIDERS,
persistSession: false, persistSession: false,
logger: options.logger,
agentConfigOverrides: { agentConfigOverrides: {
title: "Branch name generator", title: "Branch name generator",
internal: true, internal: true,
@@ -84,14 +86,13 @@ export async function generateBranchNameFromFirstAgentContext(
}); });
return result.branch.trim() || null; return result.branch.trim() || null;
} catch (error) { } catch (error) {
if ( const attempts = error instanceof StructuredAgentFallbackError ? error.attempts : undefined;
error instanceof StructuredAgentResponseError || options.logger.error(
error instanceof StructuredAgentFallbackError { err: error, attempts },
) { error instanceof StructuredAgentResponseError || error instanceof StructuredAgentFallbackError
options.logger.warn({ err: error }, "Structured branch name generation failed"); ? "Structured branch name generation failed"
return null; : "Branch name generation failed",
} );
options.logger.error({ err: error }, "Branch name generation failed");
return null; return null;
} }
} }