@gholl-studio/pier-connector 0.3.20 → 0.3.22
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 +1 -1
- package/src/inbound.ts +13 -12
- package/src/index.ts +39 -7
- package/src/robot.ts +13 -1
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.
|
|
4
|
+
"version": "0.3.22",
|
|
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
|
@@ -7,21 +7,22 @@ import type { InboundMessage } from './types.js';
|
|
|
7
7
|
import { truncate } from './job-handler.js';
|
|
8
8
|
|
|
9
9
|
export async function handleInbound(
|
|
10
|
-
|
|
10
|
+
ctx: any, // Gateway Context
|
|
11
11
|
inbound: InboundMessage,
|
|
12
12
|
jobId: string,
|
|
13
13
|
robot: any,
|
|
14
14
|
pierPlugin: any
|
|
15
15
|
) {
|
|
16
|
-
const logger =
|
|
16
|
+
const logger = ctx.log || console;
|
|
17
|
+
const channelRuntime = ctx.channelRuntime;
|
|
17
18
|
|
|
18
|
-
if (!
|
|
19
|
-
console.error(`[pier-connector][${robot.accountId}] SDK Error:
|
|
19
|
+
if (!channelRuntime?.reply) {
|
|
20
|
+
console.error(`[pier-connector][${robot.accountId}] SDK Error: channelRuntime.reply is not available.`);
|
|
20
21
|
return;
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
// 1. Resolve Account-Scoped Configuration
|
|
24
|
-
const rootConfig =
|
|
25
|
+
const rootConfig = ctx.cfg || {};
|
|
25
26
|
const accountScopedCfg = {
|
|
26
27
|
...rootConfig,
|
|
27
28
|
channels: {
|
|
@@ -31,7 +32,7 @@ export async function handleInbound(
|
|
|
31
32
|
};
|
|
32
33
|
|
|
33
34
|
// 2. Resolve Agent Route
|
|
34
|
-
const route =
|
|
35
|
+
const route = channelRuntime.routing.resolveAgentRoute({
|
|
35
36
|
cfg: accountScopedCfg,
|
|
36
37
|
channel: 'pier',
|
|
37
38
|
accountId: robot.accountId,
|
|
@@ -72,7 +73,7 @@ export async function handleInbound(
|
|
|
72
73
|
}
|
|
73
74
|
|
|
74
75
|
// 3. Finalize Context
|
|
75
|
-
const ctxPayload =
|
|
76
|
+
const ctxPayload = channelRuntime.reply.finalizeInboundContext({
|
|
76
77
|
Body: inbound.body,
|
|
77
78
|
BodyForAgent: inbound.body,
|
|
78
79
|
RawBody: inbound.body,
|
|
@@ -102,7 +103,7 @@ export async function handleInbound(
|
|
|
102
103
|
});
|
|
103
104
|
|
|
104
105
|
// 4. Create Dispatcher
|
|
105
|
-
const { dispatcher, markDispatchIdle } =
|
|
106
|
+
const { dispatcher, markDispatchIdle } = channelRuntime.reply.createReplyDispatcherWithTyping({
|
|
106
107
|
deliver: async (payload: any, info: any) => {
|
|
107
108
|
const currentMeta = robot.activeNodeJobs.get(jobId);
|
|
108
109
|
const resAgent = payload.agentId || finalAgentId;
|
|
@@ -126,10 +127,10 @@ export async function handleInbound(
|
|
|
126
127
|
});
|
|
127
128
|
|
|
128
129
|
// 5. Session Recording
|
|
129
|
-
if (
|
|
130
|
+
if (channelRuntime.session?.recordSessionMetaFromInbound) {
|
|
130
131
|
try {
|
|
131
|
-
const storePath =
|
|
132
|
-
await
|
|
132
|
+
const storePath = channelRuntime.session.resolveStorePath(dynamicSessionKey);
|
|
133
|
+
await channelRuntime.session.recordSessionMetaFromInbound({
|
|
133
134
|
storePath, sessionKey: dynamicSessionKey, ctx: ctxPayload
|
|
134
135
|
});
|
|
135
136
|
} catch (err: any) {
|
|
@@ -139,7 +140,7 @@ export async function handleInbound(
|
|
|
139
140
|
|
|
140
141
|
// 6. Dispatch
|
|
141
142
|
try {
|
|
142
|
-
await
|
|
143
|
+
await channelRuntime.reply.dispatchReplyFromConfig({
|
|
143
144
|
ctx: ctxPayload,
|
|
144
145
|
cfg: accountScopedCfg,
|
|
145
146
|
dispatcher,
|
package/src/index.ts
CHANGED
|
@@ -141,51 +141,83 @@ const pierPlugin: ChannelPlugin<PierAccountConfig> = {
|
|
|
141
141
|
}
|
|
142
142
|
},
|
|
143
143
|
|
|
144
|
+
// -------------------------------------------------------------------------
|
|
145
|
+
// Status Adapter
|
|
146
|
+
// -------------------------------------------------------------------------
|
|
147
|
+
status: {
|
|
148
|
+
buildAccountSnapshot: ({ account, cfg }) => {
|
|
149
|
+
const robot = instances.get(account.accountId);
|
|
150
|
+
return {
|
|
151
|
+
accountId: account.accountId,
|
|
152
|
+
running: !!robot,
|
|
153
|
+
connected: robot?.connectionStatus === 'connected',
|
|
154
|
+
lastStartAt: (robot as any)?.lastStartAt,
|
|
155
|
+
lastStopAt: (robot as any)?.lastStopAt,
|
|
156
|
+
lastError: (robot as any)?.lastError,
|
|
157
|
+
healthState: robot?.connectionStatus === 'connected' ? 'healthy' : 'degraded',
|
|
158
|
+
};
|
|
159
|
+
},
|
|
160
|
+
resolveAccountState: ({ configured, enabled }) => {
|
|
161
|
+
return configured && enabled ? 'enabled' : 'disabled';
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
|
|
144
165
|
// -------------------------------------------------------------------------
|
|
145
166
|
// Gateway Adapter
|
|
146
167
|
// -------------------------------------------------------------------------
|
|
147
168
|
gateway: {
|
|
148
169
|
startAccount: async (ctx) => {
|
|
149
170
|
const config = ctx.account;
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
171
|
+
// Use ctx as the runtime provider as it contains .channelRuntime, .log, etc.
|
|
172
|
+
const robot = new PierRobot(config, ctx as any, async (inbound, jobId) => {
|
|
173
|
+
// Pass the context containing channelRuntime
|
|
174
|
+
await handleInbound(ctx, inbound, jobId, robot, pierPlugin);
|
|
153
175
|
});
|
|
154
176
|
instances.set(ctx.accountId, robot);
|
|
155
177
|
|
|
156
178
|
try {
|
|
179
|
+
(robot as any).lastStartAt = Date.now();
|
|
157
180
|
await robot.start();
|
|
181
|
+
|
|
158
182
|
ctx.setStatus({
|
|
159
183
|
...ctx.getStatus(),
|
|
160
184
|
running: true,
|
|
161
|
-
|
|
185
|
+
connected: true,
|
|
186
|
+
lastStartAt: (robot as any).lastStartAt
|
|
162
187
|
} as any);
|
|
163
188
|
|
|
164
|
-
// Keep
|
|
189
|
+
// IMPORTANT: Keep startAccount promise active for the lifetime of the connection.
|
|
190
|
+
// If this promise resolves, the Gateway will auto-restart the account.
|
|
165
191
|
await new Promise<void>((resolve) => {
|
|
166
192
|
ctx.abortSignal.addEventListener('abort', () => {
|
|
167
193
|
resolve();
|
|
168
194
|
}, { once: true });
|
|
195
|
+
|
|
196
|
+
if (ctx.abortSignal.aborted) resolve();
|
|
169
197
|
});
|
|
198
|
+
|
|
199
|
+
console.log(`[pier-connector][${ctx.accountId}] Account signal aborted. Stopping...`);
|
|
170
200
|
} catch (err: any) {
|
|
201
|
+
(robot as any).lastError = err.message;
|
|
171
202
|
ctx.setStatus({
|
|
172
203
|
...ctx.getStatus(),
|
|
173
204
|
running: false,
|
|
174
205
|
lastError: err.message
|
|
175
206
|
} as any);
|
|
176
|
-
throw err;
|
|
207
|
+
throw err;
|
|
177
208
|
}
|
|
178
209
|
},
|
|
179
210
|
stopAccount: async (ctx) => {
|
|
180
211
|
const robot = instances.get(ctx.accountId);
|
|
181
212
|
if (robot) {
|
|
213
|
+
(robot as any).lastStopAt = Date.now();
|
|
182
214
|
await robot.stop();
|
|
183
215
|
instances.delete(ctx.accountId);
|
|
184
216
|
}
|
|
185
217
|
ctx.setStatus({
|
|
186
218
|
...ctx.getStatus(),
|
|
187
219
|
running: false,
|
|
188
|
-
lastStopAt:
|
|
220
|
+
lastStopAt: (robot as any).lastStopAt
|
|
189
221
|
} as any);
|
|
190
222
|
}
|
|
191
223
|
}
|
package/src/robot.ts
CHANGED
|
@@ -38,8 +38,20 @@ export class PierRobot {
|
|
|
38
38
|
this.config = config;
|
|
39
39
|
this.accountId = config.accountId;
|
|
40
40
|
this.runtime = runtime;
|
|
41
|
-
this.logger = runtime.log || console;
|
|
42
41
|
this.onInbound = onInbound;
|
|
42
|
+
|
|
43
|
+
// Robust logger wrapper
|
|
44
|
+
if (runtime.log && typeof runtime.log === 'object' && 'error' in runtime.log) {
|
|
45
|
+
this.logger = runtime.log;
|
|
46
|
+
} else {
|
|
47
|
+
this.logger = {
|
|
48
|
+
info: (msg: string) => (typeof runtime.log === 'function' ? runtime.log(msg) : console.log(msg)),
|
|
49
|
+
error: (msg: string) => (typeof runtime.error === 'function' ? runtime.error(msg) : console.error(msg)),
|
|
50
|
+
warn: (msg: string) => (typeof runtime.warn === 'function' ? runtime.warn(msg) : console.warn(msg)),
|
|
51
|
+
debug: (msg: string) => (typeof runtime.debug === 'function' ? runtime.debug(msg) : console.debug ? console.debug(msg) : console.log(msg)),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
43
55
|
this.client = new PierClient({
|
|
44
56
|
apiUrl: config.pierApiUrl,
|
|
45
57
|
natsUrl: config.natsUrl,
|