Download src/claws/application-schema.test.ts from SaylorTwift/openclaw: direct link, hf CLI and curl.
- Browser
- Download file 13 kB
-
https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/claws/application-schema.test.ts
- Command line
-
hf download hf://SaylorTwift/openclaw/src/claws/application-schema.test.ts
-
curl -L -o application-schema.test.ts https://huggingface.co/SaylorTwift/openclaw/resolve/main/src/claws/application-schema.test.ts
13 kB
| import { mkdir, realpath, writeFile } from "node:fs/promises"; | |
| import { join } from "node:path"; | |
| import { afterEach, describe, expect, it } from "vitest"; | |
| import { useAutoCleanupTempDirTracker } from "../../test/helpers/temp-dir.js"; | |
| import { clawProfileExtensionPackages } from "./application-plan.js"; | |
| import { buildClawAddPlan, type ClawAddPlanContext } from "./lifecycle.js"; | |
| import { parseClawManifest, parseClawOpenClawProfile } from "./schema.js"; | |
| import type { ClawManifest, ClawSourceIdentity } from "./types.js"; | |
| const tempDirs = useAutoCleanupTempDirTracker(afterEach); | |
| function requireManifest(value: unknown): ClawManifest { | |
| const result = parseClawManifest(value); | |
| if (!result.ok) { | |
| throw new Error(JSON.stringify(result.diagnostics)); | |
| } | |
| return result.manifest; | |
| } | |
| async function createPlanSource(): Promise<{ source: ClawSourceIdentity; workspace: string }> { | |
| const root = tempDirs.make("openclaw-claw-application-plan-"); | |
| await mkdir(join(root, "workspace", "schemas"), { recursive: true }); | |
| await writeFile(join(root, "workspace", "schemas", "market.json"), "{}\n", "utf8"); | |
| return { | |
| source: { | |
| kind: "package", | |
| name: "@acme/market-analyst", | |
| version: "1.0.0", | |
| packageRoot: root, | |
| manifestPath: join(root, "CLAW.md"), | |
| integrityKind: "development-snapshot", | |
| integrity: "sha256:test", | |
| byteLength: 0, | |
| }, | |
| workspace: join(await realpath(root), "new-workspace"), | |
| }; | |
| } | |
| const extension = { | |
| id: "market-data", | |
| kind: "plugin", | |
| format: "claude", | |
| source: "clawhub", | |
| ref: "@acme/market-data", | |
| version: "2.0.1", | |
| } as const; | |
| describe("Claw application schema v1", () => { | |
| it("accepts strict native extension assertions without a schema bump", () => { | |
| expect( | |
| parseClawOpenClawProfile({ | |
| schemaVersion: 1, | |
| agent: { tools: { profile: "coding", allow: ["read"] } }, | |
| extensions: [extension], | |
| }), | |
| ).toMatchObject({ | |
| ok: true, | |
| profile: { schemaVersion: 1, extensions: [{ id: "market-data", format: "claude" }] }, | |
| }); | |
| }); | |
| it("rejects duplicate extensions and unknown formats", () => { | |
| expect( | |
| parseClawOpenClawProfile({ schemaVersion: 1, agent: {}, extensions: [extension, extension] }) | |
| .ok, | |
| ).toBe(false); | |
| expect( | |
| parseClawOpenClawProfile({ | |
| schemaVersion: 1, | |
| agent: {}, | |
| extensions: [{ ...extension, format: "future" }], | |
| }).ok, | |
| ).toBe(false); | |
| }); | |
| }); | |
| describe("Claw application planning v1", () => { | |
| it("discloses model and delegation effects with nonblocking local availability notices", async () => { | |
| const { source, workspace } = await createPlanSource(); | |
| const agent = { | |
| model: { primary: "acme/primary", fallbacks: ["acme/missing"] }, | |
| subagents: { allowAgents: ["researcher", "writer"], delegationMode: "prefer" as const }, | |
| }; | |
| const params = { | |
| manifest: requireManifest({ schemaVersion: 1, agent: { id: "analyst" } }), | |
| openClawProfile: { schemaVersion: 1 as const, agent }, | |
| source, | |
| }; | |
| const context: ClawAddPlanContext = { | |
| workspace, | |
| existingAgentIds: ["researcher"], | |
| config: { | |
| models: { | |
| providers: { | |
| acme: { | |
| baseUrl: "https://models.example.test", | |
| models: [ | |
| { | |
| id: "primary", | |
| name: "Primary", | |
| reasoning: false, | |
| input: ["text"], | |
| cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, | |
| maxTokens: 4096, | |
| }, | |
| ], | |
| }, | |
| }, | |
| }, | |
| }, | |
| }; | |
| const plan = await buildClawAddPlan({ ...params, context }); | |
| expect(plan.agent.config).toMatchObject(agent); | |
| expect(plan.capabilityChanges).toContainEqual( | |
| expect.objectContaining({ kind: "agent", effect: agent }), | |
| ); | |
| expect(plan.blockers).toEqual([]); | |
| expect(plan.readiness).toEqual({ ready: true, requirements: [] }); | |
| expect(plan.diagnostics).toMatchObject([ | |
| { | |
| level: "warning", | |
| phase: "plan", | |
| code: "delegation_target_unresolved", | |
| path: "$.profiles.openclaw.agent.subagents.allowAgents[1]", | |
| }, | |
| { | |
| level: "warning", | |
| phase: "plan", | |
| code: "model_not_in_catalog", | |
| path: "$.profiles.openclaw.agent.model.fallbacks[0]", | |
| }, | |
| ]); | |
| const unavailable = await buildClawAddPlan({ ...params, context: { workspace } }); | |
| expect(unavailable.diagnostics).toContainEqual( | |
| expect.objectContaining({ | |
| code: "model_not_in_catalog", | |
| path: "$.profiles.openclaw.agent.model.primary", | |
| }), | |
| ); | |
| expect(unavailable.blockers).toEqual([]); | |
| expect(unavailable.planIntegrity).not.toBe(plan.planIntegrity); | |
| }); | |
| it("projects profile extensions onto canonical plugin package identities", () => { | |
| expect( | |
| clawProfileExtensionPackages({ schemaVersion: 1, agent: {}, extensions: [extension] }), | |
| ).toEqual([ | |
| { | |
| kind: "plugin", | |
| source: "clawhub", | |
| ref: "@acme/market-data", | |
| version: "2.0.1", | |
| }, | |
| ]); | |
| expect(clawProfileExtensionPackages(undefined)).toEqual([]); | |
| }); | |
| it("plans a canonical extension and an ordinary managed schema asset", async () => { | |
| const { source, workspace } = await createPlanSource(); | |
| const manifest = requireManifest({ | |
| schemaVersion: 1, | |
| agent: { id: "market-analyst" }, | |
| workspace: { | |
| files: [{ source: "workspace/schemas/market.json", path: "schemas/market.json" }], | |
| }, | |
| }); | |
| const plan = await buildClawAddPlan({ | |
| manifest, | |
| openClawProfile: { schemaVersion: 1, agent: {}, extensions: [extension] }, | |
| source, | |
| context: { | |
| workspace, | |
| packagePreflight: async () => ({ | |
| ok: true, | |
| action: "install", | |
| integrity: `sha256:${"b".repeat(64)}`, | |
| installId: "market-data", | |
| detectedFormat: "claude", | |
| mapped: ["commands", "skills"], | |
| unavailable: ["agents"], | |
| adapterIdentity: "openclaw/test", | |
| }), | |
| }, | |
| }); | |
| expect(plan.extensions).toEqual([ | |
| expect.objectContaining({ | |
| id: "market-data", | |
| detectedFormat: "claude", | |
| mapped: ["commands", "skills"], | |
| unavailable: ["agents"], | |
| requirementState: "missing-installable", | |
| blocked: false, | |
| }), | |
| ]); | |
| expect(plan.actions).toContainEqual( | |
| expect.objectContaining({ | |
| kind: "package", | |
| id: "plugin:@acme/market-data", | |
| blocked: false, | |
| details: expect.objectContaining({ | |
| extension: expect.objectContaining({ | |
| id: "market-data", | |
| adapterIdentity: "openclaw/test", | |
| }), | |
| }), | |
| }), | |
| ); | |
| expect(plan.actions).toContainEqual( | |
| expect.objectContaining({ kind: "workspaceFile", id: "schemas/market.json" }), | |
| ); | |
| }); | |
| it("reports a reused extension with remaining local setup as setup-required", async () => { | |
| const { source, workspace } = await createPlanSource(); | |
| const prerequisite = { | |
| kind: "plugin-setup" as const, | |
| plugin: "market-data", | |
| provider: "market-data", | |
| envVars: ["MARKET_DATA_TOKEN"], | |
| authMethods: [], | |
| }; | |
| const plan = await buildClawAddPlan({ | |
| manifest: requireManifest({ schemaVersion: 1, agent: { id: "market-analyst" } }), | |
| openClawProfile: { schemaVersion: 1, agent: {}, extensions: [extension] }, | |
| source, | |
| context: { | |
| workspace, | |
| packagePreflight: async () => ({ | |
| ok: true, | |
| action: "reuse", | |
| integrity: `sha256:${"b".repeat(64)}`, | |
| installId: "market-data", | |
| detectedFormat: "claude", | |
| mapped: ["skills"], | |
| unavailable: [], | |
| adapterIdentity: "openclaw/test", | |
| requirements: [prerequisite], | |
| }), | |
| }, | |
| }); | |
| expect(plan.extensions?.[0]).toMatchObject({ | |
| requirementState: "setup-required", | |
| ownerAction: "reuse", | |
| }); | |
| expect(plan.actions).toContainEqual( | |
| expect.objectContaining({ | |
| kind: "package", | |
| action: "reuse", | |
| details: expect.objectContaining({ requirementState: "setup-required" }), | |
| }), | |
| ); | |
| expect(plan.readiness).toEqual({ ready: false, requirements: [prerequisite] }); | |
| }); | |
| it("blocks incomplete adapter provenance", async () => { | |
| const { source, workspace } = await createPlanSource(); | |
| const plan = await buildClawAddPlan({ | |
| manifest: requireManifest({ schemaVersion: 1, agent: { id: "market-analyst" } }), | |
| openClawProfile: { schemaVersion: 1, agent: {}, extensions: [extension] }, | |
| source, | |
| context: { | |
| workspace, | |
| packagePreflight: async () => ({ | |
| ok: true, | |
| action: "install", | |
| integrity: `sha256:${"b".repeat(64)}`, | |
| installId: "market-data", | |
| detectedFormat: "claude", | |
| mapped: ["skills"], | |
| unavailable: [], | |
| }), | |
| }, | |
| }); | |
| expect(plan.blockers).toContainEqual( | |
| expect.objectContaining({ code: "extension_provenance_incomplete" }), | |
| ); | |
| expect(plan.actions).toContainEqual( | |
| expect.objectContaining({ id: "plugin:@acme/market-data", blocked: true }), | |
| ); | |
| }); | |
| it("blocks duplicate portable and profile package declarations", async () => { | |
| const { source, workspace } = await createPlanSource(); | |
| const manifest = requireManifest({ | |
| schemaVersion: 1, | |
| agent: { id: "market-analyst" }, | |
| packages: [ | |
| { | |
| kind: "plugin", | |
| source: "clawhub", | |
| ref: "@acme/market-data", | |
| version: "2.0.1", | |
| }, | |
| ], | |
| }); | |
| const plan = await buildClawAddPlan({ | |
| manifest, | |
| openClawProfile: { schemaVersion: 1, agent: {}, extensions: [extension] }, | |
| source, | |
| context: { | |
| workspace, | |
| packagePreflight: async () => ({ | |
| ok: true, | |
| action: "install", | |
| integrity: `sha256:${"b".repeat(64)}`, | |
| installId: "market-data", | |
| detectedFormat: "claude", | |
| mapped: ["skills"], | |
| unavailable: [], | |
| adapterIdentity: "openclaw/test", | |
| }), | |
| }, | |
| }); | |
| expect(plan.blockers).toContainEqual( | |
| expect.objectContaining({ code: "extension_package_collision" }), | |
| ); | |
| expect(plan.actions.filter((action) => action.id === "plugin:@acme/market-data")).toHaveLength( | |
| 1, | |
| ); | |
| }); | |
| it("blocks a declared format that differs from canonical detection", async () => { | |
| const { source, workspace } = await createPlanSource(); | |
| const plan = await buildClawAddPlan({ | |
| manifest: requireManifest({ schemaVersion: 1, agent: { id: "market-analyst" } }), | |
| openClawProfile: { | |
| schemaVersion: 1, | |
| agent: {}, | |
| extensions: [{ ...extension, format: "codex" }], | |
| }, | |
| source, | |
| context: { | |
| workspace, | |
| packagePreflight: async () => ({ | |
| ok: true, | |
| action: "install", | |
| integrity: `sha256:${"b".repeat(64)}`, | |
| installId: "market-data", | |
| detectedFormat: "claude", | |
| mapped: ["skills"], | |
| unavailable: [], | |
| adapterIdentity: "openclaw/test", | |
| }), | |
| }, | |
| }); | |
| expect(plan.extensions?.[0]?.blocked).toBe(true); | |
| expect(plan.blockers).toContainEqual( | |
| expect.objectContaining({ | |
| code: "extension_format_mismatch", | |
| path: "$.profiles.openclaw.extensions[0].format", | |
| }), | |
| ); | |
| }); | |
| }); | |
| describe("parseClawOpenClawProfile model and delegation", () => { | |
| it.each([ | |
| { | |
| model: { primary: "acme/model", fallbacks: ["acme/team/fallback"] }, | |
| subagents: { allowAgents: ["researcher", "writer_2"], delegationMode: "prefer" }, | |
| }, | |
| { | |
| model: { primary: "acme/model", fallbacks: [] }, | |
| subagents: { allowAgents: [], delegationMode: "suggest" }, | |
| }, | |
| { model: { primary: "acme/model" }, subagents: {} }, | |
| ])("preserves declared selections: %j", (agent) => { | |
| expect(parseClawOpenClawProfile({ schemaVersion: 1, agent })).toMatchObject({ | |
| ok: true, | |
| profile: { agent }, | |
| }); | |
| }); | |
| it.each([ | |
| { model: {} }, | |
| { model: "acme/model" }, | |
| { model: { primary: "model" } }, | |
| { model: { primary: "/model" } }, | |
| { model: { primary: "acme/" } }, | |
| { model: { primary: "acme/has space" } }, | |
| { model: { primary: "acme/model", fallbacks: [""] } }, | |
| { model: { primary: "acme/model", fallbacks: ["invalid"] } }, | |
| { model: { primary: "acme/model", extra: true } }, | |
| { subagents: { delegationMode: "required" } }, | |
| { subagents: { allowAgents: ["Invalid"] } }, | |
| { subagents: { allowAgents: ["*"] } }, | |
| { subagents: { allowAgents: [""] } }, | |
| { subagents: { extra: true } }, | |
| ])("rejects invalid profile selections: %j", (agent) => { | |
| expect(parseClawOpenClawProfile({ schemaVersion: 1, agent }).ok).toBe(false); | |
| }); | |
| }); | |