SDK สำหรับ TESAIoT Dev Kit
คู่มืออ้างอิง API และ Tutorial (MTB & µPython)
Loading...
Searching...
No Matches

Functions

void claw_cb_init (void)
 รีเซ็ต circuit breaker ให้กลับเป็น closed; เรียกเพียงครั้งเดียวผ่าน bentoclaw_ensure_init() เท่านั้น
bool claw_cb_allow (void)
 gate ที่หนึ่งของลำดับที่กำหนดตายตัว: breaker อนุญาตให้ทำงานหรือไม่
void claw_cb_success (void)
 บันทึกผลสำเร็จ: รีเซ็ตตัวนับข้อผิดพลาดและทำให้ breaker กลับเป็น closed
void claw_cb_failure (void)
 บันทึกความล้มเหลวก่อนการ raise ที่ไม่คืนการทำงานกลับมา; breaker จะเปิดวงจรเมื่อครบ 3 ครั้ง
claw_cb_state_t claw_cb_state (void)
 ส่วนที่ใช้อ่านสถานะ: สถานะปัจจุบันของ breaker (closed / open / half-open)
uint32_t claw_cb_cooldown_remaining (void)
 จำนวนมิลลิวินาทีที่เหลือใน cooldown ขณะ breaker เปิดวงจร; เป็น 0 เมื่อไม่ได้อยู่ใน cooldown
void claw_rate_init (void)
 ล้างตารางหน้าต่างเลื่อนประจำแต่ละ tool; เรียกเพียงครั้งเดียวผ่าน bentoclaw_ensure_init() เท่านั้น
bool claw_rate_check (const char *tool_name)
 gate ที่สาม: tool นั้นยังอยู่ใต้ค่าจำกัดต่อนาทีหรือไม่ การตรวจไม่กินโควตา
void claw_rate_record (const char *tool_name)
 นับการเรียกหนึ่งครั้งในหน้าต่างปัจจุบัน; ไปถึงได้เฉพาะหลัง gate ทั้งสามผ่านแล้วเท่านั้น
void claw_rate_set (const char *tool_name, uint16_t max_per_minute)
 ติดตั้งค่าจำกัดประจำ tool แทนค่าเริ่มต้น 10 ครั้งต่อนาที
void claw_trust_set (claw_trust_level_t level)
 ตั้งระดับ trust ของ transport; การยกระดับเป็น HTTPS ทุกครั้งจับคู่กับการตั้งกลับเป็น USB
claw_trust_level_t claw_trust_get (void)
 ส่วนที่ใช้อ่านสถานะ: ระดับ trust ปัจจุบัน
bool claw_trust_allows (uint8_t risk)
 gate ที่สอง: ระดับ trust ปัจจุบันยอมรับความเสี่ยงที่ tool ประกาศไว้หรือไม่

Detailed Description

13 ฟังก์ชัน: circuit breaker (ตัวตัดวงจร) คือ claw_cb_*, rate limiter (ตัวจำกัดอัตราการเรียก) ประจำแต่ละ tool คือ claw_rate_* และระดับ trust ของ transport คือ claw_trust_* ทั้งหมดเขียนไว้ใน claw_safety.c ซึ่งคอมไพล์รวมอยู่ใน libbento_mpy.a และไม่ได้ส่งมอบมาเป็นซอร์ส; เทมเพลตส่งมอบมาเพียง claw_safety.h ตัวอย่างอ้างอิงทุกชิ้นในกลุ่มฟังก์ชันนี้เป็นโค้ดจริงของผู้ใช้ไลบรารีจาก template/bento_libs/claw/common/mpy/modbentoclaw.c

มีสำนวนการเขียน 2 แบบที่ปรากฏซ้ำ และเป็นข้อกำหนดทั้งหมดของกลุ่มฟังก์ชันนี้:

  • การเริ่มต้นระบบผ่านฟังก์ชัน idempotent เพียงตัวเดียว จุดเข้าทุกจุดในของที่ส่งมอบจริงเรียก bentoclaw_ensure_init() ก่อนเสมอ; ฟังก์ชันนั้นเรียก claw_rate_init(), claw_cb_init(), claw_session_init() และลูป claw_rate_set() เพียงครั้งเดียวต่อหนึ่ง soft reset ฟังก์ชัน _init ทั้ง 3 ตัวไม่ถูกเรียกจากที่อื่นเลย
  • ลำดับของ gate (ด่านกั้น) ถูกกำหนดตายตัว: circuit breaker → trust → rate check → rate record ตัว breaker ถูกตรวจก่อนเพราะเป็น gate ที่ถูกที่สุดและเป็น gate ที่ปิดกั้นทุกอย่าง; rate limiter ถูกตรวจเป็นตัวสุดท้าย และบันทึกก็ต่อเมื่อ gate ทั้งสามผ่านแล้วเท่านั้น

