packages feed

pms-infra-agent-serial-0.0.1.0: README.md

# pms-infra-agent-serial

----
## ⚠️ Caution

**Do not grant unrestricted control to AI.**

Unsupervised use or misuse may lead to unintended consequences.
All AI systems must remain strictly under human oversight and control.
Use responsibly, with full awareness and at your own risk.

----
## πŸ“˜ Overview

**`pms-infra-agent-serial`** is a Haskell infrastructure library that provides AI agents with direct, low-level control over serial communication endpoints.

Unlike prompt-oriented serial abstractions, this library exposes raw serial I/O as both UTF-8 strings and byte-level hex strings. This allows agents to handle device-specific protocols, binary command frames, console sessions, and real-time serial monitoring with fine-grained control.

The library is a core component of the [`pty-mcp-server`](https://github.com/phoityne/pty-mcp-server) ecosystem and implements the `agent-serial-*` family of MCP tools.

---

## πŸ”§ Provided MCP Tools

### `agent-serial-open`
Opens a serial port connection for subsequent read/write operations.
Only one serial port connection can be active at a time.

- `device` β€” Serial device path (for example `/dev/ttyUSB0` or `COM3`)
- `commSpeed` β€” Baud rate (for example `9600` or `115200`; default: `9600`)
- `bitsPerWord` β€” Data bits (`5` to `8`; default: `8`)
- `stopb` β€” Stop bits (`1` or `2`; default: `1`)
- `parity` β€” Parity (`NoParity`, `Odd`, or `Even`; default: `NoParity`)
- `flowControl` β€” Flow control (`NoFlowControl` or `Software`; default: `NoFlowControl`)
- `timeout` β€” Read timeout in tenths of a second (default: `1`)

### `agent-serial-close`
Closes the active serial port connection and releases all associated resources.

### `agent-serial-read`
Reads up to the specified number of bytes from the active serial port and returns the data as a **UTF-8 string**.
Returns an empty string if no data is available before timeout.

- `size` β€” Maximum number of bytes to read

> ⚠️ If the received data contains non-UTF-8 bytes or binary protocol frames, use `agent-serial-read-byte` instead.

### `agent-serial-read-byte`
Reads up to the specified number of bytes from the active serial port and returns the data as an **uppercase hex string** (e.g., `FF0A1B41`).
Use this for binary protocols or when precise byte-level inspection is required.

- `size` β€” Maximum number of bytes to read

### `agent-serial-write`
Writes the specified **UTF-8 string** to the active serial port.

- `data` β€” Text data to write
- `appendNewline` β€” When omitted or `true`, appends CR+LF automatically. When `false`, sends the string as-is.

> ⚠️ To send exact byte sequences (for example binary frames, checksums, or explicit CR+LF bytes), use `agent-serial-write-byte`.

### `agent-serial-write-byte`
Decodes the specified **hex string** and writes the resulting bytes to the active serial port.
Use this for binary protocols or when precise byte-level control is required.

- `data` β€” Hex string to decode and write (e.g., `DEADBEEF0D0A`; uppercase and lowercase are accepted)

---

## πŸ’‘ Usage Notes

### Serial protocol handling
Prompt detection, command framing, response parsing, retries, checksums, and other protocol-specific behavior are the **responsibility of the agent**, not the library.
Use `agent-serial-read-byte` and `agent-serial-write-byte` when communicating with devices that require byte-accurate exchanges.

Example binary command flow:
```
β†’ 010300000002C40B   (Agent: write Modbus RTU request as bytes)
← 010304000A0014DA3E (Device: response read as bytes)
```

Example console flow:
```
← "login: "          (Device prompt β€” read as UTF-8 string)
β†’ "admin\r\n"        (Username β€” send with appendNewline or exact bytes)
← "Password: "       (Password prompt)
```

### Newline behavior
`agent-serial-write` appends CR+LF by default to support common serial-console workflows.
Set `appendNewline` to `false` when the target protocol requires exact text without automatic line endings.

### Read size limit
Read operations cap the requested size to the internal read buffer size.
For large outputs, poll repeatedly with `agent-serial-read` or `agent-serial-read-byte`.

---

## πŸ—οΈ Architecture

### Module Structure

```
PMS.Infra.Agent.Serial
β”œβ”€β”€ DM.Type        -- Data type definitions (AppData, tool parameter types)
β”œβ”€β”€ DM.Constant    -- Constants
β”œβ”€β”€ DS.Core        -- Core domain service logic
β”œβ”€β”€ DS.Utility     -- Utility functions (serial settings, hex decoding, AppContext helpers)
└── App.Control    -- Application control: tool dispatch and serial lifecycle management
```

### Key Design Points

- **Single active port**: Only one serial port can be open at a time per server instance. State is managed via `STM.TMVar`.
- **Configurable serial settings**: `agent-serial-open` supports baud rate, data bits, stop bits, parity, flow control, and read timeout.
- **Non-blocking reads**: Read operations return available data within the configured serial timeout, allowing the agent to poll at its own pace.
- **Byte-level I/F**: In addition to UTF-8 string I/F, hex string I/F is provided for binary protocol handling. Device protocol processing is delegated to the agent.

---

## πŸ“¦ Dependencies

- [`pms-domain-model`](https://github.com/phoityne/pms-domain-model)
- [`serialport`](https://hackage.haskell.org/package/serialport)

---

## πŸ“œ Credits & License

- **Execution & Process Lead:** Claude Sonnet 4.6, Gemini 3 Flash, GPT-5.5
- **Direction & Policy:** phoityne
- **License:** Apache-2.0 β€” see [LICENSE](./LICENSE)

---