Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@thushan
Copy link
Owner

@thushan thushan commented Sep 26, 2025

This PR implements the SGLang backend.

Summary by CodeRabbit

  • New Features

    • Added native SGLang backend support: OpenAI‑compatible endpoints for models, routing and provider recognition across the app; SGLang now listed in supported backends and response headers.
    • Exposes SGLang health, metrics and version endpoints with Prometheus metrics and model-specific resource/timeout hints.
  • Documentation

    • Comprehensive SGLang integration guide and API reference, navigation and README updates with usage examples (chat, generation, batch, vision, speculative decoding) and monitoring.

@coderabbitai
Copy link

coderabbitai bot commented Sep 26, 2025

Walkthrough

Adds SGLang as a first-class backend/provider: new profile (sglang.yaml), parser, converter, constants, routes, and documentation. Updates navigation, API reference, README, and profiles index. Tests added/updated for factory and new converter. vLLM profile gains a home URL. Supported backends list expanded to include sglang.

Changes

Cohort / File(s) Summary
Profiles: SGLang add, vLLM tweak
config/profiles/sglang.yaml, config/profiles/vllm.yaml, config/profiles/README.md
New SGLang profile with endpoints, model/resource/metrics configuration; vLLM adds home_url; profiles README updated to include sglang and adjust OpenAI description.
Docs: Index, Overview, API, Integration, Nav
docs/content/index.md, docs/content/integrations/overview.md, docs/content/api-reference/overview.md, docs/content/integrations/backend/sglang.md, docs/mkdocs.yml, docs/content/api-reference/sglang.md, docs/content/configuration/reference.md, docs/content/development/contributing.md
Adds SGLang documentation pages and nav entries; inserts SGLang into API reference and site content; small anchor and contributing additions.
Converter: SGLang support
internal/adapter/converter/sglang_converter.go, internal/adapter/converter/factory.go, internal/adapter/converter/factory_test.go
Implements SGLangConverter, registers it in factory, and updates factory test to expect sglang format.
Parser & Profile types: SGLang
internal/adapter/registry/profile/sglang.go, internal/adapter/registry/profile/sglang_parser.go, internal/adapter/registry/profile/parsers.go
Adds SGLang OpenAI-compatible model types and a parser; registers parser case for sglang.
Routing & Provider wiring
internal/app/handlers/server_routes.go, internal/app/handlers/handler_common.go
Registers SGLang provider routes, model listing handler and marks provider supported.
Core constants & versioning
internal/core/constants/providers.go, internal/core/domain/profile.go, internal/version/version.go
Adds ProviderTypeSGLang/display constant, ProfileSGLang and includes sglang in supported backends.
Tests: Converter
internal/adapter/converter/sglang_converter_test.go
New comprehensive tests covering conversion, metadata handling, owner/alias logic, filtering and performance.
Top-level README
readme.md
Reworks provider list into a table and adds SGLang badge/entry.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant C as Client
  participant GW as Olla API Gateway
  participant RH as Routes/Handlers
  participant CV as Model Converter
  participant SG as SGLang Server

  Note over C,GW: List models via OpenAI-compatible endpoint
  C->>GW: GET /v1/models (X-Olla-Backend-Type: sglang)
  GW->>RH: genericProviderModelsHandler(sglang, openai)
  RH->>SG: GET /v1/models (SGLang)
  SG-->>RH: SGLang model list (JSON)
  RH->>CV: Convert SGLang->OpenAI model list
  CV-->>RH: OpenAI-compatible models
  RH-->>C: 200 OK, models (X-Olla-Backend-Type: sglang)

  rect rgba(230,245,255,0.6)
    Note right of CV: New/changed: SGLang converter — owner/parent/vision/radix/spec-decoding fields
  end
Loading
sequenceDiagram
  autonumber
  participant D as Discovery Job
  participant SG as SGLang Server
  participant PR as SGLang Parser
  participant REG as Model Registry

  Note over D,REG: Periodic backend discovery
  D->>SG: GET /v1/models
  SG-->>D: SGLangResponse
  D->>PR: Parse SGLangResponse
  PR-->>D: []*ModelInfo (type=sglang, details)
  D->>REG: Upsert models
  REG-->>D: Ack
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

enhancement, llm-backend

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “feat: backend/sglang” clearly indicates that this pull request introduces a new feature related to the SGLang backend, which aligns directly with the extensive code and documentation changes for SGLang integration described in the PR.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch integration/sglang

