Skip to content

feat: add Kilo as a native provider#13765

Open
Nomadcxx wants to merge 1 commit intoanomalyco:devfrom
Nomadcxx:feat/kilo-provider
Open

feat: add Kilo as a native provider#13765
Nomadcxx wants to merge 1 commit intoanomalyco:devfrom
Nomadcxx:feat/kilo-provider

Conversation

@Nomadcxx
Copy link

@Nomadcxx Nomadcxx commented Feb 15, 2026

What does this PR do?

Adds Kilo as a built-in provider. Kilo's gateway is OpenAI-compatible, so this mostly wires up model discovery and auth — no new SDK needed.

The main thing: models are fetched dynamically from api.kilo.ai/api/gateway/models at startup, so users don't need to manually configure models in opencode.json. Select Kilo from the provider list, enter your API key, and all available models show up.

Changes:

  • provider.tsfetchKiloModels() hits the Kilo models endpoint, maps pricing/capabilities/limits to opencode's schema. Kilo entry is always injected into the database (even before auth) so it appears in the provider list. Models populate once authenticated.
  • auth.ts — Kilo in CLI auth login flow with priority and info message
  • dialog-provider.tsx — Kilo in TUI provider dialog with priority and description
  • provider.test.ts — 7 tests covering dynamic model loading, error handling, and config-based setup

Fixes #13767

How did you verify your code works?

  • Full test suite passes (985 pass, 5 skip, 0 fail)
  • Typecheck passes (all 12 packages)
  • Tested against live Kilo Gateway — 346 models fetched, chat completions working

@github-actions
Copy link
Contributor

Thanks for your contribution!

This PR doesn't have a linked issue. All PRs must reference an existing issue.

Please:

  1. Open an issue describing the bug/feature (if one doesn't exist)
  2. Add Fixes #<number> or Closes #<number> to this PR description

See CONTRIBUTING.md for details.

@github-actions
Copy link
Contributor

The following comment was made by an LLM, it may be inaccurate:

Potential Duplicate Found

PR #5709: feat: api.kilo.ai/api support
#5709

Why it might be related: This PR appears to address Kilo support, potentially overlapping with the current PR #13765 which adds Kilo as a native provider. Both seem to be related to integrating Kilo API support, though the current PR appears to be a more comprehensive native provider implementation.

Please verify if PR #5709 is a duplicate, merged, or an earlier iteration that this PR supercedes.

@Nomadcxx
Copy link
Author

Technically this is a backport, Kilo cli forked opencode, so we're just bringing the family back together here.

@Nomadcxx Nomadcxx marked this pull request as ready for review February 15, 2026 21:24
@micuintus
Copy link

I used a different approach by directly integrating the package from Kilo: #13863

@Nomadcxx
Copy link
Author

@micuintus this is a good approach but it's importing 30 plus files via @kilocode/kilo-gateway. The approach above just follows github copilot enterprise syntethic database injection method, there are zero dependencies and we get dynamic model listing and we have full integration with auth flow all at around 160 lines (350 lines of tests).

Kilo's gateway is openai-compatible and returns models in openrouter format so the integration is really just plumbing, not a package import. Happy to discuss further if the maintainers have a preference either way.

I agree though that a plugin is not the right answer here, this is a very simple addition to opencode versus bloated and rushed npms from #13826 #13531 .. I think one of them even hardcodes models right in there..

The last thing opencode needs is this level of fragmentation.. what can be incorporated simply without adding bloat should be.. 30x vibe coded pluggins are not the solution IMO.

@Nomadcxx
Copy link
Author

rekram1-node this is an easy one mate.

@Daltonganger
Copy link

I support @Nomadcxx in this. I even made a models.dev update that's accepted for importing Kilo models, so its always flexibel and not needed to import in opencode.json as some do. See anomalyco/models.dev#928

@smetanokr
Copy link

currently bugged:

ERROR 2026-02-17T16:18:04 +1ms service=default e=ProviderInitError rejection
INFO  2026-02-17T16:18:04 +0ms service=server status=completed duration=1 method=GET path=/session/ses_3939b01deffe0mMFhOrhMvXXU5/diff request
INFO  2026-02-17T16:18:04 +75ms service=provider status=completed duration=117 providerID=kilo getSDK
ERROR 2026-02-17T16:18:04 +1ms service=session.processor error=ProviderInitError Caused by: fn3 is not a function. (In 'fn3({
            name: model.providerID,
            ...options2
          })', 'fn3' is undefined) stack="ProviderInitError: ProviderInitError\n    at getSDK (src/provider/provider.ts:1132:17)\n    at processTicksAndRejections (native:7:39)" process
