codex@macbookpro
·
2026-04-01
normalize.ts
1import {
2 buildBaaInstructionDedupeBasis,
3 buildBaaInstructionDedupeKey,
4 buildBaaInstructionId
5} from "./dedupe.js";
6import type {
7 BaaInstructionEnvelope,
8 BaaInstructionSourceMessage,
9 BaaParsedInstruction
10} from "./types.js";
11
12function requireNonEmptyField(name: string, value: string): string {
13 const normalized = value.trim();
14
15 if (normalized === "") {
16 throw new Error(`${name} must be a non-empty string.`);
17 }
18
19 return normalized;
20}
21
22function normalizeOptionalStringField(value: string | null): string | null {
23 if (value == null) {
24 return null;
25 }
26
27 const normalized = value.trim();
28 return normalized === "" ? null : normalized;
29}
30
31export function normalizeBaaInstructionSourceMessage(
32 source: BaaInstructionSourceMessage
33): BaaInstructionSourceMessage {
34 return {
35 assistantMessageId: requireNonEmptyField("assistantMessageId", source.assistantMessageId),
36 conversationId: normalizeOptionalStringField(source.conversationId),
37 platform: requireNonEmptyField("platform", source.platform)
38 };
39}
40
41export function normalizeBaaInstruction(
42 source: BaaInstructionSourceMessage,
43 instruction: BaaParsedInstruction
44): BaaInstructionEnvelope {
45 const normalizedSource = normalizeBaaInstructionSourceMessage(source);
46 const dedupeBasis = buildBaaInstructionDedupeBasis(normalizedSource, instruction);
47 const dedupeKey = buildBaaInstructionDedupeKey(dedupeBasis);
48
49 return {
50 assistantMessageId: normalizedSource.assistantMessageId,
51 blockIndex: instruction.blockIndex,
52 conversationId: normalizedSource.conversationId,
53 dedupeBasis,
54 dedupeKey,
55 envelopeVersion: "baa.v1",
56 instructionId: buildBaaInstructionId(dedupeKey),
57 params: instruction.params,
58 paramsKind: instruction.paramsKind,
59 platform: normalizedSource.platform,
60 rawBlock: instruction.rawBlock,
61 rawInstruction: instruction.rawInstruction,
62 target: instruction.target,
63 tool: instruction.tool
64 };
65}