BAGOMBEKA-JOB-DEV/skyl

One Go interface for every AI model. Skyl is a small, dependency-light Go library that lets you talk to Claude, GPT, Gemini, and 400+ other models through a single, stable interface — then switch between them by changing one string

Go

1

67 commits

updated Oct 1, 2026

See the code

README

skyl

CI Go Reference License: Apache 2.0

One Go interface for every AI model.

📖 skyl-docs.vercel.app — the documentation site.

skyl is a small, dependency-light Go library that lets you talk to Claude, GPT, Gemini, and 400+ other models through a single, stable interface — then switch between them by changing one string.

client := skyl.New(anthropic.New(os.Getenv("ANTHROPIC_API_KEY")))

resp, err := client.Complete(ctx, &skyl.Request{
	Model:    "claude-opus-5",
	Messages: []skyl.Message{skyl.UserText("Explain Go channels in two sentences.")},
})
fmt.Println(resp.Text())

Swapping to GPT is a one-line change:

client := skyl.New(openai.New(os.Getenv("OPENAI_API_KEY")))

Why skyl

Integrating an AI model into a Go service means writing the same 400 lines every time: request mapping, SSE parsing, retry with jitter, rate-limit backoff, token accounting, error classification. Then your provider ships a new model, or you want to A/B two vendors, and you write it again.

skyl does that once, properly, with tests.

Provider-agnosticOne Request/Response shape across every vendor
Zero-day model supportModel IDs are pass-through strings — new models work the day they launch, with no skyl release
No lock-inEvery response carries Raw — the untouched provider JSON — so you are never blocked by our abstraction
Streaming that worksUnified SSE with proper context cancellation and no goroutine leaks
Honest errorsTyped, classified, errors.Is/errors.As-friendly
Small surfaceThe core module has zero external dependencies. No router, no logger, no framework

Install

go get github.com/BAGOMBEKA-JOB-DEV/skyl

Requires Go 1.22+, and the core module has zero external dependencies — so it imposes neither a dependency graph nor a recent toolchain on you. The adapter modules below need Go 1.24+, because the vendor SDKs they wrap do.

The Anthropic adapter is a separate module, because it uses the official Anthropic SDK and that brings a dozen transitive dependencies nobody else should pay for (ADR-0006):

go get github.com/BAGOMBEKA-JOB-DEV/skyl/provider/anthropic

Provider coverage

Native adapters — full fidelity, including provider-specific features (extended thinking, prompt caching, native tool calling):

AdapterReaches
provider/anthropic ⁽*⁾Claude Opus 5, Fable 5, Sonnet 5, Haiku 4.5, all 4.x
provider/openaiGPT-5.6 (Sol/Terra/Luna), 5.5, 5.4 nano, o-series, gpt-oss
provider/geminiGemini 3.6 Flash, 3.5/3.1 Flash-Lite, 3 Pro

⁽*⁾ separate module — install it explicitly, as shown above.

provider/openaicompat — one adapter, configured per host, reaches the long tail of vendors that speak OpenAI's wire format:

xAI (Grok) · DeepSeek · Mistral · Groq · Together · Fireworks · OpenRouter · Perplexity · Cerebras · DeepInfra · Qwen/DashScope · Moonshot (Kimi) · Z.ai (GLM) · Nvidia NIM · Ollama · vLLM · LM Studio · llama.cpp

// Any OpenAI-compatible endpoint, including local ones.
client := skyl.New(openaicompat.New(
	openaicompat.WithBaseURL("http://localhost:11434/v1"),
	openaicompat.WithName("ollama"),
))

Full details and the model-discovery story: docs/providers.md.

On GitHub Copilot: skyl deliberately does not ship a Copilot provider. Copilot has no public completions API — its REST endpoints are administrative only, and the Copilot SDK's BYOK mode forwards to other vendors' keys. A "Copilot provider" could only be a relabelled OpenAI call, which would be dishonest. See ADR-0005.

The optional gateway

gateway/ is a separate module (its own go.mod) that exposes skyl over HTTP using go-chi — one REST + SSE endpoint that fans out to any configured provider. Use it when non-Go services need model access, or when you want API keys held in exactly one place.

