Skip to content

Providers, policy, caps and cost

Artekis's gateway configuration is three documents plus the context models, edited on the pages under Services → Artekis or as files under config/resources/core/com.artek.artekis/ (provider/<name>/config.json, policy/config.json, settings/config.json, context-model/<collection>/config.json). Files hot-reload on a config scan. Configuration is always saved as a whole document: a page reads {revision, config} and writes it back with that revision, so a second editor's stale save is refused and must reload. An unknown key or a wrong type is refused with its path; something that may legitimately not exist yet (the database connection, the secret, a security level, the active provider) is a warning on the page, never a refusal. Every write is an Artekis.Audit log line naming the actor.

6.1 Providers

A provider resource names where model calls go and which model each role uses:

{ "kind": "anthropic", "displayName": "Plant", "endpoint": "https://api.anthropic.com",
  "secret": { "provider": "PlantSecrets", "name": "anthropic-key" }, "dataHandling": "cloud",
  "roles": { "triage":  { "model": "claude-haiku-5-5",  "effort": "low" },
             "writer":  { "model": "claude-sonnet-5-5", "effort": "medium" },
             "analyst": { "model": "claude-opus-5-5",   "effort": "high" } },
  "limits": { "usdPerDay": 10.0 }, "enabled": true }

The same provider on OpenAI's own API:

