> ## Documentation Index
> Fetch the complete documentation index at: https://extended-openai-conversation.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Read File Functions

> Read file contents safely with path restrictions

Read File functions allow AI assistants to read file contents from the filesystem with built-in security controls that restrict access to designated directories.

## Configuration

```yaml theme={null}
function:
  type: read_file
  path: "{{ filename }}"
```

<ParamField path="path" type="template" required>
  Path to the file to read. Can be absolute or relative to the working directory (`config/extended_openai_conversation/`).
</ParamField>

<ParamField path="allow_dir" type="array">
  Optional list of additional allowed directories (as templates). By default, only the working directory is allowed.
</ParamField>

## Working Directory

The default working directory is `config/extended_openai_conversation/`.

<Tabs>
  <Tab title="Relative Path">
    ```yaml theme={null}
    # Reads from /config/extended_openai_conversation/notes.txt
    function:
      type: read_file
      path: "notes.txt"
    ```
  </Tab>

  <Tab title="Subdirectory">
    ```yaml theme={null}
    # Reads from /config/extended_openai_conversation/data/config.json
    function:
      type: read_file
      path: "data/{{ filename }}"
    ```
  </Tab>

  <Tab title="Absolute Path">
    ```yaml theme={null}
    # Reads from /config/automations.yaml (must be in allowed directories)
    function:
      type: read_file
      path: "/config/automations.yaml"
    ```
  </Tab>
</Tabs>

## Examples

### Read File

```yaml theme={null}
- spec:
    name: read_file
    description: Read a file from workspace.
    parameters:
      type: object
      properties:
        filename:
          type: string
          description: Name of the file to read
      required:
      - filename
  function:
    type: read_file
    path: "{{ filename }}"
```

### Custom Allowed Directories

Extend allowed directories beyond the default workspace. The `allow_dir` parameter adds additional directories where files can be read.

```yaml theme={null}
- spec:
    name: read_file_with_allow_dir
    description: Read a file with custom allowed directories.
    parameters:
      type: object
      properties:
        filename:
          type: string
          description: Name of the file to read
      required:
      - filename
  function:
    type: read_file
    path: "{{ filename }}"
    allow_dir:
      - "/backup"
      - "/media"
```

<Info>
  `allow_dir` accepts templates, so you can use variables like `{{ config_dir }}`:

  ```yaml theme={null}
  allow_dir:
    - "{{ config_dir }}/custom_components"
    - "{{ config_dir }}/www"
  ```
</Info>

## Return Value

On success:

```json theme={null}
{
  "content": "file contents here...",
  "size": 1234
}
```

On error:

```json theme={null}
{
  "error": "File not found: filename.txt"
}
```

### Error Types

* **File not found**: The specified file doesn't exist
* **Not a file**: The path points to a directory
* **File too large**: File exceeds 1 MB size limit
* **Access denied**: File is outside allowed directories
* **Permission error**: Insufficient permissions to read file

## File Size Limit

Files larger than **1 MB** (1,048,576 bytes) are blocked to prevent memory issues:

```json theme={null}
{
  "error": "File too large: 2097152 bytes (limit: 1048576)"
}
```

<Tip>
  For large files, consider using bash functions with `head`, `tail`, or `grep` to read specific parts:

  ```yaml theme={null}
  type: bash
  command: "head -n 100 {{ large_file }}"
  ```
</Tip>

## Security

<AccordionGroup>
  <Accordion title="Path Restriction">
    Files must be within allowed directories. By default:

    * `/config/extended_openai_conversation/` (working directory)

    Additional directories can be added via `allow_dir`.
  </Accordion>

  <Accordion title="Path Traversal Protection">
    Paths are resolved to absolute paths and validated against allowed directories. Attempts to use `../` to escape allowed directories will be blocked:

    ```yaml theme={null}
    # BLOCKED - tries to escape allowed directory
    path: "../../../etc/passwd"
    ```
  </Accordion>

  <Accordion title="Size Limits">
    Files over 1 MB are automatically rejected to prevent memory exhaustion.
  </Accordion>

  <Accordion title="UTF-8 Encoding">
    Files are read with UTF-8 encoding. Binary files may not be read correctly.
  </Accordion>
</AccordionGroup>

## Use Cases

<CardGroup cols={2}>
  <Card title="Configuration Review" icon="gear">
    Read and analyze Home Assistant configuration files
  </Card>

  <Card title="Log Analysis" icon="file-lines">
    Read log files to diagnose issues
  </Card>

  <Card title="Data Files" icon="database">
    Access JSON, YAML, CSV, or text data files
  </Card>

  <Card title="Script Review" icon="code">
    Read automation scripts and templates
  </Card>
</CardGroup>

## Common Patterns

### Read YAML Configuration

```yaml theme={null}
- spec:
    name: read_automation_config
    description: Read automation configuration
    parameters:
      type: object
      properties: {}
  function:
    type: composite
    sequence:
      - type: read_file
        path: "/config/automations.yaml"
        response_variable: file_content
      - type: template
        value_template: |
          {% set data = file_content.content | from_yaml %}
          Found {{ data | length }} automations:
          {% for auto in data %}
          - {{ auto.alias }}
          {% endfor %}
```

### Read and Parse JSON

