Skip to main content

terminal-agent

A minimal terminal coding agent built with LangGraph (agent loop), LangChain (tool + model abstraction), LangSmith (tracing), and a Hugging Face model as the LLM. Same shape as OpenCode/Terminus 2: read task -> decide -> run tool -> observe result -> repeat.

Setup

pip install -r requirements.txt
cp .env.example .env

Edit .env:

Run

python main.py

If OPENROUTER_API_KEY isn't set (env or .env), the agent prompts you to paste one at startup — input is hidden — and offers to save it to .env for next time. You can rotate it later with the /key command.

Switching models

/models            list all OpenRouter models (● = current, free first)
/models qwen       filter the list by name
/models --refresh  force a fresh fetch (list is cached for 24h)
/model 12          switch by list number
/model qwen/qwen-2.5-72b-instruct   or any OpenRouter model id directly

The list comes live from OpenRouter's API and is cached for 24 hours in ~/.cache/closecode/; if you're offline it falls back to a curated shortlist. The model choice is saved per session, so /resume restores the model you were using. Free-tier :free models cost nothing; check https://openrouter.ai/models for paid-model pricing before switching.

The agent operates inside ./sandbox (configurable via AGENT_WORKDIR) and will ask for permission before running shell commands or writing files, unless AGENT_AUTO_APPROVE=true.

Persistent sessions (SQLite)

Conversations are stored in ./sessions/sessions.db as per-message rows plus session metadata (name, model, mode, created/updated timestamps, message count). Existing session_*.json files are auto-migrated into the DB on the first run.

  • --continue — resume the most recently used session (its mode/model are restored from metadata).
  • /sessions — list all saved sessions with metadata.
  • /resume <id> — switch to a saved conversation.
  • /delete <id> — delete a saved session.
  • Each turn is saved automatically; a session's name is derived from its first user message.

Guardrails

The agent is scoped to coding only, and guardrails.py enforces that with four layers:

  1. Input scope — off-topic chatter (greetings, opinions, trivia, creative writing, news takes) is redirected to a coding task, and clearly malicious requests (keyloggers, account hacking, phishing kits) are refused before they reach the model.
  2. Command blocking — destructive shells commands (rm -rf /, mkfs, disk wipes, fork bombs, curl | sh, reverse shells) are blocked before execution, even when auto-approve is on.
  3. Write scanning — file writes/edits containing malware indicators (ransomware, keyloggers, miners, persistence, injection) are refused.
  4. Output redaction — the model's final answer is scanned and flagged content is scrubbed from conversation history.

These are conservative heuristics on top of the sandbox + per-action permission prompts, not a hard guarantee. Set AGENT_DISABLE_GUARDRAILS=true in .env to disable them entirely (only for trusted, isolated testing).

A note on model choice

Tool-calling reliability varies significantly across open Hugging Face models — this is the single biggest factor in whether this agent actually works well. Frontier closed models (what Claude Code / OpenCode use by default) are heavily trained specifically for reliable tool use; open models are improving but inconsistent.

Models worth trying, roughly in order of tool-calling reliability:

  • Qwen/Qwen2.5-72B-Instruct
  • meta-llama/Meta-Llama-3.1-70B-Instruct
  • meta-llama/Meta-Llama-3.1-8B-Instruct (fastest/cheapest, least reliable)

If a smaller model frequently fails to call tools correctly, or hallucinates tool arguments, that's expected — it's a real, documented gap between open and closed models on agentic tasks, not a bug in this code. Swapping HF_MODEL_ID is the first thing to try before changing anything else.

Where to go next

  1. Watch a trace in LangSmith (smith.langchain.com) once you have a run — seeing the exact messages/tool calls at each step is the fastest way to debug why the agent did something unexpected.
  2. Add more tools — list_dir, edit_file (targeted find/replace instead of full overwrite), run_tests.
  3. Split client/server — move build_graph() behind a small FastAPI/ WebSocket server, and make main.py a thin client that streams from it. This is the step that makes it architecturally closer to OpenCode.
  4. Swap the sandbox for Docker — the current harness restricts file paths but shell commands still run on your actual machine. For anything beyond personal experimentation, run bash calls inside a container instead.

Metadata

Release files for closecode-ai 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for closecode-ai 0.1.0
File Size Uploaded
closecode_ai-0.1.0.tar.gz 33.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for closecode-ai 0.1.0
File Interpreter ABI Platform
closecode_ai-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 70.4 kB

Release files / closecode_ai-0.1.0.tar.gz

Download URL closecode_ai-0.1.0.tar.gz
Size 33.1 kB
Tags Source
SHA-256 checksum
How to use checksums
f468917adde640851b0e6c4d76e2de70e8870d8082d189509a981b3ad2a66c1f
BLAKE2b-256 checksum
How to use checksums
6bcaf8bb68f5fd273eb18d07b69fe863109c411430b548d3d3e908592a62e7d0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / closecode_ai-0.1.0-py3-none-any.whl

Download URL closecode_ai-0.1.0-py3-none-any.whl
Size 37.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4da2c04f998c401790f208e515a372c6da51ce8b65c22fea69948d9b5e9b7f3b
BLAKE2b-256 checksum
How to use checksums
831098551a9f86ca229bf86fd08e4a2fd6cae322dcdca80ed6d48ecdc308c2f0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page