Make it startable from playwright and also isolate (#5016)
Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use anyhow::Result;
|
||||
use console::style;
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use goose::config::paths::Paths;
|
||||
use goose::config::Config;
|
||||
use serde_yaml;
|
||||
|
||||
@@ -9,11 +9,8 @@ fn print_aligned(label: &str, value: &str, width: usize) {
|
||||
}
|
||||
|
||||
pub fn handle_info(verbose: bool) -> Result<()> {
|
||||
let data_dir = choose_app_strategy(crate::APP_STRATEGY.clone())?;
|
||||
let logs_dir = data_dir
|
||||
.in_state_dir("logs")
|
||||
.unwrap_or_else(|| data_dir.in_data_dir("logs"));
|
||||
let sessions_dir = data_dir.in_data_dir("sessions");
|
||||
let logs_dir = Paths::in_state_dir("logs");
|
||||
let sessions_dir = Paths::in_data_dir("sessions");
|
||||
|
||||
// Get paths using a stored reference to the global config
|
||||
let config = Config::global();
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
use etcetera::AppStrategyArgs;
|
||||
use once_cell::sync::Lazy;
|
||||
pub mod cli;
|
||||
pub mod commands;
|
||||
pub mod logging;
|
||||
@@ -11,9 +9,3 @@ pub mod signal;
|
||||
|
||||
// Re-export commonly used types
|
||||
pub use session::CliSession;
|
||||
|
||||
pub static APP_STRATEGY: Lazy<AppStrategyArgs> = Lazy::new(|| AppStrategyArgs {
|
||||
top_level_domain: "Block".to_string(),
|
||||
author: "Block".to_string(),
|
||||
app_name: "goose".to_string(),
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use anyhow::{Context, Result};
|
||||
use chrono::{DateTime, Utc};
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use goose::config::paths::Paths;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
@@ -41,11 +41,7 @@ pub struct ProjectInfoDisplay {
|
||||
impl ProjectTracker {
|
||||
/// Get the path to the projects.json file
|
||||
fn get_projects_file() -> Result<PathBuf> {
|
||||
let projects_file = choose_app_strategy(crate::APP_STRATEGY.clone())
|
||||
.context("goose requires a home dir")?
|
||||
.in_data_dir("projects.json");
|
||||
|
||||
// Ensure data directory exists
|
||||
let projects_file = Paths::in_data_dir("projects.json");
|
||||
if let Some(parent) = projects_file.parent() {
|
||||
if !parent.exists() {
|
||||
fs::create_dir_all(parent)?;
|
||||
|
||||
@@ -25,7 +25,6 @@ use goose::utils::safe_truncate;
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use completion::GooseCompleter;
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use goose::agents::extension::{Envs, ExtensionConfig};
|
||||
use goose::agents::types::RetryConfig;
|
||||
use goose::agents::{Agent, SessionConfig};
|
||||
@@ -37,6 +36,7 @@ use rmcp::model::PromptMessage;
|
||||
use rmcp::model::ServerNotification;
|
||||
use rmcp::model::{ErrorCode, ErrorData};
|
||||
|
||||
use goose::config::paths::Paths;
|
||||
use goose::conversation::message::{Message, MessageContent};
|
||||
use rand::{distributions::Alphanumeric, Rng};
|
||||
use rustyline::EditMode;
|
||||
@@ -413,29 +413,20 @@ impl CliSession {
|
||||
let completer = GooseCompleter::new(self.completion_cache.clone());
|
||||
editor.set_helper(Some(completer));
|
||||
|
||||
// Create and use a global history file in ~/.config/goose directory
|
||||
// This allows command history to persist across different chat sessions
|
||||
// instead of being tied to each individual session's messages
|
||||
let strategy =
|
||||
choose_app_strategy(crate::APP_STRATEGY.clone()).expect("goose requires a home dir");
|
||||
let config_dir = strategy.config_dir();
|
||||
let history_file = config_dir.join("history.txt");
|
||||
let history_file = Paths::config_dir().join("history.txt");
|
||||
|
||||
// Ensure config directory exists
|
||||
if let Some(parent) = history_file.parent() {
|
||||
if !parent.exists() {
|
||||
std::fs::create_dir_all(parent)?;
|
||||
}
|
||||
}
|
||||
|
||||
// Load history from the global file
|
||||
if history_file.exists() {
|
||||
if let Err(err) = editor.load_history(&history_file) {
|
||||
eprintln!("Warning: Failed to load command history: {}", err);
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to save history after commands
|
||||
let save_history =
|
||||
|editor: &mut rustyline::Editor<GooseCompleter, rustyline::history::DefaultHistory>| {
|
||||
if let Err(err) = editor.save_history(&history_file) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use goose::config::get_config_dir;
|
||||
use std::{env, ffi::OsString, process::Stdio};
|
||||
|
||||
use goose::config::paths::Paths;
|
||||
#[cfg(unix)]
|
||||
#[allow(unused_imports)] // False positive: trait is used for process_group method
|
||||
use std::os::unix::process::CommandExt;
|
||||
@@ -30,7 +30,7 @@ impl Default for ShellConfig {
|
||||
|
||||
// Configure environment based on shell type
|
||||
let envs = if shell_name == "bash" {
|
||||
let bash_env = get_config_dir().join(".bash_env").into_os_string();
|
||||
let bash_env = Paths::config_dir().join(".bash_env").into_os_string();
|
||||
vec![(OsString::from("BASH_ENV"), bash_env)]
|
||||
} else {
|
||||
vec![]
|
||||
|
||||
@@ -5,9 +5,8 @@ use axum::{
|
||||
routing::{delete, get, post},
|
||||
Json, Router,
|
||||
};
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use goose::config::paths::Paths;
|
||||
use goose::config::ExtensionEntry;
|
||||
use goose::config::APP_STRATEGY;
|
||||
use goose::config::{Config, ConfigError};
|
||||
use goose::model::ModelConfig;
|
||||
use goose::providers::base::ProviderMetadata;
|
||||
@@ -565,11 +564,7 @@ pub async fn upsert_permissions(
|
||||
)
|
||||
)]
|
||||
pub async fn backup_config() -> Result<Json<String>, StatusCode> {
|
||||
let config_dir = choose_app_strategy(APP_STRATEGY.clone())
|
||||
.expect("goose requires a home dir")
|
||||
.config_dir();
|
||||
|
||||
let config_path = config_dir.join("config.yaml");
|
||||
let config_path = Paths::config_dir().join("config.yaml");
|
||||
|
||||
if config_path.exists() {
|
||||
let file_name = config_path
|
||||
@@ -630,11 +625,7 @@ pub async fn recover_config() -> Result<Json<String>, StatusCode> {
|
||||
)
|
||||
)]
|
||||
pub async fn validate_config() -> Result<Json<String>, StatusCode> {
|
||||
let config_dir = choose_app_strategy(APP_STRATEGY.clone())
|
||||
.expect("goose requires a home dir")
|
||||
.config_dir();
|
||||
|
||||
let config_path = config_dir.join("config.yaml");
|
||||
let config_path = Paths::config_dir().join("config.yaml");
|
||||
|
||||
if !config_path.exists() {
|
||||
return Ok(Json("Config file does not exist".to_string()));
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use etcetera::{choose_app_strategy, AppStrategy, AppStrategyArgs};
|
||||
use crate::config::paths::Paths;
|
||||
use fs2::FileExt;
|
||||
use keyring::Entry;
|
||||
use once_cell::sync::{Lazy, OnceCell};
|
||||
use once_cell::sync::OnceCell;
|
||||
use serde::Deserialize;
|
||||
use serde_json::Value;
|
||||
use std::collections::HashMap;
|
||||
@@ -11,12 +11,6 @@ use std::io::Write;
|
||||
use std::path::{Path, PathBuf};
|
||||
use thiserror::Error;
|
||||
|
||||
pub static APP_STRATEGY: Lazy<AppStrategyArgs> = Lazy::new(|| AppStrategyArgs {
|
||||
top_level_domain: "Block".to_string(),
|
||||
author: "Block".to_string(),
|
||||
app_name: "goose".to_string(),
|
||||
});
|
||||
|
||||
const KEYRING_SERVICE: &str = "goose";
|
||||
const KEYRING_USERNAME: &str = "secrets";
|
||||
|
||||
@@ -116,18 +110,9 @@ enum SecretStorage {
|
||||
// Global instance
|
||||
static GLOBAL_CONFIG: OnceCell<Config> = OnceCell::new();
|
||||
|
||||
pub fn get_config_dir() -> PathBuf {
|
||||
choose_app_strategy(APP_STRATEGY.clone())
|
||||
.expect("goose requires a home dir")
|
||||
.config_dir()
|
||||
}
|
||||
|
||||
impl Default for Config {
|
||||
fn default() -> Self {
|
||||
// choose_app_strategy().config_dir()
|
||||
// - macOS/Linux: ~/.config/goose/
|
||||
// - Windows: ~\AppData\Roaming\Block\goose\config\
|
||||
let config_dir = get_config_dir();
|
||||
let config_dir = Paths::config_dir();
|
||||
|
||||
std::fs::create_dir_all(&config_dir).expect("Failed to create config directory");
|
||||
|
||||
|
||||
@@ -1,20 +1,17 @@
|
||||
use crate::config::{Config, APP_STRATEGY};
|
||||
use crate::config::paths::Paths;
|
||||
use crate::config::Config;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::anthropic::AnthropicProvider;
|
||||
use crate::providers::base::ModelInfo;
|
||||
use crate::providers::ollama::OllamaProvider;
|
||||
use crate::providers::openai::OpenAiProvider;
|
||||
use anyhow::Result;
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::path::Path;
|
||||
|
||||
pub fn custom_providers_dir() -> std::path::PathBuf {
|
||||
choose_app_strategy(APP_STRATEGY.clone())
|
||||
.expect("goose requires a home dir")
|
||||
.config_dir()
|
||||
.join("custom_providers")
|
||||
Paths::config_dir().join("custom_providers")
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
|
||||
@@ -2,12 +2,13 @@ pub mod base;
|
||||
pub mod custom_providers;
|
||||
mod experiments;
|
||||
pub mod extensions;
|
||||
pub mod paths;
|
||||
pub mod permission;
|
||||
pub mod signup_openrouter;
|
||||
pub mod signup_tetrate;
|
||||
|
||||
pub use crate::agents::ExtensionConfig;
|
||||
pub use base::{get_config_dir, Config, ConfigError, APP_STRATEGY};
|
||||
pub use base::{Config, ConfigError};
|
||||
pub use custom_providers::CustomProviderConfig;
|
||||
pub use experiments::ExperimentManager;
|
||||
pub use extensions::{
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
use etcetera::{choose_app_strategy, AppStrategy, AppStrategyArgs};
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub struct Paths;
|
||||
|
||||
impl Paths {
|
||||
fn get_dir(dir_type: DirType) -> PathBuf {
|
||||
if let Ok(test_root) = std::env::var("GOOSE_PATH_ROOT") {
|
||||
let base = PathBuf::from(test_root);
|
||||
match dir_type {
|
||||
DirType::Config => base.join("config"),
|
||||
DirType::Data => base.join("data"),
|
||||
DirType::State => base.join("state"),
|
||||
}
|
||||
} else {
|
||||
let strategy = choose_app_strategy(AppStrategyArgs {
|
||||
top_level_domain: "Block".to_string(),
|
||||
author: "Block".to_string(),
|
||||
app_name: "goose".to_string(),
|
||||
})
|
||||
.expect("goose requires a home dir");
|
||||
|
||||
match dir_type {
|
||||
DirType::Config => strategy.config_dir(),
|
||||
DirType::Data => strategy.data_dir(),
|
||||
DirType::State => strategy.state_dir().unwrap_or(strategy.data_dir()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn config_dir() -> PathBuf {
|
||||
Self::get_dir(DirType::Config)
|
||||
}
|
||||
|
||||
pub fn data_dir() -> PathBuf {
|
||||
Self::get_dir(DirType::Data)
|
||||
}
|
||||
|
||||
pub fn state_dir() -> PathBuf {
|
||||
Self::get_dir(DirType::State)
|
||||
}
|
||||
|
||||
pub fn in_state_dir(subpath: &str) -> PathBuf {
|
||||
Self::state_dir().join(subpath)
|
||||
}
|
||||
|
||||
pub fn in_config_dir(subpath: &str) -> PathBuf {
|
||||
Self::config_dir().join(subpath)
|
||||
}
|
||||
|
||||
pub fn in_data_dir(subpath: &str) -> PathBuf {
|
||||
Self::data_dir().join(subpath)
|
||||
}
|
||||
}
|
||||
|
||||
enum DirType {
|
||||
Config,
|
||||
Data,
|
||||
State,
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
use super::APP_STRATEGY;
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use crate::config::paths::Paths;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::fs;
|
||||
@@ -37,14 +36,7 @@ const SMART_APPROVE_PERMISSION: &str = "smart_approve";
|
||||
/// Implements the default constructor for `PermissionManager`.
|
||||
impl Default for PermissionManager {
|
||||
fn default() -> Self {
|
||||
// Choose the app strategy and determine the config directory
|
||||
let config_dir = choose_app_strategy(APP_STRATEGY.clone())
|
||||
.expect("goose requires a home dir")
|
||||
.config_dir();
|
||||
|
||||
// Ensure the configuration directory exists
|
||||
std::fs::create_dir_all(&config_dir).expect("Failed to create config directory");
|
||||
let config_path = config_dir.join("permission.yaml");
|
||||
let config_path = Paths::config_dir().join("permission.yaml");
|
||||
|
||||
// Load the existing configuration file or create an empty map if the file doesn't exist
|
||||
let permission_map = if config_path.exists() {
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
use crate::agents::extension::PlatformExtensionContext;
|
||||
use crate::agents::Agent;
|
||||
use crate::config::APP_STRATEGY;
|
||||
use crate::config::paths::Paths;
|
||||
use crate::model::ModelConfig;
|
||||
use crate::providers::create;
|
||||
use crate::scheduler_factory::SchedulerFactory;
|
||||
use crate::scheduler_trait::SchedulerTrait;
|
||||
use anyhow::Result;
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use lru::LruCache;
|
||||
use std::num::NonZeroUsize;
|
||||
use std::sync::Arc;
|
||||
@@ -37,10 +36,7 @@ impl AgentManager {
|
||||
|
||||
// Private constructor - prevents direct instantiation in production
|
||||
async fn new(max_sessions: Option<usize>) -> Result<Self> {
|
||||
// Construct scheduler with the standard goose-server path
|
||||
let schedule_file_path = choose_app_strategy(APP_STRATEGY.clone())?
|
||||
.data_dir()
|
||||
.join("schedule.json");
|
||||
let schedule_file_path = Paths::data_dir().join("schedule.json");
|
||||
|
||||
let scheduler = SchedulerFactory::create(schedule_file_path).await?;
|
||||
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
use crate::config::paths::Paths;
|
||||
use anyhow::{Context, Result};
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::config::APP_STRATEGY;
|
||||
|
||||
/// Returns the directory where log files should be stored for a specific component.
|
||||
/// Creates the directory structure if it doesn't exist.
|
||||
///
|
||||
@@ -12,17 +10,8 @@ use crate::config::APP_STRATEGY;
|
||||
///
|
||||
/// * `component` - The component name (e.g., "cli", "server", "debug")
|
||||
/// * `use_date_subdir` - Whether to create a date-based subdirectory
|
||||
///
|
||||
/// # Returns
|
||||
///
|
||||
/// The path to the log directory for the specified component
|
||||
pub fn get_log_directory(component: &str, use_date_subdir: bool) -> Result<PathBuf> {
|
||||
let home_dir =
|
||||
choose_app_strategy(APP_STRATEGY.clone()).context("HOME environment variable not set")?;
|
||||
|
||||
let base_log_dir = home_dir
|
||||
.in_state_dir("logs")
|
||||
.unwrap_or_else(|| home_dir.in_data_dir("logs"));
|
||||
let base_log_dir = Paths::in_state_dir("logs");
|
||||
|
||||
let component_dir = base_log_dir.join(component);
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::config::paths::Paths;
|
||||
use crate::conversation::message::ToolRequest;
|
||||
use anyhow::Result;
|
||||
use blake3::Hasher;
|
||||
use chrono::Utc;
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::time::Duration;
|
||||
@@ -35,14 +35,10 @@ impl Default for ToolPermissionStore {
|
||||
|
||||
impl ToolPermissionStore {
|
||||
pub fn new() -> Self {
|
||||
let permissions_dir = choose_app_strategy(crate::config::APP_STRATEGY.clone())
|
||||
.map(|strategy| strategy.config_dir())
|
||||
.unwrap_or_else(|_| PathBuf::from(".config/goose"));
|
||||
|
||||
Self {
|
||||
permissions: HashMap::new(),
|
||||
version: 1,
|
||||
permissions_dir,
|
||||
permissions_dir: Paths::config_dir().join("permissions"),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::config::paths::Paths;
|
||||
use anyhow::{anyhow, Context, Result};
|
||||
use async_trait::async_trait;
|
||||
use axum::http;
|
||||
use chrono::{DateTime, Utc};
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use reqwest::Client;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
@@ -81,9 +81,7 @@ struct DiskCache {
|
||||
|
||||
impl DiskCache {
|
||||
fn new() -> Self {
|
||||
let cache_path = choose_app_strategy(crate::config::APP_STRATEGY.clone())
|
||||
.expect("goose requires a home dir")
|
||||
.in_config_dir("githubcopilot/info.json");
|
||||
let cache_path = Paths::in_config_dir("githubcopilot/info.json");
|
||||
Self { cache_path }
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use crate::config::paths::Paths;
|
||||
use anyhow::Result;
|
||||
use axum::{extract::Query, response::Html, routing::get, Router};
|
||||
use base64::Engine;
|
||||
use chrono::{DateTime, Utc};
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use once_cell::sync::Lazy;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
@@ -38,12 +38,7 @@ struct TokenCache {
|
||||
}
|
||||
|
||||
fn get_base_path() -> PathBuf {
|
||||
// choose_app_strategy().config_dir()
|
||||
// - macOS/Linux: ~/.config/goose/databricks/oauth
|
||||
// - Windows: ~\AppData\Roaming\Block\goose\config\databricks\oauth\
|
||||
choose_app_strategy(crate::config::APP_STRATEGY.clone())
|
||||
.expect("goose requires a home dir")
|
||||
.in_config_dir("databricks/oauth")
|
||||
Paths::in_config_dir("databricks/oauth")
|
||||
}
|
||||
|
||||
impl TokenCache {
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use crate::config::APP_STRATEGY;
|
||||
use crate::config::paths::Paths;
|
||||
use crate::recipe::read_recipe_file_content::{read_recipe_file, RecipeFile};
|
||||
use crate::recipe::Recipe;
|
||||
use crate::recipe::RECIPE_FILE_EXTENSIONS;
|
||||
@@ -14,10 +13,7 @@ const GOOSE_RECIPE_PATH_ENV_VAR: &str = "GOOSE_RECIPE_PATH";
|
||||
|
||||
pub fn get_recipe_library_dir(is_global: bool) -> PathBuf {
|
||||
if is_global {
|
||||
choose_app_strategy(APP_STRATEGY.clone())
|
||||
.expect("goose requires a home dir")
|
||||
.config_dir()
|
||||
.join("recipes")
|
||||
Paths::config_dir().join("recipes")
|
||||
} else {
|
||||
std::env::current_dir().unwrap().join(".goose/recipes")
|
||||
}
|
||||
|
||||
@@ -7,14 +7,14 @@ use std::sync::Arc;
|
||||
use anyhow::{anyhow, Result};
|
||||
use async_trait::async_trait;
|
||||
use chrono::{DateTime, Utc};
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use tokio::sync::Mutex;
|
||||
use tokio_cron_scheduler::{job::JobId, Job, JobScheduler as TokioJobScheduler};
|
||||
|
||||
use crate::agents::AgentEvent;
|
||||
use crate::agents::{Agent, SessionConfig};
|
||||
use crate::config::{self, Config};
|
||||
use crate::config::paths::Paths;
|
||||
use crate::config::Config;
|
||||
use crate::conversation::message::Message;
|
||||
use crate::conversation::Conversation;
|
||||
use crate::providers::base::Provider as GooseProvider; // Alias to avoid conflict in test section
|
||||
@@ -63,18 +63,13 @@ pub fn normalize_cron_expression(src: &str) -> String {
|
||||
}
|
||||
|
||||
pub fn get_default_scheduler_storage_path() -> Result<PathBuf, io::Error> {
|
||||
let strategy = choose_app_strategy(config::APP_STRATEGY.clone())
|
||||
.map_err(|e| io::Error::new(io::ErrorKind::NotFound, e.to_string()))?;
|
||||
let data_dir = strategy.data_dir();
|
||||
let data_dir = Paths::data_dir();
|
||||
fs::create_dir_all(&data_dir)?;
|
||||
Ok(data_dir.join("schedules.json"))
|
||||
}
|
||||
|
||||
pub fn get_default_scheduled_recipes_dir() -> Result<PathBuf, SchedulerError> {
|
||||
let strategy = choose_app_strategy(config::APP_STRATEGY.clone()).map_err(|e| {
|
||||
SchedulerError::StorageError(io::Error::new(io::ErrorKind::NotFound, e.to_string()))
|
||||
})?;
|
||||
let data_dir = strategy.data_dir();
|
||||
let data_dir = Paths::data_dir();
|
||||
let recipes_dir = data_dir.join("scheduled_recipes");
|
||||
fs::create_dir_all(&recipes_dir).map_err(SchedulerError::StorageError)?;
|
||||
tracing::debug!(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use crate::config::APP_STRATEGY;
|
||||
use crate::config::paths::Paths;
|
||||
use crate::conversation::message::Message;
|
||||
use crate::conversation::Conversation;
|
||||
use crate::providers::base::{Provider, MSG_COUNT_FOR_SESSION_NAME_GENERATION};
|
||||
@@ -6,7 +6,6 @@ use crate::recipe::Recipe;
|
||||
use crate::session::extension_data::ExtensionData;
|
||||
use anyhow::Result;
|
||||
use chrono::{DateTime, Utc};
|
||||
use etcetera::{choose_app_strategy, AppStrategy};
|
||||
use rmcp::model::Role;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sqlx::sqlite::SqliteConnectOptions;
|
||||
@@ -241,16 +240,13 @@ pub struct SessionStorage {
|
||||
}
|
||||
|
||||
pub fn ensure_session_dir() -> Result<PathBuf> {
|
||||
let data_dir = choose_app_strategy(APP_STRATEGY.clone())
|
||||
.expect("goose requires a home dir")
|
||||
.data_dir()
|
||||
.join("sessions");
|
||||
let session_dir = Paths::data_dir().join("sessions");
|
||||
|
||||
if !data_dir.exists() {
|
||||
fs::create_dir_all(&data_dir)?;
|
||||
if !session_dir.exists() {
|
||||
fs::create_dir_all(&session_dir)?;
|
||||
}
|
||||
|
||||
Ok(data_dir)
|
||||
Ok(session_dir)
|
||||
}
|
||||
|
||||
fn role_to_string(role: &Role) -> &'static str {
|
||||
|
||||
Reference in New Issue
Block a user