Files
Genarrative/server-rs/crates/shared-contracts/src/external_generation.rs
T
menghao 03a4410272
Project CI / Repository checks (push) Successful in 1m5s
Project CI / Frontend tests (push) Successful in 3m20s
Project CI / Backend tests (push) Successful in 4m1s
Project CI / Native shell tests (push) Failing after 11m56s
game agent无限画布开发 (#136)
主要工作是共享同一套“画布内核与通用 UI 源码”,网站和 Tauri 只分别实现宿主适配层。

---------

Co-authored-by: 段舒康 <kdletters@qq.com>
Co-authored-by: kdletters <kdletters@qq.com>
Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/136
Co-authored-by: menghao <mh18530625731@163.com>
Co-committed-by: menghao <mh18530625731@163.com>
2026-08-12 10:54:16 +08:00

164 lines
5.4 KiB
Rust

use serde::{Deserialize, Serialize};
use serde_json::Value;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
pub enum ExternalGenerationJobStatus {
Queued,
Running,
Completed,
Failed,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExternalGenerationQueueOverview {
pub pending_count: u32,
pub running_count: u32,
pub unacknowledged_terminal_count: u32,
pub updated_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExternalGenerationQueueOverviewResponse {
pub overview: ExternalGenerationQueueOverview,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExternalGenerationJobStatusRecord {
pub operation_id: String,
pub status: ExternalGenerationJobStatus,
pub phase_label: String,
pub phase_detail: String,
pub progress: u8,
pub error: Option<String>,
pub updated_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExternalGenerationJobStatusDetailRecord {
#[serde(flatten)]
pub status: ExternalGenerationJobStatusRecord,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub warning: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub result: Option<Value>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExternalGenerationJobStatusResponse {
pub job: ExternalGenerationJobStatusDetailRecord,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExternalEditorGenerationSubmissionResponse {
pub operation_id: String,
pub kind: String,
pub status: ExternalGenerationJobStatus,
pub status_url: String,
pub poll_after_ms: u64,
pub updated_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExternalEditorGenerationJobResponse {
pub operation_id: String,
pub kind: String,
pub status: ExternalGenerationJobStatus,
pub phase_label: String,
pub phase_detail: String,
pub progress: u8,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub error: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub warning: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub result: Option<Value>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub poll_after_ms: Option<u64>,
pub updated_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExternalGenerationTaskRecord {
pub job_id: String,
pub job_kind: String,
pub source_module: String,
pub source_entity_id: String,
pub request_label: String,
pub request_prompt: Option<String>,
pub status: ExternalGenerationJobStatus,
pub phase_label: String,
pub phase_detail: String,
pub progress: u8,
pub error: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub warning: Option<String>,
pub price_mud_points: u64,
pub refund_ledger_id: Option<String>,
pub notification_acknowledged_at: Option<String>,
pub created_at: String,
pub started_at: Option<String>,
pub completed_at: Option<String>,
pub updated_at: String,
pub updated_at_micros: i64,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExternalGenerationTaskListResponse {
pub tasks: Vec<ExternalGenerationTaskRecord>,
pub overview: ExternalGenerationQueueOverview,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExternalGenerationTaskAcknowledgeRequest {
pub job_ids: Vec<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct ExternalGenerationTaskAcknowledgeResponse {
pub acknowledged_tasks: Vec<ExternalGenerationTaskRecord>,
}
#[cfg(test)]
mod tests {
use serde_json::json;
use super::*;
#[test]
fn status_detail_serializes_warning_without_reusing_error() {
let payload = serde_json::to_value(ExternalGenerationJobStatusResponse {
job: ExternalGenerationJobStatusDetailRecord {
status: ExternalGenerationJobStatusRecord {
operation_id: "job-1".to_string(),
status: ExternalGenerationJobStatus::Completed,
phase_label: "图标素材生成".to_string(),
phase_detail: "生成已完成。".to_string(),
progress: 100,
error: None,
updated_at_micros: 1,
},
warning: Some("连通域数量不足".to_string()),
result: Some(json!({ "resourceId": "resource-1" })),
},
})
.expect("状态响应应可序列化");
assert_eq!(payload["job"]["warning"], json!("连通域数量不足"));
assert_eq!(payload["job"]["result"]["resourceId"], json!("resource-1"));
assert_eq!(payload["job"]["error"], json!(null));
assert_eq!(payload["job"]["status"], json!("completed"));
}
}