aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 385af9238b35debd246ed7f5adba983f18dd4beb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91

# Coding Agent

I use this as a wrapper for agentic tasks around the [Local LLM Gateway](https://www.aalto.fi/en/services/local-llm-gateway) provided by Aalto University.
The wrapper should be general enough to work with any OpenAI compliant API endpoint, though.

It seems that the API endpoint provided by Aalto does not support server-side chat history or chat history compaction or agentic tools, so the API is used just as a dumb endpoint for getting textual LLM responses.

## Features

The agent can call the following tools, given it has the required permissions.
- `ls`: List files at a specified path.
- `read`: Read the contents of a file.
- `write`: Write content to a file.
- `tldr`: Read simplified man pages (`tldr`) for a program.
- `shell`: Execute a shell command.
- `mypy`: Run static type checking on a Python file.
- `webgrep`: Search for keywords within the markdownified content of a URL.

If you want to add actions, just create an instance of class `Action` as in `actions.py`, and then include it in the action list passed to `query_agent` in the main function in `llm.py`.

The agent manages its context size somewhat automatically, though this functionality could be refined.

There is support for routing the queries through a SOCKS5 proxy.


## Requirements

- Python 3.x
- `openai` Python library
- `httpx2` Python library
- `socksio` Python library, if you want to proxy your connections to the API endpoint
- `tldr` if you want the agent to be able to view `tldr` documentations
- `pandoc` if you want the agent to be able to query websites
- `mypy` if you want the agent to be able to run static type checking
- An API key for the Aalto LLM Gateway (or a compatible OpenAI-style API)

## Setup

1. **Set the API Key**:
   The agent expects the API key to be stored in an environment variable:
   ```bash
   export LLM_API_KEY="your_api_key_here"
   ```
   Optionally, you can also configure the endpoint, model, and context size via environment variables:
   ```bash
   export LLM_API_ENDPOINT="https://llm-gateway.k8s.aalto.fi/api/v1"
   export LLM_MODEL="zai-org/GLM-5.3-Flash"
   export LLM_CONTEXT_SIZE=1048576
   ```

2. **Run the Agent**:
   Execute the script using Python:
   ```bash
   python3 llm.py
   ```

### Configuration

- `--workdir PATH`: Specify the directory the agent has access to. If not provided, it defaults to the current working directory.
  ```bash
  python3 llm.py --workdir /path/to/your/project
  ```
- `--endpoint URL`: The API endpoint for the LLM (defaults to `LLM_API_ENDPOINT`, or `https://llm-gateway.k8s.aalto.fi/api/v1`).
- `--key KEY`: The API key for the LLM endpoint (defaults to `LLM_API_KEY` environment variable).
- `--model MODEL`: The model name to use (defaults to `LLM_MODEL`, or `zai-org/GLM-5.3-Flash`).
- `--min-history N`: Minimum amount of most recent messages to keep intact when summarising the history to keep the context short enough (default: 3).
- `--model-context-size N`: Context size supported by the model (defaults to `LLM_CONTEXT_SIZE`, or 1048576).
- `--trust-level LEVEL`: The trust level of the agent (defaults to 2). Determines which actions require manual approval.
- `--socks5-proxy URL`: Route API queries (and `webgrep` fetches) through a SOCKS5 proxy (defaults to `LLM_SOCKS5_PROXY` environment variable).
  ```bash
  python3 llm.py --socks5-proxy socks5://user:pass@proxy.example.com:1080
  ```
  Use `socks5h://` as the scheme to also resolve DNS hostnames through the proxy. This requires the `socksio` package to be installed in the virtualenv (`pip install socksio`).


## Security and Permissions

To prevent unauthorized file system access, all file operations are restricted to the specified `--workdir` and its subdirectories. This does obviously not work for arbitrary shell commands.

Actions are assigned trust levels. If an action's required trust level exceeds the agent's current trust level, the system will explicitly prompt the user for permission before execution (`Perform [action]? [y/N]`). The trust levels are provided below, but you can edit them yourself quite easily in llm.py.

- `ls`, `read`, `tldr`, `mypy`: Level 0
- `webgrep`: Level 1
- `write`: Level 2
- `shell`: Level 3


## Use of AI

I have used this agent heavily in developing this agent, but I have manually maintained code quality and personal style.