go run github.com/BAGOMBEKA-JOB-DEV/skyl/gateway/cmd/skyl-gateway

Importing the core library never pulls in chi. See docs/gateway.md and ADR-0003.

Deploying it

The gateway builds as a multi-architecture container image — gcr.io/distroless/static:nonroot, no shell, configuration entirely from the environment. Build and run it from a clone:

docker build -t skyl-gateway .
docker run --rm -p 8080:8080 \
  -e SKYL_AUTH_TOKEN="$(openssl rand -hex 32)" \
  -e ANTHROPIC_API_KEY=sk-ant-... \
  skyl-gateway

Or with no API key at all — docker compose up --build runs it against the local sandbox, which speaks every provider's wire protocol.

Released images are published to ghcr.io/bagombeka-job-dev/skyl-gateway on each gateway/v* tag — multi-architecture, signed with cosign, and carrying an SBOM and a build-provenance attestation.

cosign verify ghcr.io/bagombeka-job-dev/skyl-gateway:1.0.0 \
  --certificate-identity-regexp '^https://github.com/BAGOMBEKA-JOB-DEV/skyl/' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

Deploy by digest rather than by tag: a tag is a mutable pointer, so pinning one makes a rollback a guess about which bytes it lands on.

For a cluster, BAGOMBEKA-JOB-DEV/skyl_infrastructure is a separate repository holding Terraform that stands up AWS, GCP or Azure behind one interface, and a Helm chart that runs identically on all three. It encodes the operational details that are easy to get wrong and expensive to discover in production — liveness on /healthz and readiness on /readyz, a 40-second termination grace period for the drain described in docs/gateway.md, secrets from the cloud's own secret store rather than from git, and images pinned by digest so a rollback lands on the bytes that were signed.

Deployment lives in its own repository for the same reason the docs site does: so that infrastructure changes never touch this repository's release history.

The three repositories

RepositoryWhat it is
skylThis one — the Go library, the adapters, and the gateway
skyl_docsThe documentation site (Next.js)
skyl_infrastructureDeployment: Terraform for three clouds, the Helm chart, CI

Documentation

The documentation site is the friendliest way in: a Learn track to read in order, and a Reference track with one page per symbol. It is built from BAGOMBEKA-JOB-DEV/skyl_docs — a separate repository, so a docs change never touches the library's release history. Corrections to the site belong there; corrections to the files below belong here.

The documents in this repository stay authoritative for anything a decision depends on — the feature matrix, the threat model, the ADRs — because they are versioned with the code they describe.

DocumentWhat it covers
docs/idea.mdThe problem, the goals, and the explicit non-goals
docs/getting-started.mdInstall → first call → streaming → tools
docs/architecture.mdHow the pieces fit and why
docs/providers.mdProvider coverage and model discovery
docs/gateway.mdThe chi HTTP gateway
docs/project-plan.mdMilestones, scope, and status
docs/roadmap.mdWhat stands between this and production use
docs/feature-matrix.mdWhich adapter supports what — including what each one silently ignores
docs/data-handling.mdWhat leaves your process, what is kept, what is logged
docs/threat-model.mdTrust boundaries, and what an authenticated gateway caller can do
docs/benchmarks.mdMeasured allocation and throughput figures
docs/migrating.mdComing from openai-go, anthropic-sdk-go, or langchaingo
docs/rules.mdEngineering rules every change must satisfy
docs/adr/Architecture decision records
CONTRIBUTING.mdHow to propose and land a change
SECURITY.mdReporting vulnerabilities; credential handling

Deployment is documented in the infrastructure repository rather than here: architecture and quickstart, the cluster runbook, and what each cloud costs.

Status

v1.0.0 — released 2026-09-06. The API is stable. Everything here is implemented, unit-tested, contract-tested, exercised end to end over real sockets, and CI-green — and as of 2026-08-05 the integration suite has been run against the real OpenAI, Anthropic and Gemini endpoints and passes.

