feat(recipe-studio): add inference_timeout configuration and validation logic

This commit is contained in:
Shine1i 2026-03-06 00:51:28 +01:00
commit f118216898
6 changed files with 33 additions and 17 deletions

View file

@ -36,6 +36,7 @@ export function ModelConfigDialog({
const tempId = `${config.id}-temperature`;
const topPId = `${config.id}-top-p`;
const maxTokensId = `${config.id}-max-tokens`;
const timeoutId = `${config.id}-timeout`;
const extraBodyId = `${config.id}-inference-extra-body`;
const providerAnchorRef = useRef<HTMLDivElement>(null);
const providerInputRef = useRef(config.provider);
@ -123,7 +124,7 @@ export function ModelConfigDialog({
label="Inference"
hint="Runtime generation params for this model alias."
/>
<div className="grid grid-cols-3 gap-2">
<div className="grid grid-cols-2 gap-2 sm:grid-cols-4">
<Input
id={tempId}
className="nodrag"
@ -151,6 +152,15 @@ export function ModelConfigDialog({
updateField("inference_max_tokens", event.target.value)
}
/>
<Input
id={timeoutId}
className="nodrag"
placeholder="Timeout (sec)"
value={config.inference_timeout ?? ""}
onChange={(event) =>
updateField("inference_timeout", event.target.value)
}
/>
</div>
</div>
<Collapsible open={optionalOpen} onOpenChange={setOptionalOpen}>

View file

@ -244,6 +244,8 @@ export type ModelConfig = {
// biome-ignore lint/style/useNamingConvention: api schema
inference_max_tokens?: string;
// biome-ignore lint/style/useNamingConvention: api schema
inference_timeout?: string;
// biome-ignore lint/style/useNamingConvention: api schema
inference_extra_body?: string;
// biome-ignore lint/style/useNamingConvention: api schema
skip_health_check?: boolean;

View file

@ -260,6 +260,8 @@ export function makeModelConfig(
// biome-ignore lint/style/useNamingConvention: api schema
inference_top_p: "",
// biome-ignore lint/style/useNamingConvention: api schema
inference_timeout: "",
// biome-ignore lint/style/useNamingConvention: api schema
inference_extra_body: "",
// biome-ignore lint/style/useNamingConvention: api schema
skip_health_check: false,

View file

@ -12,7 +12,6 @@ import { isSemanticRelation } from "./relations";
import {
isCategoryConfig,
isExpressionConfig,
isLlmConfig,
isSubcategoryConfig,
} from "../index";
import {
@ -345,6 +344,15 @@ export function applyRecipeConnection(
const semanticRelation = isSemanticRelation(source, target);
const singleRefRelation = getSingleRefRelation(source, target);
if (
singleRefRelation === "subcategory_parent" &&
isSubcategoryConfig(target)
) {
const currentParent = target.subcategory_parent?.trim() ?? "";
if (currentParent && currentParent !== source.name) {
return { edges };
}
}
const nextBaseEdges = singleRefRelation
? edges.filter(
(edge) =>
@ -405,21 +413,6 @@ export function applyRecipeConnection(
};
return { edges: nextEdges, configs: { ...configs, [target.id]: next } };
}
if (
isLlmConfig(target) &&
!semanticRelation &&
source.kind !== "seed" &&
source.kind !== "model_provider" &&
source.kind !== "model_config" &&
source.kind !== "validator"
) {
const ref = `{{ ${source.name} }}`;
const next = {
...target,
prompt: buildTemplateWithRef(target.prompt ?? "", ref),
};
return { edges: nextEdges, configs: { ...configs, [target.id]: next } };
}
if (
isExpressionConfig(target) &&
!semanticRelation &&

View file

@ -56,6 +56,8 @@ export function parseModelConfig(
// biome-ignore lint/style/useNamingConvention: api schema
inference_max_tokens: readNumberString(inference.max_tokens),
// biome-ignore lint/style/useNamingConvention: api schema
inference_timeout: readNumberString(inference.timeout),
// biome-ignore lint/style/useNamingConvention: api schema
inference_extra_body: isRecord(inference.extra_body)
? JSON.stringify(inference.extra_body, null, 2)
: "",

View file

@ -39,6 +39,7 @@ export function buildModelConfig(
const temp = config.inference_temperature?.trim();
const topP = config.inference_top_p?.trim();
const maxTokens = config.inference_max_tokens?.trim();
const timeout = config.inference_timeout?.trim();
const extraBody = parseJsonObject(
config.inference_extra_body,
`Model ${config.name} inference extra_body`,
@ -65,6 +66,12 @@ export function buildModelConfig(
inference.max_tokens = parsed;
}
}
if (timeout) {
const parsed = Number(timeout);
if (Number.isFinite(parsed)) {
inference.timeout = Math.trunc(parsed);
}
}
if (extraBody) {
// biome-ignore lint/style/useNamingConvention: api schema
inference.extra_body = extraBody;