Files
wehub-resource-sync e30e75b5d4
Changesets / Create Version PR (push) Has been cancelled
Deploy Shadcn Registry / Deploy Production (push) Has been cancelled
Template Metrics / LOC + Bundle Size (push) Has been cancelled
Code Quality / Oxlint + Oxfmt (push) Has been cancelled
Code Quality / Template Sync (push) Has been cancelled
Code Quality / Build Changed Packages (push) Has been cancelled
Code Quality / Test Changed Packages (push) Has been cancelled
Deploy Expo Example / Deploy Production (push) Has been cancelled
Deploy Ink Example / Deploy Production (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-stream, 3.12) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.10) (push) Has been cancelled
Python Tests / pytest (assistant-ui-sync-server-api, 3.12) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:40:13 +08:00

83 lines
2.1 KiB
TypeScript

import { createUIMessageStream, createUIMessageStreamResponse } from "ai";
import type { UIMessage } from "ai";
export type XuluxTurnOutcomeType =
| "assistant_response_completed"
| "budget_denied";
export type XuluxTurnOutcomeSeverity = "info" | "warning" | "error";
export type XuluxTurnOutcome = {
type: XuluxTurnOutcomeType;
status: "completed";
severity: XuluxTurnOutcomeSeverity;
requestId: string;
capturedAt: string;
sessionId?: string;
distinctId?: string;
userMessageId?: string;
code?: string;
statusCode?: number;
userVisibleMessage?: string;
technicalSummary?: string;
};
type CreateXuluxTurnOutcomeOptions = Omit<
XuluxTurnOutcome,
"capturedAt" | "severity" | "status"
> & {
capturedAt?: string;
};
export function createXuluxTurnOutcome({
capturedAt = new Date().toISOString(),
...options
}: CreateXuluxTurnOutcomeOptions): XuluxTurnOutcome {
return {
...options,
status: "completed",
severity:
options.type === "assistant_response_completed" ? "info" : "warning",
capturedAt,
};
}
export function getLatestUserMessageId(
messages: readonly UIMessage[],
): string | undefined {
for (let index = messages.length - 1; index >= 0; index -= 1) {
const message = messages[index];
if (message?.role === "user" && typeof message.id === "string") {
return message.id;
}
}
return undefined;
}
export function createXuluxDiagnosticMessageResponse({
messages,
text,
outcome,
}: {
messages: UIMessage[];
text: string;
outcome: XuluxTurnOutcome;
}): Response {
const textPartId = `text_${outcome.requestId}`;
const stream = createUIMessageStream<UIMessage>({
originalMessages: messages,
execute: ({ writer }) => {
writer.write({
type: "start",
messageMetadata: { custom: { xulux: { outcome } } },
});
writer.write({ type: "text-start", id: textPartId });
writer.write({ type: "text-delta", id: textPartId, delta: text });
writer.write({ type: "text-end", id: textPartId });
writer.write({ type: "finish", finishReason: "stop" });
},
});
return createUIMessageStreamResponse({ stream });
}