arc-agi-rs 0.1.0

🤖 A Rust client SDK for the ARC-AGI-3 API.
Documentation
// Copyright 2026 Mahmoud Harmouch.
//
// Licensed under the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! # API Response Types
//!
//! This module contains the deserialisation types for every response returned by
//! the ARC-AGI-3 REST API.
//!
//! ## Response Types
//!
//! | Type | Endpoint | Description |
//! |------|----------|-------------|
//! | [`ScorecardOpenResponse`] | `POST /api/scorecard/open` | Card ID from a new scorecard |
//! | [`AnonKeyResponse`] | `GET /api/games/anonkey` | Anonymous API key |
//! | [`EnvironmentScore`] | embedded | Per-game score with level details |
//! | [`EnvironmentScoreList`] | embedded | All runs for a single game |
//! | [`EnvironmentScorecard`] | scorecard endpoints | Full scored scorecard |
//! | [`ErrorResponse`] | all | Structured API error body |
//!
//! ## See Also
//!
//! - [ARC-AGI-3 Reference](https://arcprize.org/arc-agi/3)

use crate::models::GameState;
use serde::{Deserialize, Serialize};
use serde_json::Value;

/// Response body from `POST /api/scorecard/open`.
///
/// # Example
/// ```rust
/// use arc_agi_rs::response::ScorecardOpenResponse;
///
/// let json = r#"{"card_id":"sc-abc123"}"#;
/// let resp: ScorecardOpenResponse = serde_json::from_str(json).unwrap();
/// assert_eq!(resp.card_id, "sc-abc123");
/// ```
#[derive(Debug, Clone, Deserialize)]
pub struct ScorecardOpenResponse {
    /// Unique identifier for the newly created scorecard.
    pub card_id: String,
}

/// Response body from `GET /api/games/anonkey`.
///
/// # Example
/// ```rust
/// use arc_agi_rs::response::AnonKeyResponse;
///
/// let json = r#"{"api_key":"anon-xyz"}"#;
/// let resp: AnonKeyResponse = serde_json::from_str(json).unwrap();
/// assert_eq!(resp.api_key, "anon-xyz");
/// ```
#[derive(Debug, Clone, Deserialize)]
pub struct AnonKeyResponse {
    /// The anonymous API key to use for unauthenticated requests.
    pub api_key: String,
}

/// Structured error body returned by the API on failure.
///
/// # Example
/// ```rust
/// use arc_agi_rs::response::ErrorResponse;
///
/// let json = r#"{"error":"SERVER_ERROR","message":"game not found"}"#;
/// let resp: ErrorResponse = serde_json::from_str(json).unwrap();
/// assert_eq!(resp.error, "SERVER_ERROR");
/// ```
#[derive(Debug, Clone, Deserialize)]
pub struct ErrorResponse {
    /// Machine-readable error code (see [`crate::error::ApiError`]).
    pub error: String,
    /// Human-readable description of the error.
    pub message: Option<String>,
}

/// Per-game score for a single play-through of one environment.
///
/// Embedded inside [`EnvironmentScoreList`] and [`EnvironmentScorecard`].
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct EnvironmentScore {
    /// Game identifier this score belongs to.
    pub id: Option<String>,
    /// Unique run identifier.
    pub guid: Option<String>,
    /// Aggregate score for this run (0.0–115.0).
    pub score: f64,
    /// Number of levels completed.
    pub levels_completed: u32,
    /// Total number of actions taken.
    pub actions: u32,
    /// Number of times the environment was reset.
    pub resets: Option<u32>,
    /// Terminal game state.
    pub state: Option<GameState>,
    /// Whether the environment was fully completed.
    pub completed: Option<bool>,
    /// Per-level scores.
    pub level_scores: Option<Vec<f64>>,
    /// Per-level action counts.
    pub level_actions: Option<Vec<u32>>,
    /// Per-level human baseline action counts.
    pub level_baseline_actions: Option<Vec<i32>>,
    /// Total number of levels (present when level details are omitted).
    pub number_of_levels: Option<u32>,
    /// Total number of distinct environments (present when level details are omitted).
    pub number_of_environments: Option<u32>,
    /// Optional diagnostic message (e.g. missing baseline data).
    pub message: Option<String>,
}

/// All play-through scores for a single game environment.
///
/// The `score` field reflects the best run; `actions` is the cumulative total.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnvironmentScoreList {
    /// Game identifier.
    pub id: String,
    /// Individual run scores.
    pub runs: Vec<EnvironmentScore>,
    /// Best score across all runs.
    pub score: f64,
    /// Total actions across all runs.
    pub actions: u32,
    /// Maximum levels completed across all runs.
    pub levels_completed: u32,
    /// Whether any run reached a completed state.
    pub completed: bool,
    /// Maximum level count across all runs.
    pub level_count: u32,
    /// Total resets across all runs.
    pub resets: u32,
}

/// Full scored scorecard returned by scorecard endpoints.
///
/// Returned by [`crate::client::Client::get_scorecard`] and
/// [`crate::client::Client::close_scorecard`].
///
/// # Example
/// ```rust
/// use arc_agi_rs::response::EnvironmentScorecard;
///
/// let json = r#"{
///     "card_id": "sc-abc",
///     "score": 0.0,
///     "environments": [],
///     "tags_scores": []
/// }"#;
/// let card: EnvironmentScorecard = serde_json::from_str(json).unwrap();
/// assert_eq!(card.card_id, "sc-abc");
/// ```
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnvironmentScorecard {
    /// Unique scorecard identifier.
    pub card_id: String,
    /// Optional source URL supplied at creation time.
    pub source_url: Option<String>,
    /// Classification tags supplied at creation time.
    pub tags: Option<Vec<String>>,
    /// Freeform opaque data supplied at creation time.
    pub opaque: Option<Value>,
    /// Aggregate score across all environments (0.0–115.0).
    pub score: f64,
    /// Per-environment scored results.
    pub environments: Vec<EnvironmentScoreList>,
    /// Per-tag aggregate scores.
    pub tags_scores: Vec<EnvironmentScore>,
    /// Whether the scorecard was created in competition mode.
    pub competition_mode: Option<bool>,
    /// Total number of completed environments.
    pub total_environments_completed: Option<u32>,
    /// Total number of environments.
    pub total_environments: Option<u32>,
    /// Total levels completed across all environments.
    pub total_levels_completed: Option<u32>,
    /// Total number of levels across all environments.
    pub total_levels: Option<u32>,
    /// Total actions taken across all environments.
    pub total_actions: Option<u32>,
}

// Copyright 2026 Mahmoud Harmouch.
//
// Licensed under the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.