fix(FN-2662): honor project model overrides and stabilize tests

This commit is contained in:
gsxdsm
2026-04-28 18:21:17 -07:00
parent 964c55da77
commit 2029968d23
31 changed files with 980 additions and 361 deletions

View File

@@ -1,8 +1,16 @@
import { exec } from "node:child_process";
import { promisify } from "node:util";
import type { TaskStore } from "@fusion/core";
import type { AutomationStore } from "@fusion/core";
import type { ScheduledTask, AutomationRunResult, AutomationStep, AutomationStepResult, Column, TaskCreateInput } from "@fusion/core";
import {
resolveProjectDefaultModel,
type TaskStore,
type AutomationStore,
type ScheduledTask,
type AutomationRunResult,
type AutomationStep,
type AutomationStepResult,
type Column,
type TaskCreateInput,
} from "@fusion/core";
import { createLogger } from "./logger.js";
import { defaultShell } from "./shell-utils.js";
import { createFnAgent, promptWithFallback } from "./pi.js";
@@ -494,10 +502,11 @@ export class CronRunner {
};
}
// Resolve model: step override → settings default
// Resolve model: step override → project default override → global default
const settings = await this.store.getSettings();
const modelProvider = step.modelProvider?.trim() || settings.defaultProvider;
const modelId = step.modelId?.trim() || settings.defaultModelId;
const defaultModel = resolveProjectDefaultModel(settings);
const modelProvider = step.modelProvider?.trim() || defaultModel.provider;
const modelId = step.modelId?.trim() || defaultModel.modelId;
const model = modelProvider && modelId
? `${modelProvider}/${modelId}`

View File

@@ -6,7 +6,13 @@ import { isAbsolute, join, relative, resolve as resolvePath } from "node:path";
import { existsSync } from "node:fs";
import { readFile, writeFile } from "node:fs/promises";
import type { TaskStore, Task, TaskDetail, TaskTokenUsage, StepStatus, Settings, WorkflowStep, MissionStore, Slice, AgentState, AgentCapability, RunMutationContext } from "@fusion/core";
import { buildExecutionMemoryInstructions, getTaskMergeBlocker, resolveAgentPrompt, type RunCommandResult } from "@fusion/core";
import {
buildExecutionMemoryInstructions,
getTaskMergeBlocker,
resolveAgentPrompt,
resolveProjectDefaultModel,
type RunCommandResult,
} from "@fusion/core";
import { findWorktreeUser } from "./merger.js";
import { generateWorktreeName, slugify } from "./worktree-names.js";
import { Type, type Static } from "@mariozechner/pi-ai";
@@ -3967,11 +3973,13 @@ and show an appropriate message to the user.\`
});
// Determine primary model and an explicit fallback. The workflow step's
// own override takes precedence; otherwise we use the global default. The
// own override takes precedence; otherwise we use the project default
// override before falling through to the global default. The
// fallback is the per-step override's missing-counterpart settings, then
// the global validator/fallback pair, then the executor's `fallbackProvider`.
const primaryProvider = workflowStep.modelProvider || settings.defaultProvider;
const primaryModelId = workflowStep.modelId || settings.defaultModelId;
const defaultModel = resolveProjectDefaultModel(settings);
const primaryProvider = workflowStep.modelProvider || defaultModel.provider;
const primaryModelId = workflowStep.modelId || defaultModel.modelId;
const useOverride = !!(workflowStep.modelProvider && workflowStep.modelId);
type ModelTuple = { provider?: string; modelId?: string };