88 lines
2.5 KiB
C
88 lines
2.5 KiB
C
#define _POSIX_C_SOURCE 200809L
|
|
|
|
#include "context_format.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
static int append_text(char** buf, size_t* cap, size_t* used, const char* s, size_t len) {
|
|
if (!buf || !cap || !used || !s) return -1;
|
|
if (*used + len + 1U > *cap) {
|
|
size_t next = *cap;
|
|
while (*used + len + 1U > next) {
|
|
next = (next == 0U) ? 256U : (next * 2U);
|
|
}
|
|
char* grown = (char*)realloc(*buf, next);
|
|
if (!grown) return -1;
|
|
*buf = grown;
|
|
*cap = next;
|
|
}
|
|
memcpy(*buf + *used, s, len);
|
|
*used += len;
|
|
(*buf)[*used] = '\0';
|
|
return 0;
|
|
}
|
|
|
|
char* context_bump_headings(const char* text) {
|
|
if (!text) return NULL;
|
|
|
|
size_t cap = strlen(text) + 256; // Initial guess
|
|
size_t used = 0;
|
|
char* buf = (char*)malloc(cap);
|
|
if (!buf) return NULL;
|
|
buf[0] = '\0';
|
|
|
|
const char* p = text;
|
|
while (*p) {
|
|
const char* eol = strchr(p, '\n');
|
|
size_t line_len = eol ? (size_t)(eol - p) : strlen(p);
|
|
|
|
// Check if line starts with '#'
|
|
if (line_len > 0 && p[0] == '#') {
|
|
// Add an extra '#'
|
|
if (append_text(&buf, &cap, &used, "#", 1) != 0) {
|
|
free(buf);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
// Append the rest of the line
|
|
if (append_text(&buf, &cap, &used, p, line_len) != 0) {
|
|
free(buf);
|
|
return NULL;
|
|
}
|
|
|
|
if (eol) {
|
|
if (append_text(&buf, &cap, &used, "\n", 1) != 0) {
|
|
free(buf);
|
|
return NULL;
|
|
}
|
|
p = eol + 1;
|
|
} else {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
|
|
char* context_build_title(tools_context_t* ctx) {
|
|
if (!ctx || !ctx->cfg) return strdup("# Didactyl Agent\n\n");
|
|
|
|
const char* name = "Didactyl Agent";
|
|
|
|
// Try to get name from kind 0 profile if available
|
|
if (ctx->template_skill_lookup) {
|
|
// We don't have direct access to the parsed kind 0 here easily,
|
|
// but we can try to extract it from the agent_profile tool output
|
|
// if we really wanted to. For now, let's stick to a simple default
|
|
// or use the config if it has a name field (it doesn't currently).
|
|
// A more robust way would be to parse the kind 0 JSON here.
|
|
}
|
|
|
|
// For now, just use a generic title. The identity skill will provide the rest.
|
|
char title[256];
|
|
snprintf(title, sizeof(title), "# %s\n\n", name);
|
|
return strdup(title);
|
|
}
|