That last part is the one that took longest to be able to write. Every fake in this test suite was written from the same provider documentation as the adapter it tests, so a wrong field name is wrong identically in both and CI stays green regardless. Only a real call settles it, and one has now been made against each adapter: completions, streaming, tool calls, the multi-turn tool round trip, truncation, and error classification.

What v1.0.0 promises, and what it does not. It promises the exported API: Provider, Client, Message, Part, Request, Response, Stream, the error sentinels and every functional option are frozen, and none of them changes without a v2 (docs/rules.md §1.2). Upgrading from v0.1.0 breaks nothing.

It does not promise complete provider coverage. The feature matrix still lists what each adapter silently ignores, and docs/roadmap.md still lists what is deliberately deferred — embeddings, prompt-caching control, batch APIs, token counting, failover. A frozen API and a finished feature surface are different claims, and only the first is being made.

Nor is live validation a subscription. It is a snapshot: providers change, and docs/validating.md is how you re-run it yourself against your own account and models.

There are three suites, and the third is the one CI cannot run for you:

go test ./...                  # mapping logic, in process
go test -tags=sandbox ./...    # the full stack over real sockets — no keys needed
go test -tags=integration ./...# real providers — needs your keys, costs money

CI runs the first two on every change. The third needs credentials, so it runs by hand — reproduce it with your own:

export ANTHROPIC_API_KEY=... OPENAI_API_KEY=... GEMINI_API_KEY=...
go test -tags=integration ./provider/
cd provider/anthropic && go test -tags=integration ./...

Eight checks per provider, about nine upstream requests, pennies on a small model. docs/validating.md covers what each one proves and how to tell an adapter bug from a model being unhelpful.

To develop against skyl before you have any key, run the local sandbox — it speaks all four providers' wire protocols and costs nothing. See docs/sandbox.md.

go run ./cmd/skyl-sandbox

See docs/project-plan.md for what is done and what is next, and CHANGELOG.md for release history.

License

Apache License 2.0 — see LICENSE.

architecture
claude
gemini
go
golang
ollama
open-source
opentelemetry
rate-limiting

BAGOMBEKA-JOB-DEV/skyl

One Go interface for every AI model. Skyl is a small, dependency-light Go library that lets you talk to Claude, GPT, Gemini, and 400+ other models through a single, stable interface — then switch between them by changing one string

Go

1

67 commits

updated Oct 1, 2026

See the code

README

skyl

CI Go Reference License: Apache 2.0

One Go interface for every AI model.

📖 skyl-docs.vercel.app — the documentation site.

skyl is a small, dependency-light Go library that lets you talk to Claude, GPT, Gemini, and 400+ other models through a single, stable interface — then switch between them by changing one string.

client := skyl.New(anthropic.New(os.Getenv("ANTHROPIC_API_KEY")))

resp, err := client.Complete(ctx, &skyl.Request{
	Model:    "claude-opus-5",
	Messages: []skyl.Message{skyl.UserText("Explain Go channels in two sentences.")},
})
fmt.Println(resp.Text())

Swapping to GPT is a one-line change:

client := skyl.New(openai.New(os.Getenv("OPENAI_API_KEY")))

Why skyl

Integrating an AI model into a Go service means writing the same 400 lines every time: request mapping, SSE parsing, retry with jitter, rate-limit backoff, token accounting, error classification. Then your provider ships a new model, or you want to A/B two vendors, and you write it again.

skyl does that once, properly, with tests.

Provider-agnosticOne Request/Response shape across every vendor
Zero-day model supportModel IDs are pass-through strings — new models work the day they launch, with no skyl release
No lock-inEvery response carries Raw — the untouched provider JSON — so you are never blocked by our abstraction
Streaming that worksUnified SSE with proper context cancellation and no goroutine leaks
Honest errorsTyped, classified, errors.Is/errors.As-friendly
Small surfaceThe core module has zero external dependencies. No router, no logger, no framework

Install

go get github.com/BAGOMBEKA-JOB-DEV/skyl

Requires Go 1.22+, and the core module has zero external dependencies — so it imposes neither a dependency graph nor a recent toolchain on you. The adapter modules below need Go 1.24+, because the vendor SDKs they wrap do.

