Configure built-in retries across execution paths

This commit is contained in:
2026-09-23 16:56:20 +00:00
parent ae4540822e
commit 07a131bd33
21 changed files with 441 additions and 90 deletions

View File

@@ -43,15 +43,16 @@ var (
// Runner executes the Promptkit core use case.
type Runner struct {
promptDefs promptdef.Repository
profiles profile.Repository
backends BackendResolver
artifacts artifact.Reader
renderer prompt.Renderer
llm llm.Client
validator validate.Validator
repairer OutputRepairer
admitter RunAdmitter
promptDefs promptdef.Repository
profiles profile.Repository
backends BackendResolver
artifacts artifact.Reader
renderer prompt.Renderer
llm llm.Client
validator validate.Validator
repairer OutputRepairer
admitter RunAdmitter
defaultTransientRetries uint64
}
// BackendResolver resolves one normalized backend ID.
@@ -73,6 +74,7 @@ type preparationState struct {
targetPresence domain.ExecutionTargetPresence
effectiveContract domain.OutputContract
start time.Time
transientRetries uint64
}
type preparedOperation struct {
@@ -113,17 +115,23 @@ func NewRunnerWithRepairer(
validator validate.Validator,
repairer OutputRepairer,
admitter RunAdmitter,
defaultTransientRetries ...uint64,
) *Runner {
retries := uint64(0)
if len(defaultTransientRetries) > 0 {
retries = defaultTransientRetries[0]
}
return &Runner{
promptDefs: promptDefs,
profiles: profiles,
backends: backends,
artifacts: artifacts,
renderer: renderer,
llm: llmClient,
validator: validator,
repairer: repairer,
admitter: admitter,
promptDefs: promptDefs,
profiles: profiles,
backends: backends,
artifacts: artifacts,
renderer: renderer,
llm: llmClient,
validator: validator,
repairer: repairer,
admitter: admitter,
defaultTransientRetries: retries,
}
}
@@ -152,7 +160,7 @@ func (r *Runner) Run(ctx context.Context, req domain.RunRequest) (*domain.RunRes
}
directAPIKey := state.effectiveModel.APIKey
return r.executePreparedRun(ctx, operation.run, directAPIKey, runID, start, func(
return r.executePreparedRun(ctx, operation.run, directAPIKey, state.transientRetries, runID, start, func(
ctx context.Context,
artifact *domain.Artifact,
attemptsUsed int,
@@ -173,6 +181,7 @@ func (r *Runner) executePreparedRun(
ctx context.Context,
prepared *domain.PreparedRun,
directAPIKey string,
transientRetries uint64,
runID string,
start time.Time,
validateArtifact preparedValidationFunc,
@@ -185,6 +194,7 @@ func (r *Runner) executePreparedRun(
executionTarget,
prepared.TargetPresence,
prepared.StructuredOutput,
transientRetries,
))
if err != nil {
return nil, wrapGenerationError(err)
@@ -213,6 +223,7 @@ func (r *Runner) executePreparedRun(
Target: executionTarget,
TargetPresence: prepared.TargetPresence,
StructuredOutput: prepared.StructuredOutput,
TransientRetries: transientRetries,
Attempt: attemptsUsed,
MaxAttempts: prepared.OutputContract.RepairAttempts,
Mode: prepared.OutputContract.ValidationMode,
@@ -295,6 +306,10 @@ func (r *Runner) resolvePreparation(
req domain.RunRequest,
start time.Time,
) (*preparationState, error) {
transientRetries, err := domain.ResolveTransientRetries(r.defaultTransientRetries, req.TransientRetries)
if err != nil {
return nil, fmt.Errorf("%w: %w", ErrInvalidRequest, err)
}
if strings.TrimSpace(req.PromptID) == "" {
return nil, fmt.Errorf("%w: prompt id is required", ErrInvalidRequest)
}
@@ -346,6 +361,7 @@ func (r *Runner) resolvePreparation(
targetPresence: targetPresence,
effectiveContract: effectiveContract,
start: start,
transientRetries: transientRetries,
}, nil
}