use std::pin::Pin;
use futures::Stream;
use objectiveai_sdk::cli::command::agents::logs::token_usage::subscribe::{
AgentsInactiveTag, Request, ResponseItem, TokenUsage,
};
use crate::context::Context;
use crate::error::Error;
type ItemStream = Pin<Box<dyn Stream<Item = Result<ResponseItem, Error>> + Send>>;
fn once(item: Result<ResponseItem, Error>) -> ItemStream {
Box::pin(futures::stream::once(async move { item }))
}
pub async fn execute(ctx: &Context, request: Request) -> Result<ItemStream, Error> {
let db = ctx.db_client().await?.clone();
let state_dir = ctx.filesystem.state_dir();
let aih = request.agent_instance_hierarchy;
let previous = request.previous;
let baseline = crate::db::logs::get_agent_token_usage(&db, &aih).await?;
if let (Some(prev), Some(current)) = (previous, baseline) {
if current != prev {
return Ok(once(Ok(ResponseItem::Item(TokenUsage {
agent_instance_hierarchy: aih,
total_tokens: current,
}))));
}
}
let (lock_dir, lock_key) =
crate::command::agents::locks::agent_instance_lock(&state_dir, &aih);
let item: Result<ResponseItem, Error> = tokio::select! {
result = crate::db::logs::wait_for_token_usage_change(&db, &aih, baseline) => {
result
.map(|total_tokens| ResponseItem::Item(TokenUsage {
agent_instance_hierarchy: aih.clone(),
total_tokens,
}))
.map_err(Error::from)
}
result = objectiveai_sdk::lockfile::wait_released(&lock_dir, &lock_key) => {
match result {
Ok(()) => {
match crate::db::logs::get_agent_token_usage(&db, &aih).await {
Ok(current) if current != baseline => match current {
Some(total_tokens) => Ok(ResponseItem::Item(TokenUsage {
agent_instance_hierarchy: aih.clone(),
total_tokens,
})),
None => Ok(ResponseItem::AgentsInactive(
AgentsInactiveTag::AgentsInactive,
)),
},
Ok(_) => Ok(ResponseItem::AgentsInactive(
AgentsInactiveTag::AgentsInactive,
)),
Err(e) => Err(Error::from(e)),
}
}
Err(e) => Err(Error::Lockfile { key: lock_key.clone(), source: e }),
}
}
};
Ok(once(item))
}
pub mod request_schema {
use objectiveai_sdk::cli::command::agents::logs::token_usage::subscribe as sdk;
use objectiveai_sdk::cli::command::agents::logs::token_usage::subscribe::request_schema::{
Request, Response,
};
use crate::context::Context;
use crate::error::Error;
pub async fn execute(_ctx: &Context, _request: Request) -> Result<Response, Error> {
Ok(objectiveai_sdk::cli::command::ResponseSchema(schemars::schema_for!(sdk::Request)))
}
}
pub mod response_schema {
use objectiveai_sdk::cli::command::agents::logs::token_usage::subscribe as sdk;
use objectiveai_sdk::cli::command::agents::logs::token_usage::subscribe::response_schema::{
Request, Response,
};
use crate::context::Context;
use crate::error::Error;
pub async fn execute(_ctx: &Context, _request: Request) -> Result<Response, Error> {
Ok(objectiveai_sdk::cli::command::ResponseSchema(schemars::schema_for!(sdk::ResponseItem)))
}
}