Skip to main content

TeiForge

PyPI CI Python License: MIT

A small, readable Python toolkit for building AI agents that can safely work with your files.

Give a language model a few tools (read a file, write a file, search the web, or any Python function you write) and TeiForge runs the loop: the model picks a tool, TeiForge runs it inside a sandbox, the model reads the result and answers.

  • Runs free and private on your machine with Ollama, or with OpenAI and Anthropic.
  • Safe by default: file tools cannot leave the folder you choose and never overwrite files unless asked.
  • Small enough to read: about 2,000 lines of typed, documented Python and one required dependency (requests).
  • Works without a model too: a keyword router handles simple tasks offline.

"Tei" comes from Teichi, the author's nickname (Hồ Du Tuấn Đạt). TeiForge is not related to Hugging Face Text Embeddings Inference (TEI).

Status: alpha (0.3). The API may still change. See Known limitations.

What can you build with it?

Ask questions about your own documents, without the model being able to touch anything else:

from teiforge import Agent, AgentConfig

agent = Agent(config=AgentConfig(name="reader", tools=["file_reader"], workspace="notes", temperature=0))
print(agent.run("Read meeting.txt and list the action items with their owners."))

Give the model your own functions. Type hints and the docstring become the tool description:

import datetime

from teiforge import Agent, AgentConfig, ToolError, tool


@tool
def days_until(date: str) -> str:
    """Count the days from today until a date.

    Args:
        date: The target date in YYYY-MM-DD format.
    """
    try:
        target = datetime.date.fromisoformat(date)
    except ValueError:
        raise ToolError(f"'{date}' is not a YYYY-MM-DD date.") from None
    return f"{(target - datetime.date.today()).days} days"


agent = Agent(config=AgentConfig(name="planner", temperature=0), tools=[days_until])
print(agent.run("How many days are left until 2027-01-01?"))

Chat with an assistant that remembers the conversation, from the terminal:

teiforge chat --agent files --workspace notes --memory chat.json

Type /help inside the chat for commands. The conversation is saved to chat.json and picked up again next time.

Quickstart: free, on your own machine (5 minutes)

1. Install TeiForge and a local model

Install Ollama, then:

python -m pip install "teiforge[openai]"
ollama pull llama3.1

teiforge[openai] installs the OpenAI client, which TeiForge also uses to talk to Ollama. No API key or payment is needed.

2. Point TeiForge at Ollama

PowerShell (Windows):

$env:TEIFORGE_PROVIDER = "openai"
$env:TEIFORGE_BASE_URL = "http://127.0.0.1:11434/v1"
$env:TEIFORGE_MODEL = "llama3.1"

macOS / Linux:

export TEIFORGE_PROVIDER=openai
export TEIFORGE_BASE_URL=http://127.0.0.1:11434/v1
export TEIFORGE_MODEL=llama3.1

These variables only last for the current terminal window. Run every command below in that same window, or set them permanently (PowerShell: setx TEIFORGE_PROVIDER openai, and likewise for the other two, then open a new window; macOS / Linux: add the export lines to ~/.bashrc or ~/.zshrc).

Check that TeiForge sees the model. This should print OpenAIProvider llama3.1:

python -c "from teiforge import Agent, AgentConfig; p = Agent(config=AgentConfig(name='check')).provider; print(type(p).__name__, getattr(p, 'model', None))"

If it prints NoneType None, the variables are not set in this window. Without a model, TeiForge falls back to its keyword router and warns No LLM provider is configured.

3. Try it

Create a folder notes with a text file meeting.txt in it, then:

teiforge run "Read meeting.txt and summarise it in three bullet points." --agent files --workspace notes --verbose

--verbose shows each step: the tool the model called, whether it worked, and the final answer. To see the sandbox at work, ask for a file outside notes; it is refused before anything is read:

teiforge run "Read ../secret.txt" --agent files --workspace notes --no-llm

