@tellegen/engine 0.1.1 → 0.3.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/README.md +50 -6
- package/dist/generated/contracts.d.ts +35 -17
- package/dist/generated/contracts.d.ts.map +1 -1
- package/dist/generated/contracts.js +3 -3
- package/dist/generated/study-contracts.d.ts +426 -0
- package/dist/generated/study-contracts.d.ts.map +1 -0
- package/dist/generated/study-contracts.js +4 -0
- package/dist/generated/study-contracts.js.map +1 -0
- package/dist/generated/study-schema.d.ts +2 -0
- package/dist/generated/study-schema.d.ts.map +1 -0
- package/dist/generated/study-schema.js +3 -0
- package/dist/generated/study-schema.js.map +1 -0
- package/dist/host.d.ts +12 -0
- package/dist/host.d.ts.map +1 -1
- package/dist/host.js +71 -17
- package/dist/host.js.map +1 -1
- package/dist/index.d.ts +360 -96
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +407 -89
- package/dist/index.js.map +1 -1
- package/dist/input-limit.d.ts +8 -0
- package/dist/input-limit.d.ts.map +1 -0
- package/dist/input-limit.js +14 -0
- package/dist/input-limit.js.map +1 -0
- package/dist/module.d.ts +1 -0
- package/dist/module.d.ts.map +1 -1
- package/dist/module.js.map +1 -1
- package/dist/protocol.d.ts +105 -20
- package/dist/protocol.d.ts.map +1 -1
- package/dist/protocol.js +67 -18
- package/dist/protocol.js.map +1 -1
- package/dist/study-document.d.ts +46 -0
- package/dist/study-document.d.ts.map +1 -0
- package/dist/study-document.js +183 -0
- package/dist/study-document.js.map +1 -0
- package/dist/study-document.test.d.ts +2 -0
- package/dist/study-document.test.d.ts.map +1 -0
- package/dist/study-document.test.js +119 -0
- package/dist/study-document.test.js.map +1 -0
- package/dist/wasm-pkg/tellegen.d.ts +191 -55
- package/dist/wasm-pkg/tellegen.js +754 -97
- package/dist/wasm-pkg/tellegen_bg.wasm +0 -0
- package/dist/wasm-pkg/tellegen_bg.wasm.d.ts +30 -6
- package/dist/worker.js +27 -3
- package/dist/worker.js.map +1 -1
- package/package.json +26 -4
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { isolatedEngineHost } from "./host.js";
|
|
2
|
+
async function callIsolated(request, signal) {
|
|
3
|
+
signal?.throwIfAborted();
|
|
4
|
+
const host = isolatedEngineHost();
|
|
5
|
+
const cooperative = request.op === "study_document_run";
|
|
6
|
+
const cancel = () => cooperative ? host.requestStop?.() : host.cancel?.(new DOMException("Study operation cancelled", "AbortError"));
|
|
7
|
+
signal?.addEventListener("abort", cancel, { once: true });
|
|
8
|
+
try {
|
|
9
|
+
const result = await host.call(request);
|
|
10
|
+
if (!cooperative)
|
|
11
|
+
signal?.throwIfAborted();
|
|
12
|
+
if (result === null)
|
|
13
|
+
throw new Error("The engine returned no Study result");
|
|
14
|
+
return result;
|
|
15
|
+
}
|
|
16
|
+
finally {
|
|
17
|
+
signal?.removeEventListener("abort", cancel);
|
|
18
|
+
host.cancel?.(new Error("Study operation completed"));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
export const studyBackend = {
|
|
22
|
+
async create(request, signal) { return JSON.parse(await callIsolated({ op: "study_document_create", request: JSON.stringify(request) }, signal)); },
|
|
23
|
+
async validate(text) { return JSON.parse(await callIsolated({ op: "study_document_import", bundle: text })); },
|
|
24
|
+
async execute(bundle, request, signal) {
|
|
25
|
+
return JSON.parse(await callIsolated({ op: "study_document_run", bundle: JSON.stringify(bundle), request: JSON.stringify(request) }, signal));
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
function storageError(error) {
|
|
29
|
+
const cause = error instanceof Error ? error.message : String(error);
|
|
30
|
+
return new Error(`Study was not saved: ${cause}. Free browser storage or export the Study and choose another destination before retrying.`);
|
|
31
|
+
}
|
|
32
|
+
/** IndexedDB commits the complete document and its deduplicated artifact map together. */
|
|
33
|
+
export class IndexedDbStudyStore {
|
|
34
|
+
#database;
|
|
35
|
+
constructor(name = "tellegen-studies") {
|
|
36
|
+
this.#database = new Promise((resolve, reject) => {
|
|
37
|
+
const request = indexedDB.open(name, 1);
|
|
38
|
+
request.onupgradeneeded = () => request.result.createObjectStore("studies", { keyPath: "document.id" });
|
|
39
|
+
request.onsuccess = () => { request.result.onversionchange = () => request.result.close(); resolve(request.result); };
|
|
40
|
+
request.onerror = () => reject(storageError(request.error));
|
|
41
|
+
request.onblocked = () => reject(new Error("Study storage is blocked by another tab; close its connection and reload"));
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
async load(id) {
|
|
45
|
+
const db = await this.#database;
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
const tx = db.transaction("studies", "readonly");
|
|
48
|
+
const request = tx.objectStore("studies").get(id);
|
|
49
|
+
request.onsuccess = () => resolve(request.result ?? null);
|
|
50
|
+
request.onerror = () => reject(storageError(request.error));
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async list() {
|
|
54
|
+
const db = await this.#database;
|
|
55
|
+
return new Promise((resolve, reject) => {
|
|
56
|
+
const rows = [];
|
|
57
|
+
const tx = db.transaction("studies", "readonly");
|
|
58
|
+
const request = tx.objectStore("studies").openCursor();
|
|
59
|
+
request.onsuccess = () => {
|
|
60
|
+
const cursor = request.result;
|
|
61
|
+
if (!cursor)
|
|
62
|
+
return;
|
|
63
|
+
const { id, title, revision } = cursor.value.document;
|
|
64
|
+
rows.push({ id, title, revision });
|
|
65
|
+
cursor.continue();
|
|
66
|
+
};
|
|
67
|
+
tx.oncomplete = () => resolve(rows);
|
|
68
|
+
tx.onabort = tx.onerror = () => reject(storageError(tx.error));
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
async create(bundle) { return this.#write(null, bundle); }
|
|
72
|
+
async commit(expectedRevision, bundle) { return this.#write(expectedRevision, bundle); }
|
|
73
|
+
async #write(expected, bundle) {
|
|
74
|
+
const db = await this.#database;
|
|
75
|
+
return new Promise((resolve, reject) => {
|
|
76
|
+
const tx = db.transaction("studies", "readwrite");
|
|
77
|
+
const store = tx.objectStore("studies");
|
|
78
|
+
let conflict;
|
|
79
|
+
const request = store.get(bundle.document.id);
|
|
80
|
+
request.onsuccess = () => {
|
|
81
|
+
const current = request.result;
|
|
82
|
+
if (expected === null ? current !== undefined : current?.document.revision !== expected || bundle.document.revision !== expected + 1) {
|
|
83
|
+
conflict = new Error("Study storage revision changed; reload the saved Study before retrying");
|
|
84
|
+
tx.abort();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
try {
|
|
88
|
+
store.put(bundle);
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
conflict = storageError(error);
|
|
92
|
+
tx.abort();
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
tx.oncomplete = () => resolve();
|
|
96
|
+
tx.onabort = () => reject(conflict ?? storageError(tx.error));
|
|
97
|
+
tx.onerror = () => reject(conflict ?? storageError(tx.error));
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
async close() { (await this.#database).close(); }
|
|
101
|
+
}
|
|
102
|
+
/** Browser controls and agent tools share serialized, durable Study mutations. */
|
|
103
|
+
export class StudyDocumentController {
|
|
104
|
+
#bundle;
|
|
105
|
+
#store;
|
|
106
|
+
#backend;
|
|
107
|
+
#queue = Promise.resolve();
|
|
108
|
+
#approvals = new Map();
|
|
109
|
+
constructor(bundle, store, backend) {
|
|
110
|
+
this.#bundle = bundle;
|
|
111
|
+
this.#store = store;
|
|
112
|
+
this.#backend = backend;
|
|
113
|
+
}
|
|
114
|
+
static async create(request, store, backend = studyBackend, signal) {
|
|
115
|
+
const bundle = await backend.create(request, signal);
|
|
116
|
+
signal?.throwIfAborted();
|
|
117
|
+
await store.create(bundle);
|
|
118
|
+
return new StudyDocumentController(bundle, store, backend);
|
|
119
|
+
}
|
|
120
|
+
static async open(id, store, backend = studyBackend) {
|
|
121
|
+
const saved = await store.load(id);
|
|
122
|
+
if (!saved)
|
|
123
|
+
throw new Error(`Study ${id} is unavailable`);
|
|
124
|
+
const bundle = await backend.validate(JSON.stringify(saved));
|
|
125
|
+
return new StudyDocumentController(bundle, store, backend);
|
|
126
|
+
}
|
|
127
|
+
static async import(text, store, backend = studyBackend) {
|
|
128
|
+
const bundle = await backend.validate(text);
|
|
129
|
+
await store.create(bundle);
|
|
130
|
+
return new StudyDocumentController(bundle, store, backend);
|
|
131
|
+
}
|
|
132
|
+
get bundle() { return structuredClone(this.#bundle); }
|
|
133
|
+
export() { return JSON.stringify(this.#bundle); }
|
|
134
|
+
execute(request, signal) {
|
|
135
|
+
if (request.operation.kind === "apply")
|
|
136
|
+
return Promise.reject(new Error("Apply requires explicit user approval of the current proposal"));
|
|
137
|
+
return this.#execute(request, signal);
|
|
138
|
+
}
|
|
139
|
+
#execute(request, signal) {
|
|
140
|
+
const queuedRequest = structuredClone(request);
|
|
141
|
+
const operation = this.#queue.then(async () => {
|
|
142
|
+
signal?.throwIfAborted();
|
|
143
|
+
if (queuedRequest.expected_revision !== this.#bundle.document.revision)
|
|
144
|
+
throw new Error("Stale Study revision; inspect the current Study and retry");
|
|
145
|
+
const completed = await this.#backend.execute(structuredClone(this.#bundle), queuedRequest, signal);
|
|
146
|
+
if (queuedRequest.operation.kind !== "propose")
|
|
147
|
+
signal?.throwIfAborted();
|
|
148
|
+
await this.#store.commit(queuedRequest.expected_revision, completed.bundle);
|
|
149
|
+
this.#bundle = completed.bundle;
|
|
150
|
+
if (["inspect", "compare", "record_evidence"].includes(queuedRequest.operation.kind)) {
|
|
151
|
+
for (const approval of this.#approvals.values())
|
|
152
|
+
approval.revision = completed.bundle.document.revision;
|
|
153
|
+
}
|
|
154
|
+
else
|
|
155
|
+
this.#approvals.clear();
|
|
156
|
+
return completed.result;
|
|
157
|
+
});
|
|
158
|
+
this.#queue = operation.catch(() => undefined);
|
|
159
|
+
return operation;
|
|
160
|
+
}
|
|
161
|
+
/** Call only from the user's approval action; tokens stay in this controller. */
|
|
162
|
+
recordUserApproval(proposal) {
|
|
163
|
+
const d = this.#bundle.document;
|
|
164
|
+
const experiment = d.experiments[proposal];
|
|
165
|
+
if (!experiment || !["planning", "counterfactual"].includes(experiment.kind) || !experiment.start_state || experiment.goal !== d.active_goal || !d.recommended_state || !experiment.result_states.includes(d.recommended_state))
|
|
166
|
+
throw new Error("The proposal no longer matches the active goal and recommendation");
|
|
167
|
+
const token = crypto.randomUUID();
|
|
168
|
+
this.#approvals.set(token, { proposal, state: d.recommended_state, goal: d.active_goal ?? null, base: experiment.start_state, revision: d.revision });
|
|
169
|
+
return token;
|
|
170
|
+
}
|
|
171
|
+
isApprovalCurrent(token) {
|
|
172
|
+
const approval = this.#approvals.get(token), d = this.#bundle.document;
|
|
173
|
+
return !!approval && d.revision === approval.revision && d.active_goal === approval.goal &&
|
|
174
|
+
d.recommended_state === approval.state && d.experiments[approval.proposal]?.start_state === approval.base;
|
|
175
|
+
}
|
|
176
|
+
applyApprovedProposal(token, signal) {
|
|
177
|
+
const approval = this.#approvals.get(token);
|
|
178
|
+
if (!approval || !this.isApprovalCurrent(token))
|
|
179
|
+
return Promise.reject(new Error("Proposal approval expired; review the current proposal again"));
|
|
180
|
+
return this.#execute({ expected_revision: approval.revision, operation: { kind: "apply", proposal: approval.proposal, state: approval.state, goal: approval.goal, base_state: approval.base } }, signal);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=study-document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"study-document.js","sourceRoot":"","sources":["../src/study-document.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"study-document.test.d.ts","sourceRoot":"","sources":["../src/study-document.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { describe, expect, it, vi } from "vitest";
|
|
2
|
+
import { StudyDocumentController } from "./study-document.js";
|
|
3
|
+
const input = { id: "s", title: "Study", input: "", formulation: "dcopf", request: "Lower prices", interpretation: "Weighted prices",
|
|
4
|
+
objective: { kind: "weighted_observable", operand: { Price: "Active" }, weights: [{ element: 2, weight: 1 }] },
|
|
5
|
+
decisions: { variables: [{ id: "line", element: 1, intervention: "branch_rating", lower: 0, upper: 10, increment: 1, budget_weight: 1 }], total_budget: 10, max_changed_elements: 1 } };
|
|
6
|
+
function fixture() {
|
|
7
|
+
return { document: { schema: "tellegen-study", version: 1, id: "s", title: "Study", revision: 0,
|
|
8
|
+
goals: {}, states: {}, experiments: { p: { kind: "planning", start_state: "base", goal: "g", rationale: "Test", evidence: [], trials: [], result_states: ["candidate"], solve_count: 1, termination: "completed" } },
|
|
9
|
+
experiment_order: ["p"], decisions: {}, active_goal: "g", inspected_state: "base", applied_state: "base", recommended_state: "candidate" }, artifacts: {} };
|
|
10
|
+
}
|
|
11
|
+
class Store {
|
|
12
|
+
saved = null;
|
|
13
|
+
fail = false;
|
|
14
|
+
async load() { return structuredClone(this.saved); }
|
|
15
|
+
async create(bundle) { this.saved = structuredClone(bundle); }
|
|
16
|
+
async commit(expected, bundle) {
|
|
17
|
+
if (this.fail)
|
|
18
|
+
throw new Error("QuotaExceededError: free storage");
|
|
19
|
+
if (this.saved?.document.revision !== expected)
|
|
20
|
+
throw new Error("stale stored revision");
|
|
21
|
+
this.saved = structuredClone(bundle);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function backend() {
|
|
25
|
+
return {
|
|
26
|
+
create: async () => fixture(), validate: async (text) => JSON.parse(text),
|
|
27
|
+
execute: vi.fn(async (bundle, request) => {
|
|
28
|
+
bundle.document.revision++;
|
|
29
|
+
if (request.operation.kind === "inspect")
|
|
30
|
+
bundle.document.inspected_state = request.operation.state;
|
|
31
|
+
if (request.operation.kind === "apply")
|
|
32
|
+
bundle.document.applied_state = request.operation.state;
|
|
33
|
+
const result = { summary: { id: "s", title: "Study", revision: bundle.document.revision, state_count: 0, experiment_count: 1, recent_experiments: [], unavailable_historical_states: 0 }, experiment: null, comparison: null, inspected_view: null };
|
|
34
|
+
return { bundle, result };
|
|
35
|
+
}),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
describe("durable Study controller", () => {
|
|
39
|
+
it("publishes completed mutations only after storage succeeds", async () => {
|
|
40
|
+
const store = new Store();
|
|
41
|
+
const engine = backend();
|
|
42
|
+
const controller = await StudyDocumentController.create(input, store, engine);
|
|
43
|
+
store.fail = true;
|
|
44
|
+
await expect(controller.execute({ expected_revision: 0, operation: { kind: "inspect", state: "candidate" } })).rejects.toThrow("QuotaExceededError");
|
|
45
|
+
expect(controller.bundle.document.revision).toBe(0);
|
|
46
|
+
expect(controller.bundle.document.inspected_state).toBe("base");
|
|
47
|
+
expect(store.saved?.document.revision).toBe(0);
|
|
48
|
+
store.fail = false;
|
|
49
|
+
await controller.execute({ expected_revision: 0, operation: { kind: "inspect", state: "candidate" } });
|
|
50
|
+
expect(controller.bundle.document.applied_state).toBe("base");
|
|
51
|
+
expect(store.saved?.document.inspected_state).toBe("candidate");
|
|
52
|
+
});
|
|
53
|
+
it("serializes mutations and rejects requests based on stale state", async () => {
|
|
54
|
+
const store = new Store();
|
|
55
|
+
const engine = backend();
|
|
56
|
+
const controller = await StudyDocumentController.create(input, store, engine);
|
|
57
|
+
const first = controller.execute({ expected_revision: 0, operation: { kind: "inspect", state: "candidate" } });
|
|
58
|
+
const second = controller.execute({ expected_revision: 0, operation: { kind: "inspect", state: "base" } });
|
|
59
|
+
await first;
|
|
60
|
+
await expect(second).rejects.toThrow("Stale Study revision");
|
|
61
|
+
expect(engine.execute).toHaveBeenCalledTimes(1);
|
|
62
|
+
});
|
|
63
|
+
it("binds explicit approval to a proposal and never restores approval on reload", async () => {
|
|
64
|
+
const store = new Store();
|
|
65
|
+
const engine = backend();
|
|
66
|
+
const controller = await StudyDocumentController.create(input, store, engine);
|
|
67
|
+
const token = controller.recordUserApproval("p");
|
|
68
|
+
const restored = await StudyDocumentController.open("s", store, engine);
|
|
69
|
+
await expect(restored.applyApprovedProposal(token)).rejects.toThrow("expired");
|
|
70
|
+
await expect(controller.execute({ expected_revision: 0, operation: { kind: "apply", proposal: "p", goal: "g", base_state: "base", state: "candidate" } })).rejects.toThrow("explicit user approval");
|
|
71
|
+
await controller.applyApprovedProposal(token);
|
|
72
|
+
expect(controller.bundle.document.applied_state).toBe("candidate");
|
|
73
|
+
expect(controller.export()).not.toContain(token);
|
|
74
|
+
await expect(controller.applyApprovedProposal(token)).rejects.toThrow("expired");
|
|
75
|
+
});
|
|
76
|
+
it("saves completed planning evidence when cancellation ends an active proposal", async () => {
|
|
77
|
+
const store = new Store();
|
|
78
|
+
const engine = backend();
|
|
79
|
+
const cancel = new AbortController();
|
|
80
|
+
const execute = engine.execute;
|
|
81
|
+
engine.execute = async (bundle, request, signal) => {
|
|
82
|
+
cancel.abort();
|
|
83
|
+
const completed = await execute(bundle, request, signal);
|
|
84
|
+
completed.bundle.document.experiments.p.termination = "cancelled";
|
|
85
|
+
return completed;
|
|
86
|
+
};
|
|
87
|
+
const controller = await StudyDocumentController.create(input, store, engine);
|
|
88
|
+
await controller.execute({ expected_revision: 0, operation: { kind: "propose", state: "base", goal: "g", rationale: "Explore", options: { max_solves: 5, beam_width: 2, max_iterations: 2, min_improvement: 1e-7 } } }, cancel.signal);
|
|
89
|
+
expect(controller.bundle.document.revision).toBe(1);
|
|
90
|
+
expect(store.saved?.document.experiments.p.termination).toBe("cancelled");
|
|
91
|
+
expect(store.saved?.document.applied_state).toBe("base");
|
|
92
|
+
});
|
|
93
|
+
it("invalidates approval when branching and rejects pre-cancelled work", async () => {
|
|
94
|
+
const store = new Store();
|
|
95
|
+
const engine = backend();
|
|
96
|
+
const controller = await StudyDocumentController.create(input, store, engine);
|
|
97
|
+
const token = controller.recordUserApproval("p");
|
|
98
|
+
await controller.execute({ expected_revision: 0, operation: { kind: "branch", state: "candidate", rationale: "Explore this branch" } });
|
|
99
|
+
await expect(controller.applyApprovedProposal(token)).rejects.toThrow("expired");
|
|
100
|
+
const signal = AbortSignal.abort();
|
|
101
|
+
await expect(controller.execute({ expected_revision: 1, operation: { kind: "inspect", state: "base" } }, signal)).rejects.toThrow();
|
|
102
|
+
expect(controller.bundle.document.revision).toBe(1);
|
|
103
|
+
});
|
|
104
|
+
it("keeps approval through inspection and retries a failed durable apply", async () => {
|
|
105
|
+
const store = new Store(), engine = backend();
|
|
106
|
+
const controller = await StudyDocumentController.create(input, store, engine);
|
|
107
|
+
const token = controller.recordUserApproval("p");
|
|
108
|
+
await controller.execute({ expected_revision: 0, operation: { kind: "inspect", state: "candidate" } });
|
|
109
|
+
expect(controller.isApprovalCurrent(token)).toBe(true);
|
|
110
|
+
store.fail = true;
|
|
111
|
+
await expect(controller.applyApprovedProposal(token)).rejects.toThrow("QuotaExceededError");
|
|
112
|
+
expect(controller.bundle.document.applied_state).toBe("base");
|
|
113
|
+
expect(controller.isApprovalCurrent(token)).toBe(true);
|
|
114
|
+
store.fail = false;
|
|
115
|
+
await controller.applyApprovedProposal(token);
|
|
116
|
+
expect(controller.bundle.document.applied_state).toBe("candidate");
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
//# sourceMappingURL=study-document.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"study-document.test.js","sourceRoot":"","sources":["../src/study-document.test.ts"],"names":[],"mappings":"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"}
|