feat(conformance): ingress mirror — pure parse cores + ingress vector generator - #72458
Open
benbarclay wants to merge 3 commits into
Open
feat(conformance): ingress mirror — pure parse cores + ingress vector generator#72458benbarclay wants to merge 3 commits into
benbarclay wants to merge 3 commits into
Conversation
… generator The inbound half of the conformance oracle (egress landed in #71666): - plugins/platforms/telegram/telegram_parse.py: PURE parse core extracted from TelegramAdapter._build_message_event — chat-type normalization, routable-thread rules (#3206 reply-anchor drop, #22423 General-topic '1'), reply context w/ native partial quotes (#22619), source identity. Dual access model: works on PTB objects AND raw Bot API dicts, so the generator needs no python-telegram-bot dependency. Adapter delegates (classmethod shim kept; reply-context inline logic replaced with a call; stateful fallbacks — rich echo, rich_sent_store — stay adapter-side). - gateway/platforms/whatsapp_cloud_parse.py: PURE parse core extracted from WhatsAppCloudAdapter._build_message_event_from_cloud — type mapping, body extraction (button/list titles), reply context (id + is_own vs business number), media identification, group-shape discriminator. Adapter delegates for all payload-derivable fields. - scripts/generate_ingress_vectors.py: renders 27 synthetic platform payloads (14 telegram + 13 whatsapp) through the cores and emits payload→expected-field JSON vectors, oracle-SHA stamped, committed under tests/conformance/ingress_vectors/. - tests/conformance/test_ingress_vectors.py: 8 tests in three layers — generator invariants, ORACLE FIDELITY (core ≡ real adapter on every corpus payload: telegram via PTB-style objects against the adapter shim, whatsapp via the real _build_message_event_from_cloud with state stubbed), and committed-vectors lockstep. - discord/slack ingress deferred: their native inbound paths are SDK event-object consumers; same extraction needed first (parity report). Suites: conformance 15, whatsapp_cloud 113, topics/gating 117, relay 266 — all green post-refactor (behavior-preserving).
Contributor
૮ >ﻌ< ა ci reviewran on 2a7e4d9 ℹ️ InfoDesktop E2E visual evidence · View test artifacts · View job1 visual diff. inline evidence upload failed. Failed to upload diff-665a0833239e-onboarding-overlay-diff.png with gh image (exit code 1): Error uploading /home/runner/work/_temp/e2e-evidence/diff-665a0833239e-onboarding-overlay-diff.png: step 0 (get upload token): uploadToken not found on repo page — do you have write access to NousResearch/hermes-agent? (or, if NousResearch enforces SAML SSO, authorize at https://github.com/orgs/NousResearch/sso) |
…es + corpora Completes the four-platform ingress mirror (telegram/whatsapp landed in the prior commit). Layer model (documented in discord_parse.py): layer 1 (payload→SDK object — discord.py/Bolt) is the SDK-equivalence axiom, not oracled; layer 2 (SDK-view → MessageEvent fields — the Hermes-unique rules) is THE extracted, vectored spec; layer 3 (effects) stays adapter-side. - plugins/platforms/discord/discord_parse.py: SDK-view IR (DiscordMessageView, dual access: discord.py objects OR raw-vocabulary dicts) + pure rules — chat-type classification, <@id>/<@!id> mention stripping (strip THEN command-detect), forwarded-snapshot folding, referenced-attachment inheritance, attachment→type classification (voice-note vs audio via is_voice_message/duration+waveform), guild/forum thread naming. Adapter delegates: _is_discord_voice_message_ attachment, _format_thread_chat_name, and the _handle_message classification block. - plugins/platforms/slack/slack_parse.py: DM/MPIM classification (1:1 vs shared-surface MPIM), thread_ts session scoping (#15421/#15464 invariants incl. the thread_ts==ts root shape), mention detection, bot-message classification. Adapter delegates the DM-classification and channel-scoping blocks. - scripts/generate_ingress_vectors.py: +15 discord + 12 slack vectors (54 total across four platforms). - tests/conformance/test_ingress_vectors.py: +3 oracle-fidelity tests (adapter shim ≡ core on SDK-like objects) + scar-rule coverage; 18 total. Suites: conformance 18; discord/slack gateway suites green (the only failures in the -k 'discord or slack' sweep are pre-existing order-dependent pollution — reproduce identically with this diff stashed).
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.
Conformance oracle: ingress mirror — pure parse cores + vector generator (gateway side)
Gateway half of the ingress-mirror pair: NousResearch/gateway-gateway#181. Inbound twin of the egress generator (#71666, merged): synthetic platform payloads rendered through the native inbound PARSERS become the executable spec for the connector's normalizers.
The refactor (behavior-preserving, the enabler)
The native inbound parsers were not importable as pure functions —
_build_message_event(~7.6k chars, 6 self-deps) and_build_message_event_from_cloud(~11k chars, media/dedupe/dispatch state). This PR extracts the payload-derivable half of each into pure cores; the adapters delegate:plugins/platforms/telegram/telegram_parse.py— chat-type normalization, the routable-thread rules ([Bug]: Telegram DM sends fail with 'Message thread not found' — spurious thread_id from reply chains #3206 reply-anchor drop, fix(send_message): map Telegram General topic id to None for forum groups #22423 General-topic → "1"), reply context with native partial quotes ([Bug]: Telegram native partial quotes are expanded to the full replied-to message #22619), source identity incl. the channel-post author fallback. Dual access model: every accessor works on PTBMessageobjects (adapter's caller) AND raw Bot API dicts (generator's caller — no python-telegram-bot dependency needed). Adapter's_effective_message_thread_idbecomes a delegate shim; the reply-context inline block now calls the core, with the two stateful fallbacks (rich-message echo,rich_sent_store) staying adapter-side.gateway/platforms/whatsapp_cloud_parse.py— Cloud type→MessageType mapping, body extraction (incl. button/list titles), reply context (context.id+is_ownagainst the business number), media identification (id/mime/filename — download stays adapter-side), the group-shape discriminator. Adapter delegates all payload-derivable fields.Extraction honesty is machine-checked: oracle-fidelity tests drive the REAL adapter paths against the cores on every corpus payload (Telegram via PTB-style objects through the adapter shim; WhatsApp via the real
_build_message_event_from_cloudwith state stubbed) — if an adapter regains divergent inline logic, these fail.scripts/generate_ingress_vectors.py54 synthetic payloads (14 Telegram + 13 WhatsApp + 15 Discord + 12 Slack — every inbound scar rule has a named vector) → payload→expected-field JSON, oracle-SHA stamped, committed under
tests/conformance/ingress_vectors/. UPDATE (second commit): Discord + Slack cores now included. The layer model made them tractable:discord_parse.pydefines an SDK-view IR (DiscordMessageView, dual access — discord.py objects or raw-vocabulary dicts) over the ~18 fields layer 2 reads, with the pure rules (chat-type,<@id>/<@!id>mention stripping then command detection, forwarded-snapshot folding, referenced-attachment inheritance, voice-note vs audio classification, guild/forum thread naming);slack_parse.pyextracts DM/MPIM classification (1:1 vs shared-surface), the #15421/#15464 thread_ts session-scoping invariants, mention detection, and bot-message classification. Adapters delegate at the clean seams; 3 new oracle-fidelity tests pin shim ≡ core. Corpus now 54 vectors across four platforms; 18 conformance tests.tests/conformance/test_ingress_vectors.py(8 tests, three layers)Generator invariants (determinism, shape, unique ids) · oracle fidelity (core ≡ adapter) · committed-vectors lockstep (regenerate-or-fail, the openapi.json discipline) · scar-rule coverage assertions.
Impact downstream
The connector runner found two real gg bugs on day one (Telegram reply-anchor thread leak #3206; WhatsApp button/list taps arriving as empty text) — fixed in the paired PR.
Tests
pytest tests/conformance/15 passed ·test_whatsapp_cloud.py113 · topics/gating suites 117 ·tests/gateway/relay/266 — all green post-refactor. ruff + Windows-footguns clean.