diff --git a/flake.lock b/flake.lock index 58a3778..37e7f66 100644 --- a/flake.lock +++ b/flake.lock @@ -60,16 +60,16 @@ ] }, "locked": { - "lastModified": 1774996501, - "narHash": "sha256-1sEkQDdV/qU4/N9oHR4mptllcRWt503k6HZ8Yp4EooE=", + "lastModified": 1775461158, + "narHash": "sha256-FiQzBj3C0sAnKU+WMktliqt0zM3YQDrgQbner1LOTi8=", "owner": "anomalyco", "repo": "opencode", - "rev": "892bdebaacbed3fc76976431c7aa7b81ab639fb6", + "rev": "517e6c9aa4c61dbc125e7654fc596f1d529f20d9", "type": "github" }, "original": { "owner": "anomalyco", - "ref": "v1.3.12", + "ref": "v1.3.17", "repo": "opencode", "type": "github" } diff --git a/flake.nix b/flake.nix index 4322819..af33a49 100644 --- a/flake.nix +++ b/flake.nix @@ -12,7 +12,7 @@ # opencode needs newer bun from master opencode = { - url = "github:anomalyco/opencode/v1.3.12"; + url = "github:anomalyco/opencode/v1.3.17"; inputs.nixpkgs.follows = "nixpkgs-master"; }; diff --git a/modules/nixos/honcho.nix b/modules/nixos/honcho.nix deleted file mode 100644 index 1e4e775..0000000 --- a/modules/nixos/honcho.nix +++ /dev/null @@ -1,374 +0,0 @@ -# NixOS Module for Honcho AI Memory Server -# -# This module provides systemd services for the Honcho API server and -# background deriver process, with configurable PostgreSQL and Redis backends. -# -# Usage in your NixOS configuration: -# -# imports = [ inputs.m3ta-nixpkgs.nixosModules.default ]; -# -# m3ta.honcho = { -# enable = true; -# port = 8000; -# host = "127.0.0.1"; -# -# # Database (PostgreSQL with pgvector) -# database = { -# connectionUri = "postgresql+psycopg://honcho:password@localhost:5432/honcho"; -# }; -# -# # Redis cache -# cache = { -# url = "redis://localhost:6379/0"; -# }; -# -# # LLM API keys (use agenix or sops-nix for secrets) -# environmentFile = "/run/secrets/honcho-env"; -# }; -# -# Using with m3ta.ports (recommended): -# -# m3ta.ports = { -# enable = true; -# definitions = { honcho = 8000; }; -# currentHost = config.networking.hostName; -# }; -# -# m3ta.honcho = { -# enable = true; -# port = config.m3ta.ports.get "honcho"; -# }; -{ - config, - lib, - pkgs, - ... -}: -with lib; let - cfg = config.m3ta.honcho; - - # Python environment with honcho and FastAPI CLI - pythonEnv = pkgs.python3.withPackages (ps: - with ps; [ - cfg.package - ]); - - # Start script for the API server - startScript = pkgs.writeShellScript "honcho-start" '' - set -e - - # Load environment file if specified - ${optionalString (cfg.environmentFile != null) '' - if [ -f "${cfg.environmentFile}" ]; then - set -a - source "${cfg.environmentFile}" - set +a - fi - ''} - - # Create state directory - mkdir -p ${cfg.stateDir} - - # Run database migrations - ${pythonEnv}/bin/python -c " -import sys; sys.path.insert(0, '${cfg.package}/${pythonEnv.sitePackages}') -from scripts.provision_db import * -" 2>/dev/null || echo "Skipping database provisioning (script may not be available)" - - # Run the API server - exec ${pythonEnv}/bin/fastapi run \ - --host ${cfg.host} \ - --port ${toString cfg.port} \ - ${cfg.package}/${pythonEnv.sitePackages}/src/main.py - ''; - - # Start script for the deriver background worker - deriverScript = pkgs.writeShellScript "honcho-deriver" '' - set -e - - # Load environment file if specified - ${optionalString (cfg.environmentFile != null) '' - if [ -f "${cfg.environmentFile}" ]; then - set -a - source "${cfg.environmentFile}" - set +a - fi - ''} - - # Create state directory - mkdir -p ${cfg.stateDir} - - # Run the deriver - exec ${pythonEnv}/bin/python -m src.deriver - ''; -in { - options.m3ta.honcho = { - enable = mkEnableOption "Honcho AI memory server"; - - package = mkOption { - type = types.package; - default = pkgs.honcho; - defaultText = literalExpression "pkgs.honcho"; - description = "The honcho package to use."; - }; - - host = mkOption { - type = types.str; - default = "127.0.0.1"; - description = "Host address to bind the API server to."; - }; - - port = mkOption { - type = types.port; - default = 8000; - description = "Port to run the API server on."; - }; - - stateDir = mkOption { - type = types.path; - default = "/var/lib/honcho"; - description = "Directory to store honcho data and state."; - }; - - user = mkOption { - type = types.str; - default = "honcho"; - description = "User account under which honcho runs."; - }; - - group = mkOption { - type = types.str; - default = "honcho"; - description = "Group under which honcho runs."; - }; - - environmentFile = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - Environment file containing configuration and secrets. - This file should contain KEY=value pairs, one per line. - Use this for API keys, database credentials, and other secrets. - See the honcho .env.template for available variables. - ''; - example = "/run/secrets/honcho-env"; - }; - - # Database Configuration - database = { - connectionUri = mkOption { - type = types.str; - default = "postgresql+psycopg://honcho:honcho@localhost:5432/honcho"; - description = '' - PostgreSQL connection URI with pgvector support. - Must use postgresql+psycopg prefix for SQLAlchemy compatibility. - ''; - example = "postgresql+psycopg://honcho:password@localhost:5432/honcho"; - }; - - schema = mkOption { - type = types.str; - default = "public"; - description = "Database schema to use."; - }; - - poolSize = mkOption { - type = types.int; - default = 10; - description = "Connection pool size."; - }; - - maxOverflow = mkOption { - type = types.int; - default = 20; - description = "Maximum connection pool overflow."; - }; - }; - - # Cache Configuration - cache = { - url = mkOption { - type = types.str; - default = "redis://localhost:6379/0"; - description = '' - Redis cache URL. - Set suppress=true to suppress connection errors: redis://localhost:6379/0?suppress=true - ''; - example = "redis://localhost:6379/0?suppress=true"; - }; - }; - - # Deriver (background worker) Configuration - deriver = { - enable = mkOption { - type = types.bool; - default = true; - description = '' - Enable the honcho deriver background worker. - Processes asynchronous tasks like representation updates and session summarization. - ''; - }; - - workers = mkOption { - type = types.int; - default = 1; - description = "Number of deriver worker processes."; - }; - - provider = mkOption { - type = types.str; - default = "google"; - description = "LLM provider for the deriver."; - }; - - model = mkOption { - type = types.str; - default = "gemini-2.5-flash-lite"; - description = "LLM model for the deriver."; - }; - }; - - # Logging - logLevel = mkOption { - type = types.enum ["CRITICAL" "ERROR" "WARNING" "INFO" "DEBUG"]; - default = "INFO"; - description = "Logging level for the server."; - }; - - # Authentication - auth = { - enable = mkOption { - type = types.bool; - default = false; - description = "Enable JWT authentication."; - }; - - jwtSecretFile = mkOption { - type = types.nullOr types.path; - default = null; - description = '' - Path to file containing the JWT secret key. - Required when auth is enabled. - ''; - example = "/run/secrets/honcho-jwt-secret"; - }; - }; - }; - - config = mkIf cfg.enable { - # Create user and group - users.users.${cfg.user} = { - isSystemUser = true; - group = cfg.group; - description = "Honcho service user"; - home = cfg.stateDir; - createHome = true; - }; - - users.groups.${cfg.group} = {}; - - # API Server systemd service - systemd.services.honcho = { - description = "Honcho AI Memory API Server"; - after = ["network.target"]; - wantedBy = ["multi-user.target"]; - - serviceConfig = { - Type = "simple"; - User = cfg.user; - Group = cfg.group; - ExecStart = startScript; - Restart = "on-failure"; - RestartSec = "5s"; - - # Security hardening - NoNewPrivileges = true; - PrivateTmp = true; - ProtectSystem = "strict"; - ProtectHome = true; - ReadWritePaths = [cfg.stateDir]; - ProtectKernelTunables = true; - ProtectKernelModules = true; - ProtectControlGroups = true; - RestrictRealtime = true; - RestrictNamespaces = true; - LockPersonality = true; - MemoryDenyWriteExecute = false; # Python needs this - RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"]; - }; - - environment = - { - PYTHONUNBUFFERED = "1"; - DB_CONNECTION_URI = cfg.database.connectionUri; - DB_SCHEMA = cfg.database.schema; - DB_POOL_SIZE = toString cfg.database.poolSize; - DB_MAX_OVERFLOW = toString cfg.database.maxOverflow; - CACHE_URL = cfg.cache.url; - LOG_LEVEL = cfg.logLevel; - AUTH_USE_AUTH = - if cfg.auth.enable - then "true" - else "false"; - DERIVER_ENABLED = - if cfg.deriver.enable - then "true" - else "false"; - } - // optionalAttrs (cfg.auth.jwtSecretFile != null) { - AUTH_JWT_SECRET_FILE = cfg.auth.jwtSecretFile; - }; - }; - - # Deriver background worker systemd service - systemd.services.honcho-deriver = mkIf cfg.deriver.enable { - description = "Honcho Deriver Background Worker"; - after = ["network.target"]; - wantedBy = ["multi-user.target"]; - - serviceConfig = { - Type = "simple"; - User = cfg.user; - Group = cfg.group; - ExecStart = deriverScript; - Restart = "on-failure"; - RestartSec = "5s"; - - # Security hardening - NoNewPrivileges = true; - PrivateTmp = true; - ProtectSystem = "strict"; - ProtectHome = true; - ReadWritePaths = [cfg.stateDir]; - ProtectKernelTunables = true; - ProtectKernelModules = true; - ProtectControlGroups = true; - RestrictRealtime = true; - RestrictNamespaces = true; - LockPersonality = true; - MemoryDenyWriteExecute = false; # Python needs this - RestrictAddressFamilies = ["AF_UNIX" "AF_INET" "AF_INET6"]; - }; - - environment = - { - PYTHONUNBUFFERED = "1"; - DB_CONNECTION_URI = cfg.database.connectionUri; - DB_SCHEMA = cfg.database.schema; - CACHE_URL = cfg.cache.url; - LOG_LEVEL = cfg.logLevel; - DERIVER_ENABLED = "true"; - DERIVER_WORKERS = toString cfg.deriver.workers; - DERIVER_PROVIDER = cfg.deriver.provider; - DERIVER_MODEL = cfg.deriver.model; - METRICS_ENABLED = "true"; - } - // optionalAttrs (cfg.auth.jwtSecretFile != null) { - AUTH_JWT_SECRET_FILE = cfg.auth.jwtSecretFile; - }; - }; - - # Open firewall port if binding to non-localhost - networking.firewall.allowedTCPPorts = mkIf (cfg.host != "127.0.0.1" && cfg.host != "localhost") [cfg.port]; - }; -} diff --git a/pkgs/honcho/default.nix b/pkgs/honcho/default.nix deleted file mode 100644 index bdf7d0a..0000000 --- a/pkgs/honcho/default.nix +++ /dev/null @@ -1,86 +0,0 @@ -{ - lib, - nix-update-script, - python3, - fetchFromGitHub, -}: -python3.pkgs.buildPythonPackage rec { - pname = "honcho"; - version = "3.0.5"; - pyproject = true; - - src = fetchFromGitHub { - owner = "plastic-labs"; - repo = "honcho"; - rev = "refs/heads/main"; - hash = "sha256-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="; - }; - - # Relax Python dependency version constraints - pythonRelaxDeps = true; - - build-system = with python3.pkgs; [ - hatchling - ]; - - dependencies = with python3.pkgs; [ - fastapi - groq - python-dotenv - sqlalchemy - pgvector - greenlet - psycopg - httpx - rich - nanoid - alembic - pyjwt - tenacity - tiktoken - langfuse - openai - pydantic - pydantic-settings - google-genai - pdfplumber - typing-extensions - json-repair - turbopuffer - lancedb - pyarrow - redis - cashews - scikit-learn - prometheus_client - cloudevents - fastapi-pagination - sentry-sdk - ]; - - # Skip tests - they require a running PostgreSQL with pgvector and Redis - doCheck = false; - - # Disable imports check because honcho tries to connect to database at import time - pythonImportsCheck = []; - - passthru.updateScript = nix-update-script {}; - - meta = with lib; { - description = "Memory library for building stateful AI agents"; - longDescription = '' - Honcho provides a sophisticated memory and reasoning system for AI agents: - - Rich Reasoning System: Multiple implementation methods that extract - conclusions from interactions and build comprehensive peer representations - - Chat API: Reasoning-informed responses integrating conclusions with context - - Background Processing: Asynchronous pipeline for expensive operations - - Multi-Provider Support: Configurable LLM providers (OpenAI, Anthropic, Google, Groq) - - REST API server for easy integration with any application - - PostgreSQL with pgvector for storage - ''; - homepage = "https://github.com/plastic-labs/honcho"; - license = licenses.agpl3Only; - platforms = platforms.linux; - mainProgram = "honcho"; - }; -} diff --git a/pkgs/opencode-desktop/default.nix b/pkgs/opencode-desktop/default.nix index bb571a9..06b53c7 100644 --- a/pkgs/opencode-desktop/default.nix +++ b/pkgs/opencode-desktop/default.nix @@ -31,7 +31,7 @@ # Upstream is missing outputHashes for git dependencies # Also fix stale npm deps hash in upstream node_modules FOD fixedNodeModules = opencode.node_modules.overrideAttrs { - outputHash = "sha256-C7y5FMI1pGEgMw/vcPoBhK9tw5uGg1bk0gPXPUUVhgU="; + outputHash = "sha256-LRhPPrOKCGUSCEWTpAxPdWKTKVNkg82WrvD25cP3jts="; }; opencode-desktop = rustPlatform.buildRustPackage (finalAttrs: {