@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.
- package/LICENSE +201 -0
- package/README.md +315 -0
- package/dist/install.d.ts +4 -0
- package/dist/install.js +7957 -0
- package/package.json +81 -0
- package/plugin/inline/__init__.py +4 -0
- package/plugin/inline/adapter.py +2996 -0
- package/plugin/inline/cli.py +101 -0
- package/plugin/inline/plugin.yaml +132 -0
- package/plugin/inline/sidecar/index.mjs +24941 -0
- package/plugin/inline/tools.py +663 -0
|
@@ -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
|