Interfaces
AI assistant
The complete upstream guide to ai assistant, synchronized with the product repository.
Product v0.18.26 · Complete source guide
AI assistant
NineDeploy can ask an AI model about a service: why a build failed, what a running service's logs say, and which .ninedeploy manifest fits an app you describe. It brings no model of its own. The instance operator configures one provider, a model and an API key, and every AI feature uses that configuration.
Providers (0.16.15)
Settings → AI assistant, operator only. The key is sent once, stored encrypted, and never returned by any route.
| Provider | Calls | Base URL | Example models |
|---|---|---|---|
| Claude (Anthropic) | POST <base>/v1/messages, with x-api-key and anthropic-version: 2023-06-01 | Optional; empty means https://api.anthropic.com. A gateway that speaks the Messages API works too. | claude-sonnet-5-5, claude-opus-5-5, claude-haiku-5-5 |
| OpenAI-compatible | POST <base>/chat/completions, with a bearer token | Required: OpenAI, a gateway, or a local Ollama or LM Studio | gpt-4o-mini, llama3.1 |
A configuration saved before 0.16.15 has no provider and keeps working as OpenAI-compatible.
API: GET /v1/ai/config (any signed-in user; no key material, and the base URL for operators only). PUT /v1/ai/config takes { provider?, baseUrl?, model, apiKey? } (operator). SDK: ai.getConfig, ai.updateConfig.
Who may use it
Every call spends the operator's key, so:
- only instance operators and members of a workspace an instance operator owns may use it; a seat in a workspace you created for yourself does not count;
- a diagnosis or a log analysis also needs
memberon the service; - a protected lane's logs are for its admins only (DEPLOYMENTS.md);
- each feature is limited to 10 calls a minute.
What leaves the panel
Logs are sanitized before they are sent:
- ANSI codes are removed;
- passwords in URLs,
Authorizationheaders and bearer tokens are masked; - so is the value of every assignment whose name says it is a credential (
…PASSWORD=,…TOKEN=,…SECRET=,--password, …).
Only the last 16 KB of logs is sent. A failed-deploy diagnosis also sends the current build settings, with the same sanitizer applied to each string before JSON encoding. Credential-bearing settings are excluded from proposed changes, and redaction markers cannot be applied as values. Store secrets in environment variables rather than inline commands. The sanitizer is a safety net: arbitrary unlabeled secrets in your output or settings can still escape its patterns, so choose a provider you trust with this data. Each call is audited (ai.diagnose, ai.analyze_logs, ai.suggest).
Failed-deploy diagnosis
On a failed deployment, Service → Deploys → AI diagnosis sends the build log's tail together with the service's current build settings. The answer has three parts: the root cause, the decisive log lines, and numbered fix steps.
A proposed fix (0.17.0)
The model may also propose a change. The panel validates every proposal; anything outside these limits is dropped before you see it.
- A settings change. Only these fields can be proposed: port, health path, build pack, base directory, install, build and start command, and Dockerfile path. A value equal to the current one is dropped. Lifecycle hooks are never proposed: for a non-operator they run on the host.
- The card shows each setting's current and proposed value.
- Apply and redeploy saves it with the ordinary service update, so every rule of that update still applies (a member cannot pick the static build pack, for example). Then it starts a deploy.
- File edits. Up to five, each an exact text to find in a repository file and its replacement, with the reason. They are shown as a patch to copy into your repository. The panel never writes to your repository.
The model can be wrong, so read the change before you apply it. A model that answers in prose instead of the structured form still gives its diagnosis, with no proposal.
- API:
POST /v1/ai/services/:id/deploys/:depId/diagnoseanswers{ diagnosis, model, parts?, proposal? }. - SDK:
ai.diagnose. - CLI:
ninedeploy deploys diagnose <service> <deployId> [--apply] [--json].
Runtime-log analysis (0.16.15)
On a running service, open Runtime logs on the service page and press Analyze. It sends the newest lines you are looking at (300, 1,000 or 5,000). The answer has three parts:
- Health: healthy, degraded or failing.
- Problems: each one with its log lines quoted and its likely cause.
- Next steps: what to do.
It is told not to invent problems the logs do not show. Still, an analysis can be wrong, so check the quoted lines before acting.
- API:
POST /v1/ai/services/:id/logs/analyzewith{ tail? }(20–5000, default 300).- It answers
{ analysis, model, lines }. 400 not_runningwhen the service has no runtime;400 no_logswhen it has written nothing.
- It answers
- SDK:
ai.analyzeLogs(serviceId, { tail }). - CLI:
ninedeploy logs analyze <service> [--tail <n>] [--json].
Alert investigations
When a service's alert rule fires, the panel can read the service's logs for you. The operator turns this on under Settings → AI assistant → Investigate firing alerts, or with PUT /v1/ai/config { …, "alertInvestigation": true }. A save that leaves out alertInvestigation keeps the stored choice.
What happens when a rule fires
- The newest 300 runtime log lines are read and sanitized as described above.
- They are sent together with the alert, for example
error_rate = 12 (threshold > 5). - The answer is shown under the rule in Monitoring → Alert Rules, with the model and the value the rule fired on. A later firing replaces it.
Limits
- At most 12 investigations an hour across the instance. Each one spends the operator's key.
- Only service rules are investigated. A host-wide rule has no service logs.
- A service in a protected lane is never investigated: alert rules are readable by every member of the service, and its logs are for admins only. An answer from before the service moved into a protected lane is shown only to the lane's admins.
- A stopped service, or one with no logs, is skipped.
- The answer stays in the panel. Notification channels get only the alert itself, never log lines or the answer.
- Each investigation is audited as
ai.alert_investigation. - The answer is stored as the settings row
alert_investigation:<ruleId>; there is no migration. Deleting the rule deletes it.
Manifest suggestions
In the manifest creator, describe the app in plain words and get a .ninedeploy manifest back. The model's answer is checked against the strict manifest schema before you see it, so it cannot add fields that do not exist.
API: POST /v1/ai/suggest-manifest. SDK: ai.suggestManifest.
Source guide (installer links and live inventory counts are normalized for this site): docs/AI.md.