@inline-chat/hermes-agent-adapter 1.0.0 → 1.0.1

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
@@ -60,7 +60,9 @@ one thread per conversation. Each Hermes 0.22 profile keeps its own bot, state
60
60
  and sidecar. Agents can follow, unfollow and manage chats, and they show Working
61
61
  while they work. Status and doctor report whether messages reach the agent. See
62
62
  "Upgrading to 1.0" in the [Hermes docs](https://inline.chat/docs/hermes) for every
63
- change. Pinned realtime SDK `0.0.20`.
63
+ change. Hermes `0.22.6` and later need `1.0.0`: they refuse every message from
64
+ earlier adapters with "Hermes refused this message (invalid_params)". Pinned
65
+ realtime SDK `0.0.20`.
64
66
 
65
67
  ```sh
66
68
  npm install -g @inline-chat/hermes-agent-adapter@1.0.0
@@ -195,10 +197,11 @@ mismatch, rerun the same command after rebuilding or upgrading the package.
195
197
 
196
198
  - Hermes Agent: requires the external user plugin registry and native platform
197
199
  plugin loader available in Hermes Agent `>=0.21.3`. This package was validated
198
- against Hermes Agent `0.22.5` from source commit `bf0203a794a07aac3ff764972ab9087baa4e4f4e` (tag
199
- `v0.22.5`), and installs on the minimum `0.21.3`.
200
+ against Hermes Agent `0.22.7` from source commit `b200f5bc60e31588ba2cb60e288029c4a54ba5fa` (tag
201
+ `v0.22.7`), and installs on the minimum `0.21.3`. Hermes `0.22.6` and later refuse
202
+ every message from adapters before `1.0.0`; upgrade as in Release 1.0.0 above.
200
203
  - CI checks the minimum supported Hermes release, newest stable source, and upstream
201
- `main`. A six-hour scheduled check also tests the published npm `latest` adapter.
204
+ `main`, including a full inbound turn through Hermes' production gateway. A six-hour scheduled check also tests the published npm `latest` adapter.
202
205
  `inline-hermes doctor` requires successful host loading and compatibility validation;
203
206
  unavailable Hermes diagnostics no longer count as healthy.
204
207
  - Node.js: `>=20` is required for the bundled sidecar. Hermes-managed Node 22,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inline-chat/hermes-agent-adapter",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
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",
@@ -91,12 +91,12 @@
91
91
  },
92
92
  "machineSetupProtocol": 1,
93
93
  "minHermesVersion": "0.21.3",
94
- "testedHermesVersion": "0.22.5",
95
- "testedHermesCommit": "bf0203a794a07aac3ff764972ab9087baa4e4f4e"
94
+ "testedHermesVersion": "0.22.7",
95
+ "testedHermesCommit": "b200f5bc60e31588ba2cb60e288029c4a54ba5fa"
96
96
  },
97
- "gitHead": "16c59df96eba4c530270ca1e093ef5fd22d7bd98",
97
+ "gitHead": "ec95e9296b83c13d2179b47019d915b16783c186",
98
98
  "inlineRelease": {
99
- "tag": "hermes-agent-v1.0.0",
100
- "sha": "16c59df96eba4c530270ca1e093ef5fd22d7bd98"
99
+ "tag": "hermes-agent-v1.0.1",
100
+ "sha": "ec95e9296b83c13d2179b47019d915b16783c186"
101
101
  }
102
102
  }
@@ -206,11 +206,42 @@ def _truthy(value: Any, default: bool = False) -> bool:
206
206
  return str(value).strip().lower() in {"1", "true", "yes", "on"}
207
207
 
208
208
 
209
+ _UNAVAILABLE_HERMES_SEAMS: set[str] = set()
210
+
211
+
212
+ def _hermes_seam_unavailable(seam: str, effect: str, exc: Optional[BaseException] = None) -> None:
213
+ """Warn once per process that an undocumented Hermes internal is missing or changed.
214
+
215
+ Hermes documents no public API for these seams yet; the Inline repo tracks them in
216
+ plugins/hermes-agent/docs/hermes-upstream-seams.md.
217
+ Callers degrade the one feature that needs the seam; message delivery never depends on one.
218
+ """
219
+ if seam in _UNAVAILABLE_HERMES_SEAMS:
220
+ return
221
+ _UNAVAILABLE_HERMES_SEAMS.add(seam)
222
+ reason = f"{type(exc).__name__}: {exc}" if exc is not None else "missing"
223
+ logger.warning("[inline] Hermes internal %s is unavailable (%s); %s", seam, reason, effect)
224
+
225
+
226
+ def _display_registration_fields() -> Dict[str, Any]:
227
+ """Inline's display defaults through the public PlatformEntry fields, when the host has them."""
228
+ try:
229
+ from gateway.platform_registry import PlatformEntry
230
+
231
+ fields = getattr(PlatformEntry, "__dataclass_fields__", {})
232
+ if {"display_tier", "display_overrides"}.issubset(fields):
233
+ # The overrides cover every key a tier sets, so the tier only names the closest base.
234
+ return {"display_tier": "low", "display_overrides": dict(_INLINE_DISPLAY_DEFAULTS)}
235
+ except Exception:
236
+ logger.debug("[inline] Hermes display registration fields are unavailable", exc_info=True)
237
+ return {}
238
+
239
+
209
240
  def _install_inline_display_defaults() -> None:
210
- """Register Slack-like display defaults for Inline when Hermes exposes them.
241
+ """Seed Inline's display defaults on hosts that predate PlatformEntry.display_overrides.
211
242
 
212
- Hermes core owns display resolution. External plugins do not yet have a
213
- first-class display-default hook, so we seed the same private table core
243
+ Newer hosts take the same defaults from ``ctx.register_platform`` (see
244
+ ``_display_registration_fields``); only older ones need the private table core
214
245
  platforms use. User config still wins over these defaults.
215
246
  """
216
247
  try:
@@ -218,6 +249,10 @@ def _install_inline_display_defaults() -> None:
218
249
 
219
250
  defaults = getattr(_display_config, "_PLATFORM_DEFAULTS", None)
220
251
  if not isinstance(defaults, dict):
252
+ _hermes_seam_unavailable(
253
+ "gateway.display_config._PLATFORM_DEFAULTS",
254
+ "Inline uses Hermes' generic display defaults (tool progress may be shown)",
255
+ )
221
256
  return
222
257
  inline_defaults = dict(_INLINE_DISPLAY_DEFAULTS)
223
258
  current = defaults.get("inline")
@@ -225,8 +260,12 @@ def _install_inline_display_defaults() -> None:
225
260
  defaults["inline"] = {**inline_defaults, **current}
226
261
  else:
227
262
  defaults["inline"] = inline_defaults
228
- except Exception:
229
- logger.debug("[inline] failed to install display defaults", exc_info=True)
263
+ except Exception as exc:
264
+ _hermes_seam_unavailable(
265
+ "gateway.display_config._PLATFORM_DEFAULTS",
266
+ "Inline uses Hermes' generic display defaults (tool progress may be shown)",
267
+ exc,
268
+ )
230
269
 
231
270
 
232
271
  def _reply_thread_mode(value: Any, default: str = "auto") -> str:
@@ -570,7 +609,12 @@ def _normalize_inline_plugin_command_text(text: str) -> str:
570
609
  from hermes_cli.plugins import get_plugin_commands
571
610
  if command not in (get_plugin_commands() or {}):
572
611
  return text
573
- except Exception:
612
+ except Exception as exc:
613
+ _hermes_seam_unavailable(
614
+ "hermes_cli.plugins.get_plugin_commands",
615
+ "hyphenated plugin commands must be typed with hyphens in Inline",
616
+ exc,
617
+ )
574
618
  return text
575
619
  # Inline menus require underscores, while Hermes registers plugin commands
576
620
  # with hyphens. Normalize before gateway access checks as well as dispatch.
@@ -585,16 +629,30 @@ def _normalize_inline_command_description(raw: str) -> str:
585
629
  return description
586
630
 
587
631
 
588
- def _inline_menu_commands(max_commands: int = _INLINE_COMMAND_LIMIT) -> tuple[List[Dict[str, Any]], int]:
589
- from hermes_cli.commands_platforms import telegram_menu_commands
632
+ def _hermes_menu_commands(max_commands: int) -> tuple[list, int]:
633
+ """Hermes' gateway command menu; empty when the host no longer exposes it."""
634
+ try:
635
+ from hermes_cli.commands_platforms import telegram_menu_commands
590
636
 
637
+ menu_commands, hidden_count = telegram_menu_commands(max_commands=max_commands)
638
+ return list(menu_commands or []), int(hidden_count or 0)
639
+ except Exception as exc:
640
+ _hermes_seam_unavailable(
641
+ "hermes_cli.commands_platforms.telegram_menu_commands",
642
+ "the Inline command menu lists only Inline's own commands",
643
+ exc,
644
+ )
645
+ return [], 0
646
+
647
+
648
+ def _inline_menu_commands(max_commands: int = _INLINE_COMMAND_LIMIT) -> tuple[List[Dict[str, Any]], int]:
591
649
  command_specs = _inline_command_specs()
592
650
  local_commands = [
593
651
  (spec.name, spec.description)
594
652
  for spec in command_specs[:max(0, max_commands)]
595
653
  ]
596
654
  remaining = max(0, max_commands - len(local_commands))
597
- menu_commands, hidden_count = telegram_menu_commands(max_commands=remaining)
655
+ menu_commands, hidden_count = _hermes_menu_commands(remaining)
598
656
  commands: List[Dict[str, Any]] = []
599
657
  seen: set[str] = set()
600
658
  skipped = 0
@@ -620,11 +678,15 @@ def _inline_menu_commands(max_commands: int = _INLINE_COMMAND_LIMIT) -> tuple[Li
620
678
 
621
679
  def _inline_skill_catalog() -> List[Dict[str, Any]]:
622
680
  """Return installed, enabled Hermes skills in the Bot API catalog shape."""
623
- import tools.skills_tool as skills_tool
624
-
625
- # Hermes 0.22.5 made these public; older supported hosts keep the private names.
626
- find_all = getattr(skills_tool, "find_all_skills", None) or getattr(skills_tool, "_find_all_skills")
627
- sort = getattr(skills_tool, "sort_skills", None) or getattr(skills_tool, "_sort_skills")
681
+ try:
682
+ # Public since Hermes 0.22.5 (plugins/index.md § Read the skill catalog).
683
+ from tools.skills_tool import find_all_skills as find_all, sort_skills as sort
684
+ except ImportError:
685
+ # Legacy hosts (< 0.22.5) only had the private names. Drop with that host floor.
686
+ import tools.skills_tool as legacy_skills_tool
687
+
688
+ find_all = getattr(legacy_skills_tool, "_find_all_skills")
689
+ sort = getattr(legacy_skills_tool, "_sort_skills")
628
690
  published: List[Dict[str, Any]] = []
629
691
  seen: set[str] = set()
630
692
  for skill in sort(find_all(skip_disabled=False)):
@@ -1163,12 +1225,14 @@ class InlineAdapter(BasePlatformAdapter):
1163
1225
  """Hermes' own slash-command access for this platform; None on hosts without it."""
1164
1226
  try:
1165
1227
  from gateway.slash_access import policy_from_extra
1166
- except Exception:
1167
- return None
1168
- try:
1228
+
1169
1229
  return policy_from_extra(dict(self.config.extra or {}), "dm" if chat_type == "dm" else "group")
1170
- except Exception:
1171
- logger.debug("[inline] slash access policy unavailable", exc_info=True)
1230
+ except Exception as exc:
1231
+ _hermes_seam_unavailable(
1232
+ "gateway.slash_access.policy_from_extra",
1233
+ "only a DM's owner can change reply threads; group settings are locked",
1234
+ exc,
1235
+ )
1172
1236
  return None
1173
1237
 
1174
1238
  def _may_change_reply_threads(self, actor_id: str, chat_type: str) -> bool:
@@ -1176,7 +1240,9 @@ class InlineAdapter(BasePlatformAdapter):
1176
1240
  who may run /threads. Without admin lists Hermes allows everyone, and so does this."""
1177
1241
  policy = self._slash_access_policy(chat_type)
1178
1242
  if policy is None:
1179
- return True
1243
+ # Every supported host has the policy, so its absence means the seam broke:
1244
+ # keep a DM's owner in control, but never open a group's setting to everyone.
1245
+ return chat_type == "dm"
1180
1246
  return policy.can_run(actor_id, "threads")
1181
1247
 
1182
1248
  def note_turn_thread(self, chat_id: str, message_id: str, thread_id: str) -> None:
@@ -1227,14 +1293,9 @@ class InlineAdapter(BasePlatformAdapter):
1227
1293
  return "group"
1228
1294
 
1229
1295
  def _bot_settings_runner(self) -> Any:
1230
- runner = getattr(self, "gateway_runner", None)
1231
- if runner is not None:
1232
- return runner
1233
- try:
1234
- from gateway.run import _gateway_runner_ref
1235
- return _gateway_runner_ref()
1236
- except Exception:
1237
- return None
1296
+ # BasePlatformAdapter.gateway_runner is the runner's documented back-reference;
1297
+ # every supported host sets it before the adapter connects.
1298
+ return getattr(self, "gateway_runner", None)
1238
1299
 
1239
1300
  async def _bot_settings_context(
1240
1301
  self,
@@ -1310,10 +1371,11 @@ class InlineAdapter(BasePlatformAdapter):
1310
1371
  return context
1311
1372
 
1312
1373
  try:
1313
- from gateway.run import _load_gateway_config
1374
+ from hermes_cli.config import load_config_readonly
1314
1375
  from hermes_cli.model_switch_providers import list_picker_providers
1315
1376
 
1316
- cfg = _load_gateway_config() or {}
1377
+ # Read-only: the returned dict is Hermes' shared config cache.
1378
+ cfg = load_config_readonly() or {}
1317
1379
  model_cfg = cfg.get("model") if isinstance(cfg, dict) else {}
1318
1380
  if not isinstance(model_cfg, dict):
1319
1381
  model_cfg = {"default": str(model_cfg or "")}
@@ -1415,8 +1477,16 @@ class InlineAdapter(BasePlatformAdapter):
1415
1477
  {"value": value, "label": value.capitalize()} for value in dict.fromkeys(reasoning_values)
1416
1478
  ],
1417
1479
  })
1480
+ except asyncio.TimeoutError:
1481
+ logger.warning("[inline] agent settings model catalog timed out")
1418
1482
  except Exception as exc:
1419
- logger.debug("[inline] Hermes runtime settings unavailable: %s", exc)
1483
+ # Model and reasoning rows lean on GatewayRunner internals and the model picker
1484
+ # catalog; without them the settings sheet still offers reply-thread controls.
1485
+ _hermes_seam_unavailable(
1486
+ "GatewayRunner session model/reasoning settings",
1487
+ "Inline agent settings hide the model and reasoning rows",
1488
+ exc,
1489
+ )
1420
1490
  return context
1421
1491
 
1422
1492
  @staticmethod
@@ -1632,7 +1702,11 @@ class InlineAdapter(BasePlatformAdapter):
1632
1702
  f"/model {shlex.quote(model)} --provider {shlex.quote(provider)} "
1633
1703
  f"{'--global' if item_id == 'model-default' else '--session'}"
1634
1704
  )
1635
- result = await runner._handle_model_command(MessageEvent(
1705
+ handle_model_command = getattr(runner, "_handle_model_command", None)
1706
+ if not callable(handle_model_command):
1707
+ _hermes_seam_unavailable("GatewayRunner._handle_model_command", "Inline settings cannot switch models")
1708
+ raise ValueError("model switching unavailable")
1709
+ result = await handle_model_command(MessageEvent(
1636
1710
  text=command,
1637
1711
  message_type=MessageType.TEXT,
1638
1712
  source=source,
@@ -1645,7 +1719,13 @@ class InlineAdapter(BasePlatformAdapter):
1645
1719
  selected = str(value_body.get("stringValue") or "")
1646
1720
  if selected not in {option.get("value") for option in context.get("reasoning_options") or []}:
1647
1721
  raise ValueError("reasoning unavailable")
1648
- runner._apply_reasoning_selection(context["session_key"], "inline", selected)
1722
+ apply_reasoning_selection = getattr(runner, "_apply_reasoning_selection", None)
1723
+ if not callable(apply_reasoning_selection):
1724
+ _hermes_seam_unavailable(
1725
+ "GatewayRunner._apply_reasoning_selection", "Inline settings cannot change reasoning effort",
1726
+ )
1727
+ raise ValueError("reasoning unavailable")
1728
+ apply_reasoning_selection(context["session_key"], "inline", selected)
1649
1729
  return
1650
1730
  raise ValueError("setting unavailable")
1651
1731
 
@@ -4392,6 +4472,11 @@ class InlineAdapter(BasePlatformAdapter):
4392
4472
  return True
4393
4473
  try:
4394
4474
  from tools import slash_confirm as slash_confirm_mod
4475
+ except Exception as exc:
4476
+ _hermes_seam_unavailable("tools.slash_confirm.resolve", "Inline slash-confirm buttons cannot answer", exc)
4477
+ await self._finish_action(event, "Unavailable", "This Hermes version cannot record that choice.")
4478
+ return True
4479
+ try:
4395
4480
  result = await slash_confirm_mod.resolve(session_key, confirm_id, choice)
4396
4481
  self._slash_sessions.pop(confirm_id, None)
4397
4482
  text = str(result or ("Cancelled." if choice == "cancel" else "Recorded."))
@@ -4651,7 +4736,10 @@ class InlineAdapter(BasePlatformAdapter):
4651
4736
  from hermes_cli.models_catalog_static import PROVIDER_GROUPS
4652
4737
  label, _desc, members = PROVIDER_GROUPS.get(group_id, (group_id, "", []))
4653
4738
  member_slugs = [str(member) for member in members]
4654
- except Exception:
4739
+ except Exception as exc:
4740
+ _hermes_seam_unavailable(
4741
+ "hermes_cli.models_catalog_static.PROVIDER_GROUPS", "the model picker cannot open provider groups", exc,
4742
+ )
4655
4743
  member_slugs = []
4656
4744
  by_slug = {
4657
4745
  str(provider.get("slug") or "").strip().lower(): provider
@@ -4750,8 +4838,17 @@ class InlineAdapter(BasePlatformAdapter):
4750
4838
  async def _expensive_model_warning(self, model_id: str, provider_slug: str) -> Optional[Any]:
4751
4839
  try:
4752
4840
  from hermes_cli.model_cost_guard import expensive_model_warning
4841
+ except Exception as exc:
4842
+ _hermes_seam_unavailable(
4843
+ "hermes_cli.model_cost_guard.expensive_model_warning",
4844
+ "the model picker switches without the expensive-model confirmation",
4845
+ exc,
4846
+ )
4847
+ return None
4848
+ try:
4753
4849
  return await asyncio.to_thread(expensive_model_warning, model_id, provider=provider_slug)
4754
4850
  except Exception:
4851
+ logger.warning("[inline] expensive model check failed", exc_info=True)
4755
4852
  return None
4756
4853
 
4757
4854
  async def _edit_action_message(self, event: Dict[str, Any], text: str, actions: Optional[Dict[str, Any]] = None) -> SendResult:
@@ -5396,7 +5493,8 @@ class InlineAdapter(BasePlatformAdapter):
5396
5493
  try:
5397
5494
  from hermes_cli.providers import get_label
5398
5495
  return str(get_label(slug))
5399
- except Exception:
5496
+ except Exception as exc:
5497
+ _hermes_seam_unavailable("hermes_cli.providers.get_label", "the model picker shows provider slugs", exc)
5400
5498
  return str(slug or "")
5401
5499
 
5402
5500
  def _build_provider_actions(self, picker_id: str, providers: list, *, include_back: bool = False) -> Dict[str, Any]:
@@ -5409,7 +5507,10 @@ class InlineAdapter(BasePlatformAdapter):
5409
5507
  try:
5410
5508
  from hermes_cli.models_catalog_static import group_providers
5411
5509
  grouped = group_providers(list(by_slug.keys()))
5412
- except Exception:
5510
+ except Exception as exc:
5511
+ _hermes_seam_unavailable(
5512
+ "hermes_cli.models_catalog_static.group_providers", "the model picker lists providers ungrouped", exc,
5513
+ )
5413
5514
  grouped = [{"kind": "single", "slug": slug} for slug in by_slug.keys()]
5414
5515
  for row in grouped:
5415
5516
  if row.get("kind") == "group":
@@ -5784,7 +5885,9 @@ def _inline_catalog_part_summary(part: Dict[str, Any]) -> str:
5784
5885
  def _inline_version_text(last_sync: Optional[Dict[str, Any]] = None) -> str:
5785
5886
  version = _installed_inline_plugin_version()
5786
5887
  try:
5787
- from hermes_cli import __version__ as hermes_version
5888
+ from importlib.metadata import version as _distribution_version
5889
+
5890
+ hermes_version = _distribution_version("hermes-agent")
5788
5891
  except Exception:
5789
5892
  hermes_version = None
5790
5893
 
@@ -5854,7 +5957,9 @@ def register(ctx) -> None:
5854
5957
  from . import cli as _cli
5855
5958
  from . import tools as _tools
5856
5959
 
5857
- _install_inline_display_defaults()
5960
+ display_fields = _display_registration_fields()
5961
+ if not display_fields:
5962
+ _install_inline_display_defaults()
5858
5963
  ctx.register_platform(
5859
5964
  name="inline",
5860
5965
  label="Inline",
@@ -5877,6 +5982,7 @@ def register(ctx) -> None:
5877
5982
  allow_update_command=True,
5878
5983
  platform_hint=_tools.INLINE_PLATFORM_GUIDANCE,
5879
5984
  **_target_registration_hooks(),
5985
+ **display_fields,
5880
5986
  )
5881
5987
  register_command = getattr(ctx, "register_command", None)
5882
5988
  if callable(register_command):
@@ -30,7 +30,7 @@ _MACHINE_SETUP_PROTOCOL_VERSION = 1
30
30
  # Hermes' own tolerance: macOS readings of one process's start time drift about a second
31
31
  # after boot-clock adjustments, and 200 is 2 s on every platform's scale.
32
32
  _START_TIME_DRIFT_TOLERANCE = 200
33
- _PROBE_USER_AGENT = "inline-hermes-agent-adapter/1.0.0"
33
+ _PROBE_USER_AGENT = "inline-hermes-agent-adapter/1.0.1"
34
34
  _ENV_REFERENCE_RE = re.compile(r"^\$\{([A-Za-z_][A-Za-z0-9_]*)\}$")
35
35
 
36
36
 
@@ -43,6 +43,24 @@ def _open_bot_api_probe(request: urllib.request.Request):
43
43
  return urllib.request.build_opener(_RejectRedirects()).open(request, timeout=30)
44
44
 
45
45
 
46
+ def _setup_ui():
47
+ """Wizard prompts and output through the helpers Hermes documents for ``setup_fn``:
48
+ prompts from ``hermes_cli.setup`` and output from ``hermes_cli.cli_output``."""
49
+ from types import SimpleNamespace
50
+
51
+ from hermes_cli import cli_output
52
+ from hermes_cli.setup import prompt, prompt_yes_no
53
+
54
+ return SimpleNamespace(
55
+ print_header=cli_output.print_header,
56
+ print_info=cli_output.print_info,
57
+ print_success=cli_output.print_success,
58
+ print_warning=cli_output.print_warning,
59
+ prompt=prompt,
60
+ prompt_yes_no=prompt_yes_no,
61
+ )
62
+
63
+
46
64
  def gateway_setup() -> None:
47
65
  """Interactively create or connect an Inline bot.
48
66
 
@@ -50,8 +68,9 @@ def gateway_setup() -> None:
50
68
  persistence inside Hermes' own config helper so profiles and file
51
69
  permissions behave exactly like the built-in Telegram setup.
52
70
  """
53
- from hermes_cli import gateway as hermes_gateway
54
- from hermes_cli import setup as hermes_setup
71
+ from hermes_cli import config as hermes_gateway
72
+
73
+ hermes_setup = _setup_ui()
55
74
 
56
75
  hermes_setup.print_header("Inline")
57
76
  existing = (
@@ -403,7 +422,7 @@ def _machine_setup(args) -> int:
403
422
  token = token.strip()
404
423
  if not token:
405
424
  raise SystemExit("Inline bot token from stdin is empty")
406
- from hermes_cli import gateway as hermes_gateway
425
+ from hermes_cli import config as hermes_gateway
407
426
 
408
427
  hermes_gateway.save_env_value("INLINE_TOKEN", token)
409
428
  allowed = _apply_access(
@@ -431,7 +450,7 @@ def _machine_setup(args) -> int:
431
450
 
432
451
 
433
452
  def _status(args) -> int:
434
- from hermes_cli import gateway as hermes_gateway
453
+ from hermes_cli import config as hermes_gateway
435
454
 
436
455
  raw_config = _read_inline_config(hermes_gateway)
437
456
  token = (
@@ -3,7 +3,7 @@ label: Inline
3
3
  kind: platform
4
4
  provides_tools:
5
5
  - inline
6
- version: 1.0.0
6
+ version: 1.0.1
7
7
  requires_hermes: ">=0.21.3"
8
8
  description: >
9
9
  Inline platform adapter for Hermes Agent. The adapter runs as a native