mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 12:20:44 +00:00
perf(test): slim directive and run-param imports
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { type ModelAliasIndex, modelKey } from "../agents/model-selection.js";
|
||||
import { resolveModelDirectiveSelection } from "./reply/model-selection.js";
|
||||
import type { ModelAliasIndex } from "../agents/model-selection-shared.js";
|
||||
import { resolveModelDirectiveSelection } from "./reply/model-selection-directive.js";
|
||||
|
||||
const emptyAliasIndex: ModelAliasIndex = {
|
||||
byAlias: new Map(),
|
||||
@@ -79,7 +79,7 @@ describe("directive behavior model fuzzy selection", () => {
|
||||
},
|
||||
],
|
||||
]),
|
||||
byKey: new Map([[modelKey("moonshot", "kimi-k2-0905-preview"), ["Kimi"]]]),
|
||||
byKey: new Map([["moonshot/kimi-k2-0905-preview", ["Kimi"]]]),
|
||||
};
|
||||
|
||||
expect(
|
||||
|
||||
83
src/auto-reply/reply/agent-runner-run-params.ts
Normal file
83
src/auto-reply/reply/agent-runner-run-params.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import { resolveRunModelFallbacksOverride } from "../../agents/agent-scope.js";
|
||||
import type { resolveProviderScopedAuthProfile } from "./agent-runner-auth-profile.js";
|
||||
import type { FollowupRun } from "./queue.js";
|
||||
|
||||
export type ReasoningTagProviderResolver = (
|
||||
provider: string,
|
||||
options: {
|
||||
config: FollowupRun["run"]["config"];
|
||||
workspaceDir: string;
|
||||
modelId: string;
|
||||
},
|
||||
) => boolean;
|
||||
|
||||
export const resolveEnforceFinalTagWithResolver = (
|
||||
run: FollowupRun["run"],
|
||||
provider: string,
|
||||
model = run.model,
|
||||
isReasoningTagProvider?: ReasoningTagProviderResolver,
|
||||
) =>
|
||||
(run.skipProviderRuntimeHints ? false : undefined) ??
|
||||
(run.enforceFinalTag ||
|
||||
isReasoningTagProvider?.(provider, {
|
||||
config: run.config,
|
||||
workspaceDir: run.workspaceDir,
|
||||
modelId: model,
|
||||
}) ||
|
||||
false);
|
||||
|
||||
export function resolveModelFallbackOptions(run: FollowupRun["run"]) {
|
||||
const config = run.config;
|
||||
return {
|
||||
cfg: config,
|
||||
provider: run.provider,
|
||||
model: run.model,
|
||||
agentDir: run.agentDir,
|
||||
fallbacksOverride: resolveRunModelFallbacksOverride({
|
||||
cfg: config,
|
||||
agentId: run.agentId,
|
||||
sessionKey: run.sessionKey,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildEmbeddedRunBaseParams(params: {
|
||||
run: FollowupRun["run"];
|
||||
provider: string;
|
||||
model: string;
|
||||
runId: string;
|
||||
authProfile: ReturnType<typeof resolveProviderScopedAuthProfile>;
|
||||
allowTransientCooldownProbe?: boolean;
|
||||
isReasoningTagProvider?: ReasoningTagProviderResolver;
|
||||
}) {
|
||||
const config = params.run.config;
|
||||
return {
|
||||
sessionFile: params.run.sessionFile,
|
||||
workspaceDir: params.run.workspaceDir,
|
||||
agentDir: params.run.agentDir,
|
||||
config,
|
||||
skillsSnapshot: params.run.skillsSnapshot,
|
||||
ownerNumbers: params.run.ownerNumbers,
|
||||
inputProvenance: params.run.inputProvenance,
|
||||
senderIsOwner: params.run.senderIsOwner,
|
||||
enforceFinalTag: resolveEnforceFinalTagWithResolver(
|
||||
params.run,
|
||||
params.provider,
|
||||
params.model,
|
||||
params.isReasoningTagProvider,
|
||||
),
|
||||
silentExpected: params.run.silentExpected,
|
||||
allowEmptyAssistantReplyAsSilent: params.run.allowEmptyAssistantReplyAsSilent,
|
||||
provider: params.provider,
|
||||
model: params.model,
|
||||
...params.authProfile,
|
||||
thinkLevel: params.run.thinkLevel,
|
||||
verboseLevel: params.run.verboseLevel,
|
||||
reasoningLevel: params.run.reasoningLevel,
|
||||
execOverrides: params.run.execOverrides,
|
||||
bashElevated: params.run.bashElevated,
|
||||
timeoutMs: params.run.timeoutMs,
|
||||
runId: params.runId,
|
||||
allowTransientCooldownProbe: params.allowTransientCooldownProbe,
|
||||
};
|
||||
}
|
||||
@@ -2,12 +2,9 @@ import { afterEach, describe, expect, it } from "vitest";
|
||||
import {
|
||||
clearRuntimeConfigSnapshot,
|
||||
setRuntimeConfigSnapshot,
|
||||
type OpenClawConfig,
|
||||
} from "../../config/config.js";
|
||||
import {
|
||||
buildEmbeddedRunBaseParams,
|
||||
resolveProviderScopedAuthProfile,
|
||||
} from "./agent-runner-utils.js";
|
||||
} from "../../config/runtime-snapshot.js";
|
||||
import type { OpenClawConfig } from "../../config/types.openclaw.js";
|
||||
import { buildEmbeddedRunBaseParams } from "./agent-runner-run-params.js";
|
||||
import type { FollowupRun } from "./queue.js";
|
||||
|
||||
function makeRun(config: OpenClawConfig): FollowupRun["run"] {
|
||||
@@ -73,10 +70,7 @@ describe("buildEmbeddedRunBaseParams runtime config", () => {
|
||||
provider: "openai",
|
||||
model: "gpt-4.1-mini",
|
||||
runId: "run-1",
|
||||
authProfile: resolveProviderScopedAuthProfile({
|
||||
provider: "openai",
|
||||
primaryProvider: "openai",
|
||||
}),
|
||||
authProfile: {},
|
||||
});
|
||||
|
||||
expect(resolved.config).toBe(resolvedRunConfig);
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { resolveRunModelFallbacksOverride } from "../../agents/agent-scope.js";
|
||||
import { getChannelPlugin } from "../../channels/plugins/index.js";
|
||||
import type {
|
||||
ChannelId,
|
||||
@@ -28,6 +27,12 @@ import {
|
||||
resolveRunAuthProfile,
|
||||
} from "./agent-runner-auth-profile.js";
|
||||
export { resolveProviderScopedAuthProfile, resolveRunAuthProfile };
|
||||
import {
|
||||
buildEmbeddedRunBaseParams as buildEmbeddedRunBaseParamsCore,
|
||||
resolveModelFallbackOptions,
|
||||
resolveEnforceFinalTagWithResolver,
|
||||
} from "./agent-runner-run-params.js";
|
||||
export { resolveModelFallbackOptions } from "./agent-runner-run-params.js";
|
||||
import { resolveOriginMessageProvider, resolveOriginMessageTo } from "./origin-routing.js";
|
||||
import type { FollowupRun } from "./queue.js";
|
||||
|
||||
@@ -173,63 +178,15 @@ export const resolveEnforceFinalTag = (
|
||||
run: FollowupRun["run"],
|
||||
provider: string,
|
||||
model = run.model,
|
||||
) =>
|
||||
(run.skipProviderRuntimeHints ? false : undefined) ??
|
||||
(run.enforceFinalTag ||
|
||||
isReasoningTagProvider(provider, {
|
||||
config: run.config,
|
||||
workspaceDir: run.workspaceDir,
|
||||
modelId: model,
|
||||
}));
|
||||
) => resolveEnforceFinalTagWithResolver(run, provider, model, isReasoningTagProvider);
|
||||
|
||||
export function resolveModelFallbackOptions(run: FollowupRun["run"]) {
|
||||
const config = run.config;
|
||||
return {
|
||||
cfg: config,
|
||||
provider: run.provider,
|
||||
model: run.model,
|
||||
agentDir: run.agentDir,
|
||||
fallbacksOverride: resolveRunModelFallbacksOverride({
|
||||
cfg: config,
|
||||
agentId: run.agentId,
|
||||
sessionKey: run.sessionKey,
|
||||
}),
|
||||
};
|
||||
}
|
||||
|
||||
export function buildEmbeddedRunBaseParams(params: {
|
||||
run: FollowupRun["run"];
|
||||
provider: string;
|
||||
model: string;
|
||||
runId: string;
|
||||
authProfile: ReturnType<typeof resolveProviderScopedAuthProfile>;
|
||||
allowTransientCooldownProbe?: boolean;
|
||||
}) {
|
||||
const config = params.run.config;
|
||||
return {
|
||||
sessionFile: params.run.sessionFile,
|
||||
workspaceDir: params.run.workspaceDir,
|
||||
agentDir: params.run.agentDir,
|
||||
config,
|
||||
skillsSnapshot: params.run.skillsSnapshot,
|
||||
ownerNumbers: params.run.ownerNumbers,
|
||||
inputProvenance: params.run.inputProvenance,
|
||||
senderIsOwner: params.run.senderIsOwner,
|
||||
enforceFinalTag: resolveEnforceFinalTag(params.run, params.provider, params.model),
|
||||
silentExpected: params.run.silentExpected,
|
||||
allowEmptyAssistantReplyAsSilent: params.run.allowEmptyAssistantReplyAsSilent,
|
||||
provider: params.provider,
|
||||
model: params.model,
|
||||
...params.authProfile,
|
||||
thinkLevel: params.run.thinkLevel,
|
||||
verboseLevel: params.run.verboseLevel,
|
||||
reasoningLevel: params.run.reasoningLevel,
|
||||
execOverrides: params.run.execOverrides,
|
||||
bashElevated: params.run.bashElevated,
|
||||
timeoutMs: params.run.timeoutMs,
|
||||
runId: params.runId,
|
||||
allowTransientCooldownProbe: params.allowTransientCooldownProbe,
|
||||
};
|
||||
export function buildEmbeddedRunBaseParams(
|
||||
params: Parameters<typeof buildEmbeddedRunBaseParamsCore>[0],
|
||||
) {
|
||||
return buildEmbeddedRunBaseParamsCore({
|
||||
...params,
|
||||
isReasoningTagProvider,
|
||||
});
|
||||
}
|
||||
|
||||
export function buildEmbeddedContextFromTemplate(params: {
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
import { modelKey, normalizeProviderId } from "../../agents/model-selection-normalize.js";
|
||||
import {
|
||||
resolveModelRefFromString,
|
||||
type ModelAliasIndex,
|
||||
} from "../../agents/model-selection-shared.js";
|
||||
import { splitTrailingAuthProfile } from "../../agents/model-ref-profile.js";
|
||||
import { normalizeProviderId } from "../../agents/provider-id.js";
|
||||
import { normalizeLowercaseStringOrEmpty } from "../../shared/string-coerce.js";
|
||||
|
||||
export type ModelAliasIndex = {
|
||||
byAlias: Map<
|
||||
string,
|
||||
{
|
||||
alias: string;
|
||||
ref: { provider: string; model: string };
|
||||
}
|
||||
>;
|
||||
byKey: Map<string, string[]>;
|
||||
};
|
||||
|
||||
export type ModelDirectiveSelection = {
|
||||
provider: string;
|
||||
model: string;
|
||||
@@ -24,6 +32,53 @@ const FUZZY_VARIANT_TOKENS = [
|
||||
"nano",
|
||||
];
|
||||
|
||||
function modelKey(provider: string, model: string): string {
|
||||
const providerId = provider.trim();
|
||||
const modelId = model.trim();
|
||||
if (!providerId) {
|
||||
return modelId;
|
||||
}
|
||||
if (!modelId) {
|
||||
return providerId;
|
||||
}
|
||||
return normalizeLowercaseStringOrEmpty(modelId).startsWith(
|
||||
`${normalizeLowercaseStringOrEmpty(providerId)}/`,
|
||||
)
|
||||
? modelId
|
||||
: `${providerId}/${modelId}`;
|
||||
}
|
||||
|
||||
function resolveModelRefFromDirectiveString(params: {
|
||||
raw: string;
|
||||
defaultProvider: string;
|
||||
aliasIndex: ModelAliasIndex;
|
||||
}): { ref: { provider: string; model: string }; alias?: string } | null {
|
||||
const { model } = splitTrailingAuthProfile(params.raw);
|
||||
if (!model) {
|
||||
return null;
|
||||
}
|
||||
if (!model.includes("/")) {
|
||||
const aliasKey = normalizeLowercaseStringOrEmpty(model);
|
||||
const aliasMatch = params.aliasIndex.byAlias.get(aliasKey);
|
||||
if (aliasMatch) {
|
||||
return { ref: aliasMatch.ref, alias: aliasMatch.alias };
|
||||
}
|
||||
}
|
||||
const trimmed = model.trim();
|
||||
const slash = trimmed.indexOf("/");
|
||||
const providerRaw = slash === -1 ? params.defaultProvider : trimmed.slice(0, slash).trim();
|
||||
const modelRaw = slash === -1 ? trimmed : trimmed.slice(slash + 1).trim();
|
||||
if (!providerRaw || !modelRaw) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
ref: {
|
||||
provider: normalizeProviderId(providerRaw),
|
||||
model: modelRaw,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function boundedLevenshteinDistance(a: string, b: string, maxDistance: number): number | null {
|
||||
if (a === b) {
|
||||
return 0;
|
||||
@@ -299,7 +354,7 @@ export function resolveModelDirectiveSelection(params: {
|
||||
return { selection: buildSelection(best.provider, best.model) };
|
||||
};
|
||||
|
||||
const resolved = resolveModelRefFromString({
|
||||
const resolved = resolveModelRefFromDirectiveString({
|
||||
raw: rawTrimmed,
|
||||
defaultProvider,
|
||||
aliasIndex,
|
||||
|
||||
Reference in New Issue
Block a user