diff --git a/examples/mixture-of-agents/index.html b/examples/mixture-of-agents/index.html
index a35d275..e971b73 100644
--- a/examples/mixture-of-agents/index.html
+++ b/examples/mixture-of-agents/index.html
@@ -165,7 +165,7 @@
"GPT-4o Mini",
"Llama 3.1 8B",
"Mixtral 8x7B",
- ]
+ ];
const individualResults = "{{ individual }}";
const aggResults = "{{ summaries }}";
@@ -190,7 +190,7 @@
contentArea.textContent =
individualResults[currentLayer][currentIndex].trim();
- cardTitle.textContent = `${modelNames[currentIndex]} - Layer ${ currentLayer + 1 }`;
+ cardTitle.textContent = `${modelNames[currentIndex]} - Layer ${currentLayer + 1}`;
} else {
contentArea.textContent = aggResults[currentLayer].trim();
cardTitle.textContent = `MoA Layer ${currentLayer + 1}`;
diff --git a/examples/module.ts b/examples/module.ts
new file mode 100755
index 0000000..8411089
--- /dev/null
+++ b/examples/module.ts
@@ -0,0 +1,62 @@
+#!/usr/bin/env -S npx ts-node --transpileOnly
+
+import { Substrate, Box, Module, sb } from "substrate";
+
+async function main() {
+ const SUBSTRATE_API_KEY = process.env["SUBSTRATE_API_KEY"];
+ const substrate = new Substrate({ apiKey: SUBSTRATE_API_KEY });
+
+ const x = sb.var({ type: "string", default: "hello" });
+ const y = sb.var({ type: "string" });
+ const z = sb.var({ type: "object", properties: {} });
+
+ const a = new Box({ value: { a: x, z: z, array: [x, x, x] } }, { id: "A" });
+ const b = new Box(
+ { value: { b: sb.interpolate`x=${a.future.value.get("a")}, y=${y}` } },
+ { id: "B" },
+ );
+
+ // publish the module on substrate.run
+ const publication = await substrate.module.publish({
+ name: "my reusable graph",
+ nodes: [a, b],
+ inputs: { x, y, z },
+ });
+ console.log("published:", publication.json);
+
+ // using the module from JSON
+ const mod = new Module({
+ module_json: substrate.module.serialize({
+ nodes: [a, b],
+ inputs: { x, y, z },
+ }),
+ inputs: {
+ // when commented will use "hello" because it is defined as the default above
+ // x: 123,
+ y: "yyy",
+ z: {
+ arr: ["123"],
+ },
+ },
+ });
+
+ // using the module from publication/module id
+ // const mod = new Module({
+ // module_id: publication.id,
+ // inputs: { y: "yyy", z: { arr: ["123"] } },
+ // });
+
+ const c = new Box(
+ {
+ value: {
+ "1": mod.future.get("A.value.z.arr[0]"),
+ "2": mod.future.get("B.value.b"),
+ },
+ },
+ { id: "C" },
+ );
+
+ const res = await substrate.run(mod, c);
+ console.log(JSON.stringify(res.json, null, 2));
+}
+main();
diff --git a/package-lock.json b/package-lock.json
index c11e188..f8879ac 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,6 +9,7 @@
"version": "120240617.1.7",
"license": "MIT",
"dependencies": {
+ "@types/json-schema": "^7.0.15",
"@types/node-fetch": "^2.6.11",
"node-fetch": "2.7.0",
"pako": "^2.1.0"
@@ -798,6 +799,11 @@
"integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==",
"dev": true
},
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="
+ },
"node_modules/@types/node": {
"version": "20.14.11",
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.11.tgz",
diff --git a/package.json b/package.json
index f778af3..234dbe5 100644
--- a/package.json
+++ b/package.json
@@ -43,6 +43,7 @@
"vitest": "^1.0.4"
},
"dependencies": {
+ "@types/json-schema": "^7.0.15",
"@types/node-fetch": "^2.6.11",
"node-fetch": "2.7.0",
"pako": "^2.1.0"
diff --git a/src/Future.ts b/src/Future.ts
index 75559a5..601f81c 100644
--- a/src/Future.ts
+++ b/src/Future.ts
@@ -1,5 +1,6 @@
import { idGenerator } from "substrate/idGenerator";
import { Node } from "substrate/Node";
+import { type JSONSchema7 } from "json-schema";
type Accessor = "item" | "attr";
type TraceOperation = {
@@ -122,7 +123,7 @@ export class JQ extends Directive {
rawValue: (val: JQCompatible) => ({ future_id: null, val }),
};
- override next(...items: TraceProp[]) {
+ override next(..._items: TraceProp[]) {
return new JQ(this.query, this.target);
}
@@ -315,3 +316,39 @@ export class FutureAnyObject extends Future