Tip for local models: small models (around 8B parameters) are not always reliable: they may misread a tool result or write a tool call as plain text instead of calling the tool. A temperature of 0 makes them more consistent; if an answer looks wrong, run it again or try a larger model. In Python, pass AgentConfig(..., temperature=0); for the CLI, put it in a config file (see CLI).

No model at all?

Without any provider configured, TeiForge falls back to a keyword router, which is handy for scripts and tests:

teiforge run "read:meeting.txt" --agent files --workspace notes --no-llm

Using OpenAI or Anthropic instead

python -m pip install "teiforge[openai]"       # or "teiforge[anthropic]"

Then set OPENAI_API_KEY (or ANTHROPIC_API_KEY) in your environment instead of the Ollama variables above. These services bill your own API key; see Cost.

Why TeiForge?

If you want... TeiForge
To understand how an agent loop works by reading the code Yes: the LLM loop is one function of about 50 lines (Agent._run_llm in teiforge/agent.py)
An assistant that works on your files without risking the rest of your disk Yes: every file path is checked against the workspace
To run on a laptop with a local model Yes: Ollama and other OpenAI-compatible servers work out of the box
Hundreds of integrations, vector stores, multi-agent orchestration No. Larger frameworks such as LangChain, LlamaIndex or smolagents cover that

Guide

Your own tools

Any typed function becomes a tool with @tool. Supported parameter types are str, int, float, bool, list[...], dict, Optional[...] and Literal[...]. Report a problem by raising teiforge.ToolError; the model receives the message and can react to it instead of the agent crashing. You can pass functions directly with Agent(..., tools=[my_function]) or agent.add_tool(my_function).

Seeing what the agent does

result = agent.run_detailed("Read notes.txt and summarize it", on_event=print)
result.ok           # True / False
result.mode         # "llm" or "router"
result.tool_calls() # the tool_call events
result.to_dict()    # JSON-serialisable record of the whole run

Event types: task_start, llm_response, tool_call, tool_result, final, error.

LLM providers

Provider How to enable
Ollama, LM Studio, vLLM, OpenRouter teiforge[openai], TEIFORGE_PROVIDER=openai, TEIFORGE_BASE_URL and TEIFORGE_MODEL
OpenAI teiforge[openai] and OPENAI_API_KEY
Anthropic teiforge[anthropic] and ANTHROPIC_API_KEY

You can also pass a provider object directly:

from teiforge import Agent, AgentConfig, OpenAIProvider

local = OpenAIProvider("llama3.1", base_url="http://127.0.0.1:11434/v1", temperature=0)
agent = Agent(config=AgentConfig(name="local", tools=["file_reader"]), provider=local)

For tests, teiforge.testing.ScriptedProvider replays a fixed list of responses without any network.

CLI

teiforge run "Read README.md and list the features" --agent files --workspace .
teiforge run "search: python 3.13 release" --json          # full result with events
teiforge search "AI agent libraries" --out results.txt --no-llm
teiforge chat --agent all --memory chat.json             # interactive; type /help
teiforge tools                                           # list tools and parameters

Common options: --agent research|files|all, --tools web_search,file_reader, --config agent.toml, --workspace DIR, --provider, --model, --base-url, --max-steps, --no-llm, --verbose. python -m teiforge works too.

A configuration file (TOML or JSON) sets everything at once, including temperature:

[agent]
name = "notes-assistant"
tools = ["file_reader", "file_writer"]
provider = "openai"
base_url = "http://127.0.0.1:11434/v1"
model = "llama3.1"
temperature = 0
max_steps = 6
workspace = "notes"
system_prompt = "You are a careful assistant that answers from the user's notes."
teiforge chat --config agent.toml --memory chat.json

Built-in tools

