Mercurial
comparison mrjunejune/main.c @ 265:056790c4fb0d
add role-aware Epi assistant prompts
Add verified June knowledge, guest/member/admin Copilot profiles, profile-isolated session recovery, animated Epi greetings, and a single authoritative runtime config workflow for inference.
Co-authored-by: Copilot <[email protected]>
| author | MrJuneJune <me@mrjunejune.com> |
|---|---|
| date | Fri, 07 Aug 2026 10:50:30 -0700 |
| parents | 04fee26ecce0 |
| children | e02e2036ef84 |
comparison
equal
deleted
inserted
replaced
| 264:04fee26ecce0 | 265:056790c4fb0d |
|---|---|
| 130 return byte_count; | 130 return byte_count; |
| 131 } | 131 } |
| 132 | 132 |
| 133 static void load_config(const char *config_path) | 133 static void load_config(const char *config_path) |
| 134 { | 134 { |
| 135 boolean config_loaded = FALSE; | |
| 135 FILE *f = fopen(config_path, "r"); | 136 FILE *f = fopen(config_path, "r"); |
| 136 char workspace_config_path[1024] = {0}; | 137 char workspace_config_path[1024] = {0}; |
| 137 if (!f) | 138 if (!f) |
| 138 { | 139 { |
| 139 const char *workspace = getenv("BUILD_WORKSPACE_DIRECTORY"); | 140 const char *workspace = getenv("BUILD_WORKSPACE_DIRECTORY"); |
| 153 { | 154 { |
| 154 printf("[CONFIG] Warning: Could not open %s, using defaults\n", config_path); | 155 printf("[CONFIG] Warning: Could not open %s, using defaults\n", config_path); |
| 155 } | 156 } |
| 156 else | 157 else |
| 157 { | 158 { |
| 159 config_loaded = TRUE; | |
| 158 char line[512]; | 160 char line[512]; |
| 159 while (fgets(line, sizeof(line), f)) | 161 while (fgets(line, sizeof(line), f)) |
| 160 { | 162 { |
| 161 // Skip comments and empty lines | 163 // Skip comments and empty lines |
| 162 if (line[0] == '#' || line[0] == '\n' || line[0] == '\r') continue; | 164 if (line[0] == '#' || line[0] == '\n' || line[0] == '\r') continue; |
| 266 (strcmp(value, "1") == 0 || strcmp(value, "true") == 0); | 268 (strcmp(value, "1") == 0 || strcmp(value, "true") == 0); |
| 267 } | 269 } |
| 268 else if (strcmp(key, "SERVER_HOST") == 0) | 270 else if (strcmp(key, "SERVER_HOST") == 0) |
| 269 { | 271 { |
| 270 strncpy(g_server_host, value, sizeof(g_server_host) - 1); | 272 strncpy(g_server_host, value, sizeof(g_server_host) - 1); |
| 273 } | |
| 274 else if (strcmp(key, "MRJUNEJUNE_ALLOW_GUEST_INFERENCE") == 0) | |
| 275 { | |
| 276 if (strcmp(value, "1") == 0 || strcasecmp(value, "true") == 0) | |
| 277 g_guest_inference_enabled = TRUE; | |
| 278 else if (strcmp(value, "0") == 0 || strcasecmp(value, "false") == 0) | |
| 279 g_guest_inference_enabled = FALSE; | |
| 280 else | |
| 281 { | |
| 282 fprintf( | |
| 283 stderr, | |
| 284 "[CONFIG] ERROR: MRJUNEJUNE_ALLOW_GUEST_INFERENCE must be true or false\n"); | |
| 285 exit(1); | |
| 286 } | |
| 271 } | 287 } |
| 272 else if (strcmp(key, "AUTH_GUEST_DAILY_TURNS") == 0) | 288 else if (strcmp(key, "AUTH_GUEST_DAILY_TURNS") == 0) |
| 273 { | 289 { |
| 274 int64 v; | 290 int64 v; |
| 275 if (!config__parse_int64_strict(value, &v) || | 291 if (!config__parse_int64_strict(value, &v) || |
| 318 printf("[CONFIG] Auth: secret=%s, bootstrap_user=%s, trusted_proxy=%s\n", | 334 printf("[CONFIG] Auth: secret=%s, bootstrap_user=%s, trusted_proxy=%s\n", |
| 319 g_auth_cookie_secret[0] ? "(set)" : "(not set)", | 335 g_auth_cookie_secret[0] ? "(set)" : "(not set)", |
| 320 g_auth_bootstrap_username[0] ? g_auth_bootstrap_username : "(none)", | 336 g_auth_bootstrap_username[0] ? g_auth_bootstrap_username : "(none)", |
| 321 g_auth_trusted_proxy[0] ? "(set)" : "(not set)"); | 337 g_auth_trusted_proxy[0] ? "(set)" : "(not set)"); |
| 322 | 338 |
| 323 const char *database_path_override = getenv("DB_PATH"); | 339 const char *database_path_override = getenv("MRJUNEJUNE_DB_PATH"); |
| 324 const char *test_tmpdir = getenv("TEST_TMPDIR"); | 340 const char *test_tmpdir = getenv("TEST_TMPDIR"); |
| 325 if (database_path_override && database_path_override[0] != '\0') | 341 if (database_path_override && database_path_override[0] != '\0') |
| 326 { | 342 { |
| 327 strncpy(g_db_path, database_path_override, sizeof(g_db_path) - 1); | 343 strncpy(g_db_path, database_path_override, sizeof(g_db_path) - 1); |
| 328 } | 344 } |
| 329 else if (test_tmpdir && test_tmpdir[0] != '\0') | 345 else if (test_tmpdir && test_tmpdir[0] != '\0') |
| 330 { | 346 { |
| 331 snprintf(g_db_path, sizeof(g_db_path), "%s/mrjunejune.db", test_tmpdir); | 347 snprintf(g_db_path, sizeof(g_db_path), "%s/mrjunejune.db", test_tmpdir); |
| 332 } | 348 } |
| 333 | 349 |
| 334 /* Environment overrides: env vars always take precedence over file. | 350 /* Environment configuration is a compatibility/testing fallback only when |
| 335 * Values are never logged. */ | 351 * no config file is present. Dynamic supervisor wiring is read separately. */ |
| 352 if (!config_loaded) | |
| 336 { | 353 { |
| 337 const char *env; | 354 const char *env; |
| 338 | 355 |
| 339 /* S3 / server config env overrides */ | 356 /* S3 / server config env overrides */ |
| 340 if ((env = getenv("UPLOAD_AUTH_TOKEN")) && env[0] != '\0') | 357 if ((env = getenv("UPLOAD_AUTH_TOKEN")) && env[0] != '\0') |
| 353 fprintf(stderr, "[CONFIG] ERROR: S3_URL_EXPIRES must be a positive integer\n"); | 370 fprintf(stderr, "[CONFIG] ERROR: S3_URL_EXPIRES must be a positive integer\n"); |
| 354 exit(1); | 371 exit(1); |
| 355 } | 372 } |
| 356 g_s3_url_expires = (int)v; | 373 g_s3_url_expires = (int)v; |
| 357 } | 374 } |
| 358 if ((env = getenv("MRJUNEJUNE_DB_PATH")) && env[0] != '\0') | |
| 359 strncpy(g_db_path, env, sizeof(g_db_path) - 1); | |
| 360 if ((env = getenv("AWS_MRJUNEJUNE_ACCESS_KEY")) && env[0] != '\0') | 375 if ((env = getenv("AWS_MRJUNEJUNE_ACCESS_KEY")) && env[0] != '\0') |
| 361 strncpy(g_s3_access_key, env, sizeof(g_s3_access_key) - 1); | 376 strncpy(g_s3_access_key, env, sizeof(g_s3_access_key) - 1); |
| 362 if ((env = getenv("AWS_MRJUNEJUNE_SECRET_ACCESS_KEY")) && env[0] != '\0') | 377 if ((env = getenv("AWS_MRJUNEJUNE_SECRET_ACCESS_KEY")) && env[0] != '\0') |
| 363 strncpy(g_s3_secret_key, env, sizeof(g_s3_secret_key) - 1); | 378 strncpy(g_s3_secret_key, env, sizeof(g_s3_secret_key) - 1); |
| 364 | 379 |
| 2355 { | 2370 { |
| 2356 signal(SIGINT, handle_sigint); | 2371 signal(SIGINT, handle_sigint); |
| 2357 signal(SIGTERM, handle_sigint); | 2372 signal(SIGTERM, handle_sigint); |
| 2358 | 2373 |
| 2359 // Load the ignored runtime config when present; environment overrides follow. | 2374 // Load the ignored runtime config when present; environment overrides follow. |
| 2360 load_config("mrjunejune/.config"); | 2375 const char *config_path = getenv("MRJUNEJUNE_CONFIG_PATH"); |
| 2376 load_config( | |
| 2377 config_path && config_path[0] != '\0' | |
| 2378 ? config_path | |
| 2379 : "mrjunejune/.config"); | |
| 2361 | 2380 |
| 2362 // Initialize S3 config using global credentials populated by load_config | 2381 // Initialize S3 config using global credentials populated by load_config |
| 2363 g_s3_config.access_key_id = g_s3_access_key; | 2382 g_s3_config.access_key_id = g_s3_access_key; |
| 2364 g_s3_config.secret_access_key = g_s3_secret_key; | 2383 g_s3_config.secret_access_key = g_s3_secret_key; |
| 2365 g_s3_config.region = g_s3_region; | 2384 g_s3_config.region = g_s3_region; |