Skip to main content

๐Ÿ—๏ธ Architecture

Tresor follows a clean layered structure with three core concerns: storage, engine, and API. The codebase is written in Go with no external web framework โ€” it uses net/http ServeMux directly for all routing.

๐Ÿ“ Directory Structureโ€‹

cmd/ # CLI entry points (Cobra)
โ”œโ”€โ”€ root.go # Root command, --config flag
โ”œโ”€โ”€ run.go # Daemon startup
โ”œโ”€โ”€ rule.go # Rule & alias subcommands
โ””โ”€โ”€ version.go # Version display

internal/
โ”œโ”€โ”€ config/ # YAML configuration loader with auto-detect
โ”‚ โ””โ”€โ”€ config.go
โ”‚
โ”œโ”€โ”€ store/ # SQLite data layer + upsert logic
โ”‚ โ”œโ”€โ”€ store.go # Schema creation, migrations, busy timeout
โ”‚ โ”œโ”€โ”€ rule.go # Rule CRUD + pattern matching
โ”‚ โ”œโ”€โ”€ downstream.go # Downstream CRUD + model management
โ”‚ โ”œโ”€โ”€ alias.go # Alias CRUD + group operations
โ”‚ โ””โ”€โ”€ write_config.go # YAML write-back on mutation
โ”‚
โ”œโ”€โ”€ engine/ # Core gateway handler + pipeline execution
โ”‚ โ”œโ”€โ”€ engine.go # Gateway forwarding, model resolution, auth, auto-translation
โ”‚ โ”œโ”€โ”€ pipeline.go # Transformer orchestration, streaming
โ”‚ โ””โ”€โ”€ types.go # Interfaces (RequestTransformer, etc.)
โ”‚
โ”œโ”€โ”€ plugins/ # Plugin registry + built-in transformers
โ”‚ โ”œโ”€โ”€ registry.go # Plugin registration and lookup
โ”‚ โ”œโ”€โ”€ custom_header.go # Header injection plugin
โ”‚ โ”œโ”€โ”€ openai2anthropic.go # OpenAI โ†’ Anthropic format conversion
โ”‚ โ”œโ”€โ”€ anthropic2openai.go # Anthropic โ†’ OpenAI format conversion
โ”‚ โ”œโ”€โ”€ anthropic_image_fix.go # Image extraction from tool results
โ”‚ โ””โ”€โ”€ streaming.go # SSE parsing and chunk transformation
โ”‚
โ”œโ”€โ”€ api/ # Admin REST API + embedded web UI
โ”‚ โ”œโ”€โ”€ router.go # Route registration, method enforcement, auth endpoints
โ”‚ โ”œโ”€โ”€ rules.go # Rule endpoints
โ”‚ โ”œโ”€โ”€ downstreams.go # Downstream endpoints + plugins list + fetch-models
โ”‚ โ”œโ”€โ”€ aliases.go # Alias endpoints + group operations
โ”‚ โ”œโ”€โ”€ config.go # Runtime config endpoints (proxy mode, auth keys, password, default tab)
โ”‚ โ””โ”€โ”€ embed.go # Embedded web UI via //go:embed
โ”‚
โ”œโ”€โ”€ middleware/ # Bearer-token auth for admin API
โ”‚ โ””โ”€โ”€ auth.go
โ”‚
โ”œโ”€โ”€ proxy/ # Outbound proxy mode implementation
โ”‚ โ”œโ”€โ”€ proxy.go # Mode resolution (auto/env/windows/none)
โ”‚ โ””โ”€โ”€ system_windows.go # Windows registry proxy reading
โ”‚
โ””โ”€โ”€ api/web/ # Embedded SPA
โ”œโ”€โ”€ index.html
โ”œโ”€โ”€ style.css
โ””โ”€โ”€ app.js

e2e/ # End-to-end integration tests
main.go # Binary entry point

๐Ÿ› ๏ธ Technology Stackโ€‹

ConcernChoiceReason
LanguageGo 1.26+Fast compilation, cross-platform CLI, native concurrency
Routernet/http ServeMuxNo external framework dependency
CLI FrameworkcobraDe facto standard for Go CLI applications
Databasemodernc.org/sqlitePure Go SQLite โ€” no CGO dependency
ConfigYAMLHuman-readable, portable, version-controllable
Web UIEmbedded via //go:embedNo separate frontend deployment needed

๐Ÿ”„ Request Flowโ€‹

Client Request
โ”‚
โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 1. Auth Check โ”‚ โ† Validate proxy_api_keys if configured
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 2. Model Extract โ”‚ โ† Parse model name from request body
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 3. Model Resolve โ”‚ โ† The forwarding gate:
โ”‚ โ”‚ โ€ข Active exact alias? โ†’ use alias downstream, rewrite model
โ”‚ โ”‚ โ€ข Active regex alias? โ†’ pattern match, use downstream, rewrite
โ”‚ โ”‚ โ€ข No alias? โ†’ find downstream by output_model_ids
โ”‚ โ”‚ โ€ข Neither? โ†’ return 404 "unknown model"
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 4. Rule Match โ”‚ โ† Collect ALL matching enabled rules (path+model)
โ”‚ โ”‚ Priority: exact path+model > exact path > wildcard *
โ”‚ โ”‚ Filter by: match_format, match_downstream_format,
โ”‚ โ”‚ match_downstreams. Rules never override downstream.
โ”‚ โ”‚ Pipelines from all matching rules are concatenated.
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 5. Auto- โ”‚ โ† If request format != downstream api_formats,
โ”‚ Translation โ”‚ automatically insert format converter (prepended/
โ”‚ โ”‚ appended around rule pipelines)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 6. Request โ”‚ โ† Execute request transformers sequentially
โ”‚ Pipeline โ”‚ (body + headers may change)
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 7. Forward โ”‚ โ† Send transformed request to downstream server
โ”‚ to Downstream โ”‚ Strip client auth, inject downstream API key
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 8. Response โ”‚ โ† Execute response transformers sequentially
โ”‚ Pipeline โ”‚ Non-streaming: full body transform
โ”‚ โ”‚ Streaming (SSE): event-by-event transform
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”‚
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ 9. Return to โ”‚ โ† Final response to client
โ”‚ Client โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๐Ÿ“ก Aggregated Model Listโ€‹

