@inline-chat/hermes-agent-adapter 0.0.21 → 0.0.22-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -51,6 +51,18 @@ Unsupported or intentionally limited:
51
51
  - Live voice sessions or calls. Voice file messages are supported, but realtime audio is not.
52
52
  - Media without a usable Inline CDN/local URL. Those messages still produce text summaries, but Hermes may not receive a local file path.
53
53
 
54
+ ## Alpha 0.0.22-alpha.0
55
+
56
+ This prerelease includes typed service-notice filtering before agent admission,
57
+ current shared-session setup guidance, and the pinned realtime SDK `0.0.18`.
58
+ Hermes keeps its supported agent activity surface; unsupported experimental tool
59
+ timelines remain disabled.
60
+
61
+ ```sh
62
+ npm install -g @inline-chat/hermes-agent-adapter@0.0.22-alpha.0
63
+ inline-hermes install --force
64
+ ```
65
+
54
66
  ## Install
55
67
 
56
68
  ```sh
@@ -254,26 +266,14 @@ platforms:
254
266
  enabled: true
255
267
  ```
256
268
 
257
- Inline follows Hermes' native work-chat defaults: show typing/presence while a
258
- turn is running, keep tool-call progress out of the room by default, and keep
259
- edit-based token streaming opt-in. If an older Hermes config has global
260
- `display.tool_progress: all`, add the per-platform override below so terminal
261
- and tool progress bubbles are not left in Inline chats:
269
+ Experimental tool timelines are unavailable in this adapter. The old
270
+ `INLINE_EXPERIMENTAL_AGENT_ACTIVITY` setting is ignored and logs a warning when
271
+ enabled. Hermes uses ordinary typing, optional processing reactions, and replies.
262
272
 
263
- ```yaml
264
- display:
265
- platforms:
266
- inline:
267
- tool_progress: off
268
- cleanup_progress: true
269
- streaming: false
270
- interim_assistant_messages: false
271
- ```
272
-
273
- To temporarily show live tool progress, set `tool_progress: new` or
274
- `tool_progress: all` and leave `cleanup_progress: true` so Hermes deletes the
275
- progress message after a successful final reply. Token streaming requires both
276
- top-level `streaming.enabled: true` and
273
+ Inline keeps tool progress and interim assistant messages quiet by default.
274
+ Explicit Hermes display settings still take precedence; if you enable native
275
+ tool progress, Hermes uses its ordinary progress messages. Token streaming remains
276
+ opt-in through both `streaming.enabled: true` and
277
277
  `display.platforms.inline.streaming: true`.
278
278
 
279
279
  Hermes-native sends and scheduled deliveries accept Inline's explicit target
@@ -436,6 +436,30 @@ the normal reply.
436
436
  The plugin id is `inline`, which is intentionally the same id an eventual
437
437
  bundled Hermes adapter should use.
438
438
 
439
+ ## Shared transcripts in groups and threads
440
+
441
+ To share one conversation transcript among admitted participants in a group
442
+ or thread, add these keys at the root of the `config.yaml` used by the Hermes
443
+ gateway process, outside `platforms.inline.extra`:
444
+
445
+ ```yaml
446
+ group_sessions_per_user: false
447
+ thread_sessions_per_user: false
448
+ ```
449
+
450
+ Hermes defaults `group_sessions_per_user` to `true` (groups split by sender)
451
+ and `thread_sessions_per_user` to `false` (threads shared). These settings
452
+ affect every messaging platform governed by that gateway configuration.
453
+ For separate profile gateways, configure each gateway's profile separately.
454
+ With a multiplexed gateway, do not assume a secondary profile's values control
455
+ its sessions; this adapter does not qualify per-profile session-policy overrides.
456
+
457
+ Distinct Hermes profile/gateway namespaces keep separate conversation sessions.
458
+ Swapping a bot token within one profile does not create a new transcript namespace.
459
+ These flags select shared sessions; they do not merge existing histories, import
460
+ all Inline history, grant permissions, or change access, mention, or bot wake rules.
461
+ Restart the gateway through its existing process manager after editing.
462
+
439
463
  ## Error Reporting And Privacy
440
464
 
441
465
  The Inline adapter and its supervised sidecar keep error reporting disabled
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inline-chat/hermes-agent-adapter",
3
- "version": "0.0.21",
3
+ "version": "0.0.22-alpha.0",
4
4
  "description": "Hermes Agent platform adapter for Inline, with a native Python plugin and bundled Inline realtime sidecar.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -230,11 +230,12 @@ def _install_inline_display_defaults() -> None:
230
230
  defaults = getattr(_display_config, "_PLATFORM_DEFAULTS", None)
231
231
  if not isinstance(defaults, dict):
232
232
  return
233
+ inline_defaults = dict(_INLINE_DISPLAY_DEFAULTS)
233
234
  current = defaults.get("inline")
234
235
  if isinstance(current, dict):
235
- defaults["inline"] = {**_INLINE_DISPLAY_DEFAULTS, **current}
236
+ defaults["inline"] = {**inline_defaults, **current}
236
237
  else:
