用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/braintrustdata/lingua --skill add-provider命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
正在显示 SKILL.md
基于 SOC 职业分类
| name | add-provider |
| description | Add support for a new LLM provider format to Lingua. Follow the test-first workflow with payload snapshots. |
Add support for a new LLM provider to Lingua using a test-first approach.
Full documentation: crates/lingua/docs/ADDING_PROVIDER_FORMAT.md
1. Add payload snapshots → 2. Add ProviderFormat → 3. Create module → 4. Implement adapter → 5. Validate with coverage-report
Create test fixtures from real API calls in payloads/snapshots/:
payloads/snapshots/simpleRequest/myprovider/
├── request.json
├── response.json
├── response-streaming.json
├── followup-request.json
├── followup-response.json
└── followup-response-streaming.json
Quick manual capture:
mkdir -p payloads/snapshots/simpleRequest/myprovider
# Save actual API request/response JSON to these files
Using capture system (recommended):
cd payloads && pnpm capture --providers myprovider
File: crates/lingua/src/capabilities/format.rs
pub enum ProviderFormat {
// ... existing
MyProvider, // Add here
Unknown,
}
Update Display and FromStr implementations.
Directory: crates/lingua/src/providers/myprovider/
myprovider/
├── mod.rs
├── adapter.rs # ProviderAdapter implementation
├── convert.rs # TryFromLLM conversions
├── detect.rs # Request/response types
└── params.rs # Typed params with #[serde(flatten)]
Add to crates/lingua/src/providers/mod.rs:
#[cfg(feature = "myprovider")]
pub mod myprovider;
Add feature flag to Cargo.toml:
[features]
default = ["openai", "anthropic", "google", "bedrock", "myprovider"]
myprovider = []
File: crates/lingua/src/providers/myprovider/adapter.rs
Required methods (9 total):
| Method | Purpose |
|---|---|
format() | Return ProviderFormat::MyProvider |
directory_name() | Return "myprovider" (matches snapshot dir) |
display_name() | Return "MyProvider" (for reports) |
detect_request() | Return true if payload is this format |
request_to_universal() | Provider request → UniversalRequest |
request_from_universal() | UniversalRequest → Provider request |
detect_response() | Return true if response is this format |
response_to_universal() | Provider response → UniversalResponse |
response_from_universal() | UniversalResponse → Provider response |
Register in crates/lingua/src/processing/adapters.rs:
#[cfg(feature = "myprovider")]
list.push(Box::new(crate::providers::myprovider::MyProviderAdapter));
Quick iteration (use compact mode):
cargo run --bin coverage-report -- -f compact -p myprovider
Full details for debugging:
cargo run --bin coverage-report -- -p myprovider
Document issues:
cargo run --bin coverage-report -- -p myprovider > .Codex/myprovider_bugs.md
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct MyProviderParams {
pub model: Option<String>,
pub temperature: Option<f64>,
pub max_tokens: Option<i64>,
/// Unknown fields captured automatically
#[serde(flatten)]
pub extras: BTreeMap<String, Value>,
}
Store provider-specific extras keyed by ProviderFormat to prevent cross-contamination:
// In request_to_universal:
provider_extras.insert(ProviderFormat::MyProvider, typed_params.extras);
// In request_from_universal:
if let Some(extras) = req.provider_extras.get(&ProviderFormat::MyProvider) {
// Only merge back same-provider extras
}
| Pattern | Example |
|---|---|
| Simple adapter | providers/anthropic/adapter.rs |
| Complex with streaming | providers/openai/adapter.rs |
| Bedrock (nested config) | providers/bedrock/adapter.rs |
payloads/snapshots/ProviderFormat enum updatedProviderAdapter trait implementedadapters.rsCargo.toml