A CLI chat application that connects a local LLM (via any OpenAI-compatible API)
to tshell through the Koog agent framework.
The LLM gets a single tshell tool and can execute tshell code to answer questions,
transform data, and explore files.
- JDK 21+
- A local LLM server exposing an OpenAI-compatible API with tool-call support.
llama.cpp
llama-serverworks well:
# Example: start llama-server with a model
llama-server -m model.gguf --port 8080From the repository root:
./gradlew :local-llm:installDistThis produces the runnable distribution at local-llm/build/install/local-llm/.
./local-llm/build/install/local-llm/bin/local-llmOpens a REPL. The LLM can call the tshell tool to compute answers.
./local-llm/build/install/local-llm/bin/local-llm -p "What is 2^10?"Runs one prompt and exits.
./local-llm/build/install/local-llm/bin/local-llm --url http://localhost:1234Default is http://localhost:8080.
./local-llm/build/install/local-llm/bin/local-llm -d /path/to/projectGives the LLM read-only access to the directory via tshell's FileToolkit.
The LLM can then use tree(), read("file"), glob("**/*.kt"), and
grep("path", {match: "pattern"}) to explore files.
| Option | Description |
|---|---|
--url URL |
Base URL for the OpenAI-compatible API (default: http://localhost:8080) |
-p, --prompt TEXT |
Run a single prompt and exit |
-d, --dir PATH |
Root directory for read-only file access |
- On startup, fetches
/v1/modelsfrom the server and selects a model. - Sets up a
TShellinstance withCoreToolkit(andFileToolkitif--diris given). - Wraps the shell in a
TShellToolsKoogToolSet— a singletshell(code)tool. - Creates a Koog
AIAgentwith a system prompt that includes tshell syntax reference (auto-generated byshell.toPrompt()). - Each user message is sent to the agent, which may call
tshell(...)one or more times before producing a final answer.
Console tracing (ConsoleTracingFeature) prints LLM calls, tool invocations, and
results as they happen, so you can see the agent's reasoning.
$ ./local-llm/build/install/local-llm/bin/local-llm -d .
Connecting to http://localhost:8080 ...
Using model: my-model
File access: /home/user/project (read-only)
tshell local-llm chat (type 'quit' to exit)
──────────────────────────────────────────────────
you> What files are in this project?
⟶ LLM call...
⚙ Tool call: tshell(tree())
✓ Tool result: { ... }
⟶ LLM call...
llm> The project contains src/, build.gradle.kts, README.md, ...
you> How many Kotlin files?
⟶ LLM call...
⚙ Tool call: tshell(glob("**/*.kt") |> len())
✓ Tool result: 42
⟶ LLM call...
llm> There are 42 Kotlin files in the project.
you> quit
Goodbye.