Concepts

AgentSky is built around four primitives: agents, sessions, events, and universes. Understanding these makes every API response predictable.

Agents

An agent is a reusable specification — not a running process. It stores:

  • The harness (Claude Code, Codex, Hermes, or a custom harness): determines what model orchestration the agent can do.
  • Instructions: the system prompt and personality.
  • Capabilities: which built-in tools the agent may call (web search, code execution, browser automation, …).
  • Skills: versioned instruction bundles loaded on demand.
  • agent.toml: the declarative file that configures all of the above and is committed to your repo.

Creating an agent does not start it running. You interact with it through sessions.

text
Agent
├── id: agent_…
├── harness: hermes
├── displayName: Research Agent
├── defaultSessionId: sess_…   ← created automatically on first launch
└── capabilities: [exa.search]

Sessions

A session is one running conversation with an agent. It holds:

  • The event log: every message, response, tool call, and status change, in order.
  • The context window: the live slice of the event log the agent sees on its next turn.
  • The status: idle, running, error, terminated.

A session is the unit you stream, continue, and replay. Every agent gets a defaultSessionId at launch — good for one-off use. For multi-user applications, create a session per user conversation.

Sessions live forever (until you delete them). An idle session can be continued days later; it picks up context from the event log.

text
Session
├── id: sess_…
├── agent: agent_…
├── status: idle
├── llm: claude-sonnet-5
└── events: […]

Events

Events are the messages-in and messages-out of a session. The session's event log is append-only.

Events you send:

TypeWhen to use
user.messageA new message from a user or your application
user.interruptStop the agent mid-turn cleanly
system.messageInject a system-level message (hidden from user but visible to agent)

Events the agent produces:

TypeWhat it carries
agent.messageA completed text response
agent.message.deltaA streaming chunk of a text response
agent.tool_callAn outbound tool invocation
agent.tool_resultThe result of a tool call
session.status_idleThe agent finished its turn (includes stop_reason)
session.errorAn unrecoverable error (includes code and message)

The stream (GET /v1/sessions/{id}/stream) delivers events as Server-Sent Events in real time. The event log (GET /v1/sessions/{id}/events) returns the same objects in order after the fact. Both use the same id field — deduplicate by event id when replaying a partial stream.

The session loop

Every turn follows the same shape:

text
POST /sessions/{id}/events   →  202 (queued)
GET  /sessions/{id}/stream   →  SSE: agent.message.delta … session.status_idle
POST /sessions/{id}/events   →  next turn

The stream is standing — open it once and it delivers every future turn. session.status_idle marks the end of a turn; stop_reason says why the agent stopped (end_turn, tool_use, budget_reached, interrupted, error).

Universes (workspaces)

A universe is an isolated workspace — its own agents, sessions, members, billing, and API keys. Use one per customer tenant, per deployment environment, or per team.

bash
# Create
curl -X POST https://api.agentsky.dev/v1/universes \
  -H "Authorization: Bearer ast_..." \
  -d '{ "slug": "acme", "name": "Acme" }'

# Act inside it
curl ... -H "X-Universe: acme"

Resources (agents, sessions, files) belong to exactly one universe. Members of that universe can see its resources. See Authentication for how personal vs. scoped tokens interact with universes.

Billing

AgentSky bills at three levels:

Token usage: every LLM call records input and output tokens. The model rate card is at GET /v1/generation?id=… and in the billing dashboard.

Capabilities: built-in tool calls (web search, browser automation) are charged per invocation at rates listed in the Capabilities reference.

Sessions: session compute (hosting the pod between turns) is charged per active session-hour.

A spend policy lets you cap a session's total spend before it was created or at any time:

bash
curl -X POST https://api.agentsky.dev/v1/sessions/sess_.../policies \
  -H "Authorization: Bearer ast_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Spend cap",
    "kind": "SPEND_CAP",
    "config": { "hardCapUsdMicros": 5000000, "warnUsdMicros": 4000000 }
  }'

When the hard cap is hit, the session stops with stop_reason.type: "budget_reached". Cumulative spend is on GET /v1/sessions/{id}.

See also