Skip to content

feat(ai): support complete model provider surface - #385

Merged
Haz3-jolt merged 21 commits into
Observal:mainfrom
Kaushik-Kumar-CEG:feature/model-provider-support
Sep 8, 2026
Merged

feat(ai): support complete model provider surface#385
Haz3-jolt merged 21 commits into
Observal:mainfrom
Kaushik-Kumar-CEG:feature/model-provider-support

Conversation

@Kaushik-Kumar-CEG

@Kaushik-Kumar-CEG Kaushik-Kumar-CEG commented Sep 6, 2026

Copy link
Copy Markdown
Contributor

Purpose

Complete issue 10 by implementing the full model provider, authentication, catalog, native codec, configured endpoint, and provider management surface through the existing ModelProvider contract. This matters because Axl previously exposed only an Azure-focused path and could not safely select, authenticate, discover, or operate the required provider set through daemon-owned product surfaces.

Fixes

Fixes #10

Approach

Implemented and registered all 41 provider identities with model-selected API dialects, provider-owned authentication, explicit dynamic catalog refresh, and synchronous offline static catalogs. Added the 11 required native codec surfaces, shared request preparation, deterministic provider transports, cloud and subscription authentication, daemon-owned provider management, typed SDK methods, and provider-neutral CLI and TUI workflows.

Static catalog inputs are checked-in provider-scoped JSON Lines shards with checksum-bearing provenance manifests. Generation is local and deterministic, producing a compact index plus 36 provider shards. The reviewed semantic baseline is now 1,116 models after the Azure-only correction, with SHA-256 04dfaed60a79d13a7229c2968c804242df5e0b22e705ff18da64b9c32ea4eb53.

Security boundaries remain fail closed. Credentials and prompt answers stay inside trusted provider and process-host adapters, provider listing has no credential or network side effects, cloud signing failures do not fall back to unsigned dispatch, and opaque continuation metadata is retained only for its exact provider, dialect, and model provenance.

The original implementation grouped related implementation, verification, documentation, catalog, and security work into coherent commits. Initial pull request CodeQL analysis identified two high-severity polynomial regular-expression findings in caller-controlled Azure and Radius base URL normalization. Commit 49f2adb replaces those expressions with bounded linear scans and adds long-input regressions. An unrelated draft replacement of repository development guidance in AGENTS.md was removed during final scope review.

Follow-up commit 22f65de retains Axl's ModelProvider contract and adds:

  • Native ~/.axl/models.json with named providers, provider-scoped credentials, validated reasoning metadata, and explicit migration from custom-provider.json. Configuration edits currently require a daemon restart.
  • Shared catalog normalization and policy for offline generation and explicit refresh of 35 models.dev-backed built-ins. The four existing dynamic catalogs retain provider discovery. Ant Ling and explicit custom model lists have no remote discovery.
  • Pi-style inline login: authentication method, searchable provider list with status, and cancellable prompts with masked secrets. Browser opening remains in the trusted process host; prompt answers never enter daemon RPC or canonical history.
  • Fixes for Node's pinned-DNS lookup callback shapes, named loopback providers, dispatch of refreshed Chat models, blank Enterprise-domain prompts, and aggregate refresh failures returning success.

Follow-up commit b3fa4c2 adds explicit, verified Linux recovery for older daemons without host control. It requires --interrupt --yes, validates process ownership, executable, placement, lock and listening socket, and sends SIGTERM through non-reusable PID:inode identities. Missing OS support fails closed. Ordinary startup never replaces an incompatible daemon. Mistyped daemon action flags now explain the documented subcommand syntax. This commit contains no catalog changes.

Azure-only follow-up 05a234c restores 13 already-curated Azure IDs and adds gpt-6-astra, using Axl's existing definitions and original metadata rather than copying Pi files. Shared generation and refresh now expose 80 Azure models, covering all 39 IDs in the user's Pi Azure cache. Astra has a 1,050,000-token context, 128,000-token output limit, and explicit reasoning levels. Non-reasoning definitions no longer carry contradictory reasoning maps. Other provider shards are unchanged.

