Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

agent-framework-hosting

Shared execution-state helpers for app-owned Agent Framework hosting.

This package keeps Agent Framework state separate from web-framework concerns:

  • AgentState — pairs an agent target with a core SessionStore (session_id -> AgentSession).
  • WorkflowState — resolves a workflow target, including direct Workflow instances, workflow factories, WorkflowBuilder, and orchestration builders.

The experimental SessionStore and FileSessionStore implementations live in agent-framework-core and are imported from agent_framework. SessionStore provides get/set/delete by an app-selected id. Each successful get returns an independent copy, so a run works from a snapshot instead of mutating an older continuation point in place. The store does not know how to create a new value for an id it hasn't seen before — use AgentState.get_or_create_session(...) for that, since only the state object has both the store and the resolved target. Workflow checkpointing should use the existing CheckpointStorage abstraction directly; if an app needs per-session resume, keep a small app-owned cursor such as session_id -> checkpoint_id.

SessionStore accepts opaque non-empty IDs so custom database and Redis implementations can use their native key contracts. FileSessionStore limits its direct keys to 128 ASCII letters, digits, -, and _. AgentState passes the app-selected ID to the configured store unchanged; each store implementation owns any validation or normalization required by its backend. This does not replace parameterized queries or backend-specific validation in custom stores.

FileSessionStore uses msgspec JSON. Register custom objects placed in AgentSession.state explicitly before sessions are saved or restored:

from agent_framework import register_state_type


class MyState:
    ...


# Register at module import time, before any provider instance is created.
register_state_type(MyState, type_id="my_state")

Classes with to_dict() / from_dict() methods and explicitly registered Pydantic models receive default codecs. Other classes can provide encoder= and decoder= callbacks. Keep registration at module level so importing the module prepares cold-start session restoration before its context provider is instantiated. Unregistered Pydantic models still use legacy same-process auto-registration for now, but emit DeprecationWarning; cold-start deserialization is not guaranteed on that path.

JSON is the default file format. Use MessagePack for a compact binary file:

store = FileSessionStore("storage/sessions", serialization_format="msgpack")

Use FastAPI, Starlette, Azure Functions, Django, or another framework for route registration, auth, middleware, response construction, and background work.

The core SessionStore is an in-memory dict with no eviction — every id ever stored stays resolvable for the life of the process. That is intentional: protocols such as OpenAI Responses' previous_response_id are designed to let a caller continue from any earlier point in a conversation, not just the latest turn, so every id handed out needs to stay independently resolvable. If you back the store with real storage (Redis, a database, ...), you are responsible for that store's own TTL/eviction policy; this in-memory reference implementation does not model that concern.

Quickstart

from agent_framework import FileSessionStore
from agent_framework.openai import OpenAIChatClient
from agent_framework_hosting import AgentState

agent = OpenAIChatClient().as_agent(name="Assistant")
state = AgentState(agent, session_store=FileSessionStore("storage/sessions"))
session = await state.get_or_create_session("conversation-1")
result = await (await state.get_target()).run("Hello", session=session)

If a protocol mints a new continuation id on every response, store the session explicitly after run(...) returns. run(...) may update the session, so store the post-run object:

session = await state.get_or_create_session(previous_response_id)
result = await (await state.get_target()).run("Hello", session=session)
await state.set_session(response_id, session)

This response-keyed pattern supports simultaneous branches: callers may read the same previous_response_id, receive independent working copies, and store each result under a different new response id. A stable conversation_id is different: explicitly write the completed session back under that same id to advance its mutable head, and ensure only one caller advances it at a time. AgentState does not provide that application-level locking or optimistic concurrency control.

Targets can be direct instances, synchronous factories, asynchronous factories, or awaitables:

state = AgentState(create_agent)  # cached by default
state = AgentState(create_agent, cache_target=False)

WorkflowState mirrors this shape for workflow targets:

from agent_framework import InMemoryCheckpointStorage
from agent_framework_hosting import WorkflowState

state = WorkflowState(create_workflow)
storage = InMemoryCheckpointStorage()
result = await (await state.get_target()).run("Hello", checkpoint_storage=storage)
latest = await storage.get_latest(workflow_name=(await state.get_target()).name)

A Workflow instance allows only one active run. Hosts that need simultaneous workflow runs should pass a factory or builder and set cache_target=False so each request receives a fresh workflow instance.

WorkflowState also accepts an unbuilt workflow builder directly:

from agent_framework import WorkflowBuilder
from agent_framework_hosting import WorkflowState

builder = WorkflowBuilder(start_executor=executor)
state = WorkflowState(builder)  # calls builder.build() when the target is resolved

This is structural: orchestration builders from agent_framework_orchestrations (SequentialBuilder, ConcurrentBuilder, HandoffBuilder, GroupChatBuilder, and MagenticBuilder) also work because they expose the same zero-argument build() -> Workflow method.

Cross-channel identity linking, multicast delivery, background runs, continuation tokens, and durable delivery runners are follow-up enhancements, not part of this v1 state surface.

Metadata

Release files for agent-framework-hosting 1.0.0a261002

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for agent-framework-hosting 1.0.0a261002
File Size Uploaded
agent_framework_hosting-1.0.0a261002.tar.gz 7.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for agent-framework-hosting 1.0.0a261002
File Interpreter ABI Platform
agent_framework_hosting-1.0.0a261002-py3-none-any.whl Python 3 none any Details

Total release size: 16.1 kB

Release files / agent_framework_hosting-1.0.0a261002.tar.gz

Download URL agent_framework_hosting-1.0.0a261002.tar.gz
Size 7.5 kB
Tags Source
SHA-256 checksum
How to use checksums
1f20d1fc2efcbbcc1c2c73dad1df70a884e3b6aa26890482981b7e04bea72155
BLAKE2b-256 checksum
How to use checksums
989785aac427a30a8ee6450157ff0e63bce8da9c40f54fe46fc88706a83edf89
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / agent_framework_hosting-1.0.0a261002-py3-none-any.whl

Download URL agent_framework_hosting-1.0.0a261002-py3-none-any.whl
Size 8.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
f977aa2f079f0eada78a3ce11802fad7cc8643b0c9ffbd4394c279e591605400
BLAKE2b-256 checksum
How to use checksums
96675ab3477729700139fcbbef464d8581bd62001ec34bacf91d96e03b18be06
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.22 {"installer":{"name":"uv","version":"0.12.22","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page