-
Notifications
You must be signed in to change notification settings - Fork 8
Expand file tree
/
Copy pathconstants.py
More file actions
270 lines (203 loc) · 7.83 KB
/
constants.py
File metadata and controls
270 lines (203 loc) · 7.83 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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
"""
Constants for Aegis Stack CLI.
This module centralizes magic strings and configuration keys used throughout
the CLI to improve maintainability and reduce duplication.
"""
class ComponentNames:
"""Standard component names used throughout the CLI."""
REDIS = "redis"
WORKER = "worker"
SCHEDULER = "scheduler"
DATABASE = "database"
BACKEND = "backend"
FRONTEND = "frontend"
INGRESS = "ingress"
OBSERVABILITY = "observability"
# Ordered list for interactive selection
INFRASTRUCTURE_ORDER = [REDIS, WORKER, SCHEDULER, DATABASE, INGRESS, OBSERVABILITY]
class StorageBackends:
"""Storage backend options used by scheduler and database."""
MEMORY = "memory"
SQLITE = "sqlite"
POSTGRES = "postgres"
class WorkerBackends:
"""Worker backend options for task processing."""
ARQ = "arq"
TASKIQ = "taskiq"
DRAMATIQ = "dramatiq"
ALL = [ARQ, TASKIQ, DRAMATIQ]
class AIFrameworks:
"""AI framework options for the AI service."""
PYDANTIC_AI = "pydantic-ai"
LANGCHAIN = "langchain"
ALL = [PYDANTIC_AI, LANGCHAIN]
class AIProviders:
"""AI provider options for the AI service."""
# Provider identifiers
PUBLIC = "public"
OPENAI = "openai"
ANTHROPIC = "anthropic"
GOOGLE = "google"
GROQ = "groq"
MISTRAL = "mistral"
COHERE = "cohere"
OLLAMA = "ollama"
# All valid providers (used for validation)
ALL = {PUBLIC, OPENAI, ANTHROPIC, GOOGLE, GROQ, MISTRAL, COHERE, OLLAMA}
# Default providers for bracket syntax (non-interactive)
DEFAULT = [PUBLIC]
# Default providers for interactive mode (free tier recommendations)
INTERACTIVE_DEFAULTS = [GROQ, GOOGLE]
# Provider display information: (id, display_name, description, pricing, is_recommended)
PROVIDER_INFO: list[tuple[str, str, str, str, bool]] = [
(OPENAI, "OpenAI", "GPT models", "Paid", False),
(ANTHROPIC, "Anthropic", "Claude models", "Paid", False),
(GOOGLE, "Google", "Gemini models", "Free tier", True),
(GROQ, "Groq", "Fast inference", "Free tier", True),
(MISTRAL, "Mistral", "Open models", "Mostly paid", False),
(COHERE, "Cohere", "Enterprise focus", "Limited free", False),
(OLLAMA, "Ollama", "Local inference", "Free (local)", True),
]
class PaymentProviders:
"""Payment provider options for the payment service."""
STRIPE = "stripe"
ALL = [STRIPE]
DEFAULT = STRIPE
class OllamaMode:
"""Ollama deployment mode options."""
HOST = "host" # Connect to Ollama running on host machine
DOCKER = "docker" # Run Ollama in Docker container
NONE = "none" # No Ollama (using cloud provider)
ALL = [HOST, DOCKER, NONE]
# Default URLs for each mode
HOST_URL = "http://host.docker.internal:11434" # For Mac/Windows Docker
DOCKER_URL = "http://ollama:11434" # For Docker service
class AuthLevels:
"""Auth level options for the auth service."""
BASIC = "basic"
RBAC = "rbac"
ORG = "org"
ALL = [BASIC, RBAC, ORG]
class AnswerKeys:
"""Keys in Copier .copier-answers.yml configuration."""
ANSWERS_FILENAME = ".copier-answers.yml"
# Component include flags
SCHEDULER = "include_scheduler"
WORKER = "include_worker"
REDIS = "include_redis"
DATABASE = "include_database"
CACHE = "include_cache"
INGRESS = "include_ingress"
OBSERVABILITY = "include_observability"
# Service include flags
AUTH = "include_auth"
AI = "include_ai"
COMMS = "include_comms"
INSIGHTS = "include_insights"
PAYMENT = "include_payment"
# Service names (used for selection/lookup)
SERVICE_AUTH = "auth"
SERVICE_AI = "ai"
SERVICE_COMMS = "comms"
SERVICE_INSIGHTS = "insights"
SERVICE_PAYMENT = "payment"
# Insights source flags
INSIGHTS_GITHUB = "insights_github"
INSIGHTS_PYPI = "insights_pypi"
INSIGHTS_PLAUSIBLE = "insights_plausible"
INSIGHTS_REDDIT = "insights_reddit"
# Payment configuration
PAYMENT_PROVIDER = "payment_provider"
# Configuration values
SCHEDULER_BACKEND = "scheduler_backend"
SCHEDULER_WITH_PERSISTENCE = "scheduler_with_persistence"
WORKER_BACKEND = "worker_backend"
DATABASE_ENGINE = "database_engine"
AI_FRAMEWORK = "ai_framework"
AI_PROVIDERS = "ai_providers"
AI_BACKEND = "ai_backend"
AI_WITH_PERSISTENCE = "ai_with_persistence"
AI_RAG = "ai_rag"
AUTH_LEVEL = "auth_level"
AUTH_RBAC = "include_auth_rbac"
AUTH_ORG = "include_auth_org"
AUTH_OAUTH = "include_oauth"
AI_VOICE = "ai_voice"
OLLAMA_MODE = "ollama_mode"
PROJECT_SLUG = "project_slug"
SRC_PATH = "_src_path"
@classmethod
def include_key(cls, name: str) -> str:
"""Generate include key for component/service name."""
return f"include_{name}"
class Messages:
"""User-facing CLI messages."""
# Section headers and separators
SEPARATOR_WIDTH = 40
SEPARATOR = "=" * SEPARATOR_WIDTH
SECTION_COMPONENT_SELECTION = "Component Selection"
SECTION_SERVICE_SELECTION = "Service Selection"
SECTION_COMPONENT_REMOVAL = "Component Removal"
SECTION_SERVICE_REMOVAL = "Service Removal Selection"
SECTION_SCHEDULER_PERSISTENCE = "Scheduler Persistence"
SECTION_DATABASE_ENGINE = "Database Engine"
SECTION_AI_FRAMEWORK = "AI Framework Selection"
SECTION_AI_BACKEND = "AI Conversation Persistence"
SECTION_AI_PROVIDERS = "AI Provider Selection"
# Git validation
GIT_NOT_INITIALIZED = "Project is not in a git repository"
GIT_REQUIRED_HINT = "Copier updates require git for change tracking"
GIT_INIT_HINT = (
"Projects created with 'aegis init' should have git initialized automatically"
)
GIT_MANUAL_INIT = (
"If you created this project manually, run: "
"git init && git add . && git commit -m 'Initial commit'"
)
# Copier project validation
NOT_COPIER_PROJECT = "Project was not generated with Copier"
# Component/service parsing
EMPTY_COMPONENT_NAME = "Empty component name is not allowed"
EMPTY_SERVICE_NAME = "Empty service name is not allowed"
# Interactive mode
INTERACTIVE_IGNORES_ARGS = "Warning: --interactive flag ignores component arguments"
NO_COMPONENTS_SELECTED = "No components selected"
NO_SERVICES_SELECTED = "No services selected"
# Next steps messages
NEXT_STEPS_HEADER = "Next steps:"
NEXT_STEP_MAKE_CHECK = " 1. Run 'make check' to verify the update"
NEXT_STEP_TEST = " 2. Test your application"
NEXT_STEP_COMMIT = " 3. Commit the changes with: git add . && git commit"
REVIEW_CHANGES_HEADER = "Review changes:"
REVIEW_DOCKER_COMPOSE = " git diff docker-compose.yml"
REVIEW_PYPROJECT = " git diff pyproject.toml"
@classmethod
def copier_only_command(cls, command_name: str) -> str:
"""Generate message for Copier-only command."""
from .i18n import t
return t("shared.copier_only", command=command_name)
@classmethod
def print_section_header(cls, title: str, newline_before: bool = False) -> None:
"""Print a section header with separator."""
import typer
if newline_before:
typer.echo()
typer.echo(title)
typer.echo(cls.SEPARATOR)
@classmethod
def print_next_steps(cls) -> None:
"""Print standard next steps message."""
import typer
from .i18n import t
typer.echo(f"\n{t('shared.next_steps')}")
typer.echo(t("shared.next_make_check"))
typer.echo(t("shared.next_test"))
typer.echo(t("shared.next_commit"))
@classmethod
def print_review_changes(cls) -> None:
"""Print standard review changes message."""
import typer
from .i18n import t
typer.echo(f"\n{t('shared.review_header')}")
typer.echo(t("shared.review_docker"))
typer.echo(t("shared.review_pyproject"))