diff --git a/ui/AGENTS.md b/ui/AGENTS.md index ebcc08e79ce..7f818063aac 100644 --- a/ui/AGENTS.md +++ b/ui/AGENTS.md @@ -193,6 +193,7 @@ Node.js must satisfy `^22.18.0 || >=24.12.0` as declared in `package.json`. Admin and Chat use ports 3000 and 3001 respectively, with `strictPort` enabled. `npm run lint` currently delegates to `lint:*`, but no matching scripts are defined. Use `npx eslint ` for targeted linting until those scripts are configured. +ESLint enforces multi-word Vue component names, with `index` globally exempted in `eslint.config.ts`. ## Vite Configuration diff --git a/ui/eslint.config.ts b/ui/eslint.config.ts index 89fdc89a24e..da8fbf06eb8 100644 --- a/ui/eslint.config.ts +++ b/ui/eslint.config.ts @@ -23,4 +23,10 @@ export default defineConfigWithVueTs( ...pluginOxlint.buildFromOxlintConfigFile('.oxlintrc.json'), skipFormatting, + + { + rules: { + 'vue/multi-word-component-names': ['error', { ignores: ['index'] }], + }, + }, ) diff --git a/ui/src/api/API_README.md b/ui/src/api/API_README.md index 4a9984e15aa..df58e6b0921 100644 --- a/ui/src/api/API_README.md +++ b/ui/src/api/API_README.md @@ -162,6 +162,30 @@ v3 编辑表单提交 `{ name, description }`,标题上限 64、更新说明 共享工具 API 不提供工作空间文件夹移动或批量接口;复用卡片、Action 和表单接收完整 Workspace 与 System 共享 API 的联合类型,不补造接口以匹配 Workspace 方法集合。 +### 工具代码生成 + +三个范围的 `tool/tool.ts` 均提供 `postToolGenerateCode(payload)`,沿用 v2 的 +`/workspace//tool/generate_code`、`/system/resource/tool/generate_code` 和 +`/system/shared/tool/generate_code`。无需工具或智能体 ID,创建中的工具也可生成代码。 +`ToolGenerateCodePayload`、`ToolGenerateMessage` 定义在 `types/tool.ts`;请求包含 `messages`、 +`prompt`、`init_field_list`、`input_field_list`、`model_id` 和 `model_params_setting`。 +返回原始 SSE Response,业务入口通过 `request(messages)` 回调交给 `GenerateContent`, +公共组件复用 `ConversationStream` 读取数据,处理 `content` 和 `error` 数据块。 +停止生成与 AI 节点一致,通过 `ConversationStream.cancel()` 停止读取并清理流实例。 +工具表单组件 `ToolCodeGenerate` 内部通过资源上下文选择完整 Tool/Model API; +调用方只传工具表单,不逐层传递 API、工作空间及参数列表。 + +### 系统提示词生成 + +Workspace、System 资源管理和 System 共享资源的 `application/application.ts` 均提供 +`postPromptGenerate(applicationId, modelId, payload)`,请求结构共用 `PromptGeneratePayload`。 +路径分别为 `/workspace//application//model//prompt_generate`、 +`/system/resource/application//model//prompt_generate` 和 +`/system/shared/application//model//prompt_generate`,System 接口不依赖工作空间 ID。 +均返回原始 SSE Response,由公共生成组件读取。画布的 `PromptGenerate` 通过 +`useWorkflowStore(apiType).postPromptGenerate` 调用;三个范围的 Store 适配器分别引用对应的 +Application API,直接转发生成请求,不使用查询缓存或请求去重。 + ### 知识库维护 `getKnowledgeMcpConfig(knowledgeId)` 与 `postKnowledgeKeywordIndex(knowledgeId)` 为预留接口方法, diff --git a/ui/src/api/admin/system/resource-management/application/application.ts b/ui/src/api/admin/system/resource-management/application/application.ts new file mode 100644 index 00000000000..3f1d9b40f19 --- /dev/null +++ b/ui/src/api/admin/system/resource-management/application/application.ts @@ -0,0 +1,14 @@ +import { postStream } from '@/api/admin/core/request' +import type { PromptGeneratePayload } from '@/api/types' +import { ADMIN_API_BASE_PATH } from '@/api/constants' + +const prefix = '/system/resource/application' + +/** 使用指定模型流式生成或优化 System 资源智能体的系统提示词。 */ +const postPromptGenerate = (applicationId: string, modelId: string, payload: PromptGeneratePayload) => { + return postStream(ADMIN_API_BASE_PATH, `${prefix}/${applicationId}/model/${modelId}/prompt_generate`, payload) +} + +export default { + postPromptGenerate, +} diff --git a/ui/src/api/admin/system/resource-management/tool/tool.ts b/ui/src/api/admin/system/resource-management/tool/tool.ts index f3bad309600..8076a54f872 100644 --- a/ui/src/api/admin/system/resource-management/tool/tool.ts +++ b/ui/src/api/admin/system/resource-management/tool/tool.ts @@ -1,6 +1,7 @@ -import { del, downloadRequest, getExportFile, get, post, put } from '../../../core/request' +import { del, downloadRequest, getExportFile, get, post, postStream, put } from '../../../core/request' import type { ParamsPage, ResponsePage } from '../../../core/types' -import type { Dict, ToolDebugPayload, ToolItem, ToolPayload, ToolPylintIssue } from '@/api/types' +import type { Dict, ToolDebugPayload, ToolGenerateCodePayload, ToolItem, ToolPayload, ToolPylintIssue } from '@/api/types' +import { ADMIN_API_BASE_PATH } from '@/api/constants' const prefix = '/system/resource/tool' @@ -28,6 +29,11 @@ const postToolPylint = (code: string) => { return post<{ code: string }, ToolPylintIssue[]>(`${prefix}/pylint`, { code }) } +/** 根据需求与参数定义流式生成 System 资源工具 Python 代码。 */ +const postToolGenerateCode = (payload: ToolGenerateCodePayload) => { + return postStream(ADMIN_API_BASE_PATH, `${prefix}/generate_code`, payload) +} + /** 调试普通工具代码并返回运行结果。 */ const postToolDebug = (payload: ToolDebugPayload) => { return post(`${prefix}/debug`, payload) @@ -68,6 +74,7 @@ export default { getToolDetail, downloadSkillFile, postToolDebug, + postToolGenerateCode, putUploadSkillFile, postToolPylint, postToolTestConnection, diff --git a/ui/src/api/admin/system/shared-resources/application/application.ts b/ui/src/api/admin/system/shared-resources/application/application.ts new file mode 100644 index 00000000000..b30d9f02d8e --- /dev/null +++ b/ui/src/api/admin/system/shared-resources/application/application.ts @@ -0,0 +1,14 @@ +import { postStream } from '@/api/admin/core/request' +import type { PromptGeneratePayload } from '@/api/types' +import { ADMIN_API_BASE_PATH } from '@/api/constants' + +const prefix = '/system/shared/application' + +/** 使用指定模型流式生成或优化 System 共享智能体的系统提示词。 */ +const postPromptGenerate = (applicationId: string, modelId: string, payload: PromptGeneratePayload) => { + return postStream(ADMIN_API_BASE_PATH, `${prefix}/${applicationId}/model/${modelId}/prompt_generate`, payload) +} + +export default { + postPromptGenerate, +} diff --git a/ui/src/api/admin/system/shared-resources/tool/tool.ts b/ui/src/api/admin/system/shared-resources/tool/tool.ts index 9a2df1f3e1a..df2209b2711 100644 --- a/ui/src/api/admin/system/shared-resources/tool/tool.ts +++ b/ui/src/api/admin/system/shared-resources/tool/tool.ts @@ -1,6 +1,7 @@ -import { del, downloadRequest, getExportFile, get, post, put } from '../../../core/request' +import { del, downloadRequest, getExportFile, get, post, postStream, put } from '../../../core/request' import type { ParamsPage, ResponsePage } from '../../../core/types' -import type { Dict, ToolDebugPayload, ToolItem, ToolPayload, ToolPylintIssue } from '@/api/types' +import type { Dict, ToolDebugPayload, ToolGenerateCodePayload, ToolItem, ToolPayload, ToolPylintIssue } from '@/api/types' +import { ADMIN_API_BASE_PATH } from '@/api/constants' const prefix = '/system/shared/tool' @@ -33,6 +34,11 @@ const postToolPylint = (code: string) => { return post<{ code: string }, ToolPylintIssue[]>(`${prefix}/pylint`, { code }) } +/** 根据需求与参数定义流式生成 System 共享工具 Python 代码。 */ +const postToolGenerateCode = (payload: ToolGenerateCodePayload) => { + return postStream(ADMIN_API_BASE_PATH, `${prefix}/generate_code`, payload) +} + /** 调试普通工具代码并返回运行结果。 */ const postToolDebug = (payload: ToolDebugPayload) => { return post(`${prefix}/debug`, payload) @@ -82,6 +88,7 @@ export default { downloadSkillFile, postTool, postToolDebug, + postToolGenerateCode, postToolImport, putUploadSkillFile, postToolPylint, diff --git a/ui/src/api/admin/workspace/tool/tool.ts b/ui/src/api/admin/workspace/tool/tool.ts index 2cd2d3803ce..71fbbe3a644 100644 --- a/ui/src/api/admin/workspace/tool/tool.ts +++ b/ui/src/api/admin/workspace/tool/tool.ts @@ -1,6 +1,7 @@ -import { del, downloadRequest, getExportFile, get, post, put } from '../../core/request' +import { del, downloadRequest, getExportFile, get, post, postStream, put } from '../../core/request' import type { ParamsPage, ResponsePage } from '../../core/types' -import type { Dict, ToolDebugPayload, ToolItem, ToolPayload, ToolPylintIssue } from '@/api/types' +import type { Dict, ToolDebugPayload, ToolGenerateCodePayload, ToolItem, ToolPayload, ToolPylintIssue } from '@/api/types' +import { ADMIN_API_BASE_PATH } from '@/api/constants' import { getWorkspaceId } from '@/utils/resource-context' const getPrefix = () => { @@ -46,10 +47,10 @@ const postToolPylint = (code: string) => { return post<{ code: string }, ToolPylintIssue[]>(`${getPrefix()}/pylint`, { code }) } -// const generateCode = (data: any) => { -// const p = (window.MaxKB?.prefix ? window.MaxKB?.prefix : '/admin') + '/api' -// return postStream(`${p}${getPrefix()}/generate_code`, data) -// } +/** 根据需求与参数定义流式生成工具 Python 代码。 */ +const postToolGenerateCode = (payload: ToolGenerateCodePayload) => { + return postStream(ADMIN_API_BASE_PATH, `${getPrefix()}/generate_code`, payload) +} /** 调试普通工具代码并返回运行结果。 */ const postToolDebug = (payload: ToolDebugPayload) => { @@ -110,6 +111,7 @@ export default { postTool, postToolDebug, + postToolGenerateCode, postToolImport, putUploadSkillFile, postToolPylint, diff --git a/ui/src/api/types/tool.ts b/ui/src/api/types/tool.ts index 2381292c651..cd50521d59b 100644 --- a/ui/src/api/types/tool.ts +++ b/ui/src/api/types/tool.ts @@ -31,6 +31,21 @@ export interface ToolDebugPayload { input_field_list: ToolInputField[] } +export interface ToolGenerateMessage { + content: string + role: 'user' | 'ai' +} + +/** 工具代码生成沿用 v2 的模型、参数定义与多轮消息协议。 */ +export interface ToolGenerateCodePayload { + messages: ToolGenerateMessage[] + prompt: string + model_id: string + model_params_setting: Record + init_field_list: DynamicFormField[] + input_field_list: ToolInputField[] +} + export interface ToolPylintIssue { column: number endColumn: number diff --git a/ui/src/components/COMPONENT_README.md b/ui/src/components/COMPONENT_README.md index ff1f19446f4..e078fb26b10 100644 --- a/ui/src/components/COMPONENT_README.md +++ b/ui/src/components/COMPONENT_README.md @@ -484,6 +484,8 @@ Python 与 JSON 编辑器通过 ` diff --git a/ui/src/views/tool/tool-form/tool-custom/ToolFormDrawer.vue b/ui/src/views/tool/tool-form/tool-custom/ToolFormDrawer.vue index d1ce2fca5c1..40b54759bad 100644 --- a/ui/src/views/tool/tool-form/tool-custom/ToolFormDrawer.vue +++ b/ui/src/views/tool/tool-form/tool-custom/ToolFormDrawer.vue @@ -2,7 +2,7 @@ import { reactive, ref } from 'vue' import { cloneDeep } from 'lodash' import type { FormInstance, FormRules } from 'element-plus' -import type { DynamicFormField, ToolInputField, ToolItem, ToolPayload } from '@/api/types' +import type { DynamicFormField, ToolInputField, ToolItem } from '@/api/types' import type ToolApi from '@/api/admin/workspace/tool/tool' import type SystemResourceToolApi from '@/api/admin/system/resource-management/tool/tool' import type SystemSharedToolApi from '@/api/admin/system/shared-resources/tool/tool' @@ -11,7 +11,7 @@ import { MsgConfirm, MsgSuccess } from '@/utils/message' import ToolDebugDrawer from './ToolDebugDrawer.vue' import InitFieldTable from '../component/init-field/InitFieldTable.vue' import InputFieldTable from '../component/input-field/InputFieldTable.vue' -import ToolCodeSetting from '../component/python-code/CodeSetting.vue' +import ToolCodeGenerate from '../component/python-code/CodeGenerate.vue' defineOptions({ name: 'ToolFormDrawer' }) @@ -22,6 +22,7 @@ const props = defineProps<{ api: typeof ToolApi | typeof SystemSharedToolApi | t const emit = defineEmits<{ closed: []; refresh: []; update: [tool: ToolItem] }>() interface ToolFormModel { + workspace_id?: string desc: string code: string icon: string @@ -49,7 +50,8 @@ function handleSubmit() { if (!valid) return loading.value = true - const payload: ToolPayload = cloneDeep(toolForm) + const payload = cloneDeep(toolForm) + delete payload.workspace_id const currentEditId = editId.value const isEdit = Boolean(currentEditId) const request = currentEditId @@ -83,6 +85,7 @@ function handleOpenDebug() { function fillToolForm(tool: ToolItem) { Object.assign(toolForm, { + workspace_id: tool.workspace_id, code: tool.code ?? '', desc: tool.desc ?? '', icon: tool.icon ?? '', @@ -131,7 +134,7 @@ function handleBeforeClose() { } function resetData() { - Object.assign(toolForm, { name: '', desc: '', code: '', icon: '', init_field_list: [], input_field_list: [] }) + Object.assign(toolForm, { name: '', desc: '', code: '', icon: '', init_field_list: [], input_field_list: [], workspace_id: undefined }) editId.value = undefined originalForm.value = '' loading.value = false @@ -189,7 +192,7 @@ defineExpose({ open }) - +

