mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
fix(ci): annotate unsafe boundary casts
This commit is contained in:
@@ -120,6 +120,7 @@ function resolveAnthropicVertexProjectIdFromAdc(
|
||||
return undefined;
|
||||
}
|
||||
try {
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- ADC credentials are external JSON; only optional project ids are consumed.
|
||||
const parsed = JSON.parse(readFileSync(credentialsPath, "utf8")) as AdcProjectFile;
|
||||
return (
|
||||
normalizeOptionalSecretInput(parsed.project_id) ||
|
||||
|
||||
@@ -115,6 +115,7 @@ function createAnthropicVertexOnPayload(params: {
|
||||
|
||||
function applyPolicy(payload: unknown): unknown {
|
||||
if (payload && typeof payload === "object" && !Array.isArray(payload)) {
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Anthropic payload policy mutates open provider JSON params.
|
||||
applyAnthropicPayloadPolicyToParams(payload as Record<string, unknown>, policy);
|
||||
}
|
||||
return payload;
|
||||
@@ -149,6 +150,7 @@ export function createAnthropicVertexStreamFn(
|
||||
});
|
||||
|
||||
return (model, context, options) => {
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- This stream adapter is registered only for Anthropic Messages models.
|
||||
const transportModel = model as Model<"anthropic-messages"> & {
|
||||
api: string;
|
||||
baseUrl?: string;
|
||||
@@ -188,7 +190,8 @@ export function createAnthropicVertexStreamFn(
|
||||
const budgets = options.thinkingBudgets;
|
||||
opts.thinkingBudgetTokens =
|
||||
(budgets && options.reasoning in budgets
|
||||
? budgets[options.reasoning as keyof typeof budgets]
|
||||
? // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- The key presence check above narrows runtime indexing for configured budgets.
|
||||
budgets[options.reasoning as keyof typeof budgets]
|
||||
: undefined) ?? 10000;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -67,7 +67,9 @@ function mergeMattermostAccountConfig(
|
||||
accountId: string,
|
||||
): MattermostAccountConfig {
|
||||
return resolveMergedAccountConfig<MattermostAccountConfig>({
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Mattermost channel config is plugin-owned open config merged by the account resolver.
|
||||
channelConfig: cfg.channels?.mattermost as MattermostAccountConfig | undefined,
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Mattermost account entries are plugin-owned open config records.
|
||||
accounts: cfg.channels?.mattermost?.accounts as
|
||||
| Record<string, Partial<MattermostAccountConfig>>
|
||||
| undefined,
|
||||
|
||||
@@ -82,6 +82,7 @@ function buildMattermostApiUrl(baseUrl: string, path: string): string {
|
||||
export async function readMattermostError(res: Response): Promise<string> {
|
||||
const contentType = res.headers.get("content-type") ?? "";
|
||||
if (contentType.includes("application/json")) {
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Mattermost error payloads are external JSON; only optional message is consumed.
|
||||
const data = (await res.json()) as { message?: string } | undefined;
|
||||
if (data?.message) {
|
||||
return data.message;
|
||||
@@ -151,14 +152,17 @@ export function createMattermostClient(params: {
|
||||
}
|
||||
|
||||
if (res.status === 204) {
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Generic request callers type the expected endpoint body; 204 has no body.
|
||||
return undefined as T;
|
||||
}
|
||||
|
||||
const contentType = res.headers.get("content-type") ?? "";
|
||||
if (contentType.includes("application/json")) {
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Generic request callers type the expected Mattermost endpoint body.
|
||||
return (await res.json()) as T;
|
||||
}
|
||||
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Generic request callers type the expected Mattermost endpoint body.
|
||||
return (await res.text()) as T;
|
||||
};
|
||||
|
||||
@@ -594,6 +598,7 @@ export async function uploadMattermostFile(
|
||||
throw new Error(`Mattermost API ${res.status} ${res.statusText}: ${detail || "unknown error"}`);
|
||||
}
|
||||
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Mattermost upload response is external JSON; required file id is checked below.
|
||||
const data = (await res.json()) as { file_infos?: MattermostFileInfo[] };
|
||||
const info = data.file_infos?.[0];
|
||||
if (!info?.id) {
|
||||
|
||||
@@ -165,6 +165,7 @@ export async function listMicrosoftVoices(): Promise<SpeechVoiceOption[]> {
|
||||
});
|
||||
}
|
||||
await assertOkOrThrowProviderError(response, "Microsoft voices API error");
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Microsoft voice-list payload is external JSON filtered before returning options.
|
||||
const voices = (await response.json()) as MicrosoftVoiceListEntry[];
|
||||
return Array.isArray(voices)
|
||||
? voices
|
||||
|
||||
@@ -42,7 +42,8 @@ type VydraJobPayload = {
|
||||
|
||||
function asObject(value: unknown): Record<string, unknown> | undefined {
|
||||
return typeof value === "object" && value !== null && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>)
|
||||
? // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Vydra webhook payloads are external JSON objects walked defensively by key.
|
||||
(value as Record<string, unknown>)
|
||||
: undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -351,13 +351,15 @@ function resolveTtsRuntimeConfig(cfg: OpenClawConfig): OpenClawConfig {
|
||||
|
||||
function asProviderConfig(value: unknown): SpeechProviderConfig {
|
||||
return typeof value === "object" && value !== null && !Array.isArray(value)
|
||||
? (value as SpeechProviderConfig)
|
||||
? // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Speech provider configs are open JSON records normalized at the plugin boundary.
|
||||
(value as SpeechProviderConfig)
|
||||
: {};
|
||||
}
|
||||
|
||||
function asProviderConfigMap(value: unknown): Record<string, unknown> {
|
||||
return typeof value === "object" && value !== null && !Array.isArray(value)
|
||||
? (value as Record<string, unknown>)
|
||||
? // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- TTS provider config maps are open JSON records keyed by provider id.
|
||||
(value as Record<string, unknown>)
|
||||
: {};
|
||||
}
|
||||
|
||||
@@ -728,6 +730,7 @@ function readPrefs(prefsPath: string): TtsUserPrefs {
|
||||
if (!existsSync(prefsPath)) {
|
||||
return {};
|
||||
}
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- User prefs are trusted local JSON and unknown keys are ignored by readers.
|
||||
return JSON.parse(readFileSync(prefsPath, "utf8")) as TtsUserPrefs;
|
||||
} catch {
|
||||
return {};
|
||||
@@ -900,12 +903,14 @@ export function resolveExplicitTtsOverrides(params: {
|
||||
`TTS provider "${selectedProvider}" ignored the requested model or voice overrides.`,
|
||||
);
|
||||
}
|
||||
if (!providerOverrides) {
|
||||
throw new Error(`TTS provider "${selectedProvider}" did not return talk overrides.`);
|
||||
}
|
||||
|
||||
const overridesRecord = providerOverrides as SpeechProviderOverrides;
|
||||
return {
|
||||
provider: selectedProvider,
|
||||
providerOverrides: {
|
||||
[provider.id]: overridesRecord,
|
||||
[provider.id]: providerOverrides,
|
||||
},
|
||||
};
|
||||
}
|
||||
@@ -1815,9 +1820,10 @@ export async function textToSpeechTelephony(params: {
|
||||
config,
|
||||
provider: resolvedProvider.provider,
|
||||
});
|
||||
const synthesizeTelephony = resolvedProvider.provider.synthesizeTelephony as NonNullable<
|
||||
typeof resolvedProvider.provider.synthesizeTelephony
|
||||
>;
|
||||
const synthesizeTelephony = resolvedProvider.provider.synthesizeTelephony;
|
||||
if (!synthesizeTelephony) {
|
||||
throw new Error(`TTS provider "${resolvedProvider.provider.id}" lost telephony support`);
|
||||
}
|
||||
const prepared = await prepareSpeechSynthesis({
|
||||
provider: resolvedProvider.provider,
|
||||
text: params.text,
|
||||
@@ -2044,6 +2050,7 @@ export async function maybeApplyTtsToPayload(params: {
|
||||
textForAudio = `${textForAudio.slice(0, config.maxTextLength - 3)}...`;
|
||||
}
|
||||
} catch (err) {
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Only the message is used for verbose diagnostics after a caught summarizer failure.
|
||||
const error = err as Error;
|
||||
logVerbose(`TTS: summarization failed, truncating instead: ${error.message}`);
|
||||
textForAudio = `${textForAudio.slice(0, maxLength - 3)}...`;
|
||||
|
||||
@@ -101,6 +101,7 @@ export function voiceProviderSupportsModel(
|
||||
}
|
||||
|
||||
export function resolveVoiceModelRefs(config: unknown): VoiceModelRef[] {
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Voice model config is an open config object; fields are normalized individually below.
|
||||
const voiceModel = config as VoiceModelConfig | undefined;
|
||||
if (typeof voiceModel === "string") {
|
||||
const parsed = parseVoiceModelRef(voiceModel);
|
||||
@@ -212,6 +213,7 @@ export function getVoiceProviderConfig<TConfig extends Record<string, unknown>>(
|
||||
const configuredKeys = Object.keys(params.providerConfigs);
|
||||
for (const candidate of candidates) {
|
||||
if (Object.hasOwn(params.providerConfigs, candidate)) {
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Empty provider config preserves the caller-specific config record type.
|
||||
return params.providerConfigs[candidate] ?? ({} as TConfig);
|
||||
}
|
||||
const normalizedCandidate = normalizeLowercaseString(candidate);
|
||||
@@ -219,9 +221,11 @@ export function getVoiceProviderConfig<TConfig extends Record<string, unknown>>(
|
||||
(key) => normalizeLowercaseString(key) === normalizedCandidate,
|
||||
);
|
||||
if (matchingKey) {
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Empty provider config preserves the caller-specific config record type.
|
||||
return params.providerConfigs[matchingKey] ?? ({} as TConfig);
|
||||
}
|
||||
}
|
||||
// oxlint-disable-next-line typescript/no-unsafe-type-assertion -- Empty provider config preserves the caller-specific config record type.
|
||||
return {} as TConfig;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user