Refactor/log media sampler - #40
Merged
Merged
Conversation
heshaoqiong-tuya
marked this pull request as draft
September 20, 2026 06:04
heshaoqiong-tuya
force-pushed
the
refactor/log-media-sampler
branch
from
September 20, 2026 07:41
5caba79 to
399e6f6
Compare
heshaoqiong-tuya
marked this pull request as ready for review
September 20, 2026 07:41
heshaoqiong-tuya
added a commit
that referenced
this pull request
Sep 20, 2026
- Tag the compile-time-ceiling entry (#40) and record the packet-log sink selection under it. - Backfill (#35) on the five entries that landed through the ble-pair-improve2 follow-up. - Drop the last two (PR pending) markers: 7e07e35 (docs-site English) and 2afba8f (tuya-ble dedup) entered master without a PR -- via a local eng-doc merge and a direct push respectively. Co-Authored-By: Claude Code <[email protected]>
heshaoqiong-tuya
force-pushed
the
refactor/log-media-sampler
branch
from
September 20, 2026 08:14
399e6f6 to
9082201
Compare
heshaoqiong-tuya
added a commit
that referenced
this pull request
Sep 20, 2026
- Tag the compile-time-ceiling entry (#40) and record the packet-log sink selection under it. - Backfill (#35) on the five entries that landed through the ble-pair-improve2 follow-up. - Drop the last two (PR pending) markers: 7e07e35 (docs-site English) and 2afba8f (tuya-ble dedup) entered master without a PR -- via a local eng-doc merge and a direct push respectively. Co-Authored-By: Claude Code <[email protected]>
heshaoqiong-tuya
force-pushed
the
refactor/log-media-sampler
branch
from
September 20, 2026 09:56
9082201 to
b1ad492
Compare
heshaoqiong-tuya
added a commit
that referenced
this pull request
Sep 20, 2026
- Tag the compile-time-ceiling entry (#40) and record the packet-log sink selection under it. - Backfill (#35) on the five entries that landed through the ble-pair-improve2 follow-up. - Drop the last two (PR pending) markers: 7e07e35 (docs-site English) and 2afba8f (tuya-ble dedup) entered master without a PR -- via a local eng-doc merge and a direct push respectively. Co-Authored-By: Claude Code <[email protected]>
heshaoqiong-tuya
force-pushed
the
refactor/log-media-sampler
branch
from
September 20, 2026 10:34
b1ad492 to
243e61b
Compare
heshaoqiong-tuya
marked this pull request as draft
September 20, 2026 11:08
heshaoqiong-tuya
added a commit
that referenced
this pull request
Sep 20, 2026
The one open-source idiom the facade was missing. The runtime log_set_handler() sink hands the customer fmt + va_list, and a va_list cannot be forwarded to a macro — so bridging into macro-based logging systems (ESP-IDF ESP_LOGx, Zephyr LOG_*) forced a vsnprintf-into-buffer, "%s"-back-out round trip: an extra copy, an extra truncation point, and the target macro's format checking lost. lwIP's LWIP_PLATFORM_DIAG and mbedTLS's printf-macro config are this mechanism; the facade now has it too. AGENTIC_KIT_LOG(level, tag, fmt, ...) is the one remap point, guarded by #ifndef right after the ceiling so it rides the existing integrator pickup (the same agentic_kit_config.h / -D / AGENTIC_KIT_USER_CONFIG channel as every knob — zero new mechanism). log_tag_* become thin forwarders, so one definition takes over the whole SDK (iot-client's log_error family, TAI_LOG*, TUYA_BLE_HAL_LOG* all funnel through log_tag_*), and the customer receives the tag as its own token — structured sinks and per-tag filtering become possible where the handler only ever saw the tag folded into the format string. Ground rules, binding both directions: the AGENTIC_KIT_LOG_LEVEL ceiling still gates (log_tag_* collapse to ((void)0) above it, so a remap cannot resurrect compiled-out lines and their arguments are never evaluated); a remap bypasses log_emit, so log_set_handler() no longer sees those lines — pick one per build. The default expansion is byte-identical to the previous direct log_emit call, keeping its format(printf) checking. Documents the mechanism in the knobs guide (zh+en, new anchor-checked section), the CHANGELOG #40 entry, and the two public headers' logging notes. The runtime handler stays — this is an addition, not a replacement. Verified: a pickup probe through agentic_kit_config.h (level-4 build sees info dispatched into the customer macro with the bare tag; a LEVEL=1 build compiles a struct-argument debug call site — arguments unevaluated — and the sink never sees info); full host build including examples; the CI leak grep clean; ctest 17/17; the docs-site builds clean in both locales (check:i18n included). Co-Authored-By: Claude Code <[email protected]>
heshaoqiong-tuya
added a commit
that referenced
this pull request
Sep 20, 2026
- Tag the compile-time-ceiling entry (#40) and record the packet-log sink selection under it. - Backfill (#35) on the five entries that landed through the ble-pair-improve2 follow-up. - Drop the last two (PR pending) markers: 7e07e35 (docs-site English) and 2afba8f (tuya-ble dedup) entered master without a PR -- via a local eng-doc merge and a direct push respectively. Co-Authored-By: Claude Code <[email protected]>
heshaoqiong-tuya
force-pushed
the
refactor/log-media-sampler
branch
from
September 20, 2026 12:07
bd05c05 to
f4fb70e
Compare
heshaoqiong-tuya
added a commit
that referenced
this pull request
Sep 20, 2026
- Tag the compile-time-ceiling entry (#40) and record the packet-log sink selection under it. - Backfill (#35) on the five entries that landed through the ble-pair-improve2 follow-up. - Drop the last two (PR pending) markers: 7e07e35 (docs-site English) and 2afba8f (tuya-ble dedup) entered master without a PR -- via a local eng-doc merge and a direct push respectively. Co-Authored-By: Claude Code <[email protected]>
heshaoqiong-tuya
force-pushed
the
refactor/log-media-sampler
branch
from
September 20, 2026 12:25
f4fb70e to
15021f5
Compare
heshaoqiong-tuya
added a commit
that referenced
this pull request
Sep 20, 2026
- Tag the compile-time-ceiling entry (#40) and record the packet-log sink selection under it. - Backfill (#35) on the five entries that landed through the ble-pair-improve2 follow-up. - Drop the last two (PR pending) markers: 7e07e35 (docs-site English) and 2afba8f (tuya-ble dedup) entered master without a PR -- via a local eng-doc merge and a direct push respectively. Co-Authored-By: Claude Code <[email protected]>
heshaoqiong-tuya
force-pushed
the
refactor/log-media-sampler
branch
from
September 20, 2026 12:36
15021f5 to
f4935a2
Compare
heshaoqiong-tuya
added a commit
that referenced
this pull request
Sep 21, 2026
- Tag the compile-time-ceiling entry (#40) and record the packet-log sink selection under it. - Backfill (#35) on the five entries that landed through the ble-pair-improve2 follow-up. - Drop the last two (PR pending) markers: 7e07e35 (docs-site English) and 2afba8f (tuya-ble dedup) entered master without a PR -- via a local eng-doc merge and a direct push respectively. Co-Authored-By: Claude Code <[email protected]>
heshaoqiong-tuya
force-pushed
the
refactor/log-media-sampler
branch
from
September 21, 2026 06:55
f4935a2 to
321acb1
Compare
…emap
The log refactor landed as two stages, squashed here: first the
SDK-wide compile-time ceiling, then the macro-only destination remap
that removes the last runtime log state. End state: the level is a
compile-time fact, the destination is a compile-time fact, and what
compiles in is what emits.
Stage 1 -- compile-time-only logging across the SDK:
One SDK-wide compile-time log ceiling, AGENTIC_KIT_LOG_LEVEL (0-4,
default 4), gates every SDK log macro via the log_tag_* facade in
common/log.h; module code no longer calls log_emit() directly and CI
rejects new raw call sites.
- BREAKING -DTAI_LOG_LEVEL=N (rtc-tcp-client only) and the dead
-DLOG_LEVEL move to -DAGENTIC_KIT_LOG_LEVEL=N, which now silences
the whole SDK at compile time.
- BREAKING the runtime log layer is removed: log_set_level(),
log_get_level() and the tai_set_log_level()/tai_get_log_level()
wrappers are gone, and log_emit() no longer filters -- the ceiling is
the only level gate, so what compiles in is what emits. Migrate
runtime log_set_level(N) calls to a lower ceiling at build time, or
to a level-dropping handler installed with log_set_handler().
- rtc-tcp-client packet logging selects its INFO/DEBUG sink at compile
time (sampling builds have exactly one level; flood mode needs
AGENTIC_KIT_TAI_LOG_MEDIA_SAMPLE_N=0 plus a DEBUG ceiling) and its
JSON formatter compiles out below INFO. A compile-matrix test builds
every supported level x sampling combination.
Stage 2 -- AGENTIC_KIT_LOG, macro-only remap for the log dispatch:
The one open-source idiom the facade was missing, and the follow-
through that makes it the only way in. A va_list cannot be forwarded
to a macro, so bridging the old runtime handler into macro-based
logging systems (ESP-IDF ESP_LOGx, Zephyr LOG_*) forced a
vsnprintf-into-buffer, "%s"-back-out round trip: an extra copy, an
extra truncation point, and the target macro's format checking lost.
lwIP's LWIP_PLATFORM_DIAG and mbedTLS's printf-macro config are this
mechanism; the facade now has it -- as the single dispatch point.
AGENTIC_KIT_LOG(level, tag, fmt, ...) is guarded by #ifndef right
after the ceiling so it rides the existing integrator pickup (the
same agentic_kit_config.h / -D / AGENTIC_KIT_USER_CONFIG channel as
every knob -- zero new mechanism). log_tag_* become thin forwarders,
so one definition takes over the whole SDK (iot-client's log_error
family, TAI_LOG*, TUYA_BLE_HAL_LOG* all funnel through log_tag_*),
and the customer receives the bare module tag as its own token --
structured sinks and per-tag filtering become possible where the
handler only ever saw it folded into the format string. Ground
rules: the AGENTIC_KIT_LOG_LEVEL ceiling still gates (log_tag_*
collapse to ((void)0) above it, arguments never evaluated), and the
remap must reach every target that compiles SDK sources -- there is
no runtime dispatch left to fall back on.
Because there is none: log_set_handler(), log_fn_t and the public
log_default_handler() are gone, and the SDK holds no mutable log
state at all (the benign-race handler pointer included). What varied
at runtime via handler install/uninstall becomes a mode inside the
one sink a build names; a sink implemented as a variadic function
reaches the new log_emit_valist() (the esp_log_writev role) to reuse
the default stderr output instead of re-implementing it.
Tests migrated to the same shape they now prescribe to integrators:
each test build's log_config/agentic_kit_config.h remaps
AGENTIC_KIT_LOG into one test_log_sink whose PASSTHROUGH / CAPTURE /
QUIET / COUNT are modes, not handler swaps -- test_core counts
through it, mqtt/atop capture through it (tag prefix rebuilt,
va_copy and truncation discipline carried over), test_prov goes
quiet through it, test_wire scans the captured window, and
tai_pal_loopback's lb_log env gate folds into test_log_env_default
(TAI_LOOPBACK_VERBOSE keeps its name and default-silent behavior).
The wiring lesson that shaped the CMake side: the vendored
coreHTTP/coreMQTT sources route their logs into the facade via
common/core_{http,mqtt}_config.h, so they are part of the SDK's
logging surface -- compiled outside the remap their lines bypass the
sink (exactly what a runtime handler used to catch
library-agnostically). The tuya_iot_client_testlog variant therefore
compiles them in alongside the iot sources; the ble sources compile
into the test executable the same way. The plain tuya_iot_client,
core_http and core_mqtt targets are untouched -- the examples' link
path and output are byte-identical.
The ESP-IDF pair-by-ble example drops its runtime callback for the
macro: kit_opts/agentic_kit_config.h maps the facade onto
ESP_LOG_LEVEL_LOCAL with a compile-time level ternary, and each line
keeps its real module tag instead of one shared "tuya_ble" tag.
Docs follow in both locales (destination is a compile-time fact),
plus the public header notes and the CHANGELOG BREAKING entry.
Verified: pickup probes at both ceilings against the final log.c;
full host build including examples; the CI leak grep clean; ctest
17/17 serial (capture assertions included); TAI_LOOPBACK_VERBOSE
gate (0 stderr lines by default, 742 with it set); docs-site builds
in both locales.
Docs-audit fold (usage/impact round, zh+en): the architecture
page's common-components table gains the log-facade row (common/log.h
+ common/log.c); the agent-trigger tutorial's -v row matches the
binary -- it prints a compile-time notice, not a runtime switch; the
rtc-client reference scopes its on_log / stm_open_set_log_level
runtime logging outside the compile-time facade (prebuilt library,
not compiled from source); and the log.h remap comment lists the tags
actually emitted -- the "tai" tag never existed, rtc-tcp-client
passes per-source-file tags.
Co-Authored-By: Claude Code <[email protected]>
The iot-client call-site vocabulary was the only log family in the
SDK without a module prefix (log_error/log_warn/log_info/log_debug)
and the only one that is neither public API nor porting contract --
private sugar squatting on generic names. Two costs, one already
realized: the names read like facade API (common/log.h owns
log_tag_*; nothing named log_error exists for a reader), and they
leaked into integrator-facing samples (the iot_atop.h doc comment
and the atop-generic-call guide taught log_error(...) -- a macro
that lives in src-private iot_internal.h and never compiled for
integrators).
Renamed to IOT_LOGE/LOGW/LOGI/LOGD, matching the module-prefix
convention the other vocabularies already follow (TAI_LOG*,
TUYA_BLE_HAL_LOG*), fixed tag "iot", 1:1 level mapping unchanged --
a pure rename, zero behavior change: 342 call sites across 14 src
files, plus the prose that names the family (common/log.h ceiling
comments, AGENTS.md scenarios and the log-gate note, the
compile-time-knobs guide zh+en), and the sample logging follows: the
iot_atop_call() example (header doc comment + atop-generic-call
guide, both locales) now logs through the public log_tag_error("app",
...) facade instead of the src-private log_error() -- not IOT_LOGE,
which is src-private too (iot_internal.h): a copied sample teaching
either never compiled from an iot_atop.h-only TU (docs-audit round,
compile-probe: IOT_LOGE undeclared, log_tag_error clean under -Wall
-Wextra -Werror). The error-path comment notes the facade is callable
from application code and shares the SDK's compile-time ceiling and
dispatch.
Also reworded one iot_internal.h comment ("reads exactly like
printf().") that matched the CI leak-grep pattern in .gitlab-ci.yml
as a false positive and would have failed the pipeline.
Verified: full rebuild clean; serial ctest 17/17; leak grep clean;
docs-site builds in both locales.
Co-Authored-By: Claude Code <[email protected]>
…_LEVEL Quiet one module without touching the SDK-wide AGENTIC_KIT_LOG_LEVEL: iot-client can run at info while rtc-tcp-client stays at debug. Each knob lives in its module's *_config_defaults.h, #ifndef-defaults to the global ceiling, and is lower-only (effective ceiling = min(global, module)) because the facade gate in log.h still applies -- a remap can never resurrect a compiled-out line. Each config file additionally clamps its knob to the SDK-wide ceiling right after the #ifndef default, so gates keyed on the knob alone also see the effective ceiling: the TAI block-level gates (the packet-log formatter, the flood branch, the tai_log_packet call sites) and tuya-ble's HEXDUMP body would otherwise compile dead code back in when the module value sits above the global -- a 19KB formatter with per-packet work behind ((void)0) dispatches, and -Werror builds broke on unused variables inside the resurrected branches. With the clamp, a too-high value is a true no-op at every gate. Default builds stay byte-identical (verified by strip-comparing every object against a stashed baseline, before and after the clamp). - iot-client / rtc-tcp-client: gate the IOT_LOG* / TAI_LOG* vocabularies where they are defined, plus the six TAI module-internal direct gate sites - tuya-ble: first knob via new include/tuya_ble_config_defaults.h; gate the HAL rebind in tuya_ble_internal.h (LOGI dispatches at debug, so its ceiling is 4, not 3) - tests: tai_log_module_zero_tests proves the facade still dispatches while only the module is lowered; the pkt-log compile matrix gains a tai_level dimension plus module-above-global clamp probes (19 combos asserting a knob above the global compiles exactly as the lower global ceiling alone would) - -Wextra: log-only parameters that turn unused under a lowered module ceiling get (void) suppressions (tai_transport x2, tuya_ble_prov, iot_on_boarding) -- integrator -Wextra -Werror builds stay clean - docs: compile-time-knobs zh+en (22 knobs), module references zh+en, AGENTS.md, CHANGELOG, and the porting guide names tuya-ble's knob and defaults file Verified: ctest 18/18 serial; (global 2, module 4) compiles tai_pkt_log.c to the same empty 336-byte object as global 2 alone, zero formatter symbols, -Wall -Wextra -Werror clean; tuya-ble preprocessed output with the module raised is byte-identical to the default. Docs-audit fold (usage/impact round, zh+en): the knobs guide's AGENTIC_KIT_LOG example compiles as printed (the real level-mapping ternary, no undefined lvl_of()), the tag list matches the emitted tags, and a function-sink example shows log_emit_valist() takes no tag -- the macro folds "[tag] " into the format string or every line loses its prefix; the rtc-tcp-client reference documents the flood recipe (SAMPLE_N=0 + DEBUG ceiling) and the trap that ceiling 3 with sampling 0 leaves middle frames with no logs at all. Co-Authored-By: Claude Code <[email protected]>
- .gitlab-ci.yml: tai_log_module_zero_tests joins the valgrind loop (AGENTS.md invariant: every no-subprocess binary gets leak-checked) - CMakeLists.txt: the matrix comment said eight configurations; it has been sixteen since the tai_level dimension -- now it also names the two sweeps - AGENTS.md: drop the stale "runtime-chosen level" media-sampler sentence: sampling builds have exactly one level and no runtime level comparison exists anywhere - core_mqtt_config.h: the same-shape cross-reference points at core_http_config.h; the iot_client_config_defaults.h log_* family it named no longer exists - CHANGELOG + PR draft: the "every supported level x sampling combination" overclaim becomes the 16 combinations actually built ctest 17/18 serial -- iot_ota_verify_test timed out under load from a concurrent review job; it is a 0.01 s test and passes in isolation. Co-Authored-By: Claude Code <[email protected]>
- Tag the compile-time-ceiling entry (#40) and record the packet-log sink selection under it. - Backfill (#35) on the five entries that landed through the ble-pair-improve2 follow-up. - Drop the last two (PR pending) markers: 7e07e35 (docs-site English) and 2afba8f (tuya-ble dedup) entered master without a PR -- via a local eng-doc merge and a direct push respectively. - Fix the flood knob's spelling in the #40 entry: AGENTIC_KIT_LOG_MEDIA_SAMPLE_N -> AGENTIC_KIT_TAI_LOG_MEDIA_SAMPLE_N (docs-audit round; the missing TAI_ segment defined a dead macro and silently kept 1/50 sampling). Co-Authored-By: Claude Code <[email protected]>
heshaoqiong-tuya
force-pushed
the
refactor/log-media-sampler
branch
from
September 21, 2026 09:12
321acb1 to
d52dccb
Compare
heshaoqiong-tuya
marked this pull request as ready for review
September 21, 2026 09:21
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
Five commits finish the log refactor. End state: the SDK holds no runtime log state at all — the level is a compile-time ceiling (one SDK-wide, optionally lowered per module), the destination is a compile-time macro, and what compiles in is what emits.
a7c0369feat(log)!: compile-time-only logging + AGENTIC_KIT_LOG destination remap — one SDK-wide ceilingAGENTIC_KIT_LOG_LEVEL(0–4, default 4) gates every SDK log macro via the newlog_tag_*facade incommon/log.h; module code no longer callslog_emit()directly and CI rejects new raw call sites. rtc-tcp-client packet logging picks its INFO/DEBUG sink at compile time (sampling builds have exactly one level; flood mode needsAGENTIC_KIT_TAI_LOG_MEDIA_SAMPLE_N=0plus a DEBUG ceiling) and its JSON formatter compiles out below INFO — a compile-matrix test sweeps the level × sampling combinations. On top of that,#define AGENTIC_KIT_LOG(level, tag, fmt, ...)is the single destination switch, riding the same integrator pickup as every knob (agentic_kit_config.h/-D/AGENTIC_KIT_USER_CONFIG, first-definition-wins). This is the idiom lwIP (LWIP_PLATFORM_DIAG) and mbedTLS offer: bridging intoESP_LOGx/ZephyrLOG_*no longer needs a vsnprintf-into-buffer round trip, format checking stays in the target macro, and the sink receives the module tag as its own token (per-tag filtering and structured sinks become possible).log_set_level()/log_get_level(), thetai_*_log_level()wrappers,log_set_handler(),log_fn_tand the publiclog_default_handler()are all gone; a sink written as a function reuses the default stderr output via the newlog_emit_valist()(theesp_log_writevrole). The docs-audit round is folded in here where it owns the prose: the architecture page's common table lists the log facade, the agent-trigger-vrow matches the binary (a compile-time notice, not a runtime switch), the rtc-client reference scopes its runtime logging outside the compile-time facade, and the log.h comment names the tags actually emitted.42591a3refactor(iot): log_error family -> IOT_LOG* — iot-client's unprefixedlog_error/log_warn/log_info/log_debugbecomeIOT_LOGE/LOGW/LOGI/LOGD, following the module-prefix convention of the other private vocabularies (TAI_LOG*,TUYA_BLE_HAL_LOG*). Pure rename over 342 call sites; prose in log.h / AGENTS.md / the knobs guide synced, and theiot_atop_call()sample (header + atop-generic-call guide, both locales) now logs through the publiclog_tag_error("app", ...)facade instead of the src-privatelog_error()— notIOT_LOGE, which is src-private too, so the copied sample never compiled from aniot_atop.h-only TU (compile-probed in the docs-audit round). The old names read like facade API and had already leaked into integrator-facing samples.41723f1feat(log): per-module log ceilingsAGENTIC_KIT_{IOT,TAI,TUYA_BLE}_LOG_LEVEL— quiet one module without touching the SDK-wide ceiling (iot-client at info while rtc-tcp-client stays debug). Each knob lives in its module's*_config_defaults.h,#ifndef-defaults to the global ceiling, and is lower-only (effective ceiling = min(global, module), clamped to the global once in the module's config file so block-level gates see the effective ceiling); the facade gate still applies, so a remap can never resurrect a compiled-out line. The clamp closes the hole the adversarial-verify review round caught: block-level gates (the packet-log formatter, the flood branch, tuya-ble's HEXDUMP body) keyed on the knob alone, so a module value above the global ceiling compiled dead code back in (a 19KB formatter behind((void)0)dispatches,-Werrorbreaks). tuya-ble gains its first knob and itstuya_ble_config_defaults.h. Tests:tai_log_module_zero_testskeeps probing the facade while only the module is lowered; the compile matrix grows atai_leveldimension plus module-above-global clamp probes (19 combos); log-only parameters that turn unused under a lowered module ceiling get(void)suppressions so integrator-Wextra -Werrorbuilds stay clean. Default builds verified byte-identical. The docs-audit round is folded in here for the two pages this commit last touched: the knobs guide'sAGENTIC_KIT_LOGexample compiles as printed (real level mapping, no undefinedlvl_of()), the tag list matches the emitted tags, a function-sink example showslog_emit_valist()takes no tag — fold"[tag] "into the format string — and the rtc-tcp-client reference documents the flood recipe plus the ceiling-3/sampling-0 silence trap.d9b2e5bchore(review) — two-axis review findings folded in:tai_log_module_zero_testsjoins the CI valgrind loop, a stale "runtime-chosen level" sentence leaves AGENTS.md, andcore_mqtt_config.h's cross-reference points at its surviving sibling.d52dccbdocs(changelog) — BREAKING entries plus the PR-number backfill, at the tip. Carries the docs-audit round's CHANGELOG fix: the flood knob is spelledAGENTIC_KIT_TAI_LOG_MEDIA_SAMPLE_Nagain (the missingTAI_segment defined a dead macro and silently kept 1/50 sampling).BREAKING — migration
-DTAI_LOG_LEVEL=N(rtc-tcp-client), dead-DLOG_LEVEL-DAGENTIC_KIT_LOG_LEVEL=N— silences the whole SDK at compile timelog_set_level()/log_get_level(),tai_set_log_level()/tai_get_log_level()AGENTIC_KIT_LOGtargetlog_set_handler(fn)/log_fn_t/ publiclog_default_handler()AGENTIC_KIT_LOGtarget — it now receives the level and the bare tag directlyAfter migrating, a single module can be quieted further without touching the rest:
-DAGENTIC_KIT_{IOT,TAI,TUYA_BLE}_LOG_LEVEL=N— lower-only, defaults to the global ceiling.What the ESP-IDF pair-by-ble example now ships (
examples/esp-idf/components/agentic_kit/kit_opts/agentic_kit_config.h):A sink written as a plain variadic function calls
log_emit_valist(level, fmt, args)for the default stderr output instead of re-implementing it.Two ground rules from the guide (
docs/guides/compile-time-knobs.md):AGENTIC_KIT_LOG_LEVELceiling still gates —log_tag_*collapse to((void)0)above it (arguments never evaluated), so a remap cannot resurrect compiled-out lines.common/core_{http,mqtt}_config.h.Tests & build wiring
The SDK's own tests migrated to the shape they prescribe to integrators: each test build's
log_config/agentic_kit_config.hremapsAGENTIC_KIT_LOGinto onetest_log_sinkwhose PASSTHROUGH / CAPTURE / QUIET / COUNT are modes, not handler swaps (capture rebuilds the"[tag] "prefix, withva_copyand truncation discipline carried over). The wiring lesson on the CMake side: compiled outside the remap, the vendored coreHTTP/coreMQTT lines bypass the sink — exactly what the runtime handler used to catch library-agnostically — so thetuya_iot_client_testlogvariant compiles them in alongside the iot sources, and the ble sources compile into the test executable the same way. The plaintuya_iot_client/core_http/core_mqtttargets are untouched: the examples' link path and output stay byte-identical.TAI_LOOPBACK_VERBOSEkeeps its name and default-silent behavior (nowtest_log_env_default()).Docs follow in both locales: the knobs guide, the iot-client / rtc-tcp-client reference pages, the public header notes, and the AGENTS.md maintainer guide.