mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
chore(plugins): gate deprecation hygiene in CI and purge internal deprecated usage (#108261)
* chore(plugins): gate deprecation hygiene in CI and purge internal deprecated usage * fix(agents): migrate auth-profiles oauth import to OAuthProviderId * fix(whatsapp): use durability param in delivery-recovery test * chore(scripts): declare shouldRunDeprecationHygieneChecks in check-changed types * test(plugins): update runtime-api guard for ssrf policy rename
This commit is contained in:
committed by
GitHub
parent
8160bbdf2e
commit
0393189243
@@ -11,7 +11,7 @@ import type {
|
||||
ProviderNormalizeResolvedModelContext,
|
||||
} from "openclaw/plugin-sdk/plugin-entry";
|
||||
import {
|
||||
ANTHROPIC_BY_MODEL_REPLAY_HOOKS,
|
||||
buildProviderReplayFamilyHooks,
|
||||
normalizeProviderId,
|
||||
resolveClaudeFable5ModelIdentity,
|
||||
resolveClaudeModelIdentity,
|
||||
@@ -364,7 +364,9 @@ export function registerAmazonBedrockPlugin(api: OpenClawPluginApi): void {
|
||||
] as const;
|
||||
const deprecatedTemperatureValidationRe =
|
||||
/ValidationException[\s\S]*(?:invalid_request_error[\s\S]*)?temperature[\s\S]*deprecated|ValidationException[\s\S]*deprecated[\s\S]*temperature/i;
|
||||
const anthropicByModelReplayHooks = ANTHROPIC_BY_MODEL_REPLAY_HOOKS;
|
||||
const anthropicByModelReplayHooks = buildProviderReplayFamilyHooks({
|
||||
family: "anthropic-by-model",
|
||||
});
|
||||
const startupPluginConfig = (api.pluginConfig ?? {}) as AmazonBedrockPluginConfig;
|
||||
|
||||
registerApiProvider(
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { readConfiguredProviderCatalogEntries } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import {
|
||||
NATIVE_ANTHROPIC_REPLAY_HOOKS,
|
||||
buildProviderReplayFamilyHooks,
|
||||
resolveClaudeThinkingProfile,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import {
|
||||
@@ -48,7 +48,7 @@ export default definePluginEntry({
|
||||
},
|
||||
},
|
||||
resolveConfigApiKey: ({ env }) => resolveAnthropicVertexConfigApiKey(env),
|
||||
...NATIVE_ANTHROPIC_REPLAY_HOOKS,
|
||||
...buildProviderReplayFamilyHooks({ family: "native-anthropic-by-model" }),
|
||||
normalizeResolvedModel: ({ modelId, model }) =>
|
||||
normalizeAnthropicVertexResolvedModel(modelId, model),
|
||||
resolveThinkingProfile: ({ modelId, params }) =>
|
||||
|
||||
@@ -25,9 +25,9 @@ import {
|
||||
validateAnthropicSetupToken,
|
||||
} from "openclaw/plugin-sdk/provider-auth";
|
||||
import {
|
||||
buildProviderReplayFamilyHooks,
|
||||
cloneFirstTemplateModel,
|
||||
modelCostsEqual,
|
||||
NATIVE_ANTHROPIC_REPLAY_HOOKS,
|
||||
type ProviderPlugin,
|
||||
resolveClaudeFable5ModelIdentity,
|
||||
resolveClaudeModelIdentity,
|
||||
@@ -896,7 +896,7 @@ export function buildAnthropicProvider(): ProviderPlugin {
|
||||
: undefined,
|
||||
// Publish Claude CLI rows through the provider catalog hook.
|
||||
augmentModelCatalog: () => buildClaudeCliCatalogEntries(),
|
||||
...NATIVE_ANTHROPIC_REPLAY_HOOKS,
|
||||
...buildProviderReplayFamilyHooks({ family: "native-anthropic-by-model" }),
|
||||
isModernModelRef: ({ provider, modelId }) =>
|
||||
matchesAnthropicModernModel(modelId) &&
|
||||
(!isAnthropicMandatoryClaude5Model(modelId) ||
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
readConfiguredProviderCatalogEntries,
|
||||
type ProviderCatalogContext,
|
||||
} from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import { OPENAI_COMPATIBLE_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import {
|
||||
applyArceeConfig,
|
||||
applyArceeOpenRouterConfig,
|
||||
@@ -141,7 +141,7 @@ export default definePluginEntry({
|
||||
}
|
||||
: undefined;
|
||||
},
|
||||
...OPENAI_COMPATIBLE_REPLAY_HOOKS,
|
||||
...buildProviderReplayFamilyHooks({ family: "openai-compatible" }),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
readConfiguredProviderCatalogEntries,
|
||||
} from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
||||
import { PASSTHROUGH_GEMINI_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import {
|
||||
createOpenRouterWrapper,
|
||||
isProxyReasoningUnsupported,
|
||||
@@ -104,7 +104,7 @@ export default defineSingleProviderPluginEntry({
|
||||
normalizeConfig: ({ providerConfig }) => providerConfig,
|
||||
normalizeTransport: ({ api, baseUrl }) =>
|
||||
baseUrl === "https://api.deepinfra.com/v1/openai" ? { api, baseUrl } : undefined,
|
||||
...PASSTHROUGH_GEMINI_REPLAY_HOOKS,
|
||||
...buildProviderReplayFamilyHooks({ family: "passthrough-gemini" }),
|
||||
wrapStreamFn: (ctx) => {
|
||||
const thinkingLevel = isProxyReasoningUnsupported(ctx.modelId)
|
||||
? undefined
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// Feishu tests cover the shared outbound delivery path.
|
||||
import { sendDurableMessageBatch } from "openclaw/plugin-sdk/channel-outbound";
|
||||
import {
|
||||
createOutboundTestPlugin,
|
||||
createTestRegistry,
|
||||
deliverOutboundPayloads,
|
||||
releasePinnedPluginChannelRegistry,
|
||||
resetGlobalHookRunner,
|
||||
setActivePluginRegistry,
|
||||
@@ -60,7 +60,7 @@ describe("Feishu outbound shared delivery", () => {
|
||||
});
|
||||
|
||||
it("routes oversized presentation media through one media send and chunked fallback text", async () => {
|
||||
await deliverOutboundPayloads({
|
||||
await sendDurableMessageBatch({
|
||||
cfg: {},
|
||||
channel: "feishu",
|
||||
to: "chat_1",
|
||||
|
||||
@@ -2,10 +2,10 @@
|
||||
import type { ProviderResolveDynamicModelContext } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
||||
import {
|
||||
buildProviderReplayFamilyHooks,
|
||||
cloneFirstTemplateModel,
|
||||
DEFAULT_CONTEXT_TOKENS,
|
||||
normalizeModelCompat,
|
||||
OPENAI_COMPATIBLE_REPLAY_HOOKS,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { isFireworksKimiModelId } from "./model-id.js";
|
||||
import { applyFireworksConfig, FIREWORKS_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
@@ -97,7 +97,7 @@ export default defineSingleProviderPluginEntry({
|
||||
buildProvider: buildFireworksProvider,
|
||||
allowExplicitBaseUrl: true,
|
||||
},
|
||||
...OPENAI_COMPATIBLE_REPLAY_HOOKS,
|
||||
...buildProviderReplayFamilyHooks({ family: "openai-compatible" }),
|
||||
wrapStreamFn: wrapFireworksProviderStream,
|
||||
resolveThinkingProfile: ({ modelId }) => resolveFireworksThinkingProfile(modelId),
|
||||
resolveDynamicModel: (ctx) => resolveFireworksDynamicModel(ctx),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Kilocode plugin entrypoint registers its OpenClaw integration.
|
||||
import { readConfiguredProviderCatalogEntries } from "openclaw/plugin-sdk/provider-catalog-shared";
|
||||
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
||||
import { PASSTHROUGH_GEMINI_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { applyKilocodeConfig, KILOCODE_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
import { buildKilocodeProvider, buildKilocodeProviderWithDiscovery } from "./provider-catalog.js";
|
||||
import { wrapKilocodeProviderStream } from "./stream.js";
|
||||
@@ -37,7 +37,7 @@ export default defineSingleProviderPluginEntry({
|
||||
config,
|
||||
providerId: PROVIDER_ID,
|
||||
}),
|
||||
...PASSTHROUGH_GEMINI_REPLAY_HOOKS,
|
||||
...buildProviderReplayFamilyHooks({ family: "passthrough-gemini" }),
|
||||
wrapStreamFn: wrapKilocodeProviderStream,
|
||||
isCacheTtlEligible: (ctx) => ctx.modelId.startsWith("anthropic/"),
|
||||
},
|
||||
|
||||
@@ -34,7 +34,6 @@ export {
|
||||
createPinnedDispatcher,
|
||||
resolvePinnedHostnameWithPolicy,
|
||||
ssrfPolicyFromDangerouslyAllowPrivateNetwork,
|
||||
ssrfPolicyFromAllowPrivateNetwork,
|
||||
type LookupFn,
|
||||
type SsrFPolicy,
|
||||
} from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
|
||||
@@ -71,7 +71,6 @@ export {
|
||||
isPrivateOrLoopbackHost,
|
||||
resolvePinnedHostnameWithPolicy,
|
||||
ssrfPolicyFromDangerouslyAllowPrivateNetwork,
|
||||
ssrfPolicyFromAllowPrivateNetwork,
|
||||
type LookupFn,
|
||||
type SsrFPolicy,
|
||||
} from "openclaw/plugin-sdk/ssrf-runtime";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Mattermost tests cover the shared outbound delivery path.
|
||||
import { sendDurableMessageBatch } from "openclaw/plugin-sdk/channel-outbound";
|
||||
import {
|
||||
createTestRegistry,
|
||||
deliverOutboundPayloads,
|
||||
releasePinnedPluginChannelRegistry,
|
||||
setActivePluginRegistry,
|
||||
} from "openclaw/plugin-sdk/channel-test-helpers";
|
||||
@@ -43,7 +43,7 @@ describe("Mattermost outbound delivery", () => {
|
||||
expected: "The pipeline has 3 open deals.",
|
||||
},
|
||||
])("sends sanitized $name through the channel handler", async ({ text, expected }) => {
|
||||
await deliverOutboundPayloads({
|
||||
await sendDurableMessageBatch({
|
||||
cfg: {},
|
||||
channel: "mattermost",
|
||||
to: "channel:team-1",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* Meta provider plugin entrypoint.
|
||||
*/
|
||||
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
||||
import { OPENAI_COMPATIBLE_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { applyMetaConfig, META_DEFAULT_MODEL_REF } from "./onboard.js";
|
||||
import { buildMetaProvider } from "./provider-catalog.js";
|
||||
import { wrapMetaProviderStream } from "./stream.js";
|
||||
@@ -40,7 +40,7 @@ export default defineSingleProviderPluginEntry({
|
||||
buildProvider: buildMetaProvider,
|
||||
buildStaticProvider: buildMetaProvider,
|
||||
},
|
||||
...OPENAI_COMPATIBLE_REPLAY_HOOKS,
|
||||
...buildProviderReplayFamilyHooks({ family: "openai-compatible" }),
|
||||
wrapStreamFn: wrapMetaProviderStream,
|
||||
resolveThinkingProfile: ({ modelId }) => resolveMetaThinkingProfile(modelId),
|
||||
},
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
type ModelProviderConfig,
|
||||
type ProviderPlugin,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { OPENAI_RESPONSES_STREAM_HOOKS } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { apiKeyAuthMethod, entraIdAuthMethod } from "./auth.js";
|
||||
import { prepareFoundryRuntimeAuth } from "./runtime.js";
|
||||
import {
|
||||
@@ -25,7 +25,8 @@ import {
|
||||
|
||||
type FoundryProviderHooks = Pick<ProviderPlugin, "wrapStreamFn">;
|
||||
|
||||
const wrapOpenAIResponsesStreamFn = OPENAI_RESPONSES_STREAM_HOOKS.wrapStreamFn;
|
||||
const openAIResponsesStreamHooks = buildProviderStreamFamilyHooks("openai-responses-defaults");
|
||||
const wrapOpenAIResponsesStreamFn = openAIResponsesStreamHooks.wrapStreamFn;
|
||||
|
||||
const wrapMicrosoftFoundryStreamFn: NonNullable<FoundryProviderHooks["wrapStreamFn"]> = (ctx) => {
|
||||
if (ctx.model?.api !== "openai-responses") {
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
buildProviderReplayFamilyHooks,
|
||||
normalizeModelCompat,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { MINIMAX_FAST_MODE_STREAM_HOOKS } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { fetchMinimaxUsage } from "openclaw/plugin-sdk/provider-usage";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import {
|
||||
@@ -63,7 +63,7 @@ const HYBRID_ANTHROPIC_OPENAI_REPLAY_HOOKS = buildProviderReplayFamilyHooks({
|
||||
});
|
||||
const MINIMAX_PROVIDER_HOOKS = {
|
||||
...HYBRID_ANTHROPIC_OPENAI_REPLAY_HOOKS,
|
||||
...MINIMAX_FAST_MODE_STREAM_HOOKS,
|
||||
...buildProviderStreamFamilyHooks("minimax-fast-mode"),
|
||||
resolveReasoningOutputMode: () => "native" as const,
|
||||
resolveThinkingProfile: ({ modelId }: { modelId: string }) =>
|
||||
resolveMinimaxThinkingProfile(modelId),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Moonshot plugin entrypoint registers its OpenClaw integration.
|
||||
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
||||
import { buildOpenAICompatibleReplayPolicy } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { MOONSHOT_THINKING_STREAM_HOOKS } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { applyMoonshotNativeStreamingUsageCompat } from "./api.js";
|
||||
import { moonshotMediaUnderstandingProvider } from "./media-understanding-provider.js";
|
||||
import {
|
||||
@@ -14,7 +14,7 @@ import { KIMI_K2_7_CODE_MODEL_ID, resolveThinkingProfile } from "./provider-poli
|
||||
import { createKimiWebSearchProvider } from "./src/kimi-web-search-provider.js";
|
||||
|
||||
const PROVIDER_ID = "moonshot";
|
||||
const moonshotThinkingStreamHooks = MOONSHOT_THINKING_STREAM_HOOKS;
|
||||
const moonshotThinkingStreamHooks = buildProviderStreamFamilyHooks("moonshot-thinking");
|
||||
|
||||
export default defineSingleProviderPluginEntry({
|
||||
id: PROVIDER_ID,
|
||||
|
||||
@@ -25,7 +25,7 @@ import type {
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import {
|
||||
buildOpenAICompatibleReplayPolicy,
|
||||
OPENAI_COMPATIBLE_REPLAY_HOOKS,
|
||||
buildProviderReplayFamilyHooks,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import {
|
||||
buildOllamaModelDefinition,
|
||||
@@ -540,7 +540,7 @@ export default definePluginEntry({
|
||||
) ?? OLLAMA_CLOUD_BASE_URL,
|
||||
});
|
||||
},
|
||||
...OPENAI_COMPATIBLE_REPLAY_HOOKS,
|
||||
...buildProviderReplayFamilyHooks({ family: "openai-compatible" }),
|
||||
buildReplayPolicy: (ctx) =>
|
||||
ctx.modelApi === "ollama"
|
||||
? buildNativeOllamaReplayPolicy()
|
||||
@@ -671,7 +671,7 @@ export default definePluginEntry({
|
||||
),
|
||||
});
|
||||
},
|
||||
...OPENAI_COMPATIBLE_REPLAY_HOOKS,
|
||||
...buildProviderReplayFamilyHooks({ family: "openai-compatible" }),
|
||||
buildReplayPolicy: (ctx) =>
|
||||
ctx.modelApi === "ollama"
|
||||
? buildNativeOllamaReplayPolicy()
|
||||
|
||||
@@ -4,9 +4,7 @@ export type {
|
||||
OAuthCredentials,
|
||||
OAuthLoginCallbacks,
|
||||
OAuthPrompt,
|
||||
OAuthProvider,
|
||||
OAuthProviderId,
|
||||
OAuthProviderInfo,
|
||||
OAuthProviderInterface,
|
||||
OAuthSelectOption,
|
||||
OAuthSelectPrompt,
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
matchesExactOrPrefix,
|
||||
type ProviderPlugin,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { OPENAI_RESPONSES_STREAM_HOOKS } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
import { createOpenAINativeWebSearchWrapper } from "./native-web-search.js";
|
||||
import { buildOpenAIReplayPolicy } from "./replay-policy.js";
|
||||
@@ -78,7 +78,8 @@ const resolveOpenAIResponsesWebSocketSessionPolicy: NonNullable<
|
||||
OpenAIResponsesProviderHooks["resolveWebSocketSessionPolicy"]
|
||||
> = (ctx) => resolveOpenAIWebSocketSessionPolicy(ctx);
|
||||
|
||||
const wrapOpenAIResponsesStreamFn = OPENAI_RESPONSES_STREAM_HOOKS.wrapStreamFn;
|
||||
const openAIResponsesStreamHooks = buildProviderStreamFamilyHooks("openai-responses-defaults");
|
||||
const wrapOpenAIResponsesStreamFn = openAIResponsesStreamHooks.wrapStreamFn;
|
||||
const wrapOpenAIResponsesProviderStreamFn: NonNullable<
|
||||
OpenAIResponsesProviderHooks["wrapStreamFn"]
|
||||
> = (ctx) =>
|
||||
@@ -94,7 +95,7 @@ export function buildOpenAIResponsesProviderHooks(options?: {
|
||||
return {
|
||||
buildReplayPolicy: buildOpenAIReplayPolicy,
|
||||
prepareExtraParams: (ctx) => defaultOpenAIResponsesExtraParams(ctx.extraParams, options),
|
||||
...OPENAI_RESPONSES_STREAM_HOOKS,
|
||||
...openAIResponsesStreamHooks,
|
||||
wrapStreamFn: wrapOpenAIResponsesProviderStreamFn,
|
||||
resolveTransportTurnState: resolveOpenAIResponsesTransportTurnState,
|
||||
resolveWebSocketSessionPolicy: resolveOpenAIResponsesWebSocketSessionPolicy,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Opencode Go plugin entrypoint registers its OpenClaw integration.
|
||||
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
|
||||
import { PASSTHROUGH_GEMINI_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { applyOpencodeGoConfig, OPENCODE_GO_DEFAULT_MODEL_REF } from "./api.js";
|
||||
import { opencodeGoMediaUnderstandingProvider } from "./media-understanding-provider.js";
|
||||
import {
|
||||
@@ -135,7 +135,7 @@ export default definePluginEntry({
|
||||
},
|
||||
},
|
||||
augmentModelCatalog: () => listOpencodeGoModelCatalogEntries(),
|
||||
...PASSTHROUGH_GEMINI_REPLAY_HOOKS,
|
||||
...buildProviderReplayFamilyHooks({ family: "passthrough-gemini" }),
|
||||
wrapStreamFn: (ctx) => createOpencodeGoWrapper(ctx.streamFn, ctx.thinkingLevel),
|
||||
isModernModelRef: () => true,
|
||||
});
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
|
||||
import {
|
||||
buildProviderReplayFamilyHooks,
|
||||
matchesExactOrPrefix,
|
||||
PASSTHROUGH_GEMINI_REPLAY_HOOKS,
|
||||
resolveClaudeThinkingProfile,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
|
||||
@@ -149,7 +149,7 @@ export default definePluginEntry({
|
||||
},
|
||||
},
|
||||
augmentModelCatalog: () => listOpencodeZenModelCatalogEntries(),
|
||||
...PASSTHROUGH_GEMINI_REPLAY_HOOKS,
|
||||
...buildProviderReplayFamilyHooks({ family: "passthrough-gemini" }),
|
||||
isModernModelRef: ({ modelId }) => isModernOpencodeModel(modelId),
|
||||
resolveThinkingProfile: ({ modelId }) => resolveClaudeThinkingProfile(modelId),
|
||||
});
|
||||
|
||||
@@ -8,8 +8,8 @@ import {
|
||||
} from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
|
||||
import {
|
||||
buildProviderReplayFamilyHooks,
|
||||
DEFAULT_CONTEXT_TOKENS,
|
||||
PASSTHROUGH_GEMINI_REPLAY_HOOKS,
|
||||
} from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import {
|
||||
getOpenRouterModelCapabilities,
|
||||
@@ -263,7 +263,10 @@ export default definePluginEntry({
|
||||
return OPENROUTER_CACHE_TTL_MODEL_PREFIXES.some((prefix) => modelId.startsWith(prefix));
|
||||
}
|
||||
|
||||
const passthroughReplayHook = PASSTHROUGH_GEMINI_REPLAY_HOOKS.buildReplayPolicy;
|
||||
const passthroughGeminiReplayHooks = buildProviderReplayFamilyHooks({
|
||||
family: "passthrough-gemini",
|
||||
});
|
||||
const passthroughReplayHook = passthroughGeminiReplayHooks.buildReplayPolicy;
|
||||
function buildOpenRouterReplayPolicy(ctx: ProviderReplayPolicyContext): ProviderReplayPolicy {
|
||||
const base = passthroughReplayHook?.(ctx) ?? {};
|
||||
// OpenRouter proxies Mistral, which uses non-base62 tool_call_ids and
|
||||
@@ -352,7 +355,7 @@ export default definePluginEntry({
|
||||
}
|
||||
: undefined;
|
||||
},
|
||||
...PASSTHROUGH_GEMINI_REPLAY_HOOKS,
|
||||
...passthroughGeminiReplayHooks,
|
||||
buildReplayPolicy: buildOpenRouterReplayPolicy,
|
||||
resolveReasoningOutputMode: () => "native",
|
||||
supportsXHighThinking: ({ modelId }) => supportsOpenRouterXHighThinking(modelId),
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// Openrouter plugin module implements stream behavior.
|
||||
import type { StreamFn } from "openclaw/plugin-sdk/agent-core";
|
||||
import type { ProviderWrapStreamFnContext } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { OPENROUTER_THINKING_STREAM_HOOKS } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { buildProviderStreamFamilyHooks } from "openclaw/plugin-sdk/provider-stream-family";
|
||||
import { createPayloadPatchStreamWrapper } from "openclaw/plugin-sdk/provider-stream-shared";
|
||||
import { createSubsystemLogger } from "openclaw/plugin-sdk/runtime-env";
|
||||
import { isOpenRouterDeepSeekV4ModelId } from "./models.js";
|
||||
@@ -12,6 +12,7 @@ import {
|
||||
} from "./provider-catalog.js";
|
||||
|
||||
const log = createSubsystemLogger("openrouter-stream");
|
||||
const openRouterThinkingStreamHooks = buildProviderStreamFamilyHooks("openrouter-thinking");
|
||||
|
||||
function readString(value: unknown): string | undefined {
|
||||
return typeof value === "string" ? value.trim() : undefined;
|
||||
@@ -312,7 +313,7 @@ export function wrapOpenRouterProviderStream(
|
||||
const routedStreamFn = providerRouting
|
||||
? injectOpenRouterRouting(ctx.streamFn, providerRouting)
|
||||
: ctx.streamFn;
|
||||
const wrapStreamFn = OPENROUTER_THINKING_STREAM_HOOKS.wrapStreamFn ?? undefined;
|
||||
const wrapStreamFn = openRouterThinkingStreamHooks.wrapStreamFn ?? undefined;
|
||||
if (!wrapStreamFn) {
|
||||
return createOpenRouterAnthropicPrefillWrapper(
|
||||
createOpenRouterAuthHeaderWrapper(
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Slack tests cover outbound delivery plugin behavior.
|
||||
import { sendDurableMessageBatch } from "openclaw/plugin-sdk/channel-outbound";
|
||||
import {
|
||||
addTestHook,
|
||||
createEmptyPluginRegistry,
|
||||
createOutboundTestPlugin,
|
||||
createTestRegistry,
|
||||
deliverOutboundPayloads,
|
||||
initializeGlobalHookRunner,
|
||||
releasePinnedPluginChannelRegistry,
|
||||
resetGlobalHookRunner,
|
||||
@@ -68,7 +68,7 @@ describe("slack outbound shared hook wiring", () => {
|
||||
});
|
||||
initializeGlobalHookRunner(hookRegistry);
|
||||
|
||||
await deliverOutboundPayloads({
|
||||
await sendDurableMessageBatch({
|
||||
cfg,
|
||||
channel: "slack",
|
||||
to: "C123",
|
||||
@@ -99,7 +99,7 @@ describe("slack outbound shared hook wiring", () => {
|
||||
});
|
||||
|
||||
it("passes replyToId as Slack threadTs for threaded outbound delivery", async () => {
|
||||
await deliverOutboundPayloads({
|
||||
await sendDurableMessageBatch({
|
||||
cfg,
|
||||
channel: "slack",
|
||||
to: "C123",
|
||||
@@ -131,7 +131,7 @@ describe("slack outbound shared hook wiring", () => {
|
||||
});
|
||||
initializeGlobalHookRunner(hookRegistry);
|
||||
|
||||
const result = await deliverOutboundPayloads({
|
||||
const result = await sendDurableMessageBatch({
|
||||
cfg,
|
||||
channel: "slack",
|
||||
to: "C123",
|
||||
@@ -142,6 +142,6 @@ describe("slack outbound shared hook wiring", () => {
|
||||
|
||||
expect(handler).toHaveBeenCalledTimes(1);
|
||||
expect(sendMessageSlackMock).not.toHaveBeenCalled();
|
||||
expect(result).toStrictEqual([]);
|
||||
expect(result).toMatchObject({ status: "suppressed", results: [] });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -10,7 +10,6 @@ export {
|
||||
type RuntimeEnv,
|
||||
SsrFBlockedError,
|
||||
type SsrFPolicy,
|
||||
ssrfPolicyFromAllowPrivateNetwork,
|
||||
ssrfPolicyFromDangerouslyAllowPrivateNetwork,
|
||||
} from "./runtime-api.js";
|
||||
export { tlonPlugin } from "./src/channel.js";
|
||||
|
||||
@@ -9,7 +9,6 @@ export { createLoggerBackedRuntime } from "./src/logger-runtime.js";
|
||||
export {
|
||||
fetchWithSsrFGuard,
|
||||
isBlockedHostnameOrIp,
|
||||
ssrfPolicyFromAllowPrivateNetwork,
|
||||
ssrfPolicyFromDangerouslyAllowPrivateNetwork,
|
||||
type LookupFn,
|
||||
type SsrFPolicy,
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
// cannot drift apart unnoticed.
|
||||
import http from "node:http";
|
||||
import { expectDefined } from "@openclaw/normalization-core";
|
||||
import { sendDurableMessageBatch } from "openclaw/plugin-sdk/channel-outbound";
|
||||
import {
|
||||
createTestRegistry,
|
||||
deliverOutboundPayloads,
|
||||
releasePinnedPluginChannelRegistry,
|
||||
setActivePluginRegistry,
|
||||
} from "openclaw/plugin-sdk/channel-test-helpers";
|
||||
@@ -102,7 +102,7 @@ describe("tlon outbound assistant-visible sanitization", () => {
|
||||
},
|
||||
} as OpenClawConfig;
|
||||
|
||||
await deliverOutboundPayloads({
|
||||
await sendDurableMessageBatch({
|
||||
cfg,
|
||||
channel: "tlon",
|
||||
to: "~sampel-palnet",
|
||||
@@ -121,7 +121,7 @@ describe("tlon outbound assistant-visible sanitization", () => {
|
||||
skipQueue: true,
|
||||
});
|
||||
|
||||
await deliverOutboundPayloads({
|
||||
await sendDurableMessageBatch({
|
||||
cfg,
|
||||
channel: "tlon",
|
||||
to: "chat/~host-ship/general",
|
||||
@@ -133,7 +133,7 @@ describe("tlon outbound assistant-visible sanitization", () => {
|
||||
skipQueue: true,
|
||||
});
|
||||
|
||||
await deliverOutboundPayloads({
|
||||
await sendDurableMessageBatch({
|
||||
cfg,
|
||||
channel: "tlon",
|
||||
to: "~sampel-palnet",
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Whatsapp tests cover the durable outbound handoff across startup recovery.
|
||||
import { sendDurableMessageBatch } from "openclaw/plugin-sdk/channel-outbound";
|
||||
import {
|
||||
createEmptyPluginRegistry,
|
||||
createOutboundTestPlugin,
|
||||
createTestRegistry,
|
||||
deliverOutboundPayloads,
|
||||
releasePinnedPluginChannelRegistry,
|
||||
setActivePluginRegistry,
|
||||
} from "openclaw/plugin-sdk/channel-test-helpers";
|
||||
@@ -76,15 +76,18 @@ describe("WhatsApp delivery recovery", () => {
|
||||
|
||||
it("keeps pre-connect recovery replayable, then sends exactly once after connect", async () => {
|
||||
await withStateDirEnv("openclaw-whatsapp-delivery-recovery-", async ({ stateDir }) => {
|
||||
const initialError = await deliverOutboundPayloads({
|
||||
const initialResult = await sendDurableMessageBatch({
|
||||
cfg,
|
||||
channel: "whatsapp",
|
||||
to: "+1555",
|
||||
payloads: [{ text: "queued before listener startup" }],
|
||||
queuePolicy: "required",
|
||||
}).catch((err: unknown) => err);
|
||||
expect(initialError).toMatchObject({
|
||||
cause: expect.any(PlatformMessageNotDispatchedError),
|
||||
durability: "required",
|
||||
});
|
||||
expect(initialResult).toMatchObject({
|
||||
status: "failed",
|
||||
error: {
|
||||
cause: expect.any(PlatformMessageNotDispatchedError),
|
||||
},
|
||||
});
|
||||
|
||||
const preConnectLog = await drainDefaultWhatsAppDeliveries(stateDir);
|
||||
|
||||
@@ -2,7 +2,7 @@ import { createLazyRuntimeModule } from "openclaw/plugin-sdk/lazy-runtime";
|
||||
// Xai plugin entrypoint registers its OpenClaw integration.
|
||||
import type { OpenClawPluginToolContext } from "openclaw/plugin-sdk/plugin-entry";
|
||||
import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
|
||||
import { OPENAI_COMPATIBLE_REPLAY_HOOKS } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
|
||||
import { defaultToolStreamExtraParams } from "openclaw/plugin-sdk/provider-stream-shared";
|
||||
import { jsonResult } from "openclaw/plugin-sdk/provider-web-search";
|
||||
import {
|
||||
@@ -249,7 +249,7 @@ export default defineSingleProviderPluginEntry({
|
||||
provider: buildXaiProvider(),
|
||||
}),
|
||||
},
|
||||
...OPENAI_COMPATIBLE_REPLAY_HOOKS,
|
||||
...buildProviderReplayFamilyHooks({ family: "openai-compatible" }),
|
||||
prepareExtraParams: (ctx) => defaultToolStreamExtraParams(ctx.extraParams),
|
||||
wrapStreamFn: wrapXaiProviderStream,
|
||||
// Provider-specific fallback auth stays owned by the xAI plugin so core
|
||||
|
||||
@@ -46,6 +46,7 @@ export function shouldRunRuntimeSidecarBaselineCheck(paths: string[]): boolean;
|
||||
export function shouldRunSqliteSessionSchemaBaselineCheck(paths: string[]): boolean;
|
||||
export function shouldRunPluginSdkApiBaselineCheck(paths: string[]): boolean;
|
||||
export function shouldRunPluginSdkSurfaceChecks(paths: string[]): boolean;
|
||||
export function shouldRunDeprecationHygieneChecks(paths: string[]): boolean;
|
||||
export function shouldRunCanvasA2uiNativeResourceCheck(paths: string[]): boolean;
|
||||
export function shouldRunAppcastOwnerTest(paths: string[]): boolean;
|
||||
export function shouldRunTestTempCreationReport(paths: string[]): boolean;
|
||||
|
||||
@@ -43,6 +43,8 @@ const PLUGIN_SDK_API_BASELINE_PATH_RE =
|
||||
/^(?:src\/|packages\/|extensions\/|pnpm-lock\.yaml$|tsconfig\.json$|scripts\/(?:generate-plugin-sdk-api-baseline\.ts|lib\/plugin-sdk-(?:doc-metadata\.ts|entries\.mjs|entrypoints\.json|private-local-only-subpaths\.json))|docs\/\.generated\/plugin-sdk-api-baseline\.sha256$)/u;
|
||||
const PLUGIN_SDK_SURFACE_PATH_RE =
|
||||
/^(?:package\.json$|src\/plugin-sdk\/|scripts\/(?:plugin-sdk-surface-report\.mjs|sync-plugin-sdk-exports\.mjs|lib\/plugin-sdk-(?:declaration-budget\.mjs|deprecated-barrel-subpaths\.json|deprecated-public-subpaths\.json|entries\.mjs|entrypoints\.json|private-local-only-subpaths\.json)))/u;
|
||||
const DEPRECATION_HYGIENE_PATH_RE =
|
||||
/^(?:package\.json$|src\/|extensions\/|packages\/|scripts\/(?:check-deprecated-api-usage\.mjs$|plugin-boundary-report\.ts$|lib\/plugin-sdk))/u;
|
||||
const CANVAS_A2UI_NATIVE_RESOURCE_PATH_RE =
|
||||
/^(?:pnpm-lock\.yaml$|apps\/shared\/OpenClawKit\/Sources\/OpenClawKit\/Resources\/CanvasA2UI\/|extensions\/canvas\/(?:package\.json$|scripts\/bundle-a2ui\.mjs$|src\/host\/a2ui(?:\/(?:index\.html|a2ui\.bundle\.js|\.bundle\.hash)$|-app\/))|scripts\/(?:bundle-a2ui|sync-native-a2ui)\.mjs$)/u;
|
||||
const CONTROL_UI_I18N_VERIFY_PATH_RE =
|
||||
@@ -311,6 +313,13 @@ export function shouldRunPluginSdkSurfaceChecks(paths) {
|
||||
);
|
||||
}
|
||||
|
||||
/** Returns whether changed files can alter deprecated API or plugin-boundary results. */
|
||||
export function shouldRunDeprecationHygieneChecks(paths) {
|
||||
return paths.some((changedPath) =>
|
||||
DEPRECATION_HYGIENE_PATH_RE.test(normalizeChangedPath(changedPath)),
|
||||
);
|
||||
}
|
||||
|
||||
export function shouldRunCanvasA2uiNativeResourceCheck(paths) {
|
||||
return paths.some((changedPath) =>
|
||||
CANVAS_A2UI_NATIVE_RESOURCE_PATH_RE.test(normalizeChangedPath(changedPath)),
|
||||
@@ -462,6 +471,12 @@ export function createChangedCheckPlan(result, options = {}) {
|
||||
add("Plugin SDK package exports", ["plugin-sdk:check-exports"]);
|
||||
add("Plugin SDK surface budget", ["plugin-sdk:surface:check"]);
|
||||
}
|
||||
if (result.lanes.all || shouldRunDeprecationHygieneChecks(result.paths)) {
|
||||
add("deprecated API usage", ["check:deprecated-api-usage"]);
|
||||
// After 2026-07-24, lapsed compatibility windows intentionally fail this gate
|
||||
// until their scheduled deletion PRs land.
|
||||
add("plugin boundaries", ["plugins:boundary-report:ci"]);
|
||||
}
|
||||
if (shouldRunCanvasA2uiNativeResourceCheck(result.paths)) {
|
||||
addCommand(
|
||||
"Canvas A2UI native resource sync",
|
||||
|
||||
@@ -213,10 +213,8 @@ const rules = [
|
||||
"src/infra/outbound/deliver.ts",
|
||||
"src/plugin-sdk/channel-message-runtime.ts",
|
||||
"src/plugin-sdk/channel-message.ts",
|
||||
"src/plugin-sdk/channel-test-helpers.ts",
|
||||
"src/plugin-sdk/inbound-reply-dispatch.ts",
|
||||
"src/plugin-sdk/outbound-runtime.ts",
|
||||
"src/plugin-sdk/test-helpers/outbound-delivery.ts",
|
||||
],
|
||||
message: "use sendDurableMessageBatch or deliverInboundReplyWithMessageSendContext",
|
||||
},
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
[
|
||||
"agent-config-primitives",
|
||||
"agent-runtime-test-contracts",
|
||||
"channel-config-schema-legacy",
|
||||
"channel-contract-testing",
|
||||
"channel-envelope",
|
||||
"channel-inbound-roots",
|
||||
"channel-lifecycle",
|
||||
@@ -16,8 +14,6 @@
|
||||
"channel-runtime",
|
||||
"channel-secret-runtime",
|
||||
"channel-streaming",
|
||||
"channel-target-testing",
|
||||
"channel-test-helpers",
|
||||
"command-auth",
|
||||
"compat",
|
||||
"config-runtime",
|
||||
@@ -43,11 +39,7 @@
|
||||
"music-generation-core",
|
||||
"outbound-runtime",
|
||||
"outbound-send-deps",
|
||||
"plugin-test-api",
|
||||
"plugin-test-contracts",
|
||||
"provider-auth-login",
|
||||
"provider-http-test-mocks",
|
||||
"provider-test-contracts",
|
||||
"provider-zai-endpoint",
|
||||
"reply-dedupe",
|
||||
"runtime-logger",
|
||||
@@ -56,9 +48,6 @@
|
||||
"setup-adapter-runtime",
|
||||
"telegram-account",
|
||||
"telegram-command-config",
|
||||
"test-env",
|
||||
"test-fixtures",
|
||||
"test-node-mocks",
|
||||
"text-runtime",
|
||||
"webhook-path",
|
||||
"zalouser",
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
getOAuthApiKey,
|
||||
getOAuthProviders,
|
||||
type OAuthCredentials,
|
||||
type OAuthProvider,
|
||||
type OAuthProviderId,
|
||||
} from "../../llm/oauth.js";
|
||||
import {
|
||||
formatProviderAuthProfileApiKeyWithPlugin,
|
||||
@@ -67,10 +67,10 @@ function listOAuthProviderIds(): string[] {
|
||||
|
||||
const OAUTH_PROVIDER_IDS = new Set<string>(listOAuthProviderIds());
|
||||
|
||||
const isOAuthProvider = (provider: string): provider is OAuthProvider =>
|
||||
const isOAuthProvider = (provider: string): provider is OAuthProviderId =>
|
||||
OAUTH_PROVIDER_IDS.has(provider);
|
||||
|
||||
const resolveOAuthProvider = (provider: string): OAuthProvider | null =>
|
||||
const resolveOAuthProvider = (provider: string): OAuthProviderId | null =>
|
||||
isOAuthProvider(provider) ? provider : null;
|
||||
|
||||
/** Bearer-token auth modes that are interchangeable (oauth tokens and raw tokens). */
|
||||
|
||||
@@ -3,7 +3,6 @@ export type {
|
||||
OAuthCredentials,
|
||||
OAuthLoginCallbacks,
|
||||
OAuthPrompt,
|
||||
OAuthProvider,
|
||||
OAuthProviderId,
|
||||
OAuthProviderInterface,
|
||||
} from "../../../plugin-sdk/provider-oauth-runtime.js";
|
||||
|
||||
@@ -19,8 +19,6 @@ export {
|
||||
setActivePluginRegistry,
|
||||
type PluginHookRegistration,
|
||||
} from "./test-helpers/outbound-delivery.js";
|
||||
/** @deprecated Direct outbound delivery is runtime substrate; use channel message runtime helpers. */
|
||||
export { deliverOutboundPayloads } from "./test-helpers/outbound-delivery.js";
|
||||
export {
|
||||
createPluginRuntimeMediaMock,
|
||||
createPluginRuntimeMock,
|
||||
|
||||
@@ -11,5 +11,3 @@ export {
|
||||
setActivePluginRegistry,
|
||||
} from "../../plugins/runtime.js";
|
||||
export { createOutboundTestPlugin, createTestRegistry } from "../../test-utils/channel-plugins.js";
|
||||
/** @deprecated Direct outbound delivery is runtime substrate; use channel message runtime helpers. */
|
||||
export { deliverOutboundPayloads } from "../../infra/outbound/deliver.js";
|
||||
|
||||
@@ -149,7 +149,7 @@ const RUNTIME_API_EXPORT_GUARDS: Record<string, readonly string[]> = {
|
||||
'export { getMatrixScopedEnvVarNames, listMatrixEnvAccountIds, resolveMatrixEnvAccountToken } from "./src/env-vars.js";',
|
||||
'export { hashMatrixAccessToken, resolveMatrixAccountStorageRoot, resolveMatrixCredentialsDir, resolveMatrixCredentialsFilename, resolveMatrixCredentialsPath, resolveMatrixHomeserverKey, sanitizeMatrixPathSegment } from "./src/storage-paths.js";',
|
||||
'export { ensureMatrixSdkInstalled, isMatrixSdkAvailable } from "./src/matrix/deps.js";',
|
||||
'export { assertHttpUrlTargetsPrivateNetwork, closeDispatcher, createPinnedDispatcher, resolvePinnedHostnameWithPolicy, ssrfPolicyFromDangerouslyAllowPrivateNetwork, ssrfPolicyFromAllowPrivateNetwork, type LookupFn, type SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";',
|
||||
'export { assertHttpUrlTargetsPrivateNetwork, closeDispatcher, createPinnedDispatcher, resolvePinnedHostnameWithPolicy, ssrfPolicyFromDangerouslyAllowPrivateNetwork, type LookupFn, type SsrFPolicy } from "openclaw/plugin-sdk/ssrf-runtime";',
|
||||
'export { setMatrixThreadBindingIdleTimeoutBySessionKey, setMatrixThreadBindingMaxAgeBySessionKey } from "./src/matrix/thread-bindings-shared.js";',
|
||||
'export { setMatrixRuntime } from "./src/runtime.js";',
|
||||
'export { writeJsonFileAtomically } from "openclaw/plugin-sdk/json-store";',
|
||||
|
||||
@@ -32,6 +32,7 @@ const SHARED_FAMILY_HOOK_PATTERNS: ReadonlyArray<{
|
||||
const PROVIDER_BOUNDARY_TEST_SIGNALS = [
|
||||
/\bregister(?:Single)?ProviderPlugin\s*\(/u,
|
||||
/\bcreateTestPluginApi\s*\(/u,
|
||||
/\bcapturePluginRegistration\s*\(/u,
|
||||
/\bexpectPassthroughReplayPolicy\s*\(/u,
|
||||
] as const;
|
||||
const EXPECTED_SENTINEL_SHARED_FAMILY_ASSIGNMENTS: Record<string, ExpectedSharedFamilyContract> = {
|
||||
@@ -41,8 +42,10 @@ const EXPECTED_SENTINEL_SHARED_FAMILY_ASSIGNMENTS: Record<string, ExpectedShared
|
||||
},
|
||||
minimax: {
|
||||
replayFamilies: ["hybrid-anthropic-openai"],
|
||||
streamFamilies: ["minimax-fast-mode"],
|
||||
},
|
||||
openai: {
|
||||
streamFamilies: ["openai-responses-defaults"],
|
||||
toolCompatFamilies: ["openai"],
|
||||
},
|
||||
};
|
||||
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
shouldRunRuntimeSidecarBaselineCheck,
|
||||
shouldRunShrinkwrapGuard,
|
||||
shouldRunPluginSdkApiBaselineCheck,
|
||||
shouldRunDeprecationHygieneChecks,
|
||||
shouldRunPluginSdkSurfaceChecks,
|
||||
shouldRunSqliteSessionSchemaBaselineCheck,
|
||||
shouldRunTestTempCreationReport,
|
||||
@@ -1436,6 +1437,8 @@ describe("scripts/changed-lanes", () => {
|
||||
"duplicate scan target coverage",
|
||||
"dependency pin guard",
|
||||
"format changed files",
|
||||
"deprecated API usage",
|
||||
"plugin boundaries",
|
||||
"package patch guard",
|
||||
"test temp creation report (warning-only)",
|
||||
"typecheck core tests",
|
||||
@@ -1721,6 +1724,8 @@ describe("scripts/changed-lanes", () => {
|
||||
"deps:pins:check",
|
||||
"format:check",
|
||||
"scripts/generate-npm-shrinkwrap.mjs",
|
||||
"check:deprecated-api-usage",
|
||||
"plugins:boundary-report:ci",
|
||||
"deps:patches:check",
|
||||
"release-metadata:check",
|
||||
"android:version:check",
|
||||
@@ -1926,6 +1931,37 @@ describe("scripts/changed-lanes", () => {
|
||||
);
|
||||
});
|
||||
|
||||
it("runs deprecation hygiene checks for outcome-changing paths and all lanes", () => {
|
||||
expect(
|
||||
shouldRunDeprecationHygieneChecks([
|
||||
"src/plugin-sdk/core.ts",
|
||||
"extensions/slack/index.ts",
|
||||
"packages/gateway-protocol/src/index.ts",
|
||||
"scripts/lib/plugin-sdk-entries.mjs",
|
||||
"scripts/check-deprecated-api-usage.mjs",
|
||||
"scripts/plugin-boundary-report.ts",
|
||||
"src/plugins/compat/registry.ts",
|
||||
"package.json",
|
||||
]),
|
||||
).toBe(true);
|
||||
expect(shouldRunDeprecationHygieneChecks(["docs/plugins/sdk-migration.md"])).toBe(false);
|
||||
|
||||
for (const result of [
|
||||
detectChangedLanes(["extensions/slack/index.ts"]),
|
||||
detectChangedLanes(["unknown-surface.foo"]),
|
||||
]) {
|
||||
const plan = createChangedCheckPlan(result);
|
||||
expect(plan.commands).toContainEqual({
|
||||
name: "deprecated API usage",
|
||||
args: ["check:deprecated-api-usage"],
|
||||
});
|
||||
expect(plan.commands).toContainEqual({
|
||||
name: "plugin boundaries",
|
||||
args: ["plugins:boundary-report:ci"],
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
it("guards release metadata package changes to the top-level version field", () => {
|
||||
const dir = makeTempRepoRoot(tempDirs, "openclaw-release-metadata-");
|
||||
git(dir, ["init", "-q", "--initial-branch=main"]);
|
||||
|
||||
Reference in New Issue
Block a user