mirror of
https://github.com/lukaszraczylo/traefik-llmgateway.git
synced 2026-10-12 04:54:45 +00:00
Adds integration/ (separate module): docker compose stack with real Traefik v3.5 + localPlugins, mock openai/anthropic/gemini/tool providers, shared Redis, and a raw-TCP streaming timing probe. 6/7 tests pass; streaming incrementality fails on a confirmed external yaegi/Traefik bug (see task-15-report.md), not a plugin defect. Fixes 4 real Yaegi-interpretation bugs surfaced by running the plugin under real Traefik for the first time (none caught by go test or yaegi-check, which never exercises chat/embeddings/streaming/Redis): - .traefik.yml: add basePkg (Traefik derives the yaegi binding identifier from the module path, not the package's own declared name; without this override the plugin never loads at all). - registry.go: resolveAgainst's multi-value return panicked yaegi on an inline string concatenation; assign to a local first. - routes_unified.go: errors.As panicked yaegi on interpreted pointer error types; use plain type assertions (both types are always returned bare, never wrapped). - sse.go: readSSE's dispatch closure hit the same multi-value-assignment panic as registry.go; split into separate statements. - resp.go: respErr as a defined string type was indistinguishable from a plain string in a yaegi type assertion, misreading every successful Redis SELECT reply as failed and silently disabling rate limiting; changed to a struct.
123 lines
3.3 KiB
YAML
123 lines
3.3 KiB
YAML
networks:
|
|
llmgw-integration:
|
|
driver: bridge
|
|
|
|
services:
|
|
redis:
|
|
image: redis:7-alpine
|
|
networks: ["llmgw-integration"]
|
|
healthcheck:
|
|
test: ["CMD", "redis-cli", "ping"]
|
|
interval: 2s
|
|
timeout: 2s
|
|
retries: 15
|
|
|
|
mockopenai:
|
|
build:
|
|
context: .
|
|
dockerfile: mock/Dockerfile
|
|
command: ["-mode", "openai"]
|
|
networks: ["llmgw-integration"]
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-qO-", "http://localhost:8080/healthz"]
|
|
interval: 2s
|
|
timeout: 2s
|
|
retries: 15
|
|
|
|
mockanthropic:
|
|
build:
|
|
context: .
|
|
dockerfile: mock/Dockerfile
|
|
command: ["-mode", "anthropic"]
|
|
networks: ["llmgw-integration"]
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-qO-", "http://localhost:8080/healthz"]
|
|
interval: 2s
|
|
timeout: 2s
|
|
retries: 15
|
|
|
|
mockgemini:
|
|
build:
|
|
context: .
|
|
dockerfile: mock/Dockerfile
|
|
command: ["-mode", "gemini"]
|
|
networks: ["llmgw-integration"]
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-qO-", "http://localhost:8080/healthz"]
|
|
interval: 2s
|
|
timeout: 2s
|
|
retries: 15
|
|
|
|
mocktool:
|
|
build:
|
|
context: .
|
|
dockerfile: mock/Dockerfile
|
|
command: ["-mode", "tool"]
|
|
networks: ["llmgw-integration"]
|
|
healthcheck:
|
|
test: ["CMD", "wget", "-qO-", "http://localhost:8080/healthz"]
|
|
interval: 2s
|
|
timeout: 2s
|
|
retries: 15
|
|
|
|
traefik1:
|
|
image: traefik:v3.5
|
|
command: ["--configfile=/etc/traefik/traefik.yml"]
|
|
networks: ["llmgw-integration"]
|
|
ports:
|
|
- "19081:80"
|
|
volumes:
|
|
- ../:/plugins-local/src/github.com/lukaszraczylo/traefik-llmgateway:ro
|
|
- ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro
|
|
- ./traefik/dynamic.yml:/etc/traefik/dynamic.yml:ro
|
|
- ./users:/users:ro
|
|
depends_on:
|
|
redis:
|
|
condition: service_healthy
|
|
mockopenai:
|
|
condition: service_healthy
|
|
mockanthropic:
|
|
condition: service_healthy
|
|
mockgemini:
|
|
condition: service_healthy
|
|
mocktool:
|
|
condition: service_healthy
|
|
|
|
traefik2:
|
|
image: traefik:v3.5
|
|
command: ["--configfile=/etc/traefik/traefik.yml"]
|
|
networks: ["llmgw-integration"]
|
|
ports:
|
|
- "19082:80"
|
|
volumes:
|
|
- ../:/plugins-local/src/github.com/lukaszraczylo/traefik-llmgateway:ro
|
|
- ./traefik/traefik.yml:/etc/traefik/traefik.yml:ro
|
|
- ./traefik/dynamic.yml:/etc/traefik/dynamic.yml:ro
|
|
- ./users:/users:ro
|
|
depends_on:
|
|
redis:
|
|
condition: service_healthy
|
|
mockopenai:
|
|
condition: service_healthy
|
|
mockanthropic:
|
|
condition: service_healthy
|
|
mockgemini:
|
|
condition: service_healthy
|
|
mocktool:
|
|
condition: service_healthy
|
|
|
|
# In-network streaming timing prober. Never started by `up`; the test
|
|
# invokes it on demand via `docker compose run --rm probe`, from inside
|
|
# this same compose network so its raw-TCP read against traefik1
|
|
# reflects true inter-chunk arrival timing instead of the buffered
|
|
# behaviour Docker Desktop's host port-proxy would introduce.
|
|
probe:
|
|
build:
|
|
context: .
|
|
dockerfile: mock/Dockerfile
|
|
command: ["-probe", "-target", "traefik1:80", "-apikey", "sk-int-alice", "-model", "openai/gpt-mock"]
|
|
networks: ["llmgw-integration"]
|
|
profiles: ["probe"]
|
|
depends_on:
|
|
- traefik1
|