Token counting, model quotas, and sliding window rate limiter
Swap all direct os I/O calls for coreio.Local equivalents: - os.ReadFile → coreio.Local.Read (returns string; []byte cast at call sites) - os.WriteFile + os.MkdirAll → coreio.Local.Write (creates parent dirs internally) Affected: Load(), Persist(), MigrateYAMLToSQLite(). go.mod gains forge.lthn.ai/core/go-io v0.1.2 as a direct dependency. Co-Authored-By: Virgil <virgil@lethean.io> |
||
|---|---|---|
| .core | ||
| .forgejo/workflows | ||
| docs | ||
| .editorconfig | ||
| .gitignore | ||
| .golangci.yml | ||
| CLAUDE.md | ||
| CONTRIBUTING.md | ||
| error_test.go | ||
| go.mod | ||
| go.sum | ||
| iter_test.go | ||
| ratelimit.go | ||
| ratelimit_test.go | ||
| README.md | ||
| sqlite.go | ||
| sqlite_test.go | ||
go-ratelimit
Provider-agnostic sliding window rate limiter for LLM API calls. Enforces requests per minute (RPM), tokens per minute (TPM), and requests per day (RPD) quotas per model using an in-memory sliding window. Ships with default quota profiles for Gemini, OpenAI, Anthropic, and a local inference provider. State persists across process restarts via YAML (single-process) or SQLite (multi-process, WAL mode). Includes a Gemini-specific token counting helper and a YAML-to-SQLite migration path.
Module: forge.lthn.ai/core/go-ratelimit
Licence: EUPL-1.2
Language: Go 1.25
Quick Start
import "forge.lthn.ai/core/go-ratelimit"
// YAML backend (default, single-process)
rl, err := ratelimit.New()
// SQLite backend (multi-process)
rl, err := ratelimit.NewWithSQLite("~/.core/ratelimits.db")
defer rl.Close()
ok, reason := rl.CanSend("gemini-2.0-flash", 1500)
if ok {
rl.RecordUsage("gemini-2.0-flash", 1500)
}
Documentation
- Architecture — sliding window algorithm, provider quotas, YAML and SQLite backends
- Development Guide — prerequisites, test patterns, coding standards
- Project History — completed phases with commit hashes, known limitations
Build & Test
go test ./...
go test -race ./...
go vet ./...
go build ./...
Licence
European Union Public Licence 1.2 — see LICENCE for details.