Skip to content

Commit ddaccd0

Browse files
committed
docs: define embeddable library hosting boundary
1 parent 75dc0ae commit ddaccd0

1 file changed

Lines changed: 217 additions & 0 deletions

File tree

Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
# AI Router Embeddable Library and Hosting Design
2+
3+
## Context
4+
5+
`ai-router` must be useful both as a standalone gateway and as a reusable .NET library embedded inside another application. The standalone `AiRouter.Server` is a reference host, not the product boundary.
6+
7+
This document extends the main AI Router design with the public package and hosting contract.
8+
9+
## Decision
10+
11+
The routing engine is host-agnostic. HTTP protocols, persistence, and executable hosting are optional adapters around `AiRouter`.
12+
13+
A consumer must be able to reference only the core package and call routing APIs directly without ASP.NET Core, SQLite, Docker, or `AiRouter.Server`.
14+
15+
## Package Boundary
16+
17+
### `AiRouter`
18+
19+
Core NuGet package.
20+
21+
Owns:
22+
23+
- `IAiRouter`
24+
- provider contracts and provider management
25+
- provider runtime health and cooldown state
26+
- route definitions and route resolution
27+
- priority fallback and round-robin behavior
28+
- in-memory provider and route stores
29+
- normalized/common request-routing metadata
30+
31+
Must not reference:
32+
33+
- ASP.NET Core hosting/MVC/minimal APIs
34+
- EF Core or SQLite
35+
- `AiRouter.Server`
36+
- AI Studio
37+
38+
The existing low-level JSON API remains valid for protocol adapters:
39+
40+
```csharp
41+
Task<RouterResult> ChatAsync(
42+
string model,
43+
JsonElement body,
44+
bool stream = false,
45+
CancellationToken ct = default);
46+
47+
Task<RouterResult> ResponsesAsync(
48+
string model,
49+
JsonElement body,
50+
bool stream = false,
51+
CancellationToken ct = default);
52+
```
53+
54+
A later typed convenience layer may be added without changing the routing engine, but v1 does not require consumers to adopt an HTTP protocol.
55+
56+
### `AiRouter.Providers.OpenAI`
57+
58+
OpenAI-compatible upstream transport package.
59+
60+
Owns:
61+
62+
- generic OpenAI-compatible provider implementation
63+
- upstream authentication and custom headers
64+
- `/chat/completions`, `/responses`, and `/models` transport
65+
- OpenAI error classification
66+
- Responses-to-Chat compatibility translation when needed
67+
68+
This package describes how the router calls an upstream provider. It does not host inbound HTTP endpoints.
69+
70+
### `AiRouter.Persistence.Sqlite`
71+
72+
Optional persistence implementation for `IProviderStore` and `IRouteStore`.
73+
74+
Consumers that already have a database/configuration system should not need this package. They can implement the storage abstractions themselves.
75+
76+
### `AiRouter.AspNetCore`
77+
78+
Optional ASP.NET Core hosting adapter.
79+
80+
Owns endpoint mapping and HTTP-specific behavior. It must not own routing policy.
81+
82+
Target extension surface:
83+
84+
```csharp
85+
builder.Services.AddAiRouter();
86+
builder.Services.AddOpenAiCompatibleProvider();
87+
builder.Services.AddAiRouterAspNetCore();
88+
89+
app.MapAiRouterOpenAiEndpoints();
90+
app.MapAiRouterManagementEndpoints();
91+
```
92+
93+
The OpenAI-compatible mapping exposes:
94+
95+
```text
96+
POST /v1/chat/completions
97+
POST /v1/responses
98+
GET /v1/models
99+
```
100+
101+
Management endpoints remain separately mappable so embedded applications can apply their own authentication and authorization policies.
102+
103+
### `AiRouter.Server`
104+
105+
Reference executable host and Docker target.
106+
107+
It composes:
108+
109+
- `AiRouter`
110+
- `AiRouter.Providers.OpenAI`
111+
- `AiRouter.Persistence.Sqlite`
112+
- `AiRouter.AspNetCore`
113+
114+
It does not contain routing logic that is unavailable to embedded users.
115+
116+
## Supported Consumption Styles
117+
118+
### 1. Library-only
119+
120+
A worker, desktop application, background service, MCP server, test host, or other .NET process can inject/use `IAiRouter` directly.
121+
122+
There is no HTTP listener unless the consuming application creates one.
123+
124+
### 2. Custom application host
125+
126+
An ASP.NET Core application can inject `IAiRouter` into its own controllers/minimal APIs and expose any route shape it wants, for example:
127+
128+
```text
129+
/api/assistant
130+
/api/llm/chat
131+
/internal/generate
132+
```
133+
134+
The application owns its request DTOs, authentication, authorization, response envelope, logging, and lifecycle.
135+
136+
### 3. OpenAI-compatible host
137+
138+
An application can opt into the standard OpenAI-compatible endpoint mapper so existing OpenAI SDKs and tools can use the router with only a base-URL change.
139+
140+
This is a convenience protocol adapter, not the core API contract.
141+
142+
### 4. Additional inbound protocols
143+
144+
Future protocol adapters such as Ollama-style endpoints, gRPC, MCP-facing tools, or custom company APIs should depend on `AiRouter`, not modify it.
145+
146+
For example, a future Ollama adapter could be a separate package such as `AiRouter.AspNetCore.Ollama`.
147+
148+
## Dependency Direction
149+
150+
```text
151+
Custom application ───────┐
152+
OpenAI HTTP adapter ──────┤
153+
Future Ollama adapter ────┤
154+
MCP/gRPC/custom host ─────┼──> AiRouter ──> IAiProvider implementations
155+
Direct C# consumer ───────┘
156+
157+
AiRouter.Server
158+
├── AiRouter.AspNetCore
159+
├── AiRouter.Persistence.Sqlite
160+
├── AiRouter.Providers.OpenAI
161+
└── AiRouter
162+
```
163+
164+
Dependencies never point from `AiRouter` back toward a host or protocol adapter.
165+
166+
## Public API Stability
167+
168+
The package boundary is part of the v1 contract.
169+
170+
- `IAiRouter`, provider/store abstractions, routing definitions, and result metadata should be designed for consumption outside this repository.
171+
- Server-only configuration types must not leak into core interfaces.
172+
- ASP.NET types (`HttpContext`, `IResult`, MVC attributes) must not appear in `AiRouter` public contracts.
173+
- EF/SQLite entity types must not appear in `AiRouter` public contracts.
174+
- The standalone server must use the same public abstractions available to external consumers.
175+
176+
## OpenAI Compatibility Versus Core API
177+
178+
OpenAI compatibility is important because it gives immediate interoperability, but OpenAI JSON is not the architecture boundary.
179+
180+
The core router accepts protocol-neutral routing inputs plus payload data required by a provider adapter. The OpenAI adapter is responsible for OpenAI request/response semantics.
181+
182+
This prevents the project from becoming impossible to reuse when another host wants a different contract.
183+
184+
## Documentation Requirement
185+
186+
The repository must ship `docs/library-usage.md` covering:
187+
188+
1. package selection,
189+
2. library-only usage,
190+
3. custom ASP.NET hosting,
191+
4. OpenAI-compatible hosting,
192+
5. custom stores/providers,
193+
6. what is optional versus required,
194+
7. streaming disposal/cancellation responsibilities.
195+
196+
README should link to the guide when the public packages are ready for release.
197+
198+
## Testing Requirement
199+
200+
Add architecture/contract tests that prove:
201+
202+
- `AiRouter` does not reference ASP.NET Core hosting packages,
203+
- `AiRouter` does not reference EF Core/SQLite,
204+
- `AiRouter.Server` depends on adapters rather than owning routing implementations,
205+
- direct `IAiRouter` usage works without creating a `WebApplication`,
206+
- OpenAI endpoint mapping routes through the same `IAiRouter` used by direct consumers,
207+
- a custom host can replace persistence and authentication without depending on `AiRouter.Server`.
208+
209+
## Non-Goals
210+
211+
For v1 we will not:
212+
213+
- create a universal protocol abstraction for every AI API,
214+
- implement an Ollama inbound API until there is a concrete need,
215+
- force all consumers to use SQLite,
216+
- force all consumers to use ASP.NET Core,
217+
- expose AI Studio-specific services through public contracts.

0 commit comments

Comments
 (0)