feat: make the conversation kill controls settable from the dashboard

The `conversations` section was only reachable by editing config.yaml, which
production ignores: config is database-backed and the YAML is imported once,
when the database has not yet been seeded. `AdvancedConfigSchema` is also a
strict object, so a PUT carrying the section was rejected outright.

- Add `conversations` to the advanced config schema and payload, so it appears
  in the dashboard's advanced JSON editor and survives a save.
- Apply the edited section field by field rather than replacing the objects,
  and read the flags through to the live config from the account runtime, so a
  save applies to a running account without a restart.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Jamie BruntonandClaude Opus 5 committed 2026-08-10 12:57:56 +01:00
1 parent 4404ae75ff
commit 0a4e0064f2
4 files changed
+148 -7

No files matched your search

@@ -257,16 +257,15 @@ async function buildRuntime(
undefined,
undefined,
mediaExchange,
// Read through to the live config object rather than snapshotting, so a
// dashboard configuration save applies to a running account without a
// restart. The service reads these on every inbound reply.
{
offPlatformKill: accountConfig.conversations.offPlatformKill,
killOnSellerKeyword: accountConfig.conversations.killOnSellerKeyword,
get offPlatformKill() { return accountConfig.conversations.offPlatformKill; },
get killOnSellerKeyword() { return accountConfig.conversations.killOnSellerKeyword; },
triage: conversationReadStateRepo,
screener: aiClient,
screening: {
enabled: accountConfig.conversations.aiReplyScreening.enabled,
killConfidence: accountConfig.conversations.aiReplyScreening.killConfidence,
flagConfidence: accountConfig.conversations.aiReplyScreening.flagConfidence,
},
get screening() { return accountConfig.conversations.aiReplyScreening; },
},
);