@gholl-studio/pier-connector 0.2.16 → 0.2.17

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 +26 -11
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.16",
4
+ "version": "0.2.17",
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
@@ -188,13 +188,25 @@ export default function register(api) {
188
188
  }
189
189
  });
190
190
 
191
+ const dynamicSessionKey = `pier-job-${jobId}`;
192
+ const injectedPrompt = [
193
+ "=========================================",
194
+ "CRITICAL DIRECTIVE - PIER TRADING NETWORK",
195
+ "=========================================",
196
+ "You are an autonomous AI worker on Pier.",
197
+ "1. You MUST USE the `pier_finish_task` tool to submit the final result when your work is complete.",
198
+ "2. If you need to negotiate or clarify requirements with the employer, use `pier_chat`.",
199
+ "3. Do not just wait in silence. Always officially finish the task if the employer's goal is met.",
200
+ inbound.systemPrompt ? `\nEmployer Guidelines:\n${inbound.systemPrompt}` : ""
201
+ ].join('\n');
202
+
191
203
  const ctxPayload = api.runtime.channel.reply.finalizeInboundContext({
192
204
  Body: inbound.text,
193
205
  BodyForAgent: inbound.text,
194
206
  RawBody: inbound.text,
195
207
  From: inbound.senderId,
196
208
  To: `pier:${jobId}`,
197
- SessionKey: route.sessionKey,
209
+ SessionKey: dynamicSessionKey,
198
210
  AccountId: route.accountId,
199
211
  ChatType: 'direct',
200
212
  SenderId: inbound.senderId,
@@ -204,7 +216,7 @@ export default function register(api) {
204
216
  OriginatingTo: `pier:${jobId}`,
205
217
  WasMentioned: true,
206
218
  CommandAuthorized: true,
207
- SystemPrompt: inbound.systemPrompt || undefined,
219
+ SystemPrompt: injectedPrompt,
208
220
  MessageId: inbound.messageId || jobId
209
221
  });
210
222
 
@@ -215,7 +227,7 @@ export default function register(api) {
215
227
  cfg: api.config,
216
228
  agentId: route.agentId,
217
229
  onIdle: () => {
218
- logger.debug(`[pier-connector] Dispatcher idle for session ${route.sessionKey}`);
230
+ logger.debug(`[pier-connector] Dispatcher idle for session ${dynamicSessionKey}`);
219
231
  },
220
232
  deliver: async (payload) => {
221
233
  const metadata = activeNodeJobs.get(jobId);
@@ -239,10 +251,10 @@ export default function register(api) {
239
251
  // Record session meta
240
252
  if (api.runtime.channel.session?.recordSessionMetaFromInbound) {
241
253
  try {
242
- const storePath = api.runtime.channel.session.resolveStorePath(api.config, route.sessionKey);
254
+ const storePath = api.runtime.channel.session.resolveStorePath(api.config, dynamicSessionKey);
243
255
  await api.runtime.channel.session.recordSessionMetaFromInbound({
244
256
  storePath,
245
- sessionKey: route.sessionKey,
257
+ sessionKey: dynamicSessionKey,
246
258
  ctx: ctxPayload
247
259
  });
248
260
  } catch (err) {
@@ -251,14 +263,14 @@ export default function register(api) {
251
263
  }
252
264
 
253
265
  try {
254
- logger.info(`[pier-connector] 🧠 Triggering agent for session ${route.sessionKey}...`);
266
+ logger.info(`[pier-connector] 🧠 Triggering agent for session ${dynamicSessionKey}...`);
255
267
  // Dispatch reply — this will trigger outbound: sendText in pierChannel
256
268
  await api.runtime.channel.reply.dispatchReplyFromConfig({
257
269
  ctx: ctxPayload,
258
270
  cfg: api.config,
259
271
  dispatcher
260
272
  });
261
- logger.info(`[pier-connector] 🧠 Agent dispatch completed for ${route.sessionKey}`);
273
+ logger.info(`[pier-connector] 🧠 Agent dispatch completed for ${dynamicSessionKey}`);
262
274
  } finally {
263
275
  markDispatchIdle();
264
276
  }
@@ -546,9 +558,11 @@ export default function register(api) {
546
558
  logger.warn(`[pier-connector] ⚠️ Failed to restore active jobs: ${err.message}`);
547
559
  }
548
560
 
549
- // Public pool with load balancing via JetStream Durable Consumer
561
+ // Public pool with broadcast via JetStream Durable Consumer
550
562
  if (publicSubject) {
551
- const durableName = `pier_marketplace_${config.queueGroup || 'default'}`;
563
+ // For Bidding, every node needs to see the marketplace requests to evaluate them,
564
+ // so we do not use the shared queueGroup. We use a unique durable per node.
565
+ const durableName = `pier_market_${config.nodeId.replace(/-/g, '_')}`;
552
566
  const streamName = 'PIER_JOBS';
553
567
  logger.info(`[pier-connector] 👂 Listening to Marketplace (JetStream): ${publicSubject} (Durable: ${durableName})`);
554
568
 
@@ -567,7 +581,7 @@ export default function register(api) {
567
581
  filter_subject: publicSubject,
568
582
  deliver_policy: DeliverPolicy.New, // SDK-3: Only new messages
569
583
  ack_policy: AckPolicy.Explicit,
570
- deliver_group: config.queueGroup
584
+ // Removed deliver_group to ensure it's a broadcast to all independent nodes
571
585
  });
572
586
  } catch (addErr) {
573
587
  // SDK-5: Config mismatch — delete old and recreate
@@ -578,7 +592,6 @@ export default function register(api) {
578
592
  filter_subject: publicSubject,
579
593
  deliver_policy: DeliverPolicy.New,
580
594
  ack_policy: AckPolicy.Explicit,
581
- deliver_group: config.queueGroup
582
595
  });
583
596
  }
584
597
  consumer = await js.consumers.get(streamName, durableName);
@@ -809,6 +822,7 @@ export default function register(api) {
809
822
 
810
823
  // Anti-Interference: If busy, ignore new marketplace jobs (BUG-34)
811
824
  if (isBusy) {
825
+ logger.debug(`[pier-connector] 🚫 Busy. Ignoring new job payload: ${rawData.substring(0, 50)}...`);
812
826
  // NAK so others in the queue group can take it
813
827
  msg.nak();
814
828
  return;
@@ -1142,6 +1156,7 @@ export default function register(api) {
1142
1156
  };
1143
1157
 
1144
1158
  // For Node (Worker)
1159
+ registerSystemActionTool('pier_bid_task', 'Bid on an open marketplace task to offer your services to the employer', 'task_bid', { message: { type: 'string', description: 'Your pitch explaining why you are a good fit for this task' } });
1145
1160
  registerSystemActionTool('pier_accept_task', 'Accept an offered task from the employer in the current chat', 'task_accept', {});
1146
1161
  registerSystemActionTool('pier_finish_task', 'Submit the final result for a task', 'task_submit', { result: { type: 'string', description: 'The final result or file links' } });
1147
1162