@gholl-studio/pier-connector 0.3.0 → 0.3.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.
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.0",
4
+ "version": "0.3.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.ts",
package/src/inbound.ts CHANGED
@@ -102,7 +102,7 @@ export async function handleInbound(
102
102
  }
103
103
 
104
104
  const ctxPayload = api.runtime.channel.reply.finalizeInboundContext({
105
- agentId: finalAgentId,
105
+ AgentId: finalAgentId,
106
106
  Body: inbound.body,
107
107
  BodyForAgent: inbound.body,
108
108
  RawBody: inbound.body,
package/src/index.ts CHANGED
@@ -130,6 +130,148 @@ const register = (api: PierPluginApi) => {
130
130
  }
131
131
  }, { optional: true });
132
132
 
133
+ api.registerTool(
134
+ {
135
+ name: 'pier_chat',
136
+ label: 'Pier Chat',
137
+ description: 'Send a message to the employer regarding a specific job.',
138
+ parameters: {
139
+ type: 'object',
140
+ properties: {
141
+ jobId: { type: 'string' },
142
+ text: { type: 'string' },
143
+ accountId: { type: 'string' }
144
+ },
145
+ required: ['jobId', 'text']
146
+ },
147
+ async execute(_id, params, ctx: any) {
148
+ const accountId = params.accountId || 'default';
149
+ const robot = instances.get(accountId) || instances.values().next().value;
150
+ if (!robot || robot.connectionStatus !== 'connected') {
151
+ return { content: [{ type: 'text', text: 'Error: Robot not connected' }], details: {} };
152
+ }
153
+
154
+ try {
155
+ const subject = `chat.${params.jobId}`;
156
+ let metadata = robot.activeNodeJobs.get(params.jobId);
157
+
158
+ if (!metadata && ctx.to) {
159
+ const toId = ctx.to.replace(/^pier:/, '');
160
+ metadata = robot.activeNodeJobs.get(toId);
161
+ }
162
+
163
+ const jobId = metadata?.pierJobId || params.jobId;
164
+
165
+ if (!robot.js) {
166
+ return { content: [{ type: 'text', text: 'Error: JetStream not available' }], details: {} };
167
+ }
168
+
169
+ const payload = {
170
+ id: (globalThis.crypto as any).randomUUID ? (globalThis.crypto as any).randomUUID() : (Math.random().toString(36).substring(2)),
171
+ job_id: jobId,
172
+ sender_id: robot.config.nodeId,
173
+ sender_name: accountId,
174
+ sender_type: 'node',
175
+ content: params.text,
176
+ created_at: new Date().toISOString(),
177
+ auth_token: robot.config.secretKey
178
+ };
179
+
180
+ await robot.js.publish(subject, new TextEncoder().encode(JSON.stringify(payload)));
181
+ return { content: [{ type: 'text', text: 'Message sent' }], details: {} };
182
+ } catch (err: any) {
183
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], details: {} };
184
+ }
185
+ }
186
+ },
187
+ { optional: true }
188
+ );
189
+
190
+ const registerSystemActionTool = (name: string, label: string, description: string, action: string, extraParams: any, userRole = 'node') => {
191
+ api.registerTool({
192
+ name,
193
+ label,
194
+ description,
195
+ parameters: {
196
+ type: 'object',
197
+ properties: {
198
+ jobId: { type: 'string', description: 'The ID of the job' },
199
+ accountId: { type: 'string' },
200
+ ...extraParams
201
+ },
202
+ required: ['jobId', ...Object.keys(extraParams)]
203
+ },
204
+ async execute(_id, params) {
205
+ const accountId = params.accountId || 'default';
206
+ const robot = instances.get(accountId) || instances.values().next().value;
207
+ if (!robot || robot.connectionStatus !== 'connected') {
208
+ return { content: [{ type: 'text', text: 'Error: Robot not connected' }], details: {} };
209
+ }
210
+
211
+ try {
212
+ const subject = `chat.${params.jobId}`;
213
+ const { jobId: j, accountId: _, ...p } = params;
214
+
215
+ if (!robot.js) {
216
+ return { content: [{ type: 'text', text: 'Error: JetStream not available' }], details: {} };
217
+ }
218
+
219
+ const msgData = {
220
+ id: (globalThis.crypto as any).randomUUID ? (globalThis.crypto as any).randomUUID() : (Math.random().toString(36).substring(2)),
221
+ job_id: params.jobId,
222
+ sender_id: userRole === 'user' ? 'user_' + robot.config.nodeId : robot.config.nodeId,
223
+ sender_type: userRole,
224
+ content: JSON.stringify({ type: 'system_action', action, payload: p }),
225
+ created_at: new Date().toISOString(),
226
+ auth_token: robot.config.secretKey,
227
+ type: 'system_action',
228
+ action: action
229
+ };
230
+
231
+ await robot.js.publish(subject, new TextEncoder().encode(JSON.stringify(msgData)));
232
+ return { content: [{ type: 'text', text: `${action} executed successfully` }], details: {} };
233
+ } catch (err: any) {
234
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], details: {} };
235
+ }
236
+ }
237
+ }, { optional: true });
238
+ };
239
+
240
+ registerSystemActionTool('pier_bid_task', 'Bid on task', 'Bid on an marketplace task', 'task_bid', { message: { type: 'string', description: 'Your pitch' } });
241
+ registerSystemActionTool('pier_accept_task', 'Accept task', 'Accept offered task', 'task_accept', {});
242
+ registerSystemActionTool('pier_finish_task', 'Finish task', 'Submit final result', 'task_submit', { result: { type: 'string', description: 'Final result' } });
243
+ registerSystemActionTool('pier_propose_task', 'Offer task', 'Offer task to a node', 'task_offer', {
244
+ price: { type: 'number' },
245
+ description: { type: 'string' }
246
+ }, 'user');
247
+ registerSystemActionTool('pier_rate_task', 'Rate task', 'Rate the node', 'task_rate', {
248
+ score: { type: 'number' },
249
+ comment: { type: 'string' }
250
+ }, 'user');
251
+ registerSystemActionTool('pier_reject_task', 'Reject task', 'Reject task', 'task_reject', { reason: { type: 'string' } });
252
+ registerSystemActionTool('pier_fail_task', 'Report error', 'Report that the task has failed', 'task_error', { error: { type: 'string' } });
253
+ registerSystemActionTool('pier_cancel_task', 'Cancel task', 'Cancel the task', 'task_cancel', { reason: { type: 'string' } }, 'user');
254
+
255
+ api.registerTool({
256
+ name: 'pier_get_profile',
257
+ label: 'Pier Profile',
258
+ description: 'Get current Pier profile and node stats.',
259
+ parameters: {
260
+ type: 'object',
261
+ properties: { accountId: { type: 'string' } }
262
+ },
263
+ async execute(_id, params) {
264
+ const robot = instances.get(params.accountId || 'default') || instances.values().next().value;
265
+ if (!robot) return { content: [{ type: 'text', text: 'Error: Robot not found' }], details: {} };
266
+ try {
267
+ const profile = await robot.client.getUserProfile(robot.config.secretKey);
268
+ return { content: [{ type: 'text', text: JSON.stringify(profile, null, 2) }], details: {} };
269
+ } catch (err: any) {
270
+ return { content: [{ type: 'text', text: `Error: ${err.message}` }], details: {} };
271
+ }
272
+ }
273
+ }, { optional: true });
274
+
133
275
  // Register simple status command
134
276
  api.registerCommand({
135
277
  name: 'pier',