4.8 KiB
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.Contextfor cancellation
Primary outputs:
domain.PreparedRunfromPreparedomain.RunResultfromRun- wrapped sentinel errors for adapter mapping
LLM boundary types:
domain.GenerateRequestdomain.GenerateResponse
Dependencies
Runner depends on package interfaces instead of concrete adapter types:
promptdef.Repositoryprofile.Repositoryartifact.Readerprompt.Rendererllm.Clientvalidate.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_dirprofile_dirschema_dirserver.artifact_root- HTTP request/artifact/response size limits
Runtime model settings are resolved from the selected profile plus request overrides.
Prepare Flow
Prepare:
- requires a non-empty prompt ID.
- loads the prompt definition and computes its hash.
- selects the profile from request
profile_id, then promptdefault_profile. - loads the selected execution profile.
- merges built-in execution defaults, profile values, and request overrides.
- applies request-scoped direct API key values for public Go callers.
- validates endpoint, model, and credential requirements.
- resolves the output contract and JSON Schema document when required.
- reads input artifacts.
- renders prompt messages and hashes the rendered prompt.
- 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:
- creates a run ID and start timestamp.
- calls
Prepare. - calls the injected LLM client with rendered messages, effective target, target presence, and structured-output settings.
- builds the output artifact.
- validates the output.
- optionally attempts bounded repair when a repairer is injected and the contract permits repair.
- 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_attemptsis greater than zero- validation status is
failed - validation mode is
jsonorjson_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:
ErrInvalidRequestErrProfileRequiredErrAPIKeyEnvMissingErrAPIKeyRequiredErrPromptLoadErrProfileLoadErrArtifactLoadErrPromptRenderErrLLMGenerateErrValidation
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.gointernal/usecase/integration_test.goengine_test.gointernal/adapter/cli/run_test.gointernal/adapter/http/handler_test.go
Architectural Invariants
- Use-case decisions stay in
internal/usecase. RunreusesPrepare.- 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_attemptsand repairer presence. - Resolved secret values are never serialized or emitted.