@miller-tech/uap 1.27.0 → 1.29.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/dist/.tsbuildinfo +1 -1
- package/dist/bin/cli.js +5 -0
- package/dist/bin/cli.js.map +1 -1
- package/dist/cli/deliver.d.ts +5 -0
- package/dist/cli/deliver.d.ts.map +1 -1
- package/dist/cli/deliver.js +91 -10
- package/dist/cli/deliver.js.map +1 -1
- package/dist/delivery/applier.d.ts +11 -0
- package/dist/delivery/applier.d.ts.map +1 -1
- package/dist/delivery/applier.js +189 -6
- package/dist/delivery/applier.js.map +1 -1
- package/dist/delivery/convergence-loop.d.ts +75 -13
- package/dist/delivery/convergence-loop.d.ts.map +1 -1
- package/dist/delivery/convergence-loop.js +209 -58
- package/dist/delivery/convergence-loop.js.map +1 -1
- package/dist/delivery/critic.d.ts +35 -0
- package/dist/delivery/critic.d.ts.map +1 -0
- package/dist/delivery/critic.js +77 -0
- package/dist/delivery/critic.js.map +1 -0
- package/dist/delivery/escalation.d.ts +66 -0
- package/dist/delivery/escalation.d.ts.map +1 -0
- package/dist/delivery/escalation.js +84 -0
- package/dist/delivery/escalation.js.map +1 -0
- package/dist/delivery/explorer.d.ts +77 -0
- package/dist/delivery/explorer.d.ts.map +1 -0
- package/dist/delivery/explorer.js +166 -0
- package/dist/delivery/explorer.js.map +1 -0
- package/dist/delivery/index.d.ts +7 -2
- package/dist/delivery/index.d.ts.map +1 -1
- package/dist/delivery/index.js +6 -1
- package/dist/delivery/index.js.map +1 -1
- package/dist/delivery/judge.d.ts +33 -0
- package/dist/delivery/judge.d.ts.map +1 -0
- package/dist/delivery/judge.js +70 -0
- package/dist/delivery/judge.js.map +1 -0
- package/dist/delivery/practice.d.ts +72 -0
- package/dist/delivery/practice.d.ts.map +1 -0
- package/dist/delivery/practice.js +185 -0
- package/dist/delivery/practice.js.map +1 -0
- package/package.json +1 -1
package/dist/delivery/applier.js
CHANGED
|
@@ -12,11 +12,37 @@
|
|
|
12
12
|
* emitting complete files than unified diffs. Fences of 3+ backticks are
|
|
13
13
|
* supported so file contents containing ``` can be wrapped in ````.
|
|
14
14
|
*/
|
|
15
|
-
import { mkdirSync, writeFileSync } from 'fs';
|
|
15
|
+
import { existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, rmdirSync, rmSync, writeFileSync, } from 'fs';
|
|
16
16
|
import { dirname, isAbsolute, join, relative, resolve, sep } from 'path';
|
|
17
17
|
/** Max bytes a single emitted file may have (guards runaway generations). */
|
|
18
18
|
const MAX_FILE_BYTES = 1_000_000;
|
|
19
19
|
const FILE_BLOCK_RE = /^(`{3,})file:([^\n]+)\n([\s\S]*?)^\1\s*$/gm;
|
|
20
|
+
/**
|
|
21
|
+
* Paths the model is never allowed to write. The harness executes project
|
|
22
|
+
* scripts during gate verification, so a model-supplied build/test/lint
|
|
23
|
+
* command in package.json, a git/husky hook, or a CI workflow would be
|
|
24
|
+
* arbitrary code execution against the host. These are blocked outright;
|
|
25
|
+
* delivering a change that legitimately needs them is out of scope for an
|
|
26
|
+
* autonomous loop and must go through a human.
|
|
27
|
+
*/
|
|
28
|
+
const PROTECTED_SEGMENTS = new Set([
|
|
29
|
+
'.git',
|
|
30
|
+
'.husky',
|
|
31
|
+
'.github',
|
|
32
|
+
'.gitlab',
|
|
33
|
+
'.circleci',
|
|
34
|
+
'node_modules',
|
|
35
|
+
]);
|
|
36
|
+
const PROTECTED_BASENAMES = new Set([
|
|
37
|
+
'package.json',
|
|
38
|
+
'package-lock.json',
|
|
39
|
+
'npm-shrinkwrap.json',
|
|
40
|
+
'yarn.lock',
|
|
41
|
+
'pnpm-lock.yaml',
|
|
42
|
+
'.npmrc',
|
|
43
|
+
'.yarnrc',
|
|
44
|
+
'.yarnrc.yml',
|
|
45
|
+
]);
|
|
20
46
|
/** Extract file blocks from model output without writing anything. */
|
|
21
47
|
export function parseFileBlocks(output) {
|
|
22
48
|
const blocks = [];
|
|
@@ -28,17 +54,73 @@ export function parseFileBlocks(output) {
|
|
|
28
54
|
}
|
|
29
55
|
return blocks;
|
|
30
56
|
}
|
|
31
|
-
|
|
57
|
+
/**
|
|
58
|
+
* Resolve `target`'s parent to its real (symlink-followed) location and
|
|
59
|
+
* confirm it stays inside the project root. Lexical checks alone let a
|
|
60
|
+
* pre-existing symlink inside the repo redirect a write outside it.
|
|
61
|
+
*/
|
|
62
|
+
function realParentEscapes(target, realRoot) {
|
|
63
|
+
let dir = dirname(target);
|
|
64
|
+
// Walk up to the nearest existing ancestor (target/intermediate dirs may
|
|
65
|
+
// not exist yet) and realpath that.
|
|
66
|
+
while (!existsSync(dir)) {
|
|
67
|
+
const parent = dirname(dir);
|
|
68
|
+
if (parent === dir)
|
|
69
|
+
break;
|
|
70
|
+
dir = parent;
|
|
71
|
+
}
|
|
72
|
+
let realDir;
|
|
73
|
+
try {
|
|
74
|
+
realDir = realpathSync(dir);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
const rel = relative(realRoot, realDir);
|
|
80
|
+
return rel === '..' || rel.startsWith(`..${sep}`) || isAbsolute(rel);
|
|
81
|
+
}
|
|
82
|
+
function validatePath(blockPath, projectRoot, realRoot) {
|
|
32
83
|
if (isAbsolute(blockPath))
|
|
33
84
|
return 'absolute paths are not allowed';
|
|
34
85
|
const target = resolve(projectRoot, blockPath);
|
|
35
86
|
const rel = relative(resolve(projectRoot), target);
|
|
36
|
-
if (rel.startsWith(
|
|
87
|
+
if (rel === '..' || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {
|
|
37
88
|
return 'path escapes the project root';
|
|
38
|
-
|
|
39
|
-
|
|
89
|
+
}
|
|
90
|
+
// Block protected segments anywhere in the path (case-insensitive), and
|
|
91
|
+
// protected basenames. Closes config/hook/CI-driven code execution.
|
|
92
|
+
const segments = rel.split(sep);
|
|
93
|
+
for (const seg of segments) {
|
|
94
|
+
if (PROTECTED_SEGMENTS.has(seg.toLowerCase())) {
|
|
95
|
+
return `writes into ${seg} are not allowed`;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const base = segments[segments.length - 1].toLowerCase();
|
|
99
|
+
if (PROTECTED_BASENAMES.has(base)) {
|
|
100
|
+
return `writes to ${base} are not allowed (would alter executed scripts)`;
|
|
101
|
+
}
|
|
102
|
+
// Reject writing through an existing symlink, and any symlinked ancestor.
|
|
103
|
+
try {
|
|
104
|
+
if (existsSync(target) && lstatSync(target).isSymbolicLink()) {
|
|
105
|
+
return 'target is a symlink';
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
return 'could not stat target';
|
|
110
|
+
}
|
|
111
|
+
if (realParentEscapes(target, realRoot)) {
|
|
112
|
+
return 'path resolves outside the project root via a symlink';
|
|
113
|
+
}
|
|
40
114
|
return null;
|
|
41
115
|
}
|
|
116
|
+
function realRootOf(projectRoot) {
|
|
117
|
+
try {
|
|
118
|
+
return realpathSync(resolve(projectRoot));
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return resolve(projectRoot);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
42
124
|
/**
|
|
43
125
|
* Default applier: parse file blocks and write them under projectRoot.
|
|
44
126
|
* Paths are validated against traversal and .git writes; oversized files
|
|
@@ -53,10 +135,11 @@ export function applyFileBlocks(output, projectRoot) {
|
|
|
53
135
|
error: 'No file blocks found in the output. Emit every created/modified file as a fenced block: ```file:relative/path … ```',
|
|
54
136
|
};
|
|
55
137
|
}
|
|
138
|
+
const realRoot = realRootOf(projectRoot);
|
|
56
139
|
const filesWritten = [];
|
|
57
140
|
const rejected = [];
|
|
58
141
|
for (const block of blocks) {
|
|
59
|
-
const invalid = validatePath(block.path, projectRoot);
|
|
142
|
+
const invalid = validatePath(block.path, projectRoot, realRoot);
|
|
60
143
|
if (invalid) {
|
|
61
144
|
rejected.push({ path: block.path, reason: invalid });
|
|
62
145
|
continue;
|
|
@@ -72,4 +155,104 @@ export function applyFileBlocks(output, projectRoot) {
|
|
|
72
155
|
}
|
|
73
156
|
return { filesWritten, rejected };
|
|
74
157
|
}
|
|
158
|
+
/** Topmost directory segments that did not exist before applying `paths`. */
|
|
159
|
+
function newDirsFor(paths, projectRoot) {
|
|
160
|
+
const created = new Set();
|
|
161
|
+
for (const path of paths) {
|
|
162
|
+
const segments = path.split(sep);
|
|
163
|
+
let current = projectRoot;
|
|
164
|
+
for (let i = 0; i < segments.length - 1; i++) {
|
|
165
|
+
current = join(current, segments[i]);
|
|
166
|
+
if (!existsSync(current))
|
|
167
|
+
created.add(current);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Deepest first so rmdir succeeds bottom-up
|
|
171
|
+
return [...created].sort((a, b) => b.length - a.length);
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Apply file blocks with a snapshot of the prior state of every target, so
|
|
175
|
+
* the application can be undone. Used by the explorer to evaluate competing
|
|
176
|
+
* candidates against the same baseline tree without git machinery.
|
|
177
|
+
*/
|
|
178
|
+
export function applyFileBlocksWithRollback(output, projectRoot) {
|
|
179
|
+
const blocks = parseFileBlocks(output);
|
|
180
|
+
const realRoot = realRootOf(projectRoot);
|
|
181
|
+
// Snapshot prior content (or absence) of every valid target, and the set
|
|
182
|
+
// of directories that do not yet exist, BEFORE writing anything.
|
|
183
|
+
const snapshots = new Map();
|
|
184
|
+
const validPaths = [];
|
|
185
|
+
for (const block of blocks) {
|
|
186
|
+
if (validatePath(block.path, projectRoot, realRoot))
|
|
187
|
+
continue;
|
|
188
|
+
const target = join(projectRoot, block.path);
|
|
189
|
+
if (!snapshots.has(block.path)) {
|
|
190
|
+
snapshots.set(block.path, existsSync(target) ? readFileSync(target, 'utf-8') : null);
|
|
191
|
+
validPaths.push(block.path);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
const newDirs = newDirsFor(validPaths, projectRoot);
|
|
195
|
+
// Track what actually hit disk so an exception mid-apply still rolls back.
|
|
196
|
+
const written = [];
|
|
197
|
+
let restored = false;
|
|
198
|
+
const restore = () => {
|
|
199
|
+
if (restored)
|
|
200
|
+
return;
|
|
201
|
+
restored = true;
|
|
202
|
+
for (const path of written) {
|
|
203
|
+
const target = join(projectRoot, path);
|
|
204
|
+
const prior = snapshots.get(path);
|
|
205
|
+
if (prior === null || prior === undefined) {
|
|
206
|
+
rmSync(target, { force: true });
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
writeFileSync(target, prior, 'utf-8');
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
for (const dir of newDirs) {
|
|
213
|
+
try {
|
|
214
|
+
rmdirSync(dir); // empty-only — throws (caught) if a surviving file remains
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
// Non-empty (a surviving file lives here) or already gone — leave it.
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
};
|
|
221
|
+
let result;
|
|
222
|
+
try {
|
|
223
|
+
// Re-implement the write loop here so `written` reflects partial progress.
|
|
224
|
+
if (blocks.length === 0) {
|
|
225
|
+
result = {
|
|
226
|
+
filesWritten: [],
|
|
227
|
+
rejected: [],
|
|
228
|
+
error: 'No file blocks found in the output. Emit every created/modified file as a fenced block: ```file:relative/path … ```',
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
const rejected = [];
|
|
233
|
+
for (const block of blocks) {
|
|
234
|
+
const invalid = validatePath(block.path, projectRoot, realRoot);
|
|
235
|
+
if (invalid) {
|
|
236
|
+
rejected.push({ path: block.path, reason: invalid });
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
if (Buffer.byteLength(block.content, 'utf-8') > MAX_FILE_BYTES) {
|
|
240
|
+
rejected.push({ path: block.path, reason: `file exceeds ${MAX_FILE_BYTES} bytes` });
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
const target = join(projectRoot, block.path);
|
|
244
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
245
|
+
writeFileSync(target, block.content, 'utf-8');
|
|
246
|
+
if (!written.includes(block.path))
|
|
247
|
+
written.push(block.path);
|
|
248
|
+
}
|
|
249
|
+
result = { filesWritten: [...written], rejected };
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
catch (err) {
|
|
253
|
+
restore();
|
|
254
|
+
throw err;
|
|
255
|
+
}
|
|
256
|
+
return { result, restore };
|
|
257
|
+
}
|
|
75
258
|
//# sourceMappingURL=applier.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"applier.js","sourceRoot":"","sources":["../../src/delivery/applier.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"applier.js","sourceRoot":"","sources":["../../src/delivery/applier.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Convergence Loop
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Drives an underlying model through execute → apply → verify → feedback
|
|
5
|
+
* iterations until the project's completion gates (verifier ladder) pass or
|
|
6
|
+
* the turn budget is exhausted.
|
|
7
7
|
*
|
|
8
|
-
* The loop owns
|
|
9
|
-
* changes:
|
|
8
|
+
* The loop owns pluggable seams so phases extend without breaking changes:
|
|
10
9
|
* - executor: how a prompt becomes model output
|
|
11
10
|
* - applier: how model output is materialized into the project tree
|
|
12
|
-
* - promptBuilder: how instruction/feedback/
|
|
13
|
-
*
|
|
14
|
-
* -
|
|
15
|
-
*
|
|
11
|
+
* - promptBuilder: how instruction/feedback/critique compose a prompt
|
|
12
|
+
* - ladderRunner: how gates are verified
|
|
13
|
+
* - explorer (Phase 2): best-of-N candidate exploration with judge tie-break
|
|
14
|
+
* - critic (Phase 3): structured repair plans replacing raw gate dumps
|
|
15
|
+
* - onIteration: per-turn control hook (Phase 5 escalation controllers)
|
|
16
16
|
*/
|
|
17
17
|
import type { GateRung, LadderResult, LadderOptions } from './verifier-ladder.js';
|
|
18
18
|
import type { Applier } from './applier.js';
|
|
19
|
+
import type { StrategySeed } from './explorer.js';
|
|
20
|
+
import type { Judge } from './judge.js';
|
|
21
|
+
import type { Critic } from './critic.js';
|
|
19
22
|
export type LoopExecutor = (prompt: string) => Promise<string>;
|
|
20
23
|
/** Pluggable ladder runner — production uses runLadder, tests inject a stub. */
|
|
21
24
|
export type LadderRunner = (rungs: GateRung[], projectRoot: string, options?: LadderOptions) => LadderResult | Promise<LadderResult>;
|
|
@@ -23,7 +26,7 @@ export interface PromptContext {
|
|
|
23
26
|
instruction: string;
|
|
24
27
|
/** 1-based turn about to execute */
|
|
25
28
|
turn: number;
|
|
26
|
-
/** Model output from the previous turn (
|
|
29
|
+
/** Model output from the previous turn (truncated) */
|
|
27
30
|
previousOutput?: string;
|
|
28
31
|
/** Gate feedback from the previous turn's ladder run */
|
|
29
32
|
feedback?: string;
|
|
@@ -31,8 +34,19 @@ export interface PromptContext {
|
|
|
31
34
|
applyError?: string;
|
|
32
35
|
/** Files written by the previous turn */
|
|
33
36
|
previousFiles?: string[];
|
|
37
|
+
/** Structured repair steps from the critic (Phase 3) */
|
|
38
|
+
critique?: string[];
|
|
39
|
+
/** Best-practice guidance retrieved for this task (Phase 4) */
|
|
40
|
+
practices?: string[];
|
|
34
41
|
}
|
|
35
42
|
export type PromptBuilder = (context: PromptContext) => string;
|
|
43
|
+
export interface CandidateSummary {
|
|
44
|
+
id: string;
|
|
45
|
+
strategy: string;
|
|
46
|
+
passed: boolean;
|
|
47
|
+
score: number;
|
|
48
|
+
error?: string;
|
|
49
|
+
}
|
|
36
50
|
export interface IterationRecord {
|
|
37
51
|
/** Real 1-based loop turn (executor-error turns are recorded too) */
|
|
38
52
|
turn: number;
|
|
@@ -46,6 +60,12 @@ export interface IterationRecord {
|
|
|
46
60
|
executorError?: string;
|
|
47
61
|
/** Apply failure, if output could not be materialized */
|
|
48
62
|
applyError?: string;
|
|
63
|
+
/** Strategy seed of the committed candidate (explorer mode) */
|
|
64
|
+
strategy?: string;
|
|
65
|
+
/** All candidates evaluated this turn (explorer mode) */
|
|
66
|
+
candidates?: CandidateSummary[];
|
|
67
|
+
/** Judge rationale when a tie-break decided the winner (explorer mode) */
|
|
68
|
+
judgeRationale?: string;
|
|
49
69
|
durationMs: number;
|
|
50
70
|
}
|
|
51
71
|
export interface DeliveryResult {
|
|
@@ -64,6 +84,34 @@ export interface DeliveryResult {
|
|
|
64
84
|
finalOutput: string;
|
|
65
85
|
totalDurationMs: number;
|
|
66
86
|
}
|
|
87
|
+
export interface ExplorerSettings {
|
|
88
|
+
/** Candidates per turn (default 3) */
|
|
89
|
+
candidates?: number;
|
|
90
|
+
seeds?: StrategySeed[];
|
|
91
|
+
judge?: Judge;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Directive returned from onIteration to steer the loop (Phase 5).
|
|
95
|
+
* All fields are optional; an empty object (or void) means "continue".
|
|
96
|
+
* 'stop' (string) remains supported for backward compatibility.
|
|
97
|
+
*/
|
|
98
|
+
export interface IterationDirective {
|
|
99
|
+
/** Abort the loop after this turn */
|
|
100
|
+
stop?: boolean;
|
|
101
|
+
/** Raise the turn budget to this absolute value (ignored if ≤ current) */
|
|
102
|
+
raiseMaxTurns?: number;
|
|
103
|
+
/** Enable/resize best-of-N exploration starting next turn */
|
|
104
|
+
setCandidates?: number;
|
|
105
|
+
/** Turn the structured critic on starting next turn */
|
|
106
|
+
enableCritic?: boolean;
|
|
107
|
+
/** Swap the model/executor (model escalation) */
|
|
108
|
+
switchExecutor?: LoopExecutor;
|
|
109
|
+
/** Human-readable reason, surfaced in logs and the iteration record */
|
|
110
|
+
note?: string;
|
|
111
|
+
}
|
|
112
|
+
export type OnIteration = (record: IterationRecord) => void | 'stop' | IterationDirective;
|
|
113
|
+
/** Retrieve best-practice guidance for a task (Phase 4). */
|
|
114
|
+
export type PracticeProvider = (instruction: string) => string[] | Promise<string[]>;
|
|
67
115
|
export interface ConvergenceConfig {
|
|
68
116
|
/** Maximum execute→apply→verify iterations (default 5) */
|
|
69
117
|
maxTurns?: number;
|
|
@@ -82,11 +130,21 @@ export interface ConvergenceConfig {
|
|
|
82
130
|
baselineCheck?: boolean;
|
|
83
131
|
/** Max characters of prior model output included in retry prompts (default 3000) */
|
|
84
132
|
previousOutputChars?: number;
|
|
133
|
+
/** Best-of-N exploration per turn (Phase 2); omit for single-candidate turns */
|
|
134
|
+
explorer?: ExplorerSettings;
|
|
135
|
+
/** Structured critique of failed turns (Phase 3) */
|
|
136
|
+
critic?: Critic;
|
|
137
|
+
/** Best-practice guidance injected into prompts (Phase 4) */
|
|
138
|
+
practiceProvider?: PracticeProvider;
|
|
139
|
+
/** Factory the escalation controller uses to build a critic when it
|
|
140
|
+
* enables one mid-run (Phase 5). Receives the current executor so the
|
|
141
|
+
* critic uses the same (possibly escalated) model as generation. */
|
|
142
|
+
criticFactory?: (executor: LoopExecutor) => Critic;
|
|
85
143
|
/**
|
|
86
|
-
* Called after every iteration. Return 'stop'
|
|
87
|
-
* (Phase 5 escalation controllers hook in here).
|
|
144
|
+
* Called after every iteration. Return 'stop' or an IterationDirective to
|
|
145
|
+
* steer the loop (Phase 5 escalation controllers hook in here).
|
|
88
146
|
*/
|
|
89
|
-
onIteration?:
|
|
147
|
+
onIteration?: OnIteration;
|
|
90
148
|
}
|
|
91
149
|
/** Default prompt strategy: lean contract + structured retry context. */
|
|
92
150
|
export declare const defaultPromptBuilder: PromptBuilder;
|
|
@@ -101,6 +159,10 @@ export declare class ConvergenceLoop {
|
|
|
101
159
|
applier?: Applier;
|
|
102
160
|
promptBuilder?: PromptBuilder;
|
|
103
161
|
});
|
|
162
|
+
/** Single-candidate turn: execute → apply → verify. */
|
|
163
|
+
private runSingleTurn;
|
|
164
|
+
/** Explorer turn: best-of-N candidates, commit the winner (Phase 2). */
|
|
165
|
+
private runExplorerTurn;
|
|
104
166
|
/**
|
|
105
167
|
* Run the loop for an instruction until all required gates pass or the
|
|
106
168
|
* turn budget is exhausted. Returns the full iteration history so callers
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"convergence-loop.d.ts","sourceRoot":"","sources":["../../src/delivery/convergence-loop.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAElF,OAAO,KAAK,EAAE,OAAO,EAAe,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"convergence-loop.d.ts","sourceRoot":"","sources":["../../src/delivery/convergence-loop.ts"],"names":[],"mappings":"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"}
|