synapse: a reaction continues its conversation, and the request becomes a record
Every Synapse event used to open its own service session, so two messages of
one Telegram chat landed in two unrelated chats. The dispatcher now returns a
`session_key` — derived from the payload according to the user's routing
document — and a later event carrying the same key joins the session that
opened it, within `reaction_session_ttl_minutes` of idle time (0 restores the
old always-fresh behaviour). A session that is still running is never joined:
`create_run` overwrites `state.run`, so a second run would orphan the first
one's subscribers — a busy thread gets a fresh session instead. When the
dispatcher names a different profile for the event, the session's profile is
switched through `set_profile`, never through `save()`, which does not rewrite
`name` or `profile_id`: the thread keeps its name and its history.

What the user reads in the transcript is now only the request. The event
record is a system message (`metadata.source == "synapse_event"`) drawn by a
new SynapseEventNotice.vue in the visual language of the recall badge, and the
framing plus the JSON envelope become a hidden user turn written once, on the
first event of a thread — not on every one. The instructions from Settings
reach the model through a new `current_reaction_instructions` ContextVar and
the `[Reaction session]` block of the system prompt, so they appear in no
transcript at all. The stored system record still has to reach the model, so
ContextBuilder's allowlist becomes `_LLM_SYSTEM_SOURCES = {task_note,
synapse_event}`.

The dispatcher gets a document of its own — how to route, rather than what to
do — stored beside the reaction instructions, versioned separately, and edited
in its own field in the settings panel. `synapse_instruction_versions` gains a
`doc` discriminator, so existing rows keep `'reaction'` and their history
verbatim. The new columns are added by `_MIGRATE`, and the index over `doc`
lives there too: `_DDL` runs first, so an index over a column the migration has
not added yet kills the whole batch on an existing database — which is what
the prod database is. A guard test keeps it that way.

Tests: 1776 passed, 1 skipped (backend), 242 passed (webclient, 28 files).
1 parent e995de4 commit 77606d627c372ba528f326d39cd9006a224422ac
@Eugene Sukhodolskiy Eugene Sukhodolskiy authored 8 hours ago
Showing 44 changed files
View
docs/api.md
View
docs/i18n.md
View
docs/sessions.md
View
docs/synapse.md
View
docs/tools.md
View
manuals/synapse_instructions.md 0 → 100644
View
navi/api/routes/synapse.py
View
navi/core/context_builder.py
View
navi/core/pg_session_store.py
View
navi/core/session.py
View
navi/profiles/dispatcher/system_prompt.txt
View
navi/synapse/_ddl.py
View
navi/synapse/reactions.py
View
navi/synapse/settings_store.py
View
navi/tools/_internal/base.py
View
navi/tools/synapse_instructions.py
View
tests/unit/api/test_synapse.py
View
tests/unit/core/test_context_builder.py
View
tests/unit/core/test_pg_session_store.py
View
tests/unit/core/test_synapse_ddl.py 0 → 100644
View
tests/unit/core/test_synapse_reactions.py
View
tests/unit/tools/test_notify.py
View
tests/unit/tools/test_synapse_instructions.py
View
webclient/dist/assets/index--pnFAqTO.css 100644 → 0
View
webclient/dist/assets/index-6irUhvo6.css 0 → 100644
View
webclient/dist/assets/index-Cv64uvH2.js 0 → 100644
Not supported
View
webclient/dist/assets/index-_ULQ__AM.js 100644 → 0
Not supported
View
webclient/dist/index.html
View
webclient/dist/sw.js
View
webclient/src/api/index.js
View
webclient/src/components/chat/MessageList.vue
View
webclient/src/components/messages/SynapseEventNotice.vue 0 → 100644
View
webclient/src/components/settings/SynapseInstructionsField.vue 0 → 100644
View
webclient/src/components/settings/SynapseReactionsPanel.vue
View
webclient/src/i18n/messages/en.js
View
webclient/src/i18n/messages/ru.js
View
webclient/src/i18n/messages/uk.js
View
webclient/src/stores/chat.js
View
webclient/src/stores/synapseReactions.js
View
webclient/tests/unit/components/chat/messageList.test.js
View
webclient/tests/unit/components/messages/synapseEventNotice.test.js 0 → 100644
View
webclient/tests/unit/components/settings/synapseReactionsPanel.test.js
View
webclient/tests/unit/stores/chat.test.js
View
webclient/tests/unit/stores/synapseReactions.test.js