@gholl-studio/pier-connector 0.2.50 → 0.2.52
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 +5 -3
- package/src/index.js +72 -48
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.
|
|
4
|
+
"version": "0.2.52",
|
|
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",
|
|
@@ -50,6 +50,8 @@
|
|
|
50
50
|
}
|
|
51
51
|
},
|
|
52
52
|
"devDependencies": {
|
|
53
|
-
"dotenv": "^17.3.1"
|
|
53
|
+
"dotenv": "^17.3.1",
|
|
54
|
+
"openclaw": ">=2.0.0",
|
|
55
|
+
"typescript": "^5.0.0"
|
|
54
56
|
}
|
|
55
|
-
}
|
|
57
|
+
}
|
package/src/index.js
CHANGED
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* 4. A command ("/pier") for checking connection status
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
+
import { definePluginEntry } from 'openclaw/plugin-sdk/plugin-entry';
|
|
11
12
|
import { PierClient, protocol } from '@gholl-studio/pier-sdk';
|
|
12
13
|
const { createRequestPayload, createResultPayload, createErrorPayload } = protocol;
|
|
13
14
|
import { parseJob, safeRespond, truncate } from './job-handler.js';
|
|
@@ -22,7 +23,7 @@ import path from 'path';
|
|
|
22
23
|
*
|
|
23
24
|
* @param {object} api – OpenClaw plugin API
|
|
24
25
|
*/
|
|
25
|
-
|
|
26
|
+
const register = (api) => {
|
|
26
27
|
const logger = api.logger;
|
|
27
28
|
|
|
28
29
|
// ── shared state (Instances) ───────────────────────────────────
|
|
@@ -38,11 +39,15 @@ export default function register(api) {
|
|
|
38
39
|
// ── resolve plugin config ──────────────────────────────────────────
|
|
39
40
|
|
|
40
41
|
function resolveConfigs() {
|
|
41
|
-
|
|
42
|
-
const
|
|
42
|
+
// api.config is the full global OpenClaw configuration
|
|
43
|
+
const globalAccounts = api.config?.channels?.['pier']?.accounts || {};
|
|
44
|
+
|
|
45
|
+
// api.pluginConfig is the scoped config for THIS plugin
|
|
46
|
+
const pluginAccounts = api.pluginConfig?.accounts || {};
|
|
47
|
+
|
|
43
48
|
const rawAccounts = { ...globalAccounts, ...pluginAccounts };
|
|
44
49
|
|
|
45
|
-
const legacyCfg = api.
|
|
50
|
+
const legacyCfg = api.pluginConfig || {};
|
|
46
51
|
|
|
47
52
|
// If no accounts defined at all, fallback to 'default' using legacy/env config
|
|
48
53
|
if (Object.keys(rawAccounts).length === 0) {
|
|
@@ -165,11 +170,22 @@ export default function register(api) {
|
|
|
165
170
|
return;
|
|
166
171
|
}
|
|
167
172
|
|
|
168
|
-
logger.info(`[pier-connector:trace] receiveIncoming triggered.
|
|
173
|
+
logger.info(`[pier-connector:trace] receiveIncoming triggered for jobId=${jobId}. accountId='${inbound.accountId}', senderId='${inbound.senderId}'`);
|
|
174
|
+
|
|
175
|
+
// 1. Resolve Global Configuration
|
|
176
|
+
// In OpenClaw V2, we use api.config for the full global state.
|
|
177
|
+
const rootConfig = api.config || {};
|
|
178
|
+
|
|
179
|
+
// Diagnostic logging
|
|
180
|
+
const b = rootConfig.bindings;
|
|
181
|
+
const bindingsCount = Array.isArray(b) ? b.length : (b ? Object.keys(b).length : 0);
|
|
182
|
+
const agentsCount = rootConfig.agents?.list ? (Array.isArray(rootConfig.agents.list) ? rootConfig.agents.list.length : Object.keys(rootConfig.agents.list).length) : 0;
|
|
183
|
+
|
|
184
|
+
logger.info(`[pier-connector:trace] Diagnostic: rootConfig source=api.config, bindings=${bindingsCount}, agents=${agentsCount}`);
|
|
169
185
|
|
|
170
|
-
|
|
186
|
+
// 2. Resolve Agent Route via SDK
|
|
171
187
|
const route = api.runtime.channel.routing.resolveAgentRoute({
|
|
172
|
-
cfg:
|
|
188
|
+
cfg: rootConfig,
|
|
173
189
|
channel: 'pier',
|
|
174
190
|
account: inbound.accountId,
|
|
175
191
|
peer: { kind: 'direct', id: jobId }
|
|
@@ -177,57 +193,55 @@ export default function register(api) {
|
|
|
177
193
|
|
|
178
194
|
logger.info(`[pier-connector:trace] resolveAgentRoute returned: route.agentId='${route?.agentId}', route.accountId='${route?.accountId}'`);
|
|
179
195
|
|
|
180
|
-
//
|
|
181
|
-
let finalAgentId =
|
|
182
|
-
let routingSource = '
|
|
196
|
+
// 3. Robust Routing Decision Tree
|
|
197
|
+
let finalAgentId = null;
|
|
198
|
+
let routingSource = 'unresolved';
|
|
183
199
|
|
|
184
|
-
//
|
|
185
|
-
if (
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
logger.info(`[pier-connector:trace] Manual debug: bindings_count=${bs.length}, agents_count=${al.length}`);
|
|
200
|
+
// A. Check explicit account-level binding in plugin local config (this.config)
|
|
201
|
+
if (this.config.agentId && this.config.agentId !== 'main' && this.config.agentId !== 'default') {
|
|
202
|
+
finalAgentId = this.config.agentId;
|
|
203
|
+
routingSource = 'plugin-local-config';
|
|
204
|
+
}
|
|
191
205
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
206
|
+
// B. Check Global Bindings (Manual Scan of rootConfig.bindings)
|
|
207
|
+
if (!finalAgentId) {
|
|
208
|
+
const bindings = Array.isArray(rootConfig.bindings) ? rootConfig.bindings : [];
|
|
209
|
+
const binding = bindings.find(bi =>
|
|
210
|
+
bi.match?.channel === 'pier' &&
|
|
211
|
+
(bi.match?.accountId === inbound.accountId || bi.match?.account === inbound.accountId)
|
|
196
212
|
);
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
routingSource = 'manual-global-bindings';
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
// Check agent list for name match (account ID == agent ID)
|
|
204
|
-
if (!finalAgentId) {
|
|
205
|
-
const nameMatch = al.find(a => a.id === inbound.accountId);
|
|
206
|
-
if (nameMatch) {
|
|
207
|
-
finalAgentId = inbound.accountId;
|
|
208
|
-
routingSource = 'manual-name-match';
|
|
209
|
-
}
|
|
213
|
+
if (binding?.agentId && binding.agentId !== 'main') {
|
|
214
|
+
finalAgentId = binding.agentId;
|
|
215
|
+
routingSource = 'manual-global-bindings-match';
|
|
210
216
|
}
|
|
211
217
|
}
|
|
212
218
|
|
|
213
|
-
//
|
|
219
|
+
// C. SDK Routing Result (if it actually found something non-default)
|
|
214
220
|
if (!finalAgentId && route.agentId && route.agentId !== 'main' && route.agentId !== 'default') {
|
|
215
221
|
finalAgentId = route.agentId;
|
|
216
222
|
routingSource = 'sdk-global-bindings';
|
|
217
223
|
}
|
|
218
224
|
|
|
219
|
-
//
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
225
|
+
// D. Name-Matching Fallback (CRITICAL: account name == agent ID)
|
|
226
|
+
// If we see account 'sunwukong', and we have an agent 'sunwukong', route there!
|
|
227
|
+
if (!finalAgentId && inbound.accountId && inbound.accountId !== 'default' && inbound.accountId !== 'main') {
|
|
228
|
+
// Check if such an agent exists in rootConfig
|
|
229
|
+
const agents = rootConfig.agents?.list || {};
|
|
230
|
+
const agentExists = Array.isArray(agents) ? agents.some(a => a.id === inbound.accountId) : !!agents[inbound.accountId];
|
|
231
|
+
|
|
232
|
+
if (agentExists) {
|
|
223
233
|
finalAgentId = inbound.accountId;
|
|
224
|
-
routingSource = '
|
|
225
|
-
} else {
|
|
226
|
-
finalAgentId = route.agentId || 'main'; // Ultimate fallback
|
|
227
|
-
routingSource = route.agentId ? 'global-bindings-fallback' : 'default-routing';
|
|
234
|
+
routingSource = 'account-agent-name-match';
|
|
228
235
|
}
|
|
229
236
|
}
|
|
230
237
|
|
|
238
|
+
|
|
239
|
+
// E. Ultimate Fallback
|
|
240
|
+
if (!finalAgentId) {
|
|
241
|
+
finalAgentId = route.agentId || 'main'; // Use SDK result or hard default 'main'
|
|
242
|
+
routingSource = route.agentId ? 'sdk-default-fallback' : 'hardcoded-main-fallback';
|
|
243
|
+
}
|
|
244
|
+
|
|
231
245
|
logger.info(`[pier-connector] Routing account '${inbound.accountId}' -> agent '${finalAgentId}' (Source: ${routingSource})`);
|
|
232
246
|
|
|
233
247
|
const dynamicSessionKey = `pier-job-${jobId}`;
|
|
@@ -241,7 +255,7 @@ export default function register(api) {
|
|
|
241
255
|
"=========================================",
|
|
242
256
|
"You are an autonomous AI worker on Pier. This job currently has NO assigned worker.",
|
|
243
257
|
"1. DO NOT directly solve the user's task or output the final answer right now.",
|
|
244
|
-
"2. You MUST USE the
|
|
258
|
+
"2. You MUST USE the \`pier_bid_task\` tool to send a pitch/bid to the employer explaining why you are best equipped to solve this.",
|
|
245
259
|
"3. Stop executing after submitting the bid.",
|
|
246
260
|
"4. You MUST use the Job ID provided below when calling the tool.",
|
|
247
261
|
`Job ID: ${jobId}`,
|
|
@@ -260,8 +274,9 @@ export default function register(api) {
|
|
|
260
274
|
].join('\n');
|
|
261
275
|
}
|
|
262
276
|
|
|
277
|
+
// MsgContext uses PascalCase for keys in OpenClaw V2 SDK
|
|
263
278
|
const ctxPayload = api.runtime.channel.reply.finalizeInboundContext({
|
|
264
|
-
agentId: finalAgentId, //
|
|
279
|
+
agentId: finalAgentId, // Keep lowercase here as it's the target system ID
|
|
265
280
|
Body: inbound.text,
|
|
266
281
|
BodyForAgent: inbound.text,
|
|
267
282
|
RawBody: inbound.text,
|
|
@@ -282,12 +297,13 @@ export default function register(api) {
|
|
|
282
297
|
Metadata: {
|
|
283
298
|
...metadata,
|
|
284
299
|
accountId: this.accountId,
|
|
285
|
-
pierJobId: jobId
|
|
300
|
+
pierJobId: jobId,
|
|
301
|
+
routingSource: routingSource
|
|
286
302
|
}
|
|
287
303
|
});
|
|
288
304
|
|
|
289
305
|
const { dispatcher, markDispatchIdle } = api.runtime.channel.reply.createReplyDispatcherWithTyping({
|
|
290
|
-
cfg: api.
|
|
306
|
+
cfg: api.config,
|
|
291
307
|
agentId: finalAgentId,
|
|
292
308
|
deliver: async (payload) => {
|
|
293
309
|
const currentMeta = this.activeNodeJobs.get(jobId);
|
|
@@ -314,7 +330,7 @@ export default function register(api) {
|
|
|
314
330
|
|
|
315
331
|
try {
|
|
316
332
|
await api.runtime.channel.reply.dispatchReplyFromConfig({
|
|
317
|
-
ctx: ctxPayload, cfg: api.
|
|
333
|
+
ctx: ctxPayload, cfg: api.config, dispatcher
|
|
318
334
|
});
|
|
319
335
|
} finally {
|
|
320
336
|
markDispatchIdle();
|
|
@@ -1210,3 +1226,11 @@ export default function register(api) {
|
|
|
1210
1226
|
|
|
1211
1227
|
logger.info('[pier-connector] Plugin registered');
|
|
1212
1228
|
}
|
|
1229
|
+
|
|
1230
|
+
export default definePluginEntry({
|
|
1231
|
+
id: 'pier-connector',
|
|
1232
|
+
name: 'Pier Connector',
|
|
1233
|
+
description: 'Connects OpenClaw to the Pier job marketplace.',
|
|
1234
|
+
register
|
|
1235
|
+
});
|
|
1236
|
+
|