systemprompt_traits/
file_upload.rs1use async_trait::async_trait;
2use std::sync::Arc;
3use systemprompt_identifiers::{ContextId, FileId, SessionId, TraceId, UserId};
4
5pub type FileUploadResult<T> = Result<T, FileUploadProviderError>;
6
7#[derive(Debug, thiserror::Error)]
8#[non_exhaustive]
9pub enum FileUploadProviderError {
10 #[error("Upload disabled")]
11 Disabled,
12
13 #[error("Validation failed: {0}")]
14 ValidationFailed(String),
15
16 #[error("Storage error: {0}")]
17 StorageError(String),
18
19 #[error("Internal error: {0}")]
20 Internal(String),
21}
22
23impl From<anyhow::Error> for FileUploadProviderError {
24 fn from(err: anyhow::Error) -> Self {
25 Self::Internal(err.to_string())
26 }
27}
28
29#[derive(Debug, Clone)]
30pub struct FileUploadInput {
31 pub mime_type: String,
32 pub bytes_base64: String,
33 pub name: Option<String>,
34 pub context_id: ContextId,
35 pub user_id: Option<UserId>,
36 pub session_id: Option<SessionId>,
37 pub trace_id: Option<TraceId>,
38}
39
40impl FileUploadInput {
41 #[must_use]
42 pub fn new(
43 mime_type: impl Into<String>,
44 bytes_base64: impl Into<String>,
45 context_id: ContextId,
46 ) -> Self {
47 Self {
48 mime_type: mime_type.into(),
49 bytes_base64: bytes_base64.into(),
50 name: None,
51 context_id,
52 user_id: None,
53 session_id: None,
54 trace_id: None,
55 }
56 }
57
58 #[must_use]
59 pub fn with_name(mut self, name: impl Into<String>) -> Self {
60 self.name = Some(name.into());
61 self
62 }
63
64 #[must_use]
65 pub fn with_user_id(mut self, user_id: UserId) -> Self {
66 self.user_id = Some(user_id);
67 self
68 }
69
70 #[must_use]
71 pub fn with_session_id(mut self, session_id: SessionId) -> Self {
72 self.session_id = Some(session_id);
73 self
74 }
75
76 #[must_use]
77 pub fn with_trace_id(mut self, trace_id: TraceId) -> Self {
78 self.trace_id = Some(trace_id);
79 self
80 }
81}
82
83#[derive(Debug, Clone)]
84pub struct UploadedFileInfo {
85 pub file_id: FileId,
86 pub public_url: String,
87 pub size_bytes: Option<i64>,
88}
89
90#[async_trait]
91pub trait FileUploadProvider: Send + Sync {
92 fn is_enabled(&self) -> bool;
93
94 async fn upload_file(&self, input: FileUploadInput) -> FileUploadResult<UploadedFileInfo>;
95}
96
97pub type DynFileUploadProvider = Arc<dyn FileUploadProvider>;