Put an Atelier AI agent in the decision path of your existing code. The agent can observe, allow, deny, or modify the payload of an API call, a DB write, or any function call — so you can agentify a legacy codebase one call site at a time.
pip install atelier-agentic # core (zero dependencies)
pip install "atelier-agentic[requests,schema]" # + requests auto-instrument + schema validationfrom atelier_agentic import AtelierClient
atelier = AtelierClient(
agent_id=12,
api_key="sk_...", # or env ATELIER_API_KEY
base_url="https://your-atelier", # or env ATELIER_BASE_URL
mode="enforce", # observe | suggest | enforce
)
# Guard a payload before you use it:
payload = atelier.guard(
"db.update",
{"id": 1, "status": "paid", "total": 100},
mutable_fields=["status"], # the agent may only change "status"
context={"table": "orders"},
)
db.update(payload)| mode | behaviour |
|---|---|
observe |
never changes anything — returns the original payload (use for shadow logging) |
suggest |
returns the original payload; the verdict is available via decide() |
enforce |
applies the verdict: deny raises AtelierDenied, modify returns the new payload |
Start in observe, watch the verdicts in your Atelier traces, then graduate
specific call sites to enforce.
@atelier.intercept("fn.charge", mutable_fields=["amount"])
def charge(payload):
return gateway.charge(payload)v = atelier.decide("http.post", body, schema=ORDER_SCHEMA)
print(v.decision, v.reason, v.confidence, v.changed)from atelier_agentic import install_requests
install_requests(atelier, mode="observe", methods=["POST", "PUT"])
# every requests.* call with a JSON body is now guarded- The agent may only change keys listed in
mutable_fields(None= any,[]= none). - If a JSON
schemais supplied, a modified payload that fails validation is reverted. - Network/timeout errors fail open (return the original payload) unless
fail_open=False. - Every decision is recorded in your Atelier traces.
Where guard/decide sit in the path of one action, emit is fire-and-forget: your
app reports that something happened, and Atelier runs whatever workflows you've defined
for that event (each picks its own agent). No agent_id needed.
atelier = AtelierClient(api_key="ate-...") # no agent_id required for emit
atelier.emit("todo.completed", {"todos": todos})
# -> {"event": "todo.completed", "matched": 2, "run_ids": [...]}Scope to a workspace with AtelierClient(workspace_id=1) or ATELIER_WORKSPACE_ID
(otherwise your personal workspace). See the Event Workflows guide in the docs.
trigger runs a full agent turn for an event — the agent reacts through its own tools.
Unlike emit, it targets this client's agent_id:
atelier = AtelierClient(agent_id=12, api_key="ate-...")
summary = atelier.trigger(
"todo.completed",
context={"todos": todos},
instructions="If every todo is done, clear them and add a fresh 'todo-1'.",
)