EJAgent Core
Hatch an agent of your own — a highly customizable Python runtime for reliable AI agents.
English · 简体中文
EJAgent Core is a lightweight Python runtime for creating agents that can use tools, retain conversation state, recover after restarts, and accept live control. Its model, tools, context strategy, storage, and observability are all replaceable, so you can adapt the runtime to your application instead of adapting your application to a framework.
Use it as the foundation for assistants, workflow agents, coding tools, research agents, or any application that needs a reliable model–tool loop.
What You Can Build
- Highly customized agents — replace the model provider, tool backend, context strategy, storage layer, and observers independently.
- Stateful assistants — keep typed conversation history across multiple tasks and continue from the latest committed state.
- Durable agents — persist sessions to an append-only journal and recover them after a process restart.
- Tool-using agents — expose Python functions, compose multiple tool executors, or connect MCP services through one consistent interface.
- Controllable runtimes — cancel active work, steer the next model step, queue follow-up tasks, and enforce turn or token limits.
- Context-aware agents — inject local Skills, derive summaries for long conversations, or implement your own context policy.
- Observable systems — capture structured results, failures, token usage, model events, and tool activity without coupling observers to execution.
- Provider-flexible applications — use OpenAI-compatible endpoints, Anthropic, or implement a provider adapter for another model API.
Why EJAgent Core
Agent demos are easy; agents that remain predictable as an application grows are harder. EJAgent Core provides explicit boundaries for execution, state, tools, and side effects while staying small enough to embed in an existing service, CLI, worker, or desktop application.
At its center are two focused components: RuntimeKernel executes one
model–tool Run, while AgentHarness adds durable state, resource lifecycle,
runtime control, and atomic commits across Runs. The detailed design stays out
of your application code, but every integration boundary remains replaceable.
Install
EJAgent Core requires Python 3.12 or newer.
uv add ejagent-core
Add an optional integration when needed:
uv add 'ejagent-core[anthropic]' # Anthropic
uv add 'ejagent-core[mcp]' # MCP
Quick Start
Configure an OpenAI-compatible endpoint:
MODEL_API_KEY=sk-xxxxxxxx
MODEL_URL=https://api.example.com/v1
CHAT_MODEL=your-model
Create a stateful agent:
from ejagent.contracts import SystemMessage
from ejagent.harness import AgentHarness
from ejagent.providers import ModelConfig, OpenAIModelPort
from ejagent.tools import FunctionToolExecutor
model = OpenAIModelPort(ModelConfig.from_env())
harness = AgentHarness(
agent_id="assistant",
model=model,
tools=FunctionToolExecutor(),
initial_messages=(SystemMessage("Answer precisely."),),
)
async with harness:
await harness.run("Remember that my project is EJAgent.")
answer = await harness.run("What is my project?")
print(answer.result.output)
The same agent can be upgraded without changing its calling style:
from ejagent.context import SkillsContextPipeline
from ejagent.storage import JsonlSessionStore
from ejagent.tools import McpToolExecutor
harness = AgentHarness(
agent_id="assistant",
model=model,
tools=McpToolExecutor("mcp_config.json"),
context=SkillsContextPipeline("skills"),
store=JsonlSessionStore(".ejagent-sessions"),
)
Customize Every Boundary
| You want to change | Extension point |
|---|---|
| Model provider or protocol | ModelPort |
| Local or remote tool backend | ToolExecutor |
| Context selection and projection | ContextPipeline |
| Long-history summarization | ContextCompactor |
| Session persistence | SessionStore |
| Logging, tracing, or metrics | RunObserver |
These are narrow, provider-neutral contracts. Implement only the part your application needs, then compose it with the built-in runtime.
Built-in Capabilities
- OpenAI-compatible and Anthropic streaming model adapters
- Python function tools, composite tool executors, and MCP tools
- Local Skill discovery and explicit Skill activation
- Derived context compaction without rewriting conversation history
- In-memory sessions and durable JSONL sessions
- Cooperative cancellation, live steering, and FIFO follow-ups
- Structured audit records and normalized usage accounting
- Revision-based, idempotent session commits with cross-process file locking
EJAgent Core intentionally focuses on one logical agent. Multi-agent orchestration and arbitrary mid-Run pause/resume can be built around it when an application needs them.
Documentation
- Full Usage Guide — installation, configuration, and recipes for every built-in capability.
- Core Classes and Runtime Flow — the internal model and complete Run lifecycle.
- Kernel–Harness Design — normative architectural boundaries and invariants.
- Runnable Examples — focused examples for chat, tools, MCP, Skills, recovery, and durable sessions.
Development
uv sync --locked --all-extras --group dev
uv run ruff check src tests examples benchmarks
uv run ruff format --check src tests examples benchmarks
uv run mypy
uv run python -m unittest discover -s tests -p 'test*.py' -q
uv build
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file ejagent_core-0.6.1.tar.gz.
File metadata
- Download URL: ejagent_core-0.6.1.tar.gz
- Upload date:
- Size: 193.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2f25b7caf8d80ef022816ea522001ac6f527f39b9e0110912c4fa88b5be17049
|
|
| MD5 |
0b57c987fa004c8a430e50df9ace157b
|
|
| BLAKE2b-256 |
4f91870766a812b832ed4e66cdc4cee1bcd2cb2358172d3bf76e0655197447d2
|
Provenance
The following attestation bundles were made for ejagent_core-0.6.1.tar.gz:
Publisher:
release.yml on jyh20030112/EJAgent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ejagent_core-0.6.1.tar.gz -
Subject digest:
2f25b7caf8d80ef022816ea522001ac6f527f39b9e0110912c4fa88b5be17049 - Sigstore transparency entry: 2431275395
- Sigstore integration time:
-
Permalink:
jyh20030112/EJAgent@64ab40f89cd759c413e587eddb9d029b7a1be9eb -
Branch / Tag:
refs/tags/v0.6.1 - Owner: https://github.com/jyh20030112
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@64ab40f89cd759c413e587eddb9d029b7a1be9eb -
Trigger Event:
push
-
Statement type:
File details
Details for the file ejagent_core-0.6.1-py3-none-any.whl.
File metadata
- Download URL: ejagent_core-0.6.1-py3-none-any.whl
- Upload date:
- Size: 74.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ed53198ec588b95318bfcc51b6acf87c9069273145955855518c54642357987d
|
|
| MD5 |
e11ae1da804a97d33d3558b79c778bb8
|
|
| BLAKE2b-256 |
24c0ee517c16bfe5fc2e218b8eb487167bccb3cfab4079eacca40d2064b98118
|
Provenance
The following attestation bundles were made for ejagent_core-0.6.1-py3-none-any.whl:
Publisher:
release.yml on jyh20030112/EJAgent
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
ejagent_core-0.6.1-py3-none-any.whl -
Subject digest:
ed53198ec588b95318bfcc51b6acf87c9069273145955855518c54642357987d - Sigstore transparency entry: 2431275435
- Sigstore integration time:
-
Permalink:
jyh20030112/EJAgent@64ab40f89cd759c413e587eddb9d029b7a1be9eb -
Branch / Tag:
refs/tags/v0.6.1 - Owner: https://github.com/jyh20030112
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@64ab40f89cd759c413e587eddb9d029b7a1be9eb -
Trigger Event:
push
-
Statement type: