-
Notifications
You must be signed in to change notification settings - Fork 35
/
Loop.ts
72 lines (57 loc) · 1.72 KB
/
Loop.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import { Run } from "../agent/Run";
import { Step } from "./Step";
import { StepResult } from "./StepResult";
export abstract class Loop<RUN_STATE> extends Step<RUN_STATE> {
readonly completedSteps: Array<Step<RUN_STATE>> = [];
constructor({ type, run }: { type: string; run: Run<RUN_STATE> }) {
super({ type, run });
}
protected abstract hasMoreSteps(): boolean;
protected abstract getNextStep(): PromiseLike<Step<RUN_STATE>>;
protected async update({
step,
result,
}: {
step: Step<RUN_STATE>;
result: StepResult & {
type: "succeeded" | "failed";
};
}): Promise<void> {
return Promise.resolve();
}
protected async getResult(): Promise<StepResult> {
return { type: "succeeded", summary: "Completed all tasks." };
}
protected async _execute(): Promise<StepResult> {
try {
while (this.hasMoreSteps()) {
const cancelCheck = this.run.checkCancel();
if (cancelCheck.shouldCancel) {
return { type: "cancelled", reason: cancelCheck.reason };
}
this.run.onLoopIterationStarted({ loop: this });
const step = await this.getNextStep();
const result = await step.execute();
this.completedSteps.push(step);
if (result.type === "cancelled") {
return result;
}
await this.update({ step, result });
this.run.onLoopIterationFinished({ loop: this });
}
} catch (error) {
return {
type: "failed",
summary: `Failed to run step`, // TODO better summary
error,
};
}
return this.getResult();
}
getStepCount(): number {
return this.completedSteps.reduce(
(sum, step) => sum + step.getStepCount(),
0
);
}
}