สถานะเป็นตัวแปร global ระดับโมดูลธรรมดาที่ไม่มี lock: ระบบย่อยทั้งหมดถูกขับจาก MicroPython task เพียง task เดียว และไม่มีสิ่งใดในนี้ที่ปลอดภัยต่อการเรียกจาก ISR

variant ที่ใช้ได้
mtb-mpy เท่านั้น (ไม่มีการลิงก์ libbento_mpy.a เมื่อ BENTO_HAS_MPY=0)
static void bentoclaw_ensure_init(void) {
if (s_module_inited) return;
/* Set per-tool rate limits from registry */
for (size_t i = 0; i < TOOL_COUNT; i++) {
if (s_tools[i].rate_per_min > 0) {
claw_rate_set(s_tools[i].name, s_tools[i].rate_per_min);
}
}
s_module_inited = true;
}

Function Documentation

◆ claw_cb_init()

void claw_cb_init ( void )

รีเซ็ต circuit breaker ให้กลับเป็น closed; เรียกเพียงครั้งเดียวผ่าน bentoclaw_ensure_init() เท่านั้น

ข้อกำหนดการเรียกใช้
รีเซ็ต circuit breaker ให้เป็น CLAW_CB_CLOSED พร้อมกับตัวนับข้อผิดพลาดเป็น 0 ถูกเรียกเพียงครั้งเดียว ผ่าน bentoclaw_ensure_init() เท่านั้น — ไม่มีโค้ดในของที่ส่งมอบจริงเรียกฟังก์ชันนี้โดยตรง และการเรียกเป็นครั้งที่สองขณะที่ breaker เปิดวงจรอยู่จะทิ้ง cooldown ที่กำลังทำงานอยู่ไปเงียบ ๆ ทำงานใน MicroPython task context; ไม่มีการจับ lock; เป็น void ไม่มีเส้นทางแจ้งข้อผิดพลาด
variant ที่ใช้ได้
mtb-mpy เท่านั้น (ไม่มีการลิงก์ libbento_mpy.a เมื่อ BENTO_HAS_MPY=0)
ตัวอย่าง
call site เดียวที่มีอยู่จริงในของที่ส่งมอบ อยู่ภายในลำดับเริ่มต้นระบบแบบ idempotent (snippet mpy_claw_ensure_init ซึ่งแสดงไว้ในภาพรวมของกลุ่มฟังก์ชันนี้ด้วย)
static void bentoclaw_ensure_init(void) {
if (s_module_inited) return;
/* Set per-tool rate limits from registry */
for (size_t i = 0; i < TOOL_COUNT; i++) {
if (s_tools[i].rate_per_min > 0) {
claw_rate_set(s_tools[i].name, s_tools[i].rate_per_min);
}
}
s_module_inited = true;
}

◆ claw_cb_allow()

bool claw_cb_allow ( void )

gate ที่หนึ่งของลำดับที่กำหนดตายตัว: breaker อนุญาตให้ทำงานหรือไม่

