@memberjunction/core-entities-server 6.2.0-edge.6 → 6.2.0-edge.7
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 +155 -100
- package/dist/custom/MJAIAgentExampleEntityServer.server.d.ts +2 -0
- package/dist/custom/MJAIAgentExampleEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIAgentExampleEntityServer.server.js +8 -5
- package/dist/custom/MJAIAgentExampleEntityServer.server.js.map +1 -1
- package/dist/custom/MJAIAgentNoteEntityServer.server.d.ts +2 -0
- package/dist/custom/MJAIAgentNoteEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIAgentNoteEntityServer.server.js +8 -5
- package/dist/custom/MJAIAgentNoteEntityServer.server.js.map +1 -1
- package/dist/custom/MJAIAgentRelationshipEntityServer.server.d.ts +17 -0
- package/dist/custom/MJAIAgentRelationshipEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJAIAgentRelationshipEntityServer.server.js +71 -0
- package/dist/custom/MJAIAgentRelationshipEntityServer.server.js.map +1 -0
- package/dist/custom/MJAIAgentSessionEntityServer.server.d.ts +8 -22
- package/dist/custom/MJAIAgentSessionEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIAgentSessionEntityServer.server.js +24 -1
- package/dist/custom/MJAIAgentSessionEntityServer.server.js.map +1 -1
- package/dist/custom/MJAIAgentUserPolicyEntityServer.server.d.ts +23 -0
- package/dist/custom/MJAIAgentUserPolicyEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJAIAgentUserPolicyEntityServer.server.js +53 -0
- package/dist/custom/MJAIAgentUserPolicyEntityServer.server.js.map +1 -0
- package/dist/custom/MJAIPromptEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJAIPromptEntityServer.server.js +2 -1
- package/dist/custom/MJAIPromptEntityServer.server.js.map +1 -1
- package/dist/custom/MJBrandKitEntityServer.server.d.ts +14 -0
- package/dist/custom/MJBrandKitEntityServer.server.d.ts.map +1 -0
- package/dist/custom/MJBrandKitEntityServer.server.js +75 -0
- package/dist/custom/MJBrandKitEntityServer.server.js.map +1 -0
- package/dist/custom/MJCompanyIntegrationEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJCompanyIntegrationEntityServer.server.js +1 -0
- package/dist/custom/MJCompanyIntegrationEntityServer.server.js.map +1 -1
- package/dist/custom/MJComponentEntityServer.server.d.ts +2 -0
- package/dist/custom/MJComponentEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJComponentEntityServer.server.js +5 -1
- package/dist/custom/MJComponentEntityServer.server.js.map +1 -1
- package/dist/custom/MJEntityDocumentEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJEntityDocumentEntityServer.server.js +1 -0
- package/dist/custom/MJEntityDocumentEntityServer.server.js.map +1 -1
- package/dist/custom/MJListDetailEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJListDetailEntityServer.server.js +1 -0
- package/dist/custom/MJListDetailEntityServer.server.js.map +1 -1
- package/dist/custom/MJQueryEntityServer.server.d.ts +177 -47
- package/dist/custom/MJQueryEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJQueryEntityServer.server.js +465 -162
- package/dist/custom/MJQueryEntityServer.server.js.map +1 -1
- package/dist/custom/MJQuerySQLEntityServer.server.d.ts +15 -18
- package/dist/custom/MJQuerySQLEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJQuerySQLEntityServer.server.js +34 -42
- package/dist/custom/MJQuerySQLEntityServer.server.js.map +1 -1
- package/dist/custom/MJTagEntityServer.server.d.ts +2 -0
- package/dist/custom/MJTagEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJTagEntityServer.server.js +13 -7
- package/dist/custom/MJTagEntityServer.server.js.map +1 -1
- package/dist/custom/MJUserRoutineEntityServer.server.d.ts.map +1 -1
- package/dist/custom/MJUserRoutineEntityServer.server.js +8 -1
- package/dist/custom/MJUserRoutineEntityServer.server.js.map +1 -1
- package/dist/custom/query-extraction/childRowWriter.d.ts +77 -0
- package/dist/custom/query-extraction/childRowWriter.d.ts.map +1 -0
- package/dist/custom/query-extraction/childRowWriter.js +277 -0
- package/dist/custom/query-extraction/childRowWriter.js.map +1 -0
- package/dist/custom/query-extraction/compositionTargets.d.ts +40 -0
- package/dist/custom/query-extraction/compositionTargets.d.ts.map +1 -0
- package/dist/custom/query-extraction/compositionTargets.js +99 -0
- package/dist/custom/query-extraction/compositionTargets.js.map +1 -0
- package/dist/custom/query-extraction/declared.d.ts +79 -0
- package/dist/custom/query-extraction/declared.d.ts.map +1 -0
- package/dist/custom/query-extraction/declared.js +91 -0
- package/dist/custom/query-extraction/declared.js.map +1 -0
- package/dist/custom/query-extraction/describeFacts.d.ts +40 -0
- package/dist/custom/query-extraction/describeFacts.d.ts.map +1 -0
- package/dist/custom/query-extraction/describeFacts.js +225 -0
- package/dist/custom/query-extraction/describeFacts.js.map +1 -0
- package/dist/custom/query-extraction/descriptionPass.d.ts +23 -0
- package/dist/custom/query-extraction/descriptionPass.d.ts.map +1 -0
- package/dist/custom/query-extraction/descriptionPass.js +95 -0
- package/dist/custom/query-extraction/descriptionPass.js.map +1 -0
- package/dist/custom/query-extraction/extractQuery.d.ts +25 -0
- package/dist/custom/query-extraction/extractQuery.d.ts.map +1 -0
- package/dist/custom/query-extraction/extractQuery.js +146 -0
- package/dist/custom/query-extraction/extractQuery.js.map +1 -0
- package/dist/custom/query-extraction/extractionTypes.d.ts +133 -0
- package/dist/custom/query-extraction/extractionTypes.d.ts.map +1 -0
- package/dist/custom/query-extraction/extractionTypes.js +2 -0
- package/dist/custom/query-extraction/extractionTypes.js.map +1 -0
- package/dist/custom/query-extraction/index.d.ts +16 -0
- package/dist/custom/query-extraction/index.d.ts.map +1 -1
- package/dist/custom/query-extraction/index.js +11 -1
- package/dist/custom/query-extraction/index.js.map +1 -1
- package/dist/custom/query-extraction/pipeline.d.ts +6 -2
- package/dist/custom/query-extraction/pipeline.d.ts.map +1 -1
- package/dist/custom/query-extraction/pipeline.js +21 -14
- package/dist/custom/query-extraction/pipeline.js.map +1 -1
- package/dist/custom/query-extraction/resolve.d.ts +7 -2
- package/dist/custom/query-extraction/resolve.d.ts.map +1 -1
- package/dist/custom/query-extraction/resolve.js +17 -14
- package/dist/custom/query-extraction/resolve.js.map +1 -1
- package/dist/custom/query-extraction/sourceBinding.d.ts +57 -0
- package/dist/custom/query-extraction/sourceBinding.d.ts.map +1 -0
- package/dist/custom/query-extraction/sourceBinding.js +104 -0
- package/dist/custom/query-extraction/sourceBinding.js.map +1 -0
- package/dist/custom/query-extraction/sync.d.ts +27 -3
- package/dist/custom/query-extraction/sync.d.ts.map +1 -1
- package/dist/custom/query-extraction/sync.js +69 -44
- package/dist/custom/query-extraction/sync.js.map +1 -1
- package/dist/custom/query-extraction/templateFacts.d.ts +62 -0
- package/dist/custom/query-extraction/templateFacts.d.ts.map +1 -0
- package/dist/custom/query-extraction/templateFacts.js +229 -0
- package/dist/custom/query-extraction/templateFacts.js.map +1 -0
- package/dist/custom/query-extraction/types.d.ts +4 -0
- package/dist/custom/query-extraction/types.d.ts.map +1 -1
- package/dist/custom/query-refresh/QueryExtractionService.d.ts +54 -0
- package/dist/custom/query-refresh/QueryExtractionService.d.ts.map +1 -0
- package/dist/custom/query-refresh/QueryExtractionService.js +207 -0
- package/dist/custom/query-refresh/QueryExtractionService.js.map +1 -0
- package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.d.ts +28 -0
- package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.d.ts.map +1 -0
- package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.js +106 -0
- package/dist/custom/query-refresh/QueryRefreshExtractionServerOperation.js.map +1 -0
- package/dist/custom/query-refresh/index.d.ts +14 -0
- package/dist/custom/query-refresh/index.d.ts.map +1 -0
- package/dist/custom/query-refresh/index.js +10 -0
- package/dist/custom/query-refresh/index.js.map +1 -0
- package/dist/custom/query-refresh/queryRebind.d.ts +33 -0
- package/dist/custom/query-refresh/queryRebind.d.ts.map +1 -0
- package/dist/custom/query-refresh/queryRebind.js +85 -0
- package/dist/custom/query-refresh/queryRebind.js.map +1 -0
- package/dist/custom/query-refresh/refreshAuthorization.d.ts +29 -0
- package/dist/custom/query-refresh/refreshAuthorization.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshAuthorization.js +66 -0
- package/dist/custom/query-refresh/refreshAuthorization.js.map +1 -0
- package/dist/custom/query-refresh/refreshFormat.d.ts +16 -0
- package/dist/custom/query-refresh/refreshFormat.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshFormat.js +67 -0
- package/dist/custom/query-refresh/refreshFormat.js.map +1 -0
- package/dist/custom/query-refresh/refreshOrder.d.ts +25 -0
- package/dist/custom/query-refresh/refreshOrder.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshOrder.js +95 -0
- package/dist/custom/query-refresh/refreshOrder.js.map +1 -0
- package/dist/custom/query-refresh/refreshSelection.d.ts +15 -0
- package/dist/custom/query-refresh/refreshSelection.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshSelection.js +99 -0
- package/dist/custom/query-refresh/refreshSelection.js.map +1 -0
- package/dist/custom/query-refresh/refreshTypes.d.ts +81 -0
- package/dist/custom/query-refresh/refreshTypes.d.ts.map +1 -0
- package/dist/custom/query-refresh/refreshTypes.js +5 -0
- package/dist/custom/query-refresh/refreshTypes.js.map +1 -0
- package/dist/custom/util.d.ts +8 -0
- package/dist/custom/util.d.ts.map +1 -1
- package/dist/custom/util.js +18 -1
- package/dist/custom/util.js.map +1 -1
- package/dist/engines/QueryEngineServer.d.ts +4 -1
- package/dist/engines/QueryEngineServer.d.ts.map +1 -1
- package/dist/engines/QueryEngineServer.js +10 -7
- package/dist/engines/QueryEngineServer.js.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/package.json +30 -30
package/README.md
CHANGED
|
@@ -9,14 +9,14 @@ This package contains server-side implementations of MemberJunction entity subcl
|
|
|
9
9
|
```mermaid
|
|
10
10
|
graph TD
|
|
11
11
|
A["Core Entities Server"] --> B["AIPromptEntityExtended"]
|
|
12
|
-
A --> C["
|
|
12
|
+
A --> C["MJQueryEntityServer"]
|
|
13
13
|
A --> D["ComponentEntityExtended"]
|
|
14
14
|
A --> E["MJActionEntityExtended"]
|
|
15
15
|
A --> F["ApplicationEntityExtended"]
|
|
16
16
|
A --> G["Other Server Entities"]
|
|
17
17
|
|
|
18
18
|
B -->|manages| H["Templates<br/>Template Contents"]
|
|
19
|
-
C -->|
|
|
19
|
+
C -->|extracts| L["Query Fields<br/>Parameters<br/>Entities<br/>Dependencies"]
|
|
20
20
|
D -->|generates| I["Vector Embeddings"]
|
|
21
21
|
|
|
22
22
|
J["MJ Class Factory"] -->|returns server subclass| A
|
|
@@ -32,6 +32,7 @@ graph TD
|
|
|
32
32
|
style I fill:#b8762f,stroke:#8a5722,color:#fff
|
|
33
33
|
style J fill:#2d6a9f,stroke:#1a4971,color:#fff
|
|
34
34
|
style K fill:#b8762f,stroke:#8a5722,color:#fff
|
|
35
|
+
style L fill:#2d8659,stroke:#1a5c3a,color:#fff
|
|
35
36
|
```
|
|
36
37
|
|
|
37
38
|
### Key Differences from Core Entities
|
|
@@ -49,14 +50,13 @@ npm install @memberjunction/core-entities-server
|
|
|
49
50
|
|
|
50
51
|
### Basic Setup
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
import { LoadCoreEntitiesServerSubClasses } from '@memberjunction/core-entities-server';
|
|
53
|
+
Each server-side subclass registers itself with `@RegisterClass` when the package is imported, so there is no setup function to call:
|
|
54
54
|
|
|
55
|
-
|
|
56
|
-
|
|
55
|
+
```typescript
|
|
56
|
+
import '@memberjunction/core-entities-server';
|
|
57
57
|
```
|
|
58
58
|
|
|
59
|
-
**Important**:
|
|
59
|
+
**Important**: The package must be loaded before any entities are instantiated. An MJAPI server built on `@memberjunction/server-bootstrap` loads it through the bootstrap's class-registration manifest, which also keeps a bundler from removing the classes as unused. Other server applications import the package at startup.
|
|
60
60
|
|
|
61
61
|
### Example: AI Prompt Entity
|
|
62
62
|
|
|
@@ -97,13 +97,16 @@ Extends the Component entity with automatic vector embedding generation:
|
|
|
97
97
|
- **Smart Updates**: Only regenerates embeddings when source text changes
|
|
98
98
|
- **Parallel Processing**: Generates multiple embeddings concurrently for performance
|
|
99
99
|
|
|
100
|
-
###
|
|
100
|
+
### MJQueryEntityServer
|
|
101
101
|
|
|
102
|
-
|
|
102
|
+
The server-side `MJ: Queries` entity. It extends `MJQueryEntityExtended` from `@memberjunction/core-entities`:
|
|
103
103
|
|
|
104
|
-
- **
|
|
105
|
-
- **
|
|
106
|
-
- **
|
|
104
|
+
- **Query Extraction**: Saving a new query, or a query whose SQL changed, works out the query's output fields, parameters, the entities it reads and its dependencies, and writes them as child rows. See [Query Extraction](#query-extraction).
|
|
105
|
+
- **Save-Time Rules**: A query whose template breaks a rule, or whose output repeats a column name, is refused with the reasons in the save's result.
|
|
106
|
+
- **Declared Child Rows**: A query and the `Parameters`, `Fields` and `Entities` rows it declares save together as one graph.
|
|
107
|
+
- **Embeddings**: Computes a vector from the query's name, user question and description, unless `SkipEmbeddings` is set.
|
|
108
|
+
- **Dialect Conversion**: Keeps the query's SQL variants for other database platforms in step with its SQL.
|
|
109
|
+
- **On-Demand Refresh**: `QueryExtractionService` re-runs extraction for saved queries without changing their SQL. See [Query Refresh](#query-refresh).
|
|
107
110
|
|
|
108
111
|
### MJAIAgentNoteEntityServer (v5.30.x+)
|
|
109
112
|
|
|
@@ -129,8 +132,8 @@ The **AI-from-Description** half of the [Remote Operations](../../guides/REMOTE_
|
|
|
129
132
|
|
|
130
133
|
The package uses MemberJunction's entity subclassing system:
|
|
131
134
|
|
|
132
|
-
1. At startup,
|
|
133
|
-
2.
|
|
135
|
+
1. At startup, the package is imported (directly, or through the server bootstrap's class-registration manifest)
|
|
136
|
+
2. Each subclass's `@RegisterClass` decorator registers it with the metadata system
|
|
134
137
|
3. When code requests an entity (e.g., "AI Prompts"), the metadata system returns the server-side subclass
|
|
135
138
|
4. The server-side subclass extends the base entity with additional functionality
|
|
136
139
|
|
|
@@ -305,130 +308,182 @@ export class OrderEntityServer extends OrderEntity {
|
|
|
305
308
|
}
|
|
306
309
|
```
|
|
307
310
|
|
|
308
|
-
##
|
|
311
|
+
## Query Extraction
|
|
309
312
|
|
|
310
|
-
|
|
313
|
+
When a query is saved and it is new, or its SQL changed, `MJQueryEntityServer` works out what the query reads and returns, and writes it to the query's child entities. Nothing has to be filled in by hand for a query to be usable.
|
|
311
314
|
|
|
312
|
-
###
|
|
315
|
+
### What a Save Does
|
|
313
316
|
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
+
1. **Reads the template.** MJ's own template parser reads the SQL: its parameters (with composition pass-throughs), the queries it composes (`{{query:"Category/Name(...)"}}`), and the tables and views it reads. Whether the query uses a template at all (`UsesTemplate`) comes from the lexer, so a tag inside a comment does not count.
|
|
318
|
+
2. **Asks the database server.** The query is rendered with sample parameter values (a caller can supply tested values in `ParameterHints`, keyed by parameter name), once for the base render and once for each `{% if %}` branch, and the database server is asked to describe each render without running it. The server reports each output column's exact type, nullability, and the table column it comes from, when there is one.
|
|
319
|
+
3. **Applies the save-time rules.** A rule error in the template, or an output that repeats a column name, refuses the save. Nothing is written, and the reasons are in the save's result (`LatestResult`).
|
|
320
|
+
4. **Writes the child rows** once the query row is saved:
|
|
317
321
|
|
|
318
|
-
|
|
322
|
+
| Child entity | What is written |
|
|
323
|
+
|---|---|
|
|
324
|
+
| `MJ: Query Fields` | Each output column: name, order, SQL type, nullability, whether it is computed, and its source (`SourceEntityFieldID` when the column maps to an entity field, otherwise `SourceObjectName`, the object the server reported) |
|
|
325
|
+
| `MJ: Query Parameters` | Each template parameter: name, inferred type, whether it is required, its default |
|
|
326
|
+
| `MJ: Query Entities` | Each entity whose base view, base table or alternate base view the query reads |
|
|
327
|
+
| `MJ: Query Dependencies` | Each query it composes, with the alias and parameter mapping |
|
|
319
328
|
|
|
320
|
-
|
|
321
|
-
|
|
329
|
+
5. **Records the run** on the query row (see [Extraction Status](#extraction-status)).
|
|
330
|
+
6. **Fills empty descriptions** with an LLM, after the save's transaction commits. Facts never come from the LLM. Pass `SkipEntityAIActions: true` in the save options to skip this step.
|
|
322
331
|
|
|
323
|
-
|
|
324
|
-
SELECT c.Name, c.Email, o.OrderDate, o.Total
|
|
325
|
-
FROM [dbo].[Customer] c
|
|
326
|
-
INNER JOIN [dbo].[Order] o ON o.CustomerID = c.ID
|
|
327
|
-
WHERE o.Status = 'Active'
|
|
328
|
-
`;
|
|
332
|
+
### Facts and Annotations
|
|
329
333
|
|
|
330
|
-
|
|
334
|
+
Extraction separates what the SQL determines from what a person wrote:
|
|
331
335
|
|
|
332
|
-
|
|
333
|
-
for (
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
// Output:
|
|
337
|
-
// dbo.Customer (alias: c)
|
|
338
|
-
// dbo.Order (alias: o)
|
|
336
|
+
- **Facts** are corrected on every run: names, order, types, nullability, sources and the computed flag. A fact a person edited is set back to what the SQL and the server say.
|
|
337
|
+
- **Annotations** are kept: descriptions, and for a parameter a person wrote (`DetectionMethod` `Manual`), its type, required flag, default, sample value and validation filters. Doc comments in the SQL (`{# @param ... #}`, `{# @field ... #}`, and a trailing `--:` comment on a select-list line) count as authored.
|
|
338
|
+
- **A parameter a person wrote that the SQL no longer uses** is kept, and flagged in `ExtractionMessage`.
|
|
339
|
+
- **A row extraction added that the SQL no longer produces** is removed.
|
|
339
340
|
|
|
340
|
-
|
|
341
|
-
for (const col of result.Columns) {
|
|
342
|
-
console.log(`${col.TableQualifier ? col.TableQualifier + '.' : ''}${col.ColumnName}`);
|
|
343
|
-
}
|
|
344
|
-
// Output:
|
|
345
|
-
// c.Name, c.Email, o.OrderDate, o.Total, o.CustomerID, c.ID, o.Status
|
|
341
|
+
### DetectionMethod Values
|
|
346
342
|
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
343
|
+
Each child row records who wrote it:
|
|
344
|
+
|
|
345
|
+
| Value | Used on | Meaning |
|
|
346
|
+
|---|---|---|
|
|
347
|
+
| `Database` | Query Fields | The facts came from the database server describing the query's output |
|
|
348
|
+
| `Parser` | Query Fields, Parameters, Entities | The facts came from MJ's analysis of the template and SQL structure |
|
|
349
|
+
| `Manual` | Query Fields, Parameters, Entities, Dependencies | A person wrote the row. A `Manual` parameter's annotations are never overwritten, and it is kept when the SQL stops using it |
|
|
350
|
+
| `AI` | Query Fields, Parameters, Entities | On a field, an LLM wrote its description (an LLM never sets types or sources). On a parameter or entity link, the row was written by the earlier LLM-based extraction |
|
|
351
|
+
| `Auto` | Query Dependencies | The dependency was found in the SQL |
|
|
350
352
|
|
|
351
|
-
###
|
|
353
|
+
### Extraction Status
|
|
352
354
|
|
|
353
|
-
|
|
355
|
+
Each run is recorded on the `MJ: Queries` row:
|
|
356
|
+
|
|
357
|
+
| Column | Meaning |
|
|
358
|
+
|---|---|
|
|
359
|
+
| `ExtractionStatus` | `OK`: every fact was extracted. `Warning`: extraction succeeded with findings. `Error`: the database server could not describe the query, so the stored child rows were kept. `Skipped`: the facts could not be checked, for example for a query on an external data source. `NULL`: never extracted. |
|
|
360
|
+
| `ExtractionMessage` | The run's findings, one per line: flagged parameters, rule warnings, the server's error |
|
|
361
|
+
| `ExtractedSQLHash` | A hash of the SQL and dialect the child rows were extracted from. A value that differs from the current SQL's hash means the rows may be stale |
|
|
362
|
+
|
|
363
|
+
### Controlling Extraction per Save
|
|
364
|
+
|
|
365
|
+
`MJQueryEntityServer.ExtractionOverride` sets what the next save does. It goes back to `Auto` after every save.
|
|
366
|
+
|
|
367
|
+
| Value | Behaviour |
|
|
368
|
+
|---|---|
|
|
369
|
+
| `Auto` (default) | Extract when the query is new or its SQL changed |
|
|
370
|
+
| `Skip` | Do not extract, even when the SQL changed. The save-time rules are not applied, and the child rows, the extraction columns and `UsesTemplate` stay as they are. For bulk loaders and fixtures that write those rows themselves |
|
|
371
|
+
| `Force` | Extract even when the SQL did not change. On a query whose SQL did not change, rule errors are recorded instead of refusing the save; a save that changes the SQL is still held to the save-time rules |
|
|
354
372
|
|
|
355
373
|
```typescript
|
|
356
|
-
import {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
console.
|
|
374
|
+
import { Metadata, UserInfo } from '@memberjunction/core';
|
|
375
|
+
import { MJQueryEntityServer } from '@memberjunction/core-entities-server';
|
|
376
|
+
|
|
377
|
+
async function saveQuery(contextUser: UserInfo, queryID: string, sql: string): Promise<boolean> {
|
|
378
|
+
const md = new Metadata();
|
|
379
|
+
const query = await md.GetEntityObject<MJQueryEntityServer>('MJ: Queries', contextUser);
|
|
380
|
+
if (!(await query.Load(queryID))) return false;
|
|
381
|
+
|
|
382
|
+
query.SQL = sql;
|
|
383
|
+
query.ExtractionOverride = 'Auto'; // the default; 'Skip' or 'Force' change this one save
|
|
384
|
+
const saved = await query.Save({ SkipEntityAIActions: true }); // no LLM description pass
|
|
385
|
+
if (!saved) {
|
|
386
|
+
console.error(query.LatestResult?.CompleteMessage); // the save-time rule findings
|
|
387
|
+
}
|
|
388
|
+
return saved;
|
|
389
|
+
}
|
|
369
390
|
```
|
|
370
391
|
|
|
371
|
-
###
|
|
392
|
+
### Other Behaviour
|
|
372
393
|
|
|
373
|
-
|
|
394
|
+
- **Declared child rows win by name.** A save can declare child rows through the query's `Parameters`, `Fields` and `Entities` collections, and the query and those rows save as one graph. Extraction does not add a second row with a declared row's name or delete a declared row. A declared field still gets its facts from the describe, so only its annotations are the caller's.
|
|
395
|
+
- **Written as the system user.** The child rows a save derives mirror SQL the caller was allowed to change, so they are written as the system user, inside the caller's transaction when there is one. A failed child-row write is recorded on the query as an `Error` rather than failing a save whose row is already written.
|
|
396
|
+
- **Tables named by a parameter.** A query that reads a table or view named by a template parameter is not described, because its columns depend on the arguments. Its declared fields are kept, and `ExtractionMessage` says why.
|
|
397
|
+
- **Network providers.** A query saved through a network (client) provider leaves extraction to the server it saves to.
|
|
374
398
|
|
|
375
|
-
|
|
376
|
-
import { Metadata } from '@memberjunction/core';
|
|
377
|
-
import { SQLParser } from '@memberjunction/core-entities-server';
|
|
399
|
+
### Legacy Pipeline
|
|
378
400
|
|
|
379
|
-
|
|
380
|
-
|
|
401
|
+
`RunExtractionPipeline` in `src/custom/query-extraction/pipeline.ts`, the earlier LLM-assisted extraction, is deprecated. It is not used by saves and is not exported from the package root. Saves use `ComputeQueryExtraction` with `WriteExtractedChildRows`. The pipeline is kept until 7.0 for code that imports it directly.
|
|
402
|
+
|
|
403
|
+
## Query Refresh
|
|
404
|
+
|
|
405
|
+
`QueryExtractionService` re-runs extraction for saved queries on demand, without changing their SQL. It is the same extraction a save runs, under the refresh rules: a rule error is recorded on the query, never a refusal. Use it after a schema change, after an upgrade, or when a query's child rows look stale.
|
|
406
|
+
|
|
407
|
+
- **`RefreshQuery(queryID, options)`** refreshes one query and returns a `QueryRefreshReport`.
|
|
408
|
+
- **`RefreshQueries(filter, options)`** refreshes a selection and returns a `QueryRefreshRunReport`. The `QueryRefreshFilter` selectors combine as a union: `QueryIDs`, `QueryNames` (a bare name or a full path such as `Category/Sub/Name`), `CategoryPath` (that category and every category below it), `EntityNames` or `EntityIDs` (the queries that read those entities), or `All`. A filter with no selector refreshes nothing.
|
|
409
|
+
- **`QueryRefreshOptions`**: `DryRun` works out and reports the changes without writing anything; `WithAI` queues the LLM description pass for rows still without a description (off by default); `OnProgress` is called after each query in a bulk run.
|
|
381
410
|
|
|
382
|
-
|
|
383
|
-
const entity = md.Entities.find(e =>
|
|
384
|
-
(e.BaseTable.toLowerCase() === tableRef.TableName.toLowerCase() ||
|
|
385
|
-
e.BaseView.toLowerCase() === tableRef.TableName.toLowerCase()) &&
|
|
386
|
-
e.SchemaName.toLowerCase() === tableRef.SchemaName.toLowerCase()
|
|
387
|
-
);
|
|
411
|
+
Each query is refreshed in its own transaction on the caller's provider, so a failure rolls back that query only. A bulk run refreshes the queries a composition depends on before the queries that compose them; queries that compose each other in a cycle are refreshed once, after the rest, and listed in `Cycles`.
|
|
388
412
|
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
413
|
+
Each query's report gives:
|
|
414
|
+
|
|
415
|
+
- `Outcome`: `Refreshed` (rows changed, or would change in a dry run), `Unchanged`, `NotPermitted` (a bulk run skipped it), `Unavailable` (does not exist, or the caller may not refresh it), or `Failed` (nothing was written)
|
|
416
|
+
- `Added`, `Updated` and `Removed`: the child rows changed, with the changed columns for an update
|
|
417
|
+
- `Flagged`: authored parameters the SQL no longer uses
|
|
418
|
+
- `ExtractionStatus`, `QueryColumns` (the query-row columns that change) and `Diagnostics`
|
|
419
|
+
|
|
420
|
+
```typescript
|
|
421
|
+
import { IMetadataProvider, UserInfo } from '@memberjunction/core';
|
|
422
|
+
import {
|
|
423
|
+
FormatQueryRefreshRun,
|
|
424
|
+
IsQueryRefreshProvider,
|
|
425
|
+
QueryExtractionService,
|
|
426
|
+
QueryRefreshFilter,
|
|
427
|
+
} from '@memberjunction/core-entities-server';
|
|
428
|
+
|
|
429
|
+
async function refreshSalesQueries(provider: IMetadataProvider, contextUser: UserInfo): Promise<void> {
|
|
430
|
+
if (!IsQueryRefreshProvider(provider)) {
|
|
431
|
+
throw new Error('A query refresh needs a provider that can run views');
|
|
432
|
+
}
|
|
433
|
+
const service = new QueryExtractionService({ Provider: provider, User: contextUser });
|
|
434
|
+
const filter: QueryRefreshFilter = { CategoryPath: 'Reports/Sales' };
|
|
435
|
+
|
|
436
|
+
// Review first: a dry run reports what would change and writes nothing
|
|
437
|
+
const preview = await service.RefreshQueries(filter, {
|
|
438
|
+
DryRun: true,
|
|
439
|
+
OnProgress: p => console.log(`${p.Processed}/${p.Total} ${p.Report.Outcome}: ${p.Report.QueryName}`),
|
|
440
|
+
});
|
|
441
|
+
for (const line of FormatQueryRefreshRun(preview, true)) console.log(line);
|
|
442
|
+
|
|
443
|
+
// Then apply
|
|
444
|
+
const run = await service.RefreshQueries(filter);
|
|
445
|
+
for (const report of run.Reports) {
|
|
446
|
+
if (report.Outcome === 'Failed') console.error(report.QueryName, report.Diagnostics);
|
|
392
447
|
}
|
|
393
448
|
}
|
|
394
449
|
```
|
|
395
450
|
|
|
396
|
-
###
|
|
451
|
+
### Entry Points
|
|
397
452
|
|
|
398
|
-
|
|
399
|
-
interface SQLParseResult {
|
|
400
|
-
Tables: SQLTableReference[]; // All table/view references (FROM, JOIN, subqueries, CTEs)
|
|
401
|
-
Columns: SQLColumnReference[]; // All column references (SELECT, WHERE, JOIN ON, etc.)
|
|
402
|
-
UsedASTParsing: boolean; // true = AST parsed, false = regex fallback
|
|
403
|
-
}
|
|
453
|
+
Every entry point goes through `QueryExtractionService`, so the same authorization applies to all of them:
|
|
404
454
|
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
Alias: string; // Query alias, or table name if no alias
|
|
409
|
-
}
|
|
455
|
+
- **`Query.RefreshExtraction` remote operation** (`QueryRefreshExtractionServerOperation`): a long-running operation that reports each query as a progress event. An API key needs the `query:refresh` scope.
|
|
456
|
+
- **CLI**: `mj query refresh [--id|--name|--category|--entity|--all] [--dry-run] [--with-ai]`. After an upgrade, run `mj query refresh --all --dry-run` to review, then `mj query refresh --all`.
|
|
457
|
+
- **CodeGen**: `RebindQueriesForChangedEntities` refreshes the queries that read an entity whose fields were added, dropped, or changed in type or nullability, with no description pass. The SQL is never edited: a query the change broke is recorded as an `Error` with the server's message. A query authorized by its role list (`MJ: Query Permissions`) that gains a column from a field with field permissions is recorded as a `Warning`.
|
|
410
458
|
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
459
|
+
### Refresh Authorization
|
|
460
|
+
|
|
461
|
+
- The caller needs Update on `MJ: Queries` and Create, Update and Delete on `MJ: Query Fields`, `MJ: Query Parameters`, `MJ: Query Entities` and `MJ: Query Dependencies`. A dry run needs the same, since its report shows the same metadata. Run permissions on the query play no part: refreshing is an authoring act.
|
|
462
|
+
- The caller must be able to read every entity the query reads, with no field denied on any of them, because the report and the written rows expose those entities' columns.
|
|
463
|
+
- A refused single query reads exactly like one that does not exist (`Unavailable`). A bulk run reports a refused query as `NotPermitted`, with no reason.
|
|
464
|
+
- A refresh writes the child rows as the caller, not as the system user, so each write's own permission check also applies.
|
|
416
465
|
|
|
417
|
-
|
|
466
|
+
`UserCanRefreshQueries(user, entities)` and `UserCanSeeQuerySources(user, entityIDs, entities)` expose these checks for callers that want to test them up front.
|
|
467
|
+
|
|
468
|
+
## SQL Parser
|
|
418
469
|
|
|
419
|
-
|
|
470
|
+
This package does not contain a SQL parser. SQL and template parsing live in [`@memberjunction/sql-parser`](../SQLParser/README.md), which query extraction uses. New code reads SQL with `SqlDocument.Parse(sql, dialect)` (table references, column references, output items, CTEs) and templates with `QueryTemplate.Parse(sql, dialect)` (parameters, compositions, `{% if %}` branches).
|
|
420
471
|
|
|
421
|
-
|
|
472
|
+
The legacy `SQLParser` class in `@memberjunction/sql-parser` is deprecated but kept. Its `Parse` and extraction methods now run on the new parser, which changes some results from earlier releases:
|
|
422
473
|
|
|
423
|
-
|
|
474
|
+
- A CTE name is not reported as a table, and neither are table-valued functions or derived tables.
|
|
475
|
+
- Names inside comments and string literals are never read as tables or columns.
|
|
476
|
+
- A template is read branch by branch, and the result is the union of every branch's references; a `{{query:"..."}}` composition is not a table.
|
|
477
|
+
- An unqualified table gets the dialect's default schema (`dbo` on SQL Server, `public` on PostgreSQL). The dialect defaults to SQL Server when none is given.
|
|
478
|
+
- `ParseWithTemplatePreprocessing` is the same as `Parse`. `UsedASTParsing` is true when every reading of the SQL parsed completely, and `Columns` is empty when it could not be read completely.
|
|
424
479
|
|
|
425
480
|
## Troubleshooting
|
|
426
481
|
|
|
427
482
|
### Entity subclass not being used
|
|
428
|
-
Ensure
|
|
483
|
+
Ensure the package is imported before any entity is instantiated. In a bundled server, check that it is in the class-registration manifest (`mj codegen manifest`), so the bundler does not drop the classes.
|
|
429
484
|
|
|
430
485
|
### Module loading errors
|
|
431
|
-
This package
|
|
486
|
+
This package is a native ES module (`"type": "module"`). Import it from ES module code (`import`), not with `require()`.
|
|
432
487
|
|
|
433
488
|
### Virtual properties not persisting
|
|
434
489
|
Virtual properties are not saved to the database. Use them as convenient accessors that manage real database fields behind the scenes.
|
|
@@ -13,6 +13,8 @@ export declare class MJAIAgentExampleEntityServer extends MJAIAgentExampleEntity
|
|
|
13
13
|
* Override EmbedTextLocal to use helper
|
|
14
14
|
*/
|
|
15
15
|
protected EmbedTextLocal(textToEmbed: string): Promise<SimpleEmbeddingResult>;
|
|
16
|
+
/** A stored vector from a model other than the default local one is re-embedded on save. */
|
|
17
|
+
protected IsEmbeddingStale(embeddingModelID: string | null): Promise<boolean>;
|
|
16
18
|
Save(options?: EntitySaveOptions): Promise<boolean>;
|
|
17
19
|
Delete(options?: EntityDeleteOptions): Promise<boolean>;
|
|
18
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJAIAgentExampleEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJAIAgentExampleEntityServer.server.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,mBAAmB,EAAE,iBAAiB,EAAY,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC3H,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAIvE;;;;;;;GAOG;AACH,qBACa,4BAA6B,SAAQ,sBAAsB;IACpE;;OAEG;cACsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAI7E,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"MJAIAgentExampleEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJAIAgentExampleEntityServer.server.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,mBAAmB,EAAE,iBAAiB,EAAY,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC3H,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAIvE;;;;;;;GAOG;AACH,qBACa,4BAA6B,SAAQ,sBAAsB;IACpE;;OAEG;cACsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAI5F,4FAA4F;cACnE,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;IAI7E,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAiCnD,MAAM,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;CAQzE"}
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { RegisterClass } from "@memberjunction/global";
|
|
8
8
|
import { BaseEntity, LogError } from "@memberjunction/core";
|
|
9
9
|
import { MJAIAgentExampleEntity } from "@memberjunction/core-entities";
|
|
10
|
-
import { EmbedTextLocalHelper } from "./util.js";
|
|
10
|
+
import { EmbedTextLocalHelper, IsLocalEmbeddingStaleHelper } from "./util.js";
|
|
11
11
|
import { AIEngine } from "@memberjunction/aiengine";
|
|
12
12
|
/**
|
|
13
13
|
* Server-side extension of MJAIAgentExampleEntity that:
|
|
@@ -24,12 +24,15 @@ let MJAIAgentExampleEntityServer = class MJAIAgentExampleEntityServer extends MJ
|
|
|
24
24
|
async EmbedTextLocal(textToEmbed) {
|
|
25
25
|
return EmbedTextLocalHelper(this, textToEmbed);
|
|
26
26
|
}
|
|
27
|
+
/** A stored vector from a model other than the default local one is re-embedded on save. */
|
|
28
|
+
async IsEmbeddingStale(embeddingModelID) {
|
|
29
|
+
return IsLocalEmbeddingStaleHelper(this, embeddingModelID);
|
|
30
|
+
}
|
|
27
31
|
async Save(options) {
|
|
28
32
|
try {
|
|
29
|
-
// 1. Generate/refresh the embedding
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
if (shouldGenerateEmbedding && this.ExampleInput && this.ExampleInput.trim().length > 0) {
|
|
33
|
+
// 1. Generate/refresh the embedding. GenerateEmbedding skips it unless the ExampleInput is
|
|
34
|
+
// new or dirty, or its stored vector is from another model (IsEmbeddingStale).
|
|
35
|
+
if (this.ExampleInput && this.ExampleInput.trim().length > 0) {
|
|
33
36
|
await this.GenerateEmbeddingByFieldName("ExampleInput", "EmbeddingVector", "EmbeddingModelID", "EmbeddingVectorBinary");
|
|
34
37
|
}
|
|
35
38
|
else if (!this.ExampleInput || this.ExampleInput.trim().length === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJAIAgentExampleEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJAIAgentExampleEntityServer.server.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,UAAU,EAA0C,QAAQ,EAAyB,MAAM,sBAAsB,CAAC;AAC3H,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"MJAIAgentExampleEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJAIAgentExampleEntityServer.server.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,UAAU,EAA0C,QAAQ,EAAyB,MAAM,sBAAsB,CAAC;AAC3H,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AACvE,OAAO,EAAE,oBAAoB,EAAE,2BAA2B,EAAE,MAAM,QAAQ,CAAC;AAC3E,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAEpD;;;;;;;GAOG;AAEI,IAAM,4BAA4B,GAAlC,MAAM,4BAA6B,SAAQ,sBAAsB;IACpE;;OAEG;IACgB,KAAK,CAAC,cAAc,CAAC,WAAmB;QACvD,OAAO,oBAAoB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACnD,CAAC;IAED,4FAA4F;IACzE,KAAK,CAAC,gBAAgB,CAAC,gBAA+B;QACrE,OAAO,2BAA2B,CAAC,IAAI,EAAE,gBAAgB,CAAC,CAAC;IAC/D,CAAC;IAEQ,KAAK,CAAC,IAAI,CAAC,OAA2B;QAC3C,IAAI,CAAC;YACD,2FAA2F;YAC3F,kFAAkF;YAClF,IAAI,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC3D,MAAM,IAAI,CAAC,4BAA4B,CAAC,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,uBAAuB,CAAC,CAAC;YAC5H,CAAC;iBAAM,IAAI,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACrE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;gBAC5B,IAAI,CAAC,qBAAqB,GAAG,IAAI,CAAC;gBAClC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;YACjC,CAAC;YAED,mFAAmF;YACnF,MAAM,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxC,IAAI,CAAC,KAAK;gBAAE,OAAO,KAAK,CAAC;YAEzB,uEAAuE;YACvE,wEAAwE;YACxE,wEAAwE;YACxE,MAAM,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,CAAC;YACvC,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,qBAAqB,IAAI,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC;gBACnF,QAAQ,CAAC,QAAQ,CAAC,iCAAiC,CAAC,IAAI,CAAC,CAAC;YAC9D,CAAC;iBAAM,CAAC;gBACJ,QAAQ,CAAC,QAAQ,CAAC,4BAA4B,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5D,CAAC;YACD,OAAO,IAAI,CAAC;QAChB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACT,QAAQ,CAAC,kCAAkC,EAAE,CAAC,CAAC,CAAC;YAChD,6DAA6D;YAC7D,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAEQ,KAAK,CAAC,MAAM,CAAC,OAA6B;QAC/C,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;QACnB,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAC5C,IAAI,OAAO,IAAI,EAAE,EAAE,CAAC;YAChB,QAAQ,CAAC,QAAQ,CAAC,4BAA4B,CAAC,EAAE,CAAC,CAAC;QACvD,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;CACJ,CAAA;AAtDY,4BAA4B;IADxC,aAAa,CAAC,UAAU,EAAE,uBAAuB,CAAC;GACtC,4BAA4B,CAsDxC"}
|
|
@@ -17,6 +17,8 @@ export declare class MJAIAgentNoteEntityServer extends MJAIAgentNoteEntity {
|
|
|
17
17
|
* Override EmbedTextLocal to use helper
|
|
18
18
|
*/
|
|
19
19
|
protected EmbedTextLocal(textToEmbed: string): Promise<SimpleEmbeddingResult>;
|
|
20
|
+
/** A stored vector from a model other than the default local one is re-embedded on save. */
|
|
21
|
+
protected IsEmbeddingStale(embeddingModelID: string | null): Promise<boolean>;
|
|
20
22
|
Save(options?: EntitySaveOptions): Promise<boolean>;
|
|
21
23
|
Delete(options?: EntityDeleteOptions): Promise<boolean>;
|
|
22
24
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJAIAgentNoteEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJAIAgentNoteEntityServer.server.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,mBAAmB,EAAE,iBAAiB,EAAY,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC3H,OAAO,EAAE,mBAAmB,EAA0B,MAAM,+BAA+B,CAAC;AAI5F;;;;;;;;;;;GAWG;AACH,qBACa,yBAA0B,SAAQ,mBAAmB;IAC9D;;OAEG;cACsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAI7E,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"MJAIAgentNoteEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJAIAgentNoteEntityServer.server.ts"],"names":[],"mappings":"AACA,OAAO,EAAc,mBAAmB,EAAE,iBAAiB,EAAY,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC3H,OAAO,EAAE,mBAAmB,EAA0B,MAAM,+BAA+B,CAAC;AAI5F;;;;;;;;;;;GAWG;AACH,qBACa,yBAA0B,SAAQ,mBAAmB;IAC9D;;OAEG;cACsB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAI5F,4FAA4F;cACnE,gBAAgB,CAAC,gBAAgB,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC;IAI7E,IAAI,CAAC,OAAO,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,OAAO,CAAC;IAwCnD,MAAM,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,OAAO,CAAC;CAQzE"}
|
|
@@ -7,7 +7,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
import { RegisterClass } from "@memberjunction/global";
|
|
8
8
|
import { BaseEntity, LogError } from "@memberjunction/core";
|
|
9
9
|
import { MJAIAgentNoteEntity, IsInjectableNoteStatus } from "@memberjunction/core-entities";
|
|
10
|
-
import { EmbedTextLocalHelper } from "./util.js";
|
|
10
|
+
import { EmbedTextLocalHelper, IsLocalEmbeddingStaleHelper } from "./util.js";
|
|
11
11
|
import { AIEngine } from "@memberjunction/aiengine";
|
|
12
12
|
/**
|
|
13
13
|
* Server-side extension of MJAIAgentNoteEntity that:
|
|
@@ -28,12 +28,15 @@ let MJAIAgentNoteEntityServer = class MJAIAgentNoteEntityServer extends MJAIAgen
|
|
|
28
28
|
async EmbedTextLocal(textToEmbed) {
|
|
29
29
|
return EmbedTextLocalHelper(this, textToEmbed);
|
|
30
30
|
}
|
|
31
|
+
/** A stored vector from a model other than the default local one is re-embedded on save. */
|
|
32
|
+
async IsEmbeddingStale(embeddingModelID) {
|
|
33
|
+
return IsLocalEmbeddingStaleHelper(this, embeddingModelID);
|
|
34
|
+
}
|
|
31
35
|
async Save(options) {
|
|
32
36
|
try {
|
|
33
|
-
// 1. Generate/refresh the embedding
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
if (shouldGenerateEmbedding && this.Note && this.Note.trim().length > 0) {
|
|
37
|
+
// 1. Generate/refresh the embedding. GenerateEmbedding skips it unless the Note is new or
|
|
38
|
+
// dirty, or its stored vector is from another model (IsEmbeddingStale).
|
|
39
|
+
if (this.Note && this.Note.trim().length > 0) {
|
|
37
40
|
await this.GenerateEmbeddingByFieldName("Note", "EmbeddingVector", "EmbeddingModelID", "EmbeddingVectorBinary");
|
|
38
41
|
}
|
|
39
42
|
else if (!this.Note || this.Note.trim().length === 0) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MJAIAgentNoteEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJAIAgentNoteEntityServer.server.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,UAAU,EAA0C,QAAQ,EAAyB,MAAM,sBAAsB,CAAC;AAC3H,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC;AAC5F,OAAO,EAAE,oBAAoB,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"MJAIAgentNoteEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJAIAgentNoteEntityServer.server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { ValidationErrorInfo, ValidationResult } from '@memberjunction/core';
|
|
2
|
+
import { MJAIAgentRelationshipEntity } from '@memberjunction/core-entities';
|
|
3
|
+
/**
|
|
4
|
+
* Server-side `MJ: AI Agent Relationships` entity enforcing that when `ConfigurationPresetID` is set,
|
|
5
|
+
* the referenced `MJ: AI Agent Configurations` preset exists and belongs to the relationship's `SubAgentID`.
|
|
6
|
+
*/
|
|
7
|
+
export declare class MJAIAgentRelationshipEntityServer extends MJAIAgentRelationshipEntity {
|
|
8
|
+
get DefaultSkipAsyncValidation(): boolean;
|
|
9
|
+
ValidateAsync(): Promise<ValidationResult>;
|
|
10
|
+
private validateConfigurationPreset;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* PURE invariant core for `ConfigurationPresetID` on `MJ: AI Agent Relationships`:
|
|
14
|
+
* when set, the referenced preset must exist and its `AgentID` must match `SubAgentID`.
|
|
15
|
+
*/
|
|
16
|
+
export declare function BuildConfigurationPresetOwnershipError(configurationPresetID: string | null, subAgentID: string | null, presetAgentID: string | null, presetName?: string): ValidationErrorInfo | null;
|
|
17
|
+
//# sourceMappingURL=MJAIAgentRelationshipEntityServer.server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MJAIAgentRelationshipEntityServer.server.d.ts","sourceRoot":"","sources":["../../src/custom/MJAIAgentRelationshipEntityServer.server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiC,mBAAmB,EAAuB,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAEjI,OAAO,EAAgC,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AAE1G;;;GAGG;AACH,qBACa,iCAAkC,SAAQ,2BAA2B;IAC9E,IAAoB,0BAA0B,IAAI,OAAO,CAExD;IAEqB,aAAa,IAAI,OAAO,CAAC,gBAAgB,CAAC;YAuBlD,2BAA2B;CAoB5C;AAED;;;GAGG;AACH,wBAAgB,sCAAsC,CAClD,qBAAqB,EAAE,MAAM,GAAG,IAAI,EACpC,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,aAAa,EAAE,MAAM,GAAG,IAAI,EAC5B,UAAU,CAAC,EAAE,MAAM,GACpB,mBAAmB,GAAG,IAAI,CAsB5B"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
import { BaseEntity, ValidationErrorInfo, ValidationErrorType } from '@memberjunction/core';
|
|
8
|
+
import { RegisterClass, UUIDsEqual } from '@memberjunction/global';
|
|
9
|
+
import { MJAIAgentRelationshipEntity } from '@memberjunction/core-entities';
|
|
10
|
+
/**
|
|
11
|
+
* Server-side `MJ: AI Agent Relationships` entity enforcing that when `ConfigurationPresetID` is set,
|
|
12
|
+
* the referenced `MJ: AI Agent Configurations` preset exists and belongs to the relationship's `SubAgentID`.
|
|
13
|
+
*/
|
|
14
|
+
let MJAIAgentRelationshipEntityServer = class MJAIAgentRelationshipEntityServer extends MJAIAgentRelationshipEntity {
|
|
15
|
+
get DefaultSkipAsyncValidation() {
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
async ValidateAsync() {
|
|
19
|
+
const result = await super.ValidateAsync();
|
|
20
|
+
if (!result.Success) {
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
if (!this.ConfigurationPresetID) {
|
|
24
|
+
return result;
|
|
25
|
+
}
|
|
26
|
+
const presetDirty = this.GetFieldByName('ConfigurationPresetID')?.Dirty ?? false;
|
|
27
|
+
const subAgentDirty = this.GetFieldByName('SubAgentID')?.Dirty ?? false;
|
|
28
|
+
if (!this.IsSaved || presetDirty || subAgentDirty) {
|
|
29
|
+
const presetError = await this.validateConfigurationPreset();
|
|
30
|
+
if (presetError) {
|
|
31
|
+
result.Errors.push(presetError);
|
|
32
|
+
result.Success = false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
return result;
|
|
36
|
+
}
|
|
37
|
+
async validateConfigurationPreset() {
|
|
38
|
+
if (!this.ConfigurationPresetID) {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const md = this.ProviderToUse;
|
|
42
|
+
const preset = await md.GetEntityObject('MJ: AI Agent Configurations', this.ContextCurrentUser);
|
|
43
|
+
const loaded = await preset.Load(this.ConfigurationPresetID);
|
|
44
|
+
if (!loaded) {
|
|
45
|
+
return BuildConfigurationPresetOwnershipError(this.ConfigurationPresetID, this.SubAgentID, null);
|
|
46
|
+
}
|
|
47
|
+
return BuildConfigurationPresetOwnershipError(this.ConfigurationPresetID, this.SubAgentID, preset.AgentID ?? null, preset.Name ?? undefined);
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
MJAIAgentRelationshipEntityServer = __decorate([
|
|
51
|
+
RegisterClass(BaseEntity, 'MJ: AI Agent Relationships')
|
|
52
|
+
], MJAIAgentRelationshipEntityServer);
|
|
53
|
+
export { MJAIAgentRelationshipEntityServer };
|
|
54
|
+
/**
|
|
55
|
+
* PURE invariant core for `ConfigurationPresetID` on `MJ: AI Agent Relationships`:
|
|
56
|
+
* when set, the referenced preset must exist and its `AgentID` must match `SubAgentID`.
|
|
57
|
+
*/
|
|
58
|
+
export function BuildConfigurationPresetOwnershipError(configurationPresetID, subAgentID, presetAgentID, presetName) {
|
|
59
|
+
if (!configurationPresetID) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
if (presetAgentID === null) {
|
|
63
|
+
return new ValidationErrorInfo('ConfigurationPresetID', `ConfigurationPresetID references preset '${configurationPresetID}' but no such AI Agent Configuration exists.`, configurationPresetID, ValidationErrorType.Failure);
|
|
64
|
+
}
|
|
65
|
+
if (!subAgentID || !UUIDsEqual(presetAgentID, subAgentID)) {
|
|
66
|
+
const label = presetName ? `'${presetName}' (${configurationPresetID})` : `'${configurationPresetID}'`;
|
|
67
|
+
return new ValidationErrorInfo('ConfigurationPresetID', `Configuration preset ${label} belongs to agent '${presetAgentID}', not sub-agent '${subAgentID}'.`, configurationPresetID, ValidationErrorType.Failure);
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=MJAIAgentRelationshipEntityServer.server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MJAIAgentRelationshipEntityServer.server.js","sourceRoot":"","sources":["../../src/custom/MJAIAgentRelationshipEntityServer.server.ts"],"names":[],"mappings":"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"}
|