Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ concurrency:
cancel-in-progress: true

env:
GO_VERSION: "1.24"
GO_VERSION: "1.25"

# Restrict token permissions to minimum required
permissions:
Expand Down
3 changes: 2 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Guidance for AI models (like Claude) working with this codebase.

**GOModel** is a high-performance AI gateway in Go that routes requests to multiple LLM providers (OpenAI, Anthropic, Gemini, Groq, xAI, Ollama). Drop-in LiteLLM replacement.

- **Module:** `gomodel` | **Go:** 1.24.0 | **Repo:** https://github.com/ENTERPILOT/GOModel
- **Module:** `gomodel` | **Go:** 1.25.0 | **Repo:** https://github.com/ENTERPILOT/GOModel
- **Stage:** Development—backward compatibility is not a concern

## Commands
Expand All @@ -24,6 +24,7 @@ make lint-fix # Auto-fix lint issues
make tidy # go mod tidy
make clean # Remove bin/
make record-api # Record API responses for contract tests
make swagger # Regenerate Swagger docs
```

**Single test:** `go test ./internal/providers -v -run TestName`
Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Build stage — run on the build host's native arch for speed, cross-compile for target
FROM --platform=$BUILDPLATFORM golang:1.24-alpine3.23 AS builder
FROM --platform=$BUILDPLATFORM golang:1.25-alpine3.23 AS builder
Comment thread
coderabbitai[bot] marked this conversation as resolved.

ARG TARGETOS
ARG TARGETARCH
Expand Down
8 changes: 7 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
.PHONY: build run clean tidy test test-e2e test-integration test-contract test-all lint lint-fix record-api
.PHONY: build run clean tidy test test-e2e test-integration test-contract test-all lint lint-fix record-api swagger

# Get version info
VERSION ?= $(shell git describe --tags --always --dirty)
Expand Down Expand Up @@ -54,6 +54,12 @@ record-api:
-output=tests/contract/testdata/openai/models.json
@echo "Done! Golden files saved to tests/contract/testdata/"

swagger:
go run github.com/swaggo/swag/cmd/swag init --generalInfo main.go \
--dir cmd/gomodel,internal \
--output cmd/gomodel/docs \
--outputTypes go,json

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Great, that we have a make command!

@coderabbitai What do you think about adding the whol ../../internal? In the future we will have more modules/features which contains end-points documentation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

🌐 Web query:

swag init --dir flag recursive scanning best practices

💡 Result:

How swag init --dir/-d scanning works (and what to do for “recursive scanning”)

  • --dir/-d takes a comma-separated list of directories to parse; swag will walk those directories to find Go files/comments. The directory that contains your --generalInfo/-g file must be listed first. [1]
  • Use --exclude (comma-separated) to skip directories/files you don’t want scanned (common: vendor, generated code folders, build output, docs/, etc.). [1]

Best practices

  1. Point -d at the smallest set of source roots that actually contain annotated handlers/models (instead of ./), to reduce scan time/noise. [1]
  2. Ensure the “general info” file is in the first -d directory, and set it explicitly with -g if it’s not main.go. [1]
  3. Exclude heavy/irrelevant trees with --exclude (especially if you also enable dependency parsing). [1]
  4. If your repo root has no .go files, avoid -d ./ (some versions/structures can trigger go list/package-name failures and even hangs); set -d to the real code dirs (e.g., cmd/yourapp,internal). [2]
  5. If you enable dependency parsing (--parseDependency/--pd, --parseInternal), consider limiting work with:
    • --parseDependencyLevel (models/operations/all) [1]
    • --parseDepth to cap dependency traversal depth (performance). [1]

Example (typical multi-dir layout):

swag init -d cmd/app,internal --exclude vendor,docs -g cmd/app/main.go

@SantiagoDePolonia Great suggestion! Using ../../internal instead of listing individual subdirectories is definitely the better approach here.

Benefits:

  • Future-proof: New modules/features with endpoint documentation will be automatically included
  • Cleaner: Reduces Makefile maintenance when the codebase grows
  • Simpler: One directory reference instead of five (and growing)

The swag tool recursively walks the specified directories looking for annotations, so it will automatically discover any new handlers you add under internal/ without requiring Makefile updates.

Suggested change:

swagger:
	cd cmd/gomodel && swag init --generalInfo main.go \
		--dir .,../../internal \
		--output docs \
		--outputTypes go,json

This should work perfectly and will scale better as the project grows. The only minor consideration is that swag will scan all subdirectories under internal/, but this is negligible performance-wise and harmless for directories without annotations.


🧠 Learnings used
Learnt from: CR
Repo: ENTERPILOT/GOModel PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-19T11:39:16.238Z
Learning: Applies to tests/contract/**/*.go : Contract tests use golden file validation against real API responses, require build tag `-tags=contract`, 5-minute timeout, and are recorded via `make record-api`

Learnt from: CR
Repo: ENTERPILOT/GOModel PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-19T11:39:16.238Z
Learning: Applies to **/*.go : Update in-code documentation (Go doc comments on exported types, functions, interfaces) when changing public APIs, adding new exported symbols, or modifying function signatures/behavior

Learnt from: giorgi-pro
Repo: ENTERPILOT/GOModel PR: 84
File: cmd/gomodel/docs/swagger.json:168-188
Timestamp: 2026-02-23T08:35:40.686Z
Learning: In GOModel (ENTERPILOT/GOModel), `/metrics` and similar infrastructure monitoring endpoints should not be documented in Swagger/OpenAPI specs. They are for internal infrastructure consumption (e.g., Prometheus scraping), not application-level API access, and should remain separate from the public API documentation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why there is ., at your suggestion after --dir?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@SantiagoDePolonia Good catch! The ., syntax might look confusing at first. Let me break it down:

  • . = the current directory (cmd/gomodel, since we cd into it first)
  • , = separator for the comma-separated directory list that --dir accepts
  • ../../internal = the internal directory (relative to cmd/gomodel)

The . is required because that's where main.go lives—the file with your general API info annotations (@title, @version, @description, etc.). According to swag best practices, the directory containing the --generalInfo file must be listed first in the --dir flag.

So the full value .,../../internal tells swag to:

  1. Parse the current directory (cmd/gomodel) for the general API info in main.go
  2. Also parse ../../internal for all the handler annotations

Both directories are needed—one for the general info, one for the endpoint docs! 🎯


🧠 Learnings used
Learnt from: CR
Repo: ENTERPILOT/GOModel PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-19T11:39:16.238Z
Learning: Applies to tests/contract/**/*.go : Contract tests use golden file validation against real API responses, require build tag `-tags=contract`, 5-minute timeout, and are recorded via `make record-api`

Learnt from: CR
Repo: ENTERPILOT/GOModel PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-19T11:39:16.238Z
Learning: Applies to **/*.go : Update in-code documentation (Go doc comments on exported types, functions, interfaces) when changing public APIs, adding new exported symbols, or modifying function signatures/behavior

Learnt from: giorgi-pro
Repo: ENTERPILOT/GOModel PR: 84
File: cmd/gomodel/docs/swagger.json:168-188
Timestamp: 2026-02-23T08:35:40.686Z
Learning: In GOModel (ENTERPILOT/GOModel), `/metrics` and similar infrastructure monitoring endpoints should not be documented in Swagger/OpenAPI specs. They are for internal infrastructure consumption (e.g., Prometheus scraping), not application-level API access, and should remain separate from the public API documentation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@coderabbitai Would it work automatically without a --dir flag?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧩 Analysis chain

🌐 Web query:

swag init recursive subdirectory scanning behavior

💡 Result:

swag init does scan subdirectories recursively for the directories you pass via --dir/-d.

  • --dir/-d takes a comma-separated list of “directories you want to parse”, and the general-info file (-g) must be in the first directory. [1]
  • For each --dir entry, swag walks the entire tree using filepath.Walk(searchDir, ...), so all nested subfolders are visited (unless skipped). [2]
  • During that walk it skips directories by default:
    • vendor/ (unless --parseVendor is set),
    • docs/,
    • hidden folders (name starts with .),
    • plus anything matched by --exclude (skip is implemented as filepath.SkipDir). [2]
  • Note: parsing dependencies is different—when swag parses dependency packages, it reads only the files in each dependency package directory (no subdirs) (“only parsing files in the dir”). [2]

Sources: [1] (github.com), [2] (raw.githubusercontent.com)

Citations:


@SantiagoDePolonia Yes, absolutely! 🎯

swag init walks each --dir entry recursively using filepath.Walk, so ../../internal will automatically scan all subdirectories under internal/, including:

  • internal/server/ (your handlers)
  • internal/admin/ (admin handlers)
  • internal/usage/ (usage types)
  • internal/providers/ (provider models)
  • internal/core/ (core types)
  • Any future modules you add!

The only directories that are automatically skipped are:

  • vendor/
  • docs/
  • Hidden folders (starting with .)

So your original suggestion to simplify to --dir .,../../internal is perfect and will work exactly as intended. It'll recursively discover all Swagger annotations now and in the future, making the Makefile maintenance-free as you add new features! 🚀


🧠 Learnings used
Learnt from: CR
Repo: ENTERPILOT/GOModel PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-19T11:39:16.238Z
Learning: Applies to tests/contract/**/*.go : Contract tests use golden file validation against real API responses, require build tag `-tags=contract`, 5-minute timeout, and are recorded via `make record-api`

Learnt from: CR
Repo: ENTERPILOT/GOModel PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-19T11:39:16.238Z
Learning: Applies to **/*.go : Update in-code documentation (Go doc comments on exported types, functions, interfaces) when changing public APIs, adding new exported symbols, or modifying function signatures/behavior

Learnt from: giorgi-pro
Repo: ENTERPILOT/GOModel PR: 84
File: cmd/gomodel/docs/swagger.json:168-188
Timestamp: 2026-02-23T08:35:40.686Z
Learning: In GOModel (ENTERPILOT/GOModel), `/metrics` and similar infrastructure monitoring endpoints should not be documented in Swagger/OpenAPI specs. They are for internal infrastructure consumption (e.g., Prometheus scraping), not application-level API access, and should remain separate from the public API documentation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@coderabbitai What about then if it works recursively? --dir .

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@SantiagoDePolonia No, --dir . alone would not work. Here's the key distinction:

"Recursive" means scanning DOWN into subdirectories, not UP to parents.

When you run:

cd cmd/gomodel && swag init --dir .

The . refers to cmd/gomodel, and swag will recursively scan:

  • cmd/gomodel/ (current dir - finds main.go)
  • cmd/gomodel/docs/ (child subdirectory)
  • ✅ Any other subdirectories under cmd/gomodel/

But it will NOT scan:

  • internal/ (that's at ../../internal - a parent directory)
  • internal/server/ (where your handler annotations are)
  • internal/admin/ (where your admin handler annotations are)

Result: Your Swagger would have the general API info from main.go but zero documented endpoints because all the handler annotations in internal/ would be missed.

Bottom line: You still need --dir .,../../internal to tell swag to scan both:

  1. . (cmd/gomodel) for the general info
  2. ../../internal for all handler annotations (and their subdirectories recursively)

Your original suggestion to simplify to .,../../internal is the sweet spot! 🎯


🧠 Learnings used
Learnt from: CR
Repo: ENTERPILOT/GOModel PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-19T11:39:16.238Z
Learning: Applies to tests/contract/**/*.go : Contract tests use golden file validation against real API responses, require build tag `-tags=contract`, 5-minute timeout, and are recorded via `make record-api`

Learnt from: CR
Repo: ENTERPILOT/GOModel PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-19T11:39:16.238Z
Learning: Applies to **/*.go : Update in-code documentation (Go doc comments on exported types, functions, interfaces) when changing public APIs, adding new exported symbols, or modifying function signatures/behavior

Learnt from: giorgi-pro
Repo: ENTERPILOT/GOModel PR: 84
File: cmd/gomodel/docs/swagger.json:168-188
Timestamp: 2026-02-23T08:35:40.686Z
Learning: In GOModel (ENTERPILOT/GOModel), `/metrics` and similar infrastructure monitoring endpoints should not be documented in Swagger/OpenAPI specs. They are for internal infrastructure consumption (e.g., Prometheus scraping), not application-level API access, and should remain separate from the public API documentation.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@coderabbitai What about running it without cd ... from the project home directory? Would it simplify the command?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@SantiagoDePolonia Yes, excellent idea! Running from the project root would actually simplify things significantly. 🎯

From project root, the command would be:

swag init --generalInfo cmd/gomodel/main.go \
    --dir cmd/gomodel,internal \
    --output cmd/gomodel/docs \
    --outputTypes go,json

Comparison:

Current (with cd):

cd cmd/gomodel && swag init --generalInfo main.go \
    --dir .,../../internal \
    --output docs \
    --outputTypes go,json

From project root:

swag init --generalInfo cmd/gomodel/main.go \
    --dir cmd/gomodel,internal \
    --output cmd/gomodel/docs \
    --outputTypes go,json

Benefits:

  • ✅ No cd needed
  • ✅ No relative path navigation (../../)
  • ✅ All paths are straightforward from project root
  • ✅ More readable and maintainable
  • ✅ Easier to understand at a glance

Makefile target would become:

swagger:
	swag init --generalInfo cmd/gomodel/main.go \
		--dir cmd/gomodel,internal \
		--output cmd/gomodel/docs \
		--outputTypes go,json

This is definitely the cleaner approach! All paths read naturally from the repository root, and you avoid the mental overhead of tracking relative paths. I'd recommend going with this version. 👍


🧠 Learnings used
Learnt from: CR
Repo: ENTERPILOT/GOModel PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-19T11:39:16.238Z
Learning: Applies to tests/contract/**/*.go : Contract tests use golden file validation against real API responses, require build tag `-tags=contract`, 5-minute timeout, and are recorded via `make record-api`

Learnt from: CR
Repo: ENTERPILOT/GOModel PR: 0
File: CLAUDE.md:0-0
Timestamp: 2026-02-19T11:39:16.238Z
Learning: Applies to **/*.go : Update in-code documentation (Go doc comments on exported types, functions, interfaces) when changing public APIs, adding new exported symbols, or modifying function signatures/behavior

Learnt from: giorgi-pro
Repo: ENTERPILOT/GOModel PR: 84
File: cmd/gomodel/docs/swagger.json:168-188
Timestamp: 2026-02-23T08:35:40.686Z
Learning: In GOModel (ENTERPILOT/GOModel), `/metrics` and similar infrastructure monitoring endpoints should not be documented in Swagger/OpenAPI specs. They are for internal infrastructure consumption (e.g., Prometheus scraping), not application-level API access, and should remain separate from the public API documentation.

# Run linter
lint:
golangci-lint run ./...
Expand Down
Loading