Refactor LLM config into top-level settings
Replace the monolithic agents config with a cleaner structure: - llm: holds provider credentials and default model settings - probo-agent: LLM overrides for the probo agent - evidence-describer: worker config (interval, stale-after, max-concurrency) alongside LLM overrides This makes worker tuning configurable via YAML and env vars instead of being hardcoded in Go, and separates provider credentials from per-consumer model settings. Signed-off-by: Bryan Frimin <bryan@getprobo.com>
This commit is contained in:
committed by
Sacha Al Himdani
parent
0926a8828a
commit
050154ab6a
15
cfg/dev.yaml
15
cfg/dev.yaml
@@ -85,17 +85,22 @@ probod:
|
|||||||
slack:
|
slack:
|
||||||
sender-interval: 60
|
sender-interval: 60
|
||||||
|
|
||||||
agents:
|
llm:
|
||||||
providers:
|
providers:
|
||||||
openai:
|
openai:
|
||||||
type: "openai"
|
type: openai
|
||||||
api-key: "thisisnotasecret"
|
api-key: "thisisnotasecret"
|
||||||
default:
|
defaults:
|
||||||
provider: "openai"
|
provider: openai
|
||||||
model-name: "gpt-4o"
|
model-name: gpt-4o
|
||||||
temperature: 0.1
|
temperature: 0.1
|
||||||
max-tokens: 4096
|
max-tokens: 4096
|
||||||
|
|
||||||
|
evidence-describer:
|
||||||
|
interval: 10
|
||||||
|
stale-after: 300
|
||||||
|
max-concurrency: 10
|
||||||
|
|
||||||
custom-domains:
|
custom-domains:
|
||||||
renewal-interval: 3600
|
renewal-interval: 3600
|
||||||
provision-interval: 30
|
provision-interval: 30
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
|
|||||||
CacheTTL: b.getEnvIntOrDefault("WEBHOOK_CACHE_TTL", 86400),
|
CacheTTL: b.getEnvIntOrDefault("WEBHOOK_CACHE_TTL", 86400),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Agents: probod.AgentsConfig{
|
LLM: probod.LLMSettings{
|
||||||
Providers: map[string]probod.LLMProviderConfig{
|
Providers: map[string]probod.LLMProviderConfig{
|
||||||
"openai": {
|
"openai": {
|
||||||
Type: "openai",
|
Type: "openai",
|
||||||
@@ -168,25 +168,28 @@ func (b *Builder) Build() (*probod.FullConfig, error) {
|
|||||||
APIKey: b.getEnv("ANTHROPIC_API_KEY"),
|
APIKey: b.getEnv("ANTHROPIC_API_KEY"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Default: probod.LLMAgentConfig{
|
Defaults: probod.LLMConfig{
|
||||||
Provider: b.getEnvOrDefault("AGENT_DEFAULT_PROVIDER", "openai"),
|
Provider: b.getEnvOrDefault("LLM_DEFAULT_PROVIDER", "openai"),
|
||||||
ModelName: b.getEnvOrDefault("AGENT_DEFAULT_MODEL_NAME", "gpt-4o"),
|
ModelName: b.getEnvOrDefault("LLM_DEFAULT_MODEL_NAME", "gpt-4o"),
|
||||||
Temperature: new(b.getEnvFloatOrDefault("AGENT_DEFAULT_TEMPERATURE", 0.1)),
|
Temperature: new(b.getEnvFloatOrDefault("LLM_DEFAULT_TEMPERATURE", 0.1)),
|
||||||
MaxTokens: new(b.getEnvIntOrDefault("AGENT_DEFAULT_MAX_TOKENS", 4096)),
|
MaxTokens: new(b.getEnvIntOrDefault("LLM_DEFAULT_MAX_TOKENS", 4096)),
|
||||||
},
|
|
||||||
Probo: probod.LLMAgentConfig{
|
|
||||||
Provider: b.getEnvOrDefault("AGENT_PROBO_PROVIDER", ""),
|
|
||||||
ModelName: b.getEnvOrDefault("AGENT_PROBO_MODEL_NAME", ""),
|
|
||||||
Temperature: b.getEnvFloatPtr("AGENT_PROBO_TEMPERATURE"),
|
|
||||||
MaxTokens: b.getEnvIntPtr("AGENT_PROBO_MAX_TOKENS"),
|
|
||||||
},
|
|
||||||
EvidenceDescriber: probod.LLMAgentConfig{
|
|
||||||
Provider: b.getEnvOrDefault("AGENT_EVIDENCE_DESCRIBER_PROVIDER", ""),
|
|
||||||
ModelName: b.getEnvOrDefault("AGENT_EVIDENCE_DESCRIBER_MODEL_NAME", ""),
|
|
||||||
Temperature: b.getEnvFloatPtr("AGENT_EVIDENCE_DESCRIBER_TEMPERATURE"),
|
|
||||||
MaxTokens: b.getEnvIntPtr("AGENT_EVIDENCE_DESCRIBER_MAX_TOKENS"),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
ProboAgent: probod.LLMConfig{
|
||||||
|
Provider: b.getEnvOrDefault("PROBO_AGENT_PROVIDER", ""),
|
||||||
|
ModelName: b.getEnvOrDefault("PROBO_AGENT_MODEL_NAME", ""),
|
||||||
|
Temperature: b.getEnvFloatPtr("PROBO_AGENT_TEMPERATURE"),
|
||||||
|
MaxTokens: b.getEnvIntPtr("PROBO_AGENT_MAX_TOKENS"),
|
||||||
|
},
|
||||||
|
EvidenceDescriber: probod.EvidenceDescriberConfig{
|
||||||
|
Interval: b.getEnvIntOrDefault("EVIDENCE_DESCRIBER_INTERVAL", 10),
|
||||||
|
StaleAfter: b.getEnvIntOrDefault("EVIDENCE_DESCRIBER_STALE_AFTER", 300),
|
||||||
|
MaxConcurrency: b.getEnvIntOrDefault("EVIDENCE_DESCRIBER_MAX_CONCURRENCY", 10),
|
||||||
|
Provider: b.getEnvOrDefault("EVIDENCE_DESCRIBER_PROVIDER", ""),
|
||||||
|
ModelName: b.getEnvOrDefault("EVIDENCE_DESCRIBER_MODEL_NAME", ""),
|
||||||
|
Temperature: b.getEnvFloatPtr("EVIDENCE_DESCRIBER_TEMPERATURE"),
|
||||||
|
MaxTokens: b.getEnvIntPtr("EVIDENCE_DESCRIBER_MAX_TOKENS"),
|
||||||
|
},
|
||||||
CustomDomains: probod.CustomDomainsConfig{
|
CustomDomains: probod.CustomDomainsConfig{
|
||||||
RenewalInterval: b.getEnvIntOrDefault("CUSTOM_DOMAINS_RENEWAL_INTERVAL", 3600),
|
RenewalInterval: b.getEnvIntOrDefault("CUSTOM_DOMAINS_RENEWAL_INTERVAL", 3600),
|
||||||
ProvisionInterval: b.getEnvIntOrDefault("CUSTOM_DOMAINS_PROVISION_INTERVAL", 30),
|
ProvisionInterval: b.getEnvIntOrDefault("CUSTOM_DOMAINS_PROVISION_INTERVAL", 30),
|
||||||
|
|||||||
@@ -161,20 +161,25 @@ func TestBuilder_Build_Defaults(t *testing.T) {
|
|||||||
assert.Equal(t, 5, cfg.Probod.Notifications.Webhook.SenderInterval)
|
assert.Equal(t, 5, cfg.Probod.Notifications.Webhook.SenderInterval)
|
||||||
assert.Equal(t, 86400, cfg.Probod.Notifications.Webhook.CacheTTL)
|
assert.Equal(t, 86400, cfg.Probod.Notifications.Webhook.CacheTTL)
|
||||||
|
|
||||||
// Agents config — default
|
// LLM config — defaults
|
||||||
assert.Equal(t, "openai", cfg.Probod.Agents.Default.Provider)
|
assert.Equal(t, "openai", cfg.Probod.LLM.Defaults.Provider)
|
||||||
assert.Equal(t, "gpt-4o", cfg.Probod.Agents.Default.ModelName)
|
assert.Equal(t, "gpt-4o", cfg.Probod.LLM.Defaults.ModelName)
|
||||||
assert.Equal(t, new(0.1), cfg.Probod.Agents.Default.Temperature)
|
assert.Equal(t, new(0.1), cfg.Probod.LLM.Defaults.Temperature)
|
||||||
assert.Equal(t, new(4096), cfg.Probod.Agents.Default.MaxTokens)
|
assert.Equal(t, new(4096), cfg.Probod.LLM.Defaults.MaxTokens)
|
||||||
// Agents config — per-agent overrides are empty (inherit from default)
|
// Probo agent — empty (inherits from defaults)
|
||||||
assert.Empty(t, cfg.Probod.Agents.Probo.Provider)
|
assert.Empty(t, cfg.Probod.ProboAgent.Provider)
|
||||||
assert.Empty(t, cfg.Probod.Agents.Probo.ModelName)
|
assert.Empty(t, cfg.Probod.ProboAgent.ModelName)
|
||||||
assert.Nil(t, cfg.Probod.Agents.Probo.Temperature)
|
assert.Nil(t, cfg.Probod.ProboAgent.Temperature)
|
||||||
assert.Nil(t, cfg.Probod.Agents.Probo.MaxTokens)
|
assert.Nil(t, cfg.Probod.ProboAgent.MaxTokens)
|
||||||
assert.Empty(t, cfg.Probod.Agents.EvidenceDescriber.Provider)
|
// Evidence describer — LLM fields empty (inherits from defaults)
|
||||||
assert.Empty(t, cfg.Probod.Agents.EvidenceDescriber.ModelName)
|
assert.Empty(t, cfg.Probod.EvidenceDescriber.Provider)
|
||||||
assert.Nil(t, cfg.Probod.Agents.EvidenceDescriber.Temperature)
|
assert.Empty(t, cfg.Probod.EvidenceDescriber.ModelName)
|
||||||
assert.Nil(t, cfg.Probod.Agents.EvidenceDescriber.MaxTokens)
|
assert.Nil(t, cfg.Probod.EvidenceDescriber.Temperature)
|
||||||
|
assert.Nil(t, cfg.Probod.EvidenceDescriber.MaxTokens)
|
||||||
|
// Evidence describer — worker defaults
|
||||||
|
assert.Equal(t, 10, cfg.Probod.EvidenceDescriber.Interval)
|
||||||
|
assert.Equal(t, 300, cfg.Probod.EvidenceDescriber.StaleAfter)
|
||||||
|
assert.Equal(t, 10, cfg.Probod.EvidenceDescriber.MaxConcurrency)
|
||||||
|
|
||||||
// Custom domains config
|
// Custom domains config
|
||||||
assert.Equal(t, 3600, cfg.Probod.CustomDomains.RenewalInterval)
|
assert.Equal(t, 3600, cfg.Probod.CustomDomains.RenewalInterval)
|
||||||
@@ -241,19 +246,22 @@ func TestBuilder_Build_CustomValues(t *testing.T) {
|
|||||||
env["WEBHOOK_SENDER_INTERVAL"] = "10"
|
env["WEBHOOK_SENDER_INTERVAL"] = "10"
|
||||||
env["WEBHOOK_CACHE_TTL"] = "3600"
|
env["WEBHOOK_CACHE_TTL"] = "3600"
|
||||||
env["CONNECTOR_SLACK_SIGNING_SECRET"] = "slack-signing-secret"
|
env["CONNECTOR_SLACK_SIGNING_SECRET"] = "slack-signing-secret"
|
||||||
// Agents — providers
|
// LLM — providers
|
||||||
env["OPENAI_API_KEY"] = "sk-test-key"
|
env["OPENAI_API_KEY"] = "sk-test-key"
|
||||||
env["ANTHROPIC_API_KEY"] = "sk-ant-test-key"
|
env["ANTHROPIC_API_KEY"] = "sk-ant-test-key"
|
||||||
// Agents — default
|
// LLM — defaults
|
||||||
env["AGENT_DEFAULT_PROVIDER"] = "openai"
|
env["LLM_DEFAULT_PROVIDER"] = "openai"
|
||||||
env["AGENT_DEFAULT_MODEL_NAME"] = "gpt-4-turbo"
|
env["LLM_DEFAULT_MODEL_NAME"] = "gpt-4-turbo"
|
||||||
env["AGENT_DEFAULT_TEMPERATURE"] = "0.5"
|
env["LLM_DEFAULT_TEMPERATURE"] = "0.5"
|
||||||
env["AGENT_DEFAULT_MAX_TOKENS"] = "8192"
|
env["LLM_DEFAULT_MAX_TOKENS"] = "8192"
|
||||||
// Agents — evidence-describer override
|
// Evidence describer
|
||||||
env["AGENT_EVIDENCE_DESCRIBER_PROVIDER"] = "anthropic"
|
env["EVIDENCE_DESCRIBER_PROVIDER"] = "anthropic"
|
||||||
env["AGENT_EVIDENCE_DESCRIBER_MODEL_NAME"] = "claude-sonnet-4-20250514"
|
env["EVIDENCE_DESCRIBER_MODEL_NAME"] = "claude-sonnet-4-20250514"
|
||||||
env["AGENT_EVIDENCE_DESCRIBER_TEMPERATURE"] = "0.2"
|
env["EVIDENCE_DESCRIBER_TEMPERATURE"] = "0.2"
|
||||||
env["AGENT_EVIDENCE_DESCRIBER_MAX_TOKENS"] = "4096"
|
env["EVIDENCE_DESCRIBER_MAX_TOKENS"] = "4096"
|
||||||
|
env["EVIDENCE_DESCRIBER_INTERVAL"] = "15"
|
||||||
|
env["EVIDENCE_DESCRIBER_STALE_AFTER"] = "600"
|
||||||
|
env["EVIDENCE_DESCRIBER_MAX_CONCURRENCY"] = "20"
|
||||||
// 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-----"
|
||||||
@@ -313,24 +321,28 @@ func TestBuilder_Build_CustomValues(t *testing.T) {
|
|||||||
assert.Equal(t, "slack-signing-secret", cfg.Probod.Notifications.Slack.SigningSecret)
|
assert.Equal(t, "slack-signing-secret", cfg.Probod.Notifications.Slack.SigningSecret)
|
||||||
assert.Equal(t, 10, cfg.Probod.Notifications.Webhook.SenderInterval)
|
assert.Equal(t, 10, cfg.Probod.Notifications.Webhook.SenderInterval)
|
||||||
assert.Equal(t, 3600, cfg.Probod.Notifications.Webhook.CacheTTL)
|
assert.Equal(t, 3600, cfg.Probod.Notifications.Webhook.CacheTTL)
|
||||||
// Agents — providers
|
// LLM — providers
|
||||||
assert.Equal(t, "openai", cfg.Probod.Agents.Providers["openai"].Type)
|
assert.Equal(t, "openai", cfg.Probod.LLM.Providers["openai"].Type)
|
||||||
assert.Equal(t, "sk-test-key", cfg.Probod.Agents.Providers["openai"].APIKey)
|
assert.Equal(t, "sk-test-key", cfg.Probod.LLM.Providers["openai"].APIKey)
|
||||||
assert.Equal(t, "anthropic", cfg.Probod.Agents.Providers["anthropic"].Type)
|
assert.Equal(t, "anthropic", cfg.Probod.LLM.Providers["anthropic"].Type)
|
||||||
assert.Equal(t, "sk-ant-test-key", cfg.Probod.Agents.Providers["anthropic"].APIKey)
|
assert.Equal(t, "sk-ant-test-key", cfg.Probod.LLM.Providers["anthropic"].APIKey)
|
||||||
// Agents — default
|
// LLM — defaults
|
||||||
assert.Equal(t, "openai", cfg.Probod.Agents.Default.Provider)
|
assert.Equal(t, "openai", cfg.Probod.LLM.Defaults.Provider)
|
||||||
assert.Equal(t, "gpt-4-turbo", cfg.Probod.Agents.Default.ModelName)
|
assert.Equal(t, "gpt-4-turbo", cfg.Probod.LLM.Defaults.ModelName)
|
||||||
assert.Equal(t, new(0.5), cfg.Probod.Agents.Default.Temperature)
|
assert.Equal(t, new(0.5), cfg.Probod.LLM.Defaults.Temperature)
|
||||||
assert.Equal(t, new(8192), cfg.Probod.Agents.Default.MaxTokens)
|
assert.Equal(t, new(8192), cfg.Probod.LLM.Defaults.MaxTokens)
|
||||||
// Agents — probo inherits default (no overrides set)
|
// Probo agent — inherits defaults (no overrides set)
|
||||||
assert.Empty(t, cfg.Probod.Agents.Probo.Provider)
|
assert.Empty(t, cfg.Probod.ProboAgent.Provider)
|
||||||
assert.Empty(t, cfg.Probod.Agents.Probo.ModelName)
|
assert.Empty(t, cfg.Probod.ProboAgent.ModelName)
|
||||||
// Agents — evidence-describer overrides
|
// Evidence describer — LLM overrides
|
||||||
assert.Equal(t, "anthropic", cfg.Probod.Agents.EvidenceDescriber.Provider)
|
assert.Equal(t, "anthropic", cfg.Probod.EvidenceDescriber.Provider)
|
||||||
assert.Equal(t, "claude-sonnet-4-20250514", cfg.Probod.Agents.EvidenceDescriber.ModelName)
|
assert.Equal(t, "claude-sonnet-4-20250514", cfg.Probod.EvidenceDescriber.ModelName)
|
||||||
assert.Equal(t, new(0.2), cfg.Probod.Agents.EvidenceDescriber.Temperature)
|
assert.Equal(t, new(0.2), cfg.Probod.EvidenceDescriber.Temperature)
|
||||||
assert.Equal(t, new(4096), cfg.Probod.Agents.EvidenceDescriber.MaxTokens)
|
assert.Equal(t, new(4096), cfg.Probod.EvidenceDescriber.MaxTokens)
|
||||||
|
// Evidence describer — worker config
|
||||||
|
assert.Equal(t, 15, cfg.Probod.EvidenceDescriber.Interval)
|
||||||
|
assert.Equal(t, 600, cfg.Probod.EvidenceDescriber.StaleAfter)
|
||||||
|
assert.Equal(t, 20, cfg.Probod.EvidenceDescriber.MaxConcurrency)
|
||||||
// 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)
|
||||||
|
|||||||
38
pkg/probod/evidence_describer_config.go
Normal file
38
pkg/probod/evidence_describer_config.go
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (c) 2025-2026 Probo Inc <hello@getprobo.com>.
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice appear in all copies.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||||
|
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||||
|
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||||
|
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||||
|
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||||
|
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||||
|
// PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
package probod
|
||||||
|
|
||||||
|
// EvidenceDescriberConfig holds both the worker settings and LLM overrides
|
||||||
|
// for the evidence description worker.
|
||||||
|
type EvidenceDescriberConfig struct {
|
||||||
|
Interval int `json:"interval"` // seconds
|
||||||
|
StaleAfter int `json:"stale-after"` // seconds
|
||||||
|
MaxConcurrency int `json:"max-concurrency"`
|
||||||
|
|
||||||
|
Provider string `json:"provider"`
|
||||||
|
ModelName string `json:"model-name"`
|
||||||
|
Temperature *float64 `json:"temperature"`
|
||||||
|
MaxTokens *int `json:"max-tokens"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// LLMConfig extracts the LLM-specific fields as an LLMConfig.
|
||||||
|
func (c *EvidenceDescriberConfig) LLMConfig() LLMConfig {
|
||||||
|
return LLMConfig{
|
||||||
|
Provider: c.Provider,
|
||||||
|
ModelName: c.ModelName,
|
||||||
|
Temperature: c.Temperature,
|
||||||
|
MaxTokens: c.MaxTokens,
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,40 +22,38 @@ type (
|
|||||||
APIKey string `json:"api-key"` // for OpenAI and Anthropic
|
APIKey string `json:"api-key"` // for OpenAI and Anthropic
|
||||||
}
|
}
|
||||||
|
|
||||||
// LLMAgentConfig holds model parameters for a single agent. Provider
|
// LLMConfig holds model parameters for a single LLM consumer. Provider
|
||||||
// references one of the keys in AgentsConfig.Providers.
|
// references one of the keys in LLMSettings.Providers.
|
||||||
LLMAgentConfig struct {
|
LLMConfig struct {
|
||||||
Provider string `json:"provider"` // key into AgentsConfig.Providers
|
Provider string `json:"provider"` // key into LLMSettings.Providers
|
||||||
ModelName string `json:"model-name"`
|
ModelName string `json:"model-name"`
|
||||||
Temperature *float64 `json:"temperature"`
|
Temperature *float64 `json:"temperature"`
|
||||||
MaxTokens *int `json:"max-tokens"`
|
MaxTokens *int `json:"max-tokens"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// AgentsConfig groups LLM provider credentials and per-agent model
|
// LLMSettings groups LLM provider credentials and default model
|
||||||
// settings. Default is used as a fallback when an agent-specific field
|
// settings. Defaults is used as a fallback when a consumer-specific
|
||||||
// is zero-valued.
|
// field is zero-valued.
|
||||||
AgentsConfig struct {
|
LLMSettings struct {
|
||||||
Providers map[string]LLMProviderConfig `json:"providers"`
|
Providers map[string]LLMProviderConfig `json:"providers"`
|
||||||
Default LLMAgentConfig `json:"default"`
|
Defaults LLMConfig `json:"defaults"`
|
||||||
Probo LLMAgentConfig `json:"probo"`
|
|
||||||
EvidenceDescriber LLMAgentConfig `json:"evidence-describer"`
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
// ResolveAgent returns a fully populated LLMAgentConfig by filling in
|
// ResolveLLMConfig returns a fully populated LLMConfig by filling in
|
||||||
// zero-valued fields from the default config.
|
// zero-valued fields from the defaults.
|
||||||
func (c *AgentsConfig) ResolveAgent(agent LLMAgentConfig) LLMAgentConfig {
|
func (s *LLMSettings) ResolveLLMConfig(cfg LLMConfig) LLMConfig {
|
||||||
if agent.Provider == "" {
|
if cfg.Provider == "" {
|
||||||
agent.Provider = c.Default.Provider
|
cfg.Provider = s.Defaults.Provider
|
||||||
}
|
}
|
||||||
if agent.ModelName == "" {
|
if cfg.ModelName == "" {
|
||||||
agent.ModelName = c.Default.ModelName
|
cfg.ModelName = s.Defaults.ModelName
|
||||||
}
|
}
|
||||||
if agent.Temperature == nil {
|
if cfg.Temperature == nil {
|
||||||
agent.Temperature = c.Default.Temperature
|
cfg.Temperature = s.Defaults.Temperature
|
||||||
}
|
}
|
||||||
if agent.MaxTokens == nil {
|
if cfg.MaxTokens == nil {
|
||||||
agent.MaxTokens = c.Default.MaxTokens
|
cfg.MaxTokens = s.Defaults.MaxTokens
|
||||||
}
|
}
|
||||||
return agent
|
return cfg
|
||||||
}
|
}
|
||||||
@@ -108,20 +108,22 @@ type (
|
|||||||
|
|
||||||
// Config represents the probod application configuration.
|
// Config represents the probod application configuration.
|
||||||
Config struct {
|
Config struct {
|
||||||
BaseURL string `json:"base-url"`
|
BaseURL string `json:"base-url"`
|
||||||
EncryptionKey string `json:"encryption-key"`
|
EncryptionKey string `json:"encryption-key"`
|
||||||
Pg PgConfig `json:"pg"`
|
Pg PgConfig `json:"pg"`
|
||||||
Api APIConfig `json:"api"`
|
Api APIConfig `json:"api"`
|
||||||
Auth AuthConfig `json:"auth"`
|
Auth AuthConfig `json:"auth"`
|
||||||
TrustCenter TrustCenterConfig `json:"trust-center"`
|
TrustCenter TrustCenterConfig `json:"trust-center"`
|
||||||
AWS AWSConfig `json:"aws"`
|
AWS AWSConfig `json:"aws"`
|
||||||
Notifications NotificationsConfig `json:"notifications"`
|
Notifications NotificationsConfig `json:"notifications"`
|
||||||
Connectors []ConnectorConfig `json:"connectors"`
|
Connectors []ConnectorConfig `json:"connectors"`
|
||||||
Agents AgentsConfig `json:"agents"`
|
LLM LLMSettings `json:"llm"`
|
||||||
ChromeDPAddr string `json:"chrome-dp-addr"`
|
ProboAgent LLMConfig `json:"probo-agent"`
|
||||||
CustomDomains CustomDomainsConfig `json:"custom-domains"`
|
EvidenceDescriber EvidenceDescriberConfig `json:"evidence-describer"`
|
||||||
SCIMBridge SCIMBridgeConfig `json:"scim-bridge"`
|
ChromeDPAddr string `json:"chrome-dp-addr"`
|
||||||
ESign ESignConfig `json:"esign"`
|
CustomDomains CustomDomainsConfig `json:"custom-domains"`
|
||||||
|
SCIMBridge SCIMBridgeConfig `json:"scim-bridge"`
|
||||||
|
ESign ESignConfig `json:"esign"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// TrustCenterConfig contains trust center server configuration.
|
// TrustCenterConfig contains trust center server configuration.
|
||||||
@@ -217,6 +219,11 @@ func New() *Implm {
|
|||||||
ESign: ESignConfig{
|
ESign: ESignConfig{
|
||||||
TSAURL: "http://timestamp.digicert.com",
|
TSAURL: "http://timestamp.digicert.com",
|
||||||
},
|
},
|
||||||
|
EvidenceDescriber: EvidenceDescriberConfig{
|
||||||
|
Interval: 10,
|
||||||
|
StaleAfter: 300,
|
||||||
|
MaxConcurrency: 10,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -318,8 +325,8 @@ func (impl *Implm) Run(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
proboAgentCfg := impl.cfg.Agents.ResolveAgent(impl.cfg.Agents.Probo)
|
proboAgentCfg := impl.cfg.LLM.ResolveLLMConfig(impl.cfg.ProboAgent)
|
||||||
proboProviderCfg, ok := impl.cfg.Agents.Providers[proboAgentCfg.Provider]
|
proboProviderCfg, ok := impl.cfg.LLM.Providers[proboAgentCfg.Provider]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("unknown LLM provider %q for probo agent", proboAgentCfg.Provider)
|
return fmt.Errorf("unknown LLM provider %q for probo agent", proboAgentCfg.Provider)
|
||||||
}
|
}
|
||||||
@@ -328,12 +335,12 @@ func (impl *Implm) Run(
|
|||||||
return fmt.Errorf("cannot create probo LLM client: %w", err)
|
return fmt.Errorf("cannot create probo LLM client: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
evidenceDescriberAgentCfg := impl.cfg.Agents.ResolveAgent(impl.cfg.Agents.EvidenceDescriber)
|
edLLMCfg := impl.cfg.LLM.ResolveLLMConfig(impl.cfg.EvidenceDescriber.LLMConfig())
|
||||||
evidenceDescriberProviderCfg, ok := impl.cfg.Agents.Providers[evidenceDescriberAgentCfg.Provider]
|
edProviderCfg, ok := impl.cfg.LLM.Providers[edLLMCfg.Provider]
|
||||||
if !ok {
|
if !ok {
|
||||||
return fmt.Errorf("unknown LLM provider %q for evidence-describer agent", evidenceDescriberAgentCfg.Provider)
|
return fmt.Errorf("unknown LLM provider %q for evidence-describer agent", edLLMCfg.Provider)
|
||||||
}
|
}
|
||||||
evidenceDescriberLLMClient, err := buildLLMClient(evidenceDescriberProviderCfg, l.Named("llm.evidence-describer"), tp, r)
|
evidenceDescriberLLMClient, err := buildLLMClient(edProviderCfg, l.Named("llm.evidence-describer"), tp, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("cannot create evidence describer LLM client: %w", err)
|
return fmt.Errorf("cannot create evidence describer LLM client: %w", err)
|
||||||
}
|
}
|
||||||
@@ -655,9 +662,9 @@ func (impl *Implm) Run(
|
|||||||
evidenceDescriber := evidencedescriber.New(
|
evidenceDescriber := evidencedescriber.New(
|
||||||
evidenceDescriberLLMClient,
|
evidenceDescriberLLMClient,
|
||||||
evidencedescriber.Config{
|
evidencedescriber.Config{
|
||||||
Model: evidenceDescriberAgentCfg.ModelName,
|
Model: edLLMCfg.ModelName,
|
||||||
Temp: *evidenceDescriberAgentCfg.Temperature,
|
Temp: *edLLMCfg.Temperature,
|
||||||
MaxTokens: *evidenceDescriberAgentCfg.MaxTokens,
|
MaxTokens: *edLLMCfg.MaxTokens,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
evidenceDescriptionWorker := probo.NewEvidenceDescriptionWorker(
|
evidenceDescriptionWorker := probo.NewEvidenceDescriptionWorker(
|
||||||
@@ -665,6 +672,9 @@ func (impl *Implm) Run(
|
|||||||
fileManagerService,
|
fileManagerService,
|
||||||
evidenceDescriber,
|
evidenceDescriber,
|
||||||
l.Named("evidence-description-worker"),
|
l.Named("evidence-description-worker"),
|
||||||
|
probo.WithEvidenceDescriptionWorkerInterval(time.Duration(impl.cfg.EvidenceDescriber.Interval)*time.Second),
|
||||||
|
probo.WithEvidenceDescriptionWorkerStaleAfter(time.Duration(impl.cfg.EvidenceDescriber.StaleAfter)*time.Second),
|
||||||
|
probo.WithEvidenceDescriptionWorkerMaxConcurrency(impl.cfg.EvidenceDescriber.MaxConcurrency),
|
||||||
)
|
)
|
||||||
evidenceDescriptionWorkerCtx, stopEvidenceDescriptionWorker := context.WithCancel(context.Background())
|
evidenceDescriptionWorkerCtx, stopEvidenceDescriptionWorker := context.WithCancel(context.Background())
|
||||||
wg.Go(
|
wg.Go(
|
||||||
|
|||||||
Reference in New Issue
Block a user