diff --git a/CHANGELOG.md b/CHANGELOG.md index fec490737ed..b5fa3c47e0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Docs: https://docs.openclaw.ai ### Fixes - Feishu: auto-thread `message(action="send")` replies inside the topic when the active session is group_topic or group_topic_sender, and propagate `replyInThread` through text, card, and media outbound adapters so topic-scoped sessions no longer post at the group root. Fixes #74903. (#77151) Thanks @ai-hpc. +- WhatsApp: pass routing context into voice-note transcript echo preflight so echoed transcripts can deliver to the originating chat. Fixes #79778. (#79788) Thanks @hclsys. ## 2026.5.9 diff --git a/extensions/google/onboard.ts b/extensions/google/onboard.ts index 34c22aab8cd..5c6dd39d73f 100644 --- a/extensions/google/onboard.ts +++ b/extensions/google/onboard.ts @@ -3,9 +3,7 @@ import { type OpenClawConfig, } from "openclaw/plugin-sdk/provider-onboard"; -// gemini-2.5-flash is the stable GA model; preview models share the Tier 1 free RPD=250 -// ceiling even on paid accounts, causing quota exhaustion under normal usage (#79670). -export const GOOGLE_GEMINI_DEFAULT_MODEL = "google/gemini-2.5-flash"; +export const GOOGLE_GEMINI_DEFAULT_MODEL = "google/gemini-3.1-pro-preview"; export function applyGoogleGeminiModelDefault(cfg: OpenClawConfig): { next: OpenClawConfig; diff --git a/extensions/minimax/index.test.ts b/extensions/minimax/index.test.ts index e9213007188..6f2caef2685 100644 --- a/extensions/minimax/index.test.ts +++ b/extensions/minimax/index.test.ts @@ -4,7 +4,6 @@ import { registerProviderPlugin, requireRegisteredProvider, } from "openclaw/plugin-sdk/plugin-test-runtime"; -import { MINIMAX_OAUTH_MARKER } from "openclaw/plugin-sdk/provider-auth"; import { describe, expect, it, vi } from "vitest"; import { registerMinimaxProviders } from "./provider-registration.js"; import { createMiniMaxWebSearchProvider } from "./src/minimax-web-search-provider.js"; @@ -326,33 +325,6 @@ describe("minimax provider hooks", () => { expect(result?.windows).toEqual([{ label: "5h", usedPercent: 2, resetAt: undefined }]); }); - it("portal catalog resolves OAuth token via resolveProviderAuth with oauthMarker", async () => { - const { providers } = await registerProviderPlugin({ - plugin: minimaxProviderPlugin, - id: "minimax", - name: "MiniMax Provider", - }); - const portalProvider = requireRegisteredProvider(providers, "minimax-portal"); - const resolveProviderAuth = vi.fn(() => ({ - apiKey: MINIMAX_OAUTH_MARKER, - mode: "oauth" as const, - source: "profile" as const, - })); - const result = await portalProvider.catalog?.run({ - config: {}, - resolveProviderAuth, - resolveProviderApiKey: () => ({ apiKey: undefined }), - } as never); - - expect(resolveProviderAuth).toHaveBeenCalledWith("minimax-portal", { - oauthMarker: MINIMAX_OAUTH_MARKER, - }); - expect(result).not.toBeNull(); - if (result && "provider" in result) { - expect(result.provider.apiKey).toBe(MINIMAX_OAUTH_MARKER); - } - }); - it("writes api and authHeader into the MiniMax portal OAuth config patch", async () => { const { providers } = await registerProviderPlugin({ plugin: minimaxProviderPlugin, diff --git a/extensions/minimax/provider-registration.ts b/extensions/minimax/provider-registration.ts index 91a0d04c15d..b62ef3a1cf5 100644 --- a/extensions/minimax/provider-registration.ts +++ b/extensions/minimax/provider-registration.ts @@ -6,7 +6,11 @@ import type { ProviderAuthResult, ProviderCatalogContext, } from "openclaw/plugin-sdk/plugin-entry"; -import { MINIMAX_OAUTH_MARKER } from "openclaw/plugin-sdk/provider-auth"; +import { + MINIMAX_OAUTH_MARKER, + ensureAuthProfileStore, + listProfilesForProvider, +} from "openclaw/plugin-sdk/provider-auth"; import { buildOauthProviderAuthResult } from "openclaw/plugin-sdk/provider-auth"; import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key"; import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared"; @@ -96,13 +100,13 @@ function resolveApiCatalog(ctx: ProviderCatalogContext) { function resolvePortalCatalog(ctx: ProviderCatalogContext) { const explicitProvider = ctx.config.models?.providers?.[PORTAL_PROVIDER_ID]; - const explicitApiKey = normalizeOptionalString(explicitProvider?.apiKey); - // resolveProviderAuth handles OAuth profiles via oauthMarker, returning the - // sentinel so the request layer can swap in the live access token (#79731). - const { apiKey: profileApiKey } = ctx.resolveProviderAuth(PORTAL_PROVIDER_ID, { - oauthMarker: MINIMAX_OAUTH_MARKER, + const envApiKey = ctx.resolveProviderApiKey(PORTAL_PROVIDER_ID).apiKey; + const authStore = ensureAuthProfileStore(ctx.agentDir, { + allowKeychainPrompt: false, }); - const apiKey = explicitApiKey ?? profileApiKey; + const hasProfiles = listProfilesForProvider(authStore, PORTAL_PROVIDER_ID).length > 0; + const explicitApiKey = normalizeOptionalString(explicitProvider?.apiKey); + const apiKey = envApiKey ?? explicitApiKey ?? (hasProfiles ? MINIMAX_OAUTH_MARKER : undefined); if (!apiKey) { return null; } diff --git a/extensions/whatsapp/src/auto-reply/monitor/process-message.audio-preflight.test.ts b/extensions/whatsapp/src/auto-reply/monitor/process-message.audio-preflight.test.ts index de4766b4403..13d548bd53e 100644 --- a/extensions/whatsapp/src/auto-reply/monitor/process-message.audio-preflight.test.ts +++ b/extensions/whatsapp/src/auto-reply/monitor/process-message.audio-preflight.test.ts @@ -219,8 +219,15 @@ describe("processMessage audio preflight transcription", () => { expect(transcribeFirstAudioMock).toHaveBeenCalledWith( expect.objectContaining({ ctx: expect.objectContaining({ + AccountId: "default", + From: "+15550000002", MediaPaths: ["/tmp/voice.ogg"], MediaTypes: ["audio/ogg; codecs=opus"], + OriginatingChannel: "whatsapp", + OriginatingTo: "+15550000002", + Provider: "whatsapp", + Surface: "whatsapp", + To: "+15550000001", }), }), );