668 lines
22 KiB
JSON
668 lines
22 KiB
JSON
{
|
|
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
"$id": "https://companion.ai/config-schema.json",
|
|
"title": "Companion AI Configuration",
|
|
"description": "Configuration schema for Personal Companion AI",
|
|
"type": "object",
|
|
"required": ["companion", "vault", "rag", "model", "api", "ui", "logging", "security"],
|
|
"properties": {
|
|
"companion": {
|
|
"type": "object",
|
|
"title": "Companion Settings",
|
|
"required": ["name", "persona", "memory", "chat"],
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "Display name for the companion",
|
|
"default": "SAN"
|
|
},
|
|
"persona": {
|
|
"type": "object",
|
|
"required": ["role", "tone", "style", "boundaries"],
|
|
"properties": {
|
|
"role": {
|
|
"type": "string",
|
|
"description": "Role of the companion",
|
|
"enum": ["companion", "advisor", "reflector"],
|
|
"default": "companion"
|
|
},
|
|
"tone": {
|
|
"type": "string",
|
|
"description": "Communication tone",
|
|
"enum": ["reflective", "supportive", "analytical", "mixed"],
|
|
"default": "reflective"
|
|
},
|
|
"style": {
|
|
"type": "string",
|
|
"description": "Interaction style",
|
|
"enum": ["questioning", "supportive", "direct", "mixed"],
|
|
"default": "questioning"
|
|
},
|
|
"boundaries": {
|
|
"type": "array",
|
|
"description": "Behavioral guardrails",
|
|
"items": {
|
|
"type": "string",
|
|
"enum": [
|
|
"does_not_impersonate_user",
|
|
"no_future_predictions",
|
|
"no_medical_or_legal_advice"
|
|
]
|
|
},
|
|
"default": ["does_not_impersonate_user", "no_future_predictions", "no_medical_or_legal_advice"]
|
|
}
|
|
}
|
|
},
|
|
"memory": {
|
|
"type": "object",
|
|
"required": ["session_turns", "persistent_store", "summarize_after"],
|
|
"properties": {
|
|
"session_turns": {
|
|
"type": "integer",
|
|
"description": "Messages to keep in context",
|
|
"minimum": 1,
|
|
"maximum": 100,
|
|
"default": 20
|
|
},
|
|
"persistent_store": {
|
|
"type": "string",
|
|
"description": "SQLite database path",
|
|
"default": "~/.companion/memory.db"
|
|
},
|
|
"summarize_after": {
|
|
"type": "integer",
|
|
"description": "Summarize history after N turns",
|
|
"minimum": 5,
|
|
"maximum": 50,
|
|
"default": 10
|
|
}
|
|
}
|
|
},
|
|
"chat": {
|
|
"type": "object",
|
|
"required": ["streaming", "max_response_tokens", "default_temperature", "allow_temperature_override"],
|
|
"properties": {
|
|
"streaming": {
|
|
"type": "boolean",
|
|
"description": "Stream responses in real-time",
|
|
"default": true
|
|
},
|
|
"max_response_tokens": {
|
|
"type": "integer",
|
|
"description": "Max tokens per response",
|
|
"minimum": 256,
|
|
"maximum": 8192,
|
|
"default": 2048
|
|
},
|
|
"default_temperature": {
|
|
"type": "number",
|
|
"description": "Creativity level (0.0=deterministic, 2.0=creative)",
|
|
"minimum": 0.0,
|
|
"maximum": 2.0,
|
|
"default": 0.7
|
|
},
|
|
"allow_temperature_override": {
|
|
"type": "boolean",
|
|
"description": "Let users adjust temperature",
|
|
"default": true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"vault": {
|
|
"type": "object",
|
|
"title": "Vault Settings",
|
|
"required": ["path", "indexing", "chunking_rules"],
|
|
"properties": {
|
|
"path": {
|
|
"type": "string",
|
|
"description": "Absolute path to Obsidian vault root"
|
|
},
|
|
"indexing": {
|
|
"type": "object",
|
|
"required": ["auto_sync", "auto_sync_interval_minutes", "watch_fs_events", "file_patterns", "deny_dirs", "deny_patterns"],
|
|
"properties": {
|
|
"auto_sync": {
|
|
"type": "boolean",
|
|
"description": "Enable automatic syncing",
|
|
"default": true
|
|
},
|
|
"auto_sync_interval_minutes": {
|
|
"type": "integer",
|
|
"description": "Minutes between full syncs",
|
|
"minimum": 60,
|
|
"maximum": 10080,
|
|
"default": 1440
|
|
},
|
|
"watch_fs_events": {
|
|
"type": "boolean",
|
|
"description": "Watch for file system changes",
|
|
"default": true
|
|
},
|
|
"file_patterns": {
|
|
"type": "array",
|
|
"description": "File patterns to index",
|
|
"items": { "type": "string" },
|
|
"default": ["*.md"]
|
|
},
|
|
"deny_dirs": {
|
|
"type": "array",
|
|
"description": "Directories to skip",
|
|
"items": { "type": "string" },
|
|
"default": [".obsidian", ".trash", "zzz-Archive", ".git", ".logseq"]
|
|
},
|
|
"deny_patterns": {
|
|
"type": "array",
|
|
"description": "File patterns to ignore",
|
|
"items": { "type": "string" },
|
|
"default": ["*.tmp", "*.bak", "*conflict*", ".*"]
|
|
}
|
|
}
|
|
},
|
|
"chunking_rules": {
|
|
"type": "object",
|
|
"description": "Per-directory chunking rules (key: glob pattern, value: rule)",
|
|
"additionalProperties": {
|
|
"type": "object",
|
|
"required": ["strategy", "chunk_size", "chunk_overlap"],
|
|
"properties": {
|
|
"strategy": {
|
|
"type": "string",
|
|
"enum": ["sliding_window", "section"],
|
|
"description": "Chunking strategy"
|
|
},
|
|
"chunk_size": {
|
|
"type": "integer",
|
|
"description": "Target chunk size in words",
|
|
"minimum": 50,
|
|
"maximum": 2000
|
|
},
|
|
"chunk_overlap": {
|
|
"type": "integer",
|
|
"description": "Overlap between chunks in words",
|
|
"minimum": 0,
|
|
"maximum": 500
|
|
},
|
|
"section_tags": {
|
|
"type": "array",
|
|
"description": "Tags that mark sections (for section strategy)",
|
|
"items": { "type": "string" }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"rag": {
|
|
"type": "object",
|
|
"title": "RAG Settings",
|
|
"required": ["embedding", "vector_store", "search"],
|
|
"properties": {
|
|
"embedding": {
|
|
"type": "object",
|
|
"required": ["provider", "model", "base_url", "dimensions", "batch_size"],
|
|
"properties": {
|
|
"provider": {
|
|
"type": "string",
|
|
"description": "Embedding service provider",
|
|
"enum": ["ollama"],
|
|
"default": "ollama"
|
|
},
|
|
"model": {
|
|
"type": "string",
|
|
"description": "Model name for embeddings",
|
|
"enum": ["mxbai-embed-large", "nomic-embed-text", "all-minilm"],
|
|
"default": "mxbai-embed-large"
|
|
},
|
|
"base_url": {
|
|
"type": "string",
|
|
"description": "Provider API endpoint",
|
|
"format": "uri",
|
|
"default": "http://localhost:11434"
|
|
},
|
|
"dimensions": {
|
|
"type": "integer",
|
|
"description": "Embedding vector size",
|
|
"enum": [384, 768, 1024],
|
|
"default": 1024
|
|
},
|
|
"batch_size": {
|
|
"type": "integer",
|
|
"description": "Texts per embedding batch",
|
|
"minimum": 1,
|
|
"maximum": 256,
|
|
"default": 32
|
|
}
|
|
}
|
|
},
|
|
"vector_store": {
|
|
"type": "object",
|
|
"required": ["type", "path"],
|
|
"properties": {
|
|
"type": {
|
|
"type": "string",
|
|
"description": "Vector database type",
|
|
"enum": ["lancedb"],
|
|
"default": "lancedb"
|
|
},
|
|
"path": {
|
|
"type": "string",
|
|
"description": "Storage path",
|
|
"default": "~/.companion/vectors.lance"
|
|
}
|
|
}
|
|
},
|
|
"search": {
|
|
"type": "object",
|
|
"required": ["default_top_k", "max_top_k", "similarity_threshold", "hybrid_search", "filters"],
|
|
"properties": {
|
|
"default_top_k": {
|
|
"type": "integer",
|
|
"description": "Default results to retrieve",
|
|
"minimum": 1,
|
|
"maximum": 100,
|
|
"default": 8
|
|
},
|
|
"max_top_k": {
|
|
"type": "integer",
|
|
"description": "Maximum allowed results",
|
|
"minimum": 1,
|
|
"maximum": 100,
|
|
"default": 20
|
|
},
|
|
"similarity_threshold": {
|
|
"type": "number",
|
|
"description": "Minimum relevance score (0-1)",
|
|
"minimum": 0.0,
|
|
"maximum": 1.0,
|
|
"default": 0.75
|
|
},
|
|
"hybrid_search": {
|
|
"type": "object",
|
|
"required": ["enabled", "keyword_weight", "semantic_weight"],
|
|
"properties": {
|
|
"enabled": {
|
|
"type": "boolean",
|
|
"description": "Combine keyword + semantic search",
|
|
"default": true
|
|
},
|
|
"keyword_weight": {
|
|
"type": "number",
|
|
"description": "Keyword search weight",
|
|
"minimum": 0.0,
|
|
"maximum": 1.0,
|
|
"default": 0.3
|
|
},
|
|
"semantic_weight": {
|
|
"type": "number",
|
|
"description": "Semantic search weight",
|
|
"minimum": 0.0,
|
|
"maximum": 1.0,
|
|
"default": 0.7
|
|
}
|
|
}
|
|
},
|
|
"filters": {
|
|
"type": "object",
|
|
"required": ["date_range_enabled", "tag_filter_enabled", "directory_filter_enabled"],
|
|
"properties": {
|
|
"date_range_enabled": {
|
|
"type": "boolean",
|
|
"description": "Enable date range filtering",
|
|
"default": true
|
|
},
|
|
"tag_filter_enabled": {
|
|
"type": "boolean",
|
|
"description": "Enable tag filtering",
|
|
"default": true
|
|
},
|
|
"directory_filter_enabled": {
|
|
"type": "boolean",
|
|
"description": "Enable directory filtering",
|
|
"default": true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"model": {
|
|
"type": "object",
|
|
"title": "Model Settings",
|
|
"required": ["inference", "fine_tuning", "retrain_schedule"],
|
|
"properties": {
|
|
"inference": {
|
|
"type": "object",
|
|
"required": ["backend", "model_path", "context_length", "gpu_layers", "batch_size", "threads"],
|
|
"properties": {
|
|
"backend": {
|
|
"type": "string",
|
|
"description": "Inference engine",
|
|
"enum": ["llama.cpp", "vllm"],
|
|
"default": "llama.cpp"
|
|
},
|
|
"model_path": {
|
|
"type": "string",
|
|
"description": "Path to GGUF or HF model",
|
|
"default": "~/.companion/models/companion-7b-q4.gguf"
|
|
},
|
|
"context_length": {
|
|
"type": "integer",
|
|
"description": "Max context tokens",
|
|
"minimum": 2048,
|
|
"maximum": 32768,
|
|
"default": 8192
|
|
},
|
|
"gpu_layers": {
|
|
"type": "integer",
|
|
"description": "Layers to offload to GPU (0 for CPU-only)",
|
|
"minimum": 0,
|
|
"maximum": 100,
|
|
"default": 35
|
|
},
|
|
"batch_size": {
|
|
"type": "integer",
|
|
"description": "Inference batch size",
|
|
"minimum": 1,
|
|
"maximum": 2048,
|
|
"default": 512
|
|
},
|
|
"threads": {
|
|
"type": "integer",
|
|
"description": "CPU threads for inference",
|
|
"minimum": 1,
|
|
"maximum": 64,
|
|
"default": 8
|
|
}
|
|
}
|
|
},
|
|
"fine_tuning": {
|
|
"type": "object",
|
|
"required": ["base_model", "output_dir", "lora_rank", "lora_alpha", "learning_rate", "batch_size", "gradient_accumulation_steps", "num_epochs", "warmup_steps", "save_steps", "eval_steps", "training_data_path", "validation_split"],
|
|
"properties": {
|
|
"base_model": {
|
|
"type": "string",
|
|
"description": "Base model for fine-tuning",
|
|
"default": "unsloth/Meta-Llama-3.1-8B-Instruct-bnb-4bit"
|
|
},
|
|
"output_dir": {
|
|
"type": "string",
|
|
"description": "Training outputs directory",
|
|
"default": "~/.companion/training"
|
|
},
|
|
"lora_rank": {
|
|
"type": "integer",
|
|
"description": "LoRA rank (higher = more capacity, more VRAM)",
|
|
"minimum": 4,
|
|
"maximum": 128,
|
|
"default": 16
|
|
},
|
|
"lora_alpha": {
|
|
"type": "integer",
|
|
"description": "LoRA alpha (scaling factor, typically 2x rank)",
|
|
"minimum": 8,
|
|
"maximum": 256,
|
|
"default": 32
|
|
},
|
|
"learning_rate": {
|
|
"type": "number",
|
|
"description": "Training learning rate",
|
|
"minimum": 1e-6,
|
|
"maximum": 1e-3,
|
|
"default": 0.0002
|
|
},
|
|
"batch_size": {
|
|
"type": "integer",
|
|
"description": "Per-device batch size",
|
|
"minimum": 1,
|
|
"maximum": 32,
|
|
"default": 4
|
|
},
|
|
"gradient_accumulation_steps": {
|
|
"type": "integer",
|
|
"description": "Steps to accumulate before update",
|
|
"minimum": 1,
|
|
"maximum": 64,
|
|
"default": 4
|
|
},
|
|
"num_epochs": {
|
|
"type": "integer",
|
|
"description": "Training epochs",
|
|
"minimum": 1,
|
|
"maximum": 20,
|
|
"default": 3
|
|
},
|
|
"warmup_steps": {
|
|
"type": "integer",
|
|
"description": "Learning rate warmup steps",
|
|
"minimum": 0,
|
|
"maximum": 10000,
|
|
"default": 100
|
|
},
|
|
"save_steps": {
|
|
"type": "integer",
|
|
"description": "Checkpoint frequency",
|
|
"minimum": 10,
|
|
"maximum": 10000,
|
|
"default": 500
|
|
},
|
|
"eval_steps": {
|
|
"type": "integer",
|
|
"description": "Evaluation frequency",
|
|
"minimum": 10,
|
|
"maximum": 10000,
|
|
"default": 250
|
|
},
|
|
"training_data_path": {
|
|
"type": "string",
|
|
"description": "Training data directory",
|
|
"default": "~/.companion/training_data/"
|
|
},
|
|
"validation_split": {
|
|
"type": "number",
|
|
"description": "Fraction of data for validation",
|
|
"minimum": 0.0,
|
|
"maximum": 0.5,
|
|
"default": 0.1
|
|
}
|
|
}
|
|
},
|
|
"retrain_schedule": {
|
|
"type": "object",
|
|
"required": ["auto_reminder", "default_interval_days", "reminder_channels"],
|
|
"properties": {
|
|
"auto_reminder": {
|
|
"type": "boolean",
|
|
"description": "Enable retrain reminders",
|
|
"default": true
|
|
},
|
|
"default_interval_days": {
|
|
"type": "integer",
|
|
"description": "Days between retrain reminders",
|
|
"minimum": 30,
|
|
"maximum": 365,
|
|
"default": 90
|
|
},
|
|
"reminder_channels": {
|
|
"type": "array",
|
|
"description": "Where to show reminders",
|
|
"items": {
|
|
"type": "string",
|
|
"enum": ["chat_stream", "log", "ui"]
|
|
},
|
|
"default": ["chat_stream", "log"]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"api": {
|
|
"type": "object",
|
|
"title": "API Settings",
|
|
"required": ["host", "port", "cors_origins", "auth"],
|
|
"properties": {
|
|
"host": {
|
|
"type": "string",
|
|
"description": "Bind address (use 0.0.0.0 for LAN access)",
|
|
"default": "127.0.0.1"
|
|
},
|
|
"port": {
|
|
"type": "integer",
|
|
"description": "HTTP port",
|
|
"minimum": 1,
|
|
"maximum": 65535,
|
|
"default": 7373
|
|
},
|
|
"cors_origins": {
|
|
"type": "array",
|
|
"description": "Allowed CORS origins",
|
|
"items": {
|
|
"type": "string",
|
|
"format": "uri"
|
|
},
|
|
"default": ["http://localhost:5173"]
|
|
},
|
|
"auth": {
|
|
"type": "object",
|
|
"required": ["enabled"],
|
|
"properties": {
|
|
"enabled": {
|
|
"type": "boolean",
|
|
"description": "Enable API key authentication",
|
|
"default": false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"ui": {
|
|
"type": "object",
|
|
"title": "UI Settings",
|
|
"required": ["web", "cli"],
|
|
"properties": {
|
|
"web": {
|
|
"type": "object",
|
|
"required": ["enabled", "theme", "features"],
|
|
"properties": {
|
|
"enabled": {
|
|
"type": "boolean",
|
|
"description": "Enable web interface",
|
|
"default": true
|
|
},
|
|
"theme": {
|
|
"type": "string",
|
|
"description": "UI theme",
|
|
"enum": ["obsidian"],
|
|
"default": "obsidian"
|
|
},
|
|
"features": {
|
|
"type": "object",
|
|
"required": ["streaming", "citations", "source_preview"],
|
|
"properties": {
|
|
"streaming": {
|
|
"type": "boolean",
|
|
"description": "Real-time response streaming",
|
|
"default": true
|
|
},
|
|
"citations": {
|
|
"type": "boolean",
|
|
"description": "Show source citations",
|
|
"default": true
|
|
},
|
|
"source_preview": {
|
|
"type": "boolean",
|
|
"description": "Preview source snippets",
|
|
"default": true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"cli": {
|
|
"type": "object",
|
|
"required": ["enabled", "rich_output"],
|
|
"properties": {
|
|
"enabled": {
|
|
"type": "boolean",
|
|
"description": "Enable CLI interface",
|
|
"default": true
|
|
},
|
|
"rich_output": {
|
|
"type": "boolean",
|
|
"description": "Rich terminal formatting",
|
|
"default": true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
},
|
|
"logging": {
|
|
"type": "object",
|
|
"title": "Logging Settings",
|
|
"required": ["level", "file", "max_size_mb", "backup_count"],
|
|
"properties": {
|
|
"level": {
|
|
"type": "string",
|
|
"description": "Log level",
|
|
"enum": ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"],
|
|
"default": "INFO"
|
|
},
|
|
"file": {
|
|
"type": "string",
|
|
"description": "Log file path",
|
|
"default": "~/.companion/logs/companion.log"
|
|
},
|
|
"max_size_mb": {
|
|
"type": "integer",
|
|
"description": "Max log file size in MB",
|
|
"minimum": 10,
|
|
"maximum": 1000,
|
|
"default": 100
|
|
},
|
|
"backup_count": {
|
|
"type": "integer",
|
|
"description": "Number of rotated backups",
|
|
"minimum": 1,
|
|
"maximum": 20,
|
|
"default": 5
|
|
}
|
|
}
|
|
},
|
|
"security": {
|
|
"type": "object",
|
|
"title": "Security Settings",
|
|
"required": ["local_only", "vault_path_traversal_check", "sensitive_content_detection", "sensitive_patterns", "require_confirmation_for_external_apis"],
|
|
"properties": {
|
|
"local_only": {
|
|
"type": "boolean",
|
|
"description": "Block external API calls",
|
|
"default": true
|
|
},
|
|
"vault_path_traversal_check": {
|
|
"type": "boolean",
|
|
"description": "Prevent path traversal attacks",
|
|
"default": true
|
|
},
|
|
"sensitive_content_detection": {
|
|
"type": "boolean",
|
|
"description": "Tag sensitive content",
|
|
"default": true
|
|
},
|
|
"sensitive_patterns": {
|
|
"type": "array",
|
|
"description": "Tags considered sensitive",
|
|
"items": { "type": "string" },
|
|
"default": ["#mentalhealth", "#physicalhealth", "#finance", "#Relations"]
|
|
},
|
|
"require_confirmation_for_external_apis": {
|
|
"type": "boolean",
|
|
"description": "Confirm before external API calls",
|
|
"default": true
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|