Pydantic Agents -> ISPL
Through a combination of inspection and LLM-backed completion, py-mcmas can guess about how to write ISPL specs from your existing pydantic-agents. This process is experimental and probably best thought of as semi-automatic at best, and your milage may vary depending on how powerful your LLM backend is!
If you're interested in something more deterministic, see the demo for gradual annotation of agent-frameworks.
Intro to Societies
For starters, you'll probably want to enumerate existing agents, and that's part of what api://mcmas.Society does. See the example below:
import pydantic_ai
# Declare pydantic agents as usual
alice = pydantic_ai.Agent(name="alice")
bob = pydantic_ai.Agent(name="bob")
# Declare pydantic tools as usual
@alice.tool
def tool1(expected="", arguments="", **kwargs) -> str:
return f"tool1 response {expected} {arguments}"
@bob.tool
def tool2(different="", arguments="", **kwargs) -> str: # noqa
return f"tool2 response {different} {arguments}"
# Create society from module
from mcmas import ai
society = ai.Society(pydantic_ai)
def test_society_membership():
assert alice in society, "failed to detect agent"
assert bob in society, "failed to detect agent"
def test_society_iterable():
for agent in [alice, bob]:
assert agent in society, "society should be populated and iterable"
Code to Specification
Using constructor notation you can get specification objects from pydantic agents like this:
import mcmas
import pydantic_ai
# Declare agents & tools as usual
alice = pydantic_ai.Agent(name="alice")
bob = pydantic_ai.Agent(name="bob")
@alice.tool
def tool1(*args, **kwargs) -> str:
return f"tool1 {[args,kwargs]}"
@bob.tool
def tool2(ctx, first_kwarg: int = 1, **kwargs) -> str:
return f"tool2 {[ctx, first_kwarg, kwargs]}"
def test_agent_from_pydantic():
"""
Using square-brackets notation, construct
an agent spec from an agent implementation
"""
alice_prime = mcmas.ispl.Agent[alice]
assert isinstance(alice_prime, (mcmas.Agent,))
def test_agent_complete():
bob_prime = mcmas.Agent[bob]
assert bob_prime.protocol, "default protocol should be set"
assert not bob_prime.advice, "no advice, agent is concrete"
assert bob_prime.concrete, "expected agent validates and is ready-to-run"
expected = "Agent bob" in bob_prime.model_dump_source()
err = "agent name extracted incorrectly"
assert expected, err
err = "agent-implementation's argument should be reflected in spec"
expected = "first_kwarg" in bob_prime.vars
assert expected, err
tmp = mcmas.Agent.load_from_source(bob_prime.model_dump_source())
assert "Other" in str(tmp.protocol)