@nirmos/sdk 0.3.1 → 0.3.3

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.
Files changed (91) hide show
  1. package/README.md +264 -16
  2. package/dist/cjs/client.js +1 -9
  3. package/dist/cjs/client.js.map +1 -1
  4. package/dist/cjs/core/transport.js +16 -3
  5. package/dist/cjs/core/transport.js.map +1 -1
  6. package/dist/cjs/core/version.js +6 -0
  7. package/dist/cjs/core/version.js.map +1 -0
  8. package/dist/cjs/gateway/chat-stream.js +10 -0
  9. package/dist/cjs/gateway/chat-stream.js.map +1 -1
  10. package/dist/cjs/gateway/chat.js +1 -0
  11. package/dist/cjs/gateway/chat.js.map +1 -1
  12. package/dist/cjs/gateway/embeddings.js +1 -0
  13. package/dist/cjs/gateway/embeddings.js.map +1 -1
  14. package/dist/cjs/gateway/mappers.js +39 -2
  15. package/dist/cjs/gateway/mappers.js.map +1 -1
  16. package/dist/cjs/index.js +8 -1
  17. package/dist/cjs/index.js.map +1 -1
  18. package/dist/cjs/management/manifest.js +16 -0
  19. package/dist/cjs/management/manifest.js.map +1 -1
  20. package/dist/cjs/management/resources.js +3 -1
  21. package/dist/cjs/management/resources.js.map +1 -1
  22. package/dist/cjs/prompts/render.js +12 -4
  23. package/dist/cjs/prompts/render.js.map +1 -1
  24. package/dist/cjs/prompts/variables.js +117 -0
  25. package/dist/cjs/prompts/variables.js.map +1 -0
  26. package/dist/esm/client.d.ts +6 -20
  27. package/dist/esm/client.d.ts.map +1 -1
  28. package/dist/esm/client.js +1 -9
  29. package/dist/esm/client.js.map +1 -1
  30. package/dist/esm/core/transport.js +15 -2
  31. package/dist/esm/core/transport.js.map +1 -1
  32. package/dist/esm/core/version.d.ts +2 -0
  33. package/dist/esm/core/version.d.ts.map +1 -0
  34. package/dist/esm/core/version.js +3 -0
  35. package/dist/esm/core/version.js.map +1 -0
  36. package/dist/esm/gateway/chat-stream.d.ts.map +1 -1
  37. package/dist/esm/gateway/chat-stream.js +11 -1
  38. package/dist/esm/gateway/chat-stream.js.map +1 -1
  39. package/dist/esm/gateway/chat.d.ts.map +1 -1
  40. package/dist/esm/gateway/chat.js +1 -0
  41. package/dist/esm/gateway/chat.js.map +1 -1
  42. package/dist/esm/gateway/embeddings.d.ts.map +1 -1
  43. package/dist/esm/gateway/embeddings.js +1 -0
  44. package/dist/esm/gateway/embeddings.js.map +1 -1
  45. package/dist/esm/gateway/mappers.d.ts +2 -0
  46. package/dist/esm/gateway/mappers.d.ts.map +1 -1
  47. package/dist/esm/gateway/mappers.js +38 -2
  48. package/dist/esm/gateway/mappers.js.map +1 -1
  49. package/dist/esm/gateway/types.d.ts +8 -0
  50. package/dist/esm/gateway/types.d.ts.map +1 -1
  51. package/dist/esm/index.d.ts +2 -1
  52. package/dist/esm/index.d.ts.map +1 -1
  53. package/dist/esm/index.js +1 -0
  54. package/dist/esm/index.js.map +1 -1
  55. package/dist/esm/management/contracts.d.ts +18194 -6741
  56. package/dist/esm/management/contracts.d.ts.map +1 -1
  57. package/dist/esm/management/manifest.d.ts +14 -0
  58. package/dist/esm/management/manifest.d.ts.map +1 -1
  59. package/dist/esm/management/manifest.js +16 -0
  60. package/dist/esm/management/manifest.js.map +1 -1
  61. package/dist/esm/management/resources.d.ts +2 -0
  62. package/dist/esm/management/resources.d.ts.map +1 -1
  63. package/dist/esm/management/resources.js +3 -1
  64. package/dist/esm/management/resources.js.map +1 -1
  65. package/dist/esm/memory/types.d.ts +14 -5
  66. package/dist/esm/memory/types.d.ts.map +1 -1
  67. package/dist/esm/prompts/render.js +11 -3
  68. package/dist/esm/prompts/render.js.map +1 -1
  69. package/dist/esm/prompts/variables.d.ts +29 -0
  70. package/dist/esm/prompts/variables.d.ts.map +1 -0
  71. package/dist/esm/prompts/variables.js +108 -0
  72. package/dist/esm/prompts/variables.js.map +1 -0
  73. package/examples/memory-quickstart.mjs +199 -0
  74. package/examples/memory-quickstart.ts +240 -0
  75. package/examples/tsconfig.json +5 -0
  76. package/package.json +5 -4
  77. package/src/client.ts +10 -30
  78. package/src/core/transport.ts +14 -2
  79. package/src/core/version.ts +2 -0
  80. package/src/gateway/chat-stream.ts +12 -1
  81. package/src/gateway/chat.ts +1 -0
  82. package/src/gateway/embeddings.ts +1 -0
  83. package/src/gateway/mappers.ts +55 -2
  84. package/src/gateway/types.ts +8 -0
  85. package/src/index.ts +13 -0
  86. package/src/management/contracts.ts +226 -131
  87. package/src/management/manifest.ts +16 -0
  88. package/src/management/resources.ts +3 -1
  89. package/src/memory/types.ts +15 -4
  90. package/src/prompts/render.ts +9 -4
  91. 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: { list: (query: Queries["listKnowledgeBases"] = {}, options?: RequestOptions) => transport.data<Responses["listKnowledgeBases"]>({ method: "GET", path: `/v1/knowledge-bases`, query, options }),
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 }),
@@ -79,6 +79,10 @@ export interface MemorySearchFilters {
79
79
  export interface MemorySearchRequest {
80
80
  memorySpaceId: string;
81
81
  query: string;
82
+ /** Default relevant: one bounded model check. Raw returns nearest neighbors without validation. */
83
+ relevance?: "relevant" | "raw";
84
+ /** Minimum normalized vector similarity (0–1), before ranking. Calibrate per embedding model. */
85
+ minScore?: number;
82
86
  limit?: number;
83
87
  filters?: MemorySearchFilters;
84
88
  }
@@ -100,12 +104,19 @@ export type MemoryResult = Pick<
100
104
  | "confidence"
101
105
  >;
102
106
  export interface MemorySearchResponse {
103
- memories: Array<MemoryResult & { score: number }>;
104
- }
105
- export interface MemoryContextResponse {
106
- memories: Array<MemoryResult & { score?: number }>;
107
+ memories: Array<MemoryResult & { score: number; similarityScore: number }>;
108
+ relevance: "relevant" | "raw";
107
109
  }
110
+ export type MemoryContextResponse = MemorySearchResponse;
111
+
108
112
  export interface MemoryIndexingResult {
113
+ /** Safe stage/provider diagnostics for partial indexing failures. */
114
+ diagnostics?: Array<{
115
+ code: string;
116
+ status: number;
117
+ retryable: boolean;
118
+ details?: Record<string, unknown>;
119
+ }>;
109
120
  indexed: number;
110
121
  failed: number;
111
122
  }
@@ -9,7 +9,7 @@ import type {
9
9
  RenderedPrompt,
10
10
  } from "./types.js";
11
11
 
12
- const PLACEHOLDER = /\{\{\s*([a-zA-Z][a-zA-Z0-9_.-]*)\s*\}\}/g;
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[variable.name];
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[name];
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
+ }