Skip to content

Comments

feat(craft): make output/ files downloadable from Artifacts tab#8721

Merged
rohoswagger merged 6 commits intomainfrom
craft-downloadable-outputs
Feb 24, 2026
Merged

feat(craft): make output/ files downloadable from Artifacts tab#8721
rohoswagger merged 6 commits intomainfrom
craft-downloadable-outputs

Conversation

@rohoswagger
Copy link
Contributor

@rohoswagger rohoswagger commented Feb 24, 2026

Description

Makes all output files in the outputs/ directory downloadable from the Artifacts tab in Onyx Craft. Previously, only webapp artifacts had download buttons. Now, every top-level file and folder inside outputs/ appears in the Artifacts tab with a download button:

  • Files download directly via the existing artifact download endpoint
  • Folders are zipped server-side via a new download-directory endpoint and downloaded as .zip files
  • The outputs/web directory is excluded since it's already shown as a webapp artifact with its own download

Changes:

  • Backend: Added generic download_directory method to SessionManager and GET /sessions/{id}/download-directory/{path} API endpoint
  • Frontend: Added downloadArtifactFile and downloadDirectory helpers to apiServices.ts
  • Frontend: Updated ArtifactsTab to fetch outputs/ directory listing and render each entry with a download button

Also addresses a tiny file upload connector bug for non-admin users.

How Has This Been Tested?

  • TypeScript type check passes with zero errors
  • All pre-commit hooks pass (black, ruff, prettier, etc.)
  • Python syntax validation passes

Additional Options

  • [Optional] Please cherry-pick this PR to the latest release version.
  • [Optional] Override Linear Check

Summary by cubic

Make all files and folders in outputs/ downloadable from the Artifacts tab, with expandable folders to browse and download nested files or zip whole directories. Also hardens session reuse and fixes cross-user library connector mix-ups.

  • New Features

    • Added GET /sessions/{session_id}/download-directory/{path} and SessionManager.download_directory to zip and download folders; arcname uses explicit prefix slicing.
    • Updated ArtifactsTab to list outputs/ (excluding outputs/web) with per-item downloads, expandable/collapsible folders, and filtered empty top-level dirs; added downloadArtifactFile and downloadDirectory helpers.
  • Bug Fixes

    • list_directory returns an empty listing if the directory isn’t ready; get_or_create_empty_session verifies the workspace exists before reuse.
    • get_or_create_craft_connector filters cc_pairs by creator_id and reuses the shared connector while creating per-user cc_pairs to avoid cross-user document linkage.

Written for commit e0a0db5. Summary will update on new commits.

Show top-level items from outputs/ in the Artifacts tab with download
buttons. Files download directly; folders are zipped server-side first.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@rohoswagger rohoswagger requested a review from a team as a code owner February 24, 2026 06:34
@github-actions
Copy link
Contributor

github-actions bot commented Feb 24, 2026

Preview Deployment

Status Preview Commit Updated
https://onyx-preview-a3yx36wdu-danswer.vercel.app e0a0db5 2026-02-24 20:17:01 UTC

Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 4 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 24, 2026

Greptile Summary

This PR extends the Artifacts tab to make all files and folders in the outputs/ directory downloadable, not just webapp artifacts. The implementation adds a new backend endpoint for directory downloads that zips folders server-side, and updates the frontend to fetch and display all output entries with download buttons.

Key changes:

  • Added GET /sessions/{session_id}/download-directory/{path} endpoint with proper error handling and security checks
  • Implemented SessionManager.download_directory() method that recursively collects files and creates zip archives
  • Enhanced ArtifactsTab component to fetch outputs directory listing and render files/folders with appropriate icons and download buttons
  • Added downloadArtifactFile and downloadDirectory helper functions with proper URL encoding
  • Frontend changes follow web standards (absolute imports, proper component usage, useSWR for data fetching)

Issues found:

  • One logical issue with arcname replacement logic that needs fixing to properly handle files at the root level of the target directory

Confidence Score: 4/5

  • This PR is safe to merge with one logical fix needed for the arcname handling
  • The implementation is well-structured with proper security measures (path traversal protection via sandbox manager) and follows existing patterns. However, there's a logical issue in the arcname replacement logic that could cause files at the root of the target directory to have incorrect paths in the zip archive.
  • backend/onyx/server/features/build/session/manager.py requires attention for the arcname logic fix

Important Files Changed