ข้อกำหนดการเรียกใช้
คืนค่า true เมื่อ breaker อนุญาตให้ทำงาน (CLAW_CB_CLOSED หรือ CLAW_CB_HALFOPEN ที่ยอมให้เรียกทดสอบได้หนึ่งครั้ง) และคืนค่า false ขณะที่อยู่ในสถานะ CLAW_CB_OPEN ระหว่าง cooldown claw_cb_init() ต้องทำงานมาก่อน — ในโค้ดที่ส่งมอบจริงเรียกผ่าน bentoclaw_ensure_init() นี่คือ gate ที่หนึ่งของลำดับบังคับ circuit breaker → trust → rate check → rate record; ที่จุด raise ทุกจุด ผู้เรียกจะเพิ่มค่า s_error_count ของตัวเองก่อนเรียก mp_raise_msg ที่ไม่คืนการทำงานกลับมา จุดเรียกอื่นในของที่ส่งมอบจริง: guard ของ ask() (claw_https_connected()) และเส้นทาง TACP tool-exec เป็นการอ่านอย่างเดียว; ไม่มีการจับ lock; ทำงานใน MicroPython task context
variant ที่ใช้ได้
mtb-mpy เท่านั้น (ไม่มีการลิงก์ libbento_mpy.a เมื่อ BENTO_HAS_MPY=0)
ตัวอย่าง
handler ของการเรียก tool; เป็น snippet ที่รับน้ำหนักมากที่สุดในโมดูลนี้ เพราะกำหนดลำดับของ gate และครอบคลุม claw_trust_allows(), claw_rate_check() และ claw_rate_record() ไว้ในที่เดียว
/* ...context: inside the tool-call handler; 'found' is the resolved tool entry ... */
/* Safety check: circuit breaker */
if (!claw_cb_allow()) {
s_error_count++;
mp_raise_msg(&mp_type_RuntimeError,
MP_ERROR_TEXT("circuit breaker open — cooldown active"));
}
/* Safety check: transport trust level */
if (!claw_trust_allows(found->risk)) {
s_error_count++;
mp_raise_msg(&mp_type_RuntimeError,
MP_ERROR_TEXT("tool risk exceeds transport trust level"));
}
/* Safety check: rate limiter */
if (!claw_rate_check(found->name)) {
s_error_count++;
mp_raise_msg(&mp_type_RuntimeError,
MP_ERROR_TEXT("rate limit exceeded for this tool"));
}
/* Record rate limit hit */
claw_rate_record(found->name);

◆ claw_cb_success()

void claw_cb_success ( void )

บันทึกผลสำเร็จ: รีเซ็ตตัวนับข้อผิดพลาดและทำให้ breaker กลับเป็น closed

ข้อกำหนดการเรียกใช้
บันทึกว่าการทำงานสำเร็จ: รีเซ็ตตัวนับข้อผิดพลาดต่อเนื่องและทำให้ breaker กลับเป็น closed (การเรียกทดสอบในสถานะ half-open ที่สำเร็จจะทำให้กลับเป็น closed เต็มรูป) ต้องเรียก claw_cb_init() ผ่าน bentoclaw_ensure_init() มาก่อน ใช้คู่กับ claw_cb_failure() บนการทำงานเดียวกันเสมอ: ฝั่งที่ล้มเหลวเรียก claw_cb_failure() ก่อน mp_raise_msg ที่ไม่คืนการทำงานกลับมา ส่วนฝั่งที่สำเร็จเรียก claw_cb_success() บนเส้นทาง fall-through ทั้งสองฟังก์ชันเป็น void และไม่มีเส้นทางแจ้งข้อผิดพลาด โค้ดที่ส่งมอบจริงจะผนวกรอบสนทนาฝั่ง assistant เข้าเซสชัน (claw_session_add()) ก็ต่อเมื่อ claw_cb_success() ทำงานแล้วเท่านั้น
variant ที่ใช้ได้
mtb-mpy เท่านั้น (ไม่มีการลิงก์ libbento_mpy.a เมื่อ BENTO_HAS_MPY=0)
ตัวอย่าง
ฝั่งสำเร็จและฝั่งล้มเหลวที่จับคู่กันหลัง claw_https_post()
/* ...context: inside bentoclaw_ask(), after claw_https_post() ... */
if (resp_len < 0) {
s_agent_state = CLAW_STATE_ERROR;
s_error_count++;
claw_ipc_send_ui(CLAW_UI_ERROR, "Backend error", 13);
snprintf(s_last_result, sizeof(s_last_result), "error");
claw_ipc_send_ui(CLAW_UI_LAST_RESULT, s_last_result, strlen(s_last_result));
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("HTTPS request failed"));
}
/* ...context: inside bentoclaw_ask(), success path ... */
s_agent_state = CLAW_STATE_IDLE;

◆ claw_cb_failure()

void claw_cb_failure ( void )

บันทึกความล้มเหลวก่อนการ raise ที่ไม่คืนการทำงานกลับมา; breaker จะเปิดวงจรเมื่อครบ 3 ครั้ง

