Skip to content

feat(providers): add AI/ML API preset#402

Open
D1m7asis wants to merge 3 commits into
Gitlawb:mainfrom
aimlapi:d1m7asis/aimlapi-provider
Open

feat(providers): add AI/ML API preset#402
D1m7asis wants to merge 3 commits into
Gitlawb:mainfrom
aimlapi:d1m7asis/aimlapi-provider

Conversation

@D1m7asis

@D1m7asis D1m7asis commented Jul 2, 2026

Copy link
Copy Markdown

Summary

  • add AI/ML API as a built-in OpenAI-compatible provider preset
  • configure AIMLAPI_API_KEY, the fixed https://api.aimlapi.com/v1 endpoint, and openai/gpt-5-chat as the starter model
  • attach AI/ML API partner, repository, and integration-version attribution headers to both runtime and model-discovery requests
  • document direct setup and cover catalog, onboarding, runtime, discovery, and provider-picker behavior with tests

Linked issue

Fixes #401

Testing

  • go build ./...
  • go vet ./...
  • focused tests for provider catalog, onboarding, provider factory, model discovery, and TUI
  • git diff --check
  • go test ./... (all changed packages pass; existing OAuth callback timing tests in internal/cli and internal/mcp time out on this Windows environment)

Checklist

  • The linked issue already has the issue-approved label. (approval requested)
  • go build ./..., go vet ./..., and go test ./... pass locally. (build/vet and changed packages pass; unrelated OAuth timing tests time out)
  • gofmt clean.
  • Tests added/updated for the change.
  • UI changes include screenshots or a short recording where possible. (catalog-only picker change)

Summary by CodeRabbit

  • New Features
    • Added AI/ML API (aimlapi) as a supported OpenAI-compatible provider, including provider setup guidance and required sign-in details.
    • Model discovery and requests now automatically include aimlapi attribution/trace headers for the selected provider.
  • Documentation
    • Updated “First Run” instructions to include AIMLAPI_API_KEY, plus added a one-command setup option to activate aimlapi.
  • Bug Fixes
    • Improved handling of provider- and catalog-specific headers so both model lookups and outbound requests use the correct header set automatically.

Copilot AI review requested due to automatic review settings July 2, 2026 17:22
@D1m7asis

D1m7asis commented Jul 2, 2026

Copy link
Copy Markdown
Author

@jatmn The focused AI/ML API preset implementation is ready for review. It includes the fixed provider endpoint/key setup plus attribution headers on both inference and model-discovery requests. The linked issue is #401.

@Vasanthdev2004

Copy link
Copy Markdown
Collaborator

hey thanks for making pr @D1m7asis

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

Adds AI/ML API as a first-class, OpenAI-compatible provider preset in Zero, including setup documentation, catalog placement, runtime/model-discovery attribution headers, and regression tests across CLI + TUI flows.

