/* * agent_loop.h — ReAct tool-call loop for the embedded agent * * Runs the standard ReAct (reason → act → observe) loop on a background * GThread so the GTK main thread stays responsive during long LLM calls * and multi-step tool sequences. * * Threading model (see plans/embedded-agent.md): * - LLM HTTP calls block on the background thread. * - Browser tools (snapshot, click, eval, …) hop to the GTK main thread * via g_idle_add() + GAsyncQueue because WebKitGTK is not thread-safe. * - Filesystem/shell tools run directly on the background thread. * - SQLite writes use the FULLMUTEX connection and are safe from any thread. * - Cancellation is via an atomic flag checked at the top of each iteration. */ #ifndef AGENT_LOOP_H #define AGENT_LOOP_H #include #ifdef __cplusplus extern "C" { #endif /* * Status states for the agent loop. */ typedef enum { AGENT_LOOP_IDLE, AGENT_LOOP_THINKING, AGENT_LOOP_TOOL_CALL, AGENT_LOOP_COMPLETE, AGENT_LOOP_ERROR, AGENT_LOOP_CANCELLED } agent_loop_state_t; /* * Start the agent loop for a user message. This: * 1. Adds the user message to the chat store. * 2. Spawns a background GThread that runs the ReAct loop. * 3. Returns immediately (non-blocking). * * Returns 0 on success, -1 on error (e.g. already running, no provider * configured). */ int agent_loop_run(const char *user_message); /* * Request cancellation of the running agent loop. * Sets an atomic flag checked at the top of each loop iteration. * The background thread will exit at the next check point. */ void agent_loop_cancel(void); /* * Check if the agent loop is currently running. */ gboolean agent_loop_is_running(void); /* * Get the current status of the agent loop. Returns the state and * fills the optional output parameters with current status info. * * state_out — current state (may be NULL) * iteration_out — current iteration number (may be NULL) * current_tool_out — name of tool being executed (may be NULL, caller g_free) * last_message_out — most recent assistant text (may be NULL, caller g_free) * error_out — error message if state is ERROR (may be NULL, caller g_free) */ void agent_loop_get_status(agent_loop_state_t *state_out, int *iteration_out, char **current_tool_out, char **last_message_out, char **error_out); #ifdef __cplusplus } #endif #endif /* AGENT_LOOP_H */