147 lines
4.8 KiB
Markdown
147 lines
4.8 KiB
Markdown
# Runner Internals
|
|
|
|
## Purpose
|
|
|
|
`internal/usecase.Runner` is the core prompt-execution orchestrator. It prepares prompt requests, calls the configured LLM client for `Run`, validates generated output, and returns domain results.
|
|
|
|
Transport parsing, DTOs, CLI output, HTTP status mapping, and public package type conversion belong outside the runner.
|
|
|
|
## Inputs And Outputs
|
|
|
|
Primary inputs:
|
|
|
|
- `domain.RunRequest`
|
|
- repositories/readers/renderers/validators injected at construction
|
|
- `context.Context` for cancellation
|
|
|
|
Primary outputs:
|
|
|
|
- `domain.PreparedRun` from `Prepare`
|
|
- `domain.RunResult` from `Run`
|
|
- wrapped sentinel errors for adapter mapping
|
|
|
|
LLM boundary types:
|
|
|
|
- `domain.GenerateRequest`
|
|
- `domain.GenerateResponse`
|
|
|
|
## Dependencies
|
|
|
|
`Runner` depends on package interfaces instead of concrete adapter types:
|
|
|
|
- `promptdef.Repository`
|
|
- `profile.Repository`
|
|
- `artifact.Reader`
|
|
- `prompt.Renderer`
|
|
- `llm.Client`
|
|
- `validate.Validator`
|
|
- optional `usecase.OutputRepairer`
|
|
|
|
The CLI, HTTP adapter, and public Go package construct these dependencies and pass them in.
|
|
|
|
## Config Fields
|
|
|
|
`Runner` does not read app config files. Effective behavior is determined by injected dependencies and the `domain.RunRequest`.
|
|
|
|
Adapter wiring commonly reflects these app config fields:
|
|
|
|
- `prompt_dir`
|
|
- `profile_dir`
|
|
- `schema_dir`
|
|
- `server.artifact_root`
|
|
- HTTP request/artifact/response size limits
|
|
|
|
Runtime model settings are resolved from the selected profile plus request overrides.
|
|
|
|
## Prepare Flow
|
|
|
|
`Prepare`:
|
|
|
|
1. requires a non-empty prompt ID.
|
|
2. loads the prompt definition and computes its hash.
|
|
3. selects the profile from request `profile_id`, then prompt `default_profile`.
|
|
4. loads the selected execution profile.
|
|
5. merges built-in execution defaults, profile values, and request overrides.
|
|
6. applies request-scoped direct API key values for public Go callers.
|
|
7. validates endpoint, model, and credential requirements.
|
|
8. resolves the output contract and JSON Schema document when required.
|
|
9. reads input artifacts.
|
|
10. renders prompt messages and hashes the rendered prompt.
|
|
11. returns a prepared run without calling the LLM.
|
|
|
|
Numeric request overrides are presence-aware: omitted values preserve the current effective value, while explicit zero values are real overrides.
|
|
|
|
## Run Flow
|
|
|
|
`Run`:
|
|
|
|
1. creates a run ID and start timestamp.
|
|
2. calls `Prepare`.
|
|
3. calls the injected LLM client with rendered messages, effective target, target presence, and structured-output settings.
|
|
4. builds the output artifact.
|
|
5. validates the output.
|
|
6. optionally attempts bounded repair when a repairer is injected and the contract permits repair.
|
|
7. returns the run result with artifact, raw output, validation, hashes, selected profile/model metadata, usage, and timing.
|
|
|
|
`Run` must reuse `Prepare`; prepare logic should not be duplicated elsewhere.
|
|
|
|
## Validation And Repair
|
|
|
|
Validation content failures are returned as successful run results with `Validation.Status == failed`. They are not runtime errors.
|
|
|
|
Validation runtime failures, such as schema load or compile errors, return `ErrValidation`.
|
|
|
|
Repair attempts occur only when all conditions are true:
|
|
|
|
- a repairer is injected
|
|
- `repair_attempts` is greater than zero
|
|
- validation status is `failed`
|
|
- validation mode is `json` or `json_schema`
|
|
|
|
CLI and HTTP wiring call `usecase.NewRunner(...)`, which does not inject a repairer. Normal CLI and HTTP execution therefore does not repair invalid output.
|
|
|
|
## Failure Behavior
|
|
|
|
Stable runner sentinels include:
|
|
|
|
- `ErrInvalidRequest`
|
|
- `ErrProfileRequired`
|
|
- `ErrAPIKeyEnvMissing`
|
|
- `ErrAPIKeyRequired`
|
|
- `ErrPromptLoad`
|
|
- `ErrProfileLoad`
|
|
- `ErrArtifactLoad`
|
|
- `ErrPromptRender`
|
|
- `ErrLLMGenerate`
|
|
- `ErrValidation`
|
|
|
|
Adapters should use `errors.Is` against sentinels and lower-level repository errors instead of matching message text.
|
|
|
|
Secret values must not appear in prepared output, run results, logs, HTTP responses, or serialized public package results. The effective API-key environment-variable name may appear.
|
|
|
|
## State And Manifests
|
|
|
|
The runner is stateless across requests.
|
|
|
|
- No durable run store.
|
|
- No manifest files.
|
|
- No checkpoint, skip, or resume behavior.
|
|
- Recovery is a new request after correcting inputs, config, or environment.
|
|
|
|
## Tests To Inspect
|
|
|
|
- `internal/usecase/runner_test.go`
|
|
- `internal/usecase/integration_test.go`
|
|
- `engine_test.go`
|
|
- `internal/adapter/cli/run_test.go`
|
|
- `internal/adapter/http/handler_test.go`
|
|
|
|
## Architectural Invariants
|
|
|
|
- Use-case decisions stay in `internal/usecase`.
|
|
- `Run` reuses `Prepare`.
|
|
- Prompt/profile/artifact/schema loading remains behind injected boundaries.
|
|
- Validation content failures are result state; validation runtime failures are errors.
|
|
- Repair loops are bounded by `repair_attempts` and repairer presence.
|
|
- Resolved secret values are never serialized or emitted.
|