@gholl-studio/pier-connector 0.1.8 → 0.2.1

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 +43 -32
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@gholl-studio/pier-connector",
3
3
  "author": "gholl",
4
- "version": "0.1.8",
4
+ "version": "0.2.1",
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
@@ -306,15 +306,19 @@ export default function register(api) {
306
306
  const config = getActiveConfig();
307
307
  const replySubject = `jobs.job.${jobId}.msg`;
308
308
  const replyPayload = {
309
- id: ethers.hexlify(ethers.randomBytes(16)), // Unique ID for frontend tracking
309
+ id: ethers.hexlify(ethers.randomBytes(16)),
310
+ job_id: jobId,
310
311
  sender_id: config.nodeId,
312
+ sender_type: 'node',
311
313
  content: text,
312
- created_at: new Date().toISOString()
314
+ timestamp: new Date().toISOString(),
315
+ auth_token: config.secretKey // Secure token for backend validation
313
316
  };
317
+
314
318
  await js.publish(replySubject, new TextEncoder().encode(JSON.stringify(replyPayload)));
315
- logger.info(`[pier-connector] 💬 Published agent reply to realtime chat for job ${jobId}`);
319
+ logger.info(`[pier-connector] 💬 Agent reply published directly to NATS for job ${jobId}`);
316
320
  } catch (err) {
317
- logger.error(`[pier-connector] Failed to send realtime reply: ${err.message}`);
321
+ logger.error(`[pier-connector] Failed to publish realtime reply to NATS: ${err.message}`);
318
322
  }
319
323
  } else if (js) {
320
324
  // Publish result to jobs.submit via JetStream (not msg.respond)
@@ -593,7 +597,7 @@ export default function register(api) {
593
597
  const cInfo = await jsm.consumers.add(streamName, {
594
598
  durable_name: durableName,
595
599
  filter_subject: msgSubject,
596
- deliver_policy: DeliverPolicy.New, // Only new messages to avoid replay spam
600
+ deliver_policy: DeliverPolicy.New, // Reverted to New to stop message storms (BUG-27)
597
601
  ack_policy: AckPolicy.Explicit,
598
602
  ack_wait: 30000,
599
603
  });
@@ -603,8 +607,9 @@ export default function register(api) {
603
607
  jobSubscriptions.set(jobId, iter);
604
608
 
605
609
  (async () => {
606
- logger.info(`[pier-connector] 👂 Monitoring new messages for job ${jobId}`);
610
+ logger.info(`[pier-connector] 👂 Monitoring chat subject ${msgSubject} (Durable: ${durableName})`);
607
611
 
612
+ let isProcessing = false;
608
613
  for await (const msg of iter) {
609
614
  try {
610
615
  const rawMsg = new TextDecoder().decode(msg.data);
@@ -642,10 +647,19 @@ export default function register(api) {
642
647
  }
643
648
  }
644
649
 
645
- const content = msgPayload.content;
646
- logger.info(`[pier-connector] 📥 Incoming message for ${jobId}: "${truncate(content, 40)}"`);
647
-
648
- const senderCore = msgPayload.sender_id;
650
+ if (!content) {
651
+ logger.warn(`[pier-connector] ⚠️ Skipping message from ${senderCore} for ${jobId}: Empty content`);
652
+ msg.ack();
653
+ continue;
654
+ }
655
+
656
+ if (isProcessing) {
657
+ logger.warn(`[pier-connector] ⏳ Throttling: Agent already processing for job ${jobId}`);
658
+ msg.nak();
659
+ continue;
660
+ }
661
+
662
+ logger.info(`[pier-connector] 📥 Incoming chat: [${jobId}] sender=${senderCore} "${truncate(content, 40)}"`);
649
663
 
650
664
  activeNodeJobs.set(jobId, {
651
665
  pierJobId: jobId,
@@ -653,11 +667,16 @@ export default function register(api) {
653
667
  });
654
668
 
655
669
  // Trigger agent
656
- await receiveIncoming({
657
- accountId: config.accountId || 'default',
658
- senderId: `pier:${senderCore}`,
659
- text: content,
660
- }, jobId);
670
+ try {
671
+ isProcessing = true;
672
+ await receiveIncoming({
673
+ accountId: config.accountId || 'default',
674
+ senderId: `pier:${senderCore}`,
675
+ text: content,
676
+ }, jobId);
677
+ } finally {
678
+ isProcessing = false;
679
+ }
661
680
 
662
681
  msg.ack();
663
682
  } catch (err) {
@@ -925,29 +944,21 @@ export default function register(api) {
925
944
  }
926
945
 
927
946
  try {
947
+
948
+ const config = getActiveConfig();
949
+ const subject = `jobs.job.${params.jobId}.msg`;
928
950
  const payload = {
929
- sender_id: getActiveConfig().nodeId,
951
+ id: ethers.hexlify(ethers.randomBytes(16)),
952
+ job_id: params.jobId,
953
+ sender_id: config.nodeId,
954
+ sender_type: 'node',
930
955
  content: params.text,
931
- created_at: new Date().toISOString()
956
+ timestamp: new Date().toISOString(),
957
+ auth_token: config.secretKey // Secure token for backend validation
932
958
  };
933
959
 
934
- const subject = `jobs.job.${params.jobId}.msg`;
935
960
  await js.publish(subject, new TextEncoder().encode(JSON.stringify(payload)));
936
961
 
937
- // Also SAVE to database for persistence
938
- const config = getActiveConfig();
939
- await fetch(`${config.pierApiUrl}/jobs/${params.jobId}/messages`, {
940
- method: 'POST',
941
- headers: {
942
- 'Content-Type': 'application/json',
943
- 'Authorization': `Bearer ${config.secretKey}` // BUG-7: Use Authorization header, not X-API-Key
944
- },
945
- body: JSON.stringify({
946
- sender_id: config.nodeId,
947
- content: params.text
948
- })
949
- });
950
-
951
962
  return { content: [{ type: 'text', text: 'Message sent' }] };
952
963
  } catch (err) {
953
964
  return { content: [{ type: 'text', text: `Error: ${err.message}` }] };