@terminals-tech/sdk 1.0.0 → 2.0.0-rc.1
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 +58 -12
- package/dist/{WebContainerManager-4LIOGRVM.js → WebContainerManager-NUGGUIWB.js} +2 -2
- package/dist/catalog-XA5VYWXG.js +16 -0
- package/dist/{chunk-PWAHFID5.js → chunk-D4MOOUDY.js} +3 -3
- package/dist/{chunk-FOXUEYWK.js → chunk-GOQHOLBG.js} +4 -3
- package/dist/{chunk-STMI72WH.js → chunk-ICFYWOI5.js} +35 -38
- package/dist/chunk-PKINKOW2.js +335 -0
- package/dist/chunk-PWEICJ47.js +30 -0
- package/dist/{chunk-KASHT6C5.js → chunk-Q4W3IUTD.js} +8 -8
- package/dist/{chunk-BCOQMFKT.js → chunk-TO7ETE5K.js} +2 -2
- package/dist/{chunk-Q2VI6ICE.js → chunk-UB5OINTA.js} +1 -1
- package/dist/{chunk-PPFTKJDB.js → chunk-WJCIX7RO.js} +3 -3
- package/dist/{chunk-OCLSAUCD.js → chunk-WT6L6DK3.js} +30 -2
- package/dist/{chunk-L45BSQDJ.js → chunk-Y5WLSLLW.js} +1 -1
- package/dist/{container-lite-QD3CRLS4.js → container-lite-Q3O3EP6R.js} +9 -9
- package/dist/core.machine.orchestrator-NW73YDTL.js +24 -0
- package/dist/{demo-T655Z5S4.js → demo-WARANXBT.js} +11 -11
- package/dist/{hvm-CBEP3M4F.js → hvm-A7DGZ3Q5.js} +1 -1
- package/dist/index.cjs +61426 -43456
- package/dist/index.d.cts +331 -140
- package/dist/index.d.ts +331 -140
- package/dist/index.js +253 -328
- package/dist/{neuro-state-XHRGIRVO.js → neuro-state-KINIFV2D.js} +6 -6
- package/dist/{nodes-K6GKI2FM.js → nodes-TWQZUZRM.js} +10 -10
- package/dist/{registry-5WTDYQVQ.js → registry-UARRB6CF.js} +9 -9
- package/dist/{scheduler-B5CEYKWT.js → scheduler-SAQJLKXJ.js} +16 -14
- package/dist/sematon-2EUEZESN.js +19 -0
- package/dist/{server-VW6DYDLH.js → server-JXM4Y2T6.js} +1 -1
- package/dist/{skills-VN7IN7SJ.js → skills-XOFGMUP4.js} +2 -2
- package/dist/{stack-4KWCQQP7.js → stack-4QQCK7MG.js} +17 -15
- package/dist/{supabaseService-6AYP2VY3.js → supabaseService-O4ZFFLZP.js} +2 -2
- package/dist/{webcontainer-XWCE56F3.js → webcontainer-PMWNRO4I.js} +2 -2
- package/package.json +3 -3
- package/dist/{chunk-LLGZTP3G.js → chunk-P4D4RNAV.js} +4 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @terminals-tech/sdk
|
|
2
2
|
|
|
3
|
-
Terminals OS SDK —
|
|
3
|
+
Terminals OS SDK — observable, coherence-aware primitives for building intelligent software. Available as TypeScript (`@terminals-tech/sdk`) and Rust (`terminals-core`).
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -8,6 +8,13 @@ Terminals OS SDK — publish-safe facades and primitives for building observable
|
|
|
8
8
|
npm install @terminals-tech/sdk
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
## Install (Rust)
|
|
12
|
+
|
|
13
|
+
```toml
|
|
14
|
+
[dependencies]
|
|
15
|
+
terminals-core = "0.1"
|
|
16
|
+
```
|
|
17
|
+
|
|
11
18
|
## Quickstart
|
|
12
19
|
|
|
13
20
|
```typescript
|
|
@@ -32,21 +39,42 @@ const metrics = Brain.calculateCoherence({
|
|
|
32
39
|
console.log("Coherence:", metrics.overall);
|
|
33
40
|
```
|
|
34
41
|
|
|
42
|
+
## Quickstart (Rust)
|
|
43
|
+
|
|
44
|
+
```rust
|
|
45
|
+
use terminals_core::phase::{kuramoto_step, order_parameter, phase_locking_value, Omega};
|
|
46
|
+
use terminals_core::substrate::{Sematon, witness::ConvergenceWitness, graph::PadicAddr};
|
|
47
|
+
|
|
48
|
+
// 1. Phase dynamics — same math as Brain.kuramotoStep in TypeScript
|
|
49
|
+
let phases = vec![0.0, 1.2, 2.6, 4.1];
|
|
50
|
+
let next = kuramoto_step(&phases, &Omega::Uniform(0.0), 0.8, None, 0.1, true);
|
|
51
|
+
let op = order_parameter(&next);
|
|
52
|
+
println!("Kuramoto R = {:.3}, psi = {:.3}", op.r, op.psi);
|
|
53
|
+
|
|
54
|
+
// 2. Sematon — same concept as L0.createSematon in TypeScript
|
|
55
|
+
let witness = ConvergenceWitness { r: 0.95, entropy: 0.3, converged: true, step: 10 };
|
|
56
|
+
let sem = Sematon::new(vec![1.0f32, 2.0, 3.0], witness, PadicAddr::default(), "demo");
|
|
57
|
+
println!("Constructive: {}", sem.constructive);
|
|
58
|
+
```
|
|
59
|
+
|
|
35
60
|
## Architecture
|
|
36
61
|
|
|
37
62
|
The published package exposes a curated surface oriented around stable facades and runtime-safe primitives:
|
|
38
63
|
|
|
39
|
-
| Surface
|
|
40
|
-
|
|
|
41
|
-
| Foundation
|
|
42
|
-
|
|
|
43
|
-
| Core
|
|
44
|
-
|
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
48
|
-
|
|
|
49
|
-
|
|
|
64
|
+
| Surface | Namespace / Export | Coverage | Rust crate |
|
|
65
|
+
| --------------------- | ------------------ | ------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
|
|
66
|
+
| Foundation | `L0` | Core engine math, Sematons, and Deterministic Constructor traces | `terminals_core::substrate` (Sematon, fold/unfold) |
|
|
67
|
+
| Brain | `Brain` | coherence metrics and phase primitives (`Brain.calculateCoherence`, etc.) | `terminals_core::phase` (kuramoto, PLV, order parameter) |
|
|
68
|
+
| Core | `Core` | result types, validation, DAG, registry, retry/event primitives | `terminals_core::primitives` (Result, DAG, Registry, Validated) |
|
|
69
|
+
| Wire (Rust-only) | — | — | `terminals_core::wire` (AXON binary protocol) |
|
|
70
|
+
| Audio (Rust-only) | — | — | `terminals_core::audio` (spectral entropy, band analysis) |
|
|
71
|
+
| Substrate (Rust-only) | — | — | `terminals_core::substrate` (ComputeAtom, ProjectionLayout, SubstrateEngine) |
|
|
72
|
+
| Terminal | `Terminal` | interaction lifecycle, surface identity, platform types | — |
|
|
73
|
+
| Mesh | `Mesh` | signals, action bus, delegation helpers | — |
|
|
74
|
+
| Protocol | `Protocol` | delegation helpers and the AXON protocol bridge | — |
|
|
75
|
+
| Skill | `Skill` | skill manifest types, registry access, signal codes | — |
|
|
76
|
+
| Manifold | `Manifold` | annihilation pipeline helpers and ordinal execution surfaces | — |
|
|
77
|
+
| Observer | `Observer` | observer kernel primitives and witness-oriented runtime inspection | — |
|
|
50
78
|
|
|
51
79
|
## ELI5: The L0 Foundation (Sematons & Constructors)
|
|
52
80
|
|
|
@@ -77,6 +105,23 @@ await bus.publishSDK({
|
|
|
77
105
|
console.log({ Core, Mesh, Protocol });
|
|
78
106
|
```
|
|
79
107
|
|
|
108
|
+
## TypeScript / Rust Parity
|
|
109
|
+
|
|
110
|
+
The same core math runs in both runtimes. Phase dynamics, sematonic types, DAG, registry, and validation exist in both `@terminals-tech/sdk` (TypeScript) and `terminals-core` (Rust/WASM). Higher-level orchestration (Mesh signals, Protocol delegation, Observer kernel) is TypeScript-only. Low-level substrate and wire protocol are Rust-only.
|
|
111
|
+
|
|
112
|
+
| Domain | TypeScript | Rust | Status |
|
|
113
|
+
| -------------------- | -------------------------- | ---------------------------------------- | --------- |
|
|
114
|
+
| Phase dynamics | `Brain.*` | `terminals_core::phase` | Both |
|
|
115
|
+
| Sematon / L0 | `L0.createSematon` | `terminals_core::substrate::Sematon` | Both |
|
|
116
|
+
| DAG | `Core.createDAG` | `terminals_core::primitives::dag` | Both |
|
|
117
|
+
| Validation (proof) | `Core.validated` | `terminals_core::primitives::validation` | Both |
|
|
118
|
+
| Coherence scoring | `Brain.calculateCoherence` | — | TS only |
|
|
119
|
+
| Mesh signals | `Mesh.*` | — | TS only |
|
|
120
|
+
| Protocol/AXON bridge | `Protocol.*` | — | TS only |
|
|
121
|
+
| AXON wire format | — | `terminals_core::wire` | Rust only |
|
|
122
|
+
| Substrate engine | — | `terminals_core::substrate` | Rust only |
|
|
123
|
+
| Audio analysis | — | `terminals_core::audio` | Rust only |
|
|
124
|
+
|
|
80
125
|
## Local verification
|
|
81
126
|
|
|
82
127
|
From the monorepo root:
|
|
@@ -99,6 +144,7 @@ npm run -w @terminals-tech/sdk pack:dry-run
|
|
|
99
144
|
2. Run `npm run sdk:publish:check`
|
|
100
145
|
3. Inspect the dry-run tarball summary
|
|
101
146
|
4. Publish when ready with `npm publish --workspace @terminals-tech/sdk`
|
|
147
|
+
5. For `terminals-core`: `cargo publish --manifest-path crates/terminals-core/Cargo.toml`
|
|
102
148
|
|
|
103
149
|
## License
|
|
104
150
|
|
|
@@ -2,15 +2,15 @@ import {
|
|
|
2
2
|
ProcessPriority,
|
|
3
3
|
WebContainerManager,
|
|
4
4
|
WebContainerManager_default
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-P4D4RNAV.js";
|
|
6
6
|
import "./chunk-DKFJIILR.js";
|
|
7
7
|
import "./chunk-KHR7ZYCX.js";
|
|
8
|
+
import "./chunk-WGBCRNMB.js";
|
|
8
9
|
import "./chunk-QWZRZKLZ.js";
|
|
9
10
|
import "./chunk-OSSRZOGC.js";
|
|
10
11
|
import "./chunk-TSQ3BGLA.js";
|
|
11
12
|
import "./chunk-2WTYE4SW.js";
|
|
12
13
|
import "./chunk-QJFKEQHF.js";
|
|
13
|
-
import "./chunk-WGBCRNMB.js";
|
|
14
14
|
import "./chunk-3LFMIVJM.js";
|
|
15
15
|
import "./chunk-AFDUOYHD.js";
|
|
16
16
|
import "./chunk-NTMBOESX.js";
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
getCatalog,
|
|
3
|
+
listNodes,
|
|
4
|
+
registerManifestProvider,
|
|
5
|
+
registerNode,
|
|
6
|
+
resolveNode
|
|
7
|
+
} from "./chunk-WT6L6DK3.js";
|
|
8
|
+
import "./chunk-XPJ63Y6T.js";
|
|
9
|
+
import "./chunk-2ESYSVXG.js";
|
|
10
|
+
export {
|
|
11
|
+
getCatalog,
|
|
12
|
+
listNodes,
|
|
13
|
+
registerManifestProvider,
|
|
14
|
+
registerNode,
|
|
15
|
+
resolveNode
|
|
16
|
+
};
|
|
@@ -6,10 +6,10 @@ import {
|
|
|
6
6
|
createInteractionWithEvents,
|
|
7
7
|
sanitizeTraceSegment,
|
|
8
8
|
transitionStatusWithEvent
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-TO7ETE5K.js";
|
|
10
10
|
import {
|
|
11
11
|
secureValidate
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-GOQHOLBG.js";
|
|
13
13
|
import {
|
|
14
14
|
DEFAULT_EMBEDDING_DIM
|
|
15
15
|
} from "./chunk-ZVO47SQV.js";
|
|
@@ -175,7 +175,7 @@ async function emitInteractionEvent(interactionId, type, payload, metadata) {
|
|
|
175
175
|
const userId = enrichedMeta.userId ?? enrichedMeta.user_id;
|
|
176
176
|
if (userId && typeof window !== "undefined") {
|
|
177
177
|
try {
|
|
178
|
-
const { appendSupabaseMeshEvent } = await import("./supabaseService-
|
|
178
|
+
const { appendSupabaseMeshEvent } = await import("./supabaseService-O4ZFFLZP.js");
|
|
179
179
|
await appendSupabaseMeshEvent({
|
|
180
180
|
user_id: userId,
|
|
181
181
|
interaction_id: interactionId,
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
+
import {
|
|
2
|
+
require_ajv
|
|
3
|
+
} from "./chunk-QJFKEQHF.js";
|
|
1
4
|
import {
|
|
2
5
|
untrusted,
|
|
3
6
|
validate
|
|
4
7
|
} from "./chunk-EXI3LJVJ.js";
|
|
5
|
-
import {
|
|
6
|
-
require_ajv
|
|
7
|
-
} from "./chunk-QJFKEQHF.js";
|
|
8
8
|
import {
|
|
9
9
|
__toESM
|
|
10
10
|
} from "./chunk-2ESYSVXG.js";
|
|
@@ -37,6 +37,7 @@ function secureValidate(data, schema) {
|
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
export {
|
|
40
|
+
getValidator,
|
|
40
41
|
validateWithSchema,
|
|
41
42
|
secureValidate
|
|
42
43
|
};
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
+
import {
|
|
2
|
+
onMeshFeedback,
|
|
3
|
+
orchestratorToMesh
|
|
4
|
+
} from "./chunk-UB5OINTA.js";
|
|
1
5
|
import {
|
|
2
6
|
getGlobalStore
|
|
3
7
|
} from "./chunk-VZA2NUH3.js";
|
|
4
8
|
import {
|
|
5
9
|
resolveSecretValue
|
|
6
10
|
} from "./chunk-QWXPVB2L.js";
|
|
7
|
-
import {
|
|
8
|
-
onMeshFeedback,
|
|
9
|
-
orchestratorToMesh
|
|
10
|
-
} from "./chunk-Q2VI6ICE.js";
|
|
11
|
-
import {
|
|
12
|
-
registerManifestProvider
|
|
13
|
-
} from "./chunk-OCLSAUCD.js";
|
|
14
11
|
import {
|
|
15
12
|
safeDbOperation
|
|
16
13
|
} from "./chunk-WGBCRNMB.js";
|
|
14
|
+
import {
|
|
15
|
+
getValidator
|
|
16
|
+
} from "./chunk-GOQHOLBG.js";
|
|
17
17
|
import {
|
|
18
18
|
getDB,
|
|
19
19
|
isDatabaseReady,
|
|
@@ -30,29 +30,6 @@ function buildScheduleTriggerContext(config, scheduleId) {
|
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
// ../../lib/terminals-tech/machines/core/stacksStore.ts
|
|
34
|
-
var globalStore = globalThis;
|
|
35
|
-
var memStacks = globalStore.__memStacks || /* @__PURE__ */ new Map();
|
|
36
|
-
globalStore.__memStacks = memStacks;
|
|
37
|
-
var pendingDeletes = globalStore.__pendingStackDeletes || /* @__PURE__ */ new Set();
|
|
38
|
-
globalStore.__pendingStackDeletes = pendingDeletes;
|
|
39
|
-
registerManifestProvider("stacksStore", loadStack);
|
|
40
|
-
async function loadStack(id) {
|
|
41
|
-
const { getDB: getDB2, safeDbOperation: safeDbOperation2 } = await import("./pgliteService-IUGNNOVU.js");
|
|
42
|
-
const dbResult = await safeDbOperation2(async () => {
|
|
43
|
-
const db = await getDB2();
|
|
44
|
-
await db.query(`ALTER TABLE stacks ADD COLUMN IF NOT EXISTS deleted_at TIMESTAMP`);
|
|
45
|
-
const r = await db.query(
|
|
46
|
-
`SELECT manifest FROM stacks WHERE id = $1 AND deleted_at IS NULL`,
|
|
47
|
-
[id]
|
|
48
|
-
);
|
|
49
|
-
if (!r.rows[0]) return null;
|
|
50
|
-
return r.rows[0].manifest;
|
|
51
|
-
}, null);
|
|
52
|
-
if (dbResult) return dbResult;
|
|
53
|
-
return memStacks.get(id)?.manifest || null;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
33
|
// ../../lib/terminals-tech/machines/core/manifests.ts
|
|
57
34
|
function isNodeManifest(manifest) {
|
|
58
35
|
return "kind" in manifest && "entrypoints" in manifest;
|
|
@@ -567,7 +544,7 @@ var OrchestratorV0 = class {
|
|
|
567
544
|
return true;
|
|
568
545
|
}
|
|
569
546
|
try {
|
|
570
|
-
const { neuroState } = await import("./neuro-state-
|
|
547
|
+
const { neuroState } = await import("./neuro-state-KINIFV2D.js");
|
|
571
548
|
const currentState = await new Promise((resolve) => {
|
|
572
549
|
let resolved = false;
|
|
573
550
|
let subscription = null;
|
|
@@ -690,8 +667,8 @@ var OrchestratorV0 = class {
|
|
|
690
667
|
};
|
|
691
668
|
let shapeHash;
|
|
692
669
|
try {
|
|
693
|
-
const { computeShapeHash
|
|
694
|
-
shapeHash = await
|
|
670
|
+
const { computeShapeHash } = await import("./topology-CIWWNVAN.js");
|
|
671
|
+
shapeHash = await computeShapeHash(stack);
|
|
695
672
|
} catch (err) {
|
|
696
673
|
console.error("[OrchestratorV0] Failed to compute shape hash:", err);
|
|
697
674
|
}
|
|
@@ -705,6 +682,27 @@ var OrchestratorV0 = class {
|
|
|
705
682
|
...baseInput,
|
|
706
683
|
...opts.configOverrides?.[node.id] || {}
|
|
707
684
|
};
|
|
685
|
+
if (isNodeManifest(manifest) && manifest.inputsSchema && opts.configOverrides?.[node.id]) {
|
|
686
|
+
try {
|
|
687
|
+
const validator = getValidator(manifest.inputsSchema);
|
|
688
|
+
const publicInput = {};
|
|
689
|
+
for (const [k, v] of Object.entries(input)) {
|
|
690
|
+
if (!k.startsWith("__")) publicInput[k] = v;
|
|
691
|
+
}
|
|
692
|
+
const isValid = validator(publicInput);
|
|
693
|
+
if (!isValid) {
|
|
694
|
+
console.warn(
|
|
695
|
+
`[OrchestratorV0] configOverrides for node "${node.id}" produced input that does not match inputsSchema:`,
|
|
696
|
+
validator.errors
|
|
697
|
+
);
|
|
698
|
+
}
|
|
699
|
+
} catch (schemaErr) {
|
|
700
|
+
console.warn(
|
|
701
|
+
`[OrchestratorV0] Failed to validate configOverrides for node "${node.id}":`,
|
|
702
|
+
schemaErr
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
}
|
|
708
706
|
if (opts.triggerContext) {
|
|
709
707
|
input.__triggerContext = opts.triggerContext;
|
|
710
708
|
}
|
|
@@ -922,10 +920,10 @@ var OrchestratorV0 = class {
|
|
|
922
920
|
void stackId;
|
|
923
921
|
void node;
|
|
924
922
|
if (typeof window === "undefined") {
|
|
925
|
-
const { ensureServerRunnersRegistered } = await import("./server-
|
|
923
|
+
const { ensureServerRunnersRegistered } = await import("./server-JXM4Y2T6.js");
|
|
926
924
|
await ensureServerRunnersRegistered();
|
|
927
925
|
}
|
|
928
|
-
const { runners } = await import("./registry-
|
|
926
|
+
const { runners } = await import("./registry-UARRB6CF.js");
|
|
929
927
|
const tierRunner = runners.getRunner(tier);
|
|
930
928
|
if (tierRunner) {
|
|
931
929
|
return await tierRunner(manifest, input, {
|
|
@@ -971,7 +969,7 @@ var OrchestratorV0 = class {
|
|
|
971
969
|
return { ...input };
|
|
972
970
|
}
|
|
973
971
|
if (tier === "webcontainer") {
|
|
974
|
-
const { runInWebContainer } = await import("./webcontainer-
|
|
972
|
+
const { runInWebContainer } = await import("./webcontainer-PMWNRO4I.js");
|
|
975
973
|
return await runInWebContainer(manifest, input, {
|
|
976
974
|
stackId,
|
|
977
975
|
nodeId: node.id,
|
|
@@ -979,7 +977,7 @@ var OrchestratorV0 = class {
|
|
|
979
977
|
});
|
|
980
978
|
}
|
|
981
979
|
if (tier === "wasm-hvm") {
|
|
982
|
-
const { runInHVM } = await import("./hvm-
|
|
980
|
+
const { runInHVM } = await import("./hvm-A7DGZ3Q5.js");
|
|
983
981
|
return await runInHVM(manifest, input, {
|
|
984
982
|
stackId,
|
|
985
983
|
nodeId: node.id,
|
|
@@ -1000,6 +998,5 @@ var OrchestratorV0 = class {
|
|
|
1000
998
|
|
|
1001
999
|
export {
|
|
1002
1000
|
buildScheduleTriggerContext,
|
|
1003
|
-
loadStack,
|
|
1004
1001
|
OrchestratorV0
|
|
1005
1002
|
};
|
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
// ../../lib/terminals-tech/core/L0/information.ts
|
|
2
|
+
function entropy(probabilities) {
|
|
3
|
+
if (probabilities.length === 0) return 0;
|
|
4
|
+
const sum = probabilities.reduce((a, b) => a + b, 0);
|
|
5
|
+
const normalized = sum === 0 ? probabilities : probabilities.map((p) => p / sum);
|
|
6
|
+
return normalized.reduce((h, p) => {
|
|
7
|
+
if (p <= 0) return h;
|
|
8
|
+
return h - p * Math.log2(p);
|
|
9
|
+
}, 0);
|
|
10
|
+
}
|
|
11
|
+
function jointEntropy(jointProbabilities) {
|
|
12
|
+
const flat = jointProbabilities.flat();
|
|
13
|
+
return entropy(flat);
|
|
14
|
+
}
|
|
15
|
+
function conditionalEntropy(jointProbabilities) {
|
|
16
|
+
const hXY = jointEntropy(jointProbabilities);
|
|
17
|
+
const pX = jointProbabilities.map((row) => row.reduce((a, b) => a + b, 0));
|
|
18
|
+
const hX = entropy(pX);
|
|
19
|
+
return hXY - hX;
|
|
20
|
+
}
|
|
21
|
+
function mutualInformation(pX, pY, pXY) {
|
|
22
|
+
const hX = entropy(pX);
|
|
23
|
+
const hY = entropy(pY);
|
|
24
|
+
const hXY = jointEntropy(pXY);
|
|
25
|
+
return Math.max(0, hX + hY - hXY);
|
|
26
|
+
}
|
|
27
|
+
function measurePreservation(source, transformed, roundTrip) {
|
|
28
|
+
if (source.length === 0) {
|
|
29
|
+
return {
|
|
30
|
+
retention: 1,
|
|
31
|
+
sourceEntropy: 0,
|
|
32
|
+
targetEntropy: 0,
|
|
33
|
+
mutualInfo: 0,
|
|
34
|
+
lossless: true
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
const sourceFreq = countFrequencies(source.map(String));
|
|
38
|
+
const transformedFreq = countFrequencies(transformed.map(String));
|
|
39
|
+
const n = source.length;
|
|
40
|
+
const sourceProbabilities = Object.values(sourceFreq).map((c) => c / n);
|
|
41
|
+
const transformedProbabilities = Object.values(transformedFreq).map((c) => c / n);
|
|
42
|
+
const sourceEntropy = entropy(sourceProbabilities);
|
|
43
|
+
const targetEntropy = entropy(transformedProbabilities);
|
|
44
|
+
let retention = 1;
|
|
45
|
+
let lossless = true;
|
|
46
|
+
if (roundTrip) {
|
|
47
|
+
const matches = source.filter((s, i) => String(s) === String(roundTrip[i])).length;
|
|
48
|
+
retention = matches / source.length;
|
|
49
|
+
lossless = matches === source.length;
|
|
50
|
+
} else {
|
|
51
|
+
const sourceCardinality = Object.keys(sourceFreq).length;
|
|
52
|
+
const targetCardinality = Object.keys(transformedFreq).length;
|
|
53
|
+
retention = Math.min(1, targetCardinality / sourceCardinality);
|
|
54
|
+
lossless = targetCardinality >= sourceCardinality;
|
|
55
|
+
}
|
|
56
|
+
const minEntropy = Math.min(sourceEntropy, targetEntropy);
|
|
57
|
+
const mutualInfo = retention * minEntropy;
|
|
58
|
+
return {
|
|
59
|
+
retention,
|
|
60
|
+
sourceEntropy,
|
|
61
|
+
targetEntropy,
|
|
62
|
+
mutualInfo,
|
|
63
|
+
lossless
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function calculateSemanticDensity(tokens, baselineTokensPerBit = 2) {
|
|
67
|
+
if (tokens.length === 0) {
|
|
68
|
+
return {
|
|
69
|
+
tokenCount: 0,
|
|
70
|
+
informationBits: 0,
|
|
71
|
+
density: 0,
|
|
72
|
+
compressionRatio: 1
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const freq = countFrequencies(tokens);
|
|
76
|
+
const probabilities = Object.values(freq).map((c) => c / tokens.length);
|
|
77
|
+
const informationBits = entropy(probabilities) * tokens.length;
|
|
78
|
+
const density = tokens.length > 0 ? informationBits / tokens.length : 0;
|
|
79
|
+
const baselineBits = tokens.length / baselineTokensPerBit;
|
|
80
|
+
const compressionRatio = baselineBits > 0 ? informationBits / baselineBits : 1;
|
|
81
|
+
return {
|
|
82
|
+
tokenCount: tokens.length,
|
|
83
|
+
informationBits,
|
|
84
|
+
density,
|
|
85
|
+
compressionRatio
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function estimateComplexity(data) {
|
|
89
|
+
if (data.length === 0) return 0;
|
|
90
|
+
const seen = /* @__PURE__ */ new Set();
|
|
91
|
+
let uniqueSubstrings = 0;
|
|
92
|
+
const windowSize = 8;
|
|
93
|
+
for (let i = 0; i <= data.length - windowSize; i++) {
|
|
94
|
+
const substr = data.slice(i, i + windowSize);
|
|
95
|
+
if (!seen.has(substr)) {
|
|
96
|
+
seen.add(substr);
|
|
97
|
+
uniqueSubstrings++;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
const totalPatterns = Math.max(1, data.length - windowSize + 1);
|
|
101
|
+
return uniqueSubstrings / totalPatterns;
|
|
102
|
+
}
|
|
103
|
+
function klDivergence(p, q) {
|
|
104
|
+
if (p.length !== q.length) {
|
|
105
|
+
throw new Error("Distributions must have same length");
|
|
106
|
+
}
|
|
107
|
+
let divergence = 0;
|
|
108
|
+
for (let i = 0; i < p.length; i++) {
|
|
109
|
+
if (p[i] > 0 && q[i] > 0) {
|
|
110
|
+
divergence += p[i] * Math.log2(p[i] / q[i]);
|
|
111
|
+
} else if (p[i] > 0 && q[i] === 0) {
|
|
112
|
+
return Infinity;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return divergence;
|
|
116
|
+
}
|
|
117
|
+
function jsDivergence(p, q) {
|
|
118
|
+
if (p.length !== q.length) {
|
|
119
|
+
throw new Error("Distributions must have same length");
|
|
120
|
+
}
|
|
121
|
+
const m = p.map((pi, i) => 0.5 * (pi + q[i]));
|
|
122
|
+
let jsd = 0;
|
|
123
|
+
for (let i = 0; i < p.length; i++) {
|
|
124
|
+
if (p[i] > 0 && m[i] > 0) {
|
|
125
|
+
jsd += 0.5 * p[i] * Math.log2(p[i] / m[i]);
|
|
126
|
+
}
|
|
127
|
+
if (q[i] > 0 && m[i] > 0) {
|
|
128
|
+
jsd += 0.5 * q[i] * Math.log2(q[i] / m[i]);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
return jsd;
|
|
132
|
+
}
|
|
133
|
+
function countFrequencies(values) {
|
|
134
|
+
const freq = {};
|
|
135
|
+
for (const v of values) {
|
|
136
|
+
const key = String(v);
|
|
137
|
+
freq[key] = (freq[key] || 0) + 1;
|
|
138
|
+
}
|
|
139
|
+
return freq;
|
|
140
|
+
}
|
|
141
|
+
function normalize(values) {
|
|
142
|
+
const sum = values.reduce((a, b) => a + b, 0);
|
|
143
|
+
if (sum === 0) return values.map(() => 1 / values.length);
|
|
144
|
+
return values.map((v) => v / sum);
|
|
145
|
+
}
|
|
146
|
+
function cosineSimilarity(a, b) {
|
|
147
|
+
if (a.length !== b.length || a.length === 0) return 0;
|
|
148
|
+
let dot = 0;
|
|
149
|
+
let normA = 0;
|
|
150
|
+
let normB = 0;
|
|
151
|
+
for (let i = 0; i < a.length; i++) {
|
|
152
|
+
dot += a[i] * b[i];
|
|
153
|
+
normA += a[i] * a[i];
|
|
154
|
+
normB += b[i] * b[i];
|
|
155
|
+
}
|
|
156
|
+
const denominator = Math.sqrt(normA) * Math.sqrt(normB);
|
|
157
|
+
return denominator === 0 ? 0 : dot / denominator;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// ../../lib/terminals-tech/core/L0/sematon.ts
|
|
161
|
+
var sematonCounter = 0;
|
|
162
|
+
function fnv1a(input) {
|
|
163
|
+
let hash = 2166136261;
|
|
164
|
+
for (let i = 0; i < input.length; i++) {
|
|
165
|
+
hash ^= input.charCodeAt(i);
|
|
166
|
+
hash = Math.imul(hash, 16777619);
|
|
167
|
+
}
|
|
168
|
+
return (hash >>> 0).toString(16).padStart(8, "0");
|
|
169
|
+
}
|
|
170
|
+
function computePayloadEntropy(payload) {
|
|
171
|
+
const json = JSON.stringify(payload);
|
|
172
|
+
if (!json || json.length === 0) return 0;
|
|
173
|
+
const freq = {};
|
|
174
|
+
for (let i = 0; i < json.length; i++) {
|
|
175
|
+
const ch = json[i];
|
|
176
|
+
freq[ch] = (freq[ch] || 0) + 1;
|
|
177
|
+
}
|
|
178
|
+
const probabilities = Object.values(freq).map((c) => c / json.length);
|
|
179
|
+
return entropy(probabilities);
|
|
180
|
+
}
|
|
181
|
+
function computeDensity(payload, entropyBits) {
|
|
182
|
+
const json = JSON.stringify(payload);
|
|
183
|
+
const tokenCount = json ? json.split(/\s+|[,{}[\]":]+/).filter(Boolean).length : 0;
|
|
184
|
+
return tokenCount > 0 ? entropyBits / tokenCount : 0;
|
|
185
|
+
}
|
|
186
|
+
function generatePadicAddress(kind, counter) {
|
|
187
|
+
const kindIndex = [
|
|
188
|
+
"signal",
|
|
189
|
+
"context",
|
|
190
|
+
"fractal",
|
|
191
|
+
"witness",
|
|
192
|
+
"combinator",
|
|
193
|
+
"interaction",
|
|
194
|
+
"custom"
|
|
195
|
+
].indexOf(kind);
|
|
196
|
+
return `${kindIndex}.0.${counter}`;
|
|
197
|
+
}
|
|
198
|
+
function createSematon(config) {
|
|
199
|
+
const counter = ++sematonCounter;
|
|
200
|
+
const id = `sem_${config.kind}_${counter}_${Date.now().toString(36)}`;
|
|
201
|
+
const payloadEntropy = computePayloadEntropy(config.payload);
|
|
202
|
+
const density = computeDensity(config.payload, payloadEntropy);
|
|
203
|
+
const padicAddress = config.padicAddress ?? generatePadicAddress(config.kind, counter);
|
|
204
|
+
const hashInput = [
|
|
205
|
+
config.kind,
|
|
206
|
+
JSON.stringify(config.payload),
|
|
207
|
+
config.witness.R.toFixed(6),
|
|
208
|
+
config.witness.converged.toString(),
|
|
209
|
+
padicAddress
|
|
210
|
+
].join("|");
|
|
211
|
+
const shapeHash = fnv1a(hashInput);
|
|
212
|
+
const constructive = config.witness.converged && Number.isFinite(payloadEntropy) && payloadEntropy > 0 && JSON.stringify(config.payload) !== "null" && JSON.stringify(config.payload) !== "undefined";
|
|
213
|
+
const impedance = density > 0 && config.witness.R > 0 ? payloadEntropy / (density * config.witness.R) : Infinity;
|
|
214
|
+
return {
|
|
215
|
+
id,
|
|
216
|
+
kind: config.kind,
|
|
217
|
+
payload: config.payload,
|
|
218
|
+
witness: { ...config.witness },
|
|
219
|
+
padicAddress,
|
|
220
|
+
entropy: payloadEntropy,
|
|
221
|
+
density,
|
|
222
|
+
impedance,
|
|
223
|
+
shapeHash,
|
|
224
|
+
constructive,
|
|
225
|
+
createdAt: Date.now(),
|
|
226
|
+
source: config.source ?? "unknown"
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
function sematonEntropy(sematon) {
|
|
230
|
+
return sematon.entropy;
|
|
231
|
+
}
|
|
232
|
+
function sematonDensity(sematon) {
|
|
233
|
+
return sematon.density;
|
|
234
|
+
}
|
|
235
|
+
function isRealizable(sematon) {
|
|
236
|
+
return sematon.constructive;
|
|
237
|
+
}
|
|
238
|
+
function sematonDistance(a, b) {
|
|
239
|
+
const vecA = payloadToVector(a.payload);
|
|
240
|
+
const vecB = payloadToVector(b.payload);
|
|
241
|
+
const cosSim = cosineSimilarity(vecA, vecB);
|
|
242
|
+
const rProximity = 1 - Math.abs(a.witness.R - b.witness.R);
|
|
243
|
+
const similarity = 0.7 * Math.max(0, cosSim) + 0.3 * rProximity;
|
|
244
|
+
return 1 - similarity;
|
|
245
|
+
}
|
|
246
|
+
function payloadToVector(payload) {
|
|
247
|
+
const json = JSON.stringify(payload);
|
|
248
|
+
const vec = new Array(128).fill(0);
|
|
249
|
+
if (!json) return vec;
|
|
250
|
+
for (let i = 0; i < json.length; i++) {
|
|
251
|
+
const code = json.charCodeAt(i);
|
|
252
|
+
if (code < 128) {
|
|
253
|
+
vec[code]++;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
const sum = vec.reduce((s, v) => s + v, 0);
|
|
257
|
+
if (sum > 0) {
|
|
258
|
+
for (let i = 0; i < vec.length; i++) {
|
|
259
|
+
vec[i] /= sum;
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return vec;
|
|
263
|
+
}
|
|
264
|
+
function foldSematon(sematon) {
|
|
265
|
+
return {
|
|
266
|
+
id: sematon.id,
|
|
267
|
+
kind: sematon.kind,
|
|
268
|
+
payload: JSON.stringify(sematon.payload),
|
|
269
|
+
witness: { ...sematon.witness },
|
|
270
|
+
padicAddress: sematon.padicAddress,
|
|
271
|
+
entropy: sematon.entropy,
|
|
272
|
+
density: sematon.density,
|
|
273
|
+
impedance: sematon.impedance,
|
|
274
|
+
shapeHash: sematon.shapeHash,
|
|
275
|
+
constructive: sematon.constructive,
|
|
276
|
+
createdAt: sematon.createdAt,
|
|
277
|
+
source: sematon.source
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
function unfoldSematon(folded) {
|
|
281
|
+
return {
|
|
282
|
+
id: folded.id,
|
|
283
|
+
kind: folded.kind,
|
|
284
|
+
payload: JSON.parse(folded.payload),
|
|
285
|
+
witness: { ...folded.witness },
|
|
286
|
+
padicAddress: folded.padicAddress,
|
|
287
|
+
entropy: folded.entropy,
|
|
288
|
+
density: folded.density,
|
|
289
|
+
impedance: folded.impedance,
|
|
290
|
+
shapeHash: folded.shapeHash,
|
|
291
|
+
constructive: folded.constructive,
|
|
292
|
+
createdAt: folded.createdAt,
|
|
293
|
+
source: folded.source
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
export {
|
|
298
|
+
entropy,
|
|
299
|
+
jointEntropy,
|
|
300
|
+
conditionalEntropy,
|
|
301
|
+
mutualInformation,
|
|
302
|
+
measurePreservation,
|
|
303
|
+
calculateSemanticDensity,
|
|
304
|
+
estimateComplexity,
|
|
305
|
+
klDivergence,
|
|
306
|
+
jsDivergence,
|
|
307
|
+
normalize,
|
|
308
|
+
cosineSimilarity,
|
|
309
|
+
createSematon,
|
|
310
|
+
sematonEntropy,
|
|
311
|
+
sematonDensity,
|
|
312
|
+
isRealizable,
|
|
313
|
+
sematonDistance,
|
|
314
|
+
foldSematon,
|
|
315
|
+
unfoldSematon
|
|
316
|
+
};
|
|
317
|
+
/**
|
|
318
|
+
* L0 Sematon — The Smallest Meaning-Bearing Unit
|
|
319
|
+
*
|
|
320
|
+
* The sematon is the atomic unit of operational meaning in Terminals OS.
|
|
321
|
+
* It carries a typed payload, convergence witness, p-adic address,
|
|
322
|
+
* information-theoretic metrics, and a constructor flag that guarantees
|
|
323
|
+
* the Deutsch-Marletto invariant: after transforming an input, the
|
|
324
|
+
* sematon retains the ability to transform again.
|
|
325
|
+
*
|
|
326
|
+
* The sematon unifies Signal<T>, ContextNode, FractalSnapshot,
|
|
327
|
+
* ConvergenceWitness, and CombinatorEvent into a single formal type
|
|
328
|
+
* at the L0 foundation layer.
|
|
329
|
+
*
|
|
330
|
+
* Core Engine Primitive.
|
|
331
|
+
*
|
|
332
|
+
* @license BUSL-1.1
|
|
333
|
+
* @copyright © 2026 Intuition Labs LLC. All rights reserved. Patent Pending.
|
|
334
|
+
* @module core/L0/sematon
|
|
335
|
+
*/
|