#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); /* Why the stream left the contract (for protocol-adherence experiments). */ typedef enum { CTL_EK_NONE = 0, CTL_EK_BAD_CALL, /* malformed `call` line */ CTL_EK_BAD_ARG, /* malformed `arg` header / bad heredoc tag */ CTL_EK_UNEXPECTED_LINE, /* non arg/end line inside a call (nbytes too small) */ CTL_EK_BODY_EOF, /* EOF inside a length-prefixed body (nbytes too big) */ CTL_EK_HEREDOC_EOF, /* EOF before the heredoc terminator */ CTL_EK_LINE_TOO_LONG, CTL_EK_LIMIT, /* too many args / body over CTL_MAX_ARG_BYTES */ CTL_EK_OOM } ctl_error_kind_t; typedef struct { size_t calls_open; size_t calls_ready; size_t args_nbytes; /* arg */ size_t args_inline; /* arg */ size_t args_heredoc; /* arg < 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); void ctl_parser_stats(const ctl_parser_t *p, ctl_parser_stats_t *out); #ifdef __cplusplus } #endif #endif /* CTL_H */