```yaml theme={null}
- spec:
    name: read_json_data
    description: Read and parse JSON file
    parameters:
      type: object
      properties:
        filename:
          type: string
  function:
    type: composite
    sequence:
      - type: read_file
        path: "{{ filename }}"
        response_variable: file
      - type: template
        value_template: |
          {% if 'error' in file %}
            {{ file.error }}
          {% else %}
            {% set data = file.content | from_json %}
            {{ data }}
          {% endif %}
```

### Search File Content

```yaml theme={null}
- spec:
    name: search_in_file
    description: Search for text in a file
    parameters:
      type: object
      properties:
        filename:
          type: string
        search_term:
          type: string
  function:
    type: composite
    sequence:
      - type: read_file
        path: "{{ filename }}"
        response_variable: file
      - type: template
        value_template: |
          {% if 'error' in file %}
            Error: {{ file.error }}
          {% elif search_term in file.content %}
            Found "{{ search_term }}" in {{ filename }}
          {% else %}
            "{{ search_term }}" not found in {{ filename }}
          {% endif %}
```

## Examples

### Read Multiple Files

```yaml theme={null}
- spec:
    name: read_config_files
    description: Read multiple configuration files
    parameters:
      type: object
      properties:
        files:
          type: array
          items:
            type: string
          description: List of filenames to read
  function:
    type: template
    value_template: |
      {% for filename in files %}
      === {{ filename }} ===
      {% set file = namespace(content='') %}
      {# In real implementation, use composite function to read each file #}
      {% endfor %}
```

<Note>
  To read multiple files, use a composite function that loops through each file, or create separate function calls for each file.
</Note>

### Read with Error Handling

```yaml theme={null}
- spec:
    name: safe_read_file
    description: Safely read a file with error handling
    parameters:
      type: object
      properties:
        filename:
          type: string
  function:
    type: composite
    sequence:
      - type: read_file
        path: "{{ filename }}"
        response_variable: result
      - type: template
        value_template: |
          {% if 'error' in result %}
            Unable to read file: {{ result.error }}
          {% elif 'content' in result %}
            File: {{ filename }}
            Size: {{ result.size }} bytes
            Content:
            {{ result.content }}
          {% endif %}
```

## Best Practices

<Steps>
  <Step title="Validate file paths">
    Always validate that requested files are appropriate to read:

    ```yaml theme={null}
    value_template: |
      {% if filename.endswith('.yaml') or filename.endswith('.json') %}
        {# Read file #}
      {% else %}
        Error: Only YAML and JSON files allowed
      {% endif %}
    ```
  </Step>

  <Step title="Handle errors gracefully">
    Check for errors in the response and provide helpful feedback:

    ```yaml theme={null}
    value_template: |
      {% if 'error' in file_result %}
        Could not read file: {{ file_result.error }}
      {% else %}
        {{ file_result.content }}
      {% endif %}
    ```
  </Step>

  <Step title="Be mindful of file size">
    Large files (>1MB) are blocked. For large files, use bash functions to read portions:

    ```yaml theme={null}
    type: bash
    command: "tail -n 50 {{ large_log_file }}"
    ```
  </Step>

  <Step title="Use appropriate allowed directories">
    Only add directories to `allow_dir` that the AI should legitimately access:

    ```yaml theme={null}
    # Good - specific purpose
    allow_dir:
      - "/config/www"
      - "/config/custom_components"

    # Bad - too broad
    allow_dir:
      - "/"
    ```
  </Step>
</Steps>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Access denied: path not in allowed directories">
    The file is outside allowed directories. Either:

    * Move the file to the workspace (`/config/extended_openai_conversation/`)
    * Add the file's directory to `allow_dir`
    * Use an absolute path to `/config/` if appropriate
  </Accordion>

  <Accordion title="File too large">
    The file exceeds 1 MB. Options:

    * Use bash functions to read portions (`head`, `tail`, `grep`)
    * Split the file into smaller chunks
    * Process the file externally and save results to a smaller file
  </Accordion>

  <Accordion title="File not found">
    Check:

    * File path is correct (relative to working directory)
    * File exists at the specified location
    * Path separators are correct (use `/` on all platforms)
  </Accordion>

  <Accordion title="Encoding errors">
    Files must be UTF-8 encoded. For binary files or other encodings, consider using bash functions:

    ```yaml theme={null}
    type: bash
    command: "file {{ filename }} && xxd -l 100 {{ filename }}"
    ```
  </Accordion>
</AccordionGroup>

## FAQ

<AccordionGroup>
  <Accordion title="Can I read binary files?">
    No. Read File functions use UTF-8 text encoding. For binary files, use bash functions:

    ```yaml theme={null}
    type: bash
    command: "xxd {{ binary_file }} | head -n 20"
    ```
  </Accordion>

  <Accordion title="What's the maximum file size?">
    1 MB (1,048,576 bytes). This limit prevents memory issues when processing large files.
  </Accordion>

  <Accordion title="Can I read files outside /config?">
    Yes, by adding directories to `allow_dir`. However, the default workspace and `/config` are always available.
  </Accordion>

  <Accordion title="Are symbolic links followed?">
    Yes. Paths are resolved to their real locations, then validated against allowed directories.
  </Accordion>
</AccordionGroup>

## Next Steps

<CardGroup cols={3}>
  <Card title="Write File" icon="pen" href="/functions/write_file">
    Write content to files
  </Card>

  <Card title="Edit File" icon="pen-to-square" href="/functions/edit_file">
    Edit files with find-and-replace
  </Card>

  <Card title="Bash Functions" icon="terminal" href="/functions/bash">
    More flexible file operations
  </Card>
</CardGroup>
