@saleso.innovations/bridge 0.1.7 → 0.1.9
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/INTEGRATION.md +3 -0
- package/README.md +17 -1
- package/dist/bridgePaths.d.ts +7 -0
- package/dist/bridgePaths.d.ts.map +1 -0
- package/dist/bridgePaths.js +51 -0
- package/dist/cli.js +6 -0
- package/dist/client.d.ts +8 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +13 -0
- package/dist/constants.d.ts +3 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +5 -0
- package/dist/hermesForwarder.d.ts.map +1 -1
- package/dist/hermesForwarder.js +54 -24
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/update.d.ts +8 -0
- package/dist/update.d.ts.map +1 -0
- package/dist/update.js +80 -0
- package/package.json +1 -1
package/INTEGRATION.md
CHANGED
|
@@ -34,6 +34,9 @@ export async function onCleosPairingCodeSubmitted(code: string) {
|
|
|
34
34
|
for await (const chunk of stream) {
|
|
35
35
|
reply.delta(chunk, sequence++);
|
|
36
36
|
}
|
|
37
|
+
// If you stream from Hermes /v1/chat/completions, also forward tool progress via
|
|
38
|
+
// reply.activity() when you receive `event: hermes.tool.progress` SSE events.
|
|
39
|
+
// Do not inject tool markers into assistant text (see Hermes #6972).
|
|
37
40
|
reply.complete(stream.finalText, sequence);
|
|
38
41
|
},
|
|
39
42
|
});
|
package/README.md
CHANGED
|
@@ -15,9 +15,25 @@ Requirements:
|
|
|
15
15
|
- Node.js 20+
|
|
16
16
|
- Hermes installed on the same machine (`hermes gateway` — the install script configures the API automatically)
|
|
17
17
|
|
|
18
|
+
## Update
|
|
19
|
+
|
|
20
|
+
After the first install, updates are one command:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
cleos-bridge update
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
The install script links `cleos-bridge` to `/usr/local/bin` (root) or `~/.local/bin` (non-root). If that command is not found yet, use:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
curl -fsSL https://amicable-elephant-407.convex.site/update-bridge.sh | bash
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
This installs the latest package, refreshes the CLI symlink, and restarts `cleos-bridge.service` when present.
|
|
33
|
+
|
|
18
34
|
## Manual usage
|
|
19
35
|
|
|
20
|
-
The install script puts the bridge in `~/.cleos/bridge
|
|
36
|
+
The install script puts the bridge in `~/.cleos/bridge`. To run without the symlink:
|
|
21
37
|
|
|
22
38
|
```bash
|
|
23
39
|
node ~/.cleos/bridge/node_modules/@saleso.innovations/bridge/dist/cli.js pair ABCD1234
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const BRIDGE_PACKAGE = "@saleso.innovations/bridge";
|
|
2
|
+
export declare function defaultBridgeInstallDir(): string;
|
|
3
|
+
export declare function bridgeCliPath(bridgeDir: string): string;
|
|
4
|
+
/** Directory used by `npm install --prefix` (usually ~/.cleos/bridge). */
|
|
5
|
+
export declare function resolveBridgeInstallDir(): string;
|
|
6
|
+
export declare function readInstalledBridgeVersion(bridgeDir: string): string | null;
|
|
7
|
+
//# sourceMappingURL=bridgePaths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridgePaths.d.ts","sourceRoot":"","sources":["../src/bridgePaths.ts"],"names":[],"mappings":"AAMA,eAAO,MAAM,cAAc,+BAA+B,CAAC;AAE3D,wBAAgB,uBAAuB,IAAI,MAAM,CAEhD;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvD;AAwBD,0EAA0E;AAC1E,wBAAgB,uBAAuB,IAAI,MAAM,CAMhD;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAQ3E"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { execFileSync } from "node:child_process";
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { dirname, join, sep } from "node:path";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
export const BRIDGE_PACKAGE = "@saleso.innovations/bridge";
|
|
7
|
+
export function defaultBridgeInstallDir() {
|
|
8
|
+
return join(homedir(), ".cleos", "bridge");
|
|
9
|
+
}
|
|
10
|
+
export function bridgeCliPath(bridgeDir) {
|
|
11
|
+
return join(bridgeDir, "node_modules", BRIDGE_PACKAGE, "dist", "cli.js");
|
|
12
|
+
}
|
|
13
|
+
function inferBridgeDirFromCliPath(cliPath) {
|
|
14
|
+
const marker = `${sep}node_modules${sep}${BRIDGE_PACKAGE.replace("/", sep)}${sep}`;
|
|
15
|
+
const idx = cliPath.indexOf(marker);
|
|
16
|
+
if (idx < 0)
|
|
17
|
+
return null;
|
|
18
|
+
const nodeModulesDir = join(cliPath.slice(0, idx), "node_modules");
|
|
19
|
+
return dirname(nodeModulesDir);
|
|
20
|
+
}
|
|
21
|
+
function readBridgeDirFromSystemd() {
|
|
22
|
+
try {
|
|
23
|
+
const unit = execFileSync("systemctl", ["cat", "cleos-bridge.service"], {
|
|
24
|
+
encoding: "utf8",
|
|
25
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
26
|
+
});
|
|
27
|
+
const match = unit.match(/ExecStart=\S+\s+(\S+\/dist\/cli\.js)/);
|
|
28
|
+
if (!match?.[1])
|
|
29
|
+
return null;
|
|
30
|
+
return inferBridgeDirFromCliPath(match[1]);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/** Directory used by `npm install --prefix` (usually ~/.cleos/bridge). */
|
|
37
|
+
export function resolveBridgeInstallDir() {
|
|
38
|
+
return (readBridgeDirFromSystemd() ??
|
|
39
|
+
inferBridgeDirFromCliPath(fileURLToPath(import.meta.url)) ??
|
|
40
|
+
defaultBridgeInstallDir());
|
|
41
|
+
}
|
|
42
|
+
export function readInstalledBridgeVersion(bridgeDir) {
|
|
43
|
+
const pkgJson = join(bridgeDir, "node_modules", BRIDGE_PACKAGE, "package.json");
|
|
44
|
+
try {
|
|
45
|
+
const parsed = JSON.parse(readFileSync(pkgJson, "utf8"));
|
|
46
|
+
return parsed.version ?? null;
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
package/dist/cli.js
CHANGED
|
@@ -3,6 +3,7 @@ import { credentialsPathForDisplay, loadCredentials } from "./credentials.js";
|
|
|
3
3
|
import { connectHermesAgent, pairCleosAgent, reconnectHermesAgent } from "./client.js";
|
|
4
4
|
import { startCronWatcher } from "./cronWatcher.js";
|
|
5
5
|
import { runBridgeDaemon } from "./daemon.js";
|
|
6
|
+
import { runBridgeUpdate } from "./update.js";
|
|
6
7
|
import { prepareHermesForBridge } from "./ensureHermesApi.js";
|
|
7
8
|
import { createHermesMessageHandler } from "./hermesForwarder.js";
|
|
8
9
|
import { convexSiteUrlFromEnv } from "./resolve.js";
|
|
@@ -65,6 +66,10 @@ async function main() {
|
|
|
65
66
|
await waitForExit(session, () => startCronWatcher({ session }));
|
|
66
67
|
return;
|
|
67
68
|
}
|
|
69
|
+
if (command === "update") {
|
|
70
|
+
runBridgeUpdate({ tag: codeArg || "latest" });
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
68
73
|
printUsage();
|
|
69
74
|
process.exit(1);
|
|
70
75
|
}
|
|
@@ -74,6 +79,7 @@ function printUsage() {
|
|
|
74
79
|
console.error(" cleos-bridge connect <CODE> Pair and stay connected in the foreground");
|
|
75
80
|
console.error(" cleos-bridge start [CODE] Run as a reconnecting daemon (systemd)");
|
|
76
81
|
console.error(" cleos-bridge reconnect Reconnect once using saved credentials");
|
|
82
|
+
console.error(" cleos-bridge update [TAG] Update package and restart systemd service");
|
|
77
83
|
}
|
|
78
84
|
async function waitForExit(session, onStart) {
|
|
79
85
|
const stop = onStart?.();
|
package/dist/client.d.ts
CHANGED
|
@@ -21,8 +21,16 @@ export type UserMessageMeta = {
|
|
|
21
21
|
messageId: string;
|
|
22
22
|
attachments?: UserMessageAttachment[];
|
|
23
23
|
};
|
|
24
|
+
export type AgentActivityPayload = {
|
|
25
|
+
activityType: "tool.started" | "tool.completed";
|
|
26
|
+
tool?: string;
|
|
27
|
+
label?: string;
|
|
28
|
+
emoji?: string;
|
|
29
|
+
sequence: number;
|
|
30
|
+
};
|
|
24
31
|
export type AgentReply = {
|
|
25
32
|
delta: (text: string, sequence: number) => void;
|
|
33
|
+
activity: (activity: AgentActivityPayload) => void;
|
|
26
34
|
complete: (text: string, sequence: number) => void;
|
|
27
35
|
};
|
|
28
36
|
export type CronDeliveryMeta = {
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoC,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAKhG,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACrG,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,qBAAqB,EAAE,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACtE,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAEA,OAAO,EAAoC,KAAK,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAKhG,MAAM,MAAM,cAAc,GAAG;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,EAAE,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CACrG,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,qBAAqB,EAAE,CAAC;CACvC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG;IACjC,YAAY,EAAE,cAAc,GAAG,gBAAgB,CAAC;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,QAAQ,EAAE,CAAC,QAAQ,EAAE,oBAAoB,KAAK,IAAI,CAAC;IACnD,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CACpD,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IACtB,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACtE,CAAC;AA0MF,wBAAsB,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,cAAc,EAAE,eAAe,CAAC,GAAG,OAAO,CAAC;IAC5F,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC,CA2BD;AAED,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAcxF;AAED,wBAAsB,oBAAoB,CAAC,OAAO,GAAE;IAClD,WAAW,CAAC,EAAE,qBAAqB,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,aAAa,CAAC,EAAE,cAAc,CAAC,eAAe,CAAC,CAAC;CAC5C,GAAG,OAAO,CAAC,aAAa,CAAC,CAc9B"}
|
package/dist/client.js
CHANGED
|
@@ -57,6 +57,19 @@ function createReplySender(ws, agentId, conversationId, messageId) {
|
|
|
57
57
|
sequence,
|
|
58
58
|
}));
|
|
59
59
|
},
|
|
60
|
+
activity(activity) {
|
|
61
|
+
ws.send(JSON.stringify({
|
|
62
|
+
type: "agent.activity",
|
|
63
|
+
agentId,
|
|
64
|
+
conversationId,
|
|
65
|
+
messageId,
|
|
66
|
+
activityType: activity.activityType,
|
|
67
|
+
tool: activity.tool,
|
|
68
|
+
label: activity.label,
|
|
69
|
+
emoji: activity.emoji,
|
|
70
|
+
sequence: activity.sequence,
|
|
71
|
+
}));
|
|
72
|
+
},
|
|
60
73
|
complete(text, sequence) {
|
|
61
74
|
ws.send(JSON.stringify({
|
|
62
75
|
type: "agent.message",
|
package/dist/constants.d.ts
CHANGED
|
@@ -4,5 +4,8 @@ export declare const DEFAULT_CLEOS_CONVEX_SITE_URL = "https://amicable-elephant-
|
|
|
4
4
|
export declare const DEFAULT_HERMES_API_URL = "http://127.0.0.1:8642/v1/chat/completions";
|
|
5
5
|
/** VPS one-line installer (served from public Convex HTTP). */
|
|
6
6
|
export declare const DEFAULT_BRIDGE_INSTALL_URL = "https://amicable-elephant-407.convex.site/install-bridge.sh";
|
|
7
|
+
/** VPS one-line updater (served from public Convex HTTP). */
|
|
8
|
+
export declare const DEFAULT_BRIDGE_UPDATE_URL = "https://amicable-elephant-407.convex.site/update-bridge.sh";
|
|
7
9
|
export declare function bridgeInstallCommand(code: string): string;
|
|
10
|
+
export declare function bridgeUpdateCommand(): string;
|
|
8
11
|
//# sourceMappingURL=constants.d.ts.map
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,eAAO,MAAM,6BAA6B,8CAA8C,CAAC;AAEzF,6FAA6F;AAC7F,eAAO,MAAM,sBAAsB,8CAA8C,CAAC;AAElF,+DAA+D;AAC/D,eAAO,MAAM,0BAA0B,gEACwB,CAAC;AAEhE,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD"}
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,eAAO,MAAM,6BAA6B,8CAA8C,CAAC;AAEzF,6FAA6F;AAC7F,eAAO,MAAM,sBAAsB,8CAA8C,CAAC;AAElF,+DAA+D;AAC/D,eAAO,MAAM,0BAA0B,gEACwB,CAAC;AAEhE,6DAA6D;AAC7D,eAAO,MAAM,yBAAyB,+DACwB,CAAC;AAE/D,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
|
package/dist/constants.js
CHANGED
|
@@ -4,6 +4,11 @@ export const DEFAULT_CLEOS_CONVEX_SITE_URL = "https://amicable-elephant-407.conv
|
|
|
4
4
|
export const DEFAULT_HERMES_API_URL = "http://127.0.0.1:8642/v1/chat/completions";
|
|
5
5
|
/** VPS one-line installer (served from public Convex HTTP). */
|
|
6
6
|
export const DEFAULT_BRIDGE_INSTALL_URL = "https://amicable-elephant-407.convex.site/install-bridge.sh";
|
|
7
|
+
/** VPS one-line updater (served from public Convex HTTP). */
|
|
8
|
+
export const DEFAULT_BRIDGE_UPDATE_URL = "https://amicable-elephant-407.convex.site/update-bridge.sh";
|
|
7
9
|
export function bridgeInstallCommand(code) {
|
|
8
10
|
return `curl -fsSL ${DEFAULT_BRIDGE_INSTALL_URL} | bash -s -- ${code}`;
|
|
9
11
|
}
|
|
12
|
+
export function bridgeUpdateCommand() {
|
|
13
|
+
return `curl -fsSL ${DEFAULT_BRIDGE_UPDATE_URL} | bash`;
|
|
14
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hermesForwarder.d.ts","sourceRoot":"","sources":["../src/hermesForwarder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAyB,eAAe,EAAE,MAAM,aAAa,CAAC;AAGtF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAkBF,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,sBAA2B,GAAG;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf,CAUA;
|
|
1
|
+
{"version":3,"file":"hermesForwarder.d.ts","sourceRoot":"","sources":["../src/hermesForwarder.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAyB,eAAe,EAAE,MAAM,aAAa,CAAC;AAGtF,MAAM,MAAM,sBAAsB,GAAG;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAkBF,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,sBAA2B,GAAG;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;CACf,CAUA;AAyID,wBAAsB,eAAe,CACnC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,eAAe,EACrB,KAAK,EAAE,UAAU,EACjB,OAAO,GAAE,sBAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CA4Df;AAED,wBAAgB,0BAA0B,CAAC,OAAO,GAAE,sBAA2B,IAC/D,SAAS,MAAM,EAAE,MAAM,eAAe,EAAE,OAAO,UAAU,KAAG,OAAO,CAAC,IAAI,CAAC,CAMxF"}
|
package/dist/hermesForwarder.js
CHANGED
|
@@ -64,6 +64,52 @@ function extractDeltaFromChunk(payload) {
|
|
|
64
64
|
const content = delta.content;
|
|
65
65
|
return typeof content === "string" ? content : null;
|
|
66
66
|
}
|
|
67
|
+
function processSseEventBlock(eventBlock, reply, counters, onTextDelta) {
|
|
68
|
+
let eventName = "message";
|
|
69
|
+
for (const line of eventBlock.split("\n")) {
|
|
70
|
+
if (line.startsWith("event:")) {
|
|
71
|
+
eventName = line.slice(6).trim();
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (!line.startsWith("data:"))
|
|
75
|
+
continue;
|
|
76
|
+
const data = line.slice(5).trim();
|
|
77
|
+
if (!data || data === "[DONE]")
|
|
78
|
+
continue;
|
|
79
|
+
if (eventName === "hermes.tool.progress") {
|
|
80
|
+
try {
|
|
81
|
+
const payload = JSON.parse(data);
|
|
82
|
+
const tool = typeof payload.tool === "string" ? payload.tool : undefined;
|
|
83
|
+
const label = typeof payload.label === "string" ? payload.label : undefined;
|
|
84
|
+
const emoji = typeof payload.emoji === "string" ? payload.emoji : undefined;
|
|
85
|
+
reply.activity({
|
|
86
|
+
activityType: "tool.started",
|
|
87
|
+
tool,
|
|
88
|
+
label,
|
|
89
|
+
emoji,
|
|
90
|
+
sequence: counters.activitySequence,
|
|
91
|
+
});
|
|
92
|
+
counters.activitySequence += 1;
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// Ignore malformed tool progress payloads.
|
|
96
|
+
}
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
const payload = JSON.parse(data);
|
|
101
|
+
const delta = extractDeltaFromChunk(payload);
|
|
102
|
+
if (delta) {
|
|
103
|
+
onTextDelta(delta);
|
|
104
|
+
reply.delta(delta, counters.textSequence);
|
|
105
|
+
counters.textSequence += 1;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// Ignore malformed SSE chunks.
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
67
113
|
function buildHermesUserContent(text, attachments) {
|
|
68
114
|
const trimmed = text.trim();
|
|
69
115
|
const imageParts = (attachments ?? [])
|
|
@@ -121,7 +167,7 @@ export async function forwardToHermes(content, meta, reply, options = {}) {
|
|
|
121
167
|
const reader = response.body.getReader();
|
|
122
168
|
const decoder = new TextDecoder();
|
|
123
169
|
let buffer = "";
|
|
124
|
-
|
|
170
|
+
const counters = { textSequence: 0, activitySequence: 0 };
|
|
125
171
|
let fullText = "";
|
|
126
172
|
while (true) {
|
|
127
173
|
const { done, value } = await reader.read();
|
|
@@ -130,34 +176,18 @@ export async function forwardToHermes(content, meta, reply, options = {}) {
|
|
|
130
176
|
buffer += decoder.decode(value, { stream: true });
|
|
131
177
|
const { events, rest } = parseSseDataLines(buffer);
|
|
132
178
|
buffer = rest;
|
|
133
|
-
for (const
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
const data = line.slice(6).trim();
|
|
138
|
-
if (!data || data === "[DONE]")
|
|
139
|
-
continue;
|
|
140
|
-
try {
|
|
141
|
-
const payload = JSON.parse(data);
|
|
142
|
-
const delta = extractDeltaFromChunk(payload);
|
|
143
|
-
if (delta) {
|
|
144
|
-
fullText += delta;
|
|
145
|
-
reply.delta(delta, sequence);
|
|
146
|
-
sequence += 1;
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
catch {
|
|
150
|
-
// Ignore malformed SSE chunks.
|
|
151
|
-
}
|
|
152
|
-
}
|
|
179
|
+
for (const eventBlock of events) {
|
|
180
|
+
processSseEventBlock(eventBlock, reply, counters, (delta) => {
|
|
181
|
+
fullText += delta;
|
|
182
|
+
});
|
|
153
183
|
}
|
|
154
184
|
}
|
|
155
185
|
if (!fullText.trim()) {
|
|
156
186
|
fullText = "(Hermes returned an empty response)";
|
|
157
|
-
reply.delta(fullText,
|
|
158
|
-
|
|
187
|
+
reply.delta(fullText, counters.textSequence);
|
|
188
|
+
counters.textSequence += 1;
|
|
159
189
|
}
|
|
160
|
-
reply.complete(fullText,
|
|
190
|
+
reply.complete(fullText, counters.textSequence);
|
|
161
191
|
}
|
|
162
192
|
export function createHermesMessageHandler(options = {}) {
|
|
163
193
|
return async (content, meta, reply) => {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { connectHermesAgent, pairCleosAgent, reconnectHermesAgent } from "./client.js";
|
|
2
|
-
export type { AgentReply, ConnectOptions, ConnectResult, CronDeliveryMeta, UserMessageMeta } from "./client.js";
|
|
2
|
+
export type { AgentActivityPayload, AgentReply, ConnectOptions, ConnectResult, CronDeliveryMeta, UserMessageMeta, } from "./client.js";
|
|
3
3
|
export { loadCredentials, saveCredentials, credentialsPathForDisplay } from "./credentials.js";
|
|
4
4
|
export type { SavedAgentCredentials } from "./credentials.js";
|
|
5
5
|
export { resolvePairingCode, convexSiteUrlFromEnv } from "./resolve.js";
|
|
@@ -11,5 +11,5 @@ export { startCronWatcher } from "./cronWatcher.js";
|
|
|
11
11
|
export { resolveActiveConversationId, rememberConversationId } from "./activeConversation.js";
|
|
12
12
|
export { runBridgeDaemon } from "./daemon.js";
|
|
13
13
|
export type { RunBridgeOptions } from "./daemon.js";
|
|
14
|
-
export { DEFAULT_BRIDGE_INSTALL_URL, DEFAULT_CLEOS_CONVEX_SITE_URL, DEFAULT_HERMES_API_URL, bridgeInstallCommand, } from "./constants.js";
|
|
14
|
+
export { DEFAULT_BRIDGE_INSTALL_URL, DEFAULT_BRIDGE_UPDATE_URL, DEFAULT_CLEOS_CONVEX_SITE_URL, DEFAULT_HERMES_API_URL, bridgeInstallCommand, bridgeUpdateCommand, } from "./constants.js";
|
|
15
15
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACvF,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACvF,YAAY,EACV,oBAAoB,EACpB,UAAU,EACV,cAAc,EACd,aAAa,EACb,gBAAgB,EAChB,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AAC/F,YAAY,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACxE,YAAY,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,0BAA0B,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC3G,YAAY,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AACnE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,sBAAsB,EAAE,MAAM,yBAAyB,CAAC;AAC9F,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,6BAA6B,EAC7B,sBAAsB,EACtB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,gBAAgB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -6,4 +6,4 @@ export { createHermesMessageHandler, forwardToHermes, resolveHermesApiConfig } f
|
|
|
6
6
|
export { startCronWatcher } from "./cronWatcher.js";
|
|
7
7
|
export { resolveActiveConversationId, rememberConversationId } from "./activeConversation.js";
|
|
8
8
|
export { runBridgeDaemon } from "./daemon.js";
|
|
9
|
-
export { DEFAULT_BRIDGE_INSTALL_URL, DEFAULT_CLEOS_CONVEX_SITE_URL, DEFAULT_HERMES_API_URL, bridgeInstallCommand, } from "./constants.js";
|
|
9
|
+
export { DEFAULT_BRIDGE_INSTALL_URL, DEFAULT_BRIDGE_UPDATE_URL, DEFAULT_CLEOS_CONVEX_SITE_URL, DEFAULT_HERMES_API_URL, bridgeInstallCommand, bridgeUpdateCommand, } from "./constants.js";
|
package/dist/update.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type RunBridgeUpdateOptions = {
|
|
2
|
+
/** npm dist-tag or semver, default `latest`. */
|
|
3
|
+
tag?: string;
|
|
4
|
+
/** Skip systemd / service restart after install. */
|
|
5
|
+
skipRestart?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function runBridgeUpdate(options?: RunBridgeUpdateOptions): void;
|
|
8
|
+
//# sourceMappingURL=update.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../src/update.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,sBAAsB,GAAG;IACnC,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,wBAAgB,eAAe,CAAC,OAAO,GAAE,sBAA2B,GAAG,IAAI,CAsC1E"}
|
package/dist/update.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { execFileSync, spawnSync } from "node:child_process";
|
|
2
|
+
import { chmodSync, mkdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { BRIDGE_PACKAGE, bridgeCliPath, readInstalledBridgeVersion, resolveBridgeInstallDir, } from "./bridgePaths.js";
|
|
6
|
+
export function runBridgeUpdate(options = {}) {
|
|
7
|
+
const tag = options.tag ?? "latest";
|
|
8
|
+
const bridgeDir = resolveBridgeInstallDir();
|
|
9
|
+
const beforeVersion = readInstalledBridgeVersion(bridgeDir);
|
|
10
|
+
mkdirSync(bridgeDir, { recursive: true });
|
|
11
|
+
console.log(`Updating ${BRIDGE_PACKAGE}@${tag} in ${bridgeDir}...`);
|
|
12
|
+
const npm = spawnSync("npm", [
|
|
13
|
+
"install",
|
|
14
|
+
"--prefix",
|
|
15
|
+
bridgeDir,
|
|
16
|
+
`${BRIDGE_PACKAGE}@${tag}`,
|
|
17
|
+
"--no-fund",
|
|
18
|
+
"--no-audit",
|
|
19
|
+
"--omit=dev",
|
|
20
|
+
], { stdio: "inherit", env: process.env });
|
|
21
|
+
if (npm.status !== 0) {
|
|
22
|
+
throw new Error("npm install failed");
|
|
23
|
+
}
|
|
24
|
+
const cliPath = bridgeCliPath(bridgeDir);
|
|
25
|
+
linkBridgeCli(cliPath);
|
|
26
|
+
const afterVersion = readInstalledBridgeVersion(bridgeDir);
|
|
27
|
+
if (beforeVersion && afterVersion && beforeVersion === afterVersion) {
|
|
28
|
+
console.log(`Already on ${afterVersion}.`);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
console.log(`Updated ${beforeVersion ?? "unknown"} → ${afterVersion ?? "unknown"}.`);
|
|
32
|
+
}
|
|
33
|
+
if (!options.skipRestart) {
|
|
34
|
+
restartBridgeService();
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
function linkBridgeCli(cliPath) {
|
|
38
|
+
const nodeBin = process.execPath;
|
|
39
|
+
const wrapper = `#!/usr/bin/env bash\nexec "${nodeBin}" "${cliPath}" "$@"\n`;
|
|
40
|
+
const targets = process.getuid?.() === 0
|
|
41
|
+
? ["/usr/local/bin/cleos-bridge"]
|
|
42
|
+
: [join(homedir(), ".local", "bin", "cleos-bridge")];
|
|
43
|
+
for (const target of targets) {
|
|
44
|
+
try {
|
|
45
|
+
mkdirSync(join(target, ".."), { recursive: true });
|
|
46
|
+
writeFileSync(target, wrapper, { mode: 0o755 });
|
|
47
|
+
chmodSync(target, 0o755);
|
|
48
|
+
console.log(`Linked ${target}`);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
// try next target
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function restartBridgeService() {
|
|
57
|
+
const unitExists = spawnSync("systemctl", ["cat", "cleos-bridge.service"], {
|
|
58
|
+
encoding: "utf8",
|
|
59
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
60
|
+
});
|
|
61
|
+
if (unitExists.status !== 0) {
|
|
62
|
+
console.log("No cleos-bridge.service found. Restart manually if the bridge is running:");
|
|
63
|
+
console.log(" cleos-bridge start");
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
console.log("Restarting cleos-bridge.service...");
|
|
67
|
+
let restart = spawnSync("systemctl", ["restart", "cleos-bridge.service"], { stdio: "inherit" });
|
|
68
|
+
if (restart.status === 0) {
|
|
69
|
+
console.log("cleos-bridge.service restarted.");
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
try {
|
|
73
|
+
execFileSync("sudo", ["systemctl", "restart", "cleos-bridge.service"], { stdio: "inherit" });
|
|
74
|
+
console.log("cleos-bridge.service restarted (via sudo).");
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
console.log("Could not restart the service. Run:");
|
|
78
|
+
console.log(" sudo systemctl restart cleos-bridge");
|
|
79
|
+
}
|
|
80
|
+
}
|