Auto-reply: add verbose session hint
This commit is contained in:
@@ -489,11 +489,11 @@ export async function getReplyFromConfig(
|
|||||||
|
|
||||||
const isHeartbeat = opts?.isHeartbeat === true;
|
const isHeartbeat = opts?.isHeartbeat === true;
|
||||||
|
|
||||||
if (reply && reply.mode === "command") {
|
if (reply && reply.mode === "command") {
|
||||||
const heartbeatCommand = isHeartbeat
|
const heartbeatCommand = isHeartbeat
|
||||||
? (reply as { heartbeatCommand?: string[] }).heartbeatCommand
|
? (reply as { heartbeatCommand?: string[] }).heartbeatCommand
|
||||||
: undefined;
|
: undefined;
|
||||||
const commandArgs = heartbeatCommand?.length
|
const commandArgs = heartbeatCommand?.length
|
||||||
? heartbeatCommand
|
? heartbeatCommand
|
||||||
: reply.command;
|
: reply.command;
|
||||||
|
|
||||||
@@ -502,38 +502,34 @@ export async function getReplyFromConfig(
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
await onReplyStart();
|
await onReplyStart();
|
||||||
const commandReply = {
|
const commandReply = {
|
||||||
...reply,
|
...reply,
|
||||||
command: commandArgs,
|
command: commandArgs,
|
||||||
mode: "command" as const,
|
mode: "command" as const,
|
||||||
};
|
};
|
||||||
try {
|
try {
|
||||||
const runResult = await runCommandReply({
|
const runResult = await runCommandReply({
|
||||||
reply: commandReply,
|
reply: commandReply,
|
||||||
templatingCtx,
|
templatingCtx,
|
||||||
sendSystemOnce,
|
sendSystemOnce,
|
||||||
isNewSession,
|
isNewSession,
|
||||||
isFirstTurnInSession,
|
isFirstTurnInSession,
|
||||||
systemSent,
|
systemSent,
|
||||||
timeoutMs,
|
timeoutMs,
|
||||||
timeoutSeconds,
|
timeoutSeconds,
|
||||||
commandRunner,
|
commandRunner,
|
||||||
thinkLevel: resolvedThinkLevel,
|
thinkLevel: resolvedThinkLevel,
|
||||||
verboseLevel: resolvedVerboseLevel,
|
verboseLevel: resolvedVerboseLevel,
|
||||||
});
|
});
|
||||||
const payloadArray = runResult.payloads ?? [];
|
const payloadArray = runResult.payloads ?? [];
|
||||||
const meta = runResult.meta;
|
const meta = runResult.meta;
|
||||||
const normalizedPayloads =
|
let finalPayloads = payloadArray;
|
||||||
payloadArray.length === 1 ? payloadArray[0] : payloadArray;
|
if (!finalPayloads || finalPayloads.length === 0) {
|
||||||
if (
|
return undefined;
|
||||||
!normalizedPayloads ||
|
}
|
||||||
(Array.isArray(normalizedPayloads) && normalizedPayloads.length === 0)
|
if (sessionCfg && sessionStore && sessionKey) {
|
||||||
) {
|
const returnedSessionId = meta.agentMeta?.sessionId;
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
if (sessionCfg && sessionStore && sessionKey) {
|
|
||||||
const returnedSessionId = meta.agentMeta?.sessionId;
|
|
||||||
if (returnedSessionId && returnedSessionId !== sessionId) {
|
if (returnedSessionId && returnedSessionId !== sessionId) {
|
||||||
const entry = sessionEntry ??
|
const entry = sessionEntry ??
|
||||||
sessionStore[sessionKey] ?? {
|
sessionStore[sessionKey] ?? {
|
||||||
@@ -557,14 +553,28 @@ export async function getReplyFromConfig(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (meta.agentMeta && isVerbose()) {
|
if (meta.agentMeta && isVerbose()) {
|
||||||
logVerbose(`Agent meta: ${JSON.stringify(meta.agentMeta)}`);
|
logVerbose(`Agent meta: ${JSON.stringify(meta.agentMeta)}`);
|
||||||
}
|
}
|
||||||
return normalizedPayloads;
|
// If verbose is enabled and this is a new session, prepend a session hint.
|
||||||
} finally {
|
const sessionIdHint =
|
||||||
cleanupTyping();
|
resolvedVerboseLevel === "on" && isNewSession
|
||||||
}
|
? sessionId ??
|
||||||
}
|
meta.agentMeta?.sessionId ??
|
||||||
|
templatingCtx.SessionId ??
|
||||||
|
"unknown"
|
||||||
|
: undefined;
|
||||||
|
if (sessionIdHint) {
|
||||||
|
finalPayloads = [
|
||||||
|
{ text: `🧭 New session: ${sessionIdHint}` },
|
||||||
|
...payloadArray,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return finalPayloads.length === 1 ? finalPayloads[0] : finalPayloads;
|
||||||
|
} finally {
|
||||||
|
cleanupTyping();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cleanupTyping();
|
cleanupTyping();
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|||||||
@@ -750,6 +750,42 @@ describe("config and templating", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("prepends session hint when new session and verbose on", async () => {
|
||||||
|
const runSpy = vi.spyOn(index, "runCommandWithTimeout").mockResolvedValue({
|
||||||
|
stdout: "ok",
|
||||||
|
stderr: "",
|
||||||
|
code: 0,
|
||||||
|
signal: null,
|
||||||
|
killed: false,
|
||||||
|
});
|
||||||
|
vi.spyOn(crypto, "randomUUID").mockReturnValue("sess-uuid");
|
||||||
|
const storeDir = await fs.promises.mkdtemp(
|
||||||
|
path.join(os.tmpdir(), "warelay-session-"),
|
||||||
|
);
|
||||||
|
const storePath = path.join(storeDir, "sessions.json");
|
||||||
|
const cfg = {
|
||||||
|
inbound: {
|
||||||
|
reply: {
|
||||||
|
mode: "command" as const,
|
||||||
|
command: ["echo", "{{Body}}"],
|
||||||
|
agent: { kind: "claude" },
|
||||||
|
session: { store: storePath },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await index.getReplyFromConfig(
|
||||||
|
{ Body: "/new /v on hi", From: "+1", To: "+2" },
|
||||||
|
undefined,
|
||||||
|
cfg,
|
||||||
|
runSpy,
|
||||||
|
);
|
||||||
|
|
||||||
|
const payloads = Array.isArray(res) ? res : res ? [res] : [];
|
||||||
|
expect(payloads[0]?.text).toBe("🧭 New session: sess-uuid");
|
||||||
|
expect(payloads[1]?.text).toBe("ok");
|
||||||
|
});
|
||||||
|
|
||||||
it("treats directive-only even when bracket prefixes are present", async () => {
|
it("treats directive-only even when bracket prefixes are present", async () => {
|
||||||
const runSpy = vi.spyOn(index, "runCommandWithTimeout").mockResolvedValue({
|
const runSpy = vi.spyOn(index, "runCommandWithTimeout").mockResolvedValue({
|
||||||
stdout: "ok",
|
stdout: "ok",
|
||||||
|
|||||||
Reference in New Issue
Block a user