PRIX / src /options.ts
Rachit-Tw's picture
feat: implement autonomous Auto-PR and optimize Docker image
5cb7295
Raw
History Blame Contribute Delete
6.67 kB
import {minimatch} from 'minimatch'
import {TokenLimits} from './limits'
const info = console.log
export type SeverityLevel = 'critical' | 'major' | 'minor' | 'info'
export class Options {
debug: boolean
disableReview: boolean
disableReleaseNotes: boolean
maxFiles: number
reviewSimpleChanges: boolean
reviewCommentLGTM: boolean
pathFilters: PathFilter
systemMessage: string
lightModel: string
heavyModel: string
modelTemperature: number
retries: number
timeoutMS: number
concurrencyLimit: number
githubConcurrencyLimit: number
lightTokenLimits: TokenLimits
heavyTokenLimits: TokenLimits
apiBaseUrl: string
language: string
createRemedyPR: boolean
minimumSeverity: SeverityLevel
minConfidence: number
denseMode: boolean
showImpactAnalysis: boolean
enableAutoPR: boolean
static readonly HEAVY_MODELS = [
'llama-3.3-70b-versatile',
'meta-llama/llama-4-scout-17b-16e-instruct',
'deepseek-r1-distill-llama-70b',
'openai/gpt-oss-120b',
'qwen/qwen3-32b'
]
static readonly LIGHT_MODELS = [
'meta-llama/llama-4-scout-17b-16e-instruct',
'llama-3.1-8b-instant',
'groq/compound'
]
static readonly SECURITY_MODELS = [
'openai/gpt-oss-safeguard-20b',
'meta-llama/llama-guard-4-12b',
'meta-llama/llama-prompt-guard-2-86m',
'meta-llama/llama-prompt-guard-2-22m'
]
constructor(
debug: boolean,
disableReview: boolean,
disableReleaseNotes: boolean,
maxFiles = '0',
reviewSimpleChanges = false,
reviewCommentLGTM = false,
pathFilters: string[] | null = null,
systemMessage = '',
lightModel = 'meta-llama/llama-4-scout-17b-16e-instruct',
heavyModel = 'llama-3.3-70b-versatile',
modelTemperature = '0.0',
retries = '3',
timeoutMS = '120000',
concurrencyLimit = '3',
githubConcurrencyLimit = '10',
apiBaseUrl = 'https://api.groq.com/openai/v1',
language = 'en-US',
createRemedyPR = true,
minimumSeverity: SeverityLevel = 'minor',
minConfidence = '0',
denseMode = 'false',
showImpactAnalysis = 'true',
enableAutoPR = false
) {
this.debug = debug
this.disableReview = disableReview
this.disableReleaseNotes = disableReleaseNotes
this.maxFiles = parseInt(maxFiles)
this.reviewSimpleChanges = reviewSimpleChanges
this.reviewCommentLGTM = reviewCommentLGTM
this.pathFilters = new PathFilter(pathFilters)
this.systemMessage = systemMessage
this.lightModel = lightModel
this.heavyModel = heavyModel
this.modelTemperature = parseFloat(modelTemperature)
this.retries = parseInt(retries)
this.timeoutMS = parseInt(timeoutMS)
this.concurrencyLimit = parseInt(concurrencyLimit)
this.githubConcurrencyLimit = parseInt(githubConcurrencyLimit)
this.apiBaseUrl = apiBaseUrl
this.language = language
this.createRemedyPR = createRemedyPR
this.minimumSeverity = minimumSeverity
this.minConfidence = parseInt(minConfidence)
this.denseMode = denseMode === 'true'
this.showImpactAnalysis = showImpactAnalysis === 'true'
this.enableAutoPR = enableAutoPR
this.lightTokenLimits = new TokenLimits(this.lightModel)
this.heavyTokenLimits = new TokenLimits(this.heavyModel)
}
// print all options using core.info
print(): void {
info(`debug: ${this.debug}`)
info(`disable_review: ${this.disableReview}`)
info(`disable_release_notes: ${this.disableReleaseNotes}`)
info(`max_files: ${this.maxFiles}`)
info(`review_simple_changes: ${this.reviewSimpleChanges}`)
info(`review_comment_lgtm: ${this.reviewCommentLGTM}`)
info(`path_filters: ${this.pathFilters}`)
info(`system_message: ${this.systemMessage}`)
info(`light_model: ${this.lightModel}`)
info(`heavy_model: ${this.heavyModel}`)
info(`model_temperature: ${this.modelTemperature}`)
info(`retries: ${this.retries}`)
info(`timeout_ms: ${this.timeoutMS}`)
info(`concurrency_limit: ${this.concurrencyLimit}`)
info(`github_concurrency_limit: ${this.githubConcurrencyLimit}`)
info(`summary_token_limits: ${this.lightTokenLimits.string()}`)
info(`review_token_limits: ${this.heavyTokenLimits.string()}`)
info(`api_base_url: ${this.apiBaseUrl}`)
info(`language: ${this.language}`)
info(`create_remedy_pr: ${this.createRemedyPR}`)
info(`enable_auto_pr: ${this.enableAutoPR}`)
}
checkPath(path: string): boolean {
const ok = this.pathFilters.check(path)
info(`checking path: ${path} => ${ok}`)
return ok
}
private static readonly SEVERITY_ORDER: SeverityLevel[] = [
'critical',
'major',
'minor',
'info'
]
meetsMinimumSeverity(findingSeverity: SeverityLevel): boolean {
const minIndex = Options.SEVERITY_ORDER.indexOf(this.minimumSeverity)
const findingIndex = Options.SEVERITY_ORDER.indexOf(findingSeverity)
return findingIndex >= minIndex
}
meetsConfidenceThreshold(confidence: number): boolean {
return confidence >= this.minConfidence
}
}
export class PathFilter {
private readonly rules: Array<[string /* rule */, boolean /* exclude */]>
constructor(rules: string[] | null = null) {
this.rules = []
if (rules != null) {
for (const rule of rules) {
const trimmed = rule?.trim()
if (trimmed) {
if (trimmed.startsWith('!')) {
this.rules.push([trimmed.substring(1).trim(), true])
} else {
this.rules.push([trimmed, false])
}
}
}
}
}
check(path: string): boolean {
if (this.rules.length === 0) {
return true
}
let included = false
let excluded = false
let inclusionRuleExists = false
for (const [rule, exclude] of this.rules) {
if (minimatch(path, rule)) {
if (exclude) {
excluded = true
} else {
included = true
}
}
if (!exclude) {
inclusionRuleExists = true
}
}
return (!inclusionRuleExists || included) && !excluded
}
}
export class AIOptions {
model: string
tokenLimits: TokenLimits
temperature: number
constructor(
model = 'meta-llama/llama-4-scout-17b-16e-instruct',
tokenLimits: TokenLimits | null = null,
temperature = 0.0
) {
this.model = model
this.temperature = temperature
if (tokenLimits != null) {
this.tokenLimits = tokenLimits
} else {
this.tokenLimits = new TokenLimits(model)
}
}
}