Unified Agent Interface (UAI)
UAI is a FastAPI service and CLI that exposes a simple, unified API to run different agent frameworks behind a consistent interface. It loads your agent from a kosmos.toml file and executes it either inline (for dev/tests) or via a Procrastinate worker.
Quickstart
- Install:
pip install -e . - Run API:
uai serve --host 0.0.0.0 --port 8000 - Open docs: visit
http://localhost:8000/docs
CLI Overview
uai serve: starts the FastAPI server.uai run create --input '<json or string>': creates a run for the configured agent.uai run status <task_id>: fetches current run status.uai run input <task_id> --text '<reply>': provides human input to a waiting run.uai run logs <task_id> --message '<msg>' [--level INFO]: appends a log entry.uai run cancel <task_id>/uai run stop <task_id>: cancels/stops a run (deletes it from in-memory storage).uai worker install|check|start: installs schema, checks DB, and starts the worker.uai run watch <task_id>: watches status; whenwaiting_input, prompts for input and resumes automatically.
Project Structure
src/unified_agent_interface/app.py: FastAPI app factory.src/unified_agent_interface/api/: Routers for/runand/chat.src/unified_agent_interface/models/: Pydantic models and schemas.src/unified_agent_interface/components/: In-memory storage and run agent shim.src/unified_agent_interface/frameworks/: Runtime adapters (crewai,langchain,callable).src/unified_agent_interface/queue.py: Procrastinate integration and job dispatch.examples/: Callable sample and CrewAI examples (with and without human input).
Changelog
- See
CHANGELOG.mdfor release notes.
Agent Configuration
-
Location search order:
KOSMOS_TOMLenv var,./kosmos.toml,./examples/kosmos.toml. -
Example config:
[agent] runtime = "callable" # or "crewai", "langchain", or "custom" entrypoint = "examples.simple_entrypoint:run" # Optional: for custom adapters # adapter = "path.to.module:AdapterClassOrInstance"
-
Entrypoint format:
module:attr(e.g.,examples.crewai_user_input.main:crew). UAI resolves imports relative to thekosmos.tomldirectory and also supports package-style modules. -
Custom adapters: set
agent.adapterto amodule:attrthat resolves to either an instance or a zero-arg class. The adapter must explicitly inheritunified_agent_interface.frameworks.base.RuntimeAdapter. Ifruntimeis unknown or set tocustom, UAI will load this adapter. If both a known runtime and an adapter are specified, the adapter takes precedence.
Runtimes (Adapters)
crewai: Imports aCrewand callscrew.kickoff(inputs=...).- Inputs: pass JSON via
--input '{"topic":"..."}'. Dicts are used as-is; string inputs map to{ "input": "..." }. - Human input: When the Crew calls
input(), UAI sets status towaiting_inputand populatesinput_prompt. Provide input withuai run inputand the run resumes.
- Inputs: pass JSON via
langchain: Imports a LangChainRunnable/LLMChainand callsinvoke(inputs)(orrun(...)fallback).- Inputs: dicts are passed as-is. String inputs map to
{ "text": "..." }. - Output: tries
message.content, then common dict keys (text,output_text,output,result), elsestr(result).
- Inputs: dicts are passed as-is. String inputs map to
callable: Imports a Python callable.- If
--inputis a JSON object, UAI triesfn(**obj), falling back tofn(obj); otherwise it callsfn({"input": "...", "params": {}}).
- If
custom: Provideadapter = "module:attr"inkosmos.toml; UAI imports and uses it for both run and chat if implemented.
Examples
- Callable:
examples/simple_entrypoint.pywithexamples/kosmos_callable.toml. - CrewAI (basic):
examples/crewai/main.pywithexamples/crewai/kosmos.toml. - CrewAI (human input):
examples/crewai_user_input/main.pywithexamples/crewai_user_input/kosmos.toml. - LangChain (LLMChain):
examples/langchain/app.pywithexamples/langchain/kosmos.toml. - LangChain with instrumentation (logs around LLM calls): set
KOSMOS_TOML=examples/langchain/kosmos_patched.tomlto useapp:run_patchedwhich patchesLLMChain.invokeandChatOpenAI.invokeviainstrumentation.patch_many. - CrewAI with custom logs/input detection (callbacks):
examples/crewai_custom_log_input_detection/app.pywithexamples/crewai_custom_log_input_detection/kosmos.toml.
Run API
POST /run/(body:{ "input": <any>, "params": <object?> }): creates a run.inputmay be a string or JSON object/array.GET /run/{id}: returns status with fields:status,result_text,logs,artifacts,input_prompt,input_buffer.POST /run/{id}/input(body:{ "input": "..." }): appends toinput_bufferand resumes a waiting run.POST /run/{id}/logs(body:{ level, message }): appends a log.POST /run/{id}/artifacts(body:{ id?, type?, name?, uri?, metadata? }): adds an artifact to the run (server generatesidif missing).POST /run/{id}/complete(internal): worker callback to finalize a run.
Chat API
POST /chat/: creates a chat session and returns{ session_id }.POST /chat/{session_id}: sends a user message; responds after generating the assistant reply with{ state, artifacts, messages }.GET /chat/{session_id}/messages: lists messages in the session.DELETE /chat/{session_id}: deletes the session.POST /chat/{session_id}/artifacts(body:{ id?, type?, name?, uri?, metadata? }): adds an artifact to the session (server generatesidif missing).
Background Jobs (Procrastinate)
- Default local DB: If no
PROCRASTINATE_DSN/DATABASE_URLis set, UAI connects tolocalhost:5432withuser=postgres,password=password,dbname=postgres. - Start a local Postgres (optional):
docker run --name pg-procrastinate --detach --rm -p 5432:5432 -e POSTGRES_PASSWORD=password postgres - Worker commands:
uai worker install: installs Procrastinate schema (idempotent).uai worker check: verifies DB connectivity.uai worker start: auto-installs schema, checks DB, then starts the worker.
- Inline mode (no DB):
UAI_PROCRASTINATE_INLINE=1executes runs in-process (used in tests).
Environment Variables
KOSMOS_TOML: Path tokosmos.tomlto load agent config.UAI_BASE_URL: Base URL for server (used by worker callbacks). Defaults tohttp://localhost:8000.UAI_PROCRASTINATE_INLINE: Set to1to run jobs inline without Postgres.PROCRASTINATE_DSN/DATABASE_URL: Postgres connection for the worker. If unset, UAI uses local defaults.PROCRASTINATE_HOST/PORT/USER/PASSWORD/DB: Overrides for local default connection.
Troubleshooting
- Import errors: Ensure
KOSMOS_TOMLpoints to the right example and that the entrypoint’s dependencies (e.g.,crewai,langchain_community) are installed in both server and worker environments. - PoolTimeout on worker start: Check Docker Postgres is running and accessible; use
uai worker check. Add required SSL options to your DSN if using a cloud provider (e.g.,?sslmode=require). - Human input not progressing: Confirm status shows
waiting_inputwith a non-emptyinput_prompt, then senduai run input <task_id> --text '...'.
Notes
- Storage is in-memory for now; swap with a persistent backend (Postgres/Redis) for multi-process reliability. The worker currently finalizes runs via a callback to
POST /run/{id}/complete. - LangChain chat requires sessions: stateless
POST /chat/nextis not supported and returns 400. UAI maintains a separate chain instance per session to isolate memory.
Developer Utilities
- Helper functions for user adapters/agents in
unified_agent_interface.frameworks.utils:post_wait(task_id, prompt): mark run as waiting for input with a prompt.get_status(task_id): get run status JSON.poll_for_next_input(task_id, baseline_index, timeout_seconds=300): poll until new input arrives; returns(value, new_index).request_human_input(task_id, prompt="...", baseline_index=None): convenience wrapper that posts wait and polls; returns(value, new_index).post_log(task_id, level, message): append a log entry to a run.add_run_artifact(task_id, artifact_dict): add an artifact to a run.add_chat_artifact(session_id, artifact_dict): add an artifact to a chat session.
- Instrumentation utilities in
unified_agent_interface.utils:patch_log(target, label=None, capture_return=False): persistently patch a function or method (callable or"module:attr") to auto-log calls usingpost_log.unpatch_log(target): restore a target patched viapatch_log.
patch_function(target, label=None, capture_return=False): temporary/context-managed patch.patch_many(*targets, label=None, capture_return=False): patch multiple targets within one context.
Runtime Context
- UAI tracks the current run (
task_id) and chat session (session_id) during execution so helpers can be called without IDs:unified_agent_interface.runtime.task_context(task_id)and.session_context(session_id)are used internally; helpers fall back to these whentask_id/session_idis omitted.- E.g.,
post_log(None, "INFO", "message")andrequest_human_input(None, "prompt")will route to the current run.
These utilities let custom adapters define their own session management and input-waiting behavior.
- Example (LangChain):
from langchain_openai import ChatOpenAIfrom unified_agent_interface.utils import patch_logpatch_log(ChatOpenAI.invoke, capture_return=True)- Calls to
ChatOpenAI.invokewill now be logged to the current run.
Artifacts Tracking
- Auto-collect file artifacts created during a run or chat turn.
- Enable via config or env:
- kosmos.toml:
[agent.artifacts] tracking = "auto"(optional:base_dir = "...") - env:
UAI_ARTIFACTS=auto(overrides config) - filters:
UAI_ARTIFACTS_INCLUDE="**/*.md,**/*.png",UAI_ARTIFACTS_EXCLUDE="**/.git/**",UAI_ARTIFACTS_BASEDIR=/path/to/repo
- kosmos.toml:
- How it works:
- UAI registers a Python audit hook and uses contextvars to attribute file creations to the current run/session.
- When enabled, opening files with create/append modes (e.g.,
w,x,a) oros.O_CREATis recorded as artifacts. - Artifacts are posted immediately to
/run/{id}/artifactsor/chat/{session}/artifactsand deduplicated per context.
- Notes:
- Off by default; opt-in via config/env.
- You can still add artifacts explicitly with
add_run_artifact/add_chat_artifact. - For best results, write outputs inside a known base directory and use include/exclude globs.
Metadata
Release files for unified-agent-interface 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| unified_agent_interface-0.1.1.tar.gz | 76.1 kB | With provenance | Details for unified_agent_interface-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| unified_agent_interface-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for unified_agent_interface-0.1.1-py3-none-any.whl |
Total release size: 114.1 kB
Release files / unified_agent_interface-0.1.1.tar.gz
| Download URL | unified_agent_interface-0.1.1.tar.gz |
|---|---|
| Size | 76.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7c551a4fa93c1b48328a5577f76767503a307455f06c5993543973457fcd5d6c
|
|
BLAKE2b-256 checksum How to use checksums |
e7374513f727db38e6974f624c617733ffc04f07b82a37cd54e3d5a6f2fe0943
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
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 Aug 12, 2025.
Transparency logRelease files / unified_agent_interface-0.1.1-py3-none-any.whl
| Download URL | unified_agent_interface-0.1.1-py3-none-any.whl |
|---|---|
| Size | 37.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a82db9f4ee27e608c3883bd2728f9674d87838342aca1d2404307c44e61a4355
|
|
BLAKE2b-256 checksum How to use checksums |
669853d4088aa000c4ed3d35d679fd102339ffc72d0bf1a7df7ead90342966b4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.12.9
|
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 Aug 12, 2025.
Transparency logSecurity for unified-agent-interface 0.1.1
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.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for unified_agent_interface-0.1.1.tar.gz
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 Aug 12, 2025.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.