aJent is a dynamic, highly capable AI framework written in Clojure. It utilizes a Unified Concurrent Orchestrator architecture, where a single LLM instance acts as the central brain, dynamically discovering and utilizing a fleet of decoupled RESTful microservices (Tool Servers) to accomplish complex user tasks.
Built natively around the OpenAI-compatible API standard, aJent executes robust ReAct (Reason + Act) loops to solve complex problems, running tool calls in parallel across a polyglot microservice fleet while strictly managing its own context window to ensure stable, long-running sessions.
Equipped with full host machine access, a unified tool configuration system, a Dockerized Python-as-a-Service code interpreter, and a human-in-the-loop security gate, aJent is designed to be a pragmatic, powerful digital worker for automating routine system operations, data analysis, document generation, and network tasks.
aJent intentionally champions the Single-Agent Concurrent Orchestrator model. This is the industry gold standard, used by OpenAI's Assistants API and LangChain's AgentExecutor, because it solves the core problems of multi-agent systems:
tool_calls in a single response, and aJent's Clojure backend executes the requests to different microservices in parallel using pmap. You get the performance of multi-agent systems without the complexity of inter-agent communication.aJent's most powerful capability is its integration with a Dockerized Python REST server. Instead of writing rigid REST wrappers for every conceivable data science or document generation library, aJent includes an execute_python tool.
numpy, pandas, scipy, matplotlib, pymupdf (PDF), python-docx (Word), python-pptx (PowerPoint), and openpyxl (Excel).arabic-reshaper, python-bidi, and pre-installed fonts (Vazirmatn, B Nazanin) for flawless right-to-left PDF and image generation./app/output), allowing the user instant access to AI-generated documents.Unlike sandboxed frameworks, aJent is designed as a local, single-agent automation worker. It has full, unrestricted read/write access to the host machine's file system. The LLM is instructed to use exact absolute paths for all operations, empowering it to traverse directories, read logs, and write code wherever the user points it.
Because the agent has unrestricted access, aJent implements a strict permission architecture. When the LLM attempts to perform a destructive operation (such as delete_file, delete_directory, or executing a destructive shell command like rm or mkfs), the Clojure orchestrator intercepts the request and pauses the agent loop. It prompts the user in the terminal for explicit [y/N] approval. The agent will not proceed until permission is granted, preventing catastrophic data loss from LLM hallucinations.
tool_servers.json)aJent centralizes tool server discovery into a single, structured JSON file: tool_servers.json. This replaces flat text registries and allows for rich server metadata, including:
name and description: For better logging and routing.timeout_ms: Per-server HTTP timeout configurations, preventing the agent from hanging indefinitely if a microservice crashes.enabled: Toggle servers on/off without deleting configuration entries.aJent actively protects its own memory. It employs a sliding window to age out old conversation history safely, dropping leading 'tool' or 'assistant' messages to prevent OpenAI API 400 errors. It automatically caps massive tool outputs (like recursive directory listings) via a configurable max-observation-chars limit to prevent context overflow crashes.
aJent is language-agnostic. Any microservice that adheres to the following HTTP/JSON contract can be used as an aJent REST Tool Server.
GET /schemaPOST /tools/call{ "name": "tool_name", "arguments": { "arg1": "value" } }{ "result": "Success data or string", "is_error": false } or { "error": "Description of the failure", "is_error": true }(Note: Logical errors should return HTTP 200 with the error payload so the LLM can read the error string and recover. Do not return HTTP 500 for expected logic failures).
aJent operates with a specialized fleet of REST microservices exposing high-performance native tools:
aJent's tool servers are located in the servers/ directory. To run aJent, you must start these servers first.
cd servers/python-runtime
docker build -t ajent-python-server .
docker run -d -p 4007:4007 -v ~/Documents/ajent_files:/app/output --name ajent-python ajent-python-server
cd ../..
The pre-built JAR is included in the repository. You can run it directly:
cd servers/time-server
java -jar target/time-server.jar &
cd ../..
(If you prefer to build from source, run lein uberjar inside the time-server directory).
The servers/ directory contains a CMakeLists.txt file and the include/ folder with cpp-httplib and nlohmann/json.
On Linux / macOS:
cd servers
mkdir build && cd build
cmake ..
make
# Run the compiled binaries
./math_server 127.0.0.1 4001 &
./directory_server 127.0.0.1 4002 &
./file_server 127.0.0.1 4003 &
./shell_server 127.0.0.1 4004 &
./utility_server 127.0.0.1 4005 &
cd ../..
On Windows (using CMake and Visual Studio):
cd servers
mkdir build
cd build
cmake ..
cmake --build . --config Release
:: Run the compiled executables
Release\math_server.exe 127.0.0.1 4001
Release\directory_server.exe 127.0.0.1 4002
Release\file_server.exe 127.0.0.1 4003
Release\shell_server.exe 127.0.0.1 4004
Release\utility_server.exe 127.0.0.1 4005
cd ..\..
aJent requires an OpenAI-compatible API. For local execution, llama.cpp is highly recommended.
llama-server --jinja -m ~/llms/gpt-oss-20b.gguf \
--n-gpu-layers 999 --parallel 1 --cont-batching \
--ctx-size 16384 --batch-size 1024 --flash-attn on \
--host 127.0.0.1 --port 8080
Run the framework using lein or by building an uberjar.
Via Leiningen:
lein run local http://localhost:8080 gpt-oss-20b 0.7
Via Uberjar:
lein uberjar
java -jar target/ajent.jar local http://localhost:8080 gpt-oss-20b 0.7
You will be greeted with the aJent> prompt. Type your prompts and press Enter. Type exit or quit to stop.
tool_servers.jsonLocated in the project root directory. It acts as the single source of truth for the REST tool fleet.
{
"rest_servers": [
{
"name": "python-runtime",
"description": "Dockerized Python 3 environment.",
"url": "http://127.0.0.1:4007",
"enabled": true,
"timeout_ms": 60000
},
{
"name": "math",
"url": "http://localhost:4001",
"enabled": true,
"timeout_ms": 5000,
"description": "Arithmetic, statistics and random-number tools"
}
]
}
providers.json (Optional)Allows overriding built-in LLM provider definitions or adding custom OpenAI-compatible gateways.
{
"my-company-gateway": {
"description": "Internal OpenAI-compatible gateway",
"base-url": "https://gateway.internal:8443/v1",
"api-key-env": "GATEWAY_API_KEY",
"default-model": "gpt-4o-mini",
"max-iterations": 30
}
}
execute_python tool, the LLM is strictly instructed to save generated files to the /app/output directory, ensuring the user can access them on the host machine.servers/ directory with CMake and Docker support.Prerequisites:
I would like to express my gratitude to my AI assistant and mentor, GLM-5.2, for their exceptional consultancy and collaborative support throughout the development of this project.
Copyright © 2026 Pooria Yousefi Distributed under the Eclipse Public License 2.0.
Can you improve this documentation?Edit on GitHub
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |