@buz-extensions/buz 1.0.0-beta.1 → 1.0.0-beta.11
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/index.ts +5 -22
- package/package.json +2 -2
- package/src/inbound.ts +62 -68
- package/src/setup.ts +8 -5
package/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ChannelPlugin, OpenClawPluginApi } from "openclaw/plugin-sdk/line";
|
|
2
2
|
import { emptyPluginConfigSchema } from "openclaw/plugin-sdk/line";
|
|
3
3
|
import { buildChannelConfigSchema } from "openclaw/plugin-sdk/line";
|
|
4
|
+
import { setBuzRuntime } from "./src/inbound.js";
|
|
4
5
|
import { z } from "zod";
|
|
5
6
|
|
|
6
7
|
const BuzAccountSchema = z
|
|
@@ -25,7 +26,7 @@ export const buzChannelPlugin = {
|
|
|
25
26
|
meta: {
|
|
26
27
|
id: "buz",
|
|
27
28
|
label: "buz",
|
|
28
|
-
selectionLabel: "buz (
|
|
29
|
+
selectionLabel: "buz (voice chat)",
|
|
29
30
|
docsPath: "/channels/buz",
|
|
30
31
|
blurb: "Connect OpenClaw to buz via gRPC bidirectional stream.",
|
|
31
32
|
},
|
|
@@ -84,22 +85,6 @@ export const buzChannelPlugin = {
|
|
|
84
85
|
},
|
|
85
86
|
resolveSessionTarget: ({ id }: any) => id,
|
|
86
87
|
},
|
|
87
|
-
setupWizard: {
|
|
88
|
-
steps: [
|
|
89
|
-
{
|
|
90
|
-
id: "serverAddress",
|
|
91
|
-
type: "text",
|
|
92
|
-
label: "Server Address",
|
|
93
|
-
placeholder: "e.g. grpc.buz.ai:443",
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
id: "secretKey",
|
|
97
|
-
type: "password",
|
|
98
|
-
label: "Secret Key",
|
|
99
|
-
placeholder: "Enter your IM Secret Key",
|
|
100
|
-
},
|
|
101
|
-
],
|
|
102
|
-
},
|
|
103
88
|
setup: {
|
|
104
89
|
validateInput: async (params: any) => {
|
|
105
90
|
const { setupAdapter } = await import("./src/setup.js");
|
|
@@ -107,8 +92,8 @@ export const buzChannelPlugin = {
|
|
|
107
92
|
},
|
|
108
93
|
applyAccountConfig: async (params: any) => {
|
|
109
94
|
const { setupAdapter } = await import("./src/setup.js");
|
|
110
|
-
const
|
|
111
|
-
return
|
|
95
|
+
const newCfg = await setupAdapter.applyAccountConfig(params);
|
|
96
|
+
return newCfg;
|
|
112
97
|
},
|
|
113
98
|
},
|
|
114
99
|
outbound: {
|
|
@@ -181,9 +166,7 @@ export const buzChannelPlugin = {
|
|
|
181
166
|
},
|
|
182
167
|
} as any;
|
|
183
168
|
|
|
184
|
-
export
|
|
185
|
-
// buz doesn't need special runtime setup yet
|
|
186
|
-
};
|
|
169
|
+
export { setBuzRuntime } from "./src/inbound.js";
|
|
187
170
|
|
|
188
171
|
const plugin = {
|
|
189
172
|
id: "buz",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buz-extensions/buz",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.11",
|
|
4
4
|
"description": "OpenClaw buz channel plugin",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@grpc/grpc-js": "^1.10.0",
|
|
29
29
|
"@grpc/proto-loader": "^0.7.10",
|
|
30
|
-
"zod": "^3.
|
|
30
|
+
"zod": "^4.3.6"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"openclaw": "*"
|
package/src/inbound.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { recordInboundSessionAndDispatchReply } from "openclaw/plugin-sdk";
|
|
2
2
|
import { sendText } from "./outbound.js";
|
|
3
|
+
import { resolve } from "path";
|
|
4
|
+
import { homedir } from "os";
|
|
3
5
|
|
|
4
6
|
function resolveDefaultAgentIdCompat(cfg: any): string {
|
|
5
7
|
const configured = cfg?.defaultAgentId ?? cfg?.agents?.default ?? cfg?.agent?.default;
|
|
@@ -11,14 +13,26 @@ function resolveDefaultAgentIdCompat(cfg: any): string {
|
|
|
11
13
|
return firstAgentId || "default";
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
function
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
16
|
+
function resolveStorePath(cfg: any): string {
|
|
17
|
+
const configuredPath = cfg?.session?.storePath || ".openclaw/sessions";
|
|
18
|
+
if (configuredPath.startsWith("/") || configuredPath.startsWith("~")) {
|
|
19
|
+
return configuredPath.replace(/^~/, homedir());
|
|
20
|
+
}
|
|
21
|
+
return resolve(homedir(), configuredPath);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Simple runtime store without using createPluginRuntimeStore
|
|
25
|
+
let buzRuntime: any = null;
|
|
26
|
+
|
|
27
|
+
export function setBuzRuntime(runtime: any) {
|
|
28
|
+
buzRuntime = runtime;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export function getBuzRuntime() {
|
|
32
|
+
if (!buzRuntime) {
|
|
33
|
+
throw new Error("Buz runtime not initialized");
|
|
34
|
+
}
|
|
35
|
+
return buzRuntime;
|
|
22
36
|
}
|
|
23
37
|
|
|
24
38
|
export async function handleInboundMessage(ctx: any, inboundMsg: any) {
|
|
@@ -67,77 +81,57 @@ export async function handleInboundMessage(ctx: any, inboundMsg: any) {
|
|
|
67
81
|
|
|
68
82
|
console.log("[buz inbound] ctxPayload:", JSON.stringify(ctxPayload, null, 2));
|
|
69
83
|
|
|
70
|
-
const storePath = cfg
|
|
71
|
-
console.log("[buz inbound]
|
|
84
|
+
const storePath = resolveStorePath(cfg);
|
|
85
|
+
console.log("[buz inbound] storePath:", storePath);
|
|
72
86
|
console.log("[buz inbound] sessionKey:", ctxPayload.SessionKey);
|
|
73
87
|
|
|
74
88
|
try {
|
|
75
|
-
|
|
89
|
+
console.log("[buz inbound] dispatching via recordInboundSessionAndDispatchReply...");
|
|
90
|
+
|
|
91
|
+
// Get core from ctx.runtime or global runtime
|
|
92
|
+
const core = ctx.runtime?.core || buzRuntime?.core;
|
|
93
|
+
|
|
94
|
+
if (!core) {
|
|
95
|
+
throw new Error("Core runtime not available in context. Make sure runtime is set.");
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
await recordInboundSessionAndDispatchReply({
|
|
99
|
+
recordInboundSession: core.channel.session.recordInboundSession,
|
|
100
|
+
dispatchReplyWithBufferedBlockDispatcher: core.channel.reply.dispatchReplyWithBufferedBlockDispatcher,
|
|
76
101
|
storePath,
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
102
|
+
ctxPayload,
|
|
103
|
+
agentId,
|
|
104
|
+
channel: "buz",
|
|
105
|
+
accountId,
|
|
106
|
+
deliver: async (payload: any, info: any) => {
|
|
107
|
+
console.log(
|
|
108
|
+
"[buz inbound] deliver called:",
|
|
109
|
+
info?.kind,
|
|
110
|
+
"text:",
|
|
111
|
+
payload?.text?.substring?.(0, 50),
|
|
112
|
+
);
|
|
113
|
+
if (!payload?.text) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
await sendText({
|
|
117
|
+
to: toTarget,
|
|
118
|
+
text: payload.text,
|
|
119
|
+
accountId,
|
|
120
|
+
replyToId: inboundMsg.message_id,
|
|
121
|
+
});
|
|
122
|
+
console.log("[buz inbound] reply sent successfully via gRPC");
|
|
84
123
|
},
|
|
85
|
-
onRecordError: (err) => {
|
|
124
|
+
onRecordError: (err: any) => {
|
|
86
125
|
console.error("[buz inbound] failed to record session:", err);
|
|
87
126
|
},
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
} catch (err: any) {
|
|
91
|
-
console.error("[buz inbound] error recording session:", err.message);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
const dispatchReplyWithBufferedBlockDispatcher =
|
|
95
|
-
resolveDispatchReplyWithBufferedBlockDispatcher(ctx);
|
|
96
|
-
if (!dispatchReplyWithBufferedBlockDispatcher) {
|
|
97
|
-
const error = new Error(
|
|
98
|
-
"OpenClaw reply runtime is unavailable on plugin context; missing channel reply dispatcher",
|
|
99
|
-
);
|
|
100
|
-
console.error("[buz inbound] failed to dispatch:", error.message);
|
|
101
|
-
ctx.log?.error?.(`[${accountId}] Failed to dispatch inbound message: ${error.message}`);
|
|
102
|
-
throw error;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
try {
|
|
106
|
-
console.log("[buz inbound] dispatching inbound message...");
|
|
107
|
-
await dispatchReplyWithBufferedBlockDispatcher({
|
|
108
|
-
ctx: ctxPayload as any,
|
|
109
|
-
cfg,
|
|
110
|
-
dispatcherOptions: {
|
|
111
|
-
cfg,
|
|
112
|
-
agentId,
|
|
113
|
-
channel: "buz",
|
|
114
|
-
accountId,
|
|
115
|
-
deliver: async (payload: any, info: any) => {
|
|
116
|
-
console.log(
|
|
117
|
-
"[buz inbound] deliver called:",
|
|
118
|
-
info?.kind,
|
|
119
|
-
"text:",
|
|
120
|
-
payload?.text?.substring?.(0, 50),
|
|
121
|
-
);
|
|
122
|
-
if (!payload?.text) {
|
|
123
|
-
return;
|
|
124
|
-
}
|
|
125
|
-
await sendText({
|
|
126
|
-
to: toTarget,
|
|
127
|
-
text: payload.text,
|
|
128
|
-
accountId,
|
|
129
|
-
replyToId: inboundMsg.message_id,
|
|
130
|
-
});
|
|
131
|
-
console.log("[buz inbound] reply sent successfully via gRPC");
|
|
132
|
-
},
|
|
133
|
-
onError: (err: any, info: any) => {
|
|
134
|
-
console.error(`[buz inbound] ${info?.kind || "unknown"} reply failed:`, err);
|
|
135
|
-
},
|
|
127
|
+
onDispatchError: (err: any, info: any) => {
|
|
128
|
+
console.error(`[buz inbound] ${info?.kind || "unknown"} reply failed:`, err);
|
|
136
129
|
},
|
|
137
130
|
replyOptions: {
|
|
138
131
|
disableBlockStreaming: true,
|
|
139
132
|
},
|
|
140
133
|
});
|
|
134
|
+
|
|
141
135
|
console.log("[buz inbound] message dispatched successfully");
|
|
142
136
|
ctx.log?.info?.(
|
|
143
137
|
`[${accountId}] Successfully dispatched inbound message from ${inboundMsg.sender_id}`,
|
package/src/setup.ts
CHANGED
|
@@ -17,9 +17,11 @@ export const setupAdapter = {
|
|
|
17
17
|
secretKeyLength: secretKey?.length,
|
|
18
18
|
});
|
|
19
19
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
20
|
+
// Return error message as string, or null if valid
|
|
21
|
+
// According to ChannelSetupAdapter.validateInput type: string | null
|
|
22
|
+
if (!serverAddress) return "Server Address is required";
|
|
23
|
+
if (!secretKey) return "Secret Key is required";
|
|
24
|
+
return null;
|
|
23
25
|
},
|
|
24
26
|
|
|
25
27
|
applyAccountConfig: async (params: any) => {
|
|
@@ -93,7 +95,8 @@ export const setupAdapter = {
|
|
|
93
95
|
defaultAccountKeys: Object.keys(newCfg.channels["buz"].accounts.default || {}),
|
|
94
96
|
});
|
|
95
97
|
|
|
96
|
-
// IMPORTANT: Return the
|
|
97
|
-
|
|
98
|
+
// IMPORTANT: Return only the cfg object, NOT { cfg, accountId }
|
|
99
|
+
// The ChannelSetupAdapter.applyAccountConfig expects OpenClawConfig as return type
|
|
100
|
+
return newCfg;
|
|
98
101
|
},
|
|
99
102
|
};
|