输出参数

diff --git a/ui/src/views/workflow/tool/debug/ResultDrawer.vue b/ui/src/views/workflow/tool/debug/ResultDrawer.vue index 0caedd77388..7981875aecb 100644 --- a/ui/src/views/workflow/tool/debug/ResultDrawer.vue +++ b/ui/src/views/workflow/tool/debug/ResultDrawer.vue @@ -152,7 +152,6 @@ defineExpose({ open, close }) - diff --git a/ui/src/workflow-canvas/WORKFLOW_README.md b/ui/src/workflow-canvas/WORKFLOW_README.md index ce8373b6738..0a58113fb4c 100644 --- a/ui/src/workflow-canvas/WORKFLOW_README.md +++ b/ui/src/workflow-canvas/WORKFLOW_README.md @@ -127,8 +127,10 @@ LogicFlow 的节点拖拽;仅拦截 `mousedown` 无法隔离当前版本的 Po ### 资源查询(`store/`) -`useWorkflowStore(apiType)` 是画布查询适配器,不是 Pinia Store。它自动收集 `store/api/*/index.ts`, -按范围、方法与查询参数缓存结果并复用在途请求;`store.force.xxx()` 跳过已完成缓存,仍复用同键在途请求。 +`useWorkflowStore(apiType)` 是画布资源接口适配器,不是 Pinia Store。它自动收集 `store/api/*/index.ts`, +查询方法按范围、方法与查询参数缓存结果并复用在途请求;`store.force.xxx()` 跳过已完成缓存,仍复用同键在途请求。 +`postPromptGenerate` 是流式生成方法,始终直接转发到对应范围的 Application API,不缓存或去重; +通过普通 Store 或 `force` 调用都会发起新请求,返回独立的 Response 流。 模型选项统一调用 `store.getModelListWithShared(query)`,由 API 合并工作空间和已授权共享模型; 强制刷新使用 `store.force.getModelListWithShared(query)`。动态表单配置器通过 `getSelectModelList` 注入使用该能力,循环体转发同名注入。 @@ -314,16 +316,22 @@ ID 数组及 `tool_list`、`skill_tool_list`、`application_list` 回显快照 读取资源配置、通过 `update` 提交局部变更;资源选项由 Props 传入,未接入数据源时默认为空数组。 AI 对话节点的提示词、历史记录、视觉理解和输出思考表单直接在节点入口维护,统一使用全局 -`MdEditorMagnify` 和节点表单样式;`component/PromptGenerate.vue` 同时封装生成按钮与弹窗, -接收 `modelId`、`disabled`、`modelOptions` 和 `providerOptions`,内部读取当前路由的智能体 ID。 -弹窗顶部复用 `SelectModel`,仅修改本次生成使用的模型;主体展示最新结果与主题输入框,支持停止和重新生成。 -重新生成复用上次请求消息,关闭时终止请求并在关闭动画结束后清理会话;点击替换后通过 `replace` 交由节点回写系统提示词。 -生成接口沿用智能体已保存的参数,弹窗不提供独立模型参数设置。 -主题输入直接在 `PromptGenerate.vue` 内使用 Element Plus 自适应文本域与底部发送/停止按钮, -通过本地输入值、模型和智能体状态控制提交;Enter 发送,Ctrl/Shift/Alt/Meta + Enter 在光标处换行, -输入法组合期间不提交,纯空白内容不可发送。 -长文本使用原生纯文本粘贴,输入上限为 100000 字符,不转为附件事件;输入框的键盘和粘贴事件 -停止冒泡,避免触发画布快捷键或节点粘贴。 +`MdEditorMagnify` 和节点表单样式。AI 对话、图片理解和视频理解的系统提示词生成统一使用 +`workflow-canvas/component/PromptGenerate.vue`,内部复用公共业务组件 `GenerateContent`。 +节点只传 `modelId` 并监听 `replace` 回写自己的 `system`;默认模型从当前工作流配置读取, +自定义模型使用节点配置的模型 ID,引用变量无法在编辑时确定模型,生成入口禁用。 +图片理解和视频理解使用 IMAGE 模型,AI 对话使用 LLM 模型,现有提示词接口支持这两种类型。 +共享组件维护提示词模板和请求上下文,不依赖某个节点,也不接收未使用的模型或供应商选项。 +组件将画布注入的 `apiType` 传给 `useWorkflowStore`,通过 `store.postPromptGenerate` 发起生成; +Store 适配器统一选择 Workspace、System 资源管理或 System 共享资源的 Application API。 +循环画布已转发同一上下文,组件不再单独判断资源范围。生成方法不使用 Store 的查询缓存或请求去重。 +接口仍要求当前路由的智能体 ID,生成使用智能体已保存的模型参数;没有智能体 ID 时禁用入口, +工具和知识库工作流尚未接入对应的提示词生成接口。弹窗不提供独立模型或参数设置。 +公共组件统一维护主题输入、会话消息与 `ConversationStream`;重新生成在历史中追加用户消息 +`Re generate` 后请求,停止通过 `cancel()` 终止读取,关闭动画结束后清理会话。 +点击替换后通过 `replace` 交由节点回写系统提示词。 +Enter 发送、组合键换行、输入法保护、纯空白校验及文本粘贴统一遵循公共组件约定, +键盘和粘贴事件停止冒泡,避免触发画布快捷键或节点粘贴。 AI 对话、图片理解和视频理解统一复用 `component/ThinkingSetting.vue`,后续同类入口也应复用。 组件通过 `v-model` 接收 `types.ts` 的 `ReasoningSettingData`,由节点的输出思考开关以 `v-if` 挂载, 遵循通用设置弹窗规则;开始、结束标签当前不设必填。 diff --git a/ui/src/workflow-canvas/component/PromptGenerate.vue b/ui/src/workflow-canvas/component/PromptGenerate.vue new file mode 100644 index 00000000000..0e6de328106 --- /dev/null +++ b/ui/src/workflow-canvas/component/PromptGenerate.vue @@ -0,0 +1,115 @@ + + + diff --git a/ui/src/workflow-canvas/nodes/ai-chat-node/component/PromptGenerate.vue b/ui/src/workflow-canvas/nodes/ai-chat-node/component/PromptGenerate.vue deleted file mode 100644 index 7f94dfdf305..00000000000 --- a/ui/src/workflow-canvas/nodes/ai-chat-node/component/PromptGenerate.vue +++ /dev/null @@ -1,252 +0,0 @@ - - - - - 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 3bc2f81819e..f5ac118774e 100644 --- a/ui/src/workflow-canvas/nodes/ai-chat-node/index.vue +++ b/ui/src/workflow-canvas/nodes/ai-chat-node/index.vue @@ -10,7 +10,7 @@ import { handleNodeWheel, isLastNode } from '@/workflow-canvas/core/utils' import type { WorkflowNodeModel } from '@/workflow-canvas/core/workflow-node' import { useWorkflowStore } from '@/workflow-canvas/store' import { WorkflowMode } from '@/workflow-canvas/types' -import PromptGenerate from './component/PromptGenerate.vue' +import PromptGenerate from '@/workflow-canvas/component/PromptGenerate.vue' import ThinkingSetting from '@/workflow-canvas/component/ThinkingSetting.vue' import ResourceSetting from './component/resource-setting/index.vue' import type { AiChatNodeForm } from './types' @@ -98,6 +98,12 @@ model.properties.node_data = normalizedForm const formData = computed(() => model.properties.node_data as AiChatNodeForm) +// 提示词生成使用当前生效的模型;引用变量在运行前无法确定模型。 +const promptModelId = computed(() => { + if (formData.value.model_id_type === 'reference') return '' + return formData.value.model_id_type === 'default' ? (model.getDefaultModelConfig('LLM')?.model_id ?? '') : formData.value.model_id +}) + const showSettings = computed(() => [WorkflowMode.Application, WorkflowMode.ApplicationLoop, WorkflowMode.Tool, WorkflowMode.ToolLoop].includes(workflowMode), ) @@ -143,13 +149,8 @@ onMounted(() => {
- - + + ({ set: (value) => (model.properties.node_data = value), }) +// 提示词生成使用当前生效的模型;引用变量在运行前无法确定模型。 +const promptModelId = computed(() => { + if (formData.value.model_id_type === 'reference') return '' + return formData.value.model_id_type === 'default' ? (model.getDefaultModelConfig('IMAGE')?.model_id ?? '') : formData.value.model_id +}) + const showSettings = computed(() => [WorkflowMode.Application, WorkflowMode.ApplicationLoop, WorkflowMode.Tool, WorkflowMode.ToolLoop].includes(workflowMode), ) @@ -130,10 +137,8 @@ onMounted(() => {
- - - - + +
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 56a787e75bb..faf04c0f8f6 100644 --- a/ui/src/workflow-canvas/nodes/video-understand-node/index.vue +++ b/ui/src/workflow-canvas/nodes/video-understand-node/index.vue @@ -5,6 +5,7 @@ import type { FormInstance } from 'element-plus' import type { ModelItem, ModelProviderItem } from '@/api/types' import NodeModelSelect from '@/workflow-canvas/component/node-model-select/index.vue' import ThinkingSetting from '@/workflow-canvas/component/ThinkingSetting.vue' +import PromptGenerate from '@/workflow-canvas/component/PromptGenerate.vue' import { fileTooltip } from '@/workflow-canvas/config/constants' import NodeCascader from '@/workflow-canvas/component/NodeCascader.vue' import NodeContainer from '@/workflow-canvas/core/node-container/index.vue' @@ -81,6 +82,12 @@ const formData = computed({ set: (value) => (model.properties.node_data = value), }) +// 提示词生成使用当前生效的模型;引用变量在运行前无法确定模型。 +const promptModelId = computed(() => { + if (formData.value.model_id_type === 'reference') return '' + return formData.value.model_id_type === 'default' ? (model.getDefaultModelConfig('IMAGE')?.model_id ?? '') : formData.value.model_id +}) + const showSettings = computed(() => [WorkflowMode.Application, WorkflowMode.ApplicationLoop, WorkflowMode.Tool, WorkflowMode.ToolLoop].includes(workflowMode), ) @@ -129,10 +136,8 @@ onMounted(() => {
- - - - + +
diff --git a/ui/src/workflow-canvas/store/api/system-resource/index.ts b/ui/src/workflow-canvas/store/api/system-resource/index.ts index 3c18b913609..72bd5e036ba 100644 --- a/ui/src/workflow-canvas/store/api/system-resource/index.ts +++ b/ui/src/workflow-canvas/store/api/system-resource/index.ts @@ -1,6 +1,7 @@ import { get, post } from '@/api/admin/core/request' import type { KnowledgeTagGroup } from '@/api/types' import type { McpTool } from '@/workflow-canvas/store' +import ApplicationApi from '@/api/admin/system/resource-management/application/application' import ModelApi from '@/api/admin/system/resource-management/model' import ToolApi from '@/api/admin/system/resource-management/tool/tool' import ProviderApi from '@/api/admin/model-provider' @@ -13,6 +14,7 @@ const getMcpTools = (resourceType: string, resourceId: string, mcpServers: strin const getAllTags = (knowledgeIds: string[]) => get('/system/resource/knowledge/tags', { 'knowledge_ids[]': knowledgeIds }) export default { + postPromptGenerate: ApplicationApi.postPromptGenerate, getMcpTools, getAllTags, getModelListWithShared: ModelApi.getModelListWithShared, diff --git a/ui/src/workflow-canvas/store/api/system-shared/index.ts b/ui/src/workflow-canvas/store/api/system-shared/index.ts index d91e5104905..e733b9e640f 100644 --- a/ui/src/workflow-canvas/store/api/system-shared/index.ts +++ b/ui/src/workflow-canvas/store/api/system-shared/index.ts @@ -1,6 +1,7 @@ import { get, post } from '@/api/admin/core/request' import type { KnowledgeTagGroup } from '@/api/types' import type { McpTool } from '@/workflow-canvas/store' +import ApplicationApi from '@/api/admin/system/shared-resources/application/application' import ModelApi from '@/api/admin/system/shared-resources/model' import ToolApi from '@/api/admin/system/shared-resources/tool/tool' import ProviderApi from '@/api/admin/model-provider' @@ -13,6 +14,7 @@ const getMcpTools = (resourceType: string, resourceId: string, mcpServers: strin const getAllTags = (knowledgeIds: string[]) => get('/system/shared/knowledge/tags', { 'knowledge_ids[]': knowledgeIds }) export default { + postPromptGenerate: ApplicationApi.postPromptGenerate, getMcpTools, getAllTags, getModelListWithShared: ModelApi.getModelList, diff --git a/ui/src/workflow-canvas/store/api/workspace/index.ts b/ui/src/workflow-canvas/store/api/workspace/index.ts index 7434a9fb3f8..bdc6de9e1f5 100644 --- a/ui/src/workflow-canvas/store/api/workspace/index.ts +++ b/ui/src/workflow-canvas/store/api/workspace/index.ts @@ -1,5 +1,6 @@ import { get, post } from '@/api/admin/core/request' import type { KnowledgeTagGroup } from '@/api/types' +import ApplicationApi from '@/api/admin/workspace/application/application' import modelAPI from '@/api/admin/workspace/model' import providerAPI from '@/api/admin/model-provider' import toolAPI from '@/api/admin/workspace/tool/tool' @@ -20,6 +21,7 @@ const getAllTags = (knowledgeIds: string[]) => { } export default { + postPromptGenerate: ApplicationApi.postPromptGenerate, getModelListWithShared: modelAPI.getModelListWithShared, getProviderList: providerAPI.getProviderList, getModelParamsForm: modelAPI.getModelParamsForm, diff --git a/ui/src/workflow-canvas/store/index.ts b/ui/src/workflow-canvas/store/index.ts index 132e37263bf..ad939f026c7 100644 --- a/ui/src/workflow-canvas/store/index.ts +++ b/ui/src/workflow-canvas/store/index.ts @@ -1,4 +1,4 @@ -import type { Dict, DynamicFormField, KnowledgeTagGroup, ModelItem, ModelProviderItem, ToolItem } from '@/api/types' +import type { Dict, DynamicFormField, KnowledgeTagGroup, ModelItem, ModelProviderItem, PromptGeneratePayload, ToolItem } from '@/api/types' export interface McpTool { args_schema: Record @@ -17,9 +17,10 @@ type ApiModule = { getToolListWithShared?: (query?: Dict) => Promise getToolById?: (toolId: string) => Promise getKnowledgeTags?: (knowledgeIds: string[]) => Promise + postPromptGenerate: (applicationId: string, modelId: string, payload: PromptGeneratePayload) => Promise } -// useWorkflowStore 返回的包装接口:默认走缓存,通过 store.force.xxx() 强制刷新。 +// 查询默认走缓存,通过 store.force.xxx() 强制刷新;生成请求始终直接转发。 export type WorkflowStoreApi = { getAllTags: (knowledgeIds: string[]) => Promise getModelListWithShared: (query?: Dict) => Promise @@ -29,6 +30,7 @@ export type WorkflowStoreApi = { getToolListWithShared: (query?: Dict) => Promise getToolById: (toolId: string) => Promise getKnowledgeTags: (knowledgeIds: string[]) => Promise + postPromptGenerate: (applicationId: string, modelId: string, payload: PromptGeneratePayload) => Promise } type WorkflowStore = WorkflowStoreApi & { force: WorkflowStoreApi } @@ -76,6 +78,8 @@ export function useWorkflowStore(apiType: string): WorkflowStore { // 生成一组接口方法;force 为 true 时对应的调用会跳过缓存强制刷新。 function build(force: boolean): WorkflowStoreApi { return { + // 每次生成都需要独立的响应流,不缓存或复用在途请求。 + postPromptGenerate: requestApi.postPromptGenerate, getAllTags(knowledgeIds: string[]): Promise { if (!requestApi.getAllTags) return Promise.resolve([]) return withCache(`knowledge-tags:${JSON.stringify(knowledgeIds)}`, () => requestApi.getAllTags!(knowledgeIds), force)