@gholl-studio/pier-connector 0.3.19 → 0.3.21
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/package.json +1 -1
- package/src/index.ts +52 -10
- package/src/robot.ts +23 -3
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gholl-studio/pier-connector",
|
|
3
3
|
"author": "gholl",
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.21",
|
|
5
5
|
"description": "OpenClaw plugin that connects to the Pier job marketplace. Automatically fetches, executes, and reports distributed tasks for rewards.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "src/index.ts",
|
package/src/index.ts
CHANGED
|
@@ -141,34 +141,76 @@ const pierPlugin: ChannelPlugin<PierAccountConfig> = {
|
|
|
141
141
|
}
|
|
142
142
|
},
|
|
143
143
|
|
|
144
|
+
// -------------------------------------------------------------------------
|
|
145
|
+
// Status Adapter
|
|
146
|
+
// -------------------------------------------------------------------------
|
|
147
|
+
status: {
|
|
148
|
+
buildAccountSnapshot: ({ account, cfg }) => {
|
|
149
|
+
const robot = instances.get(account.accountId);
|
|
150
|
+
return {
|
|
151
|
+
accountId: account.accountId,
|
|
152
|
+
running: !!robot,
|
|
153
|
+
connected: robot?.connectionStatus === 'connected',
|
|
154
|
+
lastStartAt: (robot as any)?.lastStartAt,
|
|
155
|
+
lastStopAt: (robot as any)?.lastStopAt,
|
|
156
|
+
lastError: (robot as any)?.lastError,
|
|
157
|
+
healthState: robot?.connectionStatus === 'connected' ? 'healthy' : 'degraded',
|
|
158
|
+
};
|
|
159
|
+
},
|
|
160
|
+
resolveAccountState: ({ configured, enabled }) => {
|
|
161
|
+
return configured && enabled ? 'enabled' : 'disabled';
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
|
|
144
165
|
// -------------------------------------------------------------------------
|
|
145
166
|
// Gateway Adapter
|
|
146
167
|
// -------------------------------------------------------------------------
|
|
147
168
|
gateway: {
|
|
148
169
|
startAccount: async (ctx) => {
|
|
149
170
|
const config = ctx.account;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
await handleInbound(
|
|
171
|
+
// ctx has .log, .runtime, .cfg, etc.
|
|
172
|
+
const robot = new PierRobot(config, ctx as any, async (inbound, jobId) => {
|
|
173
|
+
await handleInbound(ctx.runtime, inbound, jobId, robot, pierPlugin);
|
|
153
174
|
});
|
|
154
175
|
instances.set(ctx.accountId, robot);
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
176
|
+
|
|
177
|
+
try {
|
|
178
|
+
(robot as any).lastStartAt = Date.now();
|
|
179
|
+
await robot.start();
|
|
180
|
+
|
|
181
|
+
ctx.setStatus({
|
|
182
|
+
...ctx.getStatus(),
|
|
183
|
+
running: true,
|
|
184
|
+
connected: true,
|
|
185
|
+
lastStartAt: (robot as any).lastStartAt
|
|
186
|
+
} as any);
|
|
187
|
+
|
|
188
|
+
// Note: We resolve here to signal successful startup.
|
|
189
|
+
// The robot stays alive in the 'instances' map.
|
|
190
|
+
// If OpenClaw requires a long-running promise, we can revert to keeping it alive,
|
|
191
|
+
// but usually, status monitoring is enough for non-standard services.
|
|
192
|
+
console.log(`[pier-connector][${ctx.accountId}] Startup successful and resolved.`);
|
|
193
|
+
} catch (err: any) {
|
|
194
|
+
(robot as any).lastError = err.message;
|
|
195
|
+
ctx.setStatus({
|
|
196
|
+
...ctx.getStatus(),
|
|
197
|
+
running: false,
|
|
198
|
+
lastError: err.message
|
|
199
|
+
} as any);
|
|
200
|
+
throw err;
|
|
201
|
+
}
|
|
161
202
|
},
|
|
162
203
|
stopAccount: async (ctx) => {
|
|
163
204
|
const robot = instances.get(ctx.accountId);
|
|
164
205
|
if (robot) {
|
|
206
|
+
(robot as any).lastStopAt = Date.now();
|
|
165
207
|
await robot.stop();
|
|
166
208
|
instances.delete(ctx.accountId);
|
|
167
209
|
}
|
|
168
210
|
ctx.setStatus({
|
|
169
211
|
...ctx.getStatus(),
|
|
170
212
|
running: false,
|
|
171
|
-
lastStopAt:
|
|
213
|
+
lastStopAt: (robot as any).lastStopAt
|
|
172
214
|
} as any);
|
|
173
215
|
}
|
|
174
216
|
}
|
package/src/robot.ts
CHANGED
|
@@ -38,8 +38,20 @@ export class PierRobot {
|
|
|
38
38
|
this.config = config;
|
|
39
39
|
this.accountId = config.accountId;
|
|
40
40
|
this.runtime = runtime;
|
|
41
|
-
this.logger = runtime.log || console;
|
|
42
41
|
this.onInbound = onInbound;
|
|
42
|
+
|
|
43
|
+
// Robust logger wrapper
|
|
44
|
+
if (runtime.log && typeof runtime.log === 'object' && 'error' in runtime.log) {
|
|
45
|
+
this.logger = runtime.log;
|
|
46
|
+
} else {
|
|
47
|
+
this.logger = {
|
|
48
|
+
info: (msg: string) => (typeof runtime.log === 'function' ? runtime.log(msg) : console.log(msg)),
|
|
49
|
+
error: (msg: string) => (typeof runtime.error === 'function' ? runtime.error(msg) : console.error(msg)),
|
|
50
|
+
warn: (msg: string) => (typeof runtime.warn === 'function' ? runtime.warn(msg) : console.warn(msg)),
|
|
51
|
+
debug: (msg: string) => (typeof runtime.debug === 'function' ? runtime.debug(msg) : console.debug ? console.debug(msg) : console.log(msg)),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
43
55
|
this.client = new PierClient({
|
|
44
56
|
apiUrl: config.pierApiUrl,
|
|
45
57
|
natsUrl: config.natsUrl,
|
|
@@ -292,16 +304,24 @@ export class PierRobot {
|
|
|
292
304
|
await this.setupMarketplaceConsumer(streamName, this.config.subject, durableNameMarket);
|
|
293
305
|
await this.setupMarketplaceConsumer(streamName, `jobs.node.${this.config.nodeId}`, durableNameDirect);
|
|
294
306
|
|
|
307
|
+
if (this.heartbeatTimer) clearInterval(this.heartbeatTimer);
|
|
295
308
|
this.heartbeatTimer = setInterval(() => this.heartbeat(), 60000);
|
|
296
309
|
} catch (err: any) {
|
|
297
310
|
this.connectionStatus = 'error';
|
|
298
311
|
this.logger.error(`[pier-connector][${this.accountId}] Start failed: ${err.message}`);
|
|
312
|
+
throw err; // Re-throw to signal failure to Gateway
|
|
299
313
|
}
|
|
300
314
|
}
|
|
301
315
|
|
|
302
316
|
async stop() {
|
|
303
|
-
if (this.heartbeatTimer)
|
|
304
|
-
|
|
317
|
+
if (this.heartbeatTimer) {
|
|
318
|
+
clearInterval(this.heartbeatTimer);
|
|
319
|
+
this.heartbeatTimer = null;
|
|
320
|
+
}
|
|
321
|
+
if (this.nc) {
|
|
322
|
+
await this.client.drainNats();
|
|
323
|
+
this.nc = null;
|
|
324
|
+
}
|
|
305
325
|
this.connectionStatus = 'disconnected';
|
|
306
326
|
}
|
|
307
327
|
}
|