Salambo
Browse documentation
OperatePublish runtime artifacts

Publish runtime artifacts

Upload generated sandbox files as downloadable Salambo run artifacts.

View Markdown

Runtime artifacts are explicit. Salambo does not upload every file in the sandbox automatically; publish only the files that are safe and useful for the user.

A sandbox receives these runtime-scoped environment variables during run startup:

VariablePurpose
SALAMBO_ARTIFACT_UPLOAD_URLRun-scoped upload endpoint for generated artifacts.
SALAMBO_ARTIFACT_TOKENBearer token with the artifact.write capability for the current run.
SALAMBO_OUTPUT_DIRRecommended output root, defaulting to /workspace/outputs.

The token is scoped to the current account/run and does not expose storage provider credentials.

Upload a file

Use a small helper in your sandbox code instead of hardcoding an endpoint:

ts
import { createReadStream } from 'node:fs';
import { stat } from 'node:fs/promises';
import { basename } from 'node:path';

export async function uploadArtifact(
  filePath: string,
  options: { path: string; contentType?: string },
) {
  const uploadUrl = process.env.SALAMBO_ARTIFACT_UPLOAD_URL;
  const token = process.env.SALAMBO_ARTIFACT_TOKEN;

  if (!uploadUrl || !token) {
    throw new Error('Artifact publishing is not available for this run.');
  }

  const file = await stat(filePath);
  const request = {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${token}`,
      'Content-Type': options.contentType ?? 'application/octet-stream',
      'Content-Length': String(file.size),
      'x-display-path': options.path,
      'x-file-name': basename(filePath),
    },
    body: createReadStream(filePath),
    duplex: 'half',
  } satisfies RequestInit & { duplex: 'half' };
  const response = await fetch(uploadUrl, request);

  if (!response.ok) {
    const message = await response.text();
    throw new Error(`Artifact upload failed (${response.status}): ${message}`);
  }
}

Example:

ts
await uploadArtifact('/workspace/report.pdf', {
  path: '/reports/report.pdf',
  contentType: 'application/pdf',
});

Path and size rules

  • Use logical artifact paths such as /report.txt or /reports/summary.json.
  • /workspace/outputs/... remains accepted for compatibility and is normalized to a logical path.
  • Do not publish secrets, credentials, or temporary files.
  • Re-uploading the same logical path replaces the previous artifact metadata for the run.
  • The default maximum artifact size is 100 MB unless the deployment is configured otherwise.

Published files appear in the run UI and are downloadable through the Files API.