FCHT Agent — First-Class Hermes Tool Agent
Offline ReAct agent with persistent dual-memory (episodic + semantic) — runs entirely on your hardware.
🎯 What Is This?
FCHT Agent is a local-first AI agent that runs 100% offline on your machine using Ollama and your choice of local LLM (default: qwen2.5:7b). It features:
| Capability | Description |
|---|---|
| ReAct Loop | Think → Act → Observe reasoning with tool use |
| Episodic Memory | JSONL few-shot history for context-aware responses |
| Semantic Memory | ChromaDB + sentence-transformers for RAG |
| Skill System | Agent writes executable Python tools to memory/skills/ |
| 7 Built-in Tools | shell, read/write files, python_exec, list_files, remember, retrieve |
| Daemon Mode | JSON-RPC over stdin/stdout for low-latency reuse |
| CLI + Config | Full argparse interface, YAML/env config, health checks |
Zero cloud calls after initial model pull. Your data never leaves your machine.
🚀 Quick Start
Prerequisites
- Python 3.10+
- Ollama installed and running
- Pull a model:
ollama pull qwen2.5:7b
Install
pip install -e .
# or from PyPI (when published)
pip install fcht-agent
Verify Installation
fcht-agent doctor
# ✓ Ollama: http://localhost:11434
# ✓ Target model 'qwen2.5:7b' available
# ✓ All memory dirs exist
# All checks passed ✓
Run a Task
# One-shot
fcht-agent run "What is the project name? Use retrieve."
# JSON output for scripting
fcht-agent --json run "List skills in memory/skills"
# {"result": "...", "episodes_added": 1, "steps_taken": 2, "success": true}
Daemon Mode (Fast, Model Stays Loaded)
# Terminal 1: start daemon
fcht-agent-daemon
# {"jsonrpc": "2.0", "method": "ready", "params": {"model": "qwen2.5:7b"}}
# Terminal 2: send requests
echo '{"task": "What is the project name?", "id": "req-1"}' | fcht-agent-daemon
# {"id": "req-1", "result": {"output": "...", "episodes_added": 1, "steps_taken": 2, "success": true}}
🧠 Memory Architecture
memory/
├── episodes.jsonl # Episodic: few-shot conversation history
├── chroma/ # Semantic: ChromaDB vector store
│ ├── chroma.sqlite3
│ └── ...
└── skills/ # Procedural: learned Python tools
├── hello.py
├── greeting.py
└── fibonacci.py
| Memory Type | Storage | Use Case |
|---|---|---|
| Episodic | JSONL (append-only) | Few-shot prompting, conversation continuity |
| Semantic | ChromaDB + embeddings | Fact retrieval, RAG, similarity search |
| Procedural | Python files in skills/ |
Learned procedures, reusable tools |
🛠 Built-in Tools
| Tool | Description | Example |
|---|---|---|
shell |
Run shell commands | {"tool": "shell", "args": {"cmd": "ls -la"}} |
read_file |
Read file contents | {"tool": "read_file", "args": {"path": "config.yaml"}} |
write_file |
Write file contents | {"tool": "write_file", "args": {"path": "out.py", "content": "print(1)"}} |
python_exec |
Execute Python code | {"tool": "python_exec", "args": {"code": "print(2+2)"}} |
list_files |
List directory | {"tool": "list_files", "args": {"path": "memory/skills"}} |
remember |
Store in semantic memory | {"tool": "remember", "args": {"text": "API key is xyz", "metadata": {"type": "secret"}}} |
retrieve |
Search semantic memory | {"tool": "retrieve", "args": {"query": "API key", "n_results": 3}} |
⚙️ Configuration
YAML Config (config.yaml)
ollama:
host: "http://localhost:11434"
model: "qwen2.5:7b"
temperature: 0.1
timeout: 120
memory:
episodes_path: "memory/episodes.jsonl"
max_few_shot: 3
chroma_path: "memory/chroma"
embed_model: "all-MiniLM-L6-v2"
embed_cache_dir: "~/.cache/fcht-agent/embeddings"
agent:
max_steps: 10
system_prompt: |
You are a precise, helpful assistant. Use tools to accomplish tasks.
Output ONLY JSON tool calls. When done, respond with 'DONE: <result>'.
daemon:
enabled: true
host: "127.0.0.1"
port: 8765
Environment Variables (override any setting)
FCHT_OLLAMA__MODEL=llama3.1
FCHT_MEMORY__MAX_FEW_SHOT=5
FCHT_AGENT__MAX_STEPS=15
🧪 Testing
# Run all tests
pytest tests/ -v
# Memory tests
pytest tests/test_memory.py -v
# Agent tests
pytest tests/test_agent.py -v
📦 Project Structure
fcht_agent/
├── __init__.py # Exports: FCHTAgent, AgentConfig, __version__
├── config/schema.py # Pydantic settings (YAML/env/file)
├── core/agent.py # ReAct loop + Ollama client + tools
├── memory/
│ ├── episodic.py # JSONL few-shot memory
│ ├── semantic.py # ChromaDB + cached embeddings
│ └── embeddings.py # Singleton embedding model
├── tools/registry.py # 7 built-in tools
├── cli/main.py # argparse CLI: run, config, doctor, version
├── daemon/server.py # JSON-RPC stdin/stdout daemon
tests/
├── test_memory.py # Memory module tests
├── test_agent.py # Agent integration tests
setup.py # Setuptools config
📄 License
MIT License — see LICENSE for details.
🤝 Contributing
- Fork the repo
- Create a feature branch
- Add tests for new functionality
- Ensure
pytest tests/passes - Submit PR
🙋 Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Security: security@example.com (PGP key available)
Built with ❤️ for local-first AI. Runs on a GTX 1080 Ti (11GB) with qwen2.5:7b.
Metadata
Release files for fcht-agent 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fcht_agent-0.1.0.tar.gz | 29.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fcht_agent-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 58.4 kB
Release files / fcht_agent-0.1.0.tar.gz
| Download URL | fcht_agent-0.1.0.tar.gz |
|---|---|
| Size | 29.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
782e5fa1dead1f96be032fb170d1db58bd534f82c609a693dff53763c9c1a648
|
|
BLAKE2b-256 checksum How to use checksums |
531e8cc1fed59c78cfb251deb12bed43ec24355b156a2f1cb2441ddb7ec39287
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|
Release files / fcht_agent-0.1.0-py3-none-any.whl
| Download URL | fcht_agent-0.1.0-py3-none-any.whl |
|---|---|
| Size | 28.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
3587419f5b238aa5abf158443c534059960a4e6d91283e863b24d2b5f61211ca
|
|
BLAKE2b-256 checksum How to use checksums |
0d3abf4602c7ef3a9a3c3afb32c0e0334a53ec32588808bd9bc95dd2975e6ecf
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.15
|