Process Local Files with an AI Agent

Build an AI agent that can read, analyze, and process files on your local machine. This is the killer use case for Tensorify's CLI runner — your agent gets full filesystem access while remaining callable as an OpenAI-compatible API.

Uses: API Trigger, AI Agent, Code (as tools), Return, CLI Runner Time: ~15 minutes


What You'll Build

A codebase assistant that can:

  • List files and directories in your projects
  • Read file contents
  • Analyze code structure and find patterns
  • Summarize documentation

All running on your own machine, with your data never leaving your infrastructure.

Why CLI Runner for Local Files?

| Feature | Cloud (Managed) | CLI Runner | |---|---|---| | Filesystem access | Sandbox only | Full local access | | localhost services | Not available | Full access | | Environment variables | Configured in dashboard | Inherited from host | | Data privacy | Cloud-processed | Stays on your machine |

The CLI runner executes Python on your machine, so Code nodes can use Python's standard library to read files, connect to local databases, and call internal services.

Prerequisites

Step 1: Create the Workflow

  1. Create a new workflow (or use the AI Agent with Tools template as a starting point)
  2. Add these nodes:
    • API Trigger (protocol: openai-chat)
    • AI Agent
    • Code (file reader tool)
    • Code (directory lister tool)
    • Return

Step 2: Build the File Reader Tool

Add a Code node and name it "Read File":

import json

input_data = json.loads(data)
file_path = input_data.get("path", "")

try:
    with open(file_path, "r") as f:
        content = f.read()
    result = {"content": content, "path": file_path, "size": len(content)}
except FileNotFoundError:
    result = {"error": f"File not found: {file_path}"}
except PermissionError:
    result = {"error": f"Permission denied: {file_path}"}

Connect this Code node's response output to the AI Agent's tool:read_file input (the handle name comes from the node label).

Step 3: Build the Directory Lister Tool

Add another Code node and name it "List Files":

import os
import json

input_data = json.loads(data)
directory = input_data.get("path", ".")

try:
    entries = []
    for entry in os.listdir(directory):
        full_path = os.path.join(directory, entry)
        entries.append({
            "name": entry,
            "type": "directory" if os.path.isdir(full_path) else "file",
            "size": os.path.getsize(full_path) if os.path.isfile(full_path) else None,
        })
    result = {"entries": entries, "path": directory, "count": len(entries)}
except FileNotFoundError:
    result = {"error": f"Directory not found: {directory}"}

Connect this to the AI Agent's tool:list_files input.

Step 4: Configure the AI Agent

Set up the AI Agent with a system prompt that teaches it how to use the tools:

You are a codebase assistant with access to the local filesystem.
You can list directories and read files to help answer questions about code.

Available tools:
- list_files: Lists files in a directory. Pass {"path": "/absolute/path"}
- read_file: Reads a file's contents. Pass {"path": "/absolute/path/to/file"}

When asked about a project:
1. First list the directory to understand the structure
2. Read relevant files (README, main entry points, config files)
3. Provide clear, helpful analysis

Always use absolute paths. Be careful not to read binary files.

Set Max Iterations to 10 (the agent may need multiple tool calls to explore a codebase).

Step 5: Wire the Workflow

Connect the nodes:

  1. API Trigger POST → AI Agent message
  2. Code (Read File) response → AI Agent tool:read_file
  3. Code (List Files) response → AI Agent tool:list_files
  4. AI Agent response → Return input

Step 6: Deploy to CLI Runner

  1. Click Deploy
  2. Set Execution Mode to CLI
  3. Select your runner
  4. Click Deploy

Then start the runner:

tensorify runner start

Step 7: Query Your Agent

from openai import OpenAI

client = OpenAI(
    base_url="https://triggers.tensorify.io/h/YOUR_HOOK_PATH",
    api_key="your-tensorify-api-key",
)

response = client.chat.completions.create(
    model="tensorify",
    messages=[{
        "role": "user",
        "content": "Explore /home/user/projects/my-app and tell me what it does."
    }],
)

print(response.choices[0].message.content)

The agent will:

  1. Call list_files to see the project structure
  2. Call read_file on README.md, package.json, or main entry files
  3. Synthesize a summary of the project

More Tool Ideas

You can add more Code tools for advanced file processing:

Search Files by Content

import os
import json

input_data = json.loads(data)
directory = input_data.get("path", ".")
pattern = input_data.get("pattern", "")

matches = []
for root, dirs, files in os.walk(directory):
    dirs[:] = [d for d in dirs if d not in ['.git', 'node_modules', '__pycache__', '.venv']]
    for fname in files:
        fpath = os.path.join(root, fname)
        try:
            with open(fpath, 'r') as f:
                for i, line in enumerate(f, 1):
                    if pattern in line:
                        matches.append({"file": fpath, "line": i, "content": line.strip()})
        except (UnicodeDecodeError, PermissionError):
            pass

result = {"matches": matches[:50], "pattern": pattern, "total": len(matches)}

Get File Stats

import os
import json
from datetime import datetime

input_data = json.loads(data)
path = input_data.get("path", "")

stat = os.stat(path)
result = {
    "path": path,
    "size_bytes": stat.st_size,
    "modified": datetime.fromtimestamp(stat.st_mtime).isoformat(),
    "created": datetime.fromtimestamp(stat.st_ctime).isoformat(),
    "is_file": os.path.isfile(path),
    "is_dir": os.path.isdir(path),
}

Security Considerations

Since the agent has filesystem access, consider:

  • Restrict paths — Validate paths in your Code tools to prevent access to sensitive directories
  • Read-only tools — Only provide read tools unless write access is explicitly needed
  • Authentication — Use bearer tokens on the API Trigger to prevent unauthorized access
  • Local-only — The CLI runner only accepts inbound requests via the Tensorify WebSocket bridge, not direct network connections

What's Next?

On this page