Skip to content

Commit 6c5d191

Browse files
committed
feat: implement context-generic provider wiring and enhance provider configuration
1 parent 68bd7f6 commit 6c5d191

File tree

7 files changed

+812
-150
lines changed

7 files changed

+812
-150
lines changed

docs/development/CGP_ARCHITECTURE.md

Lines changed: 66 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@
44

55
VT Code applies the **Context-Generic Programming** pattern from the
66
[RustLab 2025 talk](https://contextgeneric.dev/blog/rustlab-2025-coherence/) to
7-
its tool runtime system. The pattern solves a concrete architectural problem:
8-
the same tool implementation needs to behave differently (approval policy,
9-
sandbox enforcement, logging, caching, retry) depending on the execution
10-
context (interactive session, CI pipeline, benchmarks) — without adapter
11-
explosion.
7+
its tool runtime system and LLM provider construction path. The pattern solves
8+
two concrete architectural problems:
9+
10+
- The same tool implementation needs to behave differently (approval policy,
11+
sandbox enforcement, logging, caching, retry) depending on the execution
12+
context (interactive session, CI pipeline, benchmarks) without adapter
13+
explosion.
14+
- The same LLM provider metadata and construction rules were duplicated across
15+
factory registration, zero-sized provider config types, and the external
16+
`vtcode-llm` adapter layer.
1217

1318
## Core Concepts
1419

@@ -259,6 +264,62 @@ Wrapping is idempotent: registrations created via `from_cgp_tool()` /
259264
`register_cgp_tool()` are marked as already CGP-wrapped, and
260265
`enable_cgp_pipeline()` skips them instead of nesting another facade layer.
261266

267+
## LLM Provider Construction (Phase 8)
268+
269+
Phase 8 applies the same CGP pattern to provider construction without changing
270+
the runtime string-keyed lookup model.
271+
272+
### LLM components
273+
274+
| Component | Purpose |
275+
|-----------------------------|--------------------------------------|
276+
| `ProviderMetadataComponent` | Provider key, display name, defaults |
277+
| `ProviderBuildComponent` | Build `Box<dyn LLMProvider>` |
278+
279+
### LLM consumer traits
280+
281+
| Trait | Purpose |
282+
|-----------------------|-----------------------------------------------|
283+
| `CanDescribeProvider` | Blanket metadata API for provider contexts |
284+
| `CanBuildProvider` | Blanket factory API for provider construction |
285+
286+
### LLM contexts
287+
288+
The zero-sized provider config types in
289+
`vtcode-core/src/llm/provider_config.rs` are the CGP contexts:
290+
291+
- `GeminiProviderConfig`
292+
- `OpenAIProviderConfig`
293+
- `AnthropicProviderConfig`
294+
- `HuggingFaceProviderConfig`
295+
- `LiteLLMProviderConfig`
296+
- `DeepSeekProviderConfig`
297+
- `MinimaxProviderConfig`
298+
- `OpenRouterProviderConfig`
299+
- `OpenResponsesProviderConfig`
300+
- `MoonshotProviderConfig`
301+
- `OllamaProviderConfig`
302+
- `LmStudioProviderConfig`
303+
- `ZAIProviderConfig`
304+
305+
Each context is wired once in `vtcode-core/src/llm/cgp.rs`, then consumed by:
306+
307+
- `register_builtin_cgp_providers(...)` and `LLMFactory::register_cgp_provider::<Ctx>()`
308+
for built-in and custom registration
309+
- `ProviderBuilder<T>` and the legacy core `ProviderConfig` trait as metadata
310+
shims over `CanDescribeProvider`
311+
- `create_provider_unified(...)` as a compatibility shim over the canonical
312+
factory path
313+
314+
This keeps public entrypoints stable while removing the old
315+
`BuiltinProvider`/`impl_builtin_provider!` registration split.
316+
The zero-sized provider config types now serve directly as the metadata
317+
providers too, so there is no extra descriptor-to-metadata adapter layer.
318+
319+
`vtcode-llm` uses the same `HasComponent` substrate for its
320+
`FactoryConfigProjectionComponent`, so the external config adapter does not
321+
carry a second parallel lookup trait.
322+
262323
The active CGP mode now persists in `ToolRegistry`. Any later
263324
`register_tool()` call, including post-startup skill activation, is wrapped
264325
through the same mode automatically. This closes the earlier gap where

docs/modules/vtcode_llm_environment.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ fn gemini_from_env() -> anyhow::Result<vtcode_core::llm::factory::ProviderConfig
5353
Because the trait only exposes borrowed data, callers can also point to secrets stored
5454
in files, KMS-backed fetchers, or other secret managers.
5555

56+
Internally, `vtcode-llm::config::ProviderConfig` is the canonical external
57+
surface. Both [`config::as_factory_config`](../vtcode-llm/src/config.rs) and
58+
[`config::as_factory_config_with_hooks`](../vtcode-llm/src/config.rs) now flow
59+
through the same projection layer, so plain and hook-enriched conversions stay
60+
behaviorally aligned.
61+
5662
## Wiring workspace paths and telemetry
5763

5864
When prompt caching is enabled, use

0 commit comments

Comments
 (0)