Onboarding: emoji-first flow with shape/color selection, user preferences, language setup (9 locales), and bot creation with avatarValue persistence. executor.ts: split 4928→4159 lines into 8 modules (completion, computer, effects, model, utils, tools, attachments, types). pi-runtime.ts: split 1726→561 lines into 2 modules (model-config, tool-utils). E2E: new onboarding-emoji-first tests + updated completeOnboarding helper.
44 lines
1.7 KiB
TypeScript
44 lines
1.7 KiB
TypeScript
import type { MessageBlock } from "@rakazo/contracts";
|
|
|
|
export const TURN_ATTACHMENT_UNAVAILABLE =
|
|
"An attachment in this message could not be loaded. Tell the user the attachment was unavailable and do not guess its contents.";
|
|
export const STEERING_ATTACHMENT_UNAVAILABLE = TURN_ATTACHMENT_UNAVAILABLE;
|
|
|
|
export function missingTurnImagesInstruction(
|
|
blocks: MessageBlock[] | undefined,
|
|
images: { length: number } | undefined,
|
|
): string {
|
|
const expected = blocks?.filter((block) => block.kind === "image").length ?? 0;
|
|
const loaded = images?.length ?? 0;
|
|
return expected > 0 && loaded < expected ? TURN_ATTACHMENT_UNAVAILABLE : "";
|
|
}
|
|
|
|
export async function settleSteeringAttachmentLoads<TImage, TFile>(
|
|
images: Promise<TImage[] | undefined>,
|
|
files: Promise<TFile[]>,
|
|
blocks?: MessageBlock[],
|
|
signal?: AbortSignal,
|
|
): Promise<{
|
|
images: TImage[] | undefined;
|
|
files: TFile[];
|
|
unavailableInstruction: string;
|
|
}> {
|
|
const [loadedImages, loadedFiles] = await Promise.allSettled([images, files]);
|
|
if (signal?.aborted) {
|
|
if (loadedImages.status === "rejected") throw loadedImages.reason;
|
|
if (loadedFiles.status === "rejected") throw loadedFiles.reason;
|
|
}
|
|
const expectedImageCount = blocks?.filter((block) => block.kind === "image").length ?? 0;
|
|
const loadedImageCount =
|
|
loadedImages.status === "fulfilled" ? (loadedImages.value?.length ?? 0) : 0;
|
|
const unavailable =
|
|
loadedImages.status === "rejected" ||
|
|
loadedFiles.status === "rejected" ||
|
|
loadedImageCount < expectedImageCount;
|
|
return {
|
|
images: loadedImages.status === "fulfilled" ? loadedImages.value : undefined,
|
|
files: loadedFiles.status === "fulfilled" ? loadedFiles.value : [],
|
|
unavailableInstruction: unavailable ? STEERING_ATTACHMENT_UNAVAILABLE : "",
|
|
};
|
|
}
|