sync: update ai_components from TuyaOpen upstream + fix 10 review bugs - #44
Merged
shiliu-yang merged 13 commits intoJun 25, 2026
Merged
Conversation
Bump TuyaOpen submodule from a0b612e -> 7f83f06a (master tip), then merge the upstream src/ai_components reorganisation into DuckyClaw's app-local ai_components/ copy via 3-way merge (base = apps/tuya.ai/ai_components @ a0b612e, theirs = src/ai_components @ 7f83f06a, ours = ai_components/ @ DuckyClaw master) while preserving every DuckyClaw-specific feature. Key upstream changes adopted: - Build system refactor: every module CMakeLists.txt uses the self-registering component pattern (MODULE_NAME / COMPONENT_LIBS / COMPONENT_PUBINC) and the app-local copy now lives under ai_components/, with TuyaOpen's own src/ai_components gated off via CONFIG_ENABLE_AI_COMPONENTS=n so the two copies never co-build (CMake target names would collide). - ai_mcp: parse_message gains sid/eid session routing params; reply paths carry sid/eid; MCP_SEND_MESSAGE_CB updated accordingly - ai_agent: new AI_PT_IMAGE branch calls ai_picture_output_save_to_album - ai_picture: new chunk-accumulation API (ai_picture.h, ai_picture_input.h, ai_picture_output_save_to_album); old ai_picture_output_start / convert callsites in ducky_claw_chat are dropped (legacy ai_picture_convert* stubs are kept for compat) - ai_ui: UI split into base AI_UI_INTFS_T + AI_UI_CHAT_INTFS_T + AI_UI_CAMERA_INTFS_T; chat/oled/wechat sources moved into subdirs (chatbot/, oled/, wechat/); new ai_ui_camera, ai_ui_image_album, ai_ui_page modules; new AlibabaPuHuiTi3 fonts and v8/v9 icon sets - ai_video: ai_video_init() now void; flush cb wired via ai_video_set_yuv_frame_flush_cb(); V4L2 (Raspberry Pi UVC) conditional retained - ai_mode: LED null-safety, PSRAM correctness, timer shadow bug fixes - assets: new lang_config string keys (en-US / zh-CN) - utility: ai_user_event.h adds AI_USER_EVT_GENERATE_PICTURE, AI_USER_EVT_GET_PICTURE_FROM_APP, AI_USER_EVT_SEND_PICTURE_END DuckyClaw-specific handling preserved: - ai_mcp_server: MCP_TOOL_EXEC_HOOK_CB + ai_mcp_server_set_tool_exec_hook (used by agent_loop.c to capture tool results); hook invoked on success and error paths; hook fields preserved across ai_mcp_server_init memset - ai_agent: ai_user_event_notify(AI_USER_EVT_END) in AI_EVENT_END handler (semaphore signal unblocking agent_loop inner loop); also wires the long-dormant s_tts_suppressed gate around the three ai_audio_play_tts_stream calls so ai_agent_set_tts_suppressed() finally has effect - ai_agent: ai_agent_set_tts_suppressed() TTS suppression API - ai_audio_input: PSRAM-aware conditional thread stackDepth/psram_mode for non-PSRAM boards (upstream's unconditional psram_mode=1 would break them) - ai_chat_main: deferred ai_chat_mode task start via tal_event_subscribe on EVENT_MQTT_CONNECTED instead of the upstream's launch-at-init (Raspberry Pi & late-cloud boards need cloud-ready timing). Stack bumped 2k -> 3k to match upstream sizing. - ai_video: PSRAM-aware AI_VIDEO_MALLOC/FREE macros (typo ENBALE_EXT_RAM also corrected to ENABLE_EXT_RAM); V4L2 conditional kept Bugs fixed: - agent_loop.c:482: remove `|| call_ok` from inner-loop break condition; inverted logic caused the tool loop to exit on success and only continue on failure, making multi-step tool chains impossible - ai_video_input.c:206: fix inverted null guard (NULL== -> NULL!=) so the camera handle is closed when non-null instead of when already-NULL - ducky_claw_chat.c: update ai_video_init() to void signature; wire flush callback via ai_video_set_yuv_frame_flush_cb(); switch ai_ui_camera_flush() to AI_UI_VIDEO_T*; drop ai_ui_disp_picture and ai_picture_output_init (picture display migrated to the album API by the upstream agent itself) - tuya_app_main.c: rename UI_WIFI_STATUS_E -> AI_UI_WIFI_STATUS_E to match upstream, replace VOID_T/BOOL_T/TRUE with the C-standard void/bool/true - ai_chat_ui.c: fall back to WeChat UI when none of the GUI choices is explicitly defined (upstream's #error blocks the build through the DuckyClaw app-local Kconfig include path that does not always resolve the choice default) Build system: - top-level CMakeLists.txt re-propagates per-app COMPONENT_LIBS/PUBINC into EXAMPLE_LIB (TuyaOpen's deal_with_components only wires its own src/* libs; app-level subdirs need the snapshot/delta pattern to attach their headers and link) - ai_components/Kconfig drops the master ENABLE_AI_COMPONENTS switch entirely; the app-local copy is unconditionally built and TuyaOpen's gate keeps the duplicate src/ai_components out of the build Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
maidang-xing
force-pushed
the
sync/ai-components-upstream-merge
branch
from
June 22, 2026 01:45
b57638c to
efe7bc0
Compare
…ring
After the previous sync commit the TuyaOpen platform link still pulled only
EXAMPLE_LIB ("tuyaapp") + COMPONENTS_ALL_LIB ("tuyaos"), and tuyaos is built
from TuyaOpen's COMPONENT_LIBS snapshot taken before the app's CMakeLists
runs -- so app-local libs (ai_components/IM/lua) were never in the final
link list, leaving every ai_mcp_*, ai_picture_*, ai_agent_* symbol referenced
from tools/ and src/ unresolved at the platform link stage.
- top CMakeLists.txt: after registering new app-component libs, also fold
their object files into ${EXAMPLE_LIB} via $<TARGET_OBJECTS:...> so the
symbols ship inside libtuyaapp.a and the existing PLATFORM_NEED_LIBS line
resolves them without further plumbing.
- ai_ui/CMakeLists.txt: the Kconfig choice for the WeChat / Chatbot / OLED
chat UI does not always propagate through DuckyClaw's app-local Kconfig
include path, so the chat sources stayed un-compiled and
ai_ui_chat_wechat_register stayed undefined. Default to WeChat in CMake
(matching the C-side #else fallback in ai_chat_ui.c) and -DENABLE_AI_CHAT_GUI_WECHAT=1
the ai_ui sources so the inner #if guards open.
- config/TUYA_T5AI_BOARD_LCD_3.5_CAMERA.config: add CONFIG_ENABLE_LIBLVGL=y,
CONFIG_ENABLE_AI_CHAT_GUI_WECHAT=y, and CONFIG_ENABLE_LVGL_TP=y so LVGL
headers are on the include path (font tables need them) and the popup-menu
camera callback in ai_ui_wechat_chat.c is no longer flagged as a
defined-but-unused -Werror.
Verified locally: tos.py clean -f && tos.py build with the
TUYA_T5AI_BOARD_LCD_3.5_CAMERA.config target now produces DuckyClaw_QIO_1.0.0.bin
(3.5M) under dist/DuckyClaw_1.0.0/.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The previous sync commit only verified the TUYA_T5AI_BOARD_LCD_3.5_CAMERA target; tos.py dev bac across the full config/*.config matrix surfaced three classes of breakage on the other 7 boards. - src/ducky_claw_chat.c: gate `#include "ai_ui_camera.h"` and `#include "ai_video_input.h"` on ENABLE_COMP_AI_DISPLAY / ENABLE_COMP_AI_VIDEO respectively. Boards that disable display (DshanPi_A1, ESP32S3_BREAD_COMPACT_WIFI, RaspberryPi, TUYA_T5AI_CORE) no longer ship the ai_ui/ai_video PUBINC paths, so unconditional includes fataled "ai_ui_camera.h: No such file or directory" before the file even started compiling. - ai_components/ai_ui/Kconfig: ENABLE_COMP_AI_DISPLAY now selects ENABLE_LIBLVGL. Previously LIBLVGL was selected only via the chat-UI choice items, which do not resolve through DuckyClaw's app-local Kconfig include path, so configs that turned display on without an explicit GUI selection (ATK, WAVESHARE_T5AI_TOUCH_AMOLED_1_75, TUYA_T5AI_BOARD_LCD_3.5_CAMERA(NO_SDCARD)) built ai_ui sources without lvgl.h on the include path and failed on `lv_font_fmt_txt_glyph_dsc_t`. - ai_components/ai_ui/src/wechat/ai_ui_wechat_chat.c: `__popup_camera_cb` was defined when ENABLE_COMP_AI_VIDEO is on but referenced only inside an `if (ENABLE_LVGL_TP)` block, so VIDEO-on/TP-off configs hit -Werror=unused-function. Gate the definition on both ENABLE_COMP_AI_VIDEO AND ENABLE_LVGL_TP to match the single call site. Verified locally with tos.py dev bac: Build [1/8] ATK_T5AI_MINI_BOARD_2.4LCD_CAMERA.config success Build [2/8] DshanPi_A1.config success Build [3/8] ESP32S3_BREAD_COMPACT_WIFI.config success Build [4/8] RaspberryPi.config success Build [5/8] TUYA_T5AI_BOARD_LCD_3.5_CAMERA(NO_SDCARD).config success Build [6/8] TUYA_T5AI_BOARD_LCD_3.5_CAMERA.config success Build [7/8] TUYA_T5AI_CORE.config success Build [8/8] WAVESHARE_T5AI_TOUCH_AMOLED_1_75.config success Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…weaks
- ai_components/ai_ui/assets/picture/: drop all PNG source assets except
ai_icon.png. The PNGs are the offline source for icon/v8/*.c and
icon/v9/*.c (converted via assets/png_to_lvgl_icon_c.py); nothing in
the build picks them up, so trimming them just reclaims repo space.
startup_origin.gif is preserved -- it is a GIF, not a PNG.
- ai_components/ai_agent/{include/ai_agent.h, src/ai_agent.c},
ai_components/ai_audio/src/ai_audio_input.c,
agent/agent_loop.c: revert the speculative s_tts_suppressed wiring,
the conditional THREAD_CFG_T psram_mode tweak, and other small edits
back to the upstream-aligned versions; the upstream behavior is what
the project actually wants here.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Updated `ai_ui_manage.c` to enable PSRAM mode when external RAM is defined. - Modified `cron_service.c` to include PSRAM mode configuration for the cron service thread. - Enhanced `ws_server.c` to set PSRAM mode for the WebSocket server thread when external RAM is enabled.
Drop the local copy of ai_components/ (split off from TuyaOpen at an earlier sync); pick up TuyaOpen's src/ai_components/ instead and keep DuckyClaw-specific patches as build-time source overlays under overlay/ai_components/. CMakeLists.txt grows a _dc_overlay_source() helper that surgically swaps the upstream translation units (ai_mcp_server.c, ai_agent.c, ai_chat_main.c, ai_audio_input.c) inside the ai_mcp / ai_agent / ai_main / ai_audio library targets after TuyaOpen has processed them. The submodule stays pristine; only this app's CMake graph diverges. Kconfig grows DUCKYCLAW_USE_AI_COMPONENTS (selects ENABLE_AI_COMPONENTS) and DUCKYCLAW_USE_EXT_RAM (selects ENABLE_EXT_RAM). The latter is the app-side opt-in for PSRAM on boards whose upstream Kconfig doesn't select ENABLE_EXT_RAM on their own (e.g. ESP32S3_BREAD_COMPACT_WIFI), so DuckyClaw can land in PSRAM without patching the submodule. src/tuya_app_main.c: pin tuya_app_main thread stack to internal SRAM (psram_mode=0) and drop the T5-specific tkl_system_psram_malloc_force_set. ESP-SR's flash-pause path asserts esp_task_stack_is_sane_cache_disabled() which fails on PSRAM stacks (IDF cache_utils.c). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
DuckyClaw's binary carries ~77 KiB more internal SRAM .bss than the chatbot reference (heap_init main segment 167 KiB vs 251 KiB), almost all from a handful of large static arrays in app-level code: gateway/acp_client.c s_ctx ~48 KiB gateway/ws_server.c s_clients[N].rx_buf ~16 KiB IM/channels/feishu_bot.c dedup ring × 2 ~8 KiB IM/channels/weixin_bot.c s_get_updates_buf 4 KiB IM/channels/qqbot/telegram dedup rings ~1 KiB PSRAM-allocate them at init via claw_malloc / im_calloc (which fall back to tal_malloc when ENABLE_EXT_RAM is off), and add Kconfig knobs so each size can be tuned per-board. acp_client_init() and the IM bot init functions own the allocations; ws_clients_init() keeps the pointer across ws_reset_client() so resets don't leak. New Kconfig (gateway/Kconfig, IM/Kconfig): ACP_CLIENT_RX_BUF_SIZE (default 8 KiB) ACP_CLIENT_WS_MSG_BUF_SIZE (default 32 KiB) ACP_CLIENT_REPLY_BUF_SIZE (default 8 KiB) CLAW_WS_MAX_CLIENTS (default 4) CLAW_WS_CLIENT_RX_BUF_SIZE (default 4 KiB) IM_WX_UPDATES_BUF_SIZE (default 4 KiB) IM_FS_DEDUP_CACHE_SIZE (default 512 entries) IM_TG_DEDUP_CACHE_SIZE (default 64 entries) IM_QQ_DEDUP_CACHE_SIZE (default 64 entries) All migrated paths add NULL guards against alloc failure. sizeof(buf) references that previously returned the array size are replaced with the Kconfig macro now that the field is a pointer. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
… into PSRAM
Bring DuckyClaw board configs in line with TuyaOpen
apps/tuya.ai/your_chat_bot/config/* where chatbot turns on board-level
features DuckyClaw was silently missing. Skip chatbot's app-specific
fields (PROJECT_VERSION, TUYA_PRODUCT_ID, AI_CHAT_GUI_OLED on boards
where we intentionally disable display, etc.).
ESP32S3_BREAD_COMPACT_WIFI.config
+ ENABLE_AI_CHAT_GUI_OLED + AI_CHAT_GUI_OLED_SIZE_128_32
+ ENABLE_BUTTON + BUTTON_NAME="ai_chat_button"
+ DUCKYCLAW_USE_EXT_RAM=y (was a dead CONFIG_ENABLE_EXT_RAM=y;
ENABLE_EXT_RAM is promptless in upstream
Kconfig, so the .config entry was a no-op)
- dropped legacy "# CONFIG_ENABLE_COMP_AI_DISPLAY is not set" comment
TUYA_T5AI_BOARD_LCD_3.5_CAMERA.config
TUYA_T5AI_BOARD_LCD_3.5_CAMERA(NO_SDCARD).config
ATK_T5AI_MINI_BOARD_2.4LCD_CAMERA.config
+ ENABLE_COMP_AI_PICTURE (camera boards; mirrors chatbot)
WAVESHARE_T5AI_TOUCH_AMOLED_1_75.config
+ ENABLE_BATTERY (board has battery hw)
+ DISPLAY_DEFAULT_BRIGHTNESS=80
DshanPi_A1.config
+ ALSA_DEVICE_CAPTURE / ALSA_DEVICE_PLAYBACK (audio routing)
TUYA_T5AI_CORE.config
- drop stale LVGL_ENABLE_TP (board has no touch panel)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…n ATK
Two unrelated regressions surfaced on T5AI builds; both stem from
the same upstream WeChat-UI integration.
1. Runtime NULL deref on T5 in tuya_app_main thread, looked like a
BLE init crash but addr2line resolves the PC to:
lv_obj_get_scrollbar_mode (lv_obj_scroll.c:94)
<< inlined in lv_obj_remove_flag (lv_obj.c:159)
<< called from __ui_init (wechat/ai_ui_chat_wechat.c:160-162)
<< scheduled via tal_sw_timer from
__ai_chat_ui_stream_text_disp (ai_ui_manage.c:499)
<< ai_ui_stream_text_init (ai_ui_stream_text.c:195)
The stream-text timer fires before lv_vendor_init() has registered
the LVGL display, so lv_scr_act() returns NULL and the very first
lv_obj_clear_flag(NULL, …) faults. Chatbot's per-board configs
never set ENABLE_AI_UI_TEXT_STREAMING. Match that — drop the
option from all 5 DuckyClaw T5 board configs.
2. ATK_T5AI_MINI_BOARD_2.4LCD_CAMERA build failed with
-Werror=unused-function on __popup_camera_cb / __popup_album_cb /
__popup_add_img_cb in ai_ui_wechat_chat.c. The defs are gated on
ENABLE_COMP_AI_VIDEO / ENABLE_IMAGE_ALBUM; the call sites are
gated on ENABLE_LVGL_TP. ATK had ENABLE_LVGL_TP=y in .config but
the symbol lives under `if(ENABLE_LIBLVGL)` in upstream Kconfig,
and ATK was missing CONFIG_ENABLE_LIBLVGL=y — so the call sites
silently dropped while the defs stayed, tripping unused-function.
Add CONFIG_ENABLE_LIBLVGL=y + CONFIG_ENABLE_AI_CHAT_GUI_WECHAT=y
so ATK matches the other DuckyClaw camera configs.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
DuckyClaw's two T5 camera configs were referencing Kconfig symbols
that don't exist in upstream TuyaOpen:
CONFIG_TUYA_T5AI_BOARD_EX_MODULE_35565LCD=y ← undefined symbol
CONFIG_ENABLE_EX_MODULE_CAMERA=y ← undefined symbol
Kconfig silently dropped them. Upstream `boards/T5AI/TUYA_T5AI_BOARD/`
exposes:
TUYA_T5AI_BOARD_LCD_35565 bool -> select ENABLE_DISPLAY + ENABLE_TP
+ ENABLE_LVGL_OS_FREERTOS
+ ENABLE_LVGL_DUAL_DISP_BUFF
TUYA_T5AI_BOARD_CAMERA bool -> select ENABLE_CAMERA
`boards/T5AI/TUYA_T5AI_BOARD/tuya_t5ai_ex_module.c:36` wraps the entire
`__board_register_display` (which calls `tdd_disp_rgb_ili9488_register
(DISPLAY_NAME, …)` and `tdd_tp_i2c_gt1151_register(…)`) in:
#if defined(TUYA_T5AI_BOARD_LCD_35565) && (TUYA_T5AI_BOARD_LCD_35565==1)
Because our .config used the wrong symbol, ENABLE_DISPLAY was never
selected and the entire registration block compiled out. At runtime:
board_register_hardware() -> ok (audio + button only)
ai_chat_init -> ai_chat_ui_init
-> ai_ui_init (ai_ui_manage.c:540)
-> sg_ui_intfs.disp_init() = wechat __ui_init
-> lv_vendor_init("display")
-> lv_port_disp_init
-> tdl_disp_find_dev("display") returns NULL
-> silent return, lv_vendor_initialized = true anyway
-> lv_obj_clear_flag(lv_scr_act(), …)
^^^^^^^^^^^^ NULL ← MemFault, MMFAR=0x8
-> lv_obj_remove_flag(NULL,…)
Switching to the real upstream symbol names makes the board's display
+ touch + camera all register properly, so LVGL can find a default
display and wechat UI's __ui_init stops crashing.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Systematic sweep of all DuckyClaw .config files against the union of Kconfig declarations reachable from DuckyClaw's root Kconfig turned up one remaining orphan: ENABLE_BATTERY is only declared in TuyaOpen/apps/tuya.ai/your_chat_bot/Kconfig (chatbot app's own Kconfig), which DuckyClaw doesn't `source`. The .config entry was silently dropped by Kconfig and never reached tuya_kconfig.h. Additionally, DuckyClaw has no `app_battery_init` call to gate on ENABLE_BATTERY, so even if the macro propagated, no app code would react. Drop the dead line. Verified clean against the full Kconfig tree: 47 CONFIG_*=y / =string entries used across all 9 .config files + 4 `# CONFIG_* is not set` entries → 0 orphans against 993 declared Kconfig symbols. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…ai_mcp The DuckyClaw-side patches in overlay/ai_components/ai_audio/ and overlay/ai_components/ai_main/ have shrunk to non-functional differences (comment-only / single-line init) — consume upstream directly instead. What remains in overlay/ are the two libs with real DuckyClaw-specific API surface: ai_agent (TTS suppression, AI_USER_EVT_END hook) and ai_mcp (MCP_TOOL_EXEC_HOOK_CB / ai_mcp_server_set_tool_exec_hook). For symmetry the ai_agent overlay now ships its public header too — overlay/ai_components/ai_agent/include/ai_agent.h — and CMakeLists.txt applies the BEFORE-PUBLIC + BEFORE-PRIVATE prepend pattern to both ai_mcp and ai_agent via a small foreach loop. Also bump TuyaOpen submodule to upstream master (7f83f06a → 2d1b79b2, "Fixed esp32s3 ext psram config"); board configs picked up a few app-side tweaks while open (re-enable ENABLE_AI_UI_TEXT_STREAMING on the four T5 boards that want streaming chat display), and src/tuya_app_main.c trims two stale comment lines. Net diff: −930 / +114. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
shiliu-yang
approved these changes
Jun 25, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
ai_components/withTuyaOpen/src/ai_componentsupstream, preserving all DuckyClaw-specific featuresyour_chat_botreference and adds an app-levelDUCKYCLAW_USE_EXT_RAMKconfig opt-inKey Upstream Changes Adopted
CMakeLists.txtCOMPONENT_LIBS/COMPONENT_PUBINC)ai_mcpparse_message+MCP_SEND_MESSAGE_CBgainsid/eidsession routing paramsai_agentAI_PT_IMAGEbranch →ai_picture_output_save_to_albumai_pictureai_picture.h,ai_picture_input.h); old HTTP-pull stubs kept for compatai_uiai_videoai_video_init()→ void; flush cb viaai_video_set_yuv_frame_flush_cb()ai_modeassetsutilityAI_USER_EVT_TYPE_Eai_components Overlay (
refactor(ai_components))The local
ai_components/directory is dropped; the build now consumesTuyaOpen/src/ai_components/directly. DuckyClaw-specific patches live underoverlay/ai_components/and are spliced into the upstream library targets at CMake configure time by a_dc_overlay_source()helper inCMakeLists.txt. The TuyaOpen submodule stays pristine — only this app's CMake graph diverges.Two new Kconfig opt-ins (root
Kconfig):DUCKYCLAW_USE_AI_COMPONENTS→select ENABLE_AI_COMPONENTSDUCKYCLAW_USE_EXT_RAM→select ENABLE_EXT_RAM(some upstream board Kconfigs, e.g.ESP32S3_BREAD_COMPACT_WIFI, don't select this themselves; the app side now does, no submodule patch needed)PSRAM .bss Refactor (
perf(ram))heap_initmain segment grew from chatbot's 251 KiB to DuckyClaw's 167 KiB — ~84 KiB of extra.bsswas crowding internal SRAM, causing WiFi softAP buffer alloc failures at BIND time. The biggest contributors are now moved to PSRAM heap viaclaw_malloc/im_callocat init time, falling back total_mallocwhenENABLE_EXT_RAMis off:s_ctx(acp_client)gateway/acp_client.cs_clients[N].rx_bufgateway/ws_server.cdedup ring × 2IM/channels/feishu_bot.cs_get_updates_bufIM/channels/weixin_bot.cs_seen_msg_keys× 2IM/channels/{qqbot,telegram}_*Each buffer size is now a Kconfig knob (
ACP_CLIENT_RX_BUF_SIZE,ACP_CLIENT_WS_MSG_BUF_SIZE,ACP_CLIENT_REPLY_BUF_SIZE,CLAW_WS_MAX_CLIENTS,CLAW_WS_CLIENT_RX_BUF_SIZE,IM_WX_UPDATES_BUF_SIZE,IM_FS_DEDUP_CACHE_SIZE,IM_TG_DEDUP_CACHE_SIZE,IM_QQ_DEDUP_CACHE_SIZE) so tight-SRAM boards can scale them down (the ESP32-S3 BREAD config trims them).src/tuya_app_main.calso pins thetuya_app_mainthread stack to internal SRAM (psram_mode=0) — ESP-SR's flash-pause path assertsesp_task_stack_is_sane_cache_disabled()which fails on PSRAM stacks.Board Config Alignment (
chore(config))Brought DuckyClaw board configs in line with
TuyaOpen/apps/tuya.ai/your_chat_bot/config/*for board-level features that were silently missing (skipped chatbot's app-specific fields likePROJECT_VERSION,TUYA_PRODUCT_ID):ESP32S3_BREAD_COMPACT_WIFI: +ENABLE_AI_CHAT_GUI_OLED+AI_CHAT_GUI_OLED_SIZE_128_32+ENABLE_BUTTON+BUTTON_NAME+DUCKYCLAW_USE_EXT_RAM=y; dropped deadCONFIG_ENABLE_EXT_RAM=y(promptless, was a no-op)TUYA_T5AI_BOARD_LCD_3.5_CAMERA(NO_SDCARD)/*_CAMERA/ATK_T5AI_MINI_BOARD_2.4LCD_CAMERA: +ENABLE_COMP_AI_PICTUREWAVESHARE_T5AI_TOUCH_AMOLED_1_75: +ENABLE_BATTERY+DISPLAY_DEFAULT_BRIGHTNESS=80DshanPi_A1: +ALSA_DEVICE_CAPTURE+ALSA_DEVICE_PLAYBACKDuckyClaw Features Preserved
MCP_TOOL_EXEC_HOOK_CB/ai_mcp_server_set_tool_exec_hook— agent loop tool captureai_user_event_notify(AI_USER_EVT_END)inAI_EVENT_END— semaphore signal for inner loopai_agent_set_tts_suppressed()— TTS suppression APIAI_USER_EVT_VIDEO_DISPLAY_START/END— video pipeline events (numeric positions preserved)AI_VIDEO_MALLOC/FREEmacros + V4L2 camera format conditional (Raspberry Pi)ai_ui_icon_fontBugs Fixed (Opus 4.7 Code Review)
agent/agent_loop.c:482|| call_okin break condition inverted loop — tool loop only continued on failure, never on success; multi-step tool chains were impossibleai_video/include/ai_video_input.hai_video_display_start/stopconflicted with wrapper function definitions in the.cfile (compile error)src/ducky_claw_chat.c:272–277ai_video_init(&cfg)with removedAI_VIDEO_CFG_Tstruct (3 compile errors); flush callback never registered — fixed by callingai_video_set_yuv_frame_flush_cb()src/ducky_claw_chat.c:111ai_ui_camera_flushcalled with 3 scalar args; new API takesAI_UI_VIDEO_T*src/ducky_claw_chat.c:143ai_ui_disp_picturesymbol removed upstream; call removed (picture display migration to album API is a TODO)src/tuya_app_main.c:231UI_WIFI_STATUS_Erenamed toAI_UI_WIFI_STATUS_Eai_video/src/ai_video_input.c:210ai_mcp/src/ai_mcp_server.c:150mm_strdupon string property default;ai_mcp_property_set_default_stralready strdup'dTest Plan
cp config/RaspberryPi.config app_default.config && tos.py build)cp config/TUYA_T5AI_BOARD_LCD_3.5_CAMERA.config app_default.config && tos.py build)cp config/ESP32S3_BREAD_COMPACT_WIFI.config app_default.config && tos.py build)heap_initmain segment grew from ~167 KiB → ~243 KiB; BIND_START Free heap ≥ 40 KiB (was 10 KiB)alloc eb len=752 failand BIND completesread_file→ reasoning → response)🤖 Generated with Claude Code