Regenerated doc + final submit for now
This commit is contained in:
+91
-13
@@ -170,6 +170,71 @@ namespace Romeo
|
||||
return true;
|
||||
}
|
||||
|
||||
static Juliet::String CleanAndFormatDescription(Juliet::Arena* arena, const Juliet::String& rawResponse, bool enableCoT)
|
||||
{
|
||||
Assert(arena != nullptr);
|
||||
if (rawResponse.Size == 0)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
||||
const char* pStr = CStr(rawResponse);
|
||||
size_t len = rawResponse.Size;
|
||||
|
||||
const char* thinkStart = strstr(pStr, "<think>");
|
||||
const char* thinkEnd = thinkStart ? strstr(thinkStart, "</think>") : nullptr;
|
||||
|
||||
Juliet::String thinkContent = {};
|
||||
Juliet::String mainContent = {};
|
||||
|
||||
if (thinkStart && thinkEnd && thinkEnd > thinkStart)
|
||||
{
|
||||
const char* thinkTextStart = thinkStart + 7;
|
||||
size_t thinkLen = static_cast<size_t>(thinkEnd - thinkTextStart);
|
||||
thinkContent = { const_cast<char*>(thinkTextStart), thinkLen };
|
||||
|
||||
const char* afterThink = thinkEnd + 8;
|
||||
size_t remainingLen = len - static_cast<size_t>(afterThink - pStr);
|
||||
mainContent = { const_cast<char*>(afterThink), remainingLen };
|
||||
}
|
||||
else
|
||||
{
|
||||
mainContent = rawResponse;
|
||||
}
|
||||
|
||||
// Clean mainContent (remove titles, markdown headers, leading quotes/fences)
|
||||
const char* mPtr = CStr(mainContent);
|
||||
size_t mLen = mainContent.Size;
|
||||
|
||||
while (mLen > 0 && (*mPtr == ' ' || *mPtr == '\t' || *mPtr == '\r' || *mPtr == '\n' || *mPtr == '#' || *mPtr == '`'))
|
||||
{
|
||||
mPtr++;
|
||||
mLen--;
|
||||
}
|
||||
|
||||
while (mLen > 0 && (mPtr[mLen - 1] == ' ' || mPtr[mLen - 1] == '\t' || mPtr[mLen - 1] == '\r' || mPtr[mLen - 1] == '\n' || mPtr[mLen - 1] == '`'))
|
||||
{
|
||||
mLen--;
|
||||
}
|
||||
|
||||
if (enableCoT && thinkContent.Size > 0)
|
||||
{
|
||||
size_t resultCap = thinkContent.Size + mLen + 256;
|
||||
char* resultBuf = Juliet::ArenaPushArray<char>(arena, resultCap JULIET_DEBUG_PARAM("CoTFormattedDesc"));
|
||||
int written = snprintf(resultBuf, resultCap,
|
||||
"<details>\n<summary>Chain of Thought</summary>\n\n%.*s\n\n</details>\n\n%.*s",
|
||||
static_cast<int>(thinkContent.Size), CStr(thinkContent),
|
||||
static_cast<int>(mLen), mPtr
|
||||
);
|
||||
return { resultBuf, static_cast<size_t>(written > 0 ? written : 0) };
|
||||
}
|
||||
|
||||
char* resultBuf = Juliet::ArenaPushArray<char>(arena, mLen + 1 JULIET_DEBUG_PARAM("CleanedDesc"));
|
||||
memcpy(resultBuf, mPtr, mLen);
|
||||
resultBuf[mLen] = '\0';
|
||||
return { resultBuf, mLen };
|
||||
}
|
||||
|
||||
bool AI_GenerateDescription(
|
||||
Juliet::Arena* arena,
|
||||
FileEntry& entry
|
||||
@@ -186,8 +251,23 @@ namespace Romeo
|
||||
return true;
|
||||
}
|
||||
|
||||
// Formulate the prompt
|
||||
const char* sysPrompt = "You are a technical documentation assistant. Provide a very short, concise, one-paragraph overview (MAXIMUM 50 WORDS) describing the purpose, main responsibilities, and design of this C++ component. Do not include markdown code block styling or titles in your response; return ONLY the description paragraph. If the current description provided below is already good and accurate, please return it exactly as is.";
|
||||
Juliet::String cotEnv = GetEnvironmentVar(arena, "ROMEO_ENABLE_COT");
|
||||
bool enableCoT = (cotEnv.Size > 0 && (cotEnv.Data[0] == '1' || cotEnv.Data[0] == 't' || cotEnv.Data[0] == 'T' || cotEnv.Data[0] == 'y' || cotEnv.Data[0] == 'Y'));
|
||||
|
||||
const char* sysPromptNoCoT = "You are a technical documentation assistant. Provide a single, concise, unified paragraph overview (50-80 words) describing the main purpose and design of this C++ component.\n"
|
||||
"Rules:\n"
|
||||
"1. Do NOT split your output by header file or source file.\n"
|
||||
"2. Do NOT include titles, markdown headers (e.g. # or ##), bullet lists, or code blocks.\n"
|
||||
"3. Do NOT include <think> tags or reasoning text.\n"
|
||||
"4. Return ONLY the description paragraph.";
|
||||
|
||||
const char* sysPromptCoT = "You are a technical documentation assistant. Provide a single, concise, unified paragraph overview (50-80 words) describing the main purpose and design of this C++ component.\n"
|
||||
"Rules:\n"
|
||||
"1. You may include your reasoning inside <think>...</think> tags.\n"
|
||||
"2. Following the reasoning, output ONLY the final description paragraph.\n"
|
||||
"3. Do NOT split your final output by header file or source file.";
|
||||
|
||||
const char* sysPrompt = enableCoT ? sysPromptCoT : sysPromptNoCoT;
|
||||
|
||||
size_t promptCap = strlen(sysPrompt) + entry.HeaderPath.Size + headerContent.Size + entry.CppPath.Size + cppContent.Size + entry.Description.Size + 512;
|
||||
char* promptBuf = Juliet::ArenaPushArray<char>(arena, promptCap JULIET_DEBUG_PARAM("PromptBuf"));
|
||||
@@ -229,9 +309,6 @@ namespace Romeo
|
||||
Juliet::String prompt = { promptBuf, static_cast<size_t>(written > 0 ? written : 0) };
|
||||
Juliet::String escapedPrompt = Json_EscapeString(arena, prompt);
|
||||
|
||||
// Try local Ollama
|
||||
// Default Host: localhost:11434
|
||||
// Default Model: qwen2.5-coder:1.5b
|
||||
Juliet::String host = ConstString("127.0.0.1");
|
||||
int port = 11434;
|
||||
Juliet::String modelName = GetEnvironmentVar(arena, "ROMEO_LLM_MODEL");
|
||||
@@ -240,34 +317,35 @@ namespace Romeo
|
||||
modelName = ConstString("qwen2.5-coder:1.5b");
|
||||
}
|
||||
|
||||
// Check / pull model if needed
|
||||
if (!PullOllamaModelIfNeeded(arena, host, port, modelName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
printf("Romeo AI: Querying local Ollama (%.*s) for '%.*s' description...\n",
|
||||
printf("Romeo AI: Querying local Ollama (%.*s) [CoT: %s] for '%.*s'...\n",
|
||||
static_cast<int>(modelName.Size), CStr(modelName),
|
||||
enableCoT ? "ON" : "OFF",
|
||||
static_cast<int>(entry.HeaderPath.Size > 0 ? entry.HeaderPath.Size : entry.CppPath.Size),
|
||||
CStr(entry.HeaderPath.Size > 0 ? entry.HeaderPath : entry.CppPath));
|
||||
|
||||
size_t bodyCap = modelName.Size + escapedPrompt.Size + 256;
|
||||
int maxPredictTokens = enableCoT ? 600 : 300;
|
||||
size_t bodyCap = modelName.Size + escapedPrompt.Size + 512;
|
||||
char* bodyBuf = Juliet::ArenaPushArray<char>(arena, bodyCap JULIET_DEBUG_PARAM("OllamaBody"));
|
||||
int bodyLen = snprintf(bodyBuf, bodyCap,
|
||||
"{\"model\":\"%.*s\",\"prompt\":\"%.*s\",\"stream\":false}",
|
||||
"{\"model\":\"%.*s\",\"prompt\":\"%.*s\",\"stream\":false,\"options\":{\"temperature\":0.2,\"num_predict\":%d}}",
|
||||
static_cast<int>(modelName.Size), CStr(modelName),
|
||||
static_cast<int>(escapedPrompt.Size), CStr(escapedPrompt)
|
||||
static_cast<int>(escapedPrompt.Size), CStr(escapedPrompt),
|
||||
maxPredictTokens
|
||||
);
|
||||
Juliet::String body = { bodyBuf, static_cast<size_t>(bodyLen > 0 ? bodyLen : 0) };
|
||||
|
||||
|
||||
Juliet::String response = {};
|
||||
bool success = PostWithRetry(
|
||||
arena,
|
||||
host,
|
||||
port,
|
||||
ConstString("/api/generate"),
|
||||
false, // isHttps
|
||||
false,
|
||||
body,
|
||||
response
|
||||
);
|
||||
@@ -280,7 +358,7 @@ namespace Romeo
|
||||
Juliet::String desc = {};
|
||||
if (Json_Query(root, "response", desc))
|
||||
{
|
||||
entry.Description = Juliet::StringCopy(arena, desc);
|
||||
entry.Description = CleanAndFormatDescription(arena, desc, enableCoT);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user