@@ -31,9 +31,9 @@ make ci # Full CI suite
3131## Architecture
3232
3333- ` engine/ ` — stable host-facing provider engine facade and DTO contract
34- - ` client /core/` — provider-neutral wire types, transport, stream, and retry primitives
35- - ` client /adapters/` — provider protocol adapters and construction registry
36- - ` client /` — backwards-compatible public facade, middleware, and caches
34+ - ` provider /core/` — provider-neutral wire types, transport, stream, and retry primitives
35+ - ` provider /adapters/` — provider protocol adapters and construction registry
36+ - ` provider /` — provider runtime composition root
3737- ` credentials/ ` — API key storage, lookup, and safe status projection
3838- ` catalog/ ` — model catalog, discovery, capabilities, and pricing
3939- ` router/ ` and ` runtime/ ` — route policy and runtime resolution
@@ -50,13 +50,13 @@ make ci # Full CI suite
5050## Common Pitfalls
5151
5252- ` engine ` , ` llm ` , ` graph ` and ` tools ` are the host contract surface. Rho
53- must not assemble ` client ` , ` catalog ` , ` config ` , ` credentials ` , ` router ` or
53+ must not assemble ` provider ` , ` catalog ` , ` config ` , ` credentials ` , ` router ` or
5454 ` runtime ` . Six symbols Rho needs (` ChatOptions ` , ` ContinuationConfig ` ,
5555 ` StreamResult ` , ` ResponseFormat ` , ` ImageURLPart ` , ` InputAudioPart ` ) live in
5656 ` llm ` with no ` engine ` alias; widening the facade to cover them is a
5757 deliberate API change, not an incidental one.
58- - ` client .Provider` remains the lower-level compatibility boundary for other
59- consumers; preserve its method set and the facade's type identity
58+ - ` provider/core .Provider` is the lower-level provider contract; keep its
59+ method set stable and use it across feature packages
6060- Streaming tests need careful goroutine management
6161- ` go.work ` here should stay minimal; the parent ` graycode-eco/go.work `
6262 connects this independent ` flux ` checkout beside Rho for local development.
@@ -65,20 +65,20 @@ make ci # Full CI suite
6565
6666## Naming Conventions
6767
68- - ** Provider interface** : ` client .Provider` with ` Chat() ` , ` StreamChat() ` , ` Ping() ` , ` Name() ` — implemented per LLM vendor
69- - ** Client types** : ` FluxClient ` , ` FluxMessage ` , ` FluxResponse ` , ` FluxTool ` , ` FluxUsage ` — ` Flux ` prefix for public types
70- - ** Config struct** : ` FluxConfig ` with ` Provider ` , ` APIKey ` , ` BaseURL ` , ` Model ` , ` MaxRetries ` fields
71- - ** Provider implementations** : ` AnthropicClient ` , ` OpenAIClient ` , ` GeminiClient ` , ` BedrockClient ` , etc. — in ` client/ ` package
72- - ** Compatibility configs** : ` OpenAICompat ` , ` GrokCompat ` , ` OpenRouterCompat ` — ` Compat ` suffix for provider quirks
68+ - ** Provider interface** : ` provider/core .Provider` with ` Chat() ` , ` StreamChat() ` , ` Ping() ` , ` Name() `
69+ - ** Core request types** : ` provider/core. FluxMessage` , ` FluxResponse ` , ` FluxTool ` , ` FluxUsage `
70+ - ** Config struct** : ` provider/core. FluxConfig` with ` Provider ` , ` APIKey ` , ` BaseURL ` , ` Model ` , ` MaxRetries `
71+ - ** Provider implementations** : ` provider/adapters/ AnthropicClient` , ` OpenAIClient ` , ` GeminiClient ` , etc.
72+ - ** Compatibility configs** : ` provider/adapters. OpenAICompat` , ` GrokCompat ` , ` OpenRouterCompat `
7373- ** Error type** : ` FluxError ` with ` Provider ` , ` Op ` , ` StatusCode ` , ` RequestID ` , ` Message ` , ` Err ` fields
7474- ** Stream types** : ` StreamResult ` , ` SSEEvent ` , ` StreamEvent ` — streaming is SSE-based
7575- ** Retry config** : ` RetryConfig ` embeds ` types.RetryConfig ` + adds ` RetryOn []int ` for HTTP status codes
76- - ** Version wiring** : ` client .Version` set via ` SetVersion() ` from root package — avoids circular import
76+ - ** Version wiring** : ` provider .Version` set via ` SetVersion() ` from root package — avoids circular import
7777
7878## API Patterns
7979
8080- ** Provider auto-detection** : ` DetectProvider() ` checks env vars in priority order (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.)
81- - ** Client creation** : ` client .NewFluxClient(&FluxConfig{...})` or ` client .Client(&FluxConfig{...})` — both work
81+ - ** Client creation** : ` provider .NewFluxClient(&core. FluxConfig{...})` or ` provider .Client(&core. FluxConfig{...})`
8282- ** Chat method** : ` c.Chat(ctx, messages, opts) ` — non-streaming, returns ` *FluxResponse `
8383- ** Stream method** : ` c.StreamChat(ctx, messages, opts) ` — returns ` *StreamResult ` , caller must ` defer sr.Close() `
8484- ** Auto-continuation** : ` StreamChatContinue() ` transparently retries when ` stop_reason == max_tokens `
@@ -111,38 +111,38 @@ make ci # Full CI suite
111111- ** Do not touch** : ` Provider ` interface (` Chat ` , ` StreamChat ` , ` Ping ` , ` Name ` ) — breaking change for all implementations
112112- ** Do not touch** : ` FluxMessage ` , ` FluxResponse ` , ` ChatOptions ` struct field names — serialization contract
113113- ** Do not touch** : ` FluxError ` struct — used by consumers for error type assertions
114- - ** Do not touch** : ` client .FluxConfig` — constructor contract for all consumers
114+ - ** Do not touch** : ` provider/core .FluxConfig` — constructor contract for all consumers
115115- ** Safe to extend** : add new provider implementations, new SSE event types, new cache strategies
116- - ** When adding a provider** : create ` client /<provider>.go` , implement ` Provider ` interface, register in ` provider_registry.go `
116+ - ** When adding a provider** : create ` provider /<provider>.go` , implement ` Provider ` interface, register in ` provider_registry.go `
117117
118118## Key File Locations
119119
120120| What | Where |
121121| ---| ---|
122- | Provider interface | ` client/client .go` (` Provider ` , ` FluxConfig ` , ` FluxMessage ` , ` ContentPart ` ) |
123- | Chat implementation | ` client /chat.go` (` Chat() ` , ` StreamChat() ` , ` StreamChatContinue() ` ) |
122+ | Provider interface | ` provider/core/core .go` (` Provider ` , ` FluxConfig ` , ` FluxMessage ` , ` ContentPart ` ) |
123+ | Chat implementation | ` provider /chat.go` (` Chat() ` , ` StreamChat() ` , ` StreamChatContinue() ` ) |
124124| Host-facing engine facade | ` engine/ ` |
125- | Provider-neutral core | ` client /core/` |
126- | Anthropic provider | ` client /adapters/anthropic.go` |
127- | OpenAI provider | ` client /adapters/openai.go` |
128- | Gemini provider | ` client /adapters/gemini.go` |
129- | Bedrock provider | ` client /adapters/bedrock.go` |
130- | Vertex provider | ` client /adapters/vertex.go` |
131- | Azure provider | ` client /adapters/azure.go` |
132- | Provider registry | ` client /adapters/provider_registry.go` |
133- | Provider compatibility | ` client /adapters/compat.go` (` OpenAICompat ` , ` GrokCompat ` , etc.) |
134- | SSE streaming | ` client /stream.go` (` parseSSEStream() ` , ` SSEEvent ` ) |
135- | Retry logic | ` client /retry.go` (` RetryConfig ` , ` backoffDelay() ` , ` shouldRetry() ` ) |
136- | Rate limiting | ` client/ ratelimit.go` , ` client /adaptive_ratelimit.go` |
137- | Caching | ` client /cache.go ` , ` client/semantic_cache .go` , ` client/cache_analytics .go` |
138- | Fallback chains | ` client /fallback.go` |
139- | Auto-continuation | ` client /continuation.go` |
140- | Error types | ` client /errors.go` (` FluxError ` , ` IsRetriable() ` , ` IsAuthError() ` ) |
125+ | Provider-neutral core | ` provider /core/` |
126+ | Anthropic provider | ` provider /adapters/anthropic.go` |
127+ | OpenAI provider | ` provider /adapters/openai.go` |
128+ | Gemini provider | ` provider /adapters/gemini.go` |
129+ | Bedrock provider | ` provider /adapters/bedrock.go` |
130+ | Vertex provider | ` provider /adapters/vertex.go` |
131+ | Azure provider | ` provider /adapters/azure.go` |
132+ | Provider registry | ` provider /adapters/provider_registry.go` |
133+ | Provider compatibility | ` provider /adapters/compat.go` (` OpenAICompat ` , ` GrokCompat ` , etc.) |
134+ | SSE streaming | ` provider /stream.go` (` parseSSEStream() ` , ` SSEEvent ` ) |
135+ | Retry logic | ` provider/core /retry.go` (` RetryConfig ` , ` backoffDelay() ` , ` shouldRetry() ` ) |
136+ | Rate limiting | ` provider/resilience/ ratelimit.go` , ` provider/resilience /adaptive_ratelimit.go` |
137+ | Caching | ` provider /cache/cache .go` , ` provider/cache/semantic_cache .go` |
138+ | Fallback chains | ` provider/resilience /fallback.go` |
139+ | Auto-continuation | ` provider/resilience /continuation.go` |
140+ | Error types | ` provider /errors.go` (` FluxError ` , ` IsRetriable() ` , ` IsAuthError() ` ) |
141141| Error constants | ` errors/errors.go ` (API error messages, prompt-too-long parsing) |
142142| Model catalog | ` catalog/ ` (pricing, context windows, capabilities per provider) |
143143| Credentials | ` credentials/ ` (key storage, env detection, scrubbing) — ` HasSecret ` is silent on miss (boolean predicate); ` LookupSecret ` logs ` Debug ` on ` ErrNotFound ` and ` Warn ` on real backend errors |
144- | Mock provider | ` client /mock.go` |
145- | Main test file | ` client /client_test.go` (httptest servers, provider detection) |
144+ | Mock provider | ` provider/testkit /mock.go` |
145+ | Main test file | ` provider /client_test.go` (httptest servers, provider detection) |
146146| Linter config | ` .golangci.yml ` (govet, ineffassign, misspell — minimal) |
147147
148148This is an independent repository consumed by Rho. In the local
0 commit comments