systemprompt_cli/commands/infrastructure/logs/request/
mod.rs1mod list;
2mod show;
3mod stats;
4
5use anyhow::Result;
6use clap::Subcommand;
7use schemars::JsonSchema;
8use serde::{Deserialize, Serialize};
9use systemprompt_runtime::DatabaseContext;
10
11use super::types::{MessageRow, ToolCallRow};
12use crate::CliConfig;
13
14#[derive(Debug, Subcommand)]
15pub enum RequestCommands {
16 #[command(
17 about = "List recent AI requests",
18 after_help = "EXAMPLES:\n systemprompt infra logs request list\n systemprompt infra \
19 logs request list --model gpt-4 --since 1h"
20 )]
21 List(list::ListArgs),
22
23 #[command(
24 about = "Show AI request details",
25 after_help = "EXAMPLES:\n systemprompt infra logs request show abc123\n systemprompt \
26 infra logs request show abc123 --messages --tools"
27 )]
28 Show(show::ShowArgs),
29
30 #[command(
31 about = "Show aggregate AI request statistics",
32 after_help = "EXAMPLES:\n systemprompt infra logs request stats\n systemprompt infra \
33 logs request stats --since 24h"
34 )]
35 Stats(stats::StatsArgs),
36}
37
38#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
39pub struct RequestListRow {
40 pub request_id: String,
41 pub timestamp: String,
42 pub provider: String,
43 pub model: String,
44 pub tokens: String,
45 pub cost: String,
46 #[serde(skip_serializing_if = "Option::is_none")]
47 pub latency_ms: Option<i64>,
48 pub status: String,
49}
50
51#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
52pub struct RequestListOutput {
53 pub requests: Vec<RequestListRow>,
54 pub total: u64,
55}
56
57#[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)]
58pub struct RequestShowOutput {
59 pub request_id: String,
60 pub provider: String,
61 pub model: String,
62 pub input_tokens: i32,
63 pub output_tokens: i32,
64 pub cost_dollars: f64,
65 pub latency_ms: i64,
66 pub status: String,
67 #[serde(skip_serializing_if = "Option::is_none")]
68 pub error_message: Option<String>,
69 pub messages: Vec<MessageRow>,
70 pub linked_mcp_calls: Vec<ToolCallRow>,
71}
72
73pub async fn execute(command: RequestCommands, config: &CliConfig) -> Result<()> {
74 match command {
75 RequestCommands::List(args) => list::execute(args, config).await,
76 RequestCommands::Show(args) => show::execute(args, config).await,
77 RequestCommands::Stats(args) => stats::execute(args, config).await,
78 }
79}
80
81pub async fn execute_with_pool(
82 command: RequestCommands,
83 db_ctx: &DatabaseContext,
84 config: &CliConfig,
85) -> Result<()> {
86 match command {
87 RequestCommands::List(args) => list::execute_with_pool(args, db_ctx, config).await,
88 RequestCommands::Show(args) => show::execute_with_pool(args, db_ctx, config).await,
89 RequestCommands::Stats(args) => stats::execute_with_pool(args, db_ctx, config).await,
90 }
91}