Skip to content

Commit bd4e073

Browse files
committed
MeTTa TS 0.1.0
A pure-TypeScript implementation of MeTTa (Meta Type Talk), the OpenCog Hyperon language. Runs anywhere TypeScript runs. No native addons, no WASM. Packages: @metta-ts/core, @metta-ts/hyperon, @metta-ts/edsl, @metta-ts/node, @metta-ts/browser, @metta-ts/das-client, @metta-ts/das-gateway. Validated 270/270 against Hyperon's oracle corpus and cross-checked against the Lean-verified LeaTTa semantics. Docs + live playground under website/.
0 parents  commit bd4e073

211 files changed

Lines changed: 22605 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.editorconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
root = true
2+
3+
[*]
4+
charset = utf-8
5+
indent_style = space
6+
indent_size = 2
7+
end_of_line = lf
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true

.github/workflows/ci.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
jobs:
9+
build-test:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
- uses: pnpm/action-setup@v4
14+
with:
15+
version: 11
16+
- uses: actions/setup-node@v4
17+
with:
18+
node-version: 20
19+
cache: pnpm
20+
- run: pnpm install --frozen-lockfile
21+
- run: pnpm lint
22+
- run: pnpm format:check
23+
- run: pnpm typecheck
24+
- run: pnpm test # includes the 270/270 Hyperon oracle gate
25+
- run: pnpm build

.github/workflows/deploy-docs.yml

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# SPDX-FileCopyrightText: 2026 MesTTo
2+
# SPDX-License-Identifier: MIT
3+
name: Deploy docs
4+
5+
on:
6+
push:
7+
branches: [main]
8+
workflow_dispatch:
9+
10+
permissions:
11+
contents: read
12+
pages: write
13+
id-token: write
14+
15+
concurrency:
16+
group: pages
17+
cancel-in-progress: false
18+
19+
jobs:
20+
build:
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v4
24+
- uses: pnpm/action-setup@v4
25+
- uses: actions/setup-node@v4
26+
with:
27+
node-version: 22
28+
cache: pnpm
29+
- run: pnpm install --frozen-lockfile
30+
- run: pnpm --filter @metta-ts/core build
31+
- run: pnpm --filter @metta-ts/website docs:build
32+
- uses: actions/configure-pages@v5
33+
- uses: actions/upload-pages-artifact@v3
34+
with:
35+
path: website/.vitepress/dist
36+
37+
deploy:
38+
needs: build
39+
runs-on: ubuntu-latest
40+
environment:
41+
name: github-pages
42+
url: ${{ steps.deployment.outputs.page_url }}
43+
steps:
44+
- id: deployment
45+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
node_modules/
2+
dist/
3+
*.tsbuildinfo
4+
.DS_Store
5+
zod
6+
7+
# LemmaScript generated artifacts (regenerable via `pnpm verify`)
8+
verification/*.dfy
9+
verification/*.dfy.gen
10+
verification/*.lean
11+
12+
# TypeDoc output (per-package)
13+
packages/*/docs/
14+
15+
# Internal design notes, specs, and implementation plans (not part of the public release)
16+
docs/superpowers/
17+
18+
# Internal working notes (not part of the public release)
19+
todo.md
20+
todo-review.md
21+
22+
# Playwright MCP scratch artifacts
23+
.playwright-mcp/
24+
25+
# VitePress build output
26+
website/.vitepress/dist/
27+
website/.vitepress/cache/

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
20

.prettierignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
**/dist/**
2+
**/*.metta
3+
packages/core/src/prelude.ts
4+
corpus/**
5+
pnpm-lock.yaml
6+
7+
packages/das-client/src/gen/
8+
packages/das-client/proto/

.prettierrc.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"printWidth": 100,
3+
"singleQuote": false,
4+
"semi": true,
5+
"trailingComma": "all",
6+
"arrowParens": "always"
7+
}

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 MesTTo
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

LICENSES/MIT.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
MIT License
2+
3+
Copyright (c) <year> <copyright holders>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
6+
associated documentation files (the "Software"), to deal in the Software without restriction, including
7+
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
9+
following conditions:
10+
11+
The above copyright notice and this permission notice shall be included in all copies or substantial
12+
portions of the Software.
13+
14+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
15+
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
16+
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18+
USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
# MeTTa TS
2+
3+
A pure-TypeScript implementation of **MeTTa** (Meta Type Talk), the OpenCog Hyperon language. It runs anywhere TypeScript runs: the browser, Node, Deno, Bun, edge and serverless functions, and inside TypeScript-based AI agents. No native addons, no WASM, no Rust.
4+
5+
## Why this exists
6+
7+
Every other MeTTa implementation is tied to a runtime that cannot drop into a web page or a TypeScript agent without a native or WASM boundary: Rust (hyperon-experimental, MORK), Prolog (PeTTa, MeTTaLog), the JVM (JETTA), Python (the reference bindings). MeTTa TS fills the open lane. You import it and run, from a browser tab to a serverless handler to an agent loop. As more agent tooling is written in TypeScript, a MeTTa that lives natively in that ecosystem, with zero install steps and no build-time native step, is the point.
8+
9+
## Install
10+
11+
```bash
12+
npm install @metta-ts/core # the interpreter (works in any JS runtime)
13+
# or: pnpm add @metta-ts/core / yarn add @metta-ts/core
14+
```
15+
16+
Other packages, add as needed:
17+
18+
```bash
19+
npm install @metta-ts/hyperon # a Python-hyperon-style class API
20+
npm install @metta-ts/node # CLI + file import! + a parallel matcher
21+
npm install @metta-ts/browser # web entry + in-memory virtual file system
22+
```
23+
24+
For the command-line runner, install `@metta-ts/node` globally (or use `npx`):
25+
26+
```bash
27+
npm install -g @metta-ts/node
28+
metta-ts path/to/program.metta
29+
30+
# without a global install:
31+
npx -p @metta-ts/node metta-ts path/to/program.metta
32+
```
33+
34+
## Quick start
35+
36+
Run MeTTa source from TypeScript with the core package:
37+
38+
```ts
39+
import { runProgram, format } from "@metta-ts/core";
40+
41+
const results = runProgram(`
42+
(= (fact $n) (unify $n 0 1 (* $n (fact (- $n 1)))))
43+
!(fact 5)
44+
`);
45+
46+
for (const { query, results: rs } of results) {
47+
console.log(format(query), "=>", rs.map(format));
48+
}
49+
// (fact 5) => [ '120' ]
50+
```
51+
52+
`runProgram` parses the source, adds every non-bang atom to the knowledge base, evaluates each `!`-query, and returns one result group per query.
53+
54+
## Calling TypeScript from MeTTa
55+
56+
The `@metta-ts/hyperon` package is a class API modeled on Python's `hyperon`, but TypeScript-native: no Python, no Rust, no FFI. A grounded operation is a TypeScript function the evaluator can call by name.
57+
58+
```ts
59+
import { MeTTa, ValueAtom, type GroundedAtom, type Atom } from "@metta-ts/hyperon";
60+
61+
const metta = new MeTTa();
62+
63+
metta.registerOperation("double", (args: Atom[]) => {
64+
const n = (args[0] as GroundedAtom).jsValue<number>();
65+
return [ValueAtom(n * 2)];
66+
});
67+
68+
console.log(metta.run("!(double 21)")[0].map(String)); // [ '42' ]
69+
```
70+
71+
A thrown error becomes a MeTTa `(Error ...)` atom the program can inspect, rather than crashing the run.
72+
73+
## Async MeTTa
74+
75+
MeTTa can be asynchronous. A grounded operation can do I/O (a fetch, a database query, a timer) and the evaluator awaits it. Register it with `registerAsyncOperation` and run with `runAsync`. A synchronous program gives identical results either way.
76+
77+
```ts
78+
import { MeTTa, ValueAtom } from "@metta-ts/hyperon";
79+
80+
const metta = new MeTTa();
81+
metta.registerAsyncOperation("fetch-temperature", async () => {
82+
const res = await fetch("https://example.com/temp"); // any real I/O
83+
return [ValueAtom(await res.json())];
84+
});
85+
86+
const out = await metta.runAsync("!(fetch-temperature)");
87+
console.log(out[0].map(String));
88+
```
89+
90+
## Ergonomic typed eDSL
91+
92+
For writing MeTTa in idiomatic TypeScript, [`@metta-ts/edsl`](packages/edsl) gives typed term builders, special-form combinators (`iff`, `caseOf`, `matchSelf`, arithmetic, ...), and a tagged-template surface. It builds ordinary atoms and runs on the same engine, so you get MeTTa's real semantics (rewrite rules, nondeterminism, pattern matching) rather than a relational query language. Any TypeScript value drops in as a grounded atom automatically.
93+
94+
```ts
95+
import { mettaDB, S, v, rel, iff, gt, lt, mul, sub, m, ValueAtom, type GroundedAtom } from "@metta-ts/edsl";
96+
97+
const db = mettaDB();
98+
99+
// Facts + a typed match query.
100+
db.add(rel("Likes")(S.Ada, S.Coffee), rel("Likes")(S.Ada, S.Chocolate));
101+
const thing = v<string>("thing");
102+
db.query(rel("Likes")(S.Ada, thing), { thing }); // [{ thing: "Coffee" }, { thing: "Chocolate" }]
103+
104+
// Recursive rewrite rule + grounded arithmetic.
105+
const x = v<number>("x");
106+
db.rule(rel("fact")(x), iff(gt(x, 0), mul(x, rel("fact")(sub(x, 1))), 1));
107+
db.evalJs(rel("fact")(5)); // [120]
108+
109+
// Pass a TypeScript object straight into a query (auto-grounded).
110+
db.op("balance-of", (args) => [ValueAtom((args[0] as GroundedAtom).jsValue<{ balance: number }>().balance)]);
111+
db.evalJs(rel("balance-of")({ owner: "Tom", balance: 100 })); // [100]
112+
db.evalJs(m`(balance-of ${{ owner: "Tom", balance: 100 }})`); // [100] — template surface
113+
```
114+
115+
More runnable examples are in [`examples/`](examples/): [`quickstart.ts`](examples/quickstart.ts), [`grounded-ops.ts`](examples/grounded-ops.ts), [`async.ts`](examples/async.ts), [`edsl.ts`](examples/edsl.ts), plus `.metta` source files. Run one with `npx tsx examples/quickstart.ts`.
116+
117+
## What is implemented
118+
119+
A faithful port of hyperon-experimental's minimal interpreter (the nondeterministic stack machine), with the standard library loaded as MeTTa source on top. The core passes **all 270 assertions** of Hyperon's oracle corpus: the full dependent-type tier (GADTs, dependent types, types-as-propositions), spaces and mutable state, nondeterminism, grounded operations, and documentation. Correctness is also cross-checked against [LeaTTa](https://github.com/MesTTo/LeaTTa), the machine-checked (Lean 4) MeTTa semantics, pinned to the same commit.
120+
121+
Beyond the core: transactions, async evaluation, concurrency primitives (`par`, `race`, `once`, `with-mutex`), clause indexing that scales matching to millions of atoms, a flat interned knowledge base with a worker-thread parallel matcher, and a JavaScript interop layer (`js-atom`, `js-dot`, `js-list`, `js-dict`) that calls into the host runtime directly.
122+
123+
The whole thing is pure TypeScript. The core builds to a single ESM bundle (~23 KB gzipped) that runs in Node and the browser with no native addon and no WASM.
124+
125+
```bash
126+
pnpm install
127+
pnpm build
128+
pnpm test # 270/270 Hyperon oracle gate + unit and property tests
129+
node packages/node/dist/cli.js examples/factorial.metta
130+
```
131+
132+
## Packages
133+
134+
| Package | What it is |
135+
|---------|------------|
136+
| [`@metta-ts/core`](packages/core) | The interpreter, parser, type system, and standard library. Zero platform dependencies. |
137+
| [`@metta-ts/hyperon`](packages/hyperon) | A TypeScript class API over the core, modeled on Python's `hyperon`. |
138+
| [`@metta-ts/edsl`](packages/edsl) | An ergonomic, typed eDSL: term builders, special-form combinators, and a tagged template. |
139+
| [`@metta-ts/node`](packages/node) | The `metta-ts` CLI, file `import!`, and a `SharedArrayBuffer` worker-thread parallel matcher. |
140+
| [`@metta-ts/browser`](packages/browser) | Browser entry point with an in-memory virtual file system for `import!`. |
141+
| [`@metta-ts/das-client`](packages/das-client) | Optional client to SingularityNET's Distributed AtomSpace via a Connect gateway. |
142+
143+
## Performance
144+
145+
Pure TypeScript throughout, no escape to native code. The interpreter uses a precomputed-ground short-circuit, structural sharing in substitution, a cons-list instruction stack, and Prolog-style clause indexing (by head functor and by every ground-leaf argument position). A functor-and-argument-keyed query over a 1,000,000-atom knowledge base resolves in about 0.2 to 1.4 ms. See [`packages/node/bench/RESULTS.md`](packages/node/bench/RESULTS.md) for the full benchmark log.
146+
147+
## Provenance
148+
149+
- **Semantics:** [hyperon-experimental](https://github.com/trueagi-io/hyperon-experimental), pinned to commit `3f76dc4`.
150+
- **Verified spec and differential oracle:** [LeaTTa](https://github.com/MesTTo/LeaTTa) (Lean 4).
151+
- **Distributed AtomSpace:** optional client to SingularityNET DAS via a Connect gateway (Node), reachable from the browser.
152+
153+
## License
154+
155+
[MIT](LICENSE).

0 commit comments

Comments
 (0)