@autobe/agent 0.11.2 → 0.12.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/lib/AutoBeAgent.d.ts +3 -146
- package/lib/AutoBeAgent.js +6 -180
- package/lib/AutoBeAgent.js.map +1 -1
- package/lib/AutoBeAgentBase.d.ts +18 -0
- package/lib/AutoBeAgentBase.js +54 -0
- package/lib/AutoBeAgentBase.js.map +1 -0
- package/lib/AutoBeMockAgent.d.ts +14 -0
- package/lib/AutoBeMockAgent.js +135 -0
- package/lib/AutoBeMockAgent.js.map +1 -0
- package/lib/constants/AutoBeSystemPromptConstant.d.ts +8 -4
- package/lib/constants/AutoBeSystemPromptConstant.js.map +1 -1
- package/lib/factory/getAutoBeGenerated.d.ts +3 -4
- package/lib/factory/getAutoBeGenerated.js +6 -250
- package/lib/factory/getAutoBeGenerated.js.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +883 -399
- package/lib/index.mjs.map +1 -1
- package/lib/orchestrate/analyze/orchestrateAnalyze.js +6 -1
- package/lib/orchestrate/analyze/orchestrateAnalyze.js.map +1 -1
- package/lib/orchestrate/analyze/writeDocumentUntilReviewPassed.d.ts +4 -1
- package/lib/orchestrate/analyze/writeDocumentUntilReviewPassed.js +6 -2
- package/lib/orchestrate/analyze/writeDocumentUntilReviewPassed.js.map +1 -1
- package/lib/orchestrate/realize/orchestrateRealize.js +11 -2
- package/lib/orchestrate/realize/orchestrateRealize.js.map +1 -1
- package/lib/orchestrate/realize/orchestrateRealizeCoder.js +46 -15
- package/lib/orchestrate/realize/orchestrateRealizeCoder.js.map +1 -1
- package/lib/orchestrate/realize/orchestrateRealizeDecorator.d.ts +10 -0
- package/lib/orchestrate/realize/orchestrateRealizeDecorator.js +545 -0
- package/lib/orchestrate/realize/orchestrateRealizeDecorator.js.map +1 -0
- package/lib/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.d.ts +12 -9
- package/lib/orchestrate/realize/structures/IAutoBeRealizeDecoratorApplication.d.ts +85 -0
- package/lib/orchestrate/realize/structures/IAutoBeRealizeDecoratorApplication.js +3 -0
- package/lib/orchestrate/realize/structures/IAutoBeRealizeDecoratorApplication.js.map +1 -0
- package/lib/orchestrate/realize/transformRealizeCoderHistories.d.ts +1 -1
- package/lib/orchestrate/realize/transformRealizeCoderHistories.js +24 -30
- package/lib/orchestrate/realize/transformRealizeCoderHistories.js.map +1 -1
- package/lib/orchestrate/realize/transformRealizeDecorator.d.ts +4 -0
- package/lib/orchestrate/realize/transformRealizeDecorator.js +32 -0
- package/lib/orchestrate/realize/transformRealizeDecorator.js.map +1 -0
- package/lib/orchestrate/realize/transformRealizeDecoratorCorrectHistories.d.ts +6 -0
- package/lib/orchestrate/realize/transformRealizeDecoratorCorrectHistories.js +49 -0
- package/lib/orchestrate/realize/transformRealizeDecoratorCorrectHistories.js.map +1 -0
- package/lib/orchestrate/realize/writeCodeUntilCompilePassed.js +30 -11
- package/lib/orchestrate/realize/writeCodeUntilCompilePassed.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTest.js.map +1 -1
- package/lib/orchestrate/test/orchestrateTestCorrect.js +2 -1
- package/lib/orchestrate/test/orchestrateTestCorrect.js.map +1 -1
- package/lib/utils/backoffRetry.d.ts +18 -0
- package/lib/utils/backoffRetry.js +38 -0
- package/lib/utils/backoffRetry.js.map +1 -1
- package/package.json +8 -8
- package/src/AutoBeAgent.ts +10 -203
- package/src/AutoBeAgentBase.ts +78 -0
- package/src/AutoBeMockAgent.ts +163 -0
- package/src/constants/AutoBeSystemPromptConstant.ts +8 -4
- package/src/factory/getAutoBeGenerated.ts +8 -13
- package/src/index.ts +3 -1
- package/src/orchestrate/analyze/orchestrateAnalyze.ts +7 -1
- package/src/orchestrate/analyze/writeDocumentUntilReviewPassed.ts +8 -0
- package/src/orchestrate/realize/orchestrateRealize.ts +11 -0
- package/src/orchestrate/realize/orchestrateRealizeCoder.ts +26 -4
- package/src/orchestrate/realize/orchestrateRealizeDecorator.ts +286 -0
- package/src/orchestrate/realize/structures/IAutoBeRealizeCoderApplication.ts +12 -9
- package/src/orchestrate/realize/structures/IAutoBeRealizeDecoratorApplication.ts +94 -0
- package/src/orchestrate/realize/transformRealizeCoderHistories.ts +22 -29
- package/src/orchestrate/realize/transformRealizeDecorator.ts +37 -0
- package/src/orchestrate/realize/transformRealizeDecoratorCorrectHistories.ts +58 -0
- package/src/orchestrate/realize/writeCodeUntilCompilePassed.ts +34 -9
- package/src/orchestrate/test/orchestrateTest.ts +1 -0
- package/src/orchestrate/test/orchestrateTestCorrect.ts +1 -1
- package/src/utils/backoffRetry.ts +56 -0
|
@@ -12,7 +12,6 @@ export const transformRealizeCoderHistories = (
|
|
|
12
12
|
props: RealizePlannerOutput,
|
|
13
13
|
artifacts: IAutoBeTestScenarioArtifacts,
|
|
14
14
|
previous: string | null,
|
|
15
|
-
total: IAutoBeTypeScriptCompileResult.IDiagnostic[],
|
|
16
15
|
diagnostics: IAutoBeTypeScriptCompileResult.IDiagnostic[],
|
|
17
16
|
): Array<
|
|
18
17
|
IAgenticaHistoryJson.IAssistantMessage | IAgenticaHistoryJson.ISystemMessage
|
|
@@ -90,31 +89,7 @@ export const transformRealizeCoderHistories = (
|
|
|
90
89
|
id: v4(),
|
|
91
90
|
created_at: new Date().toISOString(),
|
|
92
91
|
type: "systemMessage",
|
|
93
|
-
text: AutoBeSystemPromptConstant.
|
|
94
|
-
},
|
|
95
|
-
{
|
|
96
|
-
id: v4(),
|
|
97
|
-
created_at: new Date().toISOString(),
|
|
98
|
-
type: "systemMessage",
|
|
99
|
-
text: AutoBeSystemPromptConstant.REALIZE_CODER_TYPESCRIPT,
|
|
100
|
-
},
|
|
101
|
-
{
|
|
102
|
-
id: v4(),
|
|
103
|
-
created_at: new Date().toISOString(),
|
|
104
|
-
type: "systemMessage",
|
|
105
|
-
text: AutoBeSystemPromptConstant.REALIZE_CODER_PRISMA,
|
|
106
|
-
},
|
|
107
|
-
{
|
|
108
|
-
id: v4(),
|
|
109
|
-
created_at: new Date().toISOString(),
|
|
110
|
-
type: "systemMessage",
|
|
111
|
-
text: AutoBeSystemPromptConstant.REALIZE_CODER_BROWSER,
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
id: v4(),
|
|
115
|
-
created_at: new Date().toISOString(),
|
|
116
|
-
type: "systemMessage",
|
|
117
|
-
text: AutoBeSystemPromptConstant.REALIZE_CODER_TYPIA,
|
|
92
|
+
text: AutoBeSystemPromptConstant.REALIZE_CODER_TOTAL,
|
|
118
93
|
},
|
|
119
94
|
{
|
|
120
95
|
id: v4(),
|
|
@@ -125,8 +100,8 @@ export const transformRealizeCoderHistories = (
|
|
|
125
100
|
JSON.stringify(state.prisma.schemas),
|
|
126
101
|
)
|
|
127
102
|
.replaceAll(`{artifacts_sdk}`, JSON.stringify(artifacts.sdk))
|
|
128
|
-
.replaceAll(`{artifacts_dto}`, JSON.stringify(artifacts.dto))
|
|
129
|
-
|
|
103
|
+
.replaceAll(`{artifacts_dto}`, JSON.stringify(artifacts.dto)),
|
|
104
|
+
// .replaceAll(`{artifacts_document}`, JSON.stringify(artifacts.document)),
|
|
130
105
|
},
|
|
131
106
|
...(previous !== null
|
|
132
107
|
? [
|
|
@@ -138,7 +113,7 @@ export const transformRealizeCoderHistories = (
|
|
|
138
113
|
`{code}`,
|
|
139
114
|
previous,
|
|
140
115
|
)
|
|
141
|
-
.replaceAll("{total_diagnostics}", JSON.stringify(total))
|
|
116
|
+
// .replaceAll("{total_diagnostics}", JSON.stringify(total))
|
|
142
117
|
.replaceAll("{current_diagnostics}", JSON.stringify(diagnostics)),
|
|
143
118
|
} as const,
|
|
144
119
|
]
|
|
@@ -156,5 +131,23 @@ export const transformRealizeCoderHistories = (
|
|
|
156
131
|
"```",
|
|
157
132
|
].join("\n"),
|
|
158
133
|
},
|
|
134
|
+
{
|
|
135
|
+
id: v4(),
|
|
136
|
+
created_at: new Date().toISOString(),
|
|
137
|
+
type: "assistantMessage",
|
|
138
|
+
text: [
|
|
139
|
+
`I understand your request.`,
|
|
140
|
+
``,
|
|
141
|
+
`To summarize:`,
|
|
142
|
+
`- I must **never use the native \`Date\` type** in any code or type definitions.`,
|
|
143
|
+
`- Instead, all date and datetime values must be handled as \`string & tags.Format<'date-time'>\`.`,
|
|
144
|
+
`- This rule is **strict** and applies everywhere, including domain types, API inputs/outputs, and Prisma models.`,
|
|
145
|
+
`- Even if a library or tool returns a \`Date\`, I must convert it to the correct string format before use.`,
|
|
146
|
+
``,
|
|
147
|
+
`Especially regarding the \`Date\` type: I understand that using it can lead to type inconsistency and runtime issues, so I will completely avoid it in all circumstances.`,
|
|
148
|
+
``,
|
|
149
|
+
`I'll make sure to follow all these rules strictly. Let’s proceed with this in mind.`,
|
|
150
|
+
].join("\n"),
|
|
151
|
+
},
|
|
159
152
|
];
|
|
160
153
|
};
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { IAgenticaHistoryJson } from "@agentica/core";
|
|
2
|
+
import { ILlmSchema } from "@samchon/openapi";
|
|
3
|
+
import { v4 } from "uuid";
|
|
4
|
+
|
|
5
|
+
import { AutoBeSystemPromptConstant } from "../../constants/AutoBeSystemPromptConstant";
|
|
6
|
+
import { AutoBeContext } from "../../context/AutoBeContext";
|
|
7
|
+
|
|
8
|
+
export const transformRealizeDecoratorHistories = (
|
|
9
|
+
ctx: AutoBeContext<ILlmSchema.Model>,
|
|
10
|
+
role: string,
|
|
11
|
+
): Array<
|
|
12
|
+
IAgenticaHistoryJson.IAssistantMessage | IAgenticaHistoryJson.ISystemMessage
|
|
13
|
+
> => {
|
|
14
|
+
return [
|
|
15
|
+
{
|
|
16
|
+
id: v4(),
|
|
17
|
+
created_at: new Date().toISOString(),
|
|
18
|
+
type: "systemMessage",
|
|
19
|
+
text: AutoBeSystemPromptConstant.REALIZE_DECORATOR,
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: v4(),
|
|
23
|
+
created_at: new Date().toISOString(),
|
|
24
|
+
type: "systemMessage",
|
|
25
|
+
text: [
|
|
26
|
+
"## Role",
|
|
27
|
+
"",
|
|
28
|
+
role,
|
|
29
|
+
"",
|
|
30
|
+
"## Prisma Schema",
|
|
31
|
+
"",
|
|
32
|
+
JSON.stringify(ctx.state().prisma?.schemas, null, 2),
|
|
33
|
+
"",
|
|
34
|
+
].join("\n"),
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { IAgenticaHistoryJson } from "@agentica/core";
|
|
2
|
+
import { IAutoBeTypeScriptCompileResult } from "@autobe/interface";
|
|
3
|
+
import { ILlmSchema } from "@samchon/openapi";
|
|
4
|
+
import { v4 } from "uuid";
|
|
5
|
+
|
|
6
|
+
import { AutoBeSystemPromptConstant } from "../../constants/AutoBeSystemPromptConstant";
|
|
7
|
+
import { AutoBeContext } from "../../context/AutoBeContext";
|
|
8
|
+
import { IAutoBeRealizeDecoratorApplication } from "./structures/IAutoBeRealizeDecoratorApplication";
|
|
9
|
+
|
|
10
|
+
export const transformRealizeDecoratorCorrectHistories = (
|
|
11
|
+
ctx: AutoBeContext<ILlmSchema.Model>,
|
|
12
|
+
result: IAutoBeRealizeDecoratorApplication.IProps,
|
|
13
|
+
templateFiles: Record<string, string>,
|
|
14
|
+
diagnostics: IAutoBeTypeScriptCompileResult.IDiagnostic[],
|
|
15
|
+
): Array<
|
|
16
|
+
IAgenticaHistoryJson.IAssistantMessage | IAgenticaHistoryJson.ISystemMessage
|
|
17
|
+
> => {
|
|
18
|
+
return [
|
|
19
|
+
{
|
|
20
|
+
id: v4(),
|
|
21
|
+
created_at: new Date().toISOString(),
|
|
22
|
+
type: "systemMessage",
|
|
23
|
+
text: AutoBeSystemPromptConstant.REALIZE_DECORATOR_CORRECT,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
id: v4(),
|
|
27
|
+
created_at: new Date().toISOString(),
|
|
28
|
+
type: "assistantMessage",
|
|
29
|
+
text: [
|
|
30
|
+
"## Generated TypeScript Code",
|
|
31
|
+
"",
|
|
32
|
+
"```json",
|
|
33
|
+
`${JSON.stringify(result, null, 2)}`,
|
|
34
|
+
"```",
|
|
35
|
+
"",
|
|
36
|
+
"## Prisma Schema",
|
|
37
|
+
"",
|
|
38
|
+
"```json",
|
|
39
|
+
`${JSON.stringify(ctx.state().prisma?.schemas, null, 2)}`,
|
|
40
|
+
"```",
|
|
41
|
+
"",
|
|
42
|
+
"## File Paths",
|
|
43
|
+
"",
|
|
44
|
+
Object.keys(templateFiles)
|
|
45
|
+
.map((path) => `- ${path}`)
|
|
46
|
+
.join("\n"),
|
|
47
|
+
"",
|
|
48
|
+
"## Compile Errors",
|
|
49
|
+
"",
|
|
50
|
+
"Fix the compilation error in the provided code.",
|
|
51
|
+
"",
|
|
52
|
+
"```json",
|
|
53
|
+
JSON.stringify(diagnostics, null, 2),
|
|
54
|
+
"```",
|
|
55
|
+
].join("\n"),
|
|
56
|
+
},
|
|
57
|
+
];
|
|
58
|
+
};
|
|
@@ -19,7 +19,7 @@ export async function writeCodeUntilCompilePassed<
|
|
|
19
19
|
>(
|
|
20
20
|
ctx: AutoBeContext<Model>,
|
|
21
21
|
ops: AutoBeOpenApi.IOperation[],
|
|
22
|
-
retry: number =
|
|
22
|
+
retry: number = 3,
|
|
23
23
|
): Promise<
|
|
24
24
|
Pick<
|
|
25
25
|
IAutoBeRealizeCoderApplication.RealizeCoderOutput,
|
|
@@ -45,14 +45,20 @@ export async function writeCodeUntilCompilePassed<
|
|
|
45
45
|
total: [],
|
|
46
46
|
};
|
|
47
47
|
|
|
48
|
+
ops = ops.filter((_el, i) => i < 10);
|
|
48
49
|
for (let i = 0; i < retry; i++) {
|
|
50
|
+
const targets = ops.filter((op) =>
|
|
51
|
+
shouldProcessOperation(op, diagnostics.current),
|
|
52
|
+
);
|
|
53
|
+
|
|
54
|
+
const metadata = { total: targets.length, count: 0 };
|
|
49
55
|
const generatedCodes: (
|
|
50
56
|
| IAutoBeRealizeCompile.Success
|
|
51
57
|
| IAutoBeRealizeCompile.Fail
|
|
52
58
|
)[] = await Promise.all(
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
59
|
+
targets.map((op) => {
|
|
60
|
+
return process(ctx, metadata, op, diagnostics, entireCodes);
|
|
61
|
+
}),
|
|
56
62
|
);
|
|
57
63
|
|
|
58
64
|
for (const c of generatedCodes) {
|
|
@@ -93,7 +99,11 @@ export async function writeCodeUntilCompilePassed<
|
|
|
93
99
|
diagnostics.current = compiled.diagnostics;
|
|
94
100
|
diagnostics.total = [...diagnostics.total, ...compiled.diagnostics];
|
|
95
101
|
|
|
96
|
-
console.log(
|
|
102
|
+
console.log(
|
|
103
|
+
JSON.stringify(diagnostics.current, null, 2),
|
|
104
|
+
`현재 에러의 수: ${diagnostics.current.length}\n`,
|
|
105
|
+
`현재 시도 수: ${i}`,
|
|
106
|
+
);
|
|
97
107
|
}
|
|
98
108
|
}
|
|
99
109
|
|
|
@@ -129,6 +139,7 @@ async function loadTemplateFiles(
|
|
|
129
139
|
|
|
130
140
|
async function process<Model extends ILlmSchema.Model>(
|
|
131
141
|
ctx: AutoBeContext<Model>,
|
|
142
|
+
metadata: { total: number; count: number },
|
|
132
143
|
op: AutoBeOpenApi.IOperation,
|
|
133
144
|
diagnostics: IAutoBeRealizeCompile.CompileDiagnostics,
|
|
134
145
|
entireCodes: IAutoBeRealizeCompile.FileContentMap,
|
|
@@ -136,22 +147,36 @@ async function process<Model extends ILlmSchema.Model>(
|
|
|
136
147
|
const result = await pipe(
|
|
137
148
|
op,
|
|
138
149
|
(op) => orchestrateRealizePlanner(ctx, op),
|
|
139
|
-
(p) => {
|
|
150
|
+
async (p) => {
|
|
140
151
|
const filename = `src/providers/${p.functionName}.ts` as const;
|
|
141
152
|
const t = diagnostics.total.filter((el) => el.file === filename);
|
|
142
153
|
|
|
143
154
|
const d = diagnostics.current.filter((el) => el.file === filename);
|
|
144
155
|
const c = entireCodes[filename]?.content ?? null;
|
|
145
156
|
|
|
146
|
-
return orchestrateRealizeCoder(ctx, op, p, c, t, d)
|
|
157
|
+
return orchestrateRealizeCoder(ctx, op, p, c, t, d).then((res) => {
|
|
158
|
+
if (res === FAILED) {
|
|
159
|
+
} else {
|
|
160
|
+
ctx.dispatch({
|
|
161
|
+
type: "realizeProgress",
|
|
162
|
+
filename: res.filename,
|
|
163
|
+
content: res.implementationCode,
|
|
164
|
+
completed: ++metadata.count,
|
|
165
|
+
created_at: new Date().toISOString(),
|
|
166
|
+
step: ctx.state().analyze?.step ?? 0,
|
|
167
|
+
total: metadata.total,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return res;
|
|
171
|
+
});
|
|
147
172
|
},
|
|
148
173
|
);
|
|
149
174
|
|
|
150
175
|
if (result === FAILED) {
|
|
151
|
-
return { type: "failed", op, result } as const;
|
|
176
|
+
return { type: "failed", op: op, result } as const;
|
|
152
177
|
}
|
|
153
178
|
|
|
154
|
-
return { type: "success", op, result: result } as const;
|
|
179
|
+
return { type: "success", op: op, result: result } as const;
|
|
155
180
|
}
|
|
156
181
|
|
|
157
182
|
function shouldProcessOperation(
|
|
@@ -85,7 +85,7 @@ const predicate = async <Model extends ILlmSchema.Model>(
|
|
|
85
85
|
event: AutoBeTestValidateEvent,
|
|
86
86
|
life: number,
|
|
87
87
|
): Promise<AutoBeTestValidateEvent> => {
|
|
88
|
-
ctx.dispatch(event);
|
|
88
|
+
if (event.result.type === "failure") ctx.dispatch(event);
|
|
89
89
|
return event.result.type === "failure"
|
|
90
90
|
? correct(ctx, content, event, life - 1)
|
|
91
91
|
: event;
|
|
@@ -1,7 +1,63 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Random exponential backoff retry utility for handling rate limits
|
|
3
|
+
*/
|
|
4
|
+
export interface RetryOptions {
|
|
5
|
+
/** Maximum number of retry attempts (default: 5) */
|
|
6
|
+
maxRetries: number;
|
|
7
|
+
/** Base delay in milliseconds (default: 2000) */
|
|
8
|
+
baseDelay: number;
|
|
9
|
+
/** Maximum delay in milliseconds (default: 60_000) */
|
|
10
|
+
maxDelay: number;
|
|
11
|
+
/** Jitter factor for randomization (0-1, default: 0.3) */
|
|
12
|
+
jitter: number;
|
|
13
|
+
/** Function to determine if error should trigger retry (default: isRetryError) */
|
|
14
|
+
handleError: (error: any) => boolean;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* @param fn Function to Apply the retry logic.
|
|
19
|
+
* @param maxRetries How many time to try. Max Retry is 5.
|
|
20
|
+
* @returns
|
|
21
|
+
*/
|
|
22
|
+
export async function randomBackoffRetry<T>(
|
|
23
|
+
fn: () => Promise<T>,
|
|
24
|
+
options: Partial<RetryOptions> = {},
|
|
25
|
+
): Promise<T> {
|
|
26
|
+
const {
|
|
27
|
+
maxRetries = 5,
|
|
28
|
+
baseDelay = 4_000,
|
|
29
|
+
maxDelay = 60_000,
|
|
30
|
+
jitter = 0.8,
|
|
31
|
+
handleError = isRetryError,
|
|
32
|
+
} = options;
|
|
33
|
+
|
|
34
|
+
let lastError: unknown;
|
|
35
|
+
|
|
36
|
+
for (let attempt = 0; attempt < maxRetries; attempt++) {
|
|
37
|
+
try {
|
|
38
|
+
return await fn();
|
|
39
|
+
} catch (err) {
|
|
40
|
+
lastError = err;
|
|
41
|
+
|
|
42
|
+
if (attempt === maxRetries - 1) throw err;
|
|
43
|
+
|
|
44
|
+
if (!handleError(err)) throw err;
|
|
45
|
+
|
|
46
|
+
const tempDelay = Math.min(baseDelay * 2 ** attempt, maxDelay);
|
|
47
|
+
const delay = tempDelay * (1 + Math.random() * jitter);
|
|
48
|
+
|
|
49
|
+
await new Promise((res) => setTimeout(res, delay));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
throw lastError;
|
|
54
|
+
}
|
|
55
|
+
|
|
1
56
|
export function randomBackoffStrategy(props: {
|
|
2
57
|
count: number;
|
|
3
58
|
error: unknown;
|
|
4
59
|
}): number {
|
|
60
|
+
console.log("randomBackoffStrategy");
|
|
5
61
|
const { count, error } = props;
|
|
6
62
|
if (count > 5) {
|
|
7
63
|
throw error;
|