Commit 4509103
authored
feat(embeddings): add OpenRouter provider and WithModelString for OpenAI (#477)
* docs(15): capture phase context
* docs(state): record phase 15 context session
* docs(15): research OpenRouter embeddings compatibility
* docs(15): create phase plan for OpenRouter embeddings compatibility
* docs(15): add validation strategy for phase 15
* feat(15-01): add WithModelString to OpenAI provider and update FromConfig
- Add WithModelString option for arbitrary model names on OpenAI-compatible endpoints
- Update NewOpenAIEmbeddingFunctionFromConfig to use WithModelString for non-standard models
- Existing WithModel validation unchanged for known constants
* feat(15-01): add standalone OpenRouter embedding provider package
- Create openrouter package with Client, request/response types, and HTTP implementation
- Add ProviderPreferences struct with custom MarshalJSON and Extras field
- Add functional options: WithModel, WithEncodingFormat, WithInputType, WithProviderPreferences
- Implement EmbeddingFunction interface with config round-trip support
- Register as "openrouter" in dense embedding registry
* docs(15-01): complete OpenRouter provider and WithModelString plan
- Add 15-01-SUMMARY.md with execution results
- Update STATE.md with phase 15 progress and decisions
- Update ROADMAP.md with plan progress
* test(15-02): add WithModelString and config round-trip tests for OpenAI
- Test WithModelString accepts arbitrary model strings via httptest
- Test WithModelString rejects empty string
- Test config round-trip with non-standard model name
* test(15-02): add comprehensive OpenRouter provider unit tests
- Request serialization test for encoding_format, input_type, provider fields
- ProviderPreferences MarshalJSON: typed-only, extras-only, merge precedence
- Config round-trip with all fields including nested provider preferences
- EmbedQuery dispatches single string input
- Empty model rejected by validation
- Name returns "openrouter"
- Registry registration verified
* docs(15-02): complete OpenRouter test coverage plan
- SUMMARY.md with test coverage details
- STATE.md updated to phase 15 plan 02 complete
- ROADMAP.md phase 15 marked complete
- Requirements OR-01 through OR-05 marked complete
* docs(phase-15): complete phase execution
* docs(phase-15): evolve PROJECT.md after phase completion
* test(15): complete UAT - 7 passed, 0 issues
* fix(openrouter): harden provider config and response validation
* test(openrouter): cover validation and fallback paths
* test(openrouter): add integration tests for OpenRouter embedding provider
* fix(openrouter): add base64 embedding decoding and docs
- Add custom UnmarshalJSON on EmbeddingData to handle both float and
base64-encoded embedding responses (IEEE 754 little-endian float32)
- Fix integration test using assert.Failf before t.Skip on missing .env
- Add OpenRouter provider documentation to README, embeddings.md, and
go-examples embedding-functions.md
* fix(openrouter): truncate raw error body in API error messages
Cap unstructured error responses at 512 characters to prevent
sensitive data from upstream proxies leaking into error messages.
Refs #478
* fix(openrouter): use rune-based truncation in parseAPIError
Slice by runes instead of bytes to avoid splitting multi-byte UTF-8
characters when truncating error response bodies.1 parent 958be08 commit 4509103
25 files changed
Lines changed: 3224 additions & 17 deletions
File tree
- .planning
- phases/15-openrouter-embeddings-compatibility
- docs
- docs
- go-examples/docs/embeddings
- pkg/embeddings
- openai
- openrouter
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
71 | 71 | | |
72 | 72 | | |
73 | 73 | | |
74 | | - | |
| 74 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
84 | 84 | | |
85 | 85 | | |
86 | 86 | | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
87 | 95 | | |
88 | 96 | | |
89 | 97 | | |
| |||
155 | 163 | | |
156 | 164 | | |
157 | 165 | | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
158 | 171 | | |
159 | 172 | | |
160 | | - | |
161 | | - | |
| 173 | + | |
| 174 | + | |
162 | 175 | | |
163 | 176 | | |
164 | 177 | | |
165 | 178 | | |
166 | | - | |
| 179 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
| 31 | + | |
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
| |||
179 | 179 | | |
180 | 180 | | |
181 | 181 | | |
182 | | - | |
| 182 | + | |
183 | 183 | | |
184 | 184 | | |
185 | 185 | | |
| |||
287 | 287 | | |
288 | 288 | | |
289 | 289 | | |
290 | | - | |
| 290 | + | |
291 | 291 | | |
292 | 292 | | |
293 | | - | |
| 293 | + | |
| 294 | + | |
294 | 295 | | |
295 | 296 | | |
296 | 297 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3 | 3 | | |
4 | 4 | | |
5 | 5 | | |
6 | | - | |
7 | | - | |
| 6 | + | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | | - | |
11 | | - | |
12 | | - | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
| 26 | + | |
27 | 27 | | |
28 | 28 | | |
29 | 29 | | |
| |||
74 | 74 | | |
75 | 75 | | |
76 | 76 | | |
| 77 | + | |
| 78 | + | |
77 | 79 | | |
78 | 80 | | |
79 | 81 | | |
| |||
127 | 129 | | |
128 | 130 | | |
129 | 131 | | |
| 132 | + | |
| 133 | + | |
130 | 134 | | |
131 | 135 | | |
132 | 136 | | |
| |||
159 | 163 | | |
160 | 164 | | |
161 | 165 | | |
162 | | - | |
163 | | - | |
| 166 | + | |
| 167 | + | |
164 | 168 | | |
0 commit comments