> ## Documentation Index
> Fetch the complete documentation index at: https://yukta.infenia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# External I/O reference

> Options, ports, outputs and server settings of HTTP_REQUEST, PROCESS_EXECUTOR, AGENT_SESSION, SQL_QUERY, FILE_READ and FILE_WRITE.

# External I/O reference

These processors reach outside the server: HTTP, processes, SQL and files. Each belongs to an optional build module (see the [plugin overview](https://yukta.infenia.com/reference/plugins/overview.md#selecting-plugins-at-build-time)).

Options that accept `${...}` say so. Never put a secret in `config`: write `decrypted:<key>`; the server reads it from the environment variable `YUKTA_SECRET_<KEY>`.

## `HTTP_REQUEST`

Module `http-request`. Performs one HTTP request per message.

| Option | Type | Default | Required | Description |
| - | - | - | - | - |
| `url` | string | none | yes | Request URL; `${...}` supported. |
| `method` | `GET`, `POST`, `PUT`, `PATCH`, `DELETE` or `HEAD` | `GET` | no | HTTP method. |
| `headers` | map | none | no | Request headers; `${...}` and `decrypted:<key>` supported. |
| `body` | expression | none | no | Request body; a string supports `${...}`, an object is sent as JSON. |
| `timeout` | number | `30` | no | Seconds, positive. |
| `failureMode` | `ERROR` or `CONTINUE` | `ERROR` | no | `ERROR` fails the node on a non-2xx status or transport error; `CONTINUE` emits the result (status `0` on a transport error). |
| `routeByStatus` | boolean | `false` | no | Emit on `success` (2xx) or `failure`; needs `failureMode: CONTINUE`. |
| `concurrency` | number | `16` | no | Requests in flight at once. |

* **Output ports:** `default`, or `success` and `failure` with `routeByStatus`.
* **Payload:** `{status, success, headers, body}`; `body` is parsed when the response is JSON. Metadata gains `status`.
* **Default node timeout:** `timeout` plus 5 seconds.
* **Egress:** the URL is checked against `yukta.egress.allowed-hosts`, `yukta.egress.by-workflow.<id>` and `yukta.egress.by-session.<id>`.
* **Errors:** `url is mandatory`; `timeout must be positive, got: <n>`; `routeByStatus requires failureMode: CONTINUE`; `HTTP request failed with status <n>: <body>`.

```json theme={"system"}
{
  "nodeId": "fetch",
  "type": "HTTP_REQUEST",
  "config": { "url": "https://api.example.com/items/${payload.id}", "headers": { "Authorization": "decrypted:api-token" } }
}
```

## `PROCESS_EXECUTOR`

Module `process-executor`. Runs an external process per message.

| Option | Type | Default | Required | Description |
| - | - | - | - | - |
| `command` | list | none | yes | Command and arguments; `${...}` supported. |
| `inputMode` | `NONE`, `ENV` or `STDIN` | `NONE` | no | `ENV` exports metadata as `YUKTA_METADATA_*` and the payload as `YUKTA_PAYLOAD`; `STDIN` writes the payload to standard input. Non-string payloads are JSON-serialized. |
| `workingDir` | string | current directory | no | Working directory; SpEL supported. |
| `timeout` | number | `300` | no | Seconds, positive; SpEL supported. |
| `env` | map | none | no | Extra environment variables. |
| `useShell` | boolean | `false` | no | Run the elements as one shell script (`sh -c`, `cmd.exe /c`) so pipes and `&&` work; a literal `true` or `false`, not an expression. |
| `captureStderr` | boolean | `false` | no | Capture stderr separately instead of merging it into stdout. |
| `outputFormat` | `STRUCTURED`, `RAW`, `JSON` or `PASSTHROUGH` | `STRUCTURED` | no | Shape of the emitted payload. |
| `failureMode` | `ERROR` or `CONTINUE` | `ERROR` | no | `ERROR` fails the node on a non-zero exit or a timeout. |
| `routeByExitCode` | boolean | `false` | no | Emit on `success` (exit 0) or `failure` (non-zero exit or timeout); needs `failureMode: CONTINUE`. |
| `reports` | list | none | no | `[{format: junit\|checkstyle\|sarif, glob}]`; report files written during the run are read into `failures`. |
| `metadataFrom` | map | none | no | Node metadata key to a dotted path into the JSON the process prints; missing paths are skipped. |
| `concurrency` | number | `4` | no | Messages handled at once; each starts a process. |
| `maxOutputLines` | number | `10000` | no | Output lines kept; `0` is unlimited. Accepted, not in the declared schema. |
| `maxOutputBytes` | number | `10485760` | no | Output bytes kept; `0` is unlimited. Accepted, not in the declared schema. |
| `includeOutput` | boolean | `true` | no | Include stdout and stderr in `STRUCTURED` and `JSON` payloads. Accepted, not in the declared schema. |
| `includeInput` | boolean | `false` | no | Include the input payload under `input`. Accepted, not in the declared schema. |

`outputFormat` payloads:

| Value | Payload |
| - | - |
| `STRUCTURED` | `{exitCode, success, timedOut, durationMillis, outputTruncated, stdout?, stderr?, input?}` |
| `RAW` | stdout as one string |
| `JSON` | `STRUCTURED` plus `output`, the stdout parsed as JSON (`null` if the process failed) |
| `PASSTHROUGH` | the input payload, unchanged |

* **Output ports:** `default`, or `success` and `failure` with `routeByExitCode`.
* **Metadata:** `exitCode` (`-1` on timeout). `reports` adds `failures` (at most 50 of `{kind, file, line, rule, message, test?}`) and `totalFailures` to `STRUCTURED` and `JSON` payloads. Output past the caps is discarded and `outputTruncated` is set.
* **Default node timeout:** `timeout` plus the larger of 5 seconds and a tenth of `timeout`.
* **Server settings:** execution is off until `yukta.process.allowed-commands` lists executables or `yukta.process.allow-any` is `true` (default `false`). While `allowed-commands` is set, `useShell` is refused, the executable must be listed and environment names such as `PATH` or `LD_*` need `yukta.process.allowed-env`. `yukta.process.working-dir-root` confines `workingDir`. See [Configuration](https://yukta.infenia.com/reference/configuration.md).
* **Variable safety:** `${metadata.<key>}` refuses keys containing `PASSWORD`, `SECRET` or `KEY`. With `useShell`, an element that uses `${...}` becomes one quoted word.
* **Errors:** `command is mandatory`; `timeout must be positive, got: <n>`; `routeByExitCode requires failureMode: CONTINUE`; `Process timed out after <n>s`; `Process execution is off: set yukta.process.allowed-commands (or yukta.process.allow-any=true to run any executable)`; `Command '<name>' is not in yukta.process.allowed-commands`.

```json theme={"system"}
{ "nodeId": "test", "type": "PROCESS_EXECUTOR", "config": { "command": ["mvn", "test"], "failureMode": "CONTINUE", "routeByExitCode": true } }
```

## `SQL_QUERY`

Module `sql-query`. Runs a parameterized statement over JDBC per message. The JDBC driver must be on the classpath. The node is blocking.

| Option | Type | Default | Required | Description |
| - | - | - | - | - |
| `url` | string | none | yes | JDBC URL; `${...}` supported. |
| `username` | string | none | no | Database user; `${...}` supported. |
| `password` | secret | none | no | Password; `decrypted:<key>` supported. |
| `sql` | string | none | yes | Statement with `?` placeholders. |
| `params` | list | none | no | Payload field names bound to the placeholders, in order. |
| `maxRows` | number | `1000` | no | Most rows returned. |
| `timeoutSeconds` | number | `30` | no | Statement timeout, positive. |
| `failureMode` | `ERROR` or `CONTINUE` | `ERROR` | no | `CONTINUE` routes a SQL error to the `error` port. |

* **Output ports:** `default`; plus `error` with `failureMode: CONTINUE`.
* **Payload:** `{rows, count}` for a query; `{updated}` for an update.

```json theme={"system"}
{ "nodeId": "lookup", "type": "SQL_QUERY", "config": { "url": "jdbc:postgresql://db/app", "password": "decrypted:db", "sql": "select * from users where id = ?", "params": ["userId"] } }
```

## `FILE_READ`

Module `file-io`. Reads a UTF-8 text file from a sandbox directory. The node is blocking.

| Option | Type | Default | Required | Description |
| - | - | - | - | - |
| `baseDir` | string | none | yes | Sandbox directory; paths outside it are rejected. |
| `path` | string | `payload.path` | no | File relative to `baseDir`. |
| `maxBytes` | number | `10485760` | no | Largest file read, in bytes. |
| `failureMode` | `ERROR` or `CONTINUE` | `ERROR` | no | `CONTINUE` routes a failure to the `error` port. |

* **Output ports:** `default`; plus `error` with `failureMode: CONTINUE`.
* **Payload:** `{path, content}`.
* **Server setting:** `yukta.files.allowed-root` confines `baseDir`; a `baseDir` or path that reaches outside it through a symbolic link is refused.
* **Errors:** `file larger than maxBytes (<n>): <file>`; `baseDir <dir> is outside the operator's root (yukta.files.allowed-root)`.

```json theme={"system"}
{ "nodeId": "read", "type": "FILE_READ", "config": { "baseDir": "/srv/work", "path": "report.txt" } }
```

## `FILE_WRITE`

Module `file-io`. Writes or appends text to a file in a sandbox directory and passes the message through. The node is blocking.

| Option | Type | Default | Required | Description |
| - | - | - | - | - |
| `baseDir` | string | none | yes | Sandbox directory; paths outside it are rejected. |
| `path` | string | `payload.path` | no | File relative to `baseDir`. |
| `contentField` | string | `content` | no | Payload field that holds the text; a string payload is written as is. |
| `append` | boolean | `false` | no | Append a line instead of overwriting. |
| `failureMode` | `ERROR` or `CONTINUE` | `ERROR` | no | `CONTINUE` routes a failure to the `error` port. |

* **Output ports:** `default`; plus `error` with `failureMode: CONTINUE`.
* **Errors:** `no content in payload.<field>`; the sandbox errors of `FILE_READ`.

```json theme={"system"}
{ "nodeId": "save", "type": "FILE_WRITE", "config": { "baseDir": "/srv/work", "path": "out.log", "append": true } }
```

## `AGENT_SESSION`

Module `process-executor`. Runs an AI agent harness, such as Claude Code, on a prompt and reports how it ended. Restricted: enable it with `yukta.plugins.enabled=AGENT_SESSION` and allow the harness executable (`yukta.process.allowed-commands=claude`). The process starts through the process executor, so its limits apply, and cancelling the run kills it.

| Option | Type | Default | Required | Description |
| - | - | - | - | - |
| `harness` | string | none | yes | The preset id; `claude-code` ships. Presets are JSON files in `agent-harnesses/` or in `yukta.ai.presets-dir`. |
| `prompt` | expression | none | yes | What to ask the agent. |
| `model` | string | none | no | Only for a harness that takes a model. |
| `maxTurns` | number | none | no | Only for a harness with a turn limit. |
| `args` | list | none | no | Extra command-line arguments, for example `["--allowedTools", "Read,Edit"]`. Without them Claude Code cannot use tools that need approval. |
| `session` | expression | none | no | A session key. Messages with the same key continue one conversation (the harness resumes from the token the last turn left). Needs a harness with resume (`claude-code` has it). Without it every message starts afresh. Sessions live in memory and are lost on restart. |
| `onBusy` | `WAIT` or `FAIL` | `WAIT` | no | A session runs one turn at a time. `WAIT` queues the next turn; `FAIL` sends it to `failure` at once. |
| `approvals` | `NONE` or `ASK` | `NONE` | no | `ASK`: each tool use the harness needs permission for becomes an `APPROVAL` request on the [input request system](https://yukta.infenia.com/guides/ai/ask-for-input.md), answered by a person, a supervisor or an agent. No answer in time, a rejection or any failure refuses the tool; the agent sees the refusal. Needs a harness with the ask capability (`claude-code` has it). |
| `approvalRisk` | `LOW`, `MEDIUM`, `HIGH` | `MEDIUM` | no | Risk of the requests; a supervisor may answer only up to its `maxRisk`. |
| `approvalTimeout` | number | `300` | no | Seconds to wait for an answer. |
| `approvalAudience` | list | current tier | no | Who may answer: `supervisor:<id>`, `role:OPERATOR`, `key:<name>`, ... |
| `workingDir`, `env` | string, map | none | no | Where it runs and extra environment. |
| `timeout` | number | `600` | no | Seconds. |

* **Output ports:** `success`, `failure` (the agent or harness failed, or timed out), `incomplete` (stopped early, for example out of turns).
* **Payload:** `{status, reason, text, sessionId, turn, exitCode}`.
* **Run log:** the agent's text and the tools it uses appear as `agent` lines while it works.

```json theme={"system"}
{ "nodeId": "fix", "type": "AGENT_SESSION", "config": { "harness": "claude-code", "prompt": "Fix the failing test", "args": ["--permission-mode", "acceptEdits"], "maxTurns": 20 } }
```

## Related

* [Plugin reference](https://yukta.infenia.com/reference/plugins/overview.md)
* [Configuration reference](https://yukta.infenia.com/reference/configuration.md)
* [Security reference](https://yukta.infenia.com/reference/security.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.