{ "kind": "openai-compatible", "displayName": "Plant (OpenAI)", "endpoint": "https://api.openai.com/v1",
  "secret": { "provider": "PlantSecrets", "name": "openai-key" }, "dataHandling": "cloud",
  "roles": { "triage":  { "model": "gpt-6-luna",  "effort": "low" },
             "writer":  { "model": "gpt-6.1-sol", "effort": "medium" },
             "analyst": { "model": "gpt-6-astra", "effort": "high" } },
  "reasoningEffort": true, "limits": { "usdPerDay": 10.0 }, "enabled": true }
  • kind is anthropic or openai-compatible (any endpoint speaking the OpenAI chat API: a hosted service or a local server). Other kinds are reserved and refused with the reason on Status.
  • secret names a Secret Provider and a secret in it. An openai-compatible provider may be keyless. The key is read at call time only; it never appears on a page, in a log or in the database.
  • roles — triage (small, cheap classification), writer (digests, Ask, Gateway Health), analyst (Alarm Health, Incident). A new provider starts with the defaults of its kind, as shown in the two examples: an anthropic provider with Haiku 5.5 / Sonnet 5.5 / Opus 5.5, and an openai-compatible provider on OpenAI's endpoint with GPT-6 Luna / GPT-6.1 Sol / GPT-6 Astra and reasoningEffort on. A server that is not OpenAI's (Ollama, vLLM, Azure OpenAI) starts from the OpenAI names too: after Test, each role's model field offers the models that server lists, so pick from those. On anthropic, effort (low…max) is sent only to models that support it; on openai-compatible it is sent as reasoning_effort while reasoningEffort is on, except on a call that carries tools. For Ask on OpenAI's API, set the writer to gpt-5.4 (section 8.4). A playbook may override a role.
  • limits — usdPerDay, tokensPerDay and requestsPerMinute cap the provider's use (the first two per local day).
  • timeoutsSeconds — at the provider's top level, beside roles and limits (not inside limits, which refuses it and names this place): per role, the call timeout in seconds, 1–3600, default 300 — "timeoutsSeconds": {"writer": 900}. On an anthropic provider the answer is streamed: the API sends small keep-alive events while the model thinks, so a firewall or proxy that drops a connection quiet for 20–30 s does not lose long calls. The call timeout then bounds each attempt's whole streamed answer (timeout, not retried; a retry after a connection or server error gets a fresh window). Once the answer has started, 60 s with nothing at all received is a dead connection: a network failure, retried like any connection error, whatever the call timeout. An openai-compatible provider is not streamed: each call waits for the whole answer, so behind such a firewall keep its calls short. Other top-level keys: fallbacks (Anthropic server-side refusal fallbacks, default on); structuredOutput (OpenAI-compatible: the server honours json_schema, default on); reasoningEffort (OpenAI-compatible: send each role's effort as reasoning_effort; unset means off, and a new provider of this kind starts with it on). Switch it off if the server refuses the field (a 400 naming reasoning_effort). enabled defaults to false.

The Providers page adds, edits and deletes providers (the active one cannot be deleted), picks the secret from the Secret Provider's list, and offers Test (a free probe: the endpoint's model list, each role's model checked against it with whether its effort is sent, and for OpenAI-compatible endpoints whether tool calling works) and Test call (one small billable triage call that reports its cost). Changing Kind on a new or edited provider swaps the role models and the endpoint to the other kind's defaults only where you have not edited them.

6.2 Policy

The policy is deny-all by default: an empty list means none.

Key Meaning
activeProvider the provider runs use
maxConcurrentAnalyses runs in flight at once (1–10, default 2); Incident may run one more
read.tagProviders tag providers Artekis may read (* = all). An alarm, tag or history read outside this list is refused, and the run fails saying so
read.excludeTagPaths tag paths (patterns, *) never read, never drafted, never sent anywhere — always wins
read.projects projects whose select-type named queries the named_query grounding tool may run, and where a collection's data shapes may be read from (section 7.6)
read.scriptSources whether a data shape may name a project-library function (script:). Off by default; such a function runs as the gateway (section 7.6)
read.shapeRowCap rows kept per data-shape read, 1,000 to 1,000,000 (default 50,000; Policy page "Data-shape row cap"). A read past it keeps the newest rows and is marked partial (section 7.6)
read.dbConnections database connections named for the record: a name the gateway does not have is warned about at save and Status counts the list. It does not limit named_query, which runs against the connection the named query itself names — limit that with read.projects
outputs.mqttConnections MQTT connections an MQTT output may use
outputs.memoryTagAllowlist path prefixes under which a playbook may write memory tags
outputs.callbackAllowlist package.module prefixes a playbook callback may name
security.readSecurityLevel what a Perspective session needs to see findings (default Authenticated)
security.feedbackSecurityLevel to record a verdict (default Authenticated)
security.adminSecurityLevel to edit playbooks and context models (default Authenticated/Roles/Administrator)
security.documentUploadSecurityLevel to upload or delete documents
security.askSecurityLevel to use Ask (default Authenticated/Roles/Operator)
security.interviewSecurityLevel to start and answer an interview (default Authenticated); saving its drafts needs adminSecurityLevel (1.4.0)
egress.logPrompts how much of each prompt the egress ledger keeps (redacted by default)
egress.redactColumnNames words that mark a named-query column as secret; such columns come back «redacted»

A blank security level means no requirement. The views hide what a session lacks and the gateway checks the same levels again on every call, so a hidden control cannot be driven from a script console. The shipped defaults name roles a gateway may not have (Operator for Ask, Administrator for editing): on a gateway whose user source has no such roles the views show no editing controls and Ask refuses every question. Set the levels to your roles on the Policy page (or blank them for an open demo) right after install. For a verdict or an upload to carry the user's name, the project needs an identity provider (Project Properties → Identity Provider); without one the actor is recorded as session:<project>.

6.3 Settings

dbConnection — the gateway database connection holding the Artekis tables (unset, the module idles); retentionDays — how long runs, egress rows and the evidence of closed findings are kept (default 180, 7–3650); timezone — the zone cron schedules, shift times and daily caps use (default the gateway's; the Settings page offers every region id as a list, issue #304). It is also the plant time every text a person reads is written in: finding text, anomaly cards, Ask answers and refusals, the Status and admin pages and the views' first-seen and last-seen times read Nov 1, 9:20 AM (with the year when it is not this year). Storage, routes, evidence values and the run KPIs stay UTC ISO-8601; the model is given the plant zone with every run and any UTC time it copies into a finding or answer is rewritten to plant time.

6.4 Caps and cost

You bring your own key, so model spend is between you and your provider; Artekis prices every call from a built-in price table (Anthropic's list prices and OpenAI's for gpt-6-astra, gpt-6.1-sol, gpt-6-luna, gpt-5.5, gpt-5.4, gpt-5.4-mini and gpt-5.4-nano; an OpenAI-compatible call is priced by its served model name where a price exists, else by the role's configured model; any other model needs the role's inPerMTok/outPerMTok) and records it on the run. OpenAI's cached input is billed once, at the cache price, and it does not count toward tokensPerDay, as on Anthropic. Before any call, a pre-check prices the worst case — all input plus the full output budget — against the provider's daily caps and the playbook's budget.maxUsdPerRun; a run over either is ended SKIPPED(cap) with both figures, and a model with no price refuses while a USD cap is set. Because the pre-check reserves the full output budget (16,000 tokens, about $0.32 on Opus 5.5), a daily USD cap admits fewer runs than the actual spend suggests; set it with that margin. Daily caps reset at local midnight in the settings timezone, and the [Artekis]System/Provider/<name>/UsdToday and TokensToday tags show the day's running total.

Measured on an acceptance run against a 125,000-event alarm journal and a 19,900-tag provider with a 242-asset context model (Anthropic, default roles):

Run Time Cost
Alarm Health, 30-day window 60–78 s $0.21–$0.45 (Opus 5.5)
Alarm Health, 180-day window 122 s $0.45
Gateway Health, 24 h 16–19 s $0.02
Incident 55 s $0.13
Ask, one turn 13–17 s $0.03–$0.10 (Sonnet 5.5; the first turn of a conversation costs most: its tool results are read once at the input price, then from the prompt cache)
Context-model Suggest pass one writer call $0.006 on a small draft (Sonnet 5.5)

Measured spend is about $0.016 per Alarm Health candidate: a gateway producing 30–50 candidates a day runs $15–24 a month in model calls, a small one a few dollars. The Cost page (Services → Artekis → Cost) shows spend by day, ISO week or month, by playbook and by provider, the month to date with a projection, each provider's caps against today's spend, and any run whose model had no price (counted apart, never as $0). Show prompt on the Test run page is free and leaves no record; Run with the model is a real call, billed and listed in Cost and Egress.