Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

constants.ts 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598
  1. import type { Var } from './types'
  2. import { BlockEnum, VarType } from './types'
  3. import StartNodeDefault from './nodes/start/default'
  4. import AnswerDefault from './nodes/answer/default'
  5. import LLMDefault from './nodes/llm/default'
  6. import KnowledgeRetrievalDefault from './nodes/knowledge-retrieval/default'
  7. import QuestionClassifierDefault from './nodes/question-classifier/default'
  8. import IfElseDefault from './nodes/if-else/default'
  9. import CodeDefault from './nodes/code/default'
  10. import TemplateTransformDefault from './nodes/template-transform/default'
  11. import HttpRequestDefault from './nodes/http/default'
  12. import ParameterExtractorDefault from './nodes/parameter-extractor/default'
  13. import ToolDefault from './nodes/tool/default'
  14. import VariableAssignerDefault from './nodes/variable-assigner/default'
  15. import AssignerDefault from './nodes/assigner/default'
  16. import EndNodeDefault from './nodes/end/default'
  17. import IterationDefault from './nodes/iteration/default'
  18. import LoopDefault from './nodes/loop/default'
  19. import DocExtractorDefault from './nodes/document-extractor/default'
  20. import ListFilterDefault from './nodes/list-operator/default'
  21. import IterationStartDefault from './nodes/iteration-start/default'
  22. import AgentDefault from './nodes/agent/default'
  23. import LoopStartDefault from './nodes/loop-start/default'
  24. import LoopEndDefault from './nodes/loop-end/default'
  25. type NodesExtraData = {
  26. author: string
  27. about: string
  28. availablePrevNodes: BlockEnum[]
  29. availableNextNodes: BlockEnum[]
  30. getAvailablePrevNodes: (isChatMode: boolean) => BlockEnum[]
  31. getAvailableNextNodes: (isChatMode: boolean) => BlockEnum[]
  32. checkValid: any
  33. defaultRunInputData?: Record<string, any>
  34. }
  35. export const NODES_EXTRA_DATA: Record<BlockEnum, NodesExtraData> = {
  36. [BlockEnum.Start]: {
  37. author: 'Dify',
  38. about: '',
  39. availablePrevNodes: [],
  40. availableNextNodes: [],
  41. getAvailablePrevNodes: StartNodeDefault.getAvailablePrevNodes,
  42. getAvailableNextNodes: StartNodeDefault.getAvailableNextNodes,
  43. checkValid: StartNodeDefault.checkValid,
  44. },
  45. [BlockEnum.End]: {
  46. author: 'Dify',
  47. about: '',
  48. availablePrevNodes: [],
  49. availableNextNodes: [],
  50. getAvailablePrevNodes: EndNodeDefault.getAvailablePrevNodes,
  51. getAvailableNextNodes: EndNodeDefault.getAvailableNextNodes,
  52. checkValid: EndNodeDefault.checkValid,
  53. },
  54. [BlockEnum.Answer]: {
  55. author: 'Dify',
  56. about: '',
  57. availablePrevNodes: [],
  58. availableNextNodes: [],
  59. getAvailablePrevNodes: AnswerDefault.getAvailablePrevNodes,
  60. getAvailableNextNodes: AnswerDefault.getAvailableNextNodes,
  61. checkValid: AnswerDefault.checkValid,
  62. },
  63. [BlockEnum.LLM]: {
  64. author: 'Dify',
  65. about: '',
  66. availablePrevNodes: [],
  67. availableNextNodes: [],
  68. getAvailablePrevNodes: LLMDefault.getAvailablePrevNodes,
  69. getAvailableNextNodes: LLMDefault.getAvailableNextNodes,
  70. checkValid: LLMDefault.checkValid,
  71. defaultRunInputData: LLMDefault.defaultRunInputData,
  72. },
  73. [BlockEnum.KnowledgeRetrieval]: {
  74. author: 'Dify',
  75. about: '',
  76. availablePrevNodes: [],
  77. availableNextNodes: [],
  78. getAvailablePrevNodes: KnowledgeRetrievalDefault.getAvailablePrevNodes,
  79. getAvailableNextNodes: KnowledgeRetrievalDefault.getAvailableNextNodes,
  80. checkValid: KnowledgeRetrievalDefault.checkValid,
  81. },
  82. [BlockEnum.IfElse]: {
  83. author: 'Dify',
  84. about: '',
  85. availablePrevNodes: [],
  86. availableNextNodes: [],
  87. getAvailablePrevNodes: IfElseDefault.getAvailablePrevNodes,
  88. getAvailableNextNodes: IfElseDefault.getAvailableNextNodes,
  89. checkValid: IfElseDefault.checkValid,
  90. },
  91. [BlockEnum.Iteration]: {
  92. author: 'Dify',
  93. about: '',
  94. availablePrevNodes: [],
  95. availableNextNodes: [],
  96. getAvailablePrevNodes: IterationDefault.getAvailablePrevNodes,
  97. getAvailableNextNodes: IterationDefault.getAvailableNextNodes,
  98. checkValid: IterationDefault.checkValid,
  99. },
  100. [BlockEnum.IterationStart]: {
  101. author: 'Dify',
  102. about: '',
  103. availablePrevNodes: [],
  104. availableNextNodes: [],
  105. getAvailablePrevNodes: IterationStartDefault.getAvailablePrevNodes,
  106. getAvailableNextNodes: IterationStartDefault.getAvailableNextNodes,
  107. checkValid: IterationStartDefault.checkValid,
  108. },
  109. [BlockEnum.Loop]: {
  110. author: 'AICT-Team',
  111. about: '',
  112. availablePrevNodes: [],
  113. availableNextNodes: [],
  114. getAvailablePrevNodes: LoopDefault.getAvailablePrevNodes,
  115. getAvailableNextNodes: LoopDefault.getAvailableNextNodes,
  116. checkValid: LoopDefault.checkValid,
  117. },
  118. [BlockEnum.LoopStart]: {
  119. author: 'AICT-Team',
  120. about: '',
  121. availablePrevNodes: [],
  122. availableNextNodes: [],
  123. getAvailablePrevNodes: LoopStartDefault.getAvailablePrevNodes,
  124. getAvailableNextNodes: LoopStartDefault.getAvailableNextNodes,
  125. checkValid: LoopStartDefault.checkValid,
  126. },
  127. [BlockEnum.LoopEnd]: {
  128. author: 'Dify',
  129. about: '',
  130. availablePrevNodes: [],
  131. availableNextNodes: [],
  132. getAvailablePrevNodes: LoopEndDefault.getAvailablePrevNodes,
  133. getAvailableNextNodes: LoopEndDefault.getAvailableNextNodes,
  134. checkValid: LoopEndDefault.checkValid,
  135. },
  136. [BlockEnum.Code]: {
  137. author: 'Dify',
  138. about: '',
  139. availablePrevNodes: [],
  140. availableNextNodes: [],
  141. getAvailablePrevNodes: CodeDefault.getAvailablePrevNodes,
  142. getAvailableNextNodes: CodeDefault.getAvailableNextNodes,
  143. checkValid: CodeDefault.checkValid,
  144. },
  145. [BlockEnum.TemplateTransform]: {
  146. author: 'Dify',
  147. about: '',
  148. availablePrevNodes: [],
  149. availableNextNodes: [],
  150. getAvailablePrevNodes: TemplateTransformDefault.getAvailablePrevNodes,
  151. getAvailableNextNodes: TemplateTransformDefault.getAvailableNextNodes,
  152. checkValid: TemplateTransformDefault.checkValid,
  153. },
  154. [BlockEnum.QuestionClassifier]: {
  155. author: 'Dify',
  156. about: '',
  157. availablePrevNodes: [],
  158. availableNextNodes: [],
  159. getAvailablePrevNodes: QuestionClassifierDefault.getAvailablePrevNodes,
  160. getAvailableNextNodes: QuestionClassifierDefault.getAvailableNextNodes,
  161. checkValid: QuestionClassifierDefault.checkValid,
  162. },
  163. [BlockEnum.HttpRequest]: {
  164. author: 'Dify',
  165. about: '',
  166. availablePrevNodes: [],
  167. availableNextNodes: [],
  168. getAvailablePrevNodes: HttpRequestDefault.getAvailablePrevNodes,
  169. getAvailableNextNodes: HttpRequestDefault.getAvailableNextNodes,
  170. checkValid: HttpRequestDefault.checkValid,
  171. },
  172. [BlockEnum.VariableAssigner]: {
  173. author: 'Dify',
  174. about: '',
  175. availablePrevNodes: [],
  176. availableNextNodes: [],
  177. getAvailablePrevNodes: VariableAssignerDefault.getAvailablePrevNodes,
  178. getAvailableNextNodes: VariableAssignerDefault.getAvailableNextNodes,
  179. checkValid: VariableAssignerDefault.checkValid,
  180. },
  181. [BlockEnum.Assigner]: {
  182. author: 'Dify',
  183. about: '',
  184. availablePrevNodes: [],
  185. availableNextNodes: [],
  186. getAvailablePrevNodes: AssignerDefault.getAvailablePrevNodes,
  187. getAvailableNextNodes: AssignerDefault.getAvailableNextNodes,
  188. checkValid: AssignerDefault.checkValid,
  189. },
  190. [BlockEnum.VariableAggregator]: {
  191. author: 'Dify',
  192. about: '',
  193. availablePrevNodes: [],
  194. availableNextNodes: [],
  195. getAvailablePrevNodes: VariableAssignerDefault.getAvailablePrevNodes,
  196. getAvailableNextNodes: VariableAssignerDefault.getAvailableNextNodes,
  197. checkValid: VariableAssignerDefault.checkValid,
  198. },
  199. [BlockEnum.ParameterExtractor]: {
  200. author: 'Dify',
  201. about: '',
  202. availablePrevNodes: [],
  203. availableNextNodes: [],
  204. getAvailablePrevNodes: ParameterExtractorDefault.getAvailablePrevNodes,
  205. getAvailableNextNodes: ParameterExtractorDefault.getAvailableNextNodes,
  206. checkValid: ParameterExtractorDefault.checkValid,
  207. },
  208. [BlockEnum.Tool]: {
  209. author: 'Dify',
  210. about: '',
  211. availablePrevNodes: [],
  212. availableNextNodes: [],
  213. getAvailablePrevNodes: ToolDefault.getAvailablePrevNodes,
  214. getAvailableNextNodes: ToolDefault.getAvailableNextNodes,
  215. checkValid: ToolDefault.checkValid,
  216. },
  217. [BlockEnum.DocExtractor]: {
  218. author: 'Dify',
  219. about: '',
  220. availablePrevNodes: [],
  221. availableNextNodes: [],
  222. getAvailablePrevNodes: DocExtractorDefault.getAvailablePrevNodes,
  223. getAvailableNextNodes: DocExtractorDefault.getAvailableNextNodes,
  224. checkValid: DocExtractorDefault.checkValid,
  225. },
  226. [BlockEnum.ListFilter]: {
  227. author: 'Dify',
  228. about: '',
  229. availablePrevNodes: [],
  230. availableNextNodes: [],
  231. getAvailablePrevNodes: ListFilterDefault.getAvailablePrevNodes,
  232. getAvailableNextNodes: ListFilterDefault.getAvailableNextNodes,
  233. checkValid: ListFilterDefault.checkValid,
  234. },
  235. [BlockEnum.Agent]: {
  236. author: 'Dify',
  237. about: '',
  238. availablePrevNodes: [],
  239. availableNextNodes: [],
  240. getAvailablePrevNodes: ListFilterDefault.getAvailablePrevNodes,
  241. getAvailableNextNodes: ListFilterDefault.getAvailableNextNodes,
  242. checkValid: AgentDefault.checkValid,
  243. },
  244. }
  245. export const NODES_INITIAL_DATA = {
  246. [BlockEnum.Start]: {
  247. type: BlockEnum.Start,
  248. title: '',
  249. desc: '',
  250. ...StartNodeDefault.defaultValue,
  251. },
  252. [BlockEnum.End]: {
  253. type: BlockEnum.End,
  254. title: '',
  255. desc: '',
  256. ...EndNodeDefault.defaultValue,
  257. },
  258. [BlockEnum.Answer]: {
  259. type: BlockEnum.Answer,
  260. title: '',
  261. desc: '',
  262. ...AnswerDefault.defaultValue,
  263. },
  264. [BlockEnum.LLM]: {
  265. type: BlockEnum.LLM,
  266. title: '',
  267. desc: '',
  268. variables: [],
  269. ...LLMDefault.defaultValue,
  270. },
  271. [BlockEnum.KnowledgeRetrieval]: {
  272. type: BlockEnum.KnowledgeRetrieval,
  273. title: '',
  274. desc: '',
  275. query_variable_selector: [],
  276. dataset_ids: [],
  277. retrieval_mode: 'single',
  278. ...KnowledgeRetrievalDefault.defaultValue,
  279. },
  280. [BlockEnum.IfElse]: {
  281. type: BlockEnum.IfElse,
  282. title: '',
  283. desc: '',
  284. ...IfElseDefault.defaultValue,
  285. },
  286. [BlockEnum.Iteration]: {
  287. type: BlockEnum.Iteration,
  288. title: '',
  289. desc: '',
  290. ...IterationDefault.defaultValue,
  291. },
  292. [BlockEnum.IterationStart]: {
  293. type: BlockEnum.IterationStart,
  294. title: '',
  295. desc: '',
  296. ...IterationStartDefault.defaultValue,
  297. },
  298. [BlockEnum.Loop]: {
  299. type: BlockEnum.Loop,
  300. title: '',
  301. desc: '',
  302. ...LoopDefault.defaultValue,
  303. },
  304. [BlockEnum.LoopStart]: {
  305. type: BlockEnum.LoopStart,
  306. title: '',
  307. desc: '',
  308. ...LoopStartDefault.defaultValue,
  309. },
  310. [BlockEnum.LoopEnd]: {
  311. type: BlockEnum.LoopEnd,
  312. title: '',
  313. desc: '',
  314. ...LoopEndDefault.defaultValue,
  315. },
  316. [BlockEnum.Code]: {
  317. type: BlockEnum.Code,
  318. title: '',
  319. desc: '',
  320. variables: [],
  321. code_language: 'python3',
  322. code: '',
  323. outputs: [],
  324. ...CodeDefault.defaultValue,
  325. },
  326. [BlockEnum.TemplateTransform]: {
  327. type: BlockEnum.TemplateTransform,
  328. title: '',
  329. desc: '',
  330. variables: [],
  331. template: '',
  332. ...TemplateTransformDefault.defaultValue,
  333. },
  334. [BlockEnum.QuestionClassifier]: {
  335. type: BlockEnum.QuestionClassifier,
  336. title: '',
  337. desc: '',
  338. query_variable_selector: [],
  339. topics: [],
  340. ...QuestionClassifierDefault.defaultValue,
  341. },
  342. [BlockEnum.HttpRequest]: {
  343. type: BlockEnum.HttpRequest,
  344. title: '',
  345. desc: '',
  346. variables: [],
  347. ...HttpRequestDefault.defaultValue,
  348. },
  349. [BlockEnum.ParameterExtractor]: {
  350. type: BlockEnum.ParameterExtractor,
  351. title: '',
  352. desc: '',
  353. variables: [],
  354. ...ParameterExtractorDefault.defaultValue,
  355. },
  356. [BlockEnum.VariableAssigner]: {
  357. type: BlockEnum.VariableAssigner,
  358. title: '',
  359. desc: '',
  360. variables: [],
  361. output_type: '',
  362. ...VariableAssignerDefault.defaultValue,
  363. },
  364. [BlockEnum.VariableAggregator]: {
  365. type: BlockEnum.VariableAggregator,
  366. title: '',
  367. desc: '',
  368. variables: [],
  369. output_type: '',
  370. ...VariableAssignerDefault.defaultValue,
  371. },
  372. [BlockEnum.Assigner]: {
  373. type: BlockEnum.Assigner,
  374. title: '',
  375. desc: '',
  376. ...AssignerDefault.defaultValue,
  377. },
  378. [BlockEnum.Tool]: {
  379. type: BlockEnum.Tool,
  380. title: '',
  381. desc: '',
  382. ...ToolDefault.defaultValue,
  383. },
  384. [BlockEnum.DocExtractor]: {
  385. type: BlockEnum.DocExtractor,
  386. title: '',
  387. desc: '',
  388. ...DocExtractorDefault.defaultValue,
  389. },
  390. [BlockEnum.ListFilter]: {
  391. type: BlockEnum.ListFilter,
  392. title: '',
  393. desc: '',
  394. ...ListFilterDefault.defaultValue,
  395. },
  396. [BlockEnum.Agent]: {
  397. type: BlockEnum.Agent,
  398. title: '',
  399. desc: '',
  400. ...AgentDefault.defaultValue,
  401. },
  402. }
  403. export const MAX_ITERATION_PARALLEL_NUM = 10
  404. export const MIN_ITERATION_PARALLEL_NUM = 1
  405. export const DEFAULT_ITER_TIMES = 1
  406. export const DEFAULT_LOOP_TIMES = 1
  407. export const NODE_WIDTH = 240
  408. export const X_OFFSET = 60
  409. export const NODE_WIDTH_X_OFFSET = NODE_WIDTH + X_OFFSET
  410. export const Y_OFFSET = 39
  411. export const START_INITIAL_POSITION = { x: 80, y: 282 }
  412. export const AUTO_LAYOUT_OFFSET = {
  413. x: -42,
  414. y: 243,
  415. }
  416. export const ITERATION_NODE_Z_INDEX = 1
  417. export const ITERATION_CHILDREN_Z_INDEX = 1002
  418. export const ITERATION_PADDING = {
  419. top: 65,
  420. right: 16,
  421. bottom: 20,
  422. left: 16,
  423. }
  424. export const LOOP_NODE_Z_INDEX = 1
  425. export const LOOP_CHILDREN_Z_INDEX = 1002
  426. export const LOOP_PADDING = {
  427. top: 65,
  428. right: 16,
  429. bottom: 20,
  430. left: 16,
  431. }
  432. export const NODE_LAYOUT_HORIZONTAL_PADDING = 60
  433. export const NODE_LAYOUT_VERTICAL_PADDING = 60
  434. export const NODE_LAYOUT_MIN_DISTANCE = 100
  435. let maxParallelLimit = 10
  436. if (process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT && process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT !== '')
  437. maxParallelLimit = Number.parseInt(process.env.NEXT_PUBLIC_MAX_PARALLEL_LIMIT)
  438. else if (globalThis.document?.body?.getAttribute('data-public-max-parallel-limit') && globalThis.document.body.getAttribute('data-public-max-parallel-limit') !== '')
  439. maxParallelLimit = Number.parseInt(globalThis.document.body.getAttribute('data-public-max-parallel-limit') as string)
  440. export const PARALLEL_LIMIT = maxParallelLimit
  441. export const PARALLEL_DEPTH_LIMIT = 3
  442. export const RETRIEVAL_OUTPUT_STRUCT = `{
  443. "content": "",
  444. "title": "",
  445. "url": "",
  446. "icon": "",
  447. "metadata": {
  448. "dataset_id": "",
  449. "dataset_name": "",
  450. "document_id": [],
  451. "document_name": "",
  452. "document_data_source_type": "",
  453. "segment_id": "",
  454. "segment_position": "",
  455. "segment_word_count": "",
  456. "segment_hit_count": "",
  457. "segment_index_node_hash": "",
  458. "score": ""
  459. }
  460. }`
  461. export const SUPPORT_OUTPUT_VARS_NODE = [
  462. BlockEnum.Start, BlockEnum.LLM, BlockEnum.KnowledgeRetrieval, BlockEnum.Code, BlockEnum.TemplateTransform,
  463. BlockEnum.HttpRequest, BlockEnum.Tool, BlockEnum.VariableAssigner, BlockEnum.VariableAggregator, BlockEnum.QuestionClassifier,
  464. BlockEnum.ParameterExtractor, BlockEnum.Iteration, BlockEnum.Loop,
  465. BlockEnum.DocExtractor, BlockEnum.ListFilter,
  466. BlockEnum.Agent,
  467. ]
  468. export const LLM_OUTPUT_STRUCT: Var[] = [
  469. {
  470. variable: 'text',
  471. type: VarType.string,
  472. },
  473. ]
  474. export const KNOWLEDGE_RETRIEVAL_OUTPUT_STRUCT: Var[] = [
  475. {
  476. variable: 'result',
  477. type: VarType.arrayObject,
  478. },
  479. ]
  480. export const TEMPLATE_TRANSFORM_OUTPUT_STRUCT: Var[] = [
  481. {
  482. variable: 'output',
  483. type: VarType.string,
  484. },
  485. ]
  486. export const QUESTION_CLASSIFIER_OUTPUT_STRUCT = [
  487. {
  488. variable: 'class_name',
  489. type: VarType.string,
  490. },
  491. ]
  492. export const HTTP_REQUEST_OUTPUT_STRUCT: Var[] = [
  493. {
  494. variable: 'body',
  495. type: VarType.string,
  496. },
  497. {
  498. variable: 'status_code',
  499. type: VarType.number,
  500. },
  501. {
  502. variable: 'headers',
  503. type: VarType.object,
  504. },
  505. {
  506. variable: 'files',
  507. type: VarType.arrayFile,
  508. },
  509. ]
  510. export const TOOL_OUTPUT_STRUCT: Var[] = [
  511. {
  512. variable: 'text',
  513. type: VarType.string,
  514. },
  515. {
  516. variable: 'files',
  517. type: VarType.arrayFile,
  518. },
  519. {
  520. variable: 'json',
  521. type: VarType.arrayObject,
  522. },
  523. ]
  524. export const PARAMETER_EXTRACTOR_COMMON_STRUCT: Var[] = [
  525. {
  526. variable: '__is_success',
  527. type: VarType.number,
  528. },
  529. {
  530. variable: '__reason',
  531. type: VarType.string,
  532. },
  533. ]
  534. export const FILE_STRUCT: Var[] = [
  535. {
  536. variable: 'name',
  537. type: VarType.string,
  538. },
  539. {
  540. variable: 'size',
  541. type: VarType.number,
  542. },
  543. {
  544. variable: 'type',
  545. type: VarType.string,
  546. },
  547. {
  548. variable: 'extension',
  549. type: VarType.string,
  550. },
  551. {
  552. variable: 'mime_type',
  553. type: VarType.string,
  554. },
  555. {
  556. variable: 'transfer_method',
  557. type: VarType.string,
  558. },
  559. {
  560. variable: 'url',
  561. type: VarType.string,
  562. },
  563. {
  564. variable: 'related_id',
  565. type: VarType.string,
  566. },
  567. ]
  568. export const DEFAULT_FILE_UPLOAD_SETTING = {
  569. allowed_file_upload_methods: ['local_file', 'remote_url'],
  570. max_length: 5,
  571. allowed_file_types: ['image'],
  572. allowed_file_extensions: [],
  573. }
  574. export const WORKFLOW_DATA_UPDATE = 'WORKFLOW_DATA_UPDATE'
  575. export const CUSTOM_NODE = 'custom'
  576. export const CUSTOM_EDGE = 'custom'
  577. export const DSL_EXPORT_CHECK = 'DSL_EXPORT_CHECK'
  578. export const DEFAULT_RETRY_MAX = 3
  579. export const DEFAULT_RETRY_INTERVAL = 100