diff --git a/contrib/helm/charts/probo/values-production.yaml.example b/contrib/helm/charts/probo/values-production.yaml.example index 3b2128d3e..4d5622d4b 100644 --- a/contrib/helm/charts/probo/values-production.yaml.example +++ b/contrib/helm/charts/probo/values-production.yaml.example @@ -174,7 +174,7 @@ probo: # provider: "openai" # modelName: "gpt-4o-mini" # temperature: "0.1" - # maxTokens: "1024" + # maxTokens: "4096" # Tracker mapping worker tuning (optional; seconds for interval/agentTimeout). # Keep concurrency modest to stay under OpenAI/Firecrawl limits and the DB pool. diff --git a/pkg/bootstrap/builder.go b/pkg/bootstrap/builder.go index 017a6eb3f..70e03ab5d 100644 --- a/pkg/bootstrap/builder.go +++ b/pkg/bootstrap/builder.go @@ -209,11 +209,12 @@ func (b *Builder) Build() (*probodconfig.FullConfig, error) { TrackerMapping: probodconfig.LLMAgentConfig{ Provider: b.getEnvOrDefault("AGENT_TRACKER_MAPPING_PROVIDER", ""), ModelName: b.getEnvOrDefault("AGENT_TRACKER_MAPPING_MODEL_NAME", ""), - // The tracker agents emit tiny structured JSON, so - // they default to a smaller token budget than the - // shared default rather than inheriting it. + // The tracker agents emit tiny structured JSON, but + // the budget must leave headroom for reasoning + // models whose reasoning tokens count against + // max_tokens; too small a budget truncates the JSON. Temperature: b.getEnvFloatPtr("AGENT_TRACKER_MAPPING_TEMPERATURE"), - MaxTokens: new(b.getEnvIntOrDefault("AGENT_TRACKER_MAPPING_MAX_TOKENS", 1024)), + MaxTokens: new(b.getEnvIntOrDefault("AGENT_TRACKER_MAPPING_MAX_TOKENS", 4096)), }, Tools: probodconfig.AgentToolsConfig{ FirecrawlAPIKey: b.getEnv("FIRECRAWL_API_KEY"), diff --git a/pkg/bootstrap/builder_test.go b/pkg/bootstrap/builder_test.go index a096ad292..522e51fff 100644 --- a/pkg/bootstrap/builder_test.go +++ b/pkg/bootstrap/builder_test.go @@ -218,7 +218,7 @@ func TestBuilder_Build_Defaults(t *testing.T) { assert.Empty(t, cfg.Probod.Agents.TrackerMapping.Provider) assert.Empty(t, cfg.Probod.Agents.TrackerMapping.ModelName) assert.Nil(t, cfg.Probod.Agents.TrackerMapping.Temperature) - assert.Equal(t, new(1024), cfg.Probod.Agents.TrackerMapping.MaxTokens) + assert.Equal(t, new(4096), cfg.Probod.Agents.TrackerMapping.MaxTokens) // Tracker worker tuning — defaults assert.Equal(t, 10, cfg.Probod.TrackerMappingWorker.Interval) diff --git a/pkg/cookiebanner/tracker_mapping_agent.go b/pkg/cookiebanner/tracker_mapping_agent.go index 90b366d21..37b2fbbe0 100644 --- a/pkg/cookiebanner/tracker_mapping_agent.go +++ b/pkg/cookiebanner/tracker_mapping_agent.go @@ -40,10 +40,14 @@ const ( defaultMappingMaxTurns = 4 defaultEnrichmentMaxTurns = 3 - // defaultAgentMaxTokens caps the structured output of the mapping - // and enrichment agents when the agent config carries no max-tokens - // budget. Both outputs are tiny structured JSON. - defaultAgentMaxTokens = 1024 + // defaultAgentMaxTokens caps the output of the mapping and + // enrichment agents when the agent config carries no max-tokens + // budget. Both final outputs are tiny structured JSON, but the + // budget must leave ample headroom for reasoning models (e.g. the + // GPT-5 family): their reasoning tokens count against max_tokens, + // so too small a budget gets consumed by reasoning and truncates + // the JSON, surfacing as "unexpected end of JSON input". + defaultAgentMaxTokens = 4096 agentThirdPartyConfidenceThreshold = 0.6 // agentSourceConfidence is the fixed confidence stored on catalog diff --git a/pkg/thirdparty/disambiguation_agent.go b/pkg/thirdparty/disambiguation_agent.go index c995f65e6..35d167f0d 100644 --- a/pkg/thirdparty/disambiguation_agent.go +++ b/pkg/thirdparty/disambiguation_agent.go @@ -44,10 +44,14 @@ const ( // provider, not a real budget. defaultDisambiguationTimeout = 45 * time.Second - // defaultDisambiguationMaxTokens caps the agent's structured - // output when the config carries no max-tokens budget. The output - // is a single id plus a one-sentence rationale. - defaultDisambiguationMaxTokens = 512 + // defaultDisambiguationMaxTokens caps the agent's output when the + // config carries no max-tokens budget. The final output is tiny (a + // single id plus a one-sentence rationale), but the budget must + // leave ample headroom for reasoning models (e.g. the GPT-5 + // family): their reasoning tokens count against max_tokens, so too + // small a budget gets consumed by reasoning and truncates the JSON, + // surfacing as "unexpected end of JSON input". + defaultDisambiguationMaxTokens = 4096 ) // DisambiguationConfig configures the third-party disambiguation