162 lines
6.3 KiB
Go
162 lines
6.3 KiB
Go
package config
|
|
|
|
import (
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
type Config struct {
|
|
AppEnv string
|
|
HTTPAddr string
|
|
DatabaseURL string
|
|
RedisURL string
|
|
RedisKeyPrefix string
|
|
AuthUsername string
|
|
AuthPassword string
|
|
ModelBaseURL string
|
|
ModelAPIKey string
|
|
ModelName string
|
|
ModelContextSize int
|
|
ModelTimeoutSec int
|
|
A2AEdgeURL string
|
|
A2AAgentURL string
|
|
A2AToken string
|
|
A2ATimeoutSec int
|
|
MattermostBaseURL string
|
|
MattermostToken string
|
|
MattermostChannelID string
|
|
PlaneBaseURL string
|
|
PlaneToken string
|
|
PlaneWebhookSecret string
|
|
PlaneWorkspaceSlug string
|
|
PlaneWorkspaceID string
|
|
PlaneCreationBacklogStateID string
|
|
PlaneAgentAssigneeID string
|
|
PlaneSelfActorID string
|
|
JiraBaseURL string
|
|
JiraEmail string
|
|
JiraAPIToken string
|
|
WorkflowTaskTimeoutSec int
|
|
AuthoringStaleAfterSec int
|
|
ProtoSocketPath string
|
|
ProtoSocketHeartbeatIntervalSec int
|
|
ProtoSocketHeartbeatWaitSec int
|
|
GitoProtoSocketURL string
|
|
GitoWebhookSecret string
|
|
GitoRepoID string
|
|
GitoBranch string
|
|
GitoDevelopRepoPath string
|
|
GitoRemoteName string
|
|
RoadmapCreationTodoStateID string
|
|
ModelResponsesStream bool
|
|
}
|
|
|
|
// GitoBranchEventsEnabled reports whether the Gito branch event consumer should
|
|
// run. It requires an endpoint, a repo id, a local develop checkout path to
|
|
// scan against, and a Todo state id to project into. Any missing piece keeps the
|
|
// consumer disabled so the rest of the Core server behaves exactly as before.
|
|
func (c Config) GitoBranchEventsEnabled() bool {
|
|
return c.GitoProtoSocketURL != "" &&
|
|
c.GitoRepoID != "" &&
|
|
c.GitoDevelopRepoPath != "" &&
|
|
c.RoadmapCreationTodoStateID != ""
|
|
}
|
|
|
|
// GitoWebhookConsumerEnabled reports whether the Gito HTTP webhook receiver
|
|
// should be wired. Requires secret, repo id, develop repo path, and todo state
|
|
// id. Branch defaults to "develop" and is not required.
|
|
func (c Config) GitoWebhookConsumerEnabled() bool {
|
|
return c.GitoWebhookSecret != "" &&
|
|
c.GitoRepoID != "" &&
|
|
c.GitoDevelopRepoPath != "" &&
|
|
c.RoadmapCreationTodoStateID != ""
|
|
}
|
|
|
|
func Load() Config {
|
|
return Config{
|
|
AppEnv: getEnv("APP_ENV", "local"),
|
|
HTTPAddr: getEnv("HTTP_ADDR", ":8080"),
|
|
DatabaseURL: os.Getenv("DATABASE_URL"),
|
|
RedisURL: os.Getenv("REDIS_URL"),
|
|
RedisKeyPrefix: os.Getenv("REDIS_KEY_PREFIX"),
|
|
AuthUsername: getEnv("AUTH_USERNAME", "nomadcode"),
|
|
AuthPassword: os.Getenv("AUTH_PASSWORD"),
|
|
ModelBaseURL: getEnv("MODEL_BASE_URL", "http://toki-labs.com:18083/v1"),
|
|
ModelAPIKey: os.Getenv("MODEL_API_KEY"),
|
|
ModelName: getEnv("MODEL_NAME", "codex"),
|
|
ModelContextSize: getEnvInt("MODEL_CONTEXT_SIZE", 0),
|
|
ModelTimeoutSec: getEnvInt("MODEL_TIMEOUT_SEC", 900),
|
|
A2AEdgeURL: firstEnv("A2A_EDGE_URL", "A2A_AGENT_URL"),
|
|
A2AAgentURL: firstEnv("A2A_AGENT_URL", "A2A_EDGE_URL"),
|
|
A2AToken: os.Getenv("A2A_TOKEN"),
|
|
A2ATimeoutSec: getEnvInt("A2A_TIMEOUT_SEC", 300),
|
|
MattermostBaseURL: os.Getenv("MATTERMOST_BASE_URL"),
|
|
MattermostToken: os.Getenv("MATTERMOST_TOKEN"),
|
|
MattermostChannelID: os.Getenv("MATTERMOST_CHANNEL_ID"),
|
|
PlaneBaseURL: os.Getenv("PLANE_BASE_URL"),
|
|
PlaneToken: os.Getenv("PLANE_TOKEN"),
|
|
PlaneWebhookSecret: os.Getenv("PLANE_WEBHOOK_SECRET"),
|
|
PlaneWorkspaceSlug: os.Getenv("PLANE_WORKSPACE_SLUG"),
|
|
PlaneWorkspaceID: os.Getenv("PLANE_WORKSPACE_ID"),
|
|
PlaneCreationBacklogStateID: firstEnv("PLANE_CREATION_BACKLOG_STATE_ID", "PLANE_BACKLOG_STATE_ID"),
|
|
PlaneAgentAssigneeID: os.Getenv("PLANE_AGENT_ASSIGNEE_ID"),
|
|
PlaneSelfActorID: os.Getenv("PLANE_SELF_ACTOR_ID"),
|
|
JiraBaseURL: os.Getenv("JIRA_BASE_URL"),
|
|
JiraEmail: os.Getenv("JIRA_EMAIL"),
|
|
JiraAPIToken: os.Getenv("JIRA_API_TOKEN"),
|
|
WorkflowTaskTimeoutSec: getEnvInt("WORKFLOW_TASK_TIMEOUT_SEC", 300),
|
|
AuthoringStaleAfterSec: getEnvInt("AUTHORING_STALE_AFTER_SEC", 1200),
|
|
ProtoSocketPath: getEnv("PROTO_SOCKET_PATH", "/proto-socket"),
|
|
ProtoSocketHeartbeatIntervalSec: getEnvInt("PROTO_SOCKET_HEARTBEAT_INTERVAL_SEC", 30),
|
|
ProtoSocketHeartbeatWaitSec: getEnvInt("PROTO_SOCKET_HEARTBEAT_WAIT_SEC", 10),
|
|
GitoProtoSocketURL: os.Getenv("GITO_PROTO_SOCKET_URL"),
|
|
GitoWebhookSecret: os.Getenv("GITO_WEBHOOK_SECRET"),
|
|
GitoRepoID: os.Getenv("GITO_REPO_ID"),
|
|
GitoBranch: getEnv("GITO_BRANCH", "develop"),
|
|
GitoDevelopRepoPath: os.Getenv("GITO_DEVELOP_REPO_PATH"),
|
|
GitoRemoteName: getEnv("GITO_REMOTE_NAME", "origin"),
|
|
RoadmapCreationTodoStateID: firstEnv("ROADMAP_CREATION_TODO_STATE_ID", "PLANE_TODO_STATE_ID"),
|
|
ModelResponsesStream: getEnvBool("MODEL_RESPONSES_STREAM", false),
|
|
}
|
|
}
|
|
|
|
func getEnv(key, fallback string) string {
|
|
value := os.Getenv(key)
|
|
if value == "" {
|
|
return fallback
|
|
}
|
|
return value
|
|
}
|
|
|
|
func firstEnv(keys ...string) string {
|
|
for _, key := range keys {
|
|
if value := os.Getenv(key); value != "" {
|
|
return value
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func getEnvInt(key string, fallback int) int {
|
|
value := os.Getenv(key)
|
|
if value == "" {
|
|
return fallback
|
|
}
|
|
parsed, err := strconv.Atoi(value)
|
|
if err != nil {
|
|
return fallback
|
|
}
|
|
return parsed
|
|
}
|
|
|
|
func getEnvBool(key string, fallback bool) bool {
|
|
value := os.Getenv(key)
|
|
if value == "" {
|
|
return fallback
|
|
}
|
|
parsed, err := strconv.ParseBool(value)
|
|
if err != nil {
|
|
return fallback
|
|
}
|
|
return parsed
|
|
}
|