The first-party image command remains a limitation. OpenRouter image generation is available through @axl/ai. Only Azure has been live-tested in this follow-up; the complete provider inventory is not a claim of production verification across every backend.

How was this tested?

Azure-only follow-up verification (05a234c)

  • pnpm check: passed, including build, formatting, lint, type checking, 823 tests (815 passed, 8 existing skips), boundaries, and generated-file checks.
  • node --test --test-timeout=30000 packages/ai/test/azure-openai.test.ts packages/ai/test/catalog.test.ts packages/ai/test/catalog-refresh.test.ts: 26 passed. Generator validation first exposed contradictory reasoning maps on two older non-reasoning definitions; the implementation was corrected, not the validation.
  • node packages/ai/scripts/generate-catalog.ts: regenerated only the Azure provider shard. The explicitly reviewed baseline is now 1,116 models. All 39 Pi-cached Azure IDs are present.
  • User-authorized idle daemon restart and axl models azure-openai-responses: Astra is visible. axl refresh azure-openai-responses returned 80 models and retained Astra.
  • One authorized live inference through the built CLI/runtime returned exactly OK from Astra at requested low, with Bubblewrap enforced and no tool calls: 439 input tokens, 5 output tokens, zero reasoning tokens, catalog-derived cost $0.00464. The first launcher attempt left stdin open and timed out before prompt submission; closing stdin corrected the test launcher. Existing credential/settings and Pi cache/config files were hash-checked unchanged, and temporary resources were removed. No other provider was tested live.
  • uv tool run --offline --from reuse reuse --root <staged-snapshot> lint: 495/495 files compliant. git diff --cached --check: passed. The lockfile is unchanged from the passing vulnerability audit. Commit hooks ran; the commit is signed off.

Daemon upgrade recovery verification (b3fa4c2)

  • pnpm check: passed formatting, lint, type checking, build, 822 tests (814 passed, 8 existing platform/environment skips), package boundaries, and generated-file checks.
  • pnpm build and pnpm typecheck: passed separately.
  • node --test --test-timeout=30000 packages/cli/test/legacy-daemon.test.ts packages/cli/test/daemon-lifecycle.test.ts: the initial run found an incomplete simulated legacy greeting. The fixture was corrected without weakening the assertion. The focused legacy suite and subsequent full check passed. Coverage includes wire-8 recovery through the built CLI, history preservation, mandatory consent, unchanged ordinary startup, unrelated processes, changed identities, wrong entry points, placement mismatches, and lock permissions. Recovery tests require Linux pidfs and compatible util-linux tools; all ran on this host.
  • axl daemon status --socket <user-socket>: verified the real wire-8 daemon read-only. After explicit user authorization, axl daemon restart --socket <user-socket> --interrupt --yes succeeded and status reported wire 12. The old daemon had already disappeared by restart time, so the live command exercised missing-daemon startup; legacy shutdown was verified with isolated subprocesses.
  • uv tool run --from reuse reuse --root <staged-snapshot> lint: passed, 495/495 files covered. A direct reuse invocation failed because it was not on PATH; no check was bypassed. Untracked tmp/ files remain untouched.
  • pnpm audit --audit-level high: no known vulnerabilities. git diff --cached --check: passed. Commit hooks ran and the commit carries a matching DCO sign-off.

