Skip to content

feat(providers): add Y-API provider - #415

Open
jiweiyeah wants to merge 1 commit into
andrewyng:mainfrom
jiweiyeah:feat/yapi-provider
Open

jiweiyeah wants to merge 1 commit into
andrewyng:mainfrom
jiweiyeah:feat/yapi-provider

Conversation

@jiweiyeah

Copy link
Copy Markdown

What this adds

A Y-API provider. Y-API is an OpenAI-compatible gateway that fronts several vendors behind
one endpoint and API key, so model ids keep their vendor prefix:

client = ai.Client()
response = client.chat.completions.create(
    model="yapi:deepseek/deepseek-v4-flash",
    messages=[{"role": "user", "content": "Hello"}],
)

Discovery is automatic — per the README's "Extending aisuite" section,
yapi_provider.py → "yapi" → class YapiProvider, so there is no registry to edit.

Files

File Change
aisuite/providers/yapi_provider.py new — 100 lines
tests/providers/test_yapi_provider.py new — 9 tests
pyproject.toml +1 — yapi = ["openai"] extra

No new dependency. It reuses the openai SDK, following the same OpenAI-compatible
pattern as deepseek_provider.py / openrouter_provider.py. The yapi extra mirrors what
deepseek, ollama and lmstudio already declare (["openai"]); all needs no change
because it already pulls in openai.

Three choices worth flagging

base_url uses setdefault, not assignment. deepseek_provider.py does
config["base_url"] = "https://api.deepseek.com", which silently overrides an explicit
base_url. Since a gateway endpoint is exactly the thing someone might want to point
elsewhere (self-hosted, alternative deployment), this provider only defaults it — from
YAPI_API_BASE if set, otherwise the gateway.

Async and streaming are wired up natively, via openai.AsyncOpenAI, rather than
falling back to Provider's default thread offload. openai_provider.py does this, and
since Y-API speaks OpenAI's wire format there's no reason to take the slower path.

No docs change. docs/chat-completions-quickstart.md says "The list of supported
providers lives in aisuite/providers/ (<provider>_provider.py)" — the directory is the
list, so nothing else needs updating.

How this was tested

$ pytest tests/providers/test_yapi_provider.py -q
.........                                                                [100%]
9 passed in 0.66s

The nine tests cover: default endpoint, base_url override from config, base_url from
YAPI_API_BASE, the missing-key ValueError, a mocked completion, usage parsing,
streaming pass-through, and — the two that matter most — that ProviderFactory.create_provider("yapi")
still resolves and that "yapi" appears in get_supported_providers(). A rename that
breaks the filename convention would not fail any import
, so it is asserted explicitly.

Baseline control. My local env only has the openai SDK, so many provider tests can't
collect. I therefore diffed the failure/error set with and without my two files (moving
them aside, not git stash):

baseline     : 11 failed, 74 passed, 1 skipped, 19 errors
this branch  : 11 failed, 83 passed, 1 skipped, 19 errors
diff of FAILED/ERROR lines: (empty)

So the change is exactly +9 passing tests with no new failures — the 11 pre-existing
failures are unrelated to this PR.

black --check passes on both new files (CI runs psf/black@stable).

The tests are hermetic: the autouse fixture clears YAPI_API_BASE, so
test_yapi_provider_defaults_to_the_gateway_endpoint still passes if that variable is set
in the ambient environment (verified by running the suite with it exported to a
deliberately wrong value).

Y-API is an OpenAI-compatible gateway that fronts several vendors behind one
endpoint and API key, so model ids keep their vendor prefix:

    client.chat.completions.create(
        model="yapi:deepseek/deepseek-v4-flash", messages=messages
    )

The provider follows the OpenAI-compatible pattern used by deepseek/openrouter
and reuses the openai SDK, so it needs no new dependency. It also wires up
native async and streaming via openai.AsyncOpenAI rather than falling back to
the base class's thread offload.

The base URL is set with setdefault (not assignment), so an alternative gateway
can be pointed at via base_url in config or the YAPI_API_BASE env var.

Adds the `yapi` extra (["openai"], as deepseek/ollama/lmstudio already do) and
nine tests, including ones asserting the factory can still resolve the provider
from the filename convention — a rename there breaks discovery without failing
any import.
@jiweiyeah

Copy link
Copy Markdown
Author

Gentle bump — opened Sep 19, no activity since. The change is self-contained: a provider entry in the registry plus the OpenAI-compatible wiring, in the same shape as the other gateway providers. I can rebase onto current main if that helps.

For verification context (running now, on today's live gateway): a non-streaming chat.completions call against deepseek/deepseek-v4-flash via this exact code path returned HTTP 200 with finish_reason=stop, and GET /v1/models lists 20 models. I run Y-API, so a disclosure for the record: this is a self-sponsored provider addition.

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.

1 participant