Conversation
add tests fix parser missing model naming fix format issues add devstral for parser update tests adds converter if no aliases, use the default in converter add tests to converter add to factory and update tests add to parsers, fix tests fix test properly lm parser test failures finalise parser branch and fix up linting
update tests lint fixes refactoring unifier
re-review and adjusting of all docs.
WalkthroughAdds native Lemonade backend support across config, docs, converters, registry parsers, unifier, handlers/routes, constants and tests. Introduces Lemonade types, parser, converter and profile, registers the converter, adds provider constants and metadata fields (checkpoint, recipe), and updates site navigation and documentation. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
actor Client
participant Olla as Olla Proxy
participant Lemonade as Lemonade Backend
rect rgb(240,248,255)
note over Client,Olla: Model listing (normalised OpenAI-format)
Client->>Olla: GET /olla/lemonade/api/v1/models
Olla->>Lemonade: GET /api/v1/models
Lemonade-->>Olla: 200 JSON (Lemonade models)
Olla->>Olla: Parse LemonadeResponse → domain.ModelInfo → convert to OpenAI-format (preserve checkpoint/recipe)
Olla-->>Client: 200 JSON (object=list, data=[...]) + X-Olla-* headers
end
rect rgb(245,255,240)
note over Client,Olla: Proxyed inference
Client->>Olla: POST /olla/lemonade/v1/chat/completions
Olla->>Lemonade: POST /v1/chat/completions (forwarded)
Lemonade-->>Olla: Stream/JSON response
Olla-->>Client: Stream/JSON + X-Olla-Request-ID, X-Olla-Backend-Type=lemonade
end
rect rgb(255,250,240)
note over Olla,Lemonade: Health & status checks
Olla->>Lemonade: GET /healthz
Lemonade-->>Olla: 200 OK
Olla->>Olla: Update endpoint status/registry
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Suggested labels
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 4
🧹 Nitpick comments (1)
internal/app/handlers/handler_provider_models_test.go (1)
210-235: Consider consolidating duplicate test cases.Both
lemonade_native_formatandlemonade_openai_formattest cases are identical—they use the same handler (genericProviderModelsHandler("lemonade", "openai")), same expected format ("openai"), and same assertions. Since Lemonade doesn't have a native format distinct from OpenAI, one test case would suffice.Apply this diff to remove the duplicate test case:
- { - name: "lemonade_openai_format", - endpoint: "/olla/lemonade/v1/models", - handler: app.genericProviderModelsHandler("lemonade", "openai"), - expectedFormat: "openai", - checkResponse: func(t *testing.T, body []byte) { - var response converter.OpenAIModelResponse - require.NoError(t, json.Unmarshal(body, &response)) - assert.Equal(t, "list", response.Object) - assert.Len(t, response.Data, 1) - assert.Equal(t, "Qwen2.5-0.5B-Instruct-CPU", response.Data[0].ID) - }, - },
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (37)
config/config.yaml(1 hunks)config/profiles/README.md(2 hunks)config/profiles/lemonade.yaml(1 hunks)docs/content/api-reference/lemonade.md(1 hunks)docs/content/api-reference/overview.md(3 hunks)docs/content/concepts/overview.md(1 hunks)docs/content/configuration/overview.md(1 hunks)docs/content/faq.md(1 hunks)docs/content/getting-started/quickstart.md(2 hunks)docs/content/index.md(3 hunks)docs/content/integrations/backend/lemonade.md(1 hunks)docs/content/integrations/backend/litellm.md(1 hunks)docs/content/integrations/backend/lmstudio.md(1 hunks)docs/content/integrations/backend/ollama.md(1 hunks)docs/content/integrations/backend/sglang.md(1 hunks)docs/content/integrations/backend/vllm.md(1 hunks)docs/content/integrations/overview.md(1 hunks)docs/mkdocs.yml(2 hunks)internal/adapter/converter/factory.go(1 hunks)internal/adapter/converter/factory_test.go(3 hunks)internal/adapter/converter/lemonade_converter.go(1 hunks)internal/adapter/converter/lemonade_converter_test.go(1 hunks)internal/adapter/registry/profile/lemonade.go(1 hunks)internal/adapter/registry/profile/lemonade_parser.go(1 hunks)internal/adapter/registry/profile/lemonade_parser_test.go(1 hunks)internal/adapter/registry/profile/parsers.go(1 hunks)internal/adapter/unifier/default_unifier.go(1 hunks)internal/app/handlers/handler_common.go(1 hunks)internal/app/handlers/handler_provider_common.go(1 hunks)internal/app/handlers/handler_provider_compatibility_test.go(2 hunks)internal/app/handlers/handler_provider_models_test.go(6 hunks)internal/app/handlers/server_routes.go(1 hunks)internal/core/constants/providers.go(2 hunks)internal/core/domain/model.go(1 hunks)internal/core/domain/profile.go(1 hunks)internal/version/version.go(1 hunks)readme.md(2 hunks)
🧰 Additional context used
📓 Path-based instructions (2)
internal/app/handlers/*.go
📄 CodeRabbit inference engine (CLAUDE.md)
Set response headers on proxy responses:
X-Olla-Endpoint,X-Olla-Model,X-Olla-Backend-Type,X-Olla-Request-ID,X-Olla-Response-Time
Files:
internal/app/handlers/handler_provider_models_test.gointernal/app/handlers/handler_provider_common.gointernal/app/handlers/handler_provider_compatibility_test.gointernal/app/handlers/server_routes.gointernal/app/handlers/handler_common.go
{internal,pkg}/**/*_test.go
📄 CodeRabbit inference engine (CLAUDE.md)
Include Go benchmarks (Benchmark* functions) for critical paths, proxy engine comparisons, pooling efficiency, and circuit breaker behaviour
Files:
internal/app/handlers/handler_provider_models_test.gointernal/app/handlers/handler_provider_compatibility_test.gointernal/adapter/converter/factory_test.gointernal/adapter/converter/lemonade_converter_test.gointernal/adapter/registry/profile/lemonade_parser_test.go
🧠 Learnings (2)
📚 Learning: 2025-09-23T08:30:20.366Z
Learnt from: CR
PR: thushan/olla#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-23T08:30:20.366Z
Learning: Applies to internal/app/handlers/*.go : Set response headers on proxy responses: `X-Olla-Endpoint`, `X-Olla-Model`, `X-Olla-Backend-Type`, `X-Olla-Request-ID`, `X-Olla-Response-Time`
Applied to files:
docs/content/api-reference/overview.mddocs/content/index.md
📚 Learning: 2025-09-23T08:30:20.366Z
Learnt from: CR
PR: thushan/olla#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-23T08:30:20.366Z
Learning: Applies to config/profiles/{ollama,lmstudio,litellm,openai,vllm}.yaml : Provider-specific profiles must reside under `config/profiles/` with the specified filenames
Applied to files:
docs/content/concepts/overview.md
🧬 Code graph analysis (10)
internal/app/handlers/handler_provider_models_test.go (3)
internal/core/domain/endpoint.go (1)
StatusHealthy(52-52)internal/core/domain/model.go (1)
ModelInfo(28-35)internal/adapter/converter/openai_converter.go (1)
OpenAIModelResponse(11-14)
internal/app/handlers/handler_provider_common.go (1)
internal/core/constants/providers.go (1)
ProviderTypeLemonade(5-5)
internal/adapter/converter/factory.go (1)
internal/adapter/converter/lemonade_converter.go (1)
NewLemonadeConverter(23-27)
internal/adapter/unifier/default_unifier.go (1)
internal/core/domain/model.go (2)
ModelDetails(11-26)ModelInfo(28-35)
internal/adapter/registry/profile/lemonade_parser.go (2)
internal/core/domain/model.go (2)
ModelInfo(28-35)ModelDetails(11-26)internal/adapter/registry/profile/lemonade.go (1)
LemonadeResponse(11-14)
internal/adapter/registry/profile/parsers.go (1)
internal/core/constants/providers.go (1)
ProviderTypeLemonade(5-5)
internal/adapter/converter/lemonade_converter.go (5)
internal/adapter/registry/profile/lemonade.go (2)
LemonadeResponse(11-14)LemonadeModel(17-27)internal/adapter/converter/base_converter.go (2)
BaseConverter(8-10)NewBaseConverter(13-17)internal/core/ports/model_converter.go (2)
ModelResponseConverter(10-15)ModelFilters(18-23)internal/core/constants/providers.go (1)
ProviderTypeLemonade(5-5)internal/core/domain/unified_model.go (1)
UnifiedModel(15-31)
internal/app/handlers/server_routes.go (1)
internal/core/constants/providers.go (2)
ProviderTypeLemonade(5-5)ProviderTypeOpenAI(7-7)
internal/adapter/converter/lemonade_converter_test.go (6)
internal/adapter/converter/lemonade_converter.go (2)
NewLemonadeConverter(23-27)LemonadeConverter(18-20)internal/core/constants/providers.go (1)
ProviderTypeLemonade(5-5)internal/core/domain/unified_model.go (3)
UnifiedModel(15-31)AliasEntry(9-12)SourceEndpoint(34-44)internal/core/ports/model_converter.go (1)
ModelFilters(18-23)internal/adapter/registry/profile/lemonade.go (2)
LemonadeResponse(11-14)LemonadeModel(17-27)internal/adapter/converter/base_converter.go (2)
BaseConverter(8-10)NewBaseConverter(13-17)
internal/app/handlers/handler_common.go (1)
internal/core/constants/providers.go (3)
ProviderTypeLemonade(5-5)ProviderTypeLMStudio(6-6)ProviderTypeOllama(4-4)
🪛 markdownlint-cli2 (0.18.1)
docs/content/api-reference/lemonade.md
24-24: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
186-186: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
209-209: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
256-256: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
263-263: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
docs/content/integrations/backend/lemonade.md
167-167: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
318-318: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
541-541: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Cross-Platform Build Validation (windows-latest)
🔇 Additional comments (47)
config/profiles/README.md (1)
20-20: LGTM!The documentation additions for Lemonade SDK integration are clear and consistent with the existing profile documentation structure.
Also applies to: 133-133
config/config.yaml (1)
73-74: LGTM!The documentation reference improves usability by pointing users to endpoint configuration details.
docs/content/integrations/backend/sglang.md (2)
16-16: Verify the version downgrade.The "Since" version changed from
v0.1.0tov0.0.19, which represents a backwards version change. Please confirm this is intentional and not a documentation error.
20-20: LGTM!Adding the hyperlink to endpoint configuration improves documentation consistency and usability.
docs/content/integrations/backend/vllm.md (1)
20-20: LGTM!The hyperlink addition improves documentation consistency across backend integrations.
docs/content/integrations/backend/litellm.md (1)
20-20: LGTM!The hyperlink addition maintains consistency with other backend integration documentation.
docs/content/integrations/backend/ollama.md (1)
20-20: LGTM!The hyperlink addition aligns with the documentation pattern used across other backend integrations.
docs/content/integrations/backend/lmstudio.md (1)
20-20: LGTM!The hyperlink addition improves navigation and maintains documentation consistency.
internal/app/handlers/handler_provider_common.go (1)
45-45: LGTM!Adding Lemonade to the test scenario's minimal OpenAI-compatible profile set is consistent with the PR's objective of integrating Lemonade SDK support. The placement within the test-only branch (when
profileFactoryis nil) is appropriate.config/profiles/lemonade.yaml (1)
1-260: Comprehensive profile definition for Lemonade SDK.The profile is well-structured and covers all necessary aspects: routing, API compatibility, model management, resource requirements, and security considerations. The inclusion of hardware acceleration details (CPU, GPU, NPU) and multiple backend support (oga-cpu, oga-npu, llamacpp, etc.) aligns well with Lemonade's local inference optimisation focus.
docs/content/concepts/overview.md (1)
69-69: LGTM!The documentation update correctly reflects the addition of SGLang, Lemonade SDK, and LiteLLM to the list of pre-configured profiles.
internal/adapter/converter/factory.go (1)
24-24: LGTM!The Lemonade converter registration follows the established pattern for other providers and aligns with the factory's registration approach.
internal/adapter/registry/profile/parsers.go (1)
23-24: LGTM!The parser registration for Lemonade follows the established pattern for other providers and correctly references the provider type constant.
docs/mkdocs.yml (1)
157-157: LGTM!The navigation entries for Lemonade SDK documentation are correctly placed in both the Backends and Provider APIs sections, maintaining consistency with other providers.
Also applies to: 179-179
internal/core/constants/providers.go (1)
5-5: LGTM!The provider constants for Lemonade follow the established naming conventions and are correctly placed among the existing provider definitions.
Also applies to: 14-14
docs/content/faq.md (1)
13-13: LGTM!The FAQ update correctly includes the newly supported backends (vLLM, SGLang, Lemonade SDK, LiteLLM) in the product description.
docs/content/getting-started/quickstart.md (1)
3-4: LGTM!The quickstart guide has been appropriately updated to include the new backends in the description, keywords, and recommended next steps section.
Also applies to: 227-227
internal/version/version.go (1)
34-34: LGTM!The addition of "lemonade" to the SupportedBackends list is correct and maintains alphabetical ordering.
internal/core/domain/profile.go (1)
5-5: LGTM!The ProfileLemonade constant is correctly defined and follows the established naming convention.
docs/content/configuration/overview.md (1)
206-210: LGTM!The documentation improvements enhance discoverability by linking to the integrations overview, making it easier for users to understand supported backend types.
internal/app/handlers/handler_provider_compatibility_test.go (2)
57-62: LGTM!The test case correctly validates that the OpenAI provider accepts Lemonade endpoints, which is appropriate given Lemonade's OpenAI-compatible API.
120-138: LGTM!The test coverage for the Lemonade provider is comprehensive, including both positive cases (accepts lemonade) and negative cases (rejects ollama and vllm). This follows the established testing pattern.
internal/app/handlers/handler_common.go (1)
82-84: LGTM!The addition of Lemonade to the staticProviders map is correct and maintains alphabetical ordering. This ensures Lemonade is recognised as a valid provider type.
internal/adapter/converter/factory_test.go (3)
23-27: LGTM!The test cases correctly validate that the converter factory returns the appropriate converters for lemonade, sglang, and vllm formats.
52-55: LGTM!The error message assertions ensure that unsupported format errors properly list lemonade and sglang as valid options.
60-74: LGTM!The test correctly validates that the supported formats count increased to 7 and that lemonade is properly registered in the format map.
docs/content/index.md (4)
3-4: LGTM!The documentation metadata is correctly updated to include Lemonade SDK and SGLang in the description and keywords.
20-20: LGTM!The badge correctly reflects native Lemonade support, upgraded from OpenAI-compatible status. This accurately represents the PR's integration of native Lemonade SDK support.
27-27: LGTM!The routing description accurately reflects the addition of Lemonade SDK (AMD Ryzen AI) and SGLang (with RadixAttention) as supported backends.
98-98: LGTM!The Backend-Type response header documentation correctly includes lemonade in the list of supported backend types.
internal/core/domain/model.go (1)
23-24: Approve Checkpoint and Recipe additionsThe new optional
CheckpointandRecipefields are correctly defined and fully integrated in parsing, conversion, and registry logic, with comprehensive tests covering all scenarios.docs/content/api-reference/overview.md (4)
17-18: LGTM! Playful reminder enhances user experience.The mnemonic "4 OLLA" is a clever way to help users remember the port number. This adds personality to the documentation while serving a practical purpose.
67-72: LGTM! Lemonade SDK section properly documented.The new section follows the established pattern for other backend API sections. The description correctly highlights ONNX and GGUF model support with hardware acceleration, aligning with Lemonade's capabilities.
108-108: LGTM! Backend type examples properly updated.The addition of
lemonadeandlitellmto the examples correctly reflects the expanded backend support.
112-112: X-Olla-Routing-Reason header is implemented
The header is set in internal/adapter/proxy/core/common.go (lines 184–190) when stats.RoutingDecision.Reason is non-empty.docs/content/integrations/overview.md (1)
13-25: LGTM! Table structure improves documentation clarity.The structured table provides better visibility of backend types and descriptions compared to the previous bullet list. The addition of Lemonade SDK and OpenAI Compatible entries is well-documented and consistent with other backend entries.
The note about using the
typein Endpoint Configurations is helpful for users.internal/app/handlers/handler_provider_models_test.go (2)
33-33: LGTM! Lemonade test setup follows existing patterns.The lemonade endpoint and model registration follows the established pattern used for other providers (ollama, lmstudio, openai, vllm). The single test model "Qwen2.5-0.5B-Instruct-CPU" aligns with Lemonade's naming conventions.
Also applies to: 64-70, 87-87, 93-93
183-194: LGTM! Expected model count and assertions properly updated.The comment correctly explains that the openai provider accepts models from all OpenAI-compatible endpoints (ollama, lmstudio, openai, vllm, and lemonade). The updated count from 5 to 6 and the assertion for "Qwen2.5-0.5B-Instruct-CPU" are correct.
internal/app/handlers/server_routes.go (1)
181-188: LGTM! Lemonade static provider follows established patterns.The static provider entry for Lemonade is consistent with other providers (SGLang, vLLM). The routes correctly configure:
- Model discovery endpoints (
api/v1/modelsandv1/models) using OpenAI format- Proxy route for forwarding requests to the backend
The structure aligns with the new backend integration requirements.
internal/adapter/unifier/default_unifier.go (3)
357-372: LGTM! Refactoring improves code organisation.The extraction of detail transfer logic into
applyModelDetailsandapplyModelInfohelpers improves readability and maintainability. The centralised return site makes the function flow clearer.
374-421: LGTM! Checkpoint and Recipe metadata properly handled.The
applyModelDetailshelper correctly transfers all ModelDetails fields to the Model and its metadata, including the new Checkpoint and Recipe fields (lines 415-420). The logic for handling family selection (Family vs. Families) is preserved.
423-434: LGTM! Top-level ModelInfo fields properly transferred.The
applyModelInfohelper correctly transfers Type, Description, and LastSeen from ModelInfo to Model metadata.readme.md (2)
10-14: LGTM! Provider badges accurately reflect backend support.The badges correctly represent:
- LiteLLM as native support
- Lemonade SDK as native support with AMD Ryzen AI optimisation
- LM Deploy as OpenAI-compatible
The visual hierarchy helps users quickly understand the integration types.
81-81: LGTM! Lemonade SDK table entry provides comprehensive information.The table entry clearly describes Lemonade SDK as AMD's local inference solution with specific hardware optimisations (AMD Ryzen AI NPU, IGPU via DirectML, and CPU) and supported model formats (ONNX and GGUF).
internal/adapter/registry/profile/lemonade.go (1)
1-27: LGTM! Data contracts are well-defined and documented.The Lemonade data structures are clean and follow established patterns:
LemonadeResponsematches OpenAI-compatible list formatLemonadeModelextends OpenAI fields with Lemonade-specific metadata- Inline documentation clearly distinguishes standard vs. Lemonade-specific fields
- Checkpoint and Recipe fields are properly documented with examples
The structure aligns with the API reference documentation (line 7 reference is helpful).
internal/adapter/registry/profile/lemonade_parser.go (2)
13-83: Parser implementation is well-structured with intelligent metadata extraction.The Parse method correctly:
- Handles empty input gracefully (lines 14-16)
- Skips models with empty IDs (lines 27-29)
- Extracts creation time and maps to ModifiedAt (lines 42-46)
- Stores Checkpoint metadata (lines 50-52)
- Extracts Publisher from checkpoint path (lines 56-59)—clever use of HuggingFace path convention
- Stores Recipe and infers Format via helper (lines 64-73)
- Only applies details when present (lines 75-77)
The logic is clean and follows established patterns from other parsers in the codebase.
85-95: LGTM! Format inference maps recipes to model formats correctly.The
inferFormatFromRecipehelper provides intelligent mapping:
oga-*recipes → ONNX formatllamacppandflmrecipes → GGUF formatThis enables proper routing and compatibility checking based on the inference engine. The implementation is straightforward and maintainable.
There was a problem hiding this comment.
Actionable comments posted: 4
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
config/profiles/lemonade.yaml(1 hunks)internal/adapter/converter/lemonade_converter_test.go(1 hunks)internal/adapter/registry/profile/lemonade_parser.go(1 hunks)internal/adapter/registry/profile/lemonade_parser_test.go(1 hunks)internal/core/constants/llm.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
- config/profiles/lemonade.yaml
- internal/adapter/registry/profile/lemonade_parser.go
- internal/adapter/registry/profile/lemonade_parser_test.go
🧰 Additional context used
📓 Path-based instructions (1)
{internal,pkg}/**/*_test.go
📄 CodeRabbit inference engine (CLAUDE.md)
Include Go benchmarks (Benchmark* functions) for critical paths, proxy engine comparisons, pooling efficiency, and circuit breaker behaviour
Files:
internal/adapter/converter/lemonade_converter_test.go
🧬 Code graph analysis (1)
internal/adapter/converter/lemonade_converter_test.go (6)
internal/adapter/converter/lemonade_converter.go (2)
NewLemonadeConverter(23-27)LemonadeConverter(18-20)internal/core/constants/providers.go (1)
ProviderTypeLemonade(5-5)internal/core/domain/unified_model.go (3)
UnifiedModel(15-31)AliasEntry(9-12)SourceEndpoint(34-44)internal/core/ports/model_converter.go (1)
ModelFilters(18-23)internal/adapter/registry/profile/lemonade.go (2)
LemonadeResponse(11-14)LemonadeModel(17-27)internal/adapter/converter/base_converter.go (2)
BaseConverter(8-10)NewBaseConverter(13-17)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: Cross-Platform Build Validation (windows-latest)
🔇 Additional comments (1)
internal/adapter/converter/lemonade_converter_test.go (1)
463-500: LGTM! Past issue resolved.The benchmark correctly uses
strconv.Itoa(i)(Lines 470, 472, 476) to convert integers to strings, addressing the issue flagged in the previous review. The benchmark is well-structured with a large dataset, memory allocation reporting, and proper validation.
| func TestLemonadeConverter_ConvertToFormat_OwnerFromModelID(t *testing.T) { | ||
| converter := NewLemonadeConverter() | ||
|
|
||
| model := &domain.UnifiedModel{ | ||
| ID: "test-model", | ||
| Aliases: []domain.AliasEntry{ | ||
| {Name: "custom-org/test-model", Source: constants.ProviderTypeLemonade}, | ||
| }, | ||
| } | ||
|
|
||
| result, err := converter.ConvertToFormat([]*domain.UnifiedModel{model}, ports.ModelFilters{}) | ||
|
|
||
| require.NoError(t, err) | ||
| response, ok := result.(profile.LemonadeResponse) | ||
| require.True(t, ok) | ||
|
|
||
| require.Len(t, response.Data, 1) | ||
| lemonadeModel := response.Data[0] | ||
|
|
||
| // Owner should be extracted from model ID with slash | ||
| assert.Equal(t, "custom-org", lemonadeModel.OwnedBy) | ||
| } |
There was a problem hiding this comment.
Clarify misleading comment about owner extraction.
Line 277's comment states "Owner should be extracted from model ID with slash", but the test extracts the owner from the alias ("custom-org/test-model" on Line 263), not the model ID ("test-model" on Line 261). The comment should clarify that the owner comes from the alias.
Apply this diff to clarify the comment:
- // Owner should be extracted from model ID with slash
+ // Owner should be extracted from the alias name with slash
assert.Equal(t, "custom-org", lemonadeModel.OwnedBy)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| func TestLemonadeConverter_ConvertToFormat_OwnerFromModelID(t *testing.T) { | |
| converter := NewLemonadeConverter() | |
| model := &domain.UnifiedModel{ | |
| ID: "test-model", | |
| Aliases: []domain.AliasEntry{ | |
| {Name: "custom-org/test-model", Source: constants.ProviderTypeLemonade}, | |
| }, | |
| } | |
| result, err := converter.ConvertToFormat([]*domain.UnifiedModel{model}, ports.ModelFilters{}) | |
| require.NoError(t, err) | |
| response, ok := result.(profile.LemonadeResponse) | |
| require.True(t, ok) | |
| require.Len(t, response.Data, 1) | |
| lemonadeModel := response.Data[0] | |
| // Owner should be extracted from model ID with slash | |
| assert.Equal(t, "custom-org", lemonadeModel.OwnedBy) | |
| } | |
| func TestLemonadeConverter_ConvertToFormat_OwnerFromModelID(t *testing.T) { | |
| converter := NewLemonadeConverter() | |
| model := &domain.UnifiedModel{ | |
| ID: "test-model", | |
| Aliases: []domain.AliasEntry{ | |
| {Name: "custom-org/test-model", Source: constants.ProviderTypeLemonade}, | |
| }, | |
| } | |
| result, err := converter.ConvertToFormat([]*domain.UnifiedModel{model}, ports.ModelFilters{}) | |
| require.NoError(t, err) | |
| response, ok := result.(profile.LemonadeResponse) | |
| require.True(t, ok) | |
| require.Len(t, response.Data, 1) | |
| lemonadeModel := response.Data[0] | |
| // Owner should be extracted from the alias name with slash | |
| assert.Equal(t, "custom-org", lemonadeModel.OwnedBy) | |
| } |
🤖 Prompt for AI Agents
internal/adapter/converter/lemonade_converter_test.go around lines 257 to 278:
the inline comment on line 277 incorrectly states the owner is extracted from
the model ID; update that comment to state the owner is extracted from the alias
value (e.g., "custom-org/test-model") which contains the slash, so change the
comment to clarify the owner comes from the alias rather than the model.ID.
| const ( | ||
| BackendLlamaCpp = "llamacpp" | ||
| ) |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major
🧩 Analysis chain
Verify the constant's purpose and naming.
The PR is focused on Lemonade backend integration, but this file introduces a BackendLlamaCpp constant. Based on the Lemonade implementation, "llamacpp" appears to be a recipe/inference engine type rather than a backend. This raises two concerns:
- Is this constant intended for Lemonade's recipe field or for a separate LlamaCpp backend?
- If it's for recipes, should it be named
RecipeLlamaCppinstead ofBackendLlamaCppfor clarity?
Run the following script to verify how this constant is used:
🏁 Script executed:
#!/bin/bash
# Description: Check usage of BackendLlamaCpp constant across the codebase
# Search for references to BackendLlamaCpp
rg -nP --type=go -C3 'BackendLlamaCpp'
# Search for "llamacpp" string literals to understand context
rg -nP --type=go -C3 '"llamacpp"'Length of output: 6080
Rename BackendLlamaCpp to RecipeLlamaCpp
Update internal/core/constants/llm.go (and its references in the Lemonade parser) so the constant reflects its use as a recipe type.
- const BackendLlamaCpp = "llamacpp"
+ const RecipeLlamaCpp = "llamacpp"Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In internal/core/constants/llm.go around lines 3 to 5, the constant
BackendLlamaCpp should be renamed to RecipeLlamaCpp to reflect its role as a
recipe type; update the constant name in this file and then find and replace all
references across the codebase (including the Lemonade parser) to use
RecipeLlamaCpp, update any tests or switch/case branches that match on the old
name, and ensure import paths and compilation by running a full build and tests
after renaming.
There was a problem hiding this comment.
Actionable comments posted: 0
♻️ Duplicate comments (1)
internal/adapter/converter/lemonade_converter_test.go (1)
276-277: Correct the alias ownership comment.The owner is derived from the Lemonade alias (
custom-org/test-model), not from the unified model ID, so this note misleads future maintainers. Please update the comment to reflect the alias source.
🧹 Nitpick comments (3)
internal/core/constants/llm.go (3)
7-7: Consider consistent casing for acronyms.The constant
RecipeOnnxuses mixed case (Onnx), whilstRecipeFLMandRecipeGGUFuse all-caps for their acronyms. If ONNX is an acronym (Open Neural Network Exchange), consider using all-caps for consistency with Go conventions.Apply this diff for consistent acronym casing:
- RecipeOnnx = "onnx" + RecipeONNX = "onnx"Note: This would require updating all references to
RecipeOnnxthroughout the codebase.
3-8: Add documentation for the constants.Consider adding package-level and constant-level documentation to explain the purpose of these recipe constants and their relationship to the Lemonade backend integration. This improves maintainability and helps developers understand usage context.
Example documentation:
+// Package constants defines shared constant values used across the application, +// including LLM backend recipe identifiers for format detection and conversion. package constants +// Recipe constants define supported Lemonade backend inference engine formats. +// These are used during model metadata parsing and format detection. const ( + // RecipeLlamaCpp represents the llama.cpp inference engine format RecipeLlamaCpp = "llamacpp" + // RecipeFLM represents the FLM (Fast Language Model) format RecipeFLM = "flm" + // RecipeGGUF represents the GGUF (GPT-Generated Unified Format) format RecipeGGUF = "gguf" + // RecipeOnnx represents the ONNX (Open Neural Network Exchange) format RecipeOnnx = "onnx" )
3-8: Consider using a custom type for type safety.Defining a custom
Recipetype would provide compile-time type safety, prevent accidental misuse, and enable attaching methods for validation or conversion logic in the future.Example refactor with custom type:
+// Recipe represents a Lemonade backend inference engine format identifier. +type Recipe string + +// Recipe constants define supported Lemonade backend formats. const ( - RecipeLlamaCpp = "llamacpp" - RecipeFLM = "flm" - RecipeGGUF = "gguf" - RecipeOnnx = "onnx" + RecipeLlamaCpp Recipe = "llamacpp" + RecipeFLM Recipe = "flm" + RecipeGGUF Recipe = "gguf" + RecipeOnnx Recipe = "onnx" )This would require updating function signatures that accept or return these values to use the
Recipetype instead ofstring.
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
internal/adapter/converter/lemonade_converter_test.go(1 hunks)internal/adapter/registry/profile/lemonade_parser.go(1 hunks)internal/core/constants/llm.go(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- internal/adapter/registry/profile/lemonade_parser.go
🧰 Additional context used
📓 Path-based instructions (1)
{internal,pkg}/**/*_test.go
📄 CodeRabbit inference engine (CLAUDE.md)
Include Go benchmarks (Benchmark* functions) for critical paths, proxy engine comparisons, pooling efficiency, and circuit breaker behaviour
Files:
internal/adapter/converter/lemonade_converter_test.go
🧬 Code graph analysis (1)
internal/adapter/converter/lemonade_converter_test.go (6)
internal/adapter/converter/lemonade_converter.go (2)
NewLemonadeConverter(23-27)LemonadeConverter(18-20)internal/core/constants/providers.go (1)
ProviderTypeLemonade(5-5)internal/core/domain/unified_model.go (3)
UnifiedModel(15-31)AliasEntry(9-12)SourceEndpoint(34-44)internal/core/ports/model_converter.go (1)
ModelFilters(18-23)internal/adapter/registry/profile/lemonade.go (2)
LemonadeResponse(11-14)LemonadeModel(17-27)internal/adapter/converter/base_converter.go (2)
BaseConverter(8-10)NewBaseConverter(13-17)
🔇 Additional comments (1)
internal/core/constants/llm.go (1)
1-8: Previous feedback addressed: constant renamed appropriately.The previous review comment suggested renaming
BackendLlamaCpptoRecipeLlamaCppto better reflect its role as a recipe type rather than a backend identifier. This feedback has been properly addressed in the current implementation.
Integration of AMD enhanced Lemonade SDK.
Summary by CodeRabbit
New Features
Documentation