Tool Parameters Notes
file_reader path UTF-8 text files inside the workspace.
file_writer path, content, overwrite Refuses to replace a file unless overwrite is true.
web_search query, max_results DuckDuckGo, no API key. Results come from DuckDuckGo's public pages and may be rate-limited.
command_runner command Off unless TEIFORGE_ENABLE_COMMANDS=1; only echo, pwd, ls [path], python --version; no shell.

In router mode you can address tools explicitly: search: <query>, read:<path>, write:<path>:<content> (Windows paths such as C:\notes\a.txt work).

Configuration

Variable Purpose Default
TEIFORGE_PROVIDER openai, anthropic or none Auto-detect from API keys
OPENAI_API_KEY / ANTHROPIC_API_KEY Provider credentials Unset
TEIFORGE_MODEL Model name override gpt-4o-mini (OpenAI), claude-sonnet-5-5 (Anthropic)
TEIFORGE_BASE_URL OpenAI-compatible endpoint, e.g. Ollama Unset
TEIFORGE_WORKSPACE Directory file tools are confined to Current directory
TEIFORGE_ENABLE_COMMANDS Enable the restricted command runner 0

See .env.example. TeiForge does not load .env files itself.

Cost

TeiForge is free. Local models through Ollama cost nothing beyond your own hardware. With OpenAI or Anthropic, every step of the agent loop is one API call billed to your key, and each call resends the conversation, tool descriptions and tool results, so long files and long chats cost more. Keep max_steps low, use a narrow workspace, and set a spending limit in your provider's console. TeiForge does not yet report token usage.

Security

Agents act on model output, and web pages or files can contain prompt injections. Keep the workspace narrow, enable only the tools a task needs, and read SECURITY.md.

Upgrading from AgentForge 0.2

  • Install teiforge and change imports from agentforge to teiforge.
  • Tool.run() now returns a ToolResult (ok, output, error) instead of a string; str(result) gives the old text. Agent.run() still returns a string.
  • The CLI uses subcommands: teiforge run "task" replaces --agent research --task "task" (the old flags still work but print a deprecation note).
  • Environment variables were renamed: AGENTFORGE_MODEL -> TEIFORGE_MODEL, AGENTFORGE_ENABLE_COMMANDS -> TEIFORGE_ENABLE_COMMANDS.
  • File tools are now confined to the workspace, and file_writer no longer overwrites by default.
  • Python 3.10 or newer is required.

Contributing

Bug reports, questions and pull requests are welcome. Start with CONTRIBUTING.md; the changelog lists what changed in each release. For development:

git clone https://github.com/Tdat10052499/teiforge.git
cd teiforge
python -m pip install -e ".[dev]"
python -m pytest

License

TeiForge is distributed under the MIT License. See LICENSE.

Metadata

Release files for teiforge 0.3.1

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

Source distribution (sdist)

Source distribution for teiforge 0.3.1
File Size Uploaded
teiforge-0.3.1.tar.gz 52.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for teiforge 0.3.1
File Interpreter ABI Platform
teiforge-0.3.1-py3-none-any.whl Python 3 none any Details

Total release size: 88.2 kB

Release files / teiforge-0.3.1.tar.gz

Download URL teiforge-0.3.1.tar.gz
Size 52.0 kB
Tags Source
SHA-256 checksum
How to use checksums
283e7dcd82da274cdeb9422170d362ace089f5d181364a104c413172ac1fef55
BLAKE2b-256 checksum
How to use checksums
1587bfbbf9c8f0181ab20b9a3e52d14d45f3e92c328b5c0d886a26902c982c15
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release files / teiforge-0.3.1-py3-none-any.whl

Download URL teiforge-0.3.1-py3-none-any.whl
Size 36.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
73e7ac0a3b3af1bcc4a3f1ddcc34559cbc3ae2a2d0130cfa49d04ae9657c0fa7
BLAKE2b-256 checksum
How to use checksums
a84a719ea25b76d2bd4bb1f821d0088f72fe0ee428b7bc1f3ca5636fd75b4660
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 14, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.1 This release

2 release files

0.3.0

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