clawconnect-agent 0.1.0
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/.env.example +41 -0
- package/README.md +259 -0
- package/README.zh-CN.md +329 -0
- package/dist/commands/backup-manager.d.ts +21 -0
- package/dist/commands/backup-manager.js +346 -0
- package/dist/commands/backup-manager.js.map +1 -0
- package/dist/commands/install.d.ts +6 -0
- package/dist/commands/install.js +107 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/local-handlers.d.ts +2 -0
- package/dist/commands/local-handlers.js +375 -0
- package/dist/commands/local-handlers.js.map +1 -0
- package/dist/commands/local-runtime.d.ts +36 -0
- package/dist/commands/local-runtime.js +445 -0
- package/dist/commands/local-runtime.js.map +1 -0
- package/dist/commands/pair.d.ts +7 -0
- package/dist/commands/pair.js +100 -0
- package/dist/commands/pair.js.map +1 -0
- package/dist/commands/provider-config.d.ts +35 -0
- package/dist/commands/provider-config.js +291 -0
- package/dist/commands/provider-config.js.map +1 -0
- package/dist/commands/provider-handlers.d.ts +2 -0
- package/dist/commands/provider-handlers.js +216 -0
- package/dist/commands/provider-handlers.js.map +1 -0
- package/dist/commands/provider-registry.d.ts +19 -0
- package/dist/commands/provider-registry.js +120 -0
- package/dist/commands/provider-registry.js.map +1 -0
- package/dist/commands/run.d.ts +1 -0
- package/dist/commands/run.js +35 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/send-file-utils.d.ts +6 -0
- package/dist/commands/send-file-utils.js +94 -0
- package/dist/commands/send-file-utils.js.map +1 -0
- package/dist/commands/send-file.d.ts +41 -0
- package/dist/commands/send-file.js +492 -0
- package/dist/commands/send-file.js.map +1 -0
- package/dist/commands/set-token.d.ts +1 -0
- package/dist/commands/set-token.js +43 -0
- package/dist/commands/set-token.js.map +1 -0
- package/dist/commands/status.d.ts +1 -0
- package/dist/commands/status.js +135 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/voice-reply.d.ts +39 -0
- package/dist/commands/voice-reply.js +329 -0
- package/dist/commands/voice-reply.js.map +1 -0
- package/dist/config/config.d.ts +32 -0
- package/dist/config/config.js +103 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/env.d.ts +16 -0
- package/dist/config/env.js +138 -0
- package/dist/config/env.js.map +1 -0
- package/dist/i18n/index.d.ts +1 -0
- package/dist/i18n/index.js +147 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +117 -0
- package/dist/index.js.map +1 -0
- package/dist/platform/service-manager-common.d.ts +26 -0
- package/dist/platform/service-manager-common.js +51 -0
- package/dist/platform/service-manager-common.js.map +1 -0
- package/dist/platform/service-manager-linux.d.ts +6 -0
- package/dist/platform/service-manager-linux.js +229 -0
- package/dist/platform/service-manager-linux.js.map +1 -0
- package/dist/platform/service-manager.d.ts +16 -0
- package/dist/platform/service-manager.js +165 -0
- package/dist/platform/service-manager.js.map +1 -0
- package/dist/relay/attachment-staging.d.ts +12 -0
- package/dist/relay/attachment-staging.js +116 -0
- package/dist/relay/attachment-staging.js.map +1 -0
- package/dist/relay/chat-history.d.ts +29 -0
- package/dist/relay/chat-history.js +69 -0
- package/dist/relay/chat-history.js.map +1 -0
- package/dist/relay/chat-payload.d.ts +6 -0
- package/dist/relay/chat-payload.js +170 -0
- package/dist/relay/chat-payload.js.map +1 -0
- package/dist/relay/chat-send-attachments.d.ts +4 -0
- package/dist/relay/chat-send-attachments.js +47 -0
- package/dist/relay/chat-send-attachments.js.map +1 -0
- package/dist/relay/gateway-client.d.ts +41 -0
- package/dist/relay/gateway-client.js +288 -0
- package/dist/relay/gateway-client.js.map +1 -0
- package/dist/relay/office-payload.d.ts +19 -0
- package/dist/relay/office-payload.js +205 -0
- package/dist/relay/office-payload.js.map +1 -0
- package/dist/relay/reconnect.d.ts +14 -0
- package/dist/relay/reconnect.js +27 -0
- package/dist/relay/reconnect.js.map +1 -0
- package/dist/relay/relay-manager.d.ts +36 -0
- package/dist/relay/relay-manager.js +619 -0
- package/dist/relay/relay-manager.js.map +1 -0
- package/dist/relay/session-context.d.ts +19 -0
- package/dist/relay/session-context.js +323 -0
- package/dist/relay/session-context.js.map +1 -0
- package/dist/relay/slash-command-catalog.d.ts +8 -0
- package/dist/relay/slash-command-catalog.generated.d.ts +226 -0
- package/dist/relay/slash-command-catalog.generated.js +275 -0
- package/dist/relay/slash-command-catalog.generated.js.map +1 -0
- package/dist/relay/slash-command-catalog.js +3 -0
- package/dist/relay/slash-command-catalog.js.map +1 -0
- package/dist/relay/voice-reply-preference.d.ts +25 -0
- package/dist/relay/voice-reply-preference.js +103 -0
- package/dist/relay/voice-reply-preference.js.map +1 -0
- package/package.json +50 -0
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "fs";
|
|
2
|
+
import { configExists, readConfig, readGatewayUrl } from "../config/config.js";
|
|
3
|
+
import { t } from "../i18n/index.js";
|
|
4
|
+
import { getServiceStatus } from "../platform/service-manager.js";
|
|
5
|
+
export function statusCommand() {
|
|
6
|
+
console.log(t("status.title"));
|
|
7
|
+
if (!configExists()) {
|
|
8
|
+
console.log(t("status.notPaired"));
|
|
9
|
+
}
|
|
10
|
+
else {
|
|
11
|
+
try {
|
|
12
|
+
const config = readConfig();
|
|
13
|
+
console.log(t("status.paired"));
|
|
14
|
+
console.log(t("status.displayName", config.displayName));
|
|
15
|
+
console.log(t("status.gatewayId", config.gatewayId));
|
|
16
|
+
console.log(t("status.relayServer", config.relayServerUrl));
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
console.log(t("status.configCorrupted"));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
console.log(t("status.gateway", readGatewayUrl()));
|
|
23
|
+
const service = getServiceStatus();
|
|
24
|
+
if (service.platform === "unsupported") {
|
|
25
|
+
console.log(t("status.serviceUnsupported", process.platform));
|
|
26
|
+
console.log("");
|
|
27
|
+
return;
|
|
28
|
+
}
|
|
29
|
+
console.log(t("status.servicePlatform", service.manager));
|
|
30
|
+
if (!service.installed) {
|
|
31
|
+
console.log(t("status.serviceNotInstalled"));
|
|
32
|
+
}
|
|
33
|
+
else if (service.running) {
|
|
34
|
+
console.log(t("status.serviceRunning", service.manager));
|
|
35
|
+
console.log(t("status.serviceLog", service.logPath));
|
|
36
|
+
const health = readHealth(service.logPath);
|
|
37
|
+
console.log(formatHealthLine("status.relayHealth", health.relay));
|
|
38
|
+
console.log(formatHealthLine("status.gatewayHealth", health.gateway));
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
console.log(t("status.serviceNotRunning"));
|
|
42
|
+
if (service.servicePath) {
|
|
43
|
+
console.log(t("status.serviceFile", service.servicePath));
|
|
44
|
+
}
|
|
45
|
+
if (service.startHint) {
|
|
46
|
+
console.log(t("status.serviceStart", service.startHint));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
console.log("");
|
|
50
|
+
}
|
|
51
|
+
function readHealth(logPath) {
|
|
52
|
+
if (!existsSync(logPath)) {
|
|
53
|
+
return {
|
|
54
|
+
relay: { kind: "unknown", detail: "log missing" },
|
|
55
|
+
gateway: { kind: "unknown", detail: "log missing" },
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
const lines = readTailLines(logPath, 400);
|
|
59
|
+
return {
|
|
60
|
+
relay: parseRelayHealth(lines),
|
|
61
|
+
gateway: parseGatewayHealth(lines),
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
function readTailLines(path, maxLines) {
|
|
65
|
+
const raw = readFileSync(path, "utf-8");
|
|
66
|
+
const lines = raw.split(/\r?\n/).filter(Boolean);
|
|
67
|
+
return lines.slice(-maxLines);
|
|
68
|
+
}
|
|
69
|
+
function parseRelayHealth(lines) {
|
|
70
|
+
const connectedIndex = findLastIndex(lines, (line) => line.includes("Relay connected."));
|
|
71
|
+
const disconnectedIndex = findLastIndex(lines, (line) => line.includes("Relay disconnected.") || line.includes("Relay connection closed:"));
|
|
72
|
+
if (connectedIndex === -1 && disconnectedIndex === -1) {
|
|
73
|
+
return { kind: "unknown", detail: "no relay events yet" };
|
|
74
|
+
}
|
|
75
|
+
if (connectedIndex > disconnectedIndex) {
|
|
76
|
+
return { kind: "ok", detail: "connected" };
|
|
77
|
+
}
|
|
78
|
+
const line = disconnectedIndex >= 0 ? lines[disconnectedIndex] : "";
|
|
79
|
+
const detail = line.includes("Relay connection closed:")
|
|
80
|
+
? line.replace(/^.*Relay connection closed:\s*/, "").trim()
|
|
81
|
+
: "disconnected";
|
|
82
|
+
return { kind: "error", detail };
|
|
83
|
+
}
|
|
84
|
+
function parseGatewayHealth(lines) {
|
|
85
|
+
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
86
|
+
const line = lines[i];
|
|
87
|
+
if (line.includes("Gateway connected.")) {
|
|
88
|
+
return { kind: "ok", detail: "connected" };
|
|
89
|
+
}
|
|
90
|
+
if (line.includes("Gateway disconnected:")) {
|
|
91
|
+
return {
|
|
92
|
+
kind: classifyGatewayDetail(line),
|
|
93
|
+
detail: line.replace(/^.*Gateway disconnected:\s*/, "").trim(),
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (line.includes("[gateway-client] connect failed:")) {
|
|
97
|
+
return {
|
|
98
|
+
kind: "error",
|
|
99
|
+
detail: line.replace(/^.*connect failed:\s*/, "").trim(),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
if (line.includes("[gateway-client] ws error:")) {
|
|
103
|
+
return {
|
|
104
|
+
kind: "error",
|
|
105
|
+
detail: line.replace(/^.*ws error:\s*/, "").trim(),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return { kind: "unknown", detail: "no gateway events yet" };
|
|
110
|
+
}
|
|
111
|
+
function classifyGatewayDetail(line) {
|
|
112
|
+
const detail = line.toLowerCase();
|
|
113
|
+
if (detail.includes("unauthorized") || detail.includes("mismatch") || detail.includes("not allowed")) {
|
|
114
|
+
return "error";
|
|
115
|
+
}
|
|
116
|
+
if (detail.includes("tick timeout") || detail.includes("service restart")) {
|
|
117
|
+
return "warn";
|
|
118
|
+
}
|
|
119
|
+
return "warn";
|
|
120
|
+
}
|
|
121
|
+
function findLastIndex(lines, predicate) {
|
|
122
|
+
for (let i = lines.length - 1; i >= 0; i -= 1) {
|
|
123
|
+
if (predicate(lines[i]))
|
|
124
|
+
return i;
|
|
125
|
+
}
|
|
126
|
+
return -1;
|
|
127
|
+
}
|
|
128
|
+
function formatHealthLine(key, state) {
|
|
129
|
+
const icon = state.kind === "ok" ? "✓"
|
|
130
|
+
: state.kind === "warn" ? "⚠"
|
|
131
|
+
: state.kind === "error" ? "✗"
|
|
132
|
+
: "-";
|
|
133
|
+
return t(key, icon, state.detail ?? "");
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { sendFileCommand, type SendFileCommandOptions, type SendFileCommandDependencies } from "./send-file.js";
|
|
2
|
+
export interface VoiceReplyCommandOptions extends Pick<SendFileCommandOptions, "gateway" | "session"> {
|
|
3
|
+
text: string;
|
|
4
|
+
voice?: string;
|
|
5
|
+
rate?: string;
|
|
6
|
+
speaker?: "system" | "espeak";
|
|
7
|
+
}
|
|
8
|
+
export interface VoiceReplyCommandDependencies extends SendFileCommandDependencies {
|
|
9
|
+
sendFileCommandImpl?: typeof sendFileCommand;
|
|
10
|
+
synthesizeEdgeTtsImpl?: typeof synthesizeWithEdgeTts;
|
|
11
|
+
synthesizeSystemTtsImpl?: typeof synthesizeWithSystemTts;
|
|
12
|
+
}
|
|
13
|
+
export interface VoiceReplyCommandResult {
|
|
14
|
+
audioPath: string;
|
|
15
|
+
durationMs: number;
|
|
16
|
+
sendFileResult: Awaited<ReturnType<typeof sendFileCommand>>;
|
|
17
|
+
}
|
|
18
|
+
export declare function sendVoiceReplyCommand(opts: VoiceReplyCommandOptions, deps?: VoiceReplyCommandDependencies): Promise<VoiceReplyCommandResult>;
|
|
19
|
+
export declare function synthesizeVoiceReplyAudio(opts: {
|
|
20
|
+
text: string;
|
|
21
|
+
audioPath: string;
|
|
22
|
+
voice?: string;
|
|
23
|
+
rate?: string;
|
|
24
|
+
speaker?: "system" | "espeak";
|
|
25
|
+
}, deps?: Pick<VoiceReplyCommandDependencies, "synthesizeEdgeTtsImpl" | "synthesizeSystemTtsImpl">): Promise<void>;
|
|
26
|
+
declare function synthesizeWithEdgeTts(opts: {
|
|
27
|
+
text: string;
|
|
28
|
+
audioPath: string;
|
|
29
|
+
voice?: string;
|
|
30
|
+
rate?: string;
|
|
31
|
+
}): Promise<void>;
|
|
32
|
+
declare function synthesizeWithSystemTts(opts: {
|
|
33
|
+
text: string;
|
|
34
|
+
audioPath: string;
|
|
35
|
+
voice?: string;
|
|
36
|
+
rate?: string;
|
|
37
|
+
strict?: boolean;
|
|
38
|
+
}): Promise<void>;
|
|
39
|
+
export {};
|
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
import { execFile as execFileCb, execFileSync } from "child_process";
|
|
2
|
+
import { mkdtemp, rm, writeFile } from "fs/promises";
|
|
3
|
+
import { tmpdir } from "os";
|
|
4
|
+
import { join } from "path";
|
|
5
|
+
import { promisify } from "util";
|
|
6
|
+
import { sendFileCommand } from "./send-file.js";
|
|
7
|
+
const execFile = promisify(execFileCb);
|
|
8
|
+
export async function sendVoiceReplyCommand(opts, deps = {}) {
|
|
9
|
+
const originalText = normalizeVoiceText(opts.text);
|
|
10
|
+
if (!originalText) {
|
|
11
|
+
throw new Error("voice_reply_text_required");
|
|
12
|
+
}
|
|
13
|
+
const spokenText = stripVoiceReplyFormatting(originalText).replace(/\s+/g, " ").trim();
|
|
14
|
+
if (!spokenText) {
|
|
15
|
+
throw new Error("voice_reply_text_required");
|
|
16
|
+
}
|
|
17
|
+
const durationMs = estimateSpeechDurationMs(spokenText);
|
|
18
|
+
const tempDir = await mkdtemp(join(tmpdir(), "clawconnect-voice-reply-"));
|
|
19
|
+
const audioPath = join(tempDir, "reply.mp3");
|
|
20
|
+
try {
|
|
21
|
+
await synthesizeVoiceReplyAudio({
|
|
22
|
+
text: spokenText,
|
|
23
|
+
audioPath,
|
|
24
|
+
voice: opts.voice,
|
|
25
|
+
rate: opts.rate,
|
|
26
|
+
speaker: opts.speaker,
|
|
27
|
+
}, deps);
|
|
28
|
+
const sendFileResult = await (deps.sendFileCommandImpl ?? sendFileCommand)({
|
|
29
|
+
filePath: audioPath,
|
|
30
|
+
gateway: opts.gateway,
|
|
31
|
+
session: opts.session,
|
|
32
|
+
durationMs,
|
|
33
|
+
transcript: originalText,
|
|
34
|
+
}, deps);
|
|
35
|
+
return {
|
|
36
|
+
audioPath,
|
|
37
|
+
durationMs,
|
|
38
|
+
sendFileResult,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
throw error;
|
|
43
|
+
}
|
|
44
|
+
finally {
|
|
45
|
+
await rm(tempDir, { recursive: true, force: true });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
export async function synthesizeVoiceReplyAudio(opts, deps = {}) {
|
|
49
|
+
const synthesizeEdgeTts = deps.synthesizeEdgeTtsImpl ?? synthesizeWithEdgeTts;
|
|
50
|
+
const synthesizeSystemTts = deps.synthesizeSystemTtsImpl ?? synthesizeWithSystemTts;
|
|
51
|
+
if (opts.speaker === "espeak") {
|
|
52
|
+
await synthesizeSystemTts({
|
|
53
|
+
text: opts.text,
|
|
54
|
+
audioPath: opts.audioPath,
|
|
55
|
+
voice: opts.voice,
|
|
56
|
+
rate: opts.rate,
|
|
57
|
+
strict: true,
|
|
58
|
+
});
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (opts.speaker === "system") {
|
|
62
|
+
await synthesizeSystemTts({
|
|
63
|
+
text: opts.text,
|
|
64
|
+
audioPath: opts.audioPath,
|
|
65
|
+
voice: opts.voice,
|
|
66
|
+
rate: opts.rate,
|
|
67
|
+
strict: true,
|
|
68
|
+
});
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
await synthesizeEdgeTts({
|
|
73
|
+
text: opts.text,
|
|
74
|
+
audioPath: opts.audioPath,
|
|
75
|
+
voice: opts.voice,
|
|
76
|
+
rate: opts.rate,
|
|
77
|
+
});
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
catch (edgeError) {
|
|
81
|
+
console.warn(`[voice-reply] edge-tts-universal failed, falling back to system TTS: ${String(edgeError)}`);
|
|
82
|
+
}
|
|
83
|
+
await synthesizeSystemTts({
|
|
84
|
+
text: opts.text,
|
|
85
|
+
audioPath: opts.audioPath,
|
|
86
|
+
voice: opts.voice,
|
|
87
|
+
rate: opts.rate,
|
|
88
|
+
strict: false,
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
async function synthesizeWithEdgeTts(opts) {
|
|
92
|
+
const { EdgeTTS } = await import("edge-tts-universal");
|
|
93
|
+
const tts = new EdgeTTS(opts.text, resolveEdgeVoice(opts.text, opts.voice), resolveEdgeProsody(opts.rate));
|
|
94
|
+
const result = await tts.synthesize();
|
|
95
|
+
const audioBuffer = Buffer.from(await result.audio.arrayBuffer());
|
|
96
|
+
await writeFile(opts.audioPath, audioBuffer);
|
|
97
|
+
}
|
|
98
|
+
async function synthesizeWithSystemTts(opts) {
|
|
99
|
+
if (process.platform === "darwin") {
|
|
100
|
+
try {
|
|
101
|
+
await synthesizeWithSay(opts.text, opts.audioPath, resolveSystemVoice(opts.text, opts.voice), resolveSystemSpeechRate(opts.rate));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
if (opts.strict) {
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
await synthesizeWithEspeak(opts.text, opts.audioPath, resolveSystemSpeechRate(opts.rate));
|
|
111
|
+
}
|
|
112
|
+
async function synthesizeWithSay(text, audioPath, voice, rate) {
|
|
113
|
+
const args = ["-o", audioPath];
|
|
114
|
+
if (voice && voice.trim()) {
|
|
115
|
+
args.push("-v", voice.trim());
|
|
116
|
+
}
|
|
117
|
+
if (typeof rate === "number" && Number.isFinite(rate)) {
|
|
118
|
+
args.push("-r", String(Math.max(80, Math.min(500, Math.round(rate)))));
|
|
119
|
+
}
|
|
120
|
+
args.push(text);
|
|
121
|
+
await execFile("say", args);
|
|
122
|
+
}
|
|
123
|
+
async function synthesizeWithEspeak(text, audioPath, rate) {
|
|
124
|
+
try {
|
|
125
|
+
const args = ["-w", audioPath];
|
|
126
|
+
if (typeof rate === "number" && Number.isFinite(rate)) {
|
|
127
|
+
args.push("-s", String(Math.max(80, Math.min(450, Math.round(rate)))));
|
|
128
|
+
}
|
|
129
|
+
args.push(text);
|
|
130
|
+
await execFile("espeak-ng", args);
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
const args = ["-w", audioPath];
|
|
135
|
+
if (typeof rate === "number" && Number.isFinite(rate)) {
|
|
136
|
+
args.push("-s", String(Math.max(80, Math.min(450, Math.round(rate)))));
|
|
137
|
+
}
|
|
138
|
+
args.push(text);
|
|
139
|
+
await execFile("espeak", args);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function resolveEdgeVoice(text, voice) {
|
|
143
|
+
const preferredVoice = voice?.trim();
|
|
144
|
+
if (preferredVoice && looksLikeEdgeVoice(preferredVoice)) {
|
|
145
|
+
return preferredVoice;
|
|
146
|
+
}
|
|
147
|
+
return defaultEdgeVoice(text);
|
|
148
|
+
}
|
|
149
|
+
function resolveEdgeProsody(rate) {
|
|
150
|
+
const percent = parseRatePercent(rate);
|
|
151
|
+
if (percent === undefined || percent === 0) {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
return {
|
|
155
|
+
rate: formatRatePercent(percent),
|
|
156
|
+
volume: "+0%",
|
|
157
|
+
pitch: "+0Hz",
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function resolveSystemVoice(text, voice) {
|
|
161
|
+
const preferredVoice = voice?.trim();
|
|
162
|
+
if (preferredVoice && !looksLikeEdgeVoice(preferredVoice)) {
|
|
163
|
+
return preferredVoice;
|
|
164
|
+
}
|
|
165
|
+
if (preferredVoice) {
|
|
166
|
+
const mappedVoice = mapEdgeVoiceToSystemVoice(preferredVoice);
|
|
167
|
+
if (mappedVoice) {
|
|
168
|
+
return mappedVoice;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return defaultMacVoice(text);
|
|
172
|
+
}
|
|
173
|
+
function resolveSystemSpeechRate(rate) {
|
|
174
|
+
const percent = parseRatePercent(rate);
|
|
175
|
+
if (percent === undefined || percent === 0) {
|
|
176
|
+
return undefined;
|
|
177
|
+
}
|
|
178
|
+
const baseRate = 200;
|
|
179
|
+
return Math.max(80, Math.min(500, Math.round(baseRate * (1 + percent / 100))));
|
|
180
|
+
}
|
|
181
|
+
function looksLikeEdgeVoice(voice) {
|
|
182
|
+
return /Neural$/i.test(voice);
|
|
183
|
+
}
|
|
184
|
+
function defaultEdgeVoice(text) {
|
|
185
|
+
if (containsCjk(text)) {
|
|
186
|
+
return "zh-CN-XiaoxiaoNeural";
|
|
187
|
+
}
|
|
188
|
+
return "en-US-EmmaMultilingualNeural";
|
|
189
|
+
}
|
|
190
|
+
function defaultMacVoice(text) {
|
|
191
|
+
if (!containsCjk(text)) {
|
|
192
|
+
return undefined;
|
|
193
|
+
}
|
|
194
|
+
return process.env.OPENCLAW_TTS_VOICE?.trim() || "Ting-Ting";
|
|
195
|
+
}
|
|
196
|
+
function mapEdgeVoiceToSystemVoice(voice) {
|
|
197
|
+
const normalized = voice.trim().toLowerCase();
|
|
198
|
+
if (normalized.includes("yunxi")) {
|
|
199
|
+
return findSystemVoice([
|
|
200
|
+
"Eddy (中文(中国大陆))",
|
|
201
|
+
"Eddy (中文(台湾))",
|
|
202
|
+
"Grandpa (中文(中国大陆))",
|
|
203
|
+
"Grandpa (中文(台湾))",
|
|
204
|
+
"Daniel",
|
|
205
|
+
"Fred",
|
|
206
|
+
"Aman",
|
|
207
|
+
"Albert",
|
|
208
|
+
]);
|
|
209
|
+
}
|
|
210
|
+
if (normalized.includes("xiaoxiao")) {
|
|
211
|
+
return findSystemVoice([
|
|
212
|
+
"Flo (中文(中国大陆))",
|
|
213
|
+
"Flo (中文(台湾))",
|
|
214
|
+
"Grandma (中文(中国大陆))",
|
|
215
|
+
"Grandma (中文(台湾))",
|
|
216
|
+
"Samantha",
|
|
217
|
+
"Moira",
|
|
218
|
+
"Victoria",
|
|
219
|
+
]);
|
|
220
|
+
}
|
|
221
|
+
if (normalized.includes("andrew")) {
|
|
222
|
+
return findSystemVoice([
|
|
223
|
+
"Fred",
|
|
224
|
+
"Daniel",
|
|
225
|
+
"Aman",
|
|
226
|
+
"Albert",
|
|
227
|
+
"Eddy (英语(美国))",
|
|
228
|
+
"Grandpa (英语(美国))",
|
|
229
|
+
]);
|
|
230
|
+
}
|
|
231
|
+
if (normalized.includes("emma")) {
|
|
232
|
+
return findSystemVoice([
|
|
233
|
+
"Samantha",
|
|
234
|
+
"Victoria",
|
|
235
|
+
"Flo (英语(美国))",
|
|
236
|
+
"Flo (英语(英国))",
|
|
237
|
+
"Flo",
|
|
238
|
+
"Grandma (英语(美国))",
|
|
239
|
+
]);
|
|
240
|
+
}
|
|
241
|
+
return undefined;
|
|
242
|
+
}
|
|
243
|
+
function findSystemVoice(candidates) {
|
|
244
|
+
const available = getSystemVoiceNames();
|
|
245
|
+
for (const candidate of candidates) {
|
|
246
|
+
if (available.has(candidate)) {
|
|
247
|
+
return candidate;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return undefined;
|
|
251
|
+
}
|
|
252
|
+
let systemVoiceNamesCache = null;
|
|
253
|
+
function getSystemVoiceNames() {
|
|
254
|
+
if (systemVoiceNamesCache) {
|
|
255
|
+
return systemVoiceNamesCache;
|
|
256
|
+
}
|
|
257
|
+
if (process.platform !== "darwin") {
|
|
258
|
+
systemVoiceNamesCache = new Set();
|
|
259
|
+
return systemVoiceNamesCache;
|
|
260
|
+
}
|
|
261
|
+
try {
|
|
262
|
+
const output = execFileSync("say", ["-v", "?"], { encoding: "utf-8" });
|
|
263
|
+
const names = new Set(output
|
|
264
|
+
.split(/\r?\n/)
|
|
265
|
+
.map((line) => line.trim())
|
|
266
|
+
.filter(Boolean)
|
|
267
|
+
.map((line) => line.split(/\s{2,}/)[0]?.trim())
|
|
268
|
+
.filter((value) => typeof value === "string" && value.length > 0));
|
|
269
|
+
systemVoiceNamesCache = names;
|
|
270
|
+
return names;
|
|
271
|
+
}
|
|
272
|
+
catch {
|
|
273
|
+
systemVoiceNamesCache = new Set();
|
|
274
|
+
return systemVoiceNamesCache;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
function normalizeVoiceText(text) {
|
|
278
|
+
return text.replace(/\s+/g, " ").trim();
|
|
279
|
+
}
|
|
280
|
+
function stripVoiceReplyFormatting(text) {
|
|
281
|
+
return stripMarkdownFormatting(stripEmoji(text));
|
|
282
|
+
}
|
|
283
|
+
function stripMarkdownFormatting(text) {
|
|
284
|
+
return text
|
|
285
|
+
.replace(/!\[([^\]]*)\]\((?:[^()\\]|\\.|(?:\([^()]*\)))*\)/g, "$1")
|
|
286
|
+
.replace(/\[([^\]]+)\]\((?:[^()\\]|\\.|(?:\([^()]*\)))*\)/g, "$1")
|
|
287
|
+
.replace(/```([\s\S]*?)```/g, "$1")
|
|
288
|
+
.replace(/`([^`]+)`/g, "$1")
|
|
289
|
+
.replace(/^#{1,6}\s+/gm, "")
|
|
290
|
+
.replace(/^>\s?/gm, "")
|
|
291
|
+
.replace(/^\s*[-*+]\s+/gm, "")
|
|
292
|
+
.replace(/^\s*\d+[.)]\s+/gm, "")
|
|
293
|
+
.replace(/(\*\*|__)(.*?)\1/g, "$2")
|
|
294
|
+
.replace(/(\*|_)(.*?)\1/g, "$2")
|
|
295
|
+
.replace(/~~(.*?)~~/g, "$1")
|
|
296
|
+
.replace(/[>*_`~]/g, "");
|
|
297
|
+
}
|
|
298
|
+
function stripEmoji(text) {
|
|
299
|
+
return text.replace(/(?:\p{Extended_Pictographic}(?:\uFE0F|\uFE0E)?(?:\u200D\p{Extended_Pictographic}(?:\uFE0F|\uFE0E)?)*)|(?:[\u{1F1E6}-\u{1F1FF}]{2})/gu, "");
|
|
300
|
+
}
|
|
301
|
+
function parseRatePercent(rate) {
|
|
302
|
+
const trimmed = rate?.trim();
|
|
303
|
+
if (!trimmed) {
|
|
304
|
+
return undefined;
|
|
305
|
+
}
|
|
306
|
+
const normalized = trimmed.endsWith("%") ? trimmed.slice(0, -1).trim() : trimmed;
|
|
307
|
+
const parsed = Number(normalized);
|
|
308
|
+
if (!Number.isFinite(parsed)) {
|
|
309
|
+
return undefined;
|
|
310
|
+
}
|
|
311
|
+
return parsed;
|
|
312
|
+
}
|
|
313
|
+
function formatRatePercent(ratePercent) {
|
|
314
|
+
if (ratePercent > 0) {
|
|
315
|
+
return `+${ratePercent}%`;
|
|
316
|
+
}
|
|
317
|
+
return `${ratePercent}%`;
|
|
318
|
+
}
|
|
319
|
+
function containsCjk(text) {
|
|
320
|
+
return /[\u3400-\u9fff]/.test(text);
|
|
321
|
+
}
|
|
322
|
+
function estimateSpeechDurationMs(text) {
|
|
323
|
+
const normalized = normalizeVoiceText(text);
|
|
324
|
+
if (!normalized) {
|
|
325
|
+
return 0;
|
|
326
|
+
}
|
|
327
|
+
return Math.max(1200, Math.round(normalized.length * 180));
|
|
328
|
+
}
|
|
329
|
+
//# sourceMappingURL=voice-reply.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"voice-reply.js","sourceRoot":"","sources":["../../src/commands/voice-reply.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export interface ClawConnectConfig {
|
|
2
|
+
relayServerUrl: string;
|
|
3
|
+
gatewayId: string;
|
|
4
|
+
relaySecret: string;
|
|
5
|
+
displayName: string;
|
|
6
|
+
assistantVoiceReplyVoiceIdentifier?: string;
|
|
7
|
+
assistantVoiceReplyRatePercent?: number;
|
|
8
|
+
/** Shared token for the local OpenClaw Gateway (gateway.auth.token in openclaw config). */
|
|
9
|
+
gatewayToken?: string;
|
|
10
|
+
/** Password for the local OpenClaw Gateway (used when auth mode is "password"). */
|
|
11
|
+
gatewayPassword?: string;
|
|
12
|
+
}
|
|
13
|
+
export interface VoiceReplyConfig {
|
|
14
|
+
voiceIdentifier?: string;
|
|
15
|
+
ratePercent?: number;
|
|
16
|
+
}
|
|
17
|
+
export declare function configExists(): boolean;
|
|
18
|
+
export declare function readConfig(): ClawConnectConfig;
|
|
19
|
+
export declare function writeConfig(config: ClawConnectConfig): void;
|
|
20
|
+
export declare function readVoiceReplyConfig(cfg: ClawConnectConfig): VoiceReplyConfig;
|
|
21
|
+
export declare function updateVoiceReplyConfig(config: ClawConnectConfig, voiceReplyConfig: VoiceReplyConfig): ClawConnectConfig;
|
|
22
|
+
export declare function readGatewayUrl(): string;
|
|
23
|
+
/**
|
|
24
|
+
* Reads the gateway token or password. Priority order:
|
|
25
|
+
* 1. ~/.clawconnect/config.json (gatewayToken / gatewayPassword)
|
|
26
|
+
* 2. ~/.openclaw/openclaw.json (gateway.token / gateway.auth.token)
|
|
27
|
+
* 3. Environment variables (OPENCLAW_GATEWAY_TOKEN / OPENCLAW_GATEWAY_PASSWORD)
|
|
28
|
+
*/
|
|
29
|
+
export declare function readGatewayAuth(cfg: ClawConnectConfig): {
|
|
30
|
+
token?: string;
|
|
31
|
+
password?: string;
|
|
32
|
+
};
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { chmodSync, readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { homedir } from "os";
|
|
4
|
+
import { DEFAULT_GATEWAY_URL, getConfiguredGatewayUrl } from "./env.js";
|
|
5
|
+
const CONFIG_DIR = join(homedir(), ".clawconnect");
|
|
6
|
+
const CONFIG_PATH = join(CONFIG_DIR, "config.json");
|
|
7
|
+
const OPENCLAW_CONFIG_PATH = join(homedir(), ".openclaw", "openclaw.json");
|
|
8
|
+
export function configExists() {
|
|
9
|
+
return existsSync(CONFIG_PATH);
|
|
10
|
+
}
|
|
11
|
+
export function readConfig() {
|
|
12
|
+
if (!existsSync(CONFIG_PATH)) {
|
|
13
|
+
throw new Error(`Config not found at ${CONFIG_PATH}. Run 'clawconnect pair' first.`);
|
|
14
|
+
}
|
|
15
|
+
const raw = readFileSync(CONFIG_PATH, "utf-8");
|
|
16
|
+
return JSON.parse(raw);
|
|
17
|
+
}
|
|
18
|
+
export function writeConfig(config) {
|
|
19
|
+
mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
|
|
20
|
+
writeFileSync(CONFIG_PATH, JSON.stringify(config, null, 2), { encoding: "utf-8", mode: 0o600 });
|
|
21
|
+
chmodSync(CONFIG_PATH, 0o600);
|
|
22
|
+
}
|
|
23
|
+
export function readVoiceReplyConfig(cfg) {
|
|
24
|
+
return {
|
|
25
|
+
voiceIdentifier: normalizeVoiceIdentifier(cfg.assistantVoiceReplyVoiceIdentifier),
|
|
26
|
+
ratePercent: clampRatePercent(cfg.assistantVoiceReplyRatePercent),
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function updateVoiceReplyConfig(config, voiceReplyConfig) {
|
|
30
|
+
const nextConfig = { ...config };
|
|
31
|
+
const voiceIdentifier = normalizeVoiceIdentifier(voiceReplyConfig.voiceIdentifier);
|
|
32
|
+
const ratePercent = clampRatePercent(voiceReplyConfig.ratePercent);
|
|
33
|
+
if (voiceIdentifier === undefined) {
|
|
34
|
+
delete nextConfig.assistantVoiceReplyVoiceIdentifier;
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
nextConfig.assistantVoiceReplyVoiceIdentifier = voiceIdentifier;
|
|
38
|
+
}
|
|
39
|
+
if (ratePercent === undefined) {
|
|
40
|
+
delete nextConfig.assistantVoiceReplyRatePercent;
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
nextConfig.assistantVoiceReplyRatePercent = ratePercent;
|
|
44
|
+
}
|
|
45
|
+
writeConfig(nextConfig);
|
|
46
|
+
return nextConfig;
|
|
47
|
+
}
|
|
48
|
+
export function readGatewayUrl() {
|
|
49
|
+
const configuredGatewayUrl = getConfiguredGatewayUrl();
|
|
50
|
+
if (configuredGatewayUrl) {
|
|
51
|
+
return configuredGatewayUrl;
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
const raw = readFileSync(OPENCLAW_CONFIG_PATH, "utf-8");
|
|
55
|
+
const json = JSON.parse(raw);
|
|
56
|
+
const port = json?.gateway?.port ?? 18789;
|
|
57
|
+
return `ws://localhost:${port}`;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return DEFAULT_GATEWAY_URL;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Reads the gateway token or password. Priority order:
|
|
65
|
+
* 1. ~/.clawconnect/config.json (gatewayToken / gatewayPassword)
|
|
66
|
+
* 2. ~/.openclaw/openclaw.json (gateway.token / gateway.auth.token)
|
|
67
|
+
* 3. Environment variables (OPENCLAW_GATEWAY_TOKEN / OPENCLAW_GATEWAY_PASSWORD)
|
|
68
|
+
*/
|
|
69
|
+
export function readGatewayAuth(cfg) {
|
|
70
|
+
if (cfg.gatewayToken || cfg.gatewayPassword) {
|
|
71
|
+
return { token: cfg.gatewayToken, password: cfg.gatewayPassword };
|
|
72
|
+
}
|
|
73
|
+
// Try to read the token from OpenClaw's own config
|
|
74
|
+
try {
|
|
75
|
+
const raw = readFileSync(OPENCLAW_CONFIG_PATH, "utf-8");
|
|
76
|
+
const json = JSON.parse(raw);
|
|
77
|
+
const token = json?.gateway?.token ?? json?.gateway?.auth?.token ?? undefined;
|
|
78
|
+
const password = json?.gateway?.password ?? json?.gateway?.auth?.password ?? undefined;
|
|
79
|
+
if (token || password)
|
|
80
|
+
return { token, password };
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// ignore
|
|
84
|
+
}
|
|
85
|
+
// Fall back to environment variables (e.g. set via LaunchAgent)
|
|
86
|
+
const envToken = process.env.OPENCLAW_GATEWAY_TOKEN;
|
|
87
|
+
const envPassword = process.env.OPENCLAW_GATEWAY_PASSWORD;
|
|
88
|
+
if (envToken || envPassword) {
|
|
89
|
+
return { token: envToken, password: envPassword };
|
|
90
|
+
}
|
|
91
|
+
return {};
|
|
92
|
+
}
|
|
93
|
+
function normalizeVoiceIdentifier(voiceIdentifier) {
|
|
94
|
+
const trimmed = voiceIdentifier?.trim() ?? "";
|
|
95
|
+
return trimmed.length > 0 ? trimmed : undefined;
|
|
96
|
+
}
|
|
97
|
+
function clampRatePercent(ratePercent) {
|
|
98
|
+
if (typeof ratePercent !== "number" || !Number.isFinite(ratePercent)) {
|
|
99
|
+
return undefined;
|
|
100
|
+
}
|
|
101
|
+
return Math.min(50, Math.max(-50, Math.round(ratePercent)));
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=config.js.map
|