143 lines
4.6 KiB
Nix
143 lines
4.6 KiB
Nix
# Babysitter user profile for Pi/agent workflows.
|
|
{
|
|
config,
|
|
lib,
|
|
...
|
|
}: let
|
|
cfg = config.coding.agents.babysitter;
|
|
defaultTimestamp = "2026-05-29T00:00:00.000Z";
|
|
|
|
defaultUserProfile = {
|
|
name = config.home.username;
|
|
specialties = [
|
|
{
|
|
domain = "declarative-system-configuration";
|
|
subdomains = ["nix" "home-manager" "agents"];
|
|
}
|
|
];
|
|
expertiseLevels = {};
|
|
goals = [
|
|
{
|
|
id = "goal-agents-declarative-profile";
|
|
description = "Keep Babysitter user preferences declarative and reproducible across systems.";
|
|
category = "agents";
|
|
priority = "medium";
|
|
status = "active";
|
|
}
|
|
];
|
|
preferences = {
|
|
verbosity = "concise";
|
|
autonomyLevel = "semi-autonomous";
|
|
riskTolerance = "conservative";
|
|
};
|
|
toolPreferences = {
|
|
packageManagers = ["nix"];
|
|
languages = ["nix"];
|
|
operatingSystem = "nixos";
|
|
};
|
|
breakpointTolerance = {
|
|
global = "moderate";
|
|
skipBreakpointsForKnownPatterns = false;
|
|
alwaysBreakOn = ["destructive-operations" "secrets" "external-publication"];
|
|
};
|
|
communicationStyle = {
|
|
tone = "technical";
|
|
language = "en";
|
|
useEmojis = false;
|
|
explanationDepth = "brief";
|
|
preferredResponseFormat = "markdown";
|
|
};
|
|
experience = {};
|
|
installedPlugins = ["babysitter-pi"];
|
|
installedSkills = ["babysit" "call" "plan" "resume" "doctor" "yolo"];
|
|
installedAgents = [];
|
|
createdAt = defaultTimestamp;
|
|
updatedAt = defaultTimestamp;
|
|
version = 1;
|
|
};
|
|
|
|
effectiveProfile = lib.recursiveUpdate cfg.profile cfg.profileOverrides;
|
|
profileJsonTarget = "${cfg.profileDirectory}/user-profile.json";
|
|
profileMarkdownTarget = "${cfg.profileDirectory}/user-profile.md";
|
|
profilePreferences = effectiveProfile.preferences or {};
|
|
profileBreakpointTolerance = effectiveProfile.breakpointTolerance or {};
|
|
|
|
listMarkdown = values:
|
|
lib.concatMapStringsSep "\n" (value: "- ${toString value}") values;
|
|
|
|
specialtyDomains = map (specialty: specialty.domain or "unspecified") (effectiveProfile.specialties or []);
|
|
|
|
profileMarkdown = ''
|
|
# Babysitter User Profile
|
|
|
|
This file is generated by Home Manager from `coding.agents.babysitter`.
|
|
|
|
- Name: ${effectiveProfile.name or "unspecified"}
|
|
- Breakpoint tolerance: ${profileBreakpointTolerance.global or "unspecified"}
|
|
- Autonomy level: ${profilePreferences.autonomyLevel or "unspecified"}
|
|
- Risk tolerance: ${profilePreferences.riskTolerance or "unspecified"}
|
|
|
|
## Specialties
|
|
|
|
${listMarkdown specialtyDomains}
|
|
|
|
## Installed Babysitter Pi Skills
|
|
|
|
${listMarkdown (effectiveProfile.installedSkills or [])}
|
|
'';
|
|
in {
|
|
options.coding.agents.babysitter = {
|
|
enable = lib.mkEnableOption "Babysitter user profile for Pi/agent workflows";
|
|
|
|
profileDirectory = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = ".a5c";
|
|
description = ''
|
|
Home-relative directory where Babysitter reads the user profile.
|
|
Babysitter Pi documents the user profile at ~/.a5c/user-profile.json.
|
|
'';
|
|
};
|
|
|
|
profile = lib.mkOption {
|
|
type = lib.types.attrsOf lib.types.anything;
|
|
default = defaultUserProfile;
|
|
description = "Complete non-secret Babysitter user profile JSON.";
|
|
};
|
|
|
|
profileOverrides = lib.mkOption {
|
|
type = lib.types.attrsOf lib.types.anything;
|
|
default = {};
|
|
description = ''
|
|
Recursive overrides merged into the default Babysitter user profile.
|
|
Keep this non-secret; the result is written into the Nix store.
|
|
'';
|
|
};
|
|
};
|
|
|
|
config = lib.mkIf cfg.enable {
|
|
assertions = [
|
|
{
|
|
assertion = cfg.profileDirectory != "" && !lib.hasPrefix "/" cfg.profileDirectory;
|
|
message = "coding.agents.babysitter.profileDirectory must be a non-empty home-relative path.";
|
|
}
|
|
{
|
|
assertion = effectiveProfile ? name && builtins.isString effectiveProfile.name;
|
|
message = "coding.agents.babysitter profile must include a string name.";
|
|
}
|
|
{
|
|
assertion = effectiveProfile ? specialties && builtins.isList effectiveProfile.specialties;
|
|
message = "coding.agents.babysitter profile must include a specialties list.";
|
|
}
|
|
{
|
|
assertion = effectiveProfile ? breakpointTolerance && effectiveProfile.breakpointTolerance ? global;
|
|
message = "coding.agents.babysitter profile must include breakpointTolerance.global.";
|
|
}
|
|
];
|
|
|
|
home.file = {
|
|
"${profileJsonTarget}".text = builtins.toJSON effectiveProfile + "\n";
|
|
"${profileMarkdownTarget}".text = profileMarkdown;
|
|
};
|
|
};
|
|
}
|