@gholl-studio/pier-connector 0.3.12 → 0.3.14
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 +23 -54
- package/src/index.ts +9 -7
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.14",
|
|
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
|
@@ -19,62 +19,32 @@ export async function handleInbound(
|
|
|
19
19
|
return;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
// 1. Resolve
|
|
22
|
+
// 1. Resolve Account-Scoped Configuration
|
|
23
23
|
const rootConfig = api.config || {};
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
/**
|
|
26
|
+
* ★ Multi-Account Configuration Isolation: Build account-level ClawdbotConfig
|
|
27
|
+
*
|
|
28
|
+
* In multi-account scenarios, each account can have independent agent bindings.
|
|
29
|
+
* The SDK's resolveAgentRoute looks into cfg.channels.pier.
|
|
30
|
+
* By injecting the current robot's config here, we ensure the SDK finds
|
|
31
|
+
* the correct agentId for this specific account.
|
|
32
|
+
*/
|
|
33
|
+
const accountScopedCfg = {
|
|
34
|
+
...rootConfig,
|
|
35
|
+
channels: { ...rootConfig.channels, pier: robot.config }
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// 2. Resolve Agent Route via SDK with Scoped Config
|
|
26
39
|
const route = api.runtime.channel.routing.resolveAgentRoute({
|
|
27
|
-
cfg:
|
|
40
|
+
cfg: accountScopedCfg,
|
|
28
41
|
channel: 'pier',
|
|
29
42
|
accountId: inbound.accountId,
|
|
30
43
|
peer: { kind: 'direct', id: jobId }
|
|
31
44
|
});
|
|
32
45
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
let routingSource = 'unresolved';
|
|
36
|
-
|
|
37
|
-
// A. Check explicit account-level binding in plugin local config
|
|
38
|
-
if (robot.config.agentId && robot.config.agentId !== 'main' && robot.config.agentId !== 'default') {
|
|
39
|
-
finalAgentId = robot.config.agentId;
|
|
40
|
-
routingSource = 'plugin-local-config';
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// B. Check Global Bindings
|
|
44
|
-
if (!finalAgentId) {
|
|
45
|
-
const bindings = Array.isArray(rootConfig.bindings) ? rootConfig.bindings : [];
|
|
46
|
-
const binding = bindings.find((bi: any) =>
|
|
47
|
-
bi.match?.channel === 'pier' &&
|
|
48
|
-
(bi.match?.accountId === inbound.accountId || bi.match?.account === inbound.accountId)
|
|
49
|
-
);
|
|
50
|
-
if (binding?.agentId && binding.agentId !== 'main') {
|
|
51
|
-
finalAgentId = binding.agentId;
|
|
52
|
-
routingSource = 'manual-global-bindings-match';
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// C. SDK Routing Result
|
|
57
|
-
if (!finalAgentId && route.agentId && route.agentId !== 'main' && route.agentId !== 'default') {
|
|
58
|
-
finalAgentId = route.agentId;
|
|
59
|
-
routingSource = 'sdk-global-bindings';
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// D. Name-Matching Fallback
|
|
63
|
-
if (!finalAgentId && inbound.accountId && inbound.accountId !== 'default' && inbound.accountId !== 'main') {
|
|
64
|
-
const agents = (rootConfig as any).agents?.list || {};
|
|
65
|
-
const agentExists = Array.isArray(agents) ? agents.some((a: any) => a.id === inbound.accountId) : !!agents[inbound.accountId];
|
|
66
|
-
|
|
67
|
-
if (agentExists) {
|
|
68
|
-
finalAgentId = inbound.accountId;
|
|
69
|
-
routingSource = 'account-agent-name-match';
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// E. Ultimate Fallback
|
|
74
|
-
if (!finalAgentId) {
|
|
75
|
-
finalAgentId = route.agentId || 'main';
|
|
76
|
-
routingSource = route.agentId ? 'sdk-default-fallback' : 'hardcoded-main-fallback';
|
|
77
|
-
}
|
|
46
|
+
const finalAgentId = route.agentId || 'main';
|
|
47
|
+
const routingSource = route.agentId ? 'sdk-scoped-route' : 'sdk-default-fallback';
|
|
78
48
|
|
|
79
49
|
logger.info(`[pier-connector] Routing account '${inbound.accountId}' -> agent '${finalAgentId}' (Source: ${routingSource})`);
|
|
80
50
|
|
|
@@ -109,28 +79,27 @@ export async function handleInbound(
|
|
|
109
79
|
logger.info(`[pier-connector:trace] Finalized inbound context for job ${jobId}. Target Agent: ${finalAgentId}, Session: ${dynamicSessionKey}`);
|
|
110
80
|
|
|
111
81
|
const ctxPayload = api.runtime.channel.reply.finalizeInboundContext({
|
|
112
|
-
AgentId: finalAgentId,
|
|
113
|
-
agentId: finalAgentId, // Redundant for compatibility
|
|
114
82
|
Body: inbound.body,
|
|
115
83
|
BodyForAgent: inbound.body,
|
|
116
84
|
RawBody: inbound.body,
|
|
117
85
|
From: inbound.senderId,
|
|
118
|
-
To: `
|
|
86
|
+
To: `chat:${jobId}`,
|
|
119
87
|
SessionKey: dynamicSessionKey,
|
|
120
88
|
AccountId: inbound.accountId,
|
|
121
89
|
ChatType: 'direct',
|
|
122
90
|
SenderId: inbound.senderId,
|
|
91
|
+
SenderName: robot.accountId,
|
|
123
92
|
Provider: 'pier',
|
|
124
93
|
Surface: 'pier',
|
|
125
94
|
OriginatingChannel: 'pier',
|
|
126
|
-
OriginatingTo: `
|
|
95
|
+
OriginatingTo: `chat:${jobId}`,
|
|
127
96
|
WasMentioned: true,
|
|
128
97
|
CommandAuthorized: true,
|
|
129
98
|
SystemPrompt: injectedPrompt,
|
|
130
99
|
MessageId: jobId,
|
|
100
|
+
MessageSid: jobId,
|
|
131
101
|
Metadata: {
|
|
132
102
|
...metadata,
|
|
133
|
-
agentId: finalAgentId, // Pinning in metadata
|
|
134
103
|
accountId: robot.accountId,
|
|
135
104
|
pierJobId: jobId,
|
|
136
105
|
routingSource: routingSource
|
|
@@ -170,7 +139,7 @@ export async function handleInbound(
|
|
|
170
139
|
try {
|
|
171
140
|
logger.info(`[pier-connector:trace] Dispatching reply to agent ${finalAgentId}...`);
|
|
172
141
|
await api.runtime.channel.reply.dispatchReplyFromConfig({
|
|
173
|
-
ctx: ctxPayload, cfg:
|
|
142
|
+
ctx: ctxPayload, cfg: accountScopedCfg, dispatcher
|
|
174
143
|
});
|
|
175
144
|
logger.info(`[pier-connector:trace] dispatchReplyFromConfig completed for job ${jobId}`);
|
|
176
145
|
} catch (err: any) {
|
package/src/index.ts
CHANGED
|
@@ -117,8 +117,9 @@ const register = (api: PierPluginApi) => {
|
|
|
117
117
|
},
|
|
118
118
|
required: ['task']
|
|
119
119
|
},
|
|
120
|
-
async execute(_id, params) {
|
|
121
|
-
const
|
|
120
|
+
async execute(_id, params, ctx: any) {
|
|
121
|
+
const accountId = params.accountId || ctx?.metadata?.accountId || ctx?.accountId || 'default';
|
|
122
|
+
const robot = instances.get(accountId) || instances.values().next().value;
|
|
122
123
|
if (!robot || robot.connectionStatus !== 'connected') {
|
|
123
124
|
return {
|
|
124
125
|
content: [{ type: 'text', text: 'Robot not connected' }],
|
|
@@ -150,7 +151,7 @@ const register = (api: PierPluginApi) => {
|
|
|
150
151
|
required: ['jobId', 'text']
|
|
151
152
|
},
|
|
152
153
|
async execute(_id, params, ctx: any) {
|
|
153
|
-
const accountId = params.accountId || 'default';
|
|
154
|
+
const accountId = params.accountId || ctx?.metadata?.accountId || ctx?.accountId || 'default';
|
|
154
155
|
const robot = instances.get(accountId) || instances.values().next().value;
|
|
155
156
|
if (!robot || robot.connectionStatus !== 'connected') {
|
|
156
157
|
return { content: [{ type: 'text', text: 'Error: Robot not connected' }], details: {} };
|
|
@@ -206,8 +207,8 @@ const register = (api: PierPluginApi) => {
|
|
|
206
207
|
},
|
|
207
208
|
required: ['jobId', ...Object.keys(extraParams)]
|
|
208
209
|
},
|
|
209
|
-
async execute(_id, params) {
|
|
210
|
-
const accountId = params.accountId || 'default';
|
|
210
|
+
async execute(_id, params, ctx: any) {
|
|
211
|
+
const accountId = params.accountId || ctx?.metadata?.accountId || ctx?.accountId || 'default';
|
|
211
212
|
const robot = instances.get(accountId) || instances.values().next().value;
|
|
212
213
|
if (!robot || robot.connectionStatus !== 'connected') {
|
|
213
214
|
return { content: [{ type: 'text', text: 'Error: Robot not connected' }], details: {} };
|
|
@@ -265,8 +266,9 @@ const register = (api: PierPluginApi) => {
|
|
|
265
266
|
type: 'object',
|
|
266
267
|
properties: { accountId: { type: 'string' } }
|
|
267
268
|
},
|
|
268
|
-
async execute(_id, params) {
|
|
269
|
-
const
|
|
269
|
+
async execute(_id, params, ctx: any) {
|
|
270
|
+
const accountId = params.accountId || ctx?.metadata?.accountId || ctx?.accountId || 'default';
|
|
271
|
+
const robot = instances.get(accountId) || instances.values().next().value;
|
|
270
272
|
if (!robot) return { content: [{ type: 'text', text: 'Error: Robot not found' }], details: {} };
|
|
271
273
|
try {
|
|
272
274
|
const profile = await robot.client.getUserProfile(robot.config.secretKey);
|