156 lines
5.3 KiB
Markdown
156 lines
5.3 KiB
Markdown
# Adapter Internals
|
|
|
|
## Purpose
|
|
|
|
Adapters translate external interfaces into domain requests and translate domain results back out. They wire dependencies, apply app config, and own IO concerns, but they do not make runner decisions.
|
|
|
|
Source-loading behavior belongs in `docs/internal/sources.md`. User-facing CLI, HTTP, and package contracts belong in `docs/cli.md`, `docs/api.md`, and `docs/consumers/pkg-scriptorium.md`.
|
|
|
|
## Adapter Map
|
|
|
|
- `cmd/scriptorium`: process entrypoint.
|
|
- `internal/adapter/cli`: command parsing, config handoff, runner construction, stdout/stderr, exit codes.
|
|
- `internal/adapter/http`: `POST /v1/runs` request/response mapping and HTTP error/status mapping.
|
|
- root package `scriptorium`: public Go facade over internal runner types and dependencies.
|
|
|
|
Supporting implementation packages used during adapter wiring:
|
|
|
|
- `internal/config`
|
|
- `internal/defaults`
|
|
- `internal/format`
|
|
- `internal/llm`
|
|
- `internal/prompt`
|
|
|
|
## Inputs And Outputs
|
|
|
|
CLI adapter:
|
|
|
|
- Input: process args, optional config file, filesystem sources, environment variables.
|
|
- Output: process exit code, stdout artifact/prepared output, stderr summaries and errors.
|
|
|
|
HTTP adapter:
|
|
|
|
- Input: HTTP request method/path/headers/body for `POST /v1/runs`.
|
|
- Output: JSON success or error body with mapped status code.
|
|
|
|
Public Go facade:
|
|
|
|
- Input: typed `scriptorium.Config`, `Option`, and `RunRequest` values.
|
|
- Output: typed `PreparedRun` and `RunResult` values plus public sentinel errors.
|
|
|
|
## Boundaries
|
|
|
|
- Adapters convert external shapes to `domain.RunRequest` and back.
|
|
- Runner orchestration remains in `internal/usecase`.
|
|
- Prompt/profile/schema/artifact source rules remain in repository, validator, and artifact packages.
|
|
- LLM provider request serialization remains in `internal/llm`.
|
|
- Public package types are facade types; internal domain types do not leak across the package boundary.
|
|
|
|
## Config Fields Used
|
|
|
|
Adapter app settings:
|
|
|
|
- `prompt_dir`
|
|
- `profile_dir`
|
|
- `schema_dir`
|
|
- `server.addr`
|
|
- `server.artifact_root`
|
|
- `server.max_request_bytes`
|
|
- `server.max_artifact_bytes`
|
|
- `server.max_response_bytes`
|
|
- `defaults.render_format`
|
|
|
|
Execution request/profile settings passed through the runner:
|
|
|
|
- `endpoint`
|
|
- `model`
|
|
- `temperature`
|
|
- `max_tokens`
|
|
- `top_p`
|
|
- `timeout_seconds`
|
|
- `service_tier`
|
|
- `api_key_env`
|
|
- `reasoning_effort`
|
|
- `extra_params`
|
|
|
|
CLI and HTTP preserve numeric override presence so omitted values and explicit zero values remain distinct.
|
|
|
|
## CLI Adapter
|
|
|
|
Implemented commands:
|
|
|
|
- `run`
|
|
- `render`
|
|
- `serve`
|
|
|
|
Behavior:
|
|
|
|
- `run` constructs a runner with direct filesystem artifact reading and calls `Runner.Run`.
|
|
- `render` constructs a runner and calls `Runner.Prepare`; it does not call the LLM.
|
|
- `serve` constructs a restricted artifact reader and HTTP handler, then starts an unauthenticated HTTP server.
|
|
- `run` exits `2` when generation succeeds but validation fails.
|
|
- parse, runtime, and output-write errors exit `1`.
|
|
- deprecated `--prompt-id` and `--profile-id` aliases are accepted.
|
|
|
|
## HTTP Adapter
|
|
|
|
Behavior:
|
|
|
|
- Accepts only `POST /v1/runs`.
|
|
- Decodes JSON strictly and rejects unknown fields and trailing JSON tokens.
|
|
- Rejects empty `prompt_id` and empty `inputs` before calling the runner.
|
|
- Does not accept raw API key values in the request body.
|
|
- Returns validation failures as `200` responses with failed validation details.
|
|
- Maps request-body, artifact, and encoded-response size failures to `413`.
|
|
- Maps domain and repository errors to stable error codes without returning wrapped internal cause text.
|
|
|
|
The HTTP adapter has no built-in authentication or authorization. Deployment controls must be provided outside the process.
|
|
|
|
## Public Go Facade
|
|
|
|
Behavior:
|
|
|
|
- `NewEngine` wires the same default runner components as CLI/HTTP unless options override them.
|
|
- Prompt, profile, and schema sources may come from directories, single files, or `fs.FS` roots.
|
|
- `WithProfiles` adds in-memory profiles ahead of file-backed and built-in profiles.
|
|
- `WithLLMClient` injects custom model behavior.
|
|
- `RunRequest.APIKey` is request-scoped and direct; it is used only for generation and is stripped from public results.
|
|
- internal errors are mapped to public sentinels in `errors.go`.
|
|
|
|
## Failure Behavior
|
|
|
|
Adapters should:
|
|
|
|
- keep external error payloads concise and stable.
|
|
- avoid leaking raw secret values.
|
|
- use sentinels and typed errors for mapping.
|
|
- preserve strict external input decoding.
|
|
- keep validation content failures distinct from runtime errors.
|
|
|
|
CLI writes human-readable summaries to stderr. HTTP writes JSON error envelopes. The public Go facade returns typed errors.
|
|
|
|
## State And Manifests
|
|
|
|
Adapters do not add durable run state.
|
|
|
|
- No adapter writes run manifests.
|
|
- No adapter implements checkpoint, skip, or resume behavior.
|
|
- CLI output files are caller-selected artifacts, not internal state.
|
|
|
|
## Tests To Inspect
|
|
|
|
- `internal/adapter/cli/run_test.go`
|
|
- `internal/adapter/http/handler_test.go`
|
|
- `engine_test.go`
|
|
- `internal/format/prepared_run_test.go`
|
|
- `internal/llm/openai_compatible_client_test.go`
|
|
|
|
## Architectural Invariants
|
|
|
|
- Adapter packages stay thin and translation-focused.
|
|
- App config is resolved before dependency construction.
|
|
- External input strictness is part of contract stability.
|
|
- CLI and HTTP construct runners without a repairer.
|
|
- HTTP endpoint details remain canonical in `docs/api.md`.
|
|
- Public Go package details remain canonical in `docs/consumers/pkg-scriptorium.md`.
|