feat(gastown): custom per-role prompt instructions in town settings#1827
feat(gastown): custom per-role prompt instructions in town settings#1827
Conversation
Add custom_instructions field to town config allowing users to append free-text instructions to each agent role's system prompt (polecat, refinery, mayor). Instructions are injected as a dedicated section at the end of the system prompt, taking effect on next agent dispatch. For the mayor, a new PUT /agents/:agentId/system-prompt container endpoint rewrites AGENTS.md when instructions change so the running mayor picks them up without a full container restart. Also widens all gastown drawers by 120px and removes truncate from drawer title headers. Closes #1794
| git_author_name: z.string().optional(), | ||
| git_author_email: z.string().optional(), | ||
| disable_ai_coauthor: z.boolean().optional(), | ||
| custom_instructions: z |
There was a problem hiding this comment.
WARNING: Partial updates can erase other roles' instructions
TownConfigUpdateSchema accepts payloads like { custom_instructions: { mayor: "..." } }, but config.updateTownConfig() only shallow-merges top-level fields. Sending one role here replaces the whole custom_instructions object and drops any existing polecat/refinery values. This field needs a deep merge, or callers need to be forced to send the full object.
| alarm_interval_idle: z.number().optional(), | ||
| container: z.object({ sleep_after_minutes: z.number().optional() }).optional(), | ||
| staged_convoys_default: z.boolean().optional(), | ||
| custom_instructions: z |
There was a problem hiding this comment.
WARNING: Admin edits won't hot-apply mayor instructions
This admin mutation still patches /api/towns/:townId/config, and that handler only persists the config. The regular Gastown settings flow calls updateMayorSystemPrompt() when custom_instructions.mayor changes, but this admin path never does, so admin-edited mayor instructions will not reach the running container until the mayor/container is restarted.
Code Review SummaryStatus: 2 Issues Found | Recommendation: Address before merge Overview
Fix these issues in Kilo Cloud Issue Details (click to expand)WARNING
Other Observations (not in diff)No additional observations. Files Reviewed (15 files)
Reviewed by gpt-5.4-20260305 · 2,352,575 tokens |
Summary
custom_instructionsfield to town config schema, allowing users to append free-text instructions (up to 2000 chars each) to the system prompt for polecat, refinery, and mayor agents## Custom Instructions (from town settings)section at the end of each role's system prompt viaappendCustomInstructions()in the dispatch pathPUT /agents/:agentId/system-promptcontainer endpoint rewrites AGENTS.md when instructions change, triggered automatically from theupdateTownConfigmutationtruncatefrom drawer title headers for better readabilityCloses #1794
Verification
pnpm typecheckpasses (only pre-existingcsv-parse/syncerror in a migration script)oxfmt --list-different .passes (no formatting issues)pnpm build:typesVisual Changes
Reviewer Notes
appendCustomInstructionshelper incontainer-dispatch.tsis applied at the single point wheresystemPromptis assembled instartAgentInContainer, covering all roles (polecat usessystemPromptForRole, refinery usessystemPromptOverride, mayor usessystemPromptForRole— all get wrapped)AGENTS.md(read by kilo serve) rather than passed via the session API. The newupdateMayorSystemPrompt()method on TownDO rebuilds the prompt and pushes it to the container whencustom_instructions.mayorchangescustom_instructionsfield is fully optional and backward-compatible — existing towns without it behave identically