feat: unify installation model catalog
This commit is contained in:
@@ -10,7 +10,7 @@ import {
|
||||
} from "../src/workspaces/schema.js";
|
||||
|
||||
export const validYaml = `workspace:
|
||||
schema_version: 3
|
||||
schema_version: 4
|
||||
id: psd-clinical
|
||||
name: Policlinico San Donato
|
||||
description: Clinical data warehouse workspace
|
||||
@@ -25,33 +25,8 @@ dwh:
|
||||
- postgres_direct
|
||||
- rest_api
|
||||
- ssh_tunnel
|
||||
semantic_index:
|
||||
vector_store:
|
||||
engine: qdrant
|
||||
collection: psd-clinical
|
||||
dimensions: 1024
|
||||
distance: cosine
|
||||
embedding:
|
||||
provider: ollama_internal
|
||||
model: qwen3-embedding:0.6b
|
||||
dimensions: 1024
|
||||
llm_policy:
|
||||
default: zai/glm-5.2
|
||||
allowed:
|
||||
- zai/glm-5.2
|
||||
- openai/gpt-5
|
||||
`;
|
||||
|
||||
test("rejects a workspace whose embedding dimensions differ from its collection", () => {
|
||||
expect(() => parseWorkspaceYaml(validYaml.replace("dimensions: 1024", "dimensions: 1536")))
|
||||
.toThrow(/dimensions/i);
|
||||
});
|
||||
|
||||
test("rejects an LLM default outside its allowlist", () => {
|
||||
expect(() => parseWorkspaceYaml(validYaml.replace("- zai/glm-5.2", "- openai/gpt-5")))
|
||||
.toThrow(/allowlist/i);
|
||||
});
|
||||
|
||||
test("rejects unknown keys and invalid immutable IDs", () => {
|
||||
expect(() => parseWorkspaceYaml(validYaml.replace(" language: it", " language: it\n label: PSD")))
|
||||
.toThrow(/unrecognized key/i);
|
||||
@@ -74,94 +49,34 @@ test("accepts optional connection ports and timeouts but rejects unsafe values",
|
||||
.toThrow(/port/i);
|
||||
expect(() => parseWorkspaceYaml(validYaml.replace("timeout_ms: 5000", "timeout_ms: 0")))
|
||||
.toThrow(/timeout/i);
|
||||
expect(() => parseWorkspaceYaml(validYaml.replace("dimensions: 1024", "dimensions: 2048")))
|
||||
.toThrow(/1024|dimensions/i);
|
||||
});
|
||||
|
||||
test("accepts only the schema v3 internal qdrant semantic shape", () => {
|
||||
test("accepts a model-free schema v4 workspace", () => {
|
||||
expect(parseWorkspaceYaml(validYaml)).toMatchObject({
|
||||
workspace: { schema_version: 3, id: "psd-clinical" },
|
||||
semantic_index: {
|
||||
vector_store: {
|
||||
engine: "qdrant",
|
||||
collection: "psd-clinical",
|
||||
dimensions: 1024,
|
||||
distance: "cosine",
|
||||
},
|
||||
embedding: {
|
||||
provider: "ollama_internal",
|
||||
model: "qwen3-embedding:0.6b",
|
||||
dimensions: 1024,
|
||||
},
|
||||
},
|
||||
workspace: { schema_version: 4, id: "psd-clinical" },
|
||||
dwh: { database: "postgres", schema: "datawarehouse" },
|
||||
});
|
||||
});
|
||||
|
||||
test("committed example descriptors parse as exact schema v3 workspaces", () => {
|
||||
test("committed example descriptors parse as exact schema v4 workspaces", () => {
|
||||
const example = readFileSync(resolve(process.cwd(), "../deploy/workspaces/example.yaml"), "utf8");
|
||||
const psdExample = readFileSync(resolve(process.cwd(), "../deploy/workspaces/psd.yaml.example"), "utf8");
|
||||
|
||||
expect(() => parseWorkspaceYaml(example)).not.toThrow();
|
||||
expect(() => parseWorkspaceYaml(psdExample)).not.toThrow();
|
||||
expect(parseWorkspaceYaml(example)).toMatchObject({
|
||||
workspace: { schema_version: 3 },
|
||||
semantic_index: {
|
||||
vector_store: { engine: "qdrant", distance: "cosine", dimensions: 1024 },
|
||||
embedding: { provider: "ollama_internal", model: "qwen3-embedding:0.6b", dimensions: 1024 },
|
||||
},
|
||||
workspace: { schema_version: 4 },
|
||||
});
|
||||
expect(parseWorkspaceYaml(psdExample)).toMatchObject({
|
||||
workspace: { schema_version: 3 },
|
||||
semantic_index: {
|
||||
vector_store: { engine: "qdrant", distance: "cosine", dimensions: 1024 },
|
||||
embedding: { provider: "ollama_internal", model: "qwen3-embedding:0.6b", dimensions: 1024 },
|
||||
},
|
||||
workspace: { schema_version: 4 },
|
||||
});
|
||||
});
|
||||
|
||||
test("rejects pgvector semantic stores in schema v3", () => {
|
||||
expect(() => parseWorkspaceYaml(validYaml.replace("engine: qdrant", "engine: pgvector")))
|
||||
.toThrow(/qdrant|pgvector/i);
|
||||
});
|
||||
|
||||
test("rejects supported_transports inside schema v3 semantic identity", () => {
|
||||
const withTransport = validYaml.replace(
|
||||
" distance: cosine\n",
|
||||
" distance: cosine\n supported_transports:\n - rest_api\n",
|
||||
);
|
||||
|
||||
expect(() => parseWorkspaceYaml(withTransport)).toThrow(/unrecognized key|supported_transports/i);
|
||||
});
|
||||
|
||||
test("rejects external embedding providers in schema v3", () => {
|
||||
expect(() => parseWorkspaceYaml(validYaml.replace("provider: ollama_internal", "provider: openai_compatible")))
|
||||
.toThrow(/ollama_internal|provider/i);
|
||||
});
|
||||
|
||||
test("rejects non-cosine distance in schema v3", () => {
|
||||
expect(() => parseWorkspaceYaml(validYaml.replace("distance: cosine", "distance: l2")))
|
||||
.toThrow(/cosine|distance/i);
|
||||
});
|
||||
|
||||
test("rejects unknown fields in schema v3 semantic identity", () => {
|
||||
const withUnknownField = validYaml.replace(
|
||||
" collection: psd-clinical\n",
|
||||
" collection: psd-clinical\n namespace: psd\n",
|
||||
);
|
||||
|
||||
expect(() => parseWorkspaceYaml(withUnknownField)).toThrow(/unrecognized key/i);
|
||||
});
|
||||
|
||||
test("rejects legacy semantic connector fields and diagnostics in schema v3", () => {
|
||||
expect(() => parseWorkspaceYaml(validYaml.replace(
|
||||
" collection: psd-clinical\n",
|
||||
" collection: psd-clinical\n database: postgres\n",
|
||||
))).toThrow(/unrecognized key|database/i);
|
||||
|
||||
expect(() => parseWorkspaceYaml(validYaml.replace(
|
||||
"llm_policy:\n",
|
||||
"diagnostics:\n vector_rest:\n metadata:\n method: GET\n path: /metadata\n auth: bearer\n response:\n collection: collection\n dimensions: dimensions\n distance: distance\nllm_policy:\n",
|
||||
))).toThrow(/unrecognized key|vector_rest/i);
|
||||
test("rejects installation-owned model and vector fields", () => {
|
||||
expect(() => parseWorkspaceYaml(`${validYaml}llm_policy:\n allowed: [zai/glm-5.3]\n`))
|
||||
.toThrow(/unrecognized key|llm_policy/i);
|
||||
expect(() => parseWorkspaceYaml(`${validYaml}semantic_index: {}\n`))
|
||||
.toThrow(/unrecognized key|semantic_index/i);
|
||||
});
|
||||
|
||||
test.each([
|
||||
@@ -222,8 +137,8 @@ llm_policy:
|
||||
- zai/glm-5.2
|
||||
`],
|
||||
])("rejects schema %s descriptors at parser and object-validator boundaries", (_version, yaml) => {
|
||||
expect(() => parseWorkspaceYaml(yaml)).toThrow(/schema_version|invalid literal|3/i);
|
||||
expect(() => validateWorkspaceDescriptor(parse(yaml))).toThrow(/schema_version|invalid literal|3/i);
|
||||
expect(() => parseWorkspaceYaml(yaml)).toThrow(/schema_version|invalid literal|4/i);
|
||||
expect(() => validateWorkspaceDescriptor(parse(yaml))).toThrow(/schema_version|invalid literal|4/i);
|
||||
});
|
||||
|
||||
test("does not expose the redundant canonical validator or v1 migration", () => {
|
||||
@@ -253,9 +168,8 @@ test("rejects REST diagnostic declarations without their matching connector tran
|
||||
response:
|
||||
database: database
|
||||
schema: schema
|
||||
llm_policy:
|
||||
`;
|
||||
const declared = validYaml.replace("llm_policy:\n", diagnostics);
|
||||
const declared = `${validYaml}${diagnostics}`;
|
||||
|
||||
expect(() => parseWorkspaceYaml(declared.replace(" - rest_api\n", ""))).toThrow(/dwh_rest/i);
|
||||
});
|
||||
@@ -462,7 +376,7 @@ test.each(["curated/**/*.yaml", "curated/**"])(
|
||||
},
|
||||
);
|
||||
|
||||
test("keeps evidence optional on schema v3", () => {
|
||||
test("keeps evidence optional on schema v4", () => {
|
||||
expect(validateWorkspaceDescriptor(validWorkspaceObject())).not.toHaveProperty("evidence");
|
||||
});
|
||||
|
||||
@@ -471,7 +385,7 @@ test("serializes defaulted evidence canonically and parses it without loss", ()
|
||||
type: "filesystem",
|
||||
uri: "psd-clinical/evidence",
|
||||
}));
|
||||
if (canonical.workspace.schema_version !== 3) throw new Error("expected schema v3");
|
||||
if (canonical.workspace.schema_version !== 4) throw new Error("expected schema v4");
|
||||
|
||||
expect(parseWorkspaceYaml(serializeWorkspaceYaml(canonical))).toEqual(canonical);
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user