AI model provider in Topologix
Analytics & Apps
Not a data source — the AI model other features run on. One integration with a vendor selector: Anthropic (Claude), AWS Bedrock (Claude, Amazon Nova, Llama, Mistral in your own AWS account and region), OpenAI (GPT), Azure OpenAI (a model deployed in your own Azure resource), Google Gemini (Google AI Studio key), OpenAI-compatible (a hosted service that speaks the OpenAI API — Groq, Together, Mistral, OpenRouter, a corporate gateway) or Self-hosted (any OpenAI-compatible server on your own hardware — Ollama, vLLM, LM Studio, text-generation-inference; this is the former Local AI integration, folded in). Each organisation then decides in Organisation → AI models which provider serves which job: the monitoring assistant and workflow Agent nodes, the AI assessment of change reports, redaction rule suggestions, trace/cost analysis, and image-to-diagram vision. Every vendor gets the same treatment: native tool use for the assistant, streamed answers, and images for the Vision jobs where the model reads them.
Requirements
- Anthropic: an API key from the Anthropic Console (it starts
sk-ant-). The Topologix server must reachapi.anthropic.comon 443 — or the base URL you set for a gateway that speaks the Anthropic Messages API. - AWS Bedrock: an IAM access key (long-term
AKIA…, or STS temporaryASIA…credentials with their session token) allowedbedrock:InvokeModel(andbedrock:ListFoundationModelsfor List models), with the model enabled under Bedrock → Model access in the region you pick. The Topologix server must reachbedrock-runtime.<region>.amazonaws.com(andbedrock.<region>.amazonaws.comfor the listing) on 443. Requests are signed with AWS Signature Version 4. - OpenAI: a project API key from platform.openai.com → API keys (it starts
sk-proj-). The Topologix server must reachapi.openai.comon 443 (or the base URL of a gateway that speaks the OpenAI API). - Azure OpenAI: an Azure OpenAI resource with a model deployment, its endpoint (
https://<resource>.openai.azure.com) and one of its two keys (Azure portal → the resource → Keys and Endpoint). The Topologix server must reach*.openai.azure.comon 443. Keyless (Entra ID) authentication is not supported yet. - Google Gemini: an API key from Google AI Studio → Get API key (it starts
AIza). The Topologix server must reachgenerativelanguage.googleapis.comon 443. Vertex AI is not supported yet. - OpenAI-compatible (cloud): the service’s OpenAI-compatible base URL (Groq
https://api.groq.com/openai/v1, Togetherhttps://api.together.xyz/v1, Mistralhttps://api.mistral.ai/v1, OpenRouterhttps://openrouter.ai/api/v1) and its key, reachable from the Topologix server. - Self-hosted: an OpenAI-API-compatible endpoint (for Ollama,
http://<host>:11434/v1) reachable from the Topologix server, or from a proxy agent when the model runs on a LAN the server cannot reach (every call is then routed through that proxy). An API key only if your server requires one. - No key yet? Section 3 walks through every vendor click by click — where to sign up, where billing lives, the exact page that mints the key, a one-line test call that proves the key works, and the exact values to paste into the fields here.
- Only organisation owners and admins can create, edit or delete an AI model provider and assign roles; members use what is assigned. A personal account (no organisation) uses its own providers.
- Every credential (API key; for Bedrock the secret access key and session token — the access key id is not secret) is sealed at rest under the organisation’s key, masked in the API and never logged. The redaction engine also ships floor rules for model keys —
anthropic-key,openai-key,google-api-key(Gemini keys) — so a key pasted into a log line or a chat never leaves in clear.
1 · Set up the integration
- Open the Integrations pageClick Integrations in the toolbar and pick AI model provider from the catalogue (Analytics & Apps).
- Pick the vendor tileAnthropic, AWS Bedrock, OpenAI, Azure OpenAI, Google Gemini, OpenAI-compatible or Self-hosted. The fields below the tiles follow the choice.
- Anthropic / OpenAI / Gemini: key and modelPaste the API key (section 3 shows how to create one for each vendor). Leave Base URL blank for the vendor’s own API (Anthropic and OpenAI accept a gateway URL; Gemini has none). Pick a Model from the curated list — e.g.
claude-opus-5,gpt-5.1,gemini-2.5-pro— click List models to load what the key can actually reach, or type any model id. - AWS Bedrock: credentials, region and model idEnter the Access key ID, the Secret access key and — only for temporary credentials — the Session token; pick the Region. Pick a Model id from the curated seeds (Claude on Bedrock, Amazon Nova, Llama, Mistral — seeds, verify them against your region), click List models to load the region’s text models, or type any id. A cross-region inference profile id (
us.anthropic.…,eu.…,apac.…) is typed as free text — newer Claude models are only offered that way. - Azure OpenAI: endpoint and deploymentEnter the Endpoint, the API key and the Deployment name — the name you gave the deployment in Azure AI Foundry, not the model’s name (deployments cannot be listed with a key, so it is typed). API version defaults to
2024-10-21; set a newer one only if your deployment needs it. - OpenAI-compatible: base URL and modelEnter the service’s Base URL (the part before
/chat/completions), its key if it needs one, and the Model id exactly as the service names it (List models asks the service). Allow self-signed TLS is for an internal gateway. - Self-hosted: endpoint and modelEnter the Base URL, the optional key, and pick the Default model (List models asks the server what it has pulled). Route via proxy sends every call through a proxy agent; Allow self-signed TLS, Log analysis max tokens and Context window (tokens) are optional.
- Test, choose roles, createClick Test — a tiny completion (cloud vendors) or a model listing (Self-hosted); a wrong key reads “The OpenAI model rejected the API key (401)” (Bedrock: “The Bedrock model rejected the API key (401)” for an unknown or expired key, 403 for a key without access to the model) — then tick Use this provider for any roles it should serve and click Create.
2 · Add it to a flow
- Open Organisation → AI modelsOne row per role: Assistant (monitoring bot + the org default for workflow Agent nodes), Change assessment, Rule suggestions (redaction), Analysis (trace analysis, cloud-cost estimate) and Vision (image-to-diagram, topology extract).
- Pin or leave automaticEach row is Automatic, a specific provider, or Off. The line under it says what will actually be used and why (“Using Claude prod · claude-opus-5 · chosen by setting”), with the provider’s capability badges — tools (native tool use), vision (reads images and PDFs), streaming — or the sentence naming the fix when nothing can be used. A pinned provider never silently falls back to another one. Available providers lists every candidate with its badges.
- Use itThe monitoring bot’s model picker defaults to Organisation default (Assistant role); workflow Agent nodes offer the same; change reports, rule suggestions and the analysis features follow their roles with no per-feature setting.
3 · Get the key — per vendor, copy-paste ready
One recipe per vendor: the sign-in page, where billing is switched on (every vendor rejects calls until it is), the exact page that mints the key, the IAM / CLI equivalent where one exists, a one-line test call to run before pasting anything into Topologix, and the exact values for the integration’s fields. Replace only the <angle-bracket> placeholders. The test calls are for a bash / macOS / Linux / WSL shell; in Windows PowerShell type curl.exe instead of curl (bare curl is an alias of Invoke-WebRequest there) and set variables as $env:KEY = "…". Create every key under a dedicated service identity or project named topologix, not under a person’s login, so it survives that person leaving.
Anthropic (Claude)
The key is minted in the Anthropic Console and is shown exactly once. Calls fail until the organisation has prepaid credit.
- Sign inOpen console.anthropic.com and sign in (or Sign up — a business e-mail creates an organisation; a personal one creates an organisation named after you).
- Add creditOpen Settings → Billing → Add payment method → then Buy credits (or turn on auto-reload). Without credit every call answers
400 — Your credit balance is too low to access the Anthropic API. Optional: Settings → Limits sets a monthly spend cap. - Optional: a workspace for TopologixSettings → Workspaces → Create workspace, name
Topologix. A workspace gives the key its own usage graph and spend limit; skip it and the key lives in the Default workspace. - Create the keyOpen Settings → API keys → Create Key → name
topologix, workspace Default (or the one from step 3) → Create Key → Copy. It startssk-ant-api03-and cannot be shown again — if you lose it, create another and delete this one. - Test itRun the snippet below with your key. A working key answers with a JSON object whose
content[0].textis a short greeting; a wrong key answers401 authentication_error; an empty balance answers the 400 from step 2. - Paste into TopologixAPI key = the key; Base URL = blank; Model =
claude-opus-5(or click List models and pick). Click Test, tick the roles, Create.
Test the key (the model list, then one 16-token completion)
KEY="sk-ant-api03-…paste…"
curl -s https://api.anthropic.com/v1/models \
-H "x-api-key: $KEY" -H "anthropic-version: 2023-06-01" | head -c 400; echo
curl -s https://api.anthropic.com/v1/messages \
-H "x-api-key: $KEY" -H "anthropic-version: 2023-06-01" -H "content-type: application/json" \
-d '{"model":"claude-sonnet-4-6","max_tokens":16,"messages":[{"role":"user","content":"Say hi"}]}'Values for the integration form
Vendor tile : Anthropic
API key : sk-ant-api03-…
Base URL : (blank)
Model : claude-opus-5 # or claude-sonnet-4-6 (cheaper), claude-haiku-4-5 (fastest)OpenAI (GPT)
Keys belong to a project inside your organisation. The platform needs a payment method and, on a new account, prepaid credit before the API answers.
- Sign inOpen platform.openai.com and sign in. This is the API platform — a ChatGPT Plus / Team subscription does not include API access; the two are billed separately.
- Add billingOpen Settings → Organization → Billing → Add payment details → Add to credit balance (any amount; auto-recharge optional). Without it every call answers
429 insufficient_quota — You exceeded your current quota. Optional: Settings → Organization → Limits sets a monthly budget and alert. - Optional: a project for TopologixSettings → Organization → Projects → Create → name
Topologix. Usage and limits are then tracked per project; otherwise use Default project. - Create the keyOpen API keys → + Create new secret key → Owned by: Service account (survives staff changes; “You” also works) → name
topologix→ Project = the one from step 3 → Permissions: All (or Restricted with Model capabilities = Write and Models = Read, the two Topologix uses) → Create secret key → Copy. It startssk-proj-and is shown once. - Test itRun the snippet. A working key lists models, then answers a completion; a wrong key answers
401 invalid_api_key; a Restricted key without Model capabilities = Write answers401 insufficient permissions for this operation. - Paste into TopologixAPI key = the key; Base URL = blank; Model =
gpt-5.1(or List models). Click Test, tick the roles, Create.
Test the key
KEY="sk-proj-…paste…"
curl -s https://api.openai.com/v1/models -H "Authorization: Bearer $KEY" | head -c 400; echo
curl -s https://api.openai.com/v1/chat/completions \
-H "Authorization: Bearer $KEY" -H "content-type: application/json" \
-d '{"model":"gpt-4.1","max_completion_tokens":16,"messages":[{"role":"user","content":"Say hi"}]}'Values for the integration form
Vendor tile : OpenAI
API key : sk-proj-…
Base URL : (blank)
Model : gpt-5.1 # or gpt-5-mini (cheaper), gpt-4.1 (non-reasoning)Azure OpenAI
Three things are needed and each comes from a different screen: the resource (gives the endpoint and the key), a deployment of a model inside that resource (its deployment name is what Topologix calls), and the key itself. The portal path and an Azure CLI equivalent follow — the CLI block creates everything in one go.
- Create the resource (portal)portal.azure.com → Create a resource → Azure OpenAI → Create. Subscription; Resource group = create
rg-topologix-ai; Region = one where your model is offered (swedencentral,eastus2andwestus3carry the widest catalogue); Name =topologix-openai(becomes the hostname, so globally unique); Pricing tier = Standard S0 → Next → Network: All networks (or add the Topologix server’s IP under Selected networks) → Review + create → Create. Deployment takes about a minute. - Copy endpoint and keyOpen the resource → Resource Management → Keys and Endpoint. Copy KEY 1 and the Endpoint,
https://topologix-openai.openai.azure.com/. (A resource created in Azure AI Foundry showshttps://<name>.cognitiveservices.azure.com/orhttps://<name>.services.ai.azure.com/— paste that host the same way; Topologix appends the/openai/deployments/…path itself.) - Deploy a modelOn the resource’s Overview click Go to Azure AI Foundry portal (or open ai.azure.com and pick the resource) → left menu Deployments → + Deploy model → Deploy base model → search
gpt-4.1(orgpt-5,gpt-4o) → Confirm → Deployment name =gpt-4.1(keep it equal to the model name to avoid confusion; this exact string goes into Topologix), Deployment type = Global Standard, tokens-per-minute limit as offered → Deploy. - Or do steps 1–3 with the Azure CLIRun the CLI block below in a shell with az installed. Change the region if the model is not offered there (
az cognitiveservices model list -l swedencentral -o tableshows what is). The last two commands print the key and the endpoint. - Test itRun the test snippet with the endpoint, deployment name and key. A wrong key answers
401 Access denied due to invalid subscription key; a wrong deployment name answers404 DeploymentNotFound. - Paste into TopologixEndpoint = the host URL; API key = KEY 1; Deployment name =
gpt-4.1(the name from step 3, not the model version); API version = leave2024-10-21. Click Test, tick the roles, Create.
Azure CLI — resource, deployment, key and endpoint in one go
az login
az group create -n rg-topologix-ai -l swedencentral
az cognitiveservices account create -n topologix-openai -g rg-topologix-ai -l swedencentral \
--kind OpenAI --sku S0 --custom-domain topologix-openai
az cognitiveservices account deployment create -n topologix-openai -g rg-topologix-ai \
--deployment-name gpt-4.1 --model-name gpt-4.1 --model-version 2025-04-14 --model-format OpenAI \
--sku-name GlobalStandard --sku-capacity 50
az cognitiveservices account keys list -n topologix-openai -g rg-topologix-ai --query key1 -o tsv
az cognitiveservices account show -n topologix-openai -g rg-topologix-ai --query properties.endpoint -o tsvTest the deployment
ENDPOINT="https://topologix-openai.openai.azure.com"
DEPLOYMENT="gpt-4.1"
KEY="…paste KEY 1…"
curl -s "$ENDPOINT/openai/deployments/$DEPLOYMENT/chat/completions?api-version=2024-10-21" \
-H "api-key: $KEY" -H "content-type: application/json" \
-d '{"max_completion_tokens":16,"messages":[{"role":"user","content":"Say hi"}]}'Values for the integration form
Vendor tile : Azure OpenAI
Endpoint : https://topologix-openai.openai.azure.com
API key : (KEY 1)
Deployment name : gpt-4.1
API version : 2024-10-21 # leave the defaultGoogle Gemini
The key comes from Google AI Studio and is tied to a Google Cloud project. A project without a linked billing account runs on the free tier — low rate limits and Google may use the prompts to improve its products — so link billing before pointing monitoring data at it.
- Sign inOpen aistudio.google.com/apikey with the Google account that should own the key (a Workspace account under your company domain, not a personal Gmail).
- Create the keyClick Create API key → Create API key in new project (or pick an existing Google Cloud project) → Copy. It starts
AIza. AI Studio enables the Generative Language API on that project for you. The key stays visible in the list, so it can be re-copied later. - Switch to the paid tierOpen console.cloud.google.com → Billing → My projects → the project from step 2 → ⋮ → Change billing → pick or create a billing account → Set account. Back in AI Studio the key’s Plan column flips from Free to Paid within a few minutes. Stuck on Free, a busy assistant hits
429 RESOURCE_EXHAUSTEDquickly. - Optional: restrict the keyAPIs & Services → Credentials → the key → API restrictions → Restrict key → tick only Generative Language API → Save. A stolen key then cannot call anything else in the project.
- Test itRun the snippet. A working key lists models and answers the completion; a wrong key answers
400 API_KEY_INVALID(Topologix reports it as 401). - Paste into TopologixAPI key = the key; Model =
gemini-2.5-pro(or List models). Click Test, tick the roles, Create.
Test the key
KEY="AIza…paste…"
curl -s "https://generativelanguage.googleapis.com/v1beta/models" -H "x-goog-api-key: $KEY" | head -c 400; echo
curl -s "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash:generateContent" \
-H "x-goog-api-key: $KEY" -H "content-type: application/json" \
-d '{"contents":[{"parts":[{"text":"Say hi"}]}]}'Values for the integration form
Vendor tile : Google Gemini
API key : AIza…
Model : gemini-2.5-pro # or gemini-2.5-flash (cheaper), gemini-2.5-flash-lite (fastest)AWS Bedrock
No API key here — Topologix signs each request with an IAM access key. You need: the model switched on in one region, an IAM user (or role) allowed to invoke it, and that user’s access key pair. Console clicks first, then the same thing as four CLI commands.
- Pick a region and enable the modelSign in at console.aws.amazon.com/bedrock, set the region in the top-right (
us-east-1has the widest catalogue; pick an EU region for data residency) → left menu Model access (under Bedrock configurations). Most models show Access granted out of the box. If yours shows Available to request, click Modify model access, tick it, Next → Submit. Anthropic models ask for a one-time use-case form (company name, website, intended use) the first time an account requests them; approval is usually immediate. - Create an IAM user (portal)IAM → Users → Create user → name
topologix-bedrock→ leave Provide user access to the AWS Management Console unticked → Next → Attach policies directly → Create policy (opens a tab) → JSON → paste the policy below → Next → nameTopologixBedrockInvoke→ Create policy → back in the user tab, refresh the list, tickTopologixBedrockInvoke→ Next → Create user. - Create the access key (portal)Open the user → Security credentials tab → Access keys → Create access key → use case Application running outside AWS → Next → Create access key → copy Access key (
AKIA…) and Secret access key (shown once; Download .csv file if you want a copy) → Done. - Or do steps 2–3 with the AWS CLIWith aws installed and signed in as an administrator, run the CLI block below. The last command prints
AccessKeyIdandSecretAccessKey. - Test itRun the test snippet with the new pair. The first command lists the region’s text models (needs
bedrock:ListFoundationModels); the second sends one Converse turn.UnrecognizedClientException= wrong key id;InvalidSignatureException= wrong secret;AccessDeniedException= the policy is missing or the model is not enabled (step 1);ResourceNotFoundException= that model id does not exist in this region — copy an id from the first command’s output. - Paste into TopologixAccess key ID =
AKIA…; Secret access key = the secret; Session token = blank (only for temporaryASIA…credentials from SSO oraws sts— they expire, so a monitoring server should use the long-term pair above and rotate it); Region = the one from step 1; Model id = List models and pick, or type a cross-region profile id such asus.anthropic.claude-sonnet-4-5-20250929-v1:0(eu.…in an EU region). Click Test, tick the roles, Create.
IAM policy — TopologixBedrockInvoke (paste into the JSON editor)
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["bedrock:InvokeModel", "bedrock:ListFoundationModels"],
"Resource": "*"
}
]
}AWS CLI — user, policy and access key in one go
cat > topologix-bedrock-policy.json <<'EOF'
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["bedrock:InvokeModel","bedrock:ListFoundationModels"],"Resource":"*"}]}
EOF
aws iam create-user --user-name topologix-bedrock
aws iam put-user-policy --user-name topologix-bedrock --policy-name TopologixBedrockInvoke \
--policy-document file://topologix-bedrock-policy.json
aws iam create-access-key --user-name topologix-bedrockTest the pair (uses the aws CLI so nothing has to be signed by hand)
export AWS_ACCESS_KEY_ID="AKIA…paste…"
export AWS_SECRET_ACCESS_KEY="…paste…"
export AWS_DEFAULT_REGION="us-east-1"
aws bedrock list-foundation-models --by-output-modality TEXT --query 'modelSummaries[].modelId' --output text | tr '\t' '\n' | head -20
aws bedrock-runtime converse --model-id us.anthropic.claude-sonnet-4-5-20250929-v1:0 \
--messages '[{"role":"user","content":[{"text":"Say hi"}]}]' --inference-config '{"maxTokens":16}'Values for the integration form
Vendor tile : AWS Bedrock
Access key ID : AKIA…
Secret access key : …
Session token : (blank — only for temporary ASIA… credentials)
Region : us-east-1
Model id : us.anthropic.claude-sonnet-4-5-20250929-v1:0 # or pick from List modelsOpenAI-compatible (cloud): Groq, Together, Mistral, OpenRouter
Four hosted services that speak the OpenAI chat-completions API. The key page, the base URL to paste and a known model id per service; the same one-line test works for all of them.
| Service | Create the key | Base URL to paste | Model id to start with |
|---|---|---|---|
| Groq | console.groq.com → API Keys → Create API Key → name topologix → copy (gsk_…). Billing: Settings → Billing — the free tier is rate-limited. | https://api.groq.com/openai/v1 | llama-3.3-70b-versatile |
| Together | api.together.ai → Settings → API Keys → Create → copy. Billing: Settings → Billing → Add credits. | https://api.together.xyz/v1 | meta-llama/Llama-3.3-70B-Instruct-Turbo |
| Mistral | console.mistral.ai → API Keys → Create new key → name topologix → copy. Billing first: Billing → Add payment method (keys cannot be created on a workspace without a plan). | https://api.mistral.ai/v1 | mistral-large-latest |
| OpenRouter | openrouter.ai → Settings → Keys → Create Key → name topologix, optional credit limit → copy (sk-or-v1-…). Billing: Settings → Credits → Add credits. | https://openrouter.ai/api/v1 | openai/gpt-4.1 (any id from openrouter.ai/models) |
- Create the key and add creditFollow the row above. Every one of the four refuses calls until the account has a payment method or prepaid credit.
- Test itRun the snippet with the service’s base URL, key and model. The first command lists the model ids the key can use — copy one of those exactly, including the vendor prefix Together and OpenRouter put in front.
- Paste into TopologixBase URL = the column above (the part before
/chat/completions, no trailing slash needed); API key = the key; Model = the id (or List models). Leave Allow self-signed TLS off. Click Test, tick the roles, Create.
Test any OpenAI-compatible service
BASE="https://api.groq.com/openai/v1" # from the table
KEY="…paste…"
MODEL="llama-3.3-70b-versatile"
curl -s "$BASE/models" -H "Authorization: Bearer $KEY" | head -c 400; echo
curl -s "$BASE/chat/completions" -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
-d "{\"model\":\"$MODEL\",\"max_tokens\":16,\"messages\":[{\"role\":\"user\",\"content\":\"Say hi\"}]}"Values for the integration form
Vendor tile : OpenAI-compatible
Base URL : https://api.groq.com/openai/v1
API key : gsk_…
Model : llama-3.3-70b-versatileSelf-hosted: Ollama, vLLM, LM Studio
No vendor account at all — a model server on your own hardware. Ollama is the quickest path; vLLM the fastest on a GPU box; LM Studio the desktop option. Whatever you run, Topologix needs its OpenAI-compatible base URL (it ends in /v1) reachable from the Topologix server or from a proxy agent.
- Ollama — install and pull a modelOn the model host run the first block below. Pick a model that supports tool calling for the assistant (
gpt-oss:120b,qwen3:32b,llama3.3:70b; on a small boxqwen3:8b). The pull is 5–65 GB depending on the model. - Ollama — listen on the networkOllama binds to
127.0.0.1by default. On Linux (systemd) run the second block; on Windows set a user environment variableOLLAMA_HOST=0.0.0.0and restart Ollama from the tray; on macOS runlaunchctl setenv OLLAMA_HOST 0.0.0.0and restart the app. Open TCP 11434 on the host firewall for the Topologix server (or the proxy agent) only. - vLLM (GPU) — one containerThe third block starts vLLM with an API key of your choosing on port 8000; base URL
http://<host>:8000/v1, API key = that token, model = the Hugging Face id exactly as given to--model. - LM Studio (desktop)Load a model → Developer tab (left rail) → toggle Status: Running → in Settings tick Serve on Local Network → note the port (default
1234). Base URLhttp://<host>:1234/v1, no key; the model id is the one shown in the Developer tab. - Test itFrom the Topologix server (or the proxy host) run the fourth block. The first command must list the model; the second must answer.
- Paste into TopologixBase URL =
http://<host>:11434/v1(Ollama) /:8000/v1(vLLM) /:1234/v1(LM Studio); API key = blank unless you set one; Default model = List models and pick. Tick Route via proxy and pick the agent when the model host is on a LAN the server cannot reach. Click Test, tick the roles, Create.
Ollama — install and pull (Linux / macOS; Windows: installer from ollama.com/download, then the same pull)
curl -fsSL https://ollama.com/install.sh | sh
ollama pull qwen3:32b
ollama listOllama — listen on all interfaces (Linux systemd)
sudo mkdir -p /etc/systemd/system/ollama.service.d
printf '[Service]\nEnvironment="OLLAMA_HOST=0.0.0.0"\n' | sudo tee /etc/systemd/system/ollama.service.d/override.conf
sudo systemctl daemon-reload && sudo systemctl restart ollamavLLM — OpenAI-compatible server on a GPU host
docker run -d --name vllm --gpus all -p 8000:8000 --ipc=host \
-v ~/.cache/huggingface:/root/.cache/huggingface \
vllm/vllm-openai:latest --model Qwen/Qwen2.5-7B-Instruct --api-key topologix-local --enable-auto-tool-choice --tool-call-parser hermesTest from the Topologix server (Ollama shown; swap host, port and key for vLLM / LM Studio)
BASE="http://<model-host>:11434/v1"
curl -s "$BASE/models" | head -c 400; echo
curl -s "$BASE/chat/completions" -H "content-type: application/json" \
-d '{"model":"qwen3:32b","max_tokens":16,"messages":[{"role":"user","content":"Say hi"}]}'Values for the integration form
Vendor tile : Self-hosted
Base URL : http://<model-host>:11434/v1
API key : (blank) # vLLM: the --api-key token
Default model : qwen3:32b
Route via proxy : (only if the host is on a LAN the Topologix server cannot reach)
Context window : (blank = auto: the model's max, capped at 65 536)4 · Roles and the automatic order
With no pin, each role walks its own order and takes the first provider that is enabled, belongs to an active member of the organisation, and has the capability the role needs.
The five automatic orders
“Provider” means the organisation’s cloud AI providers (oldest first); “platform” the Topologix Admin key; “self-hosted” the organisation’s own self-hosted models.
| Role | Automatic order |
|---|---|
| Rule suggestions | self-hosted → provider → platform (text stays on your hardware when you run a model) |
| Assistant | provider → platform → self-hosted |
| Change assessment | provider → platform → self-hosted |
| Analysis | provider → platform → self-hosted |
| Vision | provider with vision → platform |
Capabilities per vendor
Vision only offers providers whose models read images. Anthropic, OpenAI (current GPT-4o / 4.1 / 5 / o-series models), Azure OpenAI and Gemini are treated as vision-capable; on AWS Bedrock it follows the model family (Claude, Amazon Nova Lite / Pro / Premier, Llama 3.2 11B / 90B and Llama 4, Pixtral — not Nova Micro, Mistral Large or the text-only Llamas); an OpenAI-compatible service and a self-hosted model are not assumed to be. Every cloud vendor uses native tool calling for the assistant; Gemma models served by the Gemini API have none and answer structured jobs as JSON in text. On Bedrock, tool support is probed once per region and model (a model family Bedrock says “doesn’t support tool use” is remembered for 30 minutes) and such a model answers the same way; answers from Bedrock arrive whole rather than streamed. A model that refuses a parameter (a reasoning model rejecting temperature or max_tokens) is retried once without it.
The platform Claude key
The Anthropic key a Topologix administrator sets in Admin → System settings is a legacy fallback. It is offered to an organisation only while that organisation has no cloud AI provider of its own, and only where the administrator allows it (Admin → System settings → Organisations — platform AI key). Once an organisation adds a provider, the platform key disappears from its picker. On the platform key each role runs on its own model: the Assistant and Change assessment on claude-opus-5, Analysis, Vision and Rule suggestions on claude-sonnet-4-6. A provider your organisation creates always uses the model configured on it. Where the licence carries an AI pack, the platform key serves up to that many model requests a month per organisation and is then skipped until the next month (your own providers take over; with none, the request is refused with ai_pack_exhausted) — see the Licensing guide, “AI packs”.
5 · What leaves your network
Anthropic
The prompt of the job — evidence packs, chat turns, the change-evidence pack, the sample you paste into a rule suggestion — goes to api.anthropic.com after your organisation’s redaction rules have run over it. Anthropic’s API data-retention terms apply: privacy.anthropic.com.
AWS Bedrock
The prompts go to bedrock-runtime.<region>.amazonaws.com in the region you picked, in your own AWS account, after redaction. Bedrock does not store prompts or responses or use them to train models, and data stays in that region — except with a cross-region inference profile (us. / eu. / apac. ids), which may process the request in another region of the same geography: docs.aws.amazon.com — Bedrock data protection. A least-privilege policy: {"Version":"2012-10-17","Statement":[{"Effect":"Allow","Action":["bedrock:InvokeModel","bedrock:ListFoundationModels"],"Resource":"*"}]} (narrow Resource to the foundation-model and inference-profile ARNs you use).
OpenAI
The same prompts go to api.openai.com (Chat Completions), after redaction. OpenAI does not train on API data by default and keeps API inputs and outputs for up to 30 days for abuse monitoring; zero-data-retention is available on request for eligible endpoints: platform.openai.com/docs/guides/your-data.
Azure OpenAI
The prompts go to your own resource at <resource>.openai.azure.com and are processed in the region (or data zone) of your deployment, under your Azure agreement; Microsoft does not use them to train models, and abuse-monitoring retention can be turned off by approved customers: learn.microsoft.com — data, privacy and security for Azure OpenAI.
Google Gemini
The prompts go to generativelanguage.googleapis.com (the Gemini API), after redaction. On a paid (billing-enabled) Cloud project Google does not use prompts or responses to improve its products; on the free tier it may — use a paid project for monitoring data: ai.google.dev/gemini-api/terms.
OpenAI-compatible (cloud)
The prompts go to the base URL you entered, from the Topologix server, after redaction; that service’s own terms apply (Groq, Together, Mistral and OpenRouter each publish theirs). Use the Self-hosted tile instead when the endpoint is inside your network and should be reached through a proxy agent.
Self-hosted
Nothing leaves your network: calls go to your server, directly or through the bound proxy agent (proxy ≥ 1.72.0 for tool use). Self-hosted providers also power the knowledge-base embeddings picker and the per-source Graylog Analyze with AI picker. Tool use is auto-detected per model (Ollama’s /api/show capabilities, else a one-token probe) — a model without tools falls back to a single grounded answer.
Context window (tokens). What Topologix sends to Ollama as num_ctx for the assistant, Forensics Ask, Alerts Explain and the daily digest. Leave it blank for auto: the model’s maximum as Ollama reports it (/api/show, through the bound proxy when there is one — proxy ≥ 1.272.0), capped at 65 536; 32 768 when the maximum cannot be detected (vLLM, LM Studio, an older proxy). A value of your own may be 4 096 up to the model’s maximum (1 048 576 when unknown). The form shows the detected maximum, the effective window and whether it is auto or custom (Detect asks again). Bigger is not free: the window is GPU memory (the KV cache), and Ollama reloads the model when it changes. Cloud models use their vendor’s known window (Claude 200k, GPT-4o 128k, Gemini 1M, …) — shown read-only, nothing to set.
6 · The monitoring bot’s tools
With a provider that supports tool use, the monitoring bot (the Assistant role) does not only read the evidence pack of the flow — it calls read-only tools to look things up itself. The registry holds 29 tools — at most 18 without Linux hosts carrying the host agent (the host tools are offered only for those); each is offered only when at least one integration that can answer it is in scope, so a typical flow shows 8–12. Several independent calls in one turn run in parallel. The method the bot follows: identify what was named (resolve_entity), look for changes and events in the incident window before metrics, size the symptom with metrics, traces and logs, and only then confirm with a live device or database read. Every tool answers with a coverage list — which sources were searched, which were not and why (searched:false + a reason), and from when each holds data — so “no event found” is never claimed beyond what was read. A source that is not configured, too old or refused is reported as such, never as zero.
The core tools
“Live” means the read goes to the source (or through its proxy) at question time and spends a slot of the live budget below; everything else reads what Topologix already stores.
| Tool | What it reads | Backends / adapters |
|---|---|---|
resolve_entity | Identifies anything named — a host, VM, Kubernetes node or pod, service, IP or MAC — across the organisation, with what it runs on and (with hops 1–3) what depends on it. “worker04” returns every cluster’s worker04. | Catalogue, flow canvas, the infra map (node → VM → ESXi host → vSphere cluster → vCenter, pods, BMCs), address inventories, stored ISE sessions (live by-IP lookup as fallback), blast radius (≤ 40 dependents) |
search_events | Events org-wide — the first call for “did X restart / crash / change”. | Stored: vcenter (guest crash, reset, HA restart, reboot, power, vMotion, host disconnect), finding (hypervisor findings), alert transitions, change records, activity (audit log), trap (SNMP traps), ad (Active Directory). Live, only with an entity or when named in sources: k8s (node conditions + Node / pod events), dynatrace (problems + events), zabbix (problems) |
what_changed | What changed around an entity or service (or org-wide) in the last N hours (default 24, max 168). | Change records, audit log, service timeline, alert transitions, VM / host reconfigure, vMotion, power and snapshot events |
get_open_problems | What is wrong right now — the Alerts page as the flow owner sees it, with this flow’s counts. | Open problems (always offered) |
search_logs | Error + warning fingerprints with counts, newest samples and level counts for a service, host, pod, text or trace id (default errors; level:"all" shows whether a service logs at all). | Graylog (live), Elasticsearch / OpenSearch (live, one absolute search; text alone = a fleet search with exact per-host counts), OpenTelemetry logs, Aria Operations for Logs (live, one call), syslog receiver, Kubernetes pod logs (live; pod = ns/pod[/container], previous:true = the crashed container, ≤ 500 lines), Zabbix log items (live; a host by name / IP / VM name, one read ≤ 1000 lines, text filtered after the read and said) |
get_traces | Recent traces of a service and latency over all of them against the usual for this weekday + hour (DEGRADED / USUAL_FOR_HOUR), or one trace id. | Zipkin (live), OpenTelemetry span buffer, Dynatrace (live; spans need a platform token), Elastic APM (live) |
get_metric_history | One series over 24 h – 90 d against its seasonal profile. | Stored history (its former PromQL expr still answers for one release — an alias of query_prometheus, no longer advertised) |
query_prometheus | Prometheus / SigNoz directly, for what the catalogue does not model — the Kubernetes control plane (apiserver, etcd, scheduler), node exporter, any scraped job: discover:"jobs" lists the scraped jobs (≤ 200), discover:"metrics" with a job (+ a substring match) lists its metric names (≤ 300; the job goes into an escaped {job="…"} matcher, one line ≤ 200 chars), then an expr over from / to (honoured; or range 1h – 7d) with an optional step. With more than one Prometheus / SigNoz in scope, integration names which. | Prometheus or SigNoz (live; each call is one slot of the live budget; the expression one line ≤ 500 chars, ≤ 7 d, ≤ 300 steps, ≤ 10 series). SigNoz’s label-values API is not verified yet — discovery may come back empty there while expr works |
fetch_data | The current metrics of one monitored entity of the flow. | The entity’s own integration (live) |
db_diagnostics | Which statement is slow or loads a database, and who is blocking whom right now. | Modes statements (live), trace_statements (SQL per trace), blocking and activity (live; Postgres, SQL Server, SAP HANA) |
network_flows | NetFlow / IPFIX / sFlow peers of an address or service (top 30). | The flow store of the organisation’s exporters |
host_vitals | The current vitals of a host or VM from Zabbix — by host name, IP or vCenter VM name: a VM answers its in-guest fields only (filesystems, swap, load; vCenter has the rest), a server nothing else covers the full set (CPU, memory, swap, load, network, filesystems, disks, uptime, cores), with the sample’s age, and — once the host has a Zabbix baseline — “usual for <weekday hour>: median (p10–p90)” per value with a usual / UNUSUAL / not-enough-weeks verdict, and the host’s software from the daily Zabbix inventory (up to 20 products, where each was found); a host read elsewhere (host agent, Server Vitals, ESXi) says where to look. | Zabbix fleet vitals (stored; offered when a Zabbix integration has Fleet vitals on) |
get_firewall_drops | Rule-level drops of a firewall against the usual, DoS drops, a deny-log sample. | Stored drops; refresh / include_deny_log are live |
recap_resolve | Whether an error is a known RECAP incident, with its post-mortem. | RECAP (live) |
search_knowledge | The organisation’s uploaded configs, service descriptions and runbooks. | Knowledge base |
run_device_diagnostic | A fixed read-only SSH diagnostic on a network device or Linux host (interface counters, LLDP neighbour, MAC / ARP entry, queue drops, CPU, recent log). | SSH CLI (live) — offered only to people who can edit the flow |
Scope — whose data the bot sees
The bot always acts as the flow’s owner, with no role — never as the person asking. A super-admin chatting on a customer’s flow therefore sees exactly the customer’s data, and nothing of another organisation is ever read. Within that tenant, search_events, what_changed, get_open_problems and resolve_entity search organisation-wide by default (every integration the owner’s catalogue holds: their own and the ones shared with the organisation) — a crash on a VM that is not wired into the flow is still found. search_logs, get_traces, fetch_data and get_metric_history look at the flow’s own entities and services first. Every tool takes scope:"flow" or scope:"org" to narrow or widen that.
Live reads — budget, timeouts and audit
Live reads are allowed for anyone who can open the flow, viewers included, under these limits:
- 30 live reads per answer (each chat turn; Admin → System → “AI: live reads per answer”, 1–60), shared by every live tool and every live adapter. When the budget is spent the bot is told to answer from what it already has, list the live reads it could not make and say that a follow-up message (“continue”) starts a fresh allowance — the panel shows the meter (“Live reads 30/30”) and a Continue investigation button.
- One live read at a time per answer (parallel store reads are unaffected).
- Durable answers: a diagnosis keeps running when the browser’s connection drops (a phone in the background, a gateway timeout) — the server keeps its answer for 30 minutes and the panel, showing “Connection dropped — waiting for the answer…”, picks it up as soon as it can, also after a reload.
- Each read has a timeout: 30 s by default, 60 s for
fetch_data,recap_resolve,db_diagnostics, PromQL ranges, pod logs and the livesearch_eventssources, 90 s for SSH diagnostics and live firewall reads. - Every live read writes an audit row (Activity):
bot.live_callwith the tool, source, integration, outcome and duration; database reads writedb.blocking/db.activitywith the database and engine; SSH writesssh.diagnostic. The bot’s own reads never show up as “changes” insearch_eventsorwhat_changed. - SSH stays edit-only:
run_device_diagnosticis not offered to view-only collaborators. - A too-old proxy is checked before the budget — the answer says “needs proxy X or later — update the proxy” and costs no slot.
Proxy versions per capability
Server-direct integrations get every capability with the server. Integrations polled through a proxy agent need:
| Capability | Proxy |
|---|---|
vCenter guest-crash / reset / HA-restart events (collected into search_events) | 1.217.0 |
db_diagnostics blocking / activity; ISE user-of-an-IP lookup; Elastic APM transactions and single traces | 1.220.0 (older: Elastic falls back to the p95 preset; a HANA blocking read falls back to its lock-wait kind) |
| Kubernetes pod logs and node conditions, PromQL range, Zabbix problems | 1.221.0 |
PromQL discovery (query_prometheus discover; its expr needs only 1.221.0) | 1.263.0 |
| Dynatrace problems | any — but before 1.221.0 only open problems of the last 24 h come back (the coverage says partial) |
Kubernetes RBAC
The cluster token needs, on top of what the Kubernetes integration already reads: get pods/log (pod logs), list nodes (node conditions) and list events (Node events cluster-wide; pod events are namespaced). A missing verb is reported in the coverage with the verb it needs (searched:false), not hidden — node conditions still answer when only events are refused. The k8s source of search_events reads at most 2 clusters and 2 pods per call.
Database permissions for blocking / activity
The reads are fixed catalogue SELECTs (never text from the model), one connection, row-capped at 20 sessions, with statement text normalised (literals → ?) and redacted.
- PostgreSQL:
pg_monitor(orpg_read_all_stats) on the monitoring role — without it other users’ sessions show no query text. Readspg_stat_activity,pg_blocking_pids()and ungrantedpg_locks. - SQL Server:
VIEW SERVER STATE(the DMVssys.dm_exec_sessions/dm_exec_requests/dm_tran_locks), read at READ UNCOMMITTED. A sleeping head blocker with an open transaction is included. - SAP HANA:
MONITORING(orCATALOG READ) forM_ACTIVE_STATEMENTS,M_CONNECTIONS,M_TRANSACTIONSandM_BLOCKED_TRANSACTIONS; blocking reuses the lock-wait read.
SSH diagnostics per platform
Seven fixed diagnostics, each a read-only command checked by an allowlist (no configuration mode, no diagnose / execute, Linux through an exact command allowlist with a shell-metacharacter sweep). Coverage: Cisco IOS / IOS-XE, Junos and Linux all seven; NX-OS and Arista EOS six (no queue-drop read); Linux uses ip, lldpcli, bridge, tc, ps / ss, journalctl; Cisco ASA four (interface, ARP, CPU, log); FortiOS three (NIC, ARP, performance). A platform without an equivalent is reported unsupported, not empty. Linux is not auto-detected (detection reads show version): set Platform to linux on the SSH integration by hand.
Backend notes
What the coverage lines and the bot’s answers lean on:
- Absence at coarse polling is not absence. A node count that stays 11 → 11 at 5-minute polls does not rule out a 90-second NotReady; the bot is told to state the polling interval and search events instead, and node conditions show transitions shorter than a poll.
- Dynatrace spans need a platform token on the integration; without one
get_tracesreports the gap in its coverage and reads nothing (problems and events work with the environment API token). - Aria Operations for Logs: text matching is
CONTAINSonly, and eachsearch_logsmakes one call. A parked or empty credential is reported as an error without a call, and two failures in a row stop the bot retrying. - Elasticsearch / OpenSearch: every
search_logsread is ONE search over an absolute window, on the flow node's stamp, the flow's Errors-per-service source or the integration's defaults (index patterns, field mapping); a service / host / trace id is matched exactly (a.keywordretry rides in the same live slot). Text alone counts the matching lines per host exactly (the busiest 20 and the rest) with the newest 20 lines. Through a proxy older than 1.265.1 the search is not sent and costs no slot. - Live
search_eventssources (k8s, Dynatrace, Zabbix) run only when an entity is named or the source is listed insources; otherwise their coverage says “live — read only with an entity”. - All tool output passes the organisation’s redaction rules before it reaches the model, as the evidence pack does. The tool list the model sees is sized to the model’s context window: under 10 000 characters (at most 29 tools) below 32k tokens, 16 000 at 32k or more, 24 000 (at most 40 tools) at 64k or more — every cloud model, and a self-hosted model on auto whose maximum is 64k or more. A list over its budget sheds parameter hints first, never a tool. A self-hosted answer whose conversation came within 10 % of the window ends with a note (“This answer may have lost early context…”): Ollama drops the oldest part of a longer prompt — the instructions and the evidence — without saying so; raise Context window (tokens) on the AI integration or use a larger model.
Export and share an analysis
Every finished answer has two small buttons on its footer, PDF and Email. Both use the server’s own copy of that answer — the panel names the answer by its id and sends no text — and the question you asked is never included: not in the PDF, not in the e-mail, not in the file name.
- The PDF (A4): the flow, when the answer was given (UTC), who shared it, the model and provider, live reads used, the tools called; the hypothesis ledger with confidence; the answer itself (headings, lists, tables, code); each evidence step with its chart; the timeline. Every page footer says “the question asked is not included”. The file is named
topologix-analysis-<flow>-<yyyymmdd-hhmm>.pdf. - Email sends that PDF as an attachment, with the answer in the message, to people you pick from the flow’s owner and the people it is shared with (those with an e-mail address). If you can edit the flow you see their e-mail addresses; a view-only user picks them by name. You cannot type an address or add a note. At most 10 recipients per send and 10 sends per person per hour; each recipient gets their own message. It needs SMTP (Admin → System → SMTP).
- Only addresses in your organisation’s e-mail domains. The domains are the organisation’s e-mail domain (Organisation settings) plus the domains allowed for its Microsoft Entra sign-in; the organisation is the flow owner’s. A colleague is offered — and the server re-checks every recipient on send — only when the part of their address after the last
@is exactly one of those domains (upper / lower case and a trailing dot do not matter). There is no subdomain wildcard: withexample.comset,ops.example.comaddresses are not offered — add that domain too. People outside the domains are not listed even when the flow is shared with them. A flow whose owner has no organisation, or whose organisation has no domain, cannot be e-mailed: the dialog says “E-mail sharing needs the organisation’s e-mail domain — an organisation admin sets it in Organisation settings.” The PDF download is not affected. - Only the person who asked can download or send an answer. View-only collaborators can export their own answers. Answers given before client 1.366.0 show the buttons disabled.
- Retention: the server keeps each finished answer for 30 days by default (Admin → System → Background workers → “AI: keep bot answers for export”, 1–365) and prunes older ones once a day; exporting an older answer says “This answer is past the retention period”. Deleting the flow deletes its stored answers.
- Audit: every download writes
bot.answer.pdfand every send writesbot.answer.emailto Activity — who, the flow, the answer’s id, the recipients’ ids and the size. - The flow’s redaction rules are applied again to everything that goes into the PDF and the e-mail.
- What this does not prevent: the answer is the model’s own text. If someone asks the bot to repeat something in its answer, that text can end up in the export. It still reaches only the flow’s owner and the people it is shared with, and every send is recorded in Activity.
Good to know
- Existing Local AI integrations were migrated in place to AI model providers with the Self-hosted tile — same id, same sealed key, same proxy routing; the embeddings and log-analysis pickers keep finding them.
- An organisation that had pinned its rule-suggestion assistant (Local AI / Claude) keeps that choice as the Rule suggestions role.
- Token counts and latency are shown as “—” when the vendor did not report them — never as 0.
Related guides
See it on your own infrastructure
Book a demo and we will walk you through Topologix with your systems in mind: on our cloud, or self-hosted in your own network.