From cf6718f3c1ec07924e8e2e5b2aa7699a3b1b140c Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sun, 21 Jun 2026 22:14:15 -0700 Subject: [PATCH] FN-6892: show default model for configured prompt nodes Prompt workflow nodes with inline prompts or names now summarize their default model instead of appearing unconfigured. - Return the localized Default model summary for model prompt nodes without pinned provider/model settings when prompt or name is present. - Cover direct prompt summary cases and all built-in workflow prompt nodes to prevent Not configured regressions. - Add localized summary text and workflow-step documentation for default-model prompt nodes. Files changed: docs/workflow-steps.md | 2 +- .../nodes/__tests__/node-summary.test.ts | 32 ++++++++++++++++++++++ .../dashboard/app/components/nodes/node-summary.ts | 7 +++++ packages/i18n/locales/en/common.json | 1 + packages/i18n/locales/es/common.json | 1 + packages/i18n/locales/fr/common.json | 1 + packages/i18n/locales/ko/common.json | 1 + packages/i18n/locales/zh-CN/common.json | 1 + packages/i18n/locales/zh-TW/common.json | 1 + 9 files changed, 46 insertions(+), 1 deletion(-) Fusion-Task-Id: FN-6892 Fusion-Task-Lineage: 5892429d-22ee-495e-bc40-06cbf81ee471 --- docs/workflow-steps.md | 2 +- .../nodes/__tests__/node-summary.test.ts | 32 +++++++++++++++++++ .../app/components/nodes/node-summary.ts | 7 ++++ packages/i18n/locales/en/common.json | 1 + packages/i18n/locales/es/common.json | 1 + packages/i18n/locales/fr/common.json | 1 + packages/i18n/locales/ko/common.json | 1 + packages/i18n/locales/zh-CN/common.json | 1 + packages/i18n/locales/zh-TW/common.json | 1 + 9 files changed, 46 insertions(+), 1 deletion(-) diff --git a/docs/workflow-steps.md b/docs/workflow-steps.md index beed5235b3..c9a6d0711c 100644 --- a/docs/workflow-steps.md +++ b/docs/workflow-steps.md @@ -343,7 +343,7 @@ A prompt-mode workflow step can set its own model with: - `modelProvider` - `modelId` -If both are set, step execution uses that model; otherwise it falls back to default model selection. +If both are set, step execution uses that model; otherwise it falls back to default model selection. Dashboard node summaries show that unpinned prompt-step state as **Default model**. ## Default-On Behavior for New Tasks diff --git a/packages/dashboard/app/components/nodes/__tests__/node-summary.test.ts b/packages/dashboard/app/components/nodes/__tests__/node-summary.test.ts index 722ff017f0..5c99e73af6 100644 --- a/packages/dashboard/app/components/nodes/__tests__/node-summary.test.ts +++ b/packages/dashboard/app/components/nodes/__tests__/node-summary.test.ts @@ -1,3 +1,4 @@ +import { BUILTIN_WORKFLOWS } from "@fusion/core"; import { describe, expect, it } from "vitest"; import { bareSkillName, nodeConfigSummary, type NodeSummaryCatalogs } from "../node-summary"; import type { WorkflowFlowNodeData, WorkflowEditorNodeKind } from "../WorkflowNodeTypes"; @@ -25,6 +26,18 @@ describe("nodeConfigSummary", () => { expect(summary).toBe("Claude 3 Opus"); }); + it("model executor with prompt and no pinned model → Default model", () => { + const summary = nodeConfigSummary(node("prompt", { executor: "model", prompt: "Research prospects" })); + expect(summary).toBe("Default model"); + }); + + it("model executor with name, prompt, and no pinned model → Default model", () => { + const summary = nodeConfigSummary( + node("prompt", { executor: "model", name: "Source prospects", prompt: "Research prospects" }), + ); + expect(summary).toBe("Default model"); + }); + it("model executor defaults when executor unset", () => { const summary = nodeConfigSummary(node("prompt", { modelProvider: "openai", modelId: "gpt-4" })); expect(summary).toBe("openai/gpt-4"); @@ -142,6 +155,25 @@ describe("nodeConfigSummary", () => { expect(summary).toBe("Not configured"); }); + it("no built-in workflow prompt node summarizes as Not configured", () => { + // Keep this invariant beside the shared helper because desktop cards and the + // mobile graph both consume nodeConfigSummary(), so one direct assertion + // covers both render paths without duplicating UI fixtures. + const offenders = BUILTIN_WORKFLOWS.flatMap((workflow) => + workflow.ir.nodes + .filter((workflowNode) => workflowNode.kind === "prompt") + .map((workflowNode) => { + const summary = nodeConfigSummary( + node(workflowNode.kind as WorkflowEditorNodeKind, workflowNode.config ?? {}), + ); + return { workflowId: workflow.id, nodeId: workflowNode.id, summary }; + }) + .filter((entry) => entry.summary === "Not configured"), + ); + + expect(offenders).toEqual([]); + }); + it("script node → scriptName", () => { const summary = nodeConfigSummary(node("script", { scriptName: "lint" })); expect(summary).toBe("lint"); diff --git a/packages/dashboard/app/components/nodes/node-summary.ts b/packages/dashboard/app/components/nodes/node-summary.ts index 9d5f2e63a3..110f3e5edb 100644 --- a/packages/dashboard/app/components/nodes/node-summary.ts +++ b/packages/dashboard/app/components/nodes/node-summary.ts @@ -98,6 +98,10 @@ export function bareSkillName(name: string): string { * Catalog name resolution is best-effort: when a catalog is missing or the id is * unknown, the raw id/command/name is returned — never blank for a configured * node (KTD-6 raw-id fallback). + * + * FNXC:WorkflowNodeSummary 2026-06-21-00:00: + * Built-in prompt nodes that use the default model are configured by their inline prompt or display name even when they do not pin modelProvider/modelId. + * Show "Default model" for that model-executor state so workflow editor and mobile graph summaries never imply those built-ins are incomplete. */ export function nodeConfigSummary( data: WorkflowFlowNodeData, @@ -163,6 +167,9 @@ export function nodeConfigSummary( const model = modelSummary(config, catalogs); if (model) return model; if (config.awaitInput === true) return t("workflowNodes.summaryAwaitInput", "Waits for user input"); + if (str(config.prompt).trim() || str(config.name).trim()) { + return t("workflowNodes.summaryDefaultModel", "Default model"); + } return t("workflowNodes.summaryNotConfigured", "Not configured"); } case "script": { diff --git a/packages/i18n/locales/en/common.json b/packages/i18n/locales/en/common.json index cd06c0d3f8..7d42a3a64a 100644 --- a/packages/i18n/locales/en/common.json +++ b/packages/i18n/locales/en/common.json @@ -223,6 +223,7 @@ "workflowNodes": { "summaryAwaitInput": "Waits for user input", "summaryCodeDefault": "TypeScript", + "summaryDefaultModel": "Default model", "summaryGateAdvisory": "Advisory", "summaryGateBlocks": "Gate (blocks)", "summaryHoldRelease": "Release: {{release}}", diff --git a/packages/i18n/locales/es/common.json b/packages/i18n/locales/es/common.json index 5dc463e9fd..28dbaca35c 100644 --- a/packages/i18n/locales/es/common.json +++ b/packages/i18n/locales/es/common.json @@ -223,6 +223,7 @@ "workflowNodes": { "summaryAwaitInput": "", "summaryCodeDefault": "", + "summaryDefaultModel": "", "summaryGateAdvisory": "", "summaryGateBlocks": "", "summaryHoldRelease": "", diff --git a/packages/i18n/locales/fr/common.json b/packages/i18n/locales/fr/common.json index 5dc463e9fd..28dbaca35c 100644 --- a/packages/i18n/locales/fr/common.json +++ b/packages/i18n/locales/fr/common.json @@ -223,6 +223,7 @@ "workflowNodes": { "summaryAwaitInput": "", "summaryCodeDefault": "", + "summaryDefaultModel": "", "summaryGateAdvisory": "", "summaryGateBlocks": "", "summaryHoldRelease": "", diff --git a/packages/i18n/locales/ko/common.json b/packages/i18n/locales/ko/common.json index 5dc463e9fd..28dbaca35c 100644 --- a/packages/i18n/locales/ko/common.json +++ b/packages/i18n/locales/ko/common.json @@ -223,6 +223,7 @@ "workflowNodes": { "summaryAwaitInput": "", "summaryCodeDefault": "", + "summaryDefaultModel": "", "summaryGateAdvisory": "", "summaryGateBlocks": "", "summaryHoldRelease": "", diff --git a/packages/i18n/locales/zh-CN/common.json b/packages/i18n/locales/zh-CN/common.json index 5dc463e9fd..28dbaca35c 100644 --- a/packages/i18n/locales/zh-CN/common.json +++ b/packages/i18n/locales/zh-CN/common.json @@ -223,6 +223,7 @@ "workflowNodes": { "summaryAwaitInput": "", "summaryCodeDefault": "", + "summaryDefaultModel": "", "summaryGateAdvisory": "", "summaryGateBlocks": "", "summaryHoldRelease": "", diff --git a/packages/i18n/locales/zh-TW/common.json b/packages/i18n/locales/zh-TW/common.json index 5dc463e9fd..28dbaca35c 100644 --- a/packages/i18n/locales/zh-TW/common.json +++ b/packages/i18n/locales/zh-TW/common.json @@ -223,6 +223,7 @@ "workflowNodes": { "summaryAwaitInput": "", "summaryCodeDefault": "", + "summaryDefaultModel": "", "summaryGateAdvisory": "", "summaryGateBlocks": "", "summaryHoldRelease": "",