-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.py
More file actions
113 lines (102 loc) · 4.95 KB
/
Copy pathconfig.py
File metadata and controls
113 lines (102 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
"""Application configuration."""
from __future__ import annotations
from pathlib import Path
from typing import Literal
from pydantic import Field
from pydantic_settings import BaseSettings, SettingsConfigDict
RetrieverType = Literal["dense", "lexical", "hybrid"]
TelemetryBackend = Literal["jsonl", "opentelemetry"]
VectorStoreType = Literal["json", "qdrant"]
class Settings(BaseSettings):
"""Runtime settings loaded from environment variables."""
model_config = SettingsConfigDict(
env_file=".env",
env_prefix="FEEDBACK_AGENT_",
extra="ignore",
)
data_path: Path = Field(default=Path("data/sample_feedback.csv"))
index_path: Path = Field(default=Path(".artifacts/vector_store.json"))
embedding_dim: int = Field(default=512, ge=64, le=8192)
vector_store: VectorStoreType = "json"
qdrant_url: str = Field(default="http://localhost:6333")
qdrant_collection: str = Field(default="feedback_intelligence")
retriever_type: RetrieverType = "dense"
dense_weight: float = Field(default=0.6, ge=0.0)
lexical_weight: float = Field(default=0.4, ge=0.0)
llm_provider: Literal[
"local", "openai", "openai_responses", "anthropic", "bedrock", "ollama"
] = "local"
openai_api_key: str | None = Field(default=None, validation_alias="OPENAI_API_KEY")
openai_model: str = Field(default="gpt-4o-mini", validation_alias="OPENAI_MODEL")
openai_base_url: str = Field(
default="https://api.openai.com", validation_alias="OPENAI_BASE_URL"
)
anthropic_api_key: str | None = Field(default=None, validation_alias="ANTHROPIC_API_KEY")
anthropic_model: str = Field(default="claude-opus-4-8", validation_alias="ANTHROPIC_MODEL")
bedrock_model: str = Field(
default="anthropic.claude-3-haiku-20240307-v1:0",
validation_alias="AWS_BEDROCK_MODEL",
)
bedrock_region: str | None = Field(default=None, validation_alias="AWS_REGION")
bedrock_max_tokens: int = Field(
default=1024,
ge=1,
validation_alias="AWS_BEDROCK_MAX_TOKENS",
)
bedrock_temperature: float = Field(
default=0.2,
ge=0.0,
validation_alias="AWS_BEDROCK_TEMPERATURE",
)
llm_resilience_enabled: bool = Field(default=True)
llm_timeout_seconds: float = Field(default=30.0, gt=0.0)
llm_retry_max_attempts: int = Field(default=3, ge=1)
llm_retry_backoff_seconds: float = Field(default=0.25, ge=0.0)
llm_circuit_failure_threshold: int = Field(default=3, ge=1)
llm_circuit_recovery_seconds: float = Field(default=30.0, gt=0.0)
hallucination_judge_enabled: bool = Field(default=False)
ollama_base_url: str = Field(
default="http://localhost:11434", validation_alias="OLLAMA_BASE_URL"
)
ollama_model: str = Field(default="llama3.2", validation_alias="OLLAMA_MODEL")
telemetry_enabled: bool = Field(default=False)
telemetry_backend: TelemetryBackend = "jsonl"
telemetry_path: Path = Field(default=Path(".artifacts/telemetry.jsonl"))
telemetry_service_name: str = Field(default="feedback-intelligence-agent")
conversation_store_path: Path = Field(default=Path(".artifacts/conversations"))
job_store_path: Path = Field(default=Path(".artifacts/jobs"))
report_store_path: Path = Field(default=Path(".artifacts/reports"))
human_feedback_store_path: Path = Field(default=Path(".artifacts/human_feedback"))
active_learning_state_store_path: Path = Field(default=Path(".artifacts/active_learning"))
api_auth_enabled: bool = Field(default=False)
api_reader_key: str | None = Field(default=None)
api_writer_key: str | None = Field(default=None)
api_admin_key: str | None = Field(default=None)
api_rate_limit_enabled: bool = Field(default=False)
api_rate_limit_max_requests: int = Field(default=120, ge=1)
api_rate_limit_window_seconds: float = Field(default=60.0, gt=0.0)
email_smtp_host: str | None = Field(default=None)
email_smtp_port: int = Field(default=587, ge=1, le=65535)
email_from_address: str = Field(default="feedback-agent@example.local")
email_smtp_username: str | None = Field(default=None)
email_smtp_password: str | None = Field(default=None)
email_smtp_use_tls: bool = Field(default=True)
cors_allow_origins: str = Field(
default=(
"http://localhost:5173,http://localhost:4173,"
"http://127.0.0.1:5173,http://127.0.0.1:4173"
)
)
@property
def cors_origins(self) -> list[str]:
"""Parse the comma-separated CORS origins into a list.
A single ``*`` allows any origin (convenient for local demos); an empty
value disables cross-origin requests entirely.
"""
value = self.cors_allow_origins.strip()
if not value:
return []
return [origin.strip() for origin in value.split(",") if origin.strip()]
def ensure_artifact_dir(self) -> None:
"""Create the parent folder used by local artifacts."""
self.index_path.parent.mkdir(parents=True, exist_ok=True)