@@ -207,6 +207,69 @@ describe("provider public artifacts", () => {
|
207 | 207 | expect(loadPluginManifestRegistry).not.toHaveBeenCalled(); |
208 | 208 | }); |
209 | 209 | |
| 210 | +it("resolves bundled policy artifacts for a plugin-owned CLI backend", async () => { |
| 211 | +const loadPluginManifestRegistry = vi.fn(() => { |
| 212 | +throw new Error("unexpected manifest registry scan"); |
| 213 | +}); |
| 214 | +const loadBundledPluginPublicArtifactModuleSync = vi.fn(({ dirName }: { dirName: string }) => { |
| 215 | +if (dirName !== "anthropic") { |
| 216 | +throw new Error(`Unable to resolve bundled plugin public surface ${dirName}`); |
| 217 | +} |
| 218 | +return { |
| 219 | +resolveThinkingProfile: ({ provider }: { provider: string }) => ({ |
| 220 | +levels: [{ id: provider }], |
| 221 | +}), |
| 222 | +}; |
| 223 | +}); |
| 224 | + |
| 225 | +vi.doMock("./manifest-registry.js", async (importOriginal) => { |
| 226 | +const actual = await importOriginal<typeof import("./manifest-registry.js")>(); |
| 227 | +return { |
| 228 | + ...actual, |
| 229 | + loadPluginManifestRegistry, |
| 230 | +}; |
| 231 | +}); |
| 232 | +vi.doMock("./public-surface-loader.js", () => ({ |
| 233 | + loadBundledPluginPublicArtifactModuleSync, |
| 234 | +})); |
| 235 | + |
| 236 | +const { resolveBundledProviderPolicySurface: resolvePolicySurface } = await importFreshModule< |
| 237 | +typeof import("./provider-public-artifacts.js") |
| 238 | +>(import.meta.url, "./provider-public-artifacts.js?scope=provider-cli-backend"); |
| 239 | + |
| 240 | +// CLI backend ids use the same provider-policy owner boundary as provider ids. |
| 241 | +// Without it, claude-cli subagents fall back to the base thinking profile. |
| 242 | +const surface = resolvePolicySurface("claude-cli", { |
| 243 | +manifestRegistry: { |
| 244 | +plugins: [ |
| 245 | +{ |
| 246 | +id: "anthropic", |
| 247 | +channels: [], |
| 248 | +cliBackends: ["claude-cli"], |
| 249 | +hooks: [], |
| 250 | +origin: "bundled", |
| 251 | +manifestPath: "/tmp/anthropic/openclaw.plugin.json", |
| 252 | +providers: ["anthropic"], |
| 253 | +rootDir: "/tmp/anthropic", |
| 254 | +skills: [], |
| 255 | +source: "/tmp/anthropic/index.js", |
| 256 | +}, |
| 257 | +], |
| 258 | +}, |
| 259 | +}); |
| 260 | + |
| 261 | +expect( |
| 262 | +surface?.resolveThinkingProfile?.({ provider: "claude-cli", modelId: "claude-opus-4-8" }), |
| 263 | +).toEqual({ |
| 264 | +levels: [{ id: "claude-cli" }], |
| 265 | +}); |
| 266 | +expect(loadBundledPluginPublicArtifactModuleSync).toHaveBeenCalledWith({ |
| 267 | +dirName: "anthropic", |
| 268 | +artifactBasename: "provider-policy-api.js", |
| 269 | +}); |
| 270 | +expect(loadPluginManifestRegistry).not.toHaveBeenCalled(); |
| 271 | +}); |
| 272 | + |
210 | 273 | it("does not cache manifest-owned provider policy aliases across bundled metadata changes", async () => { |
211 | 274 | const bundledPluginsDir = fs.mkdtempSync( |
212 | 275 | path.join(os.tmpdir(), "openclaw-provider-policy-refresh-"), |
|