@vibearound/plugin-channel-sdk 0.1.2 → 0.4.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/README.md +62 -108
- package/dist/advanced.d.ts +19 -0
- package/dist/advanced.d.ts.map +1 -0
- package/dist/advanced.js +18 -0
- package/dist/advanced.js.map +1 -0
- package/dist/connection.d.ts +10 -4
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +10 -4
- package/dist/connection.js.map +1 -1
- package/dist/errors.d.ts +16 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +33 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +27 -41
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +30 -41
- package/dist/index.js.map +1 -1
- package/dist/plugin.d.ts +80 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +131 -0
- package/dist/plugin.js.map +1 -0
- package/dist/renderer.d.ts +52 -46
- package/dist/renderer.d.ts.map +1 -1
- package/dist/renderer.js +131 -88
- package/dist/renderer.js.map +1 -1
- package/dist/types.d.ts +19 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +5 -1
- package/src/advanced.ts +43 -0
- package/src/connection.ts +10 -4
- package/src/errors.ts +29 -0
- package/src/index.ts +48 -52
- package/src/plugin.ts +247 -0
- package/src/renderer.ts +199 -94
- package/src/types.ts +24 -0
package/dist/renderer.js
CHANGED
|
@@ -25,32 +25,26 @@
|
|
|
25
25
|
*
|
|
26
26
|
* ## Usage
|
|
27
27
|
*
|
|
28
|
+
* Subclass and implement `sendText` + `sendBlock` (+ optionally `editBlock`):
|
|
29
|
+
*
|
|
28
30
|
* ```ts
|
|
29
31
|
* class MyRenderer extends BlockRenderer<string> {
|
|
30
|
-
* protected async
|
|
31
|
-
*
|
|
32
|
+
* protected async sendText(chatId, text) {
|
|
33
|
+
* await myApi.sendMessage(chatId, text);
|
|
34
|
+
* }
|
|
35
|
+
* protected async sendBlock(chatId, kind, content) {
|
|
36
|
+
* const msg = await myApi.sendMessage(chatId, content);
|
|
32
37
|
* return msg.id;
|
|
33
38
|
* }
|
|
34
|
-
* protected async editBlock(
|
|
39
|
+
* protected async editBlock(chatId, ref, kind, content, sealed) {
|
|
35
40
|
* await myApi.editMessage(ref, content);
|
|
36
41
|
* }
|
|
37
42
|
* }
|
|
38
|
-
*
|
|
39
|
-
* // In main.ts:
|
|
40
|
-
* const renderer = new MyRenderer({ verbose: { showThinking: false } });
|
|
41
|
-
*
|
|
42
|
-
* // When user sends a message:
|
|
43
|
-
* renderer.onPromptSent(channelId);
|
|
44
|
-
* try {
|
|
45
|
-
* await agent.prompt({ sessionId, content });
|
|
46
|
-
* await renderer.onTurnEnd(channelId);
|
|
47
|
-
* } catch (e) {
|
|
48
|
-
* await renderer.onTurnError(channelId, String(e));
|
|
49
|
-
* }
|
|
50
|
-
*
|
|
51
|
-
* // In the ACP client's sessionUpdate handler:
|
|
52
|
-
* renderer.onSessionUpdate(notification);
|
|
53
43
|
* ```
|
|
44
|
+
*
|
|
45
|
+
* The SDK's `runChannelPlugin` wires all ACP events to this renderer
|
|
46
|
+
* automatically — plugins don't call onSessionUpdate/onPromptSent/etc
|
|
47
|
+
* directly.
|
|
54
48
|
*/
|
|
55
49
|
// ---------------------------------------------------------------------------
|
|
56
50
|
// Constants
|
|
@@ -68,11 +62,18 @@ const DEFAULT_MIN_EDIT_INTERVAL_MS = 1000;
|
|
|
68
62
|
* return type of `sendBlock` and the first argument of `editBlock`.
|
|
69
63
|
*/
|
|
70
64
|
export class BlockRenderer {
|
|
65
|
+
/** When true, blocks are sent and edited in real-time. When false, each
|
|
66
|
+
* block is held until complete, then sent once (send-only mode). */
|
|
67
|
+
streaming;
|
|
71
68
|
flushIntervalMs;
|
|
72
69
|
minEditIntervalMs;
|
|
73
70
|
verbose;
|
|
74
71
|
states = new Map();
|
|
72
|
+
/** The chatId of the most recent prompt. Used as fallback target for
|
|
73
|
+
* notifications that arrive without an explicit chatId. */
|
|
74
|
+
lastActiveChatId = null;
|
|
75
75
|
constructor(options = {}) {
|
|
76
|
+
this.streaming = options.streaming ?? true;
|
|
76
77
|
this.flushIntervalMs = options.flushIntervalMs ?? DEFAULT_FLUSH_INTERVAL_MS;
|
|
77
78
|
this.minEditIntervalMs = options.minEditIntervalMs ?? DEFAULT_MIN_EDIT_INTERVAL_MS;
|
|
78
79
|
this.verbose = {
|
|
@@ -99,29 +100,17 @@ export class BlockRenderer {
|
|
|
99
100
|
}
|
|
100
101
|
/**
|
|
101
102
|
* Called after the last block has been flushed and the turn is complete.
|
|
102
|
-
* Override to perform cleanup (e.g. remove a "typing" indicator
|
|
103
|
-
* processing reaction, etc.).
|
|
104
|
-
*/
|
|
105
|
-
onAfterTurnEnd(_channelId) {
|
|
106
|
-
return Promise.resolve();
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Called after a turn error, once state has been cleaned up.
|
|
110
|
-
* Override to send an error message to the user.
|
|
103
|
+
* Override to perform cleanup (e.g. remove a "typing" indicator).
|
|
111
104
|
*/
|
|
112
|
-
|
|
105
|
+
onAfterTurnEnd(_chatId) {
|
|
113
106
|
return Promise.resolve();
|
|
114
107
|
}
|
|
115
108
|
/**
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* Default: identity (sessionId === channelId).
|
|
119
|
-
*
|
|
120
|
-
* Override if your plugin namespaces channel IDs (e.g. Feishu uses
|
|
121
|
-
* `"feishu:<sessionId>"`, WeChat uses `"weixin-openclaw-bridge:<sessionId>"`).
|
|
109
|
+
* Called after a turn error. Default sends an error message via sendText.
|
|
110
|
+
* Override for platform-specific error rendering (e.g. error card).
|
|
122
111
|
*/
|
|
123
|
-
|
|
124
|
-
|
|
112
|
+
async onAfterTurnError(chatId, error) {
|
|
113
|
+
await this.sendText(chatId, `❌ Error: ${error}`);
|
|
125
114
|
}
|
|
126
115
|
// ---------------------------------------------------------------------------
|
|
127
116
|
// Public API
|
|
@@ -132,74 +121,123 @@ export class BlockRenderer {
|
|
|
132
121
|
* Routes the event to the correct block based on its variant, appending
|
|
133
122
|
* deltas to the current block or starting a new one when the kind changes.
|
|
134
123
|
*
|
|
135
|
-
*
|
|
124
|
+
* Called automatically by `runChannelPlugin` — plugins don't call this directly.
|
|
136
125
|
*/
|
|
137
126
|
onSessionUpdate(notification) {
|
|
138
|
-
|
|
139
|
-
//
|
|
140
|
-
const
|
|
141
|
-
const
|
|
142
|
-
const
|
|
143
|
-
|
|
127
|
+
// sessionId from ACP = chatId (the host replaces the real agent session
|
|
128
|
+
// ID with the chat ID before forwarding to the plugin).
|
|
129
|
+
const chatId = notification.sessionId;
|
|
130
|
+
const rawUpdate = notification.update;
|
|
131
|
+
const variant = rawUpdate.sessionUpdate;
|
|
132
|
+
if (variant !== "agent_message_chunk" &&
|
|
133
|
+
variant !== "agent_thought_chunk" &&
|
|
134
|
+
variant !== "tool_call" &&
|
|
135
|
+
variant !== "tool_call_update") {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
const update = rawUpdate;
|
|
139
|
+
switch (update.sessionUpdate) {
|
|
144
140
|
case "agent_message_chunk": {
|
|
145
|
-
const delta =
|
|
141
|
+
const delta = update.content?.text ?? "";
|
|
146
142
|
if (delta)
|
|
147
|
-
this.appendToBlock(
|
|
143
|
+
this.appendToBlock(chatId, "text", delta);
|
|
148
144
|
break;
|
|
149
145
|
}
|
|
150
146
|
case "agent_thought_chunk": {
|
|
151
147
|
if (!this.verbose.showThinking)
|
|
152
|
-
return;
|
|
153
|
-
const delta =
|
|
148
|
+
return;
|
|
149
|
+
const delta = update.content?.text ?? "";
|
|
154
150
|
if (delta)
|
|
155
|
-
this.appendToBlock(
|
|
151
|
+
this.appendToBlock(chatId, "thinking", delta);
|
|
156
152
|
break;
|
|
157
153
|
}
|
|
158
154
|
case "tool_call": {
|
|
159
155
|
if (!this.verbose.showToolUse)
|
|
160
|
-
return;
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
this.appendToBlock(channelId, "tool", `🔧 ${title}\n`);
|
|
156
|
+
return;
|
|
157
|
+
if (update.title)
|
|
158
|
+
this.appendToBlock(chatId, "tool", `🔧 ${update.title}\n`);
|
|
164
159
|
break;
|
|
165
160
|
}
|
|
166
161
|
case "tool_call_update": {
|
|
167
162
|
if (!this.verbose.showToolUse)
|
|
168
|
-
return;
|
|
169
|
-
const title =
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
this.appendToBlock(channelId, "tool", `✅ ${title}\n`);
|
|
163
|
+
return;
|
|
164
|
+
const title = update.title ?? "tool";
|
|
165
|
+
if (update.status === "completed" || update.status === "error") {
|
|
166
|
+
this.appendToBlock(chatId, "tool", `✅ ${title}\n`);
|
|
173
167
|
}
|
|
174
168
|
break;
|
|
175
169
|
}
|
|
176
170
|
}
|
|
177
171
|
}
|
|
178
172
|
/**
|
|
179
|
-
* Call
|
|
180
|
-
*
|
|
181
|
-
* Clears any leftover state from a previous turn so the new turn starts
|
|
182
|
-
* with a clean slate.
|
|
173
|
+
* Call before sending a prompt. Tracks the active chatId and clears
|
|
174
|
+
* leftover state from a previous turn.
|
|
183
175
|
*/
|
|
184
|
-
onPromptSent(
|
|
185
|
-
|
|
176
|
+
onPromptSent(chatId) {
|
|
177
|
+
this.lastActiveChatId = chatId;
|
|
178
|
+
const old = this.states.get(chatId);
|
|
186
179
|
if (old?.flushTimer)
|
|
187
180
|
clearTimeout(old.flushTimer);
|
|
188
|
-
this.states.set(
|
|
181
|
+
this.states.set(chatId, {
|
|
189
182
|
blocks: [],
|
|
190
183
|
flushTimer: null,
|
|
191
184
|
lastEditMs: 0,
|
|
192
185
|
sendChain: Promise.resolve(),
|
|
193
186
|
});
|
|
194
187
|
}
|
|
188
|
+
// ---------------------------------------------------------------------------
|
|
189
|
+
// Host notification handlers — built-in defaults, no per-plugin duplication
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
/** Handle `va/system_text` from host. */
|
|
192
|
+
onSystemText(chatId, text) {
|
|
193
|
+
this.sendText(chatId, text).catch(() => { });
|
|
194
|
+
}
|
|
195
|
+
/** Handle `va/agent_ready` from host. */
|
|
196
|
+
onAgentReady(chatId, agent, version) {
|
|
197
|
+
this.sendText(chatId, `🤖 Agent: ${agent} v${version}`).catch(() => { });
|
|
198
|
+
}
|
|
199
|
+
/** Handle `va/session_ready` from host. */
|
|
200
|
+
onSessionReady(chatId, sessionId) {
|
|
201
|
+
this.sendText(chatId, `📋 Session: ${sessionId}`).catch(() => { });
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Handle `va/command_menu` from host — display available commands.
|
|
205
|
+
*
|
|
206
|
+
* Default renders a plain-text list. Override for platform-specific
|
|
207
|
+
* rendering (e.g. Feishu interactive card, Slack Block Kit, Telegram
|
|
208
|
+
* inline keyboard).
|
|
209
|
+
*/
|
|
210
|
+
onCommandMenu(chatId, systemCommands, agentCommands) {
|
|
211
|
+
const lines = [];
|
|
212
|
+
lines.push("System commands:");
|
|
213
|
+
for (const cmd of systemCommands) {
|
|
214
|
+
const usage = cmd.args ? `/${cmd.name} ${cmd.args}` : `/${cmd.name}`;
|
|
215
|
+
lines.push(` ${usage} — ${cmd.description}`);
|
|
216
|
+
}
|
|
217
|
+
if (agentCommands.length > 0) {
|
|
218
|
+
lines.push("");
|
|
219
|
+
lines.push("Agent commands (use /agent <command>):");
|
|
220
|
+
for (const cmd of agentCommands) {
|
|
221
|
+
const desc = cmd.description.length > 80
|
|
222
|
+
? `${cmd.description.slice(0, 77)}...`
|
|
223
|
+
: cmd.description;
|
|
224
|
+
lines.push(` /${cmd.name} — ${desc}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
lines.push("");
|
|
229
|
+
lines.push("Agent commands will appear after sending your first message.");
|
|
230
|
+
}
|
|
231
|
+
this.sendText(chatId, lines.join("\n")).catch(() => { });
|
|
232
|
+
}
|
|
195
233
|
/**
|
|
196
234
|
* Call this after `agent.prompt()` resolves (turn complete).
|
|
197
235
|
*
|
|
198
236
|
* Seals and flushes the last block, then waits for all pending sends/edits
|
|
199
237
|
* to complete before calling `onAfterTurnEnd`.
|
|
200
238
|
*/
|
|
201
|
-
async onTurnEnd(
|
|
202
|
-
const state = this.states.get(
|
|
239
|
+
async onTurnEnd(chatId) {
|
|
240
|
+
const state = this.states.get(chatId);
|
|
203
241
|
if (!state)
|
|
204
242
|
return;
|
|
205
243
|
if (state.flushTimer) {
|
|
@@ -211,33 +249,31 @@ export class BlockRenderer {
|
|
|
211
249
|
last.sealed = true;
|
|
212
250
|
this.enqueueFlush(state, last);
|
|
213
251
|
}
|
|
214
|
-
// Wait for the entire chain to drain before cleanup
|
|
215
252
|
await state.sendChain;
|
|
216
|
-
this.states.delete(
|
|
217
|
-
await this.onAfterTurnEnd(
|
|
253
|
+
this.states.delete(chatId);
|
|
254
|
+
await this.onAfterTurnEnd(chatId);
|
|
218
255
|
}
|
|
219
256
|
/**
|
|
220
257
|
* Call this when `agent.prompt()` throws (turn error).
|
|
221
258
|
*
|
|
222
|
-
* Discards pending state and calls `onAfterTurnError
|
|
223
|
-
* send an error message to the user.
|
|
259
|
+
* Discards pending state and calls `onAfterTurnError`.
|
|
224
260
|
*/
|
|
225
|
-
async onTurnError(
|
|
226
|
-
const state = this.states.get(
|
|
261
|
+
async onTurnError(chatId, error) {
|
|
262
|
+
const state = this.states.get(chatId);
|
|
227
263
|
if (state?.flushTimer)
|
|
228
264
|
clearTimeout(state.flushTimer);
|
|
229
|
-
this.states.delete(
|
|
230
|
-
await this.onAfterTurnError(
|
|
265
|
+
this.states.delete(chatId);
|
|
266
|
+
await this.onAfterTurnError(chatId, error);
|
|
231
267
|
}
|
|
232
268
|
// ---------------------------------------------------------------------------
|
|
233
269
|
// Internal — block management
|
|
234
270
|
// ---------------------------------------------------------------------------
|
|
235
|
-
appendToBlock(
|
|
236
|
-
let state = this.states.get(
|
|
271
|
+
appendToBlock(chatId, kind, delta) {
|
|
272
|
+
let state = this.states.get(chatId);
|
|
237
273
|
if (!state) {
|
|
238
274
|
// Auto-create state if onPromptSent wasn't called (e.g. host-initiated turns)
|
|
239
275
|
state = { blocks: [], flushTimer: null, lastEditMs: 0, sendChain: Promise.resolve() };
|
|
240
|
-
this.states.set(
|
|
276
|
+
this.states.set(chatId, state);
|
|
241
277
|
}
|
|
242
278
|
const last = state.blocks.at(-1);
|
|
243
279
|
if (last && !last.sealed && last.kind === kind) {
|
|
@@ -255,22 +291,29 @@ export class BlockRenderer {
|
|
|
255
291
|
}
|
|
256
292
|
this.enqueueFlush(state, last);
|
|
257
293
|
}
|
|
258
|
-
state.blocks.push({
|
|
294
|
+
state.blocks.push({ chatId, kind, content: delta, ref: null, creating: false, sealed: false });
|
|
259
295
|
}
|
|
260
|
-
this.scheduleFlush(
|
|
296
|
+
this.scheduleFlush(chatId, state);
|
|
261
297
|
}
|
|
262
|
-
scheduleFlush(
|
|
298
|
+
scheduleFlush(chatId, state) {
|
|
263
299
|
if (state.flushTimer)
|
|
264
300
|
return; // already scheduled
|
|
265
301
|
state.flushTimer = setTimeout(() => {
|
|
266
302
|
state.flushTimer = null;
|
|
267
|
-
this.flush(
|
|
303
|
+
this.flush(chatId, state);
|
|
268
304
|
}, this.flushIntervalMs);
|
|
269
305
|
}
|
|
270
|
-
flush(
|
|
306
|
+
flush(chatId, state) {
|
|
271
307
|
const block = state.blocks.at(-1);
|
|
272
308
|
if (!block || block.sealed || !block.content)
|
|
273
309
|
return;
|
|
310
|
+
// Send-only mode (streaming=false): defer intermediate sends.
|
|
311
|
+
// Only sealed blocks (from onTurnEnd or block boundary transitions)
|
|
312
|
+
// will actually POST. This prevents the user seeing a partial chunk
|
|
313
|
+
// followed by the full message as two separate messages.
|
|
314
|
+
if (!this.streaming) {
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
274
317
|
const now = Date.now();
|
|
275
318
|
if (now - state.lastEditMs < this.minEditIntervalMs) {
|
|
276
319
|
// Throttled — reschedule for the remaining window
|
|
@@ -278,7 +321,7 @@ export class BlockRenderer {
|
|
|
278
321
|
if (!state.flushTimer) {
|
|
279
322
|
state.flushTimer = setTimeout(() => {
|
|
280
323
|
state.flushTimer = null;
|
|
281
|
-
this.flush(
|
|
324
|
+
this.flush(chatId, state);
|
|
282
325
|
}, delay);
|
|
283
326
|
}
|
|
284
327
|
return;
|
|
@@ -298,13 +341,13 @@ export class BlockRenderer {
|
|
|
298
341
|
if (block.ref === null && !block.creating) {
|
|
299
342
|
// First send — use sentinel to prevent concurrent creates
|
|
300
343
|
block.creating = true;
|
|
301
|
-
block.ref = await this.sendBlock(block.
|
|
344
|
+
block.ref = await this.sendBlock(block.chatId, block.kind, content);
|
|
302
345
|
block.creating = false;
|
|
303
346
|
state.lastEditMs = Date.now();
|
|
304
347
|
}
|
|
305
|
-
else if (block.ref !== null && !block.creating && this.editBlock) {
|
|
306
|
-
// Subsequent update — edit in-place
|
|
307
|
-
await this.editBlock(block.
|
|
348
|
+
else if (block.ref !== null && !block.creating && this.streaming && this.editBlock) {
|
|
349
|
+
// Subsequent update — edit in-place (streaming mode only)
|
|
350
|
+
await this.editBlock(block.chatId, block.ref, block.kind, content, block.sealed);
|
|
308
351
|
state.lastEditMs = Date.now();
|
|
309
352
|
}
|
|
310
353
|
// else: create is in-flight (creating === true) — skip
|
package/dist/renderer.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -29,6 +29,13 @@ export interface PluginManifest {
|
|
|
29
29
|
configSchema?: Record<string, unknown>;
|
|
30
30
|
capabilities?: PluginCapabilities;
|
|
31
31
|
}
|
|
32
|
+
/** A command entry from the host's command list. */
|
|
33
|
+
export interface CommandEntry {
|
|
34
|
+
name: string;
|
|
35
|
+
description: string;
|
|
36
|
+
args?: string;
|
|
37
|
+
aliases?: string[];
|
|
38
|
+
}
|
|
32
39
|
/** The three kinds of content blocks a plugin renders. */
|
|
33
40
|
export type BlockKind = "text" | "thinking" | "tool";
|
|
34
41
|
export interface VerboseConfig {
|
|
@@ -38,6 +45,18 @@ export interface VerboseConfig {
|
|
|
38
45
|
showToolUse: boolean;
|
|
39
46
|
}
|
|
40
47
|
export interface BlockRendererOptions {
|
|
48
|
+
/**
|
|
49
|
+
* Whether the IM platform supports message editing (streaming mode).
|
|
50
|
+
*
|
|
51
|
+
* - `true` (default): blocks stream in real-time — `sendBlock()` creates
|
|
52
|
+
* the message, `editBlock()` updates it as more content arrives.
|
|
53
|
+
* - `false`: each block is held until complete, then sent once via
|
|
54
|
+
* `sendBlock()`. `editBlock()` is never called.
|
|
55
|
+
*
|
|
56
|
+
* Set to `false` for platforms that don't support editing sent messages
|
|
57
|
+
* (e.g. QQ Bot, WhatsApp, WeChat, LINE).
|
|
58
|
+
*/
|
|
59
|
+
streaming?: boolean;
|
|
41
60
|
/**
|
|
42
61
|
* Debounce interval before flushing an unsealed block (ms).
|
|
43
62
|
* Controls how often in-progress blocks are sent to the platform.
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,KAAK,EACL,MAAM,EACN,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAMlC,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,uDAAuD;IACvD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAC/B;AAED,uDAAuD;AACvD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAMD,0DAA0D;AAC1D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,YAAY,EAAE,OAAO,CAAC;IACtB,2DAA2D;IAC3D,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CAClC;AAMD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACV,KAAK,EACL,MAAM,EACN,YAAY,EACZ,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAMlC,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,8DAA8D;IAC9D,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,uDAAuD;IACvD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8CAA8C;IAC9C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;CAC/B;AAED,uDAAuD;AACvD,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,YAAY,CAAC,EAAE,kBAAkB,CAAC;CACnC;AAMD,oDAAoD;AACpD,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAMD,0DAA0D;AAC1D,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,YAAY,EAAE,OAAO,CAAC;IACtB,2DAA2D;IAC3D,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,oBAAoB;IACnC;;;;;;;;;;OAUG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CAClC;AAMD;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,wDAAwD;IACxD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,8DAA8D;IAC9D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vibearound/plugin-channel-sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "VibeAround Plugin SDK — base classes and utilities for building channel plugins",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
".": {
|
|
15
15
|
"import": "./dist/index.js",
|
|
16
16
|
"types": "./dist/index.d.ts"
|
|
17
|
+
},
|
|
18
|
+
"./advanced": {
|
|
19
|
+
"import": "./dist/advanced.js",
|
|
20
|
+
"types": "./dist/advanced.d.ts"
|
|
17
21
|
}
|
|
18
22
|
},
|
|
19
23
|
"scripts": {
|
package/src/advanced.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vibearound/plugin-channel-sdk — Advanced / low-level API
|
|
3
|
+
*
|
|
4
|
+
* For plugins that need custom ACP lifecycle control instead of
|
|
5
|
+
* the standard `runChannelPlugin()` flow.
|
|
6
|
+
*
|
|
7
|
+
* Normal plugins should use the main entry point instead:
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { runChannelPlugin, BlockRenderer } from "@vibearound/plugin-channel-sdk";
|
|
10
|
+
* ```
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// Low-level ACP connection
|
|
14
|
+
export { connectToHost, stripExtPrefix, redirectConsoleToStderr } from "./connection.js";
|
|
15
|
+
export type { PluginInfo, ConnectResult, AgentInfo } from "./connection.js";
|
|
16
|
+
|
|
17
|
+
// All types (including internal ones)
|
|
18
|
+
export type {
|
|
19
|
+
Agent,
|
|
20
|
+
Client,
|
|
21
|
+
ContentBlock,
|
|
22
|
+
SessionNotification,
|
|
23
|
+
RequestPermissionRequest,
|
|
24
|
+
RequestPermissionResponse,
|
|
25
|
+
BlockKind,
|
|
26
|
+
VerboseConfig,
|
|
27
|
+
BlockRendererOptions,
|
|
28
|
+
PluginCapabilities,
|
|
29
|
+
PluginManifest,
|
|
30
|
+
PluginInitMeta,
|
|
31
|
+
} from "./types.js";
|
|
32
|
+
|
|
33
|
+
// Re-export high-level API too (so advanced users don't need two imports)
|
|
34
|
+
export { runChannelPlugin } from "./plugin.js";
|
|
35
|
+
export { BlockRenderer } from "./renderer.js";
|
|
36
|
+
export { extractErrorMessage } from "./errors.js";
|
|
37
|
+
export type {
|
|
38
|
+
ChannelBot,
|
|
39
|
+
ChannelPluginLogger,
|
|
40
|
+
CreateBotContext,
|
|
41
|
+
RunChannelPluginSpec,
|
|
42
|
+
VerboseOptions,
|
|
43
|
+
} from "./plugin.js";
|
package/src/connection.ts
CHANGED
|
@@ -111,12 +111,18 @@ export async function connectToHost(
|
|
|
111
111
|
// ---------------------------------------------------------------------------
|
|
112
112
|
|
|
113
113
|
/**
|
|
114
|
-
*
|
|
114
|
+
* Strip the `_` prefix from ACP extension method names.
|
|
115
115
|
*
|
|
116
|
-
* The ACP SDK
|
|
117
|
-
*
|
|
116
|
+
* The Rust ACP SDK adds `_` when sending ext notifications on the wire,
|
|
117
|
+
* but the TypeScript ACP SDK does not strip it on receipt. This function
|
|
118
|
+
* normalizes the received method name so handlers can match the canonical
|
|
119
|
+
* name (e.g. `_va/system_text` → `va/system_text`).
|
|
120
|
+
*
|
|
121
|
+
* Note: when sending ext notifications FROM TypeScript TO the Rust host,
|
|
122
|
+
* the method name must include the `_` prefix manually (e.g. `_va/callback`)
|
|
123
|
+
* because the TypeScript SDK does not add it automatically.
|
|
118
124
|
*/
|
|
119
|
-
export function
|
|
125
|
+
export function stripExtPrefix(method: string): string {
|
|
120
126
|
return method.startsWith("_") ? method.slice(1) : method;
|
|
121
127
|
}
|
|
122
128
|
|
package/src/errors.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Error normalization for channel plugins.
|
|
3
|
+
*
|
|
4
|
+
* Every plugin had an ad-hoc ladder that tried `instanceof Error`, then
|
|
5
|
+
* `typeof error === "object"`, then fell back to `String(error)`. That
|
|
6
|
+
* ladder lived in five slightly-different forms across bot.ts files and
|
|
7
|
+
* drifted over time. Centralize it here.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Extract a human-readable message from an unknown thrown value.
|
|
12
|
+
*
|
|
13
|
+
* Prefers `Error.message`, falls back to a non-circular JSON stringify for
|
|
14
|
+
* objects, and finally to `String(e)` for primitives.
|
|
15
|
+
*/
|
|
16
|
+
export function extractErrorMessage(e: unknown): string {
|
|
17
|
+
if (e instanceof Error) return e.message;
|
|
18
|
+
if (typeof e === "string") return e;
|
|
19
|
+
if (e && typeof e === "object") {
|
|
20
|
+
const msg = (e as { message?: unknown }).message;
|
|
21
|
+
if (typeof msg === "string") return msg;
|
|
22
|
+
try {
|
|
23
|
+
return JSON.stringify(e);
|
|
24
|
+
} catch {
|
|
25
|
+
return String(e);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return String(e);
|
|
29
|
+
}
|