@signetai/connector-hermes-agent 0.200.5 → 0.200.6
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/dist/index.js +7 -5
- package/hermes-plugin/README.md +2 -2
- package/hermes-plugin/__init__.py +3 -3
- package/hermes-plugin/client.py +31 -7
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -12356,7 +12356,8 @@ var NETWORK_FILESYSTEM_TYPES = new Set(["afpfs", "nfs", "smbfs", "webdav"]);
|
|
|
12356
12356
|
var __filename2 = fileURLToPath(import.meta.url);
|
|
12357
12357
|
var __dirname2 = dirname(__filename2);
|
|
12358
12358
|
var import_yaml = __toESM2(require_dist(), 1);
|
|
12359
|
-
var
|
|
12359
|
+
var LOOPBACK_HOST = "127.0.0.1";
|
|
12360
|
+
var LOCAL_BINDS = new Set([LOOPBACK_HOST, "localhost", "::1", "::ffff:127.0.0.1"]);
|
|
12360
12361
|
var import_yaml2 = __toESM2(require_dist(), 1);
|
|
12361
12362
|
var native = null;
|
|
12362
12363
|
try {
|
|
@@ -25012,7 +25013,8 @@ function expandHome(p, home2 = homedir2()) {
|
|
|
25012
25013
|
return join22(home2, p.slice(2));
|
|
25013
25014
|
return p;
|
|
25014
25015
|
}
|
|
25015
|
-
var
|
|
25016
|
+
var LOOPBACK_HOST2 = "127.0.0.1";
|
|
25017
|
+
var LOCAL_BINDS2 = new Set([LOOPBACK_HOST2, "localhost", "::1", "::ffff:127.0.0.1"]);
|
|
25016
25018
|
var import_yaml22 = __toESM(require_dist2(), 1);
|
|
25017
25019
|
var native2 = null;
|
|
25018
25020
|
try {
|
|
@@ -25839,7 +25841,7 @@ class HermesAgentConnector extends BaseConnector {
|
|
|
25839
25841
|
}
|
|
25840
25842
|
const envPath = join4(hermesHome, ".env");
|
|
25841
25843
|
let configuredSignetAgentId = "default";
|
|
25842
|
-
const configuredDaemonUrl = (process.env.SIGNET_DAEMON_URL?.trim() || "http://
|
|
25844
|
+
const configuredDaemonUrl = (process.env.SIGNET_DAEMON_URL?.trim() || "http://127.0.0.1:3850").replace(/[\r\n]+/g, "");
|
|
25843
25845
|
try {
|
|
25844
25846
|
let envContent = "";
|
|
25845
25847
|
if (existsSync2(envPath)) {
|
|
@@ -26007,14 +26009,14 @@ ${key}=${value}
|
|
|
26007
26009
|
return diagnoseHermesIntegration({
|
|
26008
26010
|
hermesHome,
|
|
26009
26011
|
hermesRepo,
|
|
26010
|
-
daemonUrl: (process.env.SIGNET_DAEMON_URL?.trim() || "http://
|
|
26012
|
+
daemonUrl: (process.env.SIGNET_DAEMON_URL?.trim() || "http://127.0.0.1:3850").replace(/[\r\n]+/g, "")
|
|
26011
26013
|
});
|
|
26012
26014
|
}
|
|
26013
26015
|
}
|
|
26014
26016
|
async function diagnoseHermesIntegration(opts) {
|
|
26015
26017
|
const hermesHome = opts?.hermesHome ?? resolveHermesHomePath();
|
|
26016
26018
|
const hermesRepo = opts && "hermesRepo" in opts ? opts.hermesRepo ?? null : resolveHermesRepoPath();
|
|
26017
|
-
const daemonUrl = opts?.daemonUrl ?? (process.env.SIGNET_DAEMON_URL?.trim() || "http://
|
|
26019
|
+
const daemonUrl = opts?.daemonUrl ?? (process.env.SIGNET_DAEMON_URL?.trim() || "http://127.0.0.1:3850");
|
|
26018
26020
|
const configPath = resolveConfigPath(hermesHome);
|
|
26019
26021
|
const userPluginDir = getUserPluginTargetDir(hermesHome);
|
|
26020
26022
|
const repoPluginDir = hermesRepo ? getRepoPluginTargetDir(hermesRepo) : null;
|
package/hermes-plugin/README.md
CHANGED
|
@@ -4,7 +4,7 @@ Persistent cross-session memory powered by the [Signet](https://github.com/Signe
|
|
|
4
4
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
|
-
- Signet daemon running on
|
|
7
|
+
- Signet daemon running on 127.0.0.1:3850 (default)
|
|
8
8
|
- Install: `curl -fsSL https://signetai.sh/install.sh | bash`, `npm install -g signetai`, or `bun add -g signetai`
|
|
9
9
|
|
|
10
10
|
## Setup
|
|
@@ -22,7 +22,7 @@ signet start # ensure daemon is running
|
|
|
22
22
|
## Config
|
|
23
23
|
|
|
24
24
|
Environment variables:
|
|
25
|
-
- `SIGNET_DAEMON_URL` — Full daemon URL (default: `http://
|
|
25
|
+
- `SIGNET_DAEMON_URL` — Full daemon URL (default: `http://127.0.0.1:3850`)
|
|
26
26
|
- `SIGNET_HOST` / `SIGNET_PORT` — Host and port separately
|
|
27
27
|
- `SIGNET_TOKEN` — Optional daemon bearer token; sent to loopback daemon URLs by default
|
|
28
28
|
- `SIGNET_TRUSTED_DAEMON_ORIGINS` — Comma-separated remote daemon origins allowed to receive `SIGNET_TOKEN`
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Signet memory plugin — MemoryProvider for Signet persistent memory.
|
|
2
2
|
|
|
3
3
|
Bridges Hermes Agent's memory provider interface to the Signet daemon
|
|
4
|
-
(
|
|
4
|
+
(127.0.0.1:3850), providing hybrid search (BM25 + vector + knowledge graph),
|
|
5
5
|
predictive recall, cross-session memory, and the full Signet pipeline
|
|
6
6
|
(extraction, knowledge graph, retention decay, synthesis).
|
|
7
7
|
|
|
@@ -12,7 +12,7 @@ lifting: embedding, reranking, knowledge graph traversal, and predictive
|
|
|
12
12
|
scoring.
|
|
13
13
|
|
|
14
14
|
Config:
|
|
15
|
-
- SIGNET_HOST / SIGNET_PORT env vars (default:
|
|
15
|
+
- SIGNET_HOST / SIGNET_PORT env vars (default: 127.0.0.1:3850)
|
|
16
16
|
- SIGNET_DAEMON_URL env var for full URL override
|
|
17
17
|
- SIGNET_AGENT_ID env var for agent scoping (unset: daemon's configured agent, usually "default")
|
|
18
18
|
- SIGNET_AGENT_WORKSPACE env var for the active named-agent workspace
|
|
@@ -411,7 +411,7 @@ class SignetMemoryProvider(MemoryProvider):
|
|
|
411
411
|
{
|
|
412
412
|
"key": "daemon_url",
|
|
413
413
|
"description": "Signet daemon URL",
|
|
414
|
-
"default": "http://
|
|
414
|
+
"default": "http://127.0.0.1:3850",
|
|
415
415
|
"env_var": "SIGNET_DAEMON_URL",
|
|
416
416
|
},
|
|
417
417
|
{
|
package/hermes-plugin/client.py
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
"""Signet daemon HTTP client.
|
|
2
2
|
|
|
3
|
-
Communicates with the Signet daemon on
|
|
3
|
+
Communicates with the Signet daemon on 127.0.0.1:3850 (default) for
|
|
4
4
|
memory operations: search, store, hooks, and session lifecycle.
|
|
5
5
|
|
|
6
6
|
Configuration resolution:
|
|
7
7
|
1. SIGNET_HOST + SIGNET_PORT env vars
|
|
8
8
|
2. SIGNET_DAEMON_URL env var (full URL override)
|
|
9
|
-
3. Default: http://
|
|
9
|
+
3. Default: http://127.0.0.1:3850
|
|
10
10
|
"""
|
|
11
11
|
|
|
12
12
|
from __future__ import annotations
|
|
@@ -23,7 +23,7 @@ from typing import Any, Dict, List, Optional
|
|
|
23
23
|
|
|
24
24
|
logger = logging.getLogger(__name__)
|
|
25
25
|
|
|
26
|
-
_DEFAULT_HOST = "
|
|
26
|
+
_DEFAULT_HOST = "127.0.0.1"
|
|
27
27
|
_DEFAULT_PORT = 3850
|
|
28
28
|
_TIMEOUT_SECS = 5
|
|
29
29
|
_LONG_TIMEOUT_SECS = 15
|
|
@@ -95,6 +95,19 @@ def _build_recall_request_body(
|
|
|
95
95
|
return body
|
|
96
96
|
|
|
97
97
|
|
|
98
|
+
def _normalize_loopback_host(host: str) -> str:
|
|
99
|
+
"""Use the daemon's IPv4 listener for IPv6-first local aliases."""
|
|
100
|
+
normalized = host.strip().lower().strip("[]")
|
|
101
|
+
if normalized in ("localhost", "::1", "0:0:0:0:0:0:0:1"):
|
|
102
|
+
return _DEFAULT_HOST
|
|
103
|
+
return host
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
def _format_host(host: str) -> str:
|
|
107
|
+
"""Format a hostname or IPv6 literal for an HTTP origin."""
|
|
108
|
+
return host if host.startswith("[") or ":" not in host else f"[{host}]"
|
|
109
|
+
|
|
110
|
+
|
|
98
111
|
def _normalize_base_url(raw: str, source: str) -> str:
|
|
99
112
|
"""Normalize a daemon URL to an origin string."""
|
|
100
113
|
parsed = urllib.parse.urlparse(raw)
|
|
@@ -106,17 +119,28 @@ def _normalize_base_url(raw: str, source: str) -> str:
|
|
|
106
119
|
raise ValueError(f"{source} must not include query strings or fragments")
|
|
107
120
|
if parsed.path not in ("", "/"):
|
|
108
121
|
raise ValueError(f"{source} must point at the daemon origin, not a path")
|
|
109
|
-
|
|
122
|
+
try:
|
|
123
|
+
hostname = parsed.hostname
|
|
124
|
+
port = parsed.port
|
|
125
|
+
except ValueError as error:
|
|
126
|
+
raise ValueError(f"{source} must be a valid HTTP origin") from error
|
|
127
|
+
if not hostname:
|
|
128
|
+
raise ValueError(f"{source} must include a hostname")
|
|
129
|
+
normalized_host = _normalize_loopback_host(hostname)
|
|
130
|
+
authority = _format_host(normalized_host)
|
|
131
|
+
if port is not None:
|
|
132
|
+
authority = f"{authority}:{port}"
|
|
133
|
+
return urllib.parse.urlunparse((parsed.scheme, authority, "", "", "", ""))
|
|
110
134
|
|
|
111
135
|
|
|
112
136
|
def _resolve_base_url() -> str:
|
|
113
|
-
"""Resolve the Signet daemon base URL."""
|
|
137
|
+
"""Resolve the Signet daemon base URL using the canonical loopback policy."""
|
|
114
138
|
explicit = _sanitize(os.environ.get("SIGNET_DAEMON_URL", ""))
|
|
115
139
|
if explicit:
|
|
116
140
|
return _normalize_base_url(explicit, "SIGNET_DAEMON_URL")
|
|
117
|
-
host = _sanitize(os.environ.get("SIGNET_HOST", _DEFAULT_HOST))
|
|
141
|
+
host = _normalize_loopback_host(_sanitize(os.environ.get("SIGNET_HOST", _DEFAULT_HOST)))
|
|
118
142
|
port = _sanitize(os.environ.get("SIGNET_PORT", str(_DEFAULT_PORT)))
|
|
119
|
-
return _normalize_base_url(f"http://{host}:{port}", "SIGNET_HOST/SIGNET_PORT")
|
|
143
|
+
return _normalize_base_url(f"http://{_format_host(host)}:{port}", "SIGNET_HOST/SIGNET_PORT")
|
|
120
144
|
|
|
121
145
|
|
|
122
146
|
def _is_loopback_host(host: str) -> bool:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@signetai/connector-hermes-agent",
|
|
3
|
-
"version": "0.200.
|
|
3
|
+
"version": "0.200.6",
|
|
4
4
|
"description": "Signet connector for Hermes Agent — installs Signet as a pluggable memory provider",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -25,8 +25,8 @@
|
|
|
25
25
|
"typecheck": "tsc --noEmit"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@signetai/connector-base": "0.200.
|
|
29
|
-
"@signetai/core": "0.200.
|
|
28
|
+
"@signetai/connector-base": "0.200.6",
|
|
29
|
+
"@signetai/core": "0.200.6"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@types/node": "^22.0.0",
|