Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ openai_base_url: "https://api.openai.com/v1"
db_path: "./reportbot.db"
report_output_dir: "./reportbot-reports"
external_http_timeout_seconds: 90
# Skip TLS certificate verification (for internal/corporate CAs)
tls_skip_verify: false

# Channel ID used for report reminders and links
report_channel_id: "C01234567"
Expand Down
2 changes: 1 addition & 1 deletion internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import (

func Main() {
cfg := config.LoadConfig()
appliedHTTPTimeout := httpx.ConfigureExternalHTTPClient(cfg.ExternalHTTPTimeoutSeconds)
appliedHTTPTimeout := httpx.ConfigureExternalHTTPClient(cfg.ExternalHTTPTimeoutSeconds, cfg.TLSSkipVerify)
log.Printf(
"Config loaded. Team=%s Managers=%d TeamMembers=%d Timezone=%s LLMBatchSize=%d LLMConfidenceThreshold=%.2f LLMExampleCount=%d LLMExampleMaxChars=%d LLMGlossaryPath=%s OpenAIBaseURL=%s ExternalHTTPTimeout=%s",
cfg.TeamName,
Expand Down
4 changes: 3 additions & 1 deletion internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ type Config struct {
DBPath string `yaml:"db_path"`
ReportOutputDir string `yaml:"report_output_dir"`
ReportChannelID string `yaml:"report_channel_id"`
ExternalHTTPTimeoutSeconds int `yaml:"external_http_timeout_seconds"`
ExternalHTTPTimeoutSeconds int `yaml:"external_http_timeout_seconds"`
TLSSkipVerify bool `yaml:"tls_skip_verify"`

ManagerSlackIDs []string `yaml:"manager_slack_ids"`
TeamMembers []string `yaml:"team_members"`
Expand Down Expand Up @@ -107,6 +108,7 @@ func LoadConfig() Config {
envOverride(&cfg.ReportOutputDir, "REPORT_OUTPUT_DIR")
envOverride(&cfg.ReportChannelID, "REPORT_CHANNEL_ID")
envOverrideInt(&cfg.ExternalHTTPTimeoutSeconds, "EXTERNAL_HTTP_TIMEOUT_SECONDS")
envOverrideBool(&cfg.TLSSkipVerify, "TLS_SKIP_VERIFY")
envOverride(&cfg.TeamName, "TEAM_NAME")
envOverride(&cfg.NudgeDay, "NUDGE_DAY")
envOverride(&cfg.NudgeTime, "NUDGE_TIME")
Expand Down
8 changes: 7 additions & 1 deletion internal/httpx/http_client.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package httpx

import (
"crypto/tls"
"net/http"
"time"
)
Expand All @@ -11,12 +12,17 @@ var externalHTTPClient = &http.Client{
Timeout: defaultExternalHTTPTimeout,
}

func ConfigureExternalHTTPClient(timeoutSeconds int) time.Duration {
func ConfigureExternalHTTPClient(timeoutSeconds int, tlsSkipVerify bool) time.Duration {
timeout := defaultExternalHTTPTimeout
if timeoutSeconds > 0 {
timeout = time.Duration(timeoutSeconds) * time.Second
}
externalHTTPClient.Timeout = timeout
if tlsSkipVerify {
externalHTTPClient.Transport = &http.Transport{
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
}
}
return timeout
}

Expand Down
4 changes: 2 additions & 2 deletions internal/httpx/http_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ func TestConfigureExternalHTTPClient(t *testing.T) {
externalHTTPClient.Timeout = original
})

got := ConfigureExternalHTTPClient(0)
got := ConfigureExternalHTTPClient(0, false)
if got != defaultExternalHTTPTimeout {
t.Fatalf("ConfigureExternalHTTPClient(0) = %s, want %s", got, defaultExternalHTTPTimeout)
}
if externalHTTPClient.Timeout != defaultExternalHTTPTimeout {
t.Fatalf("configured timeout = %s, want %s", externalHTTPClient.Timeout, defaultExternalHTTPTimeout)
}

got = ConfigureExternalHTTPClient(120)
got = ConfigureExternalHTTPClient(120, false)
if got != 120*time.Second {
t.Fatalf("ConfigureExternalHTTPClient(120) = %s, want %s", got, 120*time.Second)
}
Expand Down
16 changes: 15 additions & 1 deletion internal/integrations/llm/llm.go
Original file line number Diff line number Diff line change
Expand Up @@ -703,9 +703,23 @@ func doOpenAIResponsesRequest(apiKey, baseURL string, reqBody openAIResponsesReq
return "", LLMUsage{}, fmt.Errorf("reading responses body: %w", err)
}

if resp.StatusCode != http.StatusOK {
truncated := string(respBody)
if len(truncated) > 512 {
truncated = truncated[:512] + "..."
}
log.Printf("llm openai responses HTTP %d: %s", resp.StatusCode, truncated)
return "", LLMUsage{}, fmt.Errorf("OpenAI Responses API HTTP %d: %s", resp.StatusCode, truncated)
}

var responsesResp openAIResponsesResponse
if err := json.Unmarshal(respBody, &responsesResp); err != nil {
return "", LLMUsage{}, fmt.Errorf("parsing OpenAI Responses payload: %w", err)
truncated := string(respBody)
if len(truncated) > 512 {
truncated = truncated[:512] + "..."
}
log.Printf("llm openai responses invalid JSON: %s", truncated)
return "", LLMUsage{}, fmt.Errorf("parsing OpenAI Responses payload: %w (body: %s)", err, truncated)
}
if responsesResp.Error != nil {
log.Printf("llm openai responses api error: %s", responsesResp.Error.Message)
Expand Down