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:

  1. Calls setup_logging → effgen/utils/logging.py.
  2. Loads configuration via effgen/config/loader.py (27 functions, 3 classes, 41 callers).
  3. Instantiates Agent (effgen/core/agent.py) – the hub module (43 inbound imports). Agent.__init__ builds a AgentConfig, registers tools (effgen/tools/base_tool.py), and creates a MessageBus.

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 its run method (e.g., effgen/tools/builtin/calculator.py).

The most‑connected modules are:

ModuleCa (importers)Ce (imports)Instability
effgen/__init__43190.31 (in cycle)
effgen/core/agent33220.40 (in cycle)
effgen/tools/builtin/__init__25140.36 (in cycle)
scripts/verify0301.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 permissions for GITHUB_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: false on checkout steps (.github/workflows/ci.yml).
  • MEDIUM – Add a non‑root USER to the image (Dockerfile).
  • MEDIUM – Pin dependency resolution to avoid known CVEs (e.g., torch@2.0.0, transformers@4.35.0).
  • LOW – Add timeout-minutes to 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.