Merge 5b149501537151fd1234e7a0324e847508a5968d into d78e13f545136fcbba1feceecc5e0485a06c33a6
This commit is contained in:
commit
aa2d35c207
@ -1262,6 +1262,7 @@ export async function runSubagentAnnounceFlow(params: {
|
||||
wakeOnDescendantSettle?: boolean;
|
||||
signal?: AbortSignal;
|
||||
bestEffortDeliver?: boolean;
|
||||
maxAnnounceChars?: number;
|
||||
}): Promise<boolean> {
|
||||
let didAnnounce = false;
|
||||
const expectsCompletionMessage = params.expectsCompletionMessage === true;
|
||||
@ -1488,6 +1489,16 @@ export async function runSubagentAnnounceFlow(params: {
|
||||
startedAt: params.startedAt,
|
||||
endedAt: params.endedAt,
|
||||
});
|
||||
|
||||
// Apply maxAnnounceChars truncation if specified
|
||||
const TRUNCATION_MARKER = "\n\n[truncated — full output in transcript]";
|
||||
const truncatedFindings =
|
||||
typeof params.maxAnnounceChars === "number" &&
|
||||
params.maxAnnounceChars >= 1 &&
|
||||
findings.length > params.maxAnnounceChars
|
||||
? findings.slice(0, params.maxAnnounceChars - TRUNCATION_MARKER.length) + TRUNCATION_MARKER
|
||||
: findings;
|
||||
|
||||
const internalEvents: AgentInternalEvent[] = [
|
||||
{
|
||||
type: "task_completion",
|
||||
@ -1498,7 +1509,7 @@ export async function runSubagentAnnounceFlow(params: {
|
||||
taskLabel,
|
||||
status: outcome.status,
|
||||
statusLabel,
|
||||
result: findings,
|
||||
result: truncatedFindings,
|
||||
statsLine,
|
||||
replyInstruction,
|
||||
},
|
||||
|
||||
@ -666,6 +666,7 @@ function startSubagentAnnounceCleanupFlow(runId: string, entry: SubagentRunRecor
|
||||
spawnMode: entry.spawnMode,
|
||||
expectsCompletionMessage: entry.expectsCompletionMessage,
|
||||
wakeOnDescendantSettle: entry.wakeOnDescendantSettle === true,
|
||||
maxAnnounceChars: entry.maxAnnounceChars,
|
||||
})
|
||||
.then((didAnnounce) => {
|
||||
finalizeAnnounceCleanup(didAnnounce);
|
||||
@ -1349,6 +1350,7 @@ export function registerSubagentRun(params: {
|
||||
runTimeoutSeconds?: number;
|
||||
expectsCompletionMessage?: boolean;
|
||||
spawnMode?: "run" | "session";
|
||||
maxAnnounceChars?: number;
|
||||
attachmentsDir?: string;
|
||||
attachmentsRootDir?: string;
|
||||
retainAttachmentsOnKeep?: boolean;
|
||||
@ -1388,6 +1390,10 @@ export function registerSubagentRun(params: {
|
||||
archiveAtMs,
|
||||
cleanupHandled: false,
|
||||
wakeOnDescendantSettle: undefined,
|
||||
maxAnnounceChars:
|
||||
typeof params.maxAnnounceChars === "number" && Number.isFinite(params.maxAnnounceChars)
|
||||
? Math.max(1, Math.floor(params.maxAnnounceChars))
|
||||
: undefined,
|
||||
attachmentsDir: params.attachmentsDir,
|
||||
attachmentsRootDir: params.attachmentsRootDir,
|
||||
retainAttachmentsOnKeep: params.retainAttachmentsOnKeep,
|
||||
|
||||
@ -60,4 +60,6 @@ export type SubagentRunRecord = {
|
||||
attachmentsDir?: string;
|
||||
attachmentsRootDir?: string;
|
||||
retainAttachmentsOnKeep?: boolean;
|
||||
/** Maximum character limit for announce message delivery (truncates with marker if exceeded). */
|
||||
maxAnnounceChars?: number;
|
||||
};
|
||||
|
||||
@ -62,6 +62,7 @@ export type SpawnSubagentParams = {
|
||||
cleanup?: "delete" | "keep";
|
||||
sandbox?: SpawnSubagentSandboxMode;
|
||||
expectsCompletionMessage?: boolean;
|
||||
maxAnnounceChars?: number;
|
||||
attachments?: Array<{
|
||||
name: string;
|
||||
content: string;
|
||||
@ -753,6 +754,7 @@ export async function spawnSubagentDirect(
|
||||
runTimeoutSeconds,
|
||||
expectsCompletionMessage,
|
||||
spawnMode,
|
||||
maxAnnounceChars: params.maxAnnounceChars,
|
||||
attachmentsDir: attachmentAbsDir,
|
||||
attachmentsRootDir: attachmentRootDir,
|
||||
retainAttachmentsOnKeep: retainOnSessionKeep,
|
||||
|
||||
@ -63,6 +63,13 @@ const SessionsSpawnToolSchema = Type.Object({
|
||||
mountPath: Type.Optional(Type.String()),
|
||||
}),
|
||||
),
|
||||
maxAnnounceChars: Type.Optional(
|
||||
Type.Number({
|
||||
minimum: 1,
|
||||
description:
|
||||
"Maximum character limit for the sub-agent completion announce message. If exceeded, the message is truncated with a marker.",
|
||||
}),
|
||||
),
|
||||
});
|
||||
|
||||
export function createSessionsSpawnTool(
|
||||
@ -81,7 +88,7 @@ export function createSessionsSpawnTool(
|
||||
label: "Sessions",
|
||||
name: "sessions_spawn",
|
||||
description:
|
||||
'Spawn an isolated session (runtime="subagent" or runtime="acp"). mode="run" is one-shot and mode="session" is persistent/thread-bound. Subagents inherit the parent workspace directory automatically.',
|
||||
'Spawn an isolated session (runtime="subagent" or runtime="acp"). mode="run" is one-shot and mode="session" is persistent/thread-bound. Subagents inherit the parent workspace directory automatically. Use maxAnnounceChars to limit completion message length for platforms with character limits (e.g., Telegram 4096 chars).',
|
||||
parameters: SessionsSpawnToolSchema,
|
||||
execute: async (_toolCallId, args) => {
|
||||
const params = args as Record<string, unknown>;
|
||||
@ -118,6 +125,10 @@ export function createSessionsSpawnTool(
|
||||
? Math.max(0, Math.floor(timeoutSecondsCandidate))
|
||||
: undefined;
|
||||
const thread = params.thread === true;
|
||||
const maxAnnounceCharsCandidate =
|
||||
typeof params.maxAnnounceChars === "number" && Number.isFinite(params.maxAnnounceChars)
|
||||
? Math.max(1, Math.floor(params.maxAnnounceChars))
|
||||
: undefined;
|
||||
const attachments = Array.isArray(params.attachments)
|
||||
? (params.attachments as Array<{
|
||||
name: string;
|
||||
@ -186,6 +197,7 @@ export function createSessionsSpawnTool(
|
||||
cleanup,
|
||||
sandbox,
|
||||
expectsCompletionMessage: true,
|
||||
maxAnnounceChars: maxAnnounceCharsCandidate,
|
||||
attachments,
|
||||
attachMountPath:
|
||||
params.attachAs && typeof params.attachAs === "object"
|
||||
|
||||
@ -314,7 +314,7 @@ export async function tryDispatchAcpReply(params: {
|
||||
await projector.flush(true);
|
||||
const ttsMode = resolveTtsConfig(params.cfg).mode ?? "final";
|
||||
const accumulatedBlockText = delivery.getAccumulatedBlockText();
|
||||
if (ttsMode === "final" && delivery.getBlockCount() > 0 && accumulatedBlockText.trim()) {
|
||||
if (ttsMode === "final" && accumulatedBlockText.trim()) {
|
||||
try {
|
||||
const ttsSyntheticReply = await maybeApplyTtsToPayload({
|
||||
payload: { text: accumulatedBlockText },
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user