INFO  2026-02-17T16:18:04 +0ms service=bus type=session.error publishing
image

@rekram1-node
Copy link
Collaborator

I don't have a kilo account so I cannot test these things but Ill leave some notes.

opencode: "(Recommended)",
anthropic: "(Claude Max or API key)",
openai: "(ChatGPT Plus/Pro or API key)",
kilo: "(Kilo subscription)",
Copy link
Collaborator

Choose a reason for hiding this comment

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

We don't want to add this as a recommended provider.

Comment on lines 228 to 236
) : props.providerID === "kilo" ? (
<box gap={1}>
<text fg={theme.textMuted}>
Use your Kilo subscription to access 340+ AI models through a single API key.
</text>
<text fg={theme.text}>
Get your key at <span style={{ fg: theme.primary }}>https://kilo.ai</span>
</text>
</box>
Copy link
Collaborator

Choose a reason for hiding this comment

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

don't need this, dont want to add as a recommended provider.

google: 4,
openrouter: 5,
vercel: 6,
kilo: 7,
Copy link
Collaborator

Choose a reason for hiding this comment

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

don't want to add as recommended provider

opencode: "recommended",
anthropic: "Claude Max or API key",
openai: "ChatGPT Plus/Pro or API key",
kilo: "kilo.ai subscription",
Copy link
Collaborator

Choose a reason for hiding this comment

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

don't want to add as recommended provider

Comment on lines 372 to 374
if (provider === "kilo") {
prompts.log.info("Get your API key at https://kilo.ai — requires a Kilo subscription")
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

don't want to add as recommended provider

Comment on lines 134 to 153
async function fetchKiloModels(
apiKey: string,
): Promise<Record<string, z.infer<typeof Model>>> {
const log = Log.create({ service: "provider.kilo" })
const url = "https://api.kilo.ai/api/gateway/models"
try {
const response = await fetch(url, {
headers: {
Authorization: `Bearer ${apiKey}`,
},
signal: AbortSignal.timeout(10_000),
})
if (!response.ok) {
log.error("Kilo models fetch failed", {
status: response.status,
})
return {}
}
const json = (await response.json()) as { data?: KiloApiModel[] }
const models: Record<string, z.infer<typeof Model>> = {}
Copy link
Collaborator

Choose a reason for hiding this comment

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

do we need this? If the models are in models.dev

Note that Im adding the dynamic model fetching this week for all the primary providers, I dont think we need this one...

Comment on lines 898 to 917
// Add Kilo provider — always visible in provider list for auth flow,
// models populated dynamically when API key is available
database["kilo"] = {
id: "kilo",
name: "Kilo",
source: "custom",
env: ["KILO_API_KEY"],
options: {},
models: {},
}
const kiloAuth = await Auth.get("kilo")
const kiloApiKey =
Env.get("KILO_API_KEY") ??
(kiloAuth?.type === "api" ? kiloAuth.key : undefined)
if (kiloApiKey) {
const kiloModels = await fetchKiloModels(kiloApiKey)
if (Object.keys(kiloModels).length > 0) {
database["kilo"].models = kiloModels
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Believe this is in models.dev

Comment on lines +680 to +688
kilo: async () => {
return {
autoload: true,
options: {
baseURL: "https://api.kilo.ai/api/gateway",
headers: {
"HTTP-Referer": "https://opencode.ai/",
"X-Title": "opencode",
},
Copy link
Collaborator

Choose a reason for hiding this comment

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

ig this is fine

@Nomadcxx
Copy link
Author

Nomadcxx commented Feb 17, 2026

Thanks for the review @rekram1-node makes total sense to not elevate Kilo as a recommended provider. I'll strip all the auth.ts and dialog-provider.tsx changes.

On fetchKiloModels() and the database injection — the reason I added those is that models.dev currently points Kilo to npm: "opencode-kilo-auth" (the JungHoonGhae plugin). That package isn't in BUNDLED_PROVIDERS and doesn't export a standard create* function, so getSDK() falls through to BunProc.install → dynamic import → fn3 is not a function. That's the exact error @smetanokr is reporting above and I get the same error with models.dev approach just merged from @Daltonganger.

The CUSTOM_LOADERS entry (which you flagged as fine) adds baseURL and headers, but it doesn't override api.npm on individual models — so the broken npm path persists.

I think the cleanest fix is:

  1. Fix models.dev to use npm: "@ai-sdk/openai-compatible" (or remove the npm field entirely so it hits the fallback) — I can open a PR there
  2. Strip this PR down to just the CUSTOM_LOADERS entry

That way models.dev provides the model catalog, CUSTOM_LOADERS provides the SDK wiring, and it all works without fetchKiloModels(). If you're adding dynamic model fetching for all primary providers this week, Kilo would get that for free too.

Want me to go that route?

Add CUSTOM_LOADERS entry for Kilo gateway with:
- baseURL pointing to api.kilo.ai/api/gateway
- HTTP-Referer and X-Title tracking headers
- autoload enabled for automatic provider registration

Kilo gateway is OpenAI-compatible, serving 340+ models.
Models catalog provided by models.dev.

Closes anomalyco#13767
@Nomadcxx
Copy link
Author

Updated — stripped everything down to just the CUSTOM_LOADERS entry per your feedback:

  • Removed all auth.ts changes
  • Removed dialog-provider.tsx changes (no longer shows as recommended provider)
  • Removed fetchKiloModels() and the synthetic database injection
  • Rebased on latest dev

The PR is now 2 files: ~12 lines in provider.ts + tests.

For the models.dev side — opened anomalyco/models.dev#939 to fix the npm field from opencode-kilo-auth@ai-sdk/openai-compatible (the fn3 is not a function bug @smetanokr reported).

Together these two changes should make the 263 Kilo models from models.dev work in OpenCode without any custom packages.

@Daltonganger
Copy link

Updated — stripped everything down to just the CUSTOM_LOADERS entry per your feedback:

  • Removed all auth.ts changes
  • Removed dialog-provider.tsx changes (no longer shows as recommended provider)
  • Removed fetchKiloModels() and the synthetic database injection
  • Rebased on latest dev

The PR is now 2 files: ~12 lines in provider.ts + tests.

For the models.dev side — opened anomalyco/models.dev#939 to fix the npm field from opencode-kilo-auth@ai-sdk/openai-compatible (the fn3 is not a function bug @smetanokr reported).

Together these two changes should make the 263 Kilo models from models.dev work in OpenCode without any custom packages.

Nice! You were quicker than me @Nomadcxx ! Hopefully we can use Kilo quickly :)

@Nomadcxx
Copy link
Author

Updated — stripped everything down to just the CUSTOM_LOADERS entry per your feedback:

  • Removed all auth.ts changes
  • Removed dialog-provider.tsx changes (no longer shows as recommended provider)
  • Removed fetchKiloModels() and the synthetic database injection
  • Rebased on latest dev

The PR is now 2 files: ~12 lines in provider.ts + tests.
For the models.dev side — opened anomalyco/models.dev#939 to fix the npm field from opencode-kilo-auth@ai-sdk/openai-compatible (the fn3 is not a function bug @smetanokr reported).
Together these two changes should make the 263 Kilo models from models.dev work in OpenCode without any custom packages.

Nice! You were quicker than me @Nomadcxx ! Hopefully we can use Kilo quickly :)

Ahaha I have my day planned out, want this fixed so I can finish issue with my cursor plugin and another project, it would trigger my OCD if it stayed unresolved too long ha.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEATURE]: Add Kilo as a native provider

5 participants