annotate mrjunejune/conversation_api.c @ 266:efaf4c63cc94

fix clean production bundle staging Recreate deployment staging before copying the Bazel bundle and verify required inference runtime paths before promoting it. Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Fri, 07 Aug 2026 12:52:30 -0700
parents 056790c4fb0d
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1 #include "mrjunejune/conversation_api.h"
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
3 #include "mrjunejune/auth_api.h"
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
4 #include "mrjunejune/inference_bridge.h"
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
5 #include "mrjunejune/conversation_store.h"
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
6 #include "auth/auth_store.h"
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
7 #include "seobeo/seobeo.h"
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
8
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
9 #include <pthread.h>
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
10 #include <stdio.h>
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
11 #include <stdarg.h>
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
12 #include <stdlib.h>
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
13 #include <string.h>
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
14 #include <strings.h>
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
15 #include <time.h>
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
16
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
17 #define CONVERSATION_TITLE_MAX 200
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
18 #define CONVERSATION_PROMPT_MAX (32 * 1024)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
19 #define CONVERSATION_RESPONSE_MAX (256 * 1024)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
20 #define CONVERSATION_HISTORY_MAX (512 * 1024)
261
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
21 #define CONVERSATION_CUSTOM_EVENT_MAX (3 * 1024)
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
22 #define CONVERSATION_EVENT_NAME_MAX 64
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
23 #define CONVERSATION_ACTIVE_MAX 4
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
24 #define CONVERSATION_TURNS_PER_MINUTE 60
265
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
25 #define CONVERSATION_PROMPT_VERSION 1
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
26 #define CONVERSATION_KNOWLEDGE_VERSION 1
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
27 /* Buffer large enough for a guest Set-Cookie directive */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
28 #define CONV_GUEST_COOKIE_CAPACITY (AUTH_CRYPTO_GUEST_COOKIE_SIZE + 256)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
29
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
30 /* Quota policy — read from env at init, validated at startup. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
31 #define CONV_GUEST_DAILY_TURNS_DEFAULT 10
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
32 #define CONV_GUEST_DAILY_OUTPUT_TOKENS_DEFAULT 20000
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
33 #define CONV_GUEST_DAILY_TURNS_MIN 1
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
34 #define CONV_GUEST_DAILY_TURNS_MAX 10000
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
35 #define CONV_GUEST_DAILY_OUTPUT_TOKENS_MIN 1
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
36 #define CONV_GUEST_DAILY_OUTPUT_TOKENS_MAX 1000000
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
37 #define CONV_GUEST_REQUEST_OUTPUT_TOKENS_MIN 1
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
38 /* Default per-request reservation (tokens); capped to daily at init. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
39 #define CONV_GUEST_REQUEST_OUTPUT_TOKENS_DEFAULT 2048
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
40
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
41 static Conversation_Store *g_conversation_store = NULL;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
42 static Inference_Bridge *g_inference_bridge = NULL;
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
43 static boolean g_guest_inference_enabled = FALSE;
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
44 static pthread_mutex_t g_pending_mutex = PTHREAD_MUTEX_INITIALIZER;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
45 static pthread_mutex_t g_admission_mutex = PTHREAD_MUTEX_INITIALIZER;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
46 static time_t g_admission_window = 0;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
47 static uint32 g_admission_turns = 0;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
48 static uint32 g_active_turns = 0;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
49
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
50 /* Quota policy (validated at init). */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
51 static int64 g_guest_daily_turns = CONV_GUEST_DAILY_TURNS_DEFAULT;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
52 static int64 g_guest_daily_output_tokens = CONV_GUEST_DAILY_OUTPUT_TOKENS_DEFAULT;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
53 static int64 g_guest_request_output_tokens = CONV_GUEST_REQUEST_OUTPUT_TOKENS_DEFAULT;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
54
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
55 typedef struct Pending_Turn {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
56 char request_id[37];
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
57 char conversation_id[37];
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
58 /* owner identity copied before request arena expires (req 8) */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
59 Conversation_Owner owner;
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
60 Seobeo_SSE_Stream *p_stream;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
61 char *content;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
62 size_t content_length;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
63 size_t content_capacity;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
64 int64 input_tokens;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
65 int64 output_tokens;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
66 boolean failed;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
67 boolean aborted;
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
68 boolean has_usage_event; /* TRUE once assistant.usage received */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
69 boolean finalized; /* TRUE once Finalize_Pending has run (once-only) */
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
70 char error_message[512];
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
71 /* Guest quota fields — copied before arena expires. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
72 boolean is_guest_reserved; /* TRUE if quota was reserved for this turn */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
73 int64 reserved_output_tokens;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
74 char guest_id[37]; /* guest_id from principal (safe copy) */
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
75 struct Pending_Turn *p_next;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
76 } Pending_Turn;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
77
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
78 static Pending_Turn *g_pending_turns = NULL;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
79
261
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
80 static boolean Conversation_API_Is_Handled_Event(const char *type)
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
81 {
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
82 return
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
83 strcmp(type, "ready") == 0 ||
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
84 strcmp(type, "turn.accepted") == 0 ||
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
85 strcmp(type, "assistant.delta") == 0 ||
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
86 strcmp(type, "assistant.completed") == 0 ||
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
87 strcmp(type, "assistant.usage") == 0 ||
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
88 strcmp(type, "turn.error") == 0 ||
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
89 strcmp(type, "turn.done") == 0;
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
90 }
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
91
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
92 static boolean Conversation_API_Is_Safe_Event_Name(const char *type)
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
93 {
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
94 if (!type || type[0] == '\0')
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
95 return FALSE;
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
96 size_t length = strlen(type);
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
97 if (length > CONVERSATION_EVENT_NAME_MAX)
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
98 return FALSE;
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
99 for (size_t i = 0; i < length; i++)
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
100 {
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
101 char character = type[i];
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
102 if (!(
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
103 (character >= 'a' && character <= 'z') ||
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
104 (character >= 'A' && character <= 'Z') ||
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
105 (character >= '0' && character <= '9') ||
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
106 character == '.' ||
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
107 character == '_' ||
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
108 character == '-'))
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
109 return FALSE;
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
110 }
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
111 return TRUE;
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
112 }
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
113
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
114 static boolean Conversation_API_Acquire_Turn_Slot(void)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
115 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
116 time_t now = time(NULL);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
117 pthread_mutex_lock(&g_admission_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
118 if (g_admission_window == 0 || now - g_admission_window >= 60)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
119 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
120 g_admission_window = now;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
121 g_admission_turns = 0;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
122 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
123 boolean allowed =
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
124 g_admission_turns < CONVERSATION_TURNS_PER_MINUTE &&
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
125 g_active_turns < CONVERSATION_ACTIVE_MAX;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
126 if (allowed)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
127 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
128 g_admission_turns++;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
129 g_active_turns++;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
130 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
131 pthread_mutex_unlock(&g_admission_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
132 return allowed;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
133 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
134
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
135 static void Conversation_API_Release_Turn_Slot(void)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
136 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
137 pthread_mutex_lock(&g_admission_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
138 if (g_active_turns > 0)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
139 g_active_turns--;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
140 pthread_mutex_unlock(&g_admission_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
141 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
142
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
143 static const char *Conversation_API_Request_Value(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
144 Seobeo_Request_Entry *p_request,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
145 const char *key)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
146 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
147 void *p_value = Dowa_HashMap_Get_Ptr(p_request, (char *)key);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
148 return p_value ? ((Seobeo_Request_Entry *)p_value)->value : NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
149 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
150
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
151 static boolean Conversation_API_Is_Inference_Ready(void)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
152 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
153 return g_guest_inference_enabled;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
154 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
155
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
156 /* UTC midnight for a Unix timestamp. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
157 static int64 conv__utc_window_start(int64 unix_ts)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
158 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
159 return (unix_ts / 86400LL) * 86400LL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
160 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
161
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
162 /* Build guest quota JSON into a fixed buffer (null-terminated). */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
163 static boolean conv_guest_quota_cb(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
164 const char *guest_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
165 int64 current_unix,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
166 char *json_out,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
167 size_t json_capacity)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
168 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
169 Auth_Store *p_store = Auth_API_Get_Store();
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
170 if (!p_store || !guest_id || !json_out || json_capacity == 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
171 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
172 if (json_out && json_capacity > 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
173 strncpy(json_out, "null", json_capacity);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
174 return TRUE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
175 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
176
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
177 int64 window_start = conv__utc_window_start(current_unix);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
178 Auth_Store_Guest_Usage usage;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
179 memset(&usage, 0, sizeof(usage));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
180 Auth_Store_Guest_Get_Usage(p_store, guest_id, window_start, &usage);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
181
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
182 int64 turns_remaining =
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
183 g_guest_daily_turns - usage.turns_used;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
184 if (turns_remaining < 0) turns_remaining = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
185 int64 tokens_remaining =
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
186 g_guest_daily_output_tokens - usage.output_tokens_used - usage.output_tokens_reserved;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
187 if (tokens_remaining < 0) tokens_remaining = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
188 int64 resets_at = window_start + 86400LL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
189
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
190 snprintf(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
191 json_out, json_capacity,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
192 "{\"turnsLimit\":%lld,\"turnsUsed\":%lld,\"turnsRemaining\":%lld,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
193 "\"outputTokensLimit\":%lld,\"outputTokensUsed\":%lld,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
194 "\"outputTokensReserved\":%lld,\"outputTokensRemaining\":%lld,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
195 "\"resetsAt\":%lld}",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
196 (long long)g_guest_daily_turns,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
197 (long long)usage.turns_used,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
198 (long long)turns_remaining,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
199 (long long)g_guest_daily_output_tokens,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
200 (long long)usage.output_tokens_used,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
201 (long long)usage.output_tokens_reserved,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
202 (long long)tokens_remaining,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
203 (long long)resets_at);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
204 return TRUE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
205 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
206
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
207 static Dowa_JSON_Entry *Conversation_API_Parse_Body(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
208 Seobeo_Request_Entry *p_request,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
209 Dowa_Arena *p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
210 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
211 const char *body = Conversation_API_Request_Value(p_request, "Body");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
212 if (!body)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
213 return NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
214 Dowa_JSON_Value value = Dowa_JSON_Parse(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
215 body, (int32)strlen(body), p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
216 return value.type == DOWA_JSON_OBJECT
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
217 ? (Dowa_JSON_Entry *)value.object_val
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
218 : NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
219 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
220
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
221 static const char *Conversation_API_Query_Param(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
222 Seobeo_Request_Entry *p_request,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
223 const char *param_name,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
224 char *output,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
225 size_t output_capacity)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
226 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
227 const char *qs = Conversation_API_Request_Value(p_request, "QueryString");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
228 if (!qs || !param_name || !output || output_capacity == 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
229 return NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
230 output[0] = '\0';
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
231 size_t name_len = strlen(param_name);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
232 const char *p = qs;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
233 while (*p)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
234 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
235 if (strncmp(p, param_name, name_len) == 0 && p[name_len] == '=')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
236 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
237 p += name_len + 1;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
238 size_t i = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
239 while (*p && *p != '&' && i < output_capacity - 1)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
240 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
241 if (p[0] == '%' && p[1] && p[2])
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
242 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
243 char hex[3] = {p[1], p[2], '\0'};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
244 output[i++] = (char)(int)strtol(hex, NULL, 16);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
245 p += 3;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
246 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
247 else if (*p == '+')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
248 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
249 output[i++] = ' ';
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
250 p++;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
251 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
252 else
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
253 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
254 output[i++] = *p++;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
255 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
256 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
257 output[i] = '\0';
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
258 return output[0] != '\0' ? output : NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
259 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
260 while (*p && *p != '&') p++;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
261 if (*p == '&') p++;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
262 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
263 return NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
264 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
265
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
266 /*
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
267 * Build a JSON response, optionally setting a guest cookie when one was
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
268 * freshly issued by Auth_API_Resolve_Principal.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
269 */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
270 static Seobeo_Request_Entry *Conversation_API_JSON_Response_With_Cookie(
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
271 Dowa_Arena *p_arena,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
272 const char *status,
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
273 const char *body,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
274 const char *new_guest_cookie)
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
275 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
276 Seobeo_Request_Entry *p_response = NULL;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
277 Dowa_HashMap_Push_Arena(p_response, "status", (char *)status, p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
278 Dowa_HashMap_Push_Arena(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
279 p_response, "content-type", "application/json; charset=utf-8", p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
280 Dowa_HashMap_Push_Arena(p_response, "cache-control", "no-store", p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
281 Dowa_HashMap_Push_Arena(p_response, "body", (char *)body, p_arena);
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
282 if (new_guest_cookie && new_guest_cookie[0] != '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
283 Dowa_HashMap_Push_Arena(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
284 p_response, "Set-Cookie", (char *)new_guest_cookie, p_arena);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
285 return p_response;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
286 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
287
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
288 static Seobeo_Request_Entry *Conversation_API_JSON_Response(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
289 Dowa_Arena *p_arena,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
290 const char *status,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
291 const char *body)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
292 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
293 return Conversation_API_JSON_Response_With_Cookie(p_arena, status, body, NULL);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
294 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
295
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
296 static Seobeo_Request_Entry *Conversation_API_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
297 Dowa_Arena *p_arena,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
298 const char *status,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
299 const char *code,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
300 const char *message)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
301 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
302 char *escaped = Dowa_JSON_Escape_String(message, 0, p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
303 size_t capacity = strlen(code) + strlen(escaped) + 64;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
304 char *body = Dowa_Arena_Allocate(p_arena, capacity);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
305 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
306 body,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
307 capacity,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
308 "{\"error\":{\"code\":\"%s\",\"message\":\"%s\"}}",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
309 code,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
310 escaped);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
311 return Conversation_API_JSON_Response(p_arena, status, body);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
312 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
313
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
314 static Seobeo_Request_Entry *Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
315 Dowa_Arena *p_arena,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
316 const char *status,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
317 const char *code,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
318 const char *message,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
319 const char *new_guest_cookie)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
320 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
321 char *escaped = Dowa_JSON_Escape_String(message, 0, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
322 size_t capacity = strlen(code) + strlen(escaped) + 64;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
323 char *body = Dowa_Arena_Allocate(p_arena, capacity);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
324 snprintf(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
325 body,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
326 capacity,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
327 "{\"error\":{\"code\":\"%s\",\"message\":\"%s\"}}",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
328 code,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
329 escaped);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
330 return Conversation_API_JSON_Response_With_Cookie(p_arena, status, body, new_guest_cookie);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
331 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
332
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
333 /*
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
334 * Resolve the principal for this request, optionally setting a new guest
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
335 * cookie on the response when returned.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
336 * Returns FALSE only on internal error (treat as 500).
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
337 */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
338 static boolean Conversation_API_Resolve(
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
339 Seobeo_Request_Entry *p_request,
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
340 Auth_Principal *p_principal,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
341 char *new_guest_cookie,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
342 Dowa_Arena *p_arena)
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
343 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
344 return Auth_API_Resolve_Principal(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
345 p_request, p_principal, p_arena,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
346 new_guest_cookie, CONV_GUEST_COOKIE_CAPACITY);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
347 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
348
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
349 /*
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
350 * Resolve an existing principal for mutation requests.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
351 * Does NOT create a new guest identity.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
352 * Returns FALSE on internal error (500); sets *p_found=FALSE when no
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
353 * existing session/guest is present (caller must return 401).
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
354 */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
355 static boolean Conversation_API_Resolve_Existing(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
356 Seobeo_Request_Entry *p_request,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
357 Auth_Principal *p_principal,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
358 Dowa_Arena *p_arena,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
359 boolean *p_found)
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
360 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
361 return Auth_API_Resolve_Existing_Principal(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
362 p_request, p_principal, p_arena, p_found);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
363 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
364
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
365 /*
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
366 * Map a resolved principal to a Conversation_Owner.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
367 * Always succeeds for USER and GUEST principals.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
368 */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
369 static void Conversation_API_Owner_From_Principal(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
370 const Auth_Principal *p_principal,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
371 Conversation_Owner *p_owner)
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
372 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
373 if (p_principal->kind == AUTH_PRINCIPAL_USER)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
374 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
375 p_owner->kind = CONVERSATION_OWNER_KIND_USER;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
376 strncpy(p_owner->id, p_principal->user_id, sizeof(p_owner->id) - 1);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
377 p_owner->id[sizeof(p_owner->id) - 1] = '\0';
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
378 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
379 else
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
380 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
381 p_owner->kind = CONVERSATION_OWNER_KIND_GUEST;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
382 strncpy(p_owner->id, p_principal->guest_id, sizeof(p_owner->id) - 1);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
383 p_owner->id[sizeof(p_owner->id) - 1] = '\0';
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
384 }
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
385 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
386
265
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
387 static boolean Conversation_API_Prompt_Profile_From_Principal(
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
388 const Auth_Principal *p_principal,
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
389 Inference_Prompt_Profile *p_profile)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
390 {
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
391 if (!p_principal || !p_profile)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
392 return FALSE;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
393 if (p_principal->kind == AUTH_PRINCIPAL_GUEST)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
394 {
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
395 *p_profile = INFERENCE_PROMPT_PROFILE_PUBLIC_VISITOR;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
396 return TRUE;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
397 }
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
398 if (p_principal->kind != AUTH_PRINCIPAL_USER)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
399 return FALSE;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
400 if (strcmp(p_principal->role, "member") == 0)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
401 {
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
402 *p_profile = INFERENCE_PROMPT_PROFILE_INVITED_FRIEND;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
403 return TRUE;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
404 }
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
405 if (strcmp(p_principal->role, "admin") == 0)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
406 {
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
407 *p_profile = INFERENCE_PROMPT_PROFILE_JUNE_ADMIN;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
408 return TRUE;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
409 }
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
410 return FALSE;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
411 }
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
412
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
413 static void Conversation_API_Send_Stream_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
414 Seobeo_Handle *p_handle,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
415 int status,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
416 const char *code,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
417 const char *message)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
418 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
419 char body[1024];
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
420 int body_length = snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
421 body,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
422 sizeof(body),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
423 "{\"error\":{\"code\":\"%s\",\"message\":\"%s\"}}",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
424 code,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
425 message);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
426 if (body_length < 0 || (size_t)body_length >= sizeof(body))
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
427 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
428 char header[512];
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
429 Seobeo_Web_Header_Generate(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
430 header,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
431 status,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
432 "application/json; charset=utf-8",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
433 body_length);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
434 Seobeo_Handle_Queue(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
435 p_handle, (const uint8 *)header, (uint32)strlen(header));
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
436 Seobeo_Handle_Queue(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
437 p_handle, (const uint8 *)body, (uint32)body_length);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
438 Seobeo_Handle_Flush(p_handle);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
439 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
440
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
441 static Pending_Turn *Conversation_API_Find_Pending(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
442 const char *request_id)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
443 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
444 for (Pending_Turn *p_turn = g_pending_turns;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
445 p_turn;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
446 p_turn = p_turn->p_next)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
447 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
448 if (strcmp(p_turn->request_id, request_id) == 0)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
449 return p_turn;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
450 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
451 return NULL;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
452 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
453
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
454 static int32 Conversation_API_Send_Event(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
455 Pending_Turn *p_turn,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
456 const char *event_name,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
457 const char *json)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
458 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
459 Seobeo_SSE_Event event = {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
460 .event = event_name,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
461 .data = json,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
462 .retry_ms = SEOBEO_SSE_RETRY_NONE,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
463 };
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
464 return Seobeo_SSE_Send(p_turn->p_stream, &event);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
465 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
466
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
467 static void Conversation_API_Remove_Pending(Pending_Turn *p_turn)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
468 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
469 Pending_Turn **pp_current = &g_pending_turns;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
470 while (*pp_current)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
471 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
472 if (*pp_current == p_turn)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
473 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
474 *pp_current = p_turn->p_next;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
475 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
476 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
477 pp_current = &(*pp_current)->p_next;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
478 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
479 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
480
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
481 static void Conversation_API_Finalize_Pending(Pending_Turn *p_turn)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
482 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
483 /* Idempotence guard — called with g_pending_mutex held. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
484 if (p_turn->finalized)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
485 return;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
486 p_turn->finalized = TRUE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
487
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
488 /* Reconcile or release guest quota reservation before persistence. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
489 if (p_turn->is_guest_reserved)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
490 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
491 Auth_Store *p_auth_store = Auth_API_Get_Store();
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
492 if (p_auth_store)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
493 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
494 if (!p_turn->failed && !p_turn->aborted)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
495 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
496 int64 actual = p_turn->has_usage_event
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
497 ? p_turn->output_tokens
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
498 : p_turn->reserved_output_tokens;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
499 Auth_Store_Guest_Reconcile(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
500 p_auth_store, p_turn->request_id, actual);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
501 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
502 else
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
503 Auth_Store_Guest_Release(p_auth_store, p_turn->request_id);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
504 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
505 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
506
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
507 Conversation_Store_Result persistence;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
508 if (p_turn->failed || p_turn->aborted)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
509 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
510 persistence = Conversation_Store_Fail_Turn(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
511 g_conversation_store,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
512 p_turn->conversation_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
513 p_turn->request_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
514 p_turn->error_message,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
515 p_turn->aborted);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
516 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
517 else
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
518 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
519 persistence = Conversation_Store_Complete_Turn(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
520 g_conversation_store,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
521 p_turn->conversation_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
522 p_turn->request_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
523 p_turn->content ? p_turn->content : "",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
524 p_turn->input_tokens,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
525 p_turn->output_tokens);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
526 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
527 if (persistence != CONVERSATION_STORE_OK)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
528 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
529 p_turn->failed = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
530 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
531 p_turn->error_message,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
532 sizeof(p_turn->error_message),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
533 "Unable to persist completed turn");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
534 Conversation_Store_Fail_Turn(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
535 g_conversation_store,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
536 p_turn->conversation_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
537 p_turn->request_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
538 p_turn->error_message,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
539 FALSE);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
540 Conversation_API_Send_Event(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
541 p_turn,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
542 "turn.error",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
543 "{\"code\":\"storage_failed\","
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
544 "\"message\":\"Unable to persist completed turn\"}");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
545 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
546
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
547 char done[256];
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
548 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
549 done,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
550 sizeof(done),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
551 "{\"request_id\":\"%s\",\"failed\":%s,\"aborted\":%s}",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
552 p_turn->request_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
553 p_turn->failed ? "true" : "false",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
554 p_turn->aborted ? "true" : "false");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
555 Conversation_API_Send_Event(p_turn, "turn.done", done);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
556 Conversation_API_Remove_Pending(p_turn);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
557 Seobeo_SSE_Close(p_turn->p_stream);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
558 Seobeo_SSE_Release(p_turn->p_stream);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
559 Conversation_API_Release_Turn_Slot();
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
560 free(p_turn->content);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
561 free(p_turn);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
562 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
563
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
564 static void Conversation_API_Handle_Inference_Event(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
565 const Inference_Event *p_event,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
566 void *p_user_data)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
567 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
568 (void)p_user_data;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
569 if (strcmp(p_event->type, "bridge.closed") == 0)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
570 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
571 pthread_mutex_lock(&g_pending_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
572 while (g_pending_turns)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
573 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
574 Pending_Turn *p_turn = g_pending_turns;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
575 p_turn->failed = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
576 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
577 p_turn->error_message,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
578 sizeof(p_turn->error_message),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
579 "Inference sidecar connection closed");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
580 Conversation_API_Send_Event(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
581 p_turn,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
582 "turn.error",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
583 "{\"code\":\"sidecar_closed\","
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
584 "\"message\":\"Inference sidecar connection closed\"}");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
585 Conversation_API_Finalize_Pending(p_turn);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
586 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
587 pthread_mutex_unlock(&g_pending_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
588 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
589 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
590 if (!p_event->request_id || p_event->request_id[0] == '\0')
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
591 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
592
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
593 boolean should_abort = FALSE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
594 char abort_request_id[37] = {0};
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
595 char abort_conversation_id[37] = {0};
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
596 pthread_mutex_lock(&g_pending_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
597 Pending_Turn *p_turn = Conversation_API_Find_Pending(p_event->request_id);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
598 if (!p_turn)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
599 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
600 pthread_mutex_unlock(&g_pending_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
601 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
602 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
603
261
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
604 if (!Conversation_API_Is_Handled_Event(p_event->type))
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
605 {
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
606 if (!Conversation_API_Is_Safe_Event_Name(p_event->type) ||
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
607 !p_event->raw_json ||
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
608 p_event->raw_json_length == 0 ||
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
609 p_event->raw_json_length > CONVERSATION_CUSTOM_EVENT_MAX)
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
610 {
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
611 p_turn->failed = TRUE;
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
612 snprintf(
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
613 p_turn->error_message,
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
614 sizeof(p_turn->error_message),
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
615 "Invalid custom inference event");
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
616 Conversation_API_Send_Event(
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
617 p_turn,
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
618 "turn.error",
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
619 "{\"code\":\"invalid_custom_event\","
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
620 "\"message\":\"Invalid custom inference event\"}");
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
621 Conversation_API_Finalize_Pending(p_turn);
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
622 }
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
623 else if (Conversation_API_Send_Event(
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
624 p_turn, p_event->type, p_event->raw_json) < 0)
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
625 {
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
626 p_turn->aborted = TRUE;
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
627 should_abort = TRUE;
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
628 snprintf(
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
629 abort_request_id,
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
630 sizeof(abort_request_id),
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
631 "%s",
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
632 p_turn->request_id);
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
633 snprintf(
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
634 abort_conversation_id,
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
635 sizeof(abort_conversation_id),
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
636 "%s",
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
637 p_turn->conversation_id);
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
638 }
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
639 pthread_mutex_unlock(&g_pending_mutex);
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
640 if (should_abort)
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
641 Inference_Bridge_Abort_Turn(
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
642 g_inference_bridge, abort_request_id, abort_conversation_id);
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
643 return;
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
644 }
b401627fc49e Add JRPG mock flows and interactive previews
MrJuneJune <mrjunejune@users.noreply.github.com>
parents: 260
diff changeset
645
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
646 size_t event_text_length =
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
647 strlen(p_event->delta ? p_event->delta : "") +
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
648 strlen(p_event->content ? p_event->content : "") +
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
649 strlen(p_event->error_code ? p_event->error_code : "") +
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
650 strlen(p_event->error_message ? p_event->error_message : "");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
651 if (event_text_length > (((size_t)-1) - 8192) / 12)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
652 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
653 p_turn->failed = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
654 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
655 p_turn->error_message,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
656 sizeof(p_turn->error_message),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
657 "Inference event exceeded memory limit");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
658 Conversation_API_Send_Event(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
659 p_turn,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
660 "turn.error",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
661 "{\"code\":\"event_too_large\","
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
662 "\"message\":\"Inference event exceeded memory limit\"}");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
663 Conversation_API_Finalize_Pending(p_turn);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
664 pthread_mutex_unlock(&g_pending_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
665 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
666 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
667 Dowa_Arena *p_arena = Dowa_Arena_Create(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
668 event_text_length * 12 + 8192);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
669 if (!p_arena)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
670 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
671 p_turn->failed = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
672 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
673 p_turn->error_message,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
674 sizeof(p_turn->error_message),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
675 "Unable to allocate inference event");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
676 Conversation_API_Send_Event(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
677 p_turn,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
678 "turn.error",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
679 "{\"code\":\"allocation_failed\","
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
680 "\"message\":\"Unable to allocate inference event\"}");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
681 Conversation_API_Finalize_Pending(p_turn);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
682 pthread_mutex_unlock(&g_pending_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
683 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
684 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
685
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
686 if (strcmp(p_event->type, "turn.accepted") == 0)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
687 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
688 char accepted[128];
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
689 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
690 accepted,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
691 sizeof(accepted),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
692 "{\"request_id\":\"%s\"}",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
693 p_turn->request_id);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
694 Conversation_API_Send_Event(p_turn, "turn.accepted", accepted);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
695 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
696 else if (strcmp(p_event->type, "assistant.delta") == 0)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
697 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
698 size_t delta_length = strlen(p_event->delta);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
699 if (p_turn->content_length + delta_length > CONVERSATION_RESPONSE_MAX)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
700 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
701 p_turn->failed = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
702 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
703 p_turn->error_message,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
704 sizeof(p_turn->error_message),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
705 "Assistant response exceeded limit");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
706 should_abort = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
707 snprintf(abort_request_id, sizeof(abort_request_id), "%s",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
708 p_turn->request_id);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
709 snprintf(abort_conversation_id, sizeof(abort_conversation_id), "%s",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
710 p_turn->conversation_id);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
711 char error[256];
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
712 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
713 error,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
714 sizeof(error),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
715 "{\"request_id\":\"%s\",\"code\":\"response_too_large\","
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
716 "\"message\":\"Assistant response exceeded limit\"}",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
717 p_turn->request_id);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
718 Conversation_API_Send_Event(p_turn, "turn.error", error);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
719 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
720 else
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
721 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
722 if (p_turn->content_length + delta_length + 1 >
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
723 p_turn->content_capacity)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
724 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
725 size_t next_capacity = p_turn->content_capacity
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
726 ? p_turn->content_capacity * 2
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
727 : 4096;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
728 while (next_capacity <
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
729 p_turn->content_length + delta_length + 1)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
730 next_capacity *= 2;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
731 char *next = realloc(p_turn->content, next_capacity);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
732 if (!next)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
733 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
734 p_turn->failed = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
735 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
736 p_turn->error_message,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
737 sizeof(p_turn->error_message),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
738 "Unable to buffer assistant response");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
739 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
740 else
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
741 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
742 p_turn->content = next;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
743 p_turn->content_capacity = next_capacity;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
744 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
745 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
746 if (!p_turn->failed)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
747 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
748 memcpy(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
749 p_turn->content + p_turn->content_length,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
750 p_event->delta,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
751 delta_length);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
752 p_turn->content_length += delta_length;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
753 p_turn->content[p_turn->content_length] = '\0';
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
754 char *delta = Dowa_JSON_Escape_String(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
755 p_event->delta, delta_length, p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
756 size_t capacity = delta ? strlen(delta) + 128 : 0;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
757 char *json = capacity
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
758 ? Dowa_Arena_Allocate(p_arena, capacity)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
759 : NULL;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
760 if (!delta || !json)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
761 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
762 p_turn->failed = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
763 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
764 p_turn->error_message,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
765 sizeof(p_turn->error_message),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
766 "Unable to serialize assistant delta");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
767 Conversation_API_Send_Event(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
768 p_turn,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
769 "turn.error",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
770 "{\"code\":\"serialize_failed\","
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
771 "\"message\":\"Unable to serialize assistant delta\"}");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
772 should_abort = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
773 snprintf(abort_request_id, sizeof(abort_request_id), "%s",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
774 p_turn->request_id);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
775 snprintf(abort_conversation_id, sizeof(abort_conversation_id), "%s",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
776 p_turn->conversation_id);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
777 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
778 else
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
779 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
780 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
781 json,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
782 capacity,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
783 "{\"request_id\":\"%s\",\"delta\":\"%s\"}",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
784 p_turn->request_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
785 delta);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
786 if (Conversation_API_Send_Event(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
787 p_turn, "assistant.delta", json) < 0)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
788 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
789 p_turn->aborted = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
790 should_abort = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
791 snprintf(abort_request_id, sizeof(abort_request_id), "%s",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
792 p_turn->request_id);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
793 snprintf(abort_conversation_id, sizeof(abort_conversation_id), "%s",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
794 p_turn->conversation_id);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
795 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
796 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
797 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
798 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
799 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
800 else if (strcmp(p_event->type, "assistant.completed") == 0)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
801 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
802 size_t content_length = strlen(p_event->content);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
803 if (content_length > CONVERSATION_RESPONSE_MAX)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
804 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
805 p_turn->failed = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
806 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
807 p_turn->error_message,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
808 sizeof(p_turn->error_message),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
809 "Assistant response exceeded limit");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
810 char error[256];
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
811 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
812 error,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
813 sizeof(error),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
814 "{\"request_id\":\"%s\",\"code\":\"response_too_large\","
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
815 "\"message\":\"Assistant response exceeded limit\"}",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
816 p_turn->request_id);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
817 Conversation_API_Send_Event(p_turn, "turn.error", error);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
818 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
819 else
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
820 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
821 char *content = realloc(p_turn->content, content_length + 1);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
822 if (content)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
823 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
824 p_turn->content = content;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
825 p_turn->content_capacity = content_length + 1;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
826 memcpy(p_turn->content, p_event->content, content_length + 1);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
827 p_turn->content_length = content_length;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
828 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
829 else
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
830 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
831 p_turn->failed = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
832 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
833 p_turn->error_message,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
834 sizeof(p_turn->error_message),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
835 "Unable to buffer assistant response");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
836 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
837 if (!p_turn->failed)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
838 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
839 char *escaped = Dowa_JSON_Escape_String(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
840 p_event->content, content_length, p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
841 size_t capacity = escaped ? strlen(escaped) + 128 : 0;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
842 char *json = capacity
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
843 ? Dowa_Arena_Allocate(p_arena, capacity)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
844 : NULL;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
845 if (!escaped || !json)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
846 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
847 p_turn->failed = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
848 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
849 p_turn->error_message,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
850 sizeof(p_turn->error_message),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
851 "Unable to serialize assistant response");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
852 Conversation_API_Send_Event(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
853 p_turn,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
854 "turn.error",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
855 "{\"code\":\"serialize_failed\","
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
856 "\"message\":\"Unable to serialize assistant response\"}");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
857 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
858 else
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
859 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
860 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
861 json,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
862 capacity,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
863 "{\"request_id\":\"%s\",\"content\":\"%s\"}",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
864 p_turn->request_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
865 escaped);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
866 Conversation_API_Send_Event(p_turn, "assistant.completed", json);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
867 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
868 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
869 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
870 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
871 else if (strcmp(p_event->type, "assistant.usage") == 0)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
872 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
873 p_turn->input_tokens = p_event->input_tokens;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
874 p_turn->output_tokens = p_event->output_tokens;
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
875 p_turn->has_usage_event = TRUE;
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
876 char usage[256];
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
877 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
878 usage,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
879 sizeof(usage),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
880 "{\"request_id\":\"%s\",\"input_tokens\":%lld,"
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
881 "\"output_tokens\":%lld}",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
882 p_turn->request_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
883 (long long)p_turn->input_tokens,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
884 (long long)p_turn->output_tokens);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
885 Conversation_API_Send_Event(p_turn, "assistant.usage", usage);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
886 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
887 else if (strcmp(p_event->type, "turn.error") == 0)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
888 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
889 p_turn->failed = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
890 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
891 p_turn->error_message,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
892 sizeof(p_turn->error_message),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
893 "%s",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
894 p_event->error_message);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
895 char *code = Dowa_JSON_Escape_String(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
896 p_event->error_code, 0, p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
897 char *message = Dowa_JSON_Escape_String(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
898 p_event->error_message, 0, p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
899 size_t capacity = code && message
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
900 ? strlen(code) + strlen(message) + 160
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
901 : 0;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
902 char *json = capacity
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
903 ? Dowa_Arena_Allocate(p_arena, capacity)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
904 : NULL;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
905 if (!code || !message || !json)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
906 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
907 Conversation_API_Send_Event(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
908 p_turn,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
909 "turn.error",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
910 "{\"code\":\"serialize_failed\","
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
911 "\"message\":\"Unable to serialize inference error\"}");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
912 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
913 else
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
914 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
915 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
916 json,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
917 capacity,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
918 "{\"request_id\":\"%s\",\"code\":\"%s\",\"message\":\"%s\"}",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
919 p_turn->request_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
920 code,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
921 message);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
922 Conversation_API_Send_Event(p_turn, "turn.error", json);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
923 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
924 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
925 else if (strcmp(p_event->type, "turn.done") == 0)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
926 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
927 p_turn->failed = p_turn->failed || p_event->failed;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
928 p_turn->aborted = p_turn->aborted || p_event->aborted;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
929 Conversation_API_Finalize_Pending(p_turn);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
930 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
931
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
932 Dowa_Arena_Free(p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
933 pthread_mutex_unlock(&g_pending_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
934 if (should_abort)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
935 Inference_Bridge_Abort_Turn(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
936 g_inference_bridge, abort_request_id, abort_conversation_id);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
937 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
938
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
939 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
940 /* HTTP handler helpers */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
941 /* ------------------------------------------------------------------ */
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
942
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
943 static boolean Conversation_API_Append(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
944 char *output,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
945 size_t capacity,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
946 size_t *p_offset,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
947 const char *format,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
948 ...)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
949 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
950 if (*p_offset >= capacity)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
951 return FALSE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
952 va_list args;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
953 va_start(args, format);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
954 int written = vsnprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
955 output + *p_offset, capacity - *p_offset, format, args);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
956 va_end(args);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
957 if (written < 0 || (size_t)written >= capacity - *p_offset)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
958 return FALSE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
959 *p_offset += (size_t)written;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
960 return TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
961 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
962
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
963 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
964 /* GET /api/conversations?cursor=<ts>_<id>&limit=20 */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
965 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
966
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
967 static Seobeo_Request_Entry *Conversation_API_List(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
968 Seobeo_Request_Entry *p_request,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
969 Dowa_Arena *p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
970 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
971 if (!g_conversation_store)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
972 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
973 p_arena, "503", "store_unavailable", "Conversation store unavailable");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
974
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
975 Auth_Principal principal;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
976 char new_guest_cookie[CONV_GUEST_COOKIE_CAPACITY] = {0};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
977 if (!Conversation_API_Resolve(p_request, &principal, new_guest_cookie, p_arena))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
978 return Conversation_API_Error(p_arena, "500", "internal_error", "Session error");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
979 if (principal.must_change_password)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
980 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
981 p_arena, "403", "password_change_required",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
982 "Password change required", new_guest_cookie);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
983
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
984 Conversation_Owner owner;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
985 Conversation_API_Owner_From_Principal(&principal, &owner);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
986
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
987 /* Parse cursor and limit from query string */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
988 char cursor_buf[80] = {0};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
989 char limit_buf[8] = {0};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
990 Conversation_API_Query_Param(p_request, "cursor", cursor_buf, sizeof(cursor_buf));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
991 Conversation_API_Query_Param(p_request, "limit", limit_buf, sizeof(limit_buf));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
992
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
993 int64 cursor_updated_at = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
994 char cursor_id[37] = {0};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
995 if (cursor_buf[0] != '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
996 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
997 /* cursor format: <updated_at>_<uuid> */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
998 const char *underscore = strchr(cursor_buf, '_');
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
999 if (!underscore || underscore == cursor_buf ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1000 strlen(underscore + 1) != 36)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1001 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1002 p_arena, "400", "invalid_cursor", "Cursor format invalid",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1003 new_guest_cookie);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1004 char ts_part[32] = {0};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1005 size_t ts_len = (size_t)(underscore - cursor_buf);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1006 if (ts_len >= sizeof(ts_part))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1007 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1008 p_arena, "400", "invalid_cursor", "Cursor format invalid",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1009 new_guest_cookie);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1010 memcpy(ts_part, cursor_buf, ts_len);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1011 cursor_updated_at = (int64)atoll(ts_part);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1012 if (cursor_updated_at <= 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1013 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1014 p_arena, "400", "invalid_cursor", "Cursor timestamp invalid",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1015 new_guest_cookie);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1016 strncpy(cursor_id, underscore + 1, 36);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1017 cursor_id[36] = '\0';
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1018 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1019
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1020 int32 limit = 20;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1021 if (limit_buf[0] != '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1022 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1023 int parsed = atoi(limit_buf);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1024 if (parsed >= 1 && parsed <= 50)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1025 limit = parsed;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1026 else if (parsed > 50)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1027 limit = 50;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1028 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1029
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1030 Conversation_Summary *summaries = NULL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1031 int32 count = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1032 Conversation_Store_Result result = Conversation_Store_List(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1033 g_conversation_store, &owner,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1034 cursor_updated_at, cursor_id[0] ? cursor_id : NULL,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1035 limit, &summaries, &count, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1036 if (result != CONVERSATION_STORE_OK)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1037 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1038 p_arena, "500", "list_failed", "Unable to list conversations",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1039 new_guest_cookie);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1040
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1041 /* Estimate response size */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1042 size_t capacity = 128;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1043 for (int32 i = 0; i < count; i++)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1044 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1045 Conversation_Summary *s = &summaries[i];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1046 capacity += (s->title ? strlen(s->title) : 0) * 6 +
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1047 (s->last_message_preview ? strlen(s->last_message_preview) : 0) * 6 +
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1048 256;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1049 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1050 char *body = Dowa_Arena_Allocate(p_arena, capacity);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1051 if (!body)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1052 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1053 p_arena, "500", "serialize_failed", "Response exceeds memory limit",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1054 new_guest_cookie);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1055
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1056 size_t offset = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1057 if (!Conversation_API_Append(body, capacity, &offset,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1058 "{\"conversations\":["))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1059 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1060 p_arena, "500", "serialize_failed", "Response too large",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1061 new_guest_cookie);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1062
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1063 for (int32 i = 0; i < count; i++)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1064 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1065 Conversation_Summary *s = &summaries[i];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1066 char *esc_title = Dowa_JSON_Escape_String(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1067 s->title ? s->title : "", 0, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1068 char *esc_preview = Dowa_JSON_Escape_String(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1069 s->last_message_preview ? s->last_message_preview : "", 0, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1070 if (!Conversation_API_Append(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1071 body, capacity, &offset,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1072 "%s{\"id\":\"%s\",\"title\":\"%s\",\"status\":\"%s\","
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1073 "\"created_at\":%lld,\"updated_at\":%lld,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1074 "\"turn_count\":%lld,\"last_message_preview\":\"%s\"}",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1075 i == 0 ? "" : ",",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1076 s->id ? s->id : "",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1077 esc_title ? esc_title : "",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1078 s->status ? s->status : "",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1079 (long long)s->created_at,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1080 (long long)s->updated_at,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1081 (long long)s->turn_count,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1082 esc_preview ? esc_preview : ""))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1083 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1084 p_arena, "500", "serialize_failed", "Response too large",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1085 new_guest_cookie);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1086 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1087
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1088 /* Next cursor: last item's (updated_at, id) */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1089 char cursor_out[80] = "null";
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1090 if (count == limit && count > 0)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1091 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1092 Conversation_Summary *last = &summaries[count - 1];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1093 if (last->id)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1094 snprintf(cursor_out, sizeof(cursor_out), "\"%lld_%s\"",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1095 (long long)last->updated_at, last->id);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1096 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1097 if (!Conversation_API_Append(body, capacity, &offset,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1098 "],\"cursor\":%s}", cursor_out))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1099 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1100 p_arena, "500", "serialize_failed", "Response too large",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1101 new_guest_cookie);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1102
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1103 return Conversation_API_JSON_Response_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1104 p_arena, "200", body, new_guest_cookie);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1105 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1106
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1107 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1108 /* POST /api/conversations */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1109 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1110
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1111 static Seobeo_Request_Entry *Conversation_API_Create(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1112 Seobeo_Request_Entry *p_request,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1113 Dowa_Arena *p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1114 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1115 if (!g_conversation_store)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1116 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1117 p_arena, "503", "store_unavailable", "Conversation store unavailable");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1118
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1119 Auth_Principal principal;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1120 boolean found = FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1121 if (!Conversation_API_Resolve_Existing(p_request, &principal, p_arena, &found))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1122 return Conversation_API_Error(p_arena, "500", "internal_error", "Session error");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1123 if (!found)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1124 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1125 p_arena, "401", "auth_required", "Bootstrap session first");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1126 if (principal.must_change_password)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1127 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1128 p_arena, "403", "password_change_required",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1129 "Password change required");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1130 if (!Auth_API_Verify_CSRF(p_request, &principal))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1131 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1132 p_arena, "403", "csrf_invalid", "Same-origin and CSRF token required");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1133
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1134 Conversation_Owner owner;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1135 Conversation_API_Owner_From_Principal(&principal, &owner);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1136
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1137 const char *title = "";
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1138 const char *body = Conversation_API_Request_Value(p_request, "Body");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1139 if (body && body[0] != '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1140 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1141 Dowa_JSON_Entry *object = Conversation_API_Parse_Body(p_request, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1142 if (!object)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1143 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1144 p_arena, "400", "invalid_json", "Request body must be a JSON object");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1145 char *parsed_title = Dowa_JSON_Get_String(object, "title");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1146 if (parsed_title)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1147 title = parsed_title;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1148 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1149 if (strlen(title) > CONVERSATION_TITLE_MAX)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1150 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1151 p_arena, "400", "invalid_title", "Title exceeds 200 bytes");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1152
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1153 char conversation_id[37];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1154 if (Conversation_Store_Create_Owned(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1155 g_conversation_store, title, &owner,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1156 conversation_id) != CONVERSATION_STORE_OK)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1157 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1158 p_arena, "500", "create_failed", "Unable to create conversation");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1159
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1160 char *response_body = Dowa_Arena_Allocate(p_arena, 64);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1161 snprintf(response_body, 64, "{\"id\":\"%s\"}", conversation_id);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1162 return Conversation_API_JSON_Response(p_arena, "201", response_body);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1163 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1164
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1165 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1166 /* GET /api/conversations/:conversation_id */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1167 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1168
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1169 static Seobeo_Request_Entry *Conversation_API_Get(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1170 Seobeo_Request_Entry *p_request,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1171 Dowa_Arena *p_arena)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1172 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1173 if (!g_conversation_store)
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1174 return Conversation_API_Error(
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1175 p_arena, "503", "store_unavailable", "Conversation store unavailable");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1176
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1177 Auth_Principal principal;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1178 char new_guest_cookie[CONV_GUEST_COOKIE_CAPACITY] = {0};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1179 if (!Conversation_API_Resolve(p_request, &principal, new_guest_cookie, p_arena))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1180 return Conversation_API_Error(p_arena, "500", "internal_error", "Session error");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1181 if (principal.must_change_password)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1182 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1183 p_arena, "403", "password_change_required",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1184 "Password change required", new_guest_cookie);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1185
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1186 Conversation_Owner owner;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1187 Conversation_API_Owner_From_Principal(&principal, &owner);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1188
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1189 const char *conversation_id =
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1190 Conversation_API_Request_Value(p_request, ":conversation_id");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1191 if (!conversation_id)
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1192 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1193 p_arena, "400", "missing_id", "Conversation ID is required",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1194 new_guest_cookie);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1195
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1196 Conversation_Record record;
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1197 Conversation_Store_Result result = Conversation_Store_Get_Owned(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1198 g_conversation_store, conversation_id, &owner, &record, p_arena);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1199 if (result == CONVERSATION_STORE_NOT_FOUND)
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1200 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1201 p_arena, "404", "not_found", "Conversation not found",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1202 new_guest_cookie);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1203 if (result != CONVERSATION_STORE_OK)
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1204 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1205 p_arena, "500", "load_failed", "Unable to load conversation",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1206 new_guest_cookie);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1207
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1208 if (!record.id || !record.title || !record.status)
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1209 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1210 p_arena, "500", "load_failed", "Conversation data exceeded limits",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1211 new_guest_cookie);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1212 size_t history_size = strlen(record.title) + strlen(record.status);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1213 for (size_t i = 0; i < Dowa_Array_Length(record.turns); i++)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1214 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1215 Conversation_Turn *p_turn = &record.turns[i];
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1216 if (!p_turn->role || !p_turn->content || !p_turn->status ||
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1217 !p_turn->request_id || !p_turn->error_message)
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1218 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1219 p_arena, "500", "load_failed", "Conversation data exceeded limits",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1220 new_guest_cookie);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1221 history_size +=
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1222 strlen(p_turn->role) + strlen(p_turn->content) +
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1223 strlen(p_turn->status) + strlen(p_turn->request_id) +
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1224 strlen(p_turn->error_message);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1225 if (history_size > CONVERSATION_HISTORY_MAX)
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1226 return Conversation_API_Error_With_Cookie(
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1227 p_arena,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1228 "413",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1229 "history_too_large",
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1230 "Conversation history exceeds response limit",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1231 new_guest_cookie);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1232 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1233 char *escaped_title = Dowa_JSON_Escape_String(record.title, 0, p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1234 if (!escaped_title)
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1235 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1236 p_arena, "500", "serialize_failed", "Unable to serialize conversation",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1237 new_guest_cookie);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1238 size_t capacity = strlen(escaped_title) + 512;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1239 for (size_t i = 0; i < Dowa_Array_Length(record.turns); i++)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1240 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1241 Conversation_Turn *p_turn = &record.turns[i];
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1242 capacity +=
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1243 (strlen(p_turn->role) + strlen(p_turn->content) +
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1244 strlen(p_turn->status) + strlen(p_turn->request_id) +
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1245 strlen(p_turn->error_message)) * 6 + 320;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1246 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1247 char *body = Dowa_Arena_Allocate(p_arena, capacity);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1248 if (!body)
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1249 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1250 p_arena, "500", "serialize_failed", "Response exceeds memory limit",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1251 new_guest_cookie);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1252 size_t offset = 0;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1253 if (!Conversation_API_Append(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1254 body,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1255 capacity,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1256 &offset,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1257 "{\"id\":\"%s\",\"title\":\"%s\",\"status\":\"%s\","
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1258 "\"created_at\":%lld,\"updated_at\":%lld,\"turns\":[",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1259 record.id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1260 escaped_title,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1261 record.status,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1262 (long long)record.created_at,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1263 (long long)record.updated_at))
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1264 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1265 p_arena, "500", "serialize_failed", "Response too large",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1266 new_guest_cookie);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1267
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1268 for (size_t i = 0; i < Dowa_Array_Length(record.turns); i++)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1269 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1270 Conversation_Turn *p_turn = &record.turns[i];
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1271 char *role = Dowa_JSON_Escape_String(p_turn->role, 0, p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1272 char *content = Dowa_JSON_Escape_String(p_turn->content, 0, p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1273 char *status = Dowa_JSON_Escape_String(p_turn->status, 0, p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1274 char *request_id = Dowa_JSON_Escape_String(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1275 p_turn->request_id, 0, p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1276 char *error = Dowa_JSON_Escape_String(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1277 p_turn->error_message, 0, p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1278 if (!Conversation_API_Append(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1279 body,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1280 capacity,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1281 &offset,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1282 "%s{\"id\":%lld,\"sequence\":%lld,\"role\":\"%s\","
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1283 "\"content\":\"%s\",\"status\":\"%s\","
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1284 "\"request_id\":\"%s\",\"error\":\"%s\","
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1285 "\"input_tokens\":%lld,\"output_tokens\":%lld,"
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1286 "\"created_at\":%lld,\"completed_at\":%lld}",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1287 i == 0 ? "" : ",",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1288 (long long)p_turn->id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1289 (long long)p_turn->sequence,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1290 role,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1291 content,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1292 status,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1293 request_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1294 error,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1295 (long long)p_turn->input_tokens,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1296 (long long)p_turn->output_tokens,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1297 (long long)p_turn->created_at,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1298 (long long)p_turn->completed_at))
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1299 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1300 p_arena, "500", "serialize_failed", "Response too large",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1301 new_guest_cookie);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1302 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1303 if (!Conversation_API_Append(body, capacity, &offset, "]}"))
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1304 return Conversation_API_Error_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1305 p_arena, "500", "serialize_failed", "Response too large",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1306 new_guest_cookie);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1307 return Conversation_API_JSON_Response_With_Cookie(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1308 p_arena, "200", body, new_guest_cookie);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1309 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1310
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1311 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1312 /* PATCH /api/conversations/:conversation_id */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1313 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1314
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1315 static Seobeo_Request_Entry *Conversation_API_Update(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1316 Seobeo_Request_Entry *p_request,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1317 Dowa_Arena *p_arena)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1318 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1319 if (!g_conversation_store)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1320 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1321 p_arena, "503", "store_unavailable", "Conversation store unavailable");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1322
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1323 Auth_Principal principal;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1324 boolean found = FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1325 if (!Conversation_API_Resolve_Existing(p_request, &principal, p_arena, &found))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1326 return Conversation_API_Error(p_arena, "500", "internal_error", "Session error");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1327 if (!found)
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1328 return Conversation_API_Error(
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1329 p_arena, "401", "auth_required", "Bootstrap session first");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1330 if (principal.must_change_password)
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1331 return Conversation_API_Error(
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1332 p_arena, "403", "password_change_required",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1333 "Password change required");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1334 if (!Auth_API_Verify_CSRF(p_request, &principal))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1335 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1336 p_arena, "403", "csrf_invalid", "Same-origin and CSRF token required");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1337
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1338 Conversation_Owner owner;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1339 Conversation_API_Owner_From_Principal(&principal, &owner);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1340
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1341 const char *conversation_id =
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1342 Conversation_API_Request_Value(p_request, ":conversation_id");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1343 Dowa_JSON_Entry *object = Conversation_API_Parse_Body(p_request, p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1344 char *title = object ? Dowa_JSON_Get_String(object, "title") : NULL;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1345 if (!conversation_id || !title)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1346 return Conversation_API_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1347 p_arena, "400", "invalid_request", "Conversation ID and title required");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1348 if (strlen(title) > CONVERSATION_TITLE_MAX)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1349 return Conversation_API_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1350 p_arena, "400", "invalid_title", "Title exceeds 200 bytes");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1351
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1352 Conversation_Store_Result result = Conversation_Store_Update_Title_Owned(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1353 g_conversation_store, conversation_id, &owner, title);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1354 if (result == CONVERSATION_STORE_NOT_FOUND)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1355 return Conversation_API_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1356 p_arena, "404", "not_found", "Conversation not found");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1357 if (result != CONVERSATION_STORE_OK)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1358 return Conversation_API_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1359 p_arena, "500", "update_failed", "Unable to update conversation");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1360 return Conversation_API_JSON_Response(p_arena, "200", "{\"ok\":true}");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1361 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1362
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1363 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1364 /* DELETE /api/conversations/:conversation_id */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1365 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1366
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1367 static Seobeo_Request_Entry *Conversation_API_Delete(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1368 Seobeo_Request_Entry *p_request,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1369 Dowa_Arena *p_arena)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1370 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1371 if (!g_conversation_store)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1372 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1373 p_arena, "503", "store_unavailable", "Conversation store unavailable");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1374
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1375 Auth_Principal principal;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1376 boolean found = FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1377 if (!Conversation_API_Resolve_Existing(p_request, &principal, p_arena, &found))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1378 return Conversation_API_Error(p_arena, "500", "internal_error", "Session error");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1379 if (!found)
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1380 return Conversation_API_Error(
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1381 p_arena, "401", "auth_required", "Bootstrap session first");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1382 if (principal.must_change_password)
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1383 return Conversation_API_Error(
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1384 p_arena, "403", "password_change_required",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1385 "Password change required");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1386 if (!Auth_API_Verify_CSRF(p_request, &principal))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1387 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1388 p_arena, "403", "csrf_invalid", "Same-origin and CSRF token required");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1389
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1390 Conversation_Owner owner;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1391 Conversation_API_Owner_From_Principal(&principal, &owner);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1392
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1393 const char *conversation_id =
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1394 Conversation_API_Request_Value(p_request, ":conversation_id");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1395 if (!conversation_id)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1396 return Conversation_API_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1397 p_arena, "400", "missing_id", "Conversation ID is required");
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1398
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1399 Conversation_Store_Result result = Conversation_Store_Delete_Owned(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1400 g_conversation_store, conversation_id, &owner);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1401 if (result == CONVERSATION_STORE_NOT_FOUND)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1402 return Conversation_API_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1403 p_arena, "404", "not_found", "Conversation not found");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1404 if (result != CONVERSATION_STORE_OK)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1405 return Conversation_API_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1406 p_arena, "500", "delete_failed", "Unable to delete conversation");
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1407
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1408 if (Inference_Bridge_Is_Ready(g_inference_bridge))
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1409 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1410 char request_id[37];
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1411 if (Conversation_Store_Generate_UUID(request_id))
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1412 Inference_Bridge_Delete_Conversation(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1413 g_inference_bridge, request_id, conversation_id);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1414 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1415
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1416 Seobeo_Request_Entry *p_response = NULL;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1417 Dowa_HashMap_Push_Arena(p_response, "status", "204", p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1418 Dowa_HashMap_Push_Arena(p_response, "body", "", p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1419 return p_response;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1420 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1421
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1422 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1423 /* POST /api/conversations/claim (body: {"conversationId":"<uuid>"}) */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1424 /* ID stays in request body — never appears in URL or request log. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1425 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1426
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1427 static Seobeo_Request_Entry *Conversation_API_Claim_Body(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1428 Seobeo_Request_Entry *p_request,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1429 Dowa_Arena *p_arena)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1430 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1431 if (!g_conversation_store)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1432 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1433 p_arena, "503", "store_unavailable", "Conversation store unavailable");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1434
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1435 Auth_Principal principal;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1436 boolean found = FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1437 if (!Conversation_API_Resolve_Existing(p_request, &principal, p_arena, &found))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1438 return Conversation_API_Error(p_arena, "500", "internal_error", "Session error");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1439 if (!found)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1440 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1441 p_arena, "401", "auth_required", "Bootstrap session first");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1442 /* Guests may not claim; forced-password-change users blocked */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1443 if (principal.kind != AUTH_PRINCIPAL_USER)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1444 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1445 p_arena, "403", "forbidden", "Must be authenticated to claim");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1446 if (principal.must_change_password)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1447 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1448 p_arena, "403", "password_change_required",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1449 "Password change required");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1450 if (!Auth_API_Verify_CSRF(p_request, &principal))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1451 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1452 p_arena, "403", "csrf_invalid", "Same-origin and CSRF token required");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1453
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1454 Dowa_JSON_Entry *object = Conversation_API_Parse_Body(p_request, p_arena);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1455 if (!object)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1456 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1457 p_arena, "400", "invalid_json", "Request body must be a JSON object");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1458 const char *conversation_id = Dowa_JSON_Get_String(object, "conversationId");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1459 if (!conversation_id || conversation_id[0] == '\0')
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1460 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1461 p_arena, "400", "missing_id", "conversationId is required");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1462 if (strlen(conversation_id) > 36)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1463 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1464 p_arena, "400", "invalid_id", "conversationId is invalid");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1465
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1466 Conversation_Store_Result result = Conversation_Store_Claim_Legacy(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1467 g_conversation_store, conversation_id, principal.user_id);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1468 if (result == CONVERSATION_STORE_NOT_FOUND)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1469 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1470 p_arena, "404", "not_found", "Conversation not found");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1471 if (result == CONVERSATION_STORE_CONFLICT)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1472 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1473 p_arena, "409", "already_owned", "Conversation is already owned");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1474 if (result != CONVERSATION_STORE_OK)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1475 return Conversation_API_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1476 p_arena, "500", "claim_failed", "Unable to claim conversation");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1477
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1478 return Conversation_API_JSON_Response(p_arena, "200", "{\"ok\":true}");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1479 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1480
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1481 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1482 /* GET /api/inference/health */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1483 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1484
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1485 static Seobeo_Request_Entry *Conversation_API_Health(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1486 Seobeo_Request_Entry *p_request,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1487 Dowa_Arena *p_arena)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1488 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1489 (void)p_request;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1490 boolean ready =
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1491 Conversation_API_Is_Inference_Ready() &&
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1492 g_conversation_store &&
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1493 Inference_Bridge_Is_Ready(g_inference_bridge);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1494 return Conversation_API_JSON_Response(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1495 p_arena,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1496 ready ? "200" : "503",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1497 ready ? "{\"status\":\"ready\"}" : "{\"status\":\"unavailable\"}");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1498 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1499
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1500 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1501 /* POST /api/conversations/:conversation_id/turns (streaming) */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1502 /* ------------------------------------------------------------------ */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1503
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1504 /*
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1505 * SSE client-disconnect callback.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1506 * Called by Seobeo_SSE_Server_Detach_Handle after g_sse_mutex is released.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1507 * Finds the pending turn for the disconnected stream and finalizes it once.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1508 * Must NOT hold g_sse_mutex when called; acquires g_pending_mutex.
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1509 */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1510 static void Conversation_API_On_SSE_Detach(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1511 Seobeo_SSE_Stream *p_stream,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1512 void *ctx)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1513 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1514 (void)ctx;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1515 pthread_mutex_lock(&g_pending_mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1516 for (Pending_Turn *p_turn = g_pending_turns;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1517 p_turn;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1518 p_turn = p_turn->p_next)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1519 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1520 if (p_turn->p_stream == p_stream && !p_turn->finalized)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1521 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1522 p_turn->aborted = TRUE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1523 snprintf(p_turn->error_message, sizeof(p_turn->error_message),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1524 "Client disconnected");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1525 Conversation_API_Finalize_Pending(p_turn);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1526 break;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1527 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1528 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1529 pthread_mutex_unlock(&g_pending_mutex);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1530 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1531
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1532 static void Conversation_API_Turn_Stream(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1533 Seobeo_Handle *p_handle,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1534 Seobeo_Request_Entry *p_request,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1535 Dowa_Arena *p_arena)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1536 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1537 /* Resolve existing identity first so we can apply controls per-principal. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1538 Auth_Principal principal;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1539 boolean found = FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1540 if (!Conversation_API_Resolve_Existing(p_request, &principal, p_arena, &found))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1541 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1542 Conversation_API_Send_Stream_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1543 p_handle, 500, "internal_error", "Session error");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1544 return;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1545 }
265
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1546 Inference_Prompt_Profile prompt_profile;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1547 if (!Conversation_API_Prompt_Profile_From_Principal(
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1548 &principal, &prompt_profile))
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1549 {
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1550 Conversation_API_Send_Stream_Error(
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1551 p_handle, 403, "invalid_role", "Conversation role is not supported");
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1552 return;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1553 }
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1554 if (!found)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1555 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1556 Conversation_API_Send_Stream_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1557 p_handle, 401, "auth_required", "Bootstrap session first");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1558 return;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1559 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1560 if (principal.must_change_password)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1561 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1562 Conversation_API_Send_Stream_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1563 p_handle, 403, "password_change_required",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1564 "Password change required");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1565 return;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1566 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1567 if (!Auth_API_Verify_CSRF(p_request, &principal))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1568 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1569 Conversation_API_Send_Stream_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1570 p_handle, 403, "csrf_invalid", "Same-origin and CSRF token required");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1571 return;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1572 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1573
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1574 /* Guests require inference to be explicitly enabled; authenticated users
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1575 * always proceed subject to the global bridge-ready check below. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1576 if (principal.kind == AUTH_PRINCIPAL_GUEST &&
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1577 !Conversation_API_Is_Inference_Ready())
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1578 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1579 Conversation_API_Send_Stream_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1580 p_handle, 503, "inference_disabled", "Inference API is disabled");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1581 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1582 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1583 if (!g_conversation_store || !Inference_Bridge_Is_Ready(g_inference_bridge))
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1584 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1585 Conversation_API_Send_Stream_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1586 p_handle, 503, "inference_unavailable", "Inference runtime unavailable");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1587 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1588 }
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1589
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1590 /* Map principal to owner — copy IDs before arena may expire (req 8) */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1591 Conversation_Owner owner;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1592 Conversation_API_Owner_From_Principal(&principal, &owner);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1593
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1594 const char *conversation_id =
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1595 Conversation_API_Request_Value(p_request, ":conversation_id");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1596 Dowa_JSON_Entry *object = Conversation_API_Parse_Body(p_request, p_arena);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1597 char *prompt = object ? Dowa_JSON_Get_String(object, "prompt") : NULL;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1598 if (!conversation_id || !prompt || prompt[0] == '\0')
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1599 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1600 Conversation_API_Send_Stream_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1601 p_handle, 400, "invalid_request", "Conversation ID and prompt required");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1602 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1603 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1604 size_t prompt_length = strlen(prompt);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1605 if (prompt_length > CONVERSATION_PROMPT_MAX)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1606 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1607 Conversation_API_Send_Stream_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1608 p_handle, 413, "prompt_too_large", "Prompt exceeds 32 KiB");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1609 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1610 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1611 if (!Conversation_API_Acquire_Turn_Slot())
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1612 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1613 /* Temporary capacity limit — advise client to retry in 5 s. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1614 static const char rate_body[] =
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1615 "{\"error\":{\"code\":\"rate_limited\","
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1616 "\"message\":\"Inference capacity exhausted\"}}";
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1617 char rate_header[512];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1618 snprintf(rate_header, sizeof(rate_header),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1619 "HTTP/1.1 429 Too Many Requests\r\n"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1620 "Content-Type: application/json; charset=utf-8\r\n"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1621 "Content-Length: %zu\r\n"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1622 "Retry-After: 5\r\n"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1623 "Connection: close\r\n"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1624 "\r\n",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1625 sizeof(rate_body) - 1);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1626 Seobeo_Handle_Queue(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1627 p_handle, (const uint8 *)rate_header, (uint32)strlen(rate_header));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1628 Seobeo_Handle_Queue(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1629 p_handle, (const uint8 *)rate_body,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1630 (uint32)(sizeof(rate_body) - 1));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1631 Seobeo_Handle_Flush(p_handle);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1632 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1633 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1634
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1635 char request_id[37];
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1636 if (!Conversation_Store_Generate_UUID(request_id))
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1637 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1638 Conversation_API_Release_Turn_Slot();
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1639 Conversation_API_Send_Stream_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1640 p_handle, 500, "id_failed", "Unable to create request ID");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1641 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1642 }
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1643
265
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1644 /* --- Load owner-verified conversation record for transcript history --- */
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1645 /* Done before quota reservation: if the conversation is missing or
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1646 * not owned by this principal we fail fast with no quota side-effects. */
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1647 Conversation_Record hist_record;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1648 memset(&hist_record, 0, sizeof(hist_record));
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1649 {
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1650 Conversation_Store_Result hist_result = Conversation_Store_Get_Owned(
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1651 g_conversation_store, conversation_id, &owner, &hist_record, p_arena);
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1652 if (hist_result == CONVERSATION_STORE_NOT_FOUND)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1653 {
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1654 Conversation_API_Release_Turn_Slot();
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1655 Conversation_API_Send_Stream_Error(
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1656 p_handle, 404, "not_found", "Conversation not found");
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1657 return;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1658 }
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1659 if (hist_result != CONVERSATION_STORE_OK)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1660 {
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1661 Conversation_API_Release_Turn_Slot();
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1662 Conversation_API_Send_Stream_Error(
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1663 p_handle, 500, "history_load_failed", "Unable to load conversation");
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1664 return;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1665 }
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1666 }
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1667
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1668 /* Build bounded history: last ≤20 qualifying turns from the persisted
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1669 * record. Include non-empty user turns and completed, non-empty assistant
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1670 * turns only. The new prompt is not yet part of history. */
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1671 Inference_Bridge_History_Message hist_msgs[INFERENCE_BRIDGE_HISTORY_MAX];
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1672 uint32 hist_count = 0;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1673 {
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1674 /* Collect qualifying turn indices in a sliding window of HIST_MAX. */
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1675 size_t qidx[INFERENCE_BRIDGE_HISTORY_MAX];
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1676 uint32 qcount = 0;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1677 size_t num_turns = Dowa_Array_Length(hist_record.turns);
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1678 for (size_t ti = 0; ti < num_turns; ti++)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1679 {
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1680 Conversation_Turn *t = &hist_record.turns[ti];
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1681 if (!t->role || !t->content || !t->status)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1682 continue;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1683 boolean is_user = strcmp(t->role, "user") == 0;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1684 boolean is_asst = strcmp(t->role, "assistant") == 0;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1685 if (!is_user && !is_asst)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1686 continue;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1687 if (t->content[0] == '\0')
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1688 continue;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1689 if (is_asst && strcmp(t->status, "complete") != 0)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1690 continue;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1691 if (qcount < INFERENCE_BRIDGE_HISTORY_MAX)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1692 qidx[qcount++] = ti;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1693 else
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1694 {
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1695 /* Shift window left to keep the most-recent HIST_MAX entries. */
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1696 for (uint32 k = 0; k + 1 < INFERENCE_BRIDGE_HISTORY_MAX; k++)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1697 qidx[k] = qidx[k + 1];
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1698 qidx[INFERENCE_BRIDGE_HISTORY_MAX - 1] = ti;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1699 }
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1700 }
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1701 hist_count = qcount;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1702 for (uint32 i = 0; i < hist_count; i++)
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1703 {
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1704 /* Strings are in p_arena; they live through the synchronous bridge write. */
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1705 hist_msgs[i].role = hist_record.turns[qidx[i]].role;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1706 hist_msgs[i].content = hist_record.turns[qidx[i]].content;
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1707 }
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1708 }
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1709
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1710 /* --- Guest quota reservation (before persisting turn) --- */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1711 boolean is_guest_reserved = FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1712 char quota_guest_id[37] = {0};
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1713 if (principal.kind == AUTH_PRINCIPAL_GUEST)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1714 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1715 Auth_Store *p_auth_store = Auth_API_Get_Store();
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1716 if (!p_auth_store)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1717 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1718 Conversation_API_Release_Turn_Slot();
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1719 Conversation_API_Send_Stream_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1720 p_handle, 503, "store_unavailable", "Auth store unavailable");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1721 return;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1722 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1723
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1724 int64 now_unix = (int64)time(NULL);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1725 int64 window_start = conv__utc_window_start(now_unix);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1726 int64 resets_at = window_start + 86400LL;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1727
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1728 Auth_Store_Guest_Quota_Result quota_result = Auth_Store_Guest_Reserve(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1729 p_auth_store,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1730 principal.guest_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1731 request_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1732 window_start,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1733 g_guest_request_output_tokens,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1734 g_guest_daily_turns,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1735 g_guest_daily_output_tokens,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1736 now_unix + 3600);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1737
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1738 if (quota_result == AUTH_STORE_GUEST_QUOTA_TURNS_EXHAUSTED ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1739 quota_result == AUTH_STORE_GUEST_QUOTA_TOKENS_EXHAUSTED)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1740 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1741 /* Fetch current usage for 429 payload. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1742 Auth_Store_Guest_Usage usage;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1743 memset(&usage, 0, sizeof(usage));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1744 Auth_Store_Guest_Get_Usage(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1745 p_auth_store, principal.guest_id, window_start, &usage);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1746
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1747 int64 turns_remaining =
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1748 g_guest_daily_turns - usage.turns_used;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1749 if (turns_remaining < 0) turns_remaining = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1750 int64 tokens_remaining =
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1751 g_guest_daily_output_tokens
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1752 - usage.output_tokens_used
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1753 - usage.output_tokens_reserved;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1754 if (tokens_remaining < 0) tokens_remaining = 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1755
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1756 const char *code = (quota_result == AUTH_STORE_GUEST_QUOTA_TURNS_EXHAUSTED)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1757 ? "guest_quota_turns_exhausted"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1758 : "guest_quota_tokens_exhausted";
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1759 const char *message = (quota_result == AUTH_STORE_GUEST_QUOTA_TURNS_EXHAUSTED)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1760 ? "Daily turn limit reached"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1761 : "Daily output token limit reached";
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1762
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1763 char quota_body[1024];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1764 int qlen = snprintf(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1765 quota_body, sizeof(quota_body),
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1766 "{\"error\":{\"code\":\"%s\",\"message\":\"%s\","
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1767 "\"quota\":{\"turnsLimit\":%lld,\"turnsUsed\":%lld,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1768 "\"turnsRemaining\":%lld,\"outputTokensLimit\":%lld,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1769 "\"outputTokensUsed\":%lld,\"outputTokensReserved\":%lld,"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1770 "\"outputTokensRemaining\":%lld,\"resetsAt\":%lld}}}",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1771 code, message,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1772 (long long)g_guest_daily_turns,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1773 (long long)usage.turns_used,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1774 (long long)turns_remaining,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1775 (long long)g_guest_daily_output_tokens,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1776 (long long)usage.output_tokens_used,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1777 (long long)usage.output_tokens_reserved,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1778 (long long)tokens_remaining,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1779 (long long)resets_at);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1780 if (qlen <= 0 || (size_t)qlen >= sizeof(quota_body))
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1781 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1782 Conversation_API_Release_Turn_Slot();
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1783 Conversation_API_Send_Stream_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1784 p_handle, 429, code, message);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1785 return;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1786 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1787 char header[512];
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1788 Seobeo_Web_Header_Generate(header, 429,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1789 "application/json; charset=utf-8", qlen);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1790 Seobeo_Handle_Queue(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1791 p_handle, (const uint8 *)header, (uint32)strlen(header));
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1792 Seobeo_Handle_Queue(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1793 p_handle, (const uint8 *)quota_body, (uint32)qlen);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1794 Seobeo_Handle_Flush(p_handle);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1795 Conversation_API_Release_Turn_Slot();
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1796 return;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1797 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1798 if (quota_result != AUTH_STORE_GUEST_QUOTA_OK)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1799 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1800 Conversation_API_Release_Turn_Slot();
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1801 Conversation_API_Send_Stream_Error(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1802 p_handle, 500, "quota_error", "Unable to check guest quota");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1803 return;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1804 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1805 is_guest_reserved = TRUE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1806 snprintf(quota_guest_id, sizeof(quota_guest_id), "%s",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1807 principal.guest_id);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1808 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1809
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1810 Conversation_Store_Result result = Conversation_Store_Begin_Turn_Owned(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1811 g_conversation_store, conversation_id, &owner, request_id, prompt);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1812 if (result == CONVERSATION_STORE_NOT_FOUND)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1813 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1814 if (is_guest_reserved)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1815 Auth_Store_Guest_Release(Auth_API_Get_Store(), request_id);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1816 Conversation_API_Release_Turn_Slot();
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1817 Conversation_API_Send_Stream_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1818 p_handle, 404, "not_found", "Conversation not found");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1819 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1820 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1821 if (result == CONVERSATION_STORE_CONFLICT)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1822 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1823 if (is_guest_reserved)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1824 Auth_Store_Guest_Release(Auth_API_Get_Store(), request_id);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1825 Conversation_API_Release_Turn_Slot();
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1826 Conversation_API_Send_Stream_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1827 p_handle, 409, "turn_in_progress", "Conversation already has an active turn");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1828 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1829 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1830 if (result != CONVERSATION_STORE_OK)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1831 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1832 if (is_guest_reserved)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1833 Auth_Store_Guest_Release(Auth_API_Get_Store(), request_id);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1834 Conversation_API_Release_Turn_Slot();
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1835 Conversation_API_Send_Stream_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1836 p_handle, 500, "turn_failed", "Unable to persist turn");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1837 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1838 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1839
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1840 Seobeo_SSE_Stream *p_stream = Seobeo_SSE_Server_Attach(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1841 p_handle,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1842 "/api/conversations/turns");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1843 if (!p_stream || !Seobeo_SSE_Retain(p_stream))
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1844 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1845 if (is_guest_reserved)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1846 Auth_Store_Guest_Release(Auth_API_Get_Store(), request_id);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1847 Conversation_API_Release_Turn_Slot();
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1848 Conversation_Store_Fail_Turn(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1849 g_conversation_store,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1850 conversation_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1851 request_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1852 "Unable to start event stream",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1853 FALSE);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1854 if (!p_stream)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1855 Conversation_API_Send_Stream_Error(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1856 p_handle, 500, "stream_failed", "Unable to start event stream");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1857 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1858 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1859
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1860 Pending_Turn *p_turn = calloc(1, sizeof(*p_turn));
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1861 if (!p_turn)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1862 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1863 if (is_guest_reserved)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1864 Auth_Store_Guest_Release(Auth_API_Get_Store(), request_id);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1865 Conversation_API_Release_Turn_Slot();
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1866 Conversation_Store_Fail_Turn(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1867 g_conversation_store,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1868 conversation_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1869 request_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1870 "Unable to allocate turn",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1871 FALSE);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1872 Seobeo_SSE_Send_Data(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1873 p_stream,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1874 "{\"error\":{\"code\":\"allocation_failed\"}}");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1875 Seobeo_SSE_Close(p_stream);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1876 Seobeo_SSE_Release(p_stream);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1877 return;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1878 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1879 snprintf(p_turn->request_id, sizeof(p_turn->request_id), "%s", request_id);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1880 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1881 p_turn->conversation_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1882 sizeof(p_turn->conversation_id),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1883 "%s",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1884 conversation_id);
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1885 /* Copy owner and quota fields before arena expires (req 8) */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1886 p_turn->owner = owner;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1887 p_turn->is_guest_reserved = is_guest_reserved;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1888 p_turn->reserved_output_tokens =
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1889 is_guest_reserved ? g_guest_request_output_tokens : 0;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1890 snprintf(p_turn->guest_id, sizeof(p_turn->guest_id), "%s", quota_guest_id);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1891 p_turn->p_stream = p_stream;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1892
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1893 /* Register detach callback so client disconnect triggers finalization. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1894 Seobeo_SSE_Set_Detach_Callback(p_stream, Conversation_API_On_SSE_Detach, NULL);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1895
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1896 pthread_mutex_lock(&g_pending_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1897 p_turn->p_next = g_pending_turns;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1898 g_pending_turns = p_turn;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1899 pthread_mutex_unlock(&g_pending_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1900
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1901 if (!Inference_Bridge_Start_Turn(
265
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1902 g_inference_bridge,
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1903 request_id,
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1904 conversation_id,
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1905 prompt,
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1906 prompt_profile,
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1907 CONVERSATION_PROMPT_VERSION,
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1908 CONVERSATION_KNOWLEDGE_VERSION,
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1909 hist_msgs,
056790c4fb0d add role-aware Epi assistant prompts
MrJuneJune <me@mrjunejune.com>
parents: 264
diff changeset
1910 hist_count))
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1911 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1912 pthread_mutex_lock(&g_pending_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1913 Pending_Turn *p_pending = Conversation_API_Find_Pending(request_id);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1914 if (p_pending)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1915 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1916 p_pending->failed = TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1917 snprintf(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1918 p_pending->error_message,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1919 sizeof(p_pending->error_message),
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1920 "Unable to dispatch inference turn");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1921 Conversation_API_Send_Event(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1922 p_pending,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1923 "turn.error",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1924 "{\"code\":\"dispatch_failed\","
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1925 "\"message\":\"Unable to dispatch inference turn\"}");
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1926 Conversation_API_Finalize_Pending(p_pending);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1927 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1928 pthread_mutex_unlock(&g_pending_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1929 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1930 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1931
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1932 boolean Conversation_API_Init(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1933 const char *database_path,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1934 const Conversation_API_Guest_Policy *p_policy)
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1935 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1936 if (g_conversation_store)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1937 return TRUE;
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1938
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1939 if (p_policy)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1940 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1941 /* Validate policy ranges. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1942 if (p_policy->daily_turns < CONV_GUEST_DAILY_TURNS_MIN ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1943 p_policy->daily_turns > CONV_GUEST_DAILY_TURNS_MAX)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1944 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1945 Seobeo_Log(SEOBEO_ERROR,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1946 "[CONV] daily_turns must be %d..%d\n",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1947 CONV_GUEST_DAILY_TURNS_MIN, CONV_GUEST_DAILY_TURNS_MAX);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1948 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1949 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1950 if (p_policy->daily_output_tokens < CONV_GUEST_DAILY_OUTPUT_TOKENS_MIN ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1951 p_policy->daily_output_tokens > CONV_GUEST_DAILY_OUTPUT_TOKENS_MAX)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1952 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1953 Seobeo_Log(SEOBEO_ERROR,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1954 "[CONV] daily_output_tokens must be %d..%d\n",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1955 CONV_GUEST_DAILY_OUTPUT_TOKENS_MIN,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1956 CONV_GUEST_DAILY_OUTPUT_TOKENS_MAX);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1957 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1958 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1959 if (p_policy->request_output_tokens < CONV_GUEST_REQUEST_OUTPUT_TOKENS_MIN ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1960 p_policy->request_output_tokens > p_policy->daily_output_tokens)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1961 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1962 Seobeo_Log(SEOBEO_ERROR,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1963 "[CONV] request_output_tokens must be 1..%lld\n",
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1964 (long long)p_policy->daily_output_tokens);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1965 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1966 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1967 g_guest_inference_enabled = p_policy->guest_inference_enabled;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1968 g_guest_daily_turns = p_policy->daily_turns;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1969 g_guest_daily_output_tokens = p_policy->daily_output_tokens;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1970 g_guest_request_output_tokens = p_policy->request_output_tokens;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1971 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1972 else
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1973 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1974 /* No explicit policy: read from environment (backwards compat). */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1975 const char *allow_guest = getenv("MRJUNEJUNE_ALLOW_GUEST_INFERENCE");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1976 if (!allow_guest)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1977 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1978 const char *allow_anon = getenv("MRJUNEJUNE_ALLOW_ANONYMOUS_INFERENCE");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1979 if (allow_anon)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1980 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1981 Seobeo_Log(SEOBEO_WARNING,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1982 "[CONV] MRJUNEJUNE_ALLOW_ANONYMOUS_INFERENCE is deprecated;"
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1983 " use MRJUNEJUNE_ALLOW_GUEST_INFERENCE\n");
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1984 allow_guest = allow_anon;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1985 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1986 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1987 g_guest_inference_enabled =
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1988 allow_guest &&
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1989 (strcmp(allow_guest, "1") == 0 ||
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1990 strcasecmp(allow_guest, "true") == 0);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1991
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1992 g_guest_request_output_tokens =
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1993 g_guest_daily_output_tokens < CONV_GUEST_REQUEST_OUTPUT_TOKENS_DEFAULT
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1994 ? g_guest_daily_output_tokens
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1995 : CONV_GUEST_REQUEST_OUTPUT_TOKENS_DEFAULT;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1996 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
1997
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1998 g_conversation_store = Conversation_Store_Create(database_path);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
1999 return g_conversation_store != NULL;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2000 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2001
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2002 boolean Conversation_API_Enable_Inference(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2003 const char *sidecar_path,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2004 const char *copilot_cli_path)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2005 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2006 if (g_inference_bridge)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2007 return Inference_Bridge_Is_Ready(g_inference_bridge);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2008 if (!sidecar_path || !copilot_cli_path)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2009 return FALSE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2010 g_inference_bridge = Inference_Bridge_Create(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2011 sidecar_path,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2012 copilot_cli_path,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2013 Conversation_API_Handle_Inference_Event,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2014 NULL);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2015 if (!g_inference_bridge)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2016 return FALSE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2017 if (!Inference_Bridge_Start(g_inference_bridge))
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2018 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2019 Inference_Bridge_Destroy(g_inference_bridge);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2020 g_inference_bridge = NULL;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2021 return FALSE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2022 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2023 return TRUE;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2024 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2025
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2026 /* Guest-to-user transfer hook registered with Auth_API on init */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2027 static boolean Conversation_API_Guest_Transfer_Hook(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2028 const char *guest_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2029 const char *user_id,
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2030 void *context)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2031 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2032 (void)context;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2033 if (!g_conversation_store)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2034 return FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2035
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2036 /* Atomically transfer conversation ownership AND clear outstanding quota
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2037 * reservations in one transaction (auth and conv tables share the same
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2038 * SQLite file, so the write lock covers both). */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2039 return Conversation_Store_Transfer_Guest_To_User_Atomic(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2040 g_conversation_store, guest_id, user_id) == CONVERSATION_STORE_OK;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2041 }
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2042
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2043 void Conversation_API_Register_Routes(void)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2044 {
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2045 /* Wire guest-to-user transfer on login */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2046 Auth_API_Register_Guest_Transfer_Hook(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2047 Conversation_API_Guest_Transfer_Hook, NULL);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2048
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2049 /* Wire quota callback for the session endpoint. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2050 Auth_API_Register_Guest_Quota_Cb(conv_guest_quota_cb);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2051
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2052 Seobeo_Router_Register(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2053 "GET", "/api/inference/health", Conversation_API_Health);
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2054 Seobeo_Router_Register(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2055 "GET", "/api/conversations", Conversation_API_List);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2056 Seobeo_Router_Register("POST", "/api/conversations", Conversation_API_Create);
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2057 /* Body-based claim: ID stays in request body, not in URL or logs. */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2058 Seobeo_Router_Register(
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2059 "POST", "/api/conversations/claim", Conversation_API_Claim_Body);
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2060 Seobeo_Router_Register(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2061 "GET", "/api/conversations/:conversation_id", Conversation_API_Get);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2062 Seobeo_Router_Register(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2063 "PATCH", "/api/conversations/:conversation_id", Conversation_API_Update);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2064 Seobeo_Router_Register(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2065 "DELETE", "/api/conversations/:conversation_id", Conversation_API_Delete);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2066 Seobeo_Router_Register_Stream(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2067 "POST",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2068 "/api/conversations/:conversation_id/turns",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2069 Conversation_API_Turn_Stream);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2070 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2071
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2072 void Conversation_API_Destroy(void)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2073 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2074 Inference_Bridge_Destroy(g_inference_bridge);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2075 g_inference_bridge = NULL;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2076 pthread_mutex_lock(&g_pending_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2077 while (g_pending_turns)
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2078 {
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2079 Pending_Turn *p_turn = g_pending_turns;
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2080 g_pending_turns = p_turn->p_next;
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2081 /* Release guest quota reservation on server shutdown (keep turn charge). */
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2082 if (p_turn->is_guest_reserved)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2083 {
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2084 Auth_Store *p_auth_store = Auth_API_Get_Store();
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2085 if (p_auth_store)
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2086 Auth_Store_Guest_Release(p_auth_store, p_turn->request_id);
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2087 }
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2088 Conversation_Store_Fail_Turn(
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2089 g_conversation_store,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2090 p_turn->conversation_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2091 p_turn->request_id,
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2092 "Server shutdown",
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2093 TRUE);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2094 Seobeo_SSE_Close(p_turn->p_stream);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2095 Seobeo_SSE_Release(p_turn->p_stream);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2096 free(p_turn->content);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2097 free(p_turn);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2098 Conversation_API_Release_Turn_Slot();
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2099 }
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2100 pthread_mutex_unlock(&g_pending_mutex);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2101 Conversation_Store_Destroy(g_conversation_store);
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2102 g_conversation_store = NULL;
264
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2103 g_guest_inference_enabled = FALSE;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2104 g_guest_daily_turns = CONV_GUEST_DAILY_TURNS_DEFAULT;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2105 g_guest_daily_output_tokens = CONV_GUEST_DAILY_OUTPUT_TOKENS_DEFAULT;
04fee26ecce0 add authenticated JRPG conversation platform
MrJuneJune <me@mrjunejune.com>
parents: 261
diff changeset
2106 g_guest_request_output_tokens = CONV_GUEST_REQUEST_OUTPUT_TOKENS_DEFAULT;
260
1f9877b637e9 Add Copilot-powered cyberpunk JRPG chat
MrJuneJune <mrjunejune@users.noreply.github.com>
parents:
diff changeset
2107 }