Fix Anthropic requests failing due to missing MaxTokens in agent configuration

Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
Bryan Frimin
2026-03-13 18:24:02 +01:00
parent 356de5ab19
commit 7c77c217c7
14 changed files with 29 additions and 10 deletions

View File

@@ -89,6 +89,7 @@ probod:
api-key: "thisisnotasecret" api-key: "thisisnotasecret"
temperature: 0.1 temperature: 0.1
model-name: "gpt-4o" model-name: "gpt-4o"
max-tokens: 4096
custom-domains: custom-domains:
renewal-interval: 3600 renewal-interval: 3600

View File

@@ -413,6 +413,7 @@ spec:
| probo.openai.apiKey | string | `""` | OpenAI API key for AI features (optional) | | probo.openai.apiKey | string | `""` | OpenAI API key for AI features (optional) |
| probo.openai.temperature | float | `0.1` | OpenAI temperature setting | | probo.openai.temperature | float | `0.1` | OpenAI temperature setting |
| probo.openai.modelName | string | `"gpt-4o"` | OpenAI model name | | probo.openai.modelName | string | `"gpt-4o"` | OpenAI model name |
| probo.openai.maxTokens | int | `4096` | Maximum output tokens for LLM requests |
| probo.customDomains.enabled | bool | `false` | Enable custom domains feature | | probo.customDomains.enabled | bool | `false` | Enable custom domains feature |
| probo.customDomains.renewalInterval | int | `3600` | Certificate renewal interval in seconds | | probo.customDomains.renewalInterval | int | `3600` | Certificate renewal interval in seconds |
| probo.customDomains.provisionInterval | int | `30` | Domain provision interval in seconds | | probo.customDomains.provisionInterval | int | `30` | Domain provision interval in seconds |

View File

@@ -217,6 +217,8 @@ spec:
value: {{ .Values.probo.openai.temperature | quote }} value: {{ .Values.probo.openai.temperature | quote }}
- name: OPENAI_MODEL_NAME - name: OPENAI_MODEL_NAME
value: {{ .Values.probo.openai.modelName | quote }} value: {{ .Values.probo.openai.modelName | quote }}
- name: OPENAI_MAX_TOKENS
value: {{ .Values.probo.openai.maxTokens | quote }}
{{- end }} {{- end }}
# Custom Domains # Custom Domains
{{- if .Values.probo.customDomains.enabled }} {{- if .Values.probo.customDomains.enabled }}

View File

@@ -157,6 +157,7 @@ probo:
apiKey: "CHANGE_ME_OPENAI_API_KEY" apiKey: "CHANGE_ME_OPENAI_API_KEY"
temperature: 0.1 temperature: 0.1
modelName: "gpt-4o" modelName: "gpt-4o"
maxTokens: 4096
# OpenTelemetry tracing (optional) # OpenTelemetry tracing (optional)
tracing: tracing:

View File

@@ -252,6 +252,7 @@ probo:
apiKey: "" apiKey: ""
temperature: 0.1 temperature: 0.1
modelName: "gpt-4o" modelName: "gpt-4o"
maxTokens: 4096
# Custom domains configuration (optional) # Custom domains configuration (optional)
customDomains: customDomains:

View File

