mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-12 01:31:08 +00:00
* feat(agent): add /btw side questions * fix(agent): gate and log /btw reviews * feat(btw): isolate side-question delivery * test(reply): update route reply runtime mocks * fix(btw): complete side-result delivery across clients * fix(gateway): handle streamed btw side results * fix(telegram): unblock btw side questions * fix(reply): make external btw replies explicit * fix(chat): keep btw side results ephemeral in internal history * fix(btw): address remaining review feedback * fix(chat): preserve btw history on mobile refresh * fix(acp): keep btw replies out of prompt history * refactor(btw): narrow side questions to live channels * fix(btw): preserve channel typing indicators * fix(btw): keep side questions isolated in chat * fix(outbound): restore typed channel send deps * fix(btw): avoid blocking replies on transcript persistence * fix(btw): keep side questions fast * docs(commands): document btw slash command * docs(changelog): add btw side questions entry * test(outbound): align session transcript mocks
81 lines
2.3 KiB
TypeScript
81 lines
2.3 KiB
TypeScript
import { runBtwSideQuestion } from "../../agents/btw.js";
|
|
import { extractBtwQuestion } from "./btw-command.js";
|
|
import { rejectUnauthorizedCommand } from "./command-gates.js";
|
|
import type { CommandHandler } from "./commands-types.js";
|
|
|
|
const BTW_USAGE = "Usage: /btw <side question>";
|
|
|
|
export const handleBtwCommand: CommandHandler = async (params, allowTextCommands) => {
|
|
if (!allowTextCommands) {
|
|
return null;
|
|
}
|
|
const question = extractBtwQuestion(params.command.commandBodyNormalized);
|
|
if (question === null) {
|
|
return null;
|
|
}
|
|
const unauthorized = rejectUnauthorizedCommand(params, "/btw");
|
|
if (unauthorized) {
|
|
return unauthorized;
|
|
}
|
|
|
|
if (!question) {
|
|
return {
|
|
shouldContinue: false,
|
|
reply: { text: BTW_USAGE },
|
|
};
|
|
}
|
|
|
|
if (!params.sessionEntry?.sessionId) {
|
|
return {
|
|
shouldContinue: false,
|
|
reply: { text: "⚠️ /btw requires an active session with existing context." },
|
|
};
|
|
}
|
|
|
|
if (!params.agentDir) {
|
|
return {
|
|
shouldContinue: false,
|
|
reply: {
|
|
text: "⚠️ /btw is unavailable because the active agent directory could not be resolved.",
|
|
},
|
|
};
|
|
}
|
|
|
|
try {
|
|
await params.typing?.startTypingLoop();
|
|
const reply = await runBtwSideQuestion({
|
|
cfg: params.cfg,
|
|
agentDir: params.agentDir,
|
|
provider: params.provider,
|
|
model: params.model,
|
|
question,
|
|
sessionEntry: params.sessionEntry,
|
|
sessionStore: params.sessionStore,
|
|
sessionKey: params.sessionKey,
|
|
storePath: params.storePath,
|
|
// BTW is intentionally a quick side question, so do not inherit slower
|
|
// session-level think/reasoning settings from the main run.
|
|
resolvedThinkLevel: "off",
|
|
resolvedReasoningLevel: "off",
|
|
blockReplyChunking: params.blockReplyChunking,
|
|
resolvedBlockStreamingBreak: params.resolvedBlockStreamingBreak,
|
|
opts: params.opts,
|
|
isNewSession: false,
|
|
});
|
|
return {
|
|
shouldContinue: false,
|
|
reply: reply ? { ...reply, btw: { question } } : reply,
|
|
};
|
|
} catch (error) {
|
|
const message = error instanceof Error ? error.message.trim() : "";
|
|
return {
|
|
shouldContinue: false,
|
|
reply: {
|
|
text: `⚠️ /btw failed${message ? `: ${message}` : "."}`,
|
|
btw: { question },
|
|
isError: true,
|
|
},
|
|
};
|
|
}
|
|
};
|