ข้อกำหนดการเรียกใช้
บันทึกว่าการทำงานล้มเหลว: เพิ่มค่าตัวนับข้อผิดพลาดต่อเนื่อง และเปลี่ยน breaker ไปเป็น CLAW_CB_OPEN (cooldown 30 s) เมื่อถึงเกณฑ์ 3 ครั้ง ต้องเรียก claw_cb_init() มาก่อน ต้องเรียกก่อนการ raise ที่ไม่คืนการทำงานกลับมาmp_raise_msg ไม่คืนการทำงาน ดังนั้น claw_cb_failure() ที่วางไว้หลังจากนั้นจะไม่ถูกเรียกเลย และ breaker จะไม่รับรู้ความล้มเหลวนั้น เป็น void ไม่มีเส้นทางแจ้งข้อผิดพลาด; ทำงานใน MicroPython task context จุดเรียกในของที่ส่งมอบจริง: เส้นทาง ask() ของ HTTPS และเส้นทาง TACP อีก 2 แห่ง
variant ที่ใช้ได้
mtb-mpy เท่านั้น (ไม่มีการลิงก์ libbento_mpy.a เมื่อ BENTO_HAS_MPY=0)
ตัวอย่าง
snippet เดียวกับที่ claw_cb_success() ใช้: บันทึกความล้มเหลวก่อนการ raise และบันทึกผลสำเร็จบนเส้นทาง fall-through
/* ...context: inside bentoclaw_ask(), after claw_https_post() ... */
if (resp_len < 0) {
s_agent_state = CLAW_STATE_ERROR;
s_error_count++;
claw_ipc_send_ui(CLAW_UI_ERROR, "Backend error", 13);
snprintf(s_last_result, sizeof(s_last_result), "error");
claw_ipc_send_ui(CLAW_UI_LAST_RESULT, s_last_result, strlen(s_last_result));
mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("HTTPS request failed"));
}
/* ...context: inside bentoclaw_ask(), success path ... */
s_agent_state = CLAW_STATE_IDLE;

◆ claw_cb_state()

claw_cb_state_t claw_cb_state ( void )

ส่วนที่ใช้อ่านสถานะ: สถานะปัจจุบันของ breaker (closed / open / half-open)

