fix(group-translate,voice-transcription): honor per-session config via signature-cached rebuild - #39
Merged
Merged
Conversation
…a signature-cached rebuild Same class of bug as PR #38 but for stateful-coordinator plugins: the hook read a coordinator cached at onEnable, ignoring per-session overrides. Fix by recomputing a config signature per event and rebuilding only when it changes — preserving the client circuit breaker across messages for an unchanged backend. - group-translate: configSignature over libretranslateUrl/apiKey/timeout/ prefix/minLength/maxLength/denyReply; rebuild only on signature change - voice-transcription: configSignature over sttBaseUrl/apiKey/model/language/ timeout/delivery/chatDelivery/enabledTypes/maxSize/maxPerHour/provider; rebuild only on signature change. Bundled with the messages:send permission fix (chatDelivery was throwing PluginCapabilityError at runtime) - gsheets-logger: README documents per-session spreadsheet routing is not supported (single-buffer single-sink design; not fixable without refactor) - Regression tests per coordinator plugin: coordinator reused for unchanged config (breaker preserved), rebuilt for changed config (override honored) typecheck clean; 401/401 tests pass.
rmyndharis
added a commit
that referenced
this pull request
Jul 18, 2026
…nslate 1.0.6, voice-transcription 1.0.2 Cut PATCH releases for the five plugins with per-session config-honor fixes: - after-hours 0.1.3 — per-event config re-parse (PR #38) - faq-bot 0.1.7 — per-event config re-parse (PR #38) - chat-flow 1.0.6 — per-event config re-parse (PR #38) - group-translate 1.0.6 — config-signature cached rebuild (PR #39) - voice-transcription 1.0.2 — messages:send permission + config-signature cached rebuild (PR #39)
rmyndharis
added a commit
that referenced
this pull request
Jul 18, 2026
…spec (#40) Make per-session config support explicit and discoverable at three layers: 1. PLUGIN-STANDARD.md (spec) — expand the Per-session config section with the author requirement (re-read ctx.config inside the hook, not a cached snapshot), the two correct patterns (per-event re-parse for plain config; config-signature caching for stateful coordinators), an explicit anti-pattern callout (cache-at-enable breaks overrides, the source of PRs #38/#39), and a documentation requirement for READMEs. 2. Root README — add a 'Per-session config support' matrix table after the plugin catalog so operators can see at a glance which plugins honor per-session overrides (✅/⚠️ /❌) and the caveat for each. 3. Each plugin README — add a '### Per-session config' subsection under Compatibility with the support tier (full / caveat / not supported), the fields that may be overridden, and any workaround (e.g. one instance per session for multi-backend isolation or single-sink designs). gsheets-logger's existing note is aligned to the same heading format.
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
Follow-up to #38 for the two remaining stateful-coordinator plugins (
group-translate,voice-transcription) that had the same per-session config-caching bug, plus a documentation note forgsheets-logger.Problem
PR #38 fixed
after-hours,chat-flow, andfaq-bot— three plugins whose hook read a config snapshot cached atonEnable, ignoring per-session overrides (the host resolvesctx.configper-session inside a hook but returns the base*config at lifecycle time).Two more plugins have the same bug but couldn't use the same simple fix: they cache a stateful coordinator (not just config values) built from the client that holds a circuit breaker. A naive per-event rebuild would reset the breaker on every message, defeating its purpose (a down backend would be hammered on every incoming message instead of being skipped after the threshold).
A third plugin (
gsheets-logger) has the same caching pattern but is not fixable without an architecture change: it holds a single buffer mixing rows from every session, so per-session spreadsheet routing can't work without splitting the buffer by session.Changes
group-translate— config-signature cachingconfigSignature(JSON of the coordinator-affecting fields:libretranslateUrl,apiKey,timeoutMs,commandPrefix,minLength,maxLength,denyReply) per event.voice-transcription— config-signature caching + permission fixconfigSignatureoversttBaseUrl,apiKey,model,language,timeoutMs, delivery config,chatDelivery,enabledMessageTypes,maxSizeBytes,maxPerHour,provider. Rebuild only on signature change.messages:sendin the manifest (v1.0.1 → v1.0.2). ThechatDeliveryfeature callsctx.messages.sendText/reply, both gated bymessages:send, but the manifest only declarednet:fetch. EnablingchatDelivery: 'self'/'reply'threwPluginCapabilityErroron every send (default'off'masked it).gsheets-logger— documentationTests
group-translate/index.test.ts(new): coordinator reused for unchanged config (breaker preserved), rebuilt for changed config (override honored).voice-transcription/index.test.ts: same two-sided regression test.Verification
npm run typecheck— cleannpm run catalog:check— up to datenpm test— 401/401 pass (was 399; +2 regression tests)