@inline-chat/hermes-agent-adapter 0.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.
@@ -0,0 +1,101 @@
1
+ """Minimal Inline setup hooks for Hermes.
2
+
3
+ The external package installer (`inline-hermes install`) handles plugin
4
+ installation. This module only provides Hermes-native setup/status hooks once
5
+ the plugin has already been discovered by Hermes.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import argparse
10
+ import os
11
+ import re
12
+ import shutil
13
+ import subprocess
14
+
15
+ from pathlib import Path
16
+
17
+ _SIDECAR_ENTRY = Path(__file__).parent / "sidecar" / "index.mjs"
18
+ _MIN_NODE_MAJOR = 20
19
+
20
+
21
+ def gateway_setup() -> None:
22
+ if _env_token_configured():
23
+ print("Inline env token configured from INLINE_TOKEN/INLINE_BOT_TOKEN.")
24
+ else:
25
+ print("Set INLINE_TOKEN or INLINE_BOT_TOKEN in the Hermes gateway environment.")
26
+ print("Alternatively set platforms.inline.token or inline.token in ~/.hermes/config.yaml.")
27
+ print("Enable Inline in ~/.hermes/config.yaml:")
28
+ print(" platforms:")
29
+ print(" inline:")
30
+ print(" enabled: true")
31
+ print("Then run: inline-hermes doctor --json")
32
+
33
+
34
+ def register_cli(parser: argparse.ArgumentParser) -> None:
35
+ subs = parser.add_subparsers(dest="inline_command", required=False)
36
+ subs.add_parser("setup", help="Show Inline setup instructions")
37
+ subs.add_parser("status", help="Show Inline adapter status")
38
+ parser.set_defaults(func=dispatch)
39
+
40
+
41
+ def dispatch(args) -> int:
42
+ command = getattr(args, "inline_command", None)
43
+ if command is None:
44
+ command = "status"
45
+ if command == "setup":
46
+ gateway_setup()
47
+ return 0
48
+ if command == "status":
49
+ configured = _env_token_configured()
50
+ print(f"Inline env token configured: {'yes' if configured else 'no'}")
51
+ print("Hermes config token support: platforms.inline.token or inline.token")
52
+ print(f"Inline sidecar bundled: {'yes' if _SIDECAR_ENTRY.exists() else 'no'}")
53
+ print(f"Node available: {_node_status()}")
54
+ if not configured:
55
+ print("Hint: use INLINE_TOKEN/INLINE_BOT_TOKEN for env setup, or platforms.inline.token/inline.token in config.yaml.")
56
+ print("Install diagnostics: inline-hermes doctor --json")
57
+ return 0
58
+ raise SystemExit(f"unknown inline command: {command}")
59
+
60
+
61
+ def _env_token_configured() -> bool:
62
+ return bool(os.getenv("INLINE_TOKEN") or os.getenv("INLINE_BOT_TOKEN"))
63
+
64
+
65
+ def _find_node_bin() -> str | None:
66
+ configured = os.getenv("INLINE_NODE_BIN")
67
+ if configured:
68
+ return configured
69
+ try:
70
+ from hermes_constants import find_node_executable
71
+ found = find_node_executable("node")
72
+ if found:
73
+ return found
74
+ except Exception:
75
+ pass
76
+ return shutil.which("node")
77
+
78
+
79
+ def _node_status() -> str:
80
+ node_bin = _find_node_bin()
81
+ if not node_bin:
82
+ return "no"
83
+ try:
84
+ result = subprocess.run(
85
+ [node_bin, "--version"],
86
+ stdout=subprocess.PIPE,
87
+ stderr=subprocess.PIPE,
88
+ text=True,
89
+ timeout=5,
90
+ check=False,
91
+ )
92
+ except Exception as exc:
93
+ return f"no ({exc})"
94
+ version = (result.stdout or result.stderr or "").strip()
95
+ if result.returncode != 0:
96
+ return f"no ({version or f'exited with status {result.returncode}'})"
97
+ match = re.search(r"\bv?(\d+)(?:\.\d+){0,2}\b", version)
98
+ major = int(match.group(1)) if match else 0
99
+ if major < _MIN_NODE_MAJOR:
100
+ return f"no ({version or 'unknown version'}, requires >=20)"
101
+ return f"yes ({version})"
@@ -0,0 +1,132 @@
1
+ name: inline-platform
2
+ label: Inline
3
+ kind: platform
4
+ version: 0.0.1
5
+ description: >
6
+ Inline platform adapter for Hermes Agent. The adapter runs as a native
7
+ Hermes Python platform plugin and supervises a local Node sidecar that uses
8
+ the official Inline realtime SDK for inbound updates, catch-up, outbound
9
+ sends, uploads, message actions, and presence.
10
+ author: Inline
11
+ requires_env:
12
+ - name: INLINE_TOKEN
13
+ description: "Inline bot or user token. Canonical env var; INLINE_BOT_TOKEN, platforms.inline.token, inline.token, and simple ${ENV_NAME} config references are also accepted."
14
+ prompt: "Inline token"
15
+ password: true
16
+ optional_env:
17
+ - name: INLINE_BOT_TOKEN
18
+ description: "Compatibility alias for INLINE_TOKEN"
19
+ prompt: "Inline token"
20
+ password: true
21
+ - name: INLINE_BASE_URL
22
+ description: "Inline API base URL (default https://api.inline.chat)"
23
+ prompt: "Inline API base URL"
24
+ password: false
25
+ - name: INLINE_PARSE_MARKDOWN
26
+ description: "Parse outbound Hermes Markdown in Inline messages (true/false, default true)"
27
+ prompt: "Parse outbound Markdown?"
28
+ password: false
29
+ - name: INLINE_SYNC_COMMANDS
30
+ description: "Sync Hermes slash commands into Inline's native / command menu on gateway connect (true/false, default true)"
31
+ prompt: "Sync native slash commands?"
32
+ password: false
33
+ - name: INLINE_COMMAND_LIMIT
34
+ description: "Maximum Inline bot commands to register, 1-100 (default 100)"
35
+ prompt: "Native slash command limit"
36
+ password: false
37
+ - name: INLINE_MEDIA_MAX_MB
38
+ description: "Maximum inbound media download size in MB (default 25)"
39
+ prompt: "Inbound media max MB"
40
+ password: false
41
+ - name: INLINE_UPLOAD_MAX_MB
42
+ description: "Maximum outbound local upload size in MB (default 300)"
43
+ prompt: "Outbound upload max MB"
44
+ password: false
45
+ - name: INLINE_ALLOWED_USERS
46
+ description: "Comma-separated Inline user ids allowed to DM the bot"
47
+ prompt: "Allowed Inline user ids"
48
+ password: false
49
+ - name: INLINE_ALLOW_ALL_USERS
50
+ description: "Allow any sender to trigger the bot"
51
+ prompt: "Allow all users? (true/false)"
52
+ password: false
53
+ - name: INLINE_DM_POLICY
54
+ description: "DM policy: open, allowlist, or disabled"
55
+ prompt: "Inline DM policy"
56
+ password: false
57
+ - name: INLINE_GROUP_POLICY
58
+ description: "Group policy: open, allowlist, or disabled"
59
+ prompt: "Inline group policy"
60
+ password: false
61
+ - name: INLINE_GROUP_ALLOW_FROM
62
+ description: "Comma-separated Inline user ids allowed in groups"
63
+ prompt: "Allowed group sender ids"
64
+ password: false
65
+ - name: INLINE_REQUIRE_MENTION
66
+ description: "Require a mention/wake word in group chats (default true)"
67
+ prompt: "Require group mention? (true/false)"
68
+ password: false
69
+ - name: INLINE_STRICT_MENTION
70
+ description: "Require an explicit mention/wake word on every group-chat turn, including replies to the bot (true/false, default false)"
71
+ prompt: "Require every group turn to mention Hermes? (true/false)"
72
+ password: false
73
+ - name: INLINE_ALLOWED_CHATS
74
+ description: "Comma-separated Inline group/thread chat ids where the bot may respond. Empty means no chat restriction."
75
+ prompt: "Allowed Inline chat ids"
76
+ password: false
77
+ - name: INLINE_FREE_RESPONSE_CHATS
78
+ description: "Comma-separated Inline group/thread chat ids where no mention is required"
79
+ prompt: "Free-response Inline chat ids"
80
+ password: false
81
+ - name: INLINE_REPLY_THREADS
82
+ description: "Create/use Inline reply threads for top-level group replies by default (true/false, default true)"
83
+ prompt: "Reply in Inline threads by default? (true/false)"
84
+ password: false
85
+ - name: INLINE_SYSTEM_EVENTS
86
+ description: "Deliver Inline lifecycle events such as edits, deletes, and participant changes as synthetic messages (true/false, default false)"
87
+ prompt: "Deliver lifecycle events? (true/false)"
88
+ password: false
89
+ - name: INLINE_MENTION_PATTERNS
90
+ description: "Mention wake-word regexes, JSON list or comma/newline-separated"
91
+ prompt: "Mention patterns"
92
+ password: false
93
+ - name: INLINE_HOME_CHANNEL
94
+ description: "Default target for cron/standalone sends, for example chat:123"
95
+ prompt: "Home Inline target"
96
+ password: false
97
+ - name: INLINE_HOME_CHANNEL_NAME
98
+ description: "Human label for the home target"
99
+ prompt: "Home target display name"
100
+ password: false
101
+ - name: INLINE_SIDECAR_PORT
102
+ description: "Loopback port for the Node sidecar, 1-65535 (default 8794)"
103
+ prompt: "Sidecar port"
104
+ password: false
105
+ - name: INLINE_SIDECAR_BIND
106
+ description: "Loopback bind host for the Node sidecar (127.0.0.1, localhost, or ::1)"
107
+ prompt: "Sidecar bind host"
108
+ password: false
109
+ - name: INLINE_STATE_PATH
110
+ description: "Persistent Inline SDK state file path"
111
+ prompt: "Inline SDK state path"
112
+ password: false
113
+ - name: INLINE_SETTINGS_PATH
114
+ description: "Adapter settings file for per-chat slash-command overrides. Defaults next to INLINE_STATE_PATH."
115
+ prompt: "Inline adapter settings path"
116
+ password: false
117
+ - name: INLINE_RPC_TIMEOUT_MS
118
+ description: "Inline realtime RPC timeout in milliseconds"
119
+ prompt: "Inline RPC timeout"
120
+ password: false
121
+ - name: INLINE_CONNECT_TIMEOUT_MS
122
+ description: "Adapter sidecar readiness timeout in milliseconds (default 20000)"
123
+ prompt: "Sidecar readiness timeout"
124
+ password: false
125
+ - name: INLINE_SIDECAR_AUTOSTART
126
+ description: "Spawn the sidecar on connect (true/false, default true)"
127
+ prompt: "Auto-start sidecar?"
128
+ password: false
129
+ - name: INLINE_NODE_BIN
130
+ description: "Path to Node.js 20+ binary"
131
+ prompt: "Node executable path"
132
+ password: false