Tresor exposes /v1/models and /models endpoints that aggregate all known model IDs from downstream output_model_ids and alias input/output model IDs. Regex aliases are excluded from the input model ID list since they represent patterns rather than concrete model names. The response is formatted as an OpenAI-style model list, so OpenAI-compatible clients can discover available models through Tresor.

๐Ÿ’พ Data Layerโ€‹

๐Ÿ—„๏ธ SQLite Schemaโ€‹

The database uses WAL mode with a 5000ms busy timeout. Four tables:

downstreams โ€” Provider endpoints

ColumnTypeDescription
idTEXT PRIMARY KEYUnique identifier
nameTEXT NOT NULLDisplay name
base_urlTEXT NOT NULLAPI base URL
api_keyTEXT NOT NULLAuthentication key
api_formatsTEXT (JSON)API format(s) this downstream speaks
created_atDATETIMECreation timestamp
updated_atDATETIMELast update timestamp

output_model_ids โ€” Model-to-downstream mapping

ColumnTypeDescription
downstream_idTEXT REFERENCES downstreamsForeign key
model_idTEXTModel identifier

(Composite unique on both columns)

rules โ€” Conditional transform pipelines with format-aware matching

ColumnTypeDescription
idTEXT PRIMARY KEYUnique identifier
nameTEXT NOT NULLDisplay name
pattern_pathTEXT NOT NULLURL path to match
pattern_modelTEXTOptional model filter
match_formatTEXT (JSON)Input request formats to match
match_downstream_formatTEXT (JSON)Downstream API formats to match
match_downstreamsTEXT (JSON)Downstream IDs to match
pipeline_configTEXT (JSON)Ordered plugin list
is_enabledINTEGERToggle (0/1)
created_atDATETIMECreation timestamp
updated_atDATETIMELast update timestamp

aliases โ€” Model name mappings

ColumnTypeDescription
idTEXT PRIMARY KEYUnique identifier
input_model_idTEXT NOT NULLClient-facing model name (group key)
downstream_idTEXT NOT NULL REFERENCES downstreamsTarget provider
output_model_idTEXT NOT NULLActual model to forward as
is_activeINTEGER DEFAULT 0Active flag (one per group)
is_regexINTEGER DEFAULT 0Treat input_model_id as a regex pattern
group_orderINTEGER DEFAULT 0Display order for group reordering
created_atDATETIMECreation timestamp
updated_atDATETIMELast update timestamp

Indexes on foreign keys and query patterns ensure efficient lookups. Regex patterns are cached (via sync.Map) to avoid recompilation on every request.

๐Ÿ”„ Upsert Semanticsโ€‹

On startup, YAML data is merged into the database:

  • Downstreams: Matched by ID โ€” updated if exists, inserted if new. api_formats carried over.
  • Rules: Matched by ID โ€” updated if exists, inserted if new. match_format, match_downstream_format, match_downstreams serialized as JSON arrays.
  • Aliases: Special logic โ€” runtime-active aliases not in YAML are preserved (protects hot-switched state); stale YAML aliases not matching DB are deleted; new YAML aliases are created
  • Model IDs: All YAML models replace existing ones for each downstream

Rows that exist only in the database (created via web UI or API) are preserved.

๐Ÿ’ฅ Cascade Deleteโ€‹

Deleting a downstream:

  • Removes the downstream ID from match_downstreams arrays on all referencing rules
  • Deletes all aliases pointing to that downstream

๐Ÿ  Default Seedsโ€‹

When no downstreams, rules, or aliases are defined in YAML, Tresor seeds three default downstreams:

IDNameBase URLModels
openai-gpt4oOpenAI GPT-4ohttps://api.openai.com/v1gpt-4o, gpt-4o-mini, gpt-3.5-turbo
anthropic-sonnetAnthropic Claude Sonnethttps://api.anthropic.comclaude-sonnet-4-20250514
anthropic-haikuAnthropic Claude Haikuhttps://api.anthropic.comclaude-haiku-4.5

Along with default alias groups for gpt-4o and claude-sonnet.

๐ŸŒ Admin APIโ€‹

Public Endpoints (no auth required)โ€‹

MethodPathPurpose
GET/api/healthHealth check
GET/api/auth/statusCheck whether auth is enabled
POST/api/auth/loginVerify password, obtain session
GET/api/versionBinary version and build time

Protected Endpointsโ€‹

All other /api/* endpoints require the configured admin_password Bearer token. See the individual documentation pages for downstream, rule, alias, and config endpoints.

Key alias endpoints include POST /api/aliases/reorder for drag-and-drop group reordering, which accepts {"order": ["gpt-4o", "claude-sonnet"]}.

Log Endpointsโ€‹

MethodPathPurpose
GET/api/logsGet recent log entries (newest first, filtered by log level)
GET/api/logs/streamSSE stream of log entries (sends initial batch + live updates)
GET/api/log_levelGet current log level
PUT/POST/api/log_levelUpdate log level

Runtime Configuration Endpointโ€‹

MethodPathPurpose
GET/api/configGet current runtime settings (proxy mode, proxy keys, password status, default tab, log level)
PUT/api/configUpdate runtime settings live (pushes changes to running engine + auth middleware, writes back to YAML)