Quickstart
Install agentsparty, then ask one agent and declare the same conversation yourself.
The smallest session is a request and a reply.
What the examples show
The first example uses a generated Shape; the second spells out the same
route with your own message classes. Both end at a typed return value, so you
can see exactly where convenience ends and the protocol begins.
Install
Core package
# Install the core package.
pip install agentspartyRequires Python 3.10+. Core has no provider dependency.
Start with core when the model is not the point
The core package is enough for protocol construction, projection checks,
Script, Machine, Policy, and ap.replies. Install a provider extra only
at the boundary where a participant makes live model calls.
Choose the core package when the host supplies its own participants, when you
are writing protocol and projection tests, or when model calls will be
replaced with ap.replies. This is enough for the offline examples below and
keeps installation small.
OpenAI-compatible backend
The examples on this page make live model calls, so install the optional OpenAI-compatible backend and set its credential:
uv add "agentsparty[openai]"
export OPENAI_API_KEY="sk-..."Needs OPENAI_API_KEY at run time. Keep the key in the process environment or
in the secret store used by the host. It is not part of a Session, a
Message, or a journal decision, so a journal can be copied for replay without
copying provider credentials into the replay artifact.
Verify the environment
Run the import probe below in the interpreter that will launch your service; a
shell may have more than one Python on PATH. Then run the session in
offline testing to exercise protocol
assembly and projection without a provider key. Expose OPENAI_API_KEY and
construct ap.model(...) only after both checks pass.
A live model call is deliberately absent from the installation check because it spends provider quota and depends on credentials and transport availability.
Development checkout
# Fetch the repository and install its development dependencies.
git clone https://github.com/qnbhd/agentsparty.git
cd agentsparty
uv sync --all-groups
# Run the test suite after installation.
uv run pytest -qVerify import
import agentsparty as apIf the import succeeds but a live example fails, read the exception family:
ModelUnavailable usually points to the extra, credential, timeout, or
provider name; ModelRefused means the provider answered and declined the
request. See error taxonomy before changing
the protocol.
One agent
# requires: api-key
import agentsparty as ap
Reader, Writer = ap.roles('Reader', 'Writer')
shape = ap.patterns.request_reply(Reader, Writer)
session = ap.Session(
shape,
{
Writer: ap.Agent(
ap.model('openai:gpt-5.6-luna'),
'Write three paragraphs.',
),
},
)
article = session.ask(
Reader,
shape.Ask('What does a multi-agent AI system mean?'),
expect=shape.Answer,
)
print(article.text)ask makes the host the Reader for one opening message. It does not remove
the Reader from the protocol; it supplies that role for this call and waits
until the projected endpoint delivers shape.Answer.
Roles are declared with ap.roles(...): a typo is a NameError, not a
new role.
Your own conversation
# requires: api-key
import agentsparty as ap
Reader, Writer = ap.roles('Reader', 'Writer')
class Question(ap.Message):
"""What the reader asks."""
text: str
class Article(ap.Message):
"""The answer, three paragraphs."""
text: str
protocol = ap.Protocol(
ap.send(Reader, Writer, Question),
ap.send(Writer, Reader, Article),
)
session = ap.Session(
protocol,
{
Writer: ap.Agent(
ap.model('openai:gpt-5.6-luna'),
'Write three paragraphs.',
),
},
)
article = session.ask(
Reader,
Question('What does a multi-agent AI system mean?'),
expect=Article,
)
print(article.text)How it works
rolesnames the seats; the protocol connects those seats with typed messages.- The pattern returns a
Shape, which contains the closedProtocol,Ask, andAnswerclasses. askplays the caller role for exactly one opening message, whileWriterremains in the cast.expect=shape.Answermakes the returned value typed, so the result is anAnswer, not an unstructured dictionary.
The protocol owns the route. The model only fills the declared payload or picks one of the classes currently on offer.
Next steps
Read messages to see how classes become wire values,
protocol to add branches and loops, and
patterns for the six ready-made topologies. A
deterministic version of this session uses ap.replies and needs no key; see
offline testing.