owpenwork 0.1.14 → 0.1.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bridge.js +38 -0
- package/dist/cli.js +18 -3
- package/dist/config.js +6 -6
- package/dist/telegram.js +4 -0
- package/package.json +1 -1
package/dist/bridge.js
CHANGED
|
@@ -31,8 +31,20 @@ export async function startBridge(config, logger, reporter) {
|
|
|
31
31
|
store.seedAllowlist("telegram", config.allowlist.telegram);
|
|
32
32
|
store.seedAllowlist("whatsapp", [...config.whatsappAllowFrom].filter((entry) => entry !== "*"));
|
|
33
33
|
store.prunePairingRequests();
|
|
34
|
+
logger.debug({
|
|
35
|
+
configPath: config.configPath,
|
|
36
|
+
opencodeUrl: config.opencodeUrl,
|
|
37
|
+
opencodeDirectory: config.opencodeDirectory,
|
|
38
|
+
telegramEnabled: config.telegramEnabled,
|
|
39
|
+
telegramTokenPresent: Boolean(config.telegramToken),
|
|
40
|
+
whatsappEnabled: config.whatsappEnabled,
|
|
41
|
+
groupsEnabled: config.groupsEnabled,
|
|
42
|
+
permissionMode: config.permissionMode,
|
|
43
|
+
toolUpdatesEnabled: config.toolUpdatesEnabled,
|
|
44
|
+
}, "bridge config");
|
|
34
45
|
const adapters = new Map();
|
|
35
46
|
if (config.telegramEnabled && config.telegramToken) {
|
|
47
|
+
logger.debug("telegram adapter enabled");
|
|
36
48
|
adapters.set("telegram", createTelegramAdapter(config, logger, handleInbound));
|
|
37
49
|
}
|
|
38
50
|
else {
|
|
@@ -40,6 +52,7 @@ export async function startBridge(config, logger, reporter) {
|
|
|
40
52
|
reportStatus?.("Telegram adapter disabled.");
|
|
41
53
|
}
|
|
42
54
|
if (config.whatsappEnabled) {
|
|
55
|
+
logger.debug("whatsapp adapter enabled");
|
|
43
56
|
adapters.set("whatsapp", createWhatsAppAdapter(config, logger, handleInbound, { printQr: true, onStatus: reportStatus }));
|
|
44
57
|
}
|
|
45
58
|
else {
|
|
@@ -241,6 +254,7 @@ export async function startBridge(config, logger, reporter) {
|
|
|
241
254
|
if (!adapter)
|
|
242
255
|
return;
|
|
243
256
|
const kind = options.kind ?? "system";
|
|
257
|
+
logger.debug({ channel, peerId, kind, length: text.length }, "sendText requested");
|
|
244
258
|
if (options.display !== false) {
|
|
245
259
|
reporter?.onOutbound?.({ channel, peerId, text, kind });
|
|
246
260
|
}
|
|
@@ -255,6 +269,13 @@ export async function startBridge(config, logger, reporter) {
|
|
|
255
269
|
if (!adapter)
|
|
256
270
|
return;
|
|
257
271
|
let inbound = message;
|
|
272
|
+
logger.debug({
|
|
273
|
+
channel: inbound.channel,
|
|
274
|
+
peerId: inbound.peerId,
|
|
275
|
+
fromMe: inbound.fromMe,
|
|
276
|
+
length: inbound.text.length,
|
|
277
|
+
preview: truncateText(inbound.text.trim(), 120),
|
|
278
|
+
}, "inbound received");
|
|
258
279
|
logger.info({ channel: inbound.channel, peerId: inbound.peerId, length: inbound.text.length }, "received message");
|
|
259
280
|
const peerKey = inbound.channel === "whatsapp" ? normalizeWhatsAppId(inbound.peerId) : inbound.peerId;
|
|
260
281
|
if (inbound.channel === "whatsapp") {
|
|
@@ -264,6 +285,7 @@ export async function startBridge(config, logger, reporter) {
|
|
|
264
285
|
const allowAll = config.whatsappDmPolicy === "open" || config.whatsappAllowFrom.has("*");
|
|
265
286
|
const isSelf = Boolean(inbound.fromMe && config.whatsappSelfChatMode);
|
|
266
287
|
const allowed = allowAll || isSelf || store.isAllowed("whatsapp", peerKey);
|
|
288
|
+
logger.debug({ allowAll, isSelf, allowed, dmPolicy: config.whatsappDmPolicy, peerKey }, "whatsapp allowlist check");
|
|
267
289
|
if (!allowed) {
|
|
268
290
|
if (config.whatsappDmPolicy === "allowlist") {
|
|
269
291
|
await sendText(inbound.channel, inbound.peerId, "Access denied. Ask the owner to allowlist your number.", { kind: "system" });
|
|
@@ -286,6 +308,7 @@ export async function startBridge(config, logger, reporter) {
|
|
|
286
308
|
}
|
|
287
309
|
else if (config.allowlist[inbound.channel].size > 0) {
|
|
288
310
|
if (!store.isAllowed(inbound.channel, peerKey)) {
|
|
311
|
+
logger.debug({ channel: inbound.channel, peerKey }, "telegram allowlist denied");
|
|
289
312
|
await sendText(inbound.channel, inbound.peerId, "Access denied.", { kind: "system" });
|
|
290
313
|
return;
|
|
291
314
|
}
|
|
@@ -298,6 +321,12 @@ export async function startBridge(config, logger, reporter) {
|
|
|
298
321
|
});
|
|
299
322
|
const session = store.getSession(inbound.channel, peerKey);
|
|
300
323
|
const sessionID = session?.session_id ?? (await createSession({ ...inbound, peerId: peerKey }));
|
|
324
|
+
logger.debug({
|
|
325
|
+
sessionID,
|
|
326
|
+
channel: inbound.channel,
|
|
327
|
+
peerId: inbound.peerId,
|
|
328
|
+
reused: Boolean(session?.session_id),
|
|
329
|
+
}, "session resolved");
|
|
301
330
|
enqueue(sessionID, async () => {
|
|
302
331
|
const runState = {
|
|
303
332
|
sessionID,
|
|
@@ -310,20 +339,29 @@ export async function startBridge(config, logger, reporter) {
|
|
|
310
339
|
reportThinking(runState);
|
|
311
340
|
startTyping(runState);
|
|
312
341
|
try {
|
|
342
|
+
logger.debug({ sessionID, length: inbound.text.length }, "prompt start");
|
|
313
343
|
const response = await client.session.prompt({
|
|
314
344
|
sessionID,
|
|
315
345
|
parts: [{ type: "text", text: inbound.text }],
|
|
316
346
|
});
|
|
317
347
|
const parts = response.parts ?? [];
|
|
348
|
+
const textParts = parts.filter((part) => part.type === "text" && !part.ignored);
|
|
349
|
+
logger.debug({
|
|
350
|
+
sessionID,
|
|
351
|
+
partCount: parts.length,
|
|
352
|
+
textCount: textParts.length,
|
|
353
|
+
}, "prompt response");
|
|
318
354
|
const reply = parts
|
|
319
355
|
.filter((part) => part.type === "text" && !part.ignored)
|
|
320
356
|
.map((part) => part.text ?? "")
|
|
321
357
|
.join("\n")
|
|
322
358
|
.trim();
|
|
323
359
|
if (reply) {
|
|
360
|
+
logger.debug({ sessionID, replyLength: reply.length }, "reply built");
|
|
324
361
|
await sendText(inbound.channel, inbound.peerId, reply, { kind: "reply" });
|
|
325
362
|
}
|
|
326
363
|
else {
|
|
364
|
+
logger.debug({ sessionID }, "reply empty");
|
|
327
365
|
await sendText(inbound.channel, inbound.peerId, "No response generated. Try again.", {
|
|
328
366
|
kind: "system",
|
|
329
367
|
});
|
package/dist/cli.js
CHANGED
|
@@ -10,7 +10,7 @@ import { createLogger } from "./logger.js";
|
|
|
10
10
|
import { createClient } from "./opencode.js";
|
|
11
11
|
import { truncateText } from "./text.js";
|
|
12
12
|
import { loginWhatsApp, unpairWhatsApp } from "./whatsapp.js";
|
|
13
|
-
const VERSION = "0.1.
|
|
13
|
+
const VERSION = "0.1.16";
|
|
14
14
|
const STEP_OPTIONS = [
|
|
15
15
|
{
|
|
16
16
|
value: "config",
|
|
@@ -54,12 +54,14 @@ function parseSelections(raw) {
|
|
|
54
54
|
.filter((item) => STEP_SET.has(item));
|
|
55
55
|
return selections.length ? selections : [];
|
|
56
56
|
}
|
|
57
|
-
function defaultSelections(configExists, whatsappLinked) {
|
|
57
|
+
function defaultSelections(configExists, whatsappLinked, telegramLinked) {
|
|
58
58
|
const selections = [];
|
|
59
59
|
if (!configExists)
|
|
60
60
|
selections.push("config");
|
|
61
61
|
if (!whatsappLinked)
|
|
62
62
|
selections.push("whatsapp");
|
|
63
|
+
if (!telegramLinked)
|
|
64
|
+
selections.push("telegram");
|
|
63
65
|
selections.push("start");
|
|
64
66
|
return selections;
|
|
65
67
|
}
|
|
@@ -182,6 +184,19 @@ async function runSetupWizard(config, options) {
|
|
|
182
184
|
allowFrom = allowFrom.length ? allowFrom : ["*"];
|
|
183
185
|
}
|
|
184
186
|
}
|
|
187
|
+
const currentWorkspace = config.configFile.opencodeDirectory ?? config.opencodeDirectory;
|
|
188
|
+
const keepDefault = unwrap(await confirm({
|
|
189
|
+
message: `Use this OpenCode workspace? (${currentWorkspace})`,
|
|
190
|
+
initialValue: true,
|
|
191
|
+
}));
|
|
192
|
+
if (!keepDefault) {
|
|
193
|
+
const workspace = unwrap(await text({
|
|
194
|
+
message: "OpenCode workspace path",
|
|
195
|
+
placeholder: "/path/to/workspace",
|
|
196
|
+
validate: (value) => (String(value ?? "").trim() ? undefined : "Path required"),
|
|
197
|
+
}));
|
|
198
|
+
next.opencodeDirectory = workspace.trim();
|
|
199
|
+
}
|
|
185
200
|
next.channels = next.channels ?? {};
|
|
186
201
|
next.channels.whatsapp = {
|
|
187
202
|
dmPolicy,
|
|
@@ -275,7 +290,7 @@ async function runGuidedFlow(pathArg, opts) {
|
|
|
275
290
|
unwrap(await multiselect({
|
|
276
291
|
message: "Select what to set up",
|
|
277
292
|
options: STEP_OPTIONS,
|
|
278
|
-
initialValues: defaultSelections(configExists, whatsappLinked),
|
|
293
|
+
initialValues: defaultSelections(configExists, whatsappLinked, Boolean(config.telegramToken)),
|
|
279
294
|
required: false,
|
|
280
295
|
}));
|
|
281
296
|
const selectedSteps = Array.isArray(selections) ? selections : [];
|
package/dist/config.js
CHANGED
|
@@ -118,16 +118,16 @@ function parseAllowlist(env) {
|
|
|
118
118
|
}
|
|
119
119
|
export function loadConfig(env = process.env, options = {}) {
|
|
120
120
|
const requireOpencode = options.requireOpencode ?? false;
|
|
121
|
-
const opencodeDirectory = env.OPENCODE_DIRECTORY?.trim() ?? "";
|
|
122
|
-
if (!opencodeDirectory && requireOpencode) {
|
|
123
|
-
throw new Error("OPENCODE_DIRECTORY is required");
|
|
124
|
-
}
|
|
125
|
-
const resolvedDirectory = opencodeDirectory || process.cwd();
|
|
126
121
|
const dataDir = expandHome(env.OWPENBOT_DATA_DIR ?? "~/.owpenbot");
|
|
127
122
|
const dbPath = expandHome(env.OWPENBOT_DB_PATH ?? path.join(dataDir, "owpenbot.db"));
|
|
128
123
|
const logFile = expandHome(env.OWPENBOT_LOG_FILE ?? path.join(dataDir, "logs", "owpenbot.log"));
|
|
129
124
|
const configPath = resolveConfigPath(dataDir, env);
|
|
130
125
|
const { config: configFile } = readConfigFile(configPath);
|
|
126
|
+
const opencodeDirectory = env.OPENCODE_DIRECTORY?.trim() || configFile.opencodeDirectory || "";
|
|
127
|
+
if (!opencodeDirectory && requireOpencode) {
|
|
128
|
+
throw new Error("OPENCODE_DIRECTORY is required");
|
|
129
|
+
}
|
|
130
|
+
const resolvedDirectory = opencodeDirectory || process.cwd();
|
|
131
131
|
const whatsappFile = configFile.channels?.whatsapp ?? {};
|
|
132
132
|
const whatsappAccountId = env.WHATSAPP_ACCOUNT_ID?.trim() || "default";
|
|
133
133
|
const accountAuthDir = whatsappFile.accounts?.[whatsappAccountId]?.authDir;
|
|
@@ -146,7 +146,7 @@ export function loadConfig(env = process.env, options = {}) {
|
|
|
146
146
|
return {
|
|
147
147
|
configPath,
|
|
148
148
|
configFile,
|
|
149
|
-
opencodeUrl: env.OPENCODE_URL?.trim()
|
|
149
|
+
opencodeUrl: env.OPENCODE_URL?.trim() || configFile.opencodeUrl || "http://127.0.0.1:4096",
|
|
150
150
|
opencodeDirectory: resolvedDirectory,
|
|
151
151
|
opencodeUsername: env.OPENCODE_SERVER_USERNAME?.trim() || undefined,
|
|
152
152
|
opencodePassword: env.OPENCODE_SERVER_PASSWORD?.trim() || undefined,
|
package/dist/telegram.js
CHANGED
|
@@ -4,6 +4,7 @@ export function createTelegramAdapter(config, logger, onMessage) {
|
|
|
4
4
|
if (!config.telegramToken) {
|
|
5
5
|
throw new Error("TELEGRAM_BOT_TOKEN is required for Telegram adapter");
|
|
6
6
|
}
|
|
7
|
+
logger.debug({ tokenPresent: true }, "telegram adapter init");
|
|
7
8
|
const bot = new Bot(config.telegramToken);
|
|
8
9
|
bot.catch((err) => {
|
|
9
10
|
logger.error({ error: err.error }, "telegram bot error");
|
|
@@ -15,11 +16,13 @@ export function createTelegramAdapter(config, logger, onMessage) {
|
|
|
15
16
|
const chatType = msg.chat.type;
|
|
16
17
|
const isGroup = chatType === "group" || chatType === "supergroup" || chatType === "channel";
|
|
17
18
|
if (isGroup && !config.groupsEnabled) {
|
|
19
|
+
logger.debug({ chatId: msg.chat.id, chatType }, "telegram message ignored (group disabled)");
|
|
18
20
|
return;
|
|
19
21
|
}
|
|
20
22
|
const text = msg.text ?? msg.caption ?? "";
|
|
21
23
|
if (!text.trim())
|
|
22
24
|
return;
|
|
25
|
+
logger.debug({ chatId: msg.chat.id, chatType, length: text.length, preview: text.slice(0, 120) }, "telegram message received");
|
|
23
26
|
try {
|
|
24
27
|
await onMessage({
|
|
25
28
|
channel: "telegram",
|
|
@@ -36,6 +39,7 @@ export function createTelegramAdapter(config, logger, onMessage) {
|
|
|
36
39
|
name: "telegram",
|
|
37
40
|
maxTextLength: MAX_TEXT_LENGTH,
|
|
38
41
|
async start() {
|
|
42
|
+
logger.debug("telegram adapter starting");
|
|
39
43
|
await bot.start();
|
|
40
44
|
logger.info("telegram adapter started");
|
|
41
45
|
},
|