The Anthropic adapter is a separate module, because it uses the official Anthropic SDK and that brings a dozen transitive dependencies nobody else should pay for (ADR-0006):

go get github.com/BAGOMBEKA-JOB-DEV/skyl/provider/anthropic

Provider coverage

Native adapters — full fidelity, including provider-specific features (extended thinking, prompt caching, native tool calling):

AdapterReaches
provider/anthropic ⁽*⁾Claude Opus 5, Fable 5, Sonnet 5, Haiku 4.5, all 4.x
provider/openaiGPT-5.6 (Sol/Terra/Luna), 5.5, 5.4 nano, o-series, gpt-oss
provider/geminiGemini 3.6 Flash, 3.5/3.1 Flash-Lite, 3 Pro

⁽*⁾ separate module — install it explicitly, as shown above.

provider/openaicompat — one adapter, configured per host, reaches the long tail of vendors that speak OpenAI's wire format:

xAI (Grok) · DeepSeek · Mistral · Groq · Together · Fireworks · OpenRouter · Perplexity · Cerebras · DeepInfra · Qwen/DashScope · Moonshot (Kimi) · Z.ai (GLM) · Nvidia NIM · Ollama · vLLM · LM Studio · llama.cpp

// Any OpenAI-compatible endpoint, including local ones.
client := skyl.New(openaicompat.New(
	openaicompat.WithBaseURL("http://localhost:11434/v1"),
	openaicompat.WithName("ollama"),
))

Full details and the model-discovery story: docs/providers.md.

On GitHub Copilot: skyl deliberately does not ship a Copilot provider. Copilot has no public completions API — its REST endpoints are administrative only, and the Copilot SDK's BYOK mode forwards to other vendors' keys. A "Copilot provider" could only be a relabelled OpenAI call, which would be dishonest. See ADR-0005.

The optional gateway

gateway/ is a separate module (its own go.mod) that exposes skyl over HTTP using go-chi — one REST + SSE endpoint that fans out to any configured provider. Use it when non-Go services need model access, or when you want API keys held in exactly one place.

go run github.com/BAGOMBEKA-JOB-DEV/skyl/gateway/cmd/skyl-gateway

Importing the core library never pulls in chi. See docs/gateway.md and ADR-0003.

Deploying it

The gateway builds as a multi-architecture container image — gcr.io/distroless/static:nonroot, no shell, configuration entirely from the environment. Build and run it from a clone:

docker build -t skyl-gateway .
docker run --rm -p 8080:8080 \
  -e SKYL_AUTH_TOKEN="$(openssl rand -hex 32)" \
  -e ANTHROPIC_API_KEY=sk-ant-... \
  skyl-gateway

Or with no API key at all — docker compose up --build runs it against the local sandbox, which speaks every provider's wire protocol.

Released images are published to ghcr.io/bagombeka-job-dev/skyl-gateway on each gateway/v* tag — multi-architecture, signed with cosign, and carrying an SBOM and a build-provenance attestation.

cosign verify ghcr.io/bagombeka-job-dev/skyl-gateway:1.0.0 \
  --certificate-identity-regexp '^https://github.com/BAGOMBEKA-JOB-DEV/skyl/' \
  --certificate-oidc-issuer https://token.actions.githubusercontent.com

Deploy by digest rather than by tag: a tag is a mutable pointer, so pinning one makes a rollback a guess about which bytes it lands on.

For a cluster, BAGOMBEKA-JOB-DEV/skyl_infrastructure is a separate repository holding Terraform that stands up AWS, GCP or Azure behind one interface, and a Helm chart that runs identically on all three. It encodes the operational details that are easy to get wrong and expensive to discover in production — liveness on /healthz and readiness on /readyz, a 40-second termination grace period for the drain described in docs/gateway.md, secrets from the cloud's own secret store rather than from git, and images pinned by digest so a rollback lands on the bytes that were signed.

Deployment lives in its own repository for the same reason the docs site does: so that infrastructure changes never touch this repository's release history.

The three repositories

