fix: route subagent transcripts and keep tool action enums (#708) (thanks @xMikeMickelson)

This commit is contained in:
Peter Steinberger
2026-01-11 11:19:38 +00:00
parent dc3c733612
commit 6b46217d19
4 changed files with 42 additions and 5 deletions

View File

@@ -10,6 +10,8 @@
### Fixes
- CLI/Update: preserve base environment when passing overrides to update subprocesses. (#713) — thanks @danielz1z.
- Agents: treat message tool errors as failures so fallback replies still send; require `to` + `message` for `action=send`. (#717) — thanks @theglove44.
- Agents: route subagent transcripts to the target agent sessions directory and add regression coverage. (#708) — thanks @xMikeMickelson.
- Agents/Tools: preserve action enums when flattening tool schemas. (#708) — thanks @xMikeMickelson.
## 2026.1.10

View File

@@ -127,6 +127,18 @@ function extractEnumValues(schema: unknown): unknown[] | undefined {
const record = schema as Record<string, unknown>;
if (Array.isArray(record.enum)) return record.enum;
if ("const" in record) return [record.const];
const variants = Array.isArray(record.anyOf)
? record.anyOf
: Array.isArray(record.oneOf)
? record.oneOf
: null;
if (variants) {
const values = variants.flatMap((variant) => {
const extracted = extractEnumValues(variant);
return extracted ?? [];
});
return values.length > 0 ? values : undefined;
}
return undefined;
}

View File

@@ -62,7 +62,6 @@ const AllMessageActions = [
"ban",
];
const MessageToolCommonSchema = {
provider: Type.Optional(Type.String()),
media: Type.Optional(Type.String()),
@@ -379,8 +378,7 @@ export function createMessageTool(options?: MessageToolOptions): AnyAgentTool {
const mediaUrl =
readStringParam(params, "media", { trim: false }) ??
(parsed.mediaUrls?.[0] || parsed.mediaUrl);
const replyTo =
readStringParam(params, "replyTo") ?? parsed.replyToId;
const replyTo = readStringParam(params, "replyTo") ?? parsed.replyToId;
const threadId = readStringParam(params, "threadId");
const buttons = params.buttons;
const gifPlayback =
@@ -844,8 +842,7 @@ export function createMessageTool(options?: MessageToolOptions): AnyAgentTool {
const mediaUrl =
readStringParam(params, "media", { trim: false }) ??
(parsed.mediaUrls?.[0] || parsed.mediaUrl);
const replyTo =
readStringParam(params, "replyTo") ?? parsed.replyToId;
const replyTo = readStringParam(params, "replyTo") ?? parsed.replyToId;
return await handleDiscordAction(
{
action: "threadReply",

View File

@@ -7,6 +7,7 @@ import {
buildGroupDisplayName,
deriveSessionKey,
loadSessionStore,
resolveSessionFilePath,
resolveSessionKey,
resolveSessionTranscriptPath,
resolveSessionTranscriptsDir,
@@ -189,6 +190,31 @@ describe("sessions", () => {
}
});
it("uses agent id when resolving session file fallback paths", () => {
const prev = process.env.CLAWDBOT_STATE_DIR;
process.env.CLAWDBOT_STATE_DIR = "/custom/state";
try {
const sessionFile = resolveSessionFilePath("sess-2", undefined, {
agentId: "codex",
});
expect(sessionFile).toBe(
path.join(
path.resolve("/custom/state"),
"agents",
"codex",
"sessions",
"sess-2.jsonl",
),
);
} finally {
if (prev === undefined) {
delete process.env.CLAWDBOT_STATE_DIR;
} else {
process.env.CLAWDBOT_STATE_DIR = prev;
}
}
});
it("updateSessionStoreEntry merges concurrent patches", async () => {
const mainSessionKey = "agent:main:main";
const dir = await fs.mkdtemp(path.join(os.tmpdir(), "clawdbot-sessions-"));