@ekairos/dataset 1.22.39-beta.development.0 → 1.22.39
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 +347 -0
- package/dist/agents.d.ts +8 -0
- package/dist/agents.js +8 -0
- package/dist/builder/agentMaterializers.d.ts +9 -0
- package/dist/builder/agentMaterializers.js +10 -0
- package/dist/builder/context.d.ts +15 -0
- package/dist/builder/context.js +251 -0
- package/dist/builder/instructions.d.ts +5 -0
- package/dist/builder/instructions.js +40 -0
- package/dist/builder/materialize.d.ts +83 -0
- package/dist/builder/materialize.js +548 -0
- package/dist/builder/materializeQuery.d.ts +12 -0
- package/dist/builder/materializeQuery.js +31 -0
- package/dist/builder/persistence.d.ts +22 -0
- package/dist/builder/persistence.js +192 -0
- package/dist/builder/rows.d.ts +7 -0
- package/dist/builder/rows.js +56 -0
- package/dist/builder/schemaInference.d.ts +3 -0
- package/dist/builder/schemaInference.js +61 -0
- package/dist/builder/types.d.ts +144 -0
- package/dist/builder/types.js +1 -0
- package/dist/clearDataset.tool.d.ts +2 -3
- package/dist/clearDataset.tool.js +13 -17
- package/dist/completeDataset.steps.d.ts +117 -0
- package/dist/completeDataset.steps.js +537 -0
- package/dist/completeDataset.tool.d.ts +132 -7
- package/dist/completeDataset.tool.js +46 -192
- package/dist/contextResources.d.ts +31 -0
- package/dist/contextResources.js +151 -0
- package/dist/contextWorkspace.d.ts +79 -0
- package/dist/contextWorkspace.js +234 -0
- package/dist/dataset/steps.d.ts +39 -15
- package/dist/dataset/steps.js +96 -39
- package/dist/dataset.d.ts +3 -67
- package/dist/dataset.js +129 -521
- package/dist/datasetFiles.d.ts +5 -1
- package/dist/datasetFiles.js +29 -27
- package/dist/defineNotation.tool.d.ts +49 -0
- package/dist/defineNotation.tool.js +154 -0
- package/dist/domain.d.ts +1 -2
- package/dist/domain.js +1 -6
- package/dist/executeCommand.tool.d.ts +2 -30
- package/dist/executeCommand.tool.js +165 -39
- package/dist/file/file-dataset.agent.d.ts +19 -56
- package/dist/file/file-dataset.agent.js +181 -134
- package/dist/file/file-dataset.steps.d.ts +27 -0
- package/dist/file/file-dataset.steps.js +47 -0
- package/dist/file/file-dataset.types.d.ts +64 -0
- package/dist/file/file-dataset.types.js +1 -0
- package/dist/file/filepreview.d.ts +5 -35
- package/dist/file/filepreview.js +60 -107
- package/dist/file/filepreview.types.d.ts +31 -0
- package/dist/file/filepreview.types.js +1 -0
- package/dist/file/generateSchema.tool.d.ts +2 -3
- package/dist/file/generateSchema.tool.js +11 -15
- package/dist/file/index.d.ts +1 -2
- package/dist/file/index.js +1 -18
- package/dist/file/prompts.d.ts +2 -3
- package/dist/file/prompts.js +152 -32
- package/dist/file/scripts.generated.d.ts +1 -0
- package/dist/file/scripts.generated.js +11 -0
- package/dist/file/steps.d.ts +1 -2
- package/dist/file/steps.js +9 -7
- package/dist/id.d.ts +1 -0
- package/dist/id.js +10 -0
- package/dist/index.d.ts +9 -7
- package/dist/index.js +9 -23
- package/dist/materializeDataset.tool.d.ts +51 -31
- package/dist/materializeDataset.tool.js +81 -65
- package/dist/notation.d.ts +205 -0
- package/dist/notation.js +424 -0
- package/dist/query/index.d.ts +1 -2
- package/dist/query/index.js +1 -18
- package/dist/query/queryDomain.d.ts +3 -4
- package/dist/query/queryDomain.js +3 -40
- package/dist/query/queryDomain.step.d.ts +1 -1
- package/dist/query/queryDomain.step.js +24 -13
- package/dist/sandbox/steps.d.ts +23 -15
- package/dist/sandbox/steps.js +73 -76
- package/dist/sandbox.steps.d.ts +1 -2
- package/dist/sandbox.steps.js +1 -18
- package/dist/schema.d.ts +15 -13
- package/dist/schema.js +27 -37
- package/dist/service.d.ts +12 -5
- package/dist/service.js +88 -15
- package/dist/skill.d.ts +0 -1
- package/dist/skill.js +12 -17
- package/dist/transform/filepreview.d.ts +2 -3
- package/dist/transform/filepreview.js +9 -26
- package/dist/transform/index.d.ts +2 -3
- package/dist/transform/index.js +2 -8
- package/dist/transform/prompts.d.ts +1 -34
- package/dist/transform/prompts.js +66 -46
- package/dist/transform/transform-dataset.agent.d.ts +20 -45
- package/dist/transform/transform-dataset.agent.js +151 -91
- package/dist/transform/transform-dataset.steps.d.ts +30 -0
- package/dist/transform/transform-dataset.steps.js +61 -0
- package/dist/transform/transform-dataset.types.d.ts +95 -0
- package/dist/transform/transform-dataset.types.js +1 -0
- package/dist/transform/transformDataset.d.ts +3 -3
- package/dist/transform/transformDataset.js +15 -18
- package/dist/writeDatasetRows.tool.d.ts +188 -0
- package/dist/writeDatasetRows.tool.js +258 -0
- package/package.json +33 -8
- package/dist/clearDataset.tool.d.ts.map +0 -1
- package/dist/clearDataset.tool.js.map +0 -1
- package/dist/completeDataset.tool.d.ts.map +0 -1
- package/dist/completeDataset.tool.js.map +0 -1
- package/dist/dataset/steps.d.ts.map +0 -1
- package/dist/dataset/steps.js.map +0 -1
- package/dist/dataset.d.ts.map +0 -1
- package/dist/dataset.js.map +0 -1
- package/dist/datasetFiles.d.ts.map +0 -1
- package/dist/datasetFiles.js.map +0 -1
- package/dist/domain.d.ts.map +0 -1
- package/dist/domain.js.map +0 -1
- package/dist/eventsReactRuntime.d.ts +0 -22
- package/dist/eventsReactRuntime.d.ts.map +0 -1
- package/dist/eventsReactRuntime.js +0 -29
- package/dist/eventsReactRuntime.js.map +0 -1
- package/dist/executeCommand.tool.d.ts.map +0 -1
- package/dist/executeCommand.tool.js.map +0 -1
- package/dist/file/file-dataset.agent.d.ts.map +0 -1
- package/dist/file/file-dataset.agent.js.map +0 -1
- package/dist/file/filepreview.d.ts.map +0 -1
- package/dist/file/filepreview.js.map +0 -1
- package/dist/file/generateSchema.tool.d.ts.map +0 -1
- package/dist/file/generateSchema.tool.js.map +0 -1
- package/dist/file/index.d.ts.map +0 -1
- package/dist/file/index.js.map +0 -1
- package/dist/file/prompts.d.ts.map +0 -1
- package/dist/file/prompts.js.map +0 -1
- package/dist/file/steps.d.ts.map +0 -1
- package/dist/file/steps.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/materializeDataset.tool.d.ts.map +0 -1
- package/dist/materializeDataset.tool.js.map +0 -1
- package/dist/query/index.d.ts.map +0 -1
- package/dist/query/index.js.map +0 -1
- package/dist/query/queryDomain.d.ts.map +0 -1
- package/dist/query/queryDomain.js.map +0 -1
- package/dist/query/queryDomain.step.d.ts.map +0 -1
- package/dist/query/queryDomain.step.js.map +0 -1
- package/dist/sandbox/steps.d.ts.map +0 -1
- package/dist/sandbox/steps.js.map +0 -1
- package/dist/sandbox.steps.d.ts.map +0 -1
- package/dist/sandbox.steps.js.map +0 -1
- package/dist/schema.d.ts.map +0 -1
- package/dist/schema.js.map +0 -1
- package/dist/service.d.ts.map +0 -1
- package/dist/service.js.map +0 -1
- package/dist/skill.d.ts.map +0 -1
- package/dist/skill.js.map +0 -1
- package/dist/transform/filepreview.d.ts.map +0 -1
- package/dist/transform/filepreview.js.map +0 -1
- package/dist/transform/index.d.ts.map +0 -1
- package/dist/transform/index.js.map +0 -1
- package/dist/transform/prompts.d.ts.map +0 -1
- package/dist/transform/prompts.js.map +0 -1
- package/dist/transform/transform-dataset.agent.d.ts.map +0 -1
- package/dist/transform/transform-dataset.agent.js.map +0 -1
- package/dist/transform/transformDataset.d.ts.map +0 -1
- package/dist/transform/transformDataset.js.map +0 -1
package/dist/notation.js
ADDED
|
@@ -0,0 +1,424 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Formal notation for datasets — the dataset stated intensionally.
|
|
3
|
+
*
|
|
4
|
+
* A dataset has TWO CO-EQUAL FACES at the same level:
|
|
5
|
+
* - its formal DEFINITION (this notation: the proposition that defines the
|
|
6
|
+
* set, in LaTeX), and
|
|
7
|
+
* - its MATERIALIZATION (the rows + the code that produces them).
|
|
8
|
+
* The notation is not a comment about the data; it IS the dataset, written
|
|
9
|
+
* as a logical statement. The materialization is the same set written
|
|
10
|
+
* extensionally. Neither is subordinate to the other.
|
|
11
|
+
*
|
|
12
|
+
* The SAME notation plays two roles across the lifecycle: it is the PLAN
|
|
13
|
+
* (status "plan": stated first, the materialization is built to realize it)
|
|
14
|
+
* and, once finalized, the RESULT (status "result": it describes exactly
|
|
15
|
+
* what was produced). It is iterated in between — every revision keeps the
|
|
16
|
+
* prior version in `history`, so the discovery trail stays visible.
|
|
17
|
+
*
|
|
18
|
+
* The definition is a logical proposition, possibly DERIVED (a syllogism),
|
|
19
|
+
* so it is NOT, in general, mechanically verifiable: a predicate may be
|
|
20
|
+
* semantic ("x es una frase divertida") and the set is still well-formed.
|
|
21
|
+
* We TRUST the formality and the produced dataset — there is no verdict.
|
|
22
|
+
*
|
|
23
|
+
* SOME predicates happen to be arithmetic (a row count, a field type, a
|
|
24
|
+
* preserved total). For those, and only those, we attach OPTIONAL evidence
|
|
25
|
+
* computed over the rows. It is advisory: a contradiction is a hint, never
|
|
26
|
+
* a claim that the dataset is invalid. Predicates with no arithmetic form
|
|
27
|
+
* are "asserted" — trusted. Nothing here blocks or changes a build; the
|
|
28
|
+
* notation rides on dataset_datasets.notation.
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Iterate the notation: every revision bumps the version and appends to
|
|
32
|
+
* history, so the discovery trail (sets/variables found along the way)
|
|
33
|
+
* stays visible.
|
|
34
|
+
*/
|
|
35
|
+
export function reviseDatasetNotation(previous, input) {
|
|
36
|
+
const version = (previous?.version ?? 0) + 1;
|
|
37
|
+
const revision = {
|
|
38
|
+
version,
|
|
39
|
+
latex: input.latex,
|
|
40
|
+
reason: input.reason,
|
|
41
|
+
at: Date.now(),
|
|
42
|
+
};
|
|
43
|
+
return {
|
|
44
|
+
version,
|
|
45
|
+
status: input.final ? "result" : "plan",
|
|
46
|
+
latex: input.latex,
|
|
47
|
+
symbols: input.symbols ?? previous?.symbols ?? [],
|
|
48
|
+
predicates: input.predicates ?? previous?.predicates ?? [],
|
|
49
|
+
history: [...(previous?.history ?? []), revision],
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/* ── LaTeX helpers ──────────────────────────────────────────────── */
|
|
53
|
+
/** escape an identifier for use inside \text{} */
|
|
54
|
+
export function latexIdentifier(name) {
|
|
55
|
+
return `\\text{${String(name).replace(/([#$%&_{}])/g, "\\$1")}}`;
|
|
56
|
+
}
|
|
57
|
+
function latexFieldType(type) {
|
|
58
|
+
if (type === "number")
|
|
59
|
+
return "\\mathbb{R}";
|
|
60
|
+
if (type === "integer")
|
|
61
|
+
return "\\mathbb{Z}";
|
|
62
|
+
if (type === "boolean")
|
|
63
|
+
return "\\{\\top,\\bot\\}";
|
|
64
|
+
return "\\Sigma^{*}";
|
|
65
|
+
}
|
|
66
|
+
const JSON_SCHEMA_KEYWORDS = new Set([
|
|
67
|
+
"type",
|
|
68
|
+
"title",
|
|
69
|
+
"description",
|
|
70
|
+
"required",
|
|
71
|
+
"items",
|
|
72
|
+
"additionalProperties",
|
|
73
|
+
]);
|
|
74
|
+
function schemaProperties(schema) {
|
|
75
|
+
const root = (schema?.schema ?? schema ?? {});
|
|
76
|
+
if (root.properties && typeof root.properties === "object") {
|
|
77
|
+
return root.properties;
|
|
78
|
+
}
|
|
79
|
+
// flat shape from query inference: { fieldName: "type", ... }
|
|
80
|
+
const flat = {};
|
|
81
|
+
for (const [key, value] of Object.entries(root)) {
|
|
82
|
+
if (JSON_SCHEMA_KEYWORDS.has(key))
|
|
83
|
+
continue;
|
|
84
|
+
if (typeof value === "string")
|
|
85
|
+
flat[key] = value;
|
|
86
|
+
else if (value && typeof value === "object" && typeof value.type === "string") {
|
|
87
|
+
flat[key] = value;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return flat;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* A query-backed dataset has a complete deterministic description: the
|
|
94
|
+
* dataset is the image of a known query over a known domain. No model is
|
|
95
|
+
* involved, so here the formal definition and its predicates derive
|
|
96
|
+
* mechanically from the query, the inferred schema and the row count — and
|
|
97
|
+
* those predicates DO carry arithmetic evidence (the special case where the
|
|
98
|
+
* formal claims happen to be fully mechanical).
|
|
99
|
+
*/
|
|
100
|
+
export function inferQueryNotation(params) {
|
|
101
|
+
const sources = params.entityNames.length ? params.entityNames : ["Domain"];
|
|
102
|
+
const sourceSymbols = sources.map((name) => ({
|
|
103
|
+
name,
|
|
104
|
+
latex: latexIdentifier(name),
|
|
105
|
+
kind: "set",
|
|
106
|
+
description: `Entidad de origen ${name}`,
|
|
107
|
+
}));
|
|
108
|
+
const union = sources.map((name) => latexIdentifier(name)).join(" \\cup ");
|
|
109
|
+
const latex = `\\mathcal{D} = \\left\\{\\, r \\;\\middle|\\; r \\in Q\\!\\left(${union}\\right) \\right\\}`;
|
|
110
|
+
const properties = schemaProperties(params.schema);
|
|
111
|
+
const predicates = [
|
|
112
|
+
{
|
|
113
|
+
id: "cardinality",
|
|
114
|
+
description: `El dataset tiene exactamente ${params.rowCount} filas`,
|
|
115
|
+
latex: `|\\mathcal{D}| = ${params.rowCount}`,
|
|
116
|
+
check: { kind: "row_count", op: "=", value: params.rowCount },
|
|
117
|
+
},
|
|
118
|
+
];
|
|
119
|
+
for (const [field, raw] of Object.entries(properties)) {
|
|
120
|
+
const type = typeof raw === "string" ? raw : String(raw?.type ?? "");
|
|
121
|
+
if (!["number", "integer", "boolean", "string"].includes(type))
|
|
122
|
+
continue;
|
|
123
|
+
predicates.push({
|
|
124
|
+
id: `type_${field}`,
|
|
125
|
+
description: `Toda fila tiene ${field} de tipo ${type} (o nulo)`,
|
|
126
|
+
latex: `\\forall r \\in \\mathcal{D}:\\; r.${latexIdentifier(field)} \\in ${latexFieldType(type)} \\cup \\{\\varnothing\\}`,
|
|
127
|
+
check: {
|
|
128
|
+
kind: "field_type",
|
|
129
|
+
field,
|
|
130
|
+
type: type,
|
|
131
|
+
allowNull: true,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return reviseDatasetNotation(null, {
|
|
136
|
+
latex,
|
|
137
|
+
symbols: [
|
|
138
|
+
{
|
|
139
|
+
name: "D",
|
|
140
|
+
latex: "\\mathcal{D}",
|
|
141
|
+
kind: "set",
|
|
142
|
+
description: params.explanation?.trim() || "Dataset materializado",
|
|
143
|
+
},
|
|
144
|
+
{
|
|
145
|
+
name: "Q",
|
|
146
|
+
kind: "function",
|
|
147
|
+
description: "Consulta InstaQL aplicada al dominio",
|
|
148
|
+
},
|
|
149
|
+
...sourceSymbols,
|
|
150
|
+
],
|
|
151
|
+
predicates,
|
|
152
|
+
reason: "Notación determinística derivada de la consulta al dominio",
|
|
153
|
+
final: true,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
/* ── arithmetic evaluation ──────────────────────────────────────── */
|
|
157
|
+
function readPath(row, path) {
|
|
158
|
+
let current = row;
|
|
159
|
+
for (const segment of String(path).split(".")) {
|
|
160
|
+
if (current === null || current === undefined)
|
|
161
|
+
return undefined;
|
|
162
|
+
current = current[segment];
|
|
163
|
+
}
|
|
164
|
+
return current;
|
|
165
|
+
}
|
|
166
|
+
function compare(op, left, right, tolerance = 0) {
|
|
167
|
+
switch (op) {
|
|
168
|
+
case "=":
|
|
169
|
+
return Math.abs(left - right) <= tolerance;
|
|
170
|
+
case "!=":
|
|
171
|
+
return Math.abs(left - right) > tolerance;
|
|
172
|
+
case "<":
|
|
173
|
+
return left < right;
|
|
174
|
+
case "<=":
|
|
175
|
+
return left <= right + tolerance;
|
|
176
|
+
case ">":
|
|
177
|
+
return left > right;
|
|
178
|
+
case ">=":
|
|
179
|
+
return left >= right - tolerance;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
export function evaluateNotationCheck(rows, check) {
|
|
183
|
+
switch (check.kind) {
|
|
184
|
+
case "row_count": {
|
|
185
|
+
const ok = compare(check.op, rows.length, check.value);
|
|
186
|
+
return { ok, detail: `|D| = ${rows.length} ${check.op} ${check.value}` };
|
|
187
|
+
}
|
|
188
|
+
case "field_type": {
|
|
189
|
+
let failures = 0;
|
|
190
|
+
let firstFailure = "";
|
|
191
|
+
for (const row of rows) {
|
|
192
|
+
const value = readPath(row, check.field);
|
|
193
|
+
if (value === null || value === undefined) {
|
|
194
|
+
if (check.allowNull)
|
|
195
|
+
continue;
|
|
196
|
+
failures += 1;
|
|
197
|
+
if (!firstFailure)
|
|
198
|
+
firstFailure = "null";
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
const okValue = check.type === "number"
|
|
202
|
+
? typeof value === "number" && Number.isFinite(value)
|
|
203
|
+
: check.type === "integer"
|
|
204
|
+
? typeof value === "number" && Number.isInteger(value)
|
|
205
|
+
: check.type === "boolean"
|
|
206
|
+
? typeof value === "boolean"
|
|
207
|
+
: typeof value === "string";
|
|
208
|
+
if (!okValue) {
|
|
209
|
+
failures += 1;
|
|
210
|
+
if (!firstFailure)
|
|
211
|
+
firstFailure = JSON.stringify(value)?.slice(0, 40) ?? "?";
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
ok: failures === 0,
|
|
216
|
+
detail: failures === 0
|
|
217
|
+
? `∀r: ${check.field} : ${check.type}`
|
|
218
|
+
: `${failures}/${rows.length} filas violan ${check.field} : ${check.type} (ej: ${firstFailure})`,
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
case "field_range": {
|
|
222
|
+
let failures = 0;
|
|
223
|
+
for (const row of rows) {
|
|
224
|
+
const value = readPath(row, check.field);
|
|
225
|
+
if (typeof value !== "number" || Number.isNaN(value))
|
|
226
|
+
continue;
|
|
227
|
+
if (check.min !== undefined && value < check.min)
|
|
228
|
+
failures += 1;
|
|
229
|
+
else if (check.max !== undefined && value > check.max)
|
|
230
|
+
failures += 1;
|
|
231
|
+
}
|
|
232
|
+
const bounds = [
|
|
233
|
+
check.min !== undefined ? `≥ ${check.min}` : "",
|
|
234
|
+
check.max !== undefined ? `≤ ${check.max}` : "",
|
|
235
|
+
]
|
|
236
|
+
.filter(Boolean)
|
|
237
|
+
.join(" ∧ ");
|
|
238
|
+
return {
|
|
239
|
+
ok: failures === 0,
|
|
240
|
+
detail: failures === 0
|
|
241
|
+
? `∀r: ${check.field} ${bounds}`
|
|
242
|
+
: `${failures}/${rows.length} filas fuera de rango en ${check.field}`,
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
case "field_in": {
|
|
246
|
+
const allowed = new Set(check.values.map((value) => JSON.stringify(value)));
|
|
247
|
+
let failures = 0;
|
|
248
|
+
for (const row of rows) {
|
|
249
|
+
const value = readPath(row, check.field);
|
|
250
|
+
if (value === null || value === undefined)
|
|
251
|
+
continue;
|
|
252
|
+
if (!allowed.has(JSON.stringify(value)))
|
|
253
|
+
failures += 1;
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
ok: failures === 0,
|
|
257
|
+
detail: failures === 0
|
|
258
|
+
? `∀r: ${check.field} ∈ {${check.values.join(", ")}}`
|
|
259
|
+
: `${failures}/${rows.length} filas con ${check.field} fuera del conjunto`,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
case "field_nonnull": {
|
|
263
|
+
let failures = 0;
|
|
264
|
+
for (const row of rows) {
|
|
265
|
+
const value = readPath(row, check.field);
|
|
266
|
+
if (value === null || value === undefined || value === "")
|
|
267
|
+
failures += 1;
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
ok: failures === 0,
|
|
271
|
+
detail: failures === 0
|
|
272
|
+
? `∀r: ${check.field} ≠ ∅`
|
|
273
|
+
: `${failures}/${rows.length} filas con ${check.field} vacío`,
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
case "field_matches": {
|
|
277
|
+
let regex;
|
|
278
|
+
try {
|
|
279
|
+
regex = new RegExp(check.pattern);
|
|
280
|
+
}
|
|
281
|
+
catch {
|
|
282
|
+
return { ok: false, detail: `patrón inválido: ${check.pattern}` };
|
|
283
|
+
}
|
|
284
|
+
let failures = 0;
|
|
285
|
+
for (const row of rows) {
|
|
286
|
+
const value = readPath(row, check.field);
|
|
287
|
+
if (typeof value !== "string")
|
|
288
|
+
continue;
|
|
289
|
+
if (!regex.test(value))
|
|
290
|
+
failures += 1;
|
|
291
|
+
}
|
|
292
|
+
return {
|
|
293
|
+
ok: failures === 0,
|
|
294
|
+
detail: failures === 0
|
|
295
|
+
? `∀r: ${check.field} ~ /${check.pattern}/`
|
|
296
|
+
: `${failures}/${rows.length} filas no matchean /${check.pattern}/`,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
case "unique": {
|
|
300
|
+
const seen = new Set();
|
|
301
|
+
let duplicates = 0;
|
|
302
|
+
for (const row of rows) {
|
|
303
|
+
const key = JSON.stringify(check.fields.map((field) => readPath(row, field)));
|
|
304
|
+
if (seen.has(key))
|
|
305
|
+
duplicates += 1;
|
|
306
|
+
else
|
|
307
|
+
seen.add(key);
|
|
308
|
+
}
|
|
309
|
+
return {
|
|
310
|
+
ok: duplicates === 0,
|
|
311
|
+
detail: duplicates === 0
|
|
312
|
+
? `(${check.fields.join(", ")}) es clave`
|
|
313
|
+
: `${duplicates} duplicados sobre (${check.fields.join(", ")})`,
|
|
314
|
+
};
|
|
315
|
+
}
|
|
316
|
+
case "aggregate": {
|
|
317
|
+
const values = [];
|
|
318
|
+
for (const row of rows) {
|
|
319
|
+
if (check.fn === "count" && !check.field)
|
|
320
|
+
continue;
|
|
321
|
+
const value = readPath(row, String(check.field));
|
|
322
|
+
if (typeof value === "number" && Number.isFinite(value))
|
|
323
|
+
values.push(value);
|
|
324
|
+
}
|
|
325
|
+
let actual;
|
|
326
|
+
switch (check.fn) {
|
|
327
|
+
case "count":
|
|
328
|
+
actual = check.field ? values.length : rows.length;
|
|
329
|
+
break;
|
|
330
|
+
case "sum":
|
|
331
|
+
actual = values.reduce((total, value) => total + value, 0);
|
|
332
|
+
break;
|
|
333
|
+
case "min":
|
|
334
|
+
actual = values.length ? Math.min(...values) : Number.NaN;
|
|
335
|
+
break;
|
|
336
|
+
case "max":
|
|
337
|
+
actual = values.length ? Math.max(...values) : Number.NaN;
|
|
338
|
+
break;
|
|
339
|
+
case "avg":
|
|
340
|
+
actual = values.length
|
|
341
|
+
? values.reduce((total, value) => total + value, 0) / values.length
|
|
342
|
+
: Number.NaN;
|
|
343
|
+
break;
|
|
344
|
+
}
|
|
345
|
+
const tolerance = check.tolerance ?? 1e-9;
|
|
346
|
+
const ok = Number.isFinite(actual) && compare(check.op, actual, check.value, tolerance);
|
|
347
|
+
return {
|
|
348
|
+
ok,
|
|
349
|
+
detail: `${check.fn}(${check.field ?? "*"}) = ${Number.isFinite(actual) ? actual : "∅"} ${check.op} ${check.value}`,
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
case "and": {
|
|
353
|
+
const results = check.checks.map((inner) => evaluateNotationCheck(rows, inner));
|
|
354
|
+
return {
|
|
355
|
+
ok: results.every((result) => result.ok),
|
|
356
|
+
detail: results.map((result) => result.detail).join(" ∧ "),
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
case "or": {
|
|
360
|
+
const results = check.checks.map((inner) => evaluateNotationCheck(rows, inner));
|
|
361
|
+
return {
|
|
362
|
+
ok: results.some((result) => result.ok),
|
|
363
|
+
detail: results.map((result) => result.detail).join(" ∨ "),
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
case "not": {
|
|
367
|
+
const result = evaluateNotationCheck(rows, check.check);
|
|
368
|
+
return { ok: !result.ok, detail: `¬(${result.detail})` };
|
|
369
|
+
}
|
|
370
|
+
case "implies": {
|
|
371
|
+
const antecedent = evaluateNotationCheck(rows, check.if);
|
|
372
|
+
if (!antecedent.ok) {
|
|
373
|
+
return { ok: true, detail: `(${antecedent.detail}) → ⊤ (antecedente falso)` };
|
|
374
|
+
}
|
|
375
|
+
const consequent = evaluateNotationCheck(rows, check.then);
|
|
376
|
+
return {
|
|
377
|
+
ok: consequent.ok,
|
|
378
|
+
detail: `(${antecedent.detail}) → (${consequent.detail})`,
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Annotate a notation with ADVISORY arithmetic evidence over the produced
|
|
385
|
+
* rows. Never throws, never blocks, and never changes the notation's
|
|
386
|
+
* lifecycle status — the dataset's validity is trusted, not proven here.
|
|
387
|
+
*
|
|
388
|
+
* Each predicate is reported as:
|
|
389
|
+
* - "asserted" no arithmetic form (formal/semantic claim, trusted)
|
|
390
|
+
* - "supported" arithmetic evidence agrees
|
|
391
|
+
* - "contradicted" arithmetic evidence disagrees (a hint to look, not a
|
|
392
|
+
* verdict that the dataset is wrong)
|
|
393
|
+
* A check that can't be evaluated stays "asserted" — we don't downgrade a
|
|
394
|
+
* trusted claim because of a malformed mechanical form.
|
|
395
|
+
*/
|
|
396
|
+
export function annotateNotationEvidence(notation, rows) {
|
|
397
|
+
const checks = [];
|
|
398
|
+
for (const predicate of notation.predicates ?? []) {
|
|
399
|
+
if (!predicate.check) {
|
|
400
|
+
checks.push({ predicateId: predicate.id, status: "asserted" });
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
try {
|
|
404
|
+
const outcome = evaluateNotationCheck(rows, predicate.check);
|
|
405
|
+
checks.push({
|
|
406
|
+
predicateId: predicate.id,
|
|
407
|
+
status: outcome.ok ? "supported" : "contradicted",
|
|
408
|
+
detail: outcome.detail,
|
|
409
|
+
});
|
|
410
|
+
}
|
|
411
|
+
catch (error) {
|
|
412
|
+
checks.push({
|
|
413
|
+
predicateId: predicate.id,
|
|
414
|
+
status: "asserted",
|
|
415
|
+
detail: `no evaluable: ${String(error).slice(0, 120)}`,
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return {
|
|
420
|
+
...notation,
|
|
421
|
+
checks,
|
|
422
|
+
evidenceAt: Date.now(),
|
|
423
|
+
};
|
|
424
|
+
}
|
package/dist/query/index.d.ts
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
export * from "./queryDomain";
|
|
2
|
-
//# sourceMappingURL=index.d.ts.map
|
|
1
|
+
export * from "./queryDomain.js";
|
package/dist/query/index.js
CHANGED
|
@@ -1,18 +1 @@
|
|
|
1
|
-
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
-
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
__exportStar(require("./queryDomain"), exports);
|
|
18
|
-
//# sourceMappingURL=index.js.map
|
|
1
|
+
export * from "./queryDomain.js";
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import type
|
|
2
|
-
export type QueryDomainInput = QueryDomainStepInput
|
|
1
|
+
import { type QueryDomainStepInput, type QueryDomainStepResult } from "./queryDomain.step.js";
|
|
2
|
+
export type QueryDomainInput = Omit<QueryDomainStepInput, "runtime">;
|
|
3
3
|
export type QueryDomainResult = QueryDomainStepResult;
|
|
4
4
|
/**
|
|
5
5
|
* Workflow-compatible domain query.
|
|
6
6
|
* Always returns a dataset + preview rows.
|
|
7
7
|
*/
|
|
8
|
-
export declare function queryDomain(input: QueryDomainInput): Promise<QueryDomainResult>;
|
|
9
|
-
//# sourceMappingURL=queryDomain.d.ts.map
|
|
8
|
+
export declare function queryDomain(runtime: any, input: QueryDomainInput): Promise<QueryDomainResult>;
|
|
@@ -1,46 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.queryDomain = queryDomain;
|
|
1
|
+
import { queryDomainStep } from "./queryDomain.step.js";
|
|
37
2
|
/**
|
|
38
3
|
* Workflow-compatible domain query.
|
|
39
4
|
* Always returns a dataset + preview rows.
|
|
40
5
|
*/
|
|
41
|
-
async function queryDomain(input) {
|
|
6
|
+
export async function queryDomain(runtime, input) {
|
|
42
7
|
"use step";
|
|
43
|
-
|
|
44
|
-
return await queryDomainStep(input);
|
|
8
|
+
return await queryDomainStep({ runtime, ...input });
|
|
45
9
|
}
|
|
46
|
-
//# sourceMappingURL=queryDomain.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export type QueryDomainStepInput = {
|
|
2
|
+
runtime: any;
|
|
2
3
|
query: Record<string, any>;
|
|
3
4
|
explanation: string;
|
|
4
5
|
title?: string;
|
|
@@ -11,4 +12,3 @@ export type QueryDomainStepResult = {
|
|
|
11
12
|
explanation: string;
|
|
12
13
|
};
|
|
13
14
|
export declare function queryDomainStep(params: QueryDomainStepInput): Promise<QueryDomainStepResult>;
|
|
14
|
-
//# sourceMappingURL=queryDomain.step.d.ts.map
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
const admin_1 = require("@instantdb/admin");
|
|
5
|
-
const runtime_1 = require("@ekairos/events/runtime");
|
|
6
|
-
const service_1 = require("../service");
|
|
1
|
+
import { DatasetService } from "../service.js";
|
|
2
|
+
import { createDatasetId } from "../id.js";
|
|
3
|
+
import { annotateNotationEvidence, inferQueryNotation } from "../notation.js";
|
|
7
4
|
function normalizeRows(result) {
|
|
8
5
|
if (!result || typeof result !== "object")
|
|
9
6
|
return [];
|
|
@@ -49,17 +46,31 @@ function inferSchema(rows) {
|
|
|
49
46
|
}
|
|
50
47
|
return { schema };
|
|
51
48
|
}
|
|
52
|
-
async function
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
async function getRuntimeDb(runtime) {
|
|
50
|
+
if (!runtime) {
|
|
51
|
+
throw new Error("Dataset query step requires runtime.");
|
|
52
|
+
}
|
|
56
53
|
const db = runtime.db;
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
return typeof db === "function" ? await db.call(runtime) : db;
|
|
55
|
+
}
|
|
56
|
+
export async function queryDomainStep(params) {
|
|
57
|
+
"use step";
|
|
58
|
+
const db = await getRuntimeDb(params.runtime);
|
|
59
|
+
const service = new DatasetService(db);
|
|
60
|
+
const datasetId = params.datasetId ?? createDatasetId();
|
|
59
61
|
const queryResult = await db.query(params.query);
|
|
60
62
|
const rows = normalizeRows(queryResult);
|
|
61
63
|
const previewRows = rows.slice(0, 20);
|
|
62
64
|
const schema = inferSchema(rows);
|
|
65
|
+
// query-backed datasets carry a fully deterministic formal notation:
|
|
66
|
+
// the set definition, its symbols and its predicates derive mechanically
|
|
67
|
+
// from the query + rows, so their arithmetic evidence is immediate
|
|
68
|
+
const notation = annotateNotationEvidence(inferQueryNotation({
|
|
69
|
+
entityNames: Object.keys(params.query ?? {}),
|
|
70
|
+
rowCount: rows.length,
|
|
71
|
+
schema,
|
|
72
|
+
explanation: params.explanation,
|
|
73
|
+
}), rows);
|
|
63
74
|
const createRes = await service.createDataset({
|
|
64
75
|
id: datasetId,
|
|
65
76
|
title: params.title ?? "domain.query",
|
|
@@ -67,6 +78,7 @@ async function queryDomainStep(params) {
|
|
|
67
78
|
instructions: params.explanation,
|
|
68
79
|
analysis: { explanation: params.explanation, query: params.query },
|
|
69
80
|
schema,
|
|
81
|
+
notation,
|
|
70
82
|
createdAt: Date.now(),
|
|
71
83
|
updatedAt: Date.now(),
|
|
72
84
|
});
|
|
@@ -101,4 +113,3 @@ async function queryDomainStep(params) {
|
|
|
101
113
|
explanation: params.explanation,
|
|
102
114
|
};
|
|
103
115
|
}
|
|
104
|
-
//# sourceMappingURL=queryDomain.step.js.map
|
package/dist/sandbox/steps.d.ts
CHANGED
|
@@ -1,13 +1,7 @@
|
|
|
1
|
+
import { type SandboxConfig } from "@ekairos/sandbox";
|
|
1
2
|
export type DatasetSandboxId = string;
|
|
2
|
-
export type CreateDatasetSandboxParams = {
|
|
3
|
-
|
|
4
|
-
timeoutMs?: number;
|
|
5
|
-
ports?: number[];
|
|
6
|
-
resources?: {
|
|
7
|
-
vcpus?: number;
|
|
8
|
-
};
|
|
9
|
-
purpose?: string;
|
|
10
|
-
params?: Record<string, any>;
|
|
3
|
+
export type CreateDatasetSandboxParams = Pick<SandboxConfig, "provider" | "timeoutMs" | "ports" | "resources" | "purpose" | "params" | "env" | "domain" | "dataset" | "vercel"> & {
|
|
4
|
+
sandboxRuntime?: string;
|
|
11
5
|
};
|
|
12
6
|
export type DatasetSandboxRunCommandResult = {
|
|
13
7
|
exitCode: number;
|
|
@@ -15,33 +9,47 @@ export type DatasetSandboxRunCommandResult = {
|
|
|
15
9
|
stderr: string;
|
|
16
10
|
};
|
|
17
11
|
export declare function createDatasetSandboxStep(params: {
|
|
18
|
-
|
|
12
|
+
runtime: any;
|
|
19
13
|
} & CreateDatasetSandboxParams): Promise<{
|
|
20
14
|
sandboxId: DatasetSandboxId;
|
|
21
15
|
}>;
|
|
22
16
|
export declare function runDatasetSandboxCommandStep(params: {
|
|
23
|
-
|
|
17
|
+
runtime: any;
|
|
24
18
|
sandboxId: DatasetSandboxId;
|
|
25
19
|
cmd: string;
|
|
26
20
|
args?: string[];
|
|
27
21
|
}): Promise<DatasetSandboxRunCommandResult>;
|
|
28
22
|
export declare function writeDatasetSandboxFilesStep(params: {
|
|
29
|
-
|
|
23
|
+
runtime: any;
|
|
30
24
|
sandboxId: DatasetSandboxId;
|
|
31
25
|
files: Array<{
|
|
32
26
|
path: string;
|
|
33
27
|
contentBase64: string;
|
|
34
28
|
}>;
|
|
35
29
|
}): Promise<void>;
|
|
30
|
+
export declare function writeDatasetSandboxTextFilesStep(params: {
|
|
31
|
+
runtime: any;
|
|
32
|
+
sandboxId: DatasetSandboxId;
|
|
33
|
+
files: Array<{
|
|
34
|
+
path: string;
|
|
35
|
+
content: string;
|
|
36
|
+
}>;
|
|
37
|
+
}): Promise<void>;
|
|
36
38
|
export declare function readDatasetSandboxFileStep(params: {
|
|
37
|
-
|
|
39
|
+
runtime: any;
|
|
38
40
|
sandboxId: DatasetSandboxId;
|
|
39
41
|
path: string;
|
|
40
42
|
}): Promise<{
|
|
41
43
|
contentBase64: string;
|
|
42
44
|
}>;
|
|
45
|
+
export declare function readDatasetSandboxTextFileStep(params: {
|
|
46
|
+
runtime: any;
|
|
47
|
+
sandboxId: DatasetSandboxId;
|
|
48
|
+
path: string;
|
|
49
|
+
}): Promise<{
|
|
50
|
+
content: string;
|
|
51
|
+
}>;
|
|
43
52
|
export declare function stopDatasetSandboxStep(params: {
|
|
44
|
-
|
|
53
|
+
runtime: any;
|
|
45
54
|
sandboxId: DatasetSandboxId;
|
|
46
55
|
}): Promise<void>;
|
|
47
|
-
//# sourceMappingURL=steps.d.ts.map
|