diff --git a/extensions/discord/src/draft-chunking.ts b/extensions/discord/src/draft-chunking.ts index f3205b46d18..a1e0dea0a64 100644 --- a/extensions/discord/src/draft-chunking.ts +++ b/extensions/discord/src/draft-chunking.ts @@ -23,9 +23,7 @@ export function resolveDiscordDraftStreamingChunking( const accountCfg = resolveAccountEntry(cfg?.channels?.discord?.accounts, normalizedAccountId); const draftCfg = resolveChannelStreamingPreviewChunk(accountCfg) ?? - resolveChannelStreamingPreviewChunk(cfg?.channels?.discord) ?? - accountCfg?.draftChunk ?? - cfg?.channels?.discord?.draftChunk; + resolveChannelStreamingPreviewChunk(cfg?.channels?.discord); const maxRequested = Math.max( 1, diff --git a/extensions/memory-wiki/src/gateway.ts b/extensions/memory-wiki/src/gateway.ts index e30059e4f34..734b46db444 100644 --- a/extensions/memory-wiki/src/gateway.ts +++ b/extensions/memory-wiki/src/gateway.ts @@ -22,7 +22,17 @@ import { initializeMemoryWikiVault } from "./vault.js"; const READ_SCOPE = "operator.read" as const; const WRITE_SCOPE = "operator.write" as const; +type GatewayMethodContext = Parameters< + Parameters[1] +>[0]; +type GatewayRespond = GatewayMethodContext["respond"]; +function readStringParam(params: Record, key: string): string | undefined; +function readStringParam( + params: Record, + key: string, + options: { required: true }, +): string; function readStringParam( params: Record, key: string, @@ -67,16 +77,9 @@ function readEnumParam( throw new Error(`${key} must be one of: ${allowed.join(", ")}.`); } -function respondError( - respond: Parameters[1] extends ( - ctx: infer T, - ) => unknown - ? T["respond"] - : never, - error: unknown, -) { +function respondError(respond: GatewayRespond, error: unknown) { const message = error instanceof Error ? error.message : String(error); - respond(false, undefined, { message }); + respond(false, undefined, { code: "internal_error", message }); } async function syncImportedSourcesIfNeeded( diff --git a/extensions/memory-wiki/src/obsidian.test.ts b/extensions/memory-wiki/src/obsidian.test.ts index 7ae346340e2..588ef0f95c1 100644 --- a/extensions/memory-wiki/src/obsidian.test.ts +++ b/extensions/memory-wiki/src/obsidian.test.ts @@ -15,12 +15,13 @@ describe("runObsidianSearch", () => { { homedir: "/Users/tester" }, ); const calls: Array<{ command: string; argv: string[] }> = []; - const exec: NonNullable< - NonNullable[0]["deps"]>["exec"] - > = async (command, argv) => { - calls.push({ command, argv: [...argv] }); + const execImpl = async (command: string, argv?: readonly string[] | null) => { + calls.push({ command, argv: argv ? [...argv] : [] }); return { stdout: "search output\n", stderr: "" }; }; + const exec = execImpl as unknown as NonNullable< + NonNullable[0]["deps"]>["exec"] + >; const result = await runObsidianSearch({ config, diff --git a/extensions/telegram/src/bot-message-dispatch.test.ts b/extensions/telegram/src/bot-message-dispatch.test.ts index 0b7ae188f19..2d82ec255eb 100644 --- a/extensions/telegram/src/bot-message-dispatch.test.ts +++ b/extensions/telegram/src/bot-message-dispatch.test.ts @@ -405,7 +405,7 @@ describe("dispatchTelegramMessage draft streaming", () => { await dispatchWithContext({ context: createContext(), - telegramCfg: { blockStreaming: true }, + telegramCfg: { streaming: { block: { enabled: true } } }, }); expect(createTelegramDraftStream).not.toHaveBeenCalled(); @@ -655,7 +655,10 @@ describe("dispatchTelegramMessage draft streaming", () => { it.each([ { label: "default account config", telegramCfg: {} }, - { label: "account blockStreaming override", telegramCfg: { blockStreaming: true } }, + { + label: "account blockStreaming override", + telegramCfg: { streaming: { block: { enabled: true } } }, + }, ])("disables block streaming when streamMode is off ($label)", async ({ telegramCfg }) => { dispatchReplyWithBufferedBlockDispatcher.mockImplementation(async ({ dispatcherOptions }) => { await dispatcherOptions.deliver({ text: "Hello" }, { kind: "final" }); diff --git a/extensions/telegram/src/bot.helpers.test.ts b/extensions/telegram/src/bot.helpers.test.ts index 5d3cf129c8d..88c3d63eb65 100644 --- a/extensions/telegram/src/bot.helpers.test.ts +++ b/extensions/telegram/src/bot.helpers.test.ts @@ -55,10 +55,14 @@ describe("resolveTelegramDraftStreamingChunking", () => { accounts: { default: { allowFrom: ["*"], - draftChunk: { - minChars: 10, - maxChars: 20, - breakPreference: "sentence", + streaming: { + preview: { + chunk: { + minChars: 10, + maxChars: 20, + breakPreference: "sentence", + }, + }, }, }, }, diff --git a/extensions/telegram/src/draft-chunking.ts b/extensions/telegram/src/draft-chunking.ts index ed297c4ee39..0091eb05085 100644 --- a/extensions/telegram/src/draft-chunking.ts +++ b/extensions/telegram/src/draft-chunking.ts @@ -23,9 +23,7 @@ export function resolveTelegramDraftStreamingChunking( const accountCfg = resolveAccountEntry(cfg?.channels?.telegram?.accounts, normalizedAccountId); const draftCfg = resolveChannelStreamingPreviewChunk(accountCfg) ?? - resolveChannelStreamingPreviewChunk(cfg?.channels?.telegram) ?? - accountCfg?.draftChunk ?? - cfg?.channels?.telegram?.draftChunk; + resolveChannelStreamingPreviewChunk(cfg?.channels?.telegram); const maxRequested = Math.max( 1, diff --git a/src/auto-reply/reply.block-streaming.test.ts b/src/auto-reply/reply.block-streaming.test.ts index 81ec783deab..b6f995c8a3a 100644 --- a/src/auto-reply/reply.block-streaming.test.ts +++ b/src/auto-reply/reply.block-streaming.test.ts @@ -110,7 +110,12 @@ function createReplyConfig(streamMode?: "block"): OpenClawConfig { workspace: "/tmp/workspace", }, }, - channels: { telegram: { allowFrom: ["*"], ...(streamMode ? { streaming: streamMode } : {}) } }, + channels: { + telegram: { + allowFrom: ["*"], + ...(streamMode ? { streaming: { mode: streamMode } } : {}), + }, + }, session: { store: "/tmp/sessions.json" }, }; } diff --git a/src/channels/plugins/setup-wizard-helpers.test.ts b/src/channels/plugins/setup-wizard-helpers.test.ts index ccd84b17dc2..1baf288ad24 100644 --- a/src/channels/plugins/setup-wizard-helpers.test.ts +++ b/src/channels/plugins/setup-wizard-helpers.test.ts @@ -981,7 +981,7 @@ describe("patchChannelConfigForAccount", () => { botToken: "legacy-token", allowFrom: ["100"], groupPolicy: "allowlist", - streaming: "partial", + streaming: { mode: "partial" }, }, }, }; @@ -997,7 +997,7 @@ describe("patchChannelConfigForAccount", () => { botToken: "legacy-token", allowFrom: ["100"], groupPolicy: "allowlist", - streaming: "partial", + streaming: { mode: "partial" }, }); expect(next.channels?.telegram?.botToken).toBeUndefined(); expect(next.channels?.telegram?.allowFrom).toBeUndefined(); diff --git a/src/commands/doctor-legacy-config.migrations.test.ts b/src/commands/doctor-legacy-config.migrations.test.ts index 4c922d0f3f9..a1bd3c83ae4 100644 --- a/src/commands/doctor-legacy-config.migrations.test.ts +++ b/src/commands/doctor-legacy-config.migrations.test.ts @@ -384,7 +384,7 @@ describe("normalizeCompatibilityConfigValues", () => { dmPolicy: "allowlist", allowFrom: ["123"], groupPolicy: "allowlist", - streaming: "partial", + streaming: { mode: "partial" }, accounts: { alerts: { enabled: true, @@ -400,7 +400,7 @@ describe("normalizeCompatibilityConfigValues", () => { dmPolicy: "allowlist", allowFrom: ["123"], groupPolicy: "allowlist", - streaming: "partial", + streaming: { mode: "partial" }, }); expect(res.config.channels?.telegram?.botToken).toBeUndefined(); expect(res.config.channels?.telegram?.dmPolicy).toBeUndefined(); diff --git a/src/config/config-misc.test.ts b/src/config/config-misc.test.ts index 3055e6777bc..d7dd4e0cc61 100644 --- a/src/config/config-misc.test.ts +++ b/src/config/config-misc.test.ts @@ -5,8 +5,8 @@ import { setConfigValueAtPath, unsetConfigValueAtPath, } from "./config-paths.js"; -import { validateConfigObject } from "./config.js"; -import { buildWebSearchProviderConfig } from "./test-helpers.js"; +import { readConfigFileSnapshot, validateConfigObject } from "./config.js"; +import { buildWebSearchProviderConfig, withTempHome, writeOpenClawConfig } from "./test-helpers.js"; import { OpenClawSchema } from "./zod-schema.js"; describe("$schema key in config (#14998)", () => { diff --git a/src/config/config.legacy-config-detection.rejects-routing-allowfrom.test.ts b/src/config/config.legacy-config-detection.rejects-routing-allowfrom.test.ts index d6d80b30880..c41ad49791a 100644 --- a/src/config/config.legacy-config-detection.rejects-routing-allowfrom.test.ts +++ b/src/config/config.legacy-config-detection.rejects-routing-allowfrom.test.ts @@ -1,4 +1,6 @@ import { describe, expect, it } from "vitest"; +import { migrateLegacyConfig } from "../commands/doctor/shared/legacy-config-migrate.js"; +import type { OpenClawConfig } from "./config.js"; import { validateConfigObject } from "./validation.js"; function getChannelConfig(config: unknown, provider: string) { @@ -234,7 +236,9 @@ describe("legacy config detection", () => { { name: "streamMode with streaming boolean", input: { channels: { discord: { streaming: false, streamMode: "block" } } }, - expectedChanges: ["Moved channels.discord.streamMode → channels.discord.streaming.mode (block)."], + expectedChanges: [ + "Moved channels.discord.streamMode → channels.discord.streaming.mode (block).", + ], expectedStreaming: "block", }, ] as const)( diff --git a/src/plugin-sdk/test-helpers.ts b/src/plugin-sdk/test-helpers.ts index cc5be2071d5..2b570213893 100644 --- a/src/plugin-sdk/test-helpers.ts +++ b/src/plugin-sdk/test-helpers.ts @@ -1,5 +1,5 @@ -import { mkdtempSync } from "node:fs"; -import { mkdtemp, rm, type RmOptions } from "node:fs/promises"; +import { mkdtempSync, type RmOptions } from "node:fs"; +import { mkdtemp, rm } from "node:fs/promises"; import { tmpdir } from "node:os"; import path from "node:path"; import { afterEach } from "vitest";