enable trollshell pet
This commit is contained in:
parent
ac5ea6e5e4
commit
a7c7df8bf8
1 changed files with 89 additions and 1 deletions
|
|
@ -1,9 +1,97 @@
|
|||
{ ... }:
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
trollshell,
|
||||
...
|
||||
}:
|
||||
let
|
||||
trollshellPkgs = trollshell.packages.${pkgs.stdenv.hostPlatform.system};
|
||||
|
||||
# The claude bridge's loopback port, shared between the daemon and the pet
|
||||
# that talks to it so there is one number to change. The address is fixed at
|
||||
# 127.0.0.1 by the bridge and is not configurable: the bridge validates no
|
||||
# bearer token at all, so reachability *is* the authorization boundary.
|
||||
bridgePort = 8787;
|
||||
in
|
||||
{
|
||||
programs.trollshell = {
|
||||
enable = true;
|
||||
weather.fallbackCity = "Berlin";
|
||||
cliphist.enable = true;
|
||||
stats.layout = "split";
|
||||
plugins = {
|
||||
pet = {
|
||||
enable = true;
|
||||
package = trollshellPkgs.hytte-plugin-pet;
|
||||
env = {
|
||||
PET_NAME = "foo";
|
||||
PET_LLM_URL = "http://127.0.0.1:${toString bridgePort}";
|
||||
# Not a real key. `hytte_ai_providers::load_key` checks this env
|
||||
# override *before* ~/.config/trollshell/openrouter.key, so this dummy
|
||||
# is what stops a genuine OpenRouter key being shipped to a loopback
|
||||
# port. It is a security control, not a placeholder — don't drop it.
|
||||
OPENROUTER_API_KEY = "local-bridge";
|
||||
};
|
||||
};
|
||||
departures = {
|
||||
enable = true;
|
||||
package = trollshellPkgs.hytte-plugin-departures;
|
||||
};
|
||||
usage = {
|
||||
enable = true;
|
||||
package = trollshellPkgs.hytte-plugin-usage;
|
||||
};
|
||||
weather = {
|
||||
enable = true;
|
||||
package = trollshellPkgs.hytte-plugin-weather;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# The keyless loopback shim that puts an OpenAI-compatible face on headless
|
||||
# `claude --print`, so pet rides the Claude Code subscription instead of
|
||||
# OpenRouter. trollshell ships the package and a reference unit under `etc/`
|
||||
# but no module option for it, so the unit is declared here — without it the
|
||||
# pet's PET_LLM_URL above points at nothing and the plugin stays canned-only.
|
||||
systemd.user.services.trollshell-claude-bridge = {
|
||||
Unit = {
|
||||
Description = "Keyless loopback OpenAI-compatible bridge to headless Claude Code";
|
||||
PartOf = [ config.programs.trollshell.systemd.target ];
|
||||
After = [ config.programs.trollshell.systemd.target ];
|
||||
};
|
||||
|
||||
Service = {
|
||||
Type = "simple";
|
||||
ExecStart = lib.getExe trollshellPkgs.hytte-claude-bridge;
|
||||
Restart = "on-failure";
|
||||
RestartSec = 5;
|
||||
|
||||
Environment = [
|
||||
"RUST_LOG=hytte_claude_bridge=info"
|
||||
"CLAUDE_BRIDGE_PORT=${toString bridgePort}"
|
||||
# `claude --model` for the child. Worth pinning: the bridge's default
|
||||
# per-request budget is 8s (it must stay under the client's 10s), and
|
||||
# the child otherwise inherits the model from ~/.claude/settings.json —
|
||||
# currently opus, which would blow that budget on nearly every reply.
|
||||
"CLAUDE_BRIDGE_MODEL=claude-haiku-4-5"
|
||||
"CLAUDE_BRIDGE_TIMEOUT_SECS=9"
|
||||
# Belt-and-braces; the copy that actually prevents a leak is the one on
|
||||
# the pet above, because load_key runs in the plugin's process.
|
||||
"OPENROUTER_API_KEY=local-bridge"
|
||||
# The bridge shells out to `claude`, which is the OTEL wrapper from
|
||||
# ./claude.nix — so pet chatter is counted as workstation usage.
|
||||
"PATH=${config.home.profileDirectory}/bin:/run/current-system/sw/bin"
|
||||
];
|
||||
|
||||
# SECURITY CONTROL — do not drop. These four would silently move `claude`
|
||||
# off the subscription and onto metered API credits (or Bedrock/Vertex).
|
||||
# The bridge cannot scrub them itself (`std::env::remove_var` is unsafe
|
||||
# under edition 2024 and that workspace forbids unsafe), so it fails
|
||||
# closed instead: it *refuses to start* if it finds any of them set.
|
||||
UnsetEnvironment = "ANTHROPIC_API_KEY ANTHROPIC_AUTH_TOKEN CLAUDE_CODE_USE_BEDROCK CLAUDE_CODE_USE_VERTEX";
|
||||
};
|
||||
|
||||
Install.WantedBy = [ config.programs.trollshell.systemd.target ];
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue