awaken-runtime 0.6.0

Phase-based execution engine, plugin system, and agent loop for Awaken
Documentation
use awaken_runtime_contract::registry_spec::ModelSpec;

use super::{CapabilitySource, ModelCapabilityPatch, ModelCapabilitySources};

pub(super) fn discovered_numeric_pair_is_usable(
    patch: &ModelCapabilityPatch,
    model_id: &str,
) -> bool {
    match (patch.context_window, patch.max_output_tokens) {
        (Some(context_window), Some(max_output_tokens))
            if context_window > 0
                && max_output_tokens > 0
                && max_output_tokens > context_window =>
        {
            tracing::warn!(
                model = model_id,
                context_window,
                max_output_tokens,
                "provider discovery ignored invalid token limit pair"
            );
            false
        }
        _ => true,
    }
}

pub(super) fn valid_context_window_candidate(
    value: u32,
    max_output_tokens: Option<u32>,
    source: CapabilitySource,
    model_id: &str,
) -> bool {
    if value == 0 {
        tracing::warn!(
            model = model_id,
            ?source,
            "ignored zero context_window capability"
        );
        return false;
    }
    if let Some(max_output_tokens) = max_output_tokens
        && max_output_tokens > 0
        && max_output_tokens > value
    {
        tracing::warn!(
            model = model_id,
            ?source,
            context_window = value,
            max_output_tokens,
            "ignored context_window capability below max_output_tokens"
        );
        return false;
    }
    true
}

pub(super) fn valid_max_output_tokens_candidate(
    value: u32,
    context_window: Option<u32>,
    source: CapabilitySource,
    model_id: &str,
) -> bool {
    if value == 0 {
        tracing::warn!(
            model = model_id,
            ?source,
            "ignored zero max_output_tokens capability"
        );
        return false;
    }
    if let Some(context_window) = context_window
        && context_window > 0
        && value > context_window
    {
        tracing::warn!(
            model = model_id,
            ?source,
            context_window,
            max_output_tokens = value,
            "ignored max_output_tokens capability above context_window"
        );
        return false;
    }
    true
}

pub(super) fn enforce_resolved_numeric_invariants(
    model: &mut ModelSpec,
    sources: &mut ModelCapabilitySources,
) {
    if model.context_window == Some(0) {
        tracing::warn!("resolved model capability dropped zero context_window");
        model.context_window = None;
        sources.context_window = None;
    }
    if model.max_output_tokens == Some(0) {
        tracing::warn!("resolved model capability dropped zero max_output_tokens");
        model.max_output_tokens = None;
        sources.max_output_tokens = None;
    }
    let (Some(context_window), Some(max_output_tokens)) =
        (model.context_window, model.max_output_tokens)
    else {
        return;
    };
    if max_output_tokens <= context_window {
        return;
    }

    if sources.max_output_tokens != Some(CapabilitySource::ExplicitSpec) {
        tracing::warn!(
            context_window,
            max_output_tokens,
            "resolved model capability dropped max_output_tokens above context_window"
        );
        model.max_output_tokens = None;
        sources.max_output_tokens = None;
    } else if sources.context_window != Some(CapabilitySource::ExplicitSpec) {
        tracing::warn!(
            context_window,
            max_output_tokens,
            "resolved model capability dropped context_window below max_output_tokens"
        );
        model.context_window = None;
        sources.context_window = None;
    } else {
        tracing::warn!(
            context_window,
            max_output_tokens,
            "resolved model capability dropped invalid explicit max_output_tokens"
        );
        model.max_output_tokens = None;
        sources.max_output_tokens = None;
    }
}

pub(super) fn sanitize_provider_capability_patch(
    model_id: &str,
    mut patch: ModelCapabilityPatch,
) -> ModelCapabilityPatch {
    if let (Some(context_window), Some(max_output_tokens)) =
        (patch.context_window, patch.max_output_tokens)
        && max_output_tokens > context_window
    {
        tracing::warn!(
            model = model_id,
            context_window,
            max_output_tokens,
            "provider discovery ignored invalid token limit pair"
        );
        patch.context_window = None;
        patch.max_output_tokens = None;
    }
    patch
}

pub(super) fn first_nonzero_u32(item: &serde_json::Value, keys: &[&str]) -> Option<u32> {
    for key in keys {
        let Some(value) = item.get(*key).and_then(json_u32) else {
            continue;
        };
        if value == 0 {
            tracing::warn!(field = *key, "provider discovery ignored zero token limit");
            continue;
        }
        return Some(value);
    }
    None
}

fn json_u32(value: &serde_json::Value) -> Option<u32> {
    if let Some(number) = value.as_u64() {
        return u32::try_from(number).ok();
    }
    value.as_str().and_then(|string| string.parse::<u32>().ok())
}