refactor: reuse streaming text normalizer across callbacks
This commit is contained in:
@@ -549,8 +549,8 @@ export async function runReplyAgent(params: {
|
|||||||
);
|
);
|
||||||
const normalizeStreamingText = (
|
const normalizeStreamingText = (
|
||||||
payload: ReplyPayload,
|
payload: ReplyPayload,
|
||||||
): string | undefined => {
|
): { text?: string; skip: boolean } => {
|
||||||
if (!allowPartialStream) return undefined;
|
if (!allowPartialStream) return { skip: true };
|
||||||
let text = payload.text;
|
let text = payload.text;
|
||||||
if (!isHeartbeat && text?.includes("HEARTBEAT_OK")) {
|
if (!isHeartbeat && text?.includes("HEARTBEAT_OK")) {
|
||||||
const stripped = stripHeartbeatToken(text, {
|
const stripped = stripHeartbeatToken(text, {
|
||||||
@@ -561,18 +561,18 @@ export async function runReplyAgent(params: {
|
|||||||
logVerbose("Stripped stray HEARTBEAT_OK token from reply");
|
logVerbose("Stripped stray HEARTBEAT_OK token from reply");
|
||||||
}
|
}
|
||||||
if (stripped.shouldSkip && (payload.mediaUrls?.length ?? 0) === 0) {
|
if (stripped.shouldSkip && (payload.mediaUrls?.length ?? 0) === 0) {
|
||||||
return undefined;
|
return { skip: true };
|
||||||
}
|
}
|
||||||
text = stripped.text;
|
text = stripped.text;
|
||||||
}
|
}
|
||||||
if (isSilentReplyText(text, SILENT_REPLY_TOKEN)) return undefined;
|
if (isSilentReplyText(text, SILENT_REPLY_TOKEN)) return { skip: true };
|
||||||
return text;
|
return { text, skip: false };
|
||||||
};
|
};
|
||||||
const handlePartialForTyping = async (
|
const handlePartialForTyping = async (
|
||||||
payload: ReplyPayload,
|
payload: ReplyPayload,
|
||||||
): Promise<string | undefined> => {
|
): Promise<string | undefined> => {
|
||||||
const text = normalizeStreamingText(payload);
|
const { text, skip } = normalizeStreamingText(payload);
|
||||||
if (!text) return undefined;
|
if (skip || !text) return undefined;
|
||||||
await typingSignals.signalTextDelta(text);
|
await typingSignals.signalTextDelta(text);
|
||||||
return text;
|
return text;
|
||||||
};
|
};
|
||||||
@@ -712,21 +712,9 @@ export async function runReplyAgent(params: {
|
|||||||
onBlockReply:
|
onBlockReply:
|
||||||
blockStreamingEnabled && opts?.onBlockReply
|
blockStreamingEnabled && opts?.onBlockReply
|
||||||
? async (payload) => {
|
? async (payload) => {
|
||||||
let text = payload.text;
|
const { text, skip } = normalizeStreamingText(payload);
|
||||||
if (!isHeartbeat && text?.includes("HEARTBEAT_OK")) {
|
const hasMedia = (payload.mediaUrls?.length ?? 0) > 0;
|
||||||
const stripped = stripHeartbeatToken(text, {
|
if (skip && !hasMedia) return;
|
||||||
mode: "message",
|
|
||||||
});
|
|
||||||
if (stripped.didStrip && !didLogHeartbeatStrip) {
|
|
||||||
didLogHeartbeatStrip = true;
|
|
||||||
logVerbose(
|
|
||||||
"Stripped stray HEARTBEAT_OK token from reply",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
const hasMedia = (payload.mediaUrls?.length ?? 0) > 0;
|
|
||||||
if (stripped.shouldSkip && !hasMedia) return;
|
|
||||||
text = stripped.text;
|
|
||||||
}
|
|
||||||
const taggedPayload = applyReplyTagsToPayload(
|
const taggedPayload = applyReplyTagsToPayload(
|
||||||
{
|
{
|
||||||
text,
|
text,
|
||||||
@@ -799,25 +787,8 @@ export async function runReplyAgent(params: {
|
|||||||
// If a tool callback starts typing after the run finalized, we can end up with
|
// If a tool callback starts typing after the run finalized, we can end up with
|
||||||
// a typing loop that never sees a matching markRunComplete(). Track and drain.
|
// a typing loop that never sees a matching markRunComplete(). Track and drain.
|
||||||
const task = (async () => {
|
const task = (async () => {
|
||||||
let text = payload.text;
|
const { text, skip } = normalizeStreamingText(payload);
|
||||||
if (!isHeartbeat && text?.includes("HEARTBEAT_OK")) {
|
if (skip) return;
|
||||||
const stripped = stripHeartbeatToken(text, {
|
|
||||||
mode: "message",
|
|
||||||
});
|
|
||||||
if (stripped.didStrip && !didLogHeartbeatStrip) {
|
|
||||||
didLogHeartbeatStrip = true;
|
|
||||||
logVerbose(
|
|
||||||
"Stripped stray HEARTBEAT_OK token from reply",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if (
|
|
||||||
stripped.shouldSkip &&
|
|
||||||
(payload.mediaUrls?.length ?? 0) === 0
|
|
||||||
) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
text = stripped.text;
|
|
||||||
}
|
|
||||||
await typingSignals.signalTextDelta(text);
|
await typingSignals.signalTextDelta(text);
|
||||||
await opts.onToolResult?.({
|
await opts.onToolResult?.({
|
||||||
text,
|
text,
|
||||||
|
|||||||
Reference in New Issue
Block a user