@dcdr/contracts 1.9.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +176 -0
- package/README.md +411 -0
- package/dist/capabilities.contract.d.ts +69 -0
- package/dist/capabilities.contract.d.ts.map +1 -0
- package/dist/capabilities.contract.js +126 -0
- package/dist/control.contract.d.ts +39 -0
- package/dist/control.contract.d.ts.map +1 -0
- package/dist/control.contract.js +2 -0
- package/dist/credentials.contract.d.ts +37 -0
- package/dist/credentials.contract.d.ts.map +1 -0
- package/dist/credentials.contract.js +15 -0
- package/dist/entitlements.contract.d.ts +107 -0
- package/dist/entitlements.contract.d.ts.map +1 -0
- package/dist/entitlements.contract.js +11 -0
- package/dist/errors.contract.d.ts +47 -0
- package/dist/errors.contract.d.ts.map +1 -0
- package/dist/errors.contract.js +48 -0
- package/dist/execution.contract.d.ts +240 -0
- package/dist/execution.contract.d.ts.map +1 -0
- package/dist/execution.contract.js +22 -0
- package/dist/http.contract.d.ts +20 -0
- package/dist/http.contract.d.ts.map +1 -0
- package/dist/http.contract.js +8 -0
- package/dist/implementations.contract.d.ts +120 -0
- package/dist/implementations.contract.d.ts.map +1 -0
- package/dist/implementations.contract.js +2 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/intent.contract.d.ts +137 -0
- package/dist/intent.contract.d.ts.map +1 -0
- package/dist/intent.contract.js +76 -0
- package/dist/logs.contract.d.ts +10 -0
- package/dist/logs.contract.d.ts.map +1 -0
- package/dist/logs.contract.js +2 -0
- package/dist/messages.contract.d.ts +16 -0
- package/dist/messages.contract.d.ts.map +1 -0
- package/dist/messages.contract.js +2 -0
- package/dist/policies.contract.d.ts +253 -0
- package/dist/policies.contract.d.ts.map +1 -0
- package/dist/policies.contract.js +283 -0
- package/dist/prompt-variable-schema.contract.d.ts +75 -0
- package/dist/prompt-variable-schema.contract.d.ts.map +1 -0
- package/dist/prompt-variable-schema.contract.js +572 -0
- package/dist/prompts.contract.d.ts +97 -0
- package/dist/prompts.contract.d.ts.map +1 -0
- package/dist/prompts.contract.js +87 -0
- package/dist/provider.contract.d.ts +477 -0
- package/dist/provider.contract.d.ts.map +1 -0
- package/dist/provider.contract.js +3310 -0
- package/dist/registry.stats.contract.d.ts +39 -0
- package/dist/registry.stats.contract.d.ts.map +1 -0
- package/dist/registry.stats.contract.js +9 -0
- package/dist/runtime.client.d.ts +362 -0
- package/dist/runtime.client.d.ts.map +1 -0
- package/dist/runtime.client.js +545 -0
- package/dist/service-tokens.contract.d.ts +29 -0
- package/dist/service-tokens.contract.d.ts.map +1 -0
- package/dist/service-tokens.contract.js +10 -0
- package/dist/session.contract.d.ts +51 -0
- package/dist/session.contract.d.ts.map +1 -0
- package/dist/session.contract.js +187 -0
- package/dist/subscription.contract.d.ts +37 -0
- package/dist/subscription.contract.d.ts.map +1 -0
- package/dist/subscription.contract.js +45 -0
- package/dist/utils.contract.d.ts +21 -0
- package/dist/utils.contract.d.ts.map +1 -0
- package/dist/utils.contract.js +79 -0
- package/package.json +57 -0
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { PromptVariable } from "./prompts.contract";
|
|
2
|
+
export declare enum PromptVariableSchemaIssueCode {
|
|
3
|
+
ROOT_OBJECT = "ROOT_OBJECT",
|
|
4
|
+
KEY_NAME_INVALID = "KEY_NAME_INVALID",
|
|
5
|
+
DEFINITION_SHAPE = "DEFINITION_SHAPE",
|
|
6
|
+
TYPE_INVALID = "TYPE_INVALID",
|
|
7
|
+
ENUM_REQUIRES_FULL = "ENUM_REQUIRES_FULL",
|
|
8
|
+
REQUIRED_BOOL = "REQUIRED_BOOL",
|
|
9
|
+
DESCRIPTION_STRING = "DESCRIPTION_STRING",
|
|
10
|
+
DESCRIPTION_LEN = "DESCRIPTION_LEN",
|
|
11
|
+
MINMAX_TYPE = "MINMAX_TYPE",
|
|
12
|
+
MINMAX_NUMBER = "MINMAX_NUMBER",
|
|
13
|
+
MINMAX_INTEGER = "MINMAX_INTEGER",
|
|
14
|
+
MINMAX_STRING_INT = "MINMAX_STRING_INT",
|
|
15
|
+
MINMAX_ARRAY_INT = "MINMAX_ARRAY_INT",
|
|
16
|
+
MINMAX_ORDER = "MINMAX_ORDER",
|
|
17
|
+
ENUM_VALUES_REQUIRED = "ENUM_VALUES_REQUIRED",
|
|
18
|
+
ENUM_VALUES_STRING = "ENUM_VALUES_STRING",
|
|
19
|
+
ENUM_VALUES_EMPTY = "ENUM_VALUES_EMPTY",
|
|
20
|
+
ENUM_VALUES_LEN = "ENUM_VALUES_LEN",
|
|
21
|
+
ENUM_VALUES_UNIQUE = "ENUM_VALUES_UNIQUE",
|
|
22
|
+
ENUM_FIELDS_DISALLOWED = "ENUM_FIELDS_DISALLOWED",
|
|
23
|
+
OBJECT_FIELDS_DISALLOWED = "OBJECT_FIELDS_DISALLOWED",
|
|
24
|
+
OBJECT_PROPERTIES_OBJECT = "OBJECT_PROPERTIES_OBJECT",
|
|
25
|
+
ARRAY_ITEMS_TYPE_REQUIRED = "ARRAY_ITEMS_TYPE_REQUIRED",
|
|
26
|
+
ARRAY_ITEMS_TYPE_INVALID = "ARRAY_ITEMS_TYPE_INVALID",
|
|
27
|
+
ARRAY_ITEMS_TYPE_NO_ARRAY = "ARRAY_ITEMS_TYPE_NO_ARRAY",
|
|
28
|
+
ARRAY_FIELDS_DISALLOWED = "ARRAY_FIELDS_DISALLOWED",
|
|
29
|
+
ARRAY_OBJECT_PROPERTIES_REQUIRED = "ARRAY_OBJECT_PROPERTIES_REQUIRED",
|
|
30
|
+
OBJECT_REQUIRES_FULL = "OBJECT_REQUIRES_FULL"
|
|
31
|
+
}
|
|
32
|
+
export interface PromptVariableSchemaIssue {
|
|
33
|
+
path: string;
|
|
34
|
+
code: PromptVariableSchemaIssueCode;
|
|
35
|
+
params?: Record<string, string | number | boolean>;
|
|
36
|
+
}
|
|
37
|
+
export interface PromptVariableSchemaValidationResult {
|
|
38
|
+
valid: boolean;
|
|
39
|
+
issues: PromptVariableSchemaIssue[];
|
|
40
|
+
}
|
|
41
|
+
export interface PromptVariableSchemaCanonicalizeResult {
|
|
42
|
+
valid: boolean;
|
|
43
|
+
issues: PromptVariableSchemaIssue[];
|
|
44
|
+
schema?: Record<string, PromptVariable>;
|
|
45
|
+
}
|
|
46
|
+
export interface PromptVariableSchemaValidationOptions {
|
|
47
|
+
/** Reject shorthand "array" definitions (require full object with itemsType). */
|
|
48
|
+
strictShorthandArray?: boolean;
|
|
49
|
+
/** Reject shorthand "object" definitions (require full object with properties or explicit object definition). */
|
|
50
|
+
strictShorthandObject?: boolean;
|
|
51
|
+
}
|
|
52
|
+
interface CanonicalizeOptions extends PromptVariableSchemaValidationOptions {
|
|
53
|
+
maxIssues?: number;
|
|
54
|
+
/** If true, expands shorthand string defs like { field: "string" } into PromptVariable objects. */
|
|
55
|
+
expandShorthand?: boolean;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Validates a PromptVariable schema record.
|
|
59
|
+
*
|
|
60
|
+
* Notes
|
|
61
|
+
* - Accepts both full object definitions and shorthand string definitions.
|
|
62
|
+
* - Issue codes are stable and UI/backend can map them to messages/i18n.
|
|
63
|
+
*/
|
|
64
|
+
export declare function validatePromptVariableSchemaRecord(value: unknown, maxIssues?: number, options?: PromptVariableSchemaValidationOptions): PromptVariableSchemaValidationResult;
|
|
65
|
+
/**
|
|
66
|
+
* Canonicalizes a PromptVariable schema record.
|
|
67
|
+
*
|
|
68
|
+
* Output
|
|
69
|
+
* - All `type/itemsType` are normalized to the canonical lowercase values from PromptVariableType.
|
|
70
|
+
* - Shorthand string definitions may be expanded to full PromptVariable objects.
|
|
71
|
+
* - Enum values are trimmed.
|
|
72
|
+
*/
|
|
73
|
+
export declare function canonicalizePromptVariableSchemaRecord(value: unknown, options?: CanonicalizeOptions): PromptVariableSchemaCanonicalizeResult;
|
|
74
|
+
export {};
|
|
75
|
+
//# sourceMappingURL=prompt-variable-schema.contract.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-variable-schema.contract.d.ts","sourceRoot":"","sources":["../src/prompt-variable-schema.contract.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAsB,MAAM,oBAAoB,CAAC;AAExE,oBAAY,6BAA6B;IACvC,WAAW,gBAAgB;IAC3B,gBAAgB,qBAAqB;IACrC,gBAAgB,qBAAqB;IACrC,YAAY,iBAAiB;IAC7B,kBAAkB,uBAAuB;IACzC,aAAa,kBAAkB;IAC/B,kBAAkB,uBAAuB;IACzC,eAAe,oBAAoB;IACnC,WAAW,gBAAgB;IAC3B,aAAa,kBAAkB;IAC/B,cAAc,mBAAmB;IACjC,iBAAiB,sBAAsB;IACvC,gBAAgB,qBAAqB;IACrC,YAAY,iBAAiB;IAC7B,oBAAoB,yBAAyB;IAC7C,kBAAkB,uBAAuB;IACzC,iBAAiB,sBAAsB;IACvC,eAAe,oBAAoB;IACnC,kBAAkB,uBAAuB;IACzC,sBAAsB,2BAA2B;IACjD,wBAAwB,6BAA6B;IACrD,wBAAwB,6BAA6B;IACrD,yBAAyB,8BAA8B;IACvD,wBAAwB,6BAA6B;IACrD,yBAAyB,8BAA8B;IACvD,uBAAuB,4BAA4B;IACnD,gCAAgC,qCAAqC;IACrE,oBAAoB,yBAAyB;CAC9C;AAED,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,6BAA6B,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,oCAAoC;IACnD,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,yBAAyB,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,sCAAsC;IACrD,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,yBAAyB,EAAE,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;CACzC;AAED,MAAM,WAAW,qCAAqC;IACpD,iFAAiF;IACjF,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,iHAAiH;IACjH,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,UAAU,mBAAoB,SAAQ,qCAAqC;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mGAAmG;IACnG,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAwID;;;;;;GAMG;AACH,wBAAgB,kCAAkC,CAChD,KAAK,EAAE,OAAO,EACd,SAAS,GAAE,MAAW,EACtB,OAAO,CAAC,EAAE,qCAAqC,GAC9C,oCAAoC,CAyXtC;AAED;;;;;;;GAOG;AACH,wBAAgB,sCAAsC,CACpD,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,mBAAmB,GAC5B,sCAAsC,CAkIxC"}
|
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PromptVariableSchemaIssueCode = void 0;
|
|
4
|
+
exports.validatePromptVariableSchemaRecord = validatePromptVariableSchemaRecord;
|
|
5
|
+
exports.canonicalizePromptVariableSchemaRecord = canonicalizePromptVariableSchemaRecord;
|
|
6
|
+
const prompts_contract_1 = require("./prompts.contract");
|
|
7
|
+
var PromptVariableSchemaIssueCode;
|
|
8
|
+
(function (PromptVariableSchemaIssueCode) {
|
|
9
|
+
PromptVariableSchemaIssueCode["ROOT_OBJECT"] = "ROOT_OBJECT";
|
|
10
|
+
PromptVariableSchemaIssueCode["KEY_NAME_INVALID"] = "KEY_NAME_INVALID";
|
|
11
|
+
PromptVariableSchemaIssueCode["DEFINITION_SHAPE"] = "DEFINITION_SHAPE";
|
|
12
|
+
PromptVariableSchemaIssueCode["TYPE_INVALID"] = "TYPE_INVALID";
|
|
13
|
+
PromptVariableSchemaIssueCode["ENUM_REQUIRES_FULL"] = "ENUM_REQUIRES_FULL";
|
|
14
|
+
PromptVariableSchemaIssueCode["REQUIRED_BOOL"] = "REQUIRED_BOOL";
|
|
15
|
+
PromptVariableSchemaIssueCode["DESCRIPTION_STRING"] = "DESCRIPTION_STRING";
|
|
16
|
+
PromptVariableSchemaIssueCode["DESCRIPTION_LEN"] = "DESCRIPTION_LEN";
|
|
17
|
+
PromptVariableSchemaIssueCode["MINMAX_TYPE"] = "MINMAX_TYPE";
|
|
18
|
+
PromptVariableSchemaIssueCode["MINMAX_NUMBER"] = "MINMAX_NUMBER";
|
|
19
|
+
PromptVariableSchemaIssueCode["MINMAX_INTEGER"] = "MINMAX_INTEGER";
|
|
20
|
+
PromptVariableSchemaIssueCode["MINMAX_STRING_INT"] = "MINMAX_STRING_INT";
|
|
21
|
+
PromptVariableSchemaIssueCode["MINMAX_ARRAY_INT"] = "MINMAX_ARRAY_INT";
|
|
22
|
+
PromptVariableSchemaIssueCode["MINMAX_ORDER"] = "MINMAX_ORDER";
|
|
23
|
+
PromptVariableSchemaIssueCode["ENUM_VALUES_REQUIRED"] = "ENUM_VALUES_REQUIRED";
|
|
24
|
+
PromptVariableSchemaIssueCode["ENUM_VALUES_STRING"] = "ENUM_VALUES_STRING";
|
|
25
|
+
PromptVariableSchemaIssueCode["ENUM_VALUES_EMPTY"] = "ENUM_VALUES_EMPTY";
|
|
26
|
+
PromptVariableSchemaIssueCode["ENUM_VALUES_LEN"] = "ENUM_VALUES_LEN";
|
|
27
|
+
PromptVariableSchemaIssueCode["ENUM_VALUES_UNIQUE"] = "ENUM_VALUES_UNIQUE";
|
|
28
|
+
PromptVariableSchemaIssueCode["ENUM_FIELDS_DISALLOWED"] = "ENUM_FIELDS_DISALLOWED";
|
|
29
|
+
PromptVariableSchemaIssueCode["OBJECT_FIELDS_DISALLOWED"] = "OBJECT_FIELDS_DISALLOWED";
|
|
30
|
+
PromptVariableSchemaIssueCode["OBJECT_PROPERTIES_OBJECT"] = "OBJECT_PROPERTIES_OBJECT";
|
|
31
|
+
PromptVariableSchemaIssueCode["ARRAY_ITEMS_TYPE_REQUIRED"] = "ARRAY_ITEMS_TYPE_REQUIRED";
|
|
32
|
+
PromptVariableSchemaIssueCode["ARRAY_ITEMS_TYPE_INVALID"] = "ARRAY_ITEMS_TYPE_INVALID";
|
|
33
|
+
PromptVariableSchemaIssueCode["ARRAY_ITEMS_TYPE_NO_ARRAY"] = "ARRAY_ITEMS_TYPE_NO_ARRAY";
|
|
34
|
+
PromptVariableSchemaIssueCode["ARRAY_FIELDS_DISALLOWED"] = "ARRAY_FIELDS_DISALLOWED";
|
|
35
|
+
PromptVariableSchemaIssueCode["ARRAY_OBJECT_PROPERTIES_REQUIRED"] = "ARRAY_OBJECT_PROPERTIES_REQUIRED";
|
|
36
|
+
PromptVariableSchemaIssueCode["OBJECT_REQUIRES_FULL"] = "OBJECT_REQUIRES_FULL";
|
|
37
|
+
})(PromptVariableSchemaIssueCode || (exports.PromptVariableSchemaIssueCode = PromptVariableSchemaIssueCode = {}));
|
|
38
|
+
function asPromptVariableDefObject(def) {
|
|
39
|
+
return def;
|
|
40
|
+
}
|
|
41
|
+
const PROMPT_VARIABLE_TYPES = [
|
|
42
|
+
prompts_contract_1.PromptVariableType.INTEGER,
|
|
43
|
+
prompts_contract_1.PromptVariableType.FLOAT,
|
|
44
|
+
prompts_contract_1.PromptVariableType.STRING,
|
|
45
|
+
prompts_contract_1.PromptVariableType.BOOLEAN,
|
|
46
|
+
prompts_contract_1.PromptVariableType.JSON,
|
|
47
|
+
prompts_contract_1.PromptVariableType.ANY,
|
|
48
|
+
prompts_contract_1.PromptVariableType.ARRAY,
|
|
49
|
+
prompts_contract_1.PromptVariableType.OBJECT,
|
|
50
|
+
prompts_contract_1.PromptVariableType.ENUM,
|
|
51
|
+
];
|
|
52
|
+
const PROMPT_VARIABLE_TYPES_SHORTHAND = [
|
|
53
|
+
prompts_contract_1.PromptVariableType.INTEGER,
|
|
54
|
+
prompts_contract_1.PromptVariableType.FLOAT,
|
|
55
|
+
prompts_contract_1.PromptVariableType.STRING,
|
|
56
|
+
prompts_contract_1.PromptVariableType.BOOLEAN,
|
|
57
|
+
prompts_contract_1.PromptVariableType.JSON,
|
|
58
|
+
prompts_contract_1.PromptVariableType.ANY,
|
|
59
|
+
prompts_contract_1.PromptVariableType.ARRAY,
|
|
60
|
+
prompts_contract_1.PromptVariableType.OBJECT,
|
|
61
|
+
];
|
|
62
|
+
function isPlainObject(value) {
|
|
63
|
+
if (value === null || value === undefined)
|
|
64
|
+
return false;
|
|
65
|
+
if (Array.isArray(value))
|
|
66
|
+
return false;
|
|
67
|
+
if (typeof value !== "object")
|
|
68
|
+
return false;
|
|
69
|
+
const proto = Object.getPrototypeOf(value);
|
|
70
|
+
return proto === Object.prototype || proto === null;
|
|
71
|
+
}
|
|
72
|
+
function isObjectRecord(value) {
|
|
73
|
+
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
74
|
+
}
|
|
75
|
+
function isValidVarName(key) {
|
|
76
|
+
return typeof key === "string" && /^[a-zA-Z0-9_]+$/.test(key);
|
|
77
|
+
}
|
|
78
|
+
function normalizePromptVariableType(raw) {
|
|
79
|
+
if (typeof raw !== "string")
|
|
80
|
+
return undefined;
|
|
81
|
+
const normalized = raw.trim().toLowerCase();
|
|
82
|
+
for (const t of PROMPT_VARIABLE_TYPES) {
|
|
83
|
+
if (t === normalized)
|
|
84
|
+
return t;
|
|
85
|
+
}
|
|
86
|
+
// Accept enum key names as a convenience (e.g. "STRING").
|
|
87
|
+
const upper = raw.trim().toUpperCase();
|
|
88
|
+
for (const [k, v] of Object.entries(prompts_contract_1.PromptVariableType)) {
|
|
89
|
+
if (k.toUpperCase() === upper)
|
|
90
|
+
return v;
|
|
91
|
+
}
|
|
92
|
+
return undefined;
|
|
93
|
+
}
|
|
94
|
+
function isFiniteNumber(value) {
|
|
95
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
96
|
+
}
|
|
97
|
+
function explainEnumValues(values, valuesPath, push) {
|
|
98
|
+
if (!Array.isArray(values) || values.length === 0) {
|
|
99
|
+
push({
|
|
100
|
+
path: valuesPath,
|
|
101
|
+
code: PromptVariableSchemaIssueCode.ENUM_VALUES_REQUIRED,
|
|
102
|
+
});
|
|
103
|
+
return { valid: false };
|
|
104
|
+
}
|
|
105
|
+
const normalized = [];
|
|
106
|
+
for (const v of values) {
|
|
107
|
+
if (typeof v !== "string") {
|
|
108
|
+
push({
|
|
109
|
+
path: valuesPath,
|
|
110
|
+
code: PromptVariableSchemaIssueCode.ENUM_VALUES_STRING,
|
|
111
|
+
});
|
|
112
|
+
return { valid: false };
|
|
113
|
+
}
|
|
114
|
+
const s = v.trim();
|
|
115
|
+
if (!s) {
|
|
116
|
+
push({
|
|
117
|
+
path: valuesPath,
|
|
118
|
+
code: PromptVariableSchemaIssueCode.ENUM_VALUES_EMPTY,
|
|
119
|
+
});
|
|
120
|
+
return { valid: false };
|
|
121
|
+
}
|
|
122
|
+
if (s.length > 256) {
|
|
123
|
+
push({
|
|
124
|
+
path: valuesPath,
|
|
125
|
+
code: PromptVariableSchemaIssueCode.ENUM_VALUES_LEN,
|
|
126
|
+
});
|
|
127
|
+
return { valid: false };
|
|
128
|
+
}
|
|
129
|
+
normalized.push(s);
|
|
130
|
+
}
|
|
131
|
+
const unique = new Set(normalized);
|
|
132
|
+
if (unique.size !== normalized.length) {
|
|
133
|
+
push({
|
|
134
|
+
path: valuesPath,
|
|
135
|
+
code: PromptVariableSchemaIssueCode.ENUM_VALUES_UNIQUE,
|
|
136
|
+
});
|
|
137
|
+
// Keep going; this is still canonicalizable.
|
|
138
|
+
}
|
|
139
|
+
return { valid: true, normalized };
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Validates a PromptVariable schema record.
|
|
143
|
+
*
|
|
144
|
+
* Notes
|
|
145
|
+
* - Accepts both full object definitions and shorthand string definitions.
|
|
146
|
+
* - Issue codes are stable and UI/backend can map them to messages/i18n.
|
|
147
|
+
*/
|
|
148
|
+
function validatePromptVariableSchemaRecord(value, maxIssues = 25, options) {
|
|
149
|
+
const issues = [];
|
|
150
|
+
const push = (issue) => {
|
|
151
|
+
if (issues.length >= maxIssues)
|
|
152
|
+
return;
|
|
153
|
+
issues.push(issue);
|
|
154
|
+
};
|
|
155
|
+
const explainDef = (def, path) => {
|
|
156
|
+
if (issues.length >= maxIssues)
|
|
157
|
+
return;
|
|
158
|
+
// Shorthand
|
|
159
|
+
if (typeof def === "string") {
|
|
160
|
+
const t = normalizePromptVariableType(def);
|
|
161
|
+
if (!t) {
|
|
162
|
+
push({
|
|
163
|
+
path,
|
|
164
|
+
code: PromptVariableSchemaIssueCode.TYPE_INVALID,
|
|
165
|
+
params: { type: String(def) },
|
|
166
|
+
});
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (t === prompts_contract_1.PromptVariableType.ENUM) {
|
|
170
|
+
push({ path, code: PromptVariableSchemaIssueCode.ENUM_REQUIRES_FULL });
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (t === prompts_contract_1.PromptVariableType.ARRAY && options?.strictShorthandArray) {
|
|
174
|
+
push({
|
|
175
|
+
path: `${path}.itemsType`,
|
|
176
|
+
code: PromptVariableSchemaIssueCode.ARRAY_ITEMS_TYPE_REQUIRED,
|
|
177
|
+
});
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (t === prompts_contract_1.PromptVariableType.OBJECT && options?.strictShorthandObject) {
|
|
181
|
+
push({
|
|
182
|
+
path,
|
|
183
|
+
code: PromptVariableSchemaIssueCode.OBJECT_REQUIRES_FULL,
|
|
184
|
+
});
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
if (!PROMPT_VARIABLE_TYPES_SHORTHAND.includes(t)) {
|
|
188
|
+
push({
|
|
189
|
+
path,
|
|
190
|
+
code: PromptVariableSchemaIssueCode.TYPE_INVALID,
|
|
191
|
+
params: { type: String(def) },
|
|
192
|
+
});
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
if (!isObjectRecord(def)) {
|
|
198
|
+
push({ path, code: PromptVariableSchemaIssueCode.DEFINITION_SHAPE });
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
const obj = asPromptVariableDefObject(def);
|
|
202
|
+
const t = normalizePromptVariableType(obj.type);
|
|
203
|
+
if (!t) {
|
|
204
|
+
push({
|
|
205
|
+
path: `${path}.type`,
|
|
206
|
+
code: PromptVariableSchemaIssueCode.TYPE_INVALID,
|
|
207
|
+
params: { type: String(obj.type ?? "") },
|
|
208
|
+
});
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
const requiredRaw = obj.required;
|
|
212
|
+
if (requiredRaw !== undefined && typeof requiredRaw !== "boolean") {
|
|
213
|
+
push({
|
|
214
|
+
path: `${path}.required`,
|
|
215
|
+
code: PromptVariableSchemaIssueCode.REQUIRED_BOOL,
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
const descriptionRaw = obj.description;
|
|
219
|
+
if (descriptionRaw !== undefined && descriptionRaw !== null) {
|
|
220
|
+
if (typeof descriptionRaw !== "string") {
|
|
221
|
+
push({
|
|
222
|
+
path: `${path}.description`,
|
|
223
|
+
code: PromptVariableSchemaIssueCode.DESCRIPTION_STRING,
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
else if (descriptionRaw.length > 1024) {
|
|
227
|
+
push({
|
|
228
|
+
path: `${path}.description`,
|
|
229
|
+
code: PromptVariableSchemaIssueCode.DESCRIPTION_LEN,
|
|
230
|
+
});
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
const hasMin = obj.min !== undefined && obj.min !== null;
|
|
234
|
+
const hasMax = obj.max !== undefined && obj.max !== null;
|
|
235
|
+
if (hasMin || hasMax) {
|
|
236
|
+
const allowMinMax = t === prompts_contract_1.PromptVariableType.INTEGER ||
|
|
237
|
+
t === prompts_contract_1.PromptVariableType.FLOAT ||
|
|
238
|
+
t === prompts_contract_1.PromptVariableType.STRING ||
|
|
239
|
+
t === prompts_contract_1.PromptVariableType.ARRAY;
|
|
240
|
+
if (!allowMinMax) {
|
|
241
|
+
push({ path, code: PromptVariableSchemaIssueCode.MINMAX_TYPE });
|
|
242
|
+
}
|
|
243
|
+
if (hasMin && !isFiniteNumber(obj.min)) {
|
|
244
|
+
push({
|
|
245
|
+
path: `${path}.min`,
|
|
246
|
+
code: PromptVariableSchemaIssueCode.MINMAX_NUMBER,
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
if (hasMax && !isFiniteNumber(obj.max)) {
|
|
250
|
+
push({
|
|
251
|
+
path: `${path}.max`,
|
|
252
|
+
code: PromptVariableSchemaIssueCode.MINMAX_NUMBER,
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
if (t === prompts_contract_1.PromptVariableType.INTEGER) {
|
|
256
|
+
if (hasMin && isFiniteNumber(obj.min) && !Number.isInteger(obj.min)) {
|
|
257
|
+
push({
|
|
258
|
+
path: `${path}.min`,
|
|
259
|
+
code: PromptVariableSchemaIssueCode.MINMAX_INTEGER,
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
if (hasMax && isFiniteNumber(obj.max) && !Number.isInteger(obj.max)) {
|
|
263
|
+
push({
|
|
264
|
+
path: `${path}.max`,
|
|
265
|
+
code: PromptVariableSchemaIssueCode.MINMAX_INTEGER,
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
if (t === prompts_contract_1.PromptVariableType.STRING) {
|
|
270
|
+
if (hasMin && (!Number.isInteger(obj.min) || obj.min < 0)) {
|
|
271
|
+
push({
|
|
272
|
+
path: `${path}.min`,
|
|
273
|
+
code: PromptVariableSchemaIssueCode.MINMAX_STRING_INT,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
if (hasMax && (!Number.isInteger(obj.max) || obj.max < 0)) {
|
|
277
|
+
push({
|
|
278
|
+
path: `${path}.max`,
|
|
279
|
+
code: PromptVariableSchemaIssueCode.MINMAX_STRING_INT,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
if (t === prompts_contract_1.PromptVariableType.ARRAY) {
|
|
284
|
+
if (hasMin && (!Number.isInteger(obj.min) || obj.min < 0)) {
|
|
285
|
+
push({
|
|
286
|
+
path: `${path}.min`,
|
|
287
|
+
code: PromptVariableSchemaIssueCode.MINMAX_ARRAY_INT,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
if (hasMax && (!Number.isInteger(obj.max) || obj.max < 0)) {
|
|
291
|
+
push({
|
|
292
|
+
path: `${path}.max`,
|
|
293
|
+
code: PromptVariableSchemaIssueCode.MINMAX_ARRAY_INT,
|
|
294
|
+
});
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
if (hasMin &&
|
|
298
|
+
hasMax &&
|
|
299
|
+
isFiniteNumber(obj.min) &&
|
|
300
|
+
isFiniteNumber(obj.max) &&
|
|
301
|
+
obj.max < obj.min) {
|
|
302
|
+
push({ path, code: PromptVariableSchemaIssueCode.MINMAX_ORDER });
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
// ENUM
|
|
306
|
+
if (t === prompts_contract_1.PromptVariableType.ENUM) {
|
|
307
|
+
explainEnumValues(obj.values, `${path}.values`, push);
|
|
308
|
+
if (obj.itemsType !== undefined && obj.itemsType !== null) {
|
|
309
|
+
push({
|
|
310
|
+
path: `${path}.itemsType`,
|
|
311
|
+
code: PromptVariableSchemaIssueCode.ENUM_FIELDS_DISALLOWED,
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
if (obj.properties !== undefined && obj.properties !== null) {
|
|
315
|
+
push({
|
|
316
|
+
path: `${path}.properties`,
|
|
317
|
+
code: PromptVariableSchemaIssueCode.ENUM_FIELDS_DISALLOWED,
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
if (hasMin || hasMax) {
|
|
321
|
+
push({
|
|
322
|
+
path,
|
|
323
|
+
code: PromptVariableSchemaIssueCode.ENUM_FIELDS_DISALLOWED,
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
// OBJECT
|
|
329
|
+
if (t === prompts_contract_1.PromptVariableType.OBJECT) {
|
|
330
|
+
if (obj.itemsType !== undefined && obj.itemsType !== null) {
|
|
331
|
+
push({
|
|
332
|
+
path: `${path}.itemsType`,
|
|
333
|
+
code: PromptVariableSchemaIssueCode.OBJECT_FIELDS_DISALLOWED,
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
if (obj.values !== undefined && obj.values !== null) {
|
|
337
|
+
push({
|
|
338
|
+
path: `${path}.values`,
|
|
339
|
+
code: PromptVariableSchemaIssueCode.OBJECT_FIELDS_DISALLOWED,
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
const propsRaw = obj.properties;
|
|
343
|
+
if (propsRaw !== undefined && propsRaw !== null) {
|
|
344
|
+
if (!isPlainObject(propsRaw)) {
|
|
345
|
+
push({
|
|
346
|
+
path: `${path}.properties`,
|
|
347
|
+
code: PromptVariableSchemaIssueCode.OBJECT_PROPERTIES_OBJECT,
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
else {
|
|
351
|
+
for (const [propName, propDef] of Object.entries(propsRaw)) {
|
|
352
|
+
if (!isValidVarName(propName)) {
|
|
353
|
+
push({
|
|
354
|
+
path: `${path}.properties.${String(propName)}`,
|
|
355
|
+
code: PromptVariableSchemaIssueCode.KEY_NAME_INVALID,
|
|
356
|
+
params: { name: String(propName) },
|
|
357
|
+
});
|
|
358
|
+
if (issues.length >= maxIssues)
|
|
359
|
+
return;
|
|
360
|
+
continue;
|
|
361
|
+
}
|
|
362
|
+
explainDef(propDef, `${path}.properties.${propName}`);
|
|
363
|
+
if (issues.length >= maxIssues)
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (hasMin || hasMax) {
|
|
369
|
+
push({
|
|
370
|
+
path,
|
|
371
|
+
code: PromptVariableSchemaIssueCode.OBJECT_FIELDS_DISALLOWED,
|
|
372
|
+
});
|
|
373
|
+
}
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
// ARRAY
|
|
377
|
+
if (t === prompts_contract_1.PromptVariableType.ARRAY) {
|
|
378
|
+
const itemsTypeRaw = obj.itemsType;
|
|
379
|
+
const itemsType = normalizePromptVariableType(itemsTypeRaw);
|
|
380
|
+
if (!itemsType) {
|
|
381
|
+
push({
|
|
382
|
+
path: `${path}.itemsType`,
|
|
383
|
+
code: PromptVariableSchemaIssueCode.ARRAY_ITEMS_TYPE_REQUIRED,
|
|
384
|
+
});
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
if (itemsType === prompts_contract_1.PromptVariableType.ARRAY) {
|
|
388
|
+
push({
|
|
389
|
+
path: `${path}.itemsType`,
|
|
390
|
+
code: PromptVariableSchemaIssueCode.ARRAY_ITEMS_TYPE_NO_ARRAY,
|
|
391
|
+
});
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
// min/max on arrays are interpreted as minItems/maxItems and are allowed.
|
|
395
|
+
if (itemsType === prompts_contract_1.PromptVariableType.OBJECT) {
|
|
396
|
+
const propsRaw = obj.properties;
|
|
397
|
+
if (propsRaw === undefined || propsRaw === null) {
|
|
398
|
+
push({
|
|
399
|
+
path: `${path}.properties`,
|
|
400
|
+
code: PromptVariableSchemaIssueCode.ARRAY_OBJECT_PROPERTIES_REQUIRED,
|
|
401
|
+
});
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
if (!isPlainObject(propsRaw)) {
|
|
405
|
+
push({
|
|
406
|
+
path: `${path}.properties`,
|
|
407
|
+
code: PromptVariableSchemaIssueCode.OBJECT_PROPERTIES_OBJECT,
|
|
408
|
+
});
|
|
409
|
+
return;
|
|
410
|
+
}
|
|
411
|
+
for (const [propName, propDef] of Object.entries(propsRaw)) {
|
|
412
|
+
if (!isValidVarName(propName)) {
|
|
413
|
+
push({
|
|
414
|
+
path: `${path}.properties.${String(propName)}`,
|
|
415
|
+
code: PromptVariableSchemaIssueCode.KEY_NAME_INVALID,
|
|
416
|
+
params: { name: String(propName) },
|
|
417
|
+
});
|
|
418
|
+
if (issues.length >= maxIssues)
|
|
419
|
+
return;
|
|
420
|
+
continue;
|
|
421
|
+
}
|
|
422
|
+
explainDef(propDef, `${path}.properties.${propName}`);
|
|
423
|
+
if (issues.length >= maxIssues)
|
|
424
|
+
return;
|
|
425
|
+
}
|
|
426
|
+
if (obj.values !== undefined && obj.values !== null) {
|
|
427
|
+
push({
|
|
428
|
+
path: `${path}.values`,
|
|
429
|
+
code: PromptVariableSchemaIssueCode.ARRAY_FIELDS_DISALLOWED,
|
|
430
|
+
});
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
if (obj.properties !== undefined && obj.properties !== null) {
|
|
435
|
+
push({
|
|
436
|
+
path: `${path}.properties`,
|
|
437
|
+
code: PromptVariableSchemaIssueCode.ARRAY_FIELDS_DISALLOWED,
|
|
438
|
+
});
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
if (itemsType === prompts_contract_1.PromptVariableType.ENUM) {
|
|
442
|
+
explainEnumValues(obj.values, `${path}.values`, push);
|
|
443
|
+
}
|
|
444
|
+
else {
|
|
445
|
+
if (obj.values !== undefined && obj.values !== null) {
|
|
446
|
+
push({
|
|
447
|
+
path: `${path}.values`,
|
|
448
|
+
code: PromptVariableSchemaIssueCode.ARRAY_FIELDS_DISALLOWED,
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
// For other types, we allow itemsType only if it is a valid type and not array (compat with UI).
|
|
455
|
+
const maybeItemsType = obj.itemsType;
|
|
456
|
+
if (maybeItemsType !== undefined && maybeItemsType !== null) {
|
|
457
|
+
const it = normalizePromptVariableType(maybeItemsType);
|
|
458
|
+
if (!it) {
|
|
459
|
+
push({
|
|
460
|
+
path: `${path}.itemsType`,
|
|
461
|
+
code: PromptVariableSchemaIssueCode.ARRAY_ITEMS_TYPE_INVALID,
|
|
462
|
+
});
|
|
463
|
+
}
|
|
464
|
+
if (it === prompts_contract_1.PromptVariableType.ARRAY) {
|
|
465
|
+
push({
|
|
466
|
+
path: `${path}.itemsType`,
|
|
467
|
+
code: PromptVariableSchemaIssueCode.ARRAY_ITEMS_TYPE_NO_ARRAY,
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
};
|
|
472
|
+
// Root allowed to be null/undefined.
|
|
473
|
+
if (value === null || value === undefined) {
|
|
474
|
+
return { valid: true, issues: [] };
|
|
475
|
+
}
|
|
476
|
+
if (!isPlainObject(value)) {
|
|
477
|
+
push({ path: "", code: PromptVariableSchemaIssueCode.ROOT_OBJECT });
|
|
478
|
+
return { valid: false, issues };
|
|
479
|
+
}
|
|
480
|
+
for (const [key, def] of Object.entries(value)) {
|
|
481
|
+
if (!isValidVarName(key)) {
|
|
482
|
+
push({
|
|
483
|
+
path: String(key),
|
|
484
|
+
code: PromptVariableSchemaIssueCode.KEY_NAME_INVALID,
|
|
485
|
+
params: { name: String(key) },
|
|
486
|
+
});
|
|
487
|
+
if (issues.length >= maxIssues)
|
|
488
|
+
break;
|
|
489
|
+
continue;
|
|
490
|
+
}
|
|
491
|
+
explainDef(def, key);
|
|
492
|
+
if (issues.length >= maxIssues)
|
|
493
|
+
break;
|
|
494
|
+
}
|
|
495
|
+
return { valid: issues.length === 0, issues };
|
|
496
|
+
}
|
|
497
|
+
/**
|
|
498
|
+
* Canonicalizes a PromptVariable schema record.
|
|
499
|
+
*
|
|
500
|
+
* Output
|
|
501
|
+
* - All `type/itemsType` are normalized to the canonical lowercase values from PromptVariableType.
|
|
502
|
+
* - Shorthand string definitions may be expanded to full PromptVariable objects.
|
|
503
|
+
* - Enum values are trimmed.
|
|
504
|
+
*/
|
|
505
|
+
function canonicalizePromptVariableSchemaRecord(value, options) {
|
|
506
|
+
const maxIssues = options?.maxIssues ?? 25;
|
|
507
|
+
const expandShorthand = options?.expandShorthand !== false;
|
|
508
|
+
const validation = validatePromptVariableSchemaRecord(value, maxIssues, options);
|
|
509
|
+
if (!validation.valid)
|
|
510
|
+
return { valid: false, issues: validation.issues };
|
|
511
|
+
if (value === null || value === undefined) {
|
|
512
|
+
return { valid: true, issues: [], schema: undefined };
|
|
513
|
+
}
|
|
514
|
+
const schema = {};
|
|
515
|
+
const toPromptVariable = (def) => {
|
|
516
|
+
if (typeof def === "string") {
|
|
517
|
+
const t = normalizePromptVariableType(def);
|
|
518
|
+
// Canonical form is always full PromptVariable objects.
|
|
519
|
+
return expandShorthand
|
|
520
|
+
? new prompts_contract_1.PromptVariable(t, false)
|
|
521
|
+
: new prompts_contract_1.PromptVariable(t, false);
|
|
522
|
+
}
|
|
523
|
+
if (!isObjectRecord(def)) {
|
|
524
|
+
// Should never happen after validation, but keep canonicalization total.
|
|
525
|
+
return new prompts_contract_1.PromptVariable(prompts_contract_1.PromptVariableType.ANY, false);
|
|
526
|
+
}
|
|
527
|
+
const obj = asPromptVariableDefObject(def);
|
|
528
|
+
const type = normalizePromptVariableType(obj.type);
|
|
529
|
+
const required = obj.required === true;
|
|
530
|
+
const description = typeof obj.description === "string" ? obj.description : undefined;
|
|
531
|
+
const min = isFiniteNumber(obj.min) ? obj.min : undefined;
|
|
532
|
+
const max = isFiniteNumber(obj.max) ? obj.max : undefined;
|
|
533
|
+
if (type === prompts_contract_1.PromptVariableType.ENUM) {
|
|
534
|
+
const enumNorm = explainEnumValues(obj.values, "values", () => {
|
|
535
|
+
/* already validated */
|
|
536
|
+
});
|
|
537
|
+
const values = enumNorm.normalized;
|
|
538
|
+
return new prompts_contract_1.PromptVariable(type, required, description, undefined, undefined, values, min, max);
|
|
539
|
+
}
|
|
540
|
+
if (type === prompts_contract_1.PromptVariableType.OBJECT) {
|
|
541
|
+
const propsRaw = obj.properties;
|
|
542
|
+
const props = isPlainObject(propsRaw)
|
|
543
|
+
? Object.fromEntries(Object.entries(propsRaw).map(([k, v]) => [k, toPromptVariable(v)]))
|
|
544
|
+
: undefined;
|
|
545
|
+
return new prompts_contract_1.PromptVariable(type, required, description, undefined, props, undefined, min, max);
|
|
546
|
+
}
|
|
547
|
+
if (type === prompts_contract_1.PromptVariableType.ARRAY) {
|
|
548
|
+
const itemsType = normalizePromptVariableType(obj.itemsType);
|
|
549
|
+
const propsRaw = obj.properties;
|
|
550
|
+
const props = itemsType === prompts_contract_1.PromptVariableType.OBJECT && isPlainObject(propsRaw)
|
|
551
|
+
? Object.fromEntries(Object.entries(propsRaw).map(([k, v]) => [
|
|
552
|
+
k,
|
|
553
|
+
toPromptVariable(v),
|
|
554
|
+
]))
|
|
555
|
+
: undefined;
|
|
556
|
+
const values = itemsType === prompts_contract_1.PromptVariableType.ENUM && Array.isArray(obj.values)
|
|
557
|
+
? obj.values
|
|
558
|
+
.filter((v) => typeof v === "string")
|
|
559
|
+
.map((v) => String(v).trim())
|
|
560
|
+
.filter((v) => v.length > 0)
|
|
561
|
+
: undefined;
|
|
562
|
+
return new prompts_contract_1.PromptVariable(type, required, description, itemsType, props, values, min, max);
|
|
563
|
+
}
|
|
564
|
+
// For scalar/json/any
|
|
565
|
+
const itemsType = normalizePromptVariableType(obj.itemsType);
|
|
566
|
+
return new prompts_contract_1.PromptVariable(type, required, description, itemsType, undefined, undefined, min, max);
|
|
567
|
+
};
|
|
568
|
+
for (const [key, def] of Object.entries(value)) {
|
|
569
|
+
schema[key] = toPromptVariable(def);
|
|
570
|
+
}
|
|
571
|
+
return { valid: true, issues: [], schema };
|
|
572
|
+
}
|