feat: custom agents (bring-your-own-agent)#96
Merged
Conversation
Rename AgentId->BuiltinAgentId (strict union) and add
AgentId = BuiltinAgentId | (string & {}) for the runtime boundary;
rename isAgentId->isBuiltinAgent. Foundation for user-defined agents.
Co-Authored-By: Rooty
DETECTORS/READERS key on BuiltinAgentId so widening AgentId can't degrade them to index signatures; resolveActiveModel narrows with isBuiltinAgent before indexing. Custom agents -> null model. Co-Authored-By: Rooty
Pure, IO-free CustomAgentSpec type + validateCustomAgent gate: id/binary charset, bounds, curated colour tokens, BLOCKED_ENV + credential-key rejection. Reused by main (load/save) and renderer (form). Co-Authored-By: Rooty
AgentRegistry reads agents.toml, validates + merges with the 7 builtins, exposes has/byId/binaryFor/argsFor/envFor/knownIds. Bad entries skipped with warnings; redacted wire descriptors omit env. Co-Authored-By: Rooty
Add LD_AUDIT/LD_PROFILE/BASH_ENV/ENV alongside the existing hijack vars; document the denylist as best-effort defense-in-depth (the trust boundary is the user's own local config). Co-Authored-By: Rooty
saveCustom/deleteCustom validate, persist via atomicWrite + TOML stringify, then reload. Round-trips args/env/ui; rejects invalid + builtin-shadow without writing. Co-Authored-By: Rooty
Live AgentRegistry in main (load at startup), reachable via agents:getRegistry/saveCustom/deleteCustom + a registryChange push. Move AgentDescriptorWire to shared so the bridge can type it. Co-Authored-By: Rooty
Custom agents now pass spawn/visibility/effective-context gates via registry.has, with their own context window folded into the lookup; env snapshot returns a neutral blank for non-builtins. Auto-updater stays builtin-only. Co-Authored-By: Rooty
pty-manager resolves custom binary/args via the registry (each shellQuoted) and merges non-secret env into the child process env, never a shell string. Builtin launch behavior unchanged. Co-Authored-By: Rooty
node-runners resolves custom binary/args from the registry (no --print, shell-quoted path probe); validateWorkflow takes an optional knownAgentIds set so the engine accepts custom ids while existing callers keep the builtin default. Co-Authored-By: Rooty
Zustand slice bootstraps the merged registry over IPC and refreshes on registryChange (templates-slice pattern); selectAgentMeta resolves display metadata with a degraded fallback for dangling/custom ids. Co-Authored-By: Rooty
Adds a Custom Agents section to the Agents screen with add/edit/clone/ delete, and a focus-trapped modal (essentials/appearance/advanced) with live validateCustomAgent + curated colour swatches + env-secret warnings. Delete routes through ConfirmDialog. Co-Authored-By: Rooty
New-session picker, project-default dropdown, command palette, AgentSelector and the workflow node editor now enumerate the merged registry (visibleAgents preserved); custom workflow nodes show a best-effort hint. Co-Authored-By: Rooty
Wire selectAgentMeta(useAgentRegistry(), id) into ~18 session/home/ history/workflow display components so custom agents show their real name/icon/short/colour (not raw id + --accent); fix AgentChipB1 render-nothing, ProjectCardB1 filter-out, EnvTab snapshot skip, and the canvas node dropdown; flag deleted agents as 'no longer registered'. Seed the renderer registry with builtin descriptors so builtins resolve pre-IPC-pull. Co-Authored-By: Rooty
- workflow runner now passes custom-agent env via the child env option - renameWorkflow threads the merged agent id set (no false Unknown agent) - non-lossy edit/clone via agents:getCustomSpec (args/env pre-filled) - ipc-pty consumes the shared BLOCKED_ENV_KEYS (closes denylist drift) - agents.toml parse warnings surface as a notification - dangling-agent spawn shows a visible 'no longer registered' notice Co-Authored-By: Rooty
DRY the builtin->descriptor mapping (toBuiltinDescriptor), add a useAgentMeta(id) hook for single-id display sites, extract the effective-context defaults closure, drop dead agentShort(). Behavior and security posture unchanged; tests green. Co-Authored-By: Rooty
Co-Authored-By: Rooty
Co-Authored-By: Rooty
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds custom agents (bring-your-own-agent): register your own CLI agents (e.g. Ollama, a local model runner, a personal wrapper) alongside the seven built-ins, so the deck isn't limited to a fixed list.
<userData>/agents.toml— each is a binary + default args + non-secret env + display metadata (name, icon, colour, context window).env, never a shell string. The strictBuiltinAgentIdunion is preserved (built-in maps stay exhaustive viasatisfies); only the runtime registry boundary accepts arbitrary ids, gated byregistry.has.Notes
safeStorage.--print) — a console agent has no headless mode; this is surfaced in the node UI.