Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.egisai.co/llms.txt

Use this file to discover all available pages before exploring further.

Many applications run multiple logical agents inside a single Python process — a triage assistant that hands off to a billing assistant, a coding agent that delegates research to a sub-agent, a multi-tenant SaaS that has a different chatbot per customer. This page collects the patterns we recommend for attributing every call correctly.

The default: one Agent per process

If your process only ever runs one logical agent, there’s nothing to do beyond egisai.init():
egisai.init(app="customer-support-bot", env="production")
Every governed call is attributed to customer-support-bot.

Several sub-agents in one process

Use egisai.set_context(agent="…") at the boundary of each sub-agent’s execution. The first time a new name is seen the SDK registers it as an Agent on the platform; subsequent uses are cache hits.
import egisai
import openai

egisai.init(app="orchestrator", env="production")
client = openai.OpenAI()

def triage(query: str) -> str:
    egisai.set_context(agent="triage-agent")
    response = client.chat.completions.create(
        model="gpt-4.1",
        messages=[
            {"role": "system", "content": "You triage incoming requests."},
            {"role": "user",   "content": query},
        ],
    )
    return response.choices[0].message.content

def billing(query: str) -> str:
    egisai.set_context(agent="billing-agent")
    response = client.chat.completions.create(
        model="gpt-4.1",
        messages=[
            {"role": "system", "content": "You answer billing questions."},
            {"role": "user",   "content": query},
        ],
    )
    return response.choices[0].message.content
Each sub-agent shows up separately on the dashboard.
Even without explicit set_context calls, the SDK fingerprints distinct system prompts and gives each one its own Agent entry. set_context(agent=…) is a way to name that agent yourself rather than letting the platform generate one.

FastAPI / async web handler

set_context() writes to a ContextVar, so each request handler sets context without leaking into other concurrent requests.
from fastapi import FastAPI
import egisai
import openai

egisai.init(app="orchestrator", env="production")
app = FastAPI()
client = openai.AsyncOpenAI()

@app.post("/agents/{name}/chat")
async def chat(name: str, body: dict):
    egisai.set_context(
        agent=name,                         # one of "triage", "billing", …
        user_id=body["user_id"],
        session_id=body["session_id"],
    )
    response = await client.chat.completions.create(
        model="gpt-4.1",
        messages=body["messages"],
    )
    return response.choices[0].message.content

Multi-tenant SaaS

Attach the end-customer identity per request — separate from the agent identity — using user_id and session_id. Both fields land on every audit event for the lifetime of the context.
egisai.set_context(
    agent="customer-support-bot",
    user_id=request.user.id,
    session_id=request.session_id,
)
You can then filter the dashboard by tenant for support and billing review.

Workflows that span multiple calls

If a single user request fans out into several model calls, group them with a shared workflow_id:
import uuid
import egisai

workflow_id = uuid.uuid4().hex
egisai.set_context(workflow_id=workflow_id, agent="planner")

plan = generate_plan(...)
for step in plan:
    egisai.set_context(agent=step.agent_name)
    run_step(step)                              # workflow_id is preserved
The dashboard groups related calls by workflow_id so you can review a full plan execution at once.

Threading and asyncio

set_context() uses contextvars, which means:
  • asyncio tasks created from a context inherit the values.
  • Threads created with concurrent.futures.ThreadPoolExecutor and friends inherit the values from the spawning thread.
  • A new top-level thread (threading.Thread(target=...)) starts with the process-level defaults from init(). If you need request-level context in that thread, call set_context() again at the top of its target function.

Resolution recap

When attributing a call, the SDK uses, in order:
  1. set_context(agent_id=...) — explicit UUID.
  2. set_context(agent=...) — explicit name (resolved to UUID once, then cached).
  3. System-prompt fingerprint — auto-detected sub-agent.
  4. app= from egisai.init() — process-level default.
Explicit calls always win. See Agents for the full picture.

What’s next

set_context reference

Every accepted parameter.

Configuration

Init-time options.