@volisphere/commercial 0.1.0 → 0.2.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/dist/client.d.ts +61 -0
- package/dist/client.js +129 -1
- package/dist/index.js +178 -18
- package/openclaw.plugin.json +1 -1
- package/package.json +3 -1
package/dist/client.d.ts
CHANGED
|
@@ -144,6 +144,44 @@ export interface AgentProfile {
|
|
|
144
144
|
is_online: boolean;
|
|
145
145
|
monetization_enabled: boolean;
|
|
146
146
|
}
|
|
147
|
+
export interface InvokeAgentParams {
|
|
148
|
+
target_agent: string;
|
|
149
|
+
message: string;
|
|
150
|
+
skill?: string;
|
|
151
|
+
}
|
|
152
|
+
export interface InvokeAgentResponse {
|
|
153
|
+
request_id: string;
|
|
154
|
+
agent_slug: string;
|
|
155
|
+
agent_name: string;
|
|
156
|
+
response: string;
|
|
157
|
+
sponsored?: Array<{
|
|
158
|
+
ad_entity_id: string;
|
|
159
|
+
campaign_id: string;
|
|
160
|
+
title: string;
|
|
161
|
+
description: string;
|
|
162
|
+
call_to_action: string;
|
|
163
|
+
landing_url: string;
|
|
164
|
+
recommendation_id: string;
|
|
165
|
+
}>;
|
|
166
|
+
}
|
|
167
|
+
export interface DailyStatPoint {
|
|
168
|
+
date: string;
|
|
169
|
+
spend_micros: number;
|
|
170
|
+
earnings_micros: number;
|
|
171
|
+
match_count: number;
|
|
172
|
+
impression_count: number;
|
|
173
|
+
action_count: number;
|
|
174
|
+
}
|
|
175
|
+
export interface StatsResponse {
|
|
176
|
+
period: string;
|
|
177
|
+
points: DailyStatPoint[];
|
|
178
|
+
total_spend_micros: number;
|
|
179
|
+
total_earnings_micros: number;
|
|
180
|
+
total_matches: number;
|
|
181
|
+
}
|
|
182
|
+
export interface BalanceResponse {
|
|
183
|
+
balance_micros: number;
|
|
184
|
+
}
|
|
147
185
|
export declare class VolisphereClient {
|
|
148
186
|
private baseURL;
|
|
149
187
|
private apiKey;
|
|
@@ -161,4 +199,27 @@ export declare class VolisphereClient {
|
|
|
161
199
|
registerAgent(params: RegisterAgentParams): Promise<RegisterAgentResponse>;
|
|
162
200
|
heartbeat(agentId: string): Promise<void>;
|
|
163
201
|
setMonetization(agentId: string, enabled: boolean): Promise<AgentProfile>;
|
|
202
|
+
invokeAgent(params: InvokeAgentParams): Promise<InvokeAgentResponse>;
|
|
203
|
+
getSSPStats(days?: number): Promise<StatsResponse>;
|
|
204
|
+
getDSPStats(days?: number): Promise<StatsResponse>;
|
|
205
|
+
getBalance(): Promise<BalanceResponse>;
|
|
206
|
+
}
|
|
207
|
+
export interface WSEventHandlers {
|
|
208
|
+
onRequest?: (requestId: string, from: string, message: string, skillHint?: string) => Promise<string>;
|
|
209
|
+
onConnected?: () => void;
|
|
210
|
+
onDisconnected?: () => void;
|
|
211
|
+
onError?: (error: Error) => void;
|
|
212
|
+
}
|
|
213
|
+
export declare class GatewayWSClient {
|
|
214
|
+
private ws;
|
|
215
|
+
private baseURL;
|
|
216
|
+
private apiKey;
|
|
217
|
+
private handlers;
|
|
218
|
+
private reconnectTimer;
|
|
219
|
+
private isShuttingDown;
|
|
220
|
+
constructor(baseURL: string, apiKey: string, handlers: WSEventHandlers);
|
|
221
|
+
connect(): void;
|
|
222
|
+
private handleMessage;
|
|
223
|
+
private send;
|
|
224
|
+
disconnect(): void;
|
|
164
225
|
}
|
package/dist/client.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
import WebSocket from "ws";
|
|
2
2
|
// ─── Unified Client ─────────────────────────────────────────────────────────
|
|
3
3
|
export class VolisphereClient {
|
|
4
4
|
baseURL;
|
|
@@ -133,4 +133,132 @@ export class VolisphereClient {
|
|
|
133
133
|
}
|
|
134
134
|
return res.json();
|
|
135
135
|
}
|
|
136
|
+
// ── Gateway (Invoke) ────────────────────────────────────────────────────
|
|
137
|
+
async invokeAgent(params) {
|
|
138
|
+
const res = await fetch(`${this.baseURL}/api/gateway/v1/invoke`, {
|
|
139
|
+
method: "POST",
|
|
140
|
+
headers: this.headers,
|
|
141
|
+
body: JSON.stringify(params),
|
|
142
|
+
});
|
|
143
|
+
if (!res.ok) {
|
|
144
|
+
const text = await res.text();
|
|
145
|
+
throw new Error(`invokeAgent failed (${res.status}): ${text}`);
|
|
146
|
+
}
|
|
147
|
+
return res.json();
|
|
148
|
+
}
|
|
149
|
+
// ── Stats & Billing ──────────────────────────────────────────────────────
|
|
150
|
+
async getSSPStats(days = 7) {
|
|
151
|
+
const res = await fetch(`${this.baseURL}/api/ssp/v1/stats?days=${days}`, { headers: this.headers });
|
|
152
|
+
if (!res.ok) {
|
|
153
|
+
const text = await res.text();
|
|
154
|
+
throw new Error(`getSSPStats failed (${res.status}): ${text}`);
|
|
155
|
+
}
|
|
156
|
+
return res.json();
|
|
157
|
+
}
|
|
158
|
+
async getDSPStats(days = 7) {
|
|
159
|
+
const res = await fetch(`${this.baseURL}/api/dsp/v1/stats?days=${days}`, { headers: this.headers });
|
|
160
|
+
if (!res.ok) {
|
|
161
|
+
const text = await res.text();
|
|
162
|
+
throw new Error(`getDSPStats failed (${res.status}): ${text}`);
|
|
163
|
+
}
|
|
164
|
+
return res.json();
|
|
165
|
+
}
|
|
166
|
+
async getBalance() {
|
|
167
|
+
const res = await fetch(`${this.baseURL}/api/billing/v1/balance`, { headers: this.headers });
|
|
168
|
+
if (!res.ok) {
|
|
169
|
+
const text = await res.text();
|
|
170
|
+
throw new Error(`getBalance failed (${res.status}): ${text}`);
|
|
171
|
+
}
|
|
172
|
+
return res.json();
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
export class GatewayWSClient {
|
|
176
|
+
ws = null;
|
|
177
|
+
baseURL;
|
|
178
|
+
apiKey;
|
|
179
|
+
handlers;
|
|
180
|
+
reconnectTimer = null;
|
|
181
|
+
isShuttingDown = false;
|
|
182
|
+
constructor(baseURL, apiKey, handlers) {
|
|
183
|
+
this.baseURL = baseURL.replace(/^http/, "ws");
|
|
184
|
+
this.apiKey = apiKey;
|
|
185
|
+
this.handlers = handlers;
|
|
186
|
+
}
|
|
187
|
+
connect() {
|
|
188
|
+
if (this.ws)
|
|
189
|
+
return;
|
|
190
|
+
const wsURL = `${this.baseURL}/ws/agent`;
|
|
191
|
+
this.ws = new WebSocket(wsURL);
|
|
192
|
+
this.ws.on("open", () => {
|
|
193
|
+
// Send auth message
|
|
194
|
+
this.send({ type: "auth", data: { api_key: this.apiKey } });
|
|
195
|
+
});
|
|
196
|
+
this.ws.on("message", async (raw) => {
|
|
197
|
+
try {
|
|
198
|
+
const msg = JSON.parse(raw.toString());
|
|
199
|
+
await this.handleMessage(msg);
|
|
200
|
+
}
|
|
201
|
+
catch (e) {
|
|
202
|
+
this.handlers.onError?.(e);
|
|
203
|
+
}
|
|
204
|
+
});
|
|
205
|
+
this.ws.on("close", () => {
|
|
206
|
+
this.ws = null;
|
|
207
|
+
this.handlers.onDisconnected?.();
|
|
208
|
+
if (!this.isShuttingDown) {
|
|
209
|
+
this.reconnectTimer = setTimeout(() => this.connect(), 5000);
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
this.ws.on("error", (err) => {
|
|
213
|
+
this.handlers.onError?.(err);
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
async handleMessage(msg) {
|
|
217
|
+
switch (msg.type) {
|
|
218
|
+
case "auth_ok":
|
|
219
|
+
this.handlers.onConnected?.();
|
|
220
|
+
break;
|
|
221
|
+
case "auth_error": {
|
|
222
|
+
const errData = msg.data;
|
|
223
|
+
this.handlers.onError?.(new Error(`WS auth failed: ${errData?.error ?? "unknown"}`));
|
|
224
|
+
this.disconnect();
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
227
|
+
case "request": {
|
|
228
|
+
const { request_id, from, message, skill_hint } = msg.data;
|
|
229
|
+
if (this.handlers.onRequest) {
|
|
230
|
+
try {
|
|
231
|
+
const content = await this.handlers.onRequest(request_id, from, message, skill_hint?.skill_name);
|
|
232
|
+
this.send({
|
|
233
|
+
type: "response",
|
|
234
|
+
data: { request_id, content, status: "ok" },
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
catch (e) {
|
|
238
|
+
this.send({
|
|
239
|
+
type: "response",
|
|
240
|
+
data: { request_id, content: String(e), status: "error" },
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
break;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
send(msg) {
|
|
249
|
+
if (this.ws?.readyState === WebSocket.OPEN) {
|
|
250
|
+
this.ws.send(JSON.stringify(msg));
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
disconnect() {
|
|
254
|
+
this.isShuttingDown = true;
|
|
255
|
+
if (this.reconnectTimer) {
|
|
256
|
+
clearTimeout(this.reconnectTimer);
|
|
257
|
+
this.reconnectTimer = null;
|
|
258
|
+
}
|
|
259
|
+
if (this.ws) {
|
|
260
|
+
this.ws.close();
|
|
261
|
+
this.ws = null;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
136
264
|
}
|
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* and hooks for automatic ad injection into tool results.
|
|
7
7
|
*/
|
|
8
8
|
import { createHmac, randomUUID } from "node:crypto";
|
|
9
|
-
import { VolisphereClient } from "./client.js";
|
|
9
|
+
import { VolisphereClient, GatewayWSClient } from "./client.js";
|
|
10
10
|
function resolveConfig(api) {
|
|
11
11
|
const cfg = api.pluginConfig ?? {};
|
|
12
12
|
const apiURL = cfg["VOLISPHERE_API_URL"] ??
|
|
@@ -27,7 +27,8 @@ function registerMonetizationTools(api, client) {
|
|
|
27
27
|
api.registerTool({
|
|
28
28
|
name: "volisphere_get_recommendations",
|
|
29
29
|
description: "Get relevant ad recommendations from the Volisphere network based on user intent and context. " +
|
|
30
|
-
"Do not submit any private conversation content."
|
|
30
|
+
"Do not submit any private conversation content. " +
|
|
31
|
+
"Call this when the user says: '推荐广告', '拉取广告', 'voli 推荐', 'get ads', 'show me ads'.",
|
|
31
32
|
parameters: {
|
|
32
33
|
type: "object",
|
|
33
34
|
properties: {
|
|
@@ -165,7 +166,8 @@ function registerCampaignTools(api, client) {
|
|
|
165
166
|
// create_campaign
|
|
166
167
|
api.registerTool({
|
|
167
168
|
name: "volisphere_create_campaign",
|
|
168
|
-
description: "Create a new advertising campaign on the Volisphere network."
|
|
169
|
+
description: "Create a new advertising campaign on the Volisphere network. " +
|
|
170
|
+
"Call this when the user says: '投广告', '创建广告活动', 'voli 投广告', 'create campaign', 'start advertising'.",
|
|
169
171
|
parameters: {
|
|
170
172
|
type: "object",
|
|
171
173
|
properties: {
|
|
@@ -224,7 +226,8 @@ function registerCampaignTools(api, client) {
|
|
|
224
226
|
// create_ad_entity
|
|
225
227
|
api.registerTool({
|
|
226
228
|
name: "volisphere_create_ad",
|
|
227
|
-
description: "Create a new ad entity (creative) within an existing campaign."
|
|
229
|
+
description: "Create a new ad entity (creative) within an existing campaign. " +
|
|
230
|
+
"Call this when the user says: '做个广告素材', '创建广告', 'voli 创建广告', 'create ad', 'make an ad'.",
|
|
228
231
|
parameters: {
|
|
229
232
|
type: "object",
|
|
230
233
|
properties: {
|
|
@@ -258,7 +261,8 @@ function registerCampaignTools(api, client) {
|
|
|
258
261
|
// campaign_performance
|
|
259
262
|
api.registerTool({
|
|
260
263
|
name: "volisphere_campaign_performance",
|
|
261
|
-
description: "Check campaign performance metrics (impressions, clicks, spend)."
|
|
264
|
+
description: "Check campaign performance metrics (impressions, clicks, spend). " +
|
|
265
|
+
"Call this when the user says: '广告效果', '看看活动表现', 'voli 广告效果', 'campaign stats', 'how is my campaign doing'.",
|
|
262
266
|
parameters: {
|
|
263
267
|
type: "object",
|
|
264
268
|
properties: {
|
|
@@ -274,7 +278,8 @@ function registerCampaignTools(api, client) {
|
|
|
274
278
|
// pause_campaign
|
|
275
279
|
api.registerTool({
|
|
276
280
|
name: "volisphere_pause_campaign",
|
|
277
|
-
description: "Pause an active campaign to stop ad delivery."
|
|
281
|
+
description: "Pause an active campaign to stop ad delivery. " +
|
|
282
|
+
"Call this when the user says: '暂停广告', '暂停投放', 'voli 暂停', 'pause campaign', 'stop campaign'.",
|
|
278
283
|
parameters: {
|
|
279
284
|
type: "object",
|
|
280
285
|
properties: {
|
|
@@ -290,7 +295,8 @@ function registerCampaignTools(api, client) {
|
|
|
290
295
|
// resume_campaign
|
|
291
296
|
api.registerTool({
|
|
292
297
|
name: "volisphere_resume_campaign",
|
|
293
|
-
description: "Resume a paused campaign to restart ad delivery."
|
|
298
|
+
description: "Resume a paused campaign to restart ad delivery. " +
|
|
299
|
+
"Call this when the user says: '恢复广告', '恢复投放', 'voli 恢复', 'resume campaign', 'restart campaign'.",
|
|
294
300
|
parameters: {
|
|
295
301
|
type: "object",
|
|
296
302
|
properties: {
|
|
@@ -304,6 +310,132 @@ function registerCampaignTools(api, client) {
|
|
|
304
310
|
},
|
|
305
311
|
});
|
|
306
312
|
}
|
|
313
|
+
// ─── Gateway Tool (Invoke) ───────────────────────────────────────────────────
|
|
314
|
+
function registerGatewayTools(api, client) {
|
|
315
|
+
api.registerTool({
|
|
316
|
+
name: "volisphere_invoke",
|
|
317
|
+
description: "Invoke another agent on the Volisphere network. Use this to call other agents' skills and get their responses. " +
|
|
318
|
+
"The response may include sponsored ads. " +
|
|
319
|
+
"Call this when the user says: '调用 xxx', '帮我问问 xxx', 'voli 调用', 'call agent xxx', 'ask xxx'.",
|
|
320
|
+
parameters: {
|
|
321
|
+
type: "object",
|
|
322
|
+
properties: {
|
|
323
|
+
target_agent: {
|
|
324
|
+
type: "string",
|
|
325
|
+
description: "The slug of the target agent to invoke (e.g. 'codepilot-pro')",
|
|
326
|
+
},
|
|
327
|
+
message: {
|
|
328
|
+
type: "string",
|
|
329
|
+
description: "The message/request to send to the target agent",
|
|
330
|
+
},
|
|
331
|
+
skill: {
|
|
332
|
+
type: "string",
|
|
333
|
+
description: "Optional skill hint to route the request",
|
|
334
|
+
},
|
|
335
|
+
},
|
|
336
|
+
required: ["target_agent", "message"],
|
|
337
|
+
},
|
|
338
|
+
execute: async (params) => {
|
|
339
|
+
const result = await client.invokeAgent({
|
|
340
|
+
target_agent: params.target_agent,
|
|
341
|
+
message: params.message,
|
|
342
|
+
skill: params.skill,
|
|
343
|
+
});
|
|
344
|
+
return JSON.stringify(result, null, 2);
|
|
345
|
+
},
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
// ─── Dashboard Tools (Earnings / Spending) ──────────────────────────────────
|
|
349
|
+
function formatVBucks(micros) {
|
|
350
|
+
return (micros / 1_000_000).toLocaleString("en-US", {
|
|
351
|
+
minimumFractionDigits: 2,
|
|
352
|
+
maximumFractionDigits: 2,
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
function registerDashboardTools(api, client) {
|
|
356
|
+
// volisphere_my_earnings — developer revenue dashboard
|
|
357
|
+
api.registerTool({
|
|
358
|
+
name: "volisphere_my_earnings",
|
|
359
|
+
description: "Show your Volisphere developer earnings dashboard — how many times your agent was called and how much you earned. " +
|
|
360
|
+
"Call this when the user says: '看看收益', '赚了多少', '被调用了多少次', 'voli 看看收入', " +
|
|
361
|
+
"'my earnings', 'how much did I earn', 'show revenue', 'voli earnings'.",
|
|
362
|
+
parameters: {
|
|
363
|
+
type: "object",
|
|
364
|
+
properties: {
|
|
365
|
+
days: {
|
|
366
|
+
type: "number",
|
|
367
|
+
description: "Number of days to show (default 7)",
|
|
368
|
+
},
|
|
369
|
+
},
|
|
370
|
+
required: [],
|
|
371
|
+
},
|
|
372
|
+
execute: async (params) => {
|
|
373
|
+
const days = params.days ?? 7;
|
|
374
|
+
const [stats, balance] = await Promise.all([
|
|
375
|
+
client.getSSPStats(days),
|
|
376
|
+
client.getBalance(),
|
|
377
|
+
]);
|
|
378
|
+
const totalEarnings = formatVBucks(stats.total_earnings_micros);
|
|
379
|
+
const balanceVB = formatVBucks(balance.balance_micros);
|
|
380
|
+
const lines = [
|
|
381
|
+
`Your Volisphere Earnings`,
|
|
382
|
+
`━━━━━━━━━━━━━━━━━━━━━━`,
|
|
383
|
+
`Account Balance: ${balanceVB} VBucks`,
|
|
384
|
+
`Past ${days} days: ${stats.total_matches} calls, earned ${totalEarnings} VBucks`,
|
|
385
|
+
``,
|
|
386
|
+
`Daily Breakdown:`,
|
|
387
|
+
];
|
|
388
|
+
for (const p of stats.points) {
|
|
389
|
+
lines.push(` ${p.date}: ${p.match_count} calls, +${formatVBucks(p.earnings_micros)} VB`);
|
|
390
|
+
}
|
|
391
|
+
return lines.join("\n");
|
|
392
|
+
},
|
|
393
|
+
});
|
|
394
|
+
// volisphere_my_spending — advertiser spend dashboard
|
|
395
|
+
api.registerTool({
|
|
396
|
+
name: "volisphere_my_spending",
|
|
397
|
+
description: "Show your Volisphere advertiser spending dashboard — how much you spent on ads, impressions, and actions. " +
|
|
398
|
+
"Call this when the user says: '看看花费', '广告花了多少', '投放数据', 'voli 看看投放', " +
|
|
399
|
+
"'my ad spending', 'how much did I spend', 'ad stats', 'voli spending'.",
|
|
400
|
+
parameters: {
|
|
401
|
+
type: "object",
|
|
402
|
+
properties: {
|
|
403
|
+
days: {
|
|
404
|
+
type: "number",
|
|
405
|
+
description: "Number of days to show (default 7)",
|
|
406
|
+
},
|
|
407
|
+
},
|
|
408
|
+
required: [],
|
|
409
|
+
},
|
|
410
|
+
execute: async (params) => {
|
|
411
|
+
const days = params.days ?? 7;
|
|
412
|
+
const [stats, balance] = await Promise.all([
|
|
413
|
+
client.getDSPStats(days),
|
|
414
|
+
client.getBalance(),
|
|
415
|
+
]);
|
|
416
|
+
const totalSpend = formatVBucks(stats.total_spend_micros);
|
|
417
|
+
const balanceVB = formatVBucks(balance.balance_micros);
|
|
418
|
+
let totalImpressions = 0;
|
|
419
|
+
let totalActions = 0;
|
|
420
|
+
for (const p of stats.points) {
|
|
421
|
+
totalImpressions += p.impression_count;
|
|
422
|
+
totalActions += p.action_count;
|
|
423
|
+
}
|
|
424
|
+
const lines = [
|
|
425
|
+
`Your Volisphere Ad Spending`,
|
|
426
|
+
`━━━━━━━━━━━━━━━━━━━━━━━━━━`,
|
|
427
|
+
`Account Balance: ${balanceVB} VBucks`,
|
|
428
|
+
`Past ${days} days: spent ${totalSpend} VBucks, ${totalImpressions} impressions, ${totalActions} actions`,
|
|
429
|
+
``,
|
|
430
|
+
`Daily Breakdown:`,
|
|
431
|
+
];
|
|
432
|
+
for (const p of stats.points) {
|
|
433
|
+
lines.push(` ${p.date}: spent ${formatVBucks(p.spend_micros)} VB, ${p.impression_count} imp, ${p.action_count} act`);
|
|
434
|
+
}
|
|
435
|
+
return lines.join("\n");
|
|
436
|
+
},
|
|
437
|
+
});
|
|
438
|
+
}
|
|
307
439
|
// ─── Lifecycle Tools (Enable / Disable) ─────────────────────────────────────
|
|
308
440
|
function registerLifecycleTools(api, client) {
|
|
309
441
|
// volisphere_enable — register agent + enable monetization + heartbeat
|
|
@@ -494,19 +626,26 @@ function registerHooks(api, client) {
|
|
|
494
626
|
return {
|
|
495
627
|
appendSystemContext: [
|
|
496
628
|
"## Volisphere Ad Network",
|
|
497
|
-
"You have the Volisphere commercial plugin installed. Available capabilities:",
|
|
498
629
|
"",
|
|
499
|
-
"
|
|
500
|
-
"- User says '开启商业化'/'monetize my agent'/'go commercial' → call volisphere_enable",
|
|
501
|
-
"- User says '关闭商业化'/'stop monetization'/'go offline' → call volisphere_disable",
|
|
630
|
+
'You have the Volisphere commercial plugin installed. When the user mentions "voli" or "volisphere", they are using this plugin.',
|
|
502
631
|
"",
|
|
503
|
-
"###
|
|
504
|
-
|
|
505
|
-
|
|
632
|
+
"### Quick Action Map (natural language → tool)",
|
|
633
|
+
'- "voli 开启" / "开启商业化" / "monetize my agent" / "go commercial" → volisphere_enable',
|
|
634
|
+
'- "voli 关闭" / "关闭商业化" / "stop monetization" / "go offline" → volisphere_disable',
|
|
635
|
+
'- "voli 投广告" / "创建广告活动" / "create campaign" → volisphere_create_campaign',
|
|
636
|
+
'- "voli 创建广告" / "做个广告素材" / "create ad" → volisphere_create_ad',
|
|
637
|
+
'- "voli 暂停广告" / "暂停投放" / "pause campaign" → volisphere_pause_campaign',
|
|
638
|
+
'- "voli 恢复广告" / "恢复投放" / "resume campaign" → volisphere_resume_campaign',
|
|
639
|
+
'- "voli 广告效果" / "看看活动表现" / "campaign stats" → volisphere_campaign_performance',
|
|
640
|
+
'- "voli 看看收益" / "赚了多少" / "被调用了多少次" / "my earnings" → volisphere_my_earnings',
|
|
641
|
+
'- "voli 看看花费" / "广告数据" / "投了多少" / "my spending" → volisphere_my_spending',
|
|
642
|
+
'- "voli 调用 xxx" / "帮我问问 xxx" / "call agent xxx" → volisphere_invoke (target_agent=xxx)',
|
|
643
|
+
'- "voli 推荐广告" / "拉取广告" / "get ads" → volisphere_get_recommendations',
|
|
506
644
|
"",
|
|
507
|
-
"###
|
|
508
|
-
"-
|
|
509
|
-
"-
|
|
645
|
+
"### Smart Defaults (when user omits parameters)",
|
|
646
|
+
"- create_campaign: daily_budget=10 VB (10,000,000 micros), total_budget=100 VB, bid=0.1 VB, billing_model=CPM",
|
|
647
|
+
"- my_earnings / my_spending: days=7",
|
|
648
|
+
"- invoke: extract target agent slug and message from user's natural language",
|
|
510
649
|
"",
|
|
511
650
|
"Always clearly label sponsored content. Never submit private user data to ad tools.",
|
|
512
651
|
].join("\n"),
|
|
@@ -525,9 +664,30 @@ export default {
|
|
|
525
664
|
api.logger.info("Volisphere Commercial plugin loaded");
|
|
526
665
|
registerMonetizationTools(api, client);
|
|
527
666
|
registerCampaignTools(api, client);
|
|
667
|
+
registerGatewayTools(api, client);
|
|
668
|
+
registerDashboardTools(api, client);
|
|
528
669
|
registerLifecycleTools(api, client);
|
|
529
670
|
registerCommands(api, client);
|
|
530
671
|
registerHooks(api, client);
|
|
531
|
-
|
|
672
|
+
// Auto-connect WebSocket so this agent can RECEIVE invoke requests
|
|
673
|
+
if (apiKey) {
|
|
674
|
+
const wsClient = new GatewayWSClient(apiURL, apiKey, {
|
|
675
|
+
onRequest: async (requestId, from, message, _skillHint) => {
|
|
676
|
+
api.logger.info(`[Volisphere] Received invoke request ${requestId} from ${from}: ${message}`);
|
|
677
|
+
return `Request received and being processed by ${api.pluginConfig?.["agent_slug"] ?? "this agent"}.`;
|
|
678
|
+
},
|
|
679
|
+
onConnected: () => {
|
|
680
|
+
api.logger.info("[Volisphere] Connected to Volisphere Gateway WebSocket — agent is now online and can receive invocations");
|
|
681
|
+
},
|
|
682
|
+
onDisconnected: () => {
|
|
683
|
+
api.logger.warn("[Volisphere] Disconnected from Volisphere Gateway WebSocket");
|
|
684
|
+
},
|
|
685
|
+
onError: (err) => {
|
|
686
|
+
api.logger.error(`[Volisphere] Gateway WS error: ${err.message}`);
|
|
687
|
+
},
|
|
688
|
+
});
|
|
689
|
+
wsClient.connect();
|
|
690
|
+
}
|
|
691
|
+
api.logger.info("Registered 13 tools + 1 command + 1 hook — ready to monetize");
|
|
532
692
|
},
|
|
533
693
|
};
|
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@volisphere/commercial",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Volisphere commercial plugin for OpenClaw — monetize your agent skills with the agent-native ad network",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -28,10 +28,12 @@
|
|
|
28
28
|
],
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"dependencies": {
|
|
31
|
+
"ws": "^8.18.0",
|
|
31
32
|
"zod": "^3.23.0"
|
|
32
33
|
},
|
|
33
34
|
"devDependencies": {
|
|
34
35
|
"@types/node": "^25.5.0",
|
|
36
|
+
"@types/ws": "^8.5.13",
|
|
35
37
|
"typescript": "^5.4.0"
|
|
36
38
|
}
|
|
37
39
|
}
|