Skip to content

[AISAGE-502] feat(gateway): route gateway traffic via KILO_AI_GATEWAY_URL - #15030

Merged
chrarnoldus merged 4 commits into
mainfrom
feat/kilo-ai-gateway-url
Oct 15, 2026
Merged

chrarnoldus merged 4 commits into
mainfrom
feat/kilo-ai-gateway-url

Conversation

@chrarnoldus

@chrarnoldus chrarnoldus commented Oct 13, 2026 •

Copy link
Copy Markdown
Collaborator

What

Adds a KILO_AI_GATEWAY_URL environment variable that overrides the base URL for AI gateway traffic only. Kilo API traffic (auth, profile, defaults, modes, notifications, tRPC, Exa search) still uses KILO_API_URL.

Which variable wins:

KILO_AI_GATEWAY_URL KILO_API_URL Gateway base
unset unset https://ai-gateway.kilo.ai/api/v1 (new default)
unset set ${KILO_API_URL}/api/gateway/v1
set any ${KILO_AI_GATEWAY_URL}

Every gateway endpoint is a path relative to that base: chat/completions, responses, messages, models, organizations/{id}/models, embeddings, embedding-models, transcription-models, audio/transcriptions, fim/completions, and edit/completions.

Why

Gateway endpoints now live in the separate ai-gateway app, and every route there is under a single /api/v1 root. The old web app split them across /api/openrouter, /api/gateway, /api/fim, /api/edit, and /api/organizations/{id}/models.

Since Kilo-Org/cloud#7420, apps/web has no gateway routes of its own. It rewrites /api/gateway/v1/:path* to the AI gateway's /api/v1/:path*, so ${KILO_API_URL}/api/gateway/v1 works the same as an AI gateway base. Because of that, setting only KILO_API_URL keeps all gateway traffic on that server (for example a local web app), without per-endpoint route mapping.

How

  • @kilocode/kilo-gateway resolves the gateway base in one place (resolveKiloAiGatewayBase, KILO_AI_GATEWAY_BASE). KILO_OPENROUTER_BASE is that base, so the core Kilo plugin, the models catalog api URL, and generate_image pick it up without further changes.
  • resolveKiloGatewayUrl(path) builds endpoint URLs for FIM, next-edit, audio transcriptions, and org model listing.
  • CloudCatalog lists models from the gateway base but still fetches defaults from the Kilo API. Gateway URLs from env vars get the same HTTPS/loopback-only validation as KILO_API_URL.

Things a reviewer should know:

  • Explicit overrides keep their current behavior: a user-configured provider.kilo.options.baseURL and URLs embedded in tokens still route through /api/openrouter and /api/gateway on that URL.
  • With no env vars set, gateway traffic now goes to a new host, ai-gateway.kilo.ai. Networks that only allow api.kilo.ai will need to allow the new host too.

@chrarnoldus chrarnoldus self-assigned this Oct 13, 2026
@github-actions github-actions Bot added area:cli CLI, TUI and core engine area:gateway Kilo Gateway and auth labels Oct 13, 2026
Comment thread packages/kilo-gateway/src/api/url.ts Outdated
if (KILO_AI_GATEWAY_BASE && text === clean(KILO_AI_GATEWAY_BASE).toString().replace(/\/+$/, "")) return `${text}/`
const parts = segments(url)
const api = parts.lastIndexOf("api")
if (api < 0 || parts[api + 1] !== "v1") return undefined

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SUGGESTION: The /api/v1 heuristic matches any base URL, not just the configured gateway