Changes:

  • Adds aimlapi provider descriptor (base URL https://api.aimlapi.com/v1, env AIMLAPI_API_KEY, default model openai/gpt-5-chat) and updates catalog ordering expectations.
  • Injects AI/ML API attribution headers for both runtime provider requests and /models discovery requests (scoped to catalog id aimlapi).
  • Documents direct setup and updates/extends tests for catalog onboarding, provider factory, model discovery, and the TUI provider wizard.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
README.md Documents AIMLAPI_API_KEY and zero providers setup aimlapi --set-active.
internal/tui/provider_wizard_test.go Makes wizard selection tests robust to catalog order changes by selecting providers by ID.
internal/providers/providerio/headers.go Adds catalog-scoped header injection helper for AIMLAPI attribution headers.
internal/providers/factory.go Applies AIMLAPI attribution headers to OpenAI/OpenAI-compatible provider construction.
internal/providers/factory_test.go Adds regression test asserting AIMLAPI attribution headers on runtime requests.
internal/providermodeldiscovery/discovery.go Applies AIMLAPI attribution headers to OpenAI-compatible model discovery requests.
internal/providermodeldiscovery/discovery_test.go Adds regression test asserting AIMLAPI attribution headers on discovery requests.
internal/providercatalog/catalog.go Adds aimlapi preset immediately after the recommended OpenGateway entry.
internal/providercatalog/catalog_test.go Updates expected catalog IDs and ordering; verifies AIMLAPI descriptor defaults.
internal/cli/provider_catalog_onboarding_test.go Verifies onboarding output includes AIMLAPI requirements and setup hint.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +66 to +78
func HeadersForCatalog(catalogID string, headers map[string]string) map[string]string {
copied := CopyHeaders(headers)
if !strings.EqualFold(strings.TrimSpace(catalogID), "aimlapi") {
return copied
}
if copied == nil {
copied = map[string]string{}
}
copied["X-AIMLAPI-Partner-ID"] = "Gitlawb"
copied["X-AIMLAPI-Integration-Repo"] = "Gitlawb/zero"
copied["X-AIMLAPI-Integration-Version"] = "1.0.0"
return copied
}

@Vasanthdev2004 Vasanthdev2004 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Verdict: Approve ✅ — correct, well-scoped, and it doesn't touch other providers

Reviewed the header plumbing carefully (that's the part that could regress every provider, not just this one). It's clean.

Header injection is correctly scoped

HeadersForCatalog(catalogID, headers) only adds the X-AIMLAPI-* attribution headers when catalogID == "aimlapi"; every other provider gets CopyHeaders(headers) unchanged. I checked CopyHeaders(nil) == nil, so non-aimlapi providers keep identical behavior — and now get a defensive copy of their custom headers instead of the aliased map, which is actually a small safety win. It's applied consistently to both runtime (factory.go) and discovery (discovery.go), so the attribution can't diverge between the two paths.

Catalog + tests are solid

  • Descriptor is a standard openAICompat entry; expectedCatalogIDs and the TransportOpenAICompat order list are both updated to match the insertion point.
  • Good coverage: descriptor fields, onboarding auth hint, factory header injection (asserting the real endpoint + Authorization + attribution + a user's own X-Trace survive), and discovery header injection.
  • Nice test-hygiene call: the two wizard tests were refactored from brittle "press Down N times" navigation to providerWizardProviderIndex(...) (id-based) — exactly right, since inserting a provider shifts the list and would otherwise silently break those tests. Verified the helper is defined and compiles.

Local: go build ./..., go vet, gofmt clean; providers, providercatalog, providermodeldiscovery, providerio, tui (wizard), and cli (catalog onboarding) all pass.

Two things for your conscious call (non-blocking)

  1. Placement. aimlapi is inserted as the 2nd catalog entry — right after the recommended OpenGateway and above first-party openai / anthropic / google. So a third-party aggregator sits near the top of the provider picker. That's a product/ordering decision, not a correctness issue — if you'd rather it not outrank the first-party providers, moving it down next to the other aggregators (openrouter/groq) is a one-line reorder (plus the two test order-lists).
  2. Default model openai/gpt-5-chat. I didn't independently confirm this id against live AI/ML API — a wrong default 400s on first run. Worth a quick check that it's a currently-served id (their model names are provider-prefixed, so the shape is right). Not blocking per the "live ids lag the manifest" norm.

Also fine: the attribution headers hardcode Partner-ID: Gitlawb / Gitlawb/zero / version 1.0.0 — that's the project's own partner attribution (like OpenRouter's X-Title), which is the intended behavior for a first-class preset.

Approving. Thanks @D1m7asis — clean, well-tested integration.

@coderabbitai

coderabbitai Bot commented Jul 2, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: c9e3317c-aef4-4d95-9cf0-0f982b9acda9

📥 Commits

Reviewing files that changed from the base of the PR and between 4b46220 and 34ab360.

📒 Files selected for processing (1)
  • internal/providers/providerio/headers_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/providers/providerio/headers_test.go

Walkthrough

Adds a new built-in aimlapi provider preset, injects catalog-scoped attribution headers into OpenAI-compatible provider and model-discovery requests, updates onboarding and README guidance, and adjusts two provider wizard tests to select providers directly.

Changes

AI/ML API provider preset

Layer / File(s) Summary
AI/ML API catalog descriptor and tests
internal/providercatalog/catalog.go, internal/providercatalog/catalog_test.go
Adds the aimlapi descriptor with its OpenAI-compatible settings and updates catalog tests for descriptor fields, ID ordering, and transport ordering.
Catalog-scoped attribution headers
internal/providers/providerio/headers.go, internal/providers/factory.go, internal/providers/factory_test.go, internal/providermodeldiscovery/discovery.go, internal/providermodeldiscovery/discovery_test.go
Adds HeadersForCatalog, wires it into provider creation and model discovery, and verifies AIMLAPI-specific attribution headers in request tests.
Onboarding docs and CLI tests
internal/cli/provider_catalog_onboarding_test.go, README.md
Adds onboarding coverage for aimlapi, asserts required auth/env hints, and documents AIMLAPI_API_KEY plus the setup command.
Provider wizard test navigation refactor
internal/tui/provider_wizard_test.go
Replaces key-down navigation with direct provider selection in two existing wizard tests.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related issues

Possibly related PRs

  • Gitlawb/zero#141: Adds the provider-catalog and providerio header plumbing this PR extends for aimlapi.
  • Gitlawb/zero#161: Also updates onboarding assertions for provider setup output.

Suggested reviewers: kevincodex1, gnanam1990, Vasanthdev2004

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding an AI/ML API provider preset.
Linked Issues check ✅ Passed The PR matches the requested AI/ML API preset scope with catalog, headers, setup docs, and regression tests.
Out of Scope Changes check ✅ Passed The changes stay within the requested narrow scope and are limited to catalog, runtime, tests, and README updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
internal/providers/providerio/headers.go (1)

66-78: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the AIMLAPI catalog ID into a shared constant

  • internal/providers/providerio/headers.go and internal/providercatalog/catalog.go both hardcode "aimlapi", so a rename or alias change would silently stop adding the attribution headers.
  • providerio can import providercatalog here without a cycle, so a shared exported constant would make the coupling explicit.
  • Add a negative test for HeadersForCatalog with a different catalog ID (for example "groq") to lock in the match behavior.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/providers/providerio/headers.go` around lines 66 - 78, The AIMLAPI
catalog ID is hardcoded in both HeadersForCatalog and the catalog definition, so
extract it into a shared exported constant from providercatalog and use that in
providerio instead of duplicating "aimlapi". Update HeadersForCatalog to
reference the shared symbol so the attribution-header check stays in sync with
catalog changes. Add a negative test for HeadersForCatalog using a non-AIMLAPI
catalog ID such as "groq" to verify headers are not added for other providers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/providers/providerio/headers.go`:
- Around line 66-78: The AIMLAPI catalog ID is hardcoded in both
HeadersForCatalog and the catalog definition, so extract it into a shared
exported constant from providercatalog and use that in providerio instead of
duplicating "aimlapi". Update HeadersForCatalog to reference the shared symbol
so the attribution-header check stays in sync with catalog changes. Add a
negative test for HeadersForCatalog using a non-AIMLAPI catalog ID such as
"groq" to verify headers are not added for other providers.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: a9aeaa8e-ec1b-4e48-8d9c-bd3f7fff5c40

📥 Commits

Reviewing files that changed from the base of the PR and between cdf9d83 and c844cbb.

📒 Files selected for processing (10)
  • README.md
  • internal/cli/provider_catalog_onboarding_test.go
  • internal/providercatalog/catalog.go
  • internal/providercatalog/catalog_test.go
  • internal/providermodeldiscovery/discovery.go
  • internal/providermodeldiscovery/discovery_test.go
  • internal/providers/factory.go
  • internal/providers/factory_test.go
  • internal/providers/providerio/headers.go
  • internal/tui/provider_wizard_test.go

@gnanam1990 gnanam1990 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approving.

Genuinely additive — no existing descriptor, ID, base URL, or order entry is mutated. The one shared-plumbing touch (routing all providers through HeadersForCatalog) is proven behavior-preserving: for any non-aimlapi catalog ID it returns CopyHeaders(headers), and CopyHeaders(nil) == nil, so nil-header providers are byte-identical to before. Verified build / vet / test green across the touched packages.

Two non-blocking nits (both from the bots): the "aimlapi" literal is duplicated between the header match and the catalog descriptor — worth a shared const + a negative test so a future rename can't silently drop the attribution header — and the map is copied even for non-aimlapi providers (micro-allocation). Optional polish, not blockers.

@kevincodex1

Copy link
Copy Markdown
Contributor

hello @D1m7asis kindly rebase to main and fix conflicts please

…ider

# Conflicts:
#	README.md
#	internal/cli/provider_catalog_onboarding_test.go
#	internal/providercatalog/catalog_test.go
@D1m7asis

D1m7asis commented Jul 3, 2026

Copy link
Copy Markdown
Author

Updated the branch by merging current upstream main (no rebase/force push) and resolved the additive provider-catalog conflicts.

Also applied the non-blocking review polish:

  • exported a shared providercatalog.AIMLAPIID constant
  • avoided copying custom headers for non-AIMLAPI providers
  • added negative isolation coverage and verified AIMLAPI attribution overrides cannot mutate/spoof the caller map
  • retained the rebate attribution headers on runtime and /models discovery requests

Validation:

  • providerio/providers/discovery/catalog/onboarding/TUI tests pass
  • targeted CLI provider-catalog tests pass
  • go vet ./... passes
  • go build ./... passes
  • git diff --check passes

The only local failure remains the unrelated flaky TestRunMCPOAuthLoginStoresTokens 10-second callback timeout.

@kevincodex1 conflicts are resolved and the branch is ready for re-review.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
internal/providers/providerio/headers_test.go (1)

28-28: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider using the shared catalog ID constant instead of a literal.

" AIMLAPI " is hardcoded here rather than referencing providercatalog.AIMLAPIID. Since the PR introduces that exported constant specifically for this purpose, using it (with whitespace/case variations appended) would keep the test coupled to the actual ID rather than a duplicated literal.

♻️ Proposed tweak
-	got := HeadersForCatalog(" AIMLAPI ", headers)
+	got := HeadersForCatalog(" "+strings.ToUpper(providercatalog.AIMLAPIID)+" ", headers)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@internal/providers/providerio/headers_test.go` at line 28, The test for
HeadersForCatalog is hardcoding the catalog ID string instead of using the
shared constant. Update the assertion setup in headers_test.go so it references
providercatalog.AIMLAPIID and applies the whitespace/case variations to that
value, keeping the test aligned with the exported catalog identifier used by
HeadersForCatalog.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@internal/providers/providerio/headers_test.go`:
- Line 28: The test for HeadersForCatalog is hardcoding the catalog ID string
instead of using the shared constant. Update the assertion setup in
headers_test.go so it references providercatalog.AIMLAPIID and applies the
whitespace/case variations to that value, keeping the test aligned with the
exported catalog identifier used by HeadersForCatalog.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 4712540b-6bc3-4820-8c41-1d56c91b1339

📥 Commits

Reviewing files that changed from the base of the PR and between c844cbb and 4b46220.

📒 Files selected for processing (7)
  • README.md
  • internal/cli/provider_catalog_onboarding_test.go
  • internal/providercatalog/catalog.go
  • internal/providercatalog/catalog_test.go
  • internal/providers/providerio/headers.go
  • internal/providers/providerio/headers_test.go
  • internal/tui/provider_wizard_test.go
✅ Files skipped from review due to trivial changes (1)
  • README.md
🚧 Files skipped from review as they are similar to previous changes (5)
  • internal/providercatalog/catalog.go
  • internal/providers/providerio/headers.go
  • internal/cli/provider_catalog_onboarding_test.go
  • internal/tui/provider_wizard_test.go
  • internal/providercatalog/catalog_test.go

@D1m7asis

D1m7asis commented Jul 3, 2026

Copy link
Copy Markdown
Author

Addressed the remaining CodeRabbit nit in 34ab360: the case/whitespace normalization test now derives its input from the shared providercatalog.AIMLAPIID constant instead of duplicating the catalog ID. Targeted providerio and providercatalog tests pass. Ready for re-review.

@gnanam1990 gnanam1990 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

VERDICT: approve

REGRESSION RISK: low

Re-review of new commits since my prior review (c844cbbb34ab3606). The new commits merge main and reuse the aimlapi catalog id consistently (addressing the prior review's finding about catalog ID consistency). The PR also rebased onto main, picking up unrelated changes. The catalog ID fix is correct — the provider now uses a single consistent id throughout.

BUILD / TEST

  • CI all green (macOS, Ubuntu, Windows, Smoke, Security, Zero Review)

FINDINGS

None. The catalog ID consistency issue from the prior review has been addressed.

BOTTOM LINE

The catalog ID consistency fix addresses the prior review's finding. Safe to merge.

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.

feat(providers): add AI/ML API provider preset

5 participants