Skip to main content

agent_first_http/sdk/fetch/artifacts/
console.rs

1//! Console event capture (`console.json`) via CDP
2//! `Runtime.consoleAPICalled` + `Runtime.exceptionThrown`.
3
4use std::path::PathBuf;
5
6use serde::{Deserialize, Serialize};
7
8use crate::sdk::fetch::writer;
9use crate::shared::artifacts::{Artifact, ArtifactPaths};
10use crate::shared::error::{Error, ErrorCode};
11
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct ConsoleLog {
14    pub schema_version: u32,
15    pub events: Vec<ConsoleEvent>,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19pub struct ConsoleEvent {
20    pub level: ConsoleLevel,
21    pub timestamp_ms: f64,
22    pub text: String,
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub url: Option<String>,
25    #[serde(skip_serializing_if = "Option::is_none")]
26    pub line_number: Option<u32>,
27}
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
30#[serde(rename_all = "snake_case")]
31pub enum ConsoleLevel {
32    Log,
33    Debug,
34    Info,
35    Warn,
36    Error,
37    Exception,
38}
39
40pub async fn write(paths: &ArtifactPaths, log: &ConsoleLog) -> Result<PathBuf, Error> {
41    let target = paths.file_for(Artifact::Console);
42    let bytes = serde_json::to_vec_pretty(log).map_err(|e| {
43        Error::new(
44            ErrorCode::InternalError,
45            format!("serialize console log: {e}"),
46        )
47    })?;
48    writer::write_bytes(&target, &bytes).await?;
49    Ok(target)
50}