237
- defaults["inline"] = dict(_INLINE_DISPLAY_DEFAULTS)
238
+ defaults["inline"] = inline_defaults
238
239
  except Exception:
239
240
  logger.debug("[inline] failed to install display defaults", exc_info=True)
240
241
 
@@ -812,6 +813,8 @@ class InlineAdapter(BasePlatformAdapter):
812
813
  super().__init__(config, Platform("inline"))
813
814
  extra = config.extra or {}
814
815
 
816
+ if _truthy(os.getenv("INLINE_EXPERIMENTAL_AGENT_ACTIVITY")):
817
+ logger.warning("[inline] experimental tool timelines are unavailable; ignoring INLINE_EXPERIMENTAL_AGENT_ACTIVITY and using ordinary typing")
815
818
  self._token = _config_token(config)
816
819
  self._base_url = os.getenv("INLINE_BASE_URL") or extra.get("base_url") or "https://api.inline.chat"
817
820
  self._sidecar_bind = _normalize_sidecar_bind(extra.get("sidecar_bind") or os.getenv("INLINE_SIDECAR_BIND"))
@@ -2444,7 +2447,14 @@ class InlineAdapter(BasePlatformAdapter):
2444
2447
 
2445
2448
  async def _dispatch_message(self, event: Dict[str, Any], *, edit: bool = False) -> None:
2446
2449
  agent_action = event.get("_inlineAgentAction") if isinstance(event.get("_inlineAgentAction"), dict) else None
2447
- msg = event.get("message") or {}
2450
+ msg = event.get("message")
2451
+ if not isinstance(msg, dict):
2452
+ return
2453
+ # History/join recovery and older sidecars can reach this entry directly.
2454
+ # Service fallback text and mentions are never conversational direction.
2455
+ raw = msg.get("raw") if isinstance(msg.get("raw"), dict) else {}
2456
+ if isinstance(msg.get("serviceMessage"), dict) or isinstance(raw.get("serviceMessage"), dict):
2457
+ return
2448
2458
  msg_id = str(msg.get("id") or "")
2449
2459
  chat_id = str(event.get("chatId") or msg.get("chatId") or "")
2450
2460
  if not msg_id or not chat_id:
@@ -27,7 +27,7 @@ _CLI_INSTALL_URL = "https://inline.chat/cli/install.sh"
27
27
  _MAX_TOKEN_BYTES = 16 * 1024
28
28
  _MAX_PROBE_RESPONSE_BYTES = 64 * 1024
29
29
  _MACHINE_SETUP_PROTOCOL_VERSION = 1
30
- _PROBE_USER_AGENT = "inline-hermes-agent-adapter/0.0.21"
30
+ _PROBE_USER_AGENT = "inline-hermes-agent-adapter/0.0.22-alpha.0"
31
31
  _ENV_REFERENCE_RE = re.compile(r"^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$")
32
32
 
33
33
 
@@ -3,7 +3,7 @@ label: Inline
3
3
  kind: platform
4
4
  provides_tools:
5
5
  - inline
6
- version: 0.0.21
6
+ version: 0.0.22-alpha.0
7
7
  requires_hermes: ">=0.21.3"
8
8
  description: >
9
9
  Inline platform adapter for Hermes Agent. The adapter runs as a native
@@ -5702,6 +5702,13 @@ var botSettingsEventKinds = new Set([
5702
5702
  function inboundEventNeedsSenderResolution(event) {
5703
5703
  return !botSettingsEventKinds.has(event.kind ?? "");
5704
5704
  }
5705
+ function inboundEventIsServiceMessage(event) {
5706
+ if (event.kind !== "message.new" && event.kind !== "message.edit")
5707
+ return false;
5708
+ const message = asOptionalRecord(event.message);
5709
+ const raw = asOptionalRecord(message?.raw);
5710
+ return Boolean(asOptionalRecord(message?.serviceMessage) || asOptionalRecord(raw?.serviceMessage));
5711
+ }
5705
5712
 
5706
5713
  class SidecarError extends Error {
5707
5714
  errorKind;
@@ -5823,6 +5830,7 @@ function normalizeMessage(message) {
5823
5830
  replies: message.replies ?? null,
5824
5831
  actions: message.actions ?? null,
5825
5832
  rev: message.rev ?? null,
5833
+ ...asOptionalRecord(message.serviceMessage) ? { serviceMessage: message.serviceMessage } : {},
5826
5834
  raw: message
5827
5835
  };
5828
5836
  }
@@ -6021,6 +6029,8 @@ function explicitlyMentionsSelf(event, meId) {
6021
6029
  return message?.entities?.entities?.some((e) => e.entity?.oneofKind === "mention" && e.entity.mention?.userId?.toString() === meId) ?? false;
6022
6030
  }
6023
6031
  async function deliverInboundEvent(event, owner) {
6032
+ if (inboundEventIsServiceMessage(event))
6033
+ return;
6024
6034
  const explicitMention = explicitlyMentionsSelf(event, owner.meId);
6025
6035
  while (!owner.signal.aborted) {
6026
6036
  const resolution = explicitMention ? { provenanceVerified: false } : inboundEventNeedsSenderResolution(event) ? await owner.resolveSender(event) : { provenanceVerified: true };