2026-02-05 18:55:38 +08:00
# include "context_builder.h"
# include "mimi_config.h"
# include "memory/memory_store.h"
2026-02-09 01:25:56 +08:00
# include "skills/skill_loader.h"
2026-02-05 18:55:38 +08:00
# include <stdio.h>
# include <string.h>
# include "esp_log.h"
static const char * TAG = " context " ;
static size_t append_file ( char * buf , size_t size , size_t offset , const char * path , const char * header )
{
FILE * f = fopen ( path , " r " ) ;
if ( ! f ) return offset ;
2026-04-01 00:50:41 +08:00
if ( offset > = size ) return offset ;
if ( header ) {
int ret = snprintf ( buf + offset , size - offset , " \n ## %s \n \n " , header ) ;
if ( ret > 0 ) offset + = ( size_t ) ret ;
if ( offset > = size ) { offset = size - 1 ; buf [ offset ] = ' \0 ' ; fclose ( f ) ; return offset ; }
2026-02-05 18:55:38 +08:00
}
size_t n = fread ( buf + offset , 1 , size - offset - 1 , f ) ;
offset + = n ;
buf [ offset ] = ' \0 ' ;
fclose ( f ) ;
return offset ;
}
esp_err_t context_build_system_prompt ( char * buf , size_t size )
{
size_t off = 0 ;
off + = snprintf ( buf + off , size - off ,
" # MimiClaw \n \n "
" You are MimiClaw, a personal AI assistant running on an ESP32-S3 device. \n "
" You communicate through Telegram and WebSocket. \n \n "
2026-02-07 00:37:43 +08:00
" Be helpful, accurate, and concise. \n \n "
" ## Available Tools \n "
" You have access to the following tools: \n "
2026-02-18 19:16:00 +08:00
" - web_search: Search the web for current information (Tavily preferred, Brave fallback when configured). "
2026-02-07 15:54:23 +08:00
" Use this when you need up-to-date facts, news, weather, or anything beyond your training data. \n "
" - get_current_time: Get the current date and time. "
2026-02-07 17:54:52 +08:00
" You do NOT have an internal clock — always use this tool when you need to know the time or date. \n "
2026-02-26 09:26:26 +08:00
" - read_file: Read a file (path must start with " MIMI_SPIFFS_BASE " /). \n "
" - write_file: Write/overwrite a file. \n "
" - edit_file: Find-and-replace edit a file. \n "
" - list_dir: List files, optionally filter by prefix. \n "
2026-02-09 01:02:33 +08:00
" - cron_add: Schedule a recurring or one-shot task. The message will trigger an agent turn when the job fires. \n "
" - cron_list: List all scheduled cron jobs. \n "
2026-03-07 16:15:37 +08:00
" - cron_remove: Remove a scheduled cron job by ID. \n "
" - gpio_write: Set a GPIO pin HIGH or LOW. Use for controlling LEDs, relays, and digital outputs. \n "
" - gpio_read: Read a single GPIO pin state (HIGH or LOW). Use for checking switches, buttons, sensors. \n "
" - gpio_read_all: Read all allowed GPIO pins at once. Good for getting a full status overview. \n \n "
2026-02-18 17:16:00 +08:00
" When using cron_add for Telegram delivery, always set channel='telegram' and a valid numeric chat_id. \n \n "
2026-03-07 16:15:37 +08:00
" ## GPIO \n "
" You can control hardware GPIO pins on the ESP32-S3. Use gpio_read to check switch/sensor states "
" (digital input confirmation), and gpio_write to control outputs. Pin range is validated by policy — "
" only allowed pins can be accessed. When asked about switch states or digital I/O, use these tools. \n \n "
2026-02-07 17:54:52 +08:00
" Use tools when needed. Provide your final answer as text after using tools. \n \n "
2026-02-08 22:43:13 +08:00
" ## Memory \n "
" You have persistent memory stored on local flash: \n "
2026-02-26 09:26:26 +08:00
" - Long-term memory: " MIMI_SPIFFS_MEMORY_DIR " /MEMORY.md \n "
" - Daily notes: " MIMI_SPIFFS_MEMORY_DIR " /daily/<YYYY-MM-DD>.md \n \n "
2026-02-08 22:43:13 +08:00
" IMPORTANT: Actively use memory to remember things across conversations. \n "
" - When you learn something new about the user (name, preferences, habits, context), write it to MEMORY.md. \n "
" - When something noteworthy happens in a conversation, append it to today's daily note. \n "
" - Always read_file MEMORY.md before writing, so you can edit_file to update without losing existing content. \n "
" - Use get_current_time to know today's date before writing daily notes. \n "
" - Keep MEMORY.md concise and organized — summarize, don't dump raw conversation. \n "
2026-02-09 01:23:13 +08:00
" - You should proactively save memory without being asked. If the user tells you their name, preferences, or important facts, persist them immediately. \n \n "
2026-02-09 01:25:56 +08:00
" ## Skills \n "
2026-02-26 09:26:26 +08:00
" Skills are specialized instruction files stored in " MIMI_SKILLS_PREFIX " . \n "
2026-02-09 01:25:56 +08:00
" When a task matches a skill, read the full skill file for detailed instructions. \n "
2026-02-26 09:26:26 +08:00
" You can create new skills using write_file to " MIMI_SKILLS_PREFIX " <name>.md. \n " ) ;
2026-02-05 18:55:38 +08:00
/* Bootstrap files */
off = append_file ( buf , size , off , MIMI_SOUL_FILE , " Personality " ) ;
off = append_file ( buf , size , off , MIMI_USER_FILE , " User Info " ) ;
/* Long-term memory */
char mem_buf [ 4096 ] ;
if ( memory_read_long_term ( mem_buf , sizeof ( mem_buf ) ) = = ESP_OK & & mem_buf [ 0 ] ) {
2026-04-01 00:50:41 +08:00
if ( off < size ) {
int ret = snprintf ( buf + off , size - off , " \n ## Long-term Memory \n \n %s \n " , mem_buf ) ;
if ( ret > 0 ) off + = ( size_t ) ret ;
if ( off > = size ) off = size - 1 ;
}
2026-02-05 18:55:38 +08:00
}
/* Recent daily notes (last 3 days) */
char recent_buf [ 4096 ] ;
if ( memory_read_recent ( recent_buf , sizeof ( recent_buf ) , 3 ) = = ESP_OK & & recent_buf [ 0 ] ) {
2026-04-01 00:50:41 +08:00
if ( off < size ) {
int ret = snprintf ( buf + off , size - off , " \n ## Recent Notes \n \n %s \n " , recent_buf ) ;
if ( ret > 0 ) off + = ( size_t ) ret ;
if ( off > = size ) off = size - 1 ;
}
2026-02-05 18:55:38 +08:00
}
2026-02-09 01:25:56 +08:00
/* Skills */
char skills_buf [ 2048 ] ;
size_t skills_len = skill_loader_build_summary ( skills_buf , sizeof ( skills_buf ) ) ;
if ( skills_len > 0 ) {
2026-04-01 00:50:41 +08:00
if ( off < size ) {
int ret = snprintf ( buf + off , size - off ,
" \n ## Available Skills \n \n "
" Available skills (use read_file to load full instructions): \n %s \n " ,
skills_buf ) ;
if ( ret > 0 ) off + = ( size_t ) ret ;
if ( off > = size ) off = size - 1 ;
}
2026-02-09 01:25:56 +08:00
}
2026-02-05 18:55:38 +08:00
ESP_LOGI ( TAG , " System prompt built: %d bytes " , ( int ) off ) ;
return ESP_OK ;
}