feat(tui): add usage overlay and sidebar for displaying usage statistics and tasks
feat(tui): implement status bar with connection and turn state indicators feat(tui): create workflow panel for agent status and progress visualization feat(web): introduce web frontend interface with static file serving feat(ws): add WebSocket interface for real-time communication and session management
This commit is contained in:
@@ -0,0 +1,82 @@
|
||||
//! Subagent LLM provider — resolves provider/model from settings and wraps
|
||||
//! `LlmClient` in a higher-level API for subagent use.
|
||||
//!
|
||||
//! Flow: `resolve_subagent_provider` is called at startup to pick a provider
|
||||
//! + model → `SubagentProvider` wraps that pair around an `LlmClient` for use
|
||||
//! inside the subagent engine loop.
|
||||
|
||||
use anyhow::Result;
|
||||
|
||||
use crate::llm::provider::LlmClient;
|
||||
use crate::tools::{tool_defs, Tool};
|
||||
use zesdex_domain::core::ChatMessage;
|
||||
|
||||
/// Provider wrapper for subagent LLM interactions.
|
||||
///
|
||||
/// Provides two convenience methods (`chat`, `chat_with_tools`) that
|
||||
/// abstract away the raw `LlmClient` parameter plumbing so the engine
|
||||
/// loop only deals with messages and tools.
|
||||
///
|
||||
/// The model identifier is already embedded in the `LlmClient` itself
|
||||
/// (its `model` field), so `SubagentProvider` does not duplicate it.
|
||||
pub struct SubagentProvider {
|
||||
client: LlmClient,
|
||||
}
|
||||
|
||||
impl SubagentProvider {
|
||||
/// Wrap an existing `LlmClient` for higher-level use.
|
||||
pub fn new(client: LlmClient) -> Self {
|
||||
Self { client }
|
||||
}
|
||||
|
||||
/// Send messages to the LLM without any tool definitions.
|
||||
///
|
||||
/// Use this for a plain text-in/text-out conversation.
|
||||
pub fn chat(
|
||||
&self,
|
||||
messages: &[ChatMessage],
|
||||
) -> Result<(ChatMessage, Option<(u64, u64)>)> {
|
||||
self.client
|
||||
.chat_with_tools_non_streaming(messages, None, Some(4096), None, None)
|
||||
}
|
||||
|
||||
/// Send messages with available tool definitions.
|
||||
///
|
||||
/// Automatically converts the `&[Box<dyn Tool>]` slice to
|
||||
/// `Vec<ToolDef>` before passing to the underlying client.
|
||||
pub fn chat_with_tools(
|
||||
&self,
|
||||
messages: &[ChatMessage],
|
||||
tools: &[Box<dyn Tool>],
|
||||
) -> Result<(ChatMessage, Option<(u64, u64)>)> {
|
||||
let defs = tool_defs(tools);
|
||||
self.client
|
||||
.chat_with_tools_non_streaming(messages, Some(defs), Some(4096), None, None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve subagent provider and model from settings.
|
||||
///
|
||||
/// Flow: reads `settings.provider` and `settings.model` → if model is empty,
|
||||
/// falls back to the provider config's `default_model` → if that is also
|
||||
/// empty, uses `"deepseek-v4-flash-free"` as the ultimate default.
|
||||
pub fn resolve_subagent_provider(
|
||||
settings: &zesdex_domain::cms::Settings,
|
||||
app_config: &zesdex_domain::cms::AppConfig,
|
||||
) -> (String, String) {
|
||||
let provider = settings.provider.clone();
|
||||
let model = settings.model.clone();
|
||||
|
||||
// Use the default model from the provider config if available
|
||||
let model = if model.is_empty() {
|
||||
app_config
|
||||
.providers
|
||||
.get(&provider)
|
||||
.and_then(|p| p.default_model.clone())
|
||||
.unwrap_or_else(|| "deepseek-v4-flash-free".to_string())
|
||||
} else {
|
||||
model
|
||||
};
|
||||
|
||||
(provider, model)
|
||||
}
|
||||
Reference in New Issue
Block a user