use crank_core::{ AgentId, AgentStatus, ApprovalRequestStatus, AuthConfig, AuthKind, ExecutionMode, ExportMode, GeneratedDraft, InvocationLevel, InvocationSource, InvocationStatus, OperationAvailability, OperationSecurityLevel, OperationStatus, OperationVersionState, PlatformApiKeyKind, PlatformApiKeyScope, Protocol, SecretKind, Target, ToolSelectionPolicy, UsagePeriod, WizardState, WorkspaceId, WorkspaceStatus, }; use crank_mapping::MappingSet; use crank_registry::{ InvocationLogRecord, PlatformApiKeyRecord, RegistryOperation, UsageAgentBreakdown, UsageOperationBreakdown, UsageOutcomeGroup, UsageSummary, UsageTimelinePoint, WorkspaceMembershipRecord, WorkspaceRecord, }; use crank_schema::Schema; use serde::{Deserialize, Serialize}; use serde_json::Value; #[derive(Clone, Debug, Deserialize)] pub struct LoginPayload { pub email: String, pub password: String, } #[derive(Clone, Debug, Deserialize)] pub struct CompleteBootstrapPayload { pub token: String, pub password: String, } #[derive(Clone, Debug, Serialize)] pub struct BootstrapStatusResponse { pub bootstrap_required: bool, } #[derive(Clone, Debug, Serialize)] pub struct SessionResponse { pub user: crank_core::User, pub memberships: Vec, pub current_workspace_id: Option, pub csrf_token: String, } #[derive(Clone, Debug, Deserialize)] pub struct UpdateProfilePayload { pub display_name: String, pub email: String, } #[derive(Clone, Debug, Deserialize)] pub struct ChangePasswordPayload { pub current_password: String, pub new_password: String, } #[derive(Clone, Debug, Deserialize)] pub struct UpdateCurrentWorkspacePayload { pub workspace_id: String, } #[derive(Clone, Debug, Deserialize, Serialize)] pub struct OperationPayload { pub name: String, pub display_name: String, #[serde(default = "default_operation_category")] pub category: String, pub protocol: Protocol, #[serde(default)] pub security_level: OperationSecurityLevel, pub target: Target, pub input_schema: Schema, pub output_schema: Schema, pub input_mapping: MappingSet, pub output_mapping: MappingSet, pub execution_config: crank_core::ExecutionConfig, pub tool_description: crank_core::ToolDescription, #[serde(default)] pub wizard_state: Option, } #[derive(Clone, Debug, Deserialize)] pub struct NewVersionPayload { #[serde(flatten)] pub operation: OperationPayload, #[serde(default)] pub change_note: Option, } #[derive(Clone, Debug, Deserialize)] pub struct PublishPayload { pub version: u32, } #[derive(Clone, Debug, Deserialize)] pub struct TestRunPayload { pub version: u32, pub input: Value, #[serde(default)] pub confirmation_token: Option, #[serde(default)] pub locale: Option, } #[derive(Clone, Debug, Serialize)] pub struct TestRunResult { pub ok: bool, pub mode: ExecutionMode, pub tested_version: u32, pub request_id: String, pub trace_id: String, pub request_preview: Value, pub response_preview: Value, pub errors: Vec, } #[derive(Clone, Debug, Deserialize)] pub struct AuthProfilePayload { pub name: String, pub kind: AuthKind, pub config: AuthConfig, } #[derive(Clone, Debug, Deserialize)] pub struct UpstreamPayload { pub name: String, pub base_url: String, #[serde(default)] pub static_headers: Value, #[serde(default)] pub auth_profile_id: Option, } #[derive(Clone, Debug, Deserialize)] pub struct SecretPayload { pub name: String, pub kind: SecretKind, pub value: Value, } #[derive(Clone, Debug, Deserialize)] pub struct RotateSecretPayload { pub value: Value, } #[derive(Clone, Debug, Deserialize)] pub struct WorkspacePayload { pub slug: String, pub display_name: String, #[serde(default)] pub settings: Value, } #[derive(Clone, Debug, Deserialize)] pub struct UpdateWorkspacePayload { pub slug: Option, pub display_name: Option, pub status: Option, pub settings: Option, } #[derive(Clone, Debug, Deserialize)] pub struct AgentPayload { pub slug: String, pub display_name: String, pub description: String, #[serde(default)] pub instructions: Value, #[serde(default)] pub tool_selection_policy: ToolSelectionPolicy, } #[derive(Clone, Debug, Deserialize)] pub struct UpdateAgentPayload { pub slug: String, pub display_name: String, pub description: String, } #[derive(Clone, Debug, Deserialize)] pub struct AgentBindingPayload { pub operation_id: String, pub operation_version: u32, pub tool_name: String, pub tool_title: String, pub tool_description_override: Option, #[serde(default = "default_enabled")] pub enabled: bool, } #[derive(Clone, Debug, Deserialize)] pub struct ToolSearchPreviewPayload { pub query: String, #[serde(default)] pub group_ids: Vec, pub bindings: Vec, pub tool_selection_policy: ToolSelectionPolicy, } #[derive(Clone, Debug, Deserialize)] #[serde(untagged)] pub enum AgentCatalogPayload { Bindings(Vec), Config { bindings: Vec, tool_selection_policy: ToolSelectionPolicy, }, } impl AgentCatalogPayload { pub fn into_parts(self) -> (Vec, Option) { match self { Self::Bindings(bindings) => (bindings, None), Self::Config { bindings, tool_selection_policy, } => (bindings, Some(tool_selection_policy)), } } } impl From> for AgentCatalogPayload { fn from(bindings: Vec) -> Self { Self::Bindings(bindings) } } #[derive(Clone, Debug, Serialize)] pub struct CreatedAgentResponse { pub agent_id: String, pub workspace_id: String, pub version: u32, pub status: AgentStatus, } #[derive(Clone, Debug, Serialize)] pub struct PublishAgentResponse { pub agent_id: String, pub workspace_id: String, pub published_version: u32, pub published_at: String, } #[derive(Clone, Debug, Serialize)] pub struct AgentSummaryView { pub id: String, pub workspace_id: String, pub slug: String, pub display_name: String, pub description: String, pub status: AgentStatus, pub current_draft_version: u32, pub latest_published_version: Option, pub catalog_revision: i64, pub created_at: String, pub updated_at: String, pub published_at: Option, pub operation_count: usize, pub operation_ids: Vec, pub tool_selection_policy: ToolSelectionPolicy, pub key_count: usize, pub calls_today: u64, pub mcp_endpoint: String, } #[derive(Clone, Debug, Serialize)] pub struct AgentMutationResult { pub agent_id: String, pub workspace_id: String, pub updated_at: String, } #[derive(Clone, Debug, Deserialize)] pub struct PlatformApiKeyPayload { pub name: String, #[serde(default = "default_platform_api_key_kind")] pub key_kind: PlatformApiKeyKind, pub scopes: Vec, #[serde(default)] pub expires_at: Option, #[serde(default)] pub allowed_origins: Vec, } fn default_platform_api_key_kind() -> PlatformApiKeyKind { PlatformApiKeyKind::McpClient } #[derive(Clone, Debug, Serialize)] pub struct CreatedPlatformApiKeyResponse { pub api_key: PlatformApiKeyRecord, pub secret: String, #[serde(skip_serializing_if = "Option::is_none")] pub connection: Option, } #[derive(Clone, Debug, Serialize)] pub struct EphemeralMcpClientConfig { pub client: String, pub config: Value, } #[derive(Clone, Debug, Serialize)] pub struct EphemeralMcpConnection { pub endpoint: String, pub clients: Vec, pub secret_display: &'static str, } #[derive(Clone, Debug, Deserialize)] #[serde(deny_unknown_fields)] pub struct OnboardingEventPayload { pub event: String, pub idempotency_key: String, pub expected_revision: i64, #[serde(default)] pub completed_steps: Option, } #[derive(Clone, Debug, Serialize)] pub struct OnboardingStepView { pub id: crank_core::OnboardingStepId, pub completed: bool, pub status: String, pub action_code: String, pub reason_code: String, } #[derive(Clone, Debug, Serialize)] pub struct OnboardingFirstCallEvidence { pub log_id: String, pub agent_id: String, pub key_id: String, pub operation_id: String, pub operation_version: u32, pub tool_name: String, pub occurred_at: String, pub request_id: Option, pub trace_id: Option, } #[derive(Clone, Debug, Serialize)] pub struct OnboardingResponse { pub schema_version: u16, pub workspace_id: String, pub revision: i64, pub status: String, pub completed: bool, pub eligible_since: Option, pub steps: Vec, pub operation_id: Option, pub operation_version: Option, pub agent_id: Option, pub catalog_revision: Option, pub platform_api_key_id: Option, pub mcp_endpoint: Option, pub first_call: Option, } #[derive(Clone, Debug, Serialize)] pub struct OnboardingEventResponse { pub accepted: bool, #[serde(flatten)] pub onboarding: OnboardingResponse, } #[derive(Clone, Debug, Deserialize)] #[serde(deny_unknown_fields)] pub struct ResetOnboardingSelectionPayload { pub expected_revision: i64, } #[derive(Clone, Debug, Serialize)] pub struct ResetOnboardingSelectionResponse { pub selection_reset: bool, #[serde(flatten)] pub onboarding: OnboardingResponse, } #[derive(Clone, Debug, Serialize)] pub struct WorkspaceCatalogSnapshotResponse { pub kind: String, pub format_version: String, pub restorable: bool, pub included: Vec, pub excluded: Vec, pub workspace: WorkspaceRecord, pub operations: Vec, pub agents: Vec, pub platform_api_keys: Vec, pub exported_at: String, } #[derive(Clone, Debug, Deserialize)] pub struct LogsQuery { pub level: Option, pub status: Option, pub outcome_group: Option, pub search: Option, pub source: Option, pub operation_id: Option, pub agent_id: Option, pub period: Option, pub created_after: Option, pub created_before: Option, pub cursor: Option, pub limit: Option, } #[derive(Clone, Debug, Deserialize)] pub struct ApprovalsQuery { pub status: Option, pub limit: Option, } #[derive(Clone, Debug, Deserialize)] pub struct ApprovalDecisionPayload { pub approve: String, #[serde(default)] pub note: Option, } #[derive(Clone, Debug, Deserialize)] pub struct UsageRequestQuery { pub period: Option, pub source: Option, pub created_after: Option, pub created_before: Option, } #[derive(Clone, Debug, Serialize)] pub struct UsageOverviewResponse { pub summary: UsageSummary, pub timeline: Vec, pub operations: Vec, pub agents: Vec, pub outcomes: Vec, } #[derive(Clone, Debug, Serialize)] pub struct LogsListResponse { pub items: Vec, pub next_cursor: Option, } #[derive(Clone, Debug, Serialize)] pub struct ProtocolCapabilityView { pub protocol: Protocol, pub supports_execution_modes: Vec, pub supports_transport_behaviors: Vec, pub supports_auth_kinds: Vec, pub supports_upload_artifacts: Vec, pub supports_cursor_path: bool, pub supports_done_path: bool, pub supports_aggregation_mode: Vec, } #[derive(Clone, Debug, Deserialize)] pub struct GenerateDraftPayload { #[serde(default)] pub sources: Vec, } #[derive(Clone, Debug, Serialize)] pub struct DraftGenerationResult { pub generated_draft: GeneratedDraft, pub input_schema: Schema, pub output_schema: Schema, pub input_mapping: MappingSet, pub output_mapping: MappingSet, } #[derive(Clone, Debug, Deserialize)] pub struct ImportQuery { #[serde(default)] pub mode: ImportMode, } #[derive(Clone, Copy, Debug, Default, Deserialize, Serialize)] #[serde(rename_all = "snake_case")] pub enum ImportMode { #[default] Create, Upsert, } #[derive(Clone, Debug, Deserialize)] pub struct ExportQuery { pub version: Option, #[serde(default = "default_export_mode")] pub mode: ExportMode, } #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct YamlOperationDocument { pub format_version: String, pub kind: String, pub operation: PortableOperation, } #[derive(Clone, Debug, Deserialize, Serialize)] #[serde(deny_unknown_fields)] pub struct PortableOperation { pub name: String, pub display_name: String, #[serde(default = "default_operation_category")] pub category: String, pub protocol: Protocol, #[serde(default)] pub security_level: OperationSecurityLevel, pub target: Target, pub input_schema: Schema, pub output_schema: Schema, pub input_mapping: MappingSet, pub output_mapping: MappingSet, pub execution_config: crank_core::ExecutionConfig, pub tool_description: crank_core::ToolDescription, } #[derive(Clone, Debug, Deserialize)] #[serde(deny_unknown_fields)] pub struct LegacyYamlOperationDocument { pub format_version: String, pub kind: String, pub operation: RegistryOperation, } #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum OpenApiUploadLocale { En, Ru, } #[derive(Clone, Debug)] pub struct OpenApiUpload { pub bytes: Vec, pub mime_type: String, pub locale: OpenApiUploadLocale, } #[derive(Clone, Debug, Serialize)] pub struct OpenApiImportPreviewResponse { pub job_id: String, pub expires_at: String, pub preview: crank_import::rest::ImportPreview, } #[derive(Clone, Debug, Deserialize)] pub struct OpenApiImportCreatePayload { pub selected_operation_keys: Vec, #[serde(default)] pub server_url: Option, #[serde(default = "default_openapi_conflict_mode")] pub conflict_mode: String, } #[derive(Clone, Debug, Serialize)] pub struct OpenApiImportCreateResponse { pub created: Vec, pub skipped: Vec, pub findings: Vec, } #[derive(Clone, Debug, PartialEq, Eq, Serialize)] pub struct OpenApiImportCreatedOperation { pub operation_key: String, pub operation_id: String, pub name: String, pub version: u32, } #[derive(Clone, Debug, PartialEq, Eq, Serialize)] pub struct OpenApiImportSkippedOperation { pub operation_key: String, pub name: String, pub reason: String, } #[derive(Clone, Debug, Serialize)] pub struct CreatedOperationResponse { pub operation_id: String, pub workspace_id: String, pub version: u32, pub status: OperationStatus, pub updated_at: String, } #[derive(Clone, Debug, Serialize)] pub struct PublishResponse { pub operation_id: String, pub workspace_id: String, pub published_version: u32, pub published_at: String, } #[derive(Clone, Debug, Deserialize)] pub struct UpdateOperationPayload { pub display_name: String, #[serde(default = "default_operation_category")] pub category: String, #[serde(default)] pub security_level: OperationSecurityLevel, pub target: Target, pub input_schema: Schema, pub output_schema: Schema, pub input_mapping: MappingSet, pub output_mapping: MappingSet, pub execution_config: crank_core::ExecutionConfig, pub tool_description: crank_core::ToolDescription, #[serde(default)] pub wizard_state: Option, } #[derive(Clone, Debug, Serialize)] pub struct OperationUsageSummaryView { pub calls_today: u64, pub error_rate_pct: f64, pub avg_latency_ms: u64, } #[derive(Clone, Debug, Serialize)] pub struct OperationAgentRefView { pub agent_id: String, pub agent_slug: String, pub display_name: String, } #[derive(Clone, Debug, Serialize)] pub struct OperationSummaryView { pub id: String, pub workspace_id: String, pub name: String, pub display_name: String, pub category: String, pub protocol: Protocol, pub security_level: OperationSecurityLevel, pub target_url: String, pub target_action: String, pub status: OperationStatus, pub current_draft_version: u32, pub latest_published_version: Option, pub can_delete: bool, pub created_at: String, pub updated_at: String, pub published_at: Option, pub usage_summary: OperationUsageSummaryView, pub agent_refs: Vec, } #[derive(Clone, Debug, Serialize)] pub struct OperationDetailView { pub id: String, pub workspace_id: String, pub name: String, pub display_name: String, pub category: String, pub protocol: Protocol, pub security_level: OperationSecurityLevel, pub status: OperationStatus, pub availability: OperationAvailability, pub current_draft_version: u32, pub latest_published_version: Option, pub created_at: String, pub updated_at: String, pub published_at: Option, pub draft_version_ref: VersionRef, pub published_version_ref: Option, pub agent_refs: Vec, } #[derive(Clone, Debug, Serialize)] pub struct VersionRef { pub version: u32, pub status: OperationVersionState, } #[derive(Clone, Debug, Serialize)] pub struct OperationMutationResult { pub operation_id: String, pub workspace_id: String, pub version: u32, pub status: OperationStatus, pub updated_at: String, } #[derive(Clone, Debug, Serialize)] pub struct ImportResponse { pub operation_id: String, pub workspace_id: String, pub version: u32, pub import_mode: ImportMode, pub warnings: Vec, } #[derive(Clone, Debug, Serialize)] pub struct DescriptorUploadResponse { pub descriptor_id: String, pub version: u32, } fn default_operation_category() -> String { "general".to_owned() } fn default_openapi_conflict_mode() -> String { "rename".to_owned() } fn default_export_mode() -> ExportMode { ExportMode::Portable } fn default_enabled() -> bool { true } pub(crate) struct InvocationRecordRequest<'a> { pub workspace_id: &'a WorkspaceId, pub agent_id: Option<&'a AgentId>, pub operation: &'a RegistryOperation, pub request_id: Option<&'a str>, pub trace_id: Option<&'a str>, pub source: InvocationSource, pub level: InvocationLevel, pub status: InvocationStatus, pub message: String, pub status_code: Option, pub error_kind: Option, pub execution_stage: Option, pub execution_error_code: Option, pub retryability: Option, pub outcome_certainty: Option, pub duration_ms: u64, pub request_preview: Value, pub response_preview: Value, }