Skip to main content
web_plus_slack.py
"""
Team briefing: Slack + Web
==========================

Cross-reference internal Slack discussion with external industry
news to produce a short briefing.

Workflow the agent performs:
  1. Pull recent messages from an engineering Slack channel
     (``query_slack`` → ``get_channel_history``).
  2. For each topic it surfaces, find a current external reference
     (``query_web`` → Parallel search).
  3. Return a briefing tying each internal thread to a supporting
     external source.

The compositional shape — one provider's output informing the next
provider's query — is the payoff of multi-provider. Parallel
"two unrelated questions" is a weaker demo; real workflows chain.

Requires:
    OPENAI_API_KEY
    PARALLEL_API_KEY   (https://platform.parallel.ai/)
    SLACK_BOT_TOKEN    (or SLACK_TOKEN fallback; scopes: channels:read,
                        channels:history, users:read)
    pip install parallel-web

Optional:
    SLACK_USER_TOKEN   (xoxp-) enables search_messages API
"""

from __future__ import annotations

import asyncio

from agno.agent import Agent
from agno.context.slack import SlackContextProvider
from agno.context.web import ParallelBackend, WebContextProvider
from agno.models.openai import OpenAIResponses

# Sub-agents do the tool work — cheaper model. Outer agent synthesizes.
provider_model = OpenAIResponses(id="gpt-5.4-mini")

backend = ParallelBackend()  # reads PARALLEL_API_KEY from env
web = WebContextProvider(backend=backend, model=provider_model)
slack = SlackContextProvider(model=provider_model)

agent = Agent(
    model=OpenAIResponses(id="gpt-5.5"),
    tools=[*web.get_tools(), *slack.get_tools()],
    instructions="\n".join([web.instructions(), slack.instructions()]),
    markdown=True,
)


if __name__ == "__main__":
    print(f"web.status()   = {web.status()}")
    print(f"slack.status() = {slack.status()}\n")

    prompt = (
        "I'm prepping a short briefing for our weekly engineering sync. "
        "Do this:\n"
        "  1. Pull the 10 most recent messages from the #agents Slack "
        "channel and identify 2 distinct topics under discussion.\n"
        "  2. For each topic, find one current (last ~month) article, "
        "release, or reference online that would be useful to link.\n"
        "\n"
        "Format as a short markdown briefing:\n"
        "  - **Topic** — 1-sentence Slack context → [external reference](url)\n"
        "\n"
        "If a topic has no clear external reference, say so; don't invent URLs."
    )
    print(f"> {prompt}\n")
    asyncio.run(agent.aprint_response(prompt))

Run the Example

1

Set up your virtual environment

uv venv --python 3.12
source .venv/bin/activate
uv venv --python 3.12
.venv\Scripts\activate
2

Install dependencies

uv pip install -U agno openai parallel-web
3

Export your API keys

export OPENAI_API_KEY="your_openai_api_key_here"
export PARALLEL_API_KEY="your_parallel_api_key_here"
export SLACK_BOT_TOKEN="your_slack_bot_token_here"
export SLACK_TOKEN="your_slack_token_here"
export SLACK_USER_TOKEN="your_slack_user_token_here"
$Env:OPENAI_API_KEY="your_openai_api_key_here"
$Env:PARALLEL_API_KEY="your_parallel_api_key_here"
$Env:SLACK_BOT_TOKEN="your_slack_bot_token_here"
$Env:SLACK_TOKEN="your_slack_token_here"
$Env:SLACK_USER_TOKEN="your_slack_user_token_here"
4

Run the example

Save the code above as web_plus_slack.py, then run:
python web_plus_slack.py
Full source: cookbook/12_context/09_web_plus_slack.py