This branch treats any resolved base whose path contains an /api/v1 segment as the AI gateway root, even when it did not come from KILO_AI_GATEWAY_BASE (for example a user-configured provider.kilo.options.baseURL or an embedder baseUrl such as https://proxy.test/api/v1/custom). Those paths are truncated to .../api/v1/, which is not the legacy routing the PR description says explicit overrides keep. Restricting the match to the configured gateway base (as the line above does) would preserve override behavior; if the broader match is intentional, it is worth calling out in the description to avoid surprising custom-proxy setups.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in eae9c90: only the configured AI gateway base (KILO_AI_GATEWAY_URL or the default) is treated as the gateway root. Custom base URLs containing /api/v1 keep the legacy /api/openrouter and /api/gateway routing, with tests covering it.

@kilo-code-bot

kilo-code-bot Bot commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

The incremental commit (7724ac46a5) refactors the gateway base so that when only KILO_API_URL is set, gateway traffic resolves to ${KILO_API_URL}/api/gateway/v1 instead of the removed undefined/legacy-route fallback. I verified the change end-to-end:

  • resolveKiloAiGatewayBase now always returns a concrete base, so KILO_OPENROUTER_BASE = KILO_AI_GATEWAY_BASE and gateway() no longer need the undefined guard; resolve() correctly drops the ?? KILO_API_BASE fallback.
  • The resolveKiloGatewayUrl(path) signature change (dropping the unused legacy arg) is applied consistently at all four call sites (edit.ts, fim.ts, server/routes.ts, httpapi/handlers/kilo-gateway.ts).
  • CloudCatalog.gateway widens the loopback allowance to also cover a KILO_API_URL-derived base, which is required so an http-loopback KILO_API_URL still passes parseServiceOrigin; non-loopback http is still rejected, so no security regression.
  • Tests (url.test.ts, cloud/defaults.test.ts) and the changeset/CONTRIBUTING docs match the new routing.

No memory-leak, lifecycle, or resource concerns are introduced — the diff is pure URL string computation.

Files Reviewed (10 files)
  • .changeset/kilo-ai-gateway-url.md
  • CONTRIBUTING.md
  • packages/kilo-gateway/src/api/constants.ts
  • packages/kilo-gateway/src/api/url.ts
  • packages/kilo-gateway/src/server/routes.ts
  • packages/kilo-gateway/src/types.ts
  • packages/kilo-gateway/test/api/url.test.ts
  • packages/opencode/src/kilocode/cloud/catalog.ts
  • packages/opencode/src/kilocode/server/httpapi/handlers/kilo-gateway.ts
  • packages/opencode/test/kilocode/cloud/defaults.test.ts
Previous Review Summaries (2 snapshots, latest commit eae9c90)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit eae9c90)

Status: No Issues Found | Recommendation: Merge

The incremental commit (eae9c90c52) resolves the previous finding: gateway() now treats only the exact configured AI gateway base (KILO_AI_GATEWAY_BASE) as the gateway root, so custom base URLs, token-embedded URLs, and explicit overrides containing /api/v1 keep the legacy /api/openrouter and /api/gateway routing. The added tests (proxy.test/api/v1/custom → /api/openrouter/, proxy.test/dev/api/v1 → /dev/api/gateway/) match the implementation, and no production caller relied on the removed /api/v1 heuristic.

Files Reviewed (2 files)
  • packages/kilo-gateway/src/api/url.ts
  • packages/kilo-gateway/test/api/url.test.ts

Previous review (commit d749650)

Status: 1 Issue Found | Recommendation: Merge

Overview

Severity Count
CRITICAL 0
WARNING 0
SUGGESTION 1

The routing refactor is consistent across all call sites: legacy KILO_API_URL-only routing, the new gateway default, and the KILO_AI_GATEWAY_URL override all resolve to the expected endpoints, and the HTTPS/loopback validation on the gateway override in CloudCatalog is preserved (defaults stay on the Kilo API). No memory-leak or lifecycle concerns were introduced.

Issue Details (click to expand)

SUGGESTION

File Line Issue
packages/kilo-gateway/src/api/url.ts 40 gateway() treats any base URL containing an /api/v1 segment as the gateway root, including explicit baseURL/embedder overrides, which diverges from the PR's stated "overrides keep legacy routing" behavior; restrict to the configured gateway base or document the broader match.
Files Reviewed (22 files)
  • .changeset/kilo-ai-gateway-url.md
  • CONTRIBUTING.md
  • packages/core/test/plugin/provider-kilo.test.ts
  • packages/kilo-gateway/src/api/constants.ts
  • packages/kilo-gateway/src/api/models.ts
  • packages/kilo-gateway/src/api/url.ts - 1 issue
  • packages/kilo-gateway/src/edit.ts
  • packages/kilo-gateway/src/fim.ts
  • packages/kilo-gateway/src/index.ts
  • packages/kilo-gateway/src/server/routes.ts
  • packages/kilo-gateway/src/types.ts
  • packages/kilo-gateway/test/api/models.test.ts
  • packages/kilo-gateway/test/api/url.test.ts
  • packages/kilo-gateway/test/edit.test.ts
  • packages/kilo-gateway/test/fim.test.ts
  • packages/kilo-indexing/test/kilocode/indexing/embedders/kilo.test.ts
  • packages/opencode/src/kilocode/cloud/catalog.ts
  • packages/opencode/src/kilocode/server/httpapi/handlers/kilo-gateway.ts
  • packages/opencode/test/kilocode/cloud/defaults.test.ts
  • packages/opencode/test/kilocode/server/httpapi-kilo-edit.test.ts
  • packages/opencode/test/kilocode/server/prompt-training-model-filter.test.ts
  • packages/opencode/test/kilocode/tool/generate-image.test.ts

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash · Input: 68.8K · Output: 13.5K · Cached: 897.3K

Review guidance: REVIEW.md from base branch main

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:cli CLI, TUI and core engine area:gateway Kilo Gateway and auth

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants