6.3 KiB
Runner Internals
Purpose
internal/usecase.Runner is the core use case orchestrator for prompt preparation and execution.
It owns request validation, prompt/profile resolution, runtime-parameter merge, artifact loading, prompt rendering, structured-output setup, LLM invocation, output validation, and result metadata.
Inputs And Outputs
Primary input type:
domain.RunRequest
Primary output types:
domain.PreparedRunfromPreparedomain.RunResultfromRun
LLM boundary types:
domain.GenerateRequestdomain.GenerateResponse
Boundaries
Runner coordinates the following interfaces:
promptdef.Repositoryprofile.Repositoryartifact.Readerprompt.Rendererllm.Clientvalidate.Validator- optional
usecase.OutputRepairer
Transport concerns (CLI flags, HTTP DTO parsing, status-code mapping) stay outside runner.
Config Fields Used
Runner does not read app config files directly.
It receives fully constructed repositories/readers/validators from adapters. Effective behavior depends on adapter wiring, including:
- prompt/profile directories
- schema base directory
- selected profile/runtime overrides in request
External Adapters Used
Runner works with adapter implementations via interfaces. Current wiring from CLI/HTTP uses:
- filesystem prompt/profile repositories
- composite artifact reader
- Go-template prompt renderer
- OpenAI-compatible LLM client
- standard validator
State And Resume Behavior
Runner is stateless across requests.
- No durable run-state storage.
- No built-in resume/skip checkpoints.
- Each
Run/Prepareexecutes from request inputs and current repositories.
Failure Behavior
Primary runner error classes:
ErrInvalidRequest: invalid run request envelope.ErrProfileRequired: specific invalid-request reason when neither requestprofile_idnor promptdefault_profileis available.ErrAPIKeyEnvMissing: specific invalid-request reason whenapi_key_envis set but the named environment variable is unset/empty.ErrPromptLoad: prompt-definition repository load failures.ErrProfileLoad: execution-profile repository load failures.ErrArtifactLoad: artifact read failures.ErrPromptRender: template render failures.ErrLLMGenerate: outbound model request failures.ErrValidation: validation runtime failures (including structured-output schema load/compile failures).
Reason sentinel behavior:
ErrProfileRequiredandErrAPIKeyEnvMissingare wrapped withErrInvalidRequest.- Adapters can use
errors.Isfor stable reason mapping without matching runner prose.
Validation content failures are not run errors:
Runcan succeed withValidation.Status == failed.- CLI maps this to exit code
2. - HTTP returns
200with failed validation details.
Prepare Flow
Prepare performs:
- validate request basics (prompt ID present).
- load prompt definition by ID/version.
- select profile ID:
- explicit request profile ID
- prompt
default_profile - otherwise return an invalid request with
ErrProfileRequired
- load execution profile.
- merge effective runtime target:
- built-in execution defaults
- selected profile values
- request overrides
- request numeric overrides are presence-aware, so omitted values preserve the current effective value and explicit zero values override it
- verify credentials when the effective target names
api_key_env:- a request-scoped direct API key satisfies the credential requirement
- otherwise a missing/empty env value returns an invalid request with
ErrAPIKeyEnvMissing - only the environment-variable name is returned in public output; secret values are never returned
- resolve output contract and structured-output schema payload when
json_schemamode is active. - read input artifacts.
- render prompt messages, including any normalized message cache-control metadata.
- compute prompt/input/render hashes and return
PreparedRun.
rendered_prompt_hash includes cache-control metadata when present because it affects the outbound provider request. Prompts without cache control keep the role/content hash behavior.
Prepare does not call the LLM.
Runtime target notes:
- Profile
extra_paramsand requestextra_paramscarry JSON-compatible values through prepared output, run metadata, anddomain.GenerateRequest.Target. - The OpenAI-compatible client serializes non-empty
reasoning_effortas a top-level provider request field. - The OpenAI-compatible client flattens
extra_paramsinto provider-specific top-level JSON request fields. - Empty
extra_paramskeys, reserved outbound field names, and values that cannot be JSON-encoded fail before the provider request. - Resolved API-key values are never serialized in prepared/run output, public results, logs, or HTTP responses.
- Public direct API-key values are carried only far enough to call the configured LLM client and are excluded from JSON/YAML serialization.
Run Flow
Run performs:
- generate run ID.
- call
Prepare. - call LLM with prepared messages/effective target/structured-output spec.
- build output artifact content type from output format.
- validate output.
- optionally attempt bounded repair when repairer is injected and contract allows it.
- return
RunResultwith artifact, raw output, validation, hashes, profile/model metadata, token/cache usage, and timestamps.
Repair Hook Boundary
Repair attempts occur only when all are true:
- repairer is injected
repair_attempts > 0- validation status is
failed - validation mode is
jsonorjson_schema
Current production wiring boundary:
- CLI and HTTP adapters call
usecase.NewRunner(...)(no repairer argument). - Therefore normal CLI/HTTP execution does not perform repair attempts today.
Tests To Inspect Before Changing
internal/usecase/runner_test.gointernal/usecase/integration_test.gointernal/adapter/cli/run_test.gointernal/adapter/http/handler_test.go
Architectural Invariants
RunreusesPrepare; prepare logic is not duplicated.- Effective API-key environment-variable name may appear; resolved secret value must not.
- Structured-output schema document must load before LLM call for
json_schemamode. - Repair loops are bounded by
repair_attemptsand repairer presence. - Runner stays transport-agnostic.