@@ -65,6 +65,7 @@ probod:
api-key: "thisisnotasecret" api-key: "thisisnotasecret"
temperature: 0.1 temperature: 0.1
model-name: "gpt-4o" model-name: "gpt-4o"
max-tokens: 4096
custom-domains: custom-domains:
renewal-interval: 3600 renewal-interval: 3600

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>. // Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
@@ -24,8 +24,9 @@ type Agent struct {
client *llm.Client client *llm.Client
model string model string
temp float64 temp float64
maxTokens int
} }
func NewAgent(l *log.Logger, client *llm.Client, model string, temp float64) *Agent { func NewAgent(l *log.Logger, client *llm.Client, model string, temp float64, maxTokens int) *Agent {
return &Agent{l: l, client: client, model: model, temp: temp} return &Agent{l: l, client: client, model: model, temp: temp, maxTokens: maxTokens}
} }

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>. // Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
@@ -55,6 +55,7 @@ func (a *Agent) GenerateChangelog(ctx context.Context, oldContent string, newCon
agent.WithInstructions(changelogGeneratorSystemPrompt), agent.WithInstructions(changelogGeneratorSystemPrompt),
agent.WithModel(a.model), agent.WithModel(a.model),
agent.WithTemperature(a.temp), agent.WithTemperature(a.temp),
agent.WithMaxTokens(a.maxTokens),
) )
result, err := ag.Run( result, err := ag.Run(

View File

@@ -1,4 +1,4 @@
// Copyright (c) 2025 Probo Inc <hello@getprobo.com>. // Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
// //
// Permission to use, copy, modify, and/or distribute this software for any // Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above // purpose with or without fee is hereby granted, provided that the above
@@ -128,6 +128,7 @@ func (a *Agent) AssessVendor(ctx context.Context, websiteURL string) (*vendorInf
agent.WithInstructions(assessVendorSystemPrompt), agent.WithInstructions(assessVendorSystemPrompt),
agent.WithModel(a.model), agent.WithModel(a.model),
agent.WithTemperature(a.temp), agent.WithTemperature(a.temp),
agent.WithMaxTokens(a.maxTokens),
) )
typedResult, err := agent.RunTyped[vendorInfo]( typedResult, err := agent.RunTyped[vendorInfo](

View File

@@ -151,6 +151,7 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
APIKey: b.getEnv("OPENAI_API_KEY"), APIKey: b.getEnv("OPENAI_API_KEY"),
Temperature: b.getEnvFloatOrDefault("OPENAI_TEMPERATURE", 0.1), Temperature: b.getEnvFloatOrDefault("OPENAI_TEMPERATURE", 0.1),
ModelName: b.getEnvOrDefault("OPENAI_MODEL_NAME", "gpt-4o"), ModelName: b.getEnvOrDefault("OPENAI_MODEL_NAME", "gpt-4o"),
MaxTokens: b.getEnvIntOrDefault("OPENAI_MAX_TOKENS", 4096),
}, },
CustomDomains: probod.CustomDomainsConfig{ CustomDomains: probod.CustomDomainsConfig{
RenewalInterval: b.getEnvIntOrDefault("CUSTOM_DOMAINS_RENEWAL_INTERVAL", 3600), RenewalInterval: b.getEnvIntOrDefault("CUSTOM_DOMAINS_RENEWAL_INTERVAL", 3600),

View File

@@ -164,6 +164,7 @@ func TestBuilder_Build_Defaults(t *testing.T) {
// OpenAI config // OpenAI config
assert.Equal(t, 0.1, cfg.Probod.OpenAI.Temperature) assert.Equal(t, 0.1, cfg.Probod.OpenAI.Temperature)
assert.Equal(t, "gpt-4o", cfg.Probod.OpenAI.ModelName) assert.Equal(t, "gpt-4o", cfg.Probod.OpenAI.ModelName)
assert.Equal(t, 4096, cfg.Probod.OpenAI.MaxTokens)
// Custom domains config // Custom domains config
assert.Equal(t, 3600, cfg.Probod.CustomDomains.RenewalInterval) assert.Equal(t, 3600, cfg.Probod.CustomDomains.RenewalInterval)
@@ -234,6 +235,7 @@ func TestBuilder_Build_CustomValues(t *testing.T) {
env["OPENAI_API_KEY"] = "sk-test-key" env["OPENAI_API_KEY"] = "sk-test-key"
env["OPENAI_TEMPERATURE"] = "0.5" env["OPENAI_TEMPERATURE"] = "0.5"
env["OPENAI_MODEL_NAME"] = "gpt-4-turbo" env["OPENAI_MODEL_NAME"] = "gpt-4-turbo"
env["OPENAI_MAX_TOKENS"] = "8192"
// Custom domains // Custom domains
env["CUSTOM_DOMAINS_RESOLVER_ADDR"] = "1.1.1.1:53" env["CUSTOM_DOMAINS_RESOLVER_ADDR"] = "1.1.1.1:53"
env["ACME_ACCOUNT_KEY"] = "-----BEGIN EC PRIVATE KEY-----\ntest\n-----END EC PRIVATE KEY-----" env["ACME_ACCOUNT_KEY"] = "-----BEGIN EC PRIVATE KEY-----\ntest\n-----END EC PRIVATE KEY-----"
@@ -297,6 +299,7 @@ func TestBuilder_Build_CustomValues(t *testing.T) {
assert.Equal(t, "sk-test-key", cfg.Probod.OpenAI.APIKey) assert.Equal(t, "sk-test-key", cfg.Probod.OpenAI.APIKey)
assert.Equal(t, 0.5, cfg.Probod.OpenAI.Temperature) assert.Equal(t, 0.5, cfg.Probod.OpenAI.Temperature)
assert.Equal(t, "gpt-4-turbo", cfg.Probod.OpenAI.ModelName) assert.Equal(t, "gpt-4-turbo", cfg.Probod.OpenAI.ModelName)
assert.Equal(t, 8192, cfg.Probod.OpenAI.MaxTokens)
// Custom domains // Custom domains
assert.Equal(t, "1.1.1.1:53", cfg.Probod.CustomDomains.ResolverAddr) assert.Equal(t, "1.1.1.1:53", cfg.Probod.CustomDomains.ResolverAddr)
assert.Equal(t, "-----BEGIN EC PRIVATE KEY-----\ntest\n-----END EC PRIVATE KEY-----", cfg.Probod.CustomDomains.ACME.AccountKey) assert.Equal(t, "-----BEGIN EC PRIVATE KEY-----\ntest\n-----END EC PRIVATE KEY-----", cfg.Probod.CustomDomains.ACME.AccountKey)

View File

@@ -59,6 +59,7 @@ type (
llmClient *llm.Client llmClient *llm.Client
llmModel string llmModel string
llmTemperature float64 llmTemperature float64
llmMaxTokens int
html2pdfConverter *html2pdf.Converter html2pdfConverter *html2pdf.Converter
acmeService *certmanager.ACMEService acmeService *certmanager.ACMEService
fileManager *filemanager.Service fileManager *filemanager.Service
@@ -132,6 +133,7 @@ func NewService(
llmClient *llm.Client, llmClient *llm.Client,
llmModel string, llmModel string,
llmTemperature float64, llmTemperature float64,
llmMaxTokens int,
html2pdfConverter *html2pdf.Converter, html2pdfConverter *html2pdf.Converter,
acmeService *certmanager.ACMEService, acmeService *certmanager.ACMEService,
fileManagerService *filemanager.Service, fileManagerService *filemanager.Service,
@@ -157,6 +159,7 @@ func NewService(
llmClient: llmClient, llmClient: llmClient,
llmModel: llmModel, llmModel: llmModel,
llmTemperature: llmTemperature, llmTemperature: llmTemperature,
llmMaxTokens: llmMaxTokens,
html2pdfConverter: html2pdfConverter, html2pdfConverter: html2pdfConverter,
acmeService: acmeService, acmeService: acmeService,
fileManager: fileManagerService, fileManager: fileManagerService,
@@ -178,7 +181,7 @@ func (s *Service) WithTenant(tenantID gid.TenantID) *TenantService {
baseURL: s.baseURL, baseURL: s.baseURL,
scope: coredata.NewScope(tenantID), scope: coredata.NewScope(tenantID),
tokenSecret: s.tokenSecret, tokenSecret: s.tokenSecret,
agent: agents.NewAgent(nil, s.llmClient, s.llmModel, s.llmTemperature), agent: agents.NewAgent(nil, s.llmClient, s.llmModel, s.llmTemperature, s.llmMaxTokens),
fileManager: s.fileManager, fileManager: s.fileManager,
esign: s.esign, esign: s.esign,
} }

View File

@@ -19,6 +19,7 @@ type LLMConfig struct {
APIKey string `json:"api-key"` // for OpenAI and Anthropic APIKey string `json:"api-key"` // for OpenAI and Anthropic
ModelName string `json:"model-name"` ModelName string `json:"model-name"`
Temperature float64 `json:"temperature"` Temperature float64 `json:"temperature"`
MaxTokens int `json:"max-tokens"`
} }
type OpenAIConfig = LLMConfig type OpenAIConfig = LLMConfig

View File

@@ -445,6 +445,7 @@ func (impl *Implm) Run(
llmClient, llmClient,
impl.cfg.OpenAI.ModelName, impl.cfg.OpenAI.ModelName,
impl.cfg.OpenAI.Temperature, impl.cfg.OpenAI.Temperature,
impl.cfg.OpenAI.MaxTokens,
html2pdfConverter, html2pdfConverter,
acmeService, acmeService,
fileManagerService, fileManagerService,