mirror of
https://github.com/openai/codex.git
synced 2026-10-26 18:38:47 +00:00
191 lines
4.1 KiB
Markdown
191 lines
4.1 KiB
Markdown
# App Server File Streaming API
|
|
|
|
## Status
|
|
|
|
Implemented in app-server and exec-server.
|
|
|
|
The existing buffered `fs/readFile` and `fs/writeFile` methods remain unchanged.
|
|
|
|
## Goals
|
|
|
|
- Read and write files without buffering the entire file in memory.
|
|
- Provide backpressure through bounded request/response chunks.
|
|
- Allow positional reads.
|
|
- Support cancellation and deterministic cleanup.
|
|
- Match the existing whole-file write behavior, including preserving the
|
|
identity and metadata of existing destination files.
|
|
|
|
## Read API
|
|
|
|
### `fs/readFile/open`
|
|
|
|
Opens a file for positional reads.
|
|
|
|
```json
|
|
{
|
|
"handleId": "read-1",
|
|
"path": "/absolute/path/to/file"
|
|
}
|
|
```
|
|
|
|
Response:
|
|
|
|
```json
|
|
{
|
|
"maxChunkBytes": 262144
|
|
}
|
|
```
|
|
|
|
### `fs/readFile/read`
|
|
|
|
Reads at most `maxBytes` starting at the absolute byte offset. If `maxBytes`
|
|
is omitted or exceeds `maxChunkBytes`, the server uses `maxChunkBytes`.
|
|
Clients may use `maxChunkBytes` to size a reusable read buffer.
|
|
|
|
```json
|
|
{
|
|
"handleId": "read-1",
|
|
"offset": 0,
|
|
"maxBytes": 65536
|
|
}
|
|
```
|
|
|
|
Response:
|
|
|
|
```json
|
|
{
|
|
"dataBase64": "SGVsbG8=",
|
|
"eof": false
|
|
}
|
|
```
|
|
|
|
`eof` means no more bytes were available at the time of the read. A later read
|
|
at the same offset may return data if the file grows.
|
|
|
|
### `fs/readFile/stat`
|
|
|
|
Returns metadata for the open file.
|
|
|
|
```json
|
|
{
|
|
"handleId": "read-1"
|
|
}
|
|
```
|
|
|
|
Response:
|
|
|
|
```json
|
|
{
|
|
"sizeBytes": 1234,
|
|
"createdAtMs": 1730910000000,
|
|
"modifiedAtMs": 1730910000000
|
|
}
|
|
```
|
|
|
|
The metadata applies to the opened file handle, so the operation remains valid
|
|
if the path is renamed or replaced after it is opened.
|
|
|
|
### `fs/readFile/close`
|
|
|
|
Closes the read handle.
|
|
|
|
```json
|
|
{
|
|
"handleId": "read-1"
|
|
}
|
|
```
|
|
|
|
Response:
|
|
|
|
```json
|
|
{}
|
|
```
|
|
|
|
## Write API
|
|
|
|
### `fs/writeFile/open`
|
|
|
|
Creates the destination if needed or truncates the existing file. Existing file
|
|
identity and metadata, including hardlinks and platform access controls, are
|
|
preserved in the same way as `fs/writeFile`.
|
|
|
|
```json
|
|
{
|
|
"handleId": "write-1",
|
|
"path": "/absolute/path/to/file"
|
|
}
|
|
```
|
|
|
|
Response:
|
|
|
|
```json
|
|
{
|
|
"maxChunkBytes": 262144
|
|
}
|
|
```
|
|
|
|
### `fs/writeFile/write`
|
|
|
|
Decodes and appends the complete chunk to the open destination file. A
|
|
successful response acknowledges the entire decoded chunk; partial success is
|
|
not exposed.
|
|
|
|
```json
|
|
{
|
|
"handleId": "write-1",
|
|
"dataBase64": "SGVsbG8="
|
|
}
|
|
```
|
|
|
|
Response:
|
|
|
|
```json
|
|
{}
|
|
```
|
|
|
|
### `fs/writeFile/close`
|
|
|
|
Closes the write handle.
|
|
|
|
```json
|
|
{
|
|
"handleId": "write-1"
|
|
}
|
|
```
|
|
|
|
Response:
|
|
|
|
```json
|
|
{}
|
|
```
|
|
|
|
## Shared Semantics
|
|
|
|
- Handle IDs are client-supplied strings scoped to one connection.
|
|
- Opening a duplicate active handle ID returns `INVALID_REQUEST`.
|
|
- Each connection may have at most 64 opening or open file handles.
|
|
- Operations for one handle are serialized. Different handles may run
|
|
concurrently.
|
|
- Reads are positional and do not maintain a server-side cursor.
|
|
- Writes are sequential appends.
|
|
- Each read or write transfers at most the `maxChunkBytes` returned by its
|
|
corresponding open operation.
|
|
- `maxChunkBytes` is currently 262144 bytes.
|
|
- Backpressure comes from awaiting bounded read and write responses. Clients
|
|
should use a bounded pipeline of up to two read requests to hide transport
|
|
round-trip latency without accumulating unbounded response data.
|
|
- Close operations are idempotent and serialized with other operations for the
|
|
same handle. Close waits for an active operation to finish, rejects queued
|
|
operations, and prevents a pending open from becoming live.
|
|
- Closing a connection closes all of its handles.
|
|
- Any filesystem or I/O error closes the affected handle. Protocol errors such
|
|
as an unknown handle do not affect other handles.
|
|
- Streamed writes are visible as they complete. Opening truncates an existing
|
|
destination, and an I/O error, cancellation, or disconnect may leave a
|
|
partially written file.
|
|
- Errors use normal JSON-RPC error responses.
|
|
- App-server operations target the app-server host filesystem. Exec-server
|
|
exposes the same pull-based handle operations for remote filesystem clients.
|
|
- Streaming through the platform sandbox helper is not supported because the
|
|
helper is one-shot and cannot retain open-file identity across requests.
|