Skip to content

ReadFile

ReadFile is the native path → bytes step: it reads a file the route names at call time into the exchange body. It is the input half of a document skill — the caller supplies a path (e.g. as a tool-call argument), read-file loads the bytes, and a downstream component consumes them (pdf://?op=extractText, xlsx://, docling://, vlm://, …).

It complements the two file:// read paths without needing an endpoint or a directory to configure:

Path Role Reads
file:// polling consumer (trigger:) route source files it discovers in a fixed directory
file://?op=read (producer step) mid-route a file relative to a configured, jailed directory
read-file (this step) mid-route a single caller-named path — no endpoint, no directory

YAML form

steps:
  - read-file:
      path: { starlang: payload.path }   # or a bare string:  path: /forms/y.pdf
      as: bytes                          # bytes (default) | text
      fail-if-missing: true              # default true
      max-size: 25MB                     # optional guard; "" = unlimited
Field Type Default Description
path value required The file to read. A bare string is a constant path; { starlang: <expr> } evaluates per-exchange (e.g. payload.path from a tool-call arg); { constant: <path> } is the explicit constant form.
as enum bytes Body type. bytes yields []byte (binary-safe — no charset mangling); text yields a string.
fail-if-missing bool true A missing file is a hard, catchable error (surfaced to do-try / on-exception). When false, a missing file leaves an empty body and sets HelixFileMissing=true.
max-size string unlimited Reject files larger than this human byte size (10MB, 512KB, 1048576) before reading them into memory. Units are binary (KB = 1024).

Constructor: NewReadFile(path engine.Expression, asText, failIfMissing bool, maxSize int64) *ReadFile.

Behaviour

  1. Evaluates path against the exchange (constant or Starlang). An empty or nil result is an error.
  2. os.Stat the path. A missing file follows fail-if-missing; a directory is an error; a file over max-size is an error.
  3. Reads the bytes and sets the body ([]byte, or string when as: text).
  4. Stamps the same provenance headers a polled file / file://?op=read gets, so downstream steps behave identically regardless of how the bytes arrived: HelixFileName, HelixFilePath, HelixFileLength (int64), HelixFileLastModified (time.Time), and Content-Type (probed from the extension).

The path is used verbatim (an absolute path reads that file; a relative path resolves against the process working directory). Unlike file://?op=read, there is no endpoint directory and therefore no jail — read-file is the endpoint-free step for trusted, caller-named paths (e.g. a skill tool an agent invokes). Point untrusted input through file://?op=read with a sandbox directory instead.

Examples

A document-input tool: the agent supplies a path at call time, the step turns it into bytes, and pdf:// extracts the text.

tools:
  - id: pdf_extract_text
    description: extract text from a PDF the caller names
    input:  { path: { type: string, required: true } }
    output: { text: { type: string } }
    steps:
      - read-file: { path: { starlang: payload.path } }
      - target: "pdf://x?op=extractText"
      - transform: { starlang: 'write({ text: payload }, "application/json")' }

Load a JSON config by constant path — a JSON body is auto-parsed, so its fields are addressable directly in the next step:

steps:
  - read-file: { path: /etc/app/settings.json }
  - transform: { starlang: '{ mode: payload.env, retries: payload.retries }' }

Tolerate a missing file and branch instead of failing:

steps:
  - read-file: { path: { starlang: payload.path }, fail-if-missing: false }
  - choice:
      when:
        - starlang: 'headers["HelixFileMissing"] == "true"'
          steps:
            - log: { message: "no file at ${payload.path}, using default" }

Source

pkg/processor/read_file.go

See also

  • file:// — op=read (jailed, endpoint-relative) and the polling consumer.
  • poll_enrich — enrich the current exchange from a polled endpoint.
  • pdf, xlsx, docling — document components that consume the bytes.