Commit graph

8982 commits

Author SHA1 Message Date
Teknium
eacce70a35
docs: comprehensive 2-week sweep of feature/PR coverage gaps (#28497)
Catch the website docs up to two weeks of merged work (May 4 – May 18, 2026,
roughly 1,080 PRs). The audit found ~50 user-visible features that had landed
in code with no docs footprint, plus a handful of stale pages. This PR closes
every gap the scan turned up.

New pages
- user-guide/features/deliverable-mode.md — extension list, agent triggers,
  kanban_complete artifacts pattern, [[as_document]] override (PR #27813).
- developer-guide/web-search-provider-plugin.md — authoring guide modeled on
  image-gen-provider-plugin, covering brave_free / ddgs / etc. (PR #25448).

Providers / auth
- Rename "Alibaba Cloud" → "Qwen Cloud (Alibaba DashScope)" everywhere the
  display label shows up; provider id stays `alibaba` (PR #24835).
- Document OAuth refresh-token quarantine for xAI / MiniMax / Codex (PRs
  #28116 / #28118 / #28119).
- Document Nous JWT minting from refresh token + invalid-refresh quarantine
  + cross-profile shared token store (PRs #27663 / #19712).
- Add `## Microsoft Entra ID authentication (keyless)` section to
  azure-foundry guide — DefaultAzureCredential, RBAC, OpenAI + Anthropic
  routing details (PR #28101 / #9df9816da).
- Custom providers `api_mode` is now prompted-and-persisted, not just URL
  autodetected (PR #25068).
- Delegation honours `api_mode` + auto-detects anthropic_messages base URLs
  (PR #26824).
- `x_search` auto-enables when xAI credentials are present (PR #27376).
- Add `xAI Grok OAuth (SuperGrok)` row to providers headline table (PR
  #26534).
- NVIDIA NIM billing-origin header is set automatically (PR #26585).

Windows / installer
- `install.ps1`: document `-Commit <sha>` and `-Tag <v>` pin params plus
  the BOM-strip / git-retry hardening (PR #28169).
- Document Hermes Desktop thin installer + first-launch bootstrap (PR
  #27822).
- Document `dep_ensure` Windows bootstrap (PR #27845).
- Document install-method auto-detection (pip / git / homebrew / nixos) and
  the matching update command (PR #27843).

Gateway / messaging
- `/platform list|pause|resume` full description + circuit-breaker
  semantics (PR #26600).
- Slack / Matrix / Mattermost get parallel `allowed_channels` /
  `allowed_rooms` allowlist sections matching Telegram/Discord/DingTalk
  (PR #21251).
- Discord `allow_any_attachment` + `max_attachment_bytes` (config and env
  vars) (PR #27245).
- Discord clarify-choice button rendering (PR #25485).
- Telegram `guest_mode` @mention bypass for allowlisted groups (PR
  #22759).
- Telegram `notifications` mode (`important` vs `all`) (PR #22793).
- `[[as_document]]` skill / response directive for forcing
  document-style media delivery (PR #21210).

CLI / TUI
- `/new [name]` argument (PR #19637).
- `/subgoal` user-supplied criteria appended to `/goal` (PR #25449).
- `/exit --delete` flag confirmation prompts for destructive slash
  commands (PR #22687).
- Status-bar additions: ▶ N background indicator (PR #27175), context
  compression count (PR #21218), YOLO mode banner+statusbar warning (PR
  #26238).
- `display.timestamps` + `docker_extra_args` config keys (PR #23599).
- TUI collapsible startup banner sections (PR #20625).
- `HERMES_SESSION_ID` exported to tool subprocesses (PR #23847).

i18n
- Refresh display.language locale list from 8 → 16 (en, zh, zh-hant, ja,
  de, es, fr, tr, uk, af, ko, it, ga, pt, ru, hu) — matches
  `agent/i18n.py:SUPPORTED_LANGUAGES`.

Tools / features
- `vision_analyze` native-pixel passthrough for vision-capable callers,
  with auxiliary text-describer fallback (PR #22955).
- `session_search` rewrite to the single-shape tool (discovery / scroll /
  browse modes) (PRs #27590 / #27840).
- Clarify MCP transport scope: client supports stdio + SSE; embedded
  `hermes mcp serve` is stdio-only (PR #21227).
- Web search backends table: add Brave Search (free tier) and DDGS rows
  (PR #21337).
- ACP session-scoped edit auto-approval modes (PR #27862).
- Curator rename map in the user-visible per-run summary (PR #22910).
- Prompt caching feature page reference in features/overview.md — Claude
  cross-session 1-hour prefix cache on native Anthropic / OpenRouter /
  Nous Portal (PR #23828).
- Cron per-job profile parameter (PR #28124).
- `--no-skills` flag for `hermes profile create` (PR #20986).

Build
- Verified with `npm run build` in `website/`; both `en` and `zh-Hans`
  locales compile. Remaining broken-link/anchor warnings are pre-existing
  (`rl-training.md` from learning-path / overview; the
  zh-Hans translation lag the docs skill already calls out).
2026-05-18 23:55:25 -07:00
Siddharth Balyan
1335ce996d
fix(web): add scheduled column to i18n type definitions (#28549)
columnLabels and columnHelp in en.ts include a scheduled entry but the
Translations interface in types.ts did not declare it, causing a
TypeScript build failure in the Nix derivation. Made the field optional
since only en.ts provides it currently.
2026-05-19 11:47:24 +05:30
Teknium
69b1d31a19 chore(release): map @alber70g for PR #25280 salvage 2026-05-18 22:59:40 -07:00
Albert G
ad2531be08 feat(telegram): skip-STT audio path + 2GB cap via local Bot API server
Two coordinated changes that unblock downstream audio pipelines
(diarization, custom transcription, archival) on attachments larger
than the public Bot API's 20MB getFile ceiling.

- `stt.enabled: false` no longer drops voice/audio with a generic
  "transcription disabled" note. The gateway probes the cached file's
  duration (wave → mutagen → ffprobe ladder) and surfaces
  `[The user sent a voice message: <abs path> (duration: M:SS)]` to
  the agent so a skill or tool can pick up the raw file. The previous
  placeholder is replaced rather than appended when present.

- `platforms.telegram.extra.base_url` set → adapter auto-lifts its
  document size cap from 20MB to 2GB (the local telegram-bot-api
  `--local` ceiling) and the "too large" reply reports the active
  limit dynamically. No new config knob; presence of `base_url` is the
  opt-in.

- `platforms.telegram.extra.local_mode: true` wires
  `Application.builder().local_mode(True)` on the python-telegram-bot
  builder. PTB then reads files from disk instead of HTTP, which is
  required when telegram-bot-api runs in `--local` mode (the server
  returns absolute filesystem paths, not `/file/bot...` URLs).

- gateway/run.py: rewrites the `stt.enabled: false` branch of
  `_enrich_message_with_transcription`. New `_format_duration` +
  `_probe_audio_duration` helpers.
- gateway/platforms/telegram.py: `_max_doc_bytes` instance attribute
  derived from `extra.base_url`; `local_mode` builder wiring;
  dynamic "too large" message.
- tests/gateway/test_stt_config.py: covers path-surfacing with and
  without an existing user message, and placeholder replacement.
- tests/gateway/test_telegram_max_doc_bytes.py: 3 cases — default 20MB
  without base_url, 2GB when set, empty-string base_url keeps default.
- website/docs/user-guide/messaging/telegram.md: new "Skipping STT"
  subsection under Voice Messages and a full "Large Files (>20MB) via
  Local Bot API Server" walkthrough (api_id/api_hash, docker-compose,
  one-time `logOut` migration, `platforms.telegram.extra` config, the
  `local_mode` disk-access requirement, the silent HTTP-fallback 404).
- website/docs/user-guide/features/voice-mode.md: documents the
  `stt.enabled` knob in the config reference.

- `pytest tests/gateway/test_telegram_max_doc_bytes.py
  tests/gateway/test_stt_config.py` → 9/9 passing.
- Verified end-to-end on a live deployment: gateway log shows
  `Using custom Telegram base_url: http://...` and
  `Using Telegram local_mode (read files from disk)` on startup;
  voice messages above 20MB cache to disk and surface their path to
  the agent.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-18 22:59:40 -07:00
Teknium
6265b3a132 chore(release): map @indigokarasu for PR #26636 salvage 2026-05-18 22:57:55 -07:00
Indigo Karasu
a724c3b9cf feat(telegram): pin incoming user message for duration of agent turn
When a user sends a message on Telegram, the incoming message is now
automatically pinned at the start of processing and unpinned when the
agent finishes its turn. This gives the user a visual indicator that
their message is being worked on, and keeps the conversation anchored.

Changes:
- telegram.py: Added pinChatMessage in on_processing_start and
  unpinChatMessage in on_processing_complete. Restructured both
  hooks so pin/unpin runs independently of the reactions feature
  (reactions are optional; pinning is always on).
- telegram.py: Pass message_id through SessionSource so it's
  available in the session context.
- session_context.py: Added HERMES_SESSION_MESSAGE_ID context var.
- run.py: Pass source.message_id through set_session_vars.

Pinning is silent (disable_notification=True) and failures are
logged at debug level without interrupting message processing.
Only the user's incoming message is pinned -- never the agent's
replies. Auto-resume events (which have no message_id) are
correctly skipped.
2026-05-18 22:57:55 -07:00
Teknium
ce46e6bf08 chore(release): map @ai-hana-ai for PR #23928 salvage 2026-05-18 22:56:22 -07:00
ai-hana-ai
6d66ad2aca docs(telegram): document ignore_root_dm feature 2026-05-18 22:56:22 -07:00
ai-hana-ai
c931dad1d9 feat(telegram): ignore_root_dm with system command lobby 2026-05-18 22:56:22 -07:00
Teknium
da48be1abf chore(release): map @OCWC22 for PR #24581 salvage 2026-05-18 22:54:15 -07:00
William Chen
fbfe294882 fix: ignore Telegram messages for other bots 2026-05-18 22:54:15 -07:00
William Chen
e90869e887 Document Telegram multi-profile gateway commands 2026-05-18 22:54:15 -07:00
William Chen
ce4d857021 Route Telegram multi-bot mentions exclusively 2026-05-18 22:54:15 -07:00
Teknium
bb8e9ea83a chore(release): map oracle@jarviss-mbp.home for PR #24014 salvage 2026-05-18 22:53:01 -07:00
Bob Yang
8a80eee02d Quiet noisy Telegram gateway errors 2026-05-18 22:53:01 -07:00
Teknium
f1cefad8c2 test+release: stub auth in channel_posts fixture; map @brndnsvr 2026-05-18 22:51:35 -07:00
Brandon Seaver
84a9b81502 test: address telegram channel post review 2026-05-18 22:51:35 -07:00
Brandon Seaver
704872a62f fix(telegram): handle channel post updates 2026-05-18 22:51:35 -07:00
Teknium
17b8121e29 chore(release): map @stevehq26-bot for PR #28015 salvage 2026-05-18 22:48:42 -07:00
stevehq26-bot
b1acf80e17 feat(telegram): support quick-command-only menus 2026-05-18 22:48:42 -07:00
Teknium
e80d3084e5 chore(release): map @khungate for PR #25829 salvage 2026-05-18 22:45:58 -07:00
khungate
1891bee9d3 fix(telegram): wire gt: callback dispatch for gmail-triage buttons
The gmail-triage skill's Telegram inline buttons emit callback_data of the
form `gt:<verb>:<arg>`, but `_handle_callback_query` had no `gt:` branch —
taps fell through silently and the spinner sat there until Telegram timed it
out.

Add `_handle_gmail_triage_callback`, dispatched from the existing callback
router, that:

- Authorizes the caller via the same `_is_callback_user_authorized` path as
  the approval / slash-confirm / clarify handlers.
- Maps each verb to a script under `~/.hermes/scripts/gmail-triage/` and runs
  it async with a 60s timeout.
- Splits verbs into one-shots (send / archive / draft / spam) — append the
  confirmation and strip the keyboard so the action can't fire twice — and
  sticky-state changes (mute / trust / vip ± -domain) — append the
  confirmation but leave the keyboard tappable so the user can stack actions
  on one email.
- On failure: toast only, keyboard preserved so the user can retry.
- Logs every callback outcome to gateway.log for debugging.
2026-05-18 22:45:58 -07:00
Teknium
4f6fef1974 chore(release): map @el-analista for PR #25368 salvage 2026-05-18 22:45:05 -07:00
analista
d81b888807 fix(telegram): report cron topic fallback 2026-05-18 22:45:05 -07:00
fonhal
16d8e44f7a fix(telegram): add DM topic typing fallback when message_thread_id rejected
When a DM topic lane's message_thread_id is rejected by Telegram
(e.g. stale or deleted topic), send_typing now falls back to sending
the typing indicator without thread_id so it at least appears in the
main DM view, rather than being silently swallowed.

Also adds test for the fallback behavior.
2026-05-18 22:43:46 -07:00
Teknium
15e89e1dcb chore(release): map @soynchux for PR #27806 salvage 2026-05-18 22:43:14 -07:00
soynchux
b38140eb8f fix(gateway): allow chat-scoped telegram auth without sender user_id 2026-05-18 22:43:14 -07:00
Teknium
721d47f439 chore(release): map @jackjin1997 for PR #27239 salvage 2026-05-18 22:42:28 -07:00
JackJin
95a0955e19 fix(gateway): restore Telegram DM topic thread_id after session split (#27166)
When context compression triggers a mid-turn session split, source.thread_id
can be None on synthetic/recovered events. _thread_metadata_for_source then
returns None, causing the Telegram adapter to send with no message_thread_id
and the response lands in the General thread instead of the active DM topic.

Fix:
- hermes_state.py: Add get_telegram_topic_binding_by_session() for reverse
  lookup by session_id (enabled by the existing UNIQUE INDEX on session_id).
- gateway/run.py: After session-split detection, if source is a Telegram DM
  and source.thread_id is None, recover it from the binding via the new
  method so _thread_metadata_for_source produces the correct thread routing.
- tests/: Coverage for the new lookup method and the recovery flow.
2026-05-18 22:42:28 -07:00
Teknium
5734c3fb10 chore(release): map @B0Tch1 for PR #27634 salvage 2026-05-18 22:40:44 -07:00
B0Tch1
9d789f3a5b feat(telegram): add disable_topic_auto_rename gateway flag
When Hermes auto-titles a session in a Telegram DM topic it currently
renames the topic itself to the generated title. That works for
operator-managed lanes (extra.dm_topics) but is disruptive for
ad-hoc Threaded-Mode topics that users name by hand — every first
exchange overwrites their chosen title.

Add gateway.platforms.telegram.extra.disable_topic_auto_rename (default
False, preserving prior behaviour). When set, both
_schedule_telegram_topic_title_rename and the underlying
_rename_telegram_topic_for_session_title short-circuit before touching
the Telegram API. Internal session titles (sessions list, TUI) keep
working unchanged.

Also bridge the legacy top-level telegram.disable_topic_auto_rename key
through to gateway.platforms.telegram.extra so users on the older
config layout don't have to migrate to enable it.

- Tests cover the runtime flag, the scheduling entry-point, and string
  truthiness coercion for YAML-loaded values.
- Docs updated in messaging/telegram.md with an example block.
2026-05-18 22:40:44 -07:00
Maxim Esipov
3ec28f34ca fix(telegram): preserve topic metadata on overflow edits 2026-05-18 22:40:03 -07:00
Teknium
c66efcff32 chore(release): map @rak135 for PR #25960 salvage 2026-05-18 22:38:08 -07:00
Martin
417a653d9e fix(gateway): prevent Windows Telegram /restart leaving gateway stopped 2026-05-18 22:38:08 -07:00
Teknium
1d378605dd test+release: stub auth in test_telegram_documents fixture; map @kiranvk-2011 2026-05-18 22:37:28 -07:00
kiranvk2011
77c4675a50 fix(telegram): route image documents (.png/.jpg/.webp/.gif) through vision pipeline
When users send images as documents (Telegram file picker), they were
rejected with "Unsupported document type" because SUPPORTED_DOCUMENT_TYPES
only includes text/office formats. Add SUPPORTED_IMAGE_DOCUMENT_TYPES
to base.py and handle them in telegram.py before the document check.

- Add SUPPORTED_IMAGE_DOCUMENT_TYPES constant to base.py
- Add MIME reverse-lookup for image types in telegram.py
- Route image documents through cache_image_from_bytes + vision pipeline
- Handle media groups for image documents

Closes: #20128, #18620
2026-05-18 22:37:28 -07:00
konsisumer
a4fb0a3ac3 fix(cron): route Telegram cron deliveries to a dedicated topic via TELEGRAM_CRON_THREAD_ID
When Telegram topic mode is enabled, cron messages delivered to the bot's
root DM (TELEGRAM_HOME_CHANNEL without a thread id) land in the system
lobby — replies there are rebuffed with the lobby reminder and
reply_to_message_id is dropped, so users cannot interact with the cron
output (#24409).

Add an optional TELEGRAM_CRON_THREAD_ID env var that overrides
TELEGRAM_HOME_CHANNEL_THREAD_ID for cron deliveries only. Operators can
create a "Cron" forum topic in the DM, point this var at its thread id,
and replies to cron messages will land in that topic's existing session
instead of the lobby. The home-channel thread id (used elsewhere, e.g.
restart notifications) is unchanged, and explicit
deliver="telegram:chat:thread" targets continue to win over the env var.

Per the reporter's clarification on 2026-05-13, option (a) (cron-side
route to a dedicated topic + config knob) was chosen.

Fixes #24409
2026-05-18 22:36:11 -07:00
Teknium
032d4cafc4 chore(release): map @booker1207 for PR #25132 salvage 2026-05-18 22:35:28 -07:00
Booker
46ce3453c1 fix(telegram): gate profile bots by allowed topics 2026-05-18 22:35:28 -07:00
Teknium
efc37409aa test+release: fix test fixture for forum_commands; map @chromalinx 2026-05-18 22:34:48 -07:00
Dani
7682198178 fix(gateway): register Telegram commands for groups
Register Telegram bot commands across default, private, and group scopes so
the slash-command menu is available outside DMs.

Changes from review feedback:
- Add asyncio.Lock to prevent race condition in _ensure_forum_commands
- Extract MAX_COMMANDS_PER_SCOPE constant (30) to avoid magic number
- Upgrade error logging from debug->warning in forum registration
- Add tests covering lazy forum registration and concurrent safety
- Remove /start handler from this PR (separate feature)

Fixes review: needs_work (race, magic number, log levels, missing tests)
2026-05-18 22:34:48 -07:00
Teknium
38356cc98b chore(release): map @kunci115 for PR #27098 salvage 2026-05-18 22:32:00 -07:00
kunci115
4abaec18b8 test(send_message): add thread-not-found retry tests for Telegram topics
Three tests covering the #27012 fix:
- test_is_thread_not_found_matches_expected_errors
- test_text_send_retries_without_thread_id_on_thread_not_found
- test_disable_web_page_preview_not_leaked_to_media_sends

116/116 existing tests still pass (no regressions).
2026-05-18 22:32:00 -07:00
kunci115
2bb04f6842 test(send_message): add thread-not-found retry tests for Telegram forum topics
Adds two tests to TestSendTelegramThreadIdMapping:
- test_thread_not_found_retries_without_message_thread_id
- test_thread_not_found_for_media_retries_without_message_thread_id

Refs #27012
2026-05-18 22:32:00 -07:00
kunci115
df530b4a0c fix(send_message): add thread-not-found retry for Telegram forum topic sends
The standalone _send_telegram path in send_message_tool lacked the
thread-not-found fallback that the gateway adapter has. When a forum
topic thread_id was stale or deleted, the send would fail entirely
instead of retrying to the General topic.

Changes:
- Add _is_telegram_thread_not_found() helper matching gateway adapter
- Add thread-not-found retry in text send path
- Add thread-not-found retry in media send path (with f.seek(0))
- Separate text_kwargs from thread_kwargs to prevent
  disable_web_page_preview leaking into send_photo/send_video calls

Closes #27012
2026-05-18 22:32:00 -07:00
Teknium
fc42bb918b chore(release): map @karthikeyann for PR #26609 salvage 2026-05-18 22:30:28 -07:00
karthikeyann
ede47a54be fix(gateway): pin Telegram DM-topic routing to user's current topic
Topic-mode DM replies were fragmenting one conversation across many sessions: a Reply on a message in another topic delivered Telegram's message_thread_id for *that* topic, and #3206's strip routed plain replies to the lobby. Both pulled the user away from their current session. Fix: when topic mode is on, rewrite source.thread_id to the user's most-recent binding if the inbound id is missing/General or not a known topic. Non-topic-mode users unchanged.
2026-05-18 22:30:28 -07:00
Teknium
470edfa901 chore(release): map @aqilaziz for PR #26406 salvage 2026-05-18 22:29:45 -07:00
aqilaziz
ed9087fce7 fix(tts): keep native audio outside Telegram voice delivery 2026-05-18 22:29:45 -07:00
Teknium
e19f4c1730 chore(release): map @samahn0601 for PR #27887 salvage 2026-05-18 22:29:03 -07:00