refactor(models): consolidate duplication into shared httpx/observe/spec layers#1092
Open
lyingbug wants to merge 1 commit into
Open
refactor(models): consolidate duplication into shared httpx/observe/spec layers#1092lyingbug wants to merge 1 commit into
lyingbug wants to merge 1 commit into
Conversation
…pec layers
Collapses 79 → 55 files and ~10.3k → ~9k LOC without changing any public
interface, wire format, or behavior. Adding a new LLM provider now takes one
declarative spec entry instead of copy-pasting a ~200-line provider file.
Key changes:
- New internal/{httpx,observe,modelconfig} helpers replace 11 copies of
doRequestWithRetry, 5 Langfuse wrappers, 5 LLM-debug wrappers, and 5
ConfigFromModel functions.
- embedding/: 6 provider files → providers.go + runner.go (declarative spec
table + shared HTTP runner). Ollama and WeKnoraCloud keep own impls.
- rerank/: 5 provider files → providers.go + runner.go, same pattern.
- provider/: 25 single-struct files → providers.go data table, with the 4
test-referenced struct names (OpenAIProvider/AliyunProvider/MiniMaxProvider/
ZhipuProvider) preserved as thin shells.
- chat/remote_api.go (978 lines) split into remote.go + remote_nonstream.go +
remote_stream.go + remote_tools.go by responsibility.
- Model-family detectors (IsQwen3/IsDeepSeek/IsLKEAP*) consolidated into
provider/model_family.go; BaseURL constants into provider/urls.go.
Public API unchanged: Chat / Embedder / Reranker / VLM / ASR interfaces,
NewXxx factories, ConfigFromModel, provider.{List,ListByModelType}, and the
utils.ChunkSlice + utils/ollama paths that are imported by application/ and
handler/ all keep their signatures. RemoteAPIChat.BuildChatCompletionRequest
(asserted on in remote_api_test.go) stays a method with the same shape.
Verified: all internal/models tests pass; go build ./... clean; the 3
pre-existing test failures in application/{repository,service} are unchanged
(SQLite schema mismatch, unrelated).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Consolidates the
internal/models/package (79 → 55 files, ~10.3k → ~9.0k LOC) without changing any public interface, wire format, or runtime behavior. Adding a new LLM provider now takes a ~15-line declarative spec entry instead of copy-pasting a ~200-line per-provider file.What changed
Shared infrastructure (new)
internal/models/internal/httpx/— oneDoPOSTwith exponential-backoff retry replaces 11 near-identicaldoRequestWithRetrycopies across embedding/rerank providers; aStreamingClientfor raw chat streams.internal/models/internal/observe/— genericWrap/WrapStreamdecorator machinery replaces 5 Langfuse wrappers + 5 LLM-debug wrappers.internal/models/internal/modelconfig/— oneFromModelhelper factors out the sharedtypes.Model → Configmapping.Per-sub-package consolidation
embedding/:openai.go,jina.go,nvidia.go,azure_openai.go,volcengine.go,aliyun.go(6 files, ~1.2k LOC) → oneproviders.godeclarative spec table +runner.goshared HTTP runner. Ollama and WeKnoraCloud keep their own impls (different transports).rerank/:openai/aliyun/jina/zhipu/nvidiareranker files (5 files, ~660 LOC) →providers.go+runner.go. WeKnoraCloud keeps its signer-based impl.provider/: 25 single-struct files consolidated intoproviders.go(data table) +urls.go(BaseURL constants) +model_family.go(IsQwen3/IsDeepSeek/IsLKEAP*detectors). The 4 struct names (OpenAIProvider,AliyunProvider,MiniMaxProvider,ZhipuProvider) thatprovider_test.goconstructs directly are preserved as thin shells.chat/remote_api.go(978 lines) split by responsibility intoremote.go(struct + constructor + request builder),remote_nonstream.go(Chat + chatWithRawHTTP),remote_stream.go(ChatStream + streamState + SSE handling), andremote_tools.go(tool-call delta processing + final_answer/thinking streaming).chat/,embedding/,rerank/,vlm/,asr/: each sub-package'slangfuse_wrapper.go+llm_debug*.gocollapsed into oneobserve.gousing the shared decorator.Guardrails verified
All externally-referenced symbols are unchanged:
chat.Chat,embedding.Embedder/EmbedderPooler,rerank.Reranker,vlm.VLM,asr.ASR.NewChat,NewEmbedder,NewReranker,NewVLM,NewVLMFromLegacyConfig,NewASR.ConfigFromModelin each sub-package.chat.{Message, ChatOptions, Tool, ToolCall, FunctionCall, FunctionDef},rerank.RankResult,asr.{Segment, TranscriptionResult}.provider.List(),provider.ListByModelType(),provider.ProviderInfo, allprovider.Provider*name constants,provider.WeKnoraCloudBaseURL.utils.ChunkSlice(imported byapplication/service/graph.goandapplication/service/retriever/...) kept at its current path.internal/models/utils/ollama.OllamaService(imported bycontainer/,application/service/model.go,application/service/image_multimodal.go,handler/initialization.go) kept at its current path.RemoteAPIChat.BuildChatCompletionRequest(asserted on inremote_api_test.go) kept as a method with the same signature.Non-goals
internal/models/continues to pass.Configfields.chat/ollama.go— the Ollama-API coupling is unavoidable and the file is self-contained.Test plan
go build ./...— cleango test ./internal/models/...— all pass (chat / embedding / rerank / vlm / asr / provider)main: the 3 pre-existing test failures ininternal/application/{repository,service}(SQLite schema mismatch withwiki_configcolumn) are unchanged — unrelated to this refactorLLM_DEBUG_LOGoutput shape match pre-refactor format