Connect processing to shared PromptKit backend capacity
This commit is contained in:
@@ -34,8 +34,6 @@ type Runner struct {
|
||||
factory ModuleFactory
|
||||
}
|
||||
|
||||
type ValidationScheduler = contracts.LLMScheduler
|
||||
|
||||
// ModuleResult captures deterministic per-module execution output.
|
||||
type ModuleResult struct {
|
||||
ModuleKey string `json:"module_key"`
|
||||
@@ -80,12 +78,9 @@ type RunInput struct {
|
||||
Transcript *schema.Transcript
|
||||
Glossary *schema.Glossary
|
||||
ModuleSpecs []contracts.ModuleRunSpec
|
||||
EffectiveConcurrency EffectiveConcurrencyLimits
|
||||
ProposalLLMClient contracts.StructuredLLMClient
|
||||
ProposalLLMScheduler contracts.LLMScheduler
|
||||
ProposalDiagnosticsDir string
|
||||
ValidationLLMClient contracts.StructuredLLMClient
|
||||
ValidationLLMScheduler ValidationScheduler
|
||||
ValidationDiagnosticsDir string
|
||||
}
|
||||
|
||||
@@ -93,7 +88,6 @@ type RunInput struct {
|
||||
type RunOutput struct {
|
||||
FinalTranscript *schema.Transcript `json:"-"`
|
||||
ModuleResults []ModuleResult `json:"module_results"`
|
||||
Utilization *UtilizationDiagnostics
|
||||
}
|
||||
|
||||
func New(factory ModuleFactory) *Runner {
|
||||
@@ -105,14 +99,6 @@ func (r *Runner) Run(ctx context.Context, input RunInput) (RunOutput, error) {
|
||||
return RunOutput{}, fmt.Errorf("runner module factory is required")
|
||||
}
|
||||
|
||||
startedAt := time.Now().UTC()
|
||||
instrumentation := newRunInstrumentation(startedAt)
|
||||
|
||||
input.ProposalLLMClient = instrumentation.wrapProposalClient(input.ProposalLLMClient)
|
||||
input.ValidationLLMClient = instrumentation.wrapValidationClient(input.ValidationLLMClient)
|
||||
input.ProposalLLMScheduler = instrumentation.wrapScheduler(input.ProposalLLMScheduler, true)
|
||||
input.ValidationLLMScheduler = instrumentation.wrapScheduler(input.ValidationLLMScheduler, false)
|
||||
|
||||
working := cloneTranscript(input.Transcript)
|
||||
results := make([]ModuleResult, 0, len(input.ModuleSpecs))
|
||||
|
||||
@@ -132,7 +118,6 @@ func (r *Runner) Run(ctx context.Context, input RunInput) (RunOutput, error) {
|
||||
return RunOutput{
|
||||
FinalTranscript: working,
|
||||
ModuleResults: results,
|
||||
Utilization: instrumentation.finalize(&RunOutput{ModuleResults: results}, time.Now().UTC(), input.EffectiveConcurrency),
|
||||
}, fmt.Errorf("module %q setup failed: %w", spec.InstanceName, err)
|
||||
}
|
||||
|
||||
@@ -152,7 +137,6 @@ func (r *Runner) Run(ctx context.Context, input RunInput) (RunOutput, error) {
|
||||
return RunOutput{
|
||||
FinalTranscript: working,
|
||||
ModuleResults: results,
|
||||
Utilization: instrumentation.finalize(&RunOutput{ModuleResults: results}, time.Now().UTC(), input.EffectiveConcurrency),
|
||||
}, fmt.Errorf("module %q chunking failed: %w", spec.InstanceName, err)
|
||||
}
|
||||
|
||||
@@ -164,12 +148,9 @@ func (r *Runner) Run(ctx context.Context, input RunInput) (RunOutput, error) {
|
||||
Glossary: input.Glossary,
|
||||
Sections: sections,
|
||||
ProposalClient: input.ProposalLLMClient,
|
||||
ProposalScheduler: input.ProposalLLMScheduler,
|
||||
DiagnosticsDir: input.ProposalDiagnosticsDir,
|
||||
ValidationClient: input.ValidationLLMClient,
|
||||
ValidationScheduler: input.ValidationLLMScheduler,
|
||||
ValidationDiagnosticsDir: input.ValidationDiagnosticsDir,
|
||||
Instrumentation: instrumentation,
|
||||
})
|
||||
if pipelineErr != nil {
|
||||
failed := ModuleResult{
|
||||
@@ -189,7 +170,6 @@ func (r *Runner) Run(ctx context.Context, input RunInput) (RunOutput, error) {
|
||||
return RunOutput{
|
||||
FinalTranscript: working,
|
||||
ModuleResults: results,
|
||||
Utilization: instrumentation.finalize(&RunOutput{ModuleResults: results}, time.Now().UTC(), input.EffectiveConcurrency),
|
||||
}, fmt.Errorf("module %q failed: %w", spec.InstanceName, pipelineErr)
|
||||
}
|
||||
|
||||
@@ -213,7 +193,6 @@ func (r *Runner) Run(ctx context.Context, input RunInput) (RunOutput, error) {
|
||||
}
|
||||
|
||||
output := RunOutput{FinalTranscript: working, ModuleResults: results}
|
||||
output.Utilization = instrumentation.finalize(&output, time.Now().UTC(), input.EffectiveConcurrency)
|
||||
return output, nil
|
||||
}
|
||||
|
||||
@@ -225,12 +204,9 @@ type collectSectionProposalsInput struct {
|
||||
Glossary *schema.Glossary
|
||||
Sections []chunking.Section
|
||||
ProposalClient contracts.StructuredLLMClient
|
||||
ProposalScheduler contracts.LLMScheduler
|
||||
DiagnosticsDir string
|
||||
ValidationClient contracts.StructuredLLMClient
|
||||
ValidationScheduler ValidationScheduler
|
||||
ValidationDiagnosticsDir string
|
||||
Instrumentation *runInstrumentation
|
||||
}
|
||||
|
||||
type sectionProposals struct {
|
||||
@@ -279,7 +255,7 @@ func collectSectionProposals(ctx context.Context, input collectSectionProposalsI
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
meta := contracts.SectionMetadataFromSection(section)
|
||||
proposalResult, err := input.Module.Propose(withModuleInstanceContext(runCtx, input.Spec.InstanceName), contracts.ProposalRequest{
|
||||
proposalResult, err := input.Module.Propose(runCtx, contracts.ProposalRequest{
|
||||
ExecutionContext: contracts.ExecutionContext{
|
||||
Config: input.Config,
|
||||
WorkingTranscript: transcriptFromSection(section),
|
||||
@@ -292,8 +268,7 @@ func collectSectionProposals(ctx context.Context, input collectSectionProposalsI
|
||||
InstanceName: input.Spec.InstanceName,
|
||||
ReplacementPolicy: input.Policy,
|
||||
},
|
||||
LLMClient: input.ProposalClient,
|
||||
LLMScheduler: input.ProposalScheduler,
|
||||
LLMClient: input.ProposalClient,
|
||||
})
|
||||
select {
|
||||
case results <- sectionProposalResult{
|
||||
@@ -402,9 +377,7 @@ func runModulePipeline(ctx context.Context, input collectSectionProposalsInput)
|
||||
Validators: validatorsOrdered,
|
||||
SectionEnriched: enriched,
|
||||
ValidationLLMClient: input.ValidationClient,
|
||||
ValidationScheduler: input.ValidationScheduler,
|
||||
DiagnosticsDir: input.ValidationDiagnosticsDir,
|
||||
Instrumentation: input.Instrumentation,
|
||||
})
|
||||
validationResults <- sectionValidationResult{
|
||||
sectionPos: sectionPos,
|
||||
@@ -503,9 +476,7 @@ type validateSectionCandidatesInput struct {
|
||||
Validators []contracts.Validator
|
||||
SectionEnriched []proposals.EnrichedCorrectionProposal
|
||||
ValidationLLMClient contracts.StructuredLLMClient
|
||||
ValidationScheduler ValidationScheduler
|
||||
DiagnosticsDir string
|
||||
Instrumentation *runInstrumentation
|
||||
}
|
||||
|
||||
type validateSectionCandidatesResult struct {
|
||||
@@ -532,8 +503,7 @@ func validateSectionCandidates(ctx context.Context, input validateSectionCandida
|
||||
}
|
||||
}
|
||||
|
||||
validatorStartedAt := time.Now().UTC()
|
||||
vResult, err := validator.Validate(withModuleInstanceContext(ctx, input.Spec.InstanceName), contracts.ValidationRequest{
|
||||
vResult, err := validator.Validate(ctx, contracts.ValidationRequest{
|
||||
WorkingTranscript: input.WorkingTranscript,
|
||||
CandidateProposal: eligible,
|
||||
ModuleKey: input.Spec.ModuleKey,
|
||||
@@ -541,19 +511,10 @@ func validateSectionCandidates(ctx context.Context, input validateSectionCandida
|
||||
ReplacementPolicy: input.Policy,
|
||||
Glossary: input.Glossary,
|
||||
Config: input.Config,
|
||||
LLMClient: validationLLMClientAdapter{client: input.ValidationLLMClient},
|
||||
Scheduler: input.ValidationScheduler,
|
||||
LLMClient: input.ValidationLLMClient,
|
||||
DiagnosticsWriter: diagnosticsWriter,
|
||||
})
|
||||
if input.Instrumentation != nil {
|
||||
input.Instrumentation.recordValidatorTiming(
|
||||
input.Spec.ModuleKey,
|
||||
input.Spec.InstanceName,
|
||||
validator.Name(),
|
||||
isLLMBackedValidator(validator),
|
||||
time.Since(validatorStartedAt),
|
||||
)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return validateSectionCandidatesResult{
|
||||
approved: eligible,
|
||||
@@ -650,9 +611,9 @@ func chunkWorkingTranscript(cfg *config.Config, transcript *schema.Transcript) (
|
||||
}, nil
|
||||
}
|
||||
chunker := chunking.NewChunker(chunking.ChunkingConfig{
|
||||
MaxSectionTokens: cfg.MaxSectionTokens,
|
||||
MinSectionTokens: cfg.MinSectionTokens,
|
||||
TargetSections: cfg.TargetSections,
|
||||
MaxSectionTokens: cfg.Chunking.MaxSectionTokens,
|
||||
MinSectionTokens: cfg.Chunking.MinSectionTokens,
|
||||
TargetSections: cfg.Chunking.TargetSections,
|
||||
})
|
||||
return chunker.ChunkTranscript(transcript)
|
||||
}
|
||||
@@ -697,34 +658,6 @@ func cloneTranscript(t *schema.Transcript) *schema.Transcript {
|
||||
return &schema.Transcript{Segments: segments}
|
||||
}
|
||||
|
||||
type validationLLMClientAdapter struct {
|
||||
client contracts.StructuredLLMClient
|
||||
}
|
||||
|
||||
func (a validationLLMClientAdapter) CompleteStructured(ctx context.Context, req validators.StructuredCompletionRequest, out any) (validators.StructuredCompletionResponse, error) {
|
||||
if a.client == nil {
|
||||
return validators.StructuredCompletionResponse{}, fmt.Errorf("validation structured LLM client is not configured")
|
||||
}
|
||||
messages := make([]contracts.LLMMessage, len(req.Messages))
|
||||
for i, m := range req.Messages {
|
||||
messages[i] = contracts.LLMMessage{Role: m.Role, Content: m.Content}
|
||||
}
|
||||
resp, err := a.client.CompleteStructured(ctx, contracts.StructuredCompletionRequest{
|
||||
StageName: req.StageName,
|
||||
Messages: messages,
|
||||
Model: req.Model,
|
||||
ResponseSchema: req.ResponseSchema,
|
||||
}, out)
|
||||
if err != nil {
|
||||
return validators.StructuredCompletionResponse{}, err
|
||||
}
|
||||
return validators.StructuredCompletionResponse{
|
||||
PromptTokens: resp.PromptTokens,
|
||||
CompletionTokens: resp.CompletionTokens,
|
||||
TotalTokens: resp.TotalTokens,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type llmDiagnosticsWriterAdapter struct {
|
||||
writer *llm.DiagnosticsWriter
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user