Skip to main content

Swiss AI Hub Bot SDK: connect users to AI agents via MS Teams, Slack, and web chat.

Project description

swiss-ai-hub-bot

The bot integration SDK for Swiss AI Hub — bring your agents to users in MS Teams, Slack, and web chat.

PyPI Python License


What is Swiss AI Hub?

Swiss AI Hub is an open-source, self-hosted AI platform for enterprises. One docker compose up starts ~30 integrated containers — LLM gateway (LiteLLM), vector search (Milvus), data pipelines (Dagster), SSO (Keycloak), observability (Langfuse), a chat UI (Open-WebUI), and more. You build agents with the Python SDK; this package puts them in the chat tools your users already live in.

What is this package?

swiss-ai-hub-bot is a Bot Framework application (built on the microsoft-agents-* SDK) that connects collaboration channels to Swiss AI Hub. It receives messages from MS Teams, Slack, and web chat, handles the channel-specific quirks (threads, mentions, file attachments, markdown, typing indicators, streaming), and routes each conversation to its destination:

  • AgentChatBot — routes a conversation to a Swiss AI Hub agent over NATS, streaming the agent's response back into the channel.
  • OpenaiChatBot — talks directly to an LLM through the platform's LiteLLM gateway (no agent), for simple chat-with-a-model endpoints.
  • Bot-in-the-loop (BITL) — when an agent needs a human, the bot delivers the question to a Slack/Teams channel and feeds the human's reply back into the agent's workflow.

It builds on swiss-ai-hub-core (installed automatically) and pairs with swiss-ai-hub-agent (the agents it surfaces).

Should you use this package?

Probably not directly — most deployments use the pre-built Docker image, which ships the bot ready to go:

# docker-compose.yml
services:
  bot:
    image: ghcr.io/bbvch-ai/aihub-core/bot:latest

Use this PyPI package when you want to compose a custom bot — mount only the handlers you need, add your own channel handler, or change how conversations are routed. It's an SDK for building a custom chat front-end on top of Swiss AI Hub, not just a standalone server.

Installation

pip install swiss-ai-hub-bot
# or
uv add swiss-ai-hub-bot

Requires Python 3.13.


Quick start

A bot is a BotRunner with the channel controllers you mount — the same shape as the production entry point:

# app.py
from swiss_ai_hub.core.auth.dependencies.keycloak_auth_handler import KeycloakAuthHandler
from swiss_ai_hub.core.routes import HealthController
from swiss_ai_hub.bot.routes import AgentChatController, OpenaiChatController, BotInTheLoopController
from swiss_ai_hub.bot.runners import BotRunner

runner = BotRunner()
auth = KeycloakAuthHandler()   # a fail-closed safety net; channel authenticity is verified per-endpoint (see below)

runner.mount(
    HealthController(auth=auth).get_health(),
    AgentChatController(auth=auth).completions_json().completions_stream(),     # chat → agent (NATS)
    OpenaiChatController(auth=auth).json_chat_completion().stream_chat_completion(),  # chat → LLM (direct)
    BotInTheLoopController(auth=auth).bot_in_the_loop_response(),               # human replies → agent
)

app = runner.create_app()

Serve it like any ASGI app (the platform ships it on port 8001):

uvicorn app:app --host 0.0.0.0 --port 8001

This exposes the Bot Framework messaging endpoints — /api/v1/agent/chat/completions/{agent_class}/{agent_id}/json (and /stream), the OpenAI-style /api/v1/openai/chat/completions/json, and /api/v1/bot_in_the_loop/response. Health is at /api/v1/health.

Connecting a channel

