Class: Aireview::ReviewPipeline
- Inherits:
-
Object
- Object
- Aireview::ReviewPipeline
- Defined in:
- lib/aireview/review_pipeline.rb
Overview
A review run: context → Generate → anchoring check against the diff → Critique (an LLM, or Jev with llm.critique.engine: jev) → report. Invalid JSON is repaired once by the same model; when the repair is invalid too, the stage restarts on another model with the original request.
Constant Summary collapse
- SchemaError =
ResultParser::SchemaError
- REPAIR_SYSTEM_PROMPT =
<<~PROMPT.strip.freeze You fix invalid JSON produced by another LLM call. Return only valid JSON matching the requested schema. Do not use markdown, code fences, comments, or text outside JSON. Do not add new review findings. PROMPT
- CUT_OFF_REASONS =
Finish reasons after which an unparsable answer gets no repair.
{ max_tokens: 'cut off at the output limit (max_tokens)', content_filter: 'blocked by the provider (content_filter)' }.freeze
Instance Method Summary collapse
-
#dry_run_prompts(merge_request:, changes:, jira_issue: nil, critique: true) ⇒ Object
The prompts of the run and everything --dry-run shows; see DryRunPrompts.
-
#initialize(config:, reviewer: nil, context_builder: nil, logger: Logger.new($stderr), **jev) ⇒ ReviewPipeline
constructor
jev — jev_shadow: and jev_stage: for tests; by default they are built from the config, the stage only when Jev is the engine.
- #run(merge_request:, changes:, jira_issue: nil, critique: true) ⇒ Object
Constructor Details
#initialize(config:, reviewer: nil, context_builder: nil, logger: Logger.new($stderr), **jev) ⇒ ReviewPipeline
jev — jev_shadow: and jev_stage: for tests; by default they are built from the config, the stage only when Jev is the engine.
38 39 40 41 42 43 44 45 46 47 |
# File 'lib/aireview/review_pipeline.rb', line 38 def initialize(config:, reviewer: nil, context_builder: nil, logger: Logger.new($stderr), **jev) @config = config @parser = ResultParser.new @reviewer = reviewer || Reviewer.new(config: config, logger: logger) @context_builder = context_builder || ContextBuilder.new(config: config, logger: logger) @jev_shadow = jev[:jev_shadow] || JevShadow.new(config: config, scrub: @context_builder.method(:scrub_text), logger: logger) @jev_stage = jev[:jev_stage] @logger = logger end |
Instance Method Details
#dry_run_prompts(merge_request:, changes:, jira_issue: nil, critique: true) ⇒ Object
The prompts of the run and everything --dry-run shows; see DryRunPrompts.
91 92 93 94 |
# File 'lib/aireview/review_pipeline.rb', line 91 def dry_run_prompts(merge_request:, changes:, jira_issue: nil, critique: true) DryRunPrompts.new(config: @config, context_builder: @context_builder, logger: @logger) .build(merge_request: merge_request, changes: changes, jira_issue: jira_issue, critique: critique) end |
#run(merge_request:, changes:, jira_issue: nil, critique: true) ⇒ Object
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/aireview/review_pipeline.rb', line 49 def run(merge_request:, changes:, jira_issue: nil, critique: true) context = @context_builder.prepare( merge_request: merge_request, changes: changes, jira_issue: jira_issue, critique: critique ) generate_prompt = @context_builder.build_generate_prompt(context) @logger.info("Pipeline generate pass started (model=#{@config.generate_model})") generate_result = run_stage('generate') do parse_with_repair( raw: @reviewer.generate(**generate_prompt), kind: 'generate result', expected: 'generate', repair_stage: 'generate' ) end summary = generate_result['summary'] candidates = Array(generate_result['candidates']) @logger.info("Pipeline generate pass completed with #{candidates.size} candidate(s) " \ "(model=#{@reviewer.answered_model('generate')})") candidates = check_candidates(context: context, changes: changes, candidates: candidates) accepted, jev_note = if critique maybe_critique(context: context, candidates: candidates) else skip_critique(candidates) end @logger.info("Pipeline finished with #{accepted.size} accepted finding(s)") ReviewRenderer.new(language: @config.review_language).render( accepted, summary: summary, coverage: context.coverage, fallback_models: @reviewer.fallback_models, critique_weaker: critique && @reviewer.critique_weaker?, jev_note: jev_note ) end |