The Problem
Small‑language‑model (SLM) agents lack a production‑ready runtime: they need consistent prompting, tool orchestration, memory handling, and a way to expose protocols without writing boilerplate. Teams building autonomous agents spend most of their effort on glue code rather than on the model logic itself.
What This Does
effGen supplies a full‑stack framework that turns an SLM into a multi‑tool agent. Core orchestration lives in effgen/core/agent.py, which builds system prompts, resolves guardrails and drives the model’s generate calls (effgen/models/*_adapter.py). Built‑in tools such as the Python REPL, calculator and web search are under effgen/tools/builtin/.
Configuration is declarative: configs/config.yaml, configs/models.yaml and configs/tools.yaml describe agents, model endpoints and tool bindings. The CLI (effgen/cli.py) parses these files, sets up logging (effgen/utils/logging.py), and launches either a local run (agent_main) or a protocol server (effgen/tools/protocols/acp/server.py, .../mcp/server.py).
The repository also ships example agents (examples/basic/, examples/advanced/) that demonstrate single‑agent, multi‑agent and streaming use‑cases, plus a Docker deployment (Dockerfile, examples/deployment/docker-compose.yml).
How It Is Wired
Execution starts at effgen/cli.py – the main function (line 1959) is the top‑level entry point used by the effgen console script. main:
- Calls
setup_logging→effgen/utils/logging.py. - Loads configuration via
effgen/config/loader.py(27 functions, 3 classes, 41 callers). - Instantiates
Agent(effgen/core/agent.py) – the hub module (43 inbound imports).Agent.__init__builds aAgentConfig, registers tools (effgen/tools/base_tool.py), and creates aMessageBus.
From there run_all_tests (used by CI) and run_agent drive the core loop:
Agent._generate→ model adapters (effgen/models/anthropic_adapter.py,.../openai_adapter.py, etc.) perform the outbound inference call (10 functions call a model).- Tool calls are dispatched via
effgen/core/tool_calling.py, which looks up the tool class in the registry (effgen/tools/registry.py) and executes itsrunmethod (e.g.,effgen/tools/builtin/calculator.py).
The most‑connected modules are:
| Module | Ca (importers) | Ce (imports) | Instability |
|---|---|---|---|
effgen/__init__ | 43 | 19 | 0.31 (in cycle) |
effgen/core/agent | 33 | 22 | 0.40 (in cycle) |
effgen/tools/builtin/__init__ | 25 | 14 | 0.36 (in cycle) |
scripts/verify | 0 | 30 | 1.00 |
Circular imports involve effgen/__init__.py, effgen/core/agent.py and effgen/tools/builtin/__init__.py, raising the risk of import‑time side effects.
External effects are limited to:
- File I/O (28 functions) – e.g., model checkpoint loading, logging, and
scripts/verify.py. - Network calls (22 functions) – model APIs, protocol servers, and optional Grafana dashboards.
- Database access (11 functions) – long‑term memory uses SQLite (
effgen/memory/long_term.py).
The call graph shows print used in 82 places and Agent in 69, indicating heavy reliance on console output for debugging rather than structured logs.
How To Use It
# Clone and install
git clone https://github.com/moses-y/effGen
cd effGen
python -m pip install -e . # installs from pyproject.toml
Configuration – edit configs/config.yaml (agent defaults), configs/models.yaml (API keys, model identifiers) and configs/tools.yaml (enable/disable built‑ins). Example keys are referenced in configs/api_keys.yaml (not committed).
Run a basic agent
python -m effgen.cli --config configs/config.yaml --agent basic_agent
Start the ACP protocol server
python -m effgen.tools.protocols.acp.server --host 0.0.0.0 --port 8000
Docker
docker build -t effgen:latest .
docker run --rm -p 8000:8000 effgen:latest
The repository’s examples/ directory contains ready‑to‑run scripts (basic_agent.py, advanced_multi_tool_agent.py) that can be invoked with the same CLI flags.
Real‑World Use
A SaaS platform that offers “AI‑assisted research” can embed effGen as a microservice. The platform supplies an OpenAI key in configs/api_keys.yaml, selects the research_agent preset, and runs the ACP server behind an API gateway. Incoming requests are forwarded to the server, which spawns an Agent instance, calls the model for reasoning, and uses the built‑in retrieval tool to fetch indexed documents from the vector store (effgen/memory/vector_store.py). The whole flow touches the model (network), the SQLite memory DB (disk), and logs to stdout via the structured logger.
Code Health & Issues
Measured findings (static analysis)
- HIGH – Pin GitHub Actions to commit SHA (
.github/workflows/*.yml). - HIGH – Add a lockfile beside
pyproject.toml. - MEDIUM – Declare least‑privilege
permissionsforGITHUB_TOKEN(.github/workflows/ci.yml). - MEDIUM – Enable Dependabot or Renovate (
.github/dependabot.yml). - MEDIUM – Pin Docker base image by digest (
Dockerfile). - MEDIUM – Set
persist-credentials: falseon checkout steps (.github/workflows/ci.yml). - MEDIUM – Add a non‑root
USERto the image (Dockerfile). - MEDIUM – Pin dependency resolution to avoid known CVEs (e.g.,
torch@2.0.0,transformers@4.35.0). - LOW – Add
timeout-minutesto workflow jobs (.github/workflows/ci.yml).
Additional observations: no lockfile, circular imports, deep nesting (max indentation depth 9) and oversized modules (effgen/core/agent.py ≈ 1850 LOC) increase maintenance cost. Broad except Exception clauses appear in several core files, reducing error visibility.
The Bottom Line
effGen delivers a usable, Docker‑compatible stack for turning SLMs into autonomous agents, with a clear separation of configuration, model adapters, and built‑in tools. The codebase is functional but suffers from high cognitive load (large hub modules, import cycles) and lacks reproducible builds (no lockfile, unpinned dependencies). It is suitable for teams ready to invest in refactoring the core modules and tightening the CI/CD pipeline before production deployment.