mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-06 11:00:42 +00:00
perf(secrets): fast-path explicit channel target lookup
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type { OpenClawConfig } from "../config/types.openclaw.js";
|
||||
import { loadBundledChannelSecretContractApi } from "./channel-contract-api.js";
|
||||
import { getPath } from "./path-utils.js";
|
||||
import { getCoreSecretTargetRegistry, getSecretTargetRegistry } from "./target-registry-data.js";
|
||||
import {
|
||||
@@ -31,6 +32,11 @@ let compiledCoreOpenClawTargetState: {
|
||||
targetsByType: Map<string, CompiledTargetRegistryEntry[]>;
|
||||
} | null = null;
|
||||
|
||||
const compiledBundledChannelOpenClawTargets = new Map<
|
||||
string,
|
||||
CompiledTargetRegistryEntry[] | null
|
||||
>();
|
||||
|
||||
function buildTargetTypeIndex(
|
||||
compiledSecretTargetRegistry: CompiledTargetRegistryEntry[],
|
||||
): Map<string, CompiledTargetRegistryEntry[]> {
|
||||
@@ -106,6 +112,24 @@ function getCompiledCoreOpenClawTargetState() {
|
||||
return compiledCoreOpenClawTargetState;
|
||||
}
|
||||
|
||||
function getCompiledBundledChannelOpenClawTargets(
|
||||
channelId: string,
|
||||
): CompiledTargetRegistryEntry[] | null {
|
||||
const normalizedChannelId = channelId.trim();
|
||||
if (!normalizedChannelId) {
|
||||
return null;
|
||||
}
|
||||
if (compiledBundledChannelOpenClawTargets.has(normalizedChannelId)) {
|
||||
return compiledBundledChannelOpenClawTargets.get(normalizedChannelId) ?? null;
|
||||
}
|
||||
const compiledEntries =
|
||||
loadBundledChannelSecretContractApi(normalizedChannelId)
|
||||
?.secretTargetRegistryEntries?.filter((entry) => entry.configFile === "openclaw.json")
|
||||
.map(compileTargetRegistryEntry) ?? null;
|
||||
compiledBundledChannelOpenClawTargets.set(normalizedChannelId, compiledEntries);
|
||||
return compiledEntries;
|
||||
}
|
||||
|
||||
function normalizeAllowedTargetIds(targetIds?: Iterable<string>): Set<string> | null {
|
||||
if (targetIds === undefined) {
|
||||
return null;
|
||||
@@ -292,6 +316,41 @@ function resolvePlanTargetAgainstEntries(
|
||||
}
|
||||
|
||||
export function resolveConfigSecretTargetByPath(pathSegments: string[]): ResolvedPlanTarget | null {
|
||||
for (const entry of getCompiledCoreOpenClawTargetState().openClawCompiledSecretTargets) {
|
||||
if (!entry.includeInPlan) {
|
||||
continue;
|
||||
}
|
||||
const matched = matchPathTokens(pathSegments, entry.pathTokens);
|
||||
if (!matched) {
|
||||
continue;
|
||||
}
|
||||
const resolved = toResolvedPlanTarget(entry, pathSegments, matched.captures);
|
||||
if (!resolved) {
|
||||
continue;
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
const explicitBundledChannelId =
|
||||
pathSegments[0] === "channels" ? (pathSegments[1]?.trim() ?? "") : "";
|
||||
const explicitBundledChannelEntries = explicitBundledChannelId
|
||||
? getCompiledBundledChannelOpenClawTargets(explicitBundledChannelId)
|
||||
: null;
|
||||
for (const entry of explicitBundledChannelEntries ?? []) {
|
||||
if (!entry.includeInPlan) {
|
||||
continue;
|
||||
}
|
||||
const matched = matchPathTokens(pathSegments, entry.pathTokens);
|
||||
if (!matched) {
|
||||
continue;
|
||||
}
|
||||
const resolved = toResolvedPlanTarget(entry, pathSegments, matched.captures);
|
||||
if (!resolved) {
|
||||
continue;
|
||||
}
|
||||
return resolved;
|
||||
}
|
||||
|
||||
for (const entry of getCompiledSecretTargetRegistryState().openClawCompiledSecretTargets) {
|
||||
if (!entry.includeInPlan) {
|
||||
continue;
|
||||
|
||||
65
src/secrets/target-registry.fast-path.test.ts
Normal file
65
src/secrets/target-registry.fast-path.test.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const { loadPluginManifestRegistryMock } = vi.hoisted(() => ({
|
||||
loadPluginManifestRegistryMock: vi.fn(() => {
|
||||
throw new Error("manifest registry should stay off the explicit channel target fast path");
|
||||
}),
|
||||
}));
|
||||
|
||||
const { loadBundledPluginPublicArtifactModuleSyncMock } = vi.hoisted(() => ({
|
||||
loadBundledPluginPublicArtifactModuleSyncMock: vi.fn(
|
||||
({ artifactBasename, dirName }: { artifactBasename: string; dirName: string }) => {
|
||||
if (dirName === "googlechat" && artifactBasename === "secret-contract-api.js") {
|
||||
return {
|
||||
secretTargetRegistryEntries: [
|
||||
{
|
||||
id: "channels.googlechat.serviceAccount",
|
||||
targetType: "channels.googlechat.serviceAccount",
|
||||
configFile: "openclaw.json",
|
||||
pathPattern: "channels.googlechat.serviceAccount",
|
||||
refPathPattern: "channels.googlechat.serviceAccountRef",
|
||||
secretShape: "sibling_ref",
|
||||
expectedResolvedValue: "string",
|
||||
includeInPlan: true,
|
||||
includeInConfigure: true,
|
||||
includeInAudit: true,
|
||||
},
|
||||
],
|
||||
};
|
||||
}
|
||||
throw new Error(
|
||||
`Unable to resolve bundled plugin public surface ${dirName}/${artifactBasename}`,
|
||||
);
|
||||
},
|
||||
),
|
||||
}));
|
||||
|
||||
vi.mock("../plugins/manifest-registry.js", () => ({
|
||||
loadPluginManifestRegistry: loadPluginManifestRegistryMock,
|
||||
}));
|
||||
|
||||
vi.mock("../plugins/public-surface-loader.js", () => ({
|
||||
loadBundledPluginPublicArtifactModuleSync: loadBundledPluginPublicArtifactModuleSyncMock,
|
||||
}));
|
||||
|
||||
import { resolveConfigSecretTargetByPath } from "./target-registry.js";
|
||||
|
||||
describe("secret target registry fast path", () => {
|
||||
beforeEach(() => {
|
||||
loadPluginManifestRegistryMock.mockClear();
|
||||
loadBundledPluginPublicArtifactModuleSyncMock.mockClear();
|
||||
});
|
||||
|
||||
it("resolves bundled channel targets by explicit channel id without manifest scans", () => {
|
||||
const target = resolveConfigSecretTargetByPath(["channels", "googlechat", "serviceAccount"]);
|
||||
|
||||
expect(target).not.toBeNull();
|
||||
expect(target?.entry.id).toBe("channels.googlechat.serviceAccount");
|
||||
expect(target?.refPathSegments).toEqual(["channels", "googlechat", "serviceAccountRef"]);
|
||||
expect(loadBundledPluginPublicArtifactModuleSyncMock).toHaveBeenCalledWith({
|
||||
dirName: "googlechat",
|
||||
artifactBasename: "secret-contract-api.js",
|
||||
});
|
||||
expect(loadPluginManifestRegistryMock).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user