Each bot endpoint is keyed by its URL path in MongoDB via a PathEntity, which holds that endpoint's Azure Bot credentials (APP_ID, APP_PASSWORD, tenant), an optional system message, and a Slack token. To wire up a real channel:

  1. Register a bot in Azure Bot Service (the SDK's setup_azure_bot helper creates the AD app registration + Bot resource and stores the credentials), then add the Teams or Slack channel in the Azure portal.
  2. Point the channel's messaging endpoint at your bot's public URL.
  3. The PathEntity for that path is seeded automatically by setup_azure_bot (or manually via add_path_entity for local development).

RoutesService.get_adapter(path) then loads the credentials, builds a cached Bot Framework adapter per endpoint, and verifies the authenticity of every incoming activity.


Development

The dev stack runs the platform infrastructure (NATS, FerretDB, Valkey, LiteLLM, …) in Docker and exposes it on localhost; the bot runs on your host:

# 1. Start the platform infrastructure (from a Swiss AI Hub checkout)
docker compose --env-file .env -f infra/docker-compose.dev.yml up -d

# 2. Load the dev connection settings into your shell
set -a && source .env && set +a

# 3. Run the bot — it connects to NATS + MongoDB and serves on :8001
uvicorn app:app --host 0.0.0.0 --port 8001

The bot connects to NATS and MongoDB, subscribes for bot-in-the-loop requests, and is ready to receive activities. Two ways to drive messages locally:

  • Bot Framework Emulator — connect it to http://localhost:8001/api/v1/messages (leave App ID/Password empty).
  • Real channels — expose your local bot to the internet with a tunnel (Azure Dev Tunnels, ngrok, …) and set that URL as the channel's messaging endpoint, so Teams/Slack can reach it.

Settings are not auto-loaded from the environment. The SDK reads connection settings only when constructed, so make sure the variables above are exported in the process that runs the bot (set -a && source .env && set +a).

Production

In production the bot runs as a container behind Traefik (so channels can reach its webhook), reaching other services by container hostname.

1. Containerize it — install the SDK from PyPI and serve with Gunicorn + Uvicorn workers:

FROM python:3.13-slim
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/

WORKDIR /app
COPY pyproject.toml uv.lock ./        # your project, depending on swiss-ai-hub-bot
RUN uv sync --frozen --no-dev
COPY . .

ENV PATH="/app/.venv/bin:$PATH" PYTHONUNBUFFERED=1
EXPOSE 8001
ENTRYPOINT ["gunicorn", "-w", "1", "-k", "uvicorn.workers.UvicornWorker", \
            "--forwarded-allow-ips=*", "-b", "0.0.0.0:8001", "app:app"]

2. Run it alongside the platform on the right networks. The bot receives channel webhooks (Traefik → proxy), routes conversations to agents over NATS and keeps conversation state in MongoDB (data), and reaches the LLM gateway (backend):

# docker-compose.my-bot.yml — deployed alongside the platform
services:
  my-bot:
    image: registry.example.com/my-bot:1.0.0
    restart: always
    environment:
      NATS_ENDPOINT: nats://nats:4222
      NATS_TOKEN: ${NATS_TOKEN}
      MONGO_CONNECTION_STRING: mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@ferretdb:27017/
      LITE_LLM_PROXY_BASE_URL: http://litellm:4000
      LITE_LLM_PROXY_API_KEY: ${LITELLM_MASTER_KEY}
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8001/api/v1/health"]
      interval: 30s
      timeout: 10s
      retries: 3
    labels:                              # expose the messaging endpoint through the platform's Traefik
      - "traefik.enable=true"
      - "traefik.http.services.my-bot.loadbalancer.server.port=8001"
    networks: [proxy, backend, data]

networks:
  proxy: { external: true }
  backend: { external: true }
  data: { external: true }
docker compose -f docker-compose.my-bot.yml up -d

Reuse the platform's secrets (from its .env) for the ${…} values, and match the actual network names of your deployment.

Network reference. proxy = external ingress via Traefik (where channel webhooks arrive). data = NATS, FerretDB. backend = LiteLLM. The bot needs no storage network.


What you get

Capability Detail
Channels MS Teams, Slack, and web chat — with channel-specific thread/mention/file/markdown handling
Agent chat AgentChatBot routes a conversation to an agent over NATS and streams the reply back
Direct LLM OpenaiChatBot talks straight to LiteLLM for simple chat-with-a-model endpoints
Streaming Token-by-token updates in the channel (falls back to non-streaming where the channel can't update messages)
Bot-in-the-loop Delivers an agent's question to a human in Slack/Teams and feeds the reply back into the workflow
Conversation state Per-endpoint config + conversation history in MongoDB, with a configurable TTL
Testing BotTestRunner and SimulatedAgentBotTestRunner for capturing outbound activities and faking an agent over NATS

See the documentation for the full handler/streaming/BITL reference.

Links

License

Apache-2.0 — see packages/bot/LICENSE. For the full per-package license matrix, see LICENSES.md.


Part of Swiss AI Hub. Built in Switzerland by bbv Software Services.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

swiss_ai_hub_bot-0.292.2.tar.gz (38.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

swiss_ai_hub_bot-0.292.2-py3-none-any.whl (55.8 kB view details)

Uploaded Python 3

File details

Details for the file swiss_ai_hub_bot-0.292.2.tar.gz.

File metadata

  • Download URL: swiss_ai_hub_bot-0.292.2.tar.gz
  • Upload date:
  • Size: 38.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for swiss_ai_hub_bot-0.292.2.tar.gz
Algorithm Hash digest
SHA256 5fd9593be98a45c6859efd8857e4d6667ebc2beb9fd605def1aa17e5cf014ba1
MD5 3942b046319f596c21674f9646b5abb5
BLAKE2b-256 214a137ad9ea624118650671dbbda67706fa96dd4c7f9721fa9ca0432e94587d

See more details on using hashes here.

File details

Details for the file swiss_ai_hub_bot-0.292.2-py3-none-any.whl.

File metadata

  • Download URL: swiss_ai_hub_bot-0.292.2-py3-none-any.whl
  • Upload date:
  • Size: 55.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.19 {"installer":{"name":"uv","version":"0.11.19","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for swiss_ai_hub_bot-0.292.2-py3-none-any.whl
Algorithm Hash digest
SHA256 5f6784574e50f65aea99ea3fbba5d9b8f62a989fd8f25a327964c492a8a50dd4
MD5 72d583b0948e0d3467595efc236f67b7
BLAKE2b-256 015b4ec8f4654fdf2256d19e7cd91d7ac672bcaafb3d9ab973ae184ba96c3e36

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page