Tip

👮 Agentic pre-merge checks are now available in preview!

Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.

  • Built-in checks – Quickly apply ready-made checks to enforce title conventions, require pull request descriptions that follow templates, validate linked issues for compliance, and more.
  • Custom agentic checks – Define your own rules using CodeRabbit’s advanced agentic capabilities to enforce organization-specific policies and workflows. For example, you can instruct CodeRabbit’s agent to verify that API documentation is updated whenever API schema files are modified in a PR. Note: Upto 5 custom checks are currently allowed during the preview period. Pricing for this feature will be announced in a few weeks.

Please see the documentation for more information.

Example:

reviews:
  pre_merge_checks:
    custom_checks:
      - name: "Undocumented Breaking Changes"
        mode: "warning"
        instructions: |
          Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).

Please share your feedback with us on this Discord post.


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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/mkdocs.yml (1)

153-178: MkDocs nav still misses the new SGLang docs.

mkdocs --strict is failing because the navigation entries point to integrations/backend/sglang.md and api-reference/sglang.md, but those files aren’t present in the repo. Please add the missing documents (or fix the paths) so the nav links resolve.

Based on the pipeline logs

🧹 Nitpick comments (6)
config/profiles/README.md (1)

22-23: Minor wording nit.

If you update openai.yaml’s blurb again later, consider mirroring the other descriptions (“OpenAI-compatible API (generic profile)”) to keep the list uniform.

internal/adapter/converter/factory_test.go (1)

55-68: Tighten the assertions for SGLang support

Since the factory now emits a sixth converter, let’s assert on it directly to avoid silent regressions. Please extend the “GetConverter returns correct converters” table (and optionally the unsupported-format error assertions) to cover "sglang" explicitly. That gives us deterministic coverage that this new backend stays wired in.

internal/adapter/converter/sglang_converter.go (4)

52-69: Make "created" deterministic and source from model when possible.

Using time.Now() at conversion time makes outputs non-deterministic and can drift from the model’s actual creation/ingest time. Prefer LastSeen or a metadata-provided timestamp, falling back to now as a last resort.

Apply this diff:

-	now := time.Now().Unix()
+	created := model.LastSeen.Unix()
+	if created == 0 {
+		if v := c.extractMetadataInt64(model.Metadata, "created"); v > 0 {
+			created = v
+		} else {
+			created = time.Now().Unix()
+		}
+	}
@@
 	sglangModel := &profile.SGLangModel{
 		ID:      modelID,
 		Object:  "model",
-		Created: now,
+		Created: created,
 		OwnedBy: c.determineOwner(modelID),
 		Root:    modelID, // SGLang typically sets root to the model ID
 	}

71-74: Fallback max context length from metadata if domain field is empty.

Some sources may only provide max_model_len in metadata; add a fallback.

 	// Set max context length if available
 	if model.MaxContextLength != nil && *model.MaxContextLength > 0 {
 		sglangModel.MaxModelLen = model.MaxContextLength
 	}
+	if sglangModel.MaxModelLen == nil {
+		if max := c.extractMetadataInt64(model.Metadata, "max_model_len"); max > 0 {
+			sglangModel.MaxModelLen = &max
+		}
+	}

106-114: Support common "parent" key as well as "parent_model".

Improves compatibility with varied metadata sources.

 func (c *SGLangConverter) getParentModel(model *domain.UnifiedModel) string {
 	// Check metadata first
 	if parentModel := c.ExtractMetadataString(model.Metadata, "parent_model"); parentModel != "" {
 		return parentModel
 	}
+	if parentModel := c.ExtractMetadataString(model.Metadata, "parent"); parentModel != "" {
+		return parentModel
+	}
 
 	return ""
 }

140-152: Harden metadata int parsing (strings).

Metadata often carries numbers as strings; parse them too.

 func (c *SGLangConverter) extractMetadataInt64(metadata map[string]interface{}, key string) int64 {
 	if val, ok := metadata[key].(int64); ok {
 		return val
 	}
 	if val, ok := metadata[key].(int); ok {
 		return int64(val)
 	}
 	if val, ok := metadata[key].(float64); ok {
 		return int64(val)
 	}
+	if val, ok := metadata[key].(string); ok {
+		if i, err := strconv.ParseInt(val, 10, 64); err == nil {
+			return i
+		}
+		if f, err := strconv.ParseFloat(val, 64); err == nil {
+			return int64(f)
+		}
+	}
 	return 0
 }

