diff --git a/ui/src/api/API_README.md b/ui/src/api/API_README.md index 20cf1688dd6..d8440cb7cc7 100644 --- a/ui/src/api/API_README.md +++ b/ui/src/api/API_README.md @@ -207,7 +207,7 @@ Workspace、System 资源管理和 System 共享资源均把 `postPromptGenerate 路径为 `/workspace//model//prompt_generate` 与 `/system/model//prompt_generate`, System 接口不依赖工作空间 ID。 均返回原始 SSE Response,由公共生成组件读取。画布的 `PromptGenerate` 通过 -`useWorkflowStore(apiType).postPromptGenerate` 调用;三个范围的 Store 适配器分别引用对应的 +`useWorkflowStore(resourceScope).postPromptGenerate` 调用;三个范围的 Store 适配器分别引用对应的 Model API,直接转发生成请求,不使用查询缓存或请求去重。 ### 知识库维护 diff --git a/ui/src/workflow-canvas/WORKFLOW_README.md b/ui/src/workflow-canvas/WORKFLOW_README.md index 3273f3ebfcd..f14470a0923 100644 --- a/ui/src/workflow-canvas/WORKFLOW_README.md +++ b/ui/src/workflow-canvas/WORKFLOW_README.md @@ -132,7 +132,7 @@ LogicFlow 的节点拖拽;仅拦截 `mousedown` 无法隔离当前版本的 Po ### 资源查询(`store/`) -`useWorkflowStore(apiType)` 是画布资源接口适配器,不是 Pinia Store。它自动收集 `store/api/*/index.ts`, +`useWorkflowStore(resourceScope)` 是画布资源接口适配器,不是 Pinia Store。它自动收集 `store/api/*/index.ts`, 查询方法按范围、方法与查询参数缓存结果并复用在途请求;`store.force.xxx()` 跳过已完成缓存,仍复用同键在途请求。 `postPromptGenerate` 是流式生成方法,始终直接转发到对应范围的 Model API,不缓存或去重; 通过普通 Store 或 `force` 调用都会发起新请求,返回独立的 Response 流。 @@ -140,7 +140,7 @@ LogicFlow 的节点拖拽;仅拦截 `mousedown` 无法隔离当前版本的 Po System 资源管理合并普通与共享模型,System 共享范围仅返回标记 `source: 'shared'` 的共享模型。 强制刷新使用 `store.force.getModelListWithShared(query)`。动态表单配置器通过 `getSelectModelList` 注入使用该能力,循环体转发同名注入。 -主画布从 `resourceScope` 注入读取范围(默认 `workspace`),通过节点上下文传递为 `apiType`。 +主画布从 `resourceScope` 注入读取范围(默认 `workspace`),通过节点上下文传递为 `resourceScope`。 当前 `workspace` 适配模型、供应商、模型参数、MCP 工具、共享工具选项、工具详情和标签查询; `system-resource` 与 `system-shared` 独立提供系统模型、供应商、参数表单、工具选项与详情、MCP 和标签查询, @@ -329,7 +329,7 @@ AI 对话节点的提示词、历史记录、视觉理解和输出思考表单 自定义模型使用节点配置的模型 ID,引用变量无法在编辑时确定模型,生成入口禁用。 图片理解和视频理解使用 IMAGE 模型,AI 对话使用 LLM 模型,现有提示词接口支持这两种类型。 共享组件维护提示词模板和请求上下文,不依赖某个节点,也不接收未使用的模型或供应商选项。 -组件将画布注入的 `apiType` 传给 `useWorkflowStore`,通过 `store.postPromptGenerate` 发起生成; +组件将画布注入的 `resourceScope` 传给 `useWorkflowStore`,通过 `store.postPromptGenerate` 发起生成; Store 适配器统一选择 Workspace、System 资源管理或 System 共享资源的 Model API。 循环画布已转发同一上下文,组件不再单独判断资源范围。生成方法不使用 Store 的查询缓存或请求去重。 生成接口不再依赖应用,改用节点自身已保存的模型参数(`model_params_setting`)并随请求体提交, diff --git a/ui/src/workflow-canvas/component/PromptGenerate.vue b/ui/src/workflow-canvas/component/PromptGenerate.vue index 82f1daa6135..3ef9f21ac5b 100644 --- a/ui/src/workflow-canvas/component/PromptGenerate.vue +++ b/ui/src/workflow-canvas/component/PromptGenerate.vue @@ -10,9 +10,9 @@ const props = defineProps<{ }>() const emit = defineEmits<{ replace: [prompt: string] }>() -// 资源范围沿用画布传递的 apiType,循环内节点也使用同一上下文。 -const apiType = inject('apiType', 'workspace') -const store = useWorkflowStore(apiType) +// 资源范围沿用画布传递的 resourceScope,循环内节点也使用同一上下文。 +const resourceScope = inject('resourceScope', 'workspace') +const store = useWorkflowStore(resourceScope) // 提示词模板:约束生成结果的角色结构与内容范围。 const PROMPT_TEMPLATE = `请根据用户描述生成一个完整的AI角色人设模板: diff --git a/ui/src/workflow-canvas/index.vue b/ui/src/workflow-canvas/index.vue index 9be47099bac..3b3a25f9d8d 100644 --- a/ui/src/workflow-canvas/index.vue +++ b/ui/src/workflow-canvas/index.vue @@ -17,7 +17,7 @@ import NodeControl from './component/NodeControl.vue' defineOptions({ name: 'WorkflowCanvas' }) type CanvasWorkflowNodeModel = WorkflowNodeModel & { set_loop_body?: () => void } -const apiType = inject('resourceScope', 'workspace') +const resourceScope = inject('resourceScope', 'workspace') const props = withDefaults( defineProps<{ data?: LogicFlow.GraphConfigData | null @@ -83,7 +83,7 @@ function renderGraphData(data: LogicFlow.GraphConfigData = props.data ?? {}) { lf.value.graphModel.get_provide = (model: LogicFlow.NodeData | null, graph: GraphModel | null) => ({ getModel: () => model, getGraph: () => graph, - apiType: apiType, + resourceScope: resourceScope, workflowMode: props.workflowMode, loopWorkflowMode: props.loopWorkflowMode, }) diff --git a/ui/src/workflow-canvas/nodes/ai-chat-node/component/resource-setting/McpSettingDialog.vue b/ui/src/workflow-canvas/nodes/ai-chat-node/component/resource-setting/McpSettingDialog.vue index 4b689024fd1..ad14fc48334 100644 --- a/ui/src/workflow-canvas/nodes/ai-chat-node/component/resource-setting/McpSettingDialog.vue +++ b/ui/src/workflow-canvas/nodes/ai-chat-node/component/resource-setting/McpSettingDialog.vue @@ -11,8 +11,8 @@ import type { McpSetting, McpSource } from '../../types' defineOptions({ name: 'AiChatNodeMcpSettingDialog' }) const emit = defineEmits<{ submit: [setting: McpSetting]; loaded: [tools: ToolItem[]] }>() -const apiType = inject('apiType', 'workspace') -const store = useWorkflowStore(apiType) +const resourceScope = inject('resourceScope', 'workspace') +const store = useWorkflowStore(resourceScope) const MCP_SERVER_EXAMPLE = `{ "math": { diff --git a/ui/src/workflow-canvas/nodes/ai-chat-node/index.vue b/ui/src/workflow-canvas/nodes/ai-chat-node/index.vue index 3f4ac70ef5b..395806a3b0b 100644 --- a/ui/src/workflow-canvas/nodes/ai-chat-node/index.vue +++ b/ui/src/workflow-canvas/nodes/ai-chat-node/index.vue @@ -20,10 +20,10 @@ import { fileTooltip } from '@/workflow-canvas/config/constants' defineOptions({ name: 'WorkflowAiChatNode' }) const getModel = inject('getModel') as () => WorkflowNodeModel -const apiType = (inject('apiType') as string) || 'workspace' +const resourceScope = (inject('resourceScope') as string) || 'workspace' const workflowMode = inject('workflowMode', WorkflowMode.Application) const model = getModel() -const store = useWorkflowStore(apiType) +const store = useWorkflowStore(resourceScope) const formRef = useTemplateRef('formRef') diff --git a/ui/src/workflow-canvas/nodes/base-node/index.vue b/ui/src/workflow-canvas/nodes/base-node/index.vue index f0be92b80ca..869b392ede3 100644 --- a/ui/src/workflow-canvas/nodes/base-node/index.vue +++ b/ui/src/workflow-canvas/nodes/base-node/index.vue @@ -27,10 +27,10 @@ import { defineOptions({ name: 'WorkflowBaseNode' }) const getModel = inject('getModel') as () => WorkflowNodeModel -const apiType = (inject('apiType') as string) || 'workspace' +const resourceScope = (inject('resourceScope') as string) || 'workspace' const model = getModel() -const store = useWorkflowStore(apiType) +const store = useWorkflowStore(resourceScope) // 为画布节点中的 ModelSelect 提供参数表单接口。 provide('getModelParamsForm', store.force.getModelParamsForm) diff --git a/ui/src/workflow-canvas/nodes/form-node/index.vue b/ui/src/workflow-canvas/nodes/form-node/index.vue index ce88195bd60..5bf689fbe2a 100644 --- a/ui/src/workflow-canvas/nodes/form-node/index.vue +++ b/ui/src/workflow-canvas/nodes/form-node/index.vue @@ -9,8 +9,8 @@ import { handleNodeWheel } from '@/workflow-canvas/core/utils' import FormSettingTable from './component/form-setting/FormSettingTable.vue' import { useWorkflowStore } from '@/workflow-canvas/store' defineOptions({ name: 'WorkflowFormNode' }) -const apiType = (inject('apiType') as string) || 'workspace' -const store = useWorkflowStore(apiType) +const resourceScope = (inject('resourceScope') as string) || 'workspace' +const store = useWorkflowStore(resourceScope) const getModel = inject<() => WorkflowNodeModel>('getModel')! const model = getModel() // 为画布节点中的 ModelSelect 提供参数表单接口。 diff --git a/ui/src/workflow-canvas/nodes/image-generate-node/index.vue b/ui/src/workflow-canvas/nodes/image-generate-node/index.vue index a48ceac63ef..1b12bb96062 100644 --- a/ui/src/workflow-canvas/nodes/image-generate-node/index.vue +++ b/ui/src/workflow-canvas/nodes/image-generate-node/index.vue @@ -11,7 +11,7 @@ import { WorkflowMode } from '@/workflow-canvas/types' defineOptions({ name: 'WorkflowImageGenerateNode' }) const getModel = inject('getModel') as () => WorkflowNodeModel -const apiType = (inject('apiType') as string) || 'workspace' +const resourceScope = (inject('resourceScope') as string) || 'workspace' const workflowMode = inject('workflowMode', WorkflowMode.Application) const model = getModel() @@ -29,7 +29,7 @@ interface ImageGenerateNodeForm { const formRef = useTemplateRef('formRef') -const store = useWorkflowStore(apiType) +const store = useWorkflowStore(resourceScope) const modelList = ref>([]) const providerOptions = ref>([]) diff --git a/ui/src/workflow-canvas/nodes/image-to-video-node/index.vue b/ui/src/workflow-canvas/nodes/image-to-video-node/index.vue index 5b82d591584..73a64727bcb 100644 --- a/ui/src/workflow-canvas/nodes/image-to-video-node/index.vue +++ b/ui/src/workflow-canvas/nodes/image-to-video-node/index.vue @@ -13,7 +13,7 @@ import { WorkflowMode } from '@/workflow-canvas/types' defineOptions({ name: 'WorkflowImageToVideoNode' }) const getModel = inject('getModel') as () => WorkflowNodeModel -const apiType = (inject('apiType') as string) || 'workspace' +const resourceScope = (inject('resourceScope') as string) || 'workspace' const workflowMode = inject('workflowMode', WorkflowMode.Application) const model = getModel() @@ -33,7 +33,7 @@ interface ImageToVideoNodeForm { const formRef = useTemplateRef('formRef') -const store = useWorkflowStore(apiType) +const store = useWorkflowStore(resourceScope) const modelList = ref>([]) const providerOptions = ref>([]) diff --git a/ui/src/workflow-canvas/nodes/image-understand-node/index.vue b/ui/src/workflow-canvas/nodes/image-understand-node/index.vue index 8df920f34b5..5c2002a5b93 100644 --- a/ui/src/workflow-canvas/nodes/image-understand-node/index.vue +++ b/ui/src/workflow-canvas/nodes/image-understand-node/index.vue @@ -16,7 +16,7 @@ import { WorkflowMode, type ReasoningSettingData } from '@/workflow-canvas/types defineOptions({ name: 'WorkflowImageUnderstandNode' }) const getModel = inject('getModel') as () => WorkflowNodeModel -const apiType = (inject('apiType') as string) || 'workspace' +const resourceScope = (inject('resourceScope') as string) || 'workspace' const workflowMode = inject('workflowMode', WorkflowMode.Application) const model = getModel() @@ -36,7 +36,7 @@ interface ImageUnderstandNodeForm { const formRef = useTemplateRef('formRef') -const store = useWorkflowStore(apiType) +const store = useWorkflowStore(resourceScope) const modelList = ref>([]) const providerOptions = ref>([]) diff --git a/ui/src/workflow-canvas/nodes/intent-node/index.vue b/ui/src/workflow-canvas/nodes/intent-node/index.vue index 02c8e972ca0..f07d12e82a9 100644 --- a/ui/src/workflow-canvas/nodes/intent-node/index.vue +++ b/ui/src/workflow-canvas/nodes/intent-node/index.vue @@ -12,7 +12,7 @@ import { randomId } from '@/utils/common' defineOptions({ name: 'WorkflowIntentNode' }) const getModel = inject('getModel') as () => WorkflowNodeModel -const apiType = (inject('apiType') as string) || 'workspace' +const resourceScope = (inject('resourceScope') as string) || 'workspace' const model = getModel() const flowModel = model as unknown as { refreshBranch?: () => void } @@ -35,7 +35,7 @@ type IntentModelSetting = Pick('formRef') -const store = useWorkflowStore(apiType) +const store = useWorkflowStore(resourceScope) const modelList = ref>([]) const providerOptions = ref>([]) diff --git a/ui/src/workflow-canvas/nodes/loop-body-node/index.vue b/ui/src/workflow-canvas/nodes/loop-body-node/index.vue index be244574518..9d58bff186a 100644 --- a/ui/src/workflow-canvas/nodes/loop-body-node/index.vue +++ b/ui/src/workflow-canvas/nodes/loop-body-node/index.vue @@ -19,7 +19,7 @@ const getModel = inject('getModel') as () => BaseNodeModel const model = getModel() const parentLoopWorkflowMode = inject('loopWorkflowMode') || WorkflowMode.ApplicationLoop -const apiType = (inject('apiType') as string) || 'workspace' +const resourceScope = (inject('resourceScope') as string) || 'workspace' const currentResource = inject('currentResource') const getSelectModelList = inject<(params: { model_type: string }) => Promise>('getSelectModelList') const modelParamsForm = inject<(modelId: string) => unknown>('getModelParamsForm') @@ -133,7 +133,7 @@ const renderGraphData = (data?: LogicFlow.GraphConfigData) => { workflowMode: parentLoopWorkflowMode, loopWorkflowMode: parentLoopWorkflowMode, currentResource, - apiType, + resourceScope, getSelectModelList, getModelParamsForm: modelParamsForm, startDragNode: nestedStartDrag, diff --git a/ui/src/workflow-canvas/nodes/mcp-node/index.vue b/ui/src/workflow-canvas/nodes/mcp-node/index.vue index ea36bf0005d..ec22c7acd98 100644 --- a/ui/src/workflow-canvas/nodes/mcp-node/index.vue +++ b/ui/src/workflow-canvas/nodes/mcp-node/index.vue @@ -20,7 +20,7 @@ import { MsgError, MsgSuccess } from '@/utils/message' defineOptions({ name: 'WorkflowMcpNode' }) const getModel = inject('getModel') as () => BaseNodeModel -const apiType = (inject('apiType') as string) || 'workspace' +const resourceScope = (inject('resourceScope') as string) || 'workspace' const workflowMode = inject('workflowMode', WorkflowMode.Application) const model = getModel() as WorkflowNodeModel const route = useRoute() @@ -37,7 +37,7 @@ const mcpResource = MCP_RESOURCE[workflowMode] ?? MCP_RESOURCE[WorkflowMode.Appl const mcpResourceType = mcpResource.type const mcpResourceId = mcpResource.id() || '' -const store = useWorkflowStore(apiType) +const store = useWorkflowStore(resourceScope) interface SchemaProperty { description?: string diff --git a/ui/src/workflow-canvas/nodes/parameter-extraction-node/index.vue b/ui/src/workflow-canvas/nodes/parameter-extraction-node/index.vue index 592b196c2e1..494819f30e4 100644 --- a/ui/src/workflow-canvas/nodes/parameter-extraction-node/index.vue +++ b/ui/src/workflow-canvas/nodes/parameter-extraction-node/index.vue @@ -14,7 +14,7 @@ import type { ParameterField } from './component/parameters-field/types' defineOptions({ name: 'WorkflowParameterExtractionNode' }) const getModel = inject('getModel') as () => BaseNodeModel -const apiType = (inject('apiType') as string) || 'workspace' +const resourceScope = (inject('resourceScope') as string) || 'workspace' const model = getModel() as WorkflowNodeModel interface ParameterExtractionForm { @@ -28,7 +28,7 @@ interface ParameterExtractionForm { const parameterExtractionFormRef = useTemplateRef('parameterExtractionFormRef') -const store = useWorkflowStore(apiType) +const store = useWorkflowStore(resourceScope) const modelList = ref>([]) const providerOptions = ref>([]) diff --git a/ui/src/workflow-canvas/nodes/question-node/index.vue b/ui/src/workflow-canvas/nodes/question-node/index.vue index 7752affc7b6..de4bf918dc9 100644 --- a/ui/src/workflow-canvas/nodes/question-node/index.vue +++ b/ui/src/workflow-canvas/nodes/question-node/index.vue @@ -12,7 +12,7 @@ import { WorkflowMode } from '@/workflow-canvas/types' defineOptions({ name: 'WorkflowQuestionNode' }) const getModel = inject('getModel') as () => WorkflowNodeModel -const apiType = (inject('apiType') as string) || 'workspace' +const resourceScope = (inject('resourceScope') as string) || 'workspace' const workflowMode = inject('workflowMode', WorkflowMode.Application) const model = getModel() @@ -30,7 +30,7 @@ interface QuestionNodeForm { const formRef = useTemplateRef('formRef') -const store = useWorkflowStore(apiType) +const store = useWorkflowStore(resourceScope) const modelList = ref>([]) const providerOptions = ref>([]) diff --git a/ui/src/workflow-canvas/nodes/reranker-node/index.vue b/ui/src/workflow-canvas/nodes/reranker-node/index.vue index 53ad1f15928..20bee6c82b1 100644 --- a/ui/src/workflow-canvas/nodes/reranker-node/index.vue +++ b/ui/src/workflow-canvas/nodes/reranker-node/index.vue @@ -14,9 +14,9 @@ import type { RerankerSetting } from './types' defineOptions({ name: 'WorkflowRerankerNode' }) const getModel = inject('getModel') as () => WorkflowNodeModel -const apiType = inject('apiType', 'workspace') +const resourceScope = inject('resourceScope', 'workspace') const model = getModel() -const store = useWorkflowStore(apiType) +const store = useWorkflowStore(resourceScope) const formRef = useTemplateRef('formRef') interface RerankerForm { diff --git a/ui/src/workflow-canvas/nodes/search-document-node/index.vue b/ui/src/workflow-canvas/nodes/search-document-node/index.vue index 45a0cb87824..d1968875045 100644 --- a/ui/src/workflow-canvas/nodes/search-document-node/index.vue +++ b/ui/src/workflow-canvas/nodes/search-document-node/index.vue @@ -16,8 +16,8 @@ import type { SearchDocumentForm } from './types' defineOptions({ name: 'WorkflowSearchDocumentNode' }) const getModel = inject('getModel') as () => WorkflowNodeModel -const apiType = (inject('apiType') as string) || 'workspace' -const store = useWorkflowStore(apiType) +const resourceScope = (inject('resourceScope') as string) || 'workspace' +const store = useWorkflowStore(resourceScope) const model = getModel() const formRef = useTemplateRef('formRef') const questionCascaderRef = useTemplateRef>('questionCascaderRef') diff --git a/ui/src/workflow-canvas/nodes/speech-to-text-node/index.vue b/ui/src/workflow-canvas/nodes/speech-to-text-node/index.vue index d191214b255..4e4743059d8 100644 --- a/ui/src/workflow-canvas/nodes/speech-to-text-node/index.vue +++ b/ui/src/workflow-canvas/nodes/speech-to-text-node/index.vue @@ -13,7 +13,7 @@ import type { ModelItem, ModelProviderItem } from '@/api/types' defineOptions({ name: 'WorkflowSpeechToTextNode' }) const getModel = inject('getModel') as () => WorkflowNodeModel -const apiType = (inject('apiType') as string) || 'workspace' +const resourceScope = (inject('resourceScope') as string) || 'workspace' const workflowMode = inject('workflowMode', WorkflowMode.Application) const model = getModel() @@ -28,7 +28,7 @@ interface SpeechToTextNodeForm { const formRef = useTemplateRef('formRef') -const store = useWorkflowStore(apiType) +const store = useWorkflowStore(resourceScope) const modelList = ref>([]) const providerOptions = ref>([]) diff --git a/ui/src/workflow-canvas/nodes/text-to-speech-node/index.vue b/ui/src/workflow-canvas/nodes/text-to-speech-node/index.vue index 29b07149a53..7feba581206 100644 --- a/ui/src/workflow-canvas/nodes/text-to-speech-node/index.vue +++ b/ui/src/workflow-canvas/nodes/text-to-speech-node/index.vue @@ -12,7 +12,7 @@ import type { ModelItem, ModelProviderItem } from '@/api/types' defineOptions({ name: 'WorkflowTextToSpeechNode' }) const getModel = inject('getModel') as () => WorkflowNodeModel -const apiType = (inject('apiType') as string) || 'workspace' +const resourceScope = (inject('resourceScope') as string) || 'workspace' const workflowMode = inject('workflowMode', WorkflowMode.Application) const model = getModel() @@ -27,7 +27,7 @@ interface TextToSpeechNodeForm { const formRef = useTemplateRef('formRef') -const store = useWorkflowStore(apiType) +const store = useWorkflowStore(resourceScope) const modelList = ref>([]) const providerOptions = ref>([]) diff --git a/ui/src/workflow-canvas/nodes/text-to-video-node/index.vue b/ui/src/workflow-canvas/nodes/text-to-video-node/index.vue index d6f94458803..14feefd554f 100644 --- a/ui/src/workflow-canvas/nodes/text-to-video-node/index.vue +++ b/ui/src/workflow-canvas/nodes/text-to-video-node/index.vue @@ -11,7 +11,7 @@ import { WorkflowMode } from '@/workflow-canvas/types' defineOptions({ name: 'WorkflowTextToVideoNode' }) const getModel = inject('getModel') as () => WorkflowNodeModel -const apiType = (inject('apiType') as string) || 'workspace' +const resourceScope = (inject('resourceScope') as string) || 'workspace' const workflowMode = inject('workflowMode', WorkflowMode.Application) const model = getModel() @@ -29,7 +29,7 @@ interface TextToVideoNodeForm { const formRef = useTemplateRef('formRef') -const store = useWorkflowStore(apiType) +const store = useWorkflowStore(resourceScope) const modelList = ref>([]) const providerOptions = ref>([]) diff --git a/ui/src/workflow-canvas/nodes/tool-lib-node/index.vue b/ui/src/workflow-canvas/nodes/tool-lib-node/index.vue index 68ccb21cada..999ab67cbda 100644 --- a/ui/src/workflow-canvas/nodes/tool-lib-node/index.vue +++ b/ui/src/workflow-canvas/nodes/tool-lib-node/index.vue @@ -26,7 +26,7 @@ interface ToolLibNodeForm { const getModel = inject('getModel') as () => WorkflowNodeModel const workflowMode = inject('workflowMode', WorkflowMode.Application) const model = getModel() -const store = useWorkflowStore(inject('apiType', 'workspace')) +const store = useWorkflowStore(inject('resourceScope', 'workspace')) const formRef = useTemplateRef('formRef') diff --git a/ui/src/workflow-canvas/nodes/tool-workflow-lib-node/index.vue b/ui/src/workflow-canvas/nodes/tool-workflow-lib-node/index.vue index 7c7ee947470..1c9e71f0632 100644 --- a/ui/src/workflow-canvas/nodes/tool-workflow-lib-node/index.vue +++ b/ui/src/workflow-canvas/nodes/tool-workflow-lib-node/index.vue @@ -31,7 +31,7 @@ interface ToolBaseProperties { const getModel = inject<() => WorkflowNodeModel>('getModel')! const workflowMode = inject('workflowMode', WorkflowMode.Application) -const store = useWorkflowStore(inject('apiType', 'workspace')) +const store = useWorkflowStore(inject('resourceScope', 'workspace')) const model = getModel() const formRef = useTemplateRef('formRef') const anchorGuard = createAnchorGuard(model) diff --git a/ui/src/workflow-canvas/nodes/video-understand-node/index.vue b/ui/src/workflow-canvas/nodes/video-understand-node/index.vue index 41d6adff9ad..76b6bc05e9e 100644 --- a/ui/src/workflow-canvas/nodes/video-understand-node/index.vue +++ b/ui/src/workflow-canvas/nodes/video-understand-node/index.vue @@ -16,7 +16,7 @@ import { WorkflowMode, type ReasoningSettingData } from '@/workflow-canvas/types defineOptions({ name: 'WorkflowVideoUnderstandNode' }) const getModel = inject('getModel') as () => WorkflowNodeModel -const apiType = (inject('apiType') as string) || 'workspace' +const resourceScope = (inject('resourceScope') as string) || 'workspace' const workflowMode = inject('workflowMode', WorkflowMode.Application) const model = getModel() @@ -36,7 +36,7 @@ interface VideoUnderstandNodeForm { const formRef = useTemplateRef('formRef') -const store = useWorkflowStore(apiType) +const store = useWorkflowStore(resourceScope) const modelList = ref>([]) const providerOptions = ref>([]) diff --git a/ui/src/workflow-canvas/store/index.ts b/ui/src/workflow-canvas/store/index.ts index f365065fdfc..c16e804a152 100644 --- a/ui/src/workflow-canvas/store/index.ts +++ b/ui/src/workflow-canvas/store/index.ts @@ -47,18 +47,18 @@ const apiMap = Object.fromEntries( const cacheMap = new Map>() const pendingMap = new Map>>() -export function useWorkflowStore(apiType: string): WorkflowStore { - const api: ApiModule | undefined = apiMap[apiType] +export function useWorkflowStore(resourceScope: string): WorkflowStore { + const api: ApiModule | undefined = apiMap[resourceScope] if (!api) { - throw new Error(`[useWorkflowStore] unknown apiType: "${apiType}"`) + throw new Error(`[useWorkflowStore] unknown resourceScope: "${resourceScope}"`) } const requestApi: ApiModule = api - const cache = cacheMap.get(apiType) ?? new Map() - cacheMap.set(apiType, cache) + const cache = cacheMap.get(resourceScope) ?? new Map() + cacheMap.set(resourceScope, cache) - const pending = pendingMap.get(apiType) ?? new Map>() - pendingMap.set(apiType, pending) + const pending = pendingMap.get(resourceScope) ?? new Map>() + pendingMap.set(resourceScope, pending) // 统一的缓存 + 请求去重逻辑。force 时跳过缓存读取并覆盖缓存,但仍复用在途请求以避免重复触发。 function withCache(key: string, fetcher: () => Promise, force = false): Promise {