Skip to content

fix(kb): canonicalize knowledge-base upload keys#5096

Merged
icecrasher321 merged 2 commits into
stagingfrom
fix/kb-upload-direct
Jun 16, 2026
Merged

fix(kb): canonicalize knowledge-base upload keys#5096
icecrasher321 merged 2 commits into
stagingfrom
fix/kb-upload-direct

Conversation

@icecrasher321

Copy link
Copy Markdown
Collaborator

Summary

Ensure new knowledge-base uploads consistently use the kb/ storage prefix across both server-side and presigned upload paths, while preserving knowledge-base/ prefix support for existing direct-upload objects.

Type of Change

  • Bug fix

Testing

Tested manually

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

@vercel

vercel Bot commented Jun 16, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jun 16, 2026 5:53pm

Request Review

@cursor

cursor Bot commented Jun 16, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Scoped upload-key generation and prefix inference for KB files; backward-compatible for existing knowledge-base/ keys with no auth or permission changes.

Overview
Knowledge-base uploads now share one storage key shape (kb/{timestamp}-{random}-{sanitizedName}) via generateKnowledgeBaseFileKey, used by both multipart upload and presigned/direct upload instead of presigned defaulting to knowledge-base/....

Context inference stays compatible with older objects: inferContextFromKey treats both kb/ and knowledge-base/ as knowledge-base, with tests covering prefixes and error cases. Presigned route tests expect kb/ keys when customKey is passed through the mock.

Reviewed by Cursor Bugbot for commit a9dc4d1. Configure here.

@greptile-apps

greptile-apps Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR centralises knowledge-base storage-key generation into a single generateKnowledgeBaseFileKey() helper, replacing two separate inline key-building patterns so that both the direct (server-side) and presigned upload paths consistently emit kb/-prefixed keys instead of letting the default ${context}/... fallback produce knowledge-base/-prefixed keys.

  • New knowledge-base-file-manager.ts — canonical key generator using Date.now() + crypto.randomBytes(8) + sanitizeFileName, giving every upload a collision-safe kb/{ts}-{random}-{name} key.
  • inferContextFromKey extended — adds knowledge-base/ as a recognised legacy prefix so existing objects stored under the old path continue to resolve correctly to the knowledge-base context.
  • Presigned route (route.ts) and direct-upload route (upload/route.ts) updated to call the shared helper, tests updated to match the kb/ pattern.

Confidence Score: 5/5

Safe to merge — both upload paths now produce consistent kb/ keys, legacy keys are still readable, and the tests cover both prefix cases.

The change is tightly scoped: a new pure-function key generator replaces two separate inline snippets, and backward compatibility for existing knowledge-base/ objects is preserved through the updated inferContextFromKey. No storage migration is needed, no existing data is affected, and both test files exercise the new and legacy paths.

No files require special attention. The new knowledge-base-file-manager.ts is simple and server-only; the route changes are minimal wiring adjustments.

Important Files Changed

Filename Overview
apps/sim/lib/uploads/contexts/knowledge-base/knowledge-base-file-manager.ts New file — exports generateKnowledgeBaseFileKey() using timestamp + 8 random bytes + sanitizeFileName; clean and server-side only.
apps/sim/app/api/files/presigned/route.ts Generates customKey before calling generatePresignedUploadUrl for knowledge-base uploads, ensuring kb/ prefix on presigned paths.
apps/sim/app/api/files/upload/route.ts Replaces three-line inline key construction with generateKnowledgeBaseFileKey(); adds the previously-absent random component that was missing in the server-side path.
apps/sim/lib/uploads/utils/file-utils.ts Backward-compat: adds knowledge-base/ as a recognised prefix alongside existing kb/, both mapping to the knowledge-base context.
apps/sim/lib/uploads/utils/file-utils.test.ts New inferContextFromKey test suite covers both prefixes, all other context prefixes, and the throw-on-unknown path.
apps/sim/app/api/files/presigned/route.test.ts Mock updated to accept optional customKey and pass it through; assertion updated from knowledge-base/ to kb/ prefix regex.

Sequence Diagram

%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
    participant Client
    participant PresignedRoute as /api/files/presigned
    participant UploadRoute as /api/files/upload
    participant KBFileManager as generateKnowledgeBaseFileKey()
    participant StorageService as generatePresignedUploadUrl()
    participant CloudStorage as S3 / Azure Blob

    Note over PresignedRoute,KBFileManager: Presigned upload path (new)
    Client->>PresignedRoute: "POST ?type=knowledge-base"
    PresignedRoute->>KBFileManager: generateKnowledgeBaseFileKey(fileName)
    KBFileManager-->>PresignedRoute: "kb/{ts}-{random}-{safe_name}"
    PresignedRoute->>StorageService: "generatePresignedUploadUrl({ customKey })"
    StorageService-->>PresignedRoute: "{ url, key: kb/... }"
    PresignedRoute-->>Client: "{ presignedUrl, fileInfo.key=kb/... }"
    Client->>CloudStorage: PUT (presigned URL)

    Note over UploadRoute,KBFileManager: Server-side upload path (updated)
    Client->>UploadRoute: POST (multipart/form-data)
    UploadRoute->>KBFileManager: generateKnowledgeBaseFileKey(originalName)
    KBFileManager-->>UploadRoute: "kb/{ts}-{random}-{safe_name}"
    UploadRoute->>CloudStorage: "uploadFile({ customKey: kb/... })"
    CloudStorage-->>UploadRoute: "fileInfo.key = kb/..."
    UploadRoute-->>Client: "{ fileInfo.key=kb/... }"

    Note over StorageService: inferContextFromKey (backward compat)
    StorageService->>StorageService: key.startsWith(kb/) → knowledge-base
    StorageService->>StorageService: key.startsWith(knowledge-base/) → knowledge-base (legacy)
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
    participant Client
    participant PresignedRoute as /api/files/presigned
    participant UploadRoute as /api/files/upload
    participant KBFileManager as generateKnowledgeBaseFileKey()
    participant StorageService as generatePresignedUploadUrl()
    participant CloudStorage as S3 / Azure Blob

    Note over PresignedRoute,KBFileManager: Presigned upload path (new)
    Client->>PresignedRoute: "POST ?type=knowledge-base"
    PresignedRoute->>KBFileManager: generateKnowledgeBaseFileKey(fileName)
    KBFileManager-->>PresignedRoute: "kb/{ts}-{random}-{safe_name}"
    PresignedRoute->>StorageService: "generatePresignedUploadUrl({ customKey })"
    StorageService-->>PresignedRoute: "{ url, key: kb/... }"
    PresignedRoute-->>Client: "{ presignedUrl, fileInfo.key=kb/... }"
    Client->>CloudStorage: PUT (presigned URL)

    Note over UploadRoute,KBFileManager: Server-side upload path (updated)
    Client->>UploadRoute: POST (multipart/form-data)
    UploadRoute->>KBFileManager: generateKnowledgeBaseFileKey(originalName)
    KBFileManager-->>UploadRoute: "kb/{ts}-{random}-{safe_name}"
    UploadRoute->>CloudStorage: "uploadFile({ customKey: kb/... })"
    CloudStorage-->>UploadRoute: "fileInfo.key = kb/..."
    UploadRoute-->>Client: "{ fileInfo.key=kb/... }"

    Note over StorageService: inferContextFromKey (backward compat)
    StorageService->>StorageService: key.startsWith(kb/) → knowledge-base
    StorageService->>StorageService: key.startsWith(knowledge-base/) → knowledge-base (legacy)
Loading

Reviews (1): Last reviewed commit: "fix(kb): canonicalize knowledge-base upl..." | Re-trigger Greptile

@icecrasher321 icecrasher321 merged commit 73c73ff into staging Jun 16, 2026
15 checks passed
@waleedlatif1 waleedlatif1 deleted the fix/kb-upload-direct branch June 16, 2026 18:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant