@happyvertical/smrt-core 0.40.62 → 0.40.63
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/AGENTS.md +16 -3
- package/README.md +12 -2
- package/agents/generators.md +22 -0
- package/dist/collection.d.ts +12 -1
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +37 -5
- package/dist/collection.js.map +1 -1
- package/dist/decorators/index.d.ts +8 -2
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js.map +1 -1
- package/dist/embeddings/types.d.ts +4 -1
- package/dist/embeddings/types.d.ts.map +1 -1
- package/dist/generators/mcp-emit.d.ts +72 -0
- package/dist/generators/mcp-emit.d.ts.map +1 -0
- package/dist/generators/mcp-emit.js +104 -0
- package/dist/generators/mcp-emit.js.map +1 -0
- package/dist/generators/mcp-runtime-template.d.ts.map +1 -1
- package/dist/generators/mcp-runtime-template.js +7 -1
- package/dist/generators/mcp-runtime-template.js.map +1 -1
- package/dist/generators/mcp.d.ts +17 -3
- package/dist/generators/mcp.d.ts.map +1 -1
- package/dist/generators/mcp.js +43 -21
- package/dist/generators/mcp.js.map +1 -1
- package/dist/manifest/generator.d.ts +5 -0
- package/dist/manifest/generator.d.ts.map +1 -1
- package/dist/manifest/generator.js +10 -7
- package/dist/manifest/generator.js.map +1 -1
- package/dist/manifest/static-manifest.js +1 -1
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.js +1 -1
- package/dist/manifest.json +1 -1
- package/dist/object.d.ts +11 -1
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +11 -1
- package/dist/object.js.map +1 -1
- package/dist/smrt-knowledge.json +7 -7
- package/dist/system/types.d.ts +4 -1
- package/dist/system/types.d.ts.map +1 -1
- package/dist/utils/scanner-module.d.ts +7 -0
- package/dist/utils/scanner-module.d.ts.map +1 -1
- package/dist/vite-plugin/index.d.ts +7 -0
- package/dist/vite-plugin/index.d.ts.map +1 -1
- package/dist/vite-plugin/index.js +3 -2
- package/dist/vite-plugin/index.js.map +1 -1
- package/package.json +10 -12
package/AGENTS.md
CHANGED
|
@@ -41,7 +41,7 @@ refreshes `last_used_at`. Keep semantic search behind the
|
|
|
41
41
|
|
|
42
42
|
```typescript
|
|
43
43
|
await collection.list({
|
|
44
|
-
where: { status: 'active', price
|
|
44
|
+
where: { status: 'active', 'price >': 10 },
|
|
45
45
|
limit: 50, offset: 0, orderBy: 'created_at DESC'
|
|
46
46
|
});
|
|
47
47
|
```
|
|
@@ -59,7 +59,20 @@ an `initialize()` hook may query through the same transaction-bound PostgreSQL
|
|
|
59
59
|
client. Keep this serialization invariant; use `select` when callers need plain
|
|
60
60
|
rows without model hydration.
|
|
61
61
|
|
|
62
|
-
**WHERE operators**: `=`, `>`, `<`, `>=`, `<=`, `!=`, `in`, `not in`, `like
|
|
62
|
+
**WHERE operators**: `=`, `>`, `<`, `>=`, `<=`, `!=`, `in`, `not in`, `like`.
|
|
63
|
+
Arrays auto-detect `IN`. NULL is a value, not an operator: `{ deletedAt: null }`
|
|
64
|
+
renders `IS NULL` and `{ 'deletedAt !=': null }` renders `IS NOT NULL`.
|
|
65
|
+
|
|
66
|
+
This list is the set `@happyvertical/sql`'s `buildWhere` can execute, and
|
|
67
|
+
`convertWhereKeys` accepts nothing outside it — an operator accepted here but
|
|
68
|
+
unknown there fails inside the query builder, after the API said the query was
|
|
69
|
+
valid (#2276). Two entries were removed for that reason and now reject at the
|
|
70
|
+
API boundary: `contains` (never existed in the SQL layer; use `like` with
|
|
71
|
+
explicit wildcards) and dot-notation JSON paths such as `metadata.userId` (never
|
|
72
|
+
rewritten into an extraction expression, so they reached SQL as qualified column
|
|
73
|
+
references). Re-adding either requires the query builder to support it first;
|
|
74
|
+
`src/__tests__/issue-2276-where-contract.test.ts` executes every accepted
|
|
75
|
+
operator against a database to keep the two in step.
|
|
63
76
|
|
|
64
77
|
STI child collections auto-filter by `_meta_type`.
|
|
65
78
|
|
|
@@ -67,7 +80,7 @@ STI child collections auto-filter by `_meta_type`.
|
|
|
67
80
|
|
|
68
81
|
Two persistence primitives every `SmrtObject`/`SmrtCollection` inherits — load-bearing for learning agents, usable by any object. Full guide: `docs/content/core.md` → "Context Memory System".
|
|
69
82
|
|
|
70
|
-
- **Context memory** (`remember`/`recall`/`recallAll`/`forget`/`forgetScope`, table `_smrt_contexts`): stores any JSON value keyed by `(owner_class, owner_id, scope, key, version)` with a `confidence` score (0–1) and a stored `expiresAt` (metadata — `recall()` does **not** filter expired rows; expiry is caller-managed). `recall()` returns the highest-confidence match with an optional `minConfidence` floor and **opt-in** hierarchical scope fallback (`includeAncestors: true` → `'a/b/c' → 'a/b' → 'a' → 'global'`; default off); `recallAll()` returns a `Map`. Typical use: cache a learned strategy (e.g. a working selector per host) and reuse it across sessions. `success_count`/`failure_count` columns exist for outcome-weighting
|
|
83
|
+
- **Context memory** (`remember`/`recall`/`recallAll`/`forget`/`forgetScope`, table `_smrt_contexts`): stores any JSON value keyed by `(owner_class, owner_id, scope, key, version)` with a `confidence` score (0–1) and a stored `expiresAt` (metadata — `recall()` does **not** filter expired rows; expiry is caller-managed). `recall()` returns the highest-confidence match with an optional `minConfidence` floor and **opt-in** hierarchical scope fallback (`includeAncestors: true` → `'a/b/c' → 'a/b' → 'a' → 'global'`; default off); `recallAll()` returns a `Map`. Typical use: cache a learned strategy (e.g. a working selector per host) and reuse it across sessions. `success_count`/`failure_count` columns exist for outcome-weighting: `SmrtObject.remember()` leaves them untouched, `SmrtCollection.remember()` resets them to zero, and neither recall path updates them. `LearningMemory` is the layer that maintains them (and that does filter expired rows).
|
|
71
84
|
- **Semantic search** (on `SmrtCollection`, table `_smrt_embeddings`): `semanticSearch(query)`, `findSimilar(object)`, `findSimilarToEmbedding(vector)` — cosine ranking over embeddings of the fields declared in `@smrt({ embeddings })`. Native pgvector/HNSW when configured, in-memory `CosineSimilarity` fallback otherwise; default local model `Xenova/bge-base-en-v1.5` (768-dim) or AI `text-embedding-3-small`. Hits hydrate via `list({ 'id in': … })`, so `@TenantScoped` isolation applies to results.
|
|
72
85
|
|
|
73
86
|
## @smrt() Decorator Options
|
package/README.md
CHANGED
|
@@ -119,7 +119,8 @@ src/routes/api/**/+server.ts
|
|
|
119
119
|
!src/routes/api/v1/**/+server.ts
|
|
120
120
|
```
|
|
121
121
|
|
|
122
|
-
Migration takes the recognized SMRT
|
|
122
|
+
Migration takes the recognized `# SMRT auto-generated routes (from Vite plugin)`
|
|
123
|
+
header — matched as a whole line — plus the contiguous run of
|
|
123
124
|
recursive `+server.ts` wildcards directly beneath it, negations included. The
|
|
124
125
|
run is matched by shape rather than against your current `routesDir`, so a
|
|
125
126
|
project that moved `routesDir` after adopting the plugin still migrates, and
|
|
@@ -372,9 +373,12 @@ Generators produce OpenAPI REST endpoints, Commander CLI commands, and MCP serve
|
|
|
372
373
|
|
|
373
374
|
Long-running item actions may opt into the experimental
|
|
374
375
|
`io.modelcontextprotocol/tasks` extension. Tasks are disabled by default; list
|
|
375
|
-
the action names explicitly and
|
|
376
|
+
the action names explicitly, and — if the class restricts what the job runner
|
|
377
|
+
may dispatch — include the action in that allowlist:
|
|
376
378
|
|
|
377
379
|
```typescript
|
|
380
|
+
import { backgroundEligible } from '@happyvertical/smrt-jobs';
|
|
381
|
+
|
|
378
382
|
@smrt({
|
|
379
383
|
mcp: { include: ['generateReport'], tasks: ['generateReport'] },
|
|
380
384
|
})
|
|
@@ -384,6 +388,12 @@ class Report extends SmrtObject {
|
|
|
384
388
|
}
|
|
385
389
|
```
|
|
386
390
|
|
|
391
|
+
`@backgroundEligible()` is owned and enforced by `@happyvertical/smrt-jobs`, not
|
|
392
|
+
by this package. It is **restrictive**: a class with no marked methods lets
|
|
393
|
+
`TaskRunner` dispatch any of its methods, and the first marked method turns the
|
|
394
|
+
set into an exhaustive allowlist that excludes every other method on the class.
|
|
395
|
+
Use it to narrow the reachable surface, and mark every method you dispatch.
|
|
396
|
+
|
|
387
397
|
The generated MCP server advertises the extension only when at least one task
|
|
388
398
|
action is enabled. A task-aware client can request the action as a durable job,
|
|
389
399
|
then use `tasks/get`, `tasks/update`, and `tasks/cancel` to observe or control
|
package/agents/generators.md
CHANGED
|
@@ -27,6 +27,28 @@ The web module also emits a build-time **`manifestHash`** constant (#1764): `com
|
|
|
27
27
|
|
|
28
28
|
Per-field web emission (#2046): `buildWebFieldDefinitions` carries `description` (from `@field({ description })`) and sanitized `ui` hints (from `@field({ ui: { basic, group, order, locked } })`, read off the manifest `_meta.ui` bag through per-key type guards) into each emitted field definition, and `buildWebToolDescriptors` threads the same `description` into browser MCP tool schemas. `sensitive`/`transient` fields are excluded from emission entirely, so their descriptions never ship. Both keys are conditional, so hint-less schemas emit byte-identical definitions (and hashes) as before; adding a description/ui hint changes the manifest hash — deliberate over-invalidation, harmless per the #1764 contract.
|
|
29
29
|
|
|
30
|
+
## Generated MCP server output language
|
|
31
|
+
|
|
32
|
+
`MCPGenerator` builds every file as TypeScript, so the requested `outputPath`
|
|
33
|
+
extension decides what is written (#2279). `.ts`/`.mts` targets keep the source
|
|
34
|
+
verbatim for `tsx` or Node type stripping — which is why the generated source
|
|
35
|
+
must stay erasable-syntax-only (no parameter properties, enums, or namespaces).
|
|
36
|
+
Every other target (`.smrt/mcp-server/index.js` by default) is transpiled to
|
|
37
|
+
JavaScript with the `typescript` dependency before writing, because the printed
|
|
38
|
+
run script and the generated `claude-config.example.json` both invoke it with
|
|
39
|
+
plain `node`. A `.cjs`/`.cts` target is rejected outright: generated servers are
|
|
40
|
+
ES modules. `src/generators/mcp-emit.ts` owns those decisions — do not
|
|
41
|
+
reintroduce a bare `writeFile` of generated source.
|
|
42
|
+
|
|
43
|
+
Modular output writes `config`, `tools/index`, and `handlers/index` with the
|
|
44
|
+
entry point's own extension, and emits the entry's relative import specifiers
|
|
45
|
+
with that same extension, so the files it imports both exist and load with the
|
|
46
|
+
same module semantics — an `.mjs` entry gets `.mjs` siblings, not `.js` ones a
|
|
47
|
+
CommonJS package would then parse as CommonJS. The entry is written at the
|
|
48
|
+
requested path rather than a hardcoded `index.js`.
|
|
49
|
+
Generated code also has to be valid in an ES module: `arguments` is not a legal
|
|
50
|
+
binding name there, however convenient it reads.
|
|
51
|
+
|
|
30
52
|
## Custom-action contract
|
|
31
53
|
|
|
32
54
|
`resolveCustomActionMetadata()` is the common discovery and invocation contract
|
package/dist/collection.d.ts
CHANGED
|
@@ -753,6 +753,10 @@ export declare class SmrtCollection<ModelType extends SmrtObject> extends SmrtCl
|
|
|
753
753
|
* Stores context applicable to all instances of this collection type.
|
|
754
754
|
* Use for patterns that apply to the entire collection (e.g., default parsing strategies).
|
|
755
755
|
*
|
|
756
|
+
* `expiresAt` is stored on the `_smrt_contexts` row as caller-managed metadata.
|
|
757
|
+
* {@link recall} and {@link recallAll} do **not** filter on it, so an expired
|
|
758
|
+
* entry is still returned; filter or delete expired entries yourself.
|
|
759
|
+
*
|
|
756
760
|
* @param options - Context options
|
|
757
761
|
* @returns Promise that resolves when context is stored
|
|
758
762
|
* @example
|
|
@@ -877,7 +881,9 @@ export declare class SmrtCollection<ModelType extends SmrtObject> extends SmrtCl
|
|
|
877
881
|
*
|
|
878
882
|
* @param query - Text to search for
|
|
879
883
|
* @param options - Search options
|
|
880
|
-
* @param options.field - Specific field to search (defaults to first embedding
|
|
884
|
+
* @param options.field - Specific field to search (defaults to first embedding
|
|
885
|
+
* field). Any configured embedding field, or the configured
|
|
886
|
+
* `combinedField.name`, is accepted.
|
|
881
887
|
* @param options.limit - Maximum results to return (default: 10)
|
|
882
888
|
* @param options.minSimilarity - Minimum similarity threshold 0-1 (default: 0)
|
|
883
889
|
* @param options.where - Additional WHERE filters to apply
|
|
@@ -893,6 +899,11 @@ export declare class SmrtCollection<ModelType extends SmrtObject> extends SmrtCl
|
|
|
893
899
|
* for (const article of results) {
|
|
894
900
|
* console.log(`${article.title} (similarity: ${article._similarity})`);
|
|
895
901
|
* }
|
|
902
|
+
*
|
|
903
|
+
* // Search the combined vector built from `combinedField.template`
|
|
904
|
+
* const combined = await articles.semanticSearch('machine learning trends', {
|
|
905
|
+
* field: 'content'
|
|
906
|
+
* });
|
|
896
907
|
* ```
|
|
897
908
|
*/
|
|
898
909
|
semanticSearch(query: string, options?: {
|
package/dist/collection.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAEL,KAAK,qBAAqB,EAQ3B,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"collection.d.ts","sourceRoot":"","sources":["../src/collection.ts"],"names":[],"mappings":"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"}
|
package/dist/collection.js
CHANGED
|
@@ -33,6 +33,22 @@ function resolveMetaTypeInWhere(where) {
|
|
|
33
33
|
return where;
|
|
34
34
|
}
|
|
35
35
|
/**
|
|
36
|
+
* Field names that carry a stored embedding vector for a class (Issue #2281)
|
|
37
|
+
*
|
|
38
|
+
* `SmrtObject.generateEmbeddings()` writes one vector per configured field and,
|
|
39
|
+
* when `combinedField` is set, an extra vector under `combinedField.name`. Any
|
|
40
|
+
* of those names is a legitimate target for the collection's semantic-search
|
|
41
|
+
* methods, so validation and error messages should describe the whole set.
|
|
42
|
+
*
|
|
43
|
+
* @param config - Resolved embedding configuration for the class
|
|
44
|
+
* @returns Configured field names, plus the combined field name when distinct
|
|
45
|
+
*/
|
|
46
|
+
function getSearchableEmbeddingFields(config) {
|
|
47
|
+
const combinedName = config.combinedField?.name;
|
|
48
|
+
if (!combinedName || config.fields.includes(combinedName)) return config.fields;
|
|
49
|
+
return [...config.fields, combinedName];
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
36
52
|
* Typed CRUD collection for a specific `SmrtObject` subclass.
|
|
37
53
|
*
|
|
38
54
|
* Each concrete collection pairs with exactly one model class via the required
|
|
@@ -111,9 +127,9 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
111
127
|
"!=",
|
|
112
128
|
"in",
|
|
113
129
|
"not in",
|
|
114
|
-
"like"
|
|
115
|
-
"contains"
|
|
130
|
+
"like"
|
|
116
131
|
];
|
|
132
|
+
const UNSUPPORTED_OPERATOR_HINTS = /* @__PURE__ */ new Map([["contains", "Use 'like' with explicit wildcards instead, e.g. { 'name like': '%term%' }."]]);
|
|
117
133
|
const fields = this.getFieldsSync();
|
|
118
134
|
const validFieldNames = new Set(Object.keys(fields).map((f) => toSnakeCase(f)));
|
|
119
135
|
const sensitiveFieldNames = this.collectSensitiveFieldNames(fields);
|
|
@@ -156,8 +172,12 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
156
172
|
const metaPathTargetsSensitive = (snakeBaseFieldName === "_meta_data" || snakeBaseFieldName === "meta_data") && !!jsonPath && jsonPath.split(".").filter(Boolean).some((segment) => sensitiveFieldNames.has(segment) || sensitiveFieldNames.has(toSnakeCase(segment)));
|
|
157
173
|
if (sensitiveFieldNames.has(snakeBaseFieldName) || metaPathTargetsSensitive) throw new Error(`Invalid WHERE clause field: '${fieldName}'. Filtering on sensitive fields is not allowed.`);
|
|
158
174
|
const effectiveOperator = operator === "=" && Array.isArray(value) ? "in" : operator;
|
|
159
|
-
if (!VALID_OPERATORS.includes(effectiveOperator))
|
|
175
|
+
if (!VALID_OPERATORS.includes(effectiveOperator)) {
|
|
176
|
+
const hint = UNSUPPORTED_OPERATOR_HINTS.get(effectiveOperator);
|
|
177
|
+
throw new Error(`Invalid WHERE clause operator: '${operator}'. Valid operators: ${VALID_OPERATORS.join(", ")}` + (hint ? `. ${hint}` : ""));
|
|
178
|
+
}
|
|
160
179
|
if (!skipFieldValidation && !validFieldNames.has(snakeBaseFieldName)) throw new Error(`Invalid WHERE clause field: '${fieldName}'. Field does not exist on ${itemClassName}. Valid fields: ${Array.from(validFieldNames).sort().join(", ")}`);
|
|
180
|
+
if (jsonPath) throw new Error(`Invalid WHERE clause field: '${fieldName}'. Dot-notation JSON paths are not supported — the path is not rewritten into a JSON extraction expression, so it would reach SQL as a qualified column reference and fail at execution. Filter on the '${baseFieldName}' column itself, or filter the extracted values in application code.`);
|
|
161
181
|
if ((effectiveOperator === "in" || effectiveOperator === "not in") && !Array.isArray(value)) throw new Error(`WHERE clause operator '${effectiveOperator}' requires an array value for field '${fieldName}', got ${typeof value}`);
|
|
162
182
|
if ((effectiveOperator === "in" || effectiveOperator === "not in") && Array.isArray(value) && value.length === 0) throw new Error(`WHERE clause operator '${effectiveOperator}' requires a non-empty array for field '${fieldName}'. Use listByIds([]) for graceful empty array handling.`);
|
|
163
183
|
if (effectiveOperator === "like" && typeof value !== "string") throw new Error(`WHERE clause operator 'like' requires a string value for field '${fieldName}', got ${typeof value}`);
|
|
@@ -1274,6 +1294,10 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
1274
1294
|
* Stores context applicable to all instances of this collection type.
|
|
1275
1295
|
* Use for patterns that apply to the entire collection (e.g., default parsing strategies).
|
|
1276
1296
|
*
|
|
1297
|
+
* `expiresAt` is stored on the `_smrt_contexts` row as caller-managed metadata.
|
|
1298
|
+
* {@link recall} and {@link recallAll} do **not** filter on it, so an expired
|
|
1299
|
+
* entry is still returned; filter or delete expired entries yourself.
|
|
1300
|
+
*
|
|
1277
1301
|
* @param options - Context options
|
|
1278
1302
|
* @returns Promise that resolves when context is stored
|
|
1279
1303
|
* @example
|
|
@@ -1502,7 +1526,9 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
1502
1526
|
*
|
|
1503
1527
|
* @param query - Text to search for
|
|
1504
1528
|
* @param options - Search options
|
|
1505
|
-
* @param options.field - Specific field to search (defaults to first embedding
|
|
1529
|
+
* @param options.field - Specific field to search (defaults to first embedding
|
|
1530
|
+
* field). Any configured embedding field, or the configured
|
|
1531
|
+
* `combinedField.name`, is accepted.
|
|
1506
1532
|
* @param options.limit - Maximum results to return (default: 10)
|
|
1507
1533
|
* @param options.minSimilarity - Minimum similarity threshold 0-1 (default: 0)
|
|
1508
1534
|
* @param options.where - Additional WHERE filters to apply
|
|
@@ -1518,6 +1544,11 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
1518
1544
|
* for (const article of results) {
|
|
1519
1545
|
* console.log(`${article.title} (similarity: ${article._similarity})`);
|
|
1520
1546
|
* }
|
|
1547
|
+
*
|
|
1548
|
+
* // Search the combined vector built from `combinedField.template`
|
|
1549
|
+
* const combined = await articles.semanticSearch('machine learning trends', {
|
|
1550
|
+
* field: 'content'
|
|
1551
|
+
* });
|
|
1521
1552
|
* ```
|
|
1522
1553
|
*/
|
|
1523
1554
|
async semanticSearch(query, options = {}) {
|
|
@@ -1525,7 +1556,8 @@ var SmrtCollection = class SmrtCollection extends SmrtClass {
|
|
|
1525
1556
|
const embeddingConfig = ObjectRegistry.resolveEmbeddingConfig(this._itemClass.name);
|
|
1526
1557
|
if (!embeddingConfig) throw new Error(`No embedding configuration found for ${this._itemClass.name}. Add embeddings config to @smrt() decorator.`);
|
|
1527
1558
|
const searchField = field || embeddingConfig.fields[0];
|
|
1528
|
-
|
|
1559
|
+
const searchableFields = getSearchableEmbeddingFields(embeddingConfig);
|
|
1560
|
+
if (!searchableFields.includes(searchField)) throw new Error(`Field '${searchField}' is not configured for embeddings on ${this._itemClass.name}. Available fields: ${searchableFields.join(", ")}`);
|
|
1529
1561
|
const [queryEmbedding] = await new EmbeddingProvider({
|
|
1530
1562
|
dimensions: embeddingConfig.dimensions,
|
|
1531
1563
|
provider: embeddingConfig.provider,
|