@nirmos/sdk 0.3.1 → 0.3.2
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/README.md +4 -1
- package/dist/cjs/client.js +1 -9
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/index.js +8 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/management/manifest.js +16 -0
- package/dist/cjs/management/manifest.js.map +1 -1
- package/dist/cjs/management/resources.js +3 -1
- package/dist/cjs/management/resources.js.map +1 -1
- package/dist/cjs/prompts/render.js +12 -4
- package/dist/cjs/prompts/render.js.map +1 -1
- package/dist/cjs/prompts/variables.js +117 -0
- package/dist/cjs/prompts/variables.js.map +1 -0
- package/dist/esm/client.d.ts +6 -20
- package/dist/esm/client.d.ts.map +1 -1
- package/dist/esm/client.js +1 -9
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/index.d.ts +2 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/management/contracts.d.ts +17826 -6455
- package/dist/esm/management/contracts.d.ts.map +1 -1
- package/dist/esm/management/manifest.d.ts +14 -0
- package/dist/esm/management/manifest.d.ts.map +1 -1
- package/dist/esm/management/manifest.js +16 -0
- package/dist/esm/management/manifest.js.map +1 -1
- package/dist/esm/management/resources.d.ts +2 -0
- package/dist/esm/management/resources.d.ts.map +1 -1
- package/dist/esm/management/resources.js +3 -1
- package/dist/esm/management/resources.js.map +1 -1
- package/dist/esm/prompts/render.js +11 -3
- package/dist/esm/prompts/render.js.map +1 -1
- package/dist/esm/prompts/variables.d.ts +29 -0
- package/dist/esm/prompts/variables.d.ts.map +1 -0
- package/dist/esm/prompts/variables.js +108 -0
- package/dist/esm/prompts/variables.js.map +1 -0
- package/package.json +1 -1
- package/src/client.ts +10 -30
- package/src/index.ts +13 -0
- package/src/management/contracts.ts +212 -117
- package/src/management/manifest.ts +16 -0
- package/src/management/resources.ts +3 -1
- package/src/prompts/render.ts +9 -4
- package/src/prompts/variables.ts +156 -0
|
@@ -1216,6 +1216,22 @@ export const managementManifest = [
|
|
|
1216
1216
|
"permission": "observability:read",
|
|
1217
1217
|
"plane": "api"
|
|
1218
1218
|
},
|
|
1219
|
+
{
|
|
1220
|
+
"method": "POST",
|
|
1221
|
+
"path": "/v1/knowledge-bases/:id/search",
|
|
1222
|
+
"operationId": "searchKnowledgeBase",
|
|
1223
|
+
"sdk": "knowledge.search",
|
|
1224
|
+
"permission": "knowledge:search",
|
|
1225
|
+
"plane": "api"
|
|
1226
|
+
},
|
|
1227
|
+
{
|
|
1228
|
+
"method": "GET",
|
|
1229
|
+
"path": "/v1/knowledge-bases/:id/search-status",
|
|
1230
|
+
"operationId": "getKnowledgeSearchStatus",
|
|
1231
|
+
"sdk": "knowledge.searchStatus",
|
|
1232
|
+
"permission": "knowledge:read",
|
|
1233
|
+
"plane": "api"
|
|
1234
|
+
},
|
|
1219
1235
|
{
|
|
1220
1236
|
"method": "GET",
|
|
1221
1237
|
"path": "/v1/knowledge-bases",
|
|
@@ -154,7 +154,9 @@ get: (id: string, options?: RequestOptions) => transport.data<Responses["getTrac
|
|
|
154
154
|
observability: { gatewayOverview: (options?: RequestOptions) => transport.data<Responses["gatewayOverview"]>({ method: "GET", path: `/v1/gateway/overview`, options }),
|
|
155
155
|
overview: (query: Queries["observabilityOverview"] = {}, options?: RequestOptions) => transport.data<Responses["observabilityOverview"]>({ method: "GET", path: `/v1/observability/overview`, query, options }),
|
|
156
156
|
metrics: (query: Queries["metrics"] = {}, options?: RequestOptions) => transport.data<Responses["metrics"]>({ method: "GET", path: `/v1/metrics`, query, options }) },
|
|
157
|
-
knowledge: {
|
|
157
|
+
knowledge: { search: (id: string, body: Requests["searchKnowledgeBase"], options?: RequestOptions) => transport.data<Responses["searchKnowledgeBase"]>({ method: "POST", path: `/v1/knowledge-bases/${encodeURIComponent(id)}/search`, body, options }),
|
|
158
|
+
searchStatus: (id: string, options?: RequestOptions) => transport.data<Responses["getKnowledgeSearchStatus"]>({ method: "GET", path: `/v1/knowledge-bases/${encodeURIComponent(id)}/search-status`, options }),
|
|
159
|
+
list: (query: Queries["listKnowledgeBases"] = {}, options?: RequestOptions) => transport.data<Responses["listKnowledgeBases"]>({ method: "GET", path: `/v1/knowledge-bases`, query, options }),
|
|
158
160
|
get: (id: string, options?: RequestOptions) => transport.data<Responses["getKnowledgeBase"]>({ method: "GET", path: `/v1/knowledge-bases/${encodeURIComponent(id)}`, options }),
|
|
159
161
|
create: (body: Requests["createKnowledgeBase"], options?: RequestOptions) => transport.data<Responses["createKnowledgeBase"]>({ method: "POST", path: `/v1/knowledge-bases`, body, options }),
|
|
160
162
|
update: (id: string, body: Requests["updateKnowledgeBase"], options?: RequestOptions) => transport.data<Responses["updateKnowledgeBase"]>({ method: "PATCH", path: `/v1/knowledge-bases/${encodeURIComponent(id)}`, body, options }),
|
package/src/prompts/render.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
RenderedPrompt,
|
|
10
10
|
} from "./types.js";
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
import { PROMPT_VARIABLE_PATTERN as PLACEHOLDER, promptVariableValue, validatePromptTemplate, validatePromptVariableValues } from "./variables.js";
|
|
13
13
|
|
|
14
14
|
export function renderPrompt(
|
|
15
15
|
prompt: Prompt,
|
|
@@ -65,7 +65,8 @@ function resolveVariables(
|
|
|
65
65
|
const missing: string[] = [];
|
|
66
66
|
|
|
67
67
|
for (const variable of definitions) {
|
|
68
|
-
const value = resolved
|
|
68
|
+
const value = promptVariableValue(resolved, variable.name);
|
|
69
|
+
if (value !== undefined) resolved[variable.name] = value as JsonValue;
|
|
69
70
|
if (value === undefined && variable.default !== undefined) {
|
|
70
71
|
resolved[variable.name] = variable.default;
|
|
71
72
|
} else if (value === undefined && variable.required) {
|
|
@@ -79,6 +80,8 @@ function resolveVariables(
|
|
|
79
80
|
missing,
|
|
80
81
|
);
|
|
81
82
|
}
|
|
83
|
+
const errors = validatePromptVariableValues(definitions, resolved);
|
|
84
|
+
if (Object.keys(errors).length) throw new PromptRenderError(Object.entries(errors).map(([name, error]) => `${name}: ${error}`).join(" "), Object.keys(errors));
|
|
82
85
|
return resolved;
|
|
83
86
|
}
|
|
84
87
|
|
|
@@ -87,14 +90,16 @@ function interpolate(
|
|
|
87
90
|
values: PromptVariableValues,
|
|
88
91
|
options: PromptRenderOptions,
|
|
89
92
|
): string {
|
|
93
|
+
const syntaxErrors = validatePromptTemplate(template);
|
|
94
|
+
if (syntaxErrors.length) throw new PromptRenderError(syntaxErrors.join(" "), []);
|
|
90
95
|
const unresolved = new Set<string>();
|
|
91
96
|
const result = template.replace(PLACEHOLDER, (placeholder, name: string) => {
|
|
92
|
-
const value = values
|
|
97
|
+
const value = promptVariableValue(values, name);
|
|
93
98
|
if (value === undefined) {
|
|
94
99
|
unresolved.add(name);
|
|
95
100
|
return placeholder;
|
|
96
101
|
}
|
|
97
|
-
return stringify(value);
|
|
102
|
+
return stringify(value as JsonValue);
|
|
98
103
|
});
|
|
99
104
|
|
|
100
105
|
if (unresolved.size > 0 && !options.allowUnresolved) {
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/** Shared placeholder semantics for managed prompts, the dashboard and execution. */
|
|
2
|
+
export const PROMPT_VARIABLE_PATTERN =
|
|
3
|
+
/\{\{\s*([a-zA-Z][a-zA-Z0-9_.-]*)\s*\}\}/g;
|
|
4
|
+
export function extractPromptVariableNames(
|
|
5
|
+
...values: Array<string | null | undefined>
|
|
6
|
+
): string[] {
|
|
7
|
+
return [
|
|
8
|
+
...new Set(
|
|
9
|
+
values.flatMap((value) =>
|
|
10
|
+
[...(value ?? "").matchAll(PROMPT_VARIABLE_PATTERN)].map(
|
|
11
|
+
(match) => match[1]!,
|
|
12
|
+
),
|
|
13
|
+
),
|
|
14
|
+
),
|
|
15
|
+
];
|
|
16
|
+
}
|
|
17
|
+
export function promptVariableValue(
|
|
18
|
+
values: Record<string, unknown>,
|
|
19
|
+
name: string,
|
|
20
|
+
): unknown {
|
|
21
|
+
if (Object.hasOwn(values, name)) return values[name];
|
|
22
|
+
let current: unknown = values;
|
|
23
|
+
for (const key of name.split(".")) {
|
|
24
|
+
if (
|
|
25
|
+
["__proto__", "prototype", "constructor"].includes(key) ||
|
|
26
|
+
!current ||
|
|
27
|
+
typeof current !== "object" ||
|
|
28
|
+
!Object.hasOwn(current, key)
|
|
29
|
+
)
|
|
30
|
+
return undefined;
|
|
31
|
+
current = (current as Record<string, unknown>)[key];
|
|
32
|
+
}
|
|
33
|
+
return current;
|
|
34
|
+
}
|
|
35
|
+
export function interpolatePromptVariables(
|
|
36
|
+
text: string,
|
|
37
|
+
values: Record<string, unknown>,
|
|
38
|
+
): string {
|
|
39
|
+
return text.replace(PROMPT_VARIABLE_PATTERN, (token, name: string) => {
|
|
40
|
+
const value = promptVariableValue(values, name);
|
|
41
|
+
return value === undefined
|
|
42
|
+
? token
|
|
43
|
+
: typeof value === "string"
|
|
44
|
+
? value
|
|
45
|
+
: JSON.stringify(value);
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
export function validatePromptTemplate(text: string): string[] {
|
|
49
|
+
const remaining = text.replace(PROMPT_VARIABLE_PATTERN, "");
|
|
50
|
+
return /\{\{|\{%/.test(remaining)
|
|
51
|
+
? [
|
|
52
|
+
"Unsupported variable syntax. Use {{name}}, {{ spaced }}, or {{user.name}}. Expressions, filters and template blocks cannot run as managed prompt variables.",
|
|
53
|
+
]
|
|
54
|
+
: [];
|
|
55
|
+
}
|
|
56
|
+
export type VariableDefinition = {
|
|
57
|
+
name: string;
|
|
58
|
+
type: string;
|
|
59
|
+
required?: boolean;
|
|
60
|
+
default?: unknown;
|
|
61
|
+
enum?: readonly string[];
|
|
62
|
+
values?: readonly string[];
|
|
63
|
+
min?: number;
|
|
64
|
+
max?: number;
|
|
65
|
+
minLength?: number;
|
|
66
|
+
maxLength?: number;
|
|
67
|
+
min_length?: number;
|
|
68
|
+
max_length?: number;
|
|
69
|
+
itemType?: string;
|
|
70
|
+
item_type?: string;
|
|
71
|
+
};
|
|
72
|
+
export function validatePromptVariableValues(
|
|
73
|
+
definitions: readonly VariableDefinition[],
|
|
74
|
+
values: Record<string, unknown>,
|
|
75
|
+
): Record<string, string> {
|
|
76
|
+
const errors: Record<string, string> = {};
|
|
77
|
+
for (const definition of definitions) {
|
|
78
|
+
const supplied = promptVariableValue(values, definition.name);
|
|
79
|
+
const value = supplied === undefined ? definition.default : supplied;
|
|
80
|
+
let error = "";
|
|
81
|
+
if (value === undefined || value === "") {
|
|
82
|
+
if (definition.required) error = "A value is required.";
|
|
83
|
+
} else {
|
|
84
|
+
const type = definition.type;
|
|
85
|
+
if (
|
|
86
|
+
type === "number" &&
|
|
87
|
+
(typeof value !== "number" || !Number.isFinite(value))
|
|
88
|
+
)
|
|
89
|
+
error = "Enter a valid number.";
|
|
90
|
+
if (type === "boolean" && typeof value !== "boolean")
|
|
91
|
+
error = "Choose true or false.";
|
|
92
|
+
if (type === "string" && typeof value !== "string") error = "Enter text.";
|
|
93
|
+
if (
|
|
94
|
+
type === "enum" &&
|
|
95
|
+
!(definition.enum ?? definition.values)?.includes(String(value))
|
|
96
|
+
)
|
|
97
|
+
error = "Choose one of the allowed values.";
|
|
98
|
+
if (type === "array" && !Array.isArray(value))
|
|
99
|
+
error = "Enter a valid array.";
|
|
100
|
+
if (
|
|
101
|
+
typeof value === "number" &&
|
|
102
|
+
((definition.min !== undefined && value < definition.min) ||
|
|
103
|
+
(definition.max !== undefined && value > definition.max))
|
|
104
|
+
)
|
|
105
|
+
error = `Enter a number between ${definition.min ?? "−∞"} and ${definition.max ?? "∞"}.`;
|
|
106
|
+
const minLength = definition.minLength ?? definition.min_length;
|
|
107
|
+
const maxLength = definition.maxLength ?? definition.max_length;
|
|
108
|
+
if (
|
|
109
|
+
typeof value === "string" &&
|
|
110
|
+
((minLength !== undefined && value.length < minLength) ||
|
|
111
|
+
(maxLength !== undefined && value.length > maxLength))
|
|
112
|
+
)
|
|
113
|
+
error = `Use ${minLength ?? 0} to ${maxLength ?? "any number of"} characters.`;
|
|
114
|
+
const itemType = definition.itemType ?? definition.item_type;
|
|
115
|
+
if (
|
|
116
|
+
Array.isArray(value) &&
|
|
117
|
+
itemType &&
|
|
118
|
+
value.some((item) =>
|
|
119
|
+
itemType === "array"
|
|
120
|
+
? !Array.isArray(item)
|
|
121
|
+
: itemType !== "enum" && typeof item !== itemType,
|
|
122
|
+
)
|
|
123
|
+
)
|
|
124
|
+
error = `Every item must be ${itemType}.`;
|
|
125
|
+
}
|
|
126
|
+
if (error) errors[definition.name] = error;
|
|
127
|
+
}
|
|
128
|
+
return errors;
|
|
129
|
+
}
|
|
130
|
+
export function validatePromptSettings(settings: {
|
|
131
|
+
temperature: unknown;
|
|
132
|
+
topP: unknown;
|
|
133
|
+
maxTokens: unknown;
|
|
134
|
+
}): Record<string, string> {
|
|
135
|
+
const errors: Record<string, string> = {};
|
|
136
|
+
for (const [field, label, min, max] of [
|
|
137
|
+
["temperature", "Temperature", 0, 2],
|
|
138
|
+
["topP", "Top P", 0, 1],
|
|
139
|
+
["maxTokens", "Max tokens", 1, 200000],
|
|
140
|
+
] as const) {
|
|
141
|
+
const raw = settings[field];
|
|
142
|
+
const value = Number(raw);
|
|
143
|
+
if (
|
|
144
|
+
raw === "" ||
|
|
145
|
+
raw === null ||
|
|
146
|
+
raw === undefined ||
|
|
147
|
+
!Number.isFinite(value) ||
|
|
148
|
+
value < min ||
|
|
149
|
+
value > max ||
|
|
150
|
+
(field === "maxTokens" && !Number.isInteger(value))
|
|
151
|
+
)
|
|
152
|
+
errors[field] =
|
|
153
|
+
`${label} must be ${field === "maxTokens" ? "a whole number" : "a number"} between ${min} and ${max}.`;
|
|
154
|
+
}
|
|
155
|
+
return errors;
|
|
156
|
+
}
|