diff --git a/.gitea/actions/review/action.yml b/.gitea/actions/review/action.yml index 2670ba9..e79a2bb 100644 --- a/.gitea/actions/review/action.yml +++ b/.gitea/actions/review/action.yml @@ -46,9 +46,25 @@ inputs: required: false default: 'README.md' temperature: - description: 'LLM temperature (0 = server default)' + timeout: + description: 'LLM request timeout in seconds (default 300)' required: false + default: '300' + description: 'LLM temperature (0 = server default)' + timeout: + description: 'LLM request timeout in seconds (default 300)' + required: false + default: '300' + required: false + timeout: + description: 'LLM request timeout in seconds (default 300)' + required: false + default: '300' default: '0' + timeout: + description: 'LLM request timeout in seconds (default 300)' + required: false + default: '300' version: description: 'review-bot version to install (e.g. v0.1.0, defaults to latest)' required: false @@ -134,6 +150,7 @@ runs: PATTERNS_REPO: ${{ inputs.patterns-repo }} PATTERNS_FILES: ${{ inputs.patterns-files }} LLM_TEMPERATURE: ${{ inputs.temperature }} + LLM_TIMEOUT: ${{ inputs.timeout }} run: | ARGS="" if [ "${{ inputs.dry-run }}" = "true" ]; then diff --git a/cmd/review-bot/main.go b/cmd/review-bot/main.go index 3e7c447..d7d30e4 100644 --- a/cmd/review-bot/main.go +++ b/cmd/review-bot/main.go @@ -32,6 +32,7 @@ func main() { patternsFiles := flag.String("patterns-files", envOrDefault("PATTERNS_FILES", "README.md"), "Comma-separated file paths to fetch from patterns repo") dryRun := flag.Bool("dry-run", false, "Print review to stdout instead of posting") llmTemp := flag.Float64("llm-temperature", envOrDefaultFloat("LLM_TEMPERATURE", 0), "LLM temperature (0 = server default)") + llmTimeout := flag.Int("llm-timeout", envOrDefaultInt("LLM_TIMEOUT", 300), "LLM request timeout in seconds (default 300)") flag.Parse() @@ -65,6 +66,9 @@ func main() { if *llmTemp > 0 { llmClient.WithTemperature(*llmTemp) } + if *llmTimeout > 0 { + llmClient.WithTimeout(time.Duration(*llmTimeout) * time.Second) + } // Create a top-level context with a 3-minute timeout for all operations ctx, cancel := context.WithTimeout(context.Background(), 3*time.Minute) @@ -285,3 +289,13 @@ func envOrDefaultFloat(key string, defaultVal float64) float64 { } return defaultVal } + +func envOrDefaultInt(key string, defaultVal int) int { + if v := os.Getenv(key); v != "" { + i, err := strconv.Atoi(v) + if err == nil { + return i + } + } + return defaultVal +} diff --git a/llm/client.go b/llm/client.go index 6067925..8ad145d 100644 --- a/llm/client.go +++ b/llm/client.go @@ -32,6 +32,12 @@ func NewClient(baseURL, apiKey, model string) *Client { } // WithTemperature sets the temperature for LLM requests (0 = omit, uses server default). +// WithTimeout sets the HTTP request timeout for LLM calls (default 5 minutes). +func (c *Client) WithTimeout(d time.Duration) *Client { + c.http.Timeout = d + return c +} + func (c *Client) WithTemperature(t float64) *Client { c.temperature = t return c