@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 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 (gRPC)",
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 result = await setupAdapter.applyAccountConfig(params);
111
- return result;
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 const setBuzRuntime = (_runtime: any) => {
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.1",
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.25.76"
30
+ "zod": "^4.3.6"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "openclaw": "*"
package/src/inbound.ts CHANGED
@@ -1,5 +1,7 @@
1
- import { recordInboundSession } from "openclaw/plugin-sdk";
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 resolveDispatchReplyWithBufferedBlockDispatcher(ctx: any):
15
- | ((params: any) => Promise<any>)
16
- | null {
17
- return (
18
- ctx?.runtime?.channel?.reply?.dispatchReplyWithBufferedBlockDispatcher ??
19
- ctx?.core?.channel?.reply?.dispatchReplyWithBufferedBlockDispatcher ??
20
- null
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?.session?.storePath || ".openclaw/sessions";
71
- console.log("[buz inbound] recording inbound session, storePath:", storePath);
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
- await recordInboundSession({
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
- sessionKey: ctxPayload.SessionKey,
78
- ctx: ctxPayload,
79
- updateLastRoute: {
80
- sessionKey: ctxPayload.SessionKey,
81
- channel: "buz",
82
- to: toTarget,
83
- accountId,
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
- console.log("[buz inbound] session recorded successfully");
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
- if (!serverAddress) return { ok: false, error: "Server Address is required" };
21
- if (!secretKey) return { ok: false, error: "Secret Key is required" };
22
- return { ok: true, values: input };
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 entire cfg object, not just the channels part
97
- return { cfg: newCfg, accountId: resolvedAccountId };
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
  };