clawconnect-agent 0.1.11 → 0.1.13
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 +16 -0
- package/README.zh-CN.md +16 -0
- package/dist/commands/install.js +3 -2
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/pair.js +2 -1
- package/dist/commands/pair.js.map +1 -1
- package/dist/commands/profile-hints.d.ts +7 -0
- package/dist/commands/profile-hints.js +71 -0
- package/dist/commands/profile-hints.js.map +1 -0
- package/dist/commands/send-file.js +25 -5
- package/dist/commands/send-file.js.map +1 -1
- package/dist/core/relay/timeline-event-builder.d.ts +5 -1
- package/dist/core/relay/timeline-event-builder.js +4 -0
- package/dist/core/relay/timeline-event-builder.js.map +1 -1
- package/dist/core/relay/timeline-event-log.d.ts +3 -0
- package/dist/core/relay/timeline-event-log.js +4 -0
- package/dist/core/relay/timeline-event-log.js.map +1 -1
- package/dist/hermes/hermes-relay-manager.d.ts +27 -24
- package/dist/hermes/hermes-relay-manager.js +126 -343
- package/dist/hermes/hermes-relay-manager.js.map +1 -1
- package/dist/hermes/hermes-runtime-test-support.d.ts +27 -0
- package/dist/hermes/hermes-runtime-test-support.js +703 -0
- package/dist/hermes/hermes-runtime-test-support.js.map +1 -0
- package/dist/hermes/hermes-runtime.d.ts +1 -2
- package/dist/hermes/hermes-runtime.js +1 -2
- package/dist/hermes/hermes-runtime.js.map +1 -1
- package/dist/hermes/relay/active-hermes-chat-runs.d.ts +12 -0
- package/dist/hermes/relay/active-hermes-chat-runs.js +42 -0
- package/dist/hermes/relay/active-hermes-chat-runs.js.map +1 -0
- package/dist/hermes/relay/hermes-slash-command-catalog.d.ts +22 -0
- package/dist/hermes/relay/hermes-slash-command-catalog.js +248 -0
- package/dist/hermes/relay/hermes-slash-command-catalog.js.map +1 -0
- package/dist/hermes/relay/hermes-state-db-realtime.d.ts +69 -0
- package/dist/hermes/relay/hermes-state-db-realtime.js +444 -0
- package/dist/hermes/relay/hermes-state-db-realtime.js.map +1 -0
- package/dist/hermes/runtime/hermes-runtime-api-client.d.ts +15 -0
- package/dist/hermes/runtime/hermes-runtime-api-client.js +510 -0
- package/dist/hermes/runtime/hermes-runtime-api-client.js.map +1 -0
- package/dist/hermes/runtime/hermes-runtime-chat.d.ts +4 -14
- package/dist/hermes/runtime/hermes-runtime-chat.js +205 -436
- package/dist/hermes/runtime/hermes-runtime-chat.js.map +1 -1
- package/dist/hermes/runtime/hermes-runtime-command-utils.d.ts +1 -0
- package/dist/hermes/runtime/hermes-runtime-command-utils.js +10 -1
- package/dist/hermes/runtime/hermes-runtime-command-utils.js.map +1 -1
- package/dist/hermes/runtime/hermes-runtime-history-completion.d.ts +12 -0
- package/dist/hermes/runtime/hermes-runtime-history-completion.js +162 -0
- package/dist/hermes/runtime/hermes-runtime-history-completion.js.map +1 -0
- package/dist/hermes/runtime/hermes-runtime-history.js +85 -22
- package/dist/hermes/runtime/hermes-runtime-history.js.map +1 -1
- package/dist/hermes/runtime/hermes-runtime-preloaded-skills.d.ts +11 -0
- package/dist/hermes/runtime/hermes-runtime-preloaded-skills.js +67 -0
- package/dist/hermes/runtime/hermes-runtime-preloaded-skills.js.map +1 -0
- package/dist/hermes/runtime/hermes-runtime-process.d.ts +3 -1
- package/dist/hermes/runtime/hermes-runtime-process.js +35 -6
- package/dist/hermes/runtime/hermes-runtime-process.js.map +1 -1
- package/dist/hermes/runtime/hermes-runtime-sessions.js +28 -3
- package/dist/hermes/runtime/hermes-runtime-sessions.js.map +1 -1
- package/dist/hermes/runtime/hermes-runtime-slash-command.d.ts +8 -0
- package/dist/hermes/runtime/hermes-runtime-slash-command.js +144 -0
- package/dist/hermes/runtime/hermes-runtime-slash-command.js.map +1 -0
- package/dist/hermes/runtime/hermes-runtime-state-db.d.ts +4 -0
- package/dist/hermes/runtime/hermes-runtime-state-db.js +193 -0
- package/dist/hermes/runtime/hermes-runtime-state-db.js.map +1 -0
- package/dist/hermes/runtime/hermes-runtime-tool-log-watcher.d.ts +8 -0
- package/dist/hermes/runtime/hermes-runtime-tool-log-watcher.js +121 -0
- package/dist/hermes/runtime/hermes-runtime-tool-log-watcher.js.map +1 -0
- package/dist/hermes/runtime/hermes-runtime-usage.d.ts +2 -0
- package/dist/hermes/runtime/hermes-runtime-usage.js +59 -5
- package/dist/hermes/runtime/hermes-runtime-usage.js.map +1 -1
- package/dist/i18n/index.js +4 -0
- package/dist/i18n/index.js.map +1 -1
- package/dist/index.js +22 -3
- package/dist/index.js.map +1 -1
- package/dist/openclaw/handlers/local-handlers.js +66 -20
- package/dist/openclaw/handlers/local-handlers.js.map +1 -1
- package/dist/openclaw/relay/chat-send-dedupe-coordinator.d.ts +20 -0
- package/dist/openclaw/relay/chat-send-dedupe-coordinator.js +161 -0
- package/dist/openclaw/relay/chat-send-dedupe-coordinator.js.map +1 -0
- package/dist/openclaw/relay/relay-manager-hello.d.ts +6 -0
- package/dist/openclaw/relay/relay-manager-hello.js +11 -0
- package/dist/openclaw/relay/relay-manager-hello.js.map +1 -0
- package/dist/openclaw/relay/relay-manager-history-timing.d.ts +5 -0
- package/dist/openclaw/relay/relay-manager-history-timing.js +6 -0
- package/dist/openclaw/relay/relay-manager-history-timing.js.map +1 -0
- package/dist/openclaw/relay/relay-manager-office-events.d.ts +2 -0
- package/dist/openclaw/relay/relay-manager-office-events.js +9 -0
- package/dist/openclaw/relay/relay-manager-office-events.js.map +1 -0
- package/dist/openclaw/relay/relay-manager-payload-helpers.d.ts +18 -0
- package/dist/openclaw/relay/relay-manager-payload-helpers.js +213 -0
- package/dist/openclaw/relay/relay-manager-payload-helpers.js.map +1 -0
- package/dist/openclaw/relay/relay-manager-protocol.d.ts +49 -0
- package/dist/openclaw/relay/relay-manager-protocol.js +2 -0
- package/dist/openclaw/relay/relay-manager-protocol.js.map +1 -0
- package/dist/openclaw/relay-manager.d.ts +3 -27
- package/dist/openclaw/relay-manager.js +19 -402
- package/dist/openclaw/relay-manager.js.map +1 -1
- package/dist/openclaw/session-store.js +42 -1
- package/dist/openclaw/session-store.js.map +1 -1
- package/package.json +1 -1
- package/dist/hermes/runtime/hermes-runtime-artifacts.d.ts +0 -3
- package/dist/hermes/runtime/hermes-runtime-artifacts.js +0 -75
- package/dist/hermes/runtime/hermes-runtime-artifacts.js.map +0 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { runHermesAsync, runHermesPythonAsync, } from "./hermes-runtime-process.js";
|
|
2
|
+
import { parseHermesSkillsList } from "./hermes-runtime-skills.js";
|
|
3
|
+
import { stringValue, toRecord } from "./hermes-runtime-values.js";
|
|
4
|
+
const HERMES_FILE_TRANSFER_SKILL = "file-transfer";
|
|
5
|
+
const HERMES_SKILLS_LIST_TIMEOUT_MS = 5_000;
|
|
6
|
+
const HERMES_SKILL_PROMPT_TIMEOUT_MS = 10_000;
|
|
7
|
+
export async function resolveHermesPreloadedSkillContext(options = {}) {
|
|
8
|
+
try {
|
|
9
|
+
const output = await runHermesAsync(["skills", "list"], HERMES_SKILLS_LIST_TIMEOUT_MS);
|
|
10
|
+
const skills = parseHermesSkillsList(output);
|
|
11
|
+
const fileTransfer = skills.find((skill) => skill.skillKey === HERMES_FILE_TRANSFER_SKILL);
|
|
12
|
+
if (fileTransfer && fileTransfer.enabled !== false) {
|
|
13
|
+
return fileTransferContext();
|
|
14
|
+
}
|
|
15
|
+
if (!fileTransfer && options.forceFileTransfer) {
|
|
16
|
+
return fileTransferContext();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
// 普通聊天不能被 skills 探测失败影响;显式文件传输则必须保留 terminal 约束,避免落到无终端的 API 文本回复。
|
|
21
|
+
if (options.forceFileTransfer) {
|
|
22
|
+
return fileTransferContext();
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return { cliArgs: [], requiredToolsets: [], skillNames: [] };
|
|
26
|
+
}
|
|
27
|
+
function fileTransferContext() {
|
|
28
|
+
return {
|
|
29
|
+
cliArgs: ["--skills", HERMES_FILE_TRANSFER_SKILL],
|
|
30
|
+
requiredToolsets: ["terminal"],
|
|
31
|
+
skillNames: [HERMES_FILE_TRANSFER_SKILL],
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
export async function buildHermesPreloadedSkillsPrompt(skillNames, taskId) {
|
|
35
|
+
const normalizedSkillNames = skillNames
|
|
36
|
+
.map((skillName) => skillName.trim())
|
|
37
|
+
.filter((skillName) => skillName.length > 0);
|
|
38
|
+
if (normalizedSkillNames.length === 0) {
|
|
39
|
+
return undefined;
|
|
40
|
+
}
|
|
41
|
+
const script = [
|
|
42
|
+
"import json",
|
|
43
|
+
"from agent.skill_commands import build_preloaded_skills_prompt",
|
|
44
|
+
`skill_names = ${JSON.stringify(normalizedSkillNames)}`,
|
|
45
|
+
`task_id = ${taskId ? JSON.stringify(taskId) : "None"}`,
|
|
46
|
+
"prompt, loaded, missing = build_preloaded_skills_prompt(skill_names, task_id=task_id)",
|
|
47
|
+
"print(json.dumps({'prompt': prompt, 'loaded': loaded, 'missing': missing}, ensure_ascii=False))",
|
|
48
|
+
].join("\n");
|
|
49
|
+
try {
|
|
50
|
+
const raw = await runHermesPythonAsync(script, {}, HERMES_SKILL_PROMPT_TIMEOUT_MS);
|
|
51
|
+
const payload = toRecord(JSON.parse(raw.trim()));
|
|
52
|
+
const missing = stringArrayValue(payload.missing);
|
|
53
|
+
const prompt = stringValue(payload.prompt);
|
|
54
|
+
// 这里必须保守:API 路径只有拿到 Hermes 自己生成的完整 skill prompt 才能替代 CLI --skills。
|
|
55
|
+
if (missing.length > 0 || !prompt) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
return prompt;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return undefined;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function stringArrayValue(value) {
|
|
65
|
+
return Array.isArray(value) ? value.filter((item) => typeof item === "string") : [];
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=hermes-runtime-preloaded-skills.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hermes-runtime-preloaded-skills.js","sourceRoot":"","sources":["../../../src/hermes/runtime/hermes-runtime-preloaded-skills.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,7 +11,8 @@ export declare const HERMES_TYPING_MARKER = "[[clawlink:typing]]";
|
|
|
11
11
|
export declare const CLAWCONNECT_MOBILE_BRIDGE_HINT: string;
|
|
12
12
|
export declare const SUBPROCESS_ENV: NodeJS.ProcessEnv;
|
|
13
13
|
export declare function resolveHermesBin(): string;
|
|
14
|
-
export declare function runHermes(args: string[], timeoutMs?: number): string;
|
|
14
|
+
export declare function runHermes(args: string[], timeoutMs?: number, env?: NodeJS.ProcessEnv): string;
|
|
15
|
+
export declare function runHermesAsync(args: string[], timeoutMs?: number, env?: NodeJS.ProcessEnv): Promise<string>;
|
|
15
16
|
export declare function runHermesWithInput(args: string[], input: string, timeoutMs?: number): string;
|
|
16
17
|
export declare function stripHermesSessionResumeNotices(output: string): string;
|
|
17
18
|
export declare function stripHermesSecurityReviewNotices(output: string): string;
|
|
@@ -22,3 +23,4 @@ export declare function errorMessageWithOutput(error: unknown): string;
|
|
|
22
23
|
export declare function isHermesMissingSessionError(error: unknown): boolean;
|
|
23
24
|
export declare function sleep(ms: number): Promise<void>;
|
|
24
25
|
export declare function runHermesPython(script: string, extraEnv?: NodeJS.ProcessEnv): string;
|
|
26
|
+
export declare function runHermesPythonAsync(script: string, extraEnv?: NodeJS.ProcessEnv, timeoutMs?: number): Promise<string>;
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { execFileSync, execSync } from "child_process";
|
|
1
|
+
import { execFile as execFileCb, execFileSync, execSync } from "child_process";
|
|
2
2
|
import { existsSync } from "fs";
|
|
3
3
|
import { homedir } from "os";
|
|
4
4
|
import { join } from "path";
|
|
5
|
+
import { promisify } from "util";
|
|
6
|
+
const execFile = promisify(execFileCb);
|
|
5
7
|
export const IS_WINDOWS = process.platform === "win32";
|
|
6
8
|
export const HERMES_INBOX_DIR = join(homedir(), ".clawconnect", "hermes", "inbox");
|
|
7
9
|
export const HERMES_HOME_DIR = process.env.HERMES_HOME?.trim() || join(homedir(), ".hermes");
|
|
@@ -15,8 +17,9 @@ export const HERMES_TYPING_MARKER = "[[clawlink:typing]]";
|
|
|
15
17
|
export const CLAWCONNECT_MOBILE_BRIDGE_HINT = [
|
|
16
18
|
"[ClawConnect mobile bridge]",
|
|
17
19
|
"You are connected to a mobile chat client through ClawConnect.",
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
+
"When the latest user request explicitly asks you to send, upload, attach, or share a local host image or file, use your Hermes file-transfer skill if it is installed.",
|
|
21
|
+
"The host-side delivery command is: clawconnect send-file --profile hermes --json <absolute-local-path>.",
|
|
22
|
+
"Do not rely on final-answer local file paths as mobile attachments; after a successful send-file call, summarize what was sent.",
|
|
20
23
|
"If the user is asking about capabilities, skills, file listings, or past work, do not repeat old file paths as sendable attachments.",
|
|
21
24
|
"Do not say you cannot send attachments merely because you are running in a CLI environment.",
|
|
22
25
|
].join(" ");
|
|
@@ -60,13 +63,21 @@ export function resolveHermesBin() {
|
|
|
60
63
|
}
|
|
61
64
|
return "hermes";
|
|
62
65
|
}
|
|
63
|
-
export function runHermes(args, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
66
|
+
export function runHermes(args, timeoutMs = DEFAULT_TIMEOUT_MS, env = SUBPROCESS_ENV) {
|
|
64
67
|
return execFileSync(resolveHermesBin(), args, {
|
|
65
|
-
env
|
|
68
|
+
env,
|
|
66
69
|
stdio: "pipe",
|
|
67
70
|
timeout: timeoutMs,
|
|
68
71
|
}).toString();
|
|
69
72
|
}
|
|
73
|
+
export async function runHermesAsync(args, timeoutMs = DEFAULT_TIMEOUT_MS, env = SUBPROCESS_ENV) {
|
|
74
|
+
const { stdout } = await execFile(resolveHermesBin(), args, {
|
|
75
|
+
encoding: "utf8",
|
|
76
|
+
env,
|
|
77
|
+
timeout: timeoutMs,
|
|
78
|
+
});
|
|
79
|
+
return stdout;
|
|
80
|
+
}
|
|
70
81
|
export function runHermesWithInput(args, input, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
71
82
|
return execFileSync(resolveHermesBin(), args, {
|
|
72
83
|
env: SUBPROCESS_ENV,
|
|
@@ -134,14 +145,32 @@ export function sleep(ms) {
|
|
|
134
145
|
return new Promise((resolveSleep) => setTimeout(resolveSleep, ms));
|
|
135
146
|
}
|
|
136
147
|
export function runHermesPython(script, extraEnv = {}) {
|
|
148
|
+
const cwd = resolveHermesAgentCwd();
|
|
137
149
|
const venvPython = join(HERMES_HOME_DIR, "hermes-agent", "venv", "bin", "python");
|
|
138
150
|
const python = process.env.HERMES_PYTHON?.trim()
|
|
139
151
|
|| (existsSync(venvPython) ? venvPython : join(homedir(), ".local", "bin", "python3.11"));
|
|
140
152
|
return execFileSync(python, ["-c", script], {
|
|
141
|
-
cwd
|
|
153
|
+
cwd,
|
|
142
154
|
env: { ...SUBPROCESS_ENV, ...extraEnv },
|
|
143
155
|
stdio: "pipe",
|
|
144
156
|
timeout: DEFAULT_TIMEOUT_MS,
|
|
145
157
|
}).toString();
|
|
146
158
|
}
|
|
159
|
+
export async function runHermesPythonAsync(script, extraEnv = {}, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
160
|
+
const cwd = resolveHermesAgentCwd();
|
|
161
|
+
const venvPython = join(HERMES_HOME_DIR, "hermes-agent", "venv", "bin", "python");
|
|
162
|
+
const python = process.env.HERMES_PYTHON?.trim()
|
|
163
|
+
|| (existsSync(venvPython) ? venvPython : join(homedir(), ".local", "bin", "python3.11"));
|
|
164
|
+
const { stdout } = await execFile(python, ["-c", script], {
|
|
165
|
+
cwd,
|
|
166
|
+
encoding: "utf8",
|
|
167
|
+
env: { ...SUBPROCESS_ENV, ...extraEnv },
|
|
168
|
+
timeout: timeoutMs,
|
|
169
|
+
});
|
|
170
|
+
return stdout;
|
|
171
|
+
}
|
|
172
|
+
function resolveHermesAgentCwd() {
|
|
173
|
+
const agentDir = join(HERMES_HOME_DIR, "hermes-agent");
|
|
174
|
+
return existsSync(agentDir) ? agentDir : homedir();
|
|
175
|
+
}
|
|
147
176
|
//# sourceMappingURL=hermes-runtime-process.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hermes-runtime-process.js","sourceRoot":"","sources":["../../../src/hermes/runtime/hermes-runtime-process.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"hermes-runtime-process.js","sourceRoot":"","sources":["../../../src/hermes/runtime/hermes-runtime-process.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { forgetHermesSession, getMappedHermesSessionId } from "../hermes-session-store.js";
|
|
2
2
|
import { listHermesSessions } from "./hermes-runtime-usage.js";
|
|
3
|
-
import { runHermesOutput } from "./hermes-runtime-command-utils.js";
|
|
3
|
+
import { runHermesOutput, runHermesOutputAsync } from "./hermes-runtime-command-utils.js";
|
|
4
4
|
import { stringParam, toRecord } from "./hermes-runtime-values.js";
|
|
5
5
|
import { errorMessageWithOutput, isHermesMissingSessionError } from "./hermes-runtime-process.js";
|
|
6
|
+
import { buildEmptyHermesHistoryExport, exportHermesSessionFromStateDb, } from "./hermes-runtime-state-db.js";
|
|
6
7
|
export async function runHermesSessionsList() {
|
|
7
8
|
try {
|
|
8
9
|
const sessions = await listHermesSessions();
|
|
@@ -49,17 +50,41 @@ export async function runHermesSessionExport(params) {
|
|
|
49
50
|
const resolved = await resolveHermesSessionIdFromParams(record);
|
|
50
51
|
const sessionId = resolved.sessionId;
|
|
51
52
|
const output = stringParam(record, "output", "outputPath");
|
|
53
|
+
const requireResolvedSession = record.requireResolvedSession === true;
|
|
54
|
+
if (sessionId) {
|
|
55
|
+
const stateDbExport = await exportHermesSessionFromStateDb(sessionId);
|
|
56
|
+
if (stateDbExport) {
|
|
57
|
+
return { ok: true, payload: { output: JSON.stringify(stateDbExport) } };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
else if (requireResolvedSession) {
|
|
61
|
+
return {
|
|
62
|
+
ok: true,
|
|
63
|
+
payload: {
|
|
64
|
+
output: JSON.stringify(buildEmptyHermesHistoryExport(resolved.sessionKey)),
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
52
68
|
const args = ["sessions", "export", output ?? "-"];
|
|
53
69
|
if (sessionId)
|
|
54
70
|
args.push("--session-id", sessionId);
|
|
55
|
-
|
|
71
|
+
// chat.history 会和 chat.send 共享同一个 relay manager 事件循环;这里必须异步,避免导出历史时饿死实时消息。
|
|
72
|
+
const result = await runHermesOutputAsync(args, 10 * 60_000);
|
|
56
73
|
if (!result.ok
|
|
57
74
|
&& resolved.fromMappedSessionKey
|
|
58
75
|
&& resolved.sessionKey
|
|
59
76
|
&& sessionId
|
|
60
77
|
&& isHermesMissingSessionError(result.error)) {
|
|
61
78
|
await forgetHermesSession(resolved.sessionKey, sessionId);
|
|
62
|
-
|
|
79
|
+
if (requireResolvedSession) {
|
|
80
|
+
return {
|
|
81
|
+
ok: true,
|
|
82
|
+
payload: {
|
|
83
|
+
output: JSON.stringify(buildEmptyHermesHistoryExport(resolved.sessionKey)),
|
|
84
|
+
},
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return await runHermesOutputAsync(["sessions", "export", output ?? "-"], 10 * 60_000);
|
|
63
88
|
}
|
|
64
89
|
return result;
|
|
65
90
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hermes-runtime-sessions.js","sourceRoot":"","sources":["../../../src/hermes/runtime/hermes-runtime-sessions.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAC3F,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"hermes-runtime-sessions.js","sourceRoot":"","sources":["../../../src/hermes/runtime/hermes-runtime-sessions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { HermesChatResult } from "./hermes-runtime-types.js";
|
|
2
|
+
export declare function isHermesSlashCommandMessage(message: string): boolean;
|
|
3
|
+
export declare function runHermesSlashCommand(params: {
|
|
4
|
+
message: string;
|
|
5
|
+
sessionKey: string;
|
|
6
|
+
hermesSessionId?: unknown;
|
|
7
|
+
runQueuedChat?: (message: string, hermesSessionId?: string) => Promise<HermesChatResult>;
|
|
8
|
+
}): Promise<HermesChatResult>;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { forgetHermesSession, getMappedHermesSessionId, rememberHermesSession, } from "../hermes-session-store.js";
|
|
2
|
+
import { runHermesPython, sanitizeHermesChatOutput, } from "./hermes-runtime-process.js";
|
|
3
|
+
import { collectHermesUsageSnapshot } from "./hermes-runtime-usage.js";
|
|
4
|
+
const HERMES_SLASH_COMMAND_SCRIPT = String.raw `
|
|
5
|
+
import contextlib
|
|
6
|
+
import io
|
|
7
|
+
import json
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
from rich.console import Console
|
|
12
|
+
|
|
13
|
+
import cli as cli_mod
|
|
14
|
+
from cli import HermesCLI
|
|
15
|
+
|
|
16
|
+
command = os.environ.get("CLAWCONNECT_HERMES_SLASH_COMMAND", "").strip()
|
|
17
|
+
resume = os.environ.get("CLAWCONNECT_HERMES_SLASH_RESUME", "").strip() or None
|
|
18
|
+
if command and not command.startswith("/"):
|
|
19
|
+
command = "/" + command
|
|
20
|
+
|
|
21
|
+
with contextlib.redirect_stdout(io.StringIO()), contextlib.redirect_stderr(io.StringIO()):
|
|
22
|
+
cli = HermesCLI(model=None, compact=True, resume=resume, verbose=False)
|
|
23
|
+
|
|
24
|
+
buf = io.StringIO()
|
|
25
|
+
cli.console = Console(file=buf, force_terminal=True, width=120)
|
|
26
|
+
|
|
27
|
+
def approve_once(prompt=""):
|
|
28
|
+
if prompt:
|
|
29
|
+
print(prompt, end="")
|
|
30
|
+
return "1"
|
|
31
|
+
|
|
32
|
+
def approve_once_modal(*args, **kwargs):
|
|
33
|
+
return "once"
|
|
34
|
+
|
|
35
|
+
try:
|
|
36
|
+
cli._prompt_text_input = approve_once
|
|
37
|
+
cli._prompt_text_input_modal = approve_once_modal
|
|
38
|
+
except Exception:
|
|
39
|
+
pass
|
|
40
|
+
|
|
41
|
+
old_cprint = getattr(cli_mod, "_cprint", None)
|
|
42
|
+
if old_cprint is not None:
|
|
43
|
+
cli_mod._cprint = lambda text: print(text)
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
with contextlib.redirect_stdout(buf), contextlib.redirect_stderr(buf):
|
|
47
|
+
keep_going = cli.process_command(command)
|
|
48
|
+
pending_inputs = []
|
|
49
|
+
pending_queue = getattr(cli, "_pending_input", None)
|
|
50
|
+
if pending_queue is not None:
|
|
51
|
+
while True:
|
|
52
|
+
try:
|
|
53
|
+
pending_inputs.append(pending_queue.get_nowait())
|
|
54
|
+
except Exception:
|
|
55
|
+
break
|
|
56
|
+
payload = {
|
|
57
|
+
"ok": True,
|
|
58
|
+
"output": buf.getvalue().rstrip(),
|
|
59
|
+
"sessionId": getattr(cli, "session_id", None),
|
|
60
|
+
"keepGoing": bool(keep_going),
|
|
61
|
+
"pendingInputs": pending_inputs,
|
|
62
|
+
}
|
|
63
|
+
except Exception as exc:
|
|
64
|
+
payload = {
|
|
65
|
+
"ok": False,
|
|
66
|
+
"output": buf.getvalue().rstrip(),
|
|
67
|
+
"error": str(exc),
|
|
68
|
+
"sessionId": getattr(cli, "session_id", None),
|
|
69
|
+
}
|
|
70
|
+
finally:
|
|
71
|
+
if old_cprint is not None:
|
|
72
|
+
cli_mod._cprint = old_cprint
|
|
73
|
+
|
|
74
|
+
sys.stdout.write(json.dumps(payload, ensure_ascii=False))
|
|
75
|
+
`;
|
|
76
|
+
export function isHermesSlashCommandMessage(message) {
|
|
77
|
+
return /^\/[A-Za-z0-9][\w-]*(?:\s|$)/.test(message.trim());
|
|
78
|
+
}
|
|
79
|
+
export async function runHermesSlashCommand(params) {
|
|
80
|
+
const command = params.message.trim();
|
|
81
|
+
const resume = typeof params.hermesSessionId === "string" && params.hermesSessionId.trim().length > 0
|
|
82
|
+
? params.hermesSessionId.trim()
|
|
83
|
+
: await getMappedHermesSessionId(params.sessionKey);
|
|
84
|
+
const raw = runHermesPython(HERMES_SLASH_COMMAND_SCRIPT, {
|
|
85
|
+
CLAWCONNECT_HERMES_SLASH_COMMAND: command,
|
|
86
|
+
CLAWCONNECT_HERMES_SLASH_RESUME: resume ?? "",
|
|
87
|
+
});
|
|
88
|
+
const payload = parseHermesSlashCommandPayload(raw);
|
|
89
|
+
const output = sanitizeHermesChatOutput(payload.output ?? "").trim();
|
|
90
|
+
if (!payload.ok) {
|
|
91
|
+
const message = [output, payload.error].filter(Boolean).join("\n").trim() || "hermes_slash_command_failed";
|
|
92
|
+
throw new Error(message);
|
|
93
|
+
}
|
|
94
|
+
const sessionId = typeof payload.sessionId === "string" && payload.sessionId.trim().length > 0
|
|
95
|
+
? payload.sessionId.trim()
|
|
96
|
+
: undefined;
|
|
97
|
+
if (sessionId) {
|
|
98
|
+
await rememberHermesSession(params.sessionKey, {
|
|
99
|
+
sessionKey: params.sessionKey,
|
|
100
|
+
hermesSessionId: sessionId,
|
|
101
|
+
displayName: sessionId,
|
|
102
|
+
label: command,
|
|
103
|
+
lastActivityAt: new Date().toISOString(),
|
|
104
|
+
kind: "hermes",
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
if (/^\/(?:new|reset)\b/i.test(command) && resume && sessionId && sessionId !== resume) {
|
|
108
|
+
await forgetHermesSession(resume, resume);
|
|
109
|
+
}
|
|
110
|
+
if (payload.pendingInputs && payload.pendingInputs.length > 0) {
|
|
111
|
+
const queuedMessage = payload.pendingInputs.join("\n\n").trim();
|
|
112
|
+
if (queuedMessage && params.runQueuedChat) {
|
|
113
|
+
const queued = await params.runQueuedChat(queuedMessage, sessionId);
|
|
114
|
+
return {
|
|
115
|
+
...queued,
|
|
116
|
+
output: [output, queued.output].filter((part) => part && part !== "(no output)").join("\n\n") || queued.output,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
const usage = await collectHermesUsageSnapshot(sessionId);
|
|
121
|
+
return {
|
|
122
|
+
output: output || "(no output)",
|
|
123
|
+
sessionKey: params.sessionKey,
|
|
124
|
+
artifactPaths: [],
|
|
125
|
+
usage,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function parseHermesSlashCommandPayload(raw) {
|
|
129
|
+
const parsed = JSON.parse(raw);
|
|
130
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
131
|
+
throw new Error("invalid_hermes_slash_command_payload");
|
|
132
|
+
}
|
|
133
|
+
const record = parsed;
|
|
134
|
+
return {
|
|
135
|
+
ok: record.ok === true,
|
|
136
|
+
output: typeof record.output === "string" ? record.output : undefined,
|
|
137
|
+
error: typeof record.error === "string" ? record.error : undefined,
|
|
138
|
+
sessionId: typeof record.sessionId === "string" ? record.sessionId : undefined,
|
|
139
|
+
pendingInputs: Array.isArray(record.pendingInputs)
|
|
140
|
+
? record.pendingInputs.filter((value) => typeof value === "string" && value.trim().length > 0)
|
|
141
|
+
: undefined,
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=hermes-runtime-slash-command.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hermes-runtime-slash-command.js","sourceRoot":"","sources":["../../../src/hermes/runtime/hermes-runtime-slash-command.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { HermesSessionItem } from "../hermes-session-store.js";
|
|
2
|
+
export declare function listHermesSessionsFromStateDb(): Promise<HermesSessionItem[] | undefined>;
|
|
3
|
+
export declare function exportHermesSessionFromStateDb(sessionId: string): Promise<Record<string, unknown> | undefined>;
|
|
4
|
+
export declare function buildEmptyHermesHistoryExport(sessionIdentity: string | undefined): Record<string, unknown>;
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import { execFile as execFileCb } from "node:child_process";
|
|
2
|
+
import { existsSync } from "node:fs";
|
|
3
|
+
import { homedir } from "node:os";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { promisify } from "node:util";
|
|
6
|
+
import { HERMES_HOME_DIR, SUBPROCESS_ENV, } from "./hermes-runtime-process.js";
|
|
7
|
+
import { stringValue, toRecord } from "./hermes-runtime-values.js";
|
|
8
|
+
const execFile = promisify(execFileCb);
|
|
9
|
+
const HERMES_STATE_DB_QUERY_TIMEOUT_MS = 5_000;
|
|
10
|
+
const HERMES_STATE_DB_LIST_LIMIT = 200;
|
|
11
|
+
const HERMES_STATE_DB_SCRIPT = String.raw `
|
|
12
|
+
import datetime
|
|
13
|
+
import json
|
|
14
|
+
import sqlite3
|
|
15
|
+
import sys
|
|
16
|
+
|
|
17
|
+
mode = sys.argv[1]
|
|
18
|
+
db_path = sys.argv[2]
|
|
19
|
+
|
|
20
|
+
def to_iso(value):
|
|
21
|
+
if value is None:
|
|
22
|
+
return None
|
|
23
|
+
try:
|
|
24
|
+
timestamp = float(value)
|
|
25
|
+
except Exception:
|
|
26
|
+
return None
|
|
27
|
+
return datetime.datetime.fromtimestamp(timestamp, datetime.timezone.utc).isoformat().replace("+00:00", "Z")
|
|
28
|
+
|
|
29
|
+
def row_dict(row):
|
|
30
|
+
return {key: row[key] for key in row.keys()}
|
|
31
|
+
|
|
32
|
+
def connect():
|
|
33
|
+
conn = sqlite3.connect(f"file:{db_path}?mode=ro", uri=True, timeout=1.0)
|
|
34
|
+
conn.row_factory = sqlite3.Row
|
|
35
|
+
conn.execute("PRAGMA query_only=ON")
|
|
36
|
+
return conn
|
|
37
|
+
|
|
38
|
+
try:
|
|
39
|
+
conn = connect()
|
|
40
|
+
if mode == "list":
|
|
41
|
+
rows = conn.execute("""
|
|
42
|
+
SELECT
|
|
43
|
+
s.id,
|
|
44
|
+
s.title,
|
|
45
|
+
s.model,
|
|
46
|
+
s.started_at,
|
|
47
|
+
s.ended_at,
|
|
48
|
+
s.message_count,
|
|
49
|
+
(
|
|
50
|
+
SELECT content FROM messages
|
|
51
|
+
WHERE session_id = s.id AND role = 'user' AND COALESCE(active, 1) != 0
|
|
52
|
+
ORDER BY id ASC LIMIT 1
|
|
53
|
+
) AS first_user_content,
|
|
54
|
+
(
|
|
55
|
+
SELECT content FROM messages
|
|
56
|
+
WHERE session_id = s.id AND COALESCE(active, 1) != 0
|
|
57
|
+
ORDER BY id DESC LIMIT 1
|
|
58
|
+
) AS latest_content,
|
|
59
|
+
(
|
|
60
|
+
SELECT timestamp FROM messages
|
|
61
|
+
WHERE session_id = s.id AND COALESCE(active, 1) != 0
|
|
62
|
+
ORDER BY id DESC LIMIT 1
|
|
63
|
+
) AS latest_message_at
|
|
64
|
+
FROM sessions s
|
|
65
|
+
WHERE COALESCE(s.archived, 0) = 0
|
|
66
|
+
ORDER BY COALESCE(latest_message_at, s.ended_at, s.started_at) DESC
|
|
67
|
+
LIMIT ?
|
|
68
|
+
""", (int(sys.argv[3]),)).fetchall()
|
|
69
|
+
payload = []
|
|
70
|
+
for row in rows:
|
|
71
|
+
last_active = row["latest_message_at"] if row["latest_message_at"] is not None else row["ended_at"]
|
|
72
|
+
if last_active is None:
|
|
73
|
+
last_active = row["started_at"]
|
|
74
|
+
payload.append({
|
|
75
|
+
"id": row["id"],
|
|
76
|
+
"title": row["title"],
|
|
77
|
+
"model": row["model"],
|
|
78
|
+
"preview": row["latest_content"] or row["first_user_content"] or row["title"] or row["id"],
|
|
79
|
+
"lastActivityAt": to_iso(last_active),
|
|
80
|
+
})
|
|
81
|
+
print(json.dumps({"ok": True, "payload": payload}, ensure_ascii=False))
|
|
82
|
+
elif mode == "export":
|
|
83
|
+
session_id = sys.argv[3]
|
|
84
|
+
session = conn.execute("SELECT * FROM sessions WHERE id = ?", (session_id,)).fetchone()
|
|
85
|
+
if session is None:
|
|
86
|
+
print(json.dumps({"ok": True, "payload": None}, ensure_ascii=False))
|
|
87
|
+
else:
|
|
88
|
+
data = row_dict(session)
|
|
89
|
+
data["sessionId"] = session_id
|
|
90
|
+
data["session_id"] = session_id
|
|
91
|
+
messages = []
|
|
92
|
+
for message in conn.execute("""
|
|
93
|
+
SELECT * FROM messages
|
|
94
|
+
WHERE session_id = ? AND COALESCE(active, 1) != 0
|
|
95
|
+
ORDER BY id ASC
|
|
96
|
+
""", (session_id,)).fetchall():
|
|
97
|
+
item = row_dict(message)
|
|
98
|
+
item["id"] = str(item.get("id"))
|
|
99
|
+
item["createdAt"] = to_iso(item.get("timestamp"))
|
|
100
|
+
messages.append(item)
|
|
101
|
+
data["messages"] = messages
|
|
102
|
+
print(json.dumps({"ok": True, "payload": data}, ensure_ascii=False))
|
|
103
|
+
else:
|
|
104
|
+
print(json.dumps({"ok": False, "error": "unsupported mode"}, ensure_ascii=False))
|
|
105
|
+
except Exception as exc:
|
|
106
|
+
print(json.dumps({"ok": False, "error": str(exc)}, ensure_ascii=False))
|
|
107
|
+
`;
|
|
108
|
+
export async function listHermesSessionsFromStateDb() {
|
|
109
|
+
const payload = await runHermesStateDbQuery("list", [String(HERMES_STATE_DB_LIST_LIMIT)]);
|
|
110
|
+
if (!Array.isArray(payload)) {
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
return payload.flatMap((entry) => {
|
|
114
|
+
const record = toRecord(entry);
|
|
115
|
+
const hermesSessionId = stringValue(record.id);
|
|
116
|
+
if (!hermesSessionId) {
|
|
117
|
+
return [];
|
|
118
|
+
}
|
|
119
|
+
const title = cleanHermesStateDbPreview(stringValue(record.title));
|
|
120
|
+
const preview = cleanHermesStateDbPreview(stringValue(record.preview));
|
|
121
|
+
return [{
|
|
122
|
+
sessionKey: `hermes:${hermesSessionId}`,
|
|
123
|
+
hermesSessionId,
|
|
124
|
+
displayName: title ?? preview ?? hermesSessionId,
|
|
125
|
+
derivedTitle: title ?? preview,
|
|
126
|
+
label: preview,
|
|
127
|
+
lastActivityAt: stringValue(record.lastActivityAt),
|
|
128
|
+
kind: "hermes",
|
|
129
|
+
}];
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
export async function exportHermesSessionFromStateDb(sessionId) {
|
|
133
|
+
const normalized = sessionId.trim();
|
|
134
|
+
if (!normalized) {
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
const payload = await runHermesStateDbQuery("export", [normalized]);
|
|
138
|
+
return payload && typeof payload === "object" && !Array.isArray(payload)
|
|
139
|
+
? payload
|
|
140
|
+
: undefined;
|
|
141
|
+
}
|
|
142
|
+
export function buildEmptyHermesHistoryExport(sessionIdentity) {
|
|
143
|
+
return {
|
|
144
|
+
sessionId: sessionIdentity?.trim() || "main",
|
|
145
|
+
messages: [],
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function resolveHermesStateDbPath() {
|
|
149
|
+
const explicit = process.env.CLAWCONNECT_HERMES_STATE_DB?.trim();
|
|
150
|
+
if (explicit) {
|
|
151
|
+
return explicit;
|
|
152
|
+
}
|
|
153
|
+
if (process.env.HERMES_BIN?.trim()) {
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
return join(process.env.HERMES_HOME?.trim() || HERMES_HOME_DIR, "state.db");
|
|
157
|
+
}
|
|
158
|
+
function resolveHermesStateDbPython() {
|
|
159
|
+
const explicit = process.env.HERMES_PYTHON?.trim();
|
|
160
|
+
if (explicit) {
|
|
161
|
+
return explicit;
|
|
162
|
+
}
|
|
163
|
+
const venvPython = join(process.env.HERMES_HOME?.trim() || HERMES_HOME_DIR, "hermes-agent", "venv", "bin", "python");
|
|
164
|
+
return existsSync(venvPython) ? venvPython : "python3";
|
|
165
|
+
}
|
|
166
|
+
async function runHermesStateDbQuery(mode, args) {
|
|
167
|
+
const dbPath = resolveHermesStateDbPath();
|
|
168
|
+
if (!dbPath || !existsSync(dbPath)) {
|
|
169
|
+
return undefined;
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
const { stdout } = await execFile(resolveHermesStateDbPython(), ["-c", HERMES_STATE_DB_SCRIPT, mode, dbPath, ...args], {
|
|
173
|
+
cwd: homedir(),
|
|
174
|
+
encoding: "utf8",
|
|
175
|
+
env: { ...SUBPROCESS_ENV, ...process.env },
|
|
176
|
+
timeout: HERMES_STATE_DB_QUERY_TIMEOUT_MS,
|
|
177
|
+
});
|
|
178
|
+
const parsed = JSON.parse(stdout.trim());
|
|
179
|
+
return parsed.ok === true ? parsed.payload : undefined;
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
function cleanHermesStateDbPreview(value) {
|
|
186
|
+
const clean = value
|
|
187
|
+
?.replace(/\[Hermes runtime context][\s\S]*$/i, "")
|
|
188
|
+
.replace(/\[ClawConnect mobile bridge][\s\S]*$/i, "")
|
|
189
|
+
.replace(/\s+/g, " ")
|
|
190
|
+
.trim();
|
|
191
|
+
return clean || undefined;
|
|
192
|
+
}
|
|
193
|
+
//# sourceMappingURL=hermes-runtime-state-db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hermes-runtime-state-db.js","sourceRoot":"","sources":["../../../src/hermes/runtime/hermes-runtime-state-db.ts"],"names":[],"mappings":"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"}
|