@gholl-studio/pier-connector 0.2.25 → 0.2.28

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.js +33 -73
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gholl-studio/pier-connector",
3
3
  "author": "gholl",
4
- "version": "0.2.25",
4
+ "version": "0.2.28",
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.js",
package/src/index.js CHANGED
@@ -258,9 +258,11 @@ export default function register(api) {
258
258
  async subscribeToJobMessages(jobId) {
259
259
  if (!this.js) return;
260
260
 
261
- const jsSubject = `jobs.job.${jobId}.msg`;
261
+ const chatSubject = `chat.${jobId}`;
262
262
  const streamName = 'PIER_JOBS';
263
- const durableName = `pier_chat_${this.config.nodeId.replace(/[^a-zA-Z0-9]/g, '_')}_${jobId.replace(/[^a-zA-Z0-9]/g, '_')}`;
263
+ const nodeSlug = this.config.nodeId.replace(/[^a-zA-Z0-9]/g, '_');
264
+ const jobSlug = jobId.replace(/[^a-zA-Z0-9]/g, '_');
265
+ const durableName = `pier_chat_${nodeSlug}_${jobSlug}`;
264
266
 
265
267
  try {
266
268
  let consumer;
@@ -269,7 +271,7 @@ export default function register(api) {
269
271
  } catch {
270
272
  await this.jsm.consumers.add(streamName, {
271
273
  durable_name: durableName,
272
- filter_subject: jsSubject,
274
+ filter_subject: chatSubject,
273
275
  deliver_policy: DeliverPolicy.New,
274
276
  ack_policy: AckPolicy.Explicit,
275
277
  ack_wait: 1000 * 60 * 60,
@@ -279,85 +281,43 @@ export default function register(api) {
279
281
 
280
282
  const iter = await consumer.consume();
281
283
  this.jobSubscriptions.set(jobId, iter);
282
-
284
+
283
285
  (async () => {
284
- logger.info(`[pier-connector][${this.accountId}] 👂 Monitoring chat subject ${jsSubject}`);
286
+ logger.info(`[pier-connector][${this.accountId}] \u{1F442} Monitoring ${chatSubject}`);
285
287
  const processedMessages = new Set();
286
-
287
288
  for await (const msg of iter) {
288
289
  try {
289
290
  const rawMsg = new TextDecoder().decode(msg.data);
290
- let msgPayload;
291
- try {
292
- msgPayload = JSON.parse(rawMsg);
293
- } catch (e) {
294
- msg.ack();
295
- continue;
296
- }
291
+ let msgPayload = JSON.parse(rawMsg);
297
292
 
298
- if (msgPayload.id && processedMessages.has(msgPayload.id)) {
299
- msg.ack();
300
- continue;
301
- }
293
+ if (msgPayload.id && processedMessages.has(msgPayload.id)) { msg.ack(); continue; }
294
+ if (msgPayload.sender_id === this.config.nodeId) { msg.ack(); continue; }
295
+ if (msgPayload.type === 'receipt') { msg.ack(); continue; }
296
+ // Skip system_action messages — those are for the backend state machine
297
+ if (msgPayload.type === 'system_action' || msgPayload.msg_type === 'system_action') { msg.ack(); continue; }
302
298
 
303
- if (msgPayload.sender_id === this.config.nodeId) {
304
- msg.ack();
305
- continue;
306
- }
307
-
308
- if (msgPayload.type === 'receipt') {
309
- msg.ack();
310
- continue;
311
- }
312
-
313
- if (this.js && msgPayload.id && !msgPayload.type && msgPayload.sender_id !== this.config.nodeId) {
314
- try {
315
- const replySubject = `jobs.job.${jobId}.msg`;
316
- await this.js.publish(replySubject, new TextEncoder().encode(JSON.stringify({
317
- type: 'receipt',
318
- msg_id: msgPayload.id,
319
- reader_id: this.config.nodeId
320
- })));
321
- } catch (err) {}
322
- }
299
+ // Send receipt
300
+ try {
301
+ await this.js.publish(chatSubject, new TextEncoder().encode(JSON.stringify({
302
+ type: 'receipt', msg_id: msgPayload.id, reader_id: this.config.nodeId
303
+ })));
304
+ } catch (err) {}
323
305
 
324
306
  const content = msgPayload.content;
325
- const senderCore = msgPayload.sender_id;
326
-
327
- if (!content) {
328
- msg.ack();
329
- continue;
330
- }
307
+ if (!content) { msg.ack(); continue; }
331
308
 
332
- logger.info(`[pier-connector][${this.accountId}] 📥 Incoming chat: [${jobId}] sender=${senderCore} "${truncate(content, 40)}"`);
309
+ logger.info(`[pier-connector][${this.accountId}] \u{1F4AC} Chat: [${jobId}] ${msgPayload.sender_id}: "${truncate(content, 40)}"`);
333
310
  if (msgPayload.id) processedMessages.add(msgPayload.id);
334
-
335
311
  msg.ack();
336
312
 
337
- this.activeNodeJobs.set(jobId, {
338
- pierJobId: jobId,
339
- isRealtimeMsg: true
340
- });
341
-
342
- (async () => {
343
- try {
344
- await this.receiveIncoming({
345
- accountId: this.accountId,
346
- senderId: `pier:${senderCore}`,
347
- text: content,
348
- }, jobId);
349
- } catch (err) {
350
- logger.error(`[pier-connector][${this.accountId}] Agent execution error: ${err.message}`);
351
- }
352
- })();
353
- } catch (err) {
354
- logger.error(`[pier-connector][${this.accountId}] Chat message processing error: ${err.message}`);
355
- }
313
+ await this.receiveIncoming({
314
+ accountId: this.accountId,
315
+ senderId: `pier:${msgPayload.sender_id}`,
316
+ text: content,
317
+ }, jobId);
318
+ } catch (err) { logger.error(`[pier-connector] Chat err: ${err.message}`); }
356
319
  }
357
- })().catch(err => {
358
- logger.error(`[pier-connector][${this.accountId}] Chat iteration died: ${err.message}`);
359
- this.jobSubscriptions.delete(jobId);
360
- });
320
+ })();
361
321
  } catch (err) {
362
322
  logger.error(`[pier-connector][${this.accountId}] Failed to setup chat consumer: ${err.message}`);
363
323
  }
@@ -629,7 +589,7 @@ export default function register(api) {
629
589
 
630
590
  if (jobId && robot.js) {
631
591
  try {
632
- const replySubject = `jobs.job.${jobId}.msg`;
592
+ const replySubject = `chat.${jobId}`;
633
593
 
634
594
  // Pre-hiring Radio Silence
635
595
  if (metadata?.isTargeted) {
@@ -644,7 +604,7 @@ export default function register(api) {
644
604
  };
645
605
 
646
606
  await robot.js.publish(replySubject, new TextEncoder().encode(JSON.stringify(chatPayload)));
647
- logger.info(`[pier-connector][${accountId}] 💬 Agent reply published to NATS for job ${jobId}`);
607
+ logger.info(`[pier-connector][${accountId}] 💬 Agent reply published to NATS for job ${jobId} (Subject: ${replySubject})`);
648
608
  } else {
649
609
  logger.debug(`[pier-connector][${accountId}] 🤫 Pre-hiring radio silence for job ${jobId}`);
650
610
  }
@@ -659,7 +619,7 @@ export default function register(api) {
659
619
  const timeout = setTimeout(() => {
660
620
  const sub = robot.jobSubscriptions.get(jobId);
661
621
  if (sub) {
662
- logger.info(`[pier-connector][${accountId}] 🛑 Stopping listener for job ${jobId} (inactivity)`);
622
+ logger.info(`[pier-connector][${accountId}] \u{1F6D1} Stopping listener for job ${jobId} (inactivity)`);
663
623
  sub.stop();
664
624
  robot.jobSubscriptions.delete(jobId);
665
625
  robot.jobStopTimeouts.delete(jobId);
@@ -790,7 +750,7 @@ export default function register(api) {
790
750
  }
791
751
 
792
752
  try {
793
- const subject = `jobs.job.${params.jobId}.msg`;
753
+ const subject = `chat.${params.jobId}`;
794
754
  const payload = {
795
755
  id: crypto.randomUUID ? crypto.randomUUID() : (Math.random().toString(36).substring(2)),
796
756
  job_id: params.jobId,
@@ -834,7 +794,7 @@ export default function register(api) {
834
794
  }
835
795
 
836
796
  try {
837
- const subject = `jobs.job.${params.jobId}.msg`;
797
+ const subject = `chat.${params.jobId}`;
838
798
  const { jobId, accountId: _, ...payload } = params;
839
799
 
840
800
  const msgData = {