ข้อกำหนดการเรียกใช้
ส่วนที่ใช้อ่านสถานะ: คืนค่า claw_cb_state_t ปัจจุบัน (CLAW_CB_CLOSED = 0, CLAW_CB_OPEN = 1, CLAW_CB_HALFOPEN = 2) ผู้ใช้ไลบรารีในของที่ส่งมอบจริงแมปค่านั้นผ่านตารางชื่อ 3 รายการ พร้อม guard ตรวจขอบเขตอย่างชัดเจน (ได้ "unknown" สำหรับค่าอื่นทั้งหมด) — ให้คัดลอก guard นั้นไปด้วย เพราะ enum ถูกคืนค่ามาจาก archive ที่เปิดดูภายในไม่ได้ เป็นการอ่านอย่างเดียว ไม่มีการจับ lock ทำงานใน MicroPython task context; bentoclaw_ensure_init() ทำงานมาก่อนหน้าแล้ว
variant ที่ใช้ได้
mtb-mpy เท่านั้น (ไม่มีการลิงก์ libbento_mpy.a เมื่อ BENTO_HAS_MPY=0)
ตัวอย่าง
bentoclaw_safety() ซึ่งเป็นตัวอย่างอ้างอิงที่จบในตัวเองเพียงชุดเดียวที่ครอบคลุม claw_cb_state(), claw_trust_get() และ claw_cb_cooldown_remaining()
static mp_obj_t bentoclaw_safety(void) {
bentoclaw_ensure_init();
mp_obj_dict_t *d = MP_OBJ_TO_PTR(mp_obj_new_dict(4));
static const char *cb_names[] = { "closed", "open", "half-open" };
const char *cb_str = (cb < 3) ? cb_names[cb] : "unknown";
static const char *trust_names[] = { "none", "https", "usb" };
const char *trust_str = (trust < 3) ? trust_names[trust] : "unknown";
mp_obj_dict_store(MP_OBJ_FROM_PTR(d),
MP_OBJ_NEW_QSTR(MP_QSTR_circuit_breaker),
mp_obj_new_str(cb_str, strlen(cb_str)));
mp_obj_dict_store(MP_OBJ_FROM_PTR(d),
MP_OBJ_NEW_QSTR(MP_QSTR_cooldown_ms),
mp_obj_new_int(claw_cb_cooldown_remaining()));

◆ claw_cb_cooldown_remaining()

uint32_t claw_cb_cooldown_remaining ( void )

จำนวนมิลลิวินาทีที่เหลือใน cooldown ขณะ breaker เปิดวงจร; เป็น 0 เมื่อไม่ได้อยู่ใน cooldown

ข้อกำหนดการเรียกใช้
ส่วนที่ใช้อ่านสถานะ: จำนวนมิลลิวินาทีที่เหลือใน cooldown ขณะ breaker เปิดวงจร และเป็น 0 เมื่อ breaker ไม่ได้อยู่ใน cooldown เปิดให้ฝั่ง Python เห็นเป็นคีย์ cooldown_ms ของ bentoclaw.safety() เป็นการอ่านอย่างเดียว ไม่มีการจับ lock ทำงานใน MicroPython task context; bentoclaw_ensure_init() ทำงานมาก่อนหน้าแล้ว
variant ที่ใช้ได้
mtb-mpy เท่านั้น (ไม่มีการลิงก์ libbento_mpy.a เมื่อ BENTO_HAS_MPY=0)
ตัวอย่าง
ตัวอย่างอ้างอิงเดียวกันคือ bentoclaw_safety()
static mp_obj_t bentoclaw_safety(void) {
bentoclaw_ensure_init();
mp_obj_dict_t *d = MP_OBJ_TO_PTR(mp_obj_new_dict(4));
static const char *cb_names[] = { "closed", "open", "half-open" };
const char *cb_str = (cb < 3) ? cb_names[cb] : "unknown";
static const char *trust_names[] = { "none", "https", "usb" };
const char *trust_str = (trust < 3) ? trust_names[trust] : "unknown";
mp_obj_dict_store(MP_OBJ_FROM_PTR(d),
MP_OBJ_NEW_QSTR(MP_QSTR_circuit_breaker),
mp_obj_new_str(cb_str, strlen(cb_str)));
mp_obj_dict_store(MP_OBJ_FROM_PTR(d),
MP_OBJ_NEW_QSTR(MP_QSTR_cooldown_ms),
mp_obj_new_int(claw_cb_cooldown_remaining()));

◆ claw_rate_init()

void claw_rate_init ( void )

ล้างตารางหน้าต่างเลื่อนประจำแต่ละ tool; เรียกเพียงครั้งเดียวผ่าน bentoclaw_ensure_init() เท่านั้น

ข้อกำหนดการเรียกใช้
ล้างตารางหน้าต่างเลื่อนประจำแต่ละ tool (CLAW_RATE_MAX_TOOLS = 16 รายการ) ถูกเรียกผ่าน bentoclaw_ensure_init() เท่านั้น ครั้งเดียวต่อหนึ่ง soft reset และตามด้วยลูป claw_rate_set() ที่ติดตั้งค่าจำกัดที่ประกาศไว้ของแต่ละ tool ทันทีในที่เดียวกัน ทำงานใน MicroPython task context; ไม่มีการจับ lock; เป็น void
variant ที่ใช้ได้
mtb-mpy เท่านั้น (ไม่มีการลิงก์ libbento_mpy.a เมื่อ BENTO_HAS_MPY=0)
ตัวอย่าง
call site เดียวที่มีอยู่จริงในของที่ส่งมอบ
static void bentoclaw_ensure_init(void) {
if (s_module_inited) return;
/* Set per-tool rate limits from registry */
for (size_t i = 0; i < TOOL_COUNT; i++) {
if (s_tools[i].rate_per_min > 0) {
claw_rate_set(s_tools[i].name, s_tools[i].rate_per_min);
}
}
s_module_inited = true;
}

◆ claw_rate_check()

bool claw_rate_check ( const char * tool_name)

gate ที่สาม: tool นั้นยังอยู่ใต้ค่าจำกัดต่อนาทีหรือไม่ การตรวจไม่กินโควตา

ข้อกำหนดการเรียกใช้
คืนค่า true เมื่อ tool_name ยังอยู่ใต้ค่าจำกัดต่อนาที และคืนค่า false เมื่อถูกจำกัดอัตราแล้ว การตรวจไม่กินโควตา — การตรวจกับ claw_rate_record() เป็นการเรียกคนละครั้งบน found->name เดียวกัน ผู้เรียกที่ตรวจแล้วไม่บันทึกจึงไม่ถูกนับเลย เป็น gate ที่สามของลำดับบังคับ (ถัดจาก breaker และระดับ trust) tool ที่ไม่มีรายการจาก claw_rate_set() จะย้อนไปใช้ค่าเริ่มต้นที่ 10 ครั้งต่อนาที เป็นการอ่านอย่างเดียว; ไม่มีการจับ lock; ทำงานใน MicroPython task context
variant ที่ใช้ได้
mtb-mpy เท่านั้น (ไม่มีการลิงก์ libbento_mpy.a เมื่อ BENTO_HAS_MPY=0)
ตัวอย่าง
snippet ที่แสดงลำดับของ gate
/* ...context: inside the tool-call handler; 'found' is the resolved tool entry ... */
/* Safety check: circuit breaker */
if (!claw_cb_allow()) {
s_error_count++;
mp_raise_msg(&mp_type_RuntimeError,
MP_ERROR_TEXT("circuit breaker open — cooldown active"));
}
/* Safety check: transport trust level */
if (!claw_trust_allows(found->risk)) {
s_error_count++;
mp_raise_msg(&mp_type_RuntimeError,
MP_ERROR_TEXT("tool risk exceeds transport trust level"));
}
/* Safety check: rate limiter */
if (!claw_rate_check(found->name)) {
s_error_count++;
mp_raise_msg(&mp_type_RuntimeError,
MP_ERROR_TEXT("rate limit exceeded for this tool"));
}
/* Record rate limit hit */
claw_rate_record(found->name);

◆ claw_rate_record()

void claw_rate_record ( const char * tool_name)

นับการเรียกหนึ่งครั้งในหน้าต่างปัจจุบัน; ไปถึงได้เฉพาะหลัง gate ทั้งสามผ่านแล้วเท่านั้น

ข้อกำหนดการเรียกใช้
เพิ่มจำนวนการเรียกของ tool นั้นในหน้าต่าง 60 วินาทีปัจจุบัน ไปถึงได้เฉพาะเมื่อ gate ทั้งสามผ่านแล้วเท่านั้น — จุดเรียกทุกจุดในของที่ส่งมอบจริงวางไว้หลังจาก claw_cb_allow(), claw_trust_allows() และ claw_rate_check() คืนค่า true ครบทุกตัวแล้ว การเรียกที่ถูกปฏิเสธจึงไม่กินโควตาเลย เป็น void; ไม่มีการจับ lock; ทำงานใน MicroPython task context
variant ที่ใช้ได้
mtb-mpy เท่านั้น (ไม่มีการลิงก์ libbento_mpy.a เมื่อ BENTO_HAS_MPY=0)
ตัวอย่าง
snippet ที่แสดงลำดับของ gate; claw_rate_record() คือบรรทัดสุดท้ายของ snippet นั้น
/* ...context: inside the tool-call handler; 'found' is the resolved tool entry ... */
/* Safety check: circuit breaker */
if (!claw_cb_allow()) {
s_error_count++;
mp_raise_msg(&mp_type_RuntimeError,
MP_ERROR_TEXT("circuit breaker open — cooldown active"));
}
/* Safety check: transport trust level */
if (!claw_trust_allows(found->risk)) {
s_error_count++;
mp_raise_msg(&mp_type_RuntimeError,
MP_ERROR_TEXT("tool risk exceeds transport trust level"));
}
/* Safety check: rate limiter */
if (!claw_rate_check(found->name)) {
s_error_count++;
mp_raise_msg(&mp_type_RuntimeError,
MP_ERROR_TEXT("rate limit exceeded for this tool"));
}
/* Record rate limit hit */
claw_rate_record(found->name);

◆ claw_rate_set()

void claw_rate_set ( const char * tool_name,
uint16_t max_per_minute )

ติดตั้งค่าจำกัดประจำ tool แทนค่าเริ่มต้น 10 ครั้งต่อนาที

ข้อกำหนดการเรียกใช้
ติดตั้งค่าจำกัดประจำ tool แทนค่าเริ่มต้น 10 ครั้งต่อนาที โค้ดที่ส่งมอบจริงดึงค่าจำกัดมาจาก registry ของ tool และเรียกฟังก์ชันนี้ เฉพาะเมื่อ rate_per_min มากกว่า 0 เท่านั้น — รายการที่มีค่าเป็น 0 หมายถึง "ให้คงค่าเริ่มต้นไว้" ไม่ใช่ "ไม่จำกัด" ทำงานอยู่ภายใน bentoclaw_ensure_init() ถัดจาก claw_rate_init(); ตารางเก็บได้ CLAW_RATE_MAX_TOOLS รายการ เป็น void; ทำงานใน MicroPython task context
variant ที่ใช้ได้
mtb-mpy เท่านั้น (ไม่มีการลิงก์ libbento_mpy.a เมื่อ BENTO_HAS_MPY=0)
ตัวอย่าง
ลูปอ่าน registry ภายในลำดับเริ่มต้นระบบแบบ idempotent
static void bentoclaw_ensure_init(void) {
if (s_module_inited) return;
/* Set per-tool rate limits from registry */
for (size_t i = 0; i < TOOL_COUNT; i++) {
if (s_tools[i].rate_per_min > 0) {
claw_rate_set(s_tools[i].name, s_tools[i].rate_per_min);
}
}
s_module_inited = true;
}

◆ claw_trust_set()

void claw_trust_set ( claw_trust_level_t level)

ตั้งระดับ trust ของ transport; การยกระดับเป็น HTTPS ทุกครั้งจับคู่กับการตั้งกลับเป็น USB

ข้อกำหนดการเรียกใช้
ตั้งระดับ trust ของ transport ที่ claw_trust_allows() ใช้ตรวจ: CLAW_TRUST_USB (2, ทุก tool), CLAW_TRUST_HTTPS (1, เฉพาะความเสี่ยงต่ำและกลางเท่านั้น), CLAW_TRUST_NONE (0, ไม่อนุญาตอะไรเลย) ให้ยกระดับ trust เป็น HTTPS ก่อนการพยายามเชื่อมต่อ เพื่อให้ระดับถูกต้องอยู่แล้วเมื่อการเรียก tool ครั้งแรกมาถึง และ การตั้งเป็น CLAW_TRUST_HTTPS ทุกครั้งมีการตั้งกลับเป็น CLAW_TRUST_USB คู่กันเสมอ ทั้งบนเส้นทางที่ล้มเหลวและบนเส้นทางตัดการเชื่อมต่อ (claw_https_disconnect()) การเชื่อมต่อที่ล้มเหลวจึงไม่ทิ้ง tool ความเสี่ยงสูงให้เปิดใช้อยู่บน transport ที่ไม่ควรมีสิทธิ์นั้น ระดับ trust เป็นตัวแปร global ธรรมดาที่ไม่มี lock bentoclaw_ensure_init() ทำงานมาก่อนแล้วที่จุดเรียกทุกจุดในของที่ส่งมอบจริง
variant ที่ใช้ได้
mtb-mpy เท่านั้น (ไม่มีการลิงก์ libbento_mpy.a เมื่อ BENTO_HAS_MPY=0)
ตัวอย่าง
ยกระดับ trust ก่อน claw_https_connect() และตั้งกลับภายใน else
/* ...context: inside bentoclaw_connect() ... */
claw_ipc_init();
claw_ipc_send_ui(CLAW_UI_STATUS_TEXT, "Connecting...", 13);
bool ok = claw_https_connect(host, port, api_key);
if (ok) {
claw_ipc_send_ui(CLAW_UI_STATUS_TEXT, "Online (HTTPS)", 14);
claw_session_add(CLAW_ROLE_SYSTEM, "Connected to TESAIoT backend");
} else {
claw_ipc_send_ui(CLAW_UI_STATUS_TEXT, "Connect failed", 14);
}

การตั้งกลับที่คู่กันบนเส้นทางตัดการเชื่อมต่อ:

static mp_obj_t bentoclaw_disconnect(void) {
if (claw_ipc_initialized) {
claw_ipc_send_ui(CLAW_UI_STATUS_TEXT, "Offline", 7);
}
claw_session_add(CLAW_ROLE_SYSTEM, "Disconnected from backend");
return mp_const_none;
}

◆ claw_trust_get()

claw_trust_level_t claw_trust_get ( void )

ส่วนที่ใช้อ่านสถานะ: ระดับ trust ปัจจุบัน

ข้อกำหนดการเรียกใช้
ส่วนที่ใช้อ่านสถานะ: คืนค่า claw_trust_level_t ปัจจุบัน ผู้ใช้ไลบรารีในของที่ส่งมอบจริงแมปค่านั้นผ่านตารางชื่อ 3 รายการ ("none", "https", "usb" — ใช้ค่าตัวเลขของ enum เป็นดัชนี คือ 0, 1, 2) พร้อม guard ตรวจขอบเขต ให้คง guard นั้นไว้ เป็นการอ่านตัวแปร global ธรรมดาอย่างเดียว; ไม่มีการจับ lock; ทำงานใน MicroPython task context
variant ที่ใช้ได้
mtb-mpy เท่านั้น (ไม่มีการลิงก์ libbento_mpy.a เมื่อ BENTO_HAS_MPY=0)
ตัวอย่าง
bentoclaw_safety()
static mp_obj_t bentoclaw_safety(void) {
bentoclaw_ensure_init();
mp_obj_dict_t *d = MP_OBJ_TO_PTR(mp_obj_new_dict(4));
static const char *cb_names[] = { "closed", "open", "half-open" };
const char *cb_str = (cb < 3) ? cb_names[cb] : "unknown";
static const char *trust_names[] = { "none", "https", "usb" };
const char *trust_str = (trust < 3) ? trust_names[trust] : "unknown";
mp_obj_dict_store(MP_OBJ_FROM_PTR(d),
MP_OBJ_NEW_QSTR(MP_QSTR_circuit_breaker),
mp_obj_new_str(cb_str, strlen(cb_str)));
mp_obj_dict_store(MP_OBJ_FROM_PTR(d),
MP_OBJ_NEW_QSTR(MP_QSTR_cooldown_ms),
mp_obj_new_int(claw_cb_cooldown_remaining()));

◆ claw_trust_allows()

bool claw_trust_allows ( uint8_t risk)

gate ที่สอง: ระดับ trust ปัจจุบันยอมรับความเสี่ยงที่ tool ประกาศไว้หรือไม่

ข้อกำหนดการเรียกใช้
เป็น gate ที่สองของลำดับบังคับ อาร์กิวเมนต์คือความเสี่ยงที่ tool ประกาศไว้ (0 = ต่ำ, 1 = กลาง, 2 = สูง) ซึ่งอ่านมาจากรายการใน registry ของ tool (found->risk) ไม่ใช่จากคำขอ คืนค่า true เมื่อระดับ trust ปัจจุบันยอมรับความเสี่ยงระดับนั้น: USB ยอมรับทั้งหมด, HTTPS ยอมรับเฉพาะต่ำและกลาง, NONE ไม่ยอมรับอะไรเลย เป็นการอ่านอย่างเดียว; ไม่มีการจับ lock; ทำงานใน MicroPython task context
variant ที่ใช้ได้
mtb-mpy เท่านั้น (ไม่มีการลิงก์ libbento_mpy.a เมื่อ BENTO_HAS_MPY=0)
ตัวอย่าง
snippet ที่แสดงลำดับของ gate
/* ...context: inside the tool-call handler; 'found' is the resolved tool entry ... */
/* Safety check: circuit breaker */
if (!claw_cb_allow()) {
s_error_count++;
mp_raise_msg(&mp_type_RuntimeError,
MP_ERROR_TEXT("circuit breaker open — cooldown active"));
}
/* Safety check: transport trust level */
if (!claw_trust_allows(found->risk)) {
s_error_count++;
mp_raise_msg(&mp_type_RuntimeError,
MP_ERROR_TEXT("tool risk exceeds transport trust level"));
}
/* Safety check: rate limiter */
if (!claw_rate_check(found->name)) {
s_error_count++;
mp_raise_msg(&mp_type_RuntimeError,
MP_ERROR_TEXT("rate limit exceeded for this tool"));
}
/* Record rate limit hit */
claw_rate_record(found->name);