RepositoryWhat it is
skylThis one — the Go library, the adapters, and the gateway
skyl_docsThe documentation site (Next.js)
skyl_infrastructureDeployment: Terraform for three clouds, the Helm chart, CI

Documentation

The documentation site is the friendliest way in: a Learn track to read in order, and a Reference track with one page per symbol. It is built from BAGOMBEKA-JOB-DEV/skyl_docs — a separate repository, so a docs change never touches the library's release history. Corrections to the site belong there; corrections to the files below belong here.

The documents in this repository stay authoritative for anything a decision depends on — the feature matrix, the threat model, the ADRs — because they are versioned with the code they describe.

DocumentWhat it covers
docs/idea.mdThe problem, the goals, and the explicit non-goals
docs/getting-started.mdInstall → first call → streaming → tools
docs/architecture.mdHow the pieces fit and why
docs/providers.mdProvider coverage and model discovery
docs/gateway.mdThe chi HTTP gateway
docs/project-plan.mdMilestones, scope, and status
docs/roadmap.mdWhat stands between this and production use
docs/feature-matrix.mdWhich adapter supports what — including what each one silently ignores
docs/data-handling.mdWhat leaves your process, what is kept, what is logged
docs/threat-model.mdTrust boundaries, and what an authenticated gateway caller can do
docs/benchmarks.mdMeasured allocation and throughput figures
docs/migrating.mdComing from openai-go, anthropic-sdk-go, or langchaingo
docs/rules.mdEngineering rules every change must satisfy
docs/adr/Architecture decision records
CONTRIBUTING.mdHow to propose and land a change
SECURITY.mdReporting vulnerabilities; credential handling

Deployment is documented in the infrastructure repository rather than here: architecture and quickstart, the cluster runbook, and what each cloud costs.

Status

v1.0.0 — released 2026-09-06. The API is stable. Everything here is implemented, unit-tested, contract-tested, exercised end to end over real sockets, and CI-green — and as of 2026-08-05 the integration suite has been run against the real OpenAI, Anthropic and Gemini endpoints and passes.

That last part is the one that took longest to be able to write. Every fake in this test suite was written from the same provider documentation as the adapter it tests, so a wrong field name is wrong identically in both and CI stays green regardless. Only a real call settles it, and one has now been made against each adapter: completions, streaming, tool calls, the multi-turn tool round trip, truncation, and error classification.

What v1.0.0 promises, and what it does not. It promises the exported API: Provider, Client, Message, Part, Request, Response, Stream, the error sentinels and every functional option are frozen, and none of them changes without a v2 (docs/rules.md §1.2). Upgrading from v0.1.0 breaks nothing.

It does not promise complete provider coverage. The feature matrix still lists what each adapter silently ignores, and docs/roadmap.md still lists what is deliberately deferred — embeddings, prompt-caching control, batch APIs, token counting, failover. A frozen API and a finished feature surface are different claims, and only the first is being made.

Nor is live validation a subscription. It is a snapshot: providers change, and docs/validating.md is how you re-run it yourself against your own account and models.

There are three suites, and the third is the one CI cannot run for you:

go test ./...                  # mapping logic, in process
go test -tags=sandbox ./...    # the full stack over real sockets — no keys needed
go test -tags=integration ./...# real providers — needs your keys, costs money

CI runs the first two on every change. The third needs credentials, so it runs by hand — reproduce it with your own:

export ANTHROPIC_API_KEY=... OPENAI_API_KEY=... GEMINI_API_KEY=...
go test -tags=integration ./provider/
cd provider/anthropic && go test -tags=integration ./...

Eight checks per provider, about nine upstream requests, pennies on a small model. docs/validating.md covers what each one proves and how to tell an adapter bug from a model being unhelpful.

To develop against skyl before you have any key, run the local sandbox — it speaks all four providers' wire protocols and costs nothing. See docs/sandbox.md.

go run ./cmd/skyl-sandbox

See docs/project-plan.md for what is done and what is next, and CHANGELOG.md for release history.

License

Apache License 2.0 — see LICENSE.

architecture
claude
gemini
go
golang
ollama
open-source
opentelemetry
rate-limiting

Languages

Go

98.1%

Shell

1.5%