diff --git a/studio/frontend/src/features/recipe-studio/dialogs/models/model-config-dialog.tsx b/studio/frontend/src/features/recipe-studio/dialogs/models/model-config-dialog.tsx index 28251bd6f2..ed03018dda 100644 --- a/studio/frontend/src/features/recipe-studio/dialogs/models/model-config-dialog.tsx +++ b/studio/frontend/src/features/recipe-studio/dialogs/models/model-config-dialog.tsx @@ -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(null); const providerInputRef = useRef(config.provider); @@ -123,7 +124,7 @@ export function ModelConfigDialog({ label="Inference" hint="Runtime generation params for this model alias." /> -
+
+ + updateField("inference_timeout", event.target.value) + } + />
diff --git a/studio/frontend/src/features/recipe-studio/types/index.ts b/studio/frontend/src/features/recipe-studio/types/index.ts index 56c1475ee6..411cb0add8 100644 --- a/studio/frontend/src/features/recipe-studio/types/index.ts +++ b/studio/frontend/src/features/recipe-studio/types/index.ts @@ -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; diff --git a/studio/frontend/src/features/recipe-studio/utils/config-factories.ts b/studio/frontend/src/features/recipe-studio/utils/config-factories.ts index 39ef028c5b..89ebac9579 100644 --- a/studio/frontend/src/features/recipe-studio/utils/config-factories.ts +++ b/studio/frontend/src/features/recipe-studio/utils/config-factories.ts @@ -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, diff --git a/studio/frontend/src/features/recipe-studio/utils/graph/recipe-graph-connection.ts b/studio/frontend/src/features/recipe-studio/utils/graph/recipe-graph-connection.ts index fc109804e6..6699ab1007 100644 --- a/studio/frontend/src/features/recipe-studio/utils/graph/recipe-graph-connection.ts +++ b/studio/frontend/src/features/recipe-studio/utils/graph/recipe-graph-connection.ts @@ -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 && diff --git a/studio/frontend/src/features/recipe-studio/utils/import/parsers/model-parser.ts b/studio/frontend/src/features/recipe-studio/utils/import/parsers/model-parser.ts index 8602da9747..5c7085a2de 100644 --- a/studio/frontend/src/features/recipe-studio/utils/import/parsers/model-parser.ts +++ b/studio/frontend/src/features/recipe-studio/utils/import/parsers/model-parser.ts @@ -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) : "", diff --git a/studio/frontend/src/features/recipe-studio/utils/payload/builders-model.ts b/studio/frontend/src/features/recipe-studio/utils/payload/builders-model.ts index 3a96b2c8d0..1d7f732122 100644 --- a/studio/frontend/src/features/recipe-studio/utils/payload/builders-model.ts +++ b/studio/frontend/src/features/recipe-studio/utils/payload/builders-model.ts @@ -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;