From a3365848affe75cfb87c90940d11c87a610f3815 Mon Sep 17 00:00:00 2001 From: Markov Date: Fri, 27 Feb 2026 16:32:32 +0100 Subject: [PATCH] Hot config update + systemd template - Router handles config.updated WS event (model, provider, prompt) - picogent@.service template: systemctl start picogent@coder --- picogent@.service | 15 +++++++++++++++ src/router.ts | 26 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) create mode 100644 picogent@.service diff --git a/picogent@.service b/picogent@.service new file mode 100644 index 0000000..6cbc29f --- /dev/null +++ b/picogent@.service @@ -0,0 +1,15 @@ +[Unit] +Description=Picogent Agent %i +After=network.target +Wants=network.target + +[Service] +Type=simple +WorkingDirectory=/root/projects/team-board/picogent +ExecStart=/usr/bin/node dist/index.js /root/projects/team-board/agents/%i/ +Restart=always +RestartSec=5 +Environment=NODE_ENV=production + +[Install] +WantedBy=multi-user.target diff --git a/src/router.ts b/src/router.ts index 526d4e2..edecea8 100644 --- a/src/router.ts +++ b/src/router.ts @@ -50,6 +50,29 @@ export class EventRouter { this.log.info({ mappings: this.chatToProject.size }, 'Project mappings set'); } + /** Handle hot config update from Tracker */ + private handleConfigUpdated(data: Record): void { + this.log.info('━━━ CONFIG UPDATED ━━━'); + if (data.model && typeof data.model === 'string') { + this.config.model = data.model; + this.log.info(' Model → %s', data.model); + } + if (data.provider && typeof data.provider === 'string') { + this.config.provider = data.provider; + this.log.info(' Provider → %s', data.provider); + } + if (data.prompt !== undefined) { + this.config.prompt = (data.prompt as string) || ''; + this.log.info(' Prompt updated (%d chars)', this.config.prompt.length); + } + if (data.chat_listen && typeof data.chat_listen === 'string') { + this.log.info(' chat_listen → %s (requires reconnect for WS filter)', data.chat_listen); + } + if (data.task_listen && typeof data.task_listen === 'string') { + this.log.info(' task_listen → %s (requires reconnect for WS filter)', data.task_listen); + } + } + private resolveProjectId(chatId?: string): string | undefined { if (chatId) return this.chatToProject.get(chatId); return undefined; @@ -63,6 +86,9 @@ export class EventRouter { case 'chat.message': await this.handleMessageNew(event.data); break; + case 'config.updated': + this.handleConfigUpdated(event.data); + break; case 'task.assigned': case 'task.created': case 'task.updated':