Add OpenClaw AI Agent module
- Systemd service running OpenClaw gateway - Configurable via sops secrets - Runs on localhost:18789 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
f013863986
commit
3a885463f0
4 changed files with 210 additions and 0 deletions
|
|
@ -5,5 +5,6 @@
|
|||
./podman.nix
|
||||
./nginx.nix
|
||||
./searxng.nix
|
||||
./openclaw.nix
|
||||
];
|
||||
}
|
||||
|
|
|
|||
80
modules/openclaw-config.json
Normal file
80
modules/openclaw-config.json
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
{
|
||||
"gateway": {
|
||||
"port": 18789,
|
||||
"bind": "loopback",
|
||||
"trustedProxies": ["::1", "127.0.0.1", "10.88.0.0/16", "10.89.0.0/16"],
|
||||
"auth": {
|
||||
"mode": "none"
|
||||
},
|
||||
"controlUi": {
|
||||
"dangerouslyAllowHostHeaderOriginFallback": true,
|
||||
"allowedOrigins": ["*"]
|
||||
}
|
||||
},
|
||||
"channels": {
|
||||
"whatsapp": {
|
||||
"enabled": false
|
||||
},
|
||||
"discord": {
|
||||
"enabled": true,
|
||||
"groupPolicy": "open",
|
||||
"dmPolicy": "open",
|
||||
"allowFrom": ["*"]
|
||||
}
|
||||
},
|
||||
"agents": {
|
||||
"defaults": {
|
||||
"model": {
|
||||
"primary": "openai/gemini-3.1-pro-high"
|
||||
},
|
||||
"memorySearch": {
|
||||
"provider": "openai",
|
||||
"model": "nomic-embed-text",
|
||||
"remote": {
|
||||
"baseUrl": "http://localhost:11434/v1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tools": {
|
||||
"exec": {
|
||||
"security": "full",
|
||||
"ask": "off"
|
||||
}
|
||||
},
|
||||
"skills": {
|
||||
"entries": {}
|
||||
},
|
||||
"commands": {
|
||||
"native": true,
|
||||
"nativeSkills": "auto",
|
||||
"restart": true,
|
||||
"ownerDisplay": "raw"
|
||||
},
|
||||
"models": {
|
||||
"mode": "merge",
|
||||
"providers": {
|
||||
"openai": {
|
||||
"baseUrl": "http://localhost:8045/v1/chat/completions",
|
||||
"apiKey": "${OPENAI_API_KEY}",
|
||||
"api": "openai",
|
||||
"models": [
|
||||
{
|
||||
"id": "gemini-3.1-pro-high",
|
||||
"name": "Gemini 3.1 Pro High",
|
||||
"reasoning": true,
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 65536
|
||||
},
|
||||
{
|
||||
"id": "claude-opus-4-6-thinking",
|
||||
"name": "Claude Opus 4.6 Thinking",
|
||||
"reasoning": true,
|
||||
"contextWindow": 1000000,
|
||||
"maxTokens": 65536
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
111
modules/openclaw.nix
Normal file
111
modules/openclaw.nix
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
# OpenClaw Module
|
||||
# Provides: AI Agent with Discord integration
|
||||
#
|
||||
# Usage:
|
||||
# myModules.openclaw = {
|
||||
# enable = true;
|
||||
# port = 18789;
|
||||
# };
|
||||
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}:
|
||||
|
||||
let
|
||||
cfg = config.myModules.openclaw;
|
||||
configDir = "/var/lib/openclaw/config";
|
||||
dataDir = "/var/lib/openclaw/data";
|
||||
workspaceDir = "/var/lib/openclaw/workspace";
|
||||
in
|
||||
{
|
||||
options.myModules.openclaw = {
|
||||
enable = lib.mkEnableOption "OpenClaw AI Agent";
|
||||
|
||||
port = lib.mkOption {
|
||||
type = lib.types.port;
|
||||
default = 18789;
|
||||
description = "Gateway port for OpenClaw";
|
||||
};
|
||||
|
||||
environmentFile = lib.mkOption {
|
||||
type = lib.types.nullOr lib.types.path;
|
||||
default = null;
|
||||
description = "Path to environment file with API keys";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# Create user for openclaw
|
||||
users.users.openclaw = {
|
||||
isSystemUser = true;
|
||||
group = "openclaw";
|
||||
home = "/var/lib/openclaw";
|
||||
createHome = true;
|
||||
};
|
||||
users.groups.openclaw = { };
|
||||
|
||||
# Create directories
|
||||
systemd.tmpfiles.settings."10-openclaw" = {
|
||||
"${configDir}".d = {
|
||||
user = "openclaw";
|
||||
group = "openclaw";
|
||||
mode = "0700";
|
||||
};
|
||||
"${dataDir}".d = {
|
||||
user = "openclaw";
|
||||
group = "openclaw";
|
||||
mode = "0700";
|
||||
};
|
||||
"${workspaceDir}".d = {
|
||||
user = "openclaw";
|
||||
group = "openclaw";
|
||||
mode = "0700";
|
||||
};
|
||||
};
|
||||
|
||||
# Copy config file
|
||||
environment.etc."openclaw/openclaw.json".source = ./openclaw-config.json;
|
||||
|
||||
# Systemd service
|
||||
systemd.services.openclaw = {
|
||||
description = "OpenClaw AI Agent";
|
||||
after = [ "network.target" ];
|
||||
wantedBy = [ "multi-user.target" ];
|
||||
|
||||
serviceConfig = {
|
||||
Type = "simple";
|
||||
User = "openclaw";
|
||||
Group = "openclaw";
|
||||
WorkingDirectory = dataDir;
|
||||
|
||||
Environment = [
|
||||
"NODE_ENV=production"
|
||||
"OPENCLAW_CONFIG_DIR=${configDir}"
|
||||
"OPENCLAW_DATA_DIR=${dataDir}"
|
||||
"OPENCLAW_WORKSPACE_DIR=${workspaceDir}"
|
||||
];
|
||||
|
||||
ExecStartPre = [
|
||||
"${pkgs.coreutils}/bin/mkdir -p ${configDir} ${dataDir} ${workspaceDir}"
|
||||
"${pkgs.coreutils}/bin/cp -n /etc/openclaw/openclaw.json ${configDir}/ || true"
|
||||
];
|
||||
|
||||
ExecStart = "${pkgs.nodejs_22}/bin/npx openclaw gateway start --port ${toString cfg.port}";
|
||||
|
||||
Restart = "on-failure";
|
||||
RestartSec = "10s";
|
||||
|
||||
# Security
|
||||
PrivateTmp = true;
|
||||
ProtectSystem = "strict";
|
||||
ReadWritePaths = [ configDir dataDir workspaceDir ];
|
||||
NoNewPrivileges = true;
|
||||
};
|
||||
} // lib.optionalAttrs (cfg.environmentFile != null) {
|
||||
serviceConfig.EnvironmentFile = cfg.environmentFile;
|
||||
};
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue