Skip to content

Commit b5d90ae

Browse files
committed
fix: validate voice-call legacy streaming numbers
1 parent b3fbe53 commit b5d90ae

2 files changed

Lines changed: 39 additions & 3 deletions

File tree

extensions/voice-call/src/config-compat.test.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,38 @@ describe("voice-call config compatibility", () => {
6262
expect(streaming?.sttModel).toBeUndefined();
6363
});
6464

65+
it("does not migrate non-finite legacy streaming numbers", () => {
66+
const migration = migrateVoiceCallLegacyConfigInput({
67+
value: {
68+
streaming: {
69+
silenceDurationMs: Number.NaN,
70+
vadThreshold: Number.POSITIVE_INFINITY,
71+
},
72+
},
73+
configPathPrefix: "plugins.entries.voice-call.config",
74+
});
75+
const streaming = migration.config.streaming as
76+
| {
77+
providers?: {
78+
openai?: {
79+
silenceDurationMs?: number;
80+
vadThreshold?: number;
81+
};
82+
};
83+
}
84+
| undefined;
85+
86+
expect(streaming?.providers?.openai).toBeUndefined();
87+
expect(migration.changes).toEqual([
88+
"Removed invalid plugins.entries.voice-call.config.streaming.silenceDurationMs.",
89+
"Removed invalid plugins.entries.voice-call.config.streaming.vadThreshold.",
90+
]);
91+
expect(migration.issues.map((issue) => issue.path)).toEqual([
92+
"streaming.silenceDurationMs",
93+
"streaming.vadThreshold",
94+
]);
95+
});
96+
6597
it("reports doctor-oriented legacy issues and warnings", () => {
6698
const raw = {
6799
provider: "log",

extensions/voice-call/src/config-compat.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ const getString = readStringField;
1515

1616
function getNumber(obj: Record<string, unknown> | undefined, key: string): number | undefined {
1717
const value = obj?.[key];
18-
return typeof value === "number" ? value : undefined;
18+
return typeof value === "number" && Number.isFinite(value) ? value : undefined;
1919
}
2020

2121
function mergeProviderConfig(
@@ -204,15 +204,19 @@ export function migrateVoiceCallLegacyConfigInput(params: {
204204
`Moved ${configPathPrefix}.streaming.sttModel → ${configPathPrefix}.streaming.providers.openai.model.`,
205205
);
206206
}
207-
if (typeof streaming?.silenceDurationMs === "number") {
207+
if (getNumber(streaming, "silenceDurationMs") !== undefined) {
208208
changes.push(
209209
`Moved ${configPathPrefix}.streaming.silenceDurationMs → ${configPathPrefix}.streaming.providers.openai.silenceDurationMs.`,
210210
);
211+
} else if (typeof streaming?.silenceDurationMs === "number") {
212+
changes.push(`Removed invalid ${configPathPrefix}.streaming.silenceDurationMs.`);
211213
}
212-
if (typeof streaming?.vadThreshold === "number") {
214+
if (getNumber(streaming, "vadThreshold") !== undefined) {
213215
changes.push(
214216
`Moved ${configPathPrefix}.streaming.vadThreshold → ${configPathPrefix}.streaming.providers.openai.vadThreshold.`,
215217
);
218+
} else if (typeof streaming?.vadThreshold === "number") {
219+
changes.push(`Removed invalid ${configPathPrefix}.streaming.vadThreshold.`);
216220
}
217221

218222
return { config, changes, issues };

0 commit comments

Comments
 (0)