AutoGen integration
Five-minute path to wiring STACK into Microsoft AutoGen agents. AutoGen's function-calling pattern maps cleanly to STACK: every function the agent can invoke goes through the credential proxy with a passport-bound scope, and every call lands in the audit log.
Examples below use AutoGen 0.2 (PyPI package pyautogen) — the version with the AssistantAgent / UserProxyAgent / register_function pattern. Microsoft is shipping a successor under autogen-agentchat (0.4+); the STACK wiring concept is identical but the AutoGen-side imports differ.
1. Install
pip install pyautogen getstackSTACK's Python SDK ships on PyPI as getstack.
2. Connect a service
Connect at least one upstream service at getstack.run/services. For this example, connect GitHub.
3. Register the agent + open a mission
import os
from getstack import Stack
stack = Stack(api_key=os.environ["STACK_API_KEY"])
agent = stack.agents.register(
name="autogen-assistant",
description="GitHub triage bot",
accountability_mode="enforced",
)
mission_cm = stack.passports.mission(
agent_id=agent.id,
intent="Triage open issues in acme/sandbox",
services=["github"],
checkpoint_interval="5m",
)mission_cm is a context manager. We keep a reference to it so the AutoGen functions defined below can capture mission in closure scope once we enter the block.
4. STACK-proxied functions
def make_github_functions(mission):
"""Define AutoGen-callable functions that proxy through STACK."""
def create_github_issue(title: str, body: str) -> dict:
"""Create a GitHub issue in acme/sandbox."""
response = mission.proxy(
service="github",
url="https://api.github.com/repos/acme/sandbox/issues",
method="POST",
body={"title": title, "body": body},
)
if not response.ok():
raise RuntimeError(f"GitHub API failed: {response.status}")
return response.body
def list_github_issues(state: str = "open") -> list[dict]:
"""List GitHub issues in acme/sandbox."""
response = mission.proxy(
service="github",
url="https://api.github.com/repos/acme/sandbox/issues",
method="GET",
query={"state": state},
)
if not response.ok():
raise RuntimeError(f"GitHub API failed: {response.status}")
return response.body
return create_github_issue, list_github_issuesmission.proxy(...) attaches the passport JWT, logs the tool call into the mission's checkpoint buffer, and validates the URL. Pass full URLs — the proxy rejects relative paths.
5. Wire into AutoGen
from autogen import AssistantAgent, UserProxyAgent, register_function
with mission_cm as mission:
create_github_issue, list_github_issues = make_github_functions(mission)
llm_config = {"model": "gpt-4o-mini", "api_key": os.environ["OPENAI_API_KEY"]}
assistant = AssistantAgent(
name="github_helper",
system_message=(
"You triage GitHub issues for acme/sandbox. You can list and "
"create issues. Your scope is bound to that one repo."
),
llm_config=llm_config,
)
user_proxy = UserProxyAgent(
name="user",
human_input_mode="NEVER",
code_execution_config=False,
)
register_function(
create_github_issue,
caller=assistant,
executor=user_proxy,
description="Create a GitHub issue in acme/sandbox",
)
register_function(
list_github_issues,
caller=assistant,
executor=user_proxy,
description="List GitHub issues in acme/sandbox",
)
user_proxy.initiate_chat(
assistant,
message="List open issues, then file one for the title-typo bug we discussed.",
)
# Mission auto-checks-out here. Post-hoc detectors run on the trajectory.6. What happens when the agent goes off-script
If the LLM hallucinates a call to a different repo or a different provider, the proxy denies it (passport scope is bound to github service for this agent) and the credential_outside_scope detector fires. In enforced mode the passport is auto-revoked; subsequent function calls raise. The trace surfaces in the dashboard /activity feed and /audit.
7. Kill switch
If you need to revoke during the run (e.g. the LLM's output looks adversarial), call:
stack.passports.revoke(mission.passport.jti, reason="off-script")Propagation is sub-60-second. Subsequent mission.proxy(...) calls fail closed.
Full SDK reference: /docs/sdk/python. For multi-agent AutoGen flows where one agent hands off to another, register each as a separate STACK agent (one passport each, scope per role) — see the CrewAI guide for the same per-agent pattern.
Why bother
- AutoGen functions are LLM-routed; STACK puts a hard fence around what each function can actually call
- Scope is enforced server-side — the LLM cannot fabricate its way past it
- Detectors catch wrong-repo / overrunning action volume / drift from the original intent
- Hash-chained audit log of every function call, exportable for compliance review