@@ -10,6 +10,7 @@ import {
1010 useContext ,
1111} from "react" ;
1212import { toast } from "sonner" ;
13+ import { getErrorMessage } from "@/lib/error-utils" ;
1314
1415interface Message {
1516 id : number ;
@@ -34,6 +35,22 @@ interface StatusChangeEvent {
3435 status : string ;
3536}
3637
38+ interface APIErrorDetail {
39+ location : string ;
40+ message : string ;
41+ value : null | string | number | boolean | object ;
42+ }
43+
44+ interface APIErrorModel {
45+ $schema : string ;
46+ detail : string ;
47+ errors : APIErrorDetail [ ] ;
48+ instance : string ;
49+ status : number ;
50+ title : string ;
51+ type : string ;
52+ }
53+
3754function isDraftMessage ( message : Message | DraftMessage ) : boolean {
3855 return message . id === undefined ;
3956}
@@ -42,11 +59,17 @@ type MessageType = "user" | "raw";
4259
4360export type ServerStatus = "stable" | "running" | "offline" | "unknown" ;
4461
62+ export interface FileUploadResponse {
63+ ok : boolean ;
64+ filePath ?: string ;
65+ }
66+
4567interface ChatContextValue {
4668 messages : ( Message | DraftMessage ) [ ] ;
4769 loading : boolean ;
4870 serverStatus : ServerStatus ;
4971 sendMessage : ( message : string , type ?: MessageType ) => void ;
72+ uploadFiles : ( formData : FormData ) => Promise < FileUploadResponse > ;
5073}
5174
5275const ChatContext = createContext < ChatContextValue | undefined > ( undefined ) ;
@@ -229,34 +252,27 @@ export function ChatProvider({ children }: PropsWithChildren) {
229252 } ) ;
230253
231254 if ( ! response . ok ) {
232- const errorData = await response . json ( ) ;
255+ const errorData = await response . json ( ) as APIErrorModel ;
233256 console . error ( "Failed to send message:" , errorData ) ;
234257 const detail = errorData . detail ;
235258 const messages =
236259 "errors" in errorData
237- ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
238- errorData . errors . map ( ( e : any ) => e . message ) . join ( ", " )
260+ ?
261+ errorData . errors . map ( ( e : APIErrorDetail ) => e . message ) . join ( ", " )
239262 : "" ;
240263
241264 const fullDetail = `${ detail } : ${ messages } ` ;
242265 toast . error ( `Failed to send message` , {
243266 description : fullDetail ,
244267 } ) ;
245268 }
246- // eslint-disable-next-line @typescript-eslint/no-explicit-any
247- } catch ( error : any ) {
248- console . error ( "Error sending message:" , error ) ;
249- const detail = error . detail ;
250- const messages =
251- "errors" in error
252- ? // eslint-disable-next-line @typescript-eslint/no-explicit-any
253- error . errors . map ( ( e : any ) => e . message ) . join ( "\n" )
254- : "" ;
255269
256- const fullDetail = `${ detail } : ${ messages } ` ;
270+ } catch ( error ) {
271+ console . error ( "Error sending message:" , error ) ;
272+ const message = getErrorMessage ( error )
257273
258274 toast . error ( `Error sending message` , {
259- description : fullDetail ,
275+ description : message ,
260276 } ) ;
261277 } finally {
262278 if ( type === "user" ) {
@@ -268,13 +284,54 @@ export function ChatProvider({ children }: PropsWithChildren) {
268284 }
269285 } ;
270286
287+ // Upload files to workspace
288+ const uploadFiles = async ( formData : FormData ) : Promise < FileUploadResponse > => {
289+ let result : FileUploadResponse = { ok : true } ;
290+ try {
291+ const response = await fetch ( `${ agentAPIUrl } /upload` , {
292+ method : 'POST' ,
293+ body : formData ,
294+ } ) ;
295+
296+ if ( ! response . ok ) {
297+ result . ok = false ;
298+ const errorData = await response . json ( ) as APIErrorModel ;
299+ console . error ( "Failed to send message:" , errorData ) ;
300+ const detail = errorData . detail ;
301+ const messages =
302+ "errors" in errorData
303+ ?
304+ errorData . errors . map ( ( e : APIErrorDetail ) => e . message ) . join ( ", " )
305+ : "" ;
306+
307+ const fullDetail = `${ detail } : ${ messages } ` ;
308+ toast . error ( `Failed to upload files` , {
309+ description : fullDetail ,
310+ } ) ;
311+ } else {
312+ result = ( await response . json ( ) ) as FileUploadResponse ;
313+ }
314+
315+ } catch ( error ) {
316+ result . ok = false ;
317+ console . error ( "Error uploading files:" , error ) ;
318+ const message = getErrorMessage ( error )
319+
320+ toast . error ( `Error uploading files` , {
321+ description : message ,
322+ } ) ;
323+ }
324+ return result ;
325+ }
326+
271327 return (
272328 < ChatContext . Provider
273329 value = { {
274330 messages,
275331 loading,
276332 sendMessage,
277333 serverStatus,
334+ uploadFiles,
278335 } }
279336 >
280337 { children }
0 commit comments