@buz-extensions/buz 1.0.0-beta.1 → 1.0.0-beta.10

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/runtime.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,31 +85,17 @@ 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");
91
+ // Returns string (error message) or null (valid)
106
92
  return setupAdapter.validateInput(params);
107
93
  },
108
94
  applyAccountConfig: async (params: any) => {
109
95
  const { setupAdapter } = await import("./src/setup.js");
110
- const result = await setupAdapter.applyAccountConfig(params);
111
- return result;
96
+ // Returns OpenClawConfig directly
97
+ const newCfg = await setupAdapter.applyAccountConfig(params);
98
+ return newCfg;
112
99
  },
113
100
  },
114
101
  outbound: {
@@ -181,9 +168,7 @@ export const buzChannelPlugin = {
181
168
  },
182
169
  } as any;
183
170
 
184
- export const setBuzRuntime = (_runtime: any) => {
185
- // buz doesn't need special runtime setup yet
186
- };
171
+ export { setBuzRuntime } from "./src/runtime.js";
187
172
 
188
173
  const plugin = {
189
174
  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.10",
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,8 @@
1
- import { recordInboundSession } from "openclaw/plugin-sdk";
1
+ import { recordInboundSessionAndDispatchReply } from "openclaw/plugin-sdk";
2
2
  import { sendText } from "./outbound.js";
3
+ import { getBuzRuntime } from "./runtime.js";
4
+ import { resolve } from "path";
5
+ import { homedir } from "os";
3
6
 
4
7
  function resolveDefaultAgentIdCompat(cfg: any): string {
5
8
  const configured = cfg?.defaultAgentId ?? cfg?.agents?.default ?? cfg?.agent?.default;
@@ -11,14 +14,14 @@ function resolveDefaultAgentIdCompat(cfg: any): string {
11
14
  return firstAgentId || "default";
12
15
  }
13
16
 
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
- );
17
+ function resolveStorePath(cfg: any): string {
18
+ const configuredPath = cfg?.session?.storePath || ".openclaw/sessions";
19
+ // If it's already an absolute path, use it as-is
20
+ if (configuredPath.startsWith("/") || configuredPath.startsWith("~")) {
21
+ return configuredPath.replace(/^~/, homedir());
22
+ }
23
+ // Otherwise, resolve relative to home directory
24
+ return resolve(homedir(), configuredPath);
22
25
  }
23
26
 
24
27
  export async function handleInboundMessage(ctx: any, inboundMsg: any) {
@@ -67,77 +70,53 @@ export async function handleInboundMessage(ctx: any, inboundMsg: any) {
67
70
 
68
71
  console.log("[buz inbound] ctxPayload:", JSON.stringify(ctxPayload, null, 2));
69
72
 
70
- const storePath = cfg?.session?.storePath || ".openclaw/sessions";
71
- console.log("[buz inbound] recording inbound session, storePath:", storePath);
73
+ const storePath = resolveStorePath(cfg);
74
+ console.log("[buz inbound] storePath:", storePath);
72
75
  console.log("[buz inbound] sessionKey:", ctxPayload.SessionKey);
73
76
 
74
77
  try {
75
- await recordInboundSession({
78
+ console.log("[buz inbound] dispatching via recordInboundSessionAndDispatchReply...");
79
+
80
+ // Get core from runtime
81
+ const core = getBuzRuntime().core;
82
+
83
+ await recordInboundSessionAndDispatchReply({
84
+ recordInboundSession: core.channel.session.recordInboundSession,
85
+ dispatchReplyWithBufferedBlockDispatcher: core.channel.reply.dispatchReplyWithBufferedBlockDispatcher,
76
86
  storePath,
77
- sessionKey: ctxPayload.SessionKey,
78
- ctx: ctxPayload,
79
- updateLastRoute: {
80
- sessionKey: ctxPayload.SessionKey,
81
- channel: "buz",
82
- to: toTarget,
83
- accountId,
87
+ ctxPayload,
88
+ agentId,
89
+ channel: "buz",
90
+ accountId,
91
+ deliver: async (payload: any, info: any) => {
92
+ console.log(
93
+ "[buz inbound] deliver called:",
94
+ info?.kind,
95
+ "text:",
96
+ payload?.text?.substring?.(0, 50),
97
+ );
98
+ if (!payload?.text) {
99
+ return;
100
+ }
101
+ await sendText({
102
+ to: toTarget,
103
+ text: payload.text,
104
+ accountId,
105
+ replyToId: inboundMsg.message_id,
106
+ });
107
+ console.log("[buz inbound] reply sent successfully via gRPC");
84
108
  },
85
- onRecordError: (err) => {
109
+ onRecordError: (err: any) => {
86
110
  console.error("[buz inbound] failed to record session:", err);
87
111
  },
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
- },
112
+ onDispatchError: (err: any, info: any) => {
113
+ console.error(`[buz inbound] ${info?.kind || "unknown"} reply failed:`, err);
136
114
  },
137
115
  replyOptions: {
138
116
  disableBlockStreaming: true,
139
117
  },
140
118
  });
119
+
141
120
  console.log("[buz inbound] message dispatched successfully");
142
121
  ctx.log?.info?.(
143
122
  `[${accountId}] Successfully dispatched inbound message from ${inboundMsg.sender_id}`,
package/src/runtime.ts ADDED
@@ -0,0 +1,7 @@
1
+ import { createPluginRuntimeStore } from "openclaw/plugin-sdk";
2
+ import type { PluginRuntime } from "openclaw/plugin-sdk";
3
+
4
+ const { setRuntime: setBuzRuntime, getRuntime: getBuzRuntime } =
5
+ createPluginRuntimeStore<PluginRuntime>("Buz runtime not initialized");
6
+
7
+ export { getBuzRuntime, setBuzRuntime };
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
  };