gglib_core/domain/agent/mod.rs
1//! Agent loop domain types.
2//!
3//! These types define the core abstractions for the backend agentic loop.
4//! They are pure domain primitives: no LLM backend references, no MCP types,
5//! no infrastructure concerns.
6//!
7//! # Modules
8//!
9//! | Module | Contents |
10//! |--------|----------|
11//! | [`config`] | [`AgentConfig`] — loop control parameters |
12//! | [`tool_types`] | [`ToolDefinition`], [`ToolCall`], [`ToolResult`] |
13//! | [`messages`] | [`AgentMessage`] — closed conversation-turn enum |
14//! | `messages_serde` | Custom `Serialize`/`Deserialize` impls for [`AssistantContent`] |
15//! | [`events`] | [`AgentEvent`] (SSE units), [`LlmStreamEvent`] (stream protocol) |
16//!
17//! # Design Principles
18//!
19//! - [`AgentMessage`] is a closed enum so the type system prevents invalid states
20//! (e.g. a `User` message carrying `tool_calls`).
21//! - [`ToolDefinition`] is a dedicated type — adapter layers convert `McpTool →
22//! ToolDefinition`; the agent domain must not depend on MCP domain types.
23//! - [`ToolResult`] with `success: false` is **context for the LLM**, not an error;
24//! tool failures are fed back into the conversation so the model can reason about
25//! them and retry or adjust its approach.
26//! - [`AgentEvent`] is the unit of SSE emission; every observable state change in
27//! the loop corresponds to exactly one variant.
28
29pub mod config;
30pub mod events;
31pub mod messages;
32mod messages_serde;
33pub mod tool_types;
34
35// Re-export everything so callers continue to use `gglib_core::AgentConfig` etc.
36pub use config::{
37 AgentConfig, AgentConfigError, DEFAULT_MAX_ITERATIONS, DEFAULT_MAX_PARALLEL_TOOLS,
38 MAX_ITERATIONS_CEILING, MAX_PARALLEL_TOOLS_CEILING, MAX_TOOL_TIMEOUT_MS_CEILING,
39 MIN_CONTEXT_BUDGET_CHARS, MIN_TOOL_TIMEOUT_MS,
40};
41pub use events::{AGENT_EVENT_CHANNEL_CAPACITY, AgentEvent, LlmStreamEvent};
42pub use messages::{AgentMessage, AssistantContent};
43pub use tool_types::{ToolCall, ToolDefinition, ToolResult};