Latest follow-up verification

  • pnpm check: passed again before push, including formatting, lint, type checking, build, 818 tests (810 passed, 8 existing platform/environment skips), boundaries, and generated-file checks.
  • pnpm check:generated: passed separately. The reviewed 1,102-model semantic baseline is unchanged.
  • node --test --test-timeout=30000 packages/ai/test/transport-safety.test.ts packages/ai/test/catalog.test.ts packages/ai/test/models-config.test.ts packages/ai/test/azure-openai.test.ts: focused checks passed. Additional Azure reasoning coverage verifies all 66 bundled Azure models across seven thinking levels, 462 combinations.
  • Built-CLI loopback inference and real PTY login smoke tests passed, including method/provider selection, Enterprise-domain prompts, secret masking, cancellation, and narrow-terminal resize.
  • pnpm audit --audit-level high: passed with no known vulnerabilities.
  • git diff --cached --check: passed.
  • uvx --offline reuse --root <staged-snapshot> lint: passed for all 492 staged product files. Direct worktree REUSE checking flags six pre-existing, untracked scratch files under tmp/; they were not changed or committed.
  • User-authorized live Azure smoke: the built CLI and daemon ran in a disposable Bubblewrap-enforced workspace using an isolated in-memory credential store. Catalog refresh returned 67 Azure models. gpt-5.6-luna returned exactly OK at requested/effective low with no clamping or tool calls. The verified call reported 195 input tokens, 5 output tokens, and catalog-derived cost of $0.000045. Credentials were absent from stdout, stderr, and canonical history; existing settings and credential files were hash-checked and unchanged.
  • The live test first exposed the DNS callback defect. A real-socket regression now covers both Node lookup callback forms. Two minimal inference calls followed: the first exited successfully but the temporary reporter used incorrect event names; the corrected reporter verified the second call. No other provider inference was tested.
  • A first aggregate run exposed picker-header clipping after the cursor correction. The implementation was fixed and the full checks subsequently passed. No valid test was weakened or skipped.

Earlier implementation verification

