Fix 4.14.x#6898
Conversation
* fix: ts * fix review * fix: form input icon store * perf: variables * perf: workflow file upload * fix: test * fix: icon refresh * add time in preview * perf: fix review * fix: file selector reference
Coverage Report
File CoverageNo changed files found. |
There was a problem hiding this comment.
Pull request overview
This PR updates the file-upload and workflow-variable pipelines to prevent signed/preview URLs and UI-only file metadata from being persisted, while also standardizing upload presign responses to include a previewUrl. It introduces a unified WorkflowVariableState to consistently manage runtime vs. stored variable representations (notably for file and password variables) across root workflows, child workflows, tools, plugins, loops, and parallel runs.
Changes:
- Add
previewUrlto S3 presigned upload responses and refactor callers to use it instead of making separate “get preview” requests. - Introduce
WorkflowVariableStateand refactor workflow dispatch to read/write variables throughvariableStatewith runtime/store conversion (esp. file/password). - Add a new
FileSelectorsanitization layer + extensive unit tests to ensure only storable file values are emitted/stored.
Reviewed changes
Copilot reviewed 78 out of 78 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| test/mocks/common/s3.ts | Updates S3 chat source mocks (incl. preview URL getter) for tests. |
| projects/app/test/components/core/chat/ChatContainer/ChatBox/utils.test.ts | Adds unit test for stripping signed URLs from chat values before sending. |
| projects/app/test/components/core/app/FileSelector/utils.test.ts | Adds comprehensive tests for FileSelector sanitization and upload/preview state helpers. |
| projects/app/src/web/core/dataset/api/file.ts | Aligns dataset upload presign API typing with shared S3 presign response type. |
| projects/app/src/pages/api/core/dataset/file/presignDatasetFilePostUrl.ts | Returns S3 upload presign response directly with updated response type. |
| projects/app/src/pages/api/core/chat/team/init.ts | Reuses computed appChatConfig and presigns variables based on resolved config variables. |
| projects/app/src/pages/api/core/chat/outLink/init.ts | Same as team init: reuse computed chat config + presign variable files using resolved config. |
| projects/app/src/pages/api/core/chat/init.ts | Same refactor for standard chat init path. |
| projects/app/src/pages/api/core/chat/helperBot/getRecords.ts | Adds preview URLs to helper-bot histories before returning. |
| projects/app/src/pages/api/core/chat/helperBot/getFilePresign.ts | Simplifies handler signature and returns S3 presign directly. |
| projects/app/src/pageComponents/dashboard/skill/detail/preview/usePreviewFileUpload.tsx | Uses previewUrl from upload presign instead of separate preview API call. |
| projects/app/src/components/core/chat/HelperBot/hooks/useFileUpload.tsx | Uses previewUrl returned from presign response; removes extra preview request. |
| projects/app/src/components/core/chat/HelperBot/api.ts | Removes helper-bot “get preview” API client and types presign response via shared schema. |
| projects/app/src/components/core/chat/components/Interactive/InteractiveComponents.tsx | Removes TTL-refresh effect and derives “uploading” state via runtime context + pending file detection. |
| projects/app/src/components/core/chat/ChatContainer/PluginRunBox/context.tsx | Removes abandoned global file handling and drops fileSelectConfig plumbing. |
| projects/app/src/components/core/chat/ChatContainer/PluginRunBox/components/RenderInput.tsx | Removes abandoned file UI state and only resets/loads variables. |
| projects/app/src/components/core/chat/ChatContainer/ChatBox/utils.ts | Adds helper to strip keyed-file URLs from user chat values. |
| projects/app/src/components/core/chat/ChatContainer/ChatBox/index.tsx | Uses stripChatValueFileUrls when converting histories to GPT messages; removes legacy file var shaping. |
| projects/app/src/components/core/chat/ChatContainer/ChatBox/hooks/useFileUpload.tsx | Uses previewUrl from presign response; removes extra preview request. |
| projects/app/src/components/core/app/FileSelector/utils.ts | Adds FileSelector sanitization + upload state helpers + icon/preview utilities. |
| projects/app/src/components/core/app/FileSelector/type.ts | Introduces FileSelector input/render/store value types. |
| projects/app/src/components/core/app/FileSelector/index.tsx | Refactors FileSelector to keep UI state internal while emitting only storable values; adds preview-url backfill for key-only values. |
| projects/app/package.json | Bumps app package version to 4.14.19. |
| packages/web/common/file/utils.ts | Removes stray debug logging from S3 upload helper. |
| packages/service/test/core/workflow/dispatch/variables.test.ts | Adds unit tests for WorkflowVariableState (file/password/runtime-only behavior). |
| packages/service/test/core/workflow/dispatch/utils.test.ts | Updates tests to validate new variable store conversion behavior via WorkflowVariableState. |
| packages/service/test/core/workflow/dispatch/tools/runUpdateVar.test.ts | Updates update-variable tool tests for variableState and file/password store semantics. |
| packages/service/test/core/workflow/dispatch/plugin/runInput.test.ts | Adds tests ensuring plugin input file objects are presigned before exposure. |
| packages/service/test/core/workflow/dispatch/interactive/formInput.test.ts | Adds tests ensuring interactive form fileSelect values are presigned/normalized to URL arrays. |
| packages/service/test/core/workflow/dispatch/abandoned/runApp.test.ts | Adds test ensuring abandoned runApp path uses isolated variable state for child workflows. |
| packages/service/test/core/chat/utils.test.ts | Adds tests for presigning variable files and interactive/workflow-tool history file URL enrichment. |
| packages/service/test/core/chat/saveChat.test.ts | Adds test ensuring fileSelect interactive values are sanitized before storage. |
| packages/service/core/workflow/dispatch/utils/variables.ts | Implements WorkflowVariableState (runtime/store split; file/password handling; parent-child restoration). |
| packages/service/core/workflow/dispatch/utils/index.ts | Removes legacy variable helpers and updates imports/paths after refactor. |
| packages/service/core/workflow/dispatch/type.ts | Broadens newVariables value type to any in dispatch response typing. |
| packages/service/core/workflow/dispatch/tools/textEditor.ts | Switches variable replacement to variableState.toRuntimeRecord(). |
| packages/service/core/workflow/dispatch/tools/runUpdateVar.ts | Refactors updates to read/write via variableState and stream toStoreRecord() to SSE. |
| packages/service/core/workflow/dispatch/tools/runLaf.ts | Switches to runtime variables from variableState. |
| packages/service/core/workflow/dispatch/tools/runIfElse.ts | Switches condition evaluation to runtime variables via variableState. |
| packages/service/core/workflow/dispatch/tools/http468.ts | Uses runtime variables via variableState and adjusts JSON replacement plumbing. |
| packages/service/core/workflow/dispatch/plugin/runInput.ts | Refactors plugin input file presigning via shared preview URL getter. |
| packages/service/core/workflow/dispatch/plugin/run.ts | Builds a child WorkflowVariableState for tool workflow runs. |
| packages/service/core/workflow/dispatch/parallelRun/runParallelRun.ts | Clones variable execution state via variableState.clone() for parallel tasks. |
| packages/service/core/workflow/dispatch/loop/runLoop.ts | Removes legacy newVariables accumulation in favor of shared variable state. |
| packages/service/core/workflow/dispatch/interactive/formInput.ts | Presigns fileSelect values into URL arrays during interactive form dispatch. |
| packages/service/core/workflow/dispatch/init/workflowStart.tsx | Reads fileUrlList from variableState rather than raw variables. |
| packages/service/core/workflow/dispatch/init/systemConfig.tsx | Returns runtime variables via variableState.toRuntimeRecord(). |
| packages/service/core/workflow/dispatch/index.ts | Creates root WorkflowVariableState, uses it throughout queue execution, and returns toStoreRecord() for newVariables. |
| packages/service/core/workflow/dispatch/child/runTool.ts | Uses uid/variableState for system variables passed to tool execution. |
| packages/service/core/workflow/dispatch/child/runApp.ts | Creates child WorkflowVariableState for child-app nodes and uses parent as source state for file restoration. |
| packages/service/core/workflow/dispatch/ai/agent/sub/tool/index.ts | Switches agent tool dispatch to read cTime via variableState and use uid. |
| packages/service/core/workflow/dispatch/ai/agent/sub/app/index.ts | Creates child variable state for agent sub-app/plugin runs. |
| packages/service/core/workflow/dispatch/ai/agent/piAgent/toolAdapter.ts | Updates agent tool adapter to pass variableState into sub-dispatches. |
| packages/service/core/workflow/dispatch/ai/agent/piAgent/index.ts | Wires pi-agent dispatch to use variableState. |
| packages/service/core/workflow/dispatch/ai/agent/master/call.ts | Updates master agent call paths to pass variableState into sub-dispatches. |
| packages/service/core/workflow/dispatch/abandoned/runApp.ts | Creates isolated child variable state in abandoned runApp path and passes it to workflow. |
| packages/service/core/chat/utils.ts | Unifies preview URL enrichment for chat histories, interactive inputs, and workflow-tool payloads; updates variable file presigning. |
| packages/service/core/chat/saveChat.ts | Sanitizes interactive fileSelect values before persistence and improves TTL key extraction safety. |
| packages/service/core/chat/fileStoreValue.ts | Adds shared normalization utilities for file store/runtime values (name/type inference, base64 filtering). |
| packages/service/common/s3/sources/chat/index.ts | Adds createChatFilePreviewUrlGetter helper to centralize preview URL creation. |
| packages/service/common/s3/contracts/type.ts | Adds required previewUrl to S3 presign contract schema. |
| packages/service/common/s3/buckets/base.ts | Ensures presigned upload creation also returns previewUrl. |
| packages/global/test/core/workflow/utils.test.ts | Updates workflow IO mapping tests to include file variable render types. |
| packages/global/test/core/workflow/runtime/utils.test.ts | Adapts tests for updated runtime util typing (variables record is unknown-typed). |
| packages/global/openapi/core/dataset/file/index.ts | Updates OpenAPI dataset presign response schema to shared S3 presign response. |
| packages/global/openapi/core/dataset/file/api.ts | Removes dataset-specific presign response schema alias in favor of shared schema. |
| packages/global/openapi/core/chat/helperBot/api.ts | Cleans up unused type imports after helper-bot API changes. |
| packages/global/core/workflow/utils.ts | Maps file variables to [fileSelect, reference] render types. |
| packages/global/core/workflow/runtime/utils.ts | Tightens variable record types used by reference/editor substitution helpers. |
| packages/global/core/workflow/runtime/type.ts | Introduces WorkflowVariableStateLike and replaces variables with variableState in dispatch props. |
| packages/global/core/chat/type.ts | Adds ChatFileStoreValue type for normalized file persistence. |
| packages/global/common/string/tools.ts | Broadens replaceVariable input typing to accept any value map. |
| packages/global/common/file/s3/type.ts | Adds required previewUrl to shared S3 presign response schema. |
| .github/workflows/preview-fastgpt-push.yml | Adds formatted timestamp to preview PR comments. |
| .github/workflows/preview-docs-push.yml | Adds formatted timestamp to preview PR comments. |
| .github/workflows/preview-admin-push.yml | Adds formatted timestamp to preview PR comments. |
| .codex/design/core/workflow/file-variable-runtime-store-split.md | Adds design doc describing the runtime/store split and migration plan. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| await Promise.all( | ||
| Object.keys(params).map(async (key) => { | ||
| const val = params[key]; | ||
| if (Array.isArray(val) && val.every(isPluginFileItem)) { | ||
| // 为文件对象重新签发 URL(如果有 key 但没有 url) | ||
| await Promise.all( | ||
| val.map(async (fileItem) => { | ||
| if (fileItem.key && !fileItem.url) { | ||
| fileItem.url = await getPreviewUrl(fileItem.key); | ||
| } | ||
| }) | ||
| ); | ||
| params[key] = val.map((item) => item.url); | ||
| } |
| S3ChatSource: vi.fn(), | ||
| getS3ChatSource: vi.fn(() => ({ | ||
| createUploadChatFileURL: vi.fn().mockResolvedValue({ | ||
| url: 'http://localhost:9000/mock-bucket', | ||
| fields: { key: 'mock-key' }, | ||
| maxSize: 5 * 1024 * 1024 | ||
| }), | ||
| createGetChatFileURL: vi.fn(async ({ key }: { key: string }) => ({ | ||
| url: `http://localhost:9000/mock-bucket/${key}` | ||
| })), |
|
✅ Admin Preview Image Ready! 🕒 Time: 2026-05-09 10:27:51 (UTC+8) |
|
✅ Build Successful - Preview code-sandbox Image for this PR: 🕒 Time: 2026-05-09 10:28:45 (UTC+8) |
|
✅ Build Successful - Preview fastgpt Image for this PR: 🕒 Time: 2026-05-09 10:28:47 (UTC+8) |
|
✅ Build Successful - Preview mcp_server Image for this PR: 🕒 Time: 2026-05-09 10:29:35 (UTC+8) |
No description provided.