adk_server/rest/controllers/
artifacts.rs1use crate::ServerConfig;
2use adk_artifact::{ListRequest, LoadRequest};
3use axum::{
4 body::Body,
5 extract::{Path, State},
6 http::{header, StatusCode},
7 response::IntoResponse,
8 Json,
9};
10
11#[derive(Clone)]
12pub struct ArtifactsController {
13 config: ServerConfig,
14}
15
16impl ArtifactsController {
17 pub fn new(config: ServerConfig) -> Self {
18 Self { config }
19 }
20}
21
22pub async fn list_artifacts(
23 State(controller): State<ArtifactsController>,
24 Path((app_name, user_id, session_id)): Path<(String, String, String)>,
25) -> Result<Json<Vec<String>>, StatusCode> {
26 if let Some(service) = &controller.config.artifact_service {
27 let resp = service
28 .list(ListRequest { app_name, user_id, session_id })
29 .await
30 .map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
31 Ok(Json(resp.file_names))
32 } else {
33 Ok(Json(vec![]))
34 }
35}
36
37pub async fn get_artifact(
38 State(controller): State<ArtifactsController>,
39 Path((app_name, user_id, session_id, artifact_name)): Path<(String, String, String, String)>,
40) -> Result<impl IntoResponse, StatusCode> {
41 if let Some(service) = &controller.config.artifact_service {
42 let resp = service
43 .load(LoadRequest {
44 app_name,
45 user_id,
46 session_id,
47 file_name: artifact_name.clone(),
48 version: None,
49 })
50 .await
51 .map_err(|_| StatusCode::NOT_FOUND)?;
52
53 let mime = mime_guess::from_path(&artifact_name).first_or_octet_stream();
54 let mime_header = header::HeaderValue::from_str(mime.as_ref())
55 .unwrap_or_else(|_| header::HeaderValue::from_static("application/octet-stream"));
56
57 match resp.part {
58 adk_core::Part::InlineData { data, .. } => {
59 Ok(([(header::CONTENT_TYPE, mime_header)], Body::from(data)))
60 }
61 adk_core::Part::Text { text } => {
62 Ok(([(header::CONTENT_TYPE, mime_header)], Body::from(text)))
63 }
64 _ => Err(StatusCode::INTERNAL_SERVER_ERROR),
65 }
66 } else {
67 Err(StatusCode::NOT_FOUND)
68 }
69}