AIPod
A governed software construction agent and compositional runtime for AI-built Python applications.
AIPod lets AI build ordinary Python applications inside a small, explicit architecture. The model generates one bounded artifact at a time; local code controls ordering, Contracts, validation, freezing, retries, and repair scope.
Model → Provider → Service → Pipeline → Interface
data capability business composition delivery
The result is not an opaque AI session. It is a resumable project with typed boundaries, registered routes, runtime evidence, and generated source code that can be inspected and maintained with normal tools.
AIPod is currently alpha software. Review generated code and platform installers before production use.
Quick start
Python 3.10 or newer is required.
pip install -U AIPodCli
mkdir todo-app
cd todo-app
aipod init
Configure an OpenAI-compatible model endpoint once:
aipod config set OPENAI_API_KEY sk-your-key
aipod config set OPENAI_BASE_URL https://api.openai.com/v1
aipod config set OPENAI_MODEL your-model
Build an application:
aipod pod --yes \
"Create a local todo application with persistent tasks, add/list/complete routes, and a CLI Adapter."
Inspect and test it:
aipod inspect --summary --json
aipod inspect project --json
aipod interface list
aipod interface smoke <interface-name>
Run a generated Interface Adapter with a JSON event:
aipod interface run <interface-name> \
--payload '{"action":"list"}'
Adapters that expose CLI-style arguments can receive raw arguments after --:
aipod interface run <interface-name> -- \
--mode once \
--payload '{"message_id":"m-1","topic":"orders","payload":{}}'
Why AIPod
Large AI-generated applications usually fail at their boundaries:
- one component produces
shipment_countwhile another expectsshipments_count; - a Model is accidentally injected as an infrastructure dependency;
- generated code imports symbols from the wrong package;
- a downstream failure causes an upstream working file to be rewritten;
- a Pipeline exists but no verified user-facing Interface reaches it;
- syntax checks pass while imports or dependency injection fail at runtime.
AIPod addresses these failures with four rules:
- Build in dependency order. Earlier layers are completed before downstream layers.
- Make boundaries machine-readable. IDs, dependencies, Contracts, routes, lifecycle, permissions, and verification commands are stored as project state.
- Freeze accepted upstream work. A downstream failure may retry or repair its own scope, but does not silently reopen stable layers.
- Require evidence before completion. Generated artifacts must pass local structural and disposable runtime checks before a stage can freeze.
The five layers
Model
Models are shared typed data. Runtime value objects and persistent SQLModel entities are both supported.
from ai_pod_cli import Model
class Message(Model):
message_id: str
topic: str
payload: dict
Models are imported as data types. They are never injected.
Provider
Providers expose infrastructure capabilities such as files, databases, HTTP clients, or message transports. They may be injected into Services.
Built-in Providers include:
ConfigStoreModelRepositoryPipelineRunner
Service
Services implement business transformations through execute(ctx).
from ai_pod_cli.context import PipelineContext
class MessageProcessingService:
def execute(self, ctx: PipelineContext) -> dict:
message_id = ctx.get("message_id")
result = {"message_id": message_id, "status": "processed"}
ctx.set("result", result)
return result
Pipeline
Pipelines compose Services in deterministic order and are registered as named routes.
from ai_pod_cli.config import load_beans
from ai_pod_cli.container import Pod, build_container
def run(ctx):
S = Pod(build_container(load_beans()))
(S(ValidateMessage) | S(ProcessMessage)).execute_all(ctx)
return ctx.summary()
Interfaces see route names and descriptions, not Service classes.
The same Pipeline Runtime also supports governed asynchronous, parallel, and streaming
execution. The operators are explicit: | always remains sequential, parallel(...)
uses isolated branch contexts and a declared merge strategy, and stream(...) applies
bounded backpressure. Existing synchronous pipelines remain compatible.
from ai_pod_cli.container import parallel
async def run(ctx):
S = Pod(build_container(load_beans()))
flow = parallel(
S(QueryInventory),
S(QueryPrice),
merge="strict",
failure_policy="collect_all",
concurrency=2,
) | S(BuildResponse)
await flow.execute_all_async(ctx)
return ctx.summary()
See docs/execution.md for async routes, deterministic branch merging, stream processing, failure policies, and Contract behavior.
Interface
An Interface is a delivery bundle around one AI-generated project Adapter. It can bridge any external event source to frozen Pipeline routes:
CLI arguments \
HTTP request \
queue message ─→ InterfaceAdapter ─→ context.run_route() ─→ Pipeline
desktop UI event /
file/timer event /
AIPod provides the stable SDK:
from ai_pod_cli.interface import InterfaceAdapter, InterfaceContext
AI generates project-specific glue:
class GeneratedInterfaceAdapter(InterfaceAdapter):
def required_routes(self):
return ["process_message"]
def start(self, context: InterfaceContext, payload=None):
message = receive_external_message(payload)
return context.run_route("process_message", message)
The Adapter cannot import Models, Providers, Services, the DI container, or
PipelineRunner. Its only business capability is InterfaceContext.run_route().
Multi-file Interface Adapters
Complex adapters are split into focused files and generated one file per model call:
interfaces/order-monitor/
├── adapter.py Adapter entry class
├── queue_consumer.py message transport
├── window.py desktop UI
├── event_bridge.py thread/UI bridge
├── install.ps1 platform lifecycle
└── interface.json canonical manifest
The manifest identifies the entry source and class:
{
"name": "order-monitor",
"kind": "windows_desktop_queue",
"platform": "windows",
"adapter": {
"entry_path": "interfaces/order-monitor/adapter.py",
"class_name": "GeneratedInterfaceAdapter"
},
"artifacts": [
{"path": "interfaces/order-monitor/adapter.py", "role": "adapter_entry"},
{"path": "interfaces/order-monitor/queue_consumer.py", "role": "adapter_module"},
{"path": "interfaces/order-monitor/window.py", "role": "adapter_module"}
],
"lifecycle": {
"run": ["{python}", "-m", "ai_pod_cli", "interface", "run", "order-monitor"]
},
"permissions": ["message_queue_connect", "desktop_notification"],
"verify": [
{
"name": "adapter_smoke",
"kind": "runtime",
"required": true,
"command": ["{python}", "-m", "ai_pod_cli", "interface", "smoke", "order-monitor"],
"timeout": 30
}
]
}
All Adapter source files are staged together, loaded as a private Python package so relative imports work, and smoked in a disposable project. The complete Interface bundle is committed atomically only after every required check passes.
The Adapter is generated during construction. Running the finished application does not call AI.
Pod Agent
aipod pod is a resumable local state machine over governed build tools:
Observe → Policy Select → Execute → Validate → Freeze → Observe
The stage order is deterministic:
generate_models
generate_providers
generate_services
compose_pipelines
generate_interfaces
verify_application
repair_current_artifact # only after real failure evidence
The model does not choose this order. It decides the contents of the current bounded artifact.
Modifying an existing Pod
Studio and --stage auto use one focused AI call to classify the earliest layer affected
by a requested change. The local scheduler then freezes upstream and rebuilds that layer
plus downstream:
aipod pod --stage auto --yes \
"Add task priority and display it in the desktop window."
An explicit stage remains available as a manual override:
aipod pod --stage interfaces --yes \
"Replace the CLI Adapter with a desktop and message-queue Adapter."
Progressive verification
Validation happens before freezing, not only at the end:
| Layer | Required evidence |
|---|---|
| Model | isolated import and class construction |
| Provider | isolated import, DI construction, declared-method smoke |
| Service | DI construction and execute(ctx) with Contract-derived input |
| Pipeline | isolated Pipeline execution before route registration |
| Interface | every Artifact validated, Adapter package imported, smoke executed |
After all layers complete, every required Interface verification command runs again. Optional installation checks remain visible but do not fail runtime proof.
Run structure-only inspection:
aipod verify --json
A structure-only result is unverified, not passed.
Run a real command:
aipod verify --json -- python -m unittest
Verification records the command, exit code, bounded stdout/stderr, project-local
traceback locations, repair candidates, and a source fingerprint. A stale pass is reset
to pending when relevant project files change.
Contracts
Components publish machine-readable inputs and outputs. AIPod validates:
- required fields;
- scalar and structured types;
- shared Model paths;
- nested schemas;
- Pipeline data flow;
- runtime values at component boundaries.
Type, Model, missing-field, and nested-schema conflicts are errors. Similar-but-different field names are warnings because semantic similarity is heuristic.
Native Studio
Install Studio support and open a project:
pip install "AIPodCli[studio]"
aipod studio .
Studio provides:
- project switching and initialization;
- Model, Provider, Service, Pipeline, and Interface visualization;
- AI component creation and visual Pipeline composition;
- Pod build progress, cancellation, and stage evidence;
- source inspection;
- Interface Adapter, lifecycle, permission, and verification inspection;
- program output and persisted run traces.
Project structure
project/
├── aipod_plan.json resumable Plan and public Agent state
├── beans_config.json Bean registry and Contracts
├── config.toml project configuration
├── routes.toml route-to-Pipeline registry
├── requirements.txt project-specific dependencies
├── modules/
│ ├── models/
│ ├── providers/
│ └── services/
├── pipelines/
├── interfaces/
│ └── <interface-id>/
│ ├── interface.json
│ ├── adapter.py
│ └── additional Adapter modules and lifecycle files
├── docs/aipod/ generated human-readable plans
└── .aipod/runs/ redacted execution traces
CLI reference
| Command | Purpose | Uses AI |
|---|---|---|
aipod init [--install-deps] |
Initialize a project | No |
| `aipod pod DESC [--file FILE] [--stage auto | LAYER] [--yes]` | Build or modify a complete Pod |
aipod create --category TYPE --name NAME --desc DESC |
Generate one component | Yes |
aipod add --category TYPE --name NAME --class-path PATH --desc DESC |
Register existing code | No |
aipod compose CMD [--name ROUTE] |
Generate and register a Pipeline | Yes |
aipod interface list |
List Interface manifests | No |
aipod interface run NAME [--payload JSON] [-- ARGS...] |
Run a frozen Adapter | No |
aipod interface smoke NAME |
Execute Adapter smoke | No |
aipod interface install/uninstall NAME |
Execute declared lifecycle command | No |
aipod run ROUTE --params JSON |
Run one Pipeline route | No |
aipod inspect [TARGET] [NAME] --json |
Read project state | No |
aipod verify --json -- COMMAND... |
Produce runtime and repair evidence | No |
aipod visualize [--output FILE] [--open] |
Export the project graph | No |
aipod studio [PATH] |
Open native Studio | No |
aipod config set/get/remove/list/path |
Manage model configuration | No |
aipod entry remains available for legacy standalone entry generation. New Pod projects
should use Interface Adapters.
Configuration
Global model configuration is stored outside individual projects. Environment variables
or a local .env override saved values:
OPENAI_API_KEY
OPENAI_BASE_URL
OPENAI_MODEL
OPENAI_TIMEOUT_SECONDS
The PyPI distribution is named AIPodCli; the Python import package is ai_pod_cli.
Security and trust boundary
AIPod provides governance, not hostile-code isolation.
- Generated code is checked structurally and executed in disposable project copies before freezing.
- Adapter code can see routes but is prohibited from importing Services or runtime internals.
- Generated lifecycle files must be reviewed before changing system integration.
- The final application is ordinary Python and runs with the current user's permissions.
- Third-party packages and remote model providers remain separate trust boundaries.
Do not treat generated code as safe for production without review, platform permissions, and deployment isolation appropriate to the application.
Current boundaries
- Synchronous code cannot safely force an async Pipeline inside an already-running event
loop; async callers must use
PipelineRunner.run_async(). - Stream processing is in-process and bounded, but durable offsets, distributed workers, and exactly-once delivery remain responsibilities of the selected queue/provider.
- Parallel execution isolates Context data, but external side effects still require idempotency and transaction design in the application Services.
- Contract analysis cannot prove arbitrary Python semantics.
- Synthetic smoke cannot prove access to real external databases, queues, accounts, or operating-system permissions.
- Complex platform installation may require explicit manual steps, signing, entitlements, or user approval.
- Model providers may time out or truncate large generations; Pod state remains resumable.
Development
git clone https://github.com/wangzhongren/ai_pod_cli.git
cd ai_pod_cli
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -e ".[studio]"
python -m unittest tests.test_runtime
Build and validate the package:
python -m build
python -m twine check dist/*
License
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 aipodcli-0.9.1.tar.gz.
File metadata
- Download URL: aipodcli-0.9.1.tar.gz
- Upload date:
- Size: 744.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
35e12f3bb6f5ef3a63b574836a07168333a9209bc83d17a5ecdfaf407455d1b0
|
|
| MD5 |
aa602d289a188ffdc320bbf8cf484b3f
|
|
| BLAKE2b-256 |
9b178dc4d64bfb7a34fe62b8adde46e1abaa66766e54c49e69e650a7106c26fc
|
File details
Details for the file aipodcli-0.9.1-py3-none-any.whl.
File metadata
- Download URL: aipodcli-0.9.1-py3-none-any.whl
- Upload date:
- Size: 739.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
75b3f7775876de1bc1985ea0e0d8f102c788b67f67fd99a853bb9cc1b4c3546d
|
|
| MD5 |
38023baf861b9e7994bdca8606c990db
|
|
| BLAKE2b-256 |
528d09dee66a9d70111540036b75b76dab4aca431c0c056c29c011080e10f41f
|