@meetlobster/openclaw-plugin 1.3.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/config.schema.json +29 -0
- package/dist/commands.d.ts +15 -0
- package/dist/commands.js +116 -0
- package/dist/commands.js.map +1 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.js +229 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/resources.d.ts +2 -0
- package/dist/resources.js +17 -0
- package/dist/resources.js.map +1 -0
- package/dist/rpc.d.ts +2 -0
- package/dist/rpc.js +14 -0
- package/dist/rpc.js.map +1 -0
- package/dist/services/lobster-service.d.ts +18 -0
- package/dist/services/lobster-service.js +250 -0
- package/dist/services/lobster-service.js.map +1 -0
- package/dist/types/lobster.d.ts +49 -0
- package/dist/types/lobster.js +3 -0
- package/dist/types/lobster.js.map +1 -0
- package/openclaw.plugin.json +22 -0
- package/package.json +23 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "LobsterOpenClawPluginConfig",
|
|
4
|
+
"type": "object",
|
|
5
|
+
"additionalProperties": false,
|
|
6
|
+
"properties": {
|
|
7
|
+
"workerBaseUrl": { "type": "string", "minLength": 1 },
|
|
8
|
+
"workerHost": { "type": "string", "minLength": 1 },
|
|
9
|
+
"workerPort": { "type": "integer", "minimum": 1, "maximum": 65535 },
|
|
10
|
+
"adapterToken": { "type": "string", "minLength": 8 },
|
|
11
|
+
"workerEntry": { "type": "string", "minLength": 1 },
|
|
12
|
+
"autoSpawnWorker": { "type": "boolean" },
|
|
13
|
+
"hookUrl": { "type": "string", "minLength": 1 },
|
|
14
|
+
"hooksToken": { "type": "string", "minLength": 8 },
|
|
15
|
+
"recallSigningSecret": { "type": "string", "minLength": 8 },
|
|
16
|
+
"recallApiKey": { "type": "string", "minLength": 1 },
|
|
17
|
+
"recallApiBaseUrl": { "type": "string", "minLength": 1 },
|
|
18
|
+
"cloudflaredBinary": { "type": "string", "minLength": 1 },
|
|
19
|
+
"cloudflaredEnabled": { "type": "boolean" },
|
|
20
|
+
"transcriptQuietMs": { "type": "integer", "minimum": 1000 },
|
|
21
|
+
"defaultVisibilityMode": { "type": "string", "enum": ["private", "shared"] },
|
|
22
|
+
"ambiguityFallbackMode": { "type": "string", "enum": ["private", "shared"] },
|
|
23
|
+
"defaultBotName": { "type": "string", "minLength": 1 },
|
|
24
|
+
"intelligenceFlushMs": { "type": "integer", "minimum": 1000 },
|
|
25
|
+
"intelligenceMaxChunks": { "type": "integer", "minimum": 1 },
|
|
26
|
+
"intelligenceContextWindow": { "type": "integer", "minimum": 1 }
|
|
27
|
+
},
|
|
28
|
+
"required": ["adapterToken", "hookUrl", "hooksToken", "recallSigningSecret"]
|
|
29
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { LobsterServiceApi, OpenClawApi } from "./types/lobster";
|
|
2
|
+
declare function stripPrefix(text: string): string;
|
|
3
|
+
declare function normalizeCommandText(rawText: string): {
|
|
4
|
+
ok: true;
|
|
5
|
+
text: string;
|
|
6
|
+
} | {
|
|
7
|
+
ok: false;
|
|
8
|
+
message: string;
|
|
9
|
+
};
|
|
10
|
+
export declare function registerLobsterCommand(api: OpenClawApi, service: LobsterServiceApi): void;
|
|
11
|
+
export declare const __testables: {
|
|
12
|
+
normalizeCommandText: typeof normalizeCommandText;
|
|
13
|
+
stripPrefix: typeof stripPrefix;
|
|
14
|
+
};
|
|
15
|
+
export {};
|
package/dist/commands.js
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.__testables = void 0;
|
|
4
|
+
exports.registerLobsterCommand = registerLobsterCommand;
|
|
5
|
+
const SYNONYMS = new Map([
|
|
6
|
+
["start", "join"],
|
|
7
|
+
["begin", "join"],
|
|
8
|
+
["exit", "leave"],
|
|
9
|
+
["quit", "leave"],
|
|
10
|
+
["pause", "stop"],
|
|
11
|
+
["continue", "resume"],
|
|
12
|
+
["unpause", "resume"],
|
|
13
|
+
["visibility-private", "private"],
|
|
14
|
+
["visibility-shared", "shared"],
|
|
15
|
+
]);
|
|
16
|
+
const CANONICAL_COMMANDS = new Set([
|
|
17
|
+
"join",
|
|
18
|
+
"leave",
|
|
19
|
+
"private",
|
|
20
|
+
"shared",
|
|
21
|
+
"transcript",
|
|
22
|
+
"stop",
|
|
23
|
+
"resume",
|
|
24
|
+
"status",
|
|
25
|
+
"summary",
|
|
26
|
+
"name",
|
|
27
|
+
"image",
|
|
28
|
+
"help",
|
|
29
|
+
]);
|
|
30
|
+
function asText(value) {
|
|
31
|
+
if (typeof value === "string" && value.trim()) {
|
|
32
|
+
return value.trim();
|
|
33
|
+
}
|
|
34
|
+
if (typeof value === "number" || typeof value === "bigint") {
|
|
35
|
+
return String(value);
|
|
36
|
+
}
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
function stripPrefix(text) {
|
|
40
|
+
const trimmed = text.trim();
|
|
41
|
+
if (trimmed.startsWith("/lobster")) {
|
|
42
|
+
return trimmed.slice("/lobster".length).trim();
|
|
43
|
+
}
|
|
44
|
+
return trimmed;
|
|
45
|
+
}
|
|
46
|
+
function normalizeCommandText(rawText) {
|
|
47
|
+
const withoutPrefix = stripPrefix(rawText);
|
|
48
|
+
if (!withoutPrefix) {
|
|
49
|
+
return { ok: true, text: "help" };
|
|
50
|
+
}
|
|
51
|
+
const [head, ...tail] = withoutPrefix.split(/\s+/);
|
|
52
|
+
const lowered = head.toLowerCase();
|
|
53
|
+
const command = SYNONYMS.get(lowered) ?? lowered;
|
|
54
|
+
if (!CANONICAL_COMMANDS.has(command)) {
|
|
55
|
+
return {
|
|
56
|
+
ok: false,
|
|
57
|
+
message: "Lobster command not recognized. Run /lobster help.",
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
if (command === "transcript") {
|
|
61
|
+
const mode = (tail[0] ?? "").toLowerCase();
|
|
62
|
+
if (mode !== "on" && mode !== "off") {
|
|
63
|
+
return {
|
|
64
|
+
ok: false,
|
|
65
|
+
message: "Transcript command must be '/lobster transcript on' or '/lobster transcript off'.",
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const rebuilt = [command, ...tail].join(" ").trim();
|
|
70
|
+
return { ok: true, text: rebuilt };
|
|
71
|
+
}
|
|
72
|
+
function toWorkerPayload(ctx, text) {
|
|
73
|
+
const senderId = asText(ctx.senderId) ?? asText(ctx.ownerId) ?? asText(ctx.from) ?? "unknown";
|
|
74
|
+
const chatId = asText(ctx.chatId) ??
|
|
75
|
+
asText(ctx.to) ??
|
|
76
|
+
asText(ctx.from) ??
|
|
77
|
+
asText(ctx.messageThreadId) ??
|
|
78
|
+
asText(ctx.channel) ??
|
|
79
|
+
"unknown";
|
|
80
|
+
return {
|
|
81
|
+
ownerId: senderId,
|
|
82
|
+
chatId,
|
|
83
|
+
messageId: asText(ctx.messageId),
|
|
84
|
+
text,
|
|
85
|
+
platform: asText(ctx.platform) ?? asText(ctx.channelId) ?? asText(ctx.channel),
|
|
86
|
+
timestamp: typeof ctx.timestamp === "string" ? ctx.timestamp : new Date().toISOString(),
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
function registerLobsterCommand(api, service) {
|
|
90
|
+
api.registerCommand({
|
|
91
|
+
name: "lobster",
|
|
92
|
+
description: "Control Lobster meeting assistant",
|
|
93
|
+
acceptsArgs: true,
|
|
94
|
+
handler: async (ctx) => {
|
|
95
|
+
const data = (ctx ?? {});
|
|
96
|
+
const rawText = asText(data.text) ??
|
|
97
|
+
asText(data.commandBody) ??
|
|
98
|
+
asText(data.command) ??
|
|
99
|
+
asText(data.args) ??
|
|
100
|
+
"/lobster help";
|
|
101
|
+
const text = rawText.startsWith("/lobster") ? rawText : `/lobster ${rawText}`.trim();
|
|
102
|
+
const normalized = normalizeCommandText(text);
|
|
103
|
+
if (!normalized.ok) {
|
|
104
|
+
return { text: normalized.message };
|
|
105
|
+
}
|
|
106
|
+
const response = await service.command(toWorkerPayload(data, normalized.text));
|
|
107
|
+
const userMessage = typeof response.userMessage === "string" ? response.userMessage.trim() : "";
|
|
108
|
+
return { text: userMessage || "Lobster command completed." };
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
exports.__testables = {
|
|
113
|
+
normalizeCommandText,
|
|
114
|
+
stripPrefix,
|
|
115
|
+
};
|
|
116
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../commands.ts"],"names":[],"mappings":"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"}
|
package/dist/config.d.ts
ADDED
package/dist/config.js
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.loadPluginConfig = loadPluginConfig;
|
|
7
|
+
exports.redactConfig = redactConfig;
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const LOOPBACK_HOSTS = new Set(["127.0.0.1", "localhost", "::1"]);
|
|
11
|
+
function normalizeHost(host) {
|
|
12
|
+
const normalized = host.trim().toLowerCase();
|
|
13
|
+
if (normalized.startsWith("[") && normalized.endsWith("]")) {
|
|
14
|
+
return normalized.slice(1, -1);
|
|
15
|
+
}
|
|
16
|
+
return normalized;
|
|
17
|
+
}
|
|
18
|
+
function isLoopbackHost(host) {
|
|
19
|
+
return LOOPBACK_HOSTS.has(normalizeHost(host));
|
|
20
|
+
}
|
|
21
|
+
function resolveDefaultWorkerEntry() {
|
|
22
|
+
const candidates = [
|
|
23
|
+
process.env.LOBSTER_WORKER_ENTRY,
|
|
24
|
+
node_path_1.default.resolve(__dirname, "../../worker/dist/index.js"),
|
|
25
|
+
node_path_1.default.resolve(process.cwd(), "node_modules/@meetlobster/worker/dist/index.js"),
|
|
26
|
+
node_path_1.default.resolve(process.cwd(), "packages/lobster-worker/dist/index.js"),
|
|
27
|
+
// Global npm install fallbacks
|
|
28
|
+
"/usr/lib/node_modules/@meetlobster/worker/dist/index.js",
|
|
29
|
+
"/usr/local/lib/node_modules/@meetlobster/worker/dist/index.js",
|
|
30
|
+
].filter(Boolean);
|
|
31
|
+
for (const candidate of candidates) {
|
|
32
|
+
if (node_fs_1.default.existsSync(candidate)) {
|
|
33
|
+
return candidate;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return candidates[0] ?? node_path_1.default.resolve(process.cwd(), "packages/lobster-worker/dist/index.js");
|
|
37
|
+
}
|
|
38
|
+
const DEFAULTS = {
|
|
39
|
+
workerBaseUrl: "http://127.0.0.1:9912",
|
|
40
|
+
workerHost: "127.0.0.1",
|
|
41
|
+
workerPort: 9912,
|
|
42
|
+
adapterToken: "",
|
|
43
|
+
workerEntry: resolveDefaultWorkerEntry(),
|
|
44
|
+
autoSpawnWorker: true,
|
|
45
|
+
hookUrl: "http://127.0.0.1:3000/hooks/wake",
|
|
46
|
+
hooksToken: "",
|
|
47
|
+
recallSigningSecret: "",
|
|
48
|
+
recallApiKey: undefined,
|
|
49
|
+
recallApiBaseUrl: "https://us-east-1.recall.ai",
|
|
50
|
+
cloudflaredBinary: "cloudflared",
|
|
51
|
+
cloudflaredEnabled: true,
|
|
52
|
+
transcriptQuietMs: 180000,
|
|
53
|
+
defaultVisibilityMode: "private",
|
|
54
|
+
ambiguityFallbackMode: "shared",
|
|
55
|
+
defaultBotName: "Lobster",
|
|
56
|
+
intelligenceFlushMs: 15_000,
|
|
57
|
+
intelligenceMaxChunks: 30,
|
|
58
|
+
intelligenceContextWindow: 50,
|
|
59
|
+
workspaceDir: undefined,
|
|
60
|
+
intelligenceTimeoutMs: 600_000,
|
|
61
|
+
intelligenceThinkLevel: "low",
|
|
62
|
+
useEmbeddedAgent: true,
|
|
63
|
+
wakeMainSession: true,
|
|
64
|
+
};
|
|
65
|
+
function parseBoolean(value, fallback) {
|
|
66
|
+
if (value === undefined) {
|
|
67
|
+
return fallback;
|
|
68
|
+
}
|
|
69
|
+
return ["1", "true", "yes", "on"].includes(value.toLowerCase());
|
|
70
|
+
}
|
|
71
|
+
function parseNumber(value, fallback) {
|
|
72
|
+
if (!value) {
|
|
73
|
+
return fallback;
|
|
74
|
+
}
|
|
75
|
+
const parsed = Number(value);
|
|
76
|
+
return Number.isFinite(parsed) ? parsed : fallback;
|
|
77
|
+
}
|
|
78
|
+
function optionalString(value) {
|
|
79
|
+
if (typeof value !== "string") {
|
|
80
|
+
return undefined;
|
|
81
|
+
}
|
|
82
|
+
const trimmed = value.trim();
|
|
83
|
+
return trimmed ? trimmed : undefined;
|
|
84
|
+
}
|
|
85
|
+
function normalizeBaseUrl(url) {
|
|
86
|
+
return url.replace(/\/+$/, "");
|
|
87
|
+
}
|
|
88
|
+
function loadSchema() {
|
|
89
|
+
const candidates = [
|
|
90
|
+
node_path_1.default.resolve(__dirname, "config.schema.json"),
|
|
91
|
+
node_path_1.default.resolve(__dirname, "../config.schema.json"),
|
|
92
|
+
node_path_1.default.resolve(process.cwd(), "packages/openclaw-lobster-plugin/config.schema.json"),
|
|
93
|
+
];
|
|
94
|
+
for (const candidate of candidates) {
|
|
95
|
+
if (node_fs_1.default.existsSync(candidate)) {
|
|
96
|
+
return JSON.parse(node_fs_1.default.readFileSync(candidate, "utf8"));
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return { properties: {}, required: [] };
|
|
100
|
+
}
|
|
101
|
+
function validateBySchema(config, schema) {
|
|
102
|
+
const issues = [];
|
|
103
|
+
const required = schema.required ?? [];
|
|
104
|
+
for (const key of required) {
|
|
105
|
+
const value = config[key];
|
|
106
|
+
if (value === undefined || value === null || value === "") {
|
|
107
|
+
issues.push(`missing required config key: ${key}`);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
for (const [key, property] of Object.entries(schema.properties ?? {})) {
|
|
111
|
+
const value = config[key];
|
|
112
|
+
if (value === undefined) {
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (property.type === "string") {
|
|
116
|
+
if (typeof value !== "string") {
|
|
117
|
+
issues.push(`config key ${String(key)} must be a string`);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (property.minLength && value.length < property.minLength) {
|
|
121
|
+
issues.push(`config key ${String(key)} must be at least ${property.minLength} chars`);
|
|
122
|
+
}
|
|
123
|
+
if (property.enum && !property.enum.includes(value)) {
|
|
124
|
+
issues.push(`config key ${String(key)} must be one of ${property.enum.join(", ")}`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
if (property.type === "integer") {
|
|
128
|
+
if (typeof value !== "number" || !Number.isInteger(value)) {
|
|
129
|
+
issues.push(`config key ${String(key)} must be an integer`);
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (property.minimum !== undefined && value < property.minimum) {
|
|
133
|
+
issues.push(`config key ${String(key)} must be >= ${property.minimum}`);
|
|
134
|
+
}
|
|
135
|
+
if (property.maximum !== undefined && value > property.maximum) {
|
|
136
|
+
issues.push(`config key ${String(key)} must be <= ${property.maximum}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
if (property.type === "boolean" && typeof value !== "boolean") {
|
|
140
|
+
issues.push(`config key ${String(key)} must be a boolean`);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
return issues;
|
|
144
|
+
}
|
|
145
|
+
function validatePluginConfig(config) {
|
|
146
|
+
const schema = loadSchema();
|
|
147
|
+
const schemaIssues = validateBySchema(config, schema);
|
|
148
|
+
const urlKeys = ["workerBaseUrl", "hookUrl"];
|
|
149
|
+
for (const key of urlKeys) {
|
|
150
|
+
try {
|
|
151
|
+
new URL(config[key]);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
schemaIssues.push(`config key ${key} must be a valid url`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (config.recallApiBaseUrl) {
|
|
158
|
+
try {
|
|
159
|
+
new URL(config.recallApiBaseUrl);
|
|
160
|
+
}
|
|
161
|
+
catch {
|
|
162
|
+
schemaIssues.push("config key recallApiBaseUrl must be a valid url");
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (!config.adapterToken) {
|
|
166
|
+
schemaIssues.push("adapterToken is required");
|
|
167
|
+
}
|
|
168
|
+
if (!isLoopbackHost(config.workerHost)) {
|
|
169
|
+
schemaIssues.push(`config key workerHost must be loopback-only (localhost, 127.0.0.1, or ::1)`);
|
|
170
|
+
}
|
|
171
|
+
try {
|
|
172
|
+
const workerBaseUrlHost = new URL(config.workerBaseUrl).hostname;
|
|
173
|
+
if (!isLoopbackHost(workerBaseUrlHost)) {
|
|
174
|
+
schemaIssues.push(`config key workerBaseUrl must use loopback host (localhost, 127.0.0.1, or ::1)`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
// URL syntax is already validated above.
|
|
179
|
+
}
|
|
180
|
+
if (schemaIssues.length > 0) {
|
|
181
|
+
throw new Error(`Invalid Lobster plugin config:\n- ${schemaIssues.join("\n- ")}`);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
function loadPluginConfig(rawInput, env = process.env) {
|
|
185
|
+
const raw = (rawInput ?? {});
|
|
186
|
+
const config = {
|
|
187
|
+
...DEFAULTS,
|
|
188
|
+
...raw,
|
|
189
|
+
workerBaseUrl: normalizeBaseUrl(raw.workerBaseUrl ?? env.LOBSTER_WORKER_BASE_URL ?? DEFAULTS.workerBaseUrl),
|
|
190
|
+
workerHost: raw.workerHost ?? env.LOBSTER_WORKER_HOST ?? DEFAULTS.workerHost,
|
|
191
|
+
workerPort: parseNumber(env.LOBSTER_WORKER_PORT, raw.workerPort ?? DEFAULTS.workerPort),
|
|
192
|
+
adapterToken: raw.adapterToken ?? env.LOBSTER_ADAPTER_TOKEN ?? DEFAULTS.adapterToken,
|
|
193
|
+
workerEntry: raw.workerEntry ?? env.LOBSTER_WORKER_ENTRY ?? DEFAULTS.workerEntry,
|
|
194
|
+
autoSpawnWorker: parseBoolean(env.LOBSTER_AUTO_SPAWN_WORKER, raw.autoSpawnWorker ?? DEFAULTS.autoSpawnWorker),
|
|
195
|
+
hookUrl: raw.hookUrl ?? env.LOBSTER_HOOK_URL ?? DEFAULTS.hookUrl,
|
|
196
|
+
hooksToken: raw.hooksToken ?? env.LOBSTER_HOOKS_TOKEN ?? DEFAULTS.hooksToken,
|
|
197
|
+
recallSigningSecret: raw.recallSigningSecret ?? env.LOBSTER_RECALL_SIGNING_SECRET ?? DEFAULTS.recallSigningSecret,
|
|
198
|
+
recallApiKey: optionalString(raw.recallApiKey ?? env.LOBSTER_RECALL_API_KEY) ?? DEFAULTS.recallApiKey,
|
|
199
|
+
recallApiBaseUrl: raw.recallApiBaseUrl ?? env.LOBSTER_RECALL_API_BASE_URL ?? DEFAULTS.recallApiBaseUrl,
|
|
200
|
+
cloudflaredBinary: raw.cloudflaredBinary ?? env.LOBSTER_CLOUDFLARED_BINARY ?? DEFAULTS.cloudflaredBinary,
|
|
201
|
+
cloudflaredEnabled: parseBoolean(env.LOBSTER_CLOUDFLARED_ENABLED, raw.cloudflaredEnabled ?? DEFAULTS.cloudflaredEnabled),
|
|
202
|
+
transcriptQuietMs: parseNumber(env.LOBSTER_TRANSCRIPT_QUIET_MS, raw.transcriptQuietMs ?? DEFAULTS.transcriptQuietMs),
|
|
203
|
+
defaultVisibilityMode: raw.defaultVisibilityMode ??
|
|
204
|
+
(env.LOBSTER_DEFAULT_VISIBILITY ?? DEFAULTS.defaultVisibilityMode),
|
|
205
|
+
ambiguityFallbackMode: raw.ambiguityFallbackMode ??
|
|
206
|
+
(env.LOBSTER_AMBIGUITY_FALLBACK ?? DEFAULTS.ambiguityFallbackMode),
|
|
207
|
+
defaultBotName: raw.defaultBotName ?? env.LOBSTER_DEFAULT_BOT_NAME ?? DEFAULTS.defaultBotName,
|
|
208
|
+
intelligenceFlushMs: parseNumber(env.LOBSTER_INTELLIGENCE_FLUSH_MS, raw.intelligenceFlushMs ?? DEFAULTS.intelligenceFlushMs),
|
|
209
|
+
intelligenceMaxChunks: parseNumber(env.LOBSTER_INTELLIGENCE_MAX_CHUNKS, raw.intelligenceMaxChunks ?? DEFAULTS.intelligenceMaxChunks),
|
|
210
|
+
intelligenceContextWindow: parseNumber(env.LOBSTER_INTELLIGENCE_CONTEXT_WINDOW, raw.intelligenceContextWindow ?? DEFAULTS.intelligenceContextWindow),
|
|
211
|
+
workspaceDir: optionalString(raw.workspaceDir ?? env.LOBSTER_WORKSPACE_DIR) ?? DEFAULTS.workspaceDir,
|
|
212
|
+
intelligenceTimeoutMs: parseNumber(env.LOBSTER_INTELLIGENCE_TIMEOUT_MS, raw.intelligenceTimeoutMs ?? DEFAULTS.intelligenceTimeoutMs),
|
|
213
|
+
intelligenceThinkLevel: raw.intelligenceThinkLevel ?? env.LOBSTER_INTELLIGENCE_THINK_LEVEL ?? DEFAULTS.intelligenceThinkLevel,
|
|
214
|
+
useEmbeddedAgent: parseBoolean(env.LOBSTER_USE_EMBEDDED_AGENT, raw.useEmbeddedAgent ?? DEFAULTS.useEmbeddedAgent),
|
|
215
|
+
wakeMainSession: parseBoolean(env.LOBSTER_WAKE_MAIN_SESSION, raw.wakeMainSession ?? DEFAULTS.wakeMainSession),
|
|
216
|
+
};
|
|
217
|
+
validatePluginConfig(config);
|
|
218
|
+
return config;
|
|
219
|
+
}
|
|
220
|
+
function redactConfig(config) {
|
|
221
|
+
return {
|
|
222
|
+
...config,
|
|
223
|
+
adapterToken: config.adapterToken ? "[set]" : "[missing]",
|
|
224
|
+
hooksToken: config.hooksToken ? "[set]" : "[missing]",
|
|
225
|
+
recallSigningSecret: config.recallSigningSecret ? "[set]" : "[missing]",
|
|
226
|
+
recallApiKey: config.recallApiKey ? "[set]" : "[missing]",
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../config.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { LobsterService } from "./services/lobster-service";
|
|
2
|
+
import type { OpenClawApi } from "./types/lobster";
|
|
3
|
+
export declare function init(api: OpenClawApi): {
|
|
4
|
+
service: LobsterService;
|
|
5
|
+
};
|
|
6
|
+
export declare function register(api: OpenClawApi): void;
|
|
7
|
+
export declare const activate: typeof register;
|
|
8
|
+
export default register;
|
|
9
|
+
export * from "./types/lobster";
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.activate = void 0;
|
|
18
|
+
exports.init = init;
|
|
19
|
+
exports.register = register;
|
|
20
|
+
const config_1 = require("./config");
|
|
21
|
+
const commands_1 = require("./commands");
|
|
22
|
+
const resources_1 = require("./resources");
|
|
23
|
+
const rpc_1 = require("./rpc");
|
|
24
|
+
const lobster_service_1 = require("./services/lobster-service");
|
|
25
|
+
function init(api) {
|
|
26
|
+
const rawConfig = api.pluginConfig ?? api.getConfig?.("lobster") ?? {};
|
|
27
|
+
const config = (0, config_1.loadPluginConfig)(rawConfig);
|
|
28
|
+
const service = new lobster_service_1.LobsterService(config, api.logger);
|
|
29
|
+
(0, commands_1.registerLobsterCommand)(api, service);
|
|
30
|
+
if (typeof api.registerResource === "function") {
|
|
31
|
+
(0, resources_1.registerLobsterResource)(api, service);
|
|
32
|
+
}
|
|
33
|
+
if (typeof api.registerRpc === "function") {
|
|
34
|
+
(0, rpc_1.registerLobsterRpc)(api, service);
|
|
35
|
+
}
|
|
36
|
+
const modernService = {
|
|
37
|
+
id: "lobster",
|
|
38
|
+
start: async () => {
|
|
39
|
+
await service.start();
|
|
40
|
+
},
|
|
41
|
+
stop: async () => {
|
|
42
|
+
await service.stop();
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
try {
|
|
46
|
+
api.registerService(modernService);
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
api.registerService("lobster", {
|
|
50
|
+
start: async () => service.start(),
|
|
51
|
+
stop: async () => service.stop(),
|
|
52
|
+
health: async () => service.health(),
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
api.logger?.info("Lobster plugin initialized", (0, config_1.redactConfig)(config));
|
|
56
|
+
// Ensure worker boot begins during plugin registration so health checks can pass without waiting for first command.
|
|
57
|
+
void service.start().catch((error) => {
|
|
58
|
+
api.logger?.warn("Lobster worker auto-start failed", {
|
|
59
|
+
error: error instanceof Error ? error.message : String(error),
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
return { service };
|
|
63
|
+
}
|
|
64
|
+
function register(api) {
|
|
65
|
+
init(api);
|
|
66
|
+
}
|
|
67
|
+
exports.activate = register;
|
|
68
|
+
exports.default = register;
|
|
69
|
+
__exportStar(require("./types/lobster"), exports);
|
|
70
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAOA,oBA4CC;AAED,4BAEC;AAvDD,qCAA0D;AAC1D,yCAAoD;AACpD,2CAAsD;AACtD,+BAA2C;AAC3C,gEAA4D;AAG5D,SAAgB,IAAI,CAAC,GAAgB;IACnC,MAAM,SAAS,GAAG,GAAG,CAAC,YAAY,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IACvE,MAAM,MAAM,GAAG,IAAA,yBAAgB,EAAC,SAAS,CAAC,CAAC;IAE3C,MAAM,OAAO,GAAG,IAAI,gCAAc,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAEvD,IAAA,iCAAsB,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACrC,IAAI,OAAO,GAAG,CAAC,gBAAgB,KAAK,UAAU,EAAE,CAAC;QAC/C,IAAA,mCAAuB,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;QAC1C,IAAA,wBAAkB,EAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACnC,CAAC;IAED,MAAM,aAAa,GAAG;QACpB,EAAE,EAAE,SAAS;QACb,KAAK,EAAE,KAAK,IAAI,EAAE;YAChB,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;QACxB,CAAC;QACD,IAAI,EAAE,KAAK,IAAI,EAAE;YACf,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC;QACvB,CAAC;KACF,CAAC;IAEF,IAAI,CAAC;QACH,GAAG,CAAC,eAAe,CAAC,aAAa,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,GAAG,CAAC,eAAe,CAAC,SAAS,EAAE;YAC7B,KAAK,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE;YAClC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE;YAChC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE;SACrC,CAAC,CAAC;IACL,CAAC;IAED,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,4BAA4B,EAAE,IAAA,qBAAY,EAAC,MAAM,CAAC,CAAC,CAAC;IAErE,oHAAoH;IACpH,KAAK,OAAO,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACnC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,kCAAkC,EAAE;YACnD,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC;AAED,SAAgB,QAAQ,CAAC,GAAgB;IACvC,IAAI,CAAC,GAAG,CAAC,CAAC;AACZ,CAAC;AAEY,QAAA,QAAQ,GAAG,QAAQ,CAAC;AACjC,kBAAe,QAAQ,CAAC;AAExB,kDAAgC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerLobsterResource = registerLobsterResource;
|
|
4
|
+
function registerLobsterResource(api, service) {
|
|
5
|
+
if (typeof api.registerResource !== "function") {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
api.registerResource("lobster.status", async () => {
|
|
9
|
+
const health = await service.health();
|
|
10
|
+
return {
|
|
11
|
+
pluginUp: true,
|
|
12
|
+
workerReachable: health.ok,
|
|
13
|
+
health,
|
|
14
|
+
};
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=resources.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resources.js","sourceRoot":"","sources":["../resources.ts"],"names":[],"mappings":";;AAGA,0DAaC;AAbD,SAAgB,uBAAuB,CAAC,GAAgB,EAAE,OAA0B;IAClF,IAAI,OAAO,GAAG,CAAC,gBAAgB,KAAK,UAAU,EAAE,CAAC;QAC/C,OAAO;IACT,CAAC;IAED,GAAG,CAAC,gBAAgB,CAAC,gBAAgB,EAAE,KAAK,IAAoC,EAAE;QAChF,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC;QACtC,OAAO;YACL,QAAQ,EAAE,IAAI;YACd,eAAe,EAAE,MAAM,CAAC,EAAE;YAC1B,MAAM;SACP,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/rpc.d.ts
ADDED
package/dist/rpc.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.registerLobsterRpc = registerLobsterRpc;
|
|
4
|
+
function registerLobsterRpc(api, service) {
|
|
5
|
+
if (typeof api.registerRpc !== "function") {
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
api.registerRpc("lobster.health", async () => service.health());
|
|
9
|
+
api.registerRpc("lobster.start", async () => service.start());
|
|
10
|
+
api.registerRpc("lobster.stop", async () => service.stop());
|
|
11
|
+
api.registerRpc("lobster.status", async () => service.status());
|
|
12
|
+
api.registerRpc("lobster.command", async (args) => service.command(args));
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=rpc.js.map
|
package/dist/rpc.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rpc.js","sourceRoot":"","sources":["../rpc.ts"],"names":[],"mappings":";;AAGA,gDAUC;AAVD,SAAgB,kBAAkB,CAAC,GAAgB,EAAE,OAA0B;IAC7E,IAAI,OAAO,GAAG,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;QAC1C,OAAO;IACT,CAAC;IAED,GAAG,CAAC,WAAW,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAChE,GAAG,CAAC,WAAW,CAAC,eAAe,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC;IAC9D,GAAG,CAAC,WAAW,CAAC,cAAc,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5D,GAAG,CAAC,WAAW,CAAC,gBAAgB,EAAE,KAAK,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAChE,GAAG,CAAC,WAAW,CAAC,iBAAiB,EAAE,KAAK,EAAE,IAAa,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,IAAsB,CAAC,CAAC,CAAC;AACvG,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { CommandRequest, CommandResponse, PluginConfig, WorkerHealth } from "@meetlobster/shared";
|
|
2
|
+
import type { LobsterServiceApi, OpenClawLogger } from "../types/lobster";
|
|
3
|
+
export declare class LobsterService implements LobsterServiceApi {
|
|
4
|
+
readonly config: PluginConfig;
|
|
5
|
+
private readonly logger;
|
|
6
|
+
private workerProcess;
|
|
7
|
+
private started;
|
|
8
|
+
private lastError;
|
|
9
|
+
constructor(config: PluginConfig, logger?: OpenClawLogger);
|
|
10
|
+
start(): Promise<WorkerHealth>;
|
|
11
|
+
stop(): Promise<WorkerHealth>;
|
|
12
|
+
health(): Promise<WorkerHealth>;
|
|
13
|
+
status(): Promise<CommandResponse["state"]>;
|
|
14
|
+
command(payload: CommandRequest): Promise<CommandResponse>;
|
|
15
|
+
private spawnWorker;
|
|
16
|
+
private resolveOpenClawRoot;
|
|
17
|
+
private waitForHealth;
|
|
18
|
+
}
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.LobsterService = void 0;
|
|
7
|
+
const node_child_process_1 = require("node:child_process");
|
|
8
|
+
const node_fs_1 = __importDefault(require("node:fs"));
|
|
9
|
+
const node_path_1 = __importDefault(require("node:path"));
|
|
10
|
+
const REQUEST_TIMEOUT_MS = 6000;
|
|
11
|
+
function sleep(ms) {
|
|
12
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
13
|
+
}
|
|
14
|
+
async function fetchJson(url, init, timeoutMs = REQUEST_TIMEOUT_MS) {
|
|
15
|
+
const controller = new AbortController();
|
|
16
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
17
|
+
try {
|
|
18
|
+
const response = await fetch(url, { ...init, signal: controller.signal });
|
|
19
|
+
if (!response.ok) {
|
|
20
|
+
const body = await response.text();
|
|
21
|
+
throw new Error(`HTTP ${response.status}: ${body}`);
|
|
22
|
+
}
|
|
23
|
+
return (await response.json());
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
clearTimeout(timer);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
class LobsterService {
|
|
30
|
+
config;
|
|
31
|
+
logger;
|
|
32
|
+
workerProcess = null;
|
|
33
|
+
started = false;
|
|
34
|
+
lastError;
|
|
35
|
+
constructor(config, logger) {
|
|
36
|
+
this.config = config;
|
|
37
|
+
this.logger =
|
|
38
|
+
logger ??
|
|
39
|
+
{
|
|
40
|
+
info: () => undefined,
|
|
41
|
+
warn: () => undefined,
|
|
42
|
+
error: () => undefined,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
async start() {
|
|
46
|
+
if (this.started) {
|
|
47
|
+
return this.health();
|
|
48
|
+
}
|
|
49
|
+
if (this.config.autoSpawnWorker) {
|
|
50
|
+
this.spawnWorker();
|
|
51
|
+
await this.waitForHealth();
|
|
52
|
+
}
|
|
53
|
+
this.started = true;
|
|
54
|
+
return this.health();
|
|
55
|
+
}
|
|
56
|
+
async stop() {
|
|
57
|
+
if (!this.started) {
|
|
58
|
+
return this.health();
|
|
59
|
+
}
|
|
60
|
+
try {
|
|
61
|
+
await fetchJson(`${this.config.workerBaseUrl}/v1/control/stop`, {
|
|
62
|
+
method: "POST",
|
|
63
|
+
headers: {
|
|
64
|
+
"Content-Type": "application/json",
|
|
65
|
+
"X-Lobster-Adapter-Token": this.config.adapterToken,
|
|
66
|
+
},
|
|
67
|
+
body: JSON.stringify({ reason: "plugin-stop" }),
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
catch (error) {
|
|
71
|
+
this.logger.warn("Lobster worker stop endpoint failed", {
|
|
72
|
+
error: error instanceof Error ? error.message : String(error),
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
if (this.workerProcess) {
|
|
76
|
+
this.workerProcess.kill("SIGTERM");
|
|
77
|
+
await sleep(250);
|
|
78
|
+
if (!this.workerProcess.killed) {
|
|
79
|
+
this.workerProcess.kill("SIGKILL");
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
this.started = false;
|
|
83
|
+
this.workerProcess = null;
|
|
84
|
+
return this.health();
|
|
85
|
+
}
|
|
86
|
+
async health() {
|
|
87
|
+
try {
|
|
88
|
+
const health = await fetchJson(`${this.config.workerBaseUrl}/v1/health`, {
|
|
89
|
+
method: "GET",
|
|
90
|
+
});
|
|
91
|
+
this.lastError = undefined;
|
|
92
|
+
return health;
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
96
|
+
this.lastError = message;
|
|
97
|
+
return {
|
|
98
|
+
ok: false,
|
|
99
|
+
queueDepth: 0,
|
|
100
|
+
sessionState: "idle",
|
|
101
|
+
tunnelActive: false,
|
|
102
|
+
lastError: message,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async status() {
|
|
107
|
+
const response = await fetchJson(`${this.config.workerBaseUrl}/v1/session`, {
|
|
108
|
+
method: "GET",
|
|
109
|
+
headers: {
|
|
110
|
+
"X-Lobster-Adapter-Token": this.config.adapterToken,
|
|
111
|
+
},
|
|
112
|
+
});
|
|
113
|
+
return response.state;
|
|
114
|
+
}
|
|
115
|
+
async command(payload) {
|
|
116
|
+
if (!this.started) {
|
|
117
|
+
await this.start();
|
|
118
|
+
}
|
|
119
|
+
try {
|
|
120
|
+
return await fetchJson(`${this.config.workerBaseUrl}/v1/commands`, {
|
|
121
|
+
method: "POST",
|
|
122
|
+
headers: {
|
|
123
|
+
"Content-Type": "application/json",
|
|
124
|
+
"X-Lobster-Adapter-Token": this.config.adapterToken,
|
|
125
|
+
},
|
|
126
|
+
body: JSON.stringify(payload),
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
131
|
+
this.logger.error("Lobster command forwarding failed", { error: message });
|
|
132
|
+
return {
|
|
133
|
+
ok: false,
|
|
134
|
+
userMessage: "Lobster is unavailable right now. Try /lobster status in a few seconds.",
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
spawnWorker() {
|
|
139
|
+
if (this.workerProcess && !this.workerProcess.killed) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const workerConfig = {
|
|
143
|
+
host: this.config.workerHost,
|
|
144
|
+
port: this.config.workerPort,
|
|
145
|
+
adapterToken: this.config.adapterToken,
|
|
146
|
+
hookUrl: this.config.hookUrl,
|
|
147
|
+
hooksToken: this.config.hooksToken,
|
|
148
|
+
recallSigningSecret: this.config.recallSigningSecret,
|
|
149
|
+
recallApiKey: this.config.recallApiKey,
|
|
150
|
+
recallApiBaseUrl: this.config.recallApiBaseUrl,
|
|
151
|
+
sessionTokenTtlMs: 4 * 60 * 60 * 1000,
|
|
152
|
+
maxPayloadBytes: 256_000,
|
|
153
|
+
queueMax: 500,
|
|
154
|
+
maxEventsPerMinute: 180,
|
|
155
|
+
retryCount: 3,
|
|
156
|
+
retryBackoffMs: 500,
|
|
157
|
+
transcriptQuietMs: this.config.transcriptQuietMs,
|
|
158
|
+
cloudflaredBinary: this.config.cloudflaredBinary,
|
|
159
|
+
cloudflaredEnabled: this.config.cloudflaredEnabled,
|
|
160
|
+
cloudflaredTargetUrl: `http://${this.config.workerHost}:${this.config.workerPort}`,
|
|
161
|
+
defaultVisibilityMode: this.config.defaultVisibilityMode,
|
|
162
|
+
ambiguityFallbackMode: this.config.ambiguityFallbackMode,
|
|
163
|
+
defaultBotName: this.config.defaultBotName,
|
|
164
|
+
intelligenceFlushMs: this.config.intelligenceFlushMs,
|
|
165
|
+
intelligenceMaxChunks: this.config.intelligenceMaxChunks,
|
|
166
|
+
intelligenceContextWindow: this.config.intelligenceContextWindow,
|
|
167
|
+
workspaceDir: this.config.workspaceDir,
|
|
168
|
+
intelligenceTimeoutMs: this.config.intelligenceTimeoutMs,
|
|
169
|
+
intelligenceThinkLevel: this.config.intelligenceThinkLevel,
|
|
170
|
+
useEmbeddedAgent: this.config.useEmbeddedAgent,
|
|
171
|
+
wakeMainSession: this.config.wakeMainSession,
|
|
172
|
+
};
|
|
173
|
+
const workerEntry = node_path_1.default.resolve(this.config.workerEntry);
|
|
174
|
+
this.logger.info("Starting Lobster worker", { workerEntry });
|
|
175
|
+
const child = (0, node_child_process_1.spawn)(process.execPath, [workerEntry], {
|
|
176
|
+
env: {
|
|
177
|
+
...process.env,
|
|
178
|
+
LOBSTER_WORKER_CONFIG_JSON: JSON.stringify(workerConfig),
|
|
179
|
+
OPENCLAW_ROOT: process.env.OPENCLAW_ROOT ?? this.resolveOpenClawRoot(),
|
|
180
|
+
},
|
|
181
|
+
stdio: "pipe",
|
|
182
|
+
});
|
|
183
|
+
child.stdout.on("data", (chunk) => {
|
|
184
|
+
this.logger.info("[lobster-worker]" + String(chunk).trim());
|
|
185
|
+
});
|
|
186
|
+
child.stderr.on("data", (chunk) => {
|
|
187
|
+
this.logger.warn("[lobster-worker]" + String(chunk).trim());
|
|
188
|
+
});
|
|
189
|
+
child.on("exit", (code, signal) => {
|
|
190
|
+
this.logger.warn("Lobster worker exited", { code, signal });
|
|
191
|
+
this.workerProcess = null;
|
|
192
|
+
this.started = false;
|
|
193
|
+
});
|
|
194
|
+
this.workerProcess = child;
|
|
195
|
+
}
|
|
196
|
+
resolveOpenClawRoot() {
|
|
197
|
+
// The plugin runs inside the OpenClaw gateway process.
|
|
198
|
+
// Traverse up from process.argv[1] (the openclaw binary entry) to find the package root.
|
|
199
|
+
// Resolve symlinks first — npm global installs create a symlink at /usr/bin/openclaw
|
|
200
|
+
// pointing to /usr/lib/node_modules/openclaw/openclaw.mjs.
|
|
201
|
+
const rawArgv1 = process.argv[1];
|
|
202
|
+
let resolvedArgv1;
|
|
203
|
+
if (rawArgv1) {
|
|
204
|
+
try {
|
|
205
|
+
resolvedArgv1 = node_fs_1.default.realpathSync(rawArgv1);
|
|
206
|
+
}
|
|
207
|
+
catch {
|
|
208
|
+
resolvedArgv1 = rawArgv1;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
const candidates = [
|
|
212
|
+
resolvedArgv1 ? node_path_1.default.dirname(resolvedArgv1) : undefined,
|
|
213
|
+
rawArgv1 ? node_path_1.default.dirname(rawArgv1) : undefined,
|
|
214
|
+
process.cwd(),
|
|
215
|
+
__dirname,
|
|
216
|
+
].filter(Boolean);
|
|
217
|
+
for (const start of candidates) {
|
|
218
|
+
let dir = start;
|
|
219
|
+
for (;;) {
|
|
220
|
+
const pkgPath = node_path_1.default.join(dir, "package.json");
|
|
221
|
+
try {
|
|
222
|
+
if (node_fs_1.default.existsSync(pkgPath)) {
|
|
223
|
+
const pkg = JSON.parse(node_fs_1.default.readFileSync(pkgPath, "utf8"));
|
|
224
|
+
if (pkg.name === "openclaw")
|
|
225
|
+
return dir;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
catch { /* ignore */ }
|
|
229
|
+
const parent = node_path_1.default.dirname(dir);
|
|
230
|
+
if (parent === dir)
|
|
231
|
+
break;
|
|
232
|
+
dir = parent;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return "";
|
|
236
|
+
}
|
|
237
|
+
async waitForHealth() {
|
|
238
|
+
const deadline = Date.now() + 12_000;
|
|
239
|
+
while (Date.now() < deadline) {
|
|
240
|
+
const health = await this.health();
|
|
241
|
+
if (health.ok) {
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
244
|
+
await sleep(250);
|
|
245
|
+
}
|
|
246
|
+
throw new Error(`Lobster worker did not become healthy. Last error: ${this.lastError ?? "unknown"}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
exports.LobsterService = LobsterService;
|
|
250
|
+
//# sourceMappingURL=lobster-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lobster-service.js","sourceRoot":"","sources":["../../services/lobster-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { CommandRequest, CommandResponse, LobsterStatusResource, PluginConfig, WorkerHealth } from "@meetlobster/shared";
|
|
2
|
+
export interface OpenClawLogger {
|
|
3
|
+
info(message: string, meta?: unknown): void;
|
|
4
|
+
warn(message: string, meta?: unknown): void;
|
|
5
|
+
error(message: string, meta?: unknown): void;
|
|
6
|
+
debug?(message: string, meta?: unknown): void;
|
|
7
|
+
}
|
|
8
|
+
export interface OpenClawCommandContext {
|
|
9
|
+
ownerId: string;
|
|
10
|
+
chatId: string;
|
|
11
|
+
messageId?: string;
|
|
12
|
+
platform?: string;
|
|
13
|
+
timestamp?: string;
|
|
14
|
+
text: string;
|
|
15
|
+
}
|
|
16
|
+
export interface OpenClawReplyPayload {
|
|
17
|
+
text?: string;
|
|
18
|
+
mediaUrl?: string;
|
|
19
|
+
mediaUrls?: string[];
|
|
20
|
+
replyToId?: string;
|
|
21
|
+
replyToTag?: boolean;
|
|
22
|
+
replyToCurrent?: boolean;
|
|
23
|
+
audioAsVoice?: boolean;
|
|
24
|
+
isError?: boolean;
|
|
25
|
+
isReasoning?: boolean;
|
|
26
|
+
channelData?: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
export interface OpenClawCommandRegistration {
|
|
29
|
+
name: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
handler: (ctx: OpenClawCommandContext) => Promise<OpenClawReplyPayload | string> | OpenClawReplyPayload | string;
|
|
32
|
+
}
|
|
33
|
+
export interface OpenClawApi {
|
|
34
|
+
pluginConfig?: unknown;
|
|
35
|
+
logger?: OpenClawLogger;
|
|
36
|
+
getConfig?: (namespace: string) => unknown;
|
|
37
|
+
registerCommand: (registration: OpenClawCommandRegistration | Record<string, unknown>) => void;
|
|
38
|
+
registerResource?: (name: string, handler: () => Promise<LobsterStatusResource> | LobsterStatusResource) => void;
|
|
39
|
+
registerRpc?: (name: string, handler: (args?: unknown) => Promise<unknown> | unknown) => void;
|
|
40
|
+
registerService: (...args: unknown[]) => void;
|
|
41
|
+
}
|
|
42
|
+
export interface LobsterServiceApi {
|
|
43
|
+
start(): Promise<WorkerHealth>;
|
|
44
|
+
stop(): Promise<WorkerHealth>;
|
|
45
|
+
health(): Promise<WorkerHealth>;
|
|
46
|
+
status(): Promise<CommandResponse["state"]>;
|
|
47
|
+
command(payload: CommandRequest): Promise<CommandResponse>;
|
|
48
|
+
readonly config: PluginConfig;
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lobster.js","sourceRoot":"","sources":["../../types/lobster.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "lobster-external",
|
|
3
|
+
"name": "Lobster",
|
|
4
|
+
"version": "1.2.0",
|
|
5
|
+
"description": "External Lobster plugin for OpenClaw chat-native meetings",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"configSchema": "./config.schema.json",
|
|
8
|
+
"permissions": [
|
|
9
|
+
"commands",
|
|
10
|
+
"resources",
|
|
11
|
+
"rpc",
|
|
12
|
+
"services",
|
|
13
|
+
"network",
|
|
14
|
+
"process"
|
|
15
|
+
],
|
|
16
|
+
"commands": [
|
|
17
|
+
{
|
|
18
|
+
"name": "lobster",
|
|
19
|
+
"description": "Control Lobster meeting assistant"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@meetlobster/openclaw-plugin",
|
|
3
|
+
"version": "1.3.0",
|
|
4
|
+
"main": "dist/index.js",
|
|
5
|
+
"types": "dist/index.d.ts",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist",
|
|
8
|
+
"openclaw.plugin.json",
|
|
9
|
+
"config.schema.json"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "rm -rf dist && tsc -p tsconfig.json",
|
|
13
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
14
|
+
"test": "vitest run"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@meetlobster/shared": "^1.3.0",
|
|
18
|
+
"@meetlobster/worker": "^1.3.0"
|
|
19
|
+
},
|
|
20
|
+
"publishConfig": {
|
|
21
|
+
"access": "public"
|
|
22
|
+
}
|
|
23
|
+
}
|