diff mrjunejune/test/inference_bridge_fake_sidecar.c @ 265:056790c4fb0d

add role-aware Epi assistant prompts Add verified June knowledge, guest/member/admin Copilot profiles, profile-isolated session recovery, animated Epi greetings, and a single authoritative runtime config workflow for inference. Co-authored-by: Copilot <[email protected]>
author MrJuneJune <me@mrjunejune.com>
date Fri, 07 Aug 2026 10:50:30 -0700
parents b401627fc49e
children
line wrap: on
line diff
--- a/mrjunejune/test/inference_bridge_fake_sidecar.c	Fri Aug 07 07:34:12 2026 -0700
+++ b/mrjunejune/test/inference_bridge_fake_sidecar.c	Fri Aug 07 10:50:30 2026 -0700
@@ -10,6 +10,63 @@
   return value ? value : "";
 }
 
+/* Validates the optional "history" array from a turn.start command.
+ * Returns TRUE if history is absent, null, or structurally valid (<=20
+ * entries, each an object with role user/assistant and string content).
+ * Returns FALSE and sets *error_out on any violation. */
+static boolean Validate_History(
+    Dowa_JSON_Entry *object,
+    Dowa_Arena *p_arena,
+    const char **error_out)
+{
+  (void)p_arena;
+  *error_out = NULL;
+  Dowa_JSON_Value *hist_val = Dowa_JSON_Get(object, "history");
+  if (!hist_val || hist_val->type == DOWA_JSON_NULL)
+    return TRUE;
+  if (hist_val->type != DOWA_JSON_ARRAY)
+  {
+    *error_out = "history must be a list";
+    return FALSE;
+  }
+  size_t count = Dowa_Array_Length(hist_val->array_val);
+  if (count > 20)
+  {
+    *error_out = "history must not exceed 20 entries";
+    return FALSE;
+  }
+  for (size_t i = 0; i < count; i++)
+  {
+    Dowa_JSON_Value *v = &hist_val->array_val[i];
+    if (v->type != DOWA_JSON_OBJECT)
+    {
+      *error_out = "each history entry must be an object";
+      return FALSE;
+    }
+    Dowa_JSON_Entry *entry = v->object_val;
+    Dowa_JSON_Value *role_val    = Dowa_JSON_Get(entry, "role");
+    Dowa_JSON_Value *content_val = Dowa_JSON_Get(entry, "content");
+    if (!role_val || role_val->type != DOWA_JSON_STRING)
+    {
+      *error_out = "history role must be a string";
+      return FALSE;
+    }
+    if (!content_val || content_val->type != DOWA_JSON_STRING)
+    {
+      *error_out = "history content must be a string";
+      return FALSE;
+    }
+    const char *role = role_val->str_val;
+    if (!role ||
+        (strcmp(role, "user") != 0 && strcmp(role, "assistant") != 0))
+    {
+      *error_out = "history role must be user or assistant";
+      return FALSE;
+    }
+  }
+  return TRUE;
+}
+
 int main(void)
 {
   printf(
@@ -45,6 +102,54 @@
     }
     if (strcmp(command, "turn.start") == 0)
     {
+      /* Validate history before any other processing. */
+      const char *hist_error = NULL;
+      if (!Validate_History(object, p_arena, &hist_error))
+      {
+        printf(
+            "{\"type\":\"turn.error\",\"request_id\":\"%s\","
+            "\"conversation_id\":\"%s\","
+            "\"error\":{\"code\":\"invalid_history\","
+            "\"message\":\"%s\"}}\n",
+            request_id,
+            conversation_id,
+            hist_error);
+        printf(
+            "{\"type\":\"turn.done\",\"request_id\":\"%s\","
+            "\"conversation_id\":\"%s\",\"failed\":true}\n",
+            request_id,
+            conversation_id);
+        fflush(stdout);
+        Dowa_Arena_Free(p_arena);
+        continue;
+      }
+
+      const char *prompt_profile = Get_String(object, "prompt_profile");
+      double prompt_version = Dowa_JSON_Get_Number(object, "prompt_version");
+      double knowledge_version =
+          Dowa_JSON_Get_Number(object, "knowledge_version");
+      boolean known_profile =
+          strcmp(prompt_profile, "public_visitor") == 0 ||
+          strcmp(prompt_profile, "invited_friend") == 0 ||
+          strcmp(prompt_profile, "june_admin") == 0;
+      if (!known_profile || prompt_version != 1 || knowledge_version != 1)
+      {
+        printf(
+            "{\"type\":\"turn.error\",\"request_id\":\"%s\","
+            "\"conversation_id\":\"%s\","
+            "\"error\":{\"code\":\"invalid_prompt_profile\","
+            "\"message\":\"prompt profile is required\"}}\n",
+            request_id,
+            conversation_id);
+        printf(
+            "{\"type\":\"turn.done\",\"request_id\":\"%s\","
+            "\"conversation_id\":\"%s\",\"failed\":true}\n",
+            request_id,
+            conversation_id);
+        fflush(stdout);
+        Dowa_Arena_Free(p_arena);
+        continue;
+      }
       printf(
           "{\"type\":\"turn.accepted\",\"request_id\":\"%s\","
           "\"conversation_id\":\"%s\"}\n",
@@ -53,9 +158,11 @@
       printf(
           "{\"type\":\"tool.started\",\"request_id\":\"%s\","
           "\"conversation_id\":\"%s\","
-          "\"tool\":{\"name\":\"mock-search\"}}\n",
+          "\"tool\":{\"name\":\"mock-search\","
+          "\"prompt_profile\":\"%s\"}}\n",
           request_id,
-          conversation_id);
+          conversation_id,
+          prompt_profile);
       printf(
           "{\"type\":\"assistant.delta\",\"request_id\":\"%s\","
           "\"conversation_id\":\"%s\","