1e186369c9
Project CI / AI game creator shell Rust crates (push) Successful in 1m24s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m56s
Project CI / AI game creator shell Rust lane 1/2 (push) Has been cancelled
Project CI / Frontend tests (push) Has been cancelled
Project CI / Backend tests (push) Has been cancelled
Project CI / Repository checks (push) Has been cancelled
Project CI / AI game creator shell web tests (push) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (push) Has been cancelled
Project CI / Native shell tests (push) Has been cancelled
Reviewed-on: https://git.genarrative.world/git/GenarrativeAI/Genarrative/pulls/446 Co-authored-by: Linghong <ink29535@proton.me> Co-committed-by: Linghong <ink29535@proton.me>
283 lines
7.1 KiB
Rust
283 lines
7.1 KiB
Rust
//! 客户端埋点上传合同;字段与本地 schema v1 保持一致。
|
|
use serde::{Deserialize, Deserializer, Serialize};
|
|
use serde_json::Value;
|
|
|
|
fn required_nullable<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
|
|
where
|
|
D: Deserializer<'de>,
|
|
T: Deserialize<'de>,
|
|
{
|
|
Option::<T>::deserialize(deserializer)
|
|
}
|
|
|
|
macro_rules! values {
|
|
($name:ident { $($variant:ident),+ $(,)? }) => {
|
|
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq)]
|
|
#[serde(rename_all = "snake_case")]
|
|
pub enum $name { $($variant),+ }
|
|
};
|
|
}
|
|
|
|
values!(Source {
|
|
Editor,
|
|
Direct,
|
|
DesignAgent,
|
|
AssetCanvas,
|
|
ResourceEditor,
|
|
UiEditor,
|
|
Manual,
|
|
System
|
|
});
|
|
values!(Status { Success, Failed });
|
|
values!(EntrySource {
|
|
DirectLaunch,
|
|
ProjectAssociation,
|
|
AppRestore
|
|
});
|
|
values!(SessionEndReason {
|
|
UserExit,
|
|
AppRestart
|
|
});
|
|
values!(FocusReason {
|
|
InitialFocus,
|
|
WindowFocus,
|
|
Restore,
|
|
AccountChange
|
|
});
|
|
values!(BlurReason {
|
|
WindowBlur,
|
|
Minimized,
|
|
AppExit,
|
|
SystemSuspend,
|
|
AccountChange
|
|
});
|
|
values!(CreationSource {
|
|
HomeGame,
|
|
HomeDesign,
|
|
Template,
|
|
SelectedDirectory
|
|
});
|
|
values!(OpenSource {
|
|
Create,
|
|
Picker,
|
|
Recent,
|
|
AppRestore,
|
|
ProjectAssociation
|
|
});
|
|
values!(AgentType {
|
|
GameAgent,
|
|
DesignAgent
|
|
});
|
|
values!(RunSource {
|
|
UserSubmit,
|
|
UserContinue,
|
|
Clarification,
|
|
Approval,
|
|
UserRetry
|
|
});
|
|
values!(RunEndReason {
|
|
Finished,
|
|
WaitingForUser,
|
|
WaitingForApproval,
|
|
Failed
|
|
});
|
|
values!(ErrorCode {
|
|
ProviderAuthFailed,
|
|
ProviderRateLimited,
|
|
ProviderUnavailable,
|
|
ProviderTimeout,
|
|
ProviderInvalidResponse,
|
|
LocalIoFailed,
|
|
RuntimeFailed,
|
|
RuntimeErrorUnclassified
|
|
});
|
|
values!(RevisionSource {
|
|
Agent,
|
|
AssetCanvas,
|
|
ResourceEditor,
|
|
UiEditor,
|
|
ManualEdit,
|
|
SystemProjection
|
|
});
|
|
values!(ChangeKind {
|
|
Code,
|
|
Asset,
|
|
Ui,
|
|
DesignDocument,
|
|
Mixed
|
|
});
|
|
values!(PreviewSource {
|
|
User,
|
|
Agent,
|
|
AutoRestore
|
|
});
|
|
values!(SaveSource {
|
|
Manual,
|
|
Auto,
|
|
Checkpoint
|
|
});
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct SessionStart {
|
|
pub entry_source: EntrySource,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub first_project_id: Option<String>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct SessionEnd {
|
|
pub end_reason: SessionEndReason,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub session_duration_ms: Option<u64>,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub last_project_id: Option<String>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct FocusStart {
|
|
pub focus_interval_id: String,
|
|
pub focus_reason: FocusReason,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub active_project_id: Option<String>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct FocusEnd {
|
|
pub focus_interval_id: String,
|
|
pub blur_reason: BlurReason,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub focus_duration_ms: Option<u64>,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub active_project_id: Option<String>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct ProjectCreated {
|
|
pub creation_source: CreationSource,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub project_template_id: Option<String>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct ProjectOpened {
|
|
pub open_source: OpenSource,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub is_first_open: Option<bool>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct EmptyProperties {}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct RunFinished {
|
|
pub agent_type: AgentType,
|
|
pub run_source: RunSource,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub duration_ms: Option<u64>,
|
|
pub retry_index: u64,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub output_change_detected: Option<bool>,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub revision_id: Option<String>,
|
|
pub end_reason: RunEndReason,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct RevisionCreated {
|
|
pub revision_id: String,
|
|
pub revision_source: RevisionSource,
|
|
pub change_kind: ChangeKind,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub files_changed_count: Option<u64>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct PreviewReady {
|
|
pub preview_source: PreviewSource,
|
|
pub preview_version: String,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub ready_duration_ms: Option<u64>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct ProjectSaved {
|
|
pub save_source: SaveSource,
|
|
#[serde(skip_serializing_if = "Option::is_none")]
|
|
pub revision_id: Option<String>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(
|
|
tag = "event_name",
|
|
content = "properties",
|
|
rename_all = "snake_case",
|
|
deny_unknown_fields
|
|
)]
|
|
pub enum EventData {
|
|
EditorSessionStart(SessionStart),
|
|
EditorSessionEnd(SessionEnd),
|
|
EditorFocusStart(FocusStart),
|
|
EditorFocusEnd(FocusEnd),
|
|
ProjectCreateSuccess(ProjectCreated),
|
|
ProjectOpen(ProjectOpened),
|
|
CreativeTaskSubmit(EmptyProperties),
|
|
AgentRunCompleted(RunFinished),
|
|
AgentRunFailed(RunFinished),
|
|
ProjectRevisionCreated(RevisionCreated),
|
|
PreviewReady(PreviewReady),
|
|
ProjectSave(ProjectSaved),
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct Event {
|
|
pub schema_version: u32,
|
|
pub event_id: String,
|
|
pub event_name: String,
|
|
pub event_time: String,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub user_id: Option<String>,
|
|
pub editor_session_id: String,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub project_id: Option<String>,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub creative_task_id: Option<String>,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub agent_run_id: Option<String>,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub agent_turn_id: Option<String>,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub status: Option<Status>,
|
|
#[serde(deserialize_with = "required_nullable")]
|
|
pub error_code: Option<ErrorCode>,
|
|
pub source: Source,
|
|
pub client_version: String,
|
|
pub properties: Value,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct AgcAnalyticsBatch {
|
|
pub schema_version: u32,
|
|
pub batch_id: String,
|
|
pub destination_origin: String,
|
|
pub user_id: String,
|
|
pub events: Vec<Event>,
|
|
}
|
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
|
#[serde(deny_unknown_fields)]
|
|
pub struct AgcAnalyticsAcknowledgement {
|
|
pub acknowledged_batch_ids: Vec<String>,
|
|
pub event_count: u32,
|
|
}
|