vv-agent 0.1.3

VectorVein agent runtime, SDK, CLI, tools, and workspace backends
Documentation
use std::collections::BTreeMap;

use serde_json::Value;

use crate::llm::LlmStreamCallback;

use super::tool_calls::StreamingToolCallParts;

pub(super) fn emit_reasoning_delta_event(
    stream_callback: &Option<LlmStreamCallback>,
    reasoning_delta: String,
    reasoning_chars: usize,
) {
    emit_stream_event(
        stream_callback,
        BTreeMap::from([
            (
                "event".to_string(),
                Value::String("reasoning_delta".to_string()),
            ),
            (
                "reasoning_delta".to_string(),
                Value::String(reasoning_delta),
            ),
            (
                "reasoning_chars".to_string(),
                Value::from(reasoning_chars as u64),
            ),
            (
                "estimated_tokens".to_string(),
                Value::from(estimate_stream_tokens(reasoning_chars) as u64),
            ),
        ]),
    );
}

pub(super) fn emit_assistant_delta_event(
    stream_callback: &Option<LlmStreamCallback>,
    content_delta: String,
    content_chars: usize,
) {
    emit_stream_event(
        stream_callback,
        BTreeMap::from([
            (
                "event".to_string(),
                Value::String("assistant_delta".to_string()),
            ),
            ("content_delta".to_string(), Value::String(content_delta)),
            (
                "content_chars".to_string(),
                Value::from(content_chars as u64),
            ),
            (
                "estimated_tokens".to_string(),
                Value::from(estimate_stream_tokens(content_chars) as u64),
            ),
        ]),
    );
}

pub(super) fn emit_tool_stream_event(
    stream_callback: &Option<LlmStreamCallback>,
    event_name: &str,
    default_tool_call_index: usize,
    tool_call: &StreamingToolCallParts,
) {
    let tool_call_index = tool_call.index.unwrap_or(default_tool_call_index);
    emit_stream_event(
        stream_callback,
        BTreeMap::from([
            ("event".to_string(), Value::String(event_name.to_string())),
            (
                "tool_call_id".to_string(),
                Value::String(tool_call.id.clone()),
            ),
            (
                "tool_call_index".to_string(),
                Value::from(tool_call_index as u64),
            ),
            (
                "function_name".to_string(),
                Value::String(tool_call.name.clone()),
            ),
            (
                "arguments_chars".to_string(),
                Value::from(tool_call.arguments.chars().count() as u64),
            ),
            (
                "estimated_tokens".to_string(),
                Value::from(estimate_stream_tokens(tool_call.arguments.chars().count()) as u64),
            ),
        ]),
    );
}

fn emit_stream_event(stream_callback: &Option<LlmStreamCallback>, event: BTreeMap<String, Value>) {
    if let Some(callback) = stream_callback {
        callback(&event);
    }
}

fn estimate_stream_tokens(char_count: usize) -> usize {
    if char_count == 0 {
        0
    } else {
        char_count.div_ceil(4)
    }
}