Revert "Standardize Session Name Attribute" (#5250)
This commit is contained in:
@@ -75,7 +75,7 @@ async fn get_session_id(identifier: Identifier) -> Result<String> {
|
||||
|
||||
sessions
|
||||
.into_iter()
|
||||
.find(|s| s.name == name || s.id == name)
|
||||
.find(|s| s.id == name || s.description.contains(&name))
|
||||
.map(|s| s.id)
|
||||
.ok_or_else(|| anyhow::anyhow!("No session found with name '{}'", name))
|
||||
} else if let Some(path) = identifier.path {
|
||||
|
||||
@@ -222,7 +222,7 @@ pub async fn handle_schedule_sessions(id: String, limit: Option<usize>) -> Resul
|
||||
" - Session ID: {}, Working Dir: {}, Description: \"{}\", Schedule ID: {:?}",
|
||||
session_name, // Display the session_name as Session ID
|
||||
metadata.working_dir.display(),
|
||||
metadata.name,
|
||||
metadata.description,
|
||||
metadata.schedule_id.as_deref().unwrap_or("N/A")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@ const TRUNCATED_DESC_LENGTH: usize = 60;
|
||||
pub async fn remove_sessions(sessions: Vec<Session>) -> Result<()> {
|
||||
println!("The following sessions will be removed:");
|
||||
for session in &sessions {
|
||||
println!("- {} {}", session.id, session.name);
|
||||
println!("- {} {}", session.id, session.description);
|
||||
}
|
||||
|
||||
let should_delete = confirm("Are you sure you want to delete these sessions?")
|
||||
@@ -45,10 +45,10 @@ fn prompt_interactive_session_removal(sessions: &[Session]) -> Result<Vec<Sessio
|
||||
let display_map: std::collections::HashMap<String, Session> = sessions
|
||||
.iter()
|
||||
.map(|s| {
|
||||
let desc = if s.name.is_empty() {
|
||||
"(no name)"
|
||||
let desc = if s.description.is_empty() {
|
||||
"(no description)"
|
||||
} else {
|
||||
&s.name
|
||||
&s.description
|
||||
};
|
||||
let truncated_desc = safe_truncate(desc, TRUNCATED_DESC_LENGTH);
|
||||
let display_text = format!("{} - {} ({})", s.updated_at, truncated_desc, s.id);
|
||||
@@ -154,7 +154,10 @@ pub async fn handle_session_list(
|
||||
|
||||
println!("Available sessions:");
|
||||
for session in sessions {
|
||||
let output = format!("{} - {} - {}", session.id, session.name, session.updated_at);
|
||||
let output = format!(
|
||||
"{} - {} - {}",
|
||||
session.id, session.description, session.updated_at
|
||||
);
|
||||
println!("{}", output);
|
||||
}
|
||||
}
|
||||
@@ -185,7 +188,7 @@ pub async fn handle_session_export(
|
||||
let conversation = session
|
||||
.conversation
|
||||
.ok_or_else(|| anyhow::anyhow!("Session has no messages"))?;
|
||||
export_session_to_markdown(conversation.messages().to_vec(), &session.name)
|
||||
export_session_to_markdown(conversation.messages().to_vec(), &session.description)
|
||||
}
|
||||
_ => return Err(anyhow::anyhow!("Unsupported format: {}", format)),
|
||||
};
|
||||
@@ -290,10 +293,10 @@ pub async fn prompt_interactive_session_selection() -> Result<String> {
|
||||
let display_map: std::collections::HashMap<String, Session> = sessions
|
||||
.iter()
|
||||
.map(|s| {
|
||||
let desc = if s.name.is_empty() {
|
||||
"(no name)"
|
||||
let desc = if s.description.is_empty() {
|
||||
"(no description)"
|
||||
} else {
|
||||
&s.name
|
||||
&s.description
|
||||
};
|
||||
let truncated_desc = safe_truncate(desc, TRUNCATED_DESC_LENGTH);
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@ async fn list_sessions() -> Json<serde_json::Value> {
|
||||
session_info.push(serde_json::json!({
|
||||
"name": session.id,
|
||||
"path": session.id,
|
||||
"description": session.name,
|
||||
"description": session.description,
|
||||
"message_count": session.message_count,
|
||||
"working_dir": session.working_dir
|
||||
}));
|
||||
|
||||
@@ -355,7 +355,7 @@ derive_utoipa!(Icon as IconSchema);
|
||||
super::routes::session::list_sessions,
|
||||
super::routes::session::get_session,
|
||||
super::routes::session::get_session_insights,
|
||||
super::routes::session::update_session_name,
|
||||
super::routes::session::update_session_description,
|
||||
super::routes::session::delete_session,
|
||||
super::routes::session::export_session,
|
||||
super::routes::session::import_session,
|
||||
@@ -398,7 +398,7 @@ derive_utoipa!(Icon as IconSchema);
|
||||
super::routes::context::ContextManageResponse,
|
||||
super::routes::session::ImportSessionRequest,
|
||||
super::routes::session::SessionListResponse,
|
||||
super::routes::session::UpdateSessionNameRequest,
|
||||
super::routes::session::UpdateSessionDescriptionRequest,
|
||||
super::routes::session::UpdateSessionUserRecipeValuesRequest,
|
||||
Message,
|
||||
MessageContent,
|
||||
|
||||
@@ -139,9 +139,9 @@ async fn start_agent(
|
||||
}
|
||||
|
||||
let counter = state.session_counter.fetch_add(1, Ordering::SeqCst) + 1;
|
||||
let name = format!("New session {}", counter);
|
||||
let description = format!("New session {}", counter);
|
||||
|
||||
let mut session = SessionManager::create_session(PathBuf::from(&working_dir), name)
|
||||
let mut session = SessionManager::create_session(PathBuf::from(&working_dir), description)
|
||||
.await
|
||||
.map_err(|err| {
|
||||
error!("Failed to create session: {}", err);
|
||||
|
||||
@@ -68,10 +68,10 @@ fn default_limit() -> u32 {
|
||||
#[derive(Serialize, utoipa::ToSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SessionDisplayInfo {
|
||||
id: String,
|
||||
name: String,
|
||||
created_at: String,
|
||||
working_dir: String,
|
||||
id: String, // Derived from session_name (filename)
|
||||
name: String, // From metadata.description
|
||||
created_at: String, // Derived from session_name, in ISO 8601 format
|
||||
working_dir: String, // from metadata.working_dir (as String)
|
||||
schedule_id: Option<String>,
|
||||
message_count: usize,
|
||||
total_tokens: Option<i32>,
|
||||
@@ -325,7 +325,7 @@ async fn sessions_handler(
|
||||
for (session_name, session) in session_tuples {
|
||||
display_infos.push(SessionDisplayInfo {
|
||||
id: session_name.clone(),
|
||||
name: session.name,
|
||||
name: session.description,
|
||||
created_at: parse_session_name_to_iso(&session_name),
|
||||
working_dir: session.working_dir.to_string_lossy().into_owned(),
|
||||
schedule_id: session.schedule_id,
|
||||
|
||||
@@ -22,9 +22,9 @@ pub struct SessionListResponse {
|
||||
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct UpdateSessionNameRequest {
|
||||
/// Updated name for the session (max 200 characters)
|
||||
name: String,
|
||||
pub struct UpdateSessionDescriptionRequest {
|
||||
/// Updated description (name) for the session (max 200 characters)
|
||||
description: String,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, ToSchema)]
|
||||
@@ -40,7 +40,7 @@ pub struct ImportSessionRequest {
|
||||
json: String,
|
||||
}
|
||||
|
||||
const MAX_NAME_LENGTH: usize = 200;
|
||||
const MAX_DESCRIPTION_LENGTH: usize = 200;
|
||||
|
||||
#[utoipa::path(
|
||||
get,
|
||||
@@ -109,14 +109,14 @@ async fn get_session_insights() -> Result<Json<SessionInsights>, StatusCode> {
|
||||
|
||||
#[utoipa::path(
|
||||
put,
|
||||
path = "/sessions/{session_id}/name",
|
||||
request_body = UpdateSessionNameRequest,
|
||||
path = "/sessions/{session_id}/description",
|
||||
request_body = UpdateSessionDescriptionRequest,
|
||||
params(
|
||||
("session_id" = String, Path, description = "Unique identifier for the session")
|
||||
),
|
||||
responses(
|
||||
(status = 200, description = "Session name updated successfully"),
|
||||
(status = 400, description = "Bad request - Name too long (max 200 characters)"),
|
||||
(status = 200, description = "Session description updated successfully"),
|
||||
(status = 400, description = "Bad request - Description too long (max 200 characters)"),
|
||||
(status = 401, description = "Unauthorized - Invalid or missing API key"),
|
||||
(status = 404, description = "Session not found"),
|
||||
(status = 500, description = "Internal server error")
|
||||
@@ -126,20 +126,16 @@ async fn get_session_insights() -> Result<Json<SessionInsights>, StatusCode> {
|
||||
),
|
||||
tag = "Session Management"
|
||||
)]
|
||||
async fn update_session_name(
|
||||
async fn update_session_description(
|
||||
Path(session_id): Path<String>,
|
||||
Json(request): Json<UpdateSessionNameRequest>,
|
||||
Json(request): Json<UpdateSessionDescriptionRequest>,
|
||||
) -> Result<StatusCode, StatusCode> {
|
||||
let name = request.name.trim();
|
||||
if name.is_empty() {
|
||||
return Err(StatusCode::BAD_REQUEST);
|
||||
}
|
||||
if name.len() > MAX_NAME_LENGTH {
|
||||
if request.description.len() > MAX_DESCRIPTION_LENGTH {
|
||||
return Err(StatusCode::BAD_REQUEST);
|
||||
}
|
||||
|
||||
SessionManager::update_session(&session_id)
|
||||
.user_provided_name(name.to_string())
|
||||
.description(request.description)
|
||||
.apply()
|
||||
.await
|
||||
.map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;
|
||||
@@ -268,7 +264,10 @@ pub fn routes(state: Arc<AppState>) -> Router {
|
||||
.route("/sessions/{session_id}/export", get(export_session))
|
||||
.route("/sessions/import", post(import_session))
|
||||
.route("/sessions/insights", get(get_session_insights))
|
||||
.route("/sessions/{session_id}/name", put(update_session_name))
|
||||
.route(
|
||||
"/sessions/{session_id}/description",
|
||||
put(update_session_description),
|
||||
)
|
||||
.route(
|
||||
"/sessions/{session_id}/user_recipe_values",
|
||||
put(update_session_user_recipe_values),
|
||||
|
||||
@@ -1042,7 +1042,9 @@ impl Agent {
|
||||
let provider = self.provider().await?;
|
||||
let session_id = session_config.id.clone();
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = SessionManager::maybe_update_name(&session_id, provider).await {
|
||||
if let Err(e) =
|
||||
SessionManager::maybe_update_description(&session_id, provider).await
|
||||
{
|
||||
warn!("Failed to generate session description: {}", e);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -18,7 +18,7 @@ use tokio::sync::OnceCell;
|
||||
use tracing::{info, warn};
|
||||
use utoipa::ToSchema;
|
||||
|
||||
const CURRENT_SCHEMA_VERSION: i32 = 4;
|
||||
const CURRENT_SCHEMA_VERSION: i32 = 3;
|
||||
|
||||
static SESSION_STORAGE: OnceCell<Arc<SessionStorage>> = OnceCell::const_new();
|
||||
|
||||
@@ -27,11 +27,7 @@ pub struct Session {
|
||||
pub id: String,
|
||||
#[schema(value_type = String)]
|
||||
pub working_dir: PathBuf,
|
||||
// Allow importing session exports from before 'description' was renamed to 'name'
|
||||
#[serde(alias = "description")]
|
||||
pub name: String,
|
||||
#[serde(default)]
|
||||
pub user_set_name: bool,
|
||||
pub description: String,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
pub extension_data: ExtensionData,
|
||||
@@ -50,8 +46,7 @@ pub struct Session {
|
||||
|
||||
pub struct SessionUpdateBuilder {
|
||||
session_id: String,
|
||||
name: Option<String>,
|
||||
user_set_name: Option<bool>,
|
||||
description: Option<String>,
|
||||
working_dir: Option<PathBuf>,
|
||||
extension_data: Option<ExtensionData>,
|
||||
total_tokens: Option<Option<i32>>,
|
||||
@@ -78,8 +73,7 @@ impl SessionUpdateBuilder {
|
||||
fn new(session_id: String) -> Self {
|
||||
Self {
|
||||
session_id,
|
||||
name: None,
|
||||
user_set_name: None,
|
||||
description: None,
|
||||
working_dir: None,
|
||||
extension_data: None,
|
||||
total_tokens: None,
|
||||
@@ -94,21 +88,8 @@ impl SessionUpdateBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn user_provided_name(mut self, name: impl Into<String>) -> Self {
|
||||
let name = name.into().trim().to_string();
|
||||
if !name.is_empty() {
|
||||
self.name = Some(name);
|
||||
self.user_set_name = Some(true);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn system_generated_name(mut self, name: impl Into<String>) -> Self {
|
||||
let name = name.into().trim().to_string();
|
||||
if !name.is_empty() {
|
||||
self.name = Some(name);
|
||||
self.user_set_name = Some(false);
|
||||
}
|
||||
pub fn description(mut self, description: impl Into<String>) -> Self {
|
||||
self.description = Some(description.into());
|
||||
self
|
||||
}
|
||||
|
||||
@@ -185,10 +166,10 @@ impl SessionManager {
|
||||
.map(Arc::clone)
|
||||
}
|
||||
|
||||
pub async fn create_session(working_dir: PathBuf, name: String) -> Result<Session> {
|
||||
pub async fn create_session(working_dir: PathBuf, description: String) -> Result<Session> {
|
||||
Self::instance()
|
||||
.await?
|
||||
.create_session(working_dir, name)
|
||||
.create_session(working_dir, description)
|
||||
.await
|
||||
}
|
||||
|
||||
@@ -238,13 +219,8 @@ impl SessionManager {
|
||||
Self::instance().await?.import_session(json).await
|
||||
}
|
||||
|
||||
pub async fn maybe_update_name(id: &str, provider: Arc<dyn Provider>) -> Result<()> {
|
||||
pub async fn maybe_update_description(id: &str, provider: Arc<dyn Provider>) -> Result<()> {
|
||||
let session = Self::get_session(id, true).await?;
|
||||
|
||||
if session.user_set_name {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let conversation = session
|
||||
.conversation
|
||||
.ok_or_else(|| anyhow::anyhow!("No messages found"))?;
|
||||
@@ -256,9 +232,9 @@ impl SessionManager {
|
||||
.count();
|
||||
|
||||
if user_message_count <= MSG_COUNT_FOR_SESSION_NAME_GENERATION {
|
||||
let name = provider.generate_session_name(&conversation).await?;
|
||||
let description = provider.generate_session_name(&conversation).await?;
|
||||
Self::update_session(id)
|
||||
.system_generated_name(name)
|
||||
.description(description)
|
||||
.apply()
|
||||
.await
|
||||
} else {
|
||||
@@ -293,8 +269,7 @@ impl Default for Session {
|
||||
Self {
|
||||
id: String::new(),
|
||||
working_dir: std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),
|
||||
name: String::new(),
|
||||
user_set_name: false,
|
||||
description: String::new(),
|
||||
created_at: Default::default(),
|
||||
updated_at: Default::default(),
|
||||
extension_data: ExtensionData::default(),
|
||||
@@ -331,17 +306,10 @@ impl sqlx::FromRow<'_, sqlx::sqlite::SqliteRow> for Session {
|
||||
let user_recipe_values =
|
||||
user_recipe_values_json.and_then(|json| serde_json::from_str(&json).ok());
|
||||
|
||||
let name: String = row
|
||||
.try_get("name")
|
||||
.or_else(|_| row.try_get("description"))?;
|
||||
|
||||
let user_set_name = row.try_get("user_set_name").unwrap_or(false);
|
||||
|
||||
Ok(Session {
|
||||
id: row.try_get("id")?,
|
||||
working_dir: PathBuf::from(row.try_get::<String, _>("working_dir")?),
|
||||
name,
|
||||
user_set_name,
|
||||
description: row.try_get("description")?,
|
||||
created_at: row.try_get("created_at")?,
|
||||
updated_at: row.try_get("updated_at")?,
|
||||
extension_data: serde_json::from_str(&row.try_get::<String, _>("extension_data")?)
|
||||
@@ -428,8 +396,7 @@ impl SessionStorage {
|
||||
r#"
|
||||
CREATE TABLE sessions (
|
||||
id TEXT PRIMARY KEY,
|
||||
name TEXT NOT NULL DEFAULT '',
|
||||
user_set_name BOOLEAN DEFAULT FALSE,
|
||||
description TEXT NOT NULL DEFAULT '',
|
||||
working_dir TEXT NOT NULL,
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
||||
@@ -537,16 +504,15 @@ impl SessionStorage {
|
||||
sqlx::query(
|
||||
r#"
|
||||
INSERT INTO sessions (
|
||||
id, name, user_set_name, working_dir, created_at, updated_at, extension_data,
|
||||
id, description, working_dir, created_at, updated_at, extension_data,
|
||||
total_tokens, input_tokens, output_tokens,
|
||||
accumulated_total_tokens, accumulated_input_tokens, accumulated_output_tokens,
|
||||
schedule_id, recipe_json, user_recipe_values_json
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||
"#,
|
||||
)
|
||||
.bind(&session.id)
|
||||
.bind(&session.name)
|
||||
.bind(session.user_set_name)
|
||||
.bind(&session.description)
|
||||
.bind(session.working_dir.to_string_lossy().as_ref())
|
||||
.bind(session.created_at)
|
||||
.bind(session.updated_at)
|
||||
@@ -654,23 +620,6 @@ impl SessionStorage {
|
||||
.execute(&self.pool)
|
||||
.await?;
|
||||
}
|
||||
4 => {
|
||||
sqlx::query(
|
||||
r#"
|
||||
ALTER TABLE sessions RENAME COLUMN description TO name
|
||||
"#,
|
||||
)
|
||||
.execute(&self.pool)
|
||||
.await?;
|
||||
|
||||
sqlx::query(
|
||||
r#"
|
||||
ALTER TABLE sessions ADD COLUMN user_set_name BOOLEAN DEFAULT FALSE
|
||||
"#,
|
||||
)
|
||||
.execute(&self.pool)
|
||||
.await?;
|
||||
}
|
||||
_ => {
|
||||
anyhow::bail!("Unknown migration version: {}", version);
|
||||
}
|
||||
@@ -679,11 +628,11 @@ impl SessionStorage {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn create_session(&self, working_dir: PathBuf, name: String) -> Result<Session> {
|
||||
async fn create_session(&self, working_dir: PathBuf, description: String) -> Result<Session> {
|
||||
let today = chrono::Utc::now().format("%Y%m%d").to_string();
|
||||
let session_id = sqlx::query_as(
|
||||
r#"
|
||||
INSERT INTO sessions (id, name, user_set_name, working_dir, extension_data)
|
||||
INSERT INTO sessions (id, description, working_dir, extension_data)
|
||||
VALUES (
|
||||
? || '_' || CAST(COALESCE((
|
||||
SELECT MAX(CAST(SUBSTR(id, 10) AS INTEGER))
|
||||
@@ -691,7 +640,6 @@ impl SessionStorage {
|
||||
WHERE id LIKE ? || '_%'
|
||||
), 0) + 1 AS TEXT),
|
||||
?,
|
||||
FALSE,
|
||||
?,
|
||||
'{}'
|
||||
)
|
||||
@@ -700,7 +648,7 @@ impl SessionStorage {
|
||||
)
|
||||
.bind(&today)
|
||||
.bind(&today)
|
||||
.bind(&name)
|
||||
.bind(&description)
|
||||
.bind(working_dir.to_string_lossy().as_ref())
|
||||
.fetch_one(&self.pool)
|
||||
.await?;
|
||||
@@ -715,7 +663,7 @@ impl SessionStorage {
|
||||
async fn get_session(&self, id: &str, include_messages: bool) -> Result<Session> {
|
||||
let mut session = sqlx::query_as::<_, Session>(
|
||||
r#"
|
||||
SELECT id, working_dir, name, user_set_name, created_at, updated_at, extension_data,
|
||||
SELECT id, working_dir, description, created_at, updated_at, extension_data,
|
||||
total_tokens, input_tokens, output_tokens,
|
||||
accumulated_total_tokens, accumulated_input_tokens, accumulated_output_tokens,
|
||||
schedule_id, recipe_json, user_recipe_values_json
|
||||
@@ -761,8 +709,7 @@ impl SessionStorage {
|
||||
};
|
||||
}
|
||||
|
||||
add_update!(builder.name, "name");
|
||||
add_update!(builder.user_set_name, "user_set_name");
|
||||
add_update!(builder.description, "description");
|
||||
add_update!(builder.working_dir, "working_dir");
|
||||
add_update!(builder.extension_data, "extension_data");
|
||||
add_update!(builder.total_tokens, "total_tokens");
|
||||
@@ -782,16 +729,15 @@ impl SessionStorage {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
query.push_str(", ");
|
||||
if !updates.is_empty() {
|
||||
query.push_str(", ");
|
||||
}
|
||||
query.push_str("updated_at = datetime('now') WHERE id = ?");
|
||||
|
||||
let mut q = sqlx::query(&query);
|
||||
|
||||
if let Some(name) = builder.name {
|
||||
q = q.bind(name);
|
||||
}
|
||||
if let Some(user_set_name) = builder.user_set_name {
|
||||
q = q.bind(user_set_name);
|
||||
if let Some(desc) = builder.description {
|
||||
q = q.bind(desc);
|
||||
}
|
||||
if let Some(wd) = builder.working_dir {
|
||||
q = q.bind(wd.to_string_lossy().to_string());
|
||||
@@ -928,7 +874,7 @@ impl SessionStorage {
|
||||
async fn list_sessions(&self) -> Result<Vec<Session>> {
|
||||
sqlx::query_as::<_, Session>(
|
||||
r#"
|
||||
SELECT s.id, s.working_dir, s.name, s.user_set_name, s.created_at, s.updated_at, s.extension_data,
|
||||
SELECT s.id, s.working_dir, s.description, s.created_at, s.updated_at, s.extension_data,
|
||||
s.total_tokens, s.input_tokens, s.output_tokens,
|
||||
s.accumulated_total_tokens, s.accumulated_input_tokens, s.accumulated_output_tokens,
|
||||
s.schedule_id, s.recipe_json, s.user_recipe_values_json,
|
||||
@@ -994,26 +940,23 @@ impl SessionStorage {
|
||||
let import: Session = serde_json::from_str(json)?;
|
||||
|
||||
let session = self
|
||||
.create_session(import.working_dir.clone(), import.name.clone())
|
||||
.create_session(import.working_dir.clone(), import.description.clone())
|
||||
.await?;
|
||||
|
||||
let mut builder = SessionUpdateBuilder::new(session.id.clone())
|
||||
.extension_data(import.extension_data)
|
||||
.total_tokens(import.total_tokens)
|
||||
.input_tokens(import.input_tokens)
|
||||
.output_tokens(import.output_tokens)
|
||||
.accumulated_total_tokens(import.accumulated_total_tokens)
|
||||
.accumulated_input_tokens(import.accumulated_input_tokens)
|
||||
.accumulated_output_tokens(import.accumulated_output_tokens)
|
||||
.schedule_id(import.schedule_id)
|
||||
.recipe(import.recipe)
|
||||
.user_recipe_values(import.user_recipe_values);
|
||||
|
||||
if import.user_set_name {
|
||||
builder = builder.user_provided_name(import.name.clone());
|
||||
}
|
||||
|
||||
self.apply_update(builder).await?;
|
||||
self.apply_update(
|
||||
SessionUpdateBuilder::new(session.id.clone())
|
||||
.extension_data(import.extension_data)
|
||||
.total_tokens(import.total_tokens)
|
||||
.input_tokens(import.input_tokens)
|
||||
.output_tokens(import.output_tokens)
|
||||
.accumulated_total_tokens(import.accumulated_total_tokens)
|
||||
.accumulated_input_tokens(import.accumulated_input_tokens)
|
||||
.accumulated_output_tokens(import.accumulated_output_tokens)
|
||||
.schedule_id(import.schedule_id)
|
||||
.recipe(import.recipe)
|
||||
.user_recipe_values(import.user_recipe_values),
|
||||
)
|
||||
.await?;
|
||||
|
||||
if let Some(conversation) = import.conversation {
|
||||
self.replace_conversation(&session.id, &conversation)
|
||||
@@ -1083,7 +1026,7 @@ mod tests {
|
||||
session_storage
|
||||
.apply_update(
|
||||
SessionUpdateBuilder::new(session.id.clone())
|
||||
.user_provided_name(format!("Updated session {}", i))
|
||||
.description(format!("Updated session {}", i))
|
||||
.total_tokens(Some(100 * i)),
|
||||
)
|
||||
.await
|
||||
@@ -1116,7 +1059,7 @@ mod tests {
|
||||
|
||||
for session in &sessions {
|
||||
assert_eq!(session.message_count, 2);
|
||||
assert!(session.name.starts_with("Updated session"));
|
||||
assert!(session.description.starts_with("Updated session"));
|
||||
}
|
||||
|
||||
let insights = storage.get_insights().await.unwrap();
|
||||
@@ -1187,7 +1130,7 @@ mod tests {
|
||||
let imported = storage.import_session(&exported).await.unwrap();
|
||||
|
||||
assert_ne!(imported.id, original.id);
|
||||
assert_eq!(imported.name, DESCRIPTION);
|
||||
assert_eq!(imported.description, DESCRIPTION);
|
||||
assert_eq!(imported.working_dir, PathBuf::from("/tmp/test"));
|
||||
assert_eq!(imported.total_tokens, Some(TOTAL_TOKENS));
|
||||
assert_eq!(imported.input_tokens, Some(INPUT_TOKENS));
|
||||
@@ -1200,28 +1143,4 @@ mod tests {
|
||||
assert_eq!(conversation.messages()[0].role, Role::User);
|
||||
assert_eq!(conversation.messages()[1].role, Role::Assistant);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_import_session_with_description_field() {
|
||||
const OLD_FORMAT_JSON: &str = r#"{
|
||||
"id": "20240101_1",
|
||||
"description": "Old format session",
|
||||
"user_set_name": true,
|
||||
"working_dir": "/tmp/test",
|
||||
"created_at": "2024-01-01T00:00:00Z",
|
||||
"updated_at": "2024-01-01T00:00:00Z",
|
||||
"extension_data": {},
|
||||
"message_count": 0
|
||||
}"#;
|
||||
|
||||
let temp_dir = TempDir::new().unwrap();
|
||||
let db_path = temp_dir.path().join("test_import.db");
|
||||
let storage = Arc::new(SessionStorage::create(&db_path).await.unwrap());
|
||||
|
||||
let imported = storage.import_session(OLD_FORMAT_JSON).await.unwrap();
|
||||
|
||||
assert_eq!(imported.name, "Old format session");
|
||||
assert!(imported.user_set_name);
|
||||
assert_eq!(imported.working_dir, PathBuf::from("/tmp/test"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -381,8 +381,7 @@ pub fn create_test_session_metadata(message_count: usize, working_dir: &str) ->
|
||||
Session {
|
||||
id: "".to_string(),
|
||||
working_dir: PathBuf::from(working_dir),
|
||||
name: "Test session".to_string(),
|
||||
user_set_name: false,
|
||||
description: "Test session".to_string(),
|
||||
created_at: Default::default(),
|
||||
schedule_id: Some("test_job".to_string()),
|
||||
recipe: None,
|
||||
|
||||
Reference in New Issue
Block a user