@ozaiya/openclaw-channel 0.10.35 → 0.10.36
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/dist/src/channel.js
CHANGED
|
@@ -117,6 +117,7 @@ function buildTaskProgressContent(dispatch, completed) {
|
|
|
117
117
|
completedAt: s.completedAt,
|
|
118
118
|
})),
|
|
119
119
|
completed,
|
|
120
|
+
stopped: dispatch.stopped,
|
|
120
121
|
plan: dispatch.plan,
|
|
121
122
|
deliverables: dispatch.deliverables,
|
|
122
123
|
live: !completed,
|
|
@@ -1487,20 +1488,24 @@ function buildChannelTools(account, cfg) {
|
|
|
1487
1488
|
createHangUpCallTool(account),
|
|
1488
1489
|
createStartInAppCallTool(account, cfg),
|
|
1489
1490
|
];
|
|
1490
|
-
|
|
1491
|
+
// A bot hosted on Ozaiya pays per addon, so its addon-backed tools appear only once the
|
|
1492
|
+
// addon is on; a self-hosted gateway keeps every tool its own config enables.
|
|
1493
|
+
const addonOn = (key) => !account.hosted || !!account.addons?.[key];
|
|
1494
|
+
const imageTool = addonOn("image_gen") ? createGenerateImageTool(account, cfg, resolveForGroup) : null;
|
|
1491
1495
|
if (imageTool)
|
|
1492
1496
|
tools.push(imageTool);
|
|
1493
|
-
|
|
1494
|
-
|
|
1497
|
+
if (addonOn("wechat"))
|
|
1498
|
+
tools.push(createDesktopTool());
|
|
1499
|
+
const xueqiuTool = addonOn("xueqiu") ? createFetchXueqiuTool(cfg) : null;
|
|
1495
1500
|
if (xueqiuTool)
|
|
1496
1501
|
tools.push(xueqiuTool);
|
|
1497
|
-
const xueqiuSearchTool = createSearchXueqiuTool(cfg);
|
|
1502
|
+
const xueqiuSearchTool = addonOn("xueqiu") ? createSearchXueqiuTool(cfg) : null;
|
|
1498
1503
|
if (xueqiuSearchTool)
|
|
1499
1504
|
tools.push(xueqiuSearchTool);
|
|
1500
|
-
const scrapeTool = createScrapeSocialMediaTool(cfg);
|
|
1505
|
+
const scrapeTool = addonOn("social_media") ? createScrapeSocialMediaTool(cfg) : null;
|
|
1501
1506
|
if (scrapeTool)
|
|
1502
1507
|
tools.push(scrapeTool);
|
|
1503
|
-
const summarizeTool = createSummarizeUrlTool(cfg);
|
|
1508
|
+
const summarizeTool = addonOn("web_research") ? createSummarizeUrlTool(cfg) : null;
|
|
1504
1509
|
if (summarizeTool)
|
|
1505
1510
|
tools.push(summarizeTool);
|
|
1506
1511
|
// Plan tool: lets the agent declare + maintain a high-level task plan that the
|
|
@@ -3406,6 +3411,7 @@ async function handlePhoneAutoTranscript(text, session, account, cfg, groupId) {
|
|
|
3406
3411
|
const bodyForAgent = `${voicePrompt}\n\n${text}`;
|
|
3407
3412
|
const body = `[ozaiya] from: phone caller | at: ${new Date().toISOString()}\n---\n${text}`;
|
|
3408
3413
|
const msgCtx = ch.reply.finalizeInboundContext({
|
|
3414
|
+
GroupSystemPrompt: account.persona,
|
|
3409
3415
|
Body: body,
|
|
3410
3416
|
BodyForAgent: bodyForAgent,
|
|
3411
3417
|
RawBody: text,
|
|
@@ -3819,6 +3825,7 @@ ctx) {
|
|
|
3819
3825
|
});
|
|
3820
3826
|
// Build finalized context for dispatch
|
|
3821
3827
|
const msgCtx = ch.reply.finalizeInboundContext({
|
|
3828
|
+
GroupSystemPrompt: account.persona,
|
|
3822
3829
|
Body: body,
|
|
3823
3830
|
BodyForAgent: effectiveAgentInput,
|
|
3824
3831
|
RawBody: agentInput,
|
|
@@ -3880,6 +3887,7 @@ ctx) {
|
|
|
3880
3887
|
agentId: route.agentId,
|
|
3881
3888
|
title: deriveTaskTitle(effectiveMessageText ?? agentInput),
|
|
3882
3889
|
replyTexts: [],
|
|
3890
|
+
abortController: new AbortController(),
|
|
3883
3891
|
};
|
|
3884
3892
|
activeDispatches.set(account.accountId, dispatch);
|
|
3885
3893
|
// Start screen recording for replay (best-effort; null if nothing recordable).
|
|
@@ -4033,9 +4041,23 @@ ctx) {
|
|
|
4033
4041
|
ctx.log?.warn?.(`ozaiya: reply dispatch error: ${String(err)}`);
|
|
4034
4042
|
},
|
|
4035
4043
|
},
|
|
4036
|
-
|
|
4044
|
+
// The abortSignal lets a "stop" callback interrupt the running turn mid-flight.
|
|
4045
|
+
replyOptions: {
|
|
4046
|
+
abortSignal: dispatch.abortController.signal,
|
|
4047
|
+
...(account.model ? { isHeartbeat: true, heartbeatModelOverride: account.model } : {}),
|
|
4048
|
+
},
|
|
4037
4049
|
});
|
|
4038
4050
|
}
|
|
4051
|
+
catch (err) {
|
|
4052
|
+
// A user-initiated stop aborts the running turn — that rejection is expected,
|
|
4053
|
+
// so don't surface it as a dispatch error (the card is finalized as "stopped" below).
|
|
4054
|
+
if (dispatch.stopped || dispatch.abortController.signal.aborted) {
|
|
4055
|
+
ctx.log?.info?.(`ozaiya: task ${dispatch.taskId} stopped by user`);
|
|
4056
|
+
}
|
|
4057
|
+
else {
|
|
4058
|
+
ctx.log?.warn?.(`ozaiya: reply dispatch threw: ${String(err)}`);
|
|
4059
|
+
}
|
|
4060
|
+
}
|
|
4039
4061
|
finally {
|
|
4040
4062
|
// Recover an inline table the model forgot to publish_artifact, BEFORE finalizing
|
|
4041
4063
|
// so the final progress card includes the deliverable.
|
|
@@ -4183,6 +4205,52 @@ ctx) {
|
|
|
4183
4205
|
if (resolved)
|
|
4184
4206
|
return; // intercepted — don't dispatch to agent
|
|
4185
4207
|
}
|
|
4208
|
+
// Intercept task-control callbacks from the chat task card.
|
|
4209
|
+
// oz_stop:<taskId> → abort the running dispatch mid-flight (interrupts the LLM turn)
|
|
4210
|
+
// oz_continue:<taskId> → resume the task with a fresh, fully-tracked dispatch
|
|
4211
|
+
if (callbackData.startsWith("oz_stop:")) {
|
|
4212
|
+
const taskId = callbackData.slice("oz_stop:".length);
|
|
4213
|
+
const dispatch = activeDispatches.get(account.accountId);
|
|
4214
|
+
if (dispatch && dispatch.taskId === taskId && !dispatch.abortController.signal.aborted) {
|
|
4215
|
+
dispatch.stopped = true; // makes finalizeTaskProgress emit a "stopped" card
|
|
4216
|
+
ctx.log?.info?.(`ozaiya: stop requested for task ${taskId} — aborting dispatch`);
|
|
4217
|
+
dispatch.abortController.abort();
|
|
4218
|
+
}
|
|
4219
|
+
else {
|
|
4220
|
+
ctx.log?.info?.(`ozaiya: stop requested for task ${taskId} but no matching live dispatch`);
|
|
4221
|
+
}
|
|
4222
|
+
return; // intercepted — don't dispatch to agent
|
|
4223
|
+
}
|
|
4224
|
+
if (callbackData.startsWith("oz_continue:")) {
|
|
4225
|
+
// Resume by feeding a synthetic "continue" message through the normal inbound
|
|
4226
|
+
// path, so it gets full task-progress tracking + a fresh live card. The agent's
|
|
4227
|
+
// session persists across dispatches, so it picks up with the task's full context.
|
|
4228
|
+
const continueText = "继续之前的任务,从你上次停下的地方接着做。\nContinue the previous task from where you stopped.";
|
|
4229
|
+
try {
|
|
4230
|
+
const groupKey = await getGroupKeyOrThrow(account, groupId);
|
|
4231
|
+
const synthetic = {
|
|
4232
|
+
event: "message.new",
|
|
4233
|
+
groupId,
|
|
4234
|
+
groupType: "group",
|
|
4235
|
+
replyAllowed: true,
|
|
4236
|
+
message: {
|
|
4237
|
+
id: `continue-${Date.now()}`,
|
|
4238
|
+
senderId: from,
|
|
4239
|
+
senderName: from,
|
|
4240
|
+
seq: 0,
|
|
4241
|
+
content: encryptMessage({ text: continueText }, groupKey),
|
|
4242
|
+
replyToId: null,
|
|
4243
|
+
createdAt: Date.now(),
|
|
4244
|
+
},
|
|
4245
|
+
};
|
|
4246
|
+
ctx.log?.info?.(`ozaiya: continue requested for task ${callbackData.slice("oz_continue:".length)} — re-dispatching`);
|
|
4247
|
+
await handleInboundMessage(synthetic, ctx);
|
|
4248
|
+
}
|
|
4249
|
+
catch (err) {
|
|
4250
|
+
ctx.log?.warn?.(`ozaiya: continue dispatch failed: ${String(err)}`);
|
|
4251
|
+
}
|
|
4252
|
+
return; // intercepted — don't run the lightweight callback dispatch
|
|
4253
|
+
}
|
|
4186
4254
|
const runtime = getOzaiyaRuntime();
|
|
4187
4255
|
const ch = runtime.channel;
|
|
4188
4256
|
const { callbackBody, callbackCommand, callbackLabel, callbackOptionIndex } = normalizeCallbackQueryPayload({
|
|
@@ -4225,6 +4293,7 @@ ctx) {
|
|
|
4225
4293
|
body: callbackBody,
|
|
4226
4294
|
});
|
|
4227
4295
|
const msgCtx = ch.reply.finalizeInboundContext({
|
|
4296
|
+
GroupSystemPrompt: account.persona,
|
|
4228
4297
|
Body: body,
|
|
4229
4298
|
BodyForAgent: callbackBody,
|
|
4230
4299
|
RawBody: callbackBody,
|
|
@@ -4401,6 +4470,7 @@ ctx) {
|
|
|
4401
4470
|
body: bodyForAgent,
|
|
4402
4471
|
});
|
|
4403
4472
|
const msgCtx = ch.reply.finalizeInboundContext({
|
|
4473
|
+
GroupSystemPrompt: account.persona,
|
|
4404
4474
|
Body: body,
|
|
4405
4475
|
BodyForAgent: bodyForAgent,
|
|
4406
4476
|
RawBody: text,
|
|
@@ -4485,6 +4555,7 @@ ctx) {
|
|
|
4485
4555
|
body: bodyForAgent,
|
|
4486
4556
|
});
|
|
4487
4557
|
const msgCtx = ch.reply.finalizeInboundContext({
|
|
4558
|
+
GroupSystemPrompt: account.persona,
|
|
4488
4559
|
Body: body,
|
|
4489
4560
|
BodyForAgent: bodyForAgent,
|
|
4490
4561
|
RawBody: lastUserMessage,
|