@evoke-build/evoke 0.10.1 → 0.11.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/core.wasm +0 -0
- package/dist/index.d.ts +1 -1
- package/dist/ops.d.ts +41 -0
- package/dist/project.d.ts +18 -2
- package/dist/project.js +98 -31
- package/dist/types.d.ts +65 -2
- package/package.json +1 -1
package/core.wasm
CHANGED
|
Binary file
|
package/dist/index.d.ts
CHANGED
|
@@ -7,4 +7,4 @@ export type { Context, Reflex, Result } from "./runtime.ts";
|
|
|
7
7
|
export type { Adapter, Trace } from "./adapter.ts";
|
|
8
8
|
export { DiagnosticError, EvokeError, FailureError, FaultError } from "./errors.ts";
|
|
9
9
|
export type { Problem } from "./errors.ts";
|
|
10
|
-
export type { Because, Binding, Bound, Cap, Choices, Contained, Contender, Diagnostic, Effect, Fault, Fix, Gate, Judgment, Limits, Missing, Needs, Prompt, Question, NonEmpty, Raw, Recognizer, Span, State, Status, Step, Text, Verdict, Weave, WeaveWhy, Why, Yield, } from "./types.ts";
|
|
10
|
+
export type { Answer, Because, Binding, Bound, Cap, Choices, Contained, Contender, Diagnostic, Effect, Fault, Fix, Gate, Judgment, Limits, Missing, Needs, Pinned, PinnedReflex, Prompt, Question, NonEmpty, Raw, Recognizer, Span, State, Status, Step, Text, Verdict, Weave, WeaveWhy, Why, Yield, } from "./types.ts";
|
package/dist/ops.d.ts
CHANGED
|
@@ -108,6 +108,7 @@ export interface Ops {
|
|
|
108
108
|
compile: {
|
|
109
109
|
input: {
|
|
110
110
|
set: T.Installed;
|
|
111
|
+
values?: T.Values;
|
|
111
112
|
limits?: T.Limits;
|
|
112
113
|
platform?: T.Platform;
|
|
113
114
|
};
|
|
@@ -413,6 +414,46 @@ export interface Ops {
|
|
|
413
414
|
};
|
|
414
415
|
output: T.Running;
|
|
415
416
|
};
|
|
417
|
+
"weave.pin": {
|
|
418
|
+
input: {
|
|
419
|
+
installed: T.Installed;
|
|
420
|
+
plan: T.Plan;
|
|
421
|
+
project: T.Project;
|
|
422
|
+
lock?: T.Lock;
|
|
423
|
+
declared: T.Declared;
|
|
424
|
+
input: string;
|
|
425
|
+
tags: T.Tag[];
|
|
426
|
+
weave: T.Weave;
|
|
427
|
+
answers: T.Answer[];
|
|
428
|
+
};
|
|
429
|
+
output: T.Pinned;
|
|
430
|
+
};
|
|
431
|
+
"weave.pinned": {
|
|
432
|
+
input: {
|
|
433
|
+
path: string;
|
|
434
|
+
json: T.Json;
|
|
435
|
+
};
|
|
436
|
+
output: T.Result<T.Pinned, T.Diagnostic>;
|
|
437
|
+
};
|
|
438
|
+
"weave.stale": {
|
|
439
|
+
input: {
|
|
440
|
+
path: string;
|
|
441
|
+
pinned: T.Pinned;
|
|
442
|
+
installed: T.Installed;
|
|
443
|
+
plan: T.Plan;
|
|
444
|
+
lock?: T.Lock;
|
|
445
|
+
declared: T.Declared;
|
|
446
|
+
};
|
|
447
|
+
output: T.Result<null, T.Diagnostic>;
|
|
448
|
+
};
|
|
449
|
+
"weave.replan": {
|
|
450
|
+
input: {
|
|
451
|
+
path: string;
|
|
452
|
+
pinned: T.Pinned;
|
|
453
|
+
plan: T.Plan;
|
|
454
|
+
};
|
|
455
|
+
output: T.Result<T.Replanned, T.Diagnostic>;
|
|
456
|
+
};
|
|
416
457
|
"systemone.settings": {
|
|
417
458
|
input: {
|
|
418
459
|
door: T.Door;
|
package/dist/project.d.ts
CHANGED
|
@@ -58,6 +58,15 @@ export interface WeaveOptions<R = AnyReflexes> extends DecideOptions {
|
|
|
58
58
|
* runs the plan as it stands. Absent and reached: nothing runs. */
|
|
59
59
|
proceed?: ((plan: W.Weave) => boolean | Promise<boolean>) | undefined;
|
|
60
60
|
}
|
|
61
|
+
/** What `weave` takes for a plan read from a file — a `Pinned`, as `steps` returned it or as `JSON.parse` read it
|
|
62
|
+
* back — beside a step's handlers: the yes over the whole plan, asked whatever its verdict, since a file's numbers
|
|
63
|
+
* are whoever wrote them. Absent and reached: nothing runs, `unanswered`. The tags are the file's. */
|
|
64
|
+
export interface PinnedOptions<R = AnyReflexes> {
|
|
65
|
+
confirm?: WeaveOptions<R>["confirm"];
|
|
66
|
+
ask?: WeaveOptions<R>["ask"];
|
|
67
|
+
proceed?: ((pinned: W.Pinned) => boolean | Promise<boolean>) | undefined;
|
|
68
|
+
signal?: AbortSignal | undefined;
|
|
69
|
+
}
|
|
61
70
|
/** One round of a step as it ran: the decision the loop settled, the input its body saw, what became of it. */
|
|
62
71
|
export interface WovenRound<R = AnyReflexes> {
|
|
63
72
|
round: number;
|
|
@@ -120,10 +129,17 @@ export interface Project<R = AnyReflexes> {
|
|
|
120
129
|
/** The whole loop: decide; ask and fill until nothing is missing; confirm; run. */
|
|
121
130
|
handle(input: string, options?: DecideOptions & Handlers<R>): Promise<Handled<R>>;
|
|
122
131
|
/** One request read into its steps, each decided as `decide` decides one, ordered by the words, a result of
|
|
123
|
-
* one threaded into a later one: the plan
|
|
124
|
-
|
|
132
|
+
* one threaded into a later one, sealed as a plan file: the sentence, the plan with its verdict before anything
|
|
133
|
+
* runs, every answer the plan took and the pins they were gathered under. `JSON.stringify` writes it; `weave`
|
|
134
|
+
* takes it, here or on another machine with the same project. Runs nothing. */
|
|
135
|
+
steps(input: string, options?: DecideOptions): Promise<W.Pinned>;
|
|
125
136
|
/** The steps, what the plan asks first answered, then every step run stage by stage under the same handlers. */
|
|
126
137
|
weave(input: string, options?: WeaveOptions<R>): Promise<Woven<R>>;
|
|
138
|
+
/** A plan file run exactly: its pins checked against this project — a `DiagnosticError` names the first that
|
|
139
|
+
* moved and its fix — the plan made again from the file's answers under the file's gate and refused when it does
|
|
140
|
+
* not read the same, `proceed` asked, then every step run under the same handlers, a value bound at run time
|
|
141
|
+
* decided by this project's adapter. */
|
|
142
|
+
weave(pinned: W.Pinned, options?: PinnedOptions<R>): Promise<Woven<R>>;
|
|
127
143
|
}
|
|
128
144
|
/** A project from its root: its installed reflexes are what `Reflexes` from evoke.d.ts names, so R is written. */
|
|
129
145
|
export declare function load<R extends object = AnyReflexes>(options: {
|
package/dist/project.js
CHANGED
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
// once; never fetched, never written. On it: `with`, the same project over a vocabulary of the call's own — a
|
|
3
3
|
// tenant's words, their own plan in milliseconds; `decide`, one input asked, answered, read and gated; `fill`, an
|
|
4
4
|
// ask answered and gated again; `run`, the chosen call's body; `handle`, the whole loop; `steps`, one request
|
|
5
|
-
// read into steps
|
|
6
|
-
//
|
|
5
|
+
// read into steps and sealed as a plan file — the sentence, the answers, the pins — and `weave`, the steps run
|
|
6
|
+
// stage by stage under the same handlers, from a sentence or from such a file, whose pins are checked and whose
|
|
7
|
+
// plan is made again from its answers. In: LoadOptions; inputs; decisions; plan files. Out: a Project, decisions,
|
|
8
|
+
// results, plans.
|
|
7
9
|
import { realpathSync, statSync } from "node:fs";
|
|
8
10
|
import { homedir } from "node:os";
|
|
9
11
|
import { answered } from "./adapter.js";
|
|
@@ -24,6 +26,7 @@ export async function load(options) {
|
|
|
24
26
|
const lock = files.lock === undefined ? undefined : call("lock", { doc: { file: { type: "lock" }, toml: files.lock } }, "load()");
|
|
25
27
|
const adapter = options.adapter ?? (await named(project, root));
|
|
26
28
|
const reflexes = {};
|
|
29
|
+
const values = {};
|
|
27
30
|
const dirs = {};
|
|
28
31
|
const bodies = {};
|
|
29
32
|
const shipped = {};
|
|
@@ -39,6 +42,10 @@ export async function load(options) {
|
|
|
39
42
|
throw refused(name, `${name} is both in evoke.toml and passed to load`, { type: "remove", reflex: name });
|
|
40
43
|
}
|
|
41
44
|
const configured = held(project.config[name] ?? {});
|
|
45
|
+
for (const [key, setting] of Object.entries(project.config[name] ?? {})) {
|
|
46
|
+
if (setting.type === "plain")
|
|
47
|
+
(values[name] ??= {})[key] = setting.value;
|
|
48
|
+
}
|
|
42
49
|
if (location.type === "local") {
|
|
43
50
|
if (root === undefined)
|
|
44
51
|
throw refused(name, `${name} is a local reflex, but load has no root`, { type: "remove", reflex: name });
|
|
@@ -94,7 +101,7 @@ export async function load(options) {
|
|
|
94
101
|
}
|
|
95
102
|
const installed = { reflexes, vocab, adapter: adapter.id, evoke: call("version", {}) };
|
|
96
103
|
const platform = options.platform ?? PLATFORM;
|
|
97
|
-
return make({ installed, adapter, platform, dirs, bodies, shipped, local }, "load()");
|
|
104
|
+
return make({ installed, values, project, lock, adapter, platform, dirs, bodies, shipped, local }, "load()");
|
|
98
105
|
}
|
|
99
106
|
/** The adapter evoke.toml names, from its own subpath; a recording is never resolved by name. */
|
|
100
107
|
async function named(project, root) {
|
|
@@ -134,11 +141,12 @@ function word(name, doc, overlay) {
|
|
|
134
141
|
const effective = call("effective", { shipped: manifest, ...(yours === undefined ? {} : { yours }) });
|
|
135
142
|
return { wording: { ok: effective }, manifest };
|
|
136
143
|
}
|
|
137
|
-
/** How each configured key is held: the
|
|
144
|
+
/** How each configured key is held: plain, its value handed beside the set, or a variable and whether it is set —
|
|
145
|
+
* never a value, never a secret. */
|
|
138
146
|
function held(settings) {
|
|
139
147
|
const held = {};
|
|
140
148
|
for (const [key, setting] of Object.entries(settings)) {
|
|
141
|
-
held[key] = setting.type === "plain" ?
|
|
149
|
+
held[key] = setting.type === "plain" ? { type: "plain" } : { type: "env", var: setting.var, set: process.env[setting.var] !== undefined };
|
|
142
150
|
}
|
|
143
151
|
return held;
|
|
144
152
|
}
|
|
@@ -178,11 +186,14 @@ function askedFor(step, tags) {
|
|
|
178
186
|
const own = narrowed ? step.reflex : undefined;
|
|
179
187
|
return own === undefined ? { text: step.text, tags } : { text: step.text, only: own };
|
|
180
188
|
}
|
|
189
|
+
function gathering() {
|
|
190
|
+
return { answers: { decided: [] }, traces: new Map(), entries: [] };
|
|
191
|
+
}
|
|
181
192
|
/** The project over its ground: the set compiled, every reflex's status read off the plan. The implementation
|
|
182
193
|
* speaks the wire's shapes; the app's R lives on the interface alone. */
|
|
183
194
|
function make(ground, invoked) {
|
|
184
|
-
const { installed, adapter, platform, dirs, bodies, shipped, local } = ground;
|
|
185
|
-
const plan = call("compile", { set: installed, platform, ...(adapter.limits === undefined ? {} : { limits: adapter.limits }) }, invoked);
|
|
195
|
+
const { installed, values, project: owned, lock, adapter, platform, dirs, bodies, shipped, local } = ground;
|
|
196
|
+
const plan = call("compile", { set: installed, values, platform, ...(adapter.limits === undefined ? {} : { limits: adapter.limits }) }, invoked);
|
|
186
197
|
if (adapter.plan !== undefined && adapter.plan !== plan.digest) {
|
|
187
198
|
const message = `the recording was made against plan ${adapter.plan}, not ${plan.digest}`;
|
|
188
199
|
throw new DiagnosticError([{ message, fix: { type: "rerun" }, command: "replay(file, { record: jev() })" }]);
|
|
@@ -198,6 +209,8 @@ function make(ground, invoked) {
|
|
|
198
209
|
}
|
|
199
210
|
}
|
|
200
211
|
const gate = adapter.gate === undefined ? {} : { gate: adapter.gate };
|
|
212
|
+
const declared = { id: adapter.id, ...(adapter.limits === undefined ? {} : { limits: adapter.limits }), ...gate };
|
|
213
|
+
const locked = lock === undefined ? {} : { lock };
|
|
201
214
|
const project = {
|
|
202
215
|
reflexes,
|
|
203
216
|
plan: plan.digest,
|
|
@@ -218,12 +231,7 @@ function make(ground, invoked) {
|
|
|
218
231
|
},
|
|
219
232
|
async decide(input, options = {}) {
|
|
220
233
|
nonEmpty(input, "decide");
|
|
221
|
-
|
|
222
|
-
const request = call("request", { plan, input, tags: options.tags ?? [], ...(options.only === undefined ? {} : { only: options.only }), scope: "full" }, invoked);
|
|
223
|
-
const { raw, trace } = await answered(adapter, request, plan.deadline, options.signal, invoked);
|
|
224
|
-
const reading = call("read", { plan, request, raw }, invoked);
|
|
225
|
-
const decision = call("gate", { plan, reading, ...gate });
|
|
226
|
-
return lined(decision, { input, plan: plan.digest, trace: [trace] });
|
|
234
|
+
return (await decidedText(input, options)).decision;
|
|
227
235
|
},
|
|
228
236
|
fill(decision, given) {
|
|
229
237
|
const asking = own(decision, "fill");
|
|
@@ -269,19 +277,23 @@ function make(ground, invoked) {
|
|
|
269
277
|
},
|
|
270
278
|
async steps(input, options = {}) {
|
|
271
279
|
nonEmpty(input, "steps");
|
|
272
|
-
|
|
280
|
+
const gathered = gathering();
|
|
281
|
+
const weave = await planned(input, options, gathered);
|
|
282
|
+
return call("weave.pin", { installed, plan, project: owned, ...locked, declared, input, tags: options.tags ?? [], weave, answers: gathered.entries });
|
|
273
283
|
},
|
|
274
284
|
async weave(input, options = {}) {
|
|
285
|
+
if (typeof input !== "string")
|
|
286
|
+
return pinnedRun(input, options);
|
|
287
|
+
const handlers = options;
|
|
275
288
|
nonEmpty(input, "weave");
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
let woven = await planned(input, options, answers, traces);
|
|
289
|
+
const gathered = gathering();
|
|
290
|
+
let woven = await planned(input, handlers, gathered);
|
|
279
291
|
// What the plan asks before anything runs: a step's own question, answered, and the plan made again.
|
|
280
292
|
while (woven.verdict.outcome === "ask") {
|
|
281
|
-
const filled = await askedUpFront(woven, answers,
|
|
293
|
+
const filled = await askedUpFront(woven, gathered.answers, handlers, gathered.traces);
|
|
282
294
|
if (filled !== "filled")
|
|
283
295
|
return { plan: woven, status: filled, steps: [] };
|
|
284
|
-
const again = await planned(input,
|
|
296
|
+
const again = await planned(input, handlers, gathered);
|
|
285
297
|
// A plan that asks the same again could not take the answer: unanswered, never a loop.
|
|
286
298
|
if (JSON.stringify(again.verdict) === JSON.stringify(woven.verdict))
|
|
287
299
|
return { plan: again, status: "unanswered", steps: [] };
|
|
@@ -290,17 +302,28 @@ function make(ground, invoked) {
|
|
|
290
302
|
if (woven.verdict.outcome === "refuse")
|
|
291
303
|
return { plan: woven, status: "refused", steps: [] };
|
|
292
304
|
if (woven.verdict.outcome === "confirm") {
|
|
293
|
-
if (
|
|
305
|
+
if (handlers.proceed === undefined)
|
|
294
306
|
return { plan: woven, status: "unanswered", steps: [] };
|
|
295
|
-
if (!(await
|
|
307
|
+
if (!(await handlers.proceed(woven)))
|
|
296
308
|
return { plan: woven, status: "declined", steps: [] };
|
|
297
309
|
}
|
|
298
|
-
return executed(woven,
|
|
310
|
+
return executed(woven, handlers, gathered);
|
|
299
311
|
},
|
|
300
312
|
};
|
|
301
|
-
/**
|
|
302
|
-
async function
|
|
313
|
+
/** One text asked, answered, read and gated, its raw answers kept beside the decision — for the plan file. */
|
|
314
|
+
async function decidedText(input, options) {
|
|
315
|
+
const invoked = invocation(input);
|
|
316
|
+
const request = call("request", { plan, input, tags: options.tags ?? [], ...(options.only === undefined ? {} : { only: options.only }), scope: "full" }, invoked);
|
|
317
|
+
const { raw, trace } = await answered(adapter, request, plan.deadline, options.signal, invoked);
|
|
318
|
+
const reading = call("read", { plan, request, raw }, invoked);
|
|
319
|
+
const decision = call("gate", { plan, reading, ...gate });
|
|
320
|
+
return { decision: lined(decision, { input, plan: plan.digest, trace: [trace] }), raw };
|
|
321
|
+
}
|
|
322
|
+
/** The plan over the answers gathered so far: the adapter asked and texts decided until it stands, every answer
|
|
323
|
+
* kept as an entry of the plan file. */
|
|
324
|
+
async function planned(input, options, gathered) {
|
|
303
325
|
const invoked = `steps(${JSON.stringify(shown(input))})`;
|
|
326
|
+
const { answers, entries } = gathered;
|
|
304
327
|
for (;;) {
|
|
305
328
|
const planning = call("weave.plan", { plan, ...gate, input, tags: options.tags ?? [], answers }, invoked);
|
|
306
329
|
if (planning.type === "done")
|
|
@@ -308,26 +331,69 @@ function make(ground, invoked) {
|
|
|
308
331
|
const { need } = planning;
|
|
309
332
|
if (need.type === "decide") {
|
|
310
333
|
// Side by side: each text is its own adapter call.
|
|
311
|
-
|
|
334
|
+
const decisions = await Promise.all(need.asked.map(async (asked) => [asked, await decided(asked, options, gathered)]));
|
|
335
|
+
answers.decided.push(...decisions);
|
|
312
336
|
continue;
|
|
313
337
|
}
|
|
314
338
|
const { raw } = await answered(adapter, need.request, plan.deadline, options.signal, invoked);
|
|
339
|
+
entries.push({ text: need.request.state.request, raw });
|
|
315
340
|
if (need.type === "judge")
|
|
316
341
|
answers.judged = raw;
|
|
317
342
|
else
|
|
318
343
|
answers.referred = raw;
|
|
319
344
|
}
|
|
320
345
|
}
|
|
321
|
-
/** One text decided as the plan asks — over the tags, or one reflex alone — its trace kept by what was asked
|
|
322
|
-
|
|
323
|
-
|
|
346
|
+
/** One text decided as the plan asks — over the tags, or one reflex alone — its trace kept by what was asked and
|
|
347
|
+
* its raw answers as an entry. */
|
|
348
|
+
async function decided(asked, options, gathered) {
|
|
349
|
+
const { decision, raw } = await decidedText(asked.text, {
|
|
324
350
|
...(asked.only === undefined ? { tags: asked.tags ?? [] } : { only: asked.only }),
|
|
325
351
|
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
326
352
|
});
|
|
327
|
-
traces.set(key(asked), decision.trace);
|
|
353
|
+
gathered.traces.set(key(asked), decision.trace);
|
|
354
|
+
gathered.entries.push({ text: asked.text, raw });
|
|
328
355
|
// The whole decision crosses: the core reads its own fields and ignores the SDK's.
|
|
329
356
|
return decision;
|
|
330
357
|
}
|
|
358
|
+
/** A plan file run: read through the core, `plan = 1` required; its pins against this project, the first that
|
|
359
|
+
* moved refused; the plan made again from its answers under its gate, refused when it does not read the same;
|
|
360
|
+
* a plan that asks or refuses runs nothing, since a file holds no one's answers; then the yes over the whole
|
|
361
|
+
* plan, and every step under the handlers, a value bound at run time decided by this project's adapter. */
|
|
362
|
+
async function pinnedRun(json, options) {
|
|
363
|
+
const path = "plan";
|
|
364
|
+
const sentence = typeof json === "object" && json !== null && typeof json.input === "string" ? json.input : "<input>";
|
|
365
|
+
const pinned = planFile("weave.pinned", { path, json }, sentence);
|
|
366
|
+
planFile("weave.stale", { path, pinned, installed, plan, ...locked, declared }, pinned.input);
|
|
367
|
+
const replanned = planFile("weave.replan", { path, pinned, plan }, pinned.input);
|
|
368
|
+
const woven = replanned.weave;
|
|
369
|
+
if (woven.verdict.outcome === "ask")
|
|
370
|
+
return { plan: woven, status: "unanswered", steps: [] };
|
|
371
|
+
if (woven.verdict.outcome === "refuse")
|
|
372
|
+
return { plan: woven, status: "refused", steps: [] };
|
|
373
|
+
if (options.proceed === undefined)
|
|
374
|
+
return { plan: woven, status: "unanswered", steps: [] };
|
|
375
|
+
if (!(await options.proceed(pinned)))
|
|
376
|
+
return { plan: woven, status: "declined", steps: [] };
|
|
377
|
+
const handlers = {
|
|
378
|
+
tags: pinned.tags ?? [],
|
|
379
|
+
...(options.confirm === undefined ? {} : { confirm: options.confirm }),
|
|
380
|
+
...(options.ask === undefined ? {} : { ask: options.ask }),
|
|
381
|
+
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
382
|
+
};
|
|
383
|
+
return executed(woven, handlers, gathering());
|
|
384
|
+
}
|
|
385
|
+
/** One op over a plan file: its refusal a `DiagnosticError` whose save line reads as the call that makes the
|
|
386
|
+
* plan again here. */
|
|
387
|
+
function planFile(op, input, sentence) {
|
|
388
|
+
const answer = reply(op, input);
|
|
389
|
+
if ("ok" in answer)
|
|
390
|
+
return answer.ok;
|
|
391
|
+
if ("bug" in answer)
|
|
392
|
+
throw bug(answer.bug);
|
|
393
|
+
const diagnostic = answer.err;
|
|
394
|
+
const fixed = diagnostic.fix.type === "save" ? `steps(${JSON.stringify(shown(sentence))})` : command(diagnostic.fix);
|
|
395
|
+
throw new DiagnosticError([{ ...diagnostic, command: fixed }]);
|
|
396
|
+
}
|
|
331
397
|
/** The plan's own questions before anything runs. A step's required argument no binding covers is asked as
|
|
332
398
|
* `handle` asks one — the ask narrowed to what nothing binds — and the step's decision replaced for the plan
|
|
333
399
|
* to stand again. Several fields, or one record of several, no handler can answer: unanswered. */
|
|
@@ -378,9 +444,10 @@ function make(ground, invoked) {
|
|
|
378
444
|
* signal aborted mid-run is a cancel: every body's group ended, the rounds under way and every round after
|
|
379
445
|
* reported `skipped · cancelled`, and the rejection — the signal's reason — carrying the record once it is
|
|
380
446
|
* whole. */
|
|
381
|
-
async function executed(woven, options,
|
|
447
|
+
async function executed(woven, options, gathered) {
|
|
382
448
|
const invoked = `weave(${JSON.stringify(shown(woven.input))})`;
|
|
383
449
|
const { signal } = options;
|
|
450
|
+
const { traces } = gathered;
|
|
384
451
|
const progress = { decided: [], handled: [] };
|
|
385
452
|
const rounds = new Map();
|
|
386
453
|
const record = (handling, decision, became) => {
|
|
@@ -413,7 +480,7 @@ function make(ground, invoked) {
|
|
|
413
480
|
const { todo } = running;
|
|
414
481
|
if (todo.type === "decide") {
|
|
415
482
|
try {
|
|
416
|
-
progress.decided.push([todo.asked, await decided(todo.asked, options,
|
|
483
|
+
progress.decided.push([todo.asked, await decided(todo.asked, options, gathered)]);
|
|
417
484
|
}
|
|
418
485
|
catch (error) {
|
|
419
486
|
// The signal aborted the decision's call: the round it was for never starts.
|
package/dist/types.d.ts
CHANGED
|
@@ -157,6 +157,10 @@ export type Fix = {
|
|
|
157
157
|
type: "test";
|
|
158
158
|
} | {
|
|
159
159
|
type: "help";
|
|
160
|
+
} | {
|
|
161
|
+
type: "save";
|
|
162
|
+
file: string;
|
|
163
|
+
input: string;
|
|
160
164
|
};
|
|
161
165
|
/** A JSON value that keeps its key order: the wire form of every boundary type. */
|
|
162
166
|
export type Json = unknown;
|
|
@@ -583,15 +587,16 @@ export interface Item {
|
|
|
583
587
|
needs?: Needs;
|
|
584
588
|
configured: Record<ConfigKey, Held>;
|
|
585
589
|
}
|
|
586
|
-
/** How a set config key is held:
|
|
590
|
+
/** How a set config key is held: plain, its value handed to `compile` beside the set and never in it, or a variable that is set or not. Never a value, never a secret. */
|
|
587
591
|
export type Held = {
|
|
588
592
|
type: "plain";
|
|
589
|
-
value: string;
|
|
590
593
|
} | {
|
|
591
594
|
type: "env";
|
|
592
595
|
var: VarName;
|
|
593
596
|
set: boolean;
|
|
594
597
|
};
|
|
598
|
+
/** The plain settings' values, per reflex and key, as `evoke.toml` holds them: handed to `compile` beside the set, so the digest holds no value. */
|
|
599
|
+
export type Values = Record<LocalName, Record<ConfigKey, string>>;
|
|
595
600
|
/** A duration in milliseconds; the host makes it an instant. */
|
|
596
601
|
export type Millis = number;
|
|
597
602
|
/** The compiled set: the active reflexes, the inactive ones with a fix per problem, every input-independent question, and the digest that keys what is derived from it. */
|
|
@@ -1085,6 +1090,64 @@ export interface Executed {
|
|
|
1085
1090
|
steps: StepOutcome[];
|
|
1086
1091
|
worst: Status;
|
|
1087
1092
|
}
|
|
1093
|
+
/** A plan file: the sentence as typed, the plan, the pins it was decided under, and every engine answer it took. What
|
|
1094
|
+
* `steps` returns and `weave` takes; `JSON.stringify` writes it. No time, no name, no trace. */
|
|
1095
|
+
export interface Pinned {
|
|
1096
|
+
/** Fixed text, ignored on read. */
|
|
1097
|
+
note: string;
|
|
1098
|
+
/** The format revision: `1`. */
|
|
1099
|
+
plan: 1;
|
|
1100
|
+
/** The sentence as typed: what a re-plan plans, since the request as read is not always read the same. */
|
|
1101
|
+
input: string;
|
|
1102
|
+
/** Absent when none. */
|
|
1103
|
+
tags?: Tag[];
|
|
1104
|
+
weave: Weave;
|
|
1105
|
+
/** The evoke that wrote it. */
|
|
1106
|
+
evoke: Version;
|
|
1107
|
+
adapter: LockedAdapter;
|
|
1108
|
+
/** The floors the plan was decided under; absent when the adapter declared none. */
|
|
1109
|
+
gate?: Gate;
|
|
1110
|
+
/** The plan digest of the set it was decided over. */
|
|
1111
|
+
set: Digest;
|
|
1112
|
+
/** Every active reflex, by the hash of its item and its pin. */
|
|
1113
|
+
reflexes: Record<LocalName, PinnedReflex>;
|
|
1114
|
+
/** Every vocabulary, by the hash of its words. */
|
|
1115
|
+
vocab: Record<VocabName, Digest>;
|
|
1116
|
+
/** Every engine answer the plan took, one per text and question set. */
|
|
1117
|
+
answers: Answer[];
|
|
1118
|
+
}
|
|
1119
|
+
/** One reflex of the plan's set: the hash of its item — wording, consent, settings — and its pin: a remote one's
|
|
1120
|
+
* ref as the lock writes it, its tag and `h1`; a local one's path as written; a reflex handed as code its item alone. */
|
|
1121
|
+
export type PinnedReflex = {
|
|
1122
|
+
item: Digest;
|
|
1123
|
+
ref: string;
|
|
1124
|
+
tag: Version;
|
|
1125
|
+
h1: Digest;
|
|
1126
|
+
} | {
|
|
1127
|
+
item: Digest;
|
|
1128
|
+
path: string;
|
|
1129
|
+
} | {
|
|
1130
|
+
item: Digest;
|
|
1131
|
+
};
|
|
1132
|
+
/** One engine answer the plan took: the text it was asked about and the `Raw` as the engine gave it; the weave's own
|
|
1133
|
+
* questions stand under the whole request's text. */
|
|
1134
|
+
export interface Answer {
|
|
1135
|
+
text: string;
|
|
1136
|
+
raw: Raw;
|
|
1137
|
+
}
|
|
1138
|
+
/** The plan made again from a file: the weave, and per text what a line is rendered from. */
|
|
1139
|
+
export interface Replanned {
|
|
1140
|
+
weave: Weave;
|
|
1141
|
+
decided: Decided[];
|
|
1142
|
+
}
|
|
1143
|
+
/** One text decided from a file's answers: what was asked, the input's candidates, the raw answers, the decision. */
|
|
1144
|
+
export interface Decided {
|
|
1145
|
+
asked: Asked;
|
|
1146
|
+
/** Absent when none. */
|
|
1147
|
+
proposed?: Proposed[];
|
|
1148
|
+
raw: Raw;
|
|
1149
|
+
decision: Decision;
|
|
1150
|
+
}
|
|
1088
1151
|
/** What changed in the contract from one version to the next, and how much it matters. */
|
|
1089
1152
|
export interface ContractDiff {
|
|
1090
1153
|
level: Level;
|