Skip to content

feat: add Infron as an open_code gateway provider - #126

Merged
AbirAbbas merged 3 commits into
Agent-Field:mainfrom
meridah7:feat/infron-provider
Sep 9, 2026
Merged

AbirAbbas merged 3 commits into
Agent-Field:mainfrom
meridah7:feat/infron-provider

Conversation

@meridah7

@meridah7 meridah7 commented Aug 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • What changed: Adds Infron as an open_code gateway provider. Infron is an OpenAI-compatible inference gateway serving the standard <provider>/<model> ids, so wiring it in is a base-URL change rather than a model-mapping exercise: infron/moonshotai/kimi-k2.6 routes the same model the bare id names, and nothing else in a deployment moves.
  • Why it changed: It gives deployers a second open-model gateway behind the exact same resolution rules, so switching (or A/B-ing) is an env-var change instead of a fork.

Disclosure: I work on Infron. Everything below is checkable from the diff and the commands under Validation.

File Change
docker/opencode.json New. The OpenCode provider block moves out of the two Dockerfiles into one shared file both images COPY, so they cannot drift apart. Declares infron (@ai-sdk/openai-compatible) next to the existing provider.
Dockerfile, go/Dockerfile Replace the inlined echo '{...}' config with COPY docker/opencode.json.
swe_af/execution/schemas.py _infron_only_env() + _INFRON_AUTO_DEFAULT_MODEL, following the existing gateway path through _default_runtime, _default_planning_model, and resolve_runtime_models.
go/internal/config/resolve.go Same, for the Go port (infronOnlyEnv, infronAutoDefaultModel).
agentfield-package.yaml, go/agentfield-package.yaml INFRON_API_KEY offered as a third llm_provider option.
.env.example, README.md Document the prefix swap and the auto-select rule.
tests/test_model_config.py, tests/test_dockerfile.py, go/internal/config/config_test.go Coverage for the new path and for the shared-config invariant.

Behavior

With only an INFRON_API_KEY set (no ANTHROPIC_API_KEY, no other gateway key, no SWE_DEFAULT_RUNTIME), SWE-AF auto-selects the open_code runtime and defaults to infron/deepseek/deepseek-v4-flash — the same rule the existing gateway path already follows, with the prefix swapped.

A gateway key that was already honored before Infron existed keeps precedence. Adding an Infron key never silently reroutes an existing deployment; moving traffic across is an explicit act (drop the other key, or set SWE_DEFAULT_MODEL=infron/...). A provider with no key set is never selected, so shipping both in the image costs nothing at runtime.

Validation

Rebased on main at 7a8dba0 and re-run today.

  • make check — python -m pytest tests/ -q: 1154 passed, 1 skipped, 0 failed, plus python -m compileall -q swe_af/ clean
    (note for anyone reproducing: tests/conftest.py requires AGENTFIELD_SERVER to be set to a local address, e.g. AGENTFIELD_SERVER=http://localhost:9999, or every test errors at fixture setup)
  • cd go && go test ./... — 27 packages ok, 0 failures (Go 1.23.4)
  • cd go && go build ./... clean; gofmt -l internal/config/ clean
  • The 81 tests covering this change specifically (tests/test_model_config.py, tests/test_dockerfile.py) pass, including test_both_dockerfiles_share_one_opencode_config, which pins the new shared-config invariant.
  • Live smoke test against the gateway: moonshotai/kimi-k2.6, minimax/minimax-m2.5 and z-ai/glm-5.2 over https://llm.onerouter.pro/v1 return well-formed completions with usage accounting, on both the sync and the streaming path, under the same ids already used in the image.

Behavior Impact

  • No behavior change — every new path is gated on INFRON_API_KEY being the only gateway key present, and an existing key wins ties.

Notes

  • The docker/opencode.json extraction is the one structural change. It was the cleanest way to avoid a ~900-character echo line and to stop the Python and Go images from drifting; test_both_dockerfiles_share_one_opencode_config now pins that. Happy to inline it back into both Dockerfiles if you would rather keep the diff to a single mechanism.
  • @ai-sdk/openai-compatible providers are not in models.dev, so the model list has to be explicit. I listed the eight open-weight models SWE-AF realistically uses (Kimi K2.6 / K2.7-Code / K3, DeepSeek V4 Flash/Pro, MiniMax M2.5/M3, GLM-5.2). Easy to extend.
  • Companion PR on the SDK side, which is what makes infron/... work for AgentField apps generally: feat(sdk/go/ai): support the Infron gateway agentfield#874. The two are independent; either can land alone.
  • Happy to follow up with a joint benchmark on SWE-AF's own workload (same model, both gateways, cost + cache + latency side by side) if that is useful for the docs.

@meridah7
meridah7 requested a review from AbirAbbas as a code owner August 4, 2026 21:50
@CLAassistant

CLAassistant commented Aug 4, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@meridah7 meridah7 changed the title feat: add Infron as an open_code gateway provider alongside OpenRouter feat: add Infron as an open_code gateway provider Aug 4, 2026
Infron is an OpenAI-compatible inference gateway that serves the standard
<provider>/<model> ids, so wiring it in is a base-URL change rather than
a model-mapping exercise: infron/moonshotai/kimi-k2.6 routes the same
model the bare id names, and nothing else in a deployment moves.

- docker/opencode.json: the OpenCode provider block moves out of the two
  Dockerfiles into one shared file both images COPY, so they cannot drift
  apart. It now declares infron (@ai-sdk/openai-compatible) next to the
  existing provider; a provider with no key set is never selected, so
  shipping both costs nothing at runtime.
- INFRON_API_KEY follows the same resolution chain the existing gateway
  key does (Python and the Go port): with only that key present, SWE-AF
  auto-selects open_code and defaults to
  infron/deepseek/deepseek-v4-flash.
- A gateway key that was already honored before Infron existed keeps
  precedence, so adding an Infron key never silently reroutes an existing
  deployment.
- Manifests offer INFRON_API_KEY as a third llm_provider option; README
  and .env.example document the prefix swap.

No behavior change for any existing deployment: every new path is gated
on INFRON_API_KEY being the only gateway key present.
@meridah7
meridah7 force-pushed the feat/infron-provider branch from d00aabc to d6b950d Compare August 4, 2026 22:03
@meridah7 meridah7 changed the title feat: add Infron as an open_code gateway provider feat: add Infron as an open_code gateway provider Aug 4, 2026

@AbirAbbas AbirAbbas 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.

Thanks for the disclosed, well-tested integration. The precedence logic is correct and symmetric in both swe_af/execution/schemas.py and go/internal/config/resolve.go (verified: an existing gateway key always wins, the two *_only_env() predicates are mutually exclusive by construction), and the shared docker/opencode.json extraction is a genuine improvement over the duplicated inline JSON. But the branch is three commits behind main and the staleness is now load-bearing. Requesting changes:

  1. Rebase onto current main (ef508a8). Four files conflict (schemas.py, resolve.go, both agentfield-package.yamls) — all mechanical.
  2. Stale model constants: #132 renamed the shared open_code default to deepseek-v4-flash-0731. _INFRON_AUTO_DEFAULT_MODEL / infronAutoDefaultModel still say infron/deepseek/deepseek-v4-flash, and two tests copied from the pre-#132 tree (test_explicit_open_code_keeps_minimax, test_model_ids_unchanged_after_prefix_swap) auto-merge cleanly and then fail. Bump both constants to -0731, add that model id to docker/opencode.json's infron.models list (OpenCode can't resolve it otherwise — your own test_infron_declares_models explains why), and update tests/test_dockerfile.py to match.
  3. The headline claim breaks inside the project's own images: both Dockerfiles bake ENV HARNESS_MODEL=openrouter/moonshotai/kimi-k2.6, which sits above the auto-gateway default in the resolution cascade. An INFRON_API_KEY-only container deployment therefore resolves every model to an OpenRouter id with no OpenRouter key and dies on auth. Document the required SWE_DEFAULT_MODEL override for Infron the same way the README already does for Codex, or make the baked default gateway-aware.
  4. INFRON_API_KEY never reaches the container: all five compose service env blocks (docker-compose.yml ×2, docker-compose.go.yml ×2, docker-compose.local.yml) enumerate provider vars explicitly and none pass it through, so the documented .env path is broken end-to-end.
  5. Re-validate after the rebase: the PR's current make check / go test numbers were measured against the old base.

Separate from the code review: adding INFRON_API_KEY to require_one_of.llm_provider promotes Infron into the af install wizard on equal footing with Anthropic/OpenRouter for every installer. That's a maintainer policy decision rather than a review item and is still being weighed — if it ends up moved to optional, everything else above still stands.

AbirAbbas and others added 2 commits September 9, 2026 19:07
Brings the branch up to date with main (13 commits) and resolves the
conflicts the staleness created.

Resolution notes:

- main's Agent-Field#97 extracted the OpenCode provider JSON into a repo-root
  opencode.json that both Dockerfiles COPY, which is the same refactor
  this branch was doing into docker/opencode.json. Dropped the branch's
  copy and added the infron provider block to the root file instead, so
  there is still exactly one config and the MiniMax providers main added
  are untouched. Both Dockerfiles keep main's COPY line verbatim.

- main's Agent-Field#132 renamed the shared open_code default to
  deepseek-v4-flash-0731. Bumped _INFRON_AUTO_DEFAULT_MODEL /
  infronAutoDefaultModel to match, declared that id in the infron
  provider's models list so OpenCode can resolve it, and updated the two
  tests that were written against the pre-Agent-Field#132 default.

- main's Agent-Field#142 scoped the HARNESS_MODEL cascade step to the open_code
  runtime. An INFRON_API_KEY-only deployment auto-selects open_code, so
  the images' baked openrouter/... HARNESS_MODEL still overrides the
  Infron auto default. Documented the required HARNESS_MODEL override in
  README and .env.example and pinned both halves of that behaviour in
  tests/test_model_config.py rather than changing the baked default.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The .env path the README documents was broken end to end: all five
service env blocks enumerate provider variables explicitly, so an
INFRON_API_KEY in .env never reached a container. Add it alongside
OPENROUTER_API_KEY in swe-agent and swe-fast (docker-compose.yml),
swe-agent-go and swe-fast-go (docker-compose.go.yml) and swe-agent
(docker-compose.local.yml), and update the SWE_DEFAULT_RUNTIME comments
that still said the auto-select only looks at an OpenRouter key.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@AbirAbbas

Copy link
Copy Markdown
Collaborator

I pushed the rebase-equivalent onto your branch as a merge from main plus two commits, so it's current and CI is green again.

On the review items: main's #97 turned out to have done the same config extraction you did, into a repo-root opencode.json that both Dockerfiles already COPY, so I dropped docker/opencode.json and moved the infron provider block into that file instead — the MiniMax entries main added are untouched and both images still share one config. The auto default is now infron/deepseek/deepseek-v4-flash-0731 on both nodes, that id is declared in infron.models, and the two tests written against the pre-#132 default are fixed. On the baked HARNESS_MODEL: #142 scoped it to open_code, which doesn't help here because an Infron-only container auto-selects open_code — so the image's openrouter/... value still wins over the Infron default. Rather than change the baked value I documented the required HARNESS_MODEL=infron/... override in the README and .env.example and pinned both directions in a test. INFRON_API_KEY now passes through all five compose service blocks.

Local runs on the merged head: make check 1229 passed / 1 skipped, and go test -race ./... green across all packages.

One thing I deliberately left alone: INFRON_API_KEY still sits in require_one_of.llm_provider, which puts Infron in the af install wizard alongside Anthropic and OpenRouter. That's a maintainer call, not a review item, so it's unchanged and still open.

@AbirAbbas
AbirAbbas merged commit acd25bc into Agent-Field:main Sep 9, 2026
3 checks passed
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.

3 participants