feat: v0.13.0 pre (#122)

Signed-off-by: phernandez <paul@basicmachines.co>
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
Paul Hernandez
2025-06-03 01:00:40 -05:00
committed by GitHub
parent 5ec4087f7c
commit 634486107b
116 changed files with 13122 additions and 2147 deletions
+46 -12
View File
@@ -9,10 +9,12 @@ from typing import Any, Dict, Literal, Optional, List
from loguru import logger
from pydantic import Field, field_validator
from pydantic_settings import BaseSettings, SettingsConfigDict
from setuptools.command.setopt import config_file
import basic_memory
from basic_memory.utils import setup_logging, generate_permalink
DATABASE_NAME = "memory.db"
APP_DATABASE_NAME = "memory.db" # Using the same name but in the app directory
DATA_DIR_NAME = ".basic-memory"
@@ -147,7 +149,11 @@ class ConfigManager:
def __init__(self) -> None:
"""Initialize the configuration manager."""
self.config_dir = Path.home() / DATA_DIR_NAME
home = os.getenv("HOME", Path.home())
if isinstance(home, str):
home = Path(home)
self.config_dir = home / DATA_DIR_NAME
self.config_file = self.config_dir / CONFIG_FILE_NAME
# Ensure config directory exists
@@ -156,9 +162,6 @@ class ConfigManager:
# Load or create configuration
self.config = self.load_config()
# Current project context for the session
self.current_project_id: int
def load_config(self) -> BasicMemoryConfig:
"""Load configuration from file or create default."""
if self.config_file.exists():
@@ -177,7 +180,7 @@ class ConfigManager:
def save_config(self, config: BasicMemoryConfig) -> None:
"""Save configuration to file."""
try:
try:
self.config_file.write_text(json.dumps(config.model_dump(), indent=2))
except Exception as e: # pragma: no cover
logger.error(f"Failed to save config: {e}")
@@ -192,7 +195,7 @@ class ConfigManager:
"""Get the default project name."""
return self.config.default_project
def add_project(self, name: str, path: str) -> None:
def add_project(self, name: str, path: str) -> ProjectConfig:
"""Add a new project to the configuration."""
if name in self.config.projects: # pragma: no cover
raise ValueError(f"Project '{name}' already exists")
@@ -203,6 +206,7 @@ class ConfigManager:
self.config.projects[name] = str(project_path)
self.save_config(self.config)
return ProjectConfig(name=name, home=project_path)
def remove_project(self, name: str) -> None:
"""Remove a project from the configuration."""
@@ -224,15 +228,36 @@ class ConfigManager:
self.save_config(self.config)
def get_project_config() -> ProjectConfig:
"""Get the project configuration for the current session."""
def get_project_config(project_name: Optional[str] = None) -> ProjectConfig:
"""
Get the project configuration for the current session.
If project_name is provided, it will be used instead of the default project.
"""
# Get project name from environment variable or use provided name or default
env_project_name = os.environ.get("BASIC_MEMORY_PROJECT", None)
actual_project_name = env_project_name or config_manager.default_project
actual_project_name = None
# load the config from file
global app_config
app_config = config_manager.load_config()
# Get project name from environment variable
os_project_name = os.environ.get("BASIC_MEMORY_PROJECT", None)
if os_project_name: # pragma: no cover
logger.warning(
f"BASIC_MEMORY_PROJECT is not supported anymore. Use the --project flag or set the default project in the config instead. Setting default project to {os_project_name}"
)
actual_project_name = project_name
# if the project_name is passed in, use it
elif not project_name:
# use default
actual_project_name = app_config.default_project
else: # pragma: no cover
actual_project_name = project_name
# the config contains a dict[str,str] of project names and absolute paths
project_path = config_manager.projects.get(actual_project_name)
assert actual_project_name is not None, "actual_project_name cannot be None"
project_path = app_config.projects.get(actual_project_name)
if not project_path: # pragma: no cover
raise ValueError(f"Project '{actual_project_name}' not found")
@@ -249,6 +274,15 @@ app_config: BasicMemoryConfig = config_manager.config
config: ProjectConfig = get_project_config()
def update_current_project(project_name: str) -> None:
"""Update the global config to use a different project.
This is used by the CLI when --project flag is specified.
"""
global config
config = get_project_config(project_name) # pragma: no cover
# setup logging to a single log file in user home directory
user_home = Path.home()
log_dir = user_home / DATA_DIR_NAME