The results below describe earlier revisions of the PR. Those routine checks were local and deterministic and did not use live provider credentials.

  • Node test runner over packages/ai/test/catalog.test.ts with a 30-second timeout: passed 7 of 7 tests, including provider counts, semantic baseline, provenance, offline behavior, and deterministic regeneration.
  • pnpm check:generated: passed.
  • Node test runner over packages/ai/test/*.test.ts with a 30-second timeout: passed 244 of 244 tests, including the exact 41-provider registration inventory.
  • pnpm check: passed formatting and lint for 330 files, root type checking, the complete build, 749 tests with 741 passing and 8 environment-dependent skips, package boundaries, and generated-file checks. There were no failures or cancellations.
  • reuse lint: passed, 490 of 490 files compliant.
  • pnpm audit with the high severity threshold: passed with no known vulnerabilities.
  • Git whitespace validation from origin/main through HEAD: passed.
  • Corrected changed-file credential-pattern scan: passed with no matches.
  • DCO and Conventional Commit audit: passed for all 18 feature commits.
  • Initial pull request CodeQL check: failed with two high-severity polynomial regular-expression findings. After the final security correction, 19 focused Azure and remaining-provider tests, targeted Biome checks, AI type checking, and the complete repository gates passed. The replacement CodeQL check passed.
  • Replacement pull request build check: the aggregate test process was canceled at the 10-minute job limit while running the TUI app suite, after all output through test 558 had passed. GitHub denied the failed-job rerun because the fork account lacks repository admin permission. This is the known aggregate TUI hang described below, not a reported assertion failure.
  • Detached synthetic merge against origin/main at e98f686935199cd39738a34c32acd5bc398bf0a7: passed without conflicts, and the staged merge tree exactly matched the feature tree.

The repository has a known intermittent aggregate TUI timing and temporary-directory cleanup flake. It did not reproduce in the final 749-test run, so no focused retry was required. Earlier aggregate attempts and focused passing retries remain recorded in docs/model-provider-handoff.md. No test was skipped or weakened, no timeout was increased, and no ineffective runner change was retained.

Learning

The implementation and executable evidence are mapped in docs/provider-support/issue-10-completion.md and docs/provider-support/deterministic-verification.md. Provider setup, environment variables, endpoint and regional policy, catalog maintenance, compatibility controls, custom endpoints, and limitations are consolidated in docs/provider-support/provider-reference.md.

The compact catalog keeps source facts, Axl policy overlays, and generated runtime data separate. This preserves offline synchronous reads while making provenance and model changes reviewable by provider.

The follow-up compared Pi revision 6c87d9a026677b601e8278030dcf1ad97fe0bd86 read-only. Pi's user-authored models.json is separate from generated catalogs and its discovery cache. Its command is pi update --models, not pi --model refresh; it refreshes providers implementing discovery rather than regenerating every static provider. Axl adopts the interaction design and shares its own normalization, without copying Pi source or introducing another provider abstraction.

Checklist

  • I reviewed the complete diff.
  • I added or updated the smallest relevant test for behavior changes.
  • I ran the relevant formatting, lint, type-check, test, boundary, and license checks.
  • Every new file has SPDX metadata, directly or through REUSE.toml.
  • Every commit has a matching DCO Signed-off-by trailer.
  • UI changes include screenshots attached to the pull request, not committed to the repository.

The UI changes are terminal-only CLI and TUI workflows with deterministic transcript and integration coverage. No screenshot is attached, so the screenshot item remains unchecked rather than being claimed as complete.

Licenses

  • models.dev factual model metadata: https://models.dev/api.json at repository revision 5c600a037417cf778ee6eb3ea2ce0f17abc12130, MIT, used for reduced provider-scoped static catalog inputs.
  • Azure Identity: @azure/identity 4.13.2, MIT, used for Microsoft Entra credential acquisition.
  • Google Auth Library: google-auth-library 11.0.2, Apache-2.0, used for Vertex ADC and service-account authentication.
  • AWS credential provider and Smithy signing packages: versions pinned in packages/ai/package.json and pnpm-lock.yaml, Apache-2.0, used for the AWS credential chain and SigV4 request signing.

AI assistance

  • Generative AI materially assisted this change. Original implementation: pi coding agent with azure-openai-responses/gpt-5.6-sol. Follow-up: pi coding agent; its model identifier was not available in the exported session metadata. Hari Srinivasan directed the follow-up and explicitly authorized publication.
  • I manually reviewed, understood, and tested the generated work.

Comment thread packages/ai/src/remaining-providers.ts Fixed
@Kaushik-Kumar-CEG
Kaushik-Kumar-CEG force-pushed the feature/model-provider-support branch 4 times, most recently from 8013afc to 42f8d84 Compare September 6, 2026 15:04
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
@Kaushik-Kumar-CEG
Kaushik-Kumar-CEG force-pushed the feature/model-provider-support branch from 42f8d84 to 1eb5a22 Compare September 6, 2026 15:18
Kaushik-Kumar-CEG and others added 4 commits September 6, 2026 21:11
Signed-off-by: Kaushik <kaushikrjpm10@gmail.com>
Share reviewed catalog normalization between generation and explicit refresh.
Load named providers from models.json and keep login prompts inside the TUI.
Validate reasoning metadata and fix pinned DNS lookup callback handling.

Verify with pnpm check, built CLI and PTY smoke tests, and an explicitly
authorized Azure request in a disposable sandboxed session.

Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Require explicit interruption and disconnection consent for legacy recovery. Verify process ownership, placement, executable, and listening socket before signaling a non-reusable Linux pidfs identity. Fail closed without the required OS utilities and keep ordinary startup non-destructive.

Cover wire-8 restart, history preservation, confirmation, unrelated processes, changed identity, and placement rejection through built CLI tests.

Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
Reuse the existing Azure definitions in shared catalog normalization so generated catalogs and explicit refresh retain missing IDs. Add Astra with reviewed limits and reasoning levels, and omit reasoning maps from non-reasoning models.

Verify all 39 Pi-cached Azure IDs are present without copying Pi sources. Regenerate only the Azure shard and review the updated semantic baseline. Test Astra dispatch, refresh, upstream precedence, offline restore, and one live sandboxed request.

Signed-off-by: Hari Srinivasan <harisrini21@gmail.com>
@Haz3-jolt
Haz3-jolt merged commit 7bb9a84 into Observal:main Sep 8, 2026
10 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.

Support the complete model provider and catalog surface

3 participants