Add the import:

 import (
+	"strconv"
 	"strings"
 	"time"
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between d2bc4af and 7aeb09f.

📒 Files selected for processing (21)
  • config/profiles/README.md (1 hunks)
  • config/profiles/sglang.yaml (1 hunks)
  • config/profiles/vllm.yaml (1 hunks)
  • docs/content/api-reference/overview.md (2 hunks)
  • docs/content/index.md (3 hunks)
  • docs/content/integrations/backend/sglang.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 (2 hunks)
  • internal/adapter/converter/sglang_converter.go (1 hunks)
  • internal/adapter/converter/sglang_converter_test.go (1 hunks)
  • internal/adapter/registry/profile/parsers.go (1 hunks)
  • internal/adapter/registry/profile/sglang.go (1 hunks)
  • internal/adapter/registry/profile/sglang_parser.go (1 hunks)
  • internal/app/handlers/handler_common.go (1 hunks)
  • internal/app/handlers/server_routes.go (1 hunks)
  • internal/core/constants/providers.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 (3)
config/profiles/{ollama,lmstudio,litellm,openai,vllm}.yaml

📄 CodeRabbit inference engine (CLAUDE.md)

Provider-specific profiles must reside under config/profiles/ with the specified filenames

Files:

  • config/profiles/vllm.yaml
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/server_routes.go
  • internal/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/adapter/converter/factory_test.go
  • internal/adapter/converter/sglang_converter_test.go
🧠 Learnings (3)
📚 Learning: 2025-09-23T08:30:20.348Z
Learnt from: CR
PR: thushan/olla#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-23T08:30:20.348Z
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.md
  • docs/content/index.md
📚 Learning: 2025-09-23T08:30:20.348Z
Learnt from: CR
PR: thushan/olla#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-23T08:30:20.348Z
Learning: Applies to internal/adapter/proxy/**/service.go : Proxy services must include response headers: `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.md
  • docs/content/index.md
📚 Learning: 2025-09-23T08:30:20.348Z
Learnt from: CR
PR: thushan/olla#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-23T08:30:20.348Z
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:

  • config/profiles/README.md
🧬 Code graph analysis (7)
internal/app/handlers/server_routes.go (1)
internal/core/constants/providers.go (2)
  • ProviderTypeSGLang (8-8)
  • ProviderTypeOpenAI (6-6)
internal/adapter/registry/profile/sglang_parser.go (2)
internal/core/domain/model.go (2)
  • ModelInfo (26-33)
  • ModelDetails (11-24)
internal/adapter/registry/profile/sglang.go (1)
  • SGLangResponse (4-7)
internal/adapter/converter/sglang_converter_test.go (6)
internal/adapter/converter/sglang_converter.go (2)
  • NewSGLangConverter (23-27)
  • SGLangConverter (18-20)
internal/core/constants/providers.go (1)
  • ProviderTypeSGLang (8-8)
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/sglang.go (1)
  • SGLangResponse (4-7)
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 (1)
  • ProviderTypeSGLang (8-8)
internal/adapter/converter/factory.go (1)
internal/adapter/converter/sglang_converter.go (1)
  • NewSGLangConverter (23-27)
internal/adapter/converter/sglang_converter.go (5)
internal/adapter/registry/profile/sglang.go (2)
  • SGLangResponse (4-7)
  • SGLangModel (10-26)
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)
  • ProviderTypeSGLang (8-8)
internal/core/domain/unified_model.go (1)
  • UnifiedModel (15-31)
internal/adapter/registry/profile/parsers.go (1)
internal/core/constants/providers.go (1)
  • ProviderTypeSGLang (8-8)
🪛 GitHub Actions: Deploy Documentation
docs/content/api-reference/overview.md

[error] 1-1: mkdocs build --clean --strict failed. Process exited with code 1 due to strict mode warnings.


[warning] 1-1: Doc file 'api-reference/overview.md' contains a link 'sglang.md', but the target 'api-reference/sglang.md' is not found among documentation files.

docs/content/integrations/overview.md

[error] 1-1: mkdocs build --clean --strict failed. Process exited with code 1 due to strict mode warnings.

docs/content/index.md

[error] 1-1: mkdocs build --clean --strict failed. Process exited with code 1 due to strict mode warnings.

docs/mkdocs.yml

[error] 1-1: mkdocs build --clean --strict failed. Process exited with code 1 due to strict mode warnings.

docs/content/integrations/backend/sglang.md

[error] 1-1: mkdocs build --clean --strict failed. Process exited with code 1 due to strict mode warnings.

🪛 markdownlint-cli2 (0.18.1)
docs/content/integrations/backend/sglang.md

754-754: Emphasis used instead of a heading

(MD036, no-emphasis-as-heading)

🔇 Additional comments (16)
internal/adapter/registry/profile/parsers.go (1)

25-26: SGLang parser wiring looks solid.

Nice work adding the SGLang case into the parser switch — this keeps provider selection consistent with the other backends.

config/profiles/README.md (1)

21-22: README aligns with the new profile.

Listing sglang.yaml alongside the other built-ins keeps the documentation accurate.

readme.md (1)

11-81: Table update is clear and accurate.

The badges and supported-backend table now reflect SGLang without breaking the existing layout. Nice refresh.

config/profiles/sglang.yaml (1)

1-244: Profile structure matches the existing schema.

The routing, detection, resource, and metrics sections line up with the other provider profiles, so this should load cleanly through the factory.

config/profiles/vllm.yaml (1)

3-3: Home URL addition looks good.

Adding the upstream link keeps the profile metadata consistent with SGLang.

internal/app/handlers/handler_common.go (1)

82-87: Static provider list updated correctly.

Including sglang here keeps isProviderSupported in sync with the newly registered routes.

internal/adapter/converter/factory.go (1)

25-25: Factory registration looks good

Nice work wiring the SGLang converter straight into the factory; this keeps the supported formats list authoritative without extra branching.

internal/core/domain/profile.go (1)

6-6: Profile constant aligned

Adding ProfileSGLang alongside the existing profiles keeps the domain layer consistent with the new backend. Nothing further needed here.

internal/version/version.go (1)

33-36: Version info updated correctly

Including sglang in SupportedBackends makes the version banner accurately advertise the new capability. All good.

internal/app/handlers/server_routes.go (1)

214-218: Static routing is consistent

The static provider map now covers SGLang with the expected OpenAI-compatible models endpoint plus proxy path, mirroring the other backends. Looks sound.

internal/core/constants/providers.go (1)

8-16: Constants synced

Provider type/display additions for SGLang line up with the broader integration work. No concerns.

docs/content/index.md (2)

16-18: Docs badge & copy refreshed

Good to see SGLang represented alongside the other native backends; the copy stays accurate and consistent.


98-99: Header table remains accurate

Appending sglang to the backend-type header keeps the docs truthful after the new integration. Looks great.

internal/adapter/registry/profile/sglang.go (2)

3-7: LGTM: response envelope mirrors OpenAI /v1/models.

object + data shape looks right for downstream consumers.


9-26: Model shape looks solid; optional metadata via pointers is a good call.

Fields and JSON tags align with OpenAI-style models while allowing SGLang extras to be omitted cleanly.

internal/adapter/converter/sglang_converter.go (1)

33-48: Response envelope looks correct.

object: "list" with a flat data array is consistent with OpenAI-style listings.

* [Ollama](./backend/ollama.md) - native support for [Ollama](https://github.com/ollama/ollama), including model unification.
* [LM Studio](./backend/lmstudio.md) - native support for [LM Studio](https://lmstudio.ai/), including model unification.
* [vLLM](./backend/vllm.md) - native support for [vLLM](https://github.com/vllm-project/vllm), including model unification.
* [SGLang](./backend/sglang.md) - native support for [SGLang](https://github.com/sgl-project/sglang) with RadixAttention and Frontend Language, including model unification and vision support.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Broken link to the new SGLang backend doc

MkDocs strict mode fails when a referenced page is missing. The freshly added [SGLang](./backend/sglang.md) link resolves to 404 because docs/content/integrations/backend/sglang.md isn’t present (or is misnamed), triggering the pipeline error you’re seeing. Please add the page—or fix the path/name—so the link builds cleanly.

🤖 Prompt for AI Agents
In docs/content/integrations/overview.md at line 18 the link
[SGLang](./backend/sglang.md) points to a missing or misnamed page causing
MkDocs strict mode to fail; either add the missing file at
docs/content/integrations/backend/sglang.md with the expected frontmatter and
content, or update the link to the correct existing path/filename (watch for
case sensitivity and the exact directory name), then verify with a local mkdocs
build to ensure the link resolves.

Comment on lines +87 to +95
// findSGLangNativeName looks for the native SGLang name from aliases
func (c *SGLangConverter) findSGLangNativeName(model *domain.UnifiedModel) string {
// Use base converter to find SGLang-specific alias
alias, found := c.BaseConverter.FindProviderAlias(model)
if found {
return alias
}
return ""
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Confirm BaseConverter helpers exist and are wired.

FindProviderAlias must be implemented on BaseConverter for this to compile and to constrain to the SGLang provider. Likewise for ExtractMetadataString/Bool and HasCapability.

Run:


🏁 Script executed:

#!/bin/bash
# Verify BaseConverter helper methods used by SGLangConverter exist.
rg -nP -C2 'func\s+\(\s*\*?BaseConverter\s*\)\s+FindProviderAlias\s*\('
rg -nP -C2 'func\s+\(\s*\*?BaseConverter\s*\)\s+ExtractMetadata(String|Bool)\s*\('
rg -nP -C2 'func\s+\(\s*\*?BaseConverter\s*\)\s+HasCapability\s*\('

# Also ensure filterModels is defined in the converter package.
rg -nP -C2 'func\s+filterModels\s*\(' --type go

Length of output: 541


Implement missing BaseConverter helper methods
BaseConverter currently lacks the methods used by SGLangConverter:

  • FindProviderAlias(model *domain.UnifiedModel) (string, bool)
  • ExtractMetadataString/Bool
  • HasCapability
    Define these in internal/adapter/converter/unified_converter.go so SGLangConverter compiles and behaves as expected.
🤖 Prompt for AI Agents
In internal/adapter/converter/unified_converter.go (add near the BaseConverter
type definition), implement the missing helper methods used by SGLangConverter:
define FindProviderAlias(model *domain.UnifiedModel) (string, bool) to search
the model for provider-specific aliases and return the matching alias plus a
found flag; add ExtractMetadataString(model *domain.UnifiedModel, key string)
(string, bool) and ExtractMetadataBool(model *domain.UnifiedModel, key string)
(bool, bool) to safely read typed values from the model.Metadata map (returning
value and present flag); and add HasCapability(model *domain.UnifiedModel,
capability string) bool to check the model’s capabilities list/set. Each method
should handle nil maps/slices safely and avoid panics so SGLangConverter
compiles and behaves as expected.

Comment on lines +3 to +20
import (
"fmt"
"time"

"github.com/thushan/olla/internal/core/domain"
)

type sglangParser struct{}

func (p *sglangParser) Parse(data []byte) ([]*domain.ModelInfo, error) {
if len(data) == 0 {
return make([]*domain.ModelInfo, 0), nil
}

var response SGLangResponse
if err := json.Unmarshal(data, &response); err != nil {
return nil, fmt.Errorf("failed to parse SGLang response: %w", err)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Add the missing encoding/json import.

Line 18 calls json.Unmarshal, but encoding/json isn’t imported, so this file will fail to compile. Please add the import.

 import (
+	"encoding/json"
 	"fmt"
 	"time"
📝 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.

Suggested change
import (
"fmt"
"time"
"github.com/thushan/olla/internal/core/domain"
)
type sglangParser struct{}
func (p *sglangParser) Parse(data []byte) ([]*domain.ModelInfo, error) {
if len(data) == 0 {
return make([]*domain.ModelInfo, 0), nil
}
var response SGLangResponse
if err := json.Unmarshal(data, &response); err != nil {
return nil, fmt.Errorf("failed to parse SGLang response: %w", err)
}
import (
"encoding/json"
"fmt"
"time"
"github.com/thushan/olla/internal/core/domain"
)
type sglangParser struct{}
func (p *sglangParser) Parse(data []byte) ([]*domain.ModelInfo, error) {
if len(data) == 0 {
return make([]*domain.ModelInfo, 0), nil
}
var response SGLangResponse
if err := json.Unmarshal(data, &response); err != nil {
return nil, fmt.Errorf("failed to parse SGLang response: %w", err)
}
🤖 Prompt for AI Agents
internal/adapter/registry/profile/sglang_parser.go lines 3-20: the code calls
json.Unmarshal but encoding/json is not imported; add the import "encoding/json"
to the import block (alongside fmt and time) so the json package is available
and the file compiles.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6ab4a15 and 77a4b8c.

📒 Files selected for processing (1)
  • internal/adapter/converter/sglang_converter_test.go (1 hunks)
🧰 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/sglang_converter_test.go
🧠 Learnings (1)
📚 Learning: 2025-09-23T08:30:20.348Z
Learnt from: CR
PR: thushan/olla#0
File: CLAUDE.md:0-0
Timestamp: 2025-09-23T08:30:20.348Z
Learning: Applies to {internal,pkg}/**/*_test.go : Include Go benchmarks (Benchmark* functions) for critical paths, proxy engine comparisons, pooling efficiency, and circuit breaker behaviour

Applied to files:

  • internal/adapter/converter/sglang_converter_test.go
🧬 Code graph analysis (1)
internal/adapter/converter/sglang_converter_test.go (6)
internal/adapter/converter/sglang_converter.go (2)
  • NewSGLangConverter (23-27)
  • SGLangConverter (18-20)
internal/core/constants/providers.go (1)
  • ProviderTypeSGLang (8-8)
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/sglang.go (1)
  • SGLangResponse (4-7)
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)

Comment on lines +333 to +365
converter := NewSGLangConverter()

// Create a large number of models to test performance
models := make([]*domain.UnifiedModel, 1000)
for i := 0; i < 1000; i++ {
models[i] = &domain.UnifiedModel{
ID: "performance-test-model-" + string(rune(i)),
MaxContextLength: func() *int64 { v := int64(8192); return &v }(),
Aliases: []domain.AliasEntry{
{Name: "performance-test-model-" + string(rune(i)), Source: constants.ProviderTypeSGLang},
},
}
}

// Report memory allocations
b.ReportAllocs()
b.ResetTimer()

for i := 0; i < b.N; i++ {
result, err := converter.ConvertToFormat(models, ports.ModelFilters{})
if err != nil {
b.Fatalf("ConvertToFormat failed: %v", err)
}

response, ok := result.(profile.SGLangResponse)
if !ok {
b.Fatal("Result is not SGLangResponse")
}

if len(response.Data) != 1000 {
b.Fatalf("Expected 1000 models, got %d", len(response.Data))
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Replace rune casting with decimal suffix in benchmark data

Using string(rune(i)) injects control characters for the first entries (e.g. \x00) and non-ASCII glyphs afterwards, so the benchmark feeds malformed/opaque IDs and aliases into the converter. That makes any downstream JSON expectations brittle and hides regressions. Let’s stringify the loop index properly before concatenation.

Apply this diff to fix the issue:

@@
-import (
-	"testing"
+import (
+	"strconv"
+	"testing"
@@
-	for i := 0; i < 1000; i++ {
-		models[i] = &domain.UnifiedModel{
-			ID:               "performance-test-model-" + string(rune(i)),
+	for i := 0; i < 1000; i++ {
+		suffix := strconv.Itoa(i)
+		models[i] = &domain.UnifiedModel{
+			ID:               "performance-test-model-" + suffix,
@@
-			Aliases: []domain.AliasEntry{
-				{Name: "performance-test-model-" + string(rune(i)), Source: constants.ProviderTypeSGLang},
-			},
+			Aliases: []domain.AliasEntry{
+				{Name: "performance-test-model-" + suffix, Source: constants.ProviderTypeSGLang},
+			},
🤖 Prompt for AI Agents
internal/adapter/converter/sglang_converter_test.go around lines 333 to 365: the
benchmark builds model IDs and alias names using string(rune(i)) which yields
control/non-ASCII characters; replace that with a decimal string conversion
(e.g., strconv.Itoa(i) or fmt.Sprintf("%d", i)) when concatenating the loop
index so IDs and aliases are valid ASCII decimal strings; update imports to
include strconv (or fmt) as needed and run tests to verify behavior.

@thushan thushan merged commit 444e577 into main Oct 1, 2025
8 checks passed
@thushan thushan deleted the integration/sglang branch October 1, 2025 23:14
@coderabbitai coderabbitai bot mentioned this pull request Oct 8, 2025
@coderabbitai coderabbitai bot mentioned this pull request Oct 22, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants