STACK
MENU
DOCS / INTEGRATIONS / AUTOGEN

AutoGen Integration

Expose STACK proxy calls as AutoGen AgentChat tools. Each tool uses one agent's Passport, so STACK can apply that agent's service grant, scope, and revocation state.

1. Install

bash
pip install -U "autogen-agentchat" "autogen-ext[openai]" getstack
npx -y @getstackrun/cli auth login

2. Register and grant the agent

python
from getstack import Stack

stack = Stack()
agent_record = stack.agents.register(
    name="autogen-github-triage",
    description="Triage issues in one GitHub repository",
    accountability_mode="logged",
    key_mode="customer_managed",
)

github = next(
    connection
    for connection in stack.services.list()
    if connection["provider"] == "github"
)
stack.services.grant_agent_access(
    agent_id=agent_record.id,
    service_connection_id=github["id"],
    scopes=github["scopes"],
)

Connect GitHub first at Connect. Grant only the scopes that the AutoGen agent needs. Customer-managed key mode lets the runtime in the next step authenticate as this agent instead of carrying the operator API key.

3. Create a STACK-backed tool

python
import asyncio

from autogen_agentchat.agents import AssistantAgent
from autogen_agentchat.ui import Console
from autogen_ext.models.openai import OpenAIChatCompletionClient

async def main() -> None:
    agent_stack = Stack(agent_id=agent_record.id)

    with agent_stack.passports.mission(
        agent_id=agent_record.id,
        intent="Triage issues in acme/sandbox",
        services=["github"],
        checkpoint_interval="5m",
    ) as mission:
        def create_github_issue(title: str, body: str) -> dict:
            """Create an 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 returned {response.status}")
            return response.body

        model_client = OpenAIChatCompletionClient(model="gpt-4o-mini")
        assistant = AssistantAgent(
            name="github_triage",
            model_client=model_client,
            tools=[create_github_issue],
            system_message="Triage acme/sandbox. Use the tool only when an issue is needed.",
        )

        await Console(assistant.run_stream(
            task="Create an issue for the title typo we confirmed."
        ))
        await model_client.close()

asyncio.run(main())

AutoGen uses the function signature and docstring as the tool schema. The function routes the action through STACK. A direct call to GitHub would bypass STACK controls.

For a durable non-GET job, pass on_operation_id to mission.proxy() and persist the ID before network I/O. Reuse it only for the unchanged request; use agent_stack.proxy.get_operation() after response loss. See Proxy operation recovery.

4. Operate the integration

  • Use one STACK agent record for each AutoGen role that needs separate attribution.
  • Give each role its own service grants and Passport.
  • Use logged mode to observe detector results before you enable enforced blocking.
  • Revoke the Passport to reject its next STACK-verified call.
  • Use drop-offs when two agents need a schema-validated one-read handoff.

The SDK method named passports.mission() manages a Passport lifecycle context. It is separate from the Mission resource.

stack | Docs