# OpenMAIC Material Management for Agents: File Upload and Extraction Pipeline

> Discover how OpenMAIC handles agent material management. Learn about its six-phase file upload and extraction pipeline, including MIME validation, slot accounting, and automatic retries.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: how-to-guide
- Published: 2026-09-11

---

**OpenMAIC manages agent file uploads through a six-phase pipeline covering MIME validation, slot accounting with a 20-file limit, concurrency-limited scheduling with identity bootstrapping, automatic retry logic, and server-side extraction before the content reaches the AI model.**

OpenMAIC, developed in the THU-MAIC/OpenMAIC repository, treats every file that an agent or user attaches to a workbench session as *material*. The system enforces strict governance over these uploads to ensure security, capacity limits, and reliable extraction for downstream AI processing.

## Material Validation and Policy Enforcement

Before any upload begins, OpenMAIC validates files against a predefined whitelist. The [`material-upload-policy.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/material-upload-policy.ts) file defines the acceptable MIME types and extensions through the `WORKBENCH_MATERIAL_ACCEPT` constant, while the `isWorkbenchMaterialMime()` function performs runtime checks.

Only whitelisted file types pass validation, preventing binary abuse and ensuring the extraction pipeline receives compatible formats. This gatekeeper logic runs client-side to fail fast before network transfer begins.

## Slot Accounting and Capacity Management

The workbench enforces a hard limit of **20 materials** per session via `MAX_COMPOSER_MATERIALS` in [`material-upload-scheduling.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/material-upload-scheduling.ts). The `MaterialSlotLedger` class tracks occupied slots, pending uploads, and available capacity through helper methods:

- `canAccept()` – Checks if the session has room for additional files
- `reserve()` – Pre-allocates slots for pending uploads
- `settle()` – Confirms successful uploads and commits slot usage
- `clearCompleted()` – Removes finished uploads from the ledger

This accounting prevents UI overflow and ensures the agent never receives more context than the interface can display.

## Upload Scheduling and Concurrency Control

OpenMAIC limits parallel uploads to **three concurrent HTTP requests** using `MATERIAL_UPLOAD_CONCURRENCY` in [`material-upload-scheduling.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/material-upload-scheduling.ts). The `MaterialUploadQueue` class serializes excess tasks, maintaining a buffer until a slot frees up.

The `scheduleMaterialUploadBatch()` function serves as the public entry point for UI components. It receives the identity gate, validated files, and an upload function, then orchestrates the entire flow including queue management and concurrency limits.

## Identity Bootstrapping and Session Ownership

The first successful upload performs **identity bootstrapping** by returning an HttpOnly *owner* cookie that identifies the session owner. Until this cookie is obtained:

1. Uploads run **serially** via `uploadFirstSuccessfulThenParallel()`
2. The `gate.identityEstablished` flag remains `false`
3. Subsequent uploads queue behind the bootstrap operation

Once the cookie sets `gate.identityEstablished = true`, the system dispatches uploads in parallel up to the concurrency limit. This pattern ensures the server establishes session ownership before handling parallel streams.

## Retry Handling and Error Resilience

Transient HTTP errors (429 Too Many Requests, 503 Service Unavailable) trigger automatic retry logic. The `retryMaterialUpload()` function implements exponential backoff with up to **three attempts** before surfacing failure to the user.

This resilience layer runs transparently within the scheduling queue, smoothing over temporary network instability without requiring manual intervention from the agent or user.

## Batch Upload Implementation

Front-end components interact with the material management system through a typed API exported from [`material-upload-scheduling.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/material-upload-scheduling.ts). The typical implementation follows this pattern:

```typescript
import {
  scheduleMaterialUploadBatch,
  createMaterialUploadIdentityGate,
  MAX_COMPOSER_MATERIALS,
  canAcceptMaterialFiles,
} from '@/lib/workbench/material-upload-scheduling';
import { isWorkbenchMaterialMime } from '@/lib/workbench/material-upload-policy';

// Initialize the identity gate once per session
const uploadGate = createMaterialUploadIdentityGate();

// Collect files from user interaction
const files: File[] = [...]; // from drag-drop or file input

// Validate MIME types against whitelist
const accepted = files.filter(f => isWorkbenchMaterialMime(f.type));

// Verify capacity against the 20-file limit
if (!canAcceptMaterialFiles(currentOccupied, accepted.length)) {
  throw new Error(
    `Too many materials – the workbench can hold at most ${MAX_COMPOSER_MATERIALS} items.`
  );
}

// Define the low-level upload function
async function uploadFile(file: File): Promise<boolean> {
  const resp = await fetch('/api/material/upload', {
    method: 'POST',
    body: file,
    credentials: 'include', // Required for HttpOnly cookie
  });
  return resp.ok;
}

// Execute the batch with automatic concurrency and retry management
await scheduleMaterialUploadBatch(uploadGate, accepted, uploadFile);

```

## Content Extraction Pipeline

After successful storage, the backend triggers the **material-extraction pipeline** referenced in the upload endpoint. This server-side process handles format normalization such as PDF-to-images, Office documents to plain text, or audio to waveform data.

Extraction workers apply the same MIME whitelist used during upload validation. Once processing completes, the backend emits a *"material-ready"* event that the client observes. The AI model then consumes these normalized artifacts rather than raw binary files, ensuring consistent downstream behavior.

## Summary

- **Validation occurs first:** `isWorkbenchMaterialMime()` in [`material-upload-policy.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/material-upload-policy.ts) enforces the MIME whitelist before network transfer.
- **Capacity is strictly capped:** `MaterialSlotLedger` maintains the 20-file limit per session via `MAX_COMPOSER_MATERIALS`.
- **Concurrency is throttled:** `MaterialUploadQueue` limits parallel requests to three, with serial fallback during identity bootstrapping.
- **Identity bootstrapping secures sessions:** The first upload must complete serially to establish the HttpOnly owner cookie before parallel processing begins.
- **Failures retry automatically:** Transient errors trigger exponential backoff with three attempts through `retryMaterialUpload()`.
- **Extraction normalizes content:** Server-side pipelines convert uploaded files into AI-ready formats, emitting completion events to the client.

## Frequently Asked Questions

### What is the maximum number of files an agent can upload in a single OpenMAIC session?

OpenMAIC enforces a hard limit of **20 materials** per workbench session through the `MAX_COMPOSER_MATERIALS` constant in [`material-upload-scheduling.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/material-upload-scheduling.ts). The `MaterialSlotLedger` class tracks occupied slots and rejects uploads that would exceed this capacity.

### How does OpenMAIC handle the first file upload differently from subsequent uploads?

The first successful upload performs **identity bootstrapping** by obtaining an HttpOnly owner cookie from the server. Until this cookie is received, uploads execute **serially** via `uploadFirstSuccessfulThenParallel()`. Once `gate.identityEstablished` becomes true, the system permits parallel uploads up to the three-request concurrency limit.

### What happens if an upload fails due to server rate limiting or temporary unavailability?

OpenMAIC automatically retries failed uploads experiencing transient HTTP errors (429 or 503 status codes). The `retryMaterialUpload()` function implements exponential backoff and attempts the upload up to **three times** before propagating the error to the user interface.

### Which file types does OpenMAIC accept for agent material uploads?

OpenMAIC accepts only MIME types and extensions defined in the `WORKBENCH_MATERIAL_ACCEPT` whitelist within [`material-upload-policy.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/material-upload-policy.ts). The `isWorkbenchMaterialMime()` function validates files against this list client-side before initiating the upload request, blocking unsupported binary formats.