#ifndef CTL_H #define CTL_H #include #include #ifdef __cplusplus extern "C" { #endif #ifndef CTL_MAX_LINE #define CTL_MAX_LINE 4096 #endif #ifndef CTL_MAX_ARGS #define CTL_MAX_ARGS 16 #endif #ifndef CTL_MAX_ARG_BYTES #define CTL_MAX_ARG_BYTES (1024 * 1024) #endif #ifndef CTL_MAX_ID #define CTL_MAX_ID 64 #endif #ifndef CTL_MAX_NAME #define CTL_MAX_NAME 64 #endif #ifndef CTL_MAX_KEY #define CTL_MAX_KEY 64 #endif typedef enum { CTL_OK = 0, CTL_ERR_CONTRACT = 1, /* left L0_tool */ CTL_ERR_NOMEM = 2, CTL_ERR_LIMIT = 3 } ctl_status_t; typedef enum { CTL_EV_NONE = 0, CTL_EV_CALL_OPEN, /* id+name confirmed */ CTL_EV_ARG, /* one arg fully confirmed */ CTL_EV_CALL_READY, /* end confirmed — safe to execute */ CTL_EV_TEXT, /* non-CTL confirmed text (outside call) */ CTL_EV_ERROR } ctl_event_type_t; typedef struct { char key[CTL_MAX_KEY]; char *value; size_t value_len; } ctl_arg_t; typedef struct { char id[CTL_MAX_ID]; char name[CTL_MAX_NAME]; ctl_arg_t args[CTL_MAX_ARGS]; int nargs; } ctl_tool_call_t; typedef struct { ctl_event_type_t type; const ctl_tool_call_t *call; /* valid for CALL_* / ARG */ const char *text; /* for TEXT */ size_t text_len; const char *error; /* for ERROR */ } ctl_event_t; typedef void (*ctl_on_event_fn)(const ctl_event_t *ev, void *userdata); typedef struct ctl_parser ctl_parser_t; ctl_parser_t *ctl_parser_create(ctl_on_event_fn on_event, void *userdata); void ctl_parser_destroy(ctl_parser_t *p); /* Feed UTF-8 bytes. Emits only confirmed events. */ ctl_status_t ctl_parser_feed(ctl_parser_t *p, const char *data, size_t len); /* EOF: flush; incomplete call => ERROR (no execute). */ ctl_status_t ctl_parser_finish(ctl_parser_t *p); /* Bytes currently pending (unconfirmed). */ size_t ctl_parser_pending(const ctl_parser_t *p); /* Peak pending observed (for experiments). */ size_t ctl_parser_pending_peak(const ctl_parser_t *p); /* Reset for a new assistant turn. */ void ctl_parser_reset(ctl_parser_t *p); #ifdef __cplusplus } #endif #endif /* CTL_H */