feat: wire up app_main with all subsystems

Startup sequence: NVS → SPIFFS → bus → memory → WiFi → CLI →
Telegram → agent loop → WebSocket → outbound dispatch.
CMakeLists registers all source files and ESP-IDF dependencies.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
crispyberry
2026-02-05 18:56:04 +08:00
parent 0b9aef22a7
commit fa4582bf70
2 changed files with 151 additions and 2 deletions

View File

@@ -1,2 +1,20 @@
idf_component_register(SRCS "mimi.c"
INCLUDE_DIRS ".")
idf_component_register(
SRCS
"mimi.c"
"bus/message_bus.c"
"wifi/wifi_manager.c"
"telegram/telegram_bot.c"
"llm/llm_proxy.c"
"agent/agent_loop.c"
"agent/context_builder.c"
"memory/memory_store.c"
"memory/session_mgr.c"
"gateway/ws_server.c"
"cli/serial_cli.c"
"ota/ota_manager.c"
INCLUDE_DIRS
"."
REQUIRES
nvs_flash esp_wifi esp_netif esp_http_client esp_http_server
esp_https_ota esp_event json spiffs console vfs
)

View File

@@ -1,6 +1,137 @@
#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_log.h"
#include "esp_event.h"
#include "esp_system.h"
#include "esp_heap_caps.h"
#include "esp_spiffs.h"
#include "nvs_flash.h"
#include "mimi_config.h"
#include "bus/message_bus.h"
#include "wifi/wifi_manager.h"
#include "telegram/telegram_bot.h"
#include "llm/llm_proxy.h"
#include "agent/agent_loop.h"
#include "memory/memory_store.h"
#include "memory/session_mgr.h"
#include "gateway/ws_server.h"
#include "cli/serial_cli.h"
static const char *TAG = "mimi";
static esp_err_t init_nvs(void)
{
esp_err_t ret = nvs_flash_init();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
ESP_LOGW(TAG, "NVS partition truncated, erasing...");
ESP_ERROR_CHECK(nvs_flash_erase());
ret = nvs_flash_init();
}
return ret;
}
static esp_err_t init_spiffs(void)
{
esp_vfs_spiffs_conf_t conf = {
.base_path = MIMI_SPIFFS_BASE,
.partition_label = NULL,
.max_files = 10,
.format_if_mount_failed = true,
};
esp_err_t ret = esp_vfs_spiffs_register(&conf);
if (ret != ESP_OK) {
ESP_LOGE(TAG, "SPIFFS mount failed: %s", esp_err_to_name(ret));
return ret;
}
size_t total = 0, used = 0;
esp_spiffs_info(NULL, &total, &used);
ESP_LOGI(TAG, "SPIFFS: total=%d, used=%d", (int)total, (int)used);
return ESP_OK;
}
/* Outbound dispatch task: reads from outbound queue and routes to channels */
static void outbound_dispatch_task(void *arg)
{
ESP_LOGI(TAG, "Outbound dispatch started");
while (1) {
mimi_msg_t msg;
if (message_bus_pop_outbound(&msg, UINT32_MAX) != ESP_OK) continue;
ESP_LOGI(TAG, "Dispatching response to %s:%s", msg.channel, msg.chat_id);
if (strcmp(msg.channel, MIMI_CHAN_TELEGRAM) == 0) {
telegram_send_message(msg.chat_id, msg.content);
} else if (strcmp(msg.channel, MIMI_CHAN_WEBSOCKET) == 0) {
ws_server_send(msg.chat_id, msg.content);
} else {
ESP_LOGW(TAG, "Unknown channel: %s", msg.channel);
}
free(msg.content);
}
}
void app_main(void)
{
ESP_LOGI(TAG, "========================================");
ESP_LOGI(TAG, " MimiClaw - ESP32-S3 AI Agent");
ESP_LOGI(TAG, "========================================");
/* Print memory info */
ESP_LOGI(TAG, "Internal free: %d bytes",
(int)heap_caps_get_free_size(MALLOC_CAP_INTERNAL));
ESP_LOGI(TAG, "PSRAM free: %d bytes",
(int)heap_caps_get_free_size(MALLOC_CAP_SPIRAM));
/* Phase 1: Core infrastructure */
ESP_ERROR_CHECK(init_nvs());
ESP_ERROR_CHECK(esp_event_loop_create_default());
ESP_ERROR_CHECK(init_spiffs());
/* Initialize subsystems */
ESP_ERROR_CHECK(message_bus_init());
ESP_ERROR_CHECK(memory_store_init());
ESP_ERROR_CHECK(session_mgr_init());
ESP_ERROR_CHECK(wifi_manager_init());
ESP_ERROR_CHECK(telegram_bot_init());
ESP_ERROR_CHECK(llm_proxy_init());
ESP_ERROR_CHECK(agent_loop_init());
/* Start Serial CLI first (works without WiFi) */
ESP_ERROR_CHECK(serial_cli_init());
/* Start WiFi */
esp_err_t wifi_err = wifi_manager_start();
if (wifi_err == ESP_OK) {
ESP_LOGI(TAG, "Waiting for WiFi connection...");
if (wifi_manager_wait_connected(30000) == ESP_OK) {
ESP_LOGI(TAG, "WiFi connected: %s", wifi_manager_get_ip());
/* Start network-dependent services */
ESP_ERROR_CHECK(telegram_bot_start());
ESP_ERROR_CHECK(agent_loop_start());
ESP_ERROR_CHECK(ws_server_start());
/* Outbound dispatch task */
xTaskCreatePinnedToCore(
outbound_dispatch_task, "outbound",
MIMI_OUTBOUND_STACK, NULL,
MIMI_OUTBOUND_PRIO, NULL, MIMI_OUTBOUND_CORE);
ESP_LOGI(TAG, "All services started!");
} else {
ESP_LOGW(TAG, "WiFi connection timeout. Configure via CLI: wifi_set <SSID> <PASS>");
}
} else {
ESP_LOGW(TAG, "No WiFi credentials. Configure via CLI: wifi_set <SSID> <PASS>");
}
ESP_LOGI(TAG, "MimiClaw ready. Type 'help' for CLI commands.");
}