hermes-agent/gateway
Teknium e4aeb65599 feat(webhook): per-route toolset overrides for webhook agent runs
Webhook agent runs default to the constrained hermes-webhook toolset
(web/vision/clarify) because payloads can carry untrusted third-party
content. That default is right for public webhooks but wrong for trusted
local pushes (e.g. an OOM monitor daemon that needs the agent to run
ps/free/py-spy): the only workaround was widening platform_toolsets.webhook,
which elevates EVERY webhook route at once.

This adds a 'toolsets' key on individual webhook route configs (static
routes in config.yaml and dynamic subscriptions in
webhook_subscriptions.json) that replaces the platform-level resolution
for that route only:

- BasePlatformAdapter.toolsets_for_source(): per-source override hook,
  default None (no behavior change for any other platform).
- WebhookAdapter.toolsets_for_source(): maps the session chat_id
  (webhook:{route}:{delivery_id}) back to its route config and returns
  the route's toolsets list.
- GatewayRunner._resolve_enabled_toolsets_for_source(): shared resolver
  used by both agent-run call sites; validates the override through the
  SAME _get_platform_tools path as platform config, so unknown names and
  platform-restricted toolsets (e.g. discord_admin) are dropped rather
  than trusted.

Deliberately NOT exposed via 'hermes webhook subscribe': granting elevated
tools is a manual config edit only, so an agent-created subscription
cannot self-grant terminal at runtime.

Cache-safe: the toolset list is resolved before agent construction and is
constant for a route, so the per-session agent signature and frozen system
prompt are unaffected mid-conversation.
2026-08-13 01:51:19 -07:00
..
assets
…
builtin_hooks
…
platforms feat(webhook): per-route toolset overrides for webhook agent runs 2026-08-13 01:51:19 -07:00
relay fix(relay): stamp logical platform + relay trust on Discord interaction events (#84318) 2026-08-12 17:04:02 +10:00
__init__.py
…
agent_cache_pressure.py
…
authz_mixin.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00
cgroup_cleanup.py
…
channel_directory.py fix(gateway): run channel-directory write off the event loop 2026-08-11 20:37:06 +05:30
code_skew.py
…
config.py feat(gateway): allow selective multiplex profile serving 2026-08-10 22:48:24 -07:00
cwd_placeholder.py
…
dead_targets.py
…
delivery.py
…
delivery_ledger.py
…
display_config.py
…
drain_control.py
…
hooks.py
…
kanban_watchers.py fix: complete kanban review lifecycle 2026-08-10 12:43:46 -07:00
lifecycle_ledger.py
…
memory_monitor.py
…
message_timestamps.py
…
mirror.py
…
pairing.py
…
platform_registry.py fix(plugins): isolate ownership by profile 2026-08-12 19:13:32 -07:00
profile_routing.py feat(gateway): allow selective multiplex profile serving 2026-08-10 22:48:24 -07:00
readiness.py
…
response_filters.py
…
restart.py
…
restart_loop_guard.py
…
rich_sent_store.py
…
run.py feat(webhook): per-route toolset overrides for webhook agent runs 2026-08-13 01:51:19 -07:00
runtime_footer.py
…
scale_to_zero.py fix(gateway): scale-to-zero gateway self-suspends via flaps socket instead of relying on Fly autostop (#84295) 2026-08-12 14:45:48 +10:00
session.py feat(gateway): allow plugins to inject session messages 2026-08-12 18:25:33 -07:00
session_context.py fix(gateway,relay): stop frozen-preview finals and dropped idle-session delegation callbacks (#82592) 2026-08-11 09:56:13 +10:00
session_stall.py
…
session_state.py
…
shutdown_flush.py
…
shutdown_forensics.py
…
shutdown_watchdog.py
…
slash_access.py
…
slash_commands.py fix(gateway): offload remaining atomic_json_write calls in async paths 2026-08-11 20:37:06 +05:30
status.py fix(gateway): classify terminal adapter connect failures + escalate long-lived retry loops (OOF-156) 2026-08-12 22:16:12 -07:00
status_phrases.py
…
sticker_cache.py
…
stream_consumer.py fix(gateway,relay): stop frozen-preview finals and dropped idle-session delegation callbacks (#82592) 2026-08-11 09:56:13 +10:00
stream_dispatch.py
…
stream_events.py
…
streaming_tts_consumer.py
…
systemd_notify.py
…
turn_context.py
…
turn_lease.py
…
wake.py
…
whatsapp_identity.py
…