@gholl-studio/pier-connector 0.3.22 → 0.3.24
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 +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.3.
|
|
4
|
+
"version": "0.3.24",
|
|
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
|
@@ -22,14 +22,10 @@ export async function handleInbound(
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
// 1. Resolve Account-Scoped Configuration
|
|
25
|
+
// 使用原始完整配置,不覆盖 channels.pier,确保 bindings 和 defaultAgent 完整可用。
|
|
26
|
+
// resolveAgentRoute 需要完整配置中的 bindings 才能正确匹配 channel+accountId 路由规则。
|
|
25
27
|
const rootConfig = ctx.cfg || {};
|
|
26
|
-
const accountScopedCfg =
|
|
27
|
-
...rootConfig,
|
|
28
|
-
channels: {
|
|
29
|
-
...rootConfig.channels,
|
|
30
|
-
pier: robot.config
|
|
31
|
-
}
|
|
32
|
-
};
|
|
28
|
+
const accountScopedCfg = rootConfig;
|
|
33
29
|
|
|
34
30
|
// 2. Resolve Agent Route
|
|
35
31
|
const route = channelRuntime.routing.resolveAgentRoute({
|
|
@@ -44,7 +40,10 @@ export async function handleInbound(
|
|
|
44
40
|
|
|
45
41
|
logger.info(`[pier-connector] Routing account '${robot.accountId}' -> agent '${finalAgentId}' (Source: ${routingSource})`);
|
|
46
42
|
|
|
47
|
-
|
|
43
|
+
// route.sessionKey 由 resolveAgentRoute 生成,格式为 agent/{agentId}/...,
|
|
44
|
+
// SDK 通过解析此 key 来确定使用哪个 agent。
|
|
45
|
+
// 若使用自定义字符串(如 pier-job-${jobId}),SDK 无法解析 agentId,会回落到默认 main agent。
|
|
46
|
+
const dynamicSessionKey = route.sessionKey;
|
|
48
47
|
const metadata = robot.activeNodeJobs.get(jobId);
|
|
49
48
|
let injectedPrompt = "";
|
|
50
49
|
|
|
@@ -79,7 +78,7 @@ export async function handleInbound(
|
|
|
79
78
|
RawBody: inbound.body,
|
|
80
79
|
From: inbound.senderId,
|
|
81
80
|
To: `chat:${jobId}`,
|
|
82
|
-
SessionKey:
|
|
81
|
+
SessionKey: route.sessionKey,
|
|
83
82
|
AccountId: robot.accountId,
|
|
84
83
|
ChatType: 'direct',
|
|
85
84
|
SenderId: inbound.senderId,
|
|
@@ -103,7 +102,10 @@ export async function handleInbound(
|
|
|
103
102
|
});
|
|
104
103
|
|
|
105
104
|
// 4. Create Dispatcher
|
|
106
|
-
|
|
105
|
+
// 必须从 createReplyDispatcherWithTyping 获取 replyOptions,
|
|
106
|
+
// 它包含 SDK 内部生命周期钉子(onReplyStart / onTypingController / onTypingCleanup),
|
|
107
|
+
// 必须传入 dispatchReplyFromConfig 才能正确启动和终止 typing controller。
|
|
108
|
+
const { dispatcher, replyOptions, markDispatchIdle, markRunComplete } = channelRuntime.reply.createReplyDispatcherWithTyping({
|
|
107
109
|
deliver: async (payload: any, info: any) => {
|
|
108
110
|
const currentMeta = robot.activeNodeJobs.get(jobId);
|
|
109
111
|
const resAgent = payload.agentId || finalAgentId;
|
|
@@ -140,19 +142,32 @@ export async function handleInbound(
|
|
|
140
142
|
|
|
141
143
|
// 6. Dispatch
|
|
142
144
|
try {
|
|
143
|
-
await channelRuntime.reply.dispatchReplyFromConfig({
|
|
145
|
+
const { queuedFinal, counts } = await channelRuntime.reply.dispatchReplyFromConfig({
|
|
144
146
|
ctx: ctxPayload,
|
|
145
147
|
cfg: accountScopedCfg,
|
|
146
148
|
dispatcher,
|
|
147
149
|
replyOptions: {
|
|
150
|
+
// 必须展开 replyOptions,否则 typing controller 永远不会被启动/停止
|
|
151
|
+
// 上一条消息的会话状态就会游跍,导致 SDK 拒绝处理下一条消息
|
|
152
|
+
...replyOptions,
|
|
148
153
|
onModelSelected: (mCtx: any) => {
|
|
149
154
|
logger.info(`[pier-connector:debug] Model selected for ${jobId}: ${mCtx.provider}/${mCtx.model}`);
|
|
150
155
|
}
|
|
151
156
|
}
|
|
152
157
|
});
|
|
158
|
+
|
|
159
|
+
// 等待所有已入队的 deliver() 调用完成(参照飞书插件 dispatch.ts L128)
|
|
160
|
+
// 不调用此方法, dispatchReplyFromConfig 可能在 deliver 永远未执行的情况下返回
|
|
161
|
+
await dispatcher.waitForIdle();
|
|
162
|
+
|
|
163
|
+
logger.info(`[pier-connector] Dispatch complete for ${jobId}. queuedFinal=${queuedFinal}, counts=${JSON.stringify(counts)}`);
|
|
153
164
|
} catch (err: any) {
|
|
154
165
|
logger.error(`[pier-connector] ✖ Dispatch error for job ${jobId}: ${err.message}`);
|
|
155
166
|
} finally {
|
|
167
|
+
// markRunComplete 通知 typing controller 运行已结束。
|
|
168
|
+
// markDispatchIdle 通知 dispatcher 空闲。
|
|
169
|
+
// 必须在 finally 块不调用不等待下一条消息。
|
|
170
|
+
markRunComplete?.();
|
|
156
171
|
markDispatchIdle?.();
|
|
157
172
|
}
|
|
158
173
|
}
|