Filename Overview
backend/onyx/server/features/build/api/sessions_api.py Added new download_directory endpoint with proper error handling and path traversal protection
backend/onyx/server/features/build/session/manager.py Implemented download_directory method for zipping arbitrary directories; minor issue with arcname logic for files at root level of target directory
web/src/app/craft/components/output-panel/ArtifactsTab.tsx Enhanced UI to display all outputs directory entries with download buttons; follows web standards correctly
web/src/app/craft/services/apiServices.ts Added download helper functions with proper URL encoding for file and directory downloads

Sequence Diagram

sequenceDiagram
    participant User
    participant ArtifactsTab
    participant API
    participant SessionManager
    participant SandboxManager

    Note over User,SandboxManager: Listing Outputs Directory
    User->>ArtifactsTab: View Artifacts Tab
    ArtifactsTab->>API: GET /sessions/{id}/files?path=outputs
    API->>SessionManager: list_directory(outputs)
    SessionManager->>SandboxManager: list_directory(outputs)
    SandboxManager-->>SessionManager: Directory entries
    SessionManager-->>API: Directory listing
    API-->>ArtifactsTab: Output files & folders
    ArtifactsTab->>User: Display files/folders with download buttons

    Note over User,SandboxManager: Downloading a File
    User->>ArtifactsTab: Click download (file)
    ArtifactsTab->>API: GET /sessions/{id}/artifacts/{path}
    API->>SessionManager: download_artifact(path)
    SessionManager->>SandboxManager: read_file(path)
    SandboxManager-->>SessionManager: File content
    SessionManager-->>API: File content + metadata
    API-->>User: Download file

    Note over User,SandboxManager: Downloading a Directory
    User->>ArtifactsTab: Click download (folder)
    ArtifactsTab->>API: GET /sessions/{id}/download-directory/{path}
    API->>SessionManager: download_directory(path)
    SessionManager->>SandboxManager: list_directory (recursive)
    loop For each file
        SessionManager->>SandboxManager: read_file(file_path)
        SandboxManager-->>SessionManager: File content
        SessionManager->>SessionManager: Add to zip
    end
    SessionManager-->>API: Zip file bytes
    API-->>User: Download .zip file
Loading

Last reviewed commit: 26d7461

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@github-actions
Copy link
Contributor

github-actions bot commented Feb 24, 2026

🖼️ Visual Regression Report

Project Changed Added Removed Unchanged Report
admin 38 0 0 71 View Report
exclusive 0 0 0 8 ✅ No changes

rohoswagger and others added 3 commits February 24, 2026 09:16
…rectory

replace() is fragile — slicing the prefix is explicit and correct by
construction regardless of path contents.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ctor

Admin users see all cc_pairs (bypassing user filters), so the first
CRAFT_FILE cc_pair found could belong to a different user. Documents
linked to the wrong cc_pair become invisible in /tree which filters
by creator_id. Now reuses the shared connector but creates per-user
cc_pairs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- list_directory now returns empty listing instead of 404 when the
  directory doesn't exist (e.g., session workspace not yet loaded)
- get_or_create_empty_session now checks session_workspace_exists
  before reusing a cached session, preventing stale sessions with
  missing workspaces from being returned

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ts tab

- Directories in the Artifacts tab are now expandable/collapsible,
  showing their contents inline with download buttons on each item
- Empty directories are filtered out from the top-level listing
- Subfolder files can be downloaded individually or whole folders
  can be downloaded as zip

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@rohoswagger rohoswagger changed the title feat(craft): make output files downloadable from Artifacts tab feat(craft): make output/ files downloadable from Artifacts tab Feb 24, 2026
Copy link
Contributor

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="web/src/app/craft/components/output-panel/ArtifactsTab.tsx">

<violation number="1" location="web/src/app/craft/components/output-panel/ArtifactsTab.tsx:72">
P2: Handle per-directory listing failures; otherwise a single fetch error rejects the entire Promise.all call and prevents any output entries from rendering.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
@rohoswagger rohoswagger added this pull request to the merge queue Feb 24, 2026
Merged via the queue into main with commit 4a04cfd Feb 24, 2026
86 checks passed
@rohoswagger rohoswagger deleted the craft-downloadable-outputs branch February 24, 2026 21:57
Danelegend pushed a commit that referenced this pull request Feb 25, 2026
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Danelegend pushed a commit that referenced this pull request Feb 25, 2026
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
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.

2 participants