@almadar/evaluator 2.35.0 → 2.36.0
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/dist/index.d.ts +22 -2
- package/dist/index.js +601 -6
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SExpr } from '@almadar/core';
|
|
1
|
+
import { SExpr, ListenPayloadEvaluator } from '@almadar/core';
|
|
2
2
|
export { CORE_BINDINGS, CoreBinding, Expression, ExpressionSchema, ParsedBinding, SExpr, SExprAtom, SExprSchema, collectBindings, getArgs, getOperator, isBinding, isSExpr, isSExprAtom, isSExprCall, isValidBinding, parseBinding, sexpr, walkSExpr } from '@almadar/core';
|
|
3
3
|
import { E as EvaluationContext } from './index-rPqsFqVO.js';
|
|
4
4
|
export { U as UserContext, c as createChildContext, a as createEffectContext, b as createMinimalContext, e as evalAbs, d as evalAdd, f as evalAnd, g as evalAtomic, h as evalCallService, i as evalCeil, j as evalClamp, k as evalConcat, l as evalCount, m as evalDecrement, n as evalDeref, o as evalDespawn, p as evalDivide, q as evalDo, r as evalEmit, s as evalEmpty, t as evalEqual, u as evalFilter, v as evalFind, w as evalFirst, x as evalFloor, y as evalFn, z as evalGreaterThan, A as evalGreaterThanOrEqual, B as evalIf, C as evalIncludes, D as evalIncrement, F as evalLast, G as evalLessThan, H as evalLessThanOrEqual, I as evalLet, J as evalList, K as evalMap, L as evalMatches, M as evalMax, N as evalMin, O as evalModulo, P as evalMultiply, Q as evalNavigate, R as evalNot, S as evalNotEqual, T as evalNotify, V as evalNth, W as evalOr, X as evalPersist, Y as evalRef, Z as evalRenderUI, _ as evalRound, $ as evalSet, a0 as evalSetDynamic, a1 as evalSpawn, a2 as evalSubtract, a3 as evalSum, a4 as evalSwap, a5 as evalWatch, a6 as evalWhen, a7 as resolveBinding } from './index-rPqsFqVO.js';
|
|
@@ -72,4 +72,24 @@ declare function evaluateGuard(expr: SExpr, ctx: EvaluationContext): boolean;
|
|
|
72
72
|
declare function executeEffect(expr: SExpr, ctx: EvaluationContext): void;
|
|
73
73
|
declare function executeEffects(effects: SExpr[], ctx: EvaluationContext): void;
|
|
74
74
|
|
|
75
|
-
|
|
75
|
+
/**
|
|
76
|
+
* The canonical evaluator for `listens { … with { field: <expr> } }` mapping
|
|
77
|
+
* values.
|
|
78
|
+
*
|
|
79
|
+
* `@almadar/core` owns the mapping contract (`applyListenPayloadMapping`) but
|
|
80
|
+
* sits upstream of this package and cannot evaluate. Every delivery path — the
|
|
81
|
+
* server runtime and the client cross-trait wiring — passes THIS function, so
|
|
82
|
+
* the two paths cannot drift into different `with{}` semantics.
|
|
83
|
+
*
|
|
84
|
+
* The binding context is payload-only, matching `orbital-core`'s listener
|
|
85
|
+
* fan-out (`runtime/listener.rs:107-109`, `runtime/kernel.rs:687-689`), which
|
|
86
|
+
* builds `BindingContextBuilder::new().payload(…).build()`. Binding `@entity`
|
|
87
|
+
* or `@config` here would let a mapping resolve on the JS path and silently
|
|
88
|
+
* yield nothing on the compiled one.
|
|
89
|
+
*
|
|
90
|
+
* @packageDocumentation
|
|
91
|
+
*/
|
|
92
|
+
|
|
93
|
+
declare const evaluateListenPayloadExpr: ListenPayloadEvaluator;
|
|
94
|
+
|
|
95
|
+
export { EvaluationContext, SExpressionEvaluator, evaluate, evaluateGuard, evaluateListenPayloadExpr, evaluator, executeEffect, executeEffects };
|
package/dist/index.js
CHANGED
|
@@ -1288,6 +1288,56 @@ function evalArrayDropLast(args, evaluate2, ctx) {
|
|
|
1288
1288
|
const n = evaluate2(args[1], ctx);
|
|
1289
1289
|
return (arr ?? []).slice(0, -n);
|
|
1290
1290
|
}
|
|
1291
|
+
function cosineSimilarity(a, b) {
|
|
1292
|
+
if (a.length !== b.length) {
|
|
1293
|
+
throw new Error(`array/cosine: vector length mismatch (${a.length} vs ${b.length})`);
|
|
1294
|
+
}
|
|
1295
|
+
if (a.length === 0) {
|
|
1296
|
+
throw new Error("array/cosine: empty vector has no defined similarity");
|
|
1297
|
+
}
|
|
1298
|
+
let dot = 0;
|
|
1299
|
+
let normA = 0;
|
|
1300
|
+
let normB = 0;
|
|
1301
|
+
for (let i = 0; i < a.length; i++) {
|
|
1302
|
+
const av = a[i];
|
|
1303
|
+
const bv = b[i];
|
|
1304
|
+
dot += av * bv;
|
|
1305
|
+
normA += av * av;
|
|
1306
|
+
normB += bv * bv;
|
|
1307
|
+
}
|
|
1308
|
+
if (normA === 0 || normB === 0) {
|
|
1309
|
+
throw new Error("array/cosine: zero-magnitude vector has no defined direction to compare");
|
|
1310
|
+
}
|
|
1311
|
+
return dot / (Math.sqrt(normA) * Math.sqrt(normB));
|
|
1312
|
+
}
|
|
1313
|
+
function evalArrayCosine(args, evaluate2, ctx) {
|
|
1314
|
+
const a = evaluate2(args[0], ctx);
|
|
1315
|
+
const b = evaluate2(args[1], ctx);
|
|
1316
|
+
return cosineSimilarity(a, b);
|
|
1317
|
+
}
|
|
1318
|
+
function evalArrayNearest(args, evaluate2, ctx) {
|
|
1319
|
+
const query = evaluate2(args[0], ctx);
|
|
1320
|
+
const candidates = evaluate2(args[1], ctx);
|
|
1321
|
+
if (candidates.length === 0) {
|
|
1322
|
+
throw new Error("array/nearest: candidates array is empty, no nearest match exists");
|
|
1323
|
+
}
|
|
1324
|
+
const scores = candidates.map((c) => cosineSimilarity(query, c));
|
|
1325
|
+
let bestIdx = 0;
|
|
1326
|
+
let bestScore = scores[0];
|
|
1327
|
+
for (let i = 1; i < scores.length; i++) {
|
|
1328
|
+
if (scores[i] > bestScore) {
|
|
1329
|
+
bestScore = scores[i];
|
|
1330
|
+
bestIdx = i;
|
|
1331
|
+
}
|
|
1332
|
+
}
|
|
1333
|
+
let secondBest = -Infinity;
|
|
1334
|
+
for (let i = 0; i < scores.length; i++) {
|
|
1335
|
+
if (i === bestIdx) continue;
|
|
1336
|
+
if (scores[i] > secondBest) secondBest = scores[i];
|
|
1337
|
+
}
|
|
1338
|
+
const margin = scores.length === 1 ? 0 : bestScore - secondBest;
|
|
1339
|
+
return { index: bestIdx, score: bestScore, margin };
|
|
1340
|
+
}
|
|
1291
1341
|
|
|
1292
1342
|
// std/object.ts
|
|
1293
1343
|
var FORBIDDEN_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
@@ -1778,11 +1828,11 @@ function evalTimeFormat(args, evaluate2, ctx) {
|
|
|
1778
1828
|
"December"
|
|
1779
1829
|
][date.getMonth()]
|
|
1780
1830
|
};
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
return
|
|
1831
|
+
const pattern = new RegExp(
|
|
1832
|
+
Object.keys(tokens).sort((a, b) => b.length - a.length).join("|"),
|
|
1833
|
+
"g"
|
|
1834
|
+
);
|
|
1835
|
+
return format.replace(pattern, (token) => tokens[token]);
|
|
1786
1836
|
}
|
|
1787
1837
|
function evalTimeYear(args, evaluate2, ctx) {
|
|
1788
1838
|
const timestamp = evaluate2(args[0], ctx);
|
|
@@ -2538,6 +2588,481 @@ function evalOsDebounce(args, evaluate2, ctx) {
|
|
|
2538
2588
|
registerTrigger(ctx, "debounce", { ms, eventType });
|
|
2539
2589
|
}
|
|
2540
2590
|
|
|
2591
|
+
// std/contract.ts
|
|
2592
|
+
function fieldName(f) {
|
|
2593
|
+
return typeof f === "string" ? f : f.name;
|
|
2594
|
+
}
|
|
2595
|
+
function isTensorValue(v) {
|
|
2596
|
+
if (typeof v === "number") return true;
|
|
2597
|
+
return Array.isArray(v) && v.every(isTensorValue);
|
|
2598
|
+
}
|
|
2599
|
+
function describeType(v) {
|
|
2600
|
+
if (v === null) return "null";
|
|
2601
|
+
if (Array.isArray(v)) return "array containing non-numeric values";
|
|
2602
|
+
return typeof v;
|
|
2603
|
+
}
|
|
2604
|
+
function tensorShape(t) {
|
|
2605
|
+
if (typeof t === "number") return [];
|
|
2606
|
+
if (t.length === 0) return [0];
|
|
2607
|
+
const first = t[0];
|
|
2608
|
+
if (typeof first === "number") return [t.length];
|
|
2609
|
+
return [t.length, ...tensorShape(first)];
|
|
2610
|
+
}
|
|
2611
|
+
function lastDimSize(t) {
|
|
2612
|
+
const shape = tensorShape(t);
|
|
2613
|
+
return shape.length === 0 ? 0 : shape[shape.length - 1];
|
|
2614
|
+
}
|
|
2615
|
+
function arraysEqual(a, b) {
|
|
2616
|
+
return a.length === b.length && a.every((v, i) => v === b[i]);
|
|
2617
|
+
}
|
|
2618
|
+
function gatherLastDim(t, dim) {
|
|
2619
|
+
if (typeof t === "number") return [];
|
|
2620
|
+
if (t.length === 0) return [];
|
|
2621
|
+
if (typeof t[0] === "number") return [t[dim]];
|
|
2622
|
+
const out = [];
|
|
2623
|
+
for (const sub of t) out.push(...gatherLastDim(sub, dim));
|
|
2624
|
+
return out;
|
|
2625
|
+
}
|
|
2626
|
+
function mapLastDim(t, dim, fn) {
|
|
2627
|
+
if (typeof t === "number") return t;
|
|
2628
|
+
if (t.length === 0) return t;
|
|
2629
|
+
if (typeof t[0] === "number") {
|
|
2630
|
+
const copy = [...t];
|
|
2631
|
+
copy[dim] = fn(copy[dim]);
|
|
2632
|
+
return copy;
|
|
2633
|
+
}
|
|
2634
|
+
return t.map((sub) => mapLastDim(sub, dim, fn));
|
|
2635
|
+
}
|
|
2636
|
+
function validateContract(tensor, contract) {
|
|
2637
|
+
if (!isTensorValue(tensor)) {
|
|
2638
|
+
return {
|
|
2639
|
+
valid: false,
|
|
2640
|
+
violations: [{ type: "not_a_tensor", actualType: describeType(tensor) }]
|
|
2641
|
+
};
|
|
2642
|
+
}
|
|
2643
|
+
const violations = [];
|
|
2644
|
+
const shape = tensorShape(tensor);
|
|
2645
|
+
if (contract.shape && !arraysEqual(shape, contract.shape)) {
|
|
2646
|
+
violations.push({ type: "shape_mismatch", expected: contract.shape, actual: shape });
|
|
2647
|
+
}
|
|
2648
|
+
const ranges = contract.ranges ?? {};
|
|
2649
|
+
const size = lastDimSize(tensor);
|
|
2650
|
+
for (const [dimStr, bounds] of Object.entries(ranges)) {
|
|
2651
|
+
const dim = Number(dimStr);
|
|
2652
|
+
if (dim >= size) continue;
|
|
2653
|
+
const vals = gatherLastDim(tensor, dim);
|
|
2654
|
+
const min = bounds.min ?? -Infinity;
|
|
2655
|
+
const max = bounds.max ?? Infinity;
|
|
2656
|
+
const actualMin = Math.min(...vals);
|
|
2657
|
+
const actualMax = Math.max(...vals);
|
|
2658
|
+
if (actualMin < min || actualMax > max) {
|
|
2659
|
+
violations.push({ type: "range_violation", dim, min, max, actualMin, actualMax });
|
|
2660
|
+
}
|
|
2661
|
+
}
|
|
2662
|
+
return { valid: violations.length === 0, violations };
|
|
2663
|
+
}
|
|
2664
|
+
function clampContract(tensor, contract) {
|
|
2665
|
+
if (!isTensorValue(tensor)) {
|
|
2666
|
+
throw new Error(
|
|
2667
|
+
`contract/clamp-output: expected a tensor (a number, or nested arrays of numbers), received ${describeType(tensor)}. Validate with contract/validate-output before clamping.`
|
|
2668
|
+
);
|
|
2669
|
+
}
|
|
2670
|
+
const ranges = contract.ranges ?? {};
|
|
2671
|
+
const size = lastDimSize(tensor);
|
|
2672
|
+
let result = tensor;
|
|
2673
|
+
for (const [dimStr, bounds] of Object.entries(ranges)) {
|
|
2674
|
+
const dim = Number(dimStr);
|
|
2675
|
+
if (dim >= size) continue;
|
|
2676
|
+
const min = bounds.min ?? -Infinity;
|
|
2677
|
+
const max = bounds.max ?? Infinity;
|
|
2678
|
+
result = mapLastDim(result, dim, (v) => Math.min(Math.max(v, min), max));
|
|
2679
|
+
}
|
|
2680
|
+
return result;
|
|
2681
|
+
}
|
|
2682
|
+
function evalContractValidateInput(args, evaluate2, ctx) {
|
|
2683
|
+
const tensor = evaluate2(args[0], ctx);
|
|
2684
|
+
const contract = evaluate2(args[1], ctx);
|
|
2685
|
+
return validateContract(tensor, contract);
|
|
2686
|
+
}
|
|
2687
|
+
function evalContractValidateOutput(args, evaluate2, ctx) {
|
|
2688
|
+
return evalContractValidateInput(args, evaluate2, ctx);
|
|
2689
|
+
}
|
|
2690
|
+
function evalContractClampOutput(args, evaluate2, ctx) {
|
|
2691
|
+
const tensor = evaluate2(args[0], ctx);
|
|
2692
|
+
const contract = evaluate2(args[1], ctx);
|
|
2693
|
+
return clampContract(tensor, contract);
|
|
2694
|
+
}
|
|
2695
|
+
function evalContractViolations(args, evaluate2, ctx) {
|
|
2696
|
+
const tensor = evaluate2(args[0], ctx);
|
|
2697
|
+
const contract = evaluate2(args[1], ctx);
|
|
2698
|
+
return validateContract(tensor, contract).violations;
|
|
2699
|
+
}
|
|
2700
|
+
function evalContractEntityToTensor(args, evaluate2, ctx) {
|
|
2701
|
+
const entity = evaluate2(args[0], ctx);
|
|
2702
|
+
const contract = evaluate2(args[1], ctx);
|
|
2703
|
+
const fields = contract.fields ?? [];
|
|
2704
|
+
return fields.map((f) => {
|
|
2705
|
+
const val = entity[fieldName(f)];
|
|
2706
|
+
return typeof val === "number" ? val : 0;
|
|
2707
|
+
});
|
|
2708
|
+
}
|
|
2709
|
+
function evalContractTensorToPayload(args, evaluate2, ctx) {
|
|
2710
|
+
const tensor = evaluate2(args[0], ctx);
|
|
2711
|
+
if (!isTensorValue(tensor)) {
|
|
2712
|
+
throw new Error(
|
|
2713
|
+
`contract/tensor-to-payload: expected a tensor (a number, or nested arrays of numbers), received ${describeType(tensor)}.`
|
|
2714
|
+
);
|
|
2715
|
+
}
|
|
2716
|
+
const contract = evaluate2(args[1], ctx);
|
|
2717
|
+
const fields = contract.fields ?? [];
|
|
2718
|
+
const values = Array.isArray(tensor) ? tensor : [tensor];
|
|
2719
|
+
const result = {};
|
|
2720
|
+
fields.forEach((f, i) => {
|
|
2721
|
+
if (i < values.length) result[fieldName(f)] = values[i];
|
|
2722
|
+
});
|
|
2723
|
+
return result;
|
|
2724
|
+
}
|
|
2725
|
+
|
|
2726
|
+
// std/graph.ts
|
|
2727
|
+
function tensorShape2(t) {
|
|
2728
|
+
if (typeof t === "number") return [];
|
|
2729
|
+
if (t.length === 0) return [0];
|
|
2730
|
+
const first = t[0];
|
|
2731
|
+
if (typeof first === "number") return [t.length];
|
|
2732
|
+
return [t.length, ...tensorShape2(first)];
|
|
2733
|
+
}
|
|
2734
|
+
function numNodes(g) {
|
|
2735
|
+
return g.x.length;
|
|
2736
|
+
}
|
|
2737
|
+
function subgraphData(g, mask) {
|
|
2738
|
+
const nodeMap = new Array(numNodes(g)).fill(-1);
|
|
2739
|
+
const x = [];
|
|
2740
|
+
let next = 0;
|
|
2741
|
+
for (let i = 0; i < numNodes(g); i++) {
|
|
2742
|
+
if (mask[i]) {
|
|
2743
|
+
nodeMap[i] = next++;
|
|
2744
|
+
x.push(g.x[i]);
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
const [srcAll, dstAll] = g.edgeIndex;
|
|
2748
|
+
const src = [];
|
|
2749
|
+
const dst = [];
|
|
2750
|
+
for (let k = 0; k < srcAll.length; k++) {
|
|
2751
|
+
const s = srcAll[k];
|
|
2752
|
+
const d = dstAll[k];
|
|
2753
|
+
if (mask[s] && mask[d]) {
|
|
2754
|
+
src.push(nodeMap[s]);
|
|
2755
|
+
dst.push(nodeMap[d]);
|
|
2756
|
+
}
|
|
2757
|
+
}
|
|
2758
|
+
return { x, edgeIndex: [src, dst] };
|
|
2759
|
+
}
|
|
2760
|
+
function evalGraphFromEntities(args, evaluate2, ctx) {
|
|
2761
|
+
const entities = evaluate2(args[0], ctx);
|
|
2762
|
+
if (entities.length === 0) {
|
|
2763
|
+
return { x: [], edgeIndex: [[], []] };
|
|
2764
|
+
}
|
|
2765
|
+
const features = entities.map((e) => {
|
|
2766
|
+
const row = Object.values(e).filter((v) => typeof v === "number" || typeof v === "boolean").map((v) => typeof v === "boolean" ? v ? 1 : 0 : v);
|
|
2767
|
+
return row.length > 0 ? row : [0];
|
|
2768
|
+
});
|
|
2769
|
+
const maxLen = Math.max(...features.map((r) => r.length));
|
|
2770
|
+
const x = features.map((r) => [...r, ...new Array(maxLen - r.length).fill(0)]);
|
|
2771
|
+
return { x, edgeIndex: [[], []] };
|
|
2772
|
+
}
|
|
2773
|
+
function evalGraphFromAdjacency(args, evaluate2, ctx) {
|
|
2774
|
+
const adjacency = evaluate2(args[0], ctx);
|
|
2775
|
+
const features = evaluate2(args[1], ctx);
|
|
2776
|
+
const src = [];
|
|
2777
|
+
const dst = [];
|
|
2778
|
+
for (let i = 0; i < adjacency.length; i++) {
|
|
2779
|
+
const row = adjacency[i];
|
|
2780
|
+
for (let j = 0; j < row.length; j++) {
|
|
2781
|
+
if (row[j] !== 0) {
|
|
2782
|
+
src.push(i);
|
|
2783
|
+
dst.push(j);
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2787
|
+
return { x: features, edgeIndex: [src, dst] };
|
|
2788
|
+
}
|
|
2789
|
+
function evalGraphFromEdgeList(args, evaluate2, ctx) {
|
|
2790
|
+
const edges = evaluate2(args[0], ctx);
|
|
2791
|
+
const features = evaluate2(args[1], ctx);
|
|
2792
|
+
const shape = tensorShape2(edges);
|
|
2793
|
+
let edgeIndex;
|
|
2794
|
+
if (shape.length === 2 && shape[1] === 2) {
|
|
2795
|
+
const rows = edges;
|
|
2796
|
+
edgeIndex = [rows.map((r) => r[0]), rows.map((r) => r[1])];
|
|
2797
|
+
} else {
|
|
2798
|
+
const pair = edges;
|
|
2799
|
+
edgeIndex = [pair[0] ?? [], pair[1] ?? []];
|
|
2800
|
+
}
|
|
2801
|
+
return { x: features, edgeIndex };
|
|
2802
|
+
}
|
|
2803
|
+
function evalGraphAddSelfLoops(args, evaluate2, ctx) {
|
|
2804
|
+
const g = evaluate2(args[0], ctx);
|
|
2805
|
+
const n = numNodes(g);
|
|
2806
|
+
const loop = Array.from({ length: n }, (_, i) => i);
|
|
2807
|
+
const [src, dst] = g.edgeIndex;
|
|
2808
|
+
return { x: g.x, edgeIndex: [[...src, ...loop], [...dst, ...loop]], edgeAttr: g.edgeAttr };
|
|
2809
|
+
}
|
|
2810
|
+
function evalGraphToUndirected(args, evaluate2, ctx) {
|
|
2811
|
+
const g = evaluate2(args[0], ctx);
|
|
2812
|
+
const [src, dst] = g.edgeIndex;
|
|
2813
|
+
return { x: g.x, edgeIndex: [[...src, ...dst], [...dst, ...src]], edgeAttr: g.edgeAttr };
|
|
2814
|
+
}
|
|
2815
|
+
function evalGraphSubgraph(args, evaluate2, ctx) {
|
|
2816
|
+
const g = evaluate2(args[0], ctx);
|
|
2817
|
+
const mask = evaluate2(args[1], ctx);
|
|
2818
|
+
return subgraphData(g, mask);
|
|
2819
|
+
}
|
|
2820
|
+
function evalGraphKHop(args, evaluate2, ctx) {
|
|
2821
|
+
const g = evaluate2(args[0], ctx);
|
|
2822
|
+
const node = evaluate2(args[1], ctx);
|
|
2823
|
+
const k = evaluate2(args[2], ctx);
|
|
2824
|
+
const [src, dst] = g.edgeIndex;
|
|
2825
|
+
const visited = /* @__PURE__ */ new Set([node]);
|
|
2826
|
+
let frontier = /* @__PURE__ */ new Set([node]);
|
|
2827
|
+
for (let hop = 0; hop < k; hop++) {
|
|
2828
|
+
const next = /* @__PURE__ */ new Set();
|
|
2829
|
+
for (const n of frontier) {
|
|
2830
|
+
for (let e = 0; e < src.length; e++) {
|
|
2831
|
+
if (src[e] === n && !visited.has(dst[e])) next.add(dst[e]);
|
|
2832
|
+
if (dst[e] === n && !visited.has(src[e])) next.add(src[e]);
|
|
2833
|
+
}
|
|
2834
|
+
}
|
|
2835
|
+
for (const v of next) visited.add(v);
|
|
2836
|
+
frontier = next;
|
|
2837
|
+
}
|
|
2838
|
+
const mask = new Array(numNodes(g)).fill(false);
|
|
2839
|
+
for (const n of visited) mask[n] = true;
|
|
2840
|
+
return subgraphData(g, mask);
|
|
2841
|
+
}
|
|
2842
|
+
function evalGraphNodeFeatures(args, evaluate2, ctx) {
|
|
2843
|
+
return evaluate2(args[0], ctx).x;
|
|
2844
|
+
}
|
|
2845
|
+
function evalGraphEdgeIndex(args, evaluate2, ctx) {
|
|
2846
|
+
return evaluate2(args[0], ctx).edgeIndex;
|
|
2847
|
+
}
|
|
2848
|
+
function evalGraphEdgeFeatures(args, evaluate2, ctx) {
|
|
2849
|
+
return evaluate2(args[0], ctx).edgeAttr;
|
|
2850
|
+
}
|
|
2851
|
+
function evalGraphNumNodes(args, evaluate2, ctx) {
|
|
2852
|
+
return numNodes(evaluate2(args[0], ctx));
|
|
2853
|
+
}
|
|
2854
|
+
function evalGraphNumEdges(args, evaluate2, ctx) {
|
|
2855
|
+
return evaluate2(args[0], ctx).edgeIndex[0].length;
|
|
2856
|
+
}
|
|
2857
|
+
function evalGraphDegree(args, evaluate2, ctx) {
|
|
2858
|
+
const g = evaluate2(args[0], ctx);
|
|
2859
|
+
const deg = new Array(numNodes(g)).fill(0);
|
|
2860
|
+
for (const s of g.edgeIndex[0]) deg[s]++;
|
|
2861
|
+
return deg;
|
|
2862
|
+
}
|
|
2863
|
+
function evalGraphBatch(args, evaluate2, ctx) {
|
|
2864
|
+
const graphs = evaluate2(args[0], ctx);
|
|
2865
|
+
if (graphs.length === 0) return { x: [], edgeIndex: [[], []] };
|
|
2866
|
+
const x = [];
|
|
2867
|
+
const src = [];
|
|
2868
|
+
const dst = [];
|
|
2869
|
+
let offset = 0;
|
|
2870
|
+
for (const g of graphs) {
|
|
2871
|
+
x.push(...g.x);
|
|
2872
|
+
src.push(...g.edgeIndex[0].map((s) => s + offset));
|
|
2873
|
+
dst.push(...g.edgeIndex[1].map((d) => d + offset));
|
|
2874
|
+
offset += numNodes(g);
|
|
2875
|
+
}
|
|
2876
|
+
return { x, edgeIndex: [src, dst] };
|
|
2877
|
+
}
|
|
2878
|
+
|
|
2879
|
+
// std/data.ts
|
|
2880
|
+
function isPlainRecord(v) {
|
|
2881
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
2882
|
+
}
|
|
2883
|
+
function datasetGetItem(dataset, idx) {
|
|
2884
|
+
const item = dataset.data[idx];
|
|
2885
|
+
if (isPlainRecord(item)) {
|
|
2886
|
+
const x = item.input ?? item.observation ?? [];
|
|
2887
|
+
const y = item.target ?? item.output ?? [];
|
|
2888
|
+
return [x, y];
|
|
2889
|
+
}
|
|
2890
|
+
if (Array.isArray(item)) {
|
|
2891
|
+
return [item, item];
|
|
2892
|
+
}
|
|
2893
|
+
return [item, item];
|
|
2894
|
+
}
|
|
2895
|
+
function seededRandom(ctx) {
|
|
2896
|
+
if (ctx._probSeed) {
|
|
2897
|
+
const seed = ctx._probSeed;
|
|
2898
|
+
let t = seed.state += 1831565813;
|
|
2899
|
+
t = Math.imul(t ^ t >>> 15, t | 1);
|
|
2900
|
+
t ^= t + Math.imul(t ^ t >>> 7, t | 61);
|
|
2901
|
+
return ((t ^ t >>> 14) >>> 0) / 4294967296;
|
|
2902
|
+
}
|
|
2903
|
+
return Math.random();
|
|
2904
|
+
}
|
|
2905
|
+
function seededGaussian(ctx) {
|
|
2906
|
+
const u1 = seededRandom(ctx);
|
|
2907
|
+
const u2 = seededRandom(ctx);
|
|
2908
|
+
return Math.sqrt(-2 * Math.log(u1)) * Math.cos(2 * Math.PI * u2);
|
|
2909
|
+
}
|
|
2910
|
+
function shuffleInPlace(arr, ctx) {
|
|
2911
|
+
for (let i = arr.length - 1; i > 0; i--) {
|
|
2912
|
+
const j = Math.floor(seededRandom(ctx) * (i + 1));
|
|
2913
|
+
const tmp = arr[i];
|
|
2914
|
+
arr[i] = arr[j];
|
|
2915
|
+
arr[j] = tmp;
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2918
|
+
function tensorShape3(t) {
|
|
2919
|
+
if (typeof t === "number") return [];
|
|
2920
|
+
if (t.length === 0) return [0];
|
|
2921
|
+
const first = t[0];
|
|
2922
|
+
if (typeof first === "number") return [t.length];
|
|
2923
|
+
return [t.length, ...tensorShape3(first)];
|
|
2924
|
+
}
|
|
2925
|
+
function rank(t) {
|
|
2926
|
+
return tensorShape3(t).length;
|
|
2927
|
+
}
|
|
2928
|
+
function sampleMean(vals) {
|
|
2929
|
+
return vals.reduce((s, v) => s + v, 0) / vals.length;
|
|
2930
|
+
}
|
|
2931
|
+
function sampleStd(vals, mean) {
|
|
2932
|
+
if (vals.length <= 1) return 0;
|
|
2933
|
+
const variance = vals.reduce((s, v) => s + (v - mean) ** 2, 0) / (vals.length - 1);
|
|
2934
|
+
return Math.sqrt(variance);
|
|
2935
|
+
}
|
|
2936
|
+
function normalizeZScore(t) {
|
|
2937
|
+
if (rank(t) <= 1) {
|
|
2938
|
+
const vals = t;
|
|
2939
|
+
const mean = sampleMean(vals);
|
|
2940
|
+
const std = Math.max(sampleStd(vals, mean), 1e-8);
|
|
2941
|
+
return vals.map((v) => (v - mean) / std);
|
|
2942
|
+
}
|
|
2943
|
+
const rows = t;
|
|
2944
|
+
const cols = rows[0].length;
|
|
2945
|
+
const means = [];
|
|
2946
|
+
const stds = [];
|
|
2947
|
+
for (let c = 0; c < cols; c++) {
|
|
2948
|
+
const col = rows.map((r) => r[c]);
|
|
2949
|
+
const m = sampleMean(col);
|
|
2950
|
+
means.push(m);
|
|
2951
|
+
stds.push(Math.max(sampleStd(col, m), 1e-8));
|
|
2952
|
+
}
|
|
2953
|
+
return rows.map((r) => r.map((v, c) => (v - means[c]) / stds[c]));
|
|
2954
|
+
}
|
|
2955
|
+
function normalizeMinMax(t) {
|
|
2956
|
+
if (rank(t) <= 1) {
|
|
2957
|
+
const vals = t;
|
|
2958
|
+
const mn = Math.min(...vals);
|
|
2959
|
+
const mx = Math.max(...vals);
|
|
2960
|
+
const denom = Math.max(mx - mn, 1e-8);
|
|
2961
|
+
return vals.map((v) => (v - mn) / denom);
|
|
2962
|
+
}
|
|
2963
|
+
const rows = t;
|
|
2964
|
+
const cols = rows[0].length;
|
|
2965
|
+
const mins = [];
|
|
2966
|
+
const maxs = [];
|
|
2967
|
+
for (let c = 0; c < cols; c++) {
|
|
2968
|
+
const col = rows.map((r) => r[c]);
|
|
2969
|
+
mins.push(Math.min(...col));
|
|
2970
|
+
maxs.push(Math.max(...col));
|
|
2971
|
+
}
|
|
2972
|
+
return rows.map((r) => r.map((v, c) => (v - mins[c]) / Math.max(maxs[c] - mins[c], 1e-8)));
|
|
2973
|
+
}
|
|
2974
|
+
function mapTensor(t, fn) {
|
|
2975
|
+
if (typeof t === "number") return fn(t);
|
|
2976
|
+
return t.map((sub) => mapTensor(sub, fn));
|
|
2977
|
+
}
|
|
2978
|
+
function padOrTruncateLastDim(t, targetLen, padValue) {
|
|
2979
|
+
if (typeof t === "number") return t;
|
|
2980
|
+
if (t.length === 0 || typeof t[0] === "number") {
|
|
2981
|
+
const row = t;
|
|
2982
|
+
if (row.length < targetLen) {
|
|
2983
|
+
return [...row, ...new Array(targetLen - row.length).fill(padValue)];
|
|
2984
|
+
}
|
|
2985
|
+
return row.slice(0, targetLen);
|
|
2986
|
+
}
|
|
2987
|
+
return t.map((sub) => padOrTruncateLastDim(sub, targetLen, padValue));
|
|
2988
|
+
}
|
|
2989
|
+
function evalDataDataset(args, evaluate2, ctx) {
|
|
2990
|
+
const data = evaluate2(args[0], ctx);
|
|
2991
|
+
const config = evaluate2(args[1], ctx);
|
|
2992
|
+
return { data: Array.isArray(data) ? data : [], config };
|
|
2993
|
+
}
|
|
2994
|
+
function evalDataDataloader(args, evaluate2, ctx) {
|
|
2995
|
+
const dataset = evaluate2(args[0], ctx);
|
|
2996
|
+
const config = evaluate2(args[1], ctx);
|
|
2997
|
+
const batchSize = config.batchSize ?? config.batch_size ?? 32;
|
|
2998
|
+
const shuffle = config.shuffle ?? true;
|
|
2999
|
+
const indices = Array.from({ length: dataset.data.length }, (_, i) => i);
|
|
3000
|
+
if (shuffle) shuffleInPlace(indices, ctx);
|
|
3001
|
+
const batches = [];
|
|
3002
|
+
for (let i = 0; i < indices.length; i += batchSize) {
|
|
3003
|
+
const chunk = indices.slice(i, i + batchSize);
|
|
3004
|
+
const x = [];
|
|
3005
|
+
const y = [];
|
|
3006
|
+
for (const idx of chunk) {
|
|
3007
|
+
const [xi, yi] = datasetGetItem(dataset, idx);
|
|
3008
|
+
x.push(xi);
|
|
3009
|
+
y.push(yi);
|
|
3010
|
+
}
|
|
3011
|
+
batches.push({ x, y });
|
|
3012
|
+
}
|
|
3013
|
+
return { batches, batchSize, numBatches: batches.length };
|
|
3014
|
+
}
|
|
3015
|
+
function evalDataSplit(args, evaluate2, ctx) {
|
|
3016
|
+
const dataset = evaluate2(args[0], ctx);
|
|
3017
|
+
const config = evaluate2(args[1], ctx);
|
|
3018
|
+
const ratio = config.trainRatio ?? config.train_ratio ?? 0.8;
|
|
3019
|
+
const trainSize = Math.trunc(dataset.data.length * ratio);
|
|
3020
|
+
const indices = Array.from({ length: dataset.data.length }, (_, i) => i);
|
|
3021
|
+
shuffleInPlace(indices, ctx);
|
|
3022
|
+
const trainIdx = indices.slice(0, trainSize);
|
|
3023
|
+
const testIdx = indices.slice(trainSize);
|
|
3024
|
+
return [
|
|
3025
|
+
{ data: trainIdx.map((i) => dataset.data[i]), config: dataset.config },
|
|
3026
|
+
{ data: testIdx.map((i) => dataset.data[i]), config: dataset.config }
|
|
3027
|
+
];
|
|
3028
|
+
}
|
|
3029
|
+
function evalDataNormalize(args, evaluate2, ctx) {
|
|
3030
|
+
const data = evaluate2(args[0], ctx);
|
|
3031
|
+
const config = evaluate2(args[1], ctx);
|
|
3032
|
+
const method = config.method ?? "zscore";
|
|
3033
|
+
if (method === "zscore") return normalizeZScore(data);
|
|
3034
|
+
if (method === "minmax") return normalizeMinMax(data);
|
|
3035
|
+
return data;
|
|
3036
|
+
}
|
|
3037
|
+
function evalDataAugment(args, evaluate2, ctx) {
|
|
3038
|
+
const data = evaluate2(args[0], ctx);
|
|
3039
|
+
const config = evaluate2(args[1], ctx);
|
|
3040
|
+
const noiseScale = config.noiseScale ?? config.noise_scale ?? 0.01;
|
|
3041
|
+
return mapTensor(data, (v) => v + seededGaussian(ctx) * noiseScale);
|
|
3042
|
+
}
|
|
3043
|
+
function evalDataTokenize(args, evaluate2, ctx) {
|
|
3044
|
+
const text = evaluate2(args[0], ctx);
|
|
3045
|
+
const config = evaluate2(args[1], ctx);
|
|
3046
|
+
const mode = config.mode ?? "char";
|
|
3047
|
+
const textStr = String(text);
|
|
3048
|
+
if (mode === "word") {
|
|
3049
|
+
const vocab = config.vocab ?? {};
|
|
3050
|
+
return textStr.split(/\s+/).filter((w) => w.length > 0).map((w) => vocab[w] ?? 0);
|
|
3051
|
+
}
|
|
3052
|
+
return Array.from(textStr).map((c) => c.codePointAt(0) ?? 0);
|
|
3053
|
+
}
|
|
3054
|
+
function evalDataPad(args, evaluate2, ctx) {
|
|
3055
|
+
const data = evaluate2(args[0], ctx);
|
|
3056
|
+
const config = evaluate2(args[1], ctx);
|
|
3057
|
+
const currentLen = (() => {
|
|
3058
|
+
const shape = tensorShape3(data);
|
|
3059
|
+
return shape.length === 0 ? 0 : shape[shape.length - 1];
|
|
3060
|
+
})();
|
|
3061
|
+
const targetLen = config.length ?? config.targetLength ?? currentLen;
|
|
3062
|
+
const padValue = config.padValue ?? config.pad_value ?? 0;
|
|
3063
|
+
return padOrTruncateLastDim(data, targetLen, padValue);
|
|
3064
|
+
}
|
|
3065
|
+
|
|
2541
3066
|
// std/llm.ts
|
|
2542
3067
|
function evalLlmGenerate(args, evaluate2, ctx) {
|
|
2543
3068
|
if (!ctx.llm) return null;
|
|
@@ -4255,6 +4780,10 @@ var SExpressionEvaluator = class {
|
|
|
4255
4780
|
return evalArrayTakeLast(args, evaluate2, ctx);
|
|
4256
4781
|
case "array/dropLast":
|
|
4257
4782
|
return evalArrayDropLast(args, evaluate2, ctx);
|
|
4783
|
+
case "array/cosine":
|
|
4784
|
+
return evalArrayCosine(args, evaluate2, ctx);
|
|
4785
|
+
case "array/nearest":
|
|
4786
|
+
return evalArrayNearest(args, evaluate2, ctx);
|
|
4258
4787
|
// ===============================
|
|
4259
4788
|
// Standard Library: object/*
|
|
4260
4789
|
// ===============================
|
|
@@ -4593,6 +5122,69 @@ var SExpressionEvaluator = class {
|
|
|
4593
5122
|
return evalIntegrationGithubGetRepo(args, evaluate2, ctx);
|
|
4594
5123
|
case "integration/github-create-issue":
|
|
4595
5124
|
return evalIntegrationGithubCreateIssue(args, evaluate2, ctx);
|
|
5125
|
+
// ===============================
|
|
5126
|
+
// Standard Library: contract/*
|
|
5127
|
+
// ===============================
|
|
5128
|
+
case "contract/validate-input":
|
|
5129
|
+
return evalContractValidateInput(args, evaluate2, ctx);
|
|
5130
|
+
case "contract/validate-output":
|
|
5131
|
+
return evalContractValidateOutput(args, evaluate2, ctx);
|
|
5132
|
+
case "contract/clamp-output":
|
|
5133
|
+
return evalContractClampOutput(args, evaluate2, ctx);
|
|
5134
|
+
case "contract/violations":
|
|
5135
|
+
return evalContractViolations(args, evaluate2, ctx);
|
|
5136
|
+
case "contract/entity-to-tensor":
|
|
5137
|
+
return evalContractEntityToTensor(args, evaluate2, ctx);
|
|
5138
|
+
case "contract/tensor-to-payload":
|
|
5139
|
+
return evalContractTensorToPayload(args, evaluate2, ctx);
|
|
5140
|
+
// ===============================
|
|
5141
|
+
// Standard Library: graph/*
|
|
5142
|
+
// ===============================
|
|
5143
|
+
case "graph/from-entities":
|
|
5144
|
+
return evalGraphFromEntities(args, evaluate2, ctx);
|
|
5145
|
+
case "graph/from-adjacency":
|
|
5146
|
+
return evalGraphFromAdjacency(args, evaluate2, ctx);
|
|
5147
|
+
case "graph/from-edge-list":
|
|
5148
|
+
return evalGraphFromEdgeList(args, evaluate2, ctx);
|
|
5149
|
+
case "graph/add-self-loops":
|
|
5150
|
+
return evalGraphAddSelfLoops(args, evaluate2, ctx);
|
|
5151
|
+
case "graph/to-undirected":
|
|
5152
|
+
return evalGraphToUndirected(args, evaluate2, ctx);
|
|
5153
|
+
case "graph/subgraph":
|
|
5154
|
+
return evalGraphSubgraph(args, evaluate2, ctx);
|
|
5155
|
+
case "graph/k-hop":
|
|
5156
|
+
return evalGraphKHop(args, evaluate2, ctx);
|
|
5157
|
+
case "graph/node-features":
|
|
5158
|
+
return evalGraphNodeFeatures(args, evaluate2, ctx);
|
|
5159
|
+
case "graph/edge-index":
|
|
5160
|
+
return evalGraphEdgeIndex(args, evaluate2, ctx);
|
|
5161
|
+
case "graph/edge-features":
|
|
5162
|
+
return evalGraphEdgeFeatures(args, evaluate2, ctx);
|
|
5163
|
+
case "graph/num-nodes":
|
|
5164
|
+
return evalGraphNumNodes(args, evaluate2, ctx);
|
|
5165
|
+
case "graph/num-edges":
|
|
5166
|
+
return evalGraphNumEdges(args, evaluate2, ctx);
|
|
5167
|
+
case "graph/degree":
|
|
5168
|
+
return evalGraphDegree(args, evaluate2, ctx);
|
|
5169
|
+
case "graph/batch":
|
|
5170
|
+
return evalGraphBatch(args, evaluate2, ctx);
|
|
5171
|
+
// ===============================
|
|
5172
|
+
// Standard Library: data/*
|
|
5173
|
+
// ===============================
|
|
5174
|
+
case "data/dataset":
|
|
5175
|
+
return evalDataDataset(args, evaluate2, ctx);
|
|
5176
|
+
case "data/dataloader":
|
|
5177
|
+
return evalDataDataloader(args, evaluate2, ctx);
|
|
5178
|
+
case "data/split":
|
|
5179
|
+
return evalDataSplit(args, evaluate2, ctx);
|
|
5180
|
+
case "data/normalize":
|
|
5181
|
+
return evalDataNormalize(args, evaluate2, ctx);
|
|
5182
|
+
case "data/augment":
|
|
5183
|
+
return evalDataAugment(args, evaluate2, ctx);
|
|
5184
|
+
case "data/tokenize":
|
|
5185
|
+
return evalDataTokenize(args, evaluate2, ctx);
|
|
5186
|
+
case "data/pad":
|
|
5187
|
+
return evalDataPad(args, evaluate2, ctx);
|
|
4596
5188
|
default:
|
|
4597
5189
|
return UNKNOWN_OPERATOR;
|
|
4598
5190
|
}
|
|
@@ -4612,6 +5204,9 @@ function executeEffects(effects, ctx) {
|
|
|
4612
5204
|
evaluator.executeEffects(effects, ctx);
|
|
4613
5205
|
}
|
|
4614
5206
|
|
|
4615
|
-
|
|
5207
|
+
// listen-payload.ts
|
|
5208
|
+
var evaluateListenPayloadExpr = (expr, payload) => evaluate(expr, createMinimalContext({}, payload));
|
|
5209
|
+
|
|
5210
|
+
export { SExpressionEvaluator, createChildContext, createEffectContext, createMinimalContext, evalAbs, evalAdd, evalAnd, evalAtomic, evalCallService, evalCeil, evalClamp, evalConcat, evalCount, evalDecrement, evalDeref, evalDespawn, evalDivide, evalDo, evalEmit, evalEmpty, evalEqual, evalFilter, evalFind, evalFirst, evalFloor, evalFn, evalGreaterThan, evalGreaterThanOrEqual, evalIf, evalIncludes, evalIncrement, evalLast, evalLessThan, evalLessThanOrEqual, evalLet, evalList, evalMap, evalMatches, evalMax, evalMin, evalModulo, evalMultiply, evalNavigate, evalNot, evalNotEqual, evalNotify, evalNth, evalOr, evalPersist, evalRef, evalRenderUI, evalRound, evalSet, evalSetDynamic, evalSpawn, evalSubtract, evalSum, evalSwap, evalWatch, evalWhen, evaluate, evaluateGuard, evaluateListenPayloadExpr, evaluator, executeEffect, executeEffects, resolveBinding };
|
|
4616
5211
|
//# sourceMappingURL=index.js.map
|
|
4617